aboutsummaryrefslogtreecommitdiff
path: root/src/progman.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/progman.c')
-rw-r--r--src/progman.c557
1 files changed, 296 insertions, 261 deletions
diff --git a/src/progman.c b/src/progman.c
index 9383aae..cee6775 100644
--- a/src/progman.c
+++ b/src/progman.c
@@ -1,18 +1,18 @@
-/* This file is part of Mailfromd.
+/* This file is part of Pies.
Copyright (C) 2007, 2008, 2009 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 of the License, or (at your
- option) any later version.
+ 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/>. */
+ You should have received a copy of the GNU General Public License
+ along with Pies. If not, see <http://www.gnu.org/licenses/>. */
#include "pies.h"
@@ -172,13 +172,11 @@ static char *
redir_tag (struct prog *master, int type)
{
static char *redirstr[2] = { "stdout", "stderr" };
- char *str = NULL;
- if (type < MU_ARRAY_SIZE(redirstr))
- asprintf (&str, "%s/%s", master->tag, redirstr[type]);
+ char *str;
+ if (type < ARRAY_SIZE(redirstr))
+ str = xasprintf ("%s/%s", master->tag, redirstr[type]);
else
- asprintf (&str, "%s/%d", master->tag, type);
- if (!str)
- xalloc_die ();
+ str = xasprintf ("%s/%d", master->tag, type);
return str;
}
@@ -261,11 +259,10 @@ prog_rebuild_prerequisites (struct prog *prog)
if (comp->prereq)
{
- mu_list_count (comp->prereq, &depc);
+ depc = gl_list_size (comp->prereq);
if (depc == 1)
{
- char *item;
- mu_list_get (comp->prereq, 0, (void**)&item);
+ const char *item = gl_list_get_at (comp->prereq, 0);
if (strcmp (item, "all") == 0)
{
dep_all = 1;
@@ -274,7 +271,10 @@ prog_rebuild_prerequisites (struct prog *prog)
depc++;
}
else if (strcmp (item, "none") == 0)
- mu_list_destroy (&comp->prereq);
+ {
+ gl_list_free (comp->prereq);
+ comp->prereq = NULL;
+ }
}
}
@@ -294,16 +294,13 @@ prog_rebuild_prerequisites (struct prog *prog)
}
else
{
- mu_iterator_t itr = NULL;
- mu_list_get_iterator (comp->prereq, &itr);
- for (mu_iterator_first (itr), depc = 0;
- !mu_iterator_is_done (itr); mu_iterator_next (itr), depc++)
+ const void *p;
+ gl_list_iterator_t itr = gl_list_iterator (comp->prereq);
+ while (gl_list_iterator_next (&itr, &p, NULL))
{
- char *str;
- mu_iterator_current (itr, (void**)&str);
- prog->prereq[depc] = str;
+ prog->prereq[depc++] = (char*) p;
}
- mu_iterator_destroy (&itr);
+ gl_list_iterator_free (&itr);
}
}
prog->prereq[depc] = NULL;
@@ -341,9 +338,9 @@ redirect_to_file (struct prog *master, int stream)
0644 & ~master->v.p.comp->umask);
if (fd == -1)
{
- mu_error (_("cannot open output file %s: %s"),
+ logmsg (LOG_ERR, _("cannot open output file %s: %s"),
master->v.p.comp->redir[stream].v.file,
- mu_strerror (errno));
+ strerror (errno));
return -1;
}
/* Fix file ownership */
@@ -405,9 +402,9 @@ open_redirector (struct prog *master, int stream)
_exit (0);
case -1:
- mu_diag_output (MU_DIAG_CRIT,
+ logmsg (LOG_CRIT,
_("cannot run redirector `%s': fork failed: %s"),
- master->tag, mu_strerror (errno));
+ master->tag, strerror (errno));
return -1;
default:
@@ -592,7 +589,7 @@ prog_start (struct prog *prog)
if (prog->v.p.count > MAXSPAWN)
{
- mu_error (ngettext (
+ logmsg (LOG_NOTICE, ngettext (
"%s is respawning too fast, disabled for %d minute",
"%s is respawning too fast, disabled for %d minutes",
SLEEPTIME / 60),
@@ -609,12 +606,12 @@ prog_start (struct prog *prog)
break;
case pies_comp_pass_fd:
- MU_DEBUG1 (pies_debug, MU_DEBUG_TRACE1, _("unlinking %s\n"),
- prog->v.p.comp->pass_fd_socket);
+ debug (1, (_("unlinking %s"), prog->v.p.comp->pass_fd_socket));
if (unlink (prog->v.p.comp->pass_fd_socket) && errno != ENOENT)
{
- mu_error (_("cannot unlink %s: %s"), prog->v.p.comp->pass_fd_socket,
- mu_strerror (errno));
+ logmsg (LOG_ERR, _("cannot unlink %s: %s"),
+ prog->v.p.comp->pass_fd_socket,
+ strerror (errno));
return;
}
/* fall through */
@@ -630,7 +627,7 @@ prog_start (struct prog *prog)
}
if (listen (prog->v.p.socket, 8))
{
- mu_error ("listen: %s", mu_strerror (errno));
+ logmsg (LOG_ERR, "listen: %s", strerror (errno));
close (prog->v.p.socket);
prog->v.p.socket = -1;
prog->v.p.status = status_disabled;
@@ -644,15 +641,14 @@ prog_start (struct prog *prog)
return;
}
- MU_DEBUG1 (pies_debug, MU_DEBUG_TRACE1, _("starting %s\n"), prog->tag);
+ debug (1, (_("starting %s"), prog->tag));
if (prog->v.p.comp->rmfile)
{
- MU_DEBUG1 (pies_debug, MU_DEBUG_TRACE1, _("unlinking %s\n"),
- prog->v.p.comp->rmfile);
+ debug (1, (_("unlinking %s"), prog->v.p.comp->rmfile));
if (unlink (prog->v.p.comp->rmfile) && errno != ENOENT)
- mu_error (_("%s: cannot remove file `%s': %s"),
- prog->tag, prog->v.p.comp->rmfile, mu_strerror (errno));
+ logmsg (LOG_ERR, _("%s: cannot remove file `%s': %s"),
+ prog->tag, prog->v.p.comp->rmfile, strerror (errno));
}
redir[RETR_OUT] = open_redirector (prog, RETR_OUT);
@@ -665,22 +661,22 @@ prog_start (struct prog *prog)
signal_setup (SIG_DFL);
if (prog->v.p.comp->dir)
{
- MU_DEBUG1 (pies_debug, MU_DEBUG_TRACE1, _("chdir %s\n"),
- prog->v.p.comp->dir);
+ debug (1, (_("chdir %s"), prog->v.p.comp->dir));
if (chdir (prog->v.p.comp->dir))
- mu_error (_("%s: cannot change to directory %s: %s"),
- prog->tag, prog->v.p.comp->dir, mu_strerror (errno));
+ logmsg (LOG_ERR, _("%s: cannot change to directory %s: %s"),
+ prog->tag, prog->v.p.comp->dir, strerror (errno));
}
environ = env_setup (prog->v.p.comp->env);
- if (mu_debug_check_level (pies_debug, MU_DEBUG_TRACE4))
+ if (debug_level >= 4)
{
int i;
for (i = 0; environ[i]; i++)
- __MU_DEBUG1 (pies_debug, MU_DEBUG_TRACE4, "%s ", environ[i]);
- mu_debug_printf (pies_debug, MU_DEBUG_TRACE4, "\n");
+ logmsg_printf (LOG_DEBUG, "%s ", environ[i]);
+ logmsg_printf (LOG_DEBUG, "\n");
}
- mf_priv_setup (&prog->v.p.comp->privs);
+
+ pies_priv_setup (&prog->v.p.comp->privs);
if (prog->v.p.comp->umask)
umask (prog->v.p.comp->umask);
@@ -688,16 +684,16 @@ prog_start (struct prog *prog)
prog->v.p.comp->limits ?
prog->v.p.comp->limits : pies_limits);
- if (mu_debug_check_level (pies_debug, MU_DEBUG_TRACE1))
+ if (debug_level >= 1)
{
- char *cmdline;
- if (mu_argcv_string (prog->v.p.argc, prog->v.p.comp->argv,
- &cmdline) == 0)
+ int i;
+ logmsg_printf (LOG_DEBUG, "executing");
+ for (i = 0; i < prog->v.p.argc; i++)
{
- __MU_DEBUG1 (pies_debug, MU_DEBUG_TRACE1,
- "executing %s\n", cmdline);
- free (cmdline);
+ /* FIXME: quote */
+ logmsg_printf (LOG_DEBUG, " %s", prog->v.p.comp->argv[i]);
}
+ logmsg_printf (LOG_DEBUG, "\n");
}
switch (prog->v.p.comp->mode)
@@ -746,15 +742,15 @@ prog_start (struct prog *prog)
execvp (prog->v.p.comp->program ?
prog->v.p.comp->program : prog->v.p.comp->argv[0],
prog->v.p.comp->argv);
- openlog (MU_LOG_TAG (), LOG_PID, mu_log_facility);
+ openlog (log_tag, LOG_PID, prog->v.p.comp->facility);
syslog (LOG_CRIT, _("cannot start `%s': %s"), prog->tag,
- mu_strerror (errno));
+ strerror (errno));
_exit (EX_SOFTWARE);
case -1:
- mu_diag_output (MU_DIAG_CRIT,
+ logmsg (LOG_CRIT,
_("cannot run `%s': fork failed: %s"),
- prog->tag, mu_strerror (errno));
+ prog->tag, strerror (errno));
break;
default:
@@ -771,48 +767,29 @@ prog_start (struct prog *prog)
}
}
-int
-pies_check_acl (mu_acl_t acl, struct sockaddr *s, int salen)
+static int
+check_acl (pies_acl_t acl, struct sockaddr *s, int salen)
{
- mu_acl_result_t res;
+ struct acl_input input;
int rc;
if (!acl)
return 0;
- rc = mu_acl_check_sockaddr (acl, s, salen, &res);
- if (rc)
+ input.addr = s;
+ input.addrlen = salen;
+ input.user = NULL;
+ input.groups = NULL;
+
+ rc = pies_acl_check (acl, &input, 1);
+ if (rc == 0)
{
- char *p = mu_sockaddr_to_astr (s, salen);
- mu_error (_("access from %s blocked: cannot check ACLs: %s"),
- p, mu_strerror (rc));
+ char *p = sockaddr_to_astr (s, salen);
+ logmsg (LOG_ERR, _("access from %s blocked"), p);
free (p);
return 1;
}
- switch (res)
- {
- case mu_acl_result_undefined:
- {
- char *p = mu_sockaddr_to_astr (s, salen);
- mu_diag_output (MU_DIAG_INFO,
- _("%s: undefined ACL result; access allowed"),
- p);
- free (p);
- }
- break;
-
- case mu_acl_result_accept:
- break;
-
- case mu_acl_result_deny:
- {
- char *p = mu_sockaddr_to_astr (s, salen);
- mu_error (_("Access from %s blocked."), p);
- free (p);
- return 1;
- }
- }
return 0;
}
@@ -831,32 +808,33 @@ progman_accept (int socket)
fd = accept (socket, (struct sockaddr*) &addr, &addrlen);
if (fd == -1)
{
- mu_error (_("accept failed: %s"), mu_strerror (errno));
+ logmsg (LOG_ERR, _("accept failed: %s"), strerror (errno));
return 1;
}
p = prog_lookup_by_socket (socket);
if (!p)
{
- mu_error (_("INTERNAL ERROR: no matching prog for fd %d"), socket);
+ logmsg (LOG_EMERG,
+ _("INTERNAL ERROR: no matching prog for fd %d"), socket);
close (fd);
return 1;
}
- if (mu_debug_check_level (pies_debug, MU_DEBUG_TRACE1))
+ if (debug_level >= 1)
{
- char *s = mu_sockaddr_to_astr ((struct sockaddr *)&addr, addrlen);
- __MU_DEBUG2 (pies_debug, MU_DEBUG_TRACE1, "%s wants %s\n", s, p->tag);
+ char *s = sockaddr_to_astr ((struct sockaddr *)&addr, addrlen);
+ logmsg (LOG_DEBUG, "%s wants %s", s, p->tag);
free (s);
}
-
- if (pies_check_acl (p->v.p.comp->acl, (struct sockaddr *)&addr, addrlen)
- || pies_check_acl (pies_acl, (struct sockaddr *)&addr, addrlen))
+
+ if (check_acl (p->v.p.comp->acl, (struct sockaddr *)&addr, addrlen)
+ || check_acl (pies_acl, (struct sockaddr *)&addr, addrlen))
{
close (fd);
return 1;
}
-
+
p = register_prog0 (p->v.p.comp, -1);
p->v.p.socket = fd;
prog_start (p);
@@ -869,40 +847,40 @@ progman_accept (int socket)
void
component_fixup_depend (struct component *comp)
{
- mu_iterator_t itr;
+ const void *p;
+ gl_list_iterator_t itr;
if (comp->depend == NULL)
return;
- mu_list_get_iterator (comp->depend, &itr);
- for (mu_iterator_first (itr);
- !mu_iterator_is_done (itr); mu_iterator_next (itr))
+ itr = gl_list_iterator (comp->depend);
+ while (gl_list_iterator_next (&itr, &p, NULL))
{
- char *tag;
+ const char *tag = p;
struct component *tgt;
- mu_iterator_current (itr, (void**)&tag);
tgt = progman_lookup_component (tag);
if (!tgt)
{
- mu_error (_("component %s declares dependency target %s, "
- "which is not declared"),
- comp->tag, tag);
+ logmsg (LOG_ERR,
+ _("component %s declares dependency target %s, "
+ "which is not declared"),
+ comp->tag, tag);
continue;
}
if (!tgt->prereq)
{
- int rc = mu_list_create (&tgt->prereq);
- if (rc)
- {
- mu_error (_("cannot create list: %s"), mu_strerror (rc));
- continue;
- }
+ tgt->prereq = gl_list_create_empty(&gl_linked_list_implementation,
+ NULL,
+ NULL,
+ NULL,
+ false);
}
/* FIXME: memory allocation */
- mu_list_append (tgt->prereq, xstrdup (comp->tag));
+ gl_list_add_last (tgt->prereq, xstrdup (comp->tag));
}
- mu_list_destroy (&comp->depend);
+ gl_list_free (comp->depend);
+ comp->depend = NULL;
}
void
@@ -930,15 +908,15 @@ print_dep (struct prog *prog)
pies_depmap_pos_t pos;
unsigned n;
- mu_diag_printf (MU_DIAG_NOTICE, "%s -> ", prog->tag);
+ logmsg_printf (LOG_NOTICE, "%s -> ", prog->tag);
for (n = depmap_first (depmap, depmap_col, prog->idx, &pos);
n != (unsigned)-1;
n = depmap_next (depmap, pos))
{
struct prog *dp = prog_lookup_by_idx (n);
- mu_diag_printf (MU_DIAG_NOTICE, "%s -> ", dp->tag);
+ logmsg_printf (LOG_NOTICE, "%s -> ", dp->tag);
}
- mu_diag_printf (MU_DIAG_NOTICE, "%s\n", prog->tag);
+ logmsg_printf (LOG_NOTICE, "%s\n", prog->tag);
}
void
@@ -1003,7 +981,7 @@ progman_build_depmap ()
if (!dep)
{
prog->v.p.status = status_disabled;
- mu_error (_("component %s depends on %s, "
+ logmsg (LOG_ERR, _("component %s depends on %s, "
"which is not declared"),
prog->tag, prog->prereq[i]);
rc++;
@@ -1018,7 +996,7 @@ progman_build_depmap ()
if (depmap_isset (dp, i, i))
{
prog = prog_lookup_by_idx (i);
- mu_error (_("component %s depends on itself"), prog->tag);
+ logmsg (LOG_ERR, _("component %s depends on itself"), prog->tag);
print_dep (prog);
prog->v.p.status = status_disabled;
rc++;
@@ -1065,7 +1043,7 @@ progman_recompute_alarm ()
time_t alarm_time = 0, x;
recompute_alarm = 0;
- MU_DEBUG (pies_debug, MU_DEBUG_TRACE2, "Recomputing alarm settings\n");
+ debug (2, ("Recomputing alarm settings"));
for (prog = proghead; prog; prog = prog->next)
if (IS_PROG (prog))
{
@@ -1087,8 +1065,7 @@ progman_recompute_alarm ()
break;
}
}
- MU_DEBUG1 (pies_debug, MU_DEBUG_TRACE2, "alarm=%lu\n",
- (unsigned long)alarm_time);
+ debug (2, ("alarm=%lu", (unsigned long)alarm_time));
if (alarm_time)
alarm (alarm_time);
}
@@ -1101,7 +1078,7 @@ progman_start ()
struct prog *prog;
recompute_alarm = 0;
- MU_DEBUG (pies_debug, MU_DEBUG_TRACE1, "Starting components\n");
+ debug (1, ("Starting components"));
for (prog = proghead; prog; prog = prog->next)
if (IS_PROG (prog)
&& ((prog->v.p.status == status_enabled && prog->pid == 0)
@@ -1115,8 +1092,9 @@ check_stopping (struct prog *prog, time_t now)
if (now - prog->v.p.timestamp >= shutdown_timeout)
{
if (prog->pid == 0)
- mu_error (_("INTERNAL ERROR: attempting to kill unexisting process %s"),
- prog->tag);
+ logmsg (LOG_EMERG,
+ _("INTERNAL ERROR: attempting to kill unexisting process %s"),
+ prog->tag);
else
kill (prog->pid, SIGKILL);
}
@@ -1130,8 +1108,7 @@ progman_wake_sleeping ()
struct prog *prog;
time_t now = time (NULL);
- MU_DEBUG (pies_debug, MU_DEBUG_TRACE1,
- "Managing sleeping/stopping components\n");
+ debug (1, ("Managing sleeping/stopping components"));
for (prog = proghead; prog; prog = prog->next)
if (IS_PROG (prog))
@@ -1174,8 +1151,7 @@ prog_start_prerequisites (struct prog *prog)
if (!prog->prereq)
return 0; /* Ok to startup */
- MU_DEBUG1 (pies_debug, MU_DEBUG_TRACE1, "Starting prerequisites of %s\n",
- prog->tag);
+ debug (1, ("Starting prerequisites of %s", prog->tag));
ret = 0;
for (i = 0; prog->prereq[i]; i++)
{
@@ -1244,9 +1220,7 @@ prog_stop_dependents (struct prog *prog)
continue;
if (!warned && dp->pid)
{
- MU_DEBUG1 (pies_debug, MU_DEBUG_TRACE1,
- "Stopping dependencies of %s\n",
- prog->tag);
+ debug (1, ("Stopping dependencies of %s", prog->tag));
warned = 1;
}
prog_stop (dp, SIGTERM);
@@ -1268,9 +1242,7 @@ prog_stop (struct prog *prog, int sig)
recompute_alarm = 1;
}
}
- MU_DEBUG2 (pies_debug, MU_DEBUG_TRACE1,
- "Stopping %s (%lu)\n",
- prog->tag, (unsigned long) prog->pid);
+ debug (1, ("Stopping %s (%lu)", prog->tag, (unsigned long) prog->pid));
kill (prog->pid, sig);
}
@@ -1279,8 +1251,7 @@ prog_stop_all (int sig)
{
struct prog *prog;
- MU_DEBUG1 (pies_debug, MU_DEBUG_TRACE1,
- "Stopping all components (signal %d)\n", sig);
+ debug (1, ("Stopping all components (signal %d)", sig));
for (prog = progtail; prog; prog = prog->prev)
if (IS_PROG (prog)
&& (prog->v.p.status == status_enabled
@@ -1310,11 +1281,10 @@ print_status (char *tag, pid_t pid, int status, int expect_term)
if (WIFEXITED (status))
{
if (WEXITSTATUS (status) == 0)
- MU_DEBUG2 (pies_debug, MU_DEBUG_TRACE1,
- _("%s (%lu) exited successfully\n"),
- tag, (unsigned long) pid);
+ debug (1, (_("%s (%lu) exited successfully"),
+ tag, (unsigned long) pid));
else
- mu_diag_output (MU_DIAG_ERR,
+ logmsg (LOG_ERR,
_("%s (%lu) failed with status %d"),
tag, (unsigned long) pid,
WEXITSTATUS (status));
@@ -1324,70 +1294,179 @@ print_status (char *tag, pid_t pid, int status, int expect_term)
int prio;
if (expect_term && WTERMSIG (status) == SIGTERM)
- prio = MU_DIAG_DEBUG;
+ prio = LOG_DEBUG;
else
- prio = MU_DIAG_ERR;
+ prio = LOG_ERR;
- mu_diag_output (prio,
+ logmsg (prio,
_("%s (%lu) terminated on signal %d"),
tag, (unsigned long) pid,
WTERMSIG (status));
}
else if (WIFSTOPPED (status))
- mu_diag_output (MU_DIAG_ERR,
+ logmsg (LOG_ERR,
_("%s (%lu) stopped on signal %d"),
tag, (unsigned long) pid,
WSTOPSIG (status));
#ifdef WCOREDUMP
else if (WCOREDUMP (status))
- mu_diag_output (MU_DIAG_ERR,
+ logmsg (LOG_ERR,
_("%s (%lu) dumped core"),
tag, (unsigned long) pid);
#endif
else
- mu_diag_output (MU_DIAG_ERR,
+ logmsg (LOG_ERR,
_("%s (%lu) terminated with unrecognized status"),
tag, (unsigned long) pid);
}
-static void
-send_msg (mu_address_t rcpt, mu_message_t msg)
+static int
+wait_for_child (pid_t pid)
{
- mu_mailer_t mailer;
- int rc;
- const char *s;
+ int rc = 127;
+ int wait_status;
- mu_address_sget_email (rcpt, 1, &s);
- MU_DEBUG1 (pies_debug, MU_DEBUG_TRACE1, "Sending email to %s\n", s);
+ while (waitpid (pid, &wait_status, 0) == -1)
+ if (errno != EINTR)
+ {
+ logmsg (LOG_ERR, _("waitpid failed: %s"), strerror (errno));
+ return EX_OSERR;
+ }
- rc = mu_mailer_create (&mailer, NULL);
- if (rc)
+ if (WIFSIGNALED (wait_status))
{
- const char *mailer_url;
- mu_mailer_get_url_default (&mailer_url);
+ int sig = WTERMSIG (wait_status);
+ logmsg (LOG_ERR, _("child died with signal %d"), sig);
+ }
+ else if (WIFEXITED (wait_status))
+ {
+ rc = WEXITSTATUS (wait_status);
+ if (rc != 0)
+ logmsg (LOG_ERR, _("child returned status %d"), rc);
+ }
+ return rc;
+}
- mu_error (_("Cannot create mailer `%s': %s"),
- mailer_url, mu_strerror (rc));
+void
+send_msg (char *rcpts, const char *msg_text)
+{
+ int i;
+ pid_t pid;
+ struct wordsplit ws;
+ int p[2];
+ size_t size;
+
+ ws.ws_offs = 3; /* sendmail -oi -t */
+ ws.ws_delim = ",";
+ if (wordsplit (rcpts, &ws,
+ WRDSF_NOVAR | WRDSF_NOCMD | WRDSF_DELIM | WRDSF_DOOFFS))
+ {
+ logmsg (LOG_ERR,
+ _("cannot parse recipient address list (%s)"),
+ rcpts);
return;
}
-
- /* FIXME: mailer flags? */
- rc = mu_mailer_open (mailer, 0);
- if (rc)
+
+ ws.ws_wordv[0] = "/usr/sbin/sendmail"; /* FIXME: path */
+ ws.ws_wordv[1] = "-oi";
+ ws.ws_wordv[2] = "-t";
+ for (i = 0; i < ws.ws_wordc; i++)
+ {
+ char *arg = ws.ws_wordv[3 + i];
+ size_t len;
+
+ while (*arg && c_isblank (*arg))
+ arg++;
+ len = strlen (arg);
+ if (len > 0)
+ {
+ while (len > 0 && c_isblank(arg[len - 1]))
+ len--;
+ }
+ if (len == 0)
+ continue; //FIXME
+ if (arg[0] == '<' && arg[len-1] == '>')
+ {
+ arg++;
+ len -= 2;
+ }
+ if (len == 0)
+ continue; //FIXME
+ memmove (ws.ws_wordv[3 + i], arg, len);
+ ws.ws_wordv[3 + i][len] = 0;
+ }
+
+ /* Fork a child: */
+ pid = fork ();
+ if (pid <= 0)
+ wordsplit_free (&ws);
+
+ if (pid < 0)
{
- const char *mailer_url;
- mu_mailer_get_url_default (&mailer_url);
+ logmsg (LOG_ERR,
+ _("cannot send mail: fork failed: %s"), strerror (errno));
+ return;
+ }
+
+ if (pid == 0)
+ //FIXME: SIGCHLD Handler? */
+ return;
- mu_mailer_destroy(&mailer);
- mu_error (_("opening mailer `%s' failed: %s"),
- mailer_url, mu_strerror (rc));
+ /* Child process */
+ /* ============= */
+ signal (SIGCHLD, SIG_DFL);
+ signal (SIGPIPE, SIG_DFL);
+
+ if (pipe (p))
+ {
+ logmsg (LOG_ERR, _("cannot send mail: pipe failed: %s"),
+ strerror (errno));
+ wordsplit_free (&ws);
+ exit (EX_OSERR);
+ }
+
+ pid = fork ();
+ if (pid <= 0)
+ wordsplit_free (&ws);
+
+ if (pid < 0)
+ {
+ logmsg (LOG_ERR,
+ _("cannot send mail: fork failed: %s"), strerror (errno));
return;
}
-
- rc = mu_mailer_send_message (mailer, msg, NULL, rcpt);
- mu_mailer_destroy (&mailer);
- if (rc)
- mu_error (_("cannot send message: %s"), mu_strerror (rc));
+
+ if (pid)
+ {
+ /* Grand-child */
+ /* =========== */
+ if (p[0] != 0 && p[1] != 0)
+ close (0);
+ close (p[1]);
+ dup2 (p[0], 0);
+ execv (ws.ws_wordv[0], ws.ws_wordv);
+ exit (127);
+ }
+
+ /* Child again */
+ close (p[0]);
+
+ size = strlen (msg_text);
+ while (size)
+ {
+ ssize_t rc = write (p[1], msg_text, size);
+ if (rc <= 0)
+ {
+ logmsg (LOG_ERR, _("cannot write to pipe: %s"),
+ rc == 0 ? "EOF" : strerror (errno));
+ break;
+ }
+ size -= rc;
+ msg_text += rc;
+ }
+ close (p[1]);
+
+ exit (wait_for_child (pid));
}
static const char default_termination_message[] =
@@ -1397,65 +1476,34 @@ static const char default_termination_message[] =
"\n";
static void
-vartab_define_project (mu_vartab_t vtab)
-{
- static struct {
- char *name;
- char *value;
- } ptab[] = {
- { "canonical-program-name", "pies" },
- { "package", PACKAGE },
- { "version", PACKAGE_VERSION },
- { "mu-version", MAILUTILS_VERSION },
- { NULL }
- };
- int i;
-
- for (i = 0; ptab[i].name; i++)
- mu_vartab_define (vtab, ptab[i].name, ptab[i].value, 1);
-}
-
-
-static void
notify (const char *tag, int status, struct action *act)
{
- mu_vartab_t vtab;
+ struct metadef mdef[] =
+ {
+ { "canonical-program-name", "pies" },
+ { "package", PACKAGE },
+ { "version", PACKAGE_VERSION },
+#define COMPONENT_IDX 3
+ { "component", NULL },
+#define RETCODE_IDX 4
+ { "retcode", NULL },
+#define PROGRAM_NAME_IDX 5
+ { "program-name", NULL },
+ { NULL }
+ };
+
char *msg_text = NULL;
- mu_message_t msg = NULL;
- mu_stream_t stream = NULL;
- int rc;
char buf[INT_BUFSIZE_BOUND (uintmax_t)];
- mu_vartab_create (&vtab);
- mu_vartab_define (vtab, "component", tag, 1);
- mu_vartab_define (vtab, "retcode", umaxtostr (status, buf), 1);
- mu_vartab_define (vtab, "program-name", mu_program_name, 1);
- vartab_define_project (vtab);
- rc = mu_vartab_expand (vtab,
- act->message ?
- act->message : default_termination_message,
- &msg_text);
- mu_vartab_destroy (&vtab);
- if (rc)
- {
- mu_error (_("cannot expand message body: %s"), mu_strerror (rc));
- /* FIXME: Notify anyway? */
- return;
- }
+ mdef[COMPONENT_IDX].value = (char*) tag;
+ mdef[RETCODE_IDX].value = umaxtostr (status, buf);
+ mdef[PROGRAM_NAME_IDX].value = (char*) program_name;
+ msg_text = meta_expand_string (act->message ?
+ act->message : default_termination_message,
+ mdef, NULL);
- rc = mu_message_create (&msg, NULL);
- if (rc)
- {
- mu_error (_("cannot create message: %s"), mu_strerror (rc));
- free (msg_text);
- }
-
- mu_message_get_stream (msg, &stream);
- mu_stream_write (stream, msg_text, strlen (msg_text), 0, NULL);
+ send_msg (act->addr, msg_text);
free (msg_text);
-
- send_msg (act->addr, msg);
- mu_message_destroy (&msg, mu_message_get_owner (msg));
}
static int
@@ -1487,7 +1535,7 @@ run_command (struct action *act, struct prog *prog, unsigned retcode,
if (pid == (pid_t) -1)
{
- mu_error ("fork: %s", mu_strerror (errno));
+ logmsg (LOG_ERR, "fork: %s", strerror (errno));
return;
}
@@ -1495,8 +1543,7 @@ run_command (struct action *act, struct prog *prog, unsigned retcode,
{
int i;
- MU_DEBUG1 (pies_debug, MU_DEBUG_TRACE1,
- _("executing %s\n"), act->command);
+ debug (1, (_("executing %s"), act->command));
/* Child */
setenv ("PIES_VERSION", PACKAGE_VERSION, 1);
setenv ("PIES_COMPONENT", prog->tag, 1);
@@ -1522,7 +1569,7 @@ run_command (struct action *act, struct prog *prog, unsigned retcode,
while (waitpid (pid, &status, 0) == -1)
if (errno != EINTR)
{
- mu_error ("waitpid: %s", mu_strerror (errno));
+ logmsg (LOG_ERR, "waitpid: %s", strerror (errno));
break;
}
signal (SIGPIPE, saved_handler);
@@ -1540,7 +1587,7 @@ progman_cleanup (int expect_term)
struct prog *prog = prog_lookup_by_pid (pid);
if (!prog)
{
- mu_diag_output (MU_DIAG_NOTICE,
+ logmsg (LOG_NOTICE,
_("subprocess %lu finished"),
(unsigned long) pid);
continue;
@@ -1592,7 +1639,7 @@ progman_cleanup (int expect_term)
break;
case action_disable:
- mu_diag_output (MU_DIAG_NOTICE,
+ logmsg (LOG_NOTICE,
_("disabling component %s: "
"exited with code %d"),
prog->tag, status);
@@ -1613,8 +1660,7 @@ progman_cleanup (int expect_term)
else
{
/* It was a redirector of an already finished inetd process. */
- MU_DEBUG1 (pies_debug, MU_DEBUG_TRACE1,
- _("removing inetd redirector %s\n"), prog->tag);
+ debug (1, (_("removing inetd redirector %s"), prog->tag));
destroy_prog (&prog);
}
}
@@ -1629,7 +1675,7 @@ progman_stop_component (const char *name)
{
struct prog *prog;
- mu_diag_output (MU_DIAG_INFO, _("stopping component `%s'"), name);
+ logmsg (LOG_INFO, _("stopping component `%s'"), name);
for (prog = proghead; prog; prog = prog->next)
if (IS_PROG (prog) && strcmp (prog->tag, name) == 0)
{
@@ -1646,7 +1692,7 @@ progman_stop_component (const char *name)
break;
default:
- mu_diag_output (MU_DIAG_INFO,
+ logmsg (LOG_INFO,
_("stopping component `%s': "
"component not started"),
name);
@@ -1659,27 +1705,27 @@ progman_dump_stats (const char *filename)
{
FILE *fp;
struct prog *prog;
- char *s;
- int rc;
char *tmpfile = NULL;
asprintf (&tmpfile, "%s.%lu", filename, (unsigned long) getpid ());
if (!tmpfile)
{
- mu_error ("%s", mu_strerror (ENOMEM));
+ logmsg (LOG_ERR, "%s", strerror (ENOMEM));
return;
}
- mu_diag_output (MU_DIAG_INFO, _("dumping statistics to `%s'"), tmpfile);
+ logmsg (LOG_INFO, _("dumping statistics to `%s'"), tmpfile);
fp = fopen (tmpfile, "w");
if (!fp)
{
- mu_error (_("cannot open file `%s' for writing: %s"),
- tmpfile, mu_strerror (errno));
+ logmsg (LOG_ERR, _("cannot open file `%s' for writing: %s"),
+ tmpfile, strerror (errno));
return;
}
for (prog = proghead; prog; prog = prog->next)
{
+ int i;
+
switch (prog->type)
{
case TYPE_COMPONENT:
@@ -1704,15 +1750,10 @@ progman_dump_stats (const char *filename)
fprintf (fp, _("[listener]"));
else
fprintf (fp, _("[not running]"));
- if (rc = mu_argcv_string (prog->v.p.argc, prog->v.p.comp->argv, &s))
- {
- mu_error (_("cannot convert argument list: %s"),
- mu_strerror (rc));
- }
- else
+ for (i = 0; i < prog->v.p.argc; i++)
{
- fprintf (fp, " %s", s);
- free (s);
+ /* FIXME: quote as appropriate */
+ fprintf (fp, " %s", prog->v.p.comp->argv[i]);
}
fputc ('\n', fp);
break;
@@ -1726,16 +1767,10 @@ progman_dump_stats (const char *filename)
unlink (filename);
if (rename (tmpfile, filename))
{
- mu_error (_("cannot rename %s to %s: %s"), tmpfile, filename,
- mu_strerror (errno));
+ logmsg (LOG_ERR, _("cannot rename %s to %s: %s"), tmpfile, filename,
+ strerror (errno));
unlink (tmpfile);
}
free (tmpfile);
}
-
-/*
- Local Variables:
- c-file-style: "gnu"
- End:
-*/
/* EOF */

Return to:

Send suggestions and report system problems to the System administrator.