Commit 8e6ef872 8e6ef8728b9e2fba89e779fc1c43a370e3ebe908 by Sergey Poznyakoff

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.
1 parent 1a7126d9
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 }
......