summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2016-10-16 10:52:21 +0300
committerSergey Poznyakoff <gray@gnu.org>2016-10-16 10:53:13 +0300
commitf2279f27831f79d036ceab51e093250546f8b9d1 (patch)
tree39bc6c44fbace859e77b7e62bb75bd402901de3a
parente3840467baf287cc14177d224dddc282674f1609 (diff)
downloadmailutils-f2279f27831f79d036ceab51e093250546f8b9d1.tar.gz
mailutils-f2279f27831f79d036ceab51e093250546f8b9d1.tar.bz2
Convert comsat to mu_cli
-rw-r--r--comsat/Makefile.am2
-rw-r--r--comsat/comsat.c165
-rw-r--r--libmailutils/cli/Makefile.am1
-rw-r--r--libmailutils/cli/acl.c267
4 files changed, 344 insertions, 91 deletions
diff --git a/comsat/Makefile.am b/comsat/Makefile.am
index e67b21848..a661ffe11 100644
--- a/comsat/Makefile.am
+++ b/comsat/Makefile.am
@@ -31,7 +31,7 @@ biff.rc.h: $(top_srcdir)/comsat/biff.rc
$(top_srcdir)/comsat/biff.rc > biff.rc.h
comsatd_LDADD = \
- ${MU_APP_LIBRARIES}\
+ ${MU_APP_NEW_LIBRARIES}\
${MU_LIB_MBOX}\
${MU_LIB_IMAP}\
${MU_LIB_POP}\
diff --git a/comsat/comsat.c b/comsat/comsat.c
index 0911a3729..c12ed2082 100644
--- a/comsat/comsat.c
+++ b/comsat/comsat.c
@@ -18,7 +18,7 @@
#include "comsat.h"
#define MU_CFG_COMPATIBILITY /* This source uses deprecated cfg interfaces */
#include "mailutils/libcfg.h"
-#include "mailutils/libargp.h"
+#include "mailutils/cli.h"
#ifndef PATH_DEV
# define PATH_DEV "/dev"
@@ -59,44 +59,62 @@ typedef struct utmp UTMP;
#define MAX_TTY_SIZE (sizeof (PATH_TTY_PFX) + sizeof (((UTMP*)0)->ut_line))
const char *program_version = "comsatd (" PACKAGE_STRING ")";
-static char doc[] = N_("GNU comsatd -- notify users about incoming mail");
-static char args_doc[] = N_("\n--test MBOX-URL MSG-QID");
-#define OPT_FOREGROUND 256
+int test_mode;
+char *biffrc = BIFF_RC;
+mu_m_server_t server;
-static struct argp_option options[] =
+static void
+set_inetd_mode (struct mu_parseopt *po, struct mu_option *opt,
+ char const *arg)
{
- { "test", 't', NULL, 0, N_("run in test mode"), 0 },
- { "foreground", OPT_FOREGROUND, 0, 0, N_("remain in foreground"), 0},
- { "inetd", 'i', 0, 0, N_("run in inetd mode"), 0 },
- { "daemon", 'd', N_("NUMBER"), OPTION_ARG_OPTIONAL,
- N_("runs in daemon mode with a maximum of NUMBER children"), 0 },
- { "file", 'f', N_("FILE"), 0,
- N_("read FILE instead of .biffrc"), 0 },
- { NULL, 0, NULL, 0, NULL, 0 }
-};
-
-static error_t comsatd_parse_opt (int key, char *arg,
- struct argp_state *state);
+ mu_m_server_set_mode (server, MODE_INTERACTIVE);
+}
+
+static void
+set_daemon_mode (struct mu_parseopt *po, struct mu_option *opt,
+ char const *arg)
+{
+ mu_m_server_set_mode (server, MODE_DAEMON);
+ if (arg)
+ {
+ size_t max_children;
+ char *errmsg;
+ int rc = mu_str_to_c (arg, mu_c_size, &max_children, &errmsg);
+ if (rc)
+ {
+ mu_parseopt_error (po, _("%s: bad argument"), arg);
+ exit (po->po_exit_error);
+ }
+ mu_m_server_set_max_children (server, max_children);
+ }
+}
-static struct argp argp = {
- options,
- comsatd_parse_opt,
- args_doc,
- doc,
- NULL,
- NULL, NULL
-};
+static void
+set_foreground (struct mu_parseopt *po, struct mu_option *opt,
+ char const *arg)
+{
+ mu_m_server_set_foreground (server, 1);
+}
-static const char *comsat_argp_capa[] = {
- "mailutils",
- "common",
- "debug",
- "logging",
- "mailbox",
- "locking",
- NULL
-};
+static struct mu_option comsat_options[] = {
+ { "test", 't', NULL, MU_OPTION_DEFAULT,
+ N_("run in test mode"),
+ mu_c_bool, &test_mode },
+ { "foreground", 0, NULL, MU_OPTION_DEFAULT,
+ N_("remain in foreground"),
+ mu_c_bool, NULL, set_foreground },
+ { "inetd", 'i', NULL, MU_OPTION_DEFAULT,
+ N_("run in inetd mode"),
+ mu_c_bool, NULL, set_inetd_mode },
+ { "daemon", 'd', N_("NUMBER"), MU_OPTION_ARG_OPTIONAL,
+ N_("runs in daemon mode with a maximum of NUMBER children"),
+ mu_c_string, NULL, set_daemon_mode },
+ { "file", 'f', N_("FILE"), MU_OPTION_DEFAULT,
+ N_("read FILE instead of .biffrc"),
+ mu_c_string, &biffrc },
+ MU_OPTION_END
+}, *options[] = { comsat_options, NULL };
#define SUCCESS 0
#define NOT_HERE 1
@@ -107,7 +125,6 @@ char *hostname;
const char *username;
int require_tty;
int biffrc_errors = BIFFRC_ERRORS_TO_TTY | BIFFRC_ERRORS_TO_ERR;
-mu_m_server_t server;
static void comsat_init (void);
static int comsat_main (int fd);
@@ -118,9 +135,6 @@ static char *mailbox_path (const char *user);
static int change_user (const char *user);
static int reload = 0;
-int test_mode;
-char *biffrc = BIFF_RC;
-
static int
biffrc_error_ctl (mu_config_value_t *val, int flag)
{
@@ -171,55 +185,30 @@ struct mu_cfg_param comsat_cfg_param[] = {
0, NULL,
N_("Set overflow control interval.") },
{ "overflow-delay-time", mu_c_time, &overflow_delay_time,
- 0, NULL,
+ 0, NULL,
N_("Time to sleep after the first overflow occurs.") },
{ ".server", mu_cfg_section, NULL, 0, NULL,
N_("Server configuration.") },
{ NULL }
};
-static error_t
-comsatd_parse_opt (int key, char *arg, struct argp_state *state)
-{
- static mu_list_t lst;
-
- switch (key)
- {
- case 'd':
- mu_argp_node_list_new (lst, "mode", "daemon");
- if (arg)
- mu_argp_node_list_new (lst, "max-children", arg);
- break;
-
- case 'f':
- biffrc = arg;
- break;
-
- case 'i':
- mu_argp_node_list_new (lst, "mode", "inetd");
- break;
+static char const *alt_args[] = { N_("--test MBOX-URL MSG-QID"), NULL };
- case OPT_FOREGROUND:
- mu_argp_node_list_new (lst, "foreground", "yes");
- break;
-
- case 't':
- test_mode = 1;
- break;
-
- case ARGP_KEY_INIT:
- mu_argp_node_list_init (&lst);
- break;
-
- case ARGP_KEY_FINI:
- mu_argp_node_list_finish (lst, NULL, NULL);
- break;
+static struct mu_cli_setup cli = {
+ options,
+ comsat_cfg_param,
+ N_("GNU comsatd -- notify users about incoming mail"),
+ "",
+ alt_args,
+};
- default:
- return ARGP_ERR_UNKNOWN;
- }
- return 0;
-}
+static char *capa[] = {
+ "debug",
+ "logging",
+ "mailbox",
+ "locking",
+ NULL
+};
static RETSIGTYPE
sig_hup (int sig)
@@ -558,12 +547,11 @@ int
main (int argc, char **argv)
{
int c;
- int ind;
-
+ char **save_argv;
+
/* Native Language Support */
MU_APP_INIT_NLS ();
- mu_argp_init (NULL, NULL);
comsat_init ();
mu_acl_cfg_init ();
mu_m_server_create (&server, program_version);
@@ -578,19 +566,16 @@ main (int argc, char **argv)
/* FIXME: timeout is not needed. How to disable it? */
mu_log_syslog = 1;
+
+ save_argv = argv;
- if (mu_app_init (&argp, comsat_argp_capa, comsat_cfg_param, argc, argv, 0,
- &ind, server))
- exit (EXIT_FAILURE);
+ mu_cli (argc, argv, &cli, capa, NULL, &argc, &argv);
if (test_mode)
{
struct passwd *pw;
char *user;
- argc -= ind;
- argv += ind;
-
mu_stdstream_strerr_setup (MU_STRERR_STDERR);
biffrc_errors = BIFFRC_ERRORS_TO_ERR;
if (argc < 2 || argc > 2)
@@ -630,7 +615,7 @@ main (int argc, char **argv)
if (mu_m_server_mode (server) == MODE_DAEMON)
{
- if (argv[0][0] != '/')
+ if (save_argv[0][0] != '/')
mu_diag_output (MU_DIAG_NOTICE,
_("program name is not absolute; reloading will not "
"be possible"));
@@ -651,7 +636,7 @@ main (int argc, char **argv)
if (reload)
{
mu_diag_output (MU_DIAG_NOTICE, _("restarting"));
- execvp (argv[0], argv);
+ execvp (save_argv[0], save_argv);
}
}
else
diff --git a/libmailutils/cli/Makefile.am b/libmailutils/cli/Makefile.am
index 48770e844..e506b9105 100644
--- a/libmailutils/cli/Makefile.am
+++ b/libmailutils/cli/Makefile.am
@@ -18,6 +18,7 @@
noinst_LTLIBRARIES = libcli.la
libcli_la_SOURCES = \
+ acl.c\
capa.c\
cli.c\
stdcapa.c
diff --git a/libmailutils/cli/acl.c b/libmailutils/cli/acl.c
new file mode 100644
index 000000000..778c3f52c
--- /dev/null
+++ b/libmailutils/cli/acl.c
@@ -0,0 +1,267 @@
+/* This file is part of GNU Mailutils
+ Copyright (C) 2007-2012, 2014-2016 Free Software Foundation, Inc.
+
+ GNU Mailutils 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 3, or (at
+ your option) any later version.
+
+ GNU Mailutils 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 GNU Mailutils. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include "mailutils/acl.h"
+#include "mailutils/argcv.h"
+#include "mailutils/cidr.h"
+#include "mailutils/cfg.h"
+#include "mailutils/errno.h"
+#include "mailutils/nls.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#define ISSPACE(c) ((c)==' '||(c)=='\t')
+
+#define SKIPWS(p) while (*(p) && ISSPACE (*(p))) (p)++;
+
+static const char *
+getword (mu_config_value_t *val, int *pn)
+{
+ int n = (*pn)++;
+ mu_config_value_t *v;
+
+ if (n >= val->v.arg.c)
+ {
+ mu_error (_("not enough arguments"));
+ return NULL;
+ }
+ v = &val->v.arg.v[n];
+ if (mu_cfg_assert_value_type (v, MU_CFG_STRING))
+ return NULL;
+ return v->v.string;
+}
+
+static int
+parsearg (mu_config_value_t *val, struct mu_cidr *cidr, char **prest)
+{
+ const char *w;
+ int n = 0;
+ int rc;
+
+ if (mu_cfg_assert_value_type (val, MU_CFG_ARRAY))
+ return 1;
+
+ w = getword (val, &n);
+ if (!w)
+ return 1;
+ if (strcmp (w, "from") == 0) {
+ w = getword (val, &n);
+ if (!w)
+ return 1;
+ }
+
+ if (strcmp (w, "any") == 0)
+ cidr->len = 0;
+ else
+ {
+ rc = mu_cidr_from_string (cidr, w);
+ if (rc)
+ {
+ mu_error (_("invalid source CIDR: %s"), mu_strerror (rc));
+ return 1;
+ }
+ }
+
+ if (prest)
+ {
+ if (n == val->v.arg.c)
+ *prest = NULL;
+ else
+ {
+ size_t size = 0;
+ int i;
+ char *buf;
+
+ for (i = n; i < val->v.arg.c; i++)
+ {
+ if (mu_cfg_assert_value_type (&val->v.arg.v[i], MU_CFG_STRING))
+ return 1;
+ size += strlen (val->v.arg.v[i].v.string) + 1;
+ }
+
+ buf = malloc (size);
+ if (!buf)
+ {
+ mu_error ("%s", mu_strerror (errno));
+ return 1;
+ }
+
+ *prest = buf;
+ for (i = n; i < val->v.arg.c; i++)
+ {
+ if (i > n)
+ *buf++ = ' ';
+ strcpy (buf, val->v.arg.v[i].v.string);
+ buf += strlen (buf);
+ }
+ *buf = 0;
+ }
+ }
+ else if (n != val->v.arg.c)
+ {
+ mu_error (_("junk after IP address"));
+ return 1;
+ }
+ return 0;
+}
+
+static int
+cb_allow (void *data, mu_config_value_t *val)
+{
+ int rc;
+ mu_acl_t acl = *(mu_acl_t*)data;
+ struct mu_cidr cidr;
+
+ if (parsearg (val, &cidr, NULL))
+ return 1;
+ rc = mu_acl_append (acl, mu_acl_accept, NULL, &cidr);
+ if (rc)
+ mu_error (_("cannot append acl entry: %s"), mu_strerror (rc));
+ return rc;
+}
+
+static int
+cb_deny (void *data, mu_config_value_t *val)
+{
+ int rc;
+ mu_acl_t acl = *(mu_acl_t*)data;
+ struct mu_cidr cidr;
+
+ if (parsearg (val, &cidr, NULL))
+ return 1;
+ rc = mu_acl_append (acl, mu_acl_deny, NULL, &cidr);
+ if (rc)
+ mu_error (_("cannot append acl entry: %s"), mu_strerror (rc));
+ return rc;
+}
+
+static int
+cb_log (void *data, mu_config_value_t *val)
+{
+ int rc;
+ mu_acl_t acl = *(mu_acl_t*)data;
+ struct mu_cidr cidr;
+ char *rest;
+
+ if (parsearg (val, &cidr, &rest))
+ return 1;
+ rc = mu_acl_append (acl, mu_acl_log, rest, &cidr);
+ if (rc)
+ mu_error (_("cannot append acl entry: %s"), mu_strerror (rc));
+ return rc;
+}
+
+static int
+cb_exec (void *data, mu_config_value_t *val)
+{
+ int rc;
+ mu_acl_t acl = *(mu_acl_t*)data;
+ struct mu_cidr cidr;
+ char *rest;
+
+ if (parsearg (val, &cidr, &rest))
+ return 1;
+ rc = mu_acl_append (acl, mu_acl_exec, rest, &cidr);
+ if (rc)
+ mu_error (_("cannot append acl entry: %s"), mu_strerror (rc));
+ return rc;
+}
+
+static int
+cb_ifexec (void *data, mu_config_value_t *val)
+{
+ int rc;
+ mu_acl_t acl = *(mu_acl_t*)data;
+ struct mu_cidr cidr;
+ char *rest;
+
+ if (parsearg (val, &cidr, &rest))
+ return 1;
+ rc = mu_acl_append (acl, mu_acl_ifexec, rest, &cidr);
+ if (rc)
+ mu_error (_("cannot append acl entry: %s"), mu_strerror (rc));
+ return rc;
+}
+
+static struct mu_cfg_param acl_param[] = {
+ { "allow", mu_cfg_callback, NULL, 0, cb_allow,
+ N_("Allow connections from this IP address. Optional word `from' is "
+ "allowed between it and its argument. The same holds true for other "
+ "actions below."),
+ N_("addr: IP") },
+ { "deny", mu_cfg_callback, NULL, 0, cb_deny,
+ N_("Deny connections from this IP address."),
+ N_("addr: IP") },
+ { "log", mu_cfg_callback, NULL, 0, cb_log,
+ N_("Log connections from this IP address."),
+ N_("addr: IP") },
+ { "exec", mu_cfg_callback, NULL, 0, cb_exec,
+ N_("Execute supplied program if a connection from this IP address is "
+ "requested. Arguments are:\n"
+ " <addr: IP> <program: string>\n"
+ "Following macros are expanded in <program> before executing:\n"
+ " address - Source IP address\n"
+ " port - Source port number\n") },
+ { "ifexec", mu_cfg_callback, NULL, 0, cb_ifexec,
+ N_("If a connection from this IP address is requested, execute supplied "
+ "program and allow or deny the connection depending on its exit code. "
+ "See `exec' for a description of its arguments.") },
+ { NULL }
+};
+
+static int
+acl_section_parser (enum mu_cfg_section_stage stage,
+ const mu_cfg_node_t *node,
+ const char *section_label, void **section_data,
+ void *call_data,
+ mu_cfg_tree_t *tree)
+{
+ switch (stage)
+ {
+ case mu_cfg_section_start:
+ {
+ void *data = *section_data;
+ mu_acl_create ((mu_acl_t*)data);
+ }
+ break;
+
+ case mu_cfg_section_end:
+ break;
+ }
+ return 0;
+}
+
+void
+mu_acl_cfg_init (void)
+{
+ struct mu_cfg_section *section;
+ if (mu_create_canned_section ("acl", &section) == 0)
+ {
+ section->parser = acl_section_parser;
+ mu_cfg_section_add_params (section, acl_param);
+ }
+}

Return to:

Send suggestions and report system problems to the System administrator.