Based on the discussion with Sam, changed handling of
mailutils' command line options. Command line is parsed using mu_argp_parse() call. mu_argp_parse scans global configuration file and processes any options found there before those from the command line. The options are separated by categories (capabilities): mailutils --maildir, --license auth --sql-.* family, --pam-service logging --log-facility daemon --daemon, --inetd, --port, --timeout If the capability name appears in configuration file, it should be prefixed with : to discern it from the utility name.
Showing
2 changed files
with
206 additions
and
14 deletions
1 | 2002-03-09 Sergey Poznyakoff | ||
2 | |||
3 | * configure.in: Check for libresolv. | ||
4 | |||
5 | Based on the discussion with Sam, changed handling of | ||
6 | mailutils' command line options. Command line is parsed using | ||
7 | mu_argp_parse() call. mu_argp_parse scans global configuration | ||
8 | file and processes any options found there before those from | ||
9 | the command line. The options are separated by categories | ||
10 | (capabilities): | ||
11 | |||
12 | mailutils --maildir, --license | ||
13 | auth --sql-.* family, --pam-service | ||
14 | logging --log-facility | ||
15 | daemon --daemon, --inetd, --port, --timeout | ||
16 | |||
17 | If a capability name appears in configuration file, it | ||
18 | should be prefixed with : to discern it from the utility | ||
19 | name. | ||
20 | |||
21 | * examples/mailutils.rc: Updated to reflect changes in the syntax. | ||
22 | |||
23 | * lib/mu_argp.c: New function mu_argp_parse is intended to be used | ||
24 | by all programs in the package in order to do command line parsing. | ||
25 | * lib/mu_argp.h: Removed unneeded prototypes. Added prototype for | ||
26 | mu_argp_parse(). | ||
27 | |||
28 | * comsat/comsat.c: Use mu_argp_parse. | ||
29 | * frm/frm.c: Likewise. | ||
30 | * guimb/main.c: Likewise. | ||
31 | * imap4d/imap4d.c: Likewise. | ||
32 | * mail/mail.c: Likewise. | ||
33 | * messages/messages.c: Likewise. | ||
34 | * pop3d/pop3d.c: Likewise. | ||
35 | * mail.local/main.c: Likewise. | ||
36 | (deliver): Restored erroneously removed variable sb. | ||
37 | |||
38 | * pop3d/apop.c (pop3d_apopuser): Changed scope of auto variable | ||
39 | rc. | ||
40 | |||
1 | 2002-03-01 Sam Roberts | 41 | 2002-03-01 Sam Roberts |
2 | 42 | ||
3 | * mailbox/mbx_mboxscan.c: Check return value of locker_lock(). | 43 | * mailbox/mbx_mboxscan.c: Check return value of locker_lock(). | ... | ... |
... | @@ -46,9 +46,20 @@ static struct argp_option mu_common_argp_option[] = | ... | @@ -46,9 +46,20 @@ static struct argp_option mu_common_argp_option[] = |
46 | { | 46 | { |
47 | {"maildir", 'm', "URL", 0, | 47 | {"maildir", 'm', "URL", 0, |
48 | "use specified URL as a mailspool directory", 0}, | 48 | "use specified URL as a mailspool directory", 0}, |
49 | { "license", 'L', NULL, 0, "print license and exit", 0 }, | ||
50 | { NULL, 0, NULL, 0, NULL, 0 } | ||
51 | }; | ||
52 | |||
53 | static struct argp_option mu_logging_argp_option[] = | ||
54 | { | ||
49 | {"log-facility", ARG_LOG_FACILITY, "FACILITY", 0, | 55 | {"log-facility", ARG_LOG_FACILITY, "FACILITY", 0, |
50 | "output logs to syslog FACILITY", 0}, | 56 | "output logs to syslog FACILITY", 0}, |
51 | { "license", 'L', NULL, 0, "print license and exit", 0 }, | 57 | { NULL, 0, NULL, 0, NULL, 0 } |
58 | }; | ||
59 | |||
60 | |||
61 | static struct argp_option mu_auth_argp_option[] = | ||
62 | { | ||
52 | #ifdef USE_LIBPAM | 63 | #ifdef USE_LIBPAM |
53 | { "pam-service", ARG_PAM_SERVICE, "STRING", 0, | 64 | { "pam-service", ARG_PAM_SERVICE, "STRING", 0, |
54 | "Use STRING as PAM service name", 0}, | 65 | "Use STRING as PAM service name", 0}, |
... | @@ -87,8 +98,10 @@ static struct argp_option mu_daemon_argp_option[] = | ... | @@ -87,8 +98,10 @@ static struct argp_option mu_daemon_argp_option[] = |
87 | { NULL, 0, NULL, 0, NULL, 0 } | 98 | { NULL, 0, NULL, 0, NULL, 0 } |
88 | }; | 99 | }; |
89 | 100 | ||
90 | static error_t mu_common_argp_parser (int key, char *arg, struct argp_state *state); | 101 | static error_t mu_common_argp_parser __P((int key, char *arg, |
91 | static error_t mu_daemon_argp_parser (int key, char *arg, struct argp_state *state); | 102 | struct argp_state *state)); |
103 | static error_t mu_daemon_argp_parser __P((int key, char *arg, | ||
104 | struct argp_state *state)); | ||
92 | 105 | ||
93 | struct argp mu_common_argp = | 106 | struct argp mu_common_argp = |
94 | { | 107 | { |
... | @@ -101,10 +114,47 @@ struct argp mu_common_argp = | ... | @@ -101,10 +114,47 @@ struct argp mu_common_argp = |
101 | NULL | 114 | NULL |
102 | }; | 115 | }; |
103 | 116 | ||
104 | struct argp_child mu_common_argp_child[] = | 117 | struct argp_child mu_common_argp_child = { |
118 | &mu_common_argp, | ||
119 | 0, | ||
120 | "Common mailutils options", | ||
121 | 1 | ||
122 | }; | ||
123 | |||
124 | struct argp mu_auth_argp = | ||
125 | { | ||
126 | mu_auth_argp_option, | ||
127 | mu_common_argp_parser, | ||
128 | "", | ||
129 | "", | ||
130 | NULL, | ||
131 | NULL, | ||
132 | NULL | ||
133 | }; | ||
134 | |||
135 | struct argp_child mu_auth_argp_child = { | ||
136 | &mu_auth_argp, | ||
137 | 0, | ||
138 | "Authentication-relevant options", | ||
139 | 1 | ||
140 | }; | ||
141 | |||
142 | struct argp mu_logging_argp = | ||
105 | { | 143 | { |
106 | {&mu_common_argp, 0, "Common mailutils options", 1}, | 144 | mu_logging_argp_option, |
107 | {NULL, 0, NULL, 0} | 145 | mu_common_argp_parser, |
146 | "", | ||
147 | "", | ||
148 | NULL, | ||
149 | NULL, | ||
150 | NULL | ||
151 | }; | ||
152 | |||
153 | struct argp_child mu_logging_argp_child = { | ||
154 | &mu_logging_argp, | ||
155 | 0, | ||
156 | "Logging options", | ||
157 | 1 | ||
108 | }; | 158 | }; |
109 | 159 | ||
110 | struct argp mu_daemon_argp = | 160 | struct argp mu_daemon_argp = |
... | @@ -118,11 +168,11 @@ struct argp mu_daemon_argp = | ... | @@ -118,11 +168,11 @@ struct argp mu_daemon_argp = |
118 | NULL | 168 | NULL |
119 | }; | 169 | }; |
120 | 170 | ||
121 | struct argp_child mu_daemon_argp_child[] = | 171 | struct argp_child mu_daemon_argp_child = { |
122 | { | 172 | &mu_daemon_argp, |
123 | {&mu_daemon_argp, 0, "Daemon configuration options", 1}, | 173 | 0, |
124 | {&mu_common_argp, 0, "Common mailutils options", 2}, | 174 | "Daemon configuration options", |
125 | {NULL, 0, NULL, 0} | 175 | 1 |
126 | }; | 176 | }; |
127 | 177 | ||
128 | int log_facility = LOG_FACILITY; | 178 | int log_facility = LOG_FACILITY; |
... | @@ -147,6 +197,7 @@ parse_log_facility (const char *str) | ... | @@ -147,6 +197,7 @@ parse_log_facility (const char *str) |
147 | { "LOCAL5", LOG_LOCAL5 }, | 197 | { "LOCAL5", LOG_LOCAL5 }, |
148 | { "LOCAL6", LOG_LOCAL6 }, | 198 | { "LOCAL6", LOG_LOCAL6 }, |
149 | { "LOCAL7", LOG_LOCAL7 }, | 199 | { "LOCAL7", LOG_LOCAL7 }, |
200 | { "MAIL", LOG_MAIL } | ||
150 | }; | 201 | }; |
151 | 202 | ||
152 | if (strncmp (str, "LOG_", 4) == 0) | 203 | if (strncmp (str, "LOG_", 4) == 0) |
... | @@ -310,8 +361,19 @@ mu_daemon_argp_parser (int key, char *arg, struct argp_state *state) | ... | @@ -310,8 +361,19 @@ mu_daemon_argp_parser (int key, char *arg, struct argp_state *state) |
310 | # define MU_CONFIG_FILE SYSCONFDIR "/mailutils.rc" | 361 | # define MU_CONFIG_FILE SYSCONFDIR "/mailutils.rc" |
311 | #endif | 362 | #endif |
312 | 363 | ||
364 | static int | ||
365 | member (const char *array[], const char *text, size_t len) | ||
366 | { | ||
367 | int i; | ||
368 | for (i = 0; array[i]; i++) | ||
369 | if (strncmp (array[i], text, len) == 0) | ||
370 | return 1; | ||
371 | return 0; | ||
372 | } | ||
373 | |||
313 | void | 374 | void |
314 | mu_create_argcv (int argc, char **argv, int *p_argc, char ***p_argv) | 375 | mu_create_argcv (const char *capa[], |
376 | int argc, char **argv, int *p_argc, char ***p_argv) | ||
315 | { | 377 | { |
316 | FILE *fp; | 378 | FILE *fp; |
317 | char *progname; | 379 | char *progname; |
... | @@ -393,8 +455,9 @@ mu_create_argcv (int argc, char **argv, int *p_argc, char ***p_argv) | ... | @@ -393,8 +455,9 @@ mu_create_argcv (int argc, char **argv, int *p_argc, char ***p_argv) |
393 | for (p = kwp; *p && !isspace (*p); p++) | 455 | for (p = kwp; *p && !isspace (*p); p++) |
394 | len++; | 456 | len++; |
395 | 457 | ||
396 | if (strncmp ("mailutils", kwp, len) == 0 | 458 | if ((kwp[0] == ':' |
397 | || strncmp (progname, kwp, len) == 0) | 459 | && member (capa, kwp+1, len-1)) |
460 | || strncmp (progname, kwp, len) == 0) | ||
398 | { | 461 | { |
399 | int n_argc = 0; | 462 | int n_argc = 0; |
400 | char **n_argv; | 463 | char **n_argv; |
... | @@ -437,3 +500,92 @@ mu_create_argcv (int argc, char **argv, int *p_argc, char ***p_argv) | ... | @@ -437,3 +500,92 @@ mu_create_argcv (int argc, char **argv, int *p_argc, char ***p_argv) |
437 | *p_argc = x_argc; | 500 | *p_argc = x_argc; |
438 | *p_argv = x_argv; | 501 | *p_argv = x_argv; |
439 | } | 502 | } |
503 | |||
504 | struct argp_capa { | ||
505 | char *capability; | ||
506 | struct argp_child *child; | ||
507 | } mu_argp_capa[] = { | ||
508 | {"mailutils", &mu_common_argp_child}, | ||
509 | {"daemon", &mu_daemon_argp_child}, | ||
510 | {"auth", &mu_auth_argp_child}, | ||
511 | {"logging", &mu_logging_argp_child}, | ||
512 | {NULL,} | ||
513 | }; | ||
514 | |||
515 | static struct argp_child * | ||
516 | find_argp_child (const char *capa) | ||
517 | { | ||
518 | int i; | ||
519 | for (i = 0; mu_argp_capa[i].capability; i++) | ||
520 | if (strcmp (mu_argp_capa[i].capability, capa) == 0) | ||
521 | return mu_argp_capa[i].child; | ||
522 | return NULL; | ||
523 | } | ||
524 | |||
525 | static struct argp * | ||
526 | mu_build_argp (const struct argp *template, const char *capa[]) | ||
527 | { | ||
528 | int n; | ||
529 | struct argp_child *ap; | ||
530 | struct argp *argp; | ||
531 | |||
532 | /* Count the capabilities */ | ||
533 | for (n = 0; capa[n]; n++) | ||
534 | ; | ||
535 | if (template->children) | ||
536 | for (; template->children[n].argp; n++) | ||
537 | ; | ||
538 | |||
539 | ap = calloc (n + 1, sizeof (*ap)); | ||
540 | if (!ap) | ||
541 | { | ||
542 | mu_error ("out of memory"); | ||
543 | abort (); | ||
544 | } | ||
545 | |||
546 | n = 0; | ||
547 | if (template->children) | ||
548 | for (; template->children[n].argp; n++) | ||
549 | ap[n] = template->children[n]; | ||
550 | |||
551 | for (; capa[n]; n++) | ||
552 | { | ||
553 | struct argp_child *tmp = find_argp_child (capa[n]); | ||
554 | if (!tmp) | ||
555 | { | ||
556 | mu_error ("INTERNAL ERROR: requested unknown argp capability %s", | ||
557 | capa[n]); | ||
558 | continue; | ||
559 | } | ||
560 | ap[n] = *tmp; | ||
561 | ap[n].group = n; | ||
562 | } | ||
563 | ap[n].argp = NULL; | ||
564 | argp = malloc (sizeof (*argp)); | ||
565 | if (!argp) | ||
566 | { | ||
567 | mu_error ("out of memory"); | ||
568 | abort (); | ||
569 | } | ||
570 | memcpy (argp, template, sizeof (*argp)); | ||
571 | argp->children = ap; | ||
572 | return argp; | ||
573 | } | ||
574 | |||
575 | error_t | ||
576 | mu_argp_parse(const struct argp *argp, | ||
577 | int *pargc, char **pargv[], | ||
578 | unsigned flags, | ||
579 | const char *capa[], | ||
580 | int *arg_index, | ||
581 | void *input) | ||
582 | { | ||
583 | error_t ret; | ||
584 | |||
585 | argp = mu_build_argp (argp, capa); | ||
586 | mu_create_argcv (capa, *pargc, *pargv, pargc, pargv); | ||
587 | ret = argp_parse (argp, *pargc, *pargv, flags, arg_index, input); | ||
588 | free ((void*) argp->children); | ||
589 | free ((void*) argp); | ||
590 | return ret; | ||
591 | } | ... | ... |
-
Please register or sign in to post a comment