Sync usage with man page.
[netbsd-mini2440.git] / external / ibm-public / postfix / dist / src / global / cfg_parser.c
blob82a61e402114d94e2a79622b0ceea40370b25e58
1 /* $NetBSD$ */
3 /*++
4 /* NAME
5 /* cfg_parser 3
6 /* SUMMARY
7 /* configuration parser utilities
8 /* SYNOPSIS
9 /* #include "cfg_parser.h"
11 /* CFG_PARSER *cfg_parser_alloc(pname)
12 /* const char *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;
19 /* const char *name;
20 /* const char *defval;
21 /* int min;
22 /* int max;
24 /* int cfg_get_int(parser, name, defval, min, max)
25 /* const CFG_PARSER *parser;
26 /* const char *name;
27 /* int defval;
28 /* int min;
29 /* int max;
31 /* int cfg_get_bool(parser, name, defval)
32 /* const CFG_PARSER *parser;
33 /* const char *name;
34 /* int defval;
35 /* DESCRIPTION
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.
60 /* DIAGNOSTICS
61 /* Fatal errors: bad string length, malformed numerical value, malformed
62 /* boolean value.
63 /* SEE ALSO
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
67 /* LICENSE
68 /* .ad
69 /* .fi
70 /* The Secure Mailer license must be distributed with this software.
71 /* AUTHOR(S)
72 /* Wietse Venema
73 /* IBM T.J. Watson Research
74 /* P.O. Box 704
75 /* Yorktown Heights, NY 10598, USA
77 /* Liviu Daia
78 /* Institute of Mathematics of the Romanian Academy
79 /* P.O. BOX 1-764
80 /* RO-014700 Bucharest, ROMANIA
81 /*--*/
83 /* System library. */
85 #include "sys_defs.h"
87 #include <stdio.h>
88 #include <string.h>
90 #ifdef STRCASECMP_IN_STRINGS_H
91 #include <strings.h>
92 #endif
94 /* Utility library. */
96 #include "msg.h"
97 #include "mymalloc.h"
98 #include "vstring.h"
99 #include "dict.h"
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,
113 int min, int max)
115 const char *strval;
116 int len;
118 if ((strval = (char *) dict_lookup(parser->name, name)) == 0)
119 strval = defval;
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,
135 int min, int max)
137 static VSTRING *buf = 0;
139 if (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)
150 const char *strval;
151 int intval;
152 char junk;
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);
158 } else
159 intval = defval;
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);
166 return (intval);
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;
176 if (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)
187 const char *strval;
188 int intval;
190 if ((strval = (char *) dict_lookup(parser->name, name)) != 0) {
191 if (strcasecmp(strval, CONFIG_BOOL_YES) == 0) {
192 intval = 1;
193 } else if (strcasecmp(strval, CONFIG_BOOL_NO) == 0) {
194 intval = 0;
195 } else {
196 msg_fatal("%s: bad boolean configuration: %s = %s",
197 parser->name, name, strval);
199 } else
200 intval = defval;
201 return (intval);
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;
211 if (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";
222 CFG_PARSER *parser;
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;
233 } else {
234 parser->get_str = get_main_str;
235 parser->get_int = get_main_int;
236 parser->get_bool = get_main_bool;
238 return (parser);
241 /* get string */
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";
247 char *strval;
249 strval = parser->get_str(parser, name, (defval ? defval : ""), min, max);
250 if (defval == 0 && *strval == 0) {
251 /* the caller wants NULL instead of "" */
252 myfree(strval);
253 strval = 0;
255 if (msg_verbose)
256 msg_info("%s: %s: %s = %s", myname, parser->name, name,
257 (strval ? strval : "<NULL>"));
258 return (strval);
261 /* get integer */
263 int cfg_get_int(const CFG_PARSER *parser, const char *name, int defval,
264 int min, int max)
266 const char *myname = "cfg_get_int";
267 int intval;
269 intval = parser->get_int(parser, name, defval, min, max);
270 if (msg_verbose)
271 msg_info("%s: %s: %s = %d", myname, parser->name, name, intval);
272 return (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";
280 int intval;
282 intval = parser->get_bool(parser, name, defval);
283 if (msg_verbose)
284 msg_info("%s: %s: %s = %s", myname, parser->name, name,
285 (intval ? "on" : "off"));
286 return (intval);
289 /* release parser */
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);
303 return (0);