4 * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
15 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
16 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 #include <sys/types.h>
29 * Config file parser. Pretty quick and simple, each line is parsed into a
30 * argv array and executed as a command.
33 void printflike2
cfg_print(struct cmd_ctx
*, const char *, ...);
34 void printflike2
cfg_error(struct cmd_ctx
*, const char *, ...);
38 struct causelist cfg_causes
= ARRAY_INITIALIZER
;
42 cfg_print(unused
struct cmd_ctx
*ctx
, unused
const char *fmt
, ...)
48 cfg_error(unused
struct cmd_ctx
*ctx
, const char *fmt
, ...)
53 xvasprintf(&cfg_cause
, fmt
, ap
);
58 cfg_add_cause(struct causelist
*causes
, const char *fmt
, ...)
64 xvasprintf(&cause
, fmt
, ap
);
67 ARRAY_ADD(causes
, cause
);
71 * Load configuration file. Returns -1 for an error with a list of messages in
72 * causes. Note that causes must be initialised by the caller!
75 load_cfg(const char *path
, struct cmd_ctx
*ctxin
, struct causelist
*causes
)
79 char *buf
, *line
, *cause
;
81 struct cmd_list
*cmdlist
;
85 if ((f
= fopen(path
, "rb")) == NULL
) {
86 cfg_add_cause(causes
, "%s: %s", path
, strerror(errno
));
93 while ((buf
= fgetln(f
, &len
))) {
94 if (buf
[len
- 1] == '\n')
98 line
= xrealloc(line
, 1, strlen(line
) + len
+ 1);
100 line
= xmalloc(len
+ 1);
104 /* Append buffer to line. strncat will terminate. */
105 strncat(line
, buf
, len
);
108 /* Continuation: get next line? */
110 if (len
> 0 && line
[len
- 1] == '\\') {
111 line
[len
- 1] = '\0';
117 if (cmd_string_parse(buf
, &cmdlist
, &cause
) != 0) {
121 cfg_add_cause(causes
, "%s: %u: %s", path
, n
, cause
);
132 ctx
.curclient
= NULL
;
133 ctx
.cmdclient
= NULL
;
135 ctx
.msgdata
= ctxin
->msgdata
;
136 ctx
.curclient
= ctxin
->curclient
;
137 ctx
.cmdclient
= ctxin
->cmdclient
;
140 ctx
.error
= cfg_error
;
141 ctx
.print
= cfg_print
;
142 ctx
.info
= cfg_print
;
145 if (cmd_list_exec(cmdlist
, &ctx
) == 1)
147 cmd_list_free(cmdlist
);
148 if (cfg_cause
!= NULL
) {
150 causes
, "%s: %d: %s", path
, n
, cfg_cause
);
155 cfg_add_cause(causes
,
156 "%s: %d: line continuation at end of file", path
, n
);