summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2002-02-05 15:00:18 +0000
committerSergey Poznyakoff <gray@gnu.org.ua>2002-02-05 15:00:18 +0000
commitbd9966ede4a26ac0cb7cd633cc3bdd8d32430a58 (patch)
tree83e6c4b2435dff46f1497e19707af2a0e5c7460c
parent1a2e2bad733b8f9863df21238bad3f6a3fe7d245 (diff)
downloadmailutils-bd9966ede4a26ac0cb7cd633cc3bdd8d32430a58.tar.gz
mailutils-bd9966ede4a26ac0cb7cd633cc3bdd8d32430a58.tar.bz2
Handle command line arguments, common for all mailutils programs.
-rw-r--r--lib/mu_argp.c404
-rw-r--r--lib/mu_argp.h21
2 files changed, 425 insertions, 0 deletions
diff --git a/lib/mu_argp.c b/lib/mu_argp.c
new file mode 100644
index 000000000..49404104f
--- /dev/null
+++ b/lib/mu_argp.c
@@ -0,0 +1,404 @@
+/* GNU mailutils - a suite of utilities for electronic mail
+ Copyright (C) 1999, 2001 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <syslog.h>
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#include <argcv.h>
+#include <mu_argp.h>
+#ifdef HAVE_MYSQL
+# include "../MySql/MySql.h"
+#endif
+
+#define ARG_LOG_FACILITY 1
+#define ARG_SQL_GETPWNAM 2
+#define ARG_SQL_GETPASS 3
+#define ARG_SQL_HOST 4
+#define ARG_SQL_USER 5
+#define ARG_SQL_PASSWD 6
+#define ARG_SQL_DB 7
+#define ARG_SQL_PORT 8
+
+static struct argp_option mu_common_argp_option[] =
+{
+ {"maildir", 'm', "URL", 0,
+ "use specified URL as a mailspool directory", 0},
+ {"log-facility", ARG_LOG_FACILITY, "FACILITY", 0,
+ "output logs to syslog FACILITY", 0},
+ { "license", 'L', NULL, 0, "print license and exit", 0 },
+#ifdef HAVE_MYSQL
+ {"sql-getpwnam", ARG_SQL_GETPWNAM, "QUERY", 0,
+ "SQL query to retrieve a passwd entry from the database", 0},
+ {"sql-getpass", ARG_SQL_GETPASS, "QUERY", 0,
+ "SQL query to retrieve a password from the database", 0},
+ {"sql-host", ARG_SQL_HOST, "HOSTNAME", 0,
+ "Name or IP of MySQL server to connect to", 0},
+ {"sql-user", ARG_SQL_USER, "NAME", 0,
+ "SQL user name", 0},
+ {"sql-passwd", ARG_SQL_PASSWD, "STRING", 0,
+ "SQL connection password", 0},
+ {"sql-db", ARG_SQL_DB, "STRING", 0,
+ "name of the database to connect to", 0},
+ {"sql-port", ARG_SQL_PORT, "NUMBER", 0,
+ "port to use", 0},
+#endif
+ { NULL, 0, NULL, 0, NULL, 0 }
+};
+
+static struct argp_option mu_daemon_argp_option[] =
+{
+ {"daemon", 'd', "NUMBER", OPTION_ARG_OPTIONAL,
+ "runs in daemon mode with a maximum of NUMBER children"},
+ {"inetd", 'i', 0, 0,
+ "run in inetd mode", 0},
+ {"port", 'p', "PORT", 0,
+ "listen on specified port number", 0},
+ {"timeout", 't', "NUMBER", 0,
+ "set idle timeout value to NUMBER seconds", 0},
+ { 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);
+
+struct argp mu_common_argp =
+{
+ mu_common_argp_option,
+ mu_common_argp_parser,
+ "",
+ "",
+ NULL,
+ NULL,
+ NULL
+};
+
+struct argp_child mu_common_argp_child[] =
+{
+ {&mu_common_argp, 0, "Common mailutils options", 1},
+ {NULL, 0, NULL, 0}
+};
+
+struct argp mu_daemon_argp =
+{
+ mu_daemon_argp_option,
+ mu_daemon_argp_parser,
+ "",
+ "",
+ NULL,
+ NULL,
+ 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}
+};
+
+char *maildir = MU_PATH_MAILDIR;
+int log_facility = LOG_FACILITY;
+
+static int
+parse_log_facility (const char *str)
+{
+ int i;
+ static struct {
+ char *name;
+ int facility;
+ } syslog_kw[] = {
+ { "USER", LOG_USER },
+ { "DAEMON", LOG_DAEMON },
+ { "AUTH", LOG_AUTH },
+ { "LOCAL0", LOG_LOCAL0 },
+ { "LOCAL1", LOG_LOCAL1 },
+ { "LOCAL2", LOG_LOCAL2 },
+ { "LOCAL3", LOG_LOCAL3 },
+ { "LOCAL4", LOG_LOCAL4 },
+ { "LOCAL5", LOG_LOCAL5 },
+ { "LOCAL6", LOG_LOCAL6 },
+ { "LOCAL7", LOG_LOCAL7 },
+ };
+
+ if (strncmp (str, "LOG_", 4) == 0)
+ str += 4;
+
+ for (i = 0; i < sizeof (syslog_kw) / sizeof (syslog_kw[0]); i++)
+ if (strcasecmp (syslog_kw[i].name, str) == 0)
+ return syslog_kw[i].facility;
+ fprintf (stderr, "unknown facility `%s'\n", str);
+ return LOG_FACILITY;
+}
+
+static char license_text[] =
+ " This program is free software; you can redistribute it and/or modify\n"
+ " it under the terms of the GNU General Public License as published by\n"
+ " the Free Software Foundation; either version 2, or (at your option)\n"
+ " any later version.\n"
+ "\n"
+ " This program is distributed in the hope that it will be useful,\n"
+ " but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+ " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+ " GNU General Public License for more details.\n"
+ "\n"
+ " You should have received a copy of the GNU General Public License\n"
+ " along with this program; if not, write to the Free Software\n"
+ " Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n";
+
+#ifdef HAVE_MYSQL
+char *sql_getpwnam_query;
+char *sql_getpass_query;
+char *sql_host = MHOST;
+char *sql_user = MUSER;
+char *sql_passwd = MPASS;
+char *sql_db = MDB;
+char *sql_socket = MSOCKET;
+int sql_port = MPORT;
+#endif
+
+static error_t
+mu_common_argp_parser (int key, char *arg, struct argp_state *state)
+{
+ switch (key)
+ {
+ case 'm':
+ maildir = arg;
+ break;
+
+ case 'L':
+ printf ("%s", license_text);
+ exit (0);
+
+ case ARG_LOG_FACILITY:
+ log_facility = parse_log_facility (arg);
+ break;
+
+#ifdef HAVE_MYSQL
+ case ARG_SQL_GETPWNAM:
+ sql_getpwnam_query = arg;
+ break;
+
+ case ARG_SQL_GETPASS:
+ sql_getpass_query = arg;
+ break;
+
+ case ARG_SQL_HOST:
+ sql_host = arg;
+ break;
+
+ case ARG_SQL_USER:
+ sql_user = arg;
+ break;
+
+ case ARG_SQL_PASSWD:
+ sql_passwd = arg;
+ break;
+
+ case ARG_SQL_DB:
+ sql_db = arg;
+ break;
+
+ case ARG_SQL_PORT:
+ sql_port = strtoul (arg, NULL, 0);
+ if (sql_port == 0)
+ {
+ sql_host = NULL;
+ sql_socket = arg;
+ }
+ break;
+
+#endif
+ default:
+ return ARGP_ERR_UNKNOWN;
+ }
+ return 0;
+}
+
+static error_t
+mu_daemon_argp_parser (int key, char *arg, struct argp_state *state)
+{
+ struct daemon_param *p = state->input;
+ if (!p)
+ return ARGP_ERR_UNKNOWN;
+ switch (key)
+ {
+ case 'd':
+ p->mode = MODE_DAEMON;
+ if (arg)
+ {
+ size_t n = strtoul (arg, NULL, 10);
+ if (n > 0)
+ p->maxchildren = n;
+ }
+ break;
+
+ case 'i':
+ p->mode = MODE_INTERACTIVE;
+ break;
+
+ case 'p':
+ p->mode = MODE_DAEMON;
+ p->port = strtoul (arg, NULL, 10);
+ break;
+
+ case 't':
+ p->timeout = strtoul (arg, NULL, 10);
+ break;
+
+ default:
+ return ARGP_ERR_UNKNOWN;
+ }
+ return 0;
+}
+
+#ifndef MU_CONFIG_FILE
+# define MU_CONFIG_FILE SYSCONFDIR "/mailutils.rc"
+#endif
+
+void
+mu_create_argcv (int argc, char **argv, int *p_argc, char ***p_argv)
+{
+ FILE *fp;
+ char *progname;
+ int x_argc;
+ char **x_argv;
+ int i;
+
+ progname = strrchr (argv[0], '/');
+ if (progname)
+ progname++;
+ else
+ progname = argv[0];
+
+ x_argv = malloc ((argc + 1) * sizeof (x_argv[0]));
+ if (!x_argv)
+ {
+ fprintf (stderr, "%s: not enough memory\n", progname);
+ exit (1);
+ }
+
+ /* Add command name */
+ x_argc = 0;
+ x_argv[x_argc] = argv[x_argc];
+ x_argc++;
+
+ /* Process the mailutils.rc file */
+ fp = fopen (MU_CONFIG_FILE, "r");
+ if (fp)
+ {
+ char *linebuf = NULL;
+ char *buf = NULL;
+ size_t n = 0;
+
+ while (getline (&buf, &n, fp) > 0)
+ {
+ char *kwp, *p;
+ int len;
+
+ for (kwp = buf; *kwp && isspace (*kwp); kwp++)
+ ;
+
+ if (*kwp == '#' || *kwp == 0)
+ continue;
+
+ len = strlen (kwp);
+ if (kwp[len-1] == '\n')
+ kwp[--len] = 0;
+
+ if (kwp[len-1] == '\\' || linebuf)
+ {
+ int cont;
+
+ if (kwp[len-1] == '\\')
+ {
+ kwp[--len] = 0;
+ cont = 1;
+ }
+ else
+ cont = 0;
+
+ if (!linebuf)
+ linebuf = calloc (len + 1, 1);
+ else
+ linebuf = realloc (linebuf, strlen (linebuf) + len + 1);
+
+ if (!linebuf)
+ {
+ fprintf (stderr, "%s: not enough memory\n", progname);
+ exit (1);
+ }
+
+ strcpy (linebuf + strlen (linebuf), kwp);
+ if (cont)
+ continue;
+ kwp = linebuf;
+ }
+
+ len = 0;
+ for (p = kwp; *p && !isspace (*p); p++)
+ len++;
+
+ if (strncmp ("mailutils", kwp, len) == 0
+ || strncmp (progname, kwp, len) == 0)
+ {
+ int n_argc = 0;
+ char **n_argv;
+
+ if (argcv_get (p, "", &n_argc, &n_argv))
+ {
+ argcv_free (n_argc, n_argv);
+ if (linebuf)
+ free (linebuf);
+ linebuf = NULL;
+ continue;
+ }
+ x_argv = realloc (x_argv,
+ (x_argc + n_argc + 1) * sizeof (x_argv[0]));
+ if (!x_argv)
+ {
+ fprintf (stderr, "%s: not enough memory\n", progname);
+ exit (1);
+ }
+
+ for (i = 0; i < n_argc; i++)
+ x_argv[x_argc++] = n_argv[i];
+
+ free (n_argv);
+ if (linebuf)
+ free (linebuf);
+ linebuf = NULL;
+ }
+ }
+ fclose (fp);
+ }
+
+ /* Finally, add the command line options */
+ for (i = 1; i < argc; i++)
+ x_argv[x_argc++] = argv[i];
+
+ x_argv[x_argc] = NULL;
+
+ *p_argc = x_argc;
+ *p_argv = x_argv;
+}
diff --git a/lib/mu_argp.h b/lib/mu_argp.h
new file mode 100644
index 000000000..14d96b7a3
--- /dev/null
+++ b/lib/mu_argp.h
@@ -0,0 +1,21 @@
+#include <argp.h>
+
+#define MODE_INTERACTIVE 0
+#define MODE_DAEMON 1
+
+struct daemon_param {
+ int mode;
+ size_t maxchildren;
+ unsigned int port;
+ unsigned int timeout;
+};
+
+
+extern char *maildir;
+extern int log_facility;
+extern struct argp_child mu_common_argp_child[];
+extern struct argp_child mu_daemon_argp_child[];
+
+extern void mu_create_argcv (int argc, char **argv,
+ int *p_argc, char ***p_argv);
+

Return to:

Send suggestions and report system problems to the System administrator.