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})