aboutsummaryrefslogtreecommitdiff
path: root/src/progman.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/progman.c')
-rw-r--r--src/progman.c121
1 files changed, 85 insertions, 36 deletions
diff --git a/src/progman.c b/src/progman.c
index 3211d9a..b85a797 100644
--- a/src/progman.c
+++ b/src/progman.c
@@ -163,6 +163,23 @@ unlink_prog (struct prog *pp)
void
destroy_prog (struct prog **pp)
{
+ struct prog *p = *pp;
+ switch (p->type)
+ {
+ case TYPE_COMPONENT:
+ break;
+
+ case TYPE_RETR:
+ {
+ struct prog *master = p->v.r.master;
+ if (p == master->v.p.redir[0])
+ master->v.p.redir[0] = NULL;
+ else if (p == master->v.p.redir[1])
+ master->v.p.redir[1] = NULL;
+ else
+ logmsg (LOG_NOTICE, _("orphan redirector: %s"), p->tag);
+ }
+ }
unlink_prog (*pp);
free (*pp);
*pp = NULL;
@@ -1350,13 +1367,13 @@ wait_for_child (pid_t pid)
void
send_msg (char *rcpts, const char *msg_text)
{
- int i;
- pid_t pid;
+ int i, j, k;
+ pid_t child_pid, grand_child_pid;
struct wordsplit ws;
int p[2];
size_t size;
- ws.ws_offs = 3; /* sendmail -oi -t */
+ ws.ws_offs = mailer_argc;
ws.ws_delim = ",";
if (wordsplit (rcpts, &ws,
WRDSF_NOVAR | WRDSF_NOCMD | WRDSF_DELIM | WRDSF_DOOFFS))
@@ -1367,12 +1384,21 @@ send_msg (char *rcpts, const char *msg_text)
return;
}
- 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++)
+ debug (1, (_("sending notification to %s"), rcpts));
+
+ /* Copy mailer arguments */
+ for (i = 0; i < mailer_argc; i++)
+ ws.ws_wordv[i] = mailer_argv[i];
+ /* j - number of the recipient;
+ i - index of the ws_wordv being converted;
+ k - index of the ws_wordv to store the converted value to.
+
+ Normally i == k, unless there are some invalid ws_wordv's,
+ in which case i > k.
+ */
+ for (j = 0, k = i; j < ws.ws_wordc; j++, i++)
{
- char *arg = ws.ws_wordv[3 + i];
+ char *arg = ws.ws_wordv[i];
size_t len;
while (*arg && c_isblank (*arg))
@@ -1380,36 +1406,38 @@ send_msg (char *rcpts, const char *msg_text)
len = strlen (arg);
if (len > 0)
{
- while (len > 0 && c_isblank(arg[len - 1]))
+ while (len > 0 && c_isblank (arg[len - 1]))
len--;
}
if (len == 0)
- continue; //FIXME
+ continue;
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;
+ continue;
+ memmove (ws.ws_wordv[k], arg, len);
+ ws.ws_wordv[k][len] = 0;
+ k++;
}
-
+ ws.ws_wordv[k] = NULL;
+
/* Fork a child: */
- pid = fork ();
- if (pid <= 0)
+ child_pid = fork ();
+ if (child_pid != 0)
wordsplit_free (&ws);
- if (pid < 0)
+ if (child_pid < 0)
{
logmsg (LOG_ERR,
_("cannot send mail: fork failed: %s"), strerror (errno));
return;
}
- if (pid == 0)
- //FIXME: SIGCHLD Handler? */
+ if (child_pid)
+ /*FIXME: SIGCHLD Handler? */
return;
/* Child process */
@@ -1425,18 +1453,15 @@ send_msg (char *rcpts, const char *msg_text)
exit (EX_OSERR);
}
- pid = fork ();
- if (pid <= 0)
- wordsplit_free (&ws);
-
- if (pid < 0)
+ grand_child_pid = fork ();
+ if (grand_child_pid < 0)
{
logmsg (LOG_ERR,
_("cannot send mail: fork failed: %s"), strerror (errno));
return;
}
- if (pid)
+ if (grand_child_pid == 0)
{
/* Grand-child */
/* =========== */
@@ -1444,7 +1469,7 @@ send_msg (char *rcpts, const char *msg_text)
close (0);
close (p[1]);
dup2 (p[0], 0);
- execv (ws.ws_wordv[0], ws.ws_wordv);
+ execv (mailer_program, ws.ws_wordv);
exit (127);
}
@@ -1466,7 +1491,7 @@ send_msg (char *rcpts, const char *msg_text)
}
close (p[1]);
- exit (wait_for_child (pid));
+ exit (wait_for_child (grand_child_pid));
}
static const char default_termination_message[] =
@@ -1485,9 +1510,11 @@ notify (const char *tag, int status, struct action *act)
{ "version", PACKAGE_VERSION },
#define COMPONENT_IDX 3
{ "component", NULL },
-#define RETCODE_IDX 4
+#define TERMINATION_IDX 4
+ { "termination", NULL },
+#define RETCODE_IDX 5
{ "retcode", NULL },
-#define PROGRAM_NAME_IDX 5
+#define PROGRAM_NAME_IDX 6
{ "program-name", NULL },
{ NULL }
};
@@ -1496,7 +1523,21 @@ notify (const char *tag, int status, struct action *act)
char buf[INT_BUFSIZE_BOUND (uintmax_t)];
mdef[COMPONENT_IDX].value = (char*) tag;
- mdef[RETCODE_IDX].value = umaxtostr (status, buf);
+ if (WIFEXITED (status))
+ {
+ mdef[TERMINATION_IDX].value = _("exited with code");
+ mdef[RETCODE_IDX].value = umaxtostr (WEXITSTATUS (status), buf);
+ }
+ else if (WIFSIGNALED (status))
+ {
+ mdef[TERMINATION_IDX].value = _("caught signal");
+ mdef[RETCODE_IDX].value = umaxtostr (WTERMSIG (status), buf);
+ }
+ else
+ {
+ mdef[TERMINATION_IDX].value = "UNKNOWN";
+ mdef[RETCODE_IDX].value = "UNKNOWN";
+ }
mdef[PROGRAM_NAME_IDX].value = (char*) program_name;
msg_text = meta_expand_string (act->message ?
act->message : default_termination_message,
@@ -1614,11 +1655,21 @@ progman_cleanup (int expect_term)
act = default_component.act_head;
if (WIFEXITED (status))
- retcode = WEXITSTATUS (status);
+ {
+ retcode = WEXITSTATUS (status);
+ debug (1, (_("%s: terminated with code %d"),
+ prog->tag, retcode));
+ }
else if (WIFSIGNALED (status))
- retcode = STATUS_SIG_BIT | WTERMSIG (status);
+ {
+ retcode = STATUS_SIG_BIT | WTERMSIG (status);
+ debug (1, (_("%s: terminated on signal %d"),
+ prog->tag, retcode));
+ }
else
{
+ debug (1, (_("%s: unrecognized termination status"),
+ prog->tag));
/* Enforce default action: */
act = NULL;
}
@@ -1639,10 +1690,8 @@ progman_cleanup (int expect_term)
break;
case action_disable:
- logmsg (LOG_NOTICE,
- _("disabling component %s: "
- "exited with code %d"),
- prog->tag, status);
+ logmsg (LOG_NOTICE, _("disabling component %s"),
+ prog->tag);
prog->v.p.status = status_disabled;
}
if (act->addr)

Return to:

Send suggestions and report system problems to the System administrator.