aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/libmf.h32
-rw-r--r--lib/optcache.c76
-rw-r--r--lib/utils.c43
-rw-r--r--src/main.c32
-rw-r--r--src/mfdbtool.c13
-rw-r--r--src/srvcfg.c75
6 files changed, 127 insertions, 144 deletions
diff --git a/lib/libmf.h b/lib/libmf.h
index 96421687..4344d1a6 100644
--- a/lib/libmf.h
+++ b/lib/libmf.h
@@ -286,32 +286,42 @@ void mf_server_check_pidfile(const char *name);
void mf_server_save_cmdline(int argc, char **argv);
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 */
- void *value; /* current value */
- int (*handler)(char *opt, void **pval, char *newval);
+ char *name; /* option name */
+ int (*handler)(char const *opt, union mf_option_value *pval, char const *arg);
/* handler function, which verifies and assigns
- newval to pval. */
- void (*set)(void *value); /* function that actually sets the option */
+ 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 *name, char *value);
+int mf_optcache_set_option(char const *name, char const *value);
void mf_optcache_flush(void);
-int mf_option_string(char *opt, void **pval, char *newval);
-int mf_option_boolean(char *opt, void **pval, char *newval);
-int mf_option_time(char *opt, void **pval, char *newval);
-int mf_option_time_t(char *opt, void **pval, char *newval);
-int mf_option_size_t(char *opt, void **pval, char *newval);
+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);
diff --git a/lib/optcache.c b/lib/optcache.c
index a059b29a..15b011b5 100644
--- a/lib/optcache.c
+++ b/lib/optcache.c
@@ -39,12 +39,13 @@ 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)
@@ -69,13 +70,13 @@ mf_optcache_add(struct mf_option_cache *tab, size_t size, int flags)
elt->opt = tab;
elt->size = size;
}
static struct mf_option_cache *
-find_option(char *name)
+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;
@@ -86,102 +87,97 @@ find_option(char *name)
}
}
return NULL;
}
int
-mf_optcache_set_option(char *name, char *value)
+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;
}
- return p->handler(name, &p->value, value);
+ 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->value && opt->set)
- opt->set(opt->value);
+ if (opt->isset && opt->set)
+ opt->set(&opt->value);
}
}
int
-mf_option_string(char *opt, void **pval, char *newval)
+mf_option_string(char const *opt, union mf_option_value *val, char const *arg)
{
- if (*pval)
- free(*pval);
- *pval = strdup(newval);
+ free(val->ov_string);
+ val->ov_string = strdup(arg);
return 0;
}
int
-mf_option_boolean(char *opt, void **pval, char *newval)
+mf_option_boolean(char const *opt, union mf_option_value *val, char const *arg)
{
- int val;
-
- if (strcmp (newval, "yes") == 0
- || strcmp (newval, "true") == 0
- || strcmp (newval, "t") == 0)
- val = 1;
- else if (strcmp (newval, "no") == 0
- || strcmp (newval, "false") == 0
- || strcmp (newval, "nil") == 0)
- val = 0;
+ 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;
- val = strtoul(newval, &p, 10);
+ b = strtoul(arg, &p, 10);
if (*p) {
errno = EINVAL;
return 1;
}
}
- *pval = (void*) val;
+ val->ov_bool = b;
return 0;
}
int
-mf_option_time(char *opt, void **pval, char *newval)
+mf_option_timeout(char const *opt, union mf_option_value *val, char const *arg)
{
time_t interval;
const char *endp;
- if (parse_time_interval(newval, &interval, &endp)) {
+
+ if (parse_time_interval(arg, &interval, &endp)) {
mu_error(_("%s: unrecognized time format (near `%s')"),
opt, endp);
return 1;
}
- if (!*pval)
- *pval = mu_alloc(sizeof(time_t));
- *(time_t*) *pval = interval;
+ val->ov_time = interval;
return 0;
}
int
-mf_option_time_t(char *opt, void **pval, char *newval)
+mf_option_size(char const *opt, union mf_option_value *val, char const *arg)
{
- if (!*pval)
- *pval = mu_alloc(sizeof(time_t));
- memcpy(*pval, newval, sizeof(time_t));
- return 0;
-}
-
-int
-mf_option_size_t(char *opt, void **pval, char *newval)
-{
- if (!*pval)
- *pval = mu_alloc(sizeof(size_t));
- memcpy(*pval, newval, sizeof(size_t));
+ 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 3fc123a3..6a19e505 100644
--- a/lib/utils.c
+++ b/lib/utils.c
@@ -111,80 +111,53 @@ config_cb_timeout (struct timeval *pt, mu_config_value_t *val)
}
free (alloc_str);
return 0;
}
int
-config_cb_time_t(void *data, mu_config_value_t *arg)
-{
- struct timeval tv;
- int rc = config_cb_timeout (&tv, arg);
- if (rc == 0)
- *(time_t*) data = tv.tv_sec;
- return rc;
-}
-
-int
config_cb_ignore(void *data, mu_config_value_t *val)
{
mu_diag_output (MU_DIAG_WARNING,
_("this statement has no effect in %s"),
PACKAGE_STRING);
return 0;
}
int
config_cb_lock_retry_count(void *data, mu_config_value_t *val)
{
- char *p;
- size_t n;
-
if (mu_cfg_assert_value_type(val, MU_CFG_STRING))
return 1;
- n = strtoul(val->v.string, &p, 10);
- if (*p) {
+ if (mf_optcache_set_option("lock-retry-count", val->v.string)) {
mu_error(_("not a number"));
return 1;
}
- mf_optcache_set_option("lock-retry-count", (void*)&n);
return 0;
}
int
config_cb_lock_retry_timeout(void *data, mu_config_value_t *val)
{
- int rc;
- time_t t;
-
- rc = config_cb_time_t(&t, val);
- if (rc == 0)
- mf_optcache_set_option("lock-retry-timeout", (void*)&t);
- return rc;
+ return mf_optcache_set_option("lock-retry-timeout", val->v.string);
}
static void
-set_lock_retry_count(void *value)
+set_lock_retry_count(union mf_option_value *val)
{
- size_t *n = value;
- mu_locker_set_default_retry_count(*n);
- free(value);
+ mu_locker_set_default_retry_count(val->ov_size);
}
static void
-set_lock_retry_timeout(void *value)
+set_lock_retry_timeout(union mf_option_value *val)
{
- time_t *t = value;
- mu_locker_set_default_retry_timeout(*t);
- free(value);
+ mu_locker_set_default_retry_timeout(val->ov_time);
}
static struct mf_option_cache lock_option_cache[] = {
- { "lock-retry-count", NULL, mf_option_size_t,
- set_lock_retry_count },
- { "lock-retry-timeout", NULL, mf_option_time_t,
- set_lock_retry_timeout },
+ { "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()
{
diff --git a/src/main.c b/src/main.c
index 5fbc3682..65329a42 100644
--- a/src/main.c
+++ b/src/main.c
@@ -256,54 +256,54 @@ host_in_relayed_domain_p(char *client)
free(hbuf);
return rc;
}
static void
-set_milter_timeout(void *value)
+set_milter_timeout(union mf_option_value *val)
{
- time_t to = *(time_t*) value;
- free(value);
- if (smfi_settimeout(to) == MI_FAILURE) {
- mu_error(_("invalid milter timeout: %lu"), (unsigned long) to);
+ if (smfi_settimeout(val->ov_time) == MI_FAILURE) {
+ mu_error(_("invalid milter timeout: %lu"),
+ (unsigned long)val->ov_time);
exit(EX_USAGE);
}
}
static int
load_relay_file(void *item, void *data)
{
read_domain_file(item);
return 0;
}
static void
-set_relay(void *value)
+set_relay(union mf_option_value *val)
{
- mu_list_foreach(value, load_relay_file, NULL);
+ mu_list_foreach(val->ov_list, load_relay_file, NULL);
+ mu_list_destroy(&val->ov_list);
}
void
-set_stack_trace(void *value)
+set_stack_trace(union mf_option_value *val)
{
- stack_trace_option = (int) value;
+ stack_trace_option = val->ov_bool;
}
static int
-option_relay(char *opt, void **pval, char *newval)
+option_relay(char const *opt, union mf_option_value *val, char const *newval)
{
- if (!*pval)
- mu_list_create((mu_list_t*)pval);
- mu_list_append(*pval, strdup(newval));
+ if (!val->ov_list)
+ mu_list_create(&val->ov_list);
+ mu_list_append(val->ov_list, strdup(newval));
return 0;
}
struct mf_option_cache option_cache[] = {
- { "stack-trace", NULL, mf_option_boolean, set_stack_trace },
- { "milter-timeout", NULL, mf_option_time, set_milter_timeout },
- { "relay", NULL, option_relay, set_relay },
+ { "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 */
diff --git a/src/mfdbtool.c b/src/mfdbtool.c
index dd723c38..4af386ad 100644
--- a/src/mfdbtool.c
+++ b/src/mfdbtool.c
@@ -355,26 +355,27 @@ struct mu_cfg_param mfdbtool_cfg_param[] = {
N_("time") },
{ NULL }
};
static void
-set_state_directory(void *value)
+set_state_directory(union mf_option_value *val)
{
- state_dir = value;
+ state_dir = val->ov_string;
}
static void
-set_debug(void *value)
+set_debug(union mf_option_value *val)
{
- mu_debug_parse_spec(value);
+ mu_debug_parse_spec(val->ov_string);
+ free(val->ov_string);
}
static struct mf_option_cache option_cache[] = {
- { "state-directory", NULL, mf_option_string, set_state_directory },
- { "debug", NULL, mf_option_string, set_debug },
+ { "state-directory", mf_option_string, set_state_directory },
+ { "debug", mf_option_string, set_debug },
{ NULL }
};
static const char *capa[] = {
"common",
diff --git a/src/srvcfg.c b/src/srvcfg.c
index 40d56b89..4b338f82 100644
--- a/src/srvcfg.c
+++ b/src/srvcfg.c
@@ -134,27 +134,28 @@ parse_milter_url(const char *str)
url = _parse_url(tmp);
free(tmp);
return url;
}
static void
-set_debug(void *value)
+set_debug(union mf_option_value *val)
{
- mu_debug_parse_spec(value);
+ mu_debug_parse_spec(val->ov_string);
+ free(val->ov_string);
}
void
-set_source_info(void *value)
+set_source_info(union mf_option_value *val)
{
- mu_debug_line_info = (int) value;
+ mu_debug_line_info = val->ov_bool;
}
static void
-set_user(void *value)
+set_user(union mf_option_value *val)
{
- mf_server_user = value;
+ mf_server_user = val->ov_string;
}
static int
gid_comp(const void *item, const void *data)
{
return (gid_t) item != (gid_t) data;
@@ -182,44 +183,43 @@ mf_option_group(const char *arg)
}
return 0;
}
static int
-option_group(char *opt, void **pval, char *newval)
+option_group(char const *opt, union mf_option_value *val, char const *arg)
{
- return mf_option_group(newval);
+ return mf_option_group(arg);
}
static int
-option_pidfile(char *opt, void **pval, char *newval)
+option_pidfile(char const *opt, union mf_option_value *val, char const *arg)
{
- if (newval[0] != '/') {
+ if (arg[0] != '/') {
mu_error(_("invalid pidfile name: must be absolute"));
return 1;
}
- return mf_option_string(opt, pval, newval);
+ return mf_option_string(opt, val, arg);
}
static void
-set_pidfile(void *value)
+set_pidfile(union mf_option_value *val)
{
- pidfile = value;
+ pidfile = val->ov_string;
}
static void
-set_io_timeout(void *value)
+set_io_timeout(union mf_option_value *val)
{
- io_timeout = *(time_t*) value;
- free(value);
+ io_timeout = val->ov_time;
}
static void
-set_logger_option(void *value)
+set_logger_option(union mf_option_value *val)
{
- log_stream = value;
+ log_stream = val->ov_string;
}
static int
mf_option_state_directory(const char *arg)
{
struct stat st;
@@ -240,21 +240,22 @@ mf_option_state_directory(const char *arg)
}
mailfromd_state_dir = mu_strdup(arg);
return 0;
}
void
-set_state_directory(void *value)
+set_state_directory(union mf_option_value *val)
{
/* nothing */
}
int
-option_state_directory(char *opt, void **pval, char *newval)
+option_state_directory(char const *opt, union mf_option_value *val,
+ char const *arg)
{
- return mf_option_state_directory(newval);
+ return mf_option_state_directory(arg);
}
void
mf_srvcfg_add(const char *type, const char *urlstr)
{
struct mf_srvcfg cfg;
@@ -279,47 +280,49 @@ mf_srvcfg_add(const char *type, const char *urlstr)
if (srv)
mfd_srvman_attach_server(srv);
}
}
static void
-set_port(void *value)
+set_port(union mf_option_value *val)
{
- mf_srvcfg_add("default", value);
+ mf_srvcfg_add("default", val->ov_string);
+ free(val->ov_string);
}
static void
-set_source_ip(void *value)
+set_source_ip(union mf_option_value *val)
{
int rc;
struct mu_sockaddr_hints hints;
memset(&hints, 0, sizeof hints);
hints.family = AF_INET;
hints.socktype = SOCK_STREAM;
hints.protocol = IPPROTO_TCP;
- rc = mu_sockaddr_from_node(&source_address, (char*)value, NULL,
+ rc = mu_sockaddr_from_node(&source_address, val->ov_string, NULL,
&hints);
if (rc) {
mu_error(_("cannot convert %s to sockaddr: %s"),
- (char*)value, mu_strerror(rc));
+ val->ov_string, mu_strerror(rc));
}
+ free(val->ov_string);
}
static struct mf_option_cache srv_option_cache[] = {
- { "debug", NULL, mf_option_string, set_debug },
- { "source-info", NULL, mf_option_boolean, set_source_info },
- { "user", NULL, mf_option_string, set_user },
- { "group", NULL, option_group, NULL },
- { "pidfile", NULL, option_pidfile, set_pidfile },
- { "source-ip", NULL, mf_option_string, set_source_ip },
- { "io-timeout", NULL, mf_option_time, set_io_timeout },
- { "logger", NULL, mf_option_string, set_logger_option },
- { "state-directory", NULL, option_state_directory,
+ { "debug", mf_option_string, set_debug },
+ { "source-info", mf_option_boolean, set_source_info },
+ { "user", mf_option_string, set_user },
+ { "group", option_group, NULL },
+ { "pidfile", option_pidfile, set_pidfile },
+ { "source-ip", mf_option_string, set_source_ip },
+ { "io-timeout", mf_option_timeout, set_io_timeout },
+ { "logger", mf_option_string, set_logger_option },
+ { "state-directory", option_state_directory,
set_state_directory },
- { "port", NULL, mf_option_string, set_port },
+ { "port", mf_option_string, set_port },
{ NULL }
};
static int
cb_debug(void *data, mu_config_value_t *arg)

Return to:

Send suggestions and report system problems to the System administrator.