46 |
{ |
{ |
47 |
{"maildir", 'm', "URL", 0, |
{"maildir", 'm', "URL", 0, |
48 |
"use specified URL as a mailspool directory", 0}, |
"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 |
|
{ |
55 |
{"log-facility", ARG_LOG_FACILITY, "FACILITY", 0, |
{"log-facility", ARG_LOG_FACILITY, "FACILITY", 0, |
56 |
"output logs to syslog FACILITY", 0}, |
"output logs to syslog FACILITY", 0}, |
57 |
{ "license", 'L', NULL, 0, "print license and exit", 0 }, |
{ NULL, 0, NULL, 0, NULL, 0 } |
58 |
|
}; |
59 |
|
|
60 |
|
|
61 |
|
static struct argp_option mu_auth_argp_option[] = |
62 |
|
{ |
63 |
#ifdef USE_LIBPAM |
#ifdef USE_LIBPAM |
64 |
{ "pam-service", ARG_PAM_SERVICE, "STRING", 0, |
{ "pam-service", ARG_PAM_SERVICE, "STRING", 0, |
65 |
"Use STRING as PAM service name", 0}, |
"Use STRING as PAM service name", 0}, |
98 |
{ NULL, 0, NULL, 0, NULL, 0 } |
{ NULL, 0, NULL, 0, NULL, 0 } |
99 |
}; |
}; |
100 |
|
|
101 |
static error_t mu_common_argp_parser (int key, char *arg, struct argp_state *state); |
static error_t mu_common_argp_parser __P((int key, char *arg, |
102 |
static error_t mu_daemon_argp_parser (int key, char *arg, struct argp_state *state); |
struct argp_state *state)); |
103 |
|
static error_t mu_daemon_argp_parser __P((int key, char *arg, |
104 |
|
struct argp_state *state)); |
105 |
|
|
106 |
struct argp mu_common_argp = |
struct argp mu_common_argp = |
107 |
{ |
{ |
114 |
NULL |
NULL |
115 |
}; |
}; |
116 |
|
|
117 |
struct argp_child mu_common_argp_child[] = |
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 = |
143 |
{ |
{ |
144 |
{&mu_common_argp, 0, "Common mailutils options", 1}, |
mu_logging_argp_option, |
145 |
{NULL, 0, NULL, 0} |
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 |
158 |
}; |
}; |
159 |
|
|
160 |
struct argp mu_daemon_argp = |
struct argp mu_daemon_argp = |
168 |
NULL |
NULL |
169 |
}; |
}; |
170 |
|
|
171 |
struct argp_child mu_daemon_argp_child[] = |
struct argp_child mu_daemon_argp_child = { |
172 |
{ |
&mu_daemon_argp, |
173 |
{&mu_daemon_argp, 0, "Daemon configuration options", 1}, |
0, |
174 |
{&mu_common_argp, 0, "Common mailutils options", 2}, |
"Daemon configuration options", |
175 |
{NULL, 0, NULL, 0} |
1 |
176 |
}; |
}; |
177 |
|
|
178 |
int log_facility = LOG_FACILITY; |
int log_facility = LOG_FACILITY; |
197 |
{ "LOCAL5", LOG_LOCAL5 }, |
{ "LOCAL5", LOG_LOCAL5 }, |
198 |
{ "LOCAL6", LOG_LOCAL6 }, |
{ "LOCAL6", LOG_LOCAL6 }, |
199 |
{ "LOCAL7", LOG_LOCAL7 }, |
{ "LOCAL7", LOG_LOCAL7 }, |
200 |
|
{ "MAIL", LOG_MAIL } |
201 |
}; |
}; |
202 |
|
|
203 |
if (strncmp (str, "LOG_", 4) == 0) |
if (strncmp (str, "LOG_", 4) == 0) |
361 |
# define MU_CONFIG_FILE SYSCONFDIR "/mailutils.rc" |
# define MU_CONFIG_FILE SYSCONFDIR "/mailutils.rc" |
362 |
#endif |
#endif |
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 |
|
|
374 |
void |
void |
375 |
mu_create_argcv (int argc, char **argv, int *p_argc, char ***p_argv) |
mu_create_argcv (const char *capa[], |
376 |
|
int argc, char **argv, int *p_argc, char ***p_argv) |
377 |
{ |
{ |
378 |
FILE *fp; |
FILE *fp; |
379 |
char *progname; |
char *progname; |
455 |
for (p = kwp; *p && !isspace (*p); p++) |
for (p = kwp; *p && !isspace (*p); p++) |
456 |
len++; |
len++; |
457 |
|
|
458 |
if (strncmp ("mailutils", kwp, len) == 0 |
if ((kwp[0] == ':' |
459 |
|| strncmp (progname, kwp, len) == 0) |
&& member (capa, kwp+1, len-1)) |
460 |
|
|| strncmp (progname, kwp, len) == 0) |
461 |
{ |
{ |
462 |
int n_argc = 0; |
int n_argc = 0; |
463 |
char **n_argv; |
char **n_argv; |
500 |
*p_argc = x_argc; |
*p_argc = x_argc; |
501 |
*p_argv = x_argv; |
*p_argv = x_argv; |
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 |
|
} |