hi there!

i'm currently looking into replacing some old packages on my system
with the versions in mailutils.  i started with comsatd - i love the
ability to run arbitrary programs, which is something i started
hacking into the old biff+comsat package ages ago but never got around
to finishing.

i ran into a few issues which i've attempted to fix in the attached
patch.  the patch may not be ideal and should probably a launching
point for discussion more than anything else.


1. in my setup, i have procmail notify comsat for a set of mailboxes
to which mail can be delivered, not just my main inbox.  i had hacked
biff+comsat to accept the new style protocol giving the mailbox
filename, and also modified its output to print hte mailbox name on
the terminal so i would know where to look for the new mail.

in the attached patch, i've modified the various expand_* functions to
accept the mailbox pathname and a stringified offset, so that these
can be inserted into commands as $f (folder/filename) and $o (offset)
respectively.  This way i can use $f in my .biffrc to show which
mailbox the new mail has arrived in.  $o might be useful for an exec'd
program that wants to examine the mailbox file directly.

i'm not sure if there was a more efficient way to do this than to pass
these two strings down the chain of functions (can they already be
gleaned from the mu_message_t object somehow?) so if there's a better
way, feel free to let me know and i'll modify this.


2. i use mutt to read mail, and mutt indicates that a folder has new
mail based on its access time being earlier than its modification
time.  the old biff+comsat in.comsat seemed to preserve this, but as
soon as i switched to the mailutils comsatd, i stopped seeing new mail
in folders that comsatd was accessing.

to work around this, the patch stats the mailbox file before the first
mu_mailbox_create call, then uses utime(2) to restore the access and
modification times after it finishes doing its thing.  i suppose this
might not be ideal (maybe better to save/restore the times while the
mailbox is locked, to prevent resetting *after* newer mail has come
in?) but it was a quick way to fix this and seems to work fine for
practical purposes.


3. (not included in the patch) - should a standard biff(1) command be
included in the mailutils package?  i'm currently using the one from
biff+comsatd, which i still find useful in some situations.  it lets
me quickly turn off the notifications in a particular terminal if i
don't want comsat messing up my screen there.  i notice that comsat
already includes logic to look for the first WRITABLE tty, skipping
over any that are not writable, so it seems to me it would still be
useful to include a biff(1) in the package?


thanks!

-damon
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:45:50.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:45:50.000000000 -0700
@@ -433,6 +433,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 +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)
     {
@@ -501,8 +512,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, "%ul", 
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-22 19:45:50.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-22 19:45:50.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:45:50.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

Reply via email to