diff options
Diffstat (limited to 'src/progman.c')
-rw-r--r-- | src/progman.c | 113 |
1 files changed, 81 insertions, 32 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)) @@ -1384,32 +1410,34 @@ send_msg (char *rcpts, const char *msg_text) 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); + debug (1, (_("%s: terminated with code %d"), + prog->tag, retcode)); + } else if (WIFSIGNALED (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) |