summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2002-03-08 22:43:22 +0000
committerSergey Poznyakoff <gray@gnu.org.ua>2002-03-08 22:43:22 +0000
commit8e6ef8728b9e2fba89e779fc1c43a370e3ebe908 (patch)
tree81d1fd4becc505a8b0a34d4dc7967c1e06398bef /lib
parent1a7126d9c0a2292a3f02621a244e64e212bd01cb (diff)
downloadmailutils-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.c180
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;
+}

Return to:

Send suggestions and report system problems to the System administrator.