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
2002-03-09 Sergey Poznyakoff
* configure.in: Check for libresolv.
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 a capability name appears in configuration file, it
should be prefixed with : to discern it from the utility
name.
* examples/mailutils.rc: Updated to reflect changes in the syntax.
* lib/mu_argp.c: New function mu_argp_parse is intended to be used
by all programs in the package in order to do command line parsing.
* lib/mu_argp.h: Removed unneeded prototypes. Added prototype for
mu_argp_parse().
* comsat/comsat.c: Use mu_argp_parse.
* frm/frm.c: Likewise.
* guimb/main.c: Likewise.
* imap4d/imap4d.c: Likewise.
* mail/mail.c: Likewise.
* messages/messages.c: Likewise.
* pop3d/pop3d.c: Likewise.
* mail.local/main.c: Likewise.
(deliver): Restored erroneously removed variable sb.
* pop3d/apop.c (pop3d_apopuser): Changed scope of auto variable
rc.
2002-03-01 Sam Roberts
* mailbox/mbx_mboxscan.c: Check return value of locker_lock().
......
......@@ -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;
}
......