aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac2
-rw-r--r--lib/Makefile.am1
-rw-r--r--lib/dbcfg.c12
-rw-r--r--lib/libmf.h35
-rw-r--r--lib/optcache.c182
-rw-r--r--lib/utils.c48
-rw-r--r--src/builtin/dns.bi6
-rw-r--r--src/builtin/io.bi2
-rw-r--r--src/builtin/mbox.bi2
-rw-r--r--src/builtin/msg.bi2
-rw-r--r--src/main.c723
-rw-r--r--src/mfdbtool.c12
-rw-r--r--src/savsrv.c3
-rw-r--r--src/srvcfg.c456
-rw-r--r--src/srvcfg.h2
15 files changed, 559 insertions, 929 deletions
diff --git a/configure.ac b/configure.ac
index 8275a927..73713291 100644
--- a/configure.ac
+++ b/configure.ac
@@ -109,7 +109,7 @@ AH_BOTTOM([
])
# Check for GNU Mailutils
-AM_GNU_MAILUTILS([2.99.99], [all auth dbm sieve cfg argp], [:])
+AM_GNU_MAILUTILS([2.99.991], [all auth dbm sieve], [:])
AC_CHECK_TYPES([struct mu_argp_node_list],,,[#include <mailutils/libargp.h>])
### Check for Emacs site-lisp directory
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 4930d4bb..7df87557 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -36,7 +36,6 @@ libmf_a_SOURCES=\
logger.c\
namefixup.c\
nls.c\
- optcache.c\
parsetime.c\
proctitle.c\
server.c\
diff --git a/lib/dbcfg.c b/lib/dbcfg.c
index c6682fb6..60a46fd2 100644
--- a/lib/dbcfg.c
+++ b/lib/dbcfg.c
@@ -84,19 +84,21 @@ struct mu_cfg_param database_section_param[] = {
{ "file", mu_cfg_callback, NULL,
offsetof(struct db_format, dbname), cb_database_file,
N_("Name of the database file") },
- { "enable", mu_cfg_bool, NULL, offsetof(struct db_format, enabled), NULL,
+ { "enable", mu_c_bool, NULL, offsetof(struct db_format, enabled), NULL,
N_("Enable or disable the database") },
{ "expire-interval", mu_cfg_callback, NULL,
offsetof(struct db_format, expire_interval), cb_db_expire_interval,
- N_("Set database record expiration interval") },
-
+ N_("Set database record expiration interval"),
+ N_("arg: interval") },
{ "positive-expire-interval", mu_cfg_callback, NULL, 0,
cb_db_positive_expire_interval,
- N_("Set positive expiration interval (for database \"cache\" only)") },
+ N_("Set positive expiration interval (for database \"cache\" only)"),
+ N_("arg: interval") },
{ "negative-expire-interval", mu_cfg_callback, NULL, 0,
cb_db_negative_expire_interval,
N_("Set negative expiration interval "
- "(for database id \"cache\")") },
+ "(for database id \"cache\")"),
+ N_("arg: interval") },
{ NULL }
};
diff --git a/lib/libmf.h b/lib/libmf.h
index ea7075fd..e27e27c4 100644
--- a/lib/libmf.h
+++ b/lib/libmf.h
@@ -297,41 +297,6 @@ void mf_server_start(const char *program, const char *dir,
const char *pidfile, int flags);
-/* optcache.c */
-union mf_option_value {
- int ov_bool;
- char *ov_string;
- time_t ov_time;
- size_t ov_size;
- mu_list_t ov_list;
-};
-
-struct mf_option_cache {
- char *name; /* option name */
- int (*handler)(char const *opt, union mf_option_value *pval, char const *arg);
- /* handler function, which verifies and assigns
- arg to pval. */
- void (*set)(union mf_option_value *value);
- /* function that actually sets the option */
- union mf_option_value value; /* current value */
- int isset; /* is the value set */
-};
-
-#define MF_OCF_NULL 0x01 /* Option_cache array is NULL-terminated */
-#define MF_OCF_STATIC 0x02 /* Option_cache array is static. */
-
-void mf_optcache_add(struct mf_option_cache *tab, size_t size, int flags);
-int mf_optcache_set_option(char const *name, char const *value);
-void mf_optcache_flush(void);
-int mf_option_string(char const *opt, union mf_option_value *val, char const *arg);
-int mf_option_boolean(char const *opt, union mf_option_value *val, char const *arg);
-int mf_option_timeout(char const *opt, union mf_option_value *val, char const *arg);
-int mf_option_size(char const *opt, union mf_option_value *val, char const *arg);
-
-
-void mf_init_lock_options(void);
-
-
/* namefixup.c */
void mf_namefixup_register(char **ptr, const char *initval);
void mf_file_name_ptr_fixup(char **ptr, char *dir, size_t dirlen);
diff --git a/lib/optcache.c b/lib/optcache.c
deleted file mode 100644
index 54b10fed..00000000
--- a/lib/optcache.c
+++ /dev/null
@@ -1,182 +0,0 @@
-/* This file is part of Mailfromd.
- Copyright (C) 2005-2011, 2015-2016 Sergey Poznyakoff
-
- 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 3, 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, see <http://www.gnu.org/licenses/>. */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include <stdlib.h>
-#include <errno.h>
-#include "libmf.h"
-#include "mailutils/alloc.h"
-
-
-struct cache_list_elt {
- struct cache_list_elt *next;
- struct mf_option_cache *opt;
- size_t size;
-};
-
-static struct cache_list_elt *head, *tail;
-
-static struct mf_option_cache *
-optcache_dup(struct mf_option_cache *tab, size_t size)
-{
- struct mf_option_cache *newtab = mu_calloc(size, sizeof(*tab));
- size_t i;
-
- for (i = 0; i < size; i++) {
- newtab[i] = tab[i];
- newtab[i].name = mu_strdup(newtab[i].name);
- newtab[i].isset = 0;
- }
- return newtab;
-}
-
-void
-mf_optcache_add(struct mf_option_cache *tab, size_t size, int flags)
-{
- struct cache_list_elt *elt;
-
- elt = mu_alloc(sizeof(*elt));
- elt->next = NULL;
- if (tail)
- tail->next = elt;
- else
- head = elt;
- tail = elt;
-
- /* If the array is null-terminated, compute its size */
- if (flags & MF_OCF_NULL)
- for (size = 0; tab[size].name; size++)
- ;
-
- /* Unless it is static, make a copy */
- tab = optcache_dup(tab, size);
-
- elt->opt = tab;
- elt->size = size;
-}
-
-static struct mf_option_cache *
-find_option(char const *name)
-{
- struct cache_list_elt *elt;
-
- for (elt = head; elt; elt = elt->next) {
- size_t i;
- struct mf_option_cache *opt;
-
- for (i = 0, opt = elt->opt; i < elt->size; i++, opt++) {
- if (strcmp(opt->name, name) == 0)
- return opt;
- }
- }
- return NULL;
-}
-
-int
-mf_optcache_set_option(char const *name, char const *value)
-{
- int rc;
- struct mf_option_cache *p = find_option(name);
- if (!p) {
- errno = ENOENT;
- return 1;
- }
- rc = p->handler(name, &p->value, value);
- if (rc == 0)
- p->isset = 1;
- return rc;
-}
-
-void
-mf_optcache_flush()
-{
- struct cache_list_elt *elt;
-
- for (elt = head; elt; elt = elt->next) {
- size_t i;
- struct mf_option_cache *opt;
-
- for (i = 0, opt = elt->opt; i < elt->size; i++, opt++)
- if (opt->isset && opt->set)
- opt->set(&opt->value);
- }
-}
-
-
-int
-mf_option_string(char const *opt, union mf_option_value *val, char const *arg)
-{
- free(val->ov_string);
- val->ov_string = strdup(arg);
- return 0;
-}
-
-int
-mf_option_boolean(char const *opt, union mf_option_value *val, char const *arg)
-{
- int b;
-
- if (strcmp (arg, "yes") == 0
- || strcmp (arg, "true") == 0
- || strcmp (arg, "t") == 0)
- b = 1;
- else if (strcmp (arg, "no") == 0
- || strcmp (arg, "false") == 0
- || strcmp (arg, "nil") == 0)
- b = 0;
- else {
- char *p;
-
- b = strtoul(arg, &p, 10);
- if (*p) {
- errno = EINVAL;
- return 1;
- }
- }
-
- val->ov_bool = b;
- return 0;
-}
-
-int
-mf_option_timeout(char const *opt, union mf_option_value *val, char const *arg)
-{
- time_t interval;
- const char *endp;
-
- if (parse_time_interval(arg, &interval, &endp)) {
- mu_error(_("%s: unrecognized time format (near `%s')"),
- opt, endp);
- return 1;
- }
- val->ov_time = interval;
- return 0;
-}
-
-int
-mf_option_size(char const *opt, union mf_option_value *val, char const *arg)
-{
- char *p;
- unsigned long n = strtoul(arg, &p, 10);
- if (*p)
- return 1;
- val->ov_size = n;
- return 0;
-}
-
diff --git a/lib/utils.c b/lib/utils.c
index 2e51ef13..c832ccba 100644
--- a/lib/utils.c
+++ b/lib/utils.c
@@ -125,45 +125,37 @@ config_cb_ignore(void *data, mu_config_value_t *val)
int
config_cb_lock_retry_count(void *data, mu_config_value_t *val)
{
+ int rc;
+ char *errmsg;
+ size_t v;
+
if (mu_cfg_assert_value_type(val, MU_CFG_STRING))
return 1;
- if (mf_optcache_set_option("lock-retry-count", val->v.string)) {
- mu_error(_("not a number"));
+ rc = mu_str_to_c(val->v.string, mu_c_size, &v, &errmsg);
+ if (rc) {
+ mu_error(_("%s: not a valid number"));
+ free(errmsg);
return 1;
}
+ mu_locker_set_default_retry_count(v);
return 0;
}
int
config_cb_lock_retry_timeout(void *data, mu_config_value_t *val)
{
- return mf_optcache_set_option("lock-retry-timeout", val->v.string);
-}
-
-static void
-set_lock_retry_count(union mf_option_value *val)
-{
- mu_locker_set_default_retry_count(val->ov_size);
-}
-
-static void
-set_lock_retry_timeout(union mf_option_value *val)
-{
- mu_locker_set_default_retry_timeout(val->ov_time);
-}
-
-static struct mf_option_cache lock_option_cache[] = {
- { "lock-retry-count", mf_option_size, set_lock_retry_count },
- { "lock-retry-timeout", mf_option_timeout, set_lock_retry_timeout },
- { NULL }
-};
-
-void
-mf_init_lock_options()
-{
- mf_optcache_add(lock_option_cache, 0, MF_OCF_NULL|MF_OCF_STATIC);
+ int rc;
+ char *errmsg;
+ time_t v;
+
+ rc = mu_str_to_c(val->v.string, mu_c_time, &v, &errmsg);
+ if (rc) {
+ mu_error(_("%s: not a valid interval"));
+ free(errmsg);
+ return 1;
+ }
+ mu_locker_set_default_retry_timeout(v);
}
-
int
stderr_closed_p()
diff --git a/src/builtin/dns.bi b/src/builtin/dns.bi
index 641cf5ae..d7596f9c 100644
--- a/src/builtin/dns.bi
+++ b/src/builtin/dns.bi
@@ -25,11 +25,11 @@ static size_t max_ptr = MAX_DNS_PTR;
static size_t max_a = MAX_DNS_A;
static size_t max_mx = MAX_DNS_MX;
static struct mu_cfg_param dns_cfg_param[] = {
- { "max-dns-reply-a", mu_cfg_size, &max_a, 0, NULL,
+ { "max-dns-reply-a", mu_c_size, &max_a, 0, NULL,
N_("Maximum number of A records in a DNS reply.") },
- { "max-dns-reply-ptr", mu_cfg_size, &max_a, 0, NULL,
+ { "max-dns-reply-ptr", mu_c_size, &max_a, 0, NULL,
N_("Maximum number of PTR records in a DNS reply.") },
- { "max-dns-reply-mx", mu_cfg_size, &max_mx, 0, NULL,
+ { "max-dns-reply-mx", mu_c_size, &max_mx, 0, NULL,
N_("Maximum number of MX records in a DNS reply.") },
{ NULL }
};
diff --git a/src/builtin/io.bi b/src/builtin/io.bi
index 72ecb770..0875937f 100644
--- a/src/builtin/io.bi
+++ b/src/builtin/io.bi
@@ -24,7 +24,7 @@
static size_t nstreams = MAX_IOSTREAMS;
static struct mu_cfg_param io_cfg_param[] = {
- { "max-streams", mu_cfg_size, &nstreams, 0, NULL,
+ { "max-streams", mu_c_size, &nstreams, 0, NULL,
N_("Maximum number of stream descriptors.") },
{ NULL }
};
diff --git a/src/builtin/mbox.bi b/src/builtin/mbox.bi
index f151bd4d..ea4c1f92 100644
--- a/src/builtin/mbox.bi
+++ b/src/builtin/mbox.bi
@@ -20,7 +20,7 @@
static size_t nmboxes = MAX_MBOXES;
static struct mu_cfg_param mbox_cfg_param[] = {
- { "max-open-mailboxes", mu_cfg_size, &nmboxes, 0, NULL,
+ { "max-open-mailboxes", mu_c_size, &nmboxes, 0, NULL,
N_("Maximum number of mailboxes to open simultaneously.") },
{ NULL }
};
diff --git a/src/builtin/msg.bi b/src/builtin/msg.bi
index 0de44a20..2fe21363 100644
--- a/src/builtin/msg.bi
+++ b/src/builtin/msg.bi
@@ -20,7 +20,7 @@
static size_t nmsgs = MAX_MSGS;
static struct mu_cfg_param msg_cfg_param[] = {
- { "max-open-messages", mu_cfg_size, &nmsgs, 0, NULL,
+ { "max-open-messages", mu_c_size, &nmsgs, 0, NULL,
N_("Maximum number of messages to open simultaneously.") },
{ NULL }
};
diff --git a/src/main.c b/src/main.c
index 255500a9..3c4b8462 100644
--- a/src/main.c
+++ b/src/main.c
@@ -35,7 +35,7 @@
#include <mailutils/mailutils.h>
#include <mailutils/server.h>
#include <mailutils/syslog.h>
-#include <mailutils/libargp.h>
+#include <mailutils/cli.h>
#include <mailutils/dbm.h>
#include "mailfromd.h"
@@ -80,6 +80,10 @@ char *callout_server_url;
mu_stream_t mf_strecho; /* Output stream for 'echo' statements */
+#define ARG_UNSET (-1)
+
+static int trace_option = ARG_UNSET;
+static mu_list_t trace_modules;
/* Preprocessor helper function */
static void
@@ -255,17 +259,8 @@ host_in_relayed_domain_p(char *client)
free(hbuf);
return rc;
}
-
-static void
-set_milter_timeout(union mf_option_value *val)
-{
- if (smfi_settimeout(val->ov_time) == MI_FAILURE) {
- mu_error(_("invalid milter timeout: %lu"),
- (unsigned long)val->ov_time);
- exit(EX_USAGE);
- }
-}
+static mu_list_t relayed_domain_files;
static int
load_relay_file(void *item, void *data)
@@ -275,427 +270,389 @@ load_relay_file(void *item, void *data)
}
static void
-set_relay(union mf_option_value *val)
+init_relayed_domains(void)
{
- mu_list_foreach(val->ov_list, load_relay_file, NULL);
- mu_list_destroy(&val->ov_list);
+ mu_list_foreach(relayed_domain_files, load_relay_file, NULL);
+ mu_list_destroy(relayed_domain_files);
}
+
+/* Command line parsing */
-void
-set_stack_trace(union mf_option_value *val)
+const char *program_version = "mailfromd (" PACKAGE_STRING ")";
+static char prog_doc[] = N_("mailfromd -- a general purpose milter daemon");
+static char args_doc[] = "[var=value...][SCRIPT]";
+
+static void
+opt_testmode(struct mu_parseopt *po, struct mu_option *op, char const *arg)
{
- stack_trace_option = val->ov_bool;
+ mode = MAILFROMD_TEST;
+ if (arg) {
+ test_state = string_to_state(arg);
+ if (test_state == smtp_state_none) {
+ mu_parseopt_error(op,
+ _("unknown smtp state tag: %s"),
+ arg);
+ exit(po->po_exit_error);
+ }
+ log_stream = "stderr";
+ need_script = 1;
+ }
}
-static int
-option_relay(char const *opt, union mf_option_value *val, char const *newval)
+static void
+opt_runmode(struct mu_parseopt *po, struct mu_option *op, char const *arg)
{
- if (!val->ov_list)
- mu_list_create(&val->ov_list);
- mu_list_append(val->ov_list, strdup(newval));
- return 0;
+ mode = MAILFROMD_RUN;
+ if (arg)
+ main_function_name = arg;
+ log_stream = "stderr";
+ need_script = 1;
}
-struct mf_option_cache option_cache[] = {
- { "stack-trace", mf_option_boolean, set_stack_trace },
- { "milter-timeout", mf_option_timeout, set_milter_timeout },
- { "relay", option_relay, set_relay },
- { NULL }
-};
-
-
-/* Command line parsing */
-
-const char *program_version = "mailfromd (" PACKAGE_STRING ")";
-static char doc[] = N_("mailfromd -- a general purpose milter daemon");
-static char args_doc[] = "[var=value...][SCRIPT]";
+static void
+opt_lint(struct mu_parseopt *po, struct mu_option *op, char const *arg)
+{
+ log_stream = "stderr";
+ script_check = 1;
+ need_script = 1;
+}
-enum mailfromd_option {
- OPTION_DAEMON = 256,
- OPTION_DOMAIN_FILE,
- OPTION_DUMP_CODE,
- OPTION_DUMP_GRAMMAR_TRACE,
- OPTION_DUMP_LEX_TRACE,
- OPTION_DUMP_MACROS,
- OPTION_DUMP_TREE,
- OPTION_DUMP_XREF,
- OPTION_LOCATION_COLUMN,
- OPTION_GACOPYZ_LOG,
- OPTION_LINT,
- OPTION_MILTER_TIMEOUT,
- OPTION_MTASIM,
- OPTION_NO_PREPROCESSOR,
- OPTION_PREPROCESSOR,
- OPTION_RUN,
- OPTION_SHOW_DEFAULTS,
- OPTION_STACK_TRACE,
- OPTION_TIMEOUT,
- OPTION_TRACE,
- OPTION_TRACE_PROGRAM,
-};
+static void
+opt_show_defaults(struct mu_parseopt *po, struct mu_option *op,
+ char const *arg)
+{
+ mode = MAILFROMD_SHOW_DEFAULTS;
+ need_script = 0;
+}
-static struct argp_option options[] = {
-#define GRP 0
- { NULL, 0, NULL, 0,
- N_("Operation modifiers"), GRP },
- { "test", 't', N_("HANDLER"), OPTION_ARG_OPTIONAL,
- N_("run in test mode"), GRP+1 },
- { "run", OPTION_RUN, N_("FUNC"), OPTION_ARG_OPTIONAL,
- N_("run script and execute function FUNC (\"main\" if not given)"),
- GRP+1 },
- { "lint", OPTION_LINT, NULL, 0,
- N_("check syntax and exit"), GRP+1 },
- { "syntax-check", 0, NULL, OPTION_ALIAS, NULL, GRP+1 },
- { "show-defaults", OPTION_SHOW_DEFAULTS, NULL, 0,
- N_("show compilation defaults"), GRP+1 },
- { "daemon", OPTION_DAEMON, NULL, 0,
- N_("run in daemon mode (default)"), GRP+1 },
-
- { NULL, 'E', NULL, 0,
- N_("preprocess source files and exit"), GRP+1 },
- /* Reserved for future use: */
- { "compile", 'c', NULL, OPTION_HIDDEN,
- N_("compile files"), GRP+1 },
- { "load", 'l', N_("FILE"), OPTION_HIDDEN,
- N_("load library"), GRP+1 },
- { "load-dir", 'L', N_("DIR"), OPTION_HIDDEN,
- N_("add DIR to the load path"), GRP+1 },
-
-#undef GRP
-#define GRP 20
- { NULL, 0, NULL, 0,
- N_("General options"), GRP },
- { "include", 'I', N_("DIR"), 0,
- N_("add the directory DIR to the list of directories to be "
- "searched for header files"), GRP+1 },
- { "port", 'p', N_("STRING"), 0,
- N_("set communication socket"), GRP+1 },
- { "mtasim", OPTION_MTASIM, NULL, 0,
- N_("run in mtasim compatibility mode"), GRP+1 },
- { "optimize", 'O', N_("LEVEL"), OPTION_ARG_OPTIONAL,
- N_("set code optimization level"), GRP+1 },
- { "variable", 'v', N_("VAR=VALUE"), 0,
- N_("assign VALUE to VAR"), GRP+1 },
- { "relayed-domain-file", OPTION_DOMAIN_FILE, N_("FILE"), 0,
- N_("read relayed domains from FILE"), GRP+1 },
-
-#undef GRP
-#define GRP 25
- { NULL, 0, NULL, 0,
- N_("Preprocessor options"), GRP },
- { "preprocessor", OPTION_PREPROCESSOR, N_("COMMAND"), 0,
- N_("use command as external preprocessor"), GRP+1 },
- { "no-preprocessor", OPTION_NO_PREPROCESSOR, NULL, 0,
- N_("disable the use of external preprocessor"), GRP+1 },
- { "define", 'D', N_("NAME[=VALUE]"), 0,
- N_("define a preprocessor symbol NAME as having VALUE, or empty"),
- GRP+1 },
- { "undefine", 'U', N_("NAME"), 0,
- N_("undefine a preprocessor symbol NAME"),
- GRP+1 },
-
-#undef GRP
-#define GRP 30
- { NULL, 0, NULL, 0,
- N_("Timeout control"), GRP },
- { "milter-timeout", OPTION_MILTER_TIMEOUT, N_("TIME"), 0,
- N_("set MTA connection timeout"), GRP+1 },
- { "timeout", OPTION_TIMEOUT, N_("TIME"), 0,
- N_("set I/O operation timeout"), GRP+1 },
-
-#undef GRP
-#define GRP 40
- { NULL, 0, NULL, 0,
- N_("Informational and debugging options"), GRP },
- { "location-column", OPTION_LOCATION_COLUMN, NULL, 0,
- N_("print location column numbers in compiler diagnostics messages"),
- GRP+1 },
- { "trace", OPTION_TRACE, NULL, 0,
- N_("trace executed actions"), GRP+1 },
- { "trace-program", OPTION_TRACE_PROGRAM, N_("MODULES"),
- OPTION_ARG_OPTIONAL,
- N_("enable filter program tracing"), GRP+1 },
- { "dump-code", OPTION_DUMP_CODE, NULL, 0,
- N_("dump disassembled code"), GRP+1 },
- { "dump-grammar-trace", OPTION_DUMP_GRAMMAR_TRACE, NULL, 0,
- N_("dump grammar traces"), GRP+1 },
- { "dump-lex-trace", OPTION_DUMP_LEX_TRACE, NULL, 0,
- N_("dump lexical analyzer traces"), GRP+1 },
- { "dump-tree", OPTION_DUMP_TREE, NULL, 0,
- N_("dump parser tree"), GRP+1 },
- { "dump-macros", OPTION_DUMP_MACROS, NULL, 0,
- N_("show used Sendmail macros"), GRP+1 },
- { "xref", OPTION_DUMP_XREF, NULL, 0,
- N_("produce a cross-reference listing"), GRP+1 },
- { "dump-xref", 0, NULL, OPTION_ALIAS, NULL, GRP+1 },
- { "gacopyz-log", OPTION_GACOPYZ_LOG, N_("LEVEL"), 0,
- N_("set Gacopyz log level"), GRP+1 },
- { "stack-trace", OPTION_STACK_TRACE, NULL, 0,
- N_("enable stack traces on runtime errors"), GRP+1 },
-#undef GRP
+static void
+opt_daemon(struct mu_parseopt *po, struct mu_option *op,
+ char const *arg)
+{
+ mode = MAILFROMD_DAEMON;
+ need_script = 1;
+}
-#if 0
-/* This entry is to pacify `make check-docs'. The options below
- are defined in libmailutils.
- */
- { "log-facility", }
- { "mailer", }
-#endif
- { NULL }
-};
+static void
+opt_include_dir(struct mu_parseopt *po, struct mu_option *op,
+ char const *arg)
+{
+ add_include_dir(arg);
+}
-static int
-validate_options()
+static void
+opt_port(struct mu_parseopt *po, struct mu_option *op,
+ char const *arg)
{
- /* FIXME */
- return 0;
+ mf_srvcfg_add("default", arg);
}
-struct arguments
+static void
+opt_mtasim(struct mu_parseopt *po, struct mu_option *op,
+ char const *arg)
{
- int trace;
- mu_list_t trace_modules;
-};
+ mtasim_option = 1;
+ server_flags |= MF_SERVER_FOREGROUND;
+}
-#define ARG_UNSET (-1)
+static void
+opt_optimize(struct mu_parseopt *po, struct mu_option *op,
+ char const *arg)
+{
+ if (!arg)
+ optimization_level = 1;
+ else {
+ char *p;
+ optimization_level = strtoul(arg, &p, 0);
+ if (*p)
+ mu_parseopt_error(po,
+ _("-O level must be a non-negative integer"));
+ }
+}
static void
-init_arguments(struct arguments *args)
+opt_variable(struct mu_parseopt *po, struct mu_option *op,
+ char const *arg)
{
- args->trace = ARG_UNSET;
- args->trace_modules = NULL;
+ char *p;
+ struct locus locus = { "<command line>", 1, 0 };
+
+ p = strchr(arg, '=');
+ if (!p) {
+ mu_parseopt_error(po,
+ _("expected assignment, but found `%s'"),
+ arg);
+ exit(po->po_exit_error);
+ }
+ *p++ = 0;
+ defer_initialize_variable(arg, p, &locus);
}
-static int
-flush_trace_module(void *item, void *data)
+static void
+opt_relayed_domain_file(struct mu_parseopt *po, struct mu_option *op,
+ char const *arg)
{
- enable_prog_trace((const char *) item);
+ if (!relayed_domain_files)
+ mu_list_create(&relayed_domain_files);
+ mu_list_append(relayed_domain_files, mu_strdup(arg));
return 0;
}
static void
-flush_arguments(struct arguments *args)
+opt_clear_ext_pp(struct mu_parseopt *po, struct mu_option *op, char const *arg)
{
- if (args->trace != ARG_UNSET)
- do_trace = args->trace;
- if (args->trace_modules) {
- mu_list_foreach(args->trace_modules, flush_trace_module, NULL);
- mu_list_destroy(&args->trace_modules);
- }
+ ext_pp = NULL;
}
static void
-destroy_trace_item(void *ptr)
+opt_define(struct mu_parseopt *po, struct mu_option *op, char const *arg)
{
- free(ptr);
+ ext_pp_options_given = 1;
+ add_pp_option("-D", arg);
}
-static error_t
-parse_opt(int key, char *arg, struct argp_state *state)
+static void
+opt_undefine(struct mu_parseopt *po, struct mu_option *op, char const *arg)
{
- struct arguments *args = state->input;
- switch (key) {
- case 'D':
- ext_pp_options_given = 1;
- add_pp_option("-D", arg);
- break;
+ ext_pp_options_given = 1;
+ add_pp_option("-U", arg);
+}
- case 'd':
- mf_optcache_set_option("debug", arg);
- break;
-
- case 'U':
- ext_pp_options_given = 1;
- add_pp_option("-U", arg);
- break;
-
- case 'E':
- preprocess_option = 1;
- break;
-
- case 'I':
- add_include_dir(arg);
- break;
-
- case OPTION_LOCATION_COLUMN:
- location_column_option = 1;
- break;
-
- case OPTION_PREPROCESSOR:
- ext_pp = arg;
- break;
+static void
+opt_set_milter_timeout(struct mu_parseopt *po, struct mu_option *op,
+ char const *arg)
+{
+ int rc;
+ time_t v;
+
+ if (mu_str_to_c(arg, mu_c_time, &v, NULL)) {
+ mu_parseopt_error(po, _("%s: not a valid interval"), arg);
+ exit(po->po_exit_error);
+ }
- case OPTION_NO_PREPROCESSOR:
- ext_pp = NULL;
- break;
-
- case 'c':
- case 'l':
- case 'L':
- argp_error(state,
- _("the option `-%c' is not yet implemented"),
- key);
- break;
-
- case OPTION_LINT:
- log_stream = "stderr";
- script_check = 1;
- need_script = 1;
- break;
-
- case 'p':
- mf_optcache_set_option("port", arg);
- break;
-
- case OPTION_RUN:
- mode = MAILFROMD_RUN;
- if (arg)
- main_function_name = arg;
- log_stream = "stderr";
- need_script = 1;
- break;
-
- case 'O':
- if (!arg)
- optimization_level = 1;
- else {
- char *p;
- optimization_level = strtoul(arg, &p, 0);
- if (*p)
- argp_error(state,
- _("-O level must be a non-negative integer"));
- }
- break;
-
- case 't':
- mode = MAILFROMD_TEST;
- if (arg) {
- test_state = string_to_state(arg);
- if (test_state == smtp_state_none)
- argp_error(state,
- _("unknown smtp state tag: %s"),
- arg);
- }
- log_stream = "stderr";
- need_script = 1;
- break;
+ if (smfi_settimeout(v) == MI_FAILURE) {
+ mu_parseopt_error(po, _("invalid milter timeout: %s"), arg);
+ exit(po->po_exit_error);
+ }
+}
- case 'v':
- {
- char *p;
- struct locus locus = { "<command line>", 1, 0 };
-
- p = strchr(arg, '=');
- if (!p)
- argp_error(state,
- _("expected assignment, but found `%s'"),
- arg);
- *p++ = 0;
- defer_initialize_variable(arg, p, &locus);
- break;
+static void
+opt_trace_program(struct mu_parseopt *po, struct mu_option *op,
+ char const *arg)
+{
+ if (!trace_modules) {
+ mu_list_create(&trace_modules);
+ mu_list_set_destroy_item(trace_modules, destroy_trace_item);
}
+ mu_list_append(trace_modules, mu_strdup(arg ? arg : "all"));
+}
- case OPTION_DAEMON:
- mode = MAILFROMD_DAEMON;
- need_script = 1;
- break;
-
- case OPTION_DOMAIN_FILE:
- mf_optcache_set_option("relay", arg);
- break;
+static void
+opt_dump_code(struct mu_parseopt *po, struct mu_option *op,
+ char const *arg)
+{
+ script_dump_code = 1;
+ log_stream = "stderr";
+}
- case OPTION_DUMP_CODE:
- script_dump_code = 1;
- log_stream = "stderr";
- break;
-
- case OPTION_DUMP_GRAMMAR_TRACE:
- script_ydebug = 1;
- log_stream = "stderr";
- break;
-
- case OPTION_DUMP_LEX_TRACE:
- yy_flex_debug = 1;
- log_stream = "stderr";
- break;
-
- case OPTION_DUMP_MACROS:
- script_dump_macros = 1;
- log_stream = "stderr";
- break;
-
- case OPTION_DUMP_TREE:
- script_dump_tree = 1;
- log_stream = "stderr";
- break;
+static void
+opt_dump_grammar_trace(struct mu_parseopt *po, struct mu_option *op,
+ char const *arg)
+{
+ script_ydebug = 1;
+ log_stream = "stderr";
+}
- case OPTION_DUMP_XREF:
- script_dump_xref = 1;
- log_stream = "stderr";
- break;
-
- case OPTION_GACOPYZ_LOG:
- {
- int lev = gacopyz_string_to_log_level(arg);
- if (lev == -1)
- argp_error(state,
- _("%s: invalid log level"),
- arg);
- milter_setlogmask(SMI_LOG_FROM(lev));
- break;
+static void
+opt_dump_lex_trace(struct mu_parseopt *po, struct mu_option *op,
+ char const *arg)
+{
+ yy_flex_debug = 1;
+ log_stream = "stderr";
+}
+
+static void
+opt_dump_macros(struct mu_parseopt *po, struct mu_option *op,
+ char const *arg)
+{
+ script_dump_macros = 1;
+ log_stream = "stderr";
+}
+
+static void
+opt_dump_tree(struct mu_parseopt *po, struct mu_option *op,
+ char const *arg)
+{
+ script_dump_tree = 1;
+ log_stream = "stderr";
+}
+
+static void
+opt_gacopyz_log(struct mu_parseopt *po, struct mu_option *op,
+ char const *arg)
+{
+ int lev = gacopyz_string_to_log_level(arg);
+ if (lev == -1) {
+ mu_parser_error(po, _("%s: invalid log level"), arg);
+ exit(po->po_exit_error);
}
-
- case OPTION_MILTER_TIMEOUT:
- mf_optcache_set_option("milter-timeout", arg);
- break;
+ milter_setlogmask(SMI_LOG_FROM(lev));
+}
- case OPTION_MTASIM:
- mtasim_option = 1;
- server_flags |= MF_SERVER_FOREGROUND;
- break;
-
- case OPTION_SHOW_DEFAULTS:
- mode = MAILFROMD_SHOW_DEFAULTS;
- need_script = 0;
- break;
+static void
+opt_dump_xref(struct mu_parseopt *po, struct mu_option *op,
+ char const *arg)
+{
+ script_dump_xref = 1;
+ log_stream = "stderr";
+}
- case OPTION_STACK_TRACE:
- mf_optcache_set_option("stack-trace", "yes");
- break;
+static struct mu_option options[] = {
+ MU_OPTION_GROUP(N_("Operation modifiers")),
+ { "test", 't', N_("HANDLER"), MU_OPTION_ARG_OPTIONAL,
+ N_("run in test mode"),
+ mu_c_string, NULL, opt_testmode },
+ { "run", 0, N_("FUNC"), MU_OPTION_ARG_OPTIONAL,
+ N_("run script and execute function FUNC (\"main\" if not given)"),
+ mu_c_string, NULL, opt_runmode },
+ { "lint", 0, NULL, MU_OPTION_DEFAULT,
+ N_("check syntax and exit"),
+ mu_c_string, NULL, opt_lint },
+ { "syntax-check", 0, NULL, MU_OPTION_ALIAS, },
+ { "show-defaults", 0, NULL, MU_OPTION_DEFAULT,
+ N_("show compilation defaults"),
+ mu_c_string, NULL, opt_show_defaults },
+
+ { "daemon", 0, NULL, MU_OPTION_DEFAULT,
+ N_("run in daemon mode (default)"),
+ mu_c_string, NULL, opt_daemon },
- case OPTION_TIMEOUT:
- mf_optcache_set_option("timeout", arg);
- break;
+ { NULL, 'E', NULL, MU_OPTION_DEFAULT,
+ N_("preprocess source files and exit"),
+ mu_c_bool, &preprocess_option },
+ /* Reserved for future use: */
+ { "compile", 'c', NULL, MU_OPTION_HIDDEN,
+ N_("compile files"),
+ mu_c_void },
+ { "load", 'l', N_("FILE"), MU_OPTION_HIDDEN,
+ N_("load library"),
+ mu_c_void },
+ { "load-dir", 'L', N_("DIR"), MU_OPTION_HIDDEN,
+ N_("add DIR to the load path"),
+ mu_c_void },
+
+ MU_OPTION_GROUP(N_("General options")),
+ { "include", 'I', N_("DIR"), MU_OPTION_DEFAULT,
+ N_("add the directory DIR to the list of directories to be "
+ "searched for header files"),
+ mu_c_string, NULL, opt_include_dir },
+ { "port", 'p', N_("STRING"), MU_OPTION_DEFAULT,
+ N_("set communication socket"),
+