aboutsummaryrefslogtreecommitdiff
path: root/src/pies.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pies.c')
-rw-r--r--src/pies.c1614
1 files changed, 941 insertions, 673 deletions
diff --git a/src/pies.c b/src/pies.c
index 10862c2..f36c21f 100644
--- a/src/pies.c
+++ b/src/pies.c
@@ -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", &section))
- 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"),
+ N_("Listen on the given url."),
+ grecs_type_string, NULL,
+ offsetof (struct component, socket_url),
+ _cb_url,
+ },
+ {"pass-fd-socket",
+ N_("name"),
+ N_("Pass fd through this socket."),
+ grecs_type_string, NULL,
+ offsetof (struct component, pass_fd_socket),
+ NULL,
+ },
+ {"acl",
+ N_("name: string"),
+ N_("Define ACL."),
+ grecs_type_section, NULL, 0,
+ acl_section_parser, NULL, acl_keywords},
+ {"remove-file",
+ N_("file"),
+ N_("Remove file before starting the component."),
+ grecs_type_string, NULL, offsetof (struct component, rmfile),
+ NULL,
+ },
+ {"facility",
+ N_("arg"),
+ N_("Override default syslog facility for this component."),
+ grecs_type_string, NULL, offsetof (struct component, facility),
+ cb_syslog_facility,
+ },
+ {"stdout",
+ /* TRANSLATORS: file and syslog are keywords. Do not translate them. */
+ N_("type: {file | syslog}> <channel: string"),
+ N_("Redirect program's standard output to the given file or "
+ "syslog priority."),
+ grecs_type_string, NULL, offsetof (struct component, redir[RETR_OUT]),
+ _cb_redir,
+ },
+ {"stderr",
+ /* TRANSLATORS: file and syslog are keywords. Do not translate them. */
+ N_("type: {file | syslog}> <channel: string"),
+ N_("Redirect program's standard error to the given file or "
+ "syslog priority."),
+ grecs_type_string, NULL, offsetof (struct component, redir[RETR_ERR]),
+ _cb_redir,
+ },
+ {"user",
+ NULL,
+ N_("Run with this user privileges."),
+ grecs_type_string, NULL, offsetof (struct component, privs.user),
+ NULL,
+ },
+ {"group",
+ NULL,
+ N_("Retain supplementary group."),
+ grecs_type_string | GRECS_LIST, NULL, offsetof (struct component,
+ privs.groups),
+ NULL,
+ },
+ {"allgroups",
+ NULL,
+ N_("Retain all supplementary groups of which user is a member."),
+ grecs_type_bool, NULL, offsetof (struct component, privs.allgroups),
+ NULL,
+ },
+ {"umask",
+ N_("arg: number"),
+ N_("Force this umask."),
+ grecs_type_string, NULL, offsetof (struct component, umask),
+ _cb_umask,
+ },
+ {"limits",
+ NULL,
+ N_("Set system limits"),
+ grecs_type_string, NULL, offsetof (struct component, limits),
+ _cb_limits,
+ },
+ {"env",
+ N_("arg: list"),
+ N_("Set program environment. Argument is a list of assignments "
+ "separated by white space."),
+ grecs_type_string, NULL, offsetof (struct component, env),
+ _cb_env,
+ },
+ {"chdir",
+ N_("dir"),
+ N_("Change to this directory before executing the component."),
+ grecs_type_string, NULL, offsetof (struct component, dir),
+ NULL,
+ },
+ {"return-code",
+ N_("<tag: exit-code-list>"),
+ NULL, /* FIXME: Docstring? */
+ grecs_type_section, NULL, 0,
+ return_code_section_parser, NULL, return_code_cfg_param},
+ {NULL}
};
+struct grecs_keyword *
+find_component_keyword (const char *ident)
+{
+ struct grecs_keyword *kwp;
+
+ for (kwp = component_cfg_param; kwp->ident; kwp++)
+ if (strcmp (kwp->ident, ident) == 0)
+ return kwp;
+ return NULL;
+}
+
static char *
make_full_name (const char *dir, const char *file)
{
char *p;
size_t len = strlen (dir);
-
- while (len > 0 && dir[len-1] == '/')
+
+ while (len > 0 && dir[len - 1] == '/')
len--;
p = xmalloc (len + 1 + strlen (file) + 1);
memcpy (p, dir, len);
@@ -771,7 +899,7 @@ make_full_name (const char *dir, const char *file)
}
static int
-component_verify (struct component *comp, mu_debug_t debug)
+component_verify (struct component *comp, grecs_locus_t * locus)
{
int header = 0;
int i;
@@ -780,14 +908,13 @@ component_verify (struct component *comp, mu_debug_t debug)
{ \
if (!header) \
{ \
- mu_cfg_format_error (debug, MU_DEBUG_ERROR, \
- _("in component %s:"), comp->tag); \
+ grecs_error (locus, 0, _("in component %s:"), comp->tag); \
header = 1; \
} \
- mu_cfg_format_error (debug, MU_DEBUG_ERROR, fmt, arg); \
+ grecs_error (locus, 0, fmt, arg); \
} \
while (0)
-
+
if (!comp->argv)
COMPERR ("%s", _("missing command line"));
if (comp->pass_fd_socket && comp->mode != pies_comp_pass_fd)
@@ -795,10 +922,10 @@ component_verify (struct component *comp, mu_debug_t debug)
switch (comp->mode)
{
case pies_comp_exec:
- if (comp->socket_url)
+ if (comp->socket_url)
COMPERR ("%s", _("socket ignored: wrong mode"));
break;
-
+
case pies_comp_pass_fd:
if (!comp->pass_fd_socket)
COMPERR ("%s", _("must supply pass-fd-socket in this mode"));
@@ -807,7 +934,7 @@ component_verify (struct component *comp, mu_debug_t debug)
if (comp->dir)
{
char *p = make_full_name (comp->dir, comp->pass_fd_socket);
- free (comp->pass_fd_socket);
+ //free (comp->pass_fd_socket);
comp->pass_fd_socket = p;
}
else
@@ -815,7 +942,7 @@ component_verify (struct component *comp, mu_debug_t debug)
"file name or chdir must be specified"));
}
/* Fall through */
-
+
case pies_comp_accept:
case pies_comp_inetd:
if (!comp->socket_url)
@@ -825,7 +952,7 @@ component_verify (struct component *comp, mu_debug_t debug)
return 1;
}
}
-
+
if (comp->mode != pies_comp_exec
&& comp->redir[RETR_OUT].type != redir_null)
{
@@ -835,7 +962,8 @@ component_verify (struct component *comp, mu_debug_t debug)
for (i = RETR_OUT; i <= RETR_ERR; i++)
{
- if (comp->redir[i].type == redir_file && comp->redir[i].v.file[0] != '/')
+ if (comp->redir[i].type == redir_file
+ && comp->redir[i].v.file[0] != '/')
{
if (comp->dir)
{
@@ -849,162 +977,227 @@ component_verify (struct component *comp, mu_debug_t debug)
comp->redir[i].v.file);
}
}
-
+
return header;
#undef COMPERR
}
+struct component *
+component_create (const char *name)
+{
+ struct component *comp = progman_lookup_component (name);
+ if (!comp)
+ {
+ comp = xzalloc (sizeof (*comp));
+ comp->facility = log_facility;
+ comp->redir[RETR_OUT].type = comp->redir[RETR_ERR].type = redir_null;
+ comp->tag = xstrdup (name);
+ }
+ return comp;
+}
+
+void
+component_finish (struct component *comp, grecs_locus_t *locus)
+{
+ if (component_verify (comp, locus) == 0)
+ {
+ /* FIXME: The prog list is traversed twice for each component
+ statement, this is suboptimal. */
+ if (progman_lookup_component (comp->tag) == NULL)
+ register_prog (comp);
+ }
+}
+
static int
-component_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)
+component_section_parser (enum grecs_callback_command cmd,
+ grecs_locus_t * locus,
+ void *varptr, grecs_value_t * value, void *cb_data)
{
struct component *comp;
+ void **section_data = cb_data;
- switch (stage)
+ switch (cmd)
{
- case mu_cfg_section_start:
- if (node->label
- && mu_cfg_assert_value_type (node->label, MU_CFG_STRING,
- tree->debug))
+ case grecs_callback_section_begin:
+ if (assert_grecs_value_type (locus, value, GRECS_TYPE_STRING))
return 1;
- comp = progman_lookup_component (node->label->v.string);
- if (!comp)
- {
- comp = xzalloc (sizeof (*comp));
- comp->facility = mu_log_facility;
- comp->redir[RETR_OUT].type = comp->redir[RETR_ERR].type = redir_null;
- comp->tag = node->label ? xstrdup (node->label->v.string) : NULL;
- }
+ comp = component_create (value->v.string);
*section_data = comp;
break;
- case mu_cfg_section_end:
+ case grecs_callback_section_end:
comp = *(struct component **) section_data;
- if (component_verify (comp, tree->debug) == 0)
- {
- /* FIXME: The prog list is traversed twice for each component
- statement, this is suboptimal. */
- if (progman_lookup_component (comp->tag) == NULL)
- register_prog (comp);
- }
+ component_finish (comp, locus);
}
return 0;
}
+
-void
-component_cfg_init ()
-{
- struct mu_cfg_section *section;
-
- if (mu_create_canned_section ("component", &section))
- exit (EX_SOFTWARE);
- section->parser = component_section_parser;
- section->label = N_("<tag: string>");
- mu_cfg_section_add_params (section, component_cfg_param);
-}
-
-
+/* syslog */
+static struct grecs_keyword syslog_kw[] = {
+ {"facility",
+ N_("name"),
+ N_("Set syslog facility. Arg is one of the following: user, daemon, "
+ "auth, authpriv, mail, cron, local0 through local7 (case-insensitive), "
+ "or a facility number."),
+ grecs_type_string, &log_facility, 0, cb_syslog_facility},
+ {"tag", N_("string"), N_("Tag syslog messages with this string"),
+ grecs_type_string, &log_tag},
+# if 0
+ {"print-priority", N_("arg"), N_("Prefix each message with its priority"),
+ grecs_type_bool, &syslog_include_prio},
+#endif
+ {NULL},
+};
+
struct component default_component;
static int
-_cb_debug (mu_debug_t debug, void *data, mu_config_value_t *arg)
+_cm_include_meta1 (enum grecs_callback_command cmd,
+ grecs_locus_t *locus,
+ void *varptr, grecs_value_t *value, void *cb_data)
{
- int rc;
-
- if (mu_cfg_assert_value_type (arg, MU_CFG_STRING, debug))
+ if (assert_grecs_value_type (locus, value, GRECS_TYPE_STRING))
return 1;
- rc = mu_debug_level_from_string (arg->v.string, &debug_level, debug);
- if (rc)
- return 0;
- if (!pies_debug)
- mu_debug_create (&pies_debug, NULL);
- mu_debug_set_level (pies_debug, debug_level);
+ meta1_config_parse (value->v.string);
return 0;
}
-static int _cm_include_meta1 (mu_debug_t, void *, mu_config_value_t *);
-
-struct mu_cfg_param pies_cfg_param[] = {
- { "component", mu_cfg_section },
- { "debug", mu_cfg_callback, NULL, 0, _cb_debug,
- N_("Set debug verbosity level.") },
- { "pidfile", mu_cfg_string, &pidfile, 0, NULL,
- N_("Write PID to this file.") },
- { "control-file", mu_cfg_string, &ctlfile, 0, NULL,
- N_("Set location of the control file.") },
- { "stat-file", mu_cfg_string, &statfile, 0, NULL,
- N_("Set location of the statistics output file.") },
- { "user", mu_cfg_string, &pies_privs.user, 0, NULL,
- N_("Run with this user privileges.") },
- { "group", MU_CFG_LIST_OF(mu_cfg_string), &pies_privs.groups, 0, NULL,
- N_("Retain supplementary group.") },
- { "allgroups", mu_cfg_bool, &pies_privs.allgroups, 0, NULL,
- N_("Retain all supplementary groups of which user is a member.") },
- { "umask", mu_cfg_callback, &pies_umask, 0, _cb_umask,
- N_("Force this umask."),
- N_("arg: number") },
- { "limits", mu_cfg_callback, &pies_limits, 0, _cb_limits,
- N_("Set global system limits.") },
- { "shutdown-timeout", mu_cfg_uint, &shutdown_timeout, 0, NULL,
- N_("Wait <n> seconds for all components to shut down."),
- "n" },
- { "return-code", mu_cfg_section, &default_component },
- { "acl", mu_cfg_section, &pies_acl, 0, NULL,
- N_("Global access control list") },
- { "include-meta1", mu_cfg_callback, NULL, 0, _cm_include_meta1,
- N_("Include components from the specified MeTA1 configuration file."),
- N_("file: string") },
- { "meta1-queue-dir", mu_cfg_string, &meta1_queue_dir, 0, NULL,
- N_("Set name of MeTA1 queue directory (default /var/spool/meta1).") },
- { NULL }
+struct grecs_keyword pies_cfg_param[] = {
+ /* FIXME */
+ {"component",
+ N_("<tag: string>"),
+ NULL, /* FIXME: Docstring */
+ grecs_type_section, NULL, 0,
+ component_section_parser, NULL, component_cfg_param},
+ {"syslog",
+ NULL,
+ N_("Configure syslog logging"),
+ grecs_type_section, NULL, 0, NULL, NULL, syslog_kw},
+ {"debug",
+ NULL,
+ N_("Set debug verbosity level."),
+ grecs_type_uint, &debug_level, 0, NULL},
+ {"source-info",
+ NULL,
+ N_("Show source info with debugging messages."),
+ grecs_type_bool, &source_info_option, 0, NULL},
+ {"pidfile",
+ NULL,
+ N_("Write PID to this file."),
+ grecs_type_string, &pidfile, 0,
+ NULL,
+ },
+ {"control-file",
+ NULL,
+ N_("Set location of the control file."),
+ grecs_type_string, &ctlfile, 0,
+ NULL,
+ },
+ {"stat-file",
+ NULL,
+ N_("Set location of the statistics output file."),
+ grecs_type_string, &statfile, 0,
+ NULL,
+ },
+ {"user",
+ NULL,
+ N_("Run with this user privileges."),
+ grecs_type_string, &pies_privs.user, 0,
+ NULL,
+ },
+ {"group",
+ NULL,
+ N_("Retain supplementary group."),
+ grecs_type_string | GRECS_LIST, /*FIXME*/ &pies_privs.groups, 0,
+ NULL,
+ },
+ {"allgroups",
+ NULL,
+ N_("Retain all supplementary groups of which user is a member."),
+ grecs_type_bool, &pies_privs.allgroups, 0,
+ NULL,
+ },
+ {"umask",
+ N_("arg: number"),
+ N_("Force this umask."),
+ grecs_type_string, &pies_umask, 0,
+ _cb_umask,
+ },
+ {"limits",
+ NULL,
+ N_("Set global system limits."),
+ grecs_type_string, &pies_limits, 0, _cb_limits,
+ },
+ {"shutdown-timeout",
+ "n",
+ N_("Wait <n> seconds for all components to shut down."),
+ grecs_type_uint, &shutdown_timeout, 0,
+ NULL,
+ },
+ {"return-code",
+ N_("<tag: exit-code-list>"),
+ NULL, /* FIXME: Docstring? */
+ grecs_type_section, &default_component, 0,
+ return_code_section_parser, NULL, return_code_cfg_param},
+ {"acl",
+ N_("name: string"),
+ N_("Define ACL."),
+ grecs_type_section, NULL, 0,
+ acl_section_parser, NULL, acl_keywords},
+ {"include-meta1",
+ N_("file: string"),
+ N_("Include components from the specified MeTA1 configuration file."),
+ grecs_type_string, NULL, 0,
+ _cm_include_meta1,
+ },
+ {"meta1-queue-dir",
+ NULL,
+ N_("Set name of MeTA1 queue directory (default /var/spool/meta1)."),
+ grecs_type_string, &meta1_queue_dir, 0,
+ NULL,
+ },
+ {NULL}
};
-static int
-_cm_include_meta1 (mu_debug_t debug, void *data, mu_config_value_t *arg)
+void
+config_init ()
{
- int flags = 0;
-
- if (mu_cfg_assert_value_type (arg, MU_CFG_STRING, debug))
- return 1;
- if (meta1_config_parse (arg->v.string) == 0)
- {
- if (mu_cfg_parser_verbose)
- flags |= MU_PARSE_CONFIG_VERBOSE;
- if (mu_cfg_parser_verbose > 1)
- flags |= MU_PARSE_CONFIG_DUMP;
- mu_cfg_tree_reduce (meta1_parse_tree, mu_program_name, pies_cfg_param,
- flags, NULL);
- }
- return 0;
+ grecs_set_keywords (pies_cfg_param);
+ grecs_include_path_setup (DEFAULT_VERSION_INCLUDE_DIR,
+ DEFAULT_INCLUDE_DIR, NULL);
+ grecs_preprocessor = DEFAULT_PREPROCESSOR;
+ grecs_log_to_stderr = log_to_stderr;
}
-
+void
+config_help ()
+{
+ static char docstring[] =
+ N_("Configuration file structure for pies.\n"
+ "For more information, use `info pies configuration'.");
+ grecs_format_docstring (stdout, docstring, 0);
+ grecs_format_statement_array (stdout, pies_cfg_param, 1, 0);
+}
+
const char *program_version = "pies (" PACKAGE_STRING ")";
const char *package_bugreport = "<" PACKAGE_BUGREPORT ">";
static char doc[] = N_("pies -- process invocation and execution supervisor");
static char args_doc[] = "";
-static const char *capa[] = {
- "common",
- "logging",
- "mailer",
- "debug",
- NULL
-};
-
-enum {
- OPT_FOREGROUND=256,
+enum
+{
+ OPT_FOREGROUND = 256,
OPT_LOG_TAG,
OPT_SYSLOG,
OPT_STDERR,
OPT_DUMP_PREREQ,
OPT_DUMP_DEPMAP,
- OPT_FORCE
+ OPT_FORCE,
+ OPT_CONFIG_HELP,
+ OPT_SOURCE_INFO
};
#define OPT_RESTART 'R'
@@ -1014,53 +1207,77 @@ enum {
static struct argp_option options[] = {
#define GRP 0
- { "foreground", OPT_FOREGROUND, 0, 0, N_("remain in foreground"), GRP+1},
- { "stderr", OPT_STDERR, NULL, 0, N_("log to stderr"), },
- { "syslog", OPT_SYSLOG, NULL, 0, N_("log to syslog"), },
- { "log-tag", OPT_LOG_TAG, N_("STRING"), 0,
- N_("set the identifier used in syslog messages to STRING"), GRP+1 },
- { "debug", 'x', N_("LEVEL"), 0,
- N_("set debug verbosity level"), GRP+1 },
- { "force", OPT_FORCE, NULL, 0,
- N_("force startup even if another instance may be running"), GRP+1 },
+ {"foreground", OPT_FOREGROUND, 0, 0, N_("remain in foreground"), GRP + 1},
+ {"stderr", OPT_STDERR, NULL, 0, N_("log to stderr"),},
+ {"syslog", OPT_SYSLOG, NULL, 0, N_("log to syslog"),},
+ {"log-tag", OPT_LOG_TAG, N_("STRING"), 0,
+ N_("set the identifier used in syslog messages to STRING"), GRP + 1},
+ {"debug", 'x', N_("LEVEL"), 0,
+ N_("set debug verbosity level"), GRP + 1},
+ {"source-info", OPT_SOURCE_INFO, NULL, 0,
+ N_("show source info with debugging messages"), GRP + 1},
+ {"force", OPT_FORCE, NULL, 0,
+ N_("force startup even if another instance may be running"), GRP + 1},
+ {"lint", 't', NULL, 0,
+ N_("parse configuration file and exit"), GRP + 1},
+ {NULL, 'E', NULL, 0,
+ N_("preprocess config and exit"), GRP + 1},
+ {"config-file", 'c', N_("FILE"), 0,
+ N_("use FILE instead of the default configuration"), GRP + 1},
+ {"config-help", OPT_CONFIG_HELP, NULL, 0,
+ N_("show configuration file summary"), GRP + 1},
#undef GRP
#define GRP 10
- { "restart-component", OPT_RESTART, NULL, 0,
- N_("restart components named in the command line"), GRP+1 },
- { "reload", OPT_RELOAD, NULL, 0,
- N_("reload the running instance of pies "), GRP+1 },
- { "hup", 0, NULL, OPTION_ALIAS },
- { "status", OPT_STATUS, NULL, 0,
- N_("display info about the running instance "), GRP+1 },
- { "stop", OPT_STOP, NULL, 0,
- N_("stop the running instance "), GRP+1 },
+ {"restart-component", OPT_RESTART, NULL, 0,
+ N_("restart components named in the command line"), GRP + 1},
+ {"reload", OPT_RELOAD, NULL, 0,
+ N_("reload the running instance of pies "), GRP + 1},
+ {"hup", 0, NULL, OPTION_ALIAS},
+ {"status", OPT_STATUS, NULL, 0,
+ N_("display info about the running instance "), GRP + 1},
+ {"stop", OPT_STOP, NULL, 0,
+ N_("stop the running instance "), GRP + 1},
#undef GRP
#define GRP 20
- { "dump-prereq", OPT_DUMP_PREREQ, NULL, 0,
- N_("dump prerequisite charts"), GRP+1 },
- { "dump-depmap", OPT_DUMP_DEPMAP, NULL, 0,
- N_("dump dependency map"), GRP+1 },
+ {"dump-prereq", OPT_DUMP_PREREQ, NULL, 0,
+ N_("dump prerequisite charts"), GRP + 1},
+ {"dump-depmap", OPT_DUMP_DEPMAP, NULL, 0,
+ N_("dump dependency map"), GRP + 1},
#undef GRP
- { NULL }
+ {NULL}
};
static error_t
parse_opt (int key, char *arg, struct argp_state *state)
{
- static struct mu_argp_node_list lst;
-
switch (key)
{
+ case 't':
+ lint_mode = 1;
+ break;
+
+ case 'E':
+ preprocess_only = 1;
+ break;
+
+ case 'c':
+ conffile = arg;
+ break;
+
+ case OPT_CONFIG_HELP:
+ config_help ();
+ exit (0);
+
case OPT_FOREGROUND:
foreground = 1;
break;
-
+
case OPT_RELOAD:
case OPT_STATUS:
case OPT_STOP:
- case OPT_RESTART:
+ case OPT_RESTART:
case OPT_DUMP_PREREQ:
case OPT_DUMP_DEPMAP:
log_to_stderr = 1;
@@ -1076,23 +1293,25 @@ parse_opt (int key, char *arg, struct argp_state *state)
break;
case 'x':
- mu_argp_node_list_new (&lst, "debug", arg);
+ debug_level = strtoul (arg, NULL, 0);
+ break;
+
+ case OPT_SOURCE_INFO:
+ source_info_option = 1;
break;
case OPT_FORCE:
force_option = 1;
break;
-
+
case OPT_LOG_TAG:
log_tag = arg;
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;
default:
@@ -1110,8 +1329,8 @@ static struct argp argp = {
NULL,
NULL
};
-
+
#define ACTION_CONT 0
#define ACTION_STOP 1
#define ACTION_RESTART 2
@@ -1135,11 +1354,11 @@ sig_handler (int sig)
case SIGINT:
case SIGQUIT:
action = ACTION_STOP;
- mu_diag_output (MU_DIAG_NOTICE, "received signal %d", sig);
+ logmsg (LOG_NOTICE, "received signal %d", sig);
break;
case SIGHUP:
- mu_diag_output (MU_DIAG_NOTICE, "received signal %d", sig);
+ logmsg (LOG_NOTICE, "received signal %d", sig);
action = ACTION_RESTART;
break;
@@ -1159,7 +1378,7 @@ sig_handler (int sig)
}
void
-signal_setup (RETSIGTYPE (*sf)(int))
+signal_setup (RETSIGTYPE (*sf) (int))
{
signal (SIGCHLD, sf);
signal (SIGTERM, sf);
@@ -1170,8 +1389,8 @@ signal_setup (RETSIGTYPE (*sf)(int))
signal (SIGUSR1, sf);
signal (SIGUSR2, sf);
}
-
+
pid_t
pidfile_read (int must_exist)
{
@@ -1181,10 +1400,9 @@ pidfile_read (int must_exist)
if (!fp)
{
if (must_exist && errno != ENOENT)
- mu_diag_output (MU_DIAG_ERR,
- _("cannot open pid file `%s': %s"),
- pidfile,
- mu_strerror (errno));
+ logmsg (LOG_ERR,
+ _("cannot open pid file `%s': %s"),
+ pidfile, strerror (errno));
return -1;
}
@@ -1196,44 +1414,44 @@ pidfile_read (int must_exist)
break;
else
{
- mu_diag_output (MU_DIAG_ERR,
- _("unexpected character %#03o in pidfile `%s'"),
- c, pidfile);
+ logmsg (LOG_ERR,
+ _("unexpected character %#03o in pidfile `%s'"),
+ c, pidfile);
return -1;
}
}
fclose (fp);
- if (kill (n, 0))
+ if (n && kill (n, 0))
{
- mu_diag_output (MU_DIAG_ERR,
- _("cannot signal master process %lu: %s"),
- (unsigned long) n, mu_strerror (errno));
+ logmsg (LOG_ERR,
+ _("cannot signal master process %lu: %s"),
+ (unsigned long) n, strerror (errno));
if (errno == EPERM)
- return n; /* be on the safe side */
+ return n; /* be on the safe side */
return -1;
}
return n;
}
-
+
enum pies_status
- {
- pies_status_ctr, /* clear to run */
- pies_status_stale,
- pies_status_noresp,
- pies_status_running
- };
+{
+ pies_status_ctr, /* clear to run */
+ pies_status_stale,
+ pies_status_noresp,
+ pies_status_running
+};
enum pies_status
-pies_check_status (pid_t *ppid)
+pies_check_status (pid_t * ppid)
{
pid_t pid = pidfile_read (0);
int i;
int rc;
-
- if (pid == -1)
+
+ if (pid <= 0)
return pies_status_ctr;
-
+
*ppid = pid;
if (kill (pid, SIGUSR2))
@@ -1246,39 +1464,39 @@ pies_check_status (pid_t *ppid)
return pies_status_noresp;
return pies_status_running;
}
-
+
void
stop_components ()
{
FILE *fp;
size_t size = 0;
char *buf = NULL;
-
- mu_diag_output (MU_DIAG_INFO, _("stopping components"));
-
+
+ logmsg (LOG_INFO, _("stopping components"));
+
fp = fopen (ctlfile, "r");
if (!fp)
{
- mu_error (_("cannot open control file `%s': %s"),
- ctlfile, mu_strerror (errno));
+ logmsg (LOG_ERR, _("cannot open control file `%s': %s"),
+ ctlfile, strerror (errno));
return;
}
if (unlink (ctlfile))
{
- mu_error (_("cannot unlink control file `%s': %s"),
- ctlfile, mu_strerror (errno));
+ logmsg (LOG_ERR, _("cannot unlink control file `%s': %s"),
+ ctlfile, strerror (errno));
fclose (fp);
return;
}
-
+
while (getline (&buf, &size, fp) > 0)
{
size_t len = strlen (buf);
if (len == 0)
continue;
- if (buf[len-1] == '\n')
- buf[len-1] = 0;
+ if (buf[len - 1] == '\n')
+ buf[len - 1] = 0;
progman_stop_component (buf);
}
@@ -1298,8 +1516,8 @@ request_restart_components (char **argv)
fp = fopen (ctlfile, "w");
if (!fp)
{
- mu_error (_("cannot open control file `%s': %s"),
- ctlfile, mu_strerror (errno));
+ logmsg (LOG_ERR, _("cannot open control file `%s': %s"),
+ ctlfile, strerror (errno));
return 1;
}
for (; *argv; argv++)
@@ -1309,8 +1527,8 @@ request_restart_components (char **argv)
kill (pid, SIGUSR1);
return 0;
}
-
+
int
pies_reload ()
{
@@ -1318,12 +1536,11 @@ pies_reload ()
if (pid == -1)
{
- mu_diag_output (MU_DIAG_CRIT, _("pies is not running"));
+ logmsg (LOG_CRIT, _("pies is not running"));
return 1;
}
-
- mu_diag_output (MU_DIAG_INFO, _("reloading pies at PID %lu"),
- (unsigned long) pid);
+
+ logmsg (LOG_INFO, _("reloading pies at PID %lu"), (unsigned long) pid);
return kill (pid, SIGHUP) ? EX_SOFTWARE : 0;
}
@@ -1332,51 +1549,50 @@ pies_status ()
{
pid_t pid;
FILE *fp;
-
+
if (unlink (statfile) && errno != ENOENT)
- mu_diag_output (MU_DIAG_ERR, _("cannot unlink statfile `%s': %s"),
- statfile, mu_strerror (errno));
+ logmsg (LOG_ERR, _("cannot unlink statfile `%s': %s"),
+ statfile, strerror (errno));
switch (pies_check_status (&pid))
{
case pies_status_ctr:
- mu_diag_output (MU_DIAG_INFO, _("pies is not running"));
+ logmsg (LOG_INFO, _("pies is not running"));
break;
-
+
case pies_status_stale:
- mu_diag_output (MU_DIAG_INFO,
- _("pies is not running, but a pidfile "
- "is found (pid %lu)"),
- (unsigned long) pid);
- return 1; /* FIXME: hm? */
+ logmsg (LOG_INFO,
+ _("pies is not running, but a pidfile "
+ "is found (pid %lu)"), (unsigned long) pid);
+ return 1; /* FIXME: hm? */
case pies_status_noresp:
- mu_diag_output (MU_DIAG_INFO,
- _("pies seems to run with pid %lu, but is not responding"),
- (unsigned long) pid);
+ logmsg (LOG_INFO,
+ _("pies seems to run with pid %lu, but is not responding"),
+ (unsigned long) pid);
if (unlink (statfile))
- mu_diag_output (MU_DIAG_ERR, _("cannot unlink statfile `%s': %s"),
- statfile, mu_strerror (errno));
+ logmsg (LOG_ERR, _("cannot unlink statfile `%s': %s"),
+ statfile, strerror (errno));
return 2;
case pies_status_running:
fp = fopen (statfile, "r");
if (!fp)
- mu_diag_output (MU_DIAG_ERR, _("cannot open statfile `%s': %s"),
- statfile, mu_strerror (errno));
+ logmsg (LOG_ERR, _("cannot open statfile `%s': %s"),
+ statfile, strerror (errno));
else
{
char c;
-
+
if (unlink (statfile))
- mu_diag_output (MU_DIAG_ERR, _("cannot unlink statfile `%s': %s"),
- statfile, mu_strerror (errno));
+ logmsg (LOG_ERR, _("cannot unlink statfile `%s': %s"),
+ statfile, strerror (errno));
while ((c = fgetc (fp)) != EOF)
fputc (c, stdout);
fclose (fp);
}
}
return 0;
-}
+}
int
pies_stop ()
@@ -1385,54 +1601,113 @@ pies_stop ()
if (pid == -1)
{
- mu_diag_output (MU_DIAG_CRIT, _("pies is not running"));
+ logmsg (LOG_CRIT, _("pies is not running"));
return EX_USAGE;
}
-
- mu_diag_output (MU_DIAG_INFO,
- _("stopping pies at PID %lu"), (unsigned long) pid);
+
+ logmsg (LOG_INFO, _("stopping pies at PID %lu"), (unsigned long) pid);
return kill (pid, SIGTERM) ? EX_SOFTWARE : 0;
}
-static int
-pies_cfg_verifier ()
+/* Pidfile */
+/* Check whether pidfile NAME exists and if so, whether its PID is still
+ active. Exit if it is. */
+void
+check_pidfile (char *name)
+{
+ unsigned long pid;
+ FILE *fp = fopen (name, "r");
+ if (!fp)
+ {
+ if (errno == ENOENT)
+ return;
+ logmsg (LOG_ERR, _("cannot open pidfile `%s': %s"),
+ name, strerror (errno));
+ exit (EX_TEMPFAIL);
+ }
+ if (fscanf (fp, "%lu", &pid) != 1)
+ {
+ logmsg (LOG_ERR, ("cannot get pid from pidfile `%s'"), name);
+ }
+ else
+ {
+ if (kill (pid, 0) == 0)
+ {
+ logmsg (LOG_ERR,
+ _
+ ("%s appears to run with pid %lu. If it does not, remove `%s' and retry."),
+ program_name, pid, name);
+ exit (EX_USAGE);
+ }
+ }
+ fclose (fp);
+ if (unlink (pidfile))
+ {
+ logmsg (LOG_ERR, _("cannot unlink pidfile `%s': %s"),
+ name, strerror (errno));
+ exit (EX_USAGE);
+ }
+}
+
+void
+create_pidfile (char *name)
{
- return progman_build_depmap ();
+ FILE *fp = fopen (name, "w");
+ if (!fp)
+ {
+ logmsg (LOG_ERR, _("cannot create pidfile `%s': %s"),
+ name, strerror (errno));
+ exit (EX_TEMPFAIL);
+ }
+ fprintf (fp, "%lu", (unsigned long) getpid ());
+ fclose (fp);
}
+void
+remove_pidfile (char *name)
+{
+ if (unlink (name))
+ logmsg (LOG_ERR, _("cannot unlink pidfile `%s': %s"),
+ name, strerror (errno));
+}
+
int
main (int argc, char **argv)
{
- int rc;
int index;
pid_t pid;
extern char **environ;
- extern char *program_invocation_short_name; /* FIXME */
-
+
+ set_program_name (argv[0]);
mf_init_nls ();
mf_proctitle_init (argc, argv, environ);
- if (!program_invocation_short_name)
- program_invocation_short_name = argv[0];
/* Set default logging */
log_setup (!stderr_closed_p ());
- mu_acl_cfg_init ();
- return_code_cfg_init ();
- component_cfg_init ();
- mu_app_cfg_verifier = pies_cfg_verifier;
- mu_argp_init (program_version, package_bugreport);
- mu_register_all_mailer_formats ();
- rc = mu_app_init (&argp, capa, pies_cfg_param, argc, argv, 0, &index, NULL);
- if (rc)
+ config_init ();
+ if (argp_parse (&argp, argc, argv, 0, &index, NULL))
+ exit (EX_USAGE);
+
+ if (preprocess_only)
+ exit (grecs_preproc_run (conffile, grecs_preprocessor) ? EX_CONFIG : 0);
+
+ if (grecs_parse (conffile))
exit (EX_CONFIG);
+ if (lint_mode)
+ {
+ progman_build_depmap ();
+ exit (0);
+ }
+
+ /* Re-setup logging: it might have been reset in the config file */
log_setup (log_to_stderr);
-
+
if (argc != index && command != 'R')
{
- mu_error ("extra command line arguments");
+ logmsg (LOG_ERR, "extra command line arguments");
exit (EX_CONFIG);
}
@@ -1440,7 +1715,7 @@ main (int argc, char **argv)
switch (command)
{
case OPT_RESTART:
- mf_priv_setup (&pies_privs);
+ pies_priv_setup (&pies_privs);
if (pies_umask)
umask (pies_umask);
exit (request_restart_components (argv + index));
@@ -1461,9 +1736,9 @@ main (int argc, char **argv)
case OPT_DUMP_DEPMAP:
progman_dump_depmap ();
exit (0);
-
+
default:
- mf_priv_setup (&pies_privs);
+ pies_priv_setup (&pies_privs);
if (pies_umask)
umask (pies_umask);
}
@@ -1476,37 +1751,36 @@ main (int argc, char **argv)
case pies_status_noresp:
if (!force_option)
{
- mu_error (_("another pies instance may be running (pid %lu), "
- "use --force to override"),
- (unsigned long) pid);
+ logmsg (LOG_ERR,
+ _("another pies instance may be running (pid %lu), "
+ "use --force to override"), (unsigned long) pid);
exit (EX_USAGE);
}
break;
case pies_status_running:
- mu_error (_("another pies instance already running (pid %lu)"),
- (unsigned long) pid);
+ logmsg (LOG_ERR, _("another pies instance already running (pid %lu)"),
+ (unsigned long) pid);
exit (EX_USAGE);
}
-
- mu_diag_output (MU_DIAG_INFO, _("%s starting"), program_version);
+
+ logmsg (LOG_INFO, _("%s starting"), program_version);
+
+ if (!foreground)
+ check_pidfile (pidfile);
if (!foreground && daemon (0, 0) == -1)
{
- mu_error (_("cannot become a daemon: %s"),
- mu_strerror (errno));
+ logmsg (LOG_ERR, _("cannot become a daemon: %s"), strerror (errno));
exit (EX_SOFTWARE);
}
- rc = mu_daemon_create_pidfile (pidfile);
- if (rc)
- mu_error (_("cannot create PID file `%s': %s"),
- pidfile, mu_strerror (rc));
-
+ create_pidfile (pidfile);
+
if (argv[0][0] != '/')
- mu_diag_output (MU_DIAG_NOTICE,
- N_("not started as an absolute pathname; "
- "SIGHUP will not work"));
+ logmsg (LOG_NOTICE,
+ N_("not started as an absolute pathname; "
+ "SIGHUP will not work"));
signal_setup (sig_handler);
@@ -1546,7 +1820,7 @@ main (int argc, char **argv)
}
}
while (action == ACTION_CONT);
-
+
progman_stop ();
if (action == ACTION_RESTART && argv[0][0] == '/')
@@ -1556,26 +1830,20 @@ main (int argc, char **argv)
for (i = getmaxfd (); i > 0; i--)
close (i);
- mu_daemon_remove_pidfile ();
+ remove_pidfile (pidfile);
signal_setup (SIG_DFL);
-
+
execv (argv[0], argv);
}
-
- mu_diag_output (MU_DIAG_INFO, _("%s terminated"), program_version);
+
+ logmsg (LOG_INFO, _("%s terminated"), program_version);
exit (EX_OK);
}
void
xalloc_die ()
{
- mu_error ("not enough memory");
+ logmsg (LOG_CRIT, _("not enough memory"));
abort ();
}
-
-/*
- Local Variables:
- c-file-style: "gnu"
- End:
-*/
/* EOF */

Return to:

Send suggestions and report system problems to the System administrator.