diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2009-10-13 16:53:42 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2009-10-13 16:53:42 +0300 |
commit | c60e857d7f35128b077eac4a30a5900925bb38e8 (patch) | |
tree | c9bae66b94b2cfbd7b8869abf1b1dbe34bcf51e9 /src/progman.c | |
parent | 8a4ba77068e5d7f6eab2cc1c1c10f31dcbccf7a6 (diff) | |
download | pies-c60e857d7f35128b077eac4a30a5900925bb38e8.tar.gz pies-c60e857d7f35128b077eac4a30a5900925bb38e8.tar.bz2 |
Bugfixes.
* README: Update.
* configure.ac: Change bug-reporting address.
* doc/pies.texi: Minor fixes.
* src/pies.c: New configuration statements: mailer-program
and mailer-command-line.
(mailer_program, mailer_command_line)
(mailer_argc, mailer_argv): New globals.
* src/pies.h (mailer_program, mailer_command_line)
(mailer_argc, mailer_argv): New globals.
* src/progman.c (destroy_prog): Bugfix: update master
program when destroying a retranslator.
(send_msg): Several bugfixes. Use mailer_argc, mailer_argv
instead of hardcoding sendmail command line. Remove
invalid recipient addresses from the resulting command line.
Diffstat (limited to 'src/progman.c')
-rw-r--r-- | src/progman.c | 121 |
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) |