Commit e0f4a7db e0f4a7db8af17b10d588db2d0a2eeeb6a9cb95f4 by Sergey Poznyakoff

Extend --config-help output. Each configuration parameter

has a docstring which is displayed as a comment before it.
A docstring is also added to the configuration group structure,
for use in future.

* include/mailutils/cfg.h (struct mu_cfg_param): New members
`docstring' and `argname'.
(struct mu_cfg_section): New member `docstring'.
(mu_cfg_format_docstring): New function.
* include/mailutils/libargp.h (mu_help_config_mode): New
declaration.
* libargp/cmdline.h (mu_help_config_mode): Remove.
* libargp/muinit.c (mu_app_init): Better format the initial
comment.
* mailbox/cfg_format.c (mu_cfg_data_type_string): Use NLS.
(mu_cfg_format_docstring): New function.
(format_param,format_section): Use mu_cfg_format_docstring.
* mailbox/cfg_lexer.c (mu_config_create_container): Initialize
allocated memory chunk with zeros.
(dup_container): Duplicate docstring.
(mu_build_container): Document include statement.

* dotlock/dotlock.c, imap4d/imap4d.c, libargp/tls.c,
libcfg/auth.c, libcfg/common.c, libcfg/gsasl.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, mimeview/mimeview.c,
movemail/movemail.c, pop3d/pop3d.c, readmsg/readmsg.c,
sieve/sieve.c: Document configuration file statements.

* pop3d/pop3d.h (expire): Change type to unsigned int.

* po/POTFILES.in: Add missing files.
1 parent 2bce826f
1 2007-12-04 Sergey Poznyakoff <gray@gnu.org.ua> 1 2007-12-04 Sergey Poznyakoff <gray@gnu.org.ua>
2 2
3 II. Extend --config-help output. Each configuration parameter
4 has a docstring which is displayed as a comment before it.
5 A docstring is also added to the configuration group structure,
6 for use in future.
7
8 * include/mailutils/cfg.h (struct mu_cfg_param): New members
9 `docstring' and `argname'.
10 (struct mu_cfg_section): New member `docstring'.
11 (mu_cfg_format_docstring): New function.
12 * include/mailutils/libargp.h (mu_help_config_mode): New
13 declaration.
14 * libargp/cmdline.h (mu_help_config_mode): Remove.
15 * libargp/muinit.c (mu_app_init): Better format the initial
16 comment.
17 * mailbox/cfg_format.c (mu_cfg_data_type_string): Use NLS.
18 (mu_cfg_format_docstring): New function.
19 (format_param,format_section): Use mu_cfg_format_docstring.
20 * mailbox/cfg_lexer.c (mu_config_create_container): Initialize
21 allocated memory chunk with zeros.
22 (dup_container): Duplicate docstring.
23 (mu_build_container): Document include statement.
24
25 * dotlock/dotlock.c, imap4d/imap4d.c, libargp/tls.c,
26 libcfg/auth.c, libcfg/common.c, libcfg/gsasl.c, libcfg/ldap.c,
27 libcfg/pam.c, libcfg/radius.c, libcfg/sieve.c, libcfg/sql.c,
28 libcfg/tls.c, libcfg/virtdomain.c, maidag/maidag.c,
29 mail.local/main.c, mail.remote/mail.remote.c, mimeview/mimeview.c,
30 movemail/movemail.c, pop3d/pop3d.c, readmsg/readmsg.c,
31 sieve/sieve.c: Document configuration file statements.
32
33 * pop3d/pop3d.h (expire): Change type to unsigned int.
34
35 * po/POTFILES.in: Add missing files.
36
37 I. Implement --config-help option, which displays configuration
38 file statements understood by the given program.
39
3 * imap4d/imap4d.h: Include xalloc.h 40 * imap4d/imap4d.h: Include xalloc.h
4 * frm/common.c, imap4d/imap4d.c: Shut compiler warnings. 41 * frm/common.c, imap4d/imap4d.c: Shut compiler warnings.
5 * include/mailutils/cfg.h (mu_cfg_format_tree): Rename to 42 * include/mailutils/cfg.h (mu_cfg_format_tree): Rename to
6 mu_cfg_format_parse_tree 43 mu_cfg_format_parse_tree.
7 (mu_cfg_format_container,mu_format_config_tree): New functions. 44 (mu_cfg_format_container,mu_format_config_tree): New functions.
8 (mu_parse_config_tree): New prototype. 45 (mu_parse_config_tree): New prototype.
9 (mu_cfg_tree_create_node): Change signature (const char* instead 46 (mu_cfg_tree_create_node): Change signature (const char* instead
......
...@@ -105,8 +105,10 @@ parse_opt (int key, char *arg, struct argp_state *state) ...@@ -105,8 +105,10 @@ parse_opt (int key, char *arg, struct argp_state *state)
105 break; 105 break;
106 106
107 case ARGP_KEY_NO_ARGS: 107 case ARGP_KEY_NO_ARGS:
108 argp_error (state, _("FILE must be specified")); 108 if (!mu_help_config_mode)
109 109 argp_error (state, _("FILE must be specified"));
110 return ARGP_ERR_UNKNOWN;
111
110 case ARGP_KEY_INIT: 112 case ARGP_KEY_INIT:
111 mu_argp_node_list_init (&lst); 113 mu_argp_node_list_init (&lst);
112 break; 114 break;
...@@ -123,9 +125,12 @@ parse_opt (int key, char *arg, struct argp_state *state) ...@@ -123,9 +125,12 @@ parse_opt (int key, char *arg, struct argp_state *state)
123 125
124 126
125 struct mu_cfg_param dotlock_cfg_param[] = { 127 struct mu_cfg_param dotlock_cfg_param[] = {
126 { "force", mu_cfg_time, &force }, 128 { "force", mu_cfg_time, &force, NULL,
127 { "retry", mu_cfg_int, &retries }, 129 N_("Forcibly break an existing lock older than the specified time.") },
128 { "debug", mu_cfg_bool, &debug }, 130 { "retry", mu_cfg_int, &retries, NULL,
131 N_("Number of times to retry acquiring the lock.") },
132 { "debug", mu_cfg_bool, &debug, NULL,
133 N_("Print details of failure reasons to stderr.") },
129 { NULL } 134 { NULL }
130 }; 135 };
131 136
......
...@@ -272,16 +272,34 @@ cb_preauth (mu_debug_t debug, void *data, char *arg) ...@@ -272,16 +272,34 @@ 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, cb_other,
276 { "shared-namespace", mu_cfg_callback, NULL, cb_shared }, 276 N_("Set other users' namespace. Argument is a colon-separated list "
277 { "login-disabled", mu_cfg_int, &login_disabled }, 277 "of directories comprising the namespace.") },
278 { "create-home-dir", mu_cfg_bool, &create_home_dir }, 278 { "shared-namespace", mu_cfg_callback, NULL, cb_shared,
279 { "home-dir-mode", mu_cfg_callback, NULL, cb_mode }, 279 N_("Set shared namespace. Argument is a colon-separated list "
280 { "tls-required", mu_cfg_int, &tls_required }, 280 "of directories comprising the namespace.") },
281 { "preauth", mu_cfg_callback, NULL, cb_preauth }, 281 { "login-disabled", mu_cfg_int, &login_disabled, NULL,
282 { "preauth-only", mu_cfg_bool, &preauth_only }, 282 N_("Disable LOGIN command.") },
283 { "ident-keyfile", mu_cfg_string, &ident_keyfile }, 283 { "create-home-dir", mu_cfg_bool, &create_home_dir, NULL,
284 { "ident-entrypt-only", mu_cfg_bool, &ident_encrypt_only }, 284 N_("If true, create non-existing user home directories.") },
285 { "home-dir-mode", mu_cfg_callback, NULL, cb_mode,
286 N_("File mode for creating user home directories (octal)."),
287 N_("mode") },
288 { "tls-required", mu_cfg_int, &tls_required, NULL,
289 N_("Always require STARTTLS before entering authentication phase.") },
290 { "preauth", mu_cfg_callback, NULL, cb_preauth,
291 N_("Configure PREAUTH mode. MODE is one of:\n"
292 " prog:///<full-program-name: string>\n"
293 " ident[://:<port: string-or-number>]\n"
294 " stdio"),
295 N_("MODE") },
296 { "preauth-only", mu_cfg_bool, &preauth_only, NULL,
297 N_("Use only preauth mode. If unable to setup it, disconnect "
298 "immediately.") },
299 { "ident-keyfile", mu_cfg_string, &ident_keyfile, NULL,
300 N_("Name of DES keyfile for decoding ecrypted ident responses.") },
301 { "ident-entrypt-only", mu_cfg_bool, &ident_encrypt_only, NULL,
302 N_("Use only ecrypted ident responses.") },
285 { NULL } 303 { NULL }
286 }; 304 };
287 305
......
...@@ -129,6 +129,8 @@ struct mu_cfg_param ...@@ -129,6 +129,8 @@ struct mu_cfg_param
129 enum mu_cfg_param_data_type type; 129 enum mu_cfg_param_data_type type;
130 void *data; 130 void *data;
131 mu_cfg_callback_t callback; 131 mu_cfg_callback_t callback;
132 const char *docstring;
133 const char *argname;
132 }; 134 };
133 135
134 enum mu_cfg_section_stage 136 enum mu_cfg_section_stage
...@@ -150,6 +152,7 @@ struct mu_cfg_section ...@@ -150,6 +152,7 @@ struct mu_cfg_section
150 void *data; 152 void *data;
151 mu_list_t /* of mu_cfg_cont/mu_cfg_section */ subsec; 153 mu_list_t /* of mu_cfg_cont/mu_cfg_section */ subsec;
152 mu_list_t /* of mu_cfg_cont/mu_cfg_param */ param; 154 mu_list_t /* of mu_cfg_cont/mu_cfg_param */ param;
155 char *docstring;
153 }; 156 };
154 157
155 enum mu_cfg_cont_type 158 enum mu_cfg_cont_type
...@@ -209,6 +212,8 @@ int mu_cfg_parse_boolean (const char *str, int *res); ...@@ -209,6 +212,8 @@ int mu_cfg_parse_boolean (const char *str, int *res);
209 212
210 extern int mu_cfg_parser_verbose; 213 extern int mu_cfg_parser_verbose;
211 214
215 void mu_cfg_format_docstring (mu_stream_t stream, const char *docstring,
216 int level);
212 void mu_cfg_format_parse_tree (mu_stream_t stream, struct mu_cfg_tree *tree); 217 void mu_cfg_format_parse_tree (mu_stream_t stream, struct mu_cfg_tree *tree);
213 void mu_cfg_format_container (mu_stream_t stream, struct mu_cfg_cont *cont); 218 void mu_cfg_format_container (mu_stream_t stream, struct mu_cfg_cont *cont);
214 void mu_format_config_tree (mu_stream_t stream, const char *progname, 219 void mu_format_config_tree (mu_stream_t stream, const char *progname,
......
...@@ -42,6 +42,8 @@ struct mu_cmdline_capa ...@@ -42,6 +42,8 @@ struct mu_cmdline_capa
42 struct argp_child *child; 42 struct argp_child *child;
43 }; 43 };
44 44
45 extern int mu_help_config_mode;
46
45 extern struct mu_cmdline_capa mu_common_cmdline; 47 extern struct mu_cmdline_capa mu_common_cmdline;
46 extern struct mu_cmdline_capa mu_logging_cmdline; 48 extern struct mu_cmdline_capa mu_logging_cmdline;
47 extern struct mu_cmdline_capa mu_license_cmdline; 49 extern struct mu_cmdline_capa mu_license_cmdline;
......
...@@ -20,4 +20,3 @@ ...@@ -20,4 +20,3 @@
20 #include "mailutils/libargp.h" 20 #include "mailutils/libargp.h"
21 21
22 extern struct mu_cfg_tree *mu_argp_tree; 22 extern struct mu_cfg_tree *mu_argp_tree;
23 extern int mu_help_config_mode;
......
...@@ -81,22 +81,28 @@ mu_app_init (struct argp *myargp, const char **capa, ...@@ -81,22 +81,28 @@ mu_app_init (struct argp *myargp, const char **capa,
81 81
82 if (mu_help_config_mode) 82 if (mu_help_config_mode)
83 { 83 {
84 char *comment;
84 char *canonical_name = get_canonical_name (); 85 char *canonical_name = get_canonical_name ();
85 mu_stream_t stream; 86 mu_stream_t stream;
86 mu_stdio_stream_create (&stream, stdout, 87 mu_stdio_stream_create (&stream, stdout,
87 MU_STREAM_NO_CHECK|MU_STREAM_NO_CLOSE); 88 MU_STREAM_NO_CHECK|MU_STREAM_NO_CLOSE);
88 mu_stream_open (stream); 89 mu_stream_open (stream);
89 mu_stream_sequential_printf (stream, 90 asprintf (&comment,
90 "# Configuration file structure for %s utility.\n", 91 "Configuration file structure for %s utility.",
91 mu_program_name); 92 mu_program_name);
92 mu_stream_sequential_printf (stream, 93 mu_cfg_format_docstring (stream, comment, 0);
93 "# For use in global configuration file (%s), enclose it\n" 94 free (comment);
94 "# in `program %s { ... };'\n", 95 asprintf (&comment,
95 MU_CONFIG_FILE, 96 "For use in global configuration file (%s), enclose it "
96 mu_program_name); 97 "in `program %s { ... };",
97 mu_stream_sequential_printf (stream, 98 MU_CONFIG_FILE,
98 "# For more information, use `info %s'.\n", 99 mu_program_name);
99 canonical_name); 100 mu_cfg_format_docstring (stream, comment, 0);
101 free (comment);
102 asprintf (&comment, "For more information, use `info %s'.",
103 canonical_name);
104 mu_cfg_format_docstring (stream, comment, 0);
105 free (comment);
100 106
101 mu_format_config_tree (stream, mu_program_name, cfg_param, 0); 107 mu_format_config_tree (stream, mu_program_name, cfg_param, 0);
102 mu_stream_destroy (&stream, NULL); 108 mu_stream_destroy (&stream, NULL);
......
...@@ -31,7 +31,7 @@ enum { ...@@ -31,7 +31,7 @@ enum {
31 31
32 static struct argp_option _tls_argp_options[] = { 32 static struct argp_option _tls_argp_options[] = {
33 {"ssl-cert", OPT_SSL_CERT, N_("FILE"), OPTION_HIDDEN, 33 {"ssl-cert", OPT_SSL_CERT, N_("FILE"), OPTION_HIDDEN,
34 N_("Specify SSL certificate file"), 0}, 34 N_("Specify SSL certificate filep"), 0},
35 {"ssl-key", OPT_SSL_KEY, N_("FILE"), OPTION_HIDDEN, 35 {"ssl-key", OPT_SSL_KEY, N_("FILE"), OPTION_HIDDEN,
36 N_("Specify SSL certificate key"), }, 36 N_("Specify SSL certificate key"), },
37 {"ssl-cafile", OPT_SSL_CAFILE, N_("FILE"), OPTION_HIDDEN, 37 {"ssl-cafile", OPT_SSL_CAFILE, N_("FILE"), OPTION_HIDDEN,
......
...@@ -50,8 +50,16 @@ cb_authorization (mu_debug_t err, void *data, char *arg) ...@@ -50,8 +50,16 @@ 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, cb_authentication,
54 { "authorization", mu_cfg_callback, NULL, cb_authorization }, 54 N_("Set a list of modules for authentication. Modlist is a "
55 "colon-separated list of module names or a word `clear' to "
56 "clear the previously set up values."),
57 N_("modlist") },
58 { "authorization", mu_cfg_callback, NULL, cb_authorization,
59 N_("Set a list of modules for authorization. Modlist is a "
60 "colon-separated list of module names or a word `clear' to "
61 "clear the previously set up values."),
62 N_("modlist") },
55 { NULL } 63 { NULL }
56 }; 64 };
57 65
......
...@@ -40,8 +40,11 @@ static struct mu_gocs_debug debug_settings; ...@@ -40,8 +40,11 @@ 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 }, 43 { "mail-spool", mu_cfg_string, &mailbox_settings.mail_spool, NULL,
44 { "mailbox-type", mu_cfg_string, &mailbox_settings.mailbox_type }, 44 N_("Use specified URL as a mailspool directory."),
45 N_("url") },
46 { "mailbox-type", mu_cfg_string, &mailbox_settings.mailbox_type, NULL,
47 N_("Default mailbox type."), N_("protocol") },
45 { NULL } 48 { NULL }
46 }; 49 };
47 50
...@@ -53,11 +56,19 @@ DCL_CFG_CAPA (mailbox); ...@@ -53,11 +56,19 @@ DCL_CFG_CAPA (mailbox);
53 /* ************************************************************************* */ 56 /* ************************************************************************* */
54 57
55 static struct mu_cfg_param mu_locking_param[] = { 58 static struct mu_cfg_param mu_locking_param[] = {
56 { "flags", mu_cfg_string, &locking_settings.lock_flags }, 59 /* FIXME: Flags are superfluous. */
57 { "retry-timeout", mu_cfg_ulong, &locking_settings.lock_retry_timeout }, 60 { "flags", mu_cfg_string, &locking_settings.lock_flags, NULL,
58 { "retry-count", mu_cfg_ulong, &locking_settings.lock_retry_count }, 61 N_("Default locker flags (E=external, R=retry, T=time, P=pid).") },
59 { "expire-timeout", mu_cfg_ulong, &locking_settings.lock_expire_timeout }, 62 { "retry-timeout", mu_cfg_ulong, &locking_settings.lock_retry_timeout, NULL,
60 { "external-locker", mu_cfg_string, &locking_settings.external_locker }, 63 N_("Set timeout for acquiring the lock.") },
64 { "retry-count", mu_cfg_ulong, &locking_settings.lock_retry_count, NULL,
65 N_("Set the maximum number of times to retry acquiring the lock.") },
66 { "expire-timeout", mu_cfg_ulong, &locking_settings.lock_expire_timeout,
67 NULL,
68 N_("Expire locks older than this amount of time.") },
69 { "external-locker", mu_cfg_string, &locking_settings.external_locker, NULL,
70 N_("Use external locker program."),
71 N_("prog") },
61 { NULL, } 72 { NULL, }
62 }; 73 };
63 74
...@@ -69,8 +80,13 @@ DCL_CFG_CAPA (locking); ...@@ -69,8 +80,13 @@ DCL_CFG_CAPA (locking);
69 /* ************************************************************************* */ 80 /* ************************************************************************* */
70 81
71 static struct mu_cfg_param mu_address_param[] = { 82 static struct mu_cfg_param mu_address_param[] = {
72 { "email-addr", mu_cfg_string, &address_settings.address }, 83 { "email-addr", mu_cfg_string, &address_settings.address, NULL,
73 { "email-domain", mu_cfg_string, &address_settings.domain }, 84 N_("Set the current user email address (default is "
85 "loginname@defaultdomain)."),
86 N_("email") },
87 { "email-domain", mu_cfg_string, &address_settings.domain, NULL,
88 N_("Set e-mail domain for unqualified user names (default is this host)"),
89 N_("domain") },
74 { NULL } 90 { NULL }
75 }; 91 };
76 92
...@@ -82,7 +98,9 @@ DCL_CFG_CAPA (address); ...@@ -82,7 +98,9 @@ DCL_CFG_CAPA (address);
82 /* ************************************************************************* */ 98 /* ************************************************************************* */
83 99
84 static struct mu_cfg_param mu_mailer_param[] = { 100 static struct mu_cfg_param mu_mailer_param[] = {
85 { "url", mu_cfg_string, &mailer_settings.mailer }, 101 { "url", mu_cfg_string, &mailer_settings.mailer, NULL,
102 N_("Use this URL as the default mailer"),
103 N_("url") },
86 { NULL } 104 { NULL }
87 }; 105 };
88 106
...@@ -107,7 +125,10 @@ cb_facility (mu_debug_t debug, void *data, char *arg) ...@@ -107,7 +125,10 @@ cb_facility (mu_debug_t debug, void *data, char *arg)
107 } 125 }
108 126
109 static struct mu_cfg_param mu_logging_param[] = { 127 static struct mu_cfg_param mu_logging_param[] = {
110 { "facility", mu_cfg_callback, NULL, cb_facility }, 128 { "facility", mu_cfg_callback, NULL, cb_facility,
129 N_("Set syslog facility. Arg is one of the following: user, daemon, "
130 "auth, authpriv, mail, cron, local0 through local7 (case-insensitive), "
131 "or a facility number.") },
111 { NULL } 132 { NULL }
112 }; 133 };
113 134
...@@ -135,12 +156,20 @@ _cb_daemon_mode (mu_debug_t debug, void *data, char *arg) ...@@ -135,12 +156,20 @@ _cb_daemon_mode (mu_debug_t debug, void *data, char *arg)
135 } 156 }
136 157
137 static struct mu_cfg_param mu_daemon_param[] = { 158 static struct mu_cfg_param mu_daemon_param[] = {
138 { "max-children", mu_cfg_ulong, &daemon_settings.maxchildren }, 159 { "max-children", mu_cfg_ulong, &daemon_settings.maxchildren, NULL,
139 { "mode", mu_cfg_callback, NULL, _cb_daemon_mode }, 160 N_("Maximum number of children processes to run simultaneously.") },
140 { "transcript", mu_cfg_bool, &daemon_settings.transcript }, 161 { "mode", mu_cfg_callback, NULL, _cb_daemon_mode,
141 { "pidfile", mu_cfg_string, &daemon_settings.pidfile }, 162 N_("Set daemon mode (either inetd (or interactive) or daemon)."),
142 { "port", mu_cfg_ushort, &daemon_settings.port }, 163 N_("mode") },
143 { "timeout", mu_cfg_ulong, &daemon_settings.timeout }, 164 { "transcript", mu_cfg_bool, &daemon_settings.transcript, NULL,
165 N_("Log the session transcript.") },
166 { "pidfile", mu_cfg_string, &daemon_settings.pidfile, NULL,
167 N_("Store PID of the master process in this file."),
168 N_("file") },
169 { "port", mu_cfg_ushort, &daemon_settings.port, NULL,
170 N_("Listen on the specified port number.") },
171 { "timeout", mu_cfg_ulong, &daemon_settings.timeout, NULL,
172 N_("Set idle timeout.") },
144 { NULL } 173 { NULL }
145 }; 174 };
146 175
...@@ -203,8 +232,12 @@ cb_debug_level (mu_debug_t debug, void *data, char *arg) ...@@ -203,8 +232,12 @@ cb_debug_level (mu_debug_t debug, void *data, char *arg)
203 } 232 }
204 233
205 static struct mu_cfg_param mu_debug_param[] = { 234 static struct mu_cfg_param mu_debug_param[] = {
206 { "level", mu_cfg_callback, NULL, &cb_debug_level }, 235 { "level", mu_cfg_callback, NULL, &cb_debug_level,
207 { "line-info", mu_cfg_bool, &debug_settings.line_info }, 236 N_("Set Mailutils debugging level. Argument is a colon-separated list "
237 "of debugging specifications in the form:\n"
238 " <object: string>[[:]=<level: number>].") },
239 { "line-info", mu_cfg_bool, &debug_settings.line_info, NULL,
240 N_("Prefix debug messages with Mailutils source locations.") },
208 { NULL } 241 { NULL }
209 }; 242 };
210 243
......
...@@ -25,7 +25,9 @@ ...@@ -25,7 +25,9 @@
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 }, 28 { "cram-passwd", mu_cfg_string, &gsasl_settings.cram_md5_pwd, NULL,
29 N_("Name of GSASL password file."),
30 N_("file") },
29 { NULL } 31 { NULL }
30 }; 32 };
31 33
......
...@@ -37,16 +37,38 @@ cb_field_map (mu_debug_t debug, void *data, char *arg) ...@@ -37,16 +37,38 @@ 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 }, 40 { "enable", mu_cfg_bool, &ldap_settings.enable, NULL,
41 { "url", mu_cfg_string, &ldap_settings.url }, 41 N_("Enable LDAP lookups.") },
42 { "base", mu_cfg_string, &ldap_settings.base }, 42 { "url", mu_cfg_string, &ldap_settings.url, NULL,
43 { "binddn", mu_cfg_string, &ldap_settings.binddn }, 43 N_("Set URL of the LDAP server."),
44 { "passwd", mu_cfg_string, &ldap_settings.passwd }, 44 N_("url") },
45 { "tls", mu_cfg_bool, &ldap_settings.tls }, 45 { "base", mu_cfg_string, &ldap_settings.base, NULL,
46 { "debug", mu_cfg_int, &ldap_settings.debug }, 46 N_("Base DN for LDAP lookups."),
47 { "field-map", mu_cfg_callback, NULL, cb_field_map }, 47 N_("dn") },
48 { "getpwnam", mu_cfg_string, &ldap_settings.getpwnam_filter }, 48 { "binddn", mu_cfg_string, &ldap_settings.binddn, NULL,
49 { "getpwuid", mu_cfg_string, &ldap_settings.getpwuid_filter }, 49 N_("DN for accessing LDAP database."),
50 N_("dn") },
51 { "passwd", mu_cfg_string, &ldap_settings.passwd, NULL,
52 N_("Password for use with binddn.") },
53 { "tls", mu_cfg_bool, &ldap_settings.tls, NULL,
54 N_("Use TLS encryption.") },
55 { "debug", mu_cfg_int, &ldap_settings.debug, NULL,
56 N_("Set LDAP debugging level.") },
57 { "field-map", mu_cfg_callback, NULL, cb_field_map,
58 N_("Set a field-map for parsing LDAP replies. The map is a "
59 "column-separated list of definitions. Each definition has the "
60 "following form:\n"
61 " <name: string>=<attr: string>\n"
62 "where <name> is one of the following: name, passwd, uid, gid, "
63 "gecos, dir, shell, mailbox, quota, and <attr> is the name of "
64 "the correspondind LDAP attribute."),
65 N_("map") },
66 { "getpwnam", mu_cfg_string, &ldap_settings.getpwnam_filter, NULL,
67 N_("LDAP filter to use for getpwnam requests."),
68 N_("filter") },
69 { "getpwuid", mu_cfg_string, &ldap_settings.getpwuid_filter, NULL,
70 N_("LDAP filter to use for getpwuid requests."),
71 N_("filter") },
50 { NULL } 72 { NULL }
51 }; 73 };
52 74
......
...@@ -24,7 +24,9 @@ ...@@ -24,7 +24,9 @@
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 }, 27 { "service", mu_cfg_string, &pam_settings, NULL,
28 N_("Set PAM service name."),
29 N_("name") },
28 { NULL } 30 { NULL }
29 }; 31 };
30 32
......
...@@ -25,10 +25,17 @@ ...@@ -25,10 +25,17 @@
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-request", mu_cfg_string, &radius_settings.auth_request }, 28 { "auth", mu_cfg_string, &radius_settings.auth_request, NULL,
29 { "getpwnam-request", mu_cfg_string, &radius_settings.getpwnam_request }, 29 N_("Radius request for authorization."),
30 { "getpwuid-request", mu_cfg_string, &radius_settings.getpwuid_request }, 30 N_("request") },
31 { "directory", mu_cfg_string, &radius_settings.config_dir }, 31 { "getpwnam", mu_cfg_string, &radius_settings.getpwnam_request, NULL,
32 N_("Radius request for getpwnam."),
33 N_("request") },
34 { "getpwuid", mu_cfg_string, &radius_settings.getpwuid_request, NULL,
35 N_("Radius request for getpwuid."),
36 N_("request") },
37 { "directory", mu_cfg_string, &radius_settings.config_dir, NULL,
38 N_("Set radius configuration directory.") },
32 { NULL } 39 { NULL }
33 }; 40 };
34 41
......
...@@ -92,10 +92,18 @@ cb_library_path (mu_debug_t debug, void *data, char *arg) ...@@ -92,10 +92,18 @@ 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, cb_clear_library_path,
96 { "clear-include-path", mu_cfg_callback, NULL, cb_clear_include_path }, 96 N_("Clear library search path.") },
97 { "library-path", mu_cfg_callback, NULL, cb_library_path }, 97 { "clear-include-path", mu_cfg_callback, NULL, cb_clear_include_path,
98 { "include-path", mu_cfg_callback, NULL, cb_include_path }, 98 N_("Clear include search path.") },
99 { "library-path", mu_cfg_callback, NULL, cb_library_path,
100 N_("Add directories to the library search path. Argument is a "
101 "comma-separated list of directories."),
102 N_("list") },
103 { "include-path", mu_cfg_callback, NULL, cb_include_path,
104 N_("Add directories to the include search path. Argument is a "
105 "comma-separated list of directories."),
106 N_("list") },
99 { NULL } 107 { NULL }
100 }; 108 };
101 109
......
...@@ -50,17 +50,39 @@ cb_field_map (mu_debug_t debug, void *data, char *arg) ...@@ -50,17 +50,39 @@ 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 }, 53 { "interface", mu_cfg_string, &sql_settings.interface, NULL,
54 { "getwpnam", mu_cfg_string, &sql_settings.getpwnam_query }, 54 N_("Set SQL interface to use (one of: mysql, odbc, or postgres).") },
55 { "getpwuid", mu_cfg_string, &sql_settings.getpwuid_query }, 55 { "getwpnam", mu_cfg_string, &sql_settings.getpwnam_query, NULL,
56 { "getpass", mu_cfg_string, &sql_settings.getpass_query }, 56 N_("SQL query to use for getpwnam requests."),
57 { "host", mu_cfg_string, &sql_settings.host }, 57 N_("query") },
58 { "user", mu_cfg_string, &sql_settings.user }, 58 { "getpwuid", mu_cfg_string, &sql_settings.getpwuid_query, NULL,
59 { "passwd", mu_cfg_string, &sql_settings.passwd }, 59 N_("SQL query to use for getpwuid requests."),
60 { "db", mu_cfg_string, &sql_settings.db }, 60 N_("query") },
61 { "port", mu_cfg_int, &sql_settings.port }, 61 { "getpass", mu_cfg_string, &sql_settings.getpass_query, NULL,
62 { "password-type", mu_cfg_callback, NULL, cb_password_type }, 62 N_("SQL query returning the user's password."),
63 { "field-map", mu_cfg_callback, NULL, cb_field_map }, 63 N_("query") },
64 { "host", mu_cfg_string, &sql_settings.host, NULL,
65 N_("SQL server host name.") },
66 { "user", mu_cfg_string, &sql_settings.user, NULL,
67 N_("SQL user name.") },
68 { "passwd", mu_cfg_string, &sql_settings.passwd, NULL,
69 N_("Password for the SQL user.") },
70 { "port", mu_cfg_int, &sql_settings.port, NULL,
71 N_("SQL server port.") },
72 { "db", mu_cfg_string, &sql_settings.db, NULL,
73 N_("Database name.") },
74 { "password-type", mu_cfg_callback, NULL, cb_password_type,
75 N_("Type of password returned by getpass query (one of: plain, hash, "
76 "scrambled).") },
77 { "field-map", mu_cfg_callback, NULL, cb_field_map,
78 N_("Set a field-map for parsing SQL replies. The map is a "
79 "column-separated list of definitions. Each definition has the "
80 "following form:\n"
81 " <name: string>=<column: string>\n"
82 "where <name> is one of the following: name, passwd, uid, gid, "
83 "gecos, dir, shell, mailbox, quota, and <column> is the name of "
84 "the corresponding SQL column."),
85 N_("map") },
64 { NULL } 86 { NULL }
65 }; 87 };
66 88
......
...@@ -25,10 +25,17 @@ ...@@ -25,10 +25,17 @@
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 }, 28 { "tls", mu_cfg_bool, &tls_settings.client_enable, NULL,
29 { "ssl-cert", mu_cfg_string, &tls_settings.ssl_cert }, 29 N_("Enable client TLS encryption.") },
30 { "ssl-key", mu_cfg_string, &tls_settings.ssl_key }, 30 { "ssl-cert", mu_cfg_string, &tls_settings.ssl_cert, NULL,
31 { "ssl-cafile", mu_cfg_string, &tls_settings.ssl_cafile }, 31 N_("Specify SSL certificate file."),
32 N_("file") },
33 { "ssl-key", mu_cfg_string, &tls_settings.ssl_key, NULL,
34 N_("Specify SSL certificate key file."),
35 N_("file") },
36 { "ssl-cafile", mu_cfg_string, &tls_settings.ssl_cafile, NULL,
37 N_("Specify trusted CAs file."),
38 N_("file") },
32 { NULL } 39 { NULL }
33 }; 40 };
34 41
......
...@@ -24,7 +24,10 @@ ...@@ -24,7 +24,10 @@
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 }, 27 { "passwd-dir", mu_cfg_string, &virtdomain_settings, NULL,
28 N_("Name of the directory where virtual domain password files are "
29 "located."),
30 N_("dir") },
28 { NULL } 31 { NULL }
29 }; 32 };
30 33
......
...@@ -66,7 +66,7 @@ N_("Debug flags are:\n\ ...@@ -66,7 +66,7 @@ N_("Debug flags are:\n\
66 t - sieve trace (MU_SIEVE_DEBUG_TRACE)\n\ 66 t - sieve trace (MU_SIEVE_DEBUG_TRACE)\n\
67 i - sieve instructions trace (MU_SIEVE_DEBUG_INSTR)\n\ 67 i - sieve instructions trace (MU_SIEVE_DEBUG_INSTR)\n\
68 l - sieve action logs\n\ 68 l - sieve action logs\n\
69 0-9 - Set mail.local debugging level\n"); 69 0-9 - Set maidag debugging level\n");
70 70
71 static char args_doc[] = N_("[recipient...]"); 71 static char args_doc[] = N_("[recipient...]");
72 72
...@@ -237,26 +237,58 @@ cb_debug (mu_debug_t debug, void *data, char *arg) ...@@ -237,26 +237,58 @@ cb_debug (mu_debug_t debug, void *data, char *arg)
237 } 237 }
238 238
239 struct mu_cfg_param maidag_cfg_param[] = { 239 struct mu_cfg_param maidag_cfg_param[] = {
240 { "exit-multiple-delivery-success", mu_cfg_bool, &multiple_delivery }, 240 { "exit-multiple-delivery-success", mu_cfg_bool, &multiple_delivery, NULL,
241 { "exit-quota-tempfail", mu_cfg_bool, &ex_quota_tempfail }, 241 N_("In case of multiple delivery, exit with code 0 if at least one "
242 "delivery succeeded.") },
243 { "exit-quota-tempfail", mu_cfg_bool, &ex_quota_tempfail, NULL,
244 N_("Indicate temporary failure if the recipient is over his mail quota.")
245 },
242 #ifdef USE_DBM 246 #ifdef USE_DBM
243 { "quota-db", mu_cfg_string, &quotadbname }, 247 { "quota-db", mu_cfg_string, &quotadbname, NULL,
248 N_("Name of DBM quota database file."),
249 N_("file") },
244 #endif 250 #endif
245 #ifdef USE_SQL 251 #ifdef USE_SQL
246 { "quota-query", mu_cfg_string, &quota_query }, 252 { "quota-query", mu_cfg_string, &quota_query, NULL,
253 N_("SQL query to retrieve mailbox quota. This is deprecated, use "
254 "sql { ... } instead."),
255 N_("query") },
247 #endif 256 #endif
248 { "sieve-filter", mu_cfg_string, &sieve_pattern }, 257 { "sieve-filter", mu_cfg_string, &sieve_pattern, NULL,
249 { "message-id-header", mu_cfg_string, &message_id_header }, 258 N_("File name or name pattern for Sieve filter file."),
259 N_("file-or-pattern") },
260 { "message-id-header", mu_cfg_string, &message_id_header, NULL,
261 N_("When logging Sieve actions, identify messages by the value of "
262 "this header."),
263 N_("name") },
250 #ifdef WITH_GUILE 264 #ifdef WITH_GUILE
251 { "guile-filter", mu_cfg_string, &progfile_pattern }, 265 { "guile-filter", mu_cfg_string, &progfile_pattern, NULL,
266 N_("File name or name pattern for Guile filter file."),
267 N_("file-or-pattern") },
252 #endif 268 #endif
253 { "debug", mu_cfg_callback, NULL, cb_debug }, 269 { "debug", mu_cfg_callback, NULL, cb_debug,
254 { "stderr", mu_cfg_bool, &log_to_stderr }, 270 N_("Set maidag debug level. Debug level consists of one or more "
271 "of the following letters:\n"
272 " g - guimb stack traces\n"
273 " t - sieve trace (MU_SIEVE_DEBUG_TRACE)\n"
274 " i - sieve instructions trace (MU_SIEVE_DEBUG_INSTR)\n"
275 " l - sieve action logs\n") },
276 { "stderr", mu_cfg_bool, &log_to_stderr, NULL,
277 N_("Log to stderr instead of syslog.") },
255 /* LMTP support */ 278 /* LMTP support */
256 { "lmtp", mu_cfg_bool, &lmtp_mode }, 279 { "lmtp", mu_cfg_bool, &lmtp_mode, NULL,
257 { "group", mu_cfg_string, &lmtp_group }, 280 N_("Run in LMTP mode.") },
258 { "listen", mu_cfg_string, &lmtp_url_string }, 281 { "group", mu_cfg_string, &lmtp_group, NULL,
259 { "reuse-address", mu_cfg_bool, &reuse_lmtp_address }, 282 N_("In LMTP mode, change to this group after startup.") },
283 { "listen", mu_cfg_string, &lmtp_url_string, NULL,
284 N_("In LMTP mode, listen on the given URL. Valid URLs are:\n"
285 " tcp://<address: string>:<port: number> (note that port is "
286 "mandatory)\n"
287 " file://<socket-file-name>\n"
288 "or socket://<socket-file-name>"),
289 N_("url") },
290 { "reuse-address", mu_cfg_bool, &reuse_lmtp_address, NULL,
291 N_("Reuse existing address (LMTP mode). Default is \"yes\".") },
260 { NULL } 292 { NULL }
261 }; 293 };
262 294
......
...@@ -255,21 +255,42 @@ cb_debug (mu_debug_t debug, void *data, char *arg) ...@@ -255,21 +255,42 @@ 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 }, 258 { "ex-multiple-delivery-success", mu_cfg_bool, &multiple_delivery, NULL,
259 { "ex-quota-tempfail", mu_cfg_bool, &ex_quota_tempfail }, 259 N_("In case of multiple delivery, exit with code 0 if at least one "
260 { "from", mu_cfg_string, &from }, 260 "delivery succeeded.") },
261 { "ex-quota-tempfail", mu_cfg_bool, &ex_quota_tempfail, NULL,
262 N_("Indicate temporary failure if the recipient is over his mail quota.")
263 },
261 #ifdef USE_DBM 264 #ifdef USE_DBM
262 { "quota-db", mu_cfg_string, &quotadbname }, 265 { "quota-db", mu_cfg_string, &quotadbname, NULL,
266 N_("Name of DBM quota database file."),
267 N_("file") },
263 #endif 268 #endif
264 #ifdef USE_SQL 269 #ifdef USE_SQL
265 { "quota-query", mu_cfg_string, &quota_query }, 270 { "quota-query", mu_cfg_string, &quota_query, NULL,
271 N_("SQL query to retrieve mailbox quota. This is deprecated, use "
272 "sql { ... } instead."),
273 N_("query") },
266 #endif 274 #endif
267 { "sieve", mu_cfg_string, &sieve_pattern }, 275 { "sieve-filter", mu_cfg_string, &sieve_pattern, NULL,
268 { "message-id-header", mu_cfg_string, &message_id_header }, 276 N_("File name or name pattern for Sieve filter file."),
277 N_("file-or-pattern") },
278 { "message-id-header", mu_cfg_string, &message_id_header, NULL,
279 N_("When logging Sieve actions, identify messages by the value of "
280 "this header."),
281 N_("name") },
269 #ifdef WITH_GUILE 282 #ifdef WITH_GUILE
270 { "source", mu_cfg_string, &progfile_pattern }, 283 { "guile-filter", mu_cfg_string, &progfile_pattern, NULL,
284 N_("File name or name pattern for Guile filter file."),
285 N_("file-or-pattern") },
271 #endif 286 #endif
272 { "debug", mu_cfg_callback, NULL, cb_debug }, 287 { "debug", mu_cfg_callback, NULL, cb_debug,
288 N_("Set mail.local debug level. Debug level consists of one or more "
289 "of the following letters:\n"
290 " g - guimb stack traces\n"
291 " t - sieve trace (MU_SIEVE_DEBUG_TRACE)\n"
292 " i - sieve instructions trace (MU_SIEVE_DEBUG_INSTR)\n"
293 " l - sieve action logs\n") },
273 { NULL } 294 { NULL }
274 }; 295 };
275 296
......
...@@ -136,10 +136,16 @@ static struct argp argp = { ...@@ -136,10 +136,16 @@ 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 }, 139 { "from", mu_cfg_string, &optfrom, NULL,
140 { "read-recipients", mu_cfg_string, &read_recipients }, 140 N_("Set sender email address."),
141 { "debug", mu_cfg_int, &optdebug }, 141 N_("email") },
142 { NULL} 142 { "read-recipients", mu_cfg_string, &read_recipients, NULL,
143 N_("Read recipient addresses from the message.") },
144 { "debug", mu_cfg_int, &optdebug, NULL,
145 N_("Set debug verbosity level. Level 1 prints envelope commands in "
146 "the SMTP protocol transaction. Levels 2 and above print the data "
147 "part of the transaction as well.") },
148 { NULL }
143 }; 149 };
144 150
145 151
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
23 #include <mailutils/cfg.h> 23 #include <mailutils/cfg.h>
24 #include <mailutils/argcv.h> 24 #include <mailutils/argcv.h>
25 #include <mailutils/nls.h> 25 #include <mailutils/nls.h>
26 #include <ctype.h>
26 27
27 struct tree_print 28 struct tree_print
28 { 29 {
...@@ -149,7 +150,7 @@ mu_cfg_data_type_string (enum mu_cfg_param_data_type type) ...@@ -149,7 +150,7 @@ mu_cfg_data_type_string (enum mu_cfg_param_data_type type)
149 switch (type) 150 switch (type)
150 { 151 {
151 case mu_cfg_string: 152 case mu_cfg_string:
152 return "string"; 153 return N_("string");
153 case mu_cfg_short: 154 case mu_cfg_short:
154 case mu_cfg_ushort: 155 case mu_cfg_ushort:
155 case mu_cfg_int: 156 case mu_cfg_int:
...@@ -158,30 +159,84 @@ mu_cfg_data_type_string (enum mu_cfg_param_data_type type) ...@@ -158,30 +159,84 @@ mu_cfg_data_type_string (enum mu_cfg_param_data_type type)
158 case mu_cfg_ulong: 159 case mu_cfg_ulong:
159 case mu_cfg_size: 160 case mu_cfg_size:
160 case mu_cfg_off: 161 case mu_cfg_off:
161 return "number"; 162 return N_("number");
162 case mu_cfg_time: 163 case mu_cfg_time:
163 return "time"; 164 return N_("time");
164 case mu_cfg_bool: 165 case mu_cfg_bool:
165 return "boolean"; 166 return N_("boolean");
166 case mu_cfg_ipv4: 167 case mu_cfg_ipv4:
167 return "ipv4"; 168 return N_("ipv4");
168 case mu_cfg_cidr: 169 case mu_cfg_cidr:
169 return "cidr"; 170 return N_("cidr");
170 case mu_cfg_host: 171 case mu_cfg_host:
171 return "host"; 172 return N_("host");
172 case mu_cfg_callback: 173 case mu_cfg_callback:
173 return "string"; /* FIXME: opaque data */ 174 return N_("string");
175 }
176 return N_("unknown");
177 }
178
179 void
180 mu_cfg_format_docstring (mu_stream_t stream, const char *docstring, int level)
181 {
182 size_t len = strlen (docstring);
183 int width = 78 - level * 2;
184
185 if (width < 0)
186 {
187 width = 78;
188 level = 0;
189 }
190
191 while (len)
192 {
193 size_t seglen;
194 const char *p;
195
196 for (seglen = 0, p = docstring; p < docstring + width && *p; p++)
197 {
198 if (*p == '\n')
199 {
200 seglen = p - docstring;
201 break;
202 }
203 if (isspace (*p))
204 seglen = p - docstring;
205 }
206 if (seglen == 0 || *p == 0)
207 seglen = p - docstring;
208
209 format_level (stream, level);
210 mu_stream_sequential_write (stream, "# ", 2);
211 mu_stream_sequential_write (stream, docstring, seglen);
212 mu_stream_sequential_write (stream, "\n", 1);
213 len -= seglen;
214 docstring += seglen;
215 if (*docstring == '\n')
216 {
217 docstring++;
218 len--;
219 }
220 else
221 while (*docstring && isspace (*docstring))
222 {
223 docstring++;
224 len--;
225 }
174 } 226 }
175 return "unknown";
176 } 227 }
177 228
178 static void 229 static void
179 format_param (mu_stream_t stream, struct mu_cfg_param *param, int level) 230 format_param (mu_stream_t stream, struct mu_cfg_param *param, int level)
180 { 231 {
232 if (param->docstring)
233 mu_cfg_format_docstring (stream, gettext (param->docstring), level);
181 format_level (stream, level); 234 format_level (stream, level);
182 mu_stream_sequential_printf (stream, "%s <%s>;\n", 235 mu_stream_sequential_printf (stream, "%s <%s: %s>;\n",
183 param->ident, 236 param->ident,
184 mu_cfg_data_type_string (param->type)); 237 gettext (param->argname ?
238 param->argname : N_("arg")),
239 gettext (mu_cfg_data_type_string (param->type)));
185 } 240 }
186 241
187 static void format_container (mu_stream_t stream, struct mu_cfg_cont *cont, 242 static void format_container (mu_stream_t stream, struct mu_cfg_cont *cont,
...@@ -200,6 +255,8 @@ static void ...@@ -200,6 +255,8 @@ static void
200 format_section (mu_stream_t stream, struct mu_cfg_section *sect, int level) 255 format_section (mu_stream_t stream, struct mu_cfg_section *sect, int level)
201 { 256 {
202 struct tree_print c; 257 struct tree_print c;
258 if (sect->docstring)
259 mu_cfg_format_docstring (stream, gettext (sect->docstring), level);
203 format_level (stream, level); 260 format_level (stream, level);
204 if (sect->ident) 261 if (sect->ident)
205 { 262 {
......
...@@ -359,7 +359,7 @@ mu_config_create_container (struct mu_cfg_cont **pcont, ...@@ -359,7 +359,7 @@ mu_config_create_container (struct mu_cfg_cont **pcont,
359 struct mu_cfg_cont *cont; 359 struct mu_cfg_cont *cont;
360 int rc; 360 int rc;
361 361
362 cont = malloc (sizeof (*cont)); 362 cont = calloc (1, sizeof (*cont));
363 if (!cont) 363 if (!cont)
364 return ENOMEM; 364 return ENOMEM;
365 rc = mu_refcount_create (&cont->refcount); 365 rc = mu_refcount_create (&cont->refcount);
...@@ -437,6 +437,7 @@ dup_container (struct mu_cfg_cont **pcont) ...@@ -437,6 +437,7 @@ dup_container (struct mu_cfg_cont **pcont)
437 newcont->v.section.ident = oldcont->v.section.ident; 437 newcont->v.section.ident = oldcont->v.section.ident;
438 newcont->v.section.parser = oldcont->v.section.parser; 438 newcont->v.section.parser = oldcont->v.section.parser;
439 newcont->v.section.data = oldcont->v.section.data; 439 newcont->v.section.data = oldcont->v.section.data;
440 newcont->v.section.docstring = oldcont->v.section.docstring;
440 newcont->v.section.subsec = NULL; 441 newcont->v.section.subsec = NULL;
441 newcont->v.section.param = NULL; 442 newcont->v.section.param = NULL;
442 mu_list_do (oldcont->v.section.subsec, _dup_section_action, &dd); 443 mu_list_do (oldcont->v.section.subsec, _dup_section_action, &dd);
...@@ -737,7 +738,12 @@ mu_build_container (const char *progname, ...@@ -737,7 +738,12 @@ mu_build_container (const char *progname,
737 struct mu_cfg_cont *cont = root_container; 738 struct mu_cfg_cont *cont = root_container;
738 struct include_data idata; 739 struct include_data idata;
739 struct mu_cfg_param mu_include_param[] = { 740 struct mu_cfg_param mu_include_param[] = {
740 { "include", mu_cfg_callback, &idata, _cb_include }, 741 { "include", mu_cfg_callback, &idata, _cb_include,
742 N_("Include contents of the given file. If a directory is given, "
743 "include contents of the file <file>/<program>, where <program> is "
744 "the name of the program. This latter form is allowed only in "
745 "the site-wide configuration file."),
746 N_("file-or-directory") },
741 { NULL } 747 { NULL }
742 }; 748 };
743 749
......
...@@ -158,10 +158,23 @@ cb_debug (mu_debug_t debug, void *data, char *arg) ...@@ -158,10 +158,23 @@ cb_debug (mu_debug_t debug, void *data, char *arg)
158 return 0; 158 return 0;
159 } 159 }
160 160
161 static int
162 cb_metamail (mu_debug_t debug, void *data, char *arg)
163 {
164 metamail = strdup ("metamail");
165 return 0;
166 }
167
161 struct mu_cfg_param mimeview_cfg_param[] = { 168 struct mu_cfg_param mimeview_cfg_param[] = {
162 {"debug", mu_cfg_callback, NULL, cb_debug }, 169 { "debug", mu_cfg_callback, NULL, cb_debug,
163 {"mimetypes", mu_cfg_string, &mimetypes_config }, 170 N_("Set debug verbosity level."),
164 {"metamail", mu_cfg_string, &metamail }, 171 N_("flags") },
172 { "mimetypes", mu_cfg_string, &mimetypes_config, NULL,
173 N_("Use this mime.types file."),
174 N_("file") },
175 { "metamail", mu_cfg_string, NULL, cb_metamail,
176 N_("Use this program to display files."),
177 N_("prog") },
165 { NULL } 178 { NULL }
166 }; 179 };
167 180
......
...@@ -90,9 +90,12 @@ static struct argp argp = { ...@@ -90,9 +90,12 @@ 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 }, 93 { "preserve", mu_cfg_bool, &preserve_mail, NULL,
94 { "reverse", mu_cfg_bool, &reverse_order }, 94 N_("Do not remove messages from the source mailbox.") },
95 { "emacs", mu_cfg_bool, &emacs_mode }, 95 { "reverse", mu_cfg_bool, &reverse_order, NULL,
96 N_("Reverse message sorting order.") },
97 { "emacs", mu_cfg_bool, &emacs_mode, NULL,
98 N_("Output information used by Emacs rmail interface.") },
96 { NULL } 99 { NULL }
97 }; 100 };
98 101
......
...@@ -32,11 +32,12 @@ lib/argp-parse.c ...@@ -32,11 +32,12 @@ lib/argp-parse.c
32 lib/getopt.c 32 lib/getopt.c
33 lib/mailcap.c 33 lib/mailcap.c
34 lib/xmalloc.c 34 lib/xmalloc.c
35 libargp/mu_argp.c
36 libargp/auth.c 35 libargp/auth.c
37 libargp/cmdline.c 36 libargp/cmdline.c
38 libargp/common.c 37 libargp/common.c
39 libargp/gsasl.c 38 libargp/gsasl.c
39 libargp/mu_argp.c
40 libargp/muinit.c
40 libargp/pam.c 41 libargp/pam.c
41 libargp/radius.c 42 libargp/radius.c
42 libargp/sql.c 43 libargp/sql.c
...@@ -46,8 +47,10 @@ libcfg/auth.c ...@@ -46,8 +47,10 @@ libcfg/auth.c
46 libcfg/common.c 47 libcfg/common.c
47 libcfg/gsasl.c 48 libcfg/gsasl.c
48 libcfg/init.c 49 libcfg/init.c
50 libcfg/ldap.c
49 libcfg/pam.c 51 libcfg/pam.c
50 libcfg/radius.c 52 libcfg/radius.c
53 libcfg/sieve.c
51 libcfg/sql.c 54 libcfg/sql.c
52 libcfg/tls.c 55 libcfg/tls.c
53 libcfg/virtdomain.c 56 libcfg/virtdomain.c
...@@ -67,6 +70,7 @@ libsieve/sieve.l ...@@ -67,6 +70,7 @@ libsieve/sieve.l
67 libsieve/sieve.y 70 libsieve/sieve.y
68 libsieve/tests.c 71 libsieve/tests.c
69 libsieve/util.c 72 libsieve/util.c
73 maidag/maidag.c
70 mail.local/mailquota.c 74 mail.local/mailquota.c
71 mail.local/main.c 75 mail.local/main.c
72 mail.local/script.c 76 mail.local/script.c
...@@ -97,6 +101,8 @@ mail/summary.c ...@@ -97,6 +101,8 @@ mail/summary.c
97 mail/unalias.c 101 mail/unalias.c
98 mail/util.c 102 mail/util.c
99 mail/z.c 103 mail/z.c
104 mailbox/cfg_format.c
105 mailbox/cfg_lexer.c
100 mailbox/errors 106 mailbox/errors
101 mailbox/file_stream.c 107 mailbox/file_stream.c
102 mailbox/filter_iconv.c 108 mailbox/filter_iconv.c
......
...@@ -54,7 +54,7 @@ time_t login_delay = 0; ...@@ -54,7 +54,7 @@ time_t login_delay = 0;
54 char *login_stat_file = LOGIN_STAT_FILE; 54 char *login_stat_file = LOGIN_STAT_FILE;
55 #endif 55 #endif
56 56
57 time_t expire = EXPIRE_NEVER; /* Expire messages after this number of days */ 57 unsigned expire = EXPIRE_NEVER; /* Expire messages after this number of days */
58 int expire_on_exit = 0; /* Delete expired messages on exit */ 58 int expire_on_exit = 0; /* Delete expired messages on exit */
59 59
60 static int pop3d_mainloop (int fd, FILE *, FILE *); 60 static int pop3d_mainloop (int fd, FILE *, FILE *);
...@@ -91,7 +91,7 @@ static struct argp_option options[] = { ...@@ -91,7 +91,7 @@ static struct argp_option options[] = {
91 #define GRP 10 91 #define GRP 10
92 #ifdef ENABLE_LOGIN_DELAY 92 #ifdef ENABLE_LOGIN_DELAY
93 {"login-delay", OPT_LOGIN_DELAY, N_("SECONDS"), OPTION_HIDDEN, 93 {"login-delay", OPT_LOGIN_DELAY, N_("SECONDS"), OPTION_HIDDEN,
94 N_("Allowed delay between the two successive logins"), GRP+1}, 94 N_("Allowed delay between two successive logins"), GRP+1},
95 {"stat-file", OPT_STAT_FILE, N_("FILENAME"), OPTION_HIDDEN, 95 {"stat-file", OPT_STAT_FILE, N_("FILENAME"), OPTION_HIDDEN,
96 N_("Name of login statistics file"), GRP+1}, 96 N_("Name of login statistics file"), GRP+1},
97 #endif 97 #endif
...@@ -134,19 +134,30 @@ cb_bulletin_db (mu_debug_t debug, void *data, char *arg) ...@@ -134,19 +134,30 @@ 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 }, 137 { "undelete", mu_cfg_int, &undelete_on_startup, NULL,
138 { "expire", mu_cfg_time, &expire }, 138 N_("On startup, clear deletion marks from all the messages.") },
139 { "delete-expired", mu_cfg_int, &expire_on_exit }, 139 { "expire", mu_cfg_uint, &expire, NULL,
140 N_("Automatically expire read messages after the given number of days."),
141 N_("days") },
142 { "delete-expired", mu_cfg_int, &expire_on_exit, NULL,
143 N_("Delete expired messages upon closing the mailbox.") },
140 #ifdef WITH_TLS 144 #ifdef WITH_TLS
141 { "tls-required", mu_cfg_callback, NULL, cb_tls_required }, 145 { "tls-required", mu_cfg_callback, NULL, cb_tls_required,
146 N_("Always require STLS before entering authentication phase.") },
142 #endif 147 #endif
143 #ifdef ENABLE_LOGIN_DELAY 148 #ifdef ENABLE_LOGIN_DELAY
144 { "login-delay", mu_cfg_time, &login_delay }, 149 { "login-delay", mu_cfg_time, &login_delay, NULL,
145 { "stat-file", mu_cfg_string, &login_stat_file }, 150 N_("Set the minimal allowed delay between two successive logins.") },
151 { "stat-file", mu_cfg_string, &login_stat_file, NULL,
152 N_("Set the name of login statistics file (for login-delay).") },
146 #endif 153 #endif
147 { "bulletin-source", mu_cfg_callback, NULL, cb_bulletin_source }, 154 { "bulletin-source", mu_cfg_callback, NULL, cb_bulletin_source,
155 N_("Get bulletins from the specified mailbox."),
156 N_("url") },
148 #ifdef USE_DBM 157 #ifdef USE_DBM
149 { "bulletin-db", mu_cfg_callback, NULL, cb_bulletin_db }, 158 { "bulletin-db", mu_cfg_callback, NULL, cb_bulletin_db,
159 N_("Set the bulletin database file name."),
160 N_("file") },
150 #endif 161 #endif
151 { NULL } 162 { NULL }
152 }; 163 };
......
...@@ -94,10 +94,10 @@ extern void login_delay_capa (void); ...@@ -94,10 +94,10 @@ extern void login_delay_capa (void);
94 #endif 94 #endif
95 95
96 /* Minimum advertise retention time for messages. */ 96 /* Minimum advertise retention time for messages. */
97 extern time_t expire; 97 extern unsigned expire;
98 extern int expire_on_exit; 98 extern int expire_on_exit;
99 99
100 #define EXPIRE_NEVER ((time_t)-1) 100 #define EXPIRE_NEVER ((unsigned)-1)
101 101
102 /* Size of the MD5 digest for APOP */ 102 /* Size of the MD5 digest for APOP */
103 #define APOP_DIGEST 70 103 #define APOP_DIGEST 70
......
...@@ -47,7 +47,7 @@ static struct argp_option options[] = ...@@ -47,7 +47,7 @@ static struct argp_option options[] =
47 { "no-header", 'n', 0, 0, N_("Exclude all headers"), 1 }, 47 { "no-header", 'n', 0, 0, N_("Exclude all headers"), 1 },
48 { "form-feeds", 'p', 0, 0, N_("Output formfeeds between messages"), 1 }, 48 { "form-feeds", 'p', 0, 0, N_("Output formfeeds between messages"), 1 },
49 { "show-all-match", 'a', NULL, 0, 49 { "show-all-match", 'a', NULL, 0,
50 N_("Print all messages matching pattern, not just the first"), 1 }, 50 N_("Print all messages matching pattern, not only the first"), 1 },
51 {0, 0, 0, 0} 51 {0, 0, 0, 0}
52 }; 52 };
53 53
...@@ -129,13 +129,22 @@ readmsg_parse_opt (int key, char *arg, struct argp_state *astate) ...@@ -129,13 +129,22 @@ 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 }, 132 { "debug", mu_cfg_int, &dbug, NULL,
133 { "header", mu_cfg_bool, &all_header }, 133 N_("Set debug verbosity level.") },
134 { "weedlist", mu_cfg_string, &weedlist }, 134 { "header", mu_cfg_bool, &all_header, NULL,
135 { "folder", mu_cfg_string, &mailbox_name }, 135 N_("Display entire headers.") },
136 { "no-header", mu_cfg_bool, &no_header }, 136 { "weedlist", mu_cfg_string, &weedlist, NULL,
137 { "form-feeds", mu_cfg_bool, &form_feed }, 137 N_("Display only headers from this list. Argument is a list of header "
138 { "show-all-match", mu_cfg_bool, &show_all }, 138 "names separated by whitespace or commas."),
139 N_("list") },
140 { "folder", mu_cfg_string, &mailbox_name, NULL,
141 N_("Read messages from this folder.") },
142 { "no-header", mu_cfg_bool, &no_header, NULL,
143 N_("Exclude all headers.") },
144 { "form-feeds", mu_cfg_bool, &form_feed, NULL,
145 N_("Output formfeed character between messages.") },
146 { "show-all-match", mu_cfg_bool, &show_all, NULL,
147 N_("Print all messages matching pattern, not only the first.") },
139 { NULL } 148 { NULL }
140 }; 149 };
141 150
......
...@@ -82,7 +82,7 @@ static struct argp_option options[] = ...@@ -82,7 +82,7 @@ static struct argp_option options[] =
82 N_("Mailbox to sieve (defaults to user's mail spool)"), 0}, 82 N_("Mailbox to sieve (defaults to user's mail spool)"), 0},
83 83
84 {"ticket", 't', N_("TICKET"), 0, 84 {"ticket", 't', N_("TICKET"), 0,
85 N_("Ticket file for mailbox authentication"), 0}, 85 N_("Ticket file for user authentication"), 0},
86 86
87 {"debug", 'd', N_("FLAGS"), OPTION_ARG_OPTIONAL, 87 {"debug", 'd', N_("FLAGS"), OPTION_ARG_OPTIONAL,
88 N_("Debug flags (defaults to \"" D_DEFAULT "\")"), 0}, 88 N_("Debug flags (defaults to \"" D_DEFAULT "\")"), 0},
...@@ -233,8 +233,10 @@ parser (int key, char *arg, struct argp_state *state) ...@@ -233,8 +233,10 @@ parser (int key, char *arg, struct argp_state *state)
233 break; 233 break;
234 234
235 case ARGP_KEY_NO_ARGS: 235 case ARGP_KEY_NO_ARGS:
236 argp_error (state, _("SCRIPT must be specified")); 236 if (!mu_help_config_mode)
237 237 argp_error (state, _("SCRIPT must be specified"));
238 return ARGP_ERR_UNKNOWN;
239
238 case ARGP_KEY_INIT: 240 case ARGP_KEY_INIT:
239 mu_argp_node_list_init (&lst); 241 mu_argp_node_list_init (&lst);
240 break; 242 break;
...@@ -285,13 +287,28 @@ cb_ticket (mu_debug_t debug, void *data, char *arg) ...@@ -285,13 +287,28 @@ cb_ticket (mu_debug_t debug, void *data, char *arg)
285 } 287 }
286 288
287 static struct mu_cfg_param sieve_cfg_param[] = { 289 static struct mu_cfg_param sieve_cfg_param[] = {
288 { "keep-going", mu_cfg_int, &keep_going }, 290 { "keep-going", mu_cfg_int, &keep_going, NULL,
289 { "mbox-url", mu_cfg_string, &mbox_url }, 291 N_("Do not abort if execution fails on a message.") },
290 { "ticket", mu_cfg_callback, NULL, cb_ticket }, 292 { "mbox-url", mu_cfg_string, &mbox_url, NULL,
291 { "debug", mu_cfg_callback, NULL, cb_debug }, 293 N_("Mailbox to sieve (defaults to user's mail spool)."),
292 { "verbose", mu_cfg_bool, &verbose }, 294 N_("url") },
293 { "line-info", mu_cfg_bool, &sieve_print_locus }, 295 { "ticket", mu_cfg_callback, NULL, cb_ticket,
294 { "email", mu_cfg_callback, NULL, cb_email }, 296 N_("Ticket file for user authentication."),
297 N_("ticket") },
298 { "debug", mu_cfg_callback, NULL, cb_debug,
299 N_("Debug flags. Argument consists of one or more of the following "
300 "flags:\n"
301 " g - main parser traces\n"
302 " T - mailutils traces (MU_DEBUG_TRACE0-MU_DEBUG_TRACE1)\n"
303 " P - network protocols (MU_DEBUG_PROT)\n"
304 " t - sieve trace (MU_SIEVE_DEBUG_TRACE)\n"
305 " i - sieve instructions trace (MU_SIEVE_DEBUG_INSTR).") },
306 { "verbose", mu_cfg_bool, &verbose, NULL,
307 N_("Log all executed actions.") },
308 { "line-info", mu_cfg_bool, &sieve_print_locus, NULL,
309 N_("Print source locations along with action logs (default).") },
310 { "email", mu_cfg_callback, NULL, cb_email,
311 N_("Set user email address.") },
295 { NULL } 312 { NULL }
296 }; 313 };
297 314
......