Commit 1b2350e5 1b2350e50f3f39fbc40811da4b942a71fd1dab8d by Sergey Poznyakoff

* include/mailutils/cfg.h (mu_cfg_section): New type.

(struct mu_cfg_param.offset): New member
(mu_offsetof): New define
(mu_cfg_section_fp): Change signature
(struct mu_cfg_section.label,target): New members.
(struct mu_cfg_section.data): Remove.
(struct mu_cfg_section.children): New member, instead of
param and subsec which are removed.
(mu_cfg_scan_tree): Change signature.
(mu_config_register_section): Change signature.
(mu_parse_config): Change signature.
(mu_parse_config_tree): Rename to mu_cfg_tree_reduce.
(mu_get_config): New proto.

* include/mailutils/libcfg.h (mu_parse_config_files): Change
prototype.

* dotlock/dotlock.c, imap4d/imap4d.c, lib/tcpwrap.h,
libargp/muinit.c, libcfg/auth.c, libcfg/common.c, libcfg/gsasl.c,
libcfg/init.c, libcfg/ldap.c, libcfg/pam.c, libcfg/radius.c,
libcfg/sieve.c, libcfg/sql.c, libcfg/tls.c, libcfg/virtdomain.c,
maidag/maidag.c, mail.local/main.c, mail.remote/mail.remote.c,
mailbox/cfg_format.c, mailbox/cfg_parser.y, mimeview/mimeview.c,
movemail/movemail.c, pop3d/pop3d.c, readmsg/readmsg.c,
sieve/sieve.c: Reflect changes to the cfg framework.

* mailbox/Makefile.am (libmailutils_la_SOURCES): Add cfg_driver.c.
* mailbox/cfg_driver.c: New file.
* mailbox/cfg_lexer.c: Move driver part into a separate file.

* examples/Makefile.am (AM_LDFLAGS): Remove libmuaux
* examples/echosrv.c: Remove getopt.h
1 parent 797a5462
1 2007-12-11 Sergey Poznyakoff <gray@gnu.org.ua>
2
3 * include/mailutils/cfg.h (mu_cfg_section): New type.
4 (struct mu_cfg_param.offset): New member
5 (mu_offsetof): New define
6 (mu_cfg_section_fp): Change signature
7 (struct mu_cfg_section.label,target): New members.
8 (struct mu_cfg_section.data): Remove.
9 (struct mu_cfg_section.children): New member, instead of
10 param and subsec which are removed.
11 (mu_cfg_scan_tree): Change signature.
12 (mu_config_register_section): Change signature.
13 (mu_parse_config): Change signature.
14 (mu_parse_config_tree): Rename to mu_cfg_tree_reduce.
15 (mu_get_config): New proto.
16
17 * include/mailutils/libcfg.h (mu_parse_config_files): Change
18 prototype.
19
20 * dotlock/dotlock.c, imap4d/imap4d.c, lib/tcpwrap.h,
21 libargp/muinit.c, libcfg/auth.c, libcfg/common.c, libcfg/gsasl.c,
22 libcfg/init.c, libcfg/ldap.c, libcfg/pam.c, libcfg/radius.c,
23 libcfg/sieve.c, libcfg/sql.c, libcfg/tls.c, libcfg/virtdomain.c,
24 maidag/maidag.c, mail.local/main.c, mail.remote/mail.remote.c,
25 mailbox/cfg_format.c, mailbox/cfg_parser.y, mimeview/mimeview.c,
26 movemail/movemail.c, pop3d/pop3d.c, readmsg/readmsg.c,
27 sieve/sieve.c: Reflect changes to the cfg framework.
28
29 * mailbox/Makefile.am (libmailutils_la_SOURCES): Add cfg_driver.c.
30 * mailbox/cfg_driver.c: New file.
31 * mailbox/cfg_lexer.c: Move driver part into a separate file.
32
33 * examples/Makefile.am (AM_LDFLAGS): Remove libmuaux
34 * examples/echosrv.c: Remove getopt.h
35
1 2007-12-09 Sergey Poznyakoff <gray@gnu.org.ua> 36 2007-12-09 Sergey Poznyakoff <gray@gnu.org.ua>
2 37
3 * examples/Makefile.am: add echosrv.c. 38 * examples/Makefile.am: add echosrv.c.
......
...@@ -125,11 +125,11 @@ parse_opt (int key, char *arg, struct argp_state *state) ...@@ -125,11 +125,11 @@ parse_opt (int key, char *arg, struct argp_state *state)
125 125
126 126
127 struct mu_cfg_param dotlock_cfg_param[] = { 127 struct mu_cfg_param dotlock_cfg_param[] = {
128 { "force", mu_cfg_time, &force, NULL, 128 { "force", mu_cfg_time, &force, 0, NULL,
129 N_("Forcibly break an existing lock older than the specified time.") }, 129 N_("Forcibly break an existing lock older than the specified time.") },
130 { "retry", mu_cfg_int, &retries, NULL, 130 { "retry", mu_cfg_int, &retries, 0, NULL,
131 N_("Number of times to retry acquiring the lock.") }, 131 N_("Number of times to retry acquiring the lock.") },
132 { "debug", mu_cfg_bool, &debug, NULL, 132 { "debug", mu_cfg_bool, &debug, 0, NULL,
133 N_("Print details of failure reasons to stderr.") }, 133 N_("Print details of failure reasons to stderr.") },
134 { NULL } 134 { NULL }
135 }; 135 };
......
...@@ -54,7 +54,6 @@ mod_LTLIBRARIES = numaddr.la ...@@ -54,7 +54,6 @@ mod_LTLIBRARIES = numaddr.la
54 INCLUDES = @MU_COMMON_INCLUDES@ 54 INCLUDES = @MU_COMMON_INCLUDES@
55 55
56 AM_LDFLAGS = \ 56 AM_LDFLAGS = \
57 ../lib/libmuaux.la\
58 ${MU_LIB_MAILUTILS}\ 57 ${MU_LIB_MAILUTILS}\
59 @MU_COMMON_LIBRARIES@ 58 @MU_COMMON_LIBRARIES@
60 59
...@@ -132,4 +131,4 @@ muauth_LDADD = \ ...@@ -132,4 +131,4 @@ muauth_LDADD = \
132 @MU_AUTHLIBS@ \ 131 @MU_AUTHLIBS@ \
133 ${MU_LIB_MAILUTILS} 132 ${MU_LIB_MAILUTILS}
134 133
135 muemail_LDADD = ${MU_APP_LIBRARIES}
...\ No newline at end of file ...\ No newline at end of file
134 muemail_LDADD = ${MU_APP_LIBRARIES}
......
...@@ -28,7 +28,6 @@ ...@@ -28,7 +28,6 @@
28 #include <arpa/inet.h> 28 #include <arpa/inet.h>
29 #include <signal.h> 29 #include <signal.h>
30 #include <sys/wait.h> 30 #include <sys/wait.h>
31 #include "getopt.h"
32 31
33 #include <mailutils/mailutils.h> 32 #include <mailutils/mailutils.h>
34 #include <mailutils/server.h> 33 #include <mailutils/server.h>
...@@ -185,7 +184,8 @@ server_idle (void *server_data) ...@@ -185,7 +184,8 @@ server_idle (void *server_data)
185 (unsigned long) pid, 184 (unsigned long) pid,
186 WTERMSIG (status)); 185 WTERMSIG (status));
187 else 186 else
188 mu_diag_output (MU_DIAG_ERR, "%lu: terminated (cause unknown)"); 187 mu_diag_output (MU_DIAG_ERR, "%lu: terminated (cause unknown)",
188 (unsigned long) pid);
189 } 189 }
190 } 190 }
191 return 0; 191 return 0;
......
...@@ -272,33 +272,33 @@ cb_preauth (mu_debug_t debug, void *data, char *arg) ...@@ -272,33 +272,33 @@ cb_preauth (mu_debug_t debug, void *data, char *arg)
272 } 272 }
273 273
274 static struct mu_cfg_param imap4d_cfg_param[] = { 274 static struct mu_cfg_param imap4d_cfg_param[] = {
275 { "other-namespace", mu_cfg_callback, NULL, cb_other, 275 { "other-namespace", mu_cfg_callback, NULL, 0, cb_other,
276 N_("Set other users' namespace. Argument is a colon-separated list " 276 N_("Set other users' namespace. Argument is a colon-separated list "
277 "of directories comprising the namespace.") }, 277 "of directories comprising the namespace.") },
278 { "shared-namespace", mu_cfg_callback, NULL, cb_shared, 278 { "shared-namespace", mu_cfg_callback, NULL, 0, cb_shared,
279 N_("Set shared namespace. Argument is a colon-separated list " 279 N_("Set shared namespace. Argument is a colon-separated list "
280 "of directories comprising the namespace.") }, 280 "of directories comprising the namespace.") },
281 { "login-disabled", mu_cfg_int, &login_disabled, NULL, 281 { "login-disabled", mu_cfg_int, &login_disabled, 0, NULL,
282 N_("Disable LOGIN command.") }, 282 N_("Disable LOGIN command.") },
283 { "create-home-dir", mu_cfg_bool, &create_home_dir, NULL, 283 { "create-home-dir", mu_cfg_bool, &create_home_dir, 0, NULL,
284 N_("If true, create non-existing user home directories.") }, 284 N_("If true, create non-existing user home directories.") },
285 { "home-dir-mode", mu_cfg_callback, NULL, cb_mode, 285 { "home-dir-mode", mu_cfg_callback, NULL, 0, cb_mode,
286 N_("File mode for creating user home directories (octal)."), 286 N_("File mode for creating user home directories (octal)."),
287 N_("mode") }, 287 N_("mode") },
288 { "tls-required", mu_cfg_int, &tls_required, NULL, 288 { "tls-required", mu_cfg_int, &tls_required, 0, NULL,
289 N_("Always require STARTTLS before entering authentication phase.") }, 289 N_("Always require STARTTLS before entering authentication phase.") },
290 { "preauth", mu_cfg_callback, NULL, cb_preauth, 290 { "preauth", mu_cfg_callback, NULL, 0, cb_preauth,
291 N_("Configure PREAUTH mode. MODE is one of:\n" 291 N_("Configure PREAUTH mode. MODE is one of:\n"
292 " prog:///<full-program-name: string>\n" 292 " prog:///<full-program-name: string>\n"
293 " ident[://:<port: string-or-number>]\n" 293 " ident[://:<port: string-or-number>]\n"
294 " stdio"), 294 " stdio"),
295 N_("MODE") }, 295 N_("MODE") },
296 { "preauth-only", mu_cfg_bool, &preauth_only, NULL, 296 { "preauth-only", mu_cfg_bool, &preauth_only, 0, NULL,
297 N_("Use only preauth mode. If unable to setup it, disconnect " 297 N_("Use only preauth mode. If unable to setup it, disconnect "
298 "immediately.") }, 298 "immediately.") },
299 { "ident-keyfile", mu_cfg_string, &ident_keyfile, NULL, 299 { "ident-keyfile", mu_cfg_string, &ident_keyfile, 0, NULL,
300 N_("Name of DES keyfile for decoding ecrypted ident responses.") }, 300 N_("Name of DES keyfile for decoding ecrypted ident responses.") },
301 { "ident-entrypt-only", mu_cfg_bool, &ident_encrypt_only, NULL, 301 { "ident-entrypt-only", mu_cfg_bool, &ident_encrypt_only, 0, NULL,
302 N_("Use only encrypted ident responses.") }, 302 N_("Use only encrypted ident responses.") },
303 TCP_WRAPPERS_CONFIG 303 TCP_WRAPPERS_CONFIG
304 { NULL } 304 { NULL }
......
...@@ -118,7 +118,8 @@ enum mu_cfg_param_data_type ...@@ -118,7 +118,8 @@ enum mu_cfg_param_data_type
118 mu_cfg_ipv4, 118 mu_cfg_ipv4,
119 mu_cfg_cidr, 119 mu_cfg_cidr,
120 mu_cfg_host, 120 mu_cfg_host,
121 mu_cfg_callback 121 mu_cfg_callback,
122 mu_cfg_section
122 }; 123 };
123 124
124 typedef int (*mu_cfg_callback_t) (mu_debug_t, void *, char *); 125 typedef int (*mu_cfg_callback_t) (mu_debug_t, void *, char *);
...@@ -128,11 +129,17 @@ struct mu_cfg_param ...@@ -128,11 +129,17 @@ struct mu_cfg_param
128 const char *ident; 129 const char *ident;
129 enum mu_cfg_param_data_type type; 130 enum mu_cfg_param_data_type type;
130 void *data; 131 void *data;
132 size_t offset;
131 mu_cfg_callback_t callback; 133 mu_cfg_callback_t callback;
132 const char *docstring; 134 const char *docstring;
133 const char *argname; 135 const char *argname;
134 }; 136 };
135 137
138 #define mu_offsetof(s,f) ((size_t)&((s*)0).f)
139
140 #define MU_TARGET_REF(f) &f, 0
141 #define MU_TARGET_OFF(s,f) NULL, mu_offsetof(s,f)
142
136 enum mu_cfg_section_stage 143 enum mu_cfg_section_stage
137 { 144 {
138 mu_cfg_section_start, 145 mu_cfg_section_start,
...@@ -141,17 +148,18 @@ enum mu_cfg_section_stage ...@@ -141,17 +148,18 @@ enum mu_cfg_section_stage
141 148
142 typedef int (*mu_cfg_section_fp) (enum mu_cfg_section_stage stage, 149 typedef int (*mu_cfg_section_fp) (enum mu_cfg_section_stage stage,
143 const mu_cfg_node_t *node, 150 const mu_cfg_node_t *node,
144 void *section_data, 151 const char *label,
152 void **section_data_ptr,
145 void *call_data, 153 void *call_data,
146 mu_cfg_tree_t *tree); 154 mu_cfg_tree_t *tree);
147 155
148 struct mu_cfg_section 156 struct mu_cfg_section
149 { 157 {
150 const char *ident; 158 const char *ident;
159 char *label;
151 mu_cfg_section_fp parser; 160 mu_cfg_section_fp parser;
152 void *data; 161 void *target;
153 mu_list_t /* of mu_cfg_cont/mu_cfg_section */ subsec; 162 mu_list_t /* of mu_cfg_cont */ children;
154 mu_list_t /* of mu_cfg_cont/mu_cfg_param */ param;
155 char *docstring; 163 char *docstring;
156 }; 164 };
157 165
...@@ -187,15 +195,15 @@ int mu_config_clone_container (struct mu_cfg_cont *cont); ...@@ -187,15 +195,15 @@ int mu_config_clone_container (struct mu_cfg_cont *cont);
187 void mu_config_destroy_container (struct mu_cfg_cont **pcont); 195 void mu_config_destroy_container (struct mu_cfg_cont **pcont);
188 196
189 int mu_cfg_scan_tree (mu_cfg_tree_t *tree, struct mu_cfg_section *sections, 197 int mu_cfg_scan_tree (mu_cfg_tree_t *tree, struct mu_cfg_section *sections,
190 void *call_data); 198 void *target, void *call_data);
191 199
192 int mu_cfg_find_section (struct mu_cfg_section *root_sec, 200 int mu_cfg_find_section (struct mu_cfg_section *root_sec,
193 const char *path, struct mu_cfg_section **retval); 201 const char *path, struct mu_cfg_section **retval);
194 202
195 int mu_config_register_section (const char *parent_path, 203 int mu_config_register_section (const char *parent_path,
196 const char *ident, 204 const char *ident,
205 const char *label,
197 mu_cfg_section_fp parser, 206 mu_cfg_section_fp parser,
198 void *data,
199 struct mu_cfg_param *param); 207 struct mu_cfg_param *param);
200 int mu_config_register_plain_section (const char *parent_path, 208 int mu_config_register_plain_section (const char *parent_path,
201 const char *ident, 209 const char *ident,
...@@ -206,7 +214,8 @@ int mu_config_register_plain_section (const char *parent_path, ...@@ -206,7 +214,8 @@ int mu_config_register_plain_section (const char *parent_path,
206 #define MU_PARSE_CONFIG_DUMP 0x4 214 #define MU_PARSE_CONFIG_DUMP 0x4
207 215
208 int mu_parse_config (const char *file, const char *progname, 216 int mu_parse_config (const char *file, const char *progname,
209 struct mu_cfg_param *progparam, int flags); 217 struct mu_cfg_param *progparam, int flags,
218 void *target_ptr);
210 219
211 int mu_cfg_parse_boolean (const char *str, int *res); 220 int mu_cfg_parse_boolean (const char *str, int *res);
212 221
...@@ -218,8 +227,14 @@ void mu_cfg_format_parse_tree (mu_stream_t stream, struct mu_cfg_tree *tree); ...@@ -218,8 +227,14 @@ void mu_cfg_format_parse_tree (mu_stream_t stream, struct mu_cfg_tree *tree);
218 void mu_cfg_format_container (mu_stream_t stream, struct mu_cfg_cont *cont); 227 void mu_cfg_format_container (mu_stream_t stream, struct mu_cfg_cont *cont);
219 void mu_format_config_tree (mu_stream_t stream, const char *progname, 228 void mu_format_config_tree (mu_stream_t stream, const char *progname,
220 struct mu_cfg_param *progparam, int flags); 229 struct mu_cfg_param *progparam, int flags);
221 int mu_parse_config_tree (mu_cfg_tree_t *parse_tree, const char *progname, 230 int mu_cfg_tree_reduce (mu_cfg_tree_t *parse_tree, const char *progname,
222 struct mu_cfg_param *progparam, int flags); 231 struct mu_cfg_param *progparam,
232 int flags, void *target_ptr);
233
234 int mu_get_config (const char *file, const char *progname,
235 struct mu_cfg_param *progparam, int flags,
236 void *target_ptr);
237
223 238
224 int mu_cfg_tree_create (struct mu_cfg_tree **ptree); 239 int mu_cfg_tree_create (struct mu_cfg_tree **ptree);
225 void mu_cfg_tree_set_debug (struct mu_cfg_tree *tree, mu_debug_t debug); 240 void mu_cfg_tree_set_debug (struct mu_cfg_tree *tree, mu_debug_t debug);
......
...@@ -49,7 +49,8 @@ extern int mu_register_cfg_capa (const char *name, ...@@ -49,7 +49,8 @@ extern int mu_register_cfg_capa (const char *name,
49 mu_cfg_section_fp *parser); 49 mu_cfg_section_fp *parser);
50 50
51 extern void mu_libcfg_init (char **cnames); 51 extern void mu_libcfg_init (char **cnames);
52 extern int mu_parse_config_files (struct mu_cfg_param *param); 52 extern int mu_parse_config_files (struct mu_cfg_param *param,
53 void *target_ptr);
53 54
54 #define __mu_common_cat2__(a,b) a ## b 55 #define __mu_common_cat2__(a,b) a ## b
55 #define __mu_common_cat3__(a,b,c) a ## b ## c 56 #define __mu_common_cat3__(a,b,c) a ## b ## c
...@@ -57,7 +58,8 @@ extern int mu_parse_config_files (struct mu_cfg_param *param); ...@@ -57,7 +58,8 @@ extern int mu_parse_config_files (struct mu_cfg_param *param);
57 int \ 58 int \
58 __mu_common_cat3__(mu_,capa,_section_parser) \ 59 __mu_common_cat3__(mu_,capa,_section_parser) \
59 (enum mu_cfg_section_stage stage, const mu_cfg_node_t *node, \ 60 (enum mu_cfg_section_stage stage, const mu_cfg_node_t *node, \
60 void *section_data, void *call_data, mu_cfg_tree_t *tree) \ 61 const char *section_label, void **section_data, \
62 void *call_data, mu_cfg_tree_t *tree) \
61 { \ 63 { \
62 switch (stage) \ 64 switch (stage) \
63 { \ 65 { \
......
...@@ -33,25 +33,27 @@ extern int mu_tcpwrapper_access (int fd); ...@@ -33,25 +33,27 @@ extern int mu_tcpwrapper_access (int fd);
33 33
34 #ifdef WITH_LIBWRAP 34 #ifdef WITH_LIBWRAP
35 # define TCP_WRAPPERS_CONFIG \ 35 # define TCP_WRAPPERS_CONFIG \
36 { "tcp-wrapper-enable", mu_cfg_bool, &mu_tcp_wrapper_enable, NULL, \ 36 { "tcp-wrapper-enable", mu_cfg_bool, &mu_tcp_wrapper_enable, 0, NULL, \
37 N_("Enable TCP wrapper access control. Default is \"yes\".") }, \ 37 N_("Enable TCP wrapper access control. Default is \"yes\".") }, \
38 { "tcp-wrapper-daemon", mu_cfg_string, &mu_tcp_wrapper_daemon, NULL, \ 38 { "tcp-wrapper-daemon", mu_cfg_string, &mu_tcp_wrapper_daemon, 0, NULL, \
39 N_("Set daemon name for TCP wrapper lookups. Default is program name."), \ 39 N_("Set daemon name for TCP wrapper lookups. Default is program name."), \
40 N_("name") }, \ 40 N_("name") }, \
41 { "hosts-allow-table", mu_cfg_callback, NULL, mu_tcp_wrapper_cb_hosts_allow,\ 41 { "hosts-allow-table", mu_cfg_callback, NULL, 0, \
42 mu_tcp_wrapper_cb_hosts_allow, \
42 N_("Use file for positive client address access control " \ 43 N_("Use file for positive client address access control " \
43 "(default: /etc/hosts.allow)."), \ 44 "(default: /etc/hosts.allow)."), \
44 N_("file") }, \ 45 N_("file") }, \
45 { "hosts-deny-table", mu_cfg_callback, NULL, mu_tcp_wrapper_cb_hosts_deny, \ 46 { "hosts-deny-table", mu_cfg_callback, NULL, 0, \
47 mu_tcp_wrapper_cb_hosts_deny, \
46 N_("Use file for negative client address access control " \ 48 N_("Use file for negative client address access control " \
47 "(default: /etc/hosts.deny)."), \ 49 "(default: /etc/hosts.deny)."), \
48 N_("file") }, \ 50 N_("file") }, \
49 { "hosts-allow-syslog-level", mu_cfg_callback, NULL, \ 51 { "hosts-allow-syslog-level", mu_cfg_callback, NULL, 0, \
50 mu_tcp_wrapper_cb_hosts_allow_syslog, \ 52 mu_tcp_wrapper_cb_hosts_allow_syslog, \
51 N_("Log host allows at this syslog level. See logging { facility } for " \ 53 N_("Log host allows at this syslog level. See logging { facility } for " \
52 "a description of argument syntax."), \ 54 "a description of argument syntax."), \
53 N_("level") }, \ 55 N_("level") }, \
54 { "hosts-allow-deny-level", mu_cfg_callback, NULL, \ 56 { "hosts-allow-deny-level", mu_cfg_callback, NULL, 0, \
55 mu_tcp_wrapper_cb_hosts_deny_syslog, \ 57 mu_tcp_wrapper_cb_hosts_deny_syslog, \
56 N_("Log host denies at this syslog level. See logging { facility } for " \ 58 N_("Log host denies at this syslog level. See logging { facility } for " \
57 "a description of argument syntax."), \ 59 "a description of argument syntax."), \
......
...@@ -77,7 +77,7 @@ mu_app_init (struct argp *myargp, const char **capa, ...@@ -77,7 +77,7 @@ mu_app_init (struct argp *myargp, const char **capa,
77 77
78 mu_libcfg_init (excapa); 78 mu_libcfg_init (excapa);
79 free (excapa); 79 free (excapa);
80 mu_parse_config_files (cfg_param); 80 mu_parse_config_files (cfg_param, data);
81 81
82 if (mu_help_config_mode) 82 if (mu_help_config_mode)
83 { 83 {
...@@ -113,8 +113,8 @@ mu_app_init (struct argp *myargp, const char **capa, ...@@ -113,8 +113,8 @@ mu_app_init (struct argp *myargp, const char **capa,
113 cfgflags |= MU_PARSE_CONFIG_VERBOSE; 113 cfgflags |= MU_PARSE_CONFIG_VERBOSE;
114 if (mu_cfg_parser_verbose > 1) 114 if (mu_cfg_parser_verbose > 1)
115 cfgflags |= MU_PARSE_CONFIG_DUMP; 115 cfgflags |= MU_PARSE_CONFIG_DUMP;
116 rc = mu_parse_config_tree (mu_argp_tree, mu_program_name, cfg_param, 116 rc = mu_cfg_tree_reduce (mu_argp_tree, mu_program_name, cfg_param,
117 cfgflags); 117 cfgflags, data);
118 118
119 mu_gocs_flush (); 119 mu_gocs_flush ();
120 mu_cfg_destroy_tree (&mu_argp_tree); 120 mu_cfg_destroy_tree (&mu_argp_tree);
......
...@@ -50,12 +50,12 @@ cb_authorization (mu_debug_t err, void *data, char *arg) ...@@ -50,12 +50,12 @@ cb_authorization (mu_debug_t err, void *data, char *arg)
50 } 50 }
51 51
52 static struct mu_cfg_param mu_auth_param[] = { 52 static struct mu_cfg_param mu_auth_param[] = {
53 { "authentication", mu_cfg_callback, NULL, cb_authentication, 53 { "authentication", mu_cfg_callback, NULL, 0, cb_authentication,
54 N_("Set a list of modules for authentication. Modlist is a " 54 N_("Set a list of modules for authentication. Modlist is a "
55 "colon-separated list of module names or a word `clear' to " 55 "colon-separated list of module names or a word `clear' to "
56 "clear the previously set up values."), 56 "clear the previously set up values."),
57 N_("modlist") }, 57 N_("modlist") },
58 { "authorization", mu_cfg_callback, NULL, cb_authorization, 58 { "authorization", mu_cfg_callback, NULL, 0, cb_authorization,
59 N_("Set a list of modules for authorization. Modlist is a " 59 N_("Set a list of modules for authorization. Modlist is a "
60 "colon-separated list of module names or a word `clear' to " 60 "colon-separated list of module names or a word `clear' to "
61 "clear the previously set up values."), 61 "clear the previously set up values."),
...@@ -66,7 +66,8 @@ static struct mu_cfg_param mu_auth_param[] = { ...@@ -66,7 +66,8 @@ static struct mu_cfg_param mu_auth_param[] = {
66 int 66 int
67 mu_auth_section_parser 67 mu_auth_section_parser
68 (enum mu_cfg_section_stage stage, const mu_cfg_node_t *node, 68 (enum mu_cfg_section_stage stage, const mu_cfg_node_t *node,
69 void *section_data, void *call_data, mu_cfg_tree_t *tree) 69 const char *section_label, void **section_data, void *call_data,
70 mu_cfg_tree_t *tree)
70 { 71 {
71 switch (stage) 72 switch (stage)
72 { 73 {
......
...@@ -40,10 +40,10 @@ static struct mu_gocs_debug debug_settings; ...@@ -40,10 +40,10 @@ static struct mu_gocs_debug debug_settings;
40 /* ************************************************************************* */ 40 /* ************************************************************************* */
41 41
42 static struct mu_cfg_param mu_mailbox_param[] = { 42 static struct mu_cfg_param mu_mailbox_param[] = {
43 { "mail-spool", mu_cfg_string, &mailbox_settings.mail_spool, NULL, 43 { "mail-spool", mu_cfg_string, &mailbox_settings.mail_spool, 0, NULL,
44 N_("Use specified URL as a mailspool directory."), 44 N_("Use specified URL as a mailspool directory."),
45 N_("url") }, 45 N_("url") },
46 { "mailbox-type", mu_cfg_string, &mailbox_settings.mailbox_type, NULL, 46 { "mailbox-type", mu_cfg_string, &mailbox_settings.mailbox_type, 0, NULL,
47 N_("Default mailbox type."), N_("protocol") }, 47 N_("Default mailbox type."), N_("protocol") },
48 { NULL } 48 { NULL }
49 }; 49 };
...@@ -57,16 +57,18 @@ DCL_CFG_CAPA (mailbox); ...@@ -57,16 +57,18 @@ DCL_CFG_CAPA (mailbox);
57 57
58 static struct mu_cfg_param mu_locking_param[] = { 58 static struct mu_cfg_param mu_locking_param[] = {
59 /* FIXME: Flags are superfluous. */ 59 /* FIXME: Flags are superfluous. */
60 { "flags", mu_cfg_string, &locking_settings.lock_flags, NULL, 60 { "flags", mu_cfg_string, &locking_settings.lock_flags, 0, NULL,
61 N_("Default locker flags (E=external, R=retry, T=time, P=pid).") }, 61 N_("Default locker flags (E=external, R=retry, T=time, P=pid).") },
62 { "retry-timeout", mu_cfg_ulong, &locking_settings.lock_retry_timeout, NULL, 62 { "retry-timeout", mu_cfg_ulong, &locking_settings.lock_retry_timeout,
63 0, NULL,
63 N_("Set timeout for acquiring the lock.") }, 64 N_("Set timeout for acquiring the lock.") },
64 { "retry-count", mu_cfg_ulong, &locking_settings.lock_retry_count, NULL, 65 { "retry-count", mu_cfg_ulong, &locking_settings.lock_retry_count, 0, NULL,
65 N_("Set the maximum number of times to retry acquiring the lock.") }, 66 N_("Set the maximum number of times to retry acquiring the lock.") },
66 { "expire-timeout", mu_cfg_ulong, &locking_settings.lock_expire_timeout, 67 { "expire-timeout", mu_cfg_ulong, &locking_settings.lock_expire_timeout,
67 NULL, 68 0, NULL,
68 N_("Expire locks older than this amount of time.") }, 69 N_("Expire locks older than this amount of time.") },
69 { "external-locker", mu_cfg_string, &locking_settings.external_locker, NULL, 70 { "external-locker", mu_cfg_string, &locking_settings.external_locker,
71 0, NULL,
70 N_("Use external locker program."), 72 N_("Use external locker program."),
71 N_("prog") }, 73 N_("prog") },
72 { NULL, } 74 { NULL, }
...@@ -80,11 +82,11 @@ DCL_CFG_CAPA (locking); ...@@ -80,11 +82,11 @@ DCL_CFG_CAPA (locking);
80 /* ************************************************************************* */ 82 /* ************************************************************************* */
81 83
82 static struct mu_cfg_param mu_address_param[] = { 84 static struct mu_cfg_param mu_address_param[] = {
83 { "email-addr", mu_cfg_string, &address_settings.address, NULL, 85 { "email-addr", mu_cfg_string, &address_settings.address, 0, NULL,
84 N_("Set the current user email address (default is " 86 N_("Set the current user email address (default is "
85 "loginname@defaultdomain)."), 87 "loginname@defaultdomain)."),
86 N_("email") }, 88 N_("email") },
87 { "email-domain", mu_cfg_string, &address_settings.domain, NULL, 89 { "email-domain", mu_cfg_string, &address_settings.domain, 0, NULL,
88 N_("Set e-mail domain for unqualified user names (default is this host)"), 90 N_("Set e-mail domain for unqualified user names (default is this host)"),
89 N_("domain") }, 91 N_("domain") },
90 { NULL } 92 { NULL }
...@@ -98,7 +100,7 @@ DCL_CFG_CAPA (address); ...@@ -98,7 +100,7 @@ DCL_CFG_CAPA (address);
98 /* ************************************************************************* */ 100 /* ************************************************************************* */
99 101
100 static struct mu_cfg_param mu_mailer_param[] = { 102 static struct mu_cfg_param mu_mailer_param[] = {
101 { "url", mu_cfg_string, &mailer_settings.mailer, NULL, 103 { "url", mu_cfg_string, &mailer_settings.mailer, 0, NULL,
102 N_("Use this URL as the default mailer"), 104 N_("Use this URL as the default mailer"),
103 N_("url") }, 105 N_("url") },
104 { NULL } 106 { NULL }
...@@ -125,7 +127,7 @@ cb_facility (mu_debug_t debug, void *data, char *arg) ...@@ -125,7 +127,7 @@ cb_facility (mu_debug_t debug, void *data, char *arg)
125 } 127 }
126 128
127 static struct mu_cfg_param mu_logging_param[] = { 129 static struct mu_cfg_param mu_logging_param[] = {
128 { "facility", mu_cfg_callback, NULL, cb_facility, 130 { "facility", mu_cfg_callback, NULL, 0, cb_facility,
129 N_("Set syslog facility. Arg is one of the following: user, daemon, " 131 N_("Set syslog facility. Arg is one of the following: user, daemon, "
130 "auth, authpriv, mail, cron, local0 through local7 (case-insensitive), " 132 "auth, authpriv, mail, cron, local0 through local7 (case-insensitive), "
131 "or a facility number.") }, 133 "or a facility number.") },
...@@ -156,19 +158,19 @@ _cb_daemon_mode (mu_debug_t debug, void *data, char *arg) ...@@ -156,19 +158,19 @@ _cb_daemon_mode (mu_debug_t debug, void *data, char *arg)
156 } 158 }
157 159
158 static struct mu_cfg_param mu_daemon_param[] = { 160 static struct mu_cfg_param mu_daemon_param[] = {
159 { "max-children", mu_cfg_ulong, &daemon_settings.maxchildren, NULL, 161 { "max-children", mu_cfg_ulong, &daemon_settings.maxchildren, 0, NULL,
160 N_("Maximum number of children processes to run simultaneously.") }, 162 N_("Maximum number of children processes to run simultaneously.") },
161 { "mode", mu_cfg_callback, NULL, _cb_daemon_mode, 163 { "mode", mu_cfg_callback, NULL, 0, _cb_daemon_mode,
162 N_("Set daemon mode (either inetd (or interactive) or daemon)."), 164 N_("Set daemon mode (either inetd (or interactive) or daemon)."),
163 N_("mode") }, 165 N_("mode") },
164 { "transcript", mu_cfg_bool, &daemon_settings.transcript, NULL, 166 { "transcript", mu_cfg_bool, &daemon_settings.transcript, 0, NULL,
165 N_("Log the session transcript.") }, 167 N_("Log the session transcript.") },
166 { "pidfile", mu_cfg_string, &daemon_settings.pidfile, NULL, 168 { "pidfile", mu_cfg_string, &daemon_settings.pidfile, 0, NULL,
167 N_("Store PID of the master process in this file."), 169 N_("Store PID of the master process in this file."),
168 N_("file") }, 170 N_("file") },
169 { "port", mu_cfg_ushort, &daemon_settings.port, NULL, 171 { "port", mu_cfg_ushort, &daemon_settings.port, 0, NULL,
170 N_("Listen on the specified port number.") }, 172 N_("Listen on the specified port number.") },
171 { "timeout", mu_cfg_ulong, &daemon_settings.timeout, NULL, 173 { "timeout", mu_cfg_ulong, &daemon_settings.timeout, 0, NULL,
172 N_("Set idle timeout.") }, 174 N_("Set idle timeout.") },
173 { NULL } 175 { NULL }
174 }; 176 };
...@@ -176,7 +178,8 @@ static struct mu_cfg_param mu_daemon_param[] = { ...@@ -176,7 +178,8 @@ static struct mu_cfg_param mu_daemon_param[] = {
176 int 178 int
177 mu_daemon_section_parser 179 mu_daemon_section_parser
178 (enum mu_cfg_section_stage stage, const mu_cfg_node_t *node, 180 (enum mu_cfg_section_stage stage, const mu_cfg_node_t *node,
179 void *section_data, void *call_data, mu_cfg_tree_t *tree) 181 const char *section_label, void **section_data,
182 void *call_data, mu_cfg_tree_t *tree)
180 { 183 {
181 switch (stage) 184 switch (stage)
182 { 185 {
...@@ -208,8 +211,10 @@ cb_debug_level (mu_debug_t debug, void *data, char *arg) ...@@ -208,8 +211,10 @@ cb_debug_level (mu_debug_t debug, void *data, char *arg)
208 size_t size; 211 size_t size;
209 char *pfx; 212 char *pfx;
210 struct mu_debug_locus locus; 213 struct mu_debug_locus locus;
211 214
212 debug_settings.string = arg; 215 if (debug_settings.string)
216 free (debug_settings.string);
217 debug_settings.string = strdup (arg);
213 if (mu_debug_get_locus (debug, &locus) == 0) 218 if (mu_debug_get_locus (debug, &locus) == 0)
214 { 219 {
215 p = umaxtostr (locus.line, buf); 220 p = umaxtostr (locus.line, buf);
...@@ -232,11 +237,11 @@ cb_debug_level (mu_debug_t debug, void *data, char *arg) ...@@ -232,11 +237,11 @@ cb_debug_level (mu_debug_t debug, void *data, char *arg)
232 } 237 }
233 238
234 static struct mu_cfg_param mu_debug_param[] = { 239 static struct mu_cfg_param mu_debug_param[] = {
235 { "level", mu_cfg_callback, NULL, &cb_debug_level, 240 { "level", mu_cfg_callback, NULL, 0, &cb_debug_level,
236 N_("Set Mailutils debugging level. Argument is a colon-separated list " 241 N_("Set Mailutils debugging level. Argument is a colon-separated list "
237 "of debugging specifications in the form:\n" 242 "of debugging specifications in the form:\n"
238 " <object: string>[[:]=<level: number>].") }, 243 " <object: string>[[:]=<level: number>].") },
239 { "line-info", mu_cfg_bool, &debug_settings.line_info, NULL, 244 { "line-info", mu_cfg_bool, &debug_settings.line_info, 0, NULL,
240 N_("Prefix debug messages with Mailutils source locations.") }, 245 N_("Prefix debug messages with Mailutils source locations.") },
241 { NULL } 246 { NULL }
242 }; 247 };
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
25 static struct mu_gsasl_module_data gsasl_settings; 25 static struct mu_gsasl_module_data gsasl_settings;
26 26
27 static struct mu_cfg_param mu_gsasl_param[] = { 27 static struct mu_cfg_param mu_gsasl_param[] = {
28 { "cram-passwd", mu_cfg_string, &gsasl_settings.cram_md5_pwd, NULL, 28 { "cram-passwd", mu_cfg_string, &gsasl_settings.cram_md5_pwd, 0, NULL,
29 N_("Name of GSASL password file."), 29 N_("Name of GSASL password file."),
30 N_("file") }, 30 N_("file") },
31 { NULL } 31 { NULL }
......
...@@ -78,14 +78,14 @@ mu_libcfg_init (char **cnames) ...@@ -78,14 +78,14 @@ mu_libcfg_init (char **cnames)
78 mu_error (_("Requested unknown configuration group `%s'"), 78 mu_error (_("Requested unknown configuration group `%s'"),
79 cnames[i]); 79 cnames[i]);
80 else 80 else
81 mu_config_register_section (NULL, cp->name, cp->parser, NULL, 81 mu_config_register_section (NULL, cp->name, NULL,
82 cp->cfgparam); 82 cp->parser, cp->cfgparam);
83 } 83 }
84 } 84 }
85 } 85 }
86 86
87 int 87 int
88 mu_parse_config_files (struct mu_cfg_param *param) 88 mu_parse_config_files (struct mu_cfg_param *param, void *target)
89 { 89 {
90 int flags = 0; 90 int flags = 0;
91 91
...@@ -96,7 +96,7 @@ mu_parse_config_files (struct mu_cfg_param *param) ...@@ -96,7 +96,7 @@ mu_parse_config_files (struct mu_cfg_param *param)
96 96
97 if (mu_load_site_rcfile) 97 if (mu_load_site_rcfile)
98 mu_parse_config (MU_CONFIG_FILE, mu_program_name, param, 98 mu_parse_config (MU_CONFIG_FILE, mu_program_name, param,
99 flags | MU_PARSE_CONFIG_GLOBAL); 99 flags | MU_PARSE_CONFIG_GLOBAL, target);
100 100
101 if (mu_load_user_rcfile && mu_program_name) 101 if (mu_load_user_rcfile && mu_program_name)
102 { 102 {
...@@ -107,14 +107,14 @@ mu_parse_config_files (struct mu_cfg_param *param) ...@@ -107,14 +107,14 @@ mu_parse_config_files (struct mu_cfg_param *param)
107 strcpy (file_name, "~/."); 107 strcpy (file_name, "~/.");
108 strcat (file_name, mu_program_name); 108 strcat (file_name, mu_program_name);
109 109
110 mu_parse_config (file_name, mu_program_name, param, flags); 110 mu_parse_config (file_name, mu_program_name, param, flags, target);
111 111
112 free (file_name); 112 free (file_name);
113 } 113 }
114 } 114 }
115 115
116 if (mu_load_rcfile) 116 if (mu_load_rcfile)
117 mu_parse_config (mu_load_rcfile, mu_program_name, param, flags); 117 mu_parse_config (mu_load_rcfile, mu_program_name, param, flags, target);
118 118
119 return 0; 119 return 0;
120 } 120 }
......
...@@ -37,24 +37,24 @@ cb_field_map (mu_debug_t debug, void *data, char *arg) ...@@ -37,24 +37,24 @@ cb_field_map (mu_debug_t debug, void *data, char *arg)
37 } 37 }
38 38
39 static struct mu_cfg_param mu_ldap_param[] = { 39 static struct mu_cfg_param mu_ldap_param[] = {
40 { "enable", mu_cfg_bool, &ldap_settings.enable, NULL, 40 { "enable", mu_cfg_bool, &ldap_settings.enable, 0, NULL,
41 N_("Enable LDAP lookups.") }, 41 N_("Enable LDAP lookups.") },
42 { "url", mu_cfg_string, &ldap_settings.url, NULL, 42 { "url", mu_cfg_string, &ldap_settings.url, 0, NULL,
43 N_("Set URL of the LDAP server."), 43 N_("Set URL of the LDAP server."),
44 N_("url") }, 44 N_("url") },
45 { "base", mu_cfg_string, &ldap_settings.base, NULL, 45 { "base", mu_cfg_string, &ldap_settings.base, 0, NULL,
46 N_("Base DN for LDAP lookups."), 46 N_("Base DN for LDAP lookups."),
47 N_("dn") }, 47 N_("dn") },
48 { "binddn", mu_cfg_string, &ldap_settings.binddn, NULL, 48 { "binddn", mu_cfg_string, &ldap_settings.binddn, 0, NULL,
49 N_("DN for accessing LDAP database."), 49 N_("DN for accessing LDAP database."),
50 N_("dn") }, 50 N_("dn") },
51 { "passwd", mu_cfg_string, &ldap_settings.passwd, NULL, 51 { "passwd", mu_cfg_string, &ldap_settings.passwd, 0, NULL,
52 N_("Password for use with binddn.") }, 52 N_("Password for use with binddn.") },
53 { "tls", mu_cfg_bool, &ldap_settings.tls, NULL, 53 { "tls", mu_cfg_bool, &ldap_settings.tls, 0, NULL,
54 N_("Use TLS encryption.") }, 54 N_("Use TLS encryption.") },
55 { "debug", mu_cfg_int, &ldap_settings.debug, NULL, 55 { "debug", mu_cfg_int, &ldap_settings.debug, 0, NULL,
56 N_("Set LDAP debugging level.") }, 56 N_("Set LDAP debugging level.") },
57 { "field-map", mu_cfg_callback, NULL, cb_field_map, 57 { "field-map", mu_cfg_callback, NULL, 0, cb_field_map,
58 N_("Set a field-map for parsing LDAP replies. The map is a " 58 N_("Set a field-map for parsing LDAP replies. The map is a "
59 "column-separated list of definitions. Each definition has the " 59 "column-separated list of definitions. Each definition has the "
60 "following form:\n" 60 "following form:\n"
...@@ -63,10 +63,10 @@ static struct mu_cfg_param mu_ldap_param[] = { ...@@ -63,10 +63,10 @@ static struct mu_cfg_param mu_ldap_param[] = {
63 "gecos, dir, shell, mailbox, quota, and <attr> is the name of " 63 "gecos, dir, shell, mailbox, quota, and <attr> is the name of "
64 "the correspondind LDAP attribute."), 64 "the correspondind LDAP attribute."),
65 N_("map") }, 65 N_("map") },
66 { "getpwnam", mu_cfg_string, &ldap_settings.getpwnam_filter, NULL, 66 { "getpwnam", mu_cfg_string, &ldap_settings.getpwnam_filter, 0, NULL,
67 N_("LDAP filter to use for getpwnam requests."), 67 N_("LDAP filter to use for getpwnam requests."),
68 N_("filter") }, 68 N_("filter") },
69 { "getpwuid", mu_cfg_string, &ldap_settings.getpwuid_filter, NULL, 69 { "getpwuid", mu_cfg_string, &ldap_settings.getpwuid_filter, 0, NULL,
70 N_("LDAP filter to use for getpwuid requests."), 70 N_("LDAP filter to use for getpwuid requests."),
71 N_("filter") }, 71 N_("filter") },
72 { NULL } 72 { NULL }
...@@ -75,7 +75,8 @@ static struct mu_cfg_param mu_ldap_param[] = { ...@@ -75,7 +75,8 @@ static struct mu_cfg_param mu_ldap_param[] = {
75 int 75 int
76 mu_ldap_section_parser 76 mu_ldap_section_parser
77 (enum mu_cfg_section_stage stage, const mu_cfg_node_t *node, 77 (enum mu_cfg_section_stage stage, const mu_cfg_node_t *node,
78 void *section_data, void *call_data, mu_cfg_tree_t *tree) 78 const char *section_label, void **section_data,
79 void *call_data, mu_cfg_tree_t *tree)
79 { 80 {
80 switch (stage) 81 switch (stage)
81 { 82 {
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
24 static char *pam_settings; 24 static char *pam_settings;
25 25
26 static struct mu_cfg_param mu_pam_param[] = { 26 static struct mu_cfg_param mu_pam_param[] = {
27 { "service", mu_cfg_string, &pam_settings, NULL, 27 { "service", mu_cfg_string, &pam_settings, 0, NULL,
28 N_("Set PAM service name."), 28 N_("Set PAM service name."),
29 N_("name") }, 29 N_("name") },
30 { NULL } 30 { NULL }
......
...@@ -25,16 +25,16 @@ ...@@ -25,16 +25,16 @@
25 static struct mu_radius_module_data radius_settings; 25 static struct mu_radius_module_data radius_settings;
26 26
27 static struct mu_cfg_param mu_radius_param[] = { 27 static struct mu_cfg_param mu_radius_param[] = {
28 { "auth", mu_cfg_string, &radius_settings.auth_request, NULL, 28 { "auth", mu_cfg_string, &radius_settings.auth_request, 0, NULL,
29 N_("Radius request for authorization."), 29 N_("Radius request for authorization."),
30 N_("request") }, 30 N_("request") },
31 { "getpwnam", mu_cfg_string, &radius_settings.getpwnam_request, NULL, 31 { "getpwnam", mu_cfg_string, &radius_settings.getpwnam_request, 0, NULL,
32 N_("Radius request for getpwnam."), 32 N_("Radius request for getpwnam."),
33 N_("request") }, 33 N_("request") },
34 { "getpwuid", mu_cfg_string, &radius_settings.getpwuid_request, NULL, 34 { "getpwuid", mu_cfg_string, &radius_settings.getpwuid_request, 0, NULL,
35 N_("Radius request for getpwuid."), 35 N_("Radius request for getpwuid."),
36 N_("request") }, 36 N_("request") },
37 { "directory", mu_cfg_string, &radius_settings.config_dir, NULL, 37 { "directory", mu_cfg_string, &radius_settings.config_dir, 0, NULL,
38 N_("Set radius configuration directory.") }, 38 N_("Set radius configuration directory.") },
39 { NULL } 39 { NULL }
40 }; 40 };
......
...@@ -92,15 +92,15 @@ cb_library_path (mu_debug_t debug, void *data, char *arg) ...@@ -92,15 +92,15 @@ cb_library_path (mu_debug_t debug, void *data, char *arg)
92 } 92 }
93 93
94 static struct mu_cfg_param mu_sieve_param[] = { 94 static struct mu_cfg_param mu_sieve_param[] = {
95 { "clear-library-path", mu_cfg_callback, NULL, cb_clear_library_path, 95 { "clear-library-path", mu_cfg_callback, NULL, 0, cb_clear_library_path,
96 N_("Clear library search path.") }, 96 N_("Clear library search path.") },
97 { "clear-include-path", mu_cfg_callback, NULL, cb_clear_include_path, 97 { "clear-include-path", mu_cfg_callback, NULL, 0, cb_clear_include_path,
98 N_("Clear include search path.") }, 98 N_("Clear include search path.") },
99 { "library-path", mu_cfg_callback, NULL, cb_library_path, 99 { "library-path", mu_cfg_callback, NULL, 0, cb_library_path,
100 N_("Add directories to the library search path. Argument is a " 100 N_("Add directories to the library search path. Argument is a "
101 "comma-separated list of directories."), 101 "comma-separated list of directories."),
102 N_("list") }, 102 N_("list") },
103 { "include-path", mu_cfg_callback, NULL, cb_include_path, 103 { "include-path", mu_cfg_callback, NULL, 0, cb_include_path,
104 N_("Add directories to the include search path. Argument is a " 104 N_("Add directories to the include search path. Argument is a "
105 "comma-separated list of directories."), 105 "comma-separated list of directories."),
106 N_("list") }, 106 N_("list") },
......
...@@ -50,31 +50,31 @@ cb_field_map (mu_debug_t debug, void *data, char *arg) ...@@ -50,31 +50,31 @@ cb_field_map (mu_debug_t debug, void *data, char *arg)
50 } 50 }
51 51
52 static struct mu_cfg_param mu_sql_param[] = { 52 static struct mu_cfg_param mu_sql_param[] = {
53 { "interface", mu_cfg_string, &sql_settings.interface, NULL, 53 { "interface", mu_cfg_string, &sql_settings.interface, 0, NULL,
54 N_("Set SQL interface to use (one of: mysql, odbc, or postgres).") }, 54 N_("Set SQL interface to use (one of: mysql, odbc, or postgres).") },
55 { "getwpnam", mu_cfg_string, &sql_settings.getpwnam_query, NULL, 55 { "getwpnam", mu_cfg_string, &sql_settings.getpwnam_query, 0, NULL,
56 N_("SQL query to use for getpwnam requests."), 56 N_("SQL query to use for getpwnam requests."),
57 N_("query") }, 57 N_("query") },
58 { "getpwuid", mu_cfg_string, &sql_settings.getpwuid_query, NULL, 58 { "getpwuid", mu_cfg_string, &sql_settings.getpwuid_query, 0, NULL,
59 N_("SQL query to use for getpwuid requests."), 59 N_("SQL query to use for getpwuid requests."),
60 N_("query") }, 60 N_("query") },
61 { "getpass", mu_cfg_string, &sql_settings.getpass_query, NULL, 61 { "getpass", mu_cfg_string, &sql_settings.getpass_query, 0, NULL,
62 N_("SQL query returning the user's password."), 62 N_("SQL query returning the user's password."),
63 N_("query") }, 63 N_("query") },
64 { "host", mu_cfg_string, &sql_settings.host, NULL, 64 { "host", mu_cfg_string, &sql_settings.host, 0, NULL,
65 N_("SQL server host name.") }, 65 N_("SQL server host name.") },
66 { "user", mu_cfg_string, &sql_settings.user, NULL, 66 { "user", mu_cfg_string, &sql_settings.user, 0, NULL,
67 N_("SQL user name.") }, 67 N_("SQL user name.") },
68 { "passwd", mu_cfg_string, &sql_settings.passwd, NULL, 68 { "passwd", mu_cfg_string, &sql_settings.passwd, 0, NULL,
69 N_("Password for the SQL user.") }, 69 N_("Password for the SQL user.") },
70 { "port", mu_cfg_int, &sql_settings.port, NULL, 70 { "port", mu_cfg_int, &sql_settings.port, 0, NULL,
71 N_("SQL server port.") }, 71 N_("SQL server port.") },
72 { "db", mu_cfg_string, &sql_settings.db, NULL, 72 { "db", mu_cfg_string, &sql_settings.db, 0, NULL,
73 N_("Database name.") }, 73 N_("Database name.") },
74 { "password-type", mu_cfg_callback, NULL, cb_password_type, 74 { "password-type", mu_cfg_callback, NULL, 0, cb_password_type,
75 N_("Type of password returned by getpass query (one of: plain, hash, " 75 N_("Type of password returned by getpass query (one of: plain, hash, "
76 "scrambled).") }, 76 "scrambled).") },
77 { "field-map", mu_cfg_callback, NULL, cb_field_map, 77 { "field-map", mu_cfg_callback, NULL, 0, cb_field_map,
78 N_("Set a field-map for parsing SQL replies. The map is a " 78 N_("Set a field-map for parsing SQL replies. The map is a "
79 "column-separated list of definitions. Each definition has the " 79 "column-separated list of definitions. Each definition has the "
80 "following form:\n" 80 "following form:\n"
......
...@@ -25,15 +25,15 @@ ...@@ -25,15 +25,15 @@
25 static struct mu_tls_module_config tls_settings; 25 static struct mu_tls_module_config tls_settings;
26 26
27 static struct mu_cfg_param mu_tls_param[] = { 27 static struct mu_cfg_param mu_tls_param[] = {
28 { "tls", mu_cfg_bool, &tls_settings.client_enable, NULL, 28 { "tls", mu_cfg_bool, &tls_settings.client_enable, 0, NULL,
29 N_("Enable client TLS encryption.") }, 29 N_("Enable client TLS encryption.") },
30 { "ssl-cert", mu_cfg_string, &tls_settings.ssl_cert, NULL, 30 { "ssl-cert", mu_cfg_string, &tls_settings.ssl_cert, 0, NULL,
31 N_("Specify SSL certificate file."), 31 N_("Specify SSL certificate file."),
32 N_("file") }, 32 N_("file") },
33 { "ssl-key", mu_cfg_string, &tls_settings.ssl_key, NULL, 33 { "ssl-key", mu_cfg_string, &tls_settings.ssl_key, 0, NULL,
34 N_("Specify SSL certificate key file."), 34 N_("Specify SSL certificate key file."),
35 N_("file") }, 35 N_("file") },
36 { "ssl-cafile", mu_cfg_string, &tls_settings.ssl_cafile, NULL, 36 { "ssl-cafile", mu_cfg_string, &tls_settings.ssl_cafile, 0, NULL,
37 N_("Specify trusted CAs file."), 37 N_("Specify trusted CAs file."),
38 N_("file") }, 38 N_("file") },
39 { NULL } 39 { NULL }
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
24 static struct mu_gocs_virtual virtdomain_settings; 24 static struct mu_gocs_virtual virtdomain_settings;
25 25
26 static struct mu_cfg_param mu_virtdomain_param[] = { 26 static struct mu_cfg_param mu_virtdomain_param[] = {
27 { "passwd-dir", mu_cfg_string, &virtdomain_settings, NULL, 27 { "passwd-dir", mu_cfg_string, &virtdomain_settings, 0, NULL,
28 N_("Name of the directory where virtual domain password files are " 28 N_("Name of the directory where virtual domain password files are "
29 "located."), 29 "located."),
30 N_("dir") }, 30 N_("dir") },
......
...@@ -238,57 +238,57 @@ cb_debug (mu_debug_t debug, void *data, char *arg) ...@@ -238,57 +238,57 @@ cb_debug (mu_debug_t debug, void *data, char *arg)
238 } 238 }
239 239
240 struct mu_cfg_param maidag_cfg_param[] = { 240 struct mu_cfg_param maidag_cfg_param[] = {
241 { "exit-multiple-delivery-success", mu_cfg_bool, &multiple_delivery, NULL, 241 { "exit-multiple-delivery-success", mu_cfg_bool, &multiple_delivery, 0, NULL,
242 N_("In case of multiple delivery, exit with code 0 if at least one " 242 N_("In case of multiple delivery, exit with code 0 if at least one "
243 "delivery succeeded.") }, 243 "delivery succeeded.") },
244 { "exit-quota-tempfail", mu_cfg_bool, &ex_quota_tempfail, NULL, 244 { "exit-quota-tempfail", mu_cfg_bool, &ex_quota_tempfail, 0, NULL,
245 N_("Indicate temporary failure if the recipient is over his mail quota.") 245 N_("Indicate temporary failure if the recipient is over his mail quota.")
246 }, 246 },
247 #ifdef USE_DBM 247 #ifdef USE_DBM
248 { "quota-db", mu_cfg_string, &quotadbname, NULL, 248 { "quota-db", mu_cfg_string, &quotadbname, 0, NULL,
249 N_("Name of DBM quota database file."), 249 N_("Name of DBM quota database file."),
250 N_("file") }, 250 N_("file") },
251 #endif 251 #endif
252 #ifdef USE_SQL 252 #ifdef USE_SQL
253 { "quota-query", mu_cfg_string, &quota_query, NULL, 253 { "quota-query", mu_cfg_string, &quota_query, 0, NULL,
254 N_("SQL query to retrieve mailbox quota. This is deprecated, use " 254 N_("SQL query to retrieve mailbox quota. This is deprecated, use "
255 "sql { ... } instead."), 255 "sql { ... } instead."),
256 N_("query") }, 256 N_("query") },
257 #endif 257 #endif
258 { "sieve-filter", mu_cfg_string, &sieve_pattern, NULL, 258 { "sieve-filter", mu_cfg_string, &sieve_pattern, 0, NULL,
259 N_("File name or name pattern for Sieve filter file."), 259 N_("File name or name pattern for Sieve filter file."),
260 N_("file-or-pattern") }, 260 N_("file-or-pattern") },
261 { "message-id-header", mu_cfg_string, &message_id_header, NULL, 261 { "message-id-header", mu_cfg_string, &message_id_header, 0, NULL,
262 N_("When logging Sieve actions, identify messages by the value of " 262 N_("When logging Sieve actions, identify messages by the value of "
263 "this header."), 263 "this header."),
264 N_("name") }, 264 N_("name") },
265 #ifdef WITH_GUILE 265 #ifdef WITH_GUILE
266 { "guile-filter", mu_cfg_string, &progfile_pattern, NULL, 266 { "guile-filter", mu_cfg_string, &progfile_pattern, 0, NULL,
267 N_("File name or name pattern for Guile filter file."), 267 N_("File name or name pattern for Guile filter file."),
268 N_("file-or-pattern") }, 268 N_("file-or-pattern") },
269 #endif 269 #endif
270 { "debug", mu_cfg_callback, NULL, cb_debug, 270 { "debug", mu_cfg_callback, NULL, 0, cb_debug,
271 N_("Set maidag debug level. Debug level consists of one or more " 271 N_("Set maidag debug level. Debug level consists of one or more "
272 "of the following letters:\n" 272 "of the following letters:\n"
273 " g - guimb stack traces\n" 273 " g - guimb stack traces\n"
274 " t - sieve trace (MU_SIEVE_DEBUG_TRACE)\n" 274 " t - sieve trace (MU_SIEVE_DEBUG_TRACE)\n"
275 " i - sieve instructions trace (MU_SIEVE_DEBUG_INSTR)\n" 275 " i - sieve instructions trace (MU_SIEVE_DEBUG_INSTR)\n"
276 " l - sieve action logs\n") }, 276 " l - sieve action logs\n") },
277 { "stderr", mu_cfg_bool, &log_to_stderr, NULL, 277 { "stderr", mu_cfg_bool, &log_to_stderr, 0, NULL,
278 N_("Log to stderr instead of syslog.") }, 278 N_("Log to stderr instead of syslog.") },
279 /* LMTP support */ 279 /* LMTP support */
280 { "lmtp", mu_cfg_bool, &lmtp_mode, NULL, 280 { "lmtp", mu_cfg_bool, &lmtp_mode, 0, NULL,
281 N_("Run in LMTP mode.") }, 281 N_("Run in LMTP mode.") },
282 { "group", mu_cfg_string, &lmtp_group, NULL, 282 { "group", mu_cfg_string, &lmtp_group, 0, NULL,
283 N_("In LMTP mode, change to this group after startup.") }, 283 N_("In LMTP mode, change to this group after startup.") },
284 { "listen", mu_cfg_string, &lmtp_url_string, NULL, 284 { "listen", mu_cfg_string, &lmtp_url_string, 0, NULL,
285 N_("In LMTP mode, listen on the given URL. Valid URLs are:\n" 285 N_("In LMTP mode, listen on the given URL. Valid URLs are:\n"
286 " tcp://<address: string>:<port: number> (note that port is " 286 " tcp://<address: string>:<port: number> (note that port is "
287 "mandatory)\n" 287 "mandatory)\n"
288 " file://<socket-file-name>\n" 288 " file://<socket-file-name>\n"
289 "or socket://<socket-file-name>"), 289 "or socket://<socket-file-name>"),
290 N_("url") }, 290 N_("url") },
291 { "reuse-address", mu_cfg_bool, &reuse_lmtp_address, NULL, 291 { "reuse-address", mu_cfg_bool, &reuse_lmtp_address, 0, NULL,
292 N_("Reuse existing address (LMTP mode). Default is \"yes\".") }, 292 N_("Reuse existing address (LMTP mode). Default is \"yes\".") },
293 TCP_WRAPPERS_CONFIG 293 TCP_WRAPPERS_CONFIG
294 { NULL } 294 { NULL }
......
...@@ -255,36 +255,36 @@ cb_debug (mu_debug_t debug, void *data, char *arg) ...@@ -255,36 +255,36 @@ cb_debug (mu_debug_t debug, void *data, char *arg)
255 } 255 }
256 256
257 struct mu_cfg_param mail_local_cfg_param[] = { 257 struct mu_cfg_param mail_local_cfg_param[] = {
258 { "ex-multiple-delivery-success", mu_cfg_bool, &multiple_delivery, NULL, 258 { "ex-multiple-delivery-success", mu_cfg_bool, &multiple_delivery, 0, NULL,
259 N_("In case of multiple delivery, exit with code 0 if at least one " 259 N_("In case of multiple delivery, exit with code 0 if at least one "
260 "delivery succeeded.") }, 260 "delivery succeeded.") },
261 { "ex-quota-tempfail", mu_cfg_bool, &ex_quota_tempfail, NULL, 261 { "ex-quota-tempfail", mu_cfg_bool, &ex_quota_tempfail, 0, NULL,
262 N_("Indicate temporary failure if the recipient is over his mail quota.") 262 N_("Indicate temporary failure if the recipient is over his mail quota.")
263 }, 263 },
264 #ifdef USE_DBM 264 #ifdef USE_DBM
265 { "quota-db", mu_cfg_string, &quotadbname, NULL, 265 { "quota-db", mu_cfg_string, &quotadbname, 0, NULL,
266 N_("Name of DBM quota database file."), 266 N_("Name of DBM quota database file."),
267 N_("file") }, 267 N_("file") },
268 #endif 268 #endif
269 #ifdef USE_SQL 269 #ifdef USE_SQL
270 { "quota-query", mu_cfg_string, &quota_query, NULL, 270 { "quota-query", mu_cfg_string, &quota_query, 0, NULL,
271 N_("SQL query to retrieve mailbox quota. This is deprecated, use " 271 N_("SQL query to retrieve mailbox quota. This is deprecated, use "
272 "sql { ... } instead."), 272 "sql { ... } instead."),
273 N_("query") }, 273 N_("query") },
274 #endif 274 #endif
275 { "sieve-filter", mu_cfg_string, &sieve_pattern, NULL, 275 { "sieve-filter", mu_cfg_string, &sieve_pattern, 0, NULL,
276 N_("File name or name pattern for Sieve filter file."), 276 N_("File name or name pattern for Sieve filter file."),
277 N_("file-or-pattern") }, 277 N_("file-or-pattern") },
278 { "message-id-header", mu_cfg_string, &message_id_header, NULL, 278 { "message-id-header", mu_cfg_string, &message_id_header, 0, NULL,
279 N_("When logging Sieve actions, identify messages by the value of " 279 N_("When logging Sieve actions, identify messages by the value of "
280 "this header."), 280 "this header."),
281 N_("name") }, 281 N_("name") },
282 #ifdef WITH_GUILE 282 #ifdef WITH_GUILE
283 { "guile-filter", mu_cfg_string, &progfile_pattern, NULL, 283 { "guile-filter", mu_cfg_string, &progfile_pattern, 0, NULL,
284 N_("File name or name pattern for Guile filter file."), 284 N_("File name or name pattern for Guile filter file."),
285 N_("file-or-pattern") }, 285 N_("file-or-pattern") },
286 #endif 286 #endif
287 { "debug", mu_cfg_callback, NULL, cb_debug, 287 { "debug", mu_cfg_callback, NULL, 0, cb_debug,
288 N_("Set mail.local debug level. Debug level consists of one or more " 288 N_("Set mail.local debug level. Debug level consists of one or more "
289 "of the following letters:\n" 289 "of the following letters:\n"
290 " g - guimb stack traces\n" 290 " g - guimb stack traces\n"
......
...@@ -136,12 +136,12 @@ static struct argp argp = { ...@@ -136,12 +136,12 @@ static struct argp argp = {
136 136
137 137
138 struct mu_cfg_param mail_remote_cfg_param[] = { 138 struct mu_cfg_param mail_remote_cfg_param[] = {
139 { "from", mu_cfg_string, &optfrom, NULL, 139 { "from", mu_cfg_string, &optfrom, 0, NULL,
140 N_("Set sender email address."), 140 N_("Set sender email address."),
141 N_("email") }, 141 N_("email") },
142 { "read-recipients", mu_cfg_string, &read_recipients, NULL, 142 { "read-recipients", mu_cfg_string, &read_recipients, 0, NULL,
143 N_("Read recipient addresses from the message.") }, 143 N_("Read recipient addresses from the message.") },
144 { "debug", mu_cfg_int, &optdebug, NULL, 144 { "debug", mu_cfg_int, &optdebug, 0, NULL,
145 N_("Set debug verbosity level. Level 1 prints envelope commands in " 145 N_("Set debug verbosity level. Level 1 prints envelope commands in "
146 "the SMTP protocol transaction. Levels 2 and above print the data " 146 "the SMTP protocol transaction. Levels 2 and above print the data "
147 "part of the transaction as well.") }, 147 "part of the transaction as well.") },
......
...@@ -50,6 +50,7 @@ libmailutils_la_SOURCES = \ ...@@ -50,6 +50,7 @@ libmailutils_la_SOURCES = \
50 dbgstderr.c\ 50 dbgstderr.c\
51 dbgsyslog.c\ 51 dbgsyslog.c\
52 debug.c\ 52 debug.c\
53 cfg_driver.c\
53 cfg_format.c\ 54 cfg_format.c\
54 cfg_lexer.c\ 55 cfg_lexer.c\
55 cfg_parser.c\ 56 cfg_parser.c\
......
...@@ -172,6 +172,8 @@ mu_cfg_data_type_string (enum mu_cfg_param_data_type type) ...@@ -172,6 +172,8 @@ mu_cfg_data_type_string (enum mu_cfg_param_data_type type)
172 return N_("host"); 172 return N_("host");
173 case mu_cfg_callback: 173 case mu_cfg_callback:
174 return N_("string"); 174 return N_("string");
175 case mu_cfg_section:
176 return N_("section");
175 } 177 }
176 return N_("unknown"); 178 return N_("unknown");
177 } 179 }
...@@ -261,19 +263,16 @@ format_section (mu_stream_t stream, struct mu_cfg_section *sect, int level) ...@@ -261,19 +263,16 @@ format_section (mu_stream_t stream, struct mu_cfg_section *sect, int level)
261 if (sect->ident) 263 if (sect->ident)
262 { 264 {
263 mu_stream_sequential_write (stream, sect->ident, strlen (sect->ident)); 265 mu_stream_sequential_write (stream, sect->ident, strlen (sect->ident));
264 if (sect->data) 266 if (sect->label)
265 { 267 {
266 /* FIXME: This is wrong in general. Data is an opaque data
267 pointer. */
268 char *s = sect->data;
269 mu_stream_sequential_write (stream, " ", 1); 268 mu_stream_sequential_write (stream, " ", 1);
270 mu_stream_sequential_write (stream, s, strlen (s)); 269 mu_stream_sequential_write (stream, sect->label,
270 strlen (sect->label));
271 } 271 }
272 mu_stream_sequential_write (stream, " {\n", 3); 272 mu_stream_sequential_write (stream, " {\n", 3);
273 c.stream = stream; 273 c.stream = stream;
274 c.level = level + 1; 274 c.level = level + 1;
275 mu_list_do (sect->subsec, _f_helper, &c); 275 mu_list_do (sect->children, _f_helper, &c);
276 mu_list_do (sect->param, _f_helper, &c);
277 format_level (stream, level); 276 format_level (stream, level);
278 mu_stream_sequential_write (stream, "};\n\n", 4); 277 mu_stream_sequential_write (stream, "};\n\n", 4);
279 } 278 }
...@@ -281,8 +280,7 @@ format_section (mu_stream_t stream, struct mu_cfg_section *sect, int level) ...@@ -281,8 +280,7 @@ format_section (mu_stream_t stream, struct mu_cfg_section *sect, int level)
281 { 280 {
282 c.stream = stream; 281 c.stream = stream;
283 c.level = level; 282 c.level = level;
284 mu_list_do (sect->subsec, _f_helper, &c); 283 mu_list_do (sect->children, _f_helper, &c);
285 mu_list_do (sect->param, _f_helper, &c);
286 } 284 }
287 } 285 }
288 286
......
...@@ -497,13 +497,15 @@ struct mu_cfg_section_list ...@@ -497,13 +497,15 @@ struct mu_cfg_section_list
497 struct scan_tree_data 497 struct scan_tree_data
498 { 498 {
499 struct mu_cfg_section_list *list; 499 struct mu_cfg_section_list *list;
500 void *target;
500 void *call_data; 501 void *call_data;
501 mu_cfg_tree_t *tree; 502 mu_cfg_tree_t *tree;
502 int error; 503 int error;
503 }; 504 };
504 505
505 static struct mu_cfg_cont * 506 static struct mu_cfg_cont *
506 find_container (mu_list_t list, const char *ident, size_t len) 507 find_container (mu_list_t list, enum mu_cfg_cont_type type,
508 const char *ident, size_t len)
507 { 509 {
508 mu_iterator_t iter; 510 mu_iterator_t iter;
509 struct mu_cfg_cont *ret = NULL; 511 struct mu_cfg_cont *ret = NULL;
...@@ -518,7 +520,8 @@ find_container (mu_list_t list, const char *ident, size_t len) ...@@ -518,7 +520,8 @@ find_container (mu_list_t list, const char *ident, size_t len)
518 struct mu_cfg_cont *cont; 520 struct mu_cfg_cont *cont;
519 mu_iterator_current (iter, (void**) &cont); 521 mu_iterator_current (iter, (void**) &cont);
520 522
521 if (strlen (cont->v.ident) == len 523 if (cont->type == type
524 && strlen (cont->v.ident) == len
522 && memcmp (cont->v.ident, ident, len) == 0) 525 && memcmp (cont->v.ident, ident, len) == 0)
523 { 526 {
524 ret = cont; 527 ret = cont;
...@@ -534,9 +537,11 @@ find_subsection (struct mu_cfg_section *sec, const char *ident, size_t len) ...@@ -534,9 +537,11 @@ find_subsection (struct mu_cfg_section *sec, const char *ident, size_t len)
534 { 537 {
535 if (sec) 538 if (sec)
536 { 539 {
537 if (sec->subsec) 540 if (sec->children)
538 { 541 {
539 struct mu_cfg_cont *cont = find_container (sec->subsec, ident, len); 542 struct mu_cfg_cont *cont = find_container (sec->children,
543 mu_cfg_cont_section,
544 ident, len);
540 if (cont) 545 if (cont)
541 return &cont->v.section; 546 return &cont->v.section;
542 } 547 }
...@@ -549,9 +554,11 @@ find_param (struct mu_cfg_section *sec, const char *ident, size_t len) ...@@ -549,9 +554,11 @@ find_param (struct mu_cfg_section *sec, const char *ident, size_t len)
549 { 554 {
550 if (sec) 555 if (sec)
551 { 556 {
552 if (sec->param) 557 if (sec->children)
553 { 558 {
554 struct mu_cfg_cont *cont = find_container (sec->param, ident, len); 559 struct mu_cfg_cont *cont = find_container (sec->children,
560 mu_cfg_cont_param,
561 ident, len);
555 if (cont) 562 if (cont)
556 return &cont->v.param; 563 return &cont->v.param;
557 } 564 }
...@@ -842,8 +849,10 @@ parse_bool (struct scan_tree_data *sdata, const mu_cfg_node_t *node, int *res) ...@@ -842,8 +849,10 @@ parse_bool (struct scan_tree_data *sdata, const mu_cfg_node_t *node, int *res)
842 static int 849 static int
843 parse_param (struct scan_tree_data *sdata, const mu_cfg_node_t *node) 850 parse_param (struct scan_tree_data *sdata, const mu_cfg_node_t *node)
844 { 851 {
852 void *tgt;
845 struct mu_cfg_param *param = find_param (sdata->list->sec, node->tag_name, 853 struct mu_cfg_param *param = find_param (sdata->list->sec, node->tag_name,
846 0); 854 0);
855
847 if (!param) 856 if (!param)
848 { 857 {
849 _mu_cfg_perror (sdata->tree->debug, &node->locus, 858 _mu_cfg_perror (sdata->tree->debug, &node->locus,
...@@ -852,6 +861,22 @@ parse_param (struct scan_tree_data *sdata, const mu_cfg_node_t *node) ...@@ -852,6 +861,22 @@ parse_param (struct scan_tree_data *sdata, const mu_cfg_node_t *node)
852 return 1; 861 return 1;
853 } 862 }
854 863
864 if (param->data)
865 tgt = param->data;
866 else if (sdata->list->sec->target)
867 tgt = (char*)sdata->list->sec->target + param->offset;
868 else if (sdata->target)
869 tgt = (char*)sdata->target + param->offset;
870 else if (param->type == mu_cfg_callback)
871 tgt = NULL;
872 else
873 {
874 _mu_cfg_perror (sdata->tree->debug, &node->locus,
875 _("INTERNAL ERROR: cannot determine target offset for "
876 "%s"), param->ident);
877 abort ();
878 }
879
855 switch (param->type) 880 switch (param->type)
856 { 881 {
857 case mu_cfg_string: 882 case mu_cfg_string:
...@@ -865,80 +890,80 @@ parse_param (struct scan_tree_data *sdata, const mu_cfg_node_t *node) ...@@ -865,80 +890,80 @@ parse_param (struct scan_tree_data *sdata, const mu_cfg_node_t *node)
865 return 1; 890 return 1;
866 } 891 }
867 strcpy (s, node->tag_label); 892 strcpy (s, node->tag_label);
868 /* FIXME: free param->data? */ 893 /* FIXME: free tgt? */
869 *(char**)param->data = s; 894 *(char**)tgt = s;
870 break; 895 break;
871 } 896 }
872 897
873 case mu_cfg_short: 898 case mu_cfg_short:
874 GETSNUM (node->tag_label, short, *(short*)param->data, 899 GETSNUM (node->tag_label, short, *(short*)tgt,
875 sdata->tree->debug); 900 sdata->tree->debug);
876 break; 901 break;
877 902
878 case mu_cfg_ushort: 903 case mu_cfg_ushort:
879 GETUNUM (node->tag_label, unsigned short, *(unsigned short*)param->data, 904 GETUNUM (node->tag_label, unsigned short, *(unsigned short*)tgt,
880 sdata->tree->debug); 905 sdata->tree->debug);
881 break; 906 break;
882 907
883 case mu_cfg_int: 908 case mu_cfg_int:
884 GETSNUM (node->tag_label, int, *(int*)param->data, sdata->tree->debug); 909 GETSNUM (node->tag_label, int, *(int*)tgt, sdata->tree->debug);
885 break; 910 break;
886 911
887 case mu_cfg_uint: 912 case mu_cfg_uint:
888 GETUNUM (node->tag_label, unsigned int, *(unsigned int*)param->data, 913 GETUNUM (node->tag_label, unsigned int, *(unsigned int*)tgt,
889 sdata->tree->debug); 914 sdata->tree->debug);
890 break; 915 break;
891 916
892 case mu_cfg_long: 917 case mu_cfg_long:
893 GETSNUM (node->tag_label, long, *(long*)param->data, 918 GETSNUM (node->tag_label, long, *(long*)tgt,
894 sdata->tree->debug); 919 sdata->tree->debug);
895 break; 920 break;
896 921
897 case mu_cfg_ulong: 922 case mu_cfg_ulong:
898 GETUNUM (node->tag_label, unsigned long, *(unsigned long*)param->data, 923 GETUNUM (node->tag_label, unsigned long, *(unsigned long*)tgt,
899 sdata->tree->debug); 924 sdata->tree->debug);
900 break; 925 break;
901 926
902 case mu_cfg_size: 927 case mu_cfg_size:
903 GETUNUM (node->tag_label, size_t, *(size_t*)param->data, 928 GETUNUM (node->tag_label, size_t, *(size_t*)tgt,
904 sdata->tree->debug); 929 sdata->tree->debug);
905 break; 930 break;
906 931
907 case mu_cfg_off: 932 case mu_cfg_off:
908 _mu_cfg_perror (sdata->tree->debug, &node->locus, 933 _mu_cfg_perror (sdata->tree->debug, &node->locus,
909 _("not implemented yet")); 934 _("not implemented yet"));
910 /* GETSNUM(node->tag_label, off_t, *(off_t*)param->data); */ 935 /* GETSNUM(node->tag_label, off_t, *(off_t*)tgt); */
911 return 1; 936 return 1;
912 937
913 case mu_cfg_time: 938 case mu_cfg_time:
914 GETUNUM (node->tag_label, time_t, *(time_t*)param->data, 939 GETUNUM (node->tag_label, time_t, *(time_t*)tgt,
915 sdata->tree->debug); 940 sdata->tree->debug);
916 break; 941 break;
917 942
918 case mu_cfg_bool: 943 case mu_cfg_bool:
919 if (parse_bool (sdata, node, (int*) param->data)) 944 if (parse_bool (sdata, node, (int*) tgt))
920 return 1; 945 return 1;
921 break; 946 break;
922 947
923 case mu_cfg_ipv4: 948 case mu_cfg_ipv4:
924 if (parse_ipv4 (sdata, node, (struct in_addr *)param->data)) 949 if (parse_ipv4 (sdata, node, (struct in_addr *)tgt))
925 return 1; 950 return 1;
926 break; 951 break;
927 952
928 case mu_cfg_cidr: 953 case mu_cfg_cidr:
929 if (parse_cidr (sdata, node, (mu_cfg_cidr_t *)param->data)) 954 if (parse_cidr (sdata, node, (mu_cfg_cidr_t *)tgt))
930 return 1; 955 return 1;
931 break; 956 break;
932 957
933 case mu_cfg_host: 958 case mu_cfg_host:
934 if (parse_host (sdata, node, (struct in_addr *)param->data)) 959 if (parse_host (sdata, node, (struct in_addr *)tgt))
935 return 1; 960 return 1;
936 break; 961 break;
937 962
938 case mu_cfg_callback: 963 case mu_cfg_callback:
939 mu_debug_set_locus (sdata->tree->debug, node->locus.file, 964 mu_debug_set_locus (sdata->tree->debug, node->locus.file,
940 node->locus.line); 965 node->locus.line);
941 if (param->callback (sdata->tree->debug, param->data, node->tag_label)) 966 if (param->callback (sdata->tree->debug, tgt, node->tag_label))
942 return 1; 967 return 1;
943 break; 968 break;
944 969
...@@ -972,11 +997,12 @@ _scan_tree_helper (const mu_cfg_node_t *node, void *data) ...@@ -972,11 +997,12 @@ _scan_tree_helper (const mu_cfg_node_t *node, void *data)
972 } 997 }
973 return MU_CFG_ITER_SKIP; 998 return MU_CFG_ITER_SKIP;
974 } 999 }
975 if (!sec->subsec && !sec->param) 1000 if (!sec->children)
976 return MU_CFG_ITER_SKIP; 1001 return MU_CFG_ITER_SKIP;
977 if (sec->parser && 1002 if (sec->parser &&
978 sec->parser (mu_cfg_section_start, node, 1003 sec->parser (mu_cfg_section_start, node,
979 sec->data, sdata->call_data, sdata->tree)) 1004 sec->label, &sec->target,
1005 sdata->call_data, sdata->tree))
980 { 1006 {
981 sdata->error++; 1007 sdata->error++;
982 return MU_CFG_ITER_SKIP; 1008 return MU_CFG_ITER_SKIP;
...@@ -1010,7 +1036,8 @@ _scan_tree_end_helper (const mu_cfg_node_t *node, void *data) ...@@ -1010,7 +1036,8 @@ _scan_tree_end_helper (const mu_cfg_node_t *node, void *data)
1010 sec = pop_section (sdata); 1036 sec = pop_section (sdata);
1011 if (sec && sec->parser) 1037 if (sec && sec->parser)
1012 { 1038 {
1013 if (sec->parser (mu_cfg_section_end, node, sec->data, 1039 if (sec->parser (mu_cfg_section_end, node,
1040 sec->label, &sec->target,
1014 sdata->call_data, sdata->tree)) 1041 sdata->call_data, sdata->tree))
1015 { 1042 {
1016 sdata->error++; 1043 sdata->error++;
...@@ -1023,13 +1050,14 @@ _scan_tree_end_helper (const mu_cfg_node_t *node, void *data) ...@@ -1023,13 +1050,14 @@ _scan_tree_end_helper (const mu_cfg_node_t *node, void *data)
1023 1050
1024 int 1051 int
1025 mu_cfg_scan_tree (mu_cfg_tree_t *tree, struct mu_cfg_section *sections, 1052 mu_cfg_scan_tree (mu_cfg_tree_t *tree, struct mu_cfg_section *sections,
1026 void *data) 1053 void *target, void *data)
1027 { 1054 {
1028 struct scan_tree_data dat; 1055 struct scan_tree_data dat;
1029 dat.tree = tree; 1056 dat.tree = tree;
1030 dat.list = NULL; 1057 dat.list = NULL;
1031 dat.error = 0; 1058 dat.error = 0;
1032 dat.call_data = data; 1059 dat.call_data = data;
1060 dat.target = target;
1033 if (push_section (&dat, sections)) 1061 if (push_section (&dat, sections))
1034 return 1; 1062 return 1;
1035 mu_cfg_preorder (tree->node, _scan_tree_helper, _scan_tree_end_helper, &dat); 1063 mu_cfg_preorder (tree->node, _scan_tree_helper, _scan_tree_end_helper, &dat);
......
...@@ -166,13 +166,13 @@ cb_metamail (mu_debug_t debug, void *data, char *arg) ...@@ -166,13 +166,13 @@ cb_metamail (mu_debug_t debug, void *data, char *arg)
166 } 166 }
167 167
168 struct mu_cfg_param mimeview_cfg_param[] = { 168 struct mu_cfg_param mimeview_cfg_param[] = {
169 { "debug", mu_cfg_callback, NULL, cb_debug, 169 { "debug", mu_cfg_callback, NULL, 0, cb_debug,
170 N_("Set debug verbosity level."), 170 N_("Set debug verbosity level."),
171 N_("flags") }, 171 N_("flags") },
172 { "mimetypes", mu_cfg_string, &mimetypes_config, NULL, 172 { "mimetypes", mu_cfg_string, &mimetypes_config, 0, NULL,
173 N_("Use this mime.types file."), 173 N_("Use this mime.types file."),
174 N_("file") }, 174 N_("file") },
175 { "metamail", mu_cfg_string, NULL, cb_metamail, 175 { "metamail", mu_cfg_string, NULL, 0, cb_metamail,
176 N_("Use this program to display files."), 176 N_("Use this program to display files."),
177 N_("prog") }, 177 N_("prog") },
178 { NULL } 178 { NULL }
......
...@@ -90,11 +90,11 @@ static struct argp argp = { ...@@ -90,11 +90,11 @@ static struct argp argp = {
90 90
91 91
92 struct mu_cfg_param movemail_cfg_param[] = { 92 struct mu_cfg_param movemail_cfg_param[] = {
93 { "preserve", mu_cfg_bool, &preserve_mail, NULL, 93 { "preserve", mu_cfg_bool, &preserve_mail, 0, NULL,
94 N_("Do not remove messages from the source mailbox.") }, 94 N_("Do not remove messages from the source mailbox.") },
95 { "reverse", mu_cfg_bool, &reverse_order, NULL, 95 { "reverse", mu_cfg_bool, &reverse_order, 0, NULL,
96 N_("Reverse message sorting order.") }, 96 N_("Reverse message sorting order.") },
97 { "emacs", mu_cfg_bool, &emacs_mode, NULL, 97 { "emacs", mu_cfg_bool, &emacs_mode, 0, NULL,
98 N_("Output information used by Emacs rmail interface.") }, 98 N_("Output information used by Emacs rmail interface.") },
99 { NULL } 99 { NULL }
100 }; 100 };
......
...@@ -134,28 +134,28 @@ cb_bulletin_db (mu_debug_t debug, void *data, char *arg) ...@@ -134,28 +134,28 @@ cb_bulletin_db (mu_debug_t debug, void *data, char *arg)
134 } 134 }
135 135
136 static struct mu_cfg_param pop3d_cfg_param[] = { 136 static struct mu_cfg_param pop3d_cfg_param[] = {
137 { "undelete", mu_cfg_int, &undelete_on_startup, NULL, 137 { "undelete", mu_cfg_int, &undelete_on_startup, 0, NULL,
138 N_("On startup, clear deletion marks from all the messages.") }, 138 N_("On startup, clear deletion marks from all the messages.") },
139 { "expire", mu_cfg_uint, &expire, NULL, 139 { "expire", mu_cfg_uint, &expire, 0, NULL,
140 N_("Automatically expire read messages after the given number of days."), 140 N_("Automatically expire read messages after the given number of days."),
141 N_("days") }, 141 N_("days") },
142 { "delete-expired", mu_cfg_int, &expire_on_exit, NULL, 142 { "delete-expired", mu_cfg_int, &expire_on_exit, 0, NULL,
143 N_("Delete expired messages upon closing the mailbox.") }, 143 N_("Delete expired messages upon closing the mailbox.") },
144 #ifdef WITH_TLS 144 #ifdef WITH_TLS
145 { "tls-required", mu_cfg_callback, NULL, cb_tls_required, 145 { "tls-required", mu_cfg_callback, NULL, 0, cb_tls_required,
146 N_("Always require STLS before entering authentication phase.") }, 146 N_("Always require STLS before entering authentication phase.") },
147 #endif 147 #endif
148 #ifdef ENABLE_LOGIN_DELAY 148 #ifdef ENABLE_LOGIN_DELAY
149 { "login-delay", mu_cfg_time, &login_delay, NULL, 149 { "login-delay", mu_cfg_time, &login_delay, 0, NULL,
150 N_("Set the minimal allowed delay between two successive logins.") }, 150 N_("Set the minimal allowed delay between two successive logins.") },
151 { "stat-file", mu_cfg_string, &login_stat_file, NULL, 151 { "stat-file", mu_cfg_string, &login_stat_file, 0, NULL,
152 N_("Set the name of login statistics file (for login-delay).") }, 152 N_("Set the name of login statistics file (for login-delay).") },
153 #endif 153 #endif
154 { "bulletin-source", mu_cfg_callback, NULL, cb_bulletin_source, 154 { "bulletin-source", mu_cfg_callback, NULL, 0, cb_bulletin_source,
155 N_("Get bulletins from the specified mailbox."), 155 N_("Get bulletins from the specified mailbox."),
156 N_("url") }, 156 N_("url") },
157 #ifdef USE_DBM 157 #ifdef USE_DBM
158 { "bulletin-db", mu_cfg_callback, NULL, cb_bulletin_db, 158 { "bulletin-db", mu_cfg_callback, NULL, 0, cb_bulletin_db,
159 N_("Set the bulletin database file name."), 159 N_("Set the bulletin database file name."),
160 N_("file") }, 160 N_("file") },
161 #endif 161 #endif
......
...@@ -129,21 +129,21 @@ readmsg_parse_opt (int key, char *arg, struct argp_state *astate) ...@@ -129,21 +129,21 @@ readmsg_parse_opt (int key, char *arg, struct argp_state *astate)
129 129
130 130
131 struct mu_cfg_param readmsg_cfg_param[] = { 131 struct mu_cfg_param readmsg_cfg_param[] = {
132 { "debug", mu_cfg_int, &dbug, NULL, 132 { "debug", mu_cfg_int, &dbug, 0, NULL,
133 N_("Set debug verbosity level.") }, 133 N_("Set debug verbosity level.") },
134 { "header", mu_cfg_bool, &all_header, NULL, 134 { "header", mu_cfg_bool, &all_header, 0, NULL,
135 N_("Display entire headers.") }, 135 N_("Display entire headers.") },
136 { "weedlist", mu_cfg_string, &weedlist, NULL, 136 { "weedlist", mu_cfg_string, &weedlist, 0, NULL,
137 N_("Display only headers from this list. Argument is a list of header " 137 N_("Display only headers from this list. Argument is a list of header "
138 "names separated by whitespace or commas."), 138 "names separated by whitespace or commas."),
139 N_("list") }, 139 N_("list") },
140 { "folder", mu_cfg_string, &mailbox_name, NULL, 140 { "folder", mu_cfg_string, &mailbox_name, 0, NULL,
141 N_("Read messages from this folder.") }, 141 N_("Read messages from this folder.") },
142 { "no-header", mu_cfg_bool, &no_header, NULL, 142 { "no-header", mu_cfg_bool, &no_header, 0, NULL,
143 N_("Exclude all headers.") }, 143 N_("Exclude all headers.") },
144 { "form-feeds", mu_cfg_bool, &form_feed, NULL, 144 { "form-feeds", mu_cfg_bool, &form_feed, 0, NULL,
145 N_("Output formfeed character between messages.") }, 145 N_("Output formfeed character between messages.") },
146 { "show-all-match", mu_cfg_bool, &show_all, NULL, 146 { "show-all-match", mu_cfg_bool, &show_all, 0, NULL,
147 N_("Print all messages matching pattern, not only the first.") }, 147 N_("Print all messages matching pattern, not only the first.") },
148 { NULL } 148 { NULL }
149 }; 149 };
......
...@@ -287,15 +287,15 @@ cb_ticket (mu_debug_t debug, void *data, char *arg) ...@@ -287,15 +287,15 @@ cb_ticket (mu_debug_t debug, void *data, char *arg)
287 } 287 }
288 288
289 static struct mu_cfg_param sieve_cfg_param[] = { 289 static struct mu_cfg_param sieve_cfg_param[] = {
290 { "keep-going", mu_cfg_int, &keep_going, NULL, 290 { "keep-going", mu_cfg_int, &keep_going, 0, NULL,
291 N_("Do not abort if execution fails on a message.") }, 291 N_("Do not abort if execution fails on a message.") },
292 { "mbox-url", mu_cfg_string, &mbox_url, NULL, 292 { "mbox-url", mu_cfg_string, &mbox_url, 0, NULL,
293 N_("Mailbox to sieve (defaults to user's mail spool)."), 293 N_("Mailbox to sieve (defaults to user's mail spool)."),
294 N_("url") }, 294 N_("url") },
295 { "ticket", mu_cfg_callback, NULL, cb_ticket, 295 { "ticket", mu_cfg_callback, NULL, 0, cb_ticket,
296 N_("Ticket file for user authentication."), 296 N_("Ticket file for user authentication."),
297 N_("ticket") }, 297 N_("ticket") },
298 { "debug", mu_cfg_callback, NULL, cb_debug, 298 { "debug", mu_cfg_callback, NULL, 0, cb_debug,
299 N_("Debug flags. Argument consists of one or more of the following " 299 N_("Debug flags. Argument consists of one or more of the following "
300 "flags:\n" 300 "flags:\n"
301 " g - main parser traces\n" 301 " g - main parser traces\n"
...@@ -303,11 +303,11 @@ static struct mu_cfg_param sieve_cfg_param[] = { ...@@ -303,11 +303,11 @@ static struct mu_cfg_param sieve_cfg_param[] = {
303 " P - network protocols (MU_DEBUG_PROT)\n" 303 " P - network protocols (MU_DEBUG_PROT)\n"
304 " t - sieve trace (MU_SIEVE_DEBUG_TRACE)\n" 304 " t - sieve trace (MU_SIEVE_DEBUG_TRACE)\n"
305 " i - sieve instructions trace (MU_SIEVE_DEBUG_INSTR).") }, 305 " i - sieve instructions trace (MU_SIEVE_DEBUG_INSTR).") },
306 { "verbose", mu_cfg_bool, &verbose, NULL, 306 { "verbose", mu_cfg_bool, &verbose, 0, NULL,
307 N_("Log all executed actions.") }, 307 N_("Log all executed actions.") },
308 { "line-info", mu_cfg_bool, &sieve_print_locus, NULL, 308 { "line-info", mu_cfg_bool, &sieve_print_locus, 0, NULL,
309 N_("Print source locations along with action logs (default).") }, 309 N_("Print source locations along with action logs (default).") },
310 { "email", mu_cfg_callback, NULL, cb_email, 310 { "email", mu_cfg_callback, NULL, 0, cb_email,
311 N_("Set user email address.") }, 311 N_("Set user email address.") },
312 { NULL } 312 { NULL }
313 }; 313 };
......