diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2009-10-12 21:14:00 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2009-10-12 21:14:00 +0300 |
commit | af04ed630f18e9003756317cc627a11084d0d59a (patch) | |
tree | 828cf1fc2c326842777942441c14e853d9894cc7 /src/pies.c | |
parent | 989a5bbb74c3620abaa2191ce2c4f8d5968dbf0a (diff) | |
download | pies-af04ed630f18e9003756317cc627a11084d0d59a.tar.gz pies-af04ed630f18e9003756317cc627a11084d0d59a.tar.bz2 |
Do not require Mailutils. Provide missing functions.
* Makefile.am (ACLOCAL_AMFLAGS): Add grecs/am
* bootstrap.conf: Skip po.
Initialize submodule.
* configure.ac: Mailutils no longer needed.
(AC_CONFIG_FILES): Add new subdirs.
* gnulib.modules: Add more modules. Arrange entries
alphabetically.
* lib/Makefile.am: Rename library to libpies.
* lib/libpies.h (mf_privs)
(switch_to_privs, get_user_groups)
(mf_priv_setup, mf_epriv_setup): Move to src/pies.h
(config_array_to_argv, config_array_to_string)
(config_cb_timeout): Remove.
(tokendef): New struct.
(strtotok_len, strtotok_len_ci)
(strtotok, strtotok_ci, toktostr): New prototypes.
* lib/nls.c: Remove call to mu_init_nls.
* src/acl.c: New file.
* src/addrfmt.c: New file.
* src/diag.c: New file.
* src/meta.c: New file.
* src/url.c: New file.
* src/userprivs.c: New file.
* src/acl.h: New file.
* src/pp-setup: New file.
* src/Makefile.am (pies_SOURCES): Add acl.c,
addrfmt.c, diag.c, meta.c, url.c, userprivs.c.
(noinst_HEADERS): Add acl.h.
(inc_DATA): Add pp-setup.
* src/limits.c, src/meta1gram.y,
src/meta1lex.h, src/meta1lex.l,
src/pies.c, src/pies.h, src/progman.c,
src/socket.c, src/userprivs.c: Remove calls to
functions from Mailutils.
Diffstat (limited to 'src/pies.c')
-rw-r--r-- | src/pies.c | 1614 |
1 files changed, 941 insertions, 673 deletions
@@ -1,27 +1,29 @@ -/* This file is part of Mailfromd. +/* This file is part of Pies. Copyright (C) 2008, 2009 Sergey Poznyakoff - This program is free software; you can redistribute it and/or modify + Pies 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, + Pies 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/>. */ + along with Pies. If not, see <http://www.gnu.org/licenses/>. */ #include "pies.h" #include "meta1lex.h" -int log_to_stderr; /* Use stderr for logging */ -char *log_tag; /* override mu_log_tag */ -mu_log_level_t debug_level; -mu_debug_t pies_debug; -struct mf_privs pies_privs; +char *conffile = SYSCONFDIR "/pies.conf"; +int preprocess_only; /* Preprocess config, do nothing more */ +int lint_mode; /* Test configuration syntax and exit */ +int log_to_stderr; /* Use stderr for logging */ +int log_facility = LOG_USER; +char *log_tag; +struct pies_privs pies_privs; int foreground; int command; char *pidfile = STATEDIR "/pies.pid"; @@ -29,34 +31,21 @@ char *ctlfile = STATEDIR "/pies.ctl"; char *statfile = STATEDIR "/pies.stat"; mode_t pies_umask = 0; unsigned long shutdown_timeout = 5; -mu_acl_t pies_acl; +pies_acl_t pies_acl; limits_record_t pies_limits; int force_option; - + /* Logging */ void log_setup (int want_stderr) { - mu_debug_t debug; - - mu_diag_get_debug (&debug); - - if (log_tag) - mu_log_tag = log_tag; - if (!want_stderr) - { - openlog (MU_LOG_TAG (), LOG_PID, mu_log_facility); - mu_debug_set_print (debug, mu_diag_syslog_printer, NULL); - mu_debug_default_printer = mu_debug_syslog_printer; - } - else - mu_debug_default_printer = mu_debug_stderr_printer; + openlog (log_tag, LOG_PID, log_facility); } - + static int -stderr_closed_p() +stderr_closed_p () { int fd = dup (0); if (fd < 0) @@ -64,77 +53,90 @@ stderr_closed_p() close (fd); return fd <= 2; } - -static int -_cb_action (mu_debug_t debug, void *data, mu_config_value_t *arg) + +int +assert_grecs_value_type (grecs_locus_t * locus, + const grecs_value_t * value, int type) { - enum return_action *pact = data; - static struct mu_kwd actab[] = { - { "disable", action_disable }, - { "restart", action_restart }, - { NULL } - }; - int res; - - if (mu_cfg_assert_value_type (arg, MU_CFG_STRING, debug)) - return 1; - if (mu_kwd_xlat_name (actab, arg->v.string, &res)) + if (!value || value->type != type) { - mu_cfg_format_error (debug, MU_DEBUG_ERROR, - _("unknown action code: %s"), arg); - return 0; + grecs_error (locus, 0, _("expected %s, but found %s"), + grecs_data_type_string (type), + grecs_data_type_string (value->type)); + return 1; } - *pact = res; return 0; } +int +assert_scalar_stmt (grecs_locus_t * locus, enum grecs_callback_command cmd) +{ + if (cmd != grecs_callback_set_value) + { + grecs_error (locus, 0, _("Unexpected block statement")); + return 1; + } + return 0; +} + + static int -_cb_notify_addr (mu_debug_t debug, void *data, mu_config_value_t *arg) +_cb_action (enum grecs_callback_command cmd, + grecs_locus_t * locus, + void *varptr, grecs_value_t * value, void *cb_data) { - mu_address_t *paddr = data; - mu_address_t addr; - int rc; + enum return_action *pact = varptr; + static struct tokendef actab[] = { + {"disable", action_disable}, + {"restart", action_restart}, + {NULL} + }; + int res; - if (mu_cfg_assert_value_type (arg, MU_CFG_STRING, debug)) + if (assert_scalar_stmt (locus, cmd) + || assert_grecs_value_type (locus, value, GRECS_TYPE_STRING)) return 1; - rc = mu_address_create (&addr, arg->v.string); - if (rc) - mu_cfg_format_error (debug, MU_DEBUG_ERROR, - _("%s: invalid e-mail address: %s"), - arg->v.string, mu_strerror (rc)); - if (*paddr) + if (strtotok (actab, value->v.string, &res)) { - mu_address_union (paddr, addr); - mu_address_destroy (&addr); + grecs_error (locus, 0, _("unknown action code: %s"), value->v.string); + return 1; } - else - *paddr = addr; + *pact = res; return 0; } -struct mu_cfg_param return_code_cfg_param[] = { - { "action", mu_cfg_callback, NULL, - mu_offsetof (struct component, act_temp.act), _cb_action, - N_("Specifies action to take when a component finishes with this " - "return code."), - /* TRANSLATORS: disable and restart are keywords, do not translate them. */ - N_("arg: {disable | restart}") }, - { "notify", mu_cfg_callback, NULL, - mu_offsetof (struct component, act_temp.addr), _cb_notify_addr, - N_("Notify this address when then component terminates."), - N_("arg: email-list") }, - { "message", mu_cfg_string, NULL, - mu_offsetof (struct component, act_temp.message), NULL, - N_("Notification message text (with headers).") }, - { "exec", mu_cfg_string, NULL, - mu_offsetof (struct component, act_temp.command), NULL, - N_("Execute this command.") }, - { NULL } +struct grecs_keyword return_code_cfg_param[] = { + {"action", + /* TRANSLATORS: disable and restart are keywords, do not translate them. */ + N_("arg: {disable | restart}"), + N_("Specifies action to take when a component finishes with this " + "return code."), + grecs_type_string, NULL, offsetof (struct component, act_temp.act), + _cb_action, + }, + {"notify", + N_("arg: emails"), + N_("Notify this address when then component terminates."), + grecs_type_string, NULL, offsetof (struct component, act_temp.addr) + }, + {"message", + NULL, + N_("Notification message text (with headers)."), + grecs_type_string, NULL, offsetof (struct component, act_temp.message), + NULL}, + {"exec", + NULL, + N_("Execute this command."), + grecs_type_string, NULL, + offsetof (struct component, act_temp.command), + NULL, + }, + {NULL} }; #define S(s) { #s, s } -static struct mu_kwd ex_kwtab[] = { +static struct tokendef ex_tokendef[] = { S (EX_OK), S (EX_USAGE), S (EX_DATAERR), @@ -151,39 +153,39 @@ static struct mu_kwd ex_kwtab[] = { S (EX_PROTOCOL), S (EX_NOPERM), S (EX_CONFIG), - { NULL } + {NULL} }; -static struct mu_kwd sig_kwtab[] = { +static struct tokendef sig_tokendef[] = { S (SIGHUP), S (SIGINT), - S (SIGQUIT), - S (SIGILL), - S (SIGTRAP), - S (SIGABRT), - S (SIGIOT), - S (SIGBUS), - S (SIGFPE), - S (SIGKILL), - S (SIGUSR1), - S (SIGSEGV), - S (SIGUSR2), - S (SIGPIPE), - S (SIGALRM), + S (SIGQUIT), + S (SIGILL), + S (SIGTRAP), + S (SIGABRT), + S (SIGIOT), + S (SIGBUS), + S (SIGFPE), + S (SIGKILL), + S (SIGUSR1), + S (SIGSEGV), + S (SIGUSR2), + S (SIGPIPE), + S (SIGALRM), S (SIGTERM), #ifdef SIGSTKFLT S (SIGSTKFLT), #endif - S (SIGCHLD), - S (SIGCONT), + S (SIGCHLD), + S (SIGCONT), S (SIGSTOP), - S (SIGTSTP), - S (SIGTTIN), - S (SIGTTOU), + S (SIGTSTP), + S (SIGTTIN), + S (SIGTTOU), #ifdef SIGURG S (SIGURG), #endif -#ifdef SIGXCPU +#ifdef SIGXCPU S (SIGXCPU), #endif #ifdef SIGXFSZ @@ -210,14 +212,16 @@ static struct mu_kwd sig_kwtab[] = { #ifdef SIGSYS S (SIGSYS), #endif - { NULL } + {NULL} }; + #undef S static struct action * -create_action(struct component *comp, - mu_debug_t debug, mu_config_value_t *val, int argc, - const char *(*getarg) (mu_config_value_t *, int, mu_debug_t)) +create_action (struct component *comp, + grecs_locus_t * locus, + grecs_value_t * val, int argc, + const char *(*getarg) (grecs_value_t *, int, grecs_locus_t *)) { int i; unsigned *retv; @@ -226,24 +230,23 @@ create_action(struct component *comp, struct action *act; retv = xcalloc (argc, sizeof *retv); - if (argc == 0 || (argc == 1 && strcmp (getarg(val, 0, debug), "*") == 0)) + if (argc == 0 || (argc == 1 && strcmp (getarg (val, 0, locus), "*") == 0)) allflag = 1; else { for (i = 0; i < argc; i++) { unsigned n; - const char *arg = getarg(val, i, debug); + const char *arg = getarg (val, i, locus); size_t len = strlen (arg); - + if (isdigit (arg[0])) { char *p; n = strtoul (arg, &p, 0); if (*p) { - mu_cfg_format_error (debug, MU_DEBUG_ERROR, - _("%s: not a number"), p); + grecs_error (locus, 0, _("%s: not a number"), p); continue; } } @@ -255,26 +258,23 @@ create_action(struct component *comp, n = strtoul (arg + 4, &p, 0); if (*p) { - mu_cfg_format_error (debug, MU_DEBUG_ERROR, - _("%s: not a number"), p); + grecs_error (locus, 0, _("%s: not a number"), p); continue; } } - else if (mu_kwd_xlat_name_ci (sig_kwtab, arg, &n)) + else if (strtotok_ci (sig_tokendef, arg, &n)) { - mu_cfg_format_error (debug, MU_DEBUG_ERROR, - _("%s: not a signal code"), arg); + grecs_error (locus, 0, _("%s: not a signal code"), arg); continue; } n |= STATUS_SIG_BIT; - } - else if (mu_kwd_xlat_name_ci (ex_kwtab, arg, &n)) + } + else if (strtotok_ci (ex_tokendef, arg, &n)) { - mu_cfg_format_error (debug, MU_DEBUG_ERROR, - _("%s: not a return code"), arg); + grecs_error (locus, 0, _("%s: not a return code"), arg); continue; - } - + } + /* Alles in ordnung */ retv[retc++] = n; } @@ -301,7 +301,7 @@ create_action(struct component *comp, } const char * -_get_string_arg (mu_config_value_t *val, int num, mu_debug_t debug) +_get_string_arg (grecs_value_t * val, int num, grecs_locus_t * locus) { if (num != 0) return NULL; @@ -309,128 +309,130 @@ _get_string_arg (mu_config_value_t *val, int num, mu_debug_t debug) } const char * -_get_array_arg (mu_config_value_t *val, int num, mu_debug_t debug) +_get_array_arg (grecs_value_t * val, int num, grecs_locus_t * locus) { if (num < val->v.arg.c) { - if (mu_cfg_assert_value_type (&val->v.arg.v[num], MU_CFG_STRING, - debug) == 0) + if (assert_grecs_value_type (locus, val, GRECS_TYPE_STRING) == 0) return val->v.arg.v[num].v.string; } return NULL; } const char * -_get_list_arg (mu_config_value_t *val, int num, mu_debug_t debug) +_get_list_arg (grecs_value_t * val, int num, grecs_locus_t * locus) { - mu_config_value_t *elt; - int rc = mu_list_get (val->v.list, num, (void**)&elt); - if (rc) + grecs_value_t *elt = (grecs_value_t *) gl_list_get_at (val->v.list, num); + if (!elt) { - mu_cfg_format_error (debug, MU_DEBUG_ERROR, - _("cannot get list item: %s"), - mu_strerror (rc)); + grecs_error (locus, 0, _("cannot get list item")); } - else if (mu_cfg_assert_value_type (elt, MU_CFG_STRING, debug) == 0) + else if (assert_grecs_value_type (locus, elt, GRECS_TYPE_STRING) == 0) return elt->v.string; return NULL; } - + static int -return_code_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) +return_code_section_parser (enum grecs_callback_command cmd, + grecs_locus_t * locus, + void *varptr, + grecs_value_t * value, void *cb_data) { - struct component *comp = *section_data; + struct component *comp = varptr; size_t count; struct action *act; - if (!node->label) - { - mu_cfg_format_error (tree->debug, MU_DEBUG_ERROR, _("missing tag")); - return 1; - } - - switch (stage) + switch (cmd) { - case mu_cfg_section_start: - switch (node->label->type) + case grecs_callback_section_begin: + if (!value) { - case MU_CFG_STRING: - act = create_action (comp, tree->debug, node->label, - 1, - _get_string_arg); + grecs_error (locus, 0, _("missing tag")); + return 1; + } + + switch (value->type) + { + case GRECS_TYPE_STRING: + act = create_action (comp, locus, value, 1, _get_string_arg); break; - - case MU_CFG_ARRAY: - act = create_action (comp, tree->debug, node->label, - node->label->v.arg.c, - _get_array_arg); + + case GRECS_TYPE_ARRAY: + act = create_action (comp, locus, value, + value->v.arg.c, _get_array_arg); break; - case MU_CFG_LIST: - mu_list_count (node->label->v.list, &count); - act = create_action (comp, tree->debug, node->label, - count, - _get_list_arg); + case GRECS_TYPE_LIST: + count = gl_list_size (value->v.list); + act = create_action (comp, locus, value, count, _get_list_arg); } - + *(struct component **) cb_data = comp; if (!act) return 1; memset (&comp->act_temp, 0, sizeof (comp->act_temp)); break; - case mu_cfg_section_end: + case grecs_callback_section_end: act = comp->act_tail; act->act = comp->act_temp.act; act->addr = comp->act_temp.addr; act->message = comp->act_temp.message; act->command = comp->act_temp.command; break; + + case grecs_callback_set_value: + grecs_error (locus, 0, _("invalid use of block statement")); } return 0; } -void -return_code_cfg_init () +static char ** +config_array_to_argv (grecs_value_t *val, grecs_locus_t *locus) { - struct mu_cfg_section *section; - - if (mu_create_canned_section ("return-code", §ion)) - exit (EX_SOFTWARE); - section->parser = return_code_section_parser; - section->label = N_("<tag: exit-code-list>"); - mu_cfg_section_add_params (section, return_code_cfg_param); + int i, j; + int argc; + char **argv; + + argc = val->v.arg.c; + argv = xcalloc (argc + 1, sizeof (argv[0])); + for (i = j = 0; i < argc; i++) + { + if (assert_grecs_value_type (locus, &val->v.arg.v[i], GRECS_TYPE_STRING) + == 0) + argv[j++] = xstrdup (val->v.arg.v[i].v.string); + } + argv[j] = NULL; + return argv; } static int -_cb_command (mu_debug_t debug, void *data, mu_config_value_t *val) +_cb_command (enum grecs_callback_command cmd, + grecs_locus_t * locus, + void *varptr, grecs_value_t * value, void *cb_data) { int argc; - char **argv, ***pargv = data; - int rc; + char **argv, ***pargv = varptr; + struct wordsplit ws; - switch (val->type) + switch (value->type) { - case MU_CFG_STRING: - rc = mu_argcv_get (val->v.string, "", NULL, &argc, &argv); - if (rc) + case GRECS_TYPE_STRING: + if (wordsplit (value->v.string, &ws, WRDSF_DEFFLAGS)) { - mu_cfg_format_error (debug, MU_DEBUG_ERROR, - "mu_argcv_get: %s", mu_strerror (rc)); + grecs_error (locus, 0, "wordsplit: %s", strerror (errno)); return 1; } + argc = ws.ws_wordc; + argv = ws.ws_wordv; + ws.ws_wordv = NULL; break; - case MU_CFG_ARRAY: - argv = config_array_to_argv (val, debug); + case GRECS_TYPE_ARRAY: + argv = config_array_to_argv (value, locus); break; - case MU_CFG_LIST: - mu_cfg_format_error (debug, MU_DEBUG_ERROR, - _("unexpected list")); + case GRECS_TYPE_LIST: + grecs_error (locus, 0, _("unexpected list")); return 1; } *pargv = argv; @@ -438,19 +440,21 @@ _cb_command (mu_debug_t debug, void *data, mu_config_value_t *val) } static int -_cb_umask (mu_debug_t debug, void *data, mu_config_value_t *arg) +_cb_umask (enum grecs_callback_command cmd, + grecs_locus_t * locus, + void *varptr, grecs_value_t * value, void *cb_data) { - mode_t *pmode = data; + mode_t *pmode = varptr; char *p; unsigned long n; - if (mu_cfg_assert_value_type (arg, MU_CFG_STRING, debug)) + if (assert_scalar_stmt (locus, cmd) + || assert_grecs_value_type (locus, value, GRECS_TYPE_STRING)) return 1; - n = strtoul (arg->v.string, &p, 8); + n = strtoul (value->v.string, &p, 8); if (*p) { - mu_cfg_format_error (debug, MU_DEBUG_ERROR, - _("invalid octal number")); + grecs_error (locus, 0, _("invalid octal number")); return 1; } *pmode = n; @@ -458,310 +462,434 @@ _cb_umask (mu_debug_t debug, void *data, mu_config_value_t *arg) } static int -_cb_env (mu_debug_t debug, void *data, mu_config_value_t *val) +_cb_env (enum grecs_callback_command cmd, + grecs_locus_t * locus, + void *varptr, grecs_value_t * value, void *cb_data) { - int rc; int argc; char **argv; - char ***penv = data; - - switch (val->type) + char ***penv = varptr; + struct wordsplit ws; + + switch (value->type) { - case MU_CFG_STRING: - rc = mu_argcv_get_np (val->v.string, strlen (val->v.string), "", - NULL, 0, &argc, &argv, NULL); - if (rc) + case GRECS_TYPE_STRING: + if (wordsplit (value->v.string, &ws, WRDSF_DEFFLAGS)) { - mu_cfg_format_error (debug, MU_DEBUG_ERROR, - "mu_argcv_get: %s", mu_strerror (rc)); + grecs_error (locus, 0, "wordsplit: %s", strerror (errno)); return 1; } + argc = ws.ws_wordc; + argv = ws.ws_wordv; + ws.ws_wordv = NULL; break; - case MU_CFG_ARRAY: - argv = config_array_to_argv (val, debug); + case GRECS_TYPE_ARRAY: + argv = config_array_to_argv (value, locus); break; - - case MU_CFG_LIST: - mu_cfg_format_error (debug, MU_DEBUG_ERROR, _("unexpected list")); + + case GRECS_TYPE_LIST: + grecs_error (locus, 0, _("unexpected list")); return 1; } - + *penv = argv; return 0; } + + +int +string_to_syslog_priority (const char *key, int *pres) +{ + static struct tokendef tokdef_prio[] = { + {"EMERG", LOG_EMERG}, + {"ALERT", LOG_ALERT}, + {"CRIT", LOG_CRIT}, + {"ERR", LOG_ERR}, + {"WARNING", LOG_WARNING}, + {"NOTICE", LOG_NOTICE}, + {"INFO", LOG_INFO}, + {"DEBUG", LOG_DEBUG}, + {NULL} + }; + + return strtotok_ci (tokdef_prio, key, pres); +} + +int +string_to_syslog_facility (const char *key, int *pres) +{ + static struct tokendef tokdef_fac[] = { + {"auth", LOG_AUTH}, + {"authpriv", LOG_AUTHPRIV}, + {"cron", LOG_CRON}, + {"daemon", LOG_DAEMON}, + {"ftp", LOG_FTP}, + {"kern", LOG_KERN}, + {"lpr", LOG_LPR}, + {"mail", LOG_MAIL}, + {"news", LOG_NEWS}, + {"syslog", LOG_SYSLOG}, + {"user", LOG_USER}, + {"uucp", LOG_UUCP}, + {"local0", LOG_LOCAL0}, + {"local1", LOG_LOCAL1}, + {"local2", LOG_LOCAL2}, + {"local3", LOG_LOCAL3}, + {"local4", LOG_LOCAL4}, + {"local5", LOG_LOCAL5}, + {"local6", LOG_LOCAL6}, + {"local7", LOG_LOCAL7}, + {NULL} + }; + + return strtotok_ci (tokdef_fac, key, pres); +} static int -_cb_facility (mu_debug_t debug, void *data, mu_config_value_t *val) +cb_syslog_facility (enum grecs_callback_command cmd, + grecs_locus_t * locus, + void *varptr, grecs_value_t * value, void *cb_data) { - if (mu_cfg_assert_value_type (val, MU_CFG_STRING, debug)) + const char *str; + + if (assert_grecs_value_type (locus, value, GRECS_TYPE_STRING)) return 1; - - if (mu_string_to_syslog_facility (val->v.string, data)) + str = value->v.string; + if (c_isdigit (str[0])) { - mu_cfg_format_error (debug, MU_DEBUG_ERROR, - _("unknown syslog facility `%s'"), - val->v.string); - return 1; + char *p; + int n = strtoul (str, &p, 10); + if (*p) + grecs_error (locus, 0, + _("expected facility number or symbolic name")); + else + *(int *) varptr = n; } - return 0; + else if (string_to_syslog_facility (str, varptr)) + grecs_error (locus, 0, _("unknown syslog facility `%s'"), str); + return 0; } static int -_cb_redir (mu_debug_t debug, void *data, mu_config_value_t *arg) +_cb_redir (enum grecs_callback_command cmd, + grecs_locus_t * locus, + void *varptr, grecs_value_t * value, void *cb_data) { - struct redirector *rp = data; - static struct mu_kwd redirtab[] = { - { "null", redir_null }, - { "syslog", redir_syslog }, - { "file", redir_file }, - { NULL } + struct redirector *rp = varptr; + static struct tokendef redirtab[] = { + {"null", redir_null}, + {"syslog", redir_syslog}, + {"file", redir_file}, + {NULL} }; int res; - - switch (arg->type) + + switch (value->type) { - case MU_CFG_STRING: - if (strcmp (arg->v.string, "null") == 0) + case GRECS_TYPE_STRING: + if (strcmp (value->v.string, "null") == 0) { rp->type = redir_null; break; } rp->type = redir_syslog; - if (mu_string_to_syslog_priority (arg->v.string, &rp->v.prio)) + if (string_to_syslog_priority (value->v.string, &rp->v.prio)) { - mu_cfg_format_error (debug, MU_DEBUG_ERROR, - _("unknown syslog priority `%s'"), - arg); + grecs_error (locus, 0, _("unknown syslog priority `%s'"), + value->v.string); return 0; } break; - case MU_CFG_ARRAY: - if (mu_cfg_assert_value_type (&arg->v.arg.v[0], MU_CFG_STRING, debug)) + case GRECS_TYPE_ARRAY: + if (assert_grecs_value_type (locus, &value->v.arg.v[0], + GRECS_TYPE_STRING)) return 0; - if (mu_kwd_xlat_name (redirtab, arg->v.arg.v[0].v.string, &res)) - mu_cfg_format_error (debug, MU_DEBUG_ERROR, - _("%s: unrecognised redirector type"), - arg->v.arg.v[0].v.string); + if (strtotok (redirtab, value->v.arg.v[0].v.string, &res)) + grecs_error (locus, 0, _("%s: unrecognised redirector type"), + value->v.arg.v[0].v.string); else { if (res != redir_null) { - if (arg->v.arg.c != 2) + if (value->v.arg.c != 2) { - mu_cfg_format_error (debug, MU_DEBUG_ERROR, - _("wrong number of arguments")); + grecs_error (locus, 0, _("wrong number of arguments")); return 0; } - if (mu_cfg_assert_value_type (&arg->v.arg.v[1], MU_CFG_STRING, - debug)) + if (assert_grecs_value_type (locus, &value->v.arg.v[1], + GRECS_TYPE_STRING)) return 0; - + switch (res) { case redir_null: break; - + case redir_syslog: - if (mu_string_to_syslog_priority (arg->v.arg.v[1].v.string, - &rp->v.prio)) + if (string_to_syslog_priority (value->v.arg.v[1].v.string, + &rp->v.prio)) { - mu_cfg_format_error (debug, MU_DEBUG_ERROR, - _("unknown syslog priority `%s'"), - arg->v.arg.v[1].v.string); + grecs_error (locus, 0, + _("unknown syslog priority `%s'"), + value->v.arg.v[1].v.string); return 0; } break; - + case redir_file: - rp->v.file = xstrdup (arg->v.arg.v[1].v.string); + rp->v.file = xstrdup (value->v.arg.v[1].v.string); break; } } rp->type = res; } break; - + default: - mu_cfg_format_error (debug, MU_DEBUG_ERROR, _("unexpected list")); + grecs_error (locus, 0, _("unexpected list")); } - + return 0; } static int -_cb_url (mu_debug_t debug, void *data, mu_config_value_t *arg) +_cb_url (enum grecs_callback_command cmd, + grecs_locus_t * locus, + void *varptr, grecs_value_t * value, void *cb_data) { - int rc; - mu_url_t url; - - if (mu_cfg_assert_value_type (arg, MU_CFG_STRING, debug)) + struct pies_url *url; + + if (assert_scalar_stmt (locus, cmd) + || assert_grecs_value_type (locus, value, GRECS_TYPE_STRING)) return 1; - rc = mu_url_create (&url, arg->v.string); - if (rc) + if (pies_url_create (&url, value->v.string)) { - mu_cfg_format_error (debug, MU_DEBUG_ERROR, - _("%s: cannot create URL: %s"), - arg->v.string, - mu_strerror (rc)); + grecs_error (locus, 0, _("%s: cannot create URL: %s"), + value->v.string, strerror (errno)); return 0; } - rc = mu_url_parse (url); - if (rc) - { - mu_cfg_format_error (debug, MU_DEBUG_ERROR, - _("%s: cannot parse URL: %s"), - arg->v.string, - mu_strerror (rc)); - mu_url_destroy (&url); - return 0; - } - *(mu_url_t*) data = url; + *(struct pies_url **) varptr = url; return 0; } -static struct mu_kwd modetab[] = { - { "exec", pies_comp_exec }, - { "wait", pies_comp_exec }, - { "accept", pies_comp_accept }, - { "inetd", pies_comp_inetd }, - { "nostartaccept", pies_comp_inetd }, - { "pass-fd", pies_comp_pass_fd }, - { "pass", pies_comp_pass_fd }, - { NULL } +static struct tokendef modetab[] = { + {"exec", pies_comp_exec}, + {"wait", pies_comp_exec}, + {"accept", pies_comp_accept}, + {"inetd", pies_comp_inetd}, + {"nostartaccept", pies_comp_inetd}, + {"pass-fd", pies_comp_pass_fd}, + {"pass", pies_comp_pass_fd}, + {NULL} }; static int -_cb_mode (mu_debug_t debug, void *data, mu_config_value_t *arg) +_cb_mode (enum grecs_callback_command cmd, + grecs_locus_t * locus, + void *varptr, grecs_value_t * value, void *cb_data) { int res; - - if (mu_cfg_assert_value_type (arg, MU_CFG_STRING, debug)) + + if (assert_scalar_stmt (locus, cmd) + || assert_grecs_value_type (locus, value, GRECS_TYPE_STRING)) return 1; - if (mu_kwd_xlat_name (modetab, arg->v.string, &res)) - mu_cfg_format_error (debug, MU_DEBUG_ERROR, - _("%s: unrecognised mode"), - arg->v.string); + if (strtotok (modetab, value->v.string, &res)) + grecs_error (locus, 0, _("%s: unrecognised mode"), value->v.string); else - *(enum pies_comp_mode *)data = res; + *(enum pies_comp_mode *) varptr = res; return 0; } static int -_cb_limits (mu_debug_t debug, void *data, mu_config_value_t *arg) +_cb_limits (enum grecs_callback_command cmd, + grecs_locus_t * locus, + void *varptr, grecs_value_t * value, void *cb_data) { - limits_record_t *plrec = data; + limits_record_t *plrec = varptr; char *p; - - if (mu_cfg_assert_value_type (arg, MU_CFG_STRING, debug)) + + if (assert_scalar_stmt (locus, cmd) + || assert_grecs_value_type (locus, value, GRECS_TYPE_STRING)) return 1; - if (parse_limits (plrec, (char*) arg->v.string, &p)) - mu_cfg_format_error (debug, MU_DEBUG_ERROR, - _("invalid limit string (near %s)"), - p); + if (parse_limits (plrec, (char *) value->v.string, &p)) + grecs_error (locus, 0, _("invalid limit string (near %s)"), p); return 0; } -struct mu_cfg_param component_cfg_param[] = { - { "mode", mu_cfg_callback, NULL, - mu_offsetof (struct component, mode), _cb_mode, - N_("Component execution mode."), - /* TRANSLATORS: The words between '{' and '}' are keywords, do not - translate them. */ - N_("mode: {exec | wait | accept | inetd | nostartaccept | pass-fd | pass}") - }, - { "program", mu_cfg_string, NULL, - mu_offsetof (struct component, program), NULL, - N_("Full name of the program.") }, - { "command", mu_cfg_callback, NULL, - mu_offsetof (struct component, argv), _cb_command, - N_("Command line.") }, - { "prerequisites", MU_CFG_LIST_OF(mu_cfg_string), NULL, - mu_offsetof (struct component, prereq), NULL, - N_("List of prerequisites."), - N_("list") }, - { "dependents", MU_CFG_LIST_OF(mu_cfg_string), NULL, - mu_offsetof (struct component, depend), NULL, - N_("List of components for which this one is a prerequisite."), - N_("list") }, - { "disable", mu_cfg_bool, NULL, - mu_offsetof (struct component, disabled), NULL, - N_("Disable this entry.") }, - { "settle-timeout", mu_cfg_uint, NULL, - mu_offsetof (struct component, settle_timeout), NULL, - N_("Time to wait before starting this component.") }, - { "precious", mu_cfg_bool, NULL, - mu_offsetof (struct component, precious), NULL, - N_("Mark this entry as precious.") }, - { "socket", mu_cfg_callback, NULL, - mu_offsetof (struct component, socket_url), _cb_url, - N_("Listen on the given url."), - N_("url: string") }, - { "pass-fd-socket", mu_cfg_string, NULL, - mu_offsetof (struct component, pass_fd_socket), NULL, - N_("Pass fd through this socket."), - N_("name") }, - { "acl", mu_cfg_section, NULL, mu_offsetof (struct component, acl), NULL, - N_("Per-component access control list") }, - { "remove-file", mu_cfg_string, NULL, - mu_offsetof (struct component, rmfile), NULL, - N_("Remove file before starting the component."), - N_("file") }, - { "facility", mu_cfg_callback, NULL, - mu_offsetof (struct component, facility), _cb_facility, - N_("Override default syslog facility for this component."), - N_("arg") }, - { "stdout", mu_cfg_callback, NULL, - mu_offsetof (struct component, redir[RETR_OUT]), _cb_redir, - N_("Redirect program's standard output to the given file or " - "syslog priority."), - /* TRANSLATORS: file and syslog are keywords. Do not translate them. */ - N_("type: {file | syslog}> <channel: string") - }, - { "stderr", mu_cfg_callback, NULL, - mu_offsetof (struct component, redir[RETR_ERR]), _cb_redir, - N_("Redirect program's standard error to the given file or " - "syslog priority."), - /* TRANSLATORS: file and syslog are keywords. Do not translate them. */ - N_("type: {file | syslog}> <channel: string") - }, - { "user", mu_cfg_string, NULL, - mu_offsetof (struct component, privs.user), NULL, - N_("Run with this user privileges.") }, - { "group", MU_CFG_LIST_OF(mu_cfg_string), NULL, - mu_offsetof (struct component, privs.groups), NULL, - N_("Retain supplementary group.") }, - { "allgroups", mu_cfg_bool, NULL, - mu_offsetof (struct component, privs.allgroups), NULL, - N_("Retain all supplementary groups of which user is a member.") }, - { "umask", mu_cfg_callback, NULL, - mu_offsetof (struct component, umask), _cb_umask, - N_("Force this umask."), - N_("arg: number") }, - { "limits", mu_cfg_callback, NULL, - mu_offsetof (struct component, limits), _cb_limits, - N_("Set system limits") }, - { "env", mu_cfg_callback, NULL, - mu_offsetof (struct component, env), _cb_env, - N_("Set program environment. Argument is a list of assignments " - "separated by white space."), - N_("arg: list") }, - { "chdir", mu_cfg_string, NULL, - mu_offsetof (struct component, dir), NULL, - N_("Change to this directory before executing the component."), - N_("dir") }, - { "return-code", mu_cfg_section }, - { NULL } +struct grecs_keyword component_cfg_param[] = { + {"mode", + /* TRANSLATORS: The words between '{' and '}' are keywords, do not + translate them. */ + N_ + ("mode: {exec | wait | accept | inetd | nostartaccept | pass-fd | pass}"), + N_("Component execution mode."), + grecs_type_string, NULL, offsetof (struct component, mode), + _cb_mode, + }, + {"program", + NULL, + N_("Full name of the program."), + grecs_type_string, NULL, + offsetof (struct component, program), + NULL, + }, + {"command", + NULL, + N_("Command line."), + grecs_type_string, NULL, offsetof (struct component, argv), + _cb_command, + }, + {"prerequisites", + N_("list"), + N_("List of prerequisites."), + grecs_type_string | GRECS_LIST, NULL, offsetof (struct component, prereq), + NULL, + }, + {"dependents", + N_("list"), + N_("List of components for which this one is a prerequisite."), + grecs_type_string | GRECS_LIST, NULL, offsetof (struct component, depend), + NULL, + }, + {"disable", + NULL, + N_("Disable this entry."), + grecs_type_bool, NULL, offsetof (struct component, disabled), + NULL, + }, + {"settle-timeout", + NULL, + N_("Time to wait before starting this component."), + grecs_type_uint, NULL, + offsetof (struct component, settle_timeout), + NULL, + }, + {"precious", + NULL, + N_("Mark this entry as precious."), + grecs_type_bool, NULL, + offsetof (struct component, precious), + NULL, + }, + {"socket", + N_("url: string"), + |