7 /* configuration parser utilities
9 /* #include "cfg_parser.h"
11 /* CFG_PARSER *cfg_parser_alloc(pname)
14 /* CFG_PARSER *cfg_parser_free(parser)
15 /* CFG_PARSER *parser;
17 /* char *cfg_get_str(parser, name, defval, min, max)
18 /* const CFG_PARSER *parser;
20 /* const char *defval;
24 /* int cfg_get_int(parser, name, defval, min, max)
25 /* const CFG_PARSER *parser;
31 /* int cfg_get_bool(parser, name, defval)
32 /* const CFG_PARSER *parser;
36 /* This module implements utilities for parsing parameters defined
37 /* either as "\fIname\fR = \fBvalue\fR" in a file pointed to by
38 /* \fIpname\fR (the old MySQL style), or as "\fIpname\fR_\fIname\fR =
39 /* \fBvalue\fR" in main.cf (the old LDAP style). It unifies the
40 /* two styles and provides support for range checking.
42 /* \fIcfg_parser_alloc\fR initializes the parser.
44 /* \fIcfg_parser_free\fR releases the parser.
46 /* \fIcfg_get_str\fR looks up a string.
48 /* \fIcfg_get_int\fR looks up an integer.
50 /* \fIcfg_get_bool\fR looks up a boolean value.
52 /* \fIdefval\fR is returned when no value was found. \fImin\fR is
53 /* zero or specifies a lower limit on the integer value or string
54 /* length; \fImax\fR is zero or specifies an upper limit on the
55 /* integer value or string length.
57 /* Conveniently, \fIcfg_get_str\fR returns \fBNULL\fR if
58 /* \fIdefval\fR is \fBNULL\fR and no value was found. The returned
59 /* string has to be freed by the caller if not \fBNULL\fR.
61 /* Fatal errors: bad string length, malformed numerical value, malformed
64 /* mail_conf_str(3) string-valued global configuration parameter support
65 /* mail_conf_int(3) integer-valued configuration parameter support
66 /* mail_conf_bool(3) boolean-valued configuration parameter support
70 /* The Secure Mailer license must be distributed with this software.
73 /* IBM T.J. Watson Research
75 /* Yorktown Heights, NY 10598, USA
78 /* Institute of Mathematics of the Romanian Academy
80 /* RO-014700 Bucharest, ROMANIA
90 #ifdef STRCASECMP_IN_STRINGS_H
94 /* Utility library. */
101 /* Global library. */
103 #include "mail_conf.h"
105 /* Application-specific. */
107 #include "cfg_parser.h"
109 /* get string from file */
111 static char *get_dict_str(const struct CFG_PARSER
*parser
,
112 const char *name
, const char *defval
,
118 if ((strval
= (char *) dict_lookup(parser
->name
, name
)) == 0)
121 len
= strlen(strval
);
122 if (min
&& len
< min
)
123 msg_fatal("%s: bad string length %d < %d: %s = %s",
124 parser
->name
, len
, min
, name
, strval
);
125 if (max
&& len
> max
)
126 msg_fatal("%s: bad string length %d > %d: %s = %s",
127 parser
->name
, len
, max
, name
, strval
);
128 return (mystrdup(strval
));
131 /* get string from main.cf */
133 static char *get_main_str(const struct CFG_PARSER
*parser
,
134 const char *name
, const char *defval
,
137 static VSTRING
*buf
= 0;
140 buf
= vstring_alloc(15);
141 vstring_sprintf(buf
, "%s_%s", parser
->name
, name
);
142 return ((char *) get_mail_conf_str(vstring_str(buf
), defval
, min
, max
));
145 /* get integer from file */
147 static int get_dict_int(const struct CFG_PARSER
*parser
,
148 const char *name
, int defval
, int min
, int max
)
154 if ((strval
= (char *) dict_lookup(parser
->name
, name
)) != 0) {
155 if (sscanf(strval
, "%d%c", &intval
, &junk
) != 1)
156 msg_fatal("%s: bad numerical configuration: %s = %s",
157 parser
->name
, name
, strval
);
160 if (min
&& intval
< min
)
161 msg_fatal("%s: invalid %s parameter value %d < %d",
162 parser
->name
, name
, intval
, min
);
163 if (max
&& intval
> max
)
164 msg_fatal("%s: invalid %s parameter value %d > %d",
165 parser
->name
, name
, intval
, max
);
169 /* get integer from main.cf */
171 static int get_main_int(const struct CFG_PARSER
*parser
,
172 const char *name
, int defval
, int min
, int max
)
174 static VSTRING
*buf
= 0;
177 buf
= vstring_alloc(15);
178 vstring_sprintf(buf
, "%s_%s", parser
->name
, name
);
179 return (get_mail_conf_int(vstring_str(buf
), defval
, min
, max
));
182 /* get boolean option from file */
184 static int get_dict_bool(const struct CFG_PARSER
*parser
,
185 const char *name
, int defval
)
190 if ((strval
= (char *) dict_lookup(parser
->name
, name
)) != 0) {
191 if (strcasecmp(strval
, CONFIG_BOOL_YES
) == 0) {
193 } else if (strcasecmp(strval
, CONFIG_BOOL_NO
) == 0) {
196 msg_fatal("%s: bad boolean configuration: %s = %s",
197 parser
->name
, name
, strval
);
204 /* get boolean option from main.cf */
206 static int get_main_bool(const struct CFG_PARSER
*parser
,
207 const char *name
, int defval
)
209 static VSTRING
*buf
= 0;
212 buf
= vstring_alloc(15);
213 vstring_sprintf(buf
, "%s_%s", parser
->name
, name
);
214 return (get_mail_conf_bool(vstring_str(buf
), defval
));
217 /* initialize parser */
219 CFG_PARSER
*cfg_parser_alloc(const char *pname
)
221 const char *myname
= "cfg_parser_alloc";
224 if (pname
== 0 || *pname
== 0)
225 msg_fatal("%s: null parser name", myname
);
226 parser
= (CFG_PARSER
*) mymalloc(sizeof(*parser
));
227 parser
->name
= mystrdup(pname
);
228 if (*parser
->name
== '/' || *parser
->name
== '.') {
229 dict_load_file(parser
->name
, parser
->name
);
230 parser
->get_str
= get_dict_str
;
231 parser
->get_int
= get_dict_int
;
232 parser
->get_bool
= get_dict_bool
;
234 parser
->get_str
= get_main_str
;
235 parser
->get_int
= get_main_int
;
236 parser
->get_bool
= get_main_bool
;
243 char *cfg_get_str(const CFG_PARSER
*parser
, const char *name
,
244 const char *defval
, int min
, int max
)
246 const char *myname
= "cfg_get_str";
249 strval
= parser
->get_str(parser
, name
, (defval
? defval
: ""), min
, max
);
250 if (defval
== 0 && *strval
== 0) {
251 /* the caller wants NULL instead of "" */
256 msg_info("%s: %s: %s = %s", myname
, parser
->name
, name
,
257 (strval
? strval
: "<NULL>"));
263 int cfg_get_int(const CFG_PARSER
*parser
, const char *name
, int defval
,
266 const char *myname
= "cfg_get_int";
269 intval
= parser
->get_int(parser
, name
, defval
, min
, max
);
271 msg_info("%s: %s: %s = %d", myname
, parser
->name
, name
, intval
);
275 /* get boolean option */
277 int cfg_get_bool(const CFG_PARSER
*parser
, const char *name
, int defval
)
279 const char *myname
= "cfg_get_bool";
282 intval
= parser
->get_bool(parser
, name
, defval
);
284 msg_info("%s: %s: %s = %s", myname
, parser
->name
, name
,
285 (intval
? "on" : "off"));
291 CFG_PARSER
*cfg_parser_free(CFG_PARSER
*parser
)
293 const char *myname
= "cfg_parser_free";
295 if (parser
->name
== 0 || *parser
->name
== 0)
296 msg_panic("%s: null parser name", myname
);
297 if (*parser
->name
== '/' || *parser
->name
== '.') {
298 if (dict_handle(parser
->name
))
299 dict_unregister(parser
->name
);
301 myfree(parser
->name
);
302 myfree((char *) parser
);