/* This file is part of Mailfromd.
Copyright (C) 2008 Sergey Poznyakoff
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#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;
int foreground;
int command;
char *pidfile = STATEDIR "/pies.pid";
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;
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;
}
static int
stderr_closed_p()
{
int fd = dup (0);
if (fd < 0)
return 1;
close (fd);
return fd <= 2;
}
static int
_cb_action (mu_debug_t debug, void *data, mu_config_value_t *arg)
{
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))
{
mu_cfg_format_error (debug, MU_DEBUG_ERROR,
_("unknown action code: %s"), arg);
return 0;
}
*pact = res;
return 0;
}
static int
_cb_notify_addr (mu_debug_t debug, void *data, mu_config_value_t *arg)
{
mu_address_t *paddr = data;
mu_address_t addr;
int rc;
if (mu_cfg_assert_value_type (arg, MU_CFG_STRING, debug))
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)
{
mu_address_union (paddr, addr);
mu_address_destroy (&addr);
}
else
*paddr = addr;
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 }
};
#define S(s) { #s, s }
static struct mu_kwd ex_kwtab[] = {
S (EX_OK),
S (EX_USAGE),
S (EX_DATAERR),
S (EX_NOINPUT),
S (EX_NOUSER),
S (EX_NOHOST),
S (EX_UNAVAILABLE),
S (EX_SOFTWARE),
S (EX_OSERR),
S (EX_OSFILE),
S (EX_CANTCREAT),
S (EX_IOERR),
S (EX_TEMPFAIL),
S (EX_PROTOCOL),
S (EX_NOPERM),
S (EX_CONFIG),
{ NULL }
};
static struct mu_kwd sig_kwtab[] = {
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 (SIGTERM),
#ifdef SIGSTKFLT
S (SIGSTKFLT),
#endif
S (SIGCHLD),
S (SIGCONT),
S (SIGSTOP),
S (SIGTSTP),
S (SIGTTIN),
S (SIGTTOU),
#ifdef SIGURG
S (SIGURG),
#endif
#ifdef SIGXCPU
S (SIGXCPU),
#endif
#ifdef SIGXFSZ
S (SIGXFSZ),
#endif
#ifdef SIGVTALRM
S (SIGVTALRM),
#endif
#ifdef SIGPROF
S (SIGPROF),
#endif
#ifdef SIGWINCH
S (SIGWINCH),
#endif
#ifdef SIGPOLL
S (SIGPOLL),
#endif
#ifdef SIGIO
S (SIGIO),
#endif
#ifdef SIGPWR
S (SIGPWR),
#endif
#ifdef SIGSYS
S (SIGSYS),
#endif
{ 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))
{
int i;
unsigned *retv;
int retc = 0;
int allflag = 0;
struct action *act;
retv = xcalloc (argc, sizeof *retv);
if (argc == 0 || (argc == 1 && strcmp (getarg(val, 0, debug), "*") == 0))
allflag = 1;
else
{
for (i = 0; i < argc; i++)
{
unsigned n;
const char *arg = getarg(val, i, debug);
size_t len = st
|