Submitted by: Damon Harper Date: 2006-08-26 Summary: Combined patches This combines the following incompatible patches: mailutils-1.0-comsatd-echo-enhancements-1.patch mailutils-1.0-comsatd-fixes1-2.patch mailutils-1.0-comsatd-new-escapes-f+o-2.patch mailutils-1.0-comsatd-reset-atime-1.patch mailutils-1.0-comsatd-sigchld-fix-1.patch diff -urN mailutils-1.0.orig/comsat/action.c mailutils-1.0/comsat/action.c --- mailutils-1.0.orig/comsat/action.c 2005-08-29 03:21:54.000000000 -0700 +++ mailutils-1.0/comsat/action.c 2006-08-26 11:48:04.000000000 -0700 @@ -45,6 +45,7 @@ char buf[256]; int cont = 1; size_t used = 0; + int lines = 0; while (cont && fgets (buf, sizeof buf, fp)) { @@ -56,6 +57,7 @@ { buf[--len] = 0; cont = 1; + lines++; } else cont = 0; @@ -77,11 +79,14 @@ if (*sptr) (*sptr)[used] = 0; - return used; + /* return the number of physical lines used */ + if (used || !feof (fp)) + lines++; + return lines; } static int -expand_escape (char **pp, mu_message_t msg, struct obstack *stk) +expand_escape (char **pp, mu_message_t msg, const char *path, const char *offset, struct obstack *stk) { char *p = *pp; char *start, *sval, *namep; @@ -108,6 +113,20 @@ rc = 0; break; + case 'f': + len = strlen (path); + obstack_grow (stk, path, len); + *pp = p; + rc = 0; + break; + + case 'o': + len = strlen (offset); + obstack_grow (stk, offset, len); + *pp = p; + rc = 0; + break; + case 'H': /* Header field */ if (*++p != '{') @@ -181,7 +200,7 @@ } static char * -expand_line (const char *str, mu_message_t msg) +expand_line (const char *str, mu_message_t msg, const char *path, const char *offset) { const char *p; int c = 0; @@ -204,7 +223,7 @@ break; case '$': - if (expand_escape ((char**)&p, msg, &stk) == 0) + if (expand_escape ((char**)&p, msg, path, offset, &stk) == 0) break; /*FALLTHRU*/ @@ -331,7 +350,7 @@ } void -run_user_action (FILE *tty, const char *cr, mu_message_t msg) +run_user_action (FILE *tty, const char *cr, mu_message_t msg, const char *path, const char *offset) { FILE *fp; int nact = 0; @@ -341,54 +360,79 @@ fp = open_rc (BIFF_RC, tty); if (fp) { - int line = 0; + int lines; + int line = 1; + int do_abort = 0; - while (act_getline (fp, &stmt, &size)) + while ((lines = act_getline (fp, &stmt, &size)) > 0) { - char *str; int argc; char **argv; + int c; - line++; - str = expand_line (stmt, msg); - if (!str) - continue; - if (mu_argcv_get (str, "", NULL, &argc, &argv) - || argc == 0 - || argv[0][0] == '#') + if (!mu_argcv_get (stmt, "", NULL, &argc, &argv) + && argc > 0 + && argv[0][0] != '#') { - free (str); - mu_argcv_free (argc, argv); - continue; - } - - if (strcmp (argv[0], "beep") == 0) - { - action_beep (tty); - nact++; - } - else if (strcmp (argv[0], "echo") == 0) - { - action_echo (tty, cr, argv[1]); - nact++; - } - else if (strcmp (argv[0], "exec") == 0) - { - action_exec (tty, line, argc-1, argv+1); - nact++; - } - else - { - fprintf (tty, _(".biffrc:%d: unknown keyword"), line); - fprintf (tty, "\r\n"); - syslog (LOG_ERR, _("%s:.biffrc:%d: unknown keyword %s"), - username, line, argv[0]); - break; - } + for(c=1; c= argc) /* loop did complete */ + { + if (strcmp (argv[0], "beep") == 0) + { + action_beep (tty); + nact++; + } + else if (strcmp (argv[0], "echo") == 0) + { + int newline = 1; + if (argc > 1) + { + int c = 1; + if (strcmp (argv[1], "-n") == 0) + { + newline = 0; + c++; + } + for (; c < argc; c++) + { + action_echo (tty, cr, argv[c]); + if (c < argc - 1) + action_echo (tty, cr, " "); + } + } + if (newline) + action_echo (tty, cr, "\n"); + nact++; + } + else if (strcmp (argv[0], "exec") == 0) + { + action_exec (tty, line, argc-1, argv+1); + nact++; + } + else + { + fprintf (tty, _(".biffrc:%d: unknown keyword\r\n.biffrc: processing stopped.\r\n"), line); + syslog (LOG_ERR, _("%s:.biffrc:%d: unknown keyword %s"), + username, line, argv[0]); + do_abort = 1; + } + } + } + mu_argcv_free (argc, argv); + if (do_abort) + break; + line += lines; } fclose (fp); } if (nact == 0) - action_echo (tty, cr, expand_line (default_action, msg)); + action_echo (tty, cr, expand_line (default_action, msg, path, offset)); } diff -urN mailutils-1.0.orig/comsat/comsat.c mailutils-1.0/comsat/comsat.c --- mailutils-1.0.orig/comsat/comsat.c 2005-09-30 03:41:07.000000000 -0700 +++ mailutils-1.0/comsat/comsat.c 2006-08-26 11:48:21.000000000 -0700 @@ -191,6 +191,20 @@ } void +comsat_parent_sig_chld (int sig) +{ + if (waitpid(-1, NULL, WNOHANG) > 0) + exit (0); /* child is finished, we can exit immediately */ +} + +void +comsat_child_sig_chld (int sig) +{ + while (waitpid(-1, NULL, WNOHANG) > 0) + ; /* reap but ignore */ +} + +void comsat_init () { mu_registrar_record (mu_path_record); @@ -199,7 +213,7 @@ /* Set signal handlers */ signal (SIGTTOU, SIG_IGN); - signal (SIGCHLD, SIG_IGN); + signal (SIGCHLD, comsat_parent_sig_chld); signal (SIGHUP, SIG_IGN); /* Ignore SIGHUP. */ } @@ -391,14 +405,15 @@ if (pid > 0) { struct timeval tv; - tv.tv_sec = 0; - tv.tv_usec = 100000; + tv.tv_sec = 1; + tv.tv_usec = 0; select (0, NULL, NULL, NULL, &tv); - kill (pid, SIGKILL); /* Just in case the child is hung */ + kill (pid, SIGKILL); /* Child has not exited; must be hung */ return 0; } /* Child: do actual I/O */ + signal (SIGCHLD, comsat_child_sig_chld); notify_user (buffer, tty, path, offset); exit (0); } @@ -433,6 +449,13 @@ int status; off_t size; size_t count, n; + char *offset_str; + int offset_str_size = 11; + int offset_str_remainder; + char *offset_str_realloc; + int reset_times = 0; + struct stat sb; + struct utimbuf ub; change_user (user); if ((fp = fopen (device, "w")) == NULL) @@ -450,6 +473,10 @@ return; } + /* Store mailbox access and modification times. */ + if (stat (path, &sb) != -1) + reset_times = 1; + if ((status = mu_mailbox_create (&mbox, path)) != 0 || (status = mu_mailbox_open (mbox, MU_STREAM_READ)) != 0) { @@ -501,8 +528,37 @@ mu_mailbox_messages_count (tmp, &count); mu_mailbox_get_message (tmp, 1, &msg); - run_user_action (fp, cr, msg); + if ((offset_str = malloc (offset_str_size)) == NULL) + { + syslog (LOG_ERR, _("Cannot allocate %d bytes"), offset_str_size); + return; + } + while (1) { + offset_str_remainder = snprintf (offset_str, offset_str_size, "%lu", offset); + if (offset_str_remainder > -1 && offset_str_remainder < offset_str_size) + break; + if (offset_str_remainder > -1) /* glibc 2.1+ - got exact remainder */ + offset_str_size = offset_str_remainder+1; + else /* glibc 2.0- - guess at new size */ + offset_str_size *= 2; + if ((offset_str_realloc = realloc (offset_str, offset_str_size)) == NULL) { + free(offset_str); + syslog (LOG_ERR, _("Cannot allocate %d bytes"), offset_str_size); + return; + } + offset_str = offset_str_realloc; + } + + run_user_action (fp, cr, msg, path, offset_str); fclose (fp); + + /* Now if possible reset the access and modification times, so programs + like mutt will still see new mail in the folder. */ + if (reset_times) { + ub.modtime = sb.st_mtime; + ub.actime = sb.st_atime; + utime (path, &ub); /* Ignore return value - if it fails, too bad. */ + } } /* Search utmp for the local user */ diff -urN mailutils-1.0.orig/comsat/comsat.h mailutils-1.0/comsat/comsat.h --- mailutils-1.0.orig/comsat/comsat.h 2005-08-29 03:21:54.000000000 -0700 +++ mailutils-1.0/comsat/comsat.h 2006-08-26 11:48:04.000000000 -0700 @@ -37,6 +37,7 @@ #include #include #include +#include #ifdef HAVE_PATHS_H # include @@ -79,4 +80,4 @@ extern void read_config (const char *config_file); int acl_match (struct sockaddr_in *sa_in); -void run_user_action (FILE *tty, const char *cr, mu_message_t msg); +void run_user_action (FILE *tty, const char *cr, mu_message_t msg, const char *path, const char *offset); diff -urN mailutils-1.0.orig/doc/texinfo/mailutils.info-1 mailutils-1.0/doc/texinfo/mailutils.info-1 --- mailutils-1.0.orig/doc/texinfo/mailutils.info-1 2006-07-05 07:30:26.000000000 -0700 +++ mailutils-1.0/doc/texinfo/mailutils.info-1 2006-08-26 11:48:04.000000000 -0700 @@ -3841,6 +3841,12 @@ $h Expands to hostname +$f + Expands to the name of the folder containing the new message. + +$o + Expands to the offset in $f where the new message starts. + $H{name} Expands to value of message header `name'. diff -urN mailutils-1.0.orig/doc/texinfo/programs.texi mailutils-1.0/doc/texinfo/programs.texi --- mailutils-1.0.orig/doc/texinfo/programs.texi 2006-04-26 05:15:06.000000000 -0700 +++ mailutils-1.0/doc/texinfo/programs.texi 2006-08-26 11:48:04.000000000 -0700 @@ -3888,6 +3888,10 @@ Expands to username @item $h Expands to hostname address@hidden $f +Expands to the name of the folder containing the new message. address@hidden $o +Expands to the offset in $f where the new message starts. @item address@hidden@} Expands to value of message header @samp{name}. @item $B(@var{c},@var{l})