i think i'm finally finished hacking up comsatd - it's now functioning
smoothly as i want it to.
i've created a few more fixes for problems i found in comsatd, and
revamped / fixed problems in some of the patches i previously posted,
all of which can be considered obsoleted by this post.
i'm attaching five individual patches, each of which should apply
cleanly against the 1.0 release. however some of these patches are
mutually incompatible so i'm also including a COMBINED patch that
combines all five into one patch against 1.0.
i've added a preamble to each patch explaining what it does and why.
i hope some or all of these will be useful and can be incorporated
into the package. a couple contain fixes for problems in the
distributed code, and the rest are feature enhancements.
i'd also love to see a biff command included in the package. right
now i'm using biff from biff+comsat-0.17, which does the trick. biff
is still very useful for temporarily stopping output to a particular
tty. i wouldn't mind writing a new one if it would be included in
mailutils.
cheers!
-damon
Submitted by: Damon Harper <[EMAIL PROTECTED]>
Date: 2006-08-26
Summary: Enhance the echo command in comsatd / .biffrc
This patch makes the `echo' .biffrc action for comsatd behave more
like the shell version of `echo':
1. Multiple arguments to echo are accepted, and are echoed back
separated by single spaces. This way you can use echo without
having to quote the entire string.
2. A newline is appended by default, unless the first argument to echo
is `-n'.
3. With no arguments, a single newline is produced.
This allows much easier to read constructions like the following
contrived example:
echo
echo New "mail :: for" [EMAIL PROTECTED]:
echo ---
echo From: $H{From}
echo Subject: $H{Subject}
echo -n $B(,5)
echo ---
NOTE: This does introduce one backwards-incompatibility, in that
current .biffrc echo commands will have an extra newline appended.
--- mailutils-1.0.orig/comsat/action.c 2005-08-29 03:21:54.000000000 -0700
+++ mailutils-1.0/comsat/action.c 2006-08-25 15:39:41.000000000 -0700
@@ -369,7 +369,24 @@
}
else if (strcmp (argv[0], "echo") == 0)
{
- action_echo (tty, cr, argv[1]);
+ 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)
Submitted by: Damon Harper <[EMAIL PROTECTED]>
Date: 2006-08-26
Summary: Fix several problems in comsatd
This patch fixes several problems in the comsat/action.c function
run_user_action.
1. Previously, escape sequences ($u, $H{field}, etc) were expanded
BEFORE mu_argcv_get was called. This led to a problem when the
substituted values contained double quotes or other characters
significant to mu_argcv_get. This is fixed by calling mu_argcv_get
first, on the unexpanded strings, then expanding each line as it is
processed.
2. mu_argcv_free was not called except in case of an error. This is
not terribly significant as the program exits after completing
run_user_action, but it could potentially consume a fair amount of
memory with a very long .biffrc file, and looks sloppy. This patch
makes sure to call mu_argcv_free wherever necessary.
3. Due to an oversight in function act_getline, line counting in
.biffrc was incorrect whenever lines were continued with
backslashes. Also, a blank line in .biffrc would cause processing
to stop since act_getline would return 0 and the while loop in
run_user_action would exit. This is fixed by having act_getline
return the number of `physical' lines returned, and using that
value to increment the line count in run_user_action.
4. act_getline returns -1 if enough memory cannot be allocated, but
this return value was ignored in run_user_action. A return of -1
from act_getline will now abort processing in run_user_action.
--- mailutils-1.0.orig/comsat/action.c 2005-08-29 03:21:54.000000000 -0700
+++ mailutils-1.0/comsat/action.c 2006-08-26 10:05:55.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,7 +79,10 @@
if (*sptr)
(*sptr)[used] = 0;
- return used;
+ /* return the number of physical lines used */
+ if (used || !feof (fp))
+ lines++;
+ return lines;
}
static int
@@ -341,50 +346,58 @@
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; c++)
+ {
+ char *oldarg = argv[c];
+ argv[c] = expand_line (argv[c], msg);
+ free(oldarg);
+ if (!argv[c])
+ break;
+ }
+ if (c >= argc) /* loop did complete */
+ {
+ 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\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);
}
Submitted by: Damon Harper <[EMAIL PROTECTED]>
Date: 2006-08-26
Summary: Add some new escapes to comsatd / .biffrc
This patch introduces two new escapes for use in comsatd's .biffrc:
$f: The full pathname of the mailbox file where the new mail is found.
$o: The offset into $f where the new mail starts.
This allows things like echoing the mailbox pathname when mail might
be in one of a number of inboxes, or passing the pathname and offset
to another program. For instance, I call a perl script that
rebroadcasts the comsat message "[EMAIL PROTECTED]:$f" to my workstation).
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-22 19:06:31.000000000 -0700
@@ -81,7 +81,7 @@
}
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 +108,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 +195,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 +218,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 +345,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;
@@ -350,7 +364,7 @@
char **argv;
line++;
- str = expand_line (stmt, msg);
+ str = expand_line (stmt, msg, path, offset);
if (!str)
continue;
if (mu_argcv_get (str, "", NULL, &argc, &argv)
@@ -390,5 +404,5 @@
}
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-22 19:06:31.000000000 -0700
@@ -433,6 +433,10 @@
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;
change_user (user);
if ((fp = fopen (device, "w")) == NULL)
@@ -501,7 +505,28 @@
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);
}
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-22 19:06:31.000000000 -0700
@@ -79,4 +79,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-22 19:06:31.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-22 19:07:00.000000000
-0700
@@ -3888,6 +3888,10 @@
Expands to username
@item $h
Expands to hostname
[EMAIL PROTECTED] $f
+Expands to the name of the folder containing the new message.
[EMAIL PROTECTED] $o
+Expands to the offset in $f where the new message starts.
@item [EMAIL PROTECTED]@}
Expands to value of message header @samp{name}.
@item $B(@var{c},@var{l})
Submitted by: Damon Harper <[EMAIL PROTECTED]>
Date: 2006-08-26
Summary: Reset access/mod times after comsatd accesses a mailbox
This patch makes comsatd reset the access and modification times on a
mailbox after scanning it for new mail. MUAs like mutt depend on the
access and modification times to let the user know if there is new
mail in a mailbox. comsatd currently causes the access time to be
updated, which thwarts this mechanism and makes it look like there is
never new mail.
There may be a better way to implement this; for example I imagine it
would be better to add an option to the various functions used to scan
mail, which causes them to reset the access time while the mailbox is
still locked. With this patch, there is a race condition that means a
legitimate access/modification time not caused by comsat might be
clobbered. However for practical purposes this quick hack seems to be
just fine.
--- mailutils-1.0/comsat/comsat.c~ 2006-08-22 19:07:59.000000000 -0700
+++ mailutils-1.0/comsat/comsat.c 2006-08-22 19:38:58.000000000 -0700
@@ -437,6 +437,9 @@
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)
@@ -454,6 +457,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)
{
@@ -528,6 +535,14 @@
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 */
--- mailutils-1.0/comsat/comsat.h~ 2006-08-22 19:07:59.000000000 -0700
+++ mailutils-1.0/comsat/comsat.h 2006-08-22 19:40:35.000000000 -0700
@@ -37,6 +37,7 @@
#include <string.h>
#include <pwd.h>
#include <ctype.h>
+#include <utime.h>
#ifdef HAVE_PATHS_H
# include <paths.h>
Submitted by: Damon Harper <[EMAIL PROTECTED]>
Date: 2006-08-26
Summary: Fix SIGCHLD handling in comsatd
This patch fixes a problem with comsatd where child processes spawned
by .biffrc commands complain because SIGCHLD has been ignored. For
example, when calling a perl script with SIGCHLD ignored, perl
generates the following error on stderr, which then gets echoed to the
tty:
Can't ignore signal CHLD, forcing to default.
With this patch, comsatd is more careful about child processes, and
also will exit more quickly if its first child exits before the
select() timeout. For this reason I've also increased the timeout
before killing a child to 1 second; unless the child is really hung,
this should never be reached.
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:44:53.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);
}
Submitted by: Damon Harper <[EMAIL PROTECTED]>
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; c++)
+ {
+ char *oldarg = argv[c];
+ argv[c] = expand_line (argv[c], msg, path, offset);
+ free(oldarg);
+ if (!argv[c])
+ break;
+ }
+ if (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 <string.h>
#include <pwd.h>
#include <ctype.h>
+#include <utime.h>
#ifdef HAVE_PATHS_H
# include <paths.h>
@@ -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
[EMAIL PROTECTED] $f
+Expands to the name of the folder containing the new message.
[EMAIL PROTECTED] $o
+Expands to the offset in $f where the new message starts.
@item [EMAIL PROTECTED]@}
Expands to value of message header @samp{name}.
@item $B(@var{c},@var{l})
_______________________________________________
Bug-mailutils mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/bug-mailutils