diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2002-03-08 22:43:22 +0000 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2002-03-08 22:43:22 +0000 |
commit | 8e6ef8728b9e2fba89e779fc1c43a370e3ebe908 (patch) | |
tree | 81d1fd4becc505a8b0a34d4dc7967c1e06398bef /lib | |
parent | 1a7126d9c0a2292a3f02621a244e64e212bd01cb (diff) | |
download | mailutils-8e6ef8728b9e2fba89e779fc1c43a370e3ebe908.tar.gz mailutils-8e6ef8728b9e2fba89e779fc1c43a370e3ebe908.tar.bz2 |
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.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/mu_argp.c | 180 |
1 files changed, 166 insertions, 14 deletions
diff --git a/lib/mu_argp.c b/lib/mu_argp.c index 7498941dd..7499bc27f 100644 --- a/lib/mu_argp.c +++ b/lib/mu_argp.c @@ -46,9 +46,20 @@ static struct argp_option mu_common_argp_option[] = { {"maildir", 'm', "URL", 0, "use specified URL as a mailspool directory", 0}, + { "license", 'L', NULL, 0, "print license and exit", 0 }, + { NULL, 0, NULL, 0, NULL, 0 } +}; + +static struct argp_option mu_logging_argp_option[] = +{ {"log-facility", ARG_LOG_FACILITY, "FACILITY", 0, "output logs to syslog FACILITY", 0}, - { "license", 'L', NULL, 0, "print license and exit", 0 }, + { NULL, 0, NULL, 0, NULL, 0 } +}; + + +static struct argp_option mu_auth_argp_option[] = +{ #ifdef USE_LIBPAM { "pam-service", ARG_PAM_SERVICE, "STRING", 0, "Use STRING as PAM service name", 0}, @@ -87,8 +98,10 @@ static struct argp_option mu_daemon_argp_option[] = { NULL, 0, NULL, 0, NULL, 0 } }; -static error_t mu_common_argp_parser (int key, char *arg, struct argp_state *state); -static error_t mu_daemon_argp_parser (int key, char *arg, struct argp_state *state); +static error_t mu_common_argp_parser __P((int key, char *arg, + struct argp_state *state)); +static error_t mu_daemon_argp_parser __P((int key, char *arg, + struct argp_state *state)); struct argp mu_common_argp = { @@ -101,10 +114,47 @@ struct argp mu_common_argp = NULL }; -struct argp_child mu_common_argp_child[] = +struct argp_child mu_common_argp_child = { + &mu_common_argp, + 0, + "Common mailutils options", + 1 +}; + +struct argp mu_auth_argp = +{ + mu_auth_argp_option, + mu_common_argp_parser, + "", + "", + NULL, + NULL, + NULL +}; + +struct argp_child mu_auth_argp_child = { + &mu_auth_argp, + 0, + "Authentication-relevant options", + 1 +}; + +struct argp mu_logging_argp = { - {&mu_common_argp, 0, "Common mailutils options", 1}, - {NULL, 0, NULL, 0} + mu_logging_argp_option, + mu_common_argp_parser, + "", + "", + NULL, + NULL, + NULL +}; + +struct argp_child mu_logging_argp_child = { + &mu_logging_argp, + 0, + "Logging options", + 1 }; struct argp mu_daemon_argp = @@ -118,11 +168,11 @@ struct argp mu_daemon_argp = NULL }; -struct argp_child mu_daemon_argp_child[] = -{ - {&mu_daemon_argp, 0, "Daemon configuration options", 1}, - {&mu_common_argp, 0, "Common mailutils options", 2}, - {NULL, 0, NULL, 0} +struct argp_child mu_daemon_argp_child = { + &mu_daemon_argp, + 0, + "Daemon configuration options", + 1 }; int log_facility = LOG_FACILITY; @@ -147,6 +197,7 @@ parse_log_facility (const char *str) { "LOCAL5", LOG_LOCAL5 }, { "LOCAL6", LOG_LOCAL6 }, { "LOCAL7", LOG_LOCAL7 }, + { "MAIL", LOG_MAIL } }; if (strncmp (str, "LOG_", 4) == 0) @@ -310,8 +361,19 @@ mu_daemon_argp_parser (int key, char *arg, struct argp_state *state) # define MU_CONFIG_FILE SYSCONFDIR "/mailutils.rc" #endif +static int +member (const char *array[], const char *text, size_t len) +{ + int i; + for (i = 0; array[i]; i++) + if (strncmp (array[i], text, len) == 0) + return 1; + return 0; +} + void -mu_create_argcv (int argc, char **argv, int *p_argc, char ***p_argv) +mu_create_argcv (const char *capa[], + int argc, char **argv, int *p_argc, char ***p_argv) { FILE *fp; char *progname; @@ -393,8 +455,9 @@ mu_create_argcv (int argc, char **argv, int *p_argc, char ***p_argv) for (p = kwp; *p && !isspace (*p); p++) len++; - if (strncmp ("mailutils", kwp, len) == 0 - || strncmp (progname, kwp, len) == 0) + if ((kwp[0] == ':' + && member (capa, kwp+1, len-1)) + || strncmp (progname, kwp, len) == 0) { int n_argc = 0; char **n_argv; @@ -437,3 +500,92 @@ mu_create_argcv (int argc, char **argv, int *p_argc, char ***p_argv) *p_argc = x_argc; *p_argv = x_argv; } + +struct argp_capa { + char *capability; + struct argp_child *child; +} mu_argp_capa[] = { + {"mailutils", &mu_common_argp_child}, + {"daemon", &mu_daemon_argp_child}, + {"auth", &mu_auth_argp_child}, + {"logging", &mu_logging_argp_child}, + {NULL,} +}; + +static struct argp_child * +find_argp_child (const char *capa) +{ + int i; + for (i = 0; mu_argp_capa[i].capability; i++) + if (strcmp (mu_argp_capa[i].capability, capa) == 0) + return mu_argp_capa[i].child; + return NULL; +} + +static struct argp * +mu_build_argp (const struct argp *template, const char *capa[]) +{ + int n; + struct argp_child *ap; + struct argp *argp; + + /* Count the capabilities */ + for (n = 0; capa[n]; n++) + ; + if (template->children) + for (; template->children[n].argp; n++) + ; + + ap = calloc (n + 1, sizeof (*ap)); + if (!ap) + { + mu_error ("out of memory"); + abort (); + } + + n = 0; + if (template->children) + for (; template->children[n].argp; n++) + ap[n] = template->children[n]; + + for (; capa[n]; n++) + { + struct argp_child *tmp = find_argp_child (capa[n]); + if (!tmp) + { + mu_error ("INTERNAL ERROR: requested unknown argp capability %s", + capa[n]); + continue; + } + ap[n] = *tmp; + ap[n].group = n; + } + ap[n].argp = NULL; + argp = malloc (sizeof (*argp)); + if (!argp) + { + mu_error ("out of memory"); + abort (); + } + memcpy (argp, template, sizeof (*argp)); + argp->children = ap; + return argp; +} + +error_t +mu_argp_parse(const struct argp *argp, + int *pargc, char **pargv[], + unsigned flags, + const char *capa[], + int *arg_index, + void *input) +{ + error_t ret; + + argp = mu_build_argp (argp, capa); + mu_create_argcv (capa, *pargc, *pargv, pargc, pargv); + ret = argp_parse (argp, *pargc, *pargv, flags, arg_index, input); + free ((void*) argp->children); + free ((void*) argp); + return ret; +} |