commit-mailutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[SCM] GNU Mailutils branch, master, updated. release-2.2-321-gb54dd74


From: Sergey Poznyakoff
Subject: [SCM] GNU Mailutils branch, master, updated. release-2.2-321-gb54dd74
Date: Thu, 23 Dec 2010 15:13:48 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU Mailutils".

http://git.savannah.gnu.org/cgit/mailutils.git/commit/?id=b54dd7430263789adc872f7568cde84cf14f66d4

The branch, master has been updated
       via  b54dd7430263789adc872f7568cde84cf14f66d4 (commit)
       via  c1421c3a608c87f900733fe336f807546cac93b1 (commit)
       via  2428c02ed615f68711f7553641b430a7160f7f0a (commit)
       via  4b30e617e722e25ed508953648dc2c0b936aa80a (commit)
       via  30b5656dcaf1511a56b965fe0f985aa7761c3a5c (commit)
       via  807f3d246e0dbe13da92328dc5dc47ca9f6d504a (commit)
       via  d3269a42e81d5df9aadae7b5cdf2e69d7dc0efc0 (commit)
       via  6bd92d3c07db00b2565730ba21f1586230510b06 (commit)
      from  886bca9c5e36d89b65fe6a28d9eb34f987f913f9 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit b54dd7430263789adc872f7568cde84cf14f66d4
Author: Sergey Poznyakoff <address@hidden>
Date:   Thu Dec 23 16:33:25 2010 +0200

    Bugfix (complements 6bd92d3c07).
    
    * libmu_sieve/util.c (mu_sieve_error, mu_sieve_debug)
    (mu_sieve_log_action): Format location only if locus.mu_file
    is not NULL.

commit c1421c3a608c87f900733fe336f807546cac93b1
Author: Sergey Poznyakoff <address@hidden>
Date:   Thu Dec 23 16:13:21 2010 +0200

    mailbox iterator: implement reverse direction and itrctl.
    
    * libmailutils/mailbox/mbxitr.c (mailbox_iterator)<backwards>: New member.
    (mbx_first): Position to the last message if itr->backwards is set.
    (mbx_next): Decrement index if itr->backwards is set.
    (mbx_finished_p): Take into account iteration direction.
    (mbx_itrctl): new method.
    (mu_mailbox_get_iterator): Set itrctl method.

commit 2428c02ed615f68711f7553641b430a7160f7f0a
Author: Sergey Poznyakoff <address@hidden>
Date:   Thu Dec 23 16:07:07 2010 +0200

    movemail: various improvements.
    
    New configuration options allow to specify the maximum number of messages
    to be copied and control the actions of movemail when an error occurs while
    appending a message.
    
    * movemail/movemail.c (ONERROR_OPTION,MAX_MESSAGES_OPTION): New option 
codes.
    (options): New options --onerror and --max-messages.
    (max_messages_option, onerror_flags): New variable.
    (ONERROR_SKIP, ONERROR_DELETE, ONERROR_COUNT): New defines.
    (parse_opt): Handle ONERROR_OPTION.
    (cb_onerror): New callback.
    (movemail_cfg_param): New configuration statements: "max-messages"
    and "onerror".
    (move_message): Delete the message if ONERROR_DELETE is set.
    (main): Handle the limit on the number of processed messages and
    onerror flags.
    Use mu_mailbox_expunge instead of mu_mailbox_flush.  This preserves
    the attributes of not processed options (in case max_messages_option is
    not 0) and speeds up the things considerably, especially on huge
    mailboxes.

commit 4b30e617e722e25ed508953648dc2c0b936aa80a
Author: Sergey Poznyakoff <address@hidden>
Date:   Thu Dec 23 16:05:02 2010 +0200

    mailer: minor improvement
    
    Be more liberal when guessing sender and recipient names. Tolerate
    deviations from RFC822.
    
    * libmailutils/mailer/mailer.c (copy_fragment)
    (recover_email, safe_address_create): New functions.
    (_set_from, _set_to): Use safe_address_create.

commit 30b5656dcaf1511a56b965fe0f985aa7761c3a5c
Author: Sergey Poznyakoff <address@hidden>
Date:   Thu Dec 23 16:02:39 2010 +0200

    Bugfixes.
    
    * frm/common.c [!HAVE_LIBFRIBIDI] (puts_bidi): Fix definition.
    * libproto/pop/mbox.c (pop_destroy): Fix coredump (occurred
    if the mailbox has not been scanned).

commit 807f3d246e0dbe13da92328dc5dc47ca9f6d504a
Author: Sergey Poznyakoff <address@hidden>
Date:   Thu Dec 23 13:34:17 2010 +0200

    Bugfixes
    
    * libmailutils/base/lcall.c (mu_parse_lc_all): Allow for arg==NULL.
    * mh/Makefile.am: Define mhlibdir.
    * mh/pick.y (match_header): Use sget accessors.
    * mh/repl.c: Accept -noquery silently.

commit d3269a42e81d5df9aadae7b5cdf2e69d7dc0efc0
Author: Sergey Poznyakoff <address@hidden>
Date:   Thu Dec 23 12:27:13 2010 +0200

    mail: fix the "shell" ("!") command.
    
    * mail/mail.h (mail_execute): Change signature. All callers updated.
    * mail/shell.c (expand_bang): Change signature.  Take the
    string to be expanded as the 2nd and the last command as 3rd arguments.
    Always allocate the return string, even if there's nothing to expand.
    (mail_execute): fix memory management.
    * mail/escape.c: Update.
    * mail/escape.c: Update calls to mail_execute.

commit 6bd92d3c07db00b2565730ba21f1586230510b06
Author: Sergey Poznyakoff <address@hidden>
Date:   Thu Dec 23 12:25:26 2010 +0200

    Follow-up to the previous commit.
    
    * libmu_sieve/util.c: Update.

-----------------------------------------------------------------------

Summary of changes:
 frm/common.c                   |    2 +-
 libmailutils/base/lcall.c      |   13 +++-
 libmailutils/mailbox/mailbox.c |    4 +-
 libmailutils/mailbox/mbxitr.c  |   86 +++++++++++++++++++--
 libmailutils/mailer/mailer.c   |   83 ++++++++++++++++++++-
 libmu_sieve/util.c             |   23 +++++-
 libproto/pop/mbox.c            |   17 +++--
 mail/escape.c                  |    4 +-
 mail/mail.h                    |    2 +-
 mail/shell.c                   |   78 ++++++++++++-------
 mh/Makefile.am                 |    2 +
 mh/pick.y                      |   14 +++-
 mh/repl.c                      |    3 +-
 movemail/movemail.c            |  164 ++++++++++++++++++++++++++++++++++------
 14 files changed, 405 insertions(+), 90 deletions(-)

diff --git a/frm/common.c b/frm/common.c
index dfecd2d..5928385 100644
--- a/frm/common.c
+++ b/frm/common.c
@@ -199,7 +199,7 @@ puts_bidi (char *string)
 }
 #else
 # define alloc_logical(s)
-# define puts_bidi(s) mu_stream_printf ("%s\n", s)
+# define puts_bidi(s) mu_printf ("%s\n", s)
 #endif
 
 
diff --git a/libmailutils/base/lcall.c b/libmailutils/base/lcall.c
index 0485699..9bc5c07 100644
--- a/libmailutils/base/lcall.c
+++ b/libmailutils/base/lcall.c
@@ -112,8 +112,19 @@ int
 mu_parse_lc_all (const char *arg, struct mu_lc_all *str, int flags)
 {
   int rc;
-  
+
   memset (str, 0, sizeof (str[0]));
+  if (!arg)
+    {
+      if (flags & MU_LC_LANG)
+       {
+         str->language = strdup ("C");
+         if (!str->language)
+           return ENOMEM;
+       }
+      return 0;
+    }
+  
   rc = _parse_lc_all (arg, str, flags);
   if (rc == 0 && !str->charset)
     {
diff --git a/libmailutils/mailbox/mailbox.c b/libmailutils/mailbox/mailbox.c
index 7960051..d3304b0 100644
--- a/libmailutils/mailbox/mailbox.c
+++ b/libmailutils/mailbox/mailbox.c
@@ -175,9 +175,7 @@ _create_mailbox (mu_mailbox_t *pmbox, const char *name)
 }
 
 /* The Mailbox Factory.
-   Create an iterator for registrar and see if any url scheme match,
-   Then we call the mailbox's mu_url_create() to parse the URL. Last
-   initialize the concrete mailbox and folder.  */
+ */
 int
 mu_mailbox_create (mu_mailbox_t *pmbox, const char *name)
 {
diff --git a/libmailutils/mailbox/mbxitr.c b/libmailutils/mailbox/mbxitr.c
index c8ae139..8885a58 100644
--- a/libmailutils/mailbox/mbxitr.c
+++ b/libmailutils/mailbox/mbxitr.c
@@ -27,6 +27,8 @@
 #include <mailutils/errno.h>
 #include <mailutils/error.h>
 #include <mailutils/iterator.h>
+#include <mailutils/message.h>
+#include <mailutils/attribute.h>
 
 #include <mailutils/sys/mailbox.h>
 
@@ -34,13 +36,17 @@ struct mailbox_iterator
 {
   mu_mailbox_t mbx;
   size_t idx;
+  int backwards;
 };
 
 static int
 mbx_first (void *owner)
 {
   struct mailbox_iterator *itr = owner;
-  itr->idx = 1;
+  if (itr->backwards)
+    return mu_mailbox_messages_count (itr->mbx, &itr->idx);
+  else
+    itr->idx = 1;
   return 0;
 }
 
@@ -48,7 +54,14 @@ static int
 mbx_next (void *owner)
 {
   struct mailbox_iterator *itr = owner;
-  itr->idx++;
+
+  if (itr->backwards)
+    {
+      if (itr->idx)
+       --itr->idx;
+    }
+  else
+    itr->idx++;
   return 0;
 }
 
@@ -74,11 +87,17 @@ static int
 mbx_finished_p (void *owner)
 {
   struct mailbox_iterator *itr = owner;
-  size_t count;
-
-  if (mu_mailbox_messages_count (itr->mbx, &count))
-    return 1;
-  return itr->idx > count;
+  
+  if (itr->backwards)
+    return itr->idx == 0;
+  else
+    {
+      size_t count;
+      
+      if (mu_mailbox_messages_count (itr->mbx, &count))
+       return 1;
+      return itr->idx > count;
+    }
 }
 
 static int
@@ -114,6 +133,55 @@ mbx_data_dup (void **ptr, void *owner)
   return 0;
 }
 
+static int
+mbx_itrctl (void *owner, enum mu_itrctl_req req, void *arg)
+{
+  int rc;
+  struct mailbox_iterator *itr = owner;
+  mu_message_t msg;
+  mu_attribute_t attr;
+  
+  if (itr->idx == 0)
+    return MU_ERR_NOENT;
+  switch (req)
+    {
+    case mu_itrctl_tell:
+      *(size_t*)arg = itr->idx;
+      break;
+
+    case mu_itrctl_delete:
+      rc = mu_mailbox_get_message (itr->mbx, itr->idx, &msg);
+      if (rc)
+       return rc;
+      rc = mu_message_get_attribute (msg, &attr);
+      if (rc)
+       return rc;
+      rc = mu_attribute_set_deleted (attr);
+      if (rc)
+       return rc;
+      break;
+
+    case mu_itrctl_qry_direction:
+      if (!arg)
+       return EINVAL;
+      else
+       *(int*)arg = itr->backwards;
+      break;
+
+    case mu_itrctl_set_direction:
+      if (!arg)
+       return EINVAL;
+      else     
+       itr->backwards = !!*(int*)arg;
+      break;
+      
+    default:
+      return ENOSYS;
+    }
+  return 0;
+}
+
+
 int
 mu_mailbox_get_iterator (mu_mailbox_t mbx, mu_iterator_t *piterator)
 {
@@ -129,7 +197,8 @@ mu_mailbox_get_iterator (mu_mailbox_t mbx, mu_iterator_t 
*piterator)
     return ENOMEM;
   itr->mbx = mbx;
   itr->idx = 1;
-
+  itr->backwards = 0;
+  
   status = mu_iterator_create (&iterator, itr);
   if (status)
     {
@@ -144,6 +213,7 @@ mu_mailbox_get_iterator (mu_mailbox_t mbx, mu_iterator_t 
*piterator)
   mu_iterator_set_curitem_p (iterator, mbx_curitem_p);
   mu_iterator_set_destroy (iterator, mbx_destroy);
   mu_iterator_set_dup (iterator, mbx_data_dup);
+  mu_iterator_set_itrctl (iterator, mbx_itrctl);
 
   mu_iterator_attach (&mbx->iterator, iterator);
 
diff --git a/libmailutils/mailer/mailer.c b/libmailutils/mailer/mailer.c
index bcc3b85..b6ad08d 100644
--- a/libmailutils/mailer/mailer.c
+++ b/libmailutils/mailer/mailer.c
@@ -51,6 +51,8 @@
 #include <mailutils/util.h>
 #include <mailutils/mime.h>
 #include <mailutils/io.h>
+#include <mailutils/cctype.h>
+#include <mailutils/parse822.h>
 
 #include <mailutils/sys/mailer.h>
 
@@ -325,6 +327,83 @@ save_fcc (mu_message_t msg)
 }
 
 static int
+copy_fragment (char **pretender, const char *p, const char *q)
+{
+  size_t len = q - p + 1;
+  *pretender = malloc (len + 1);
+  if (!*pretender)
+    return ENOMEM;
+  memcpy (*pretender, p, len);
+  (*pretender)[len] = 0;
+  return 0;
+}
+
+/* Try to extract from STRING a portion that looks like an email address */
+static int
+recover_email (const char *string, char **pretender)
+{
+  char *p, *q;
+
+  p = strchr (string, '<');
+  if (p)
+    {
+      q = strchr (p, '>');
+      if (q)
+       return copy_fragment (pretender, p, q);
+    }
+  p = mu_str_skip_class (string, MU_CTYPE_SPACE);
+  if (*p && mu_parse822_is_atom_char (*p))
+    {
+      q = p;
+      while (*++q && (mu_parse822_is_atom_char (*q) || *q == '.'))
+       ;
+      if (*q == '@')
+       while (*++q && (mu_parse822_is_atom_char (*q) || *q == '.'))
+         ;
+      q--;
+      if (q > p)
+       return copy_fragment (pretender, p, q);
+    }
+  return MU_ERR_NOENT;
+}
+
+static int
+safe_address_create (mu_address_t *paddr, const char *addr_str,
+                    const char *who)
+{
+  int status = mu_address_create (paddr, addr_str);
+  if (status == MU_ERR_BAD_822_FORMAT)
+    {
+      int rc;
+      char *p;
+      
+      mu_debug (MU_DEBCAT_MAILER, MU_DEBUG_ERROR,
+               ("bad %s address: %s", who, addr_str));
+      rc = recover_email (addr_str, &p);
+      if (rc && rc != MU_ERR_NOENT)
+       mu_debug (MU_DEBCAT_MAILER, MU_DEBUG_ERROR,
+                 ("%s address recovery failed: %s", who, mu_strerror (rc)));
+      else
+       {
+         mu_debug (MU_DEBCAT_MAILER, MU_DEBUG_TRACE1,
+                   ("recovered possible %s address: %s", who, p));
+         rc = mu_address_create (paddr, p);
+         if (rc == 0)
+           status = 0;
+         else if (rc == MU_ERR_BAD_822_FORMAT)
+           mu_debug (MU_DEBCAT_MAILER, MU_DEBUG_TRACE1,
+                     ("%s address guess failed", who));
+         else
+           mu_debug (MU_DEBCAT_MAILER, MU_DEBUG_ERROR,
+                     ("cannot convert %s address '%s': %s",
+                      who, p, mu_strerror (rc)));
+         free (p);
+       }
+    }
+  return status;
+}
+
+static int
 _set_from (mu_address_t *pfrom, mu_message_t msg, mu_address_t from,
           mu_mailer_t mailer)
 {
@@ -393,7 +472,7 @@ _set_from (mu_address_t *pfrom, mu_message_t msg, 
mu_address_t from,
          /* FIXME: should we add the From: header? */
          break;
        }
-      status = mu_address_create (pfrom, mail_from);
+      status = safe_address_create (pfrom, mail_from, "sender");
     }
   
   return status;
@@ -427,7 +506,7 @@ _set_to (mu_address_t *paddr, mu_message_t msg, 
mu_address_t to,
       mu_debug (MU_DEBCAT_MAILER, MU_DEBUG_TRACE,
                ("mu_mailer_send_message(): using RCPT TO: %s",
                 rcpt_to));
-      status = mu_address_create (paddr, rcpt_to);
+      status = safe_address_create (paddr, rcpt_to, "recipient");
     }
   
   return status;
diff --git a/libmu_sieve/util.c b/libmu_sieve/util.c
index 943662a..35685ab 100644
--- a/libmu_sieve/util.c
+++ b/libmu_sieve/util.c
@@ -209,8 +209,12 @@ mu_sieve_error (mu_sieve_machine_t mach, const char *fmt, 
...)
   va_list ap;
   
   va_start (ap, fmt);
-  mu_stream_printf (mach->errstream, "\033s<%d>\033O<%d>",
-                   MU_LOG_ERROR, MU_LOGMODE_LOCUS);
+  mu_stream_printf (mach->errstream, "\033s<%d>", MU_LOG_ERROR);
+  if (mach->locus.mu_file)
+    mu_stream_printf (mach->errstream, "\033O<%d>\033f<%u>%s\033l<%u>",
+                     MU_LOGMODE_LOCUS,
+                     strlen (mach->locus.mu_file), mach->locus.mu_file,
+                     mach->locus.mu_line);
   if (mach->identifier)
     mu_stream_printf (mach->errstream, "%s: ", mach->identifier);
   mu_stream_vprintf (mach->errstream, fmt, ap);
@@ -230,9 +234,12 @@ mu_sieve_debug (mu_sieve_machine_t mach, const char *fmt, 
...)
   va_list ap;
 
   va_start (ap, fmt);
-  mu_stream_printf (mach->errstream,
-                   "\033s<%d>\033O<%d>",
-                   MU_LOG_DEBUG, MU_LOGMODE_LOCUS);
+  mu_stream_printf (mach->errstream, "\033s<%d>", MU_LOG_DEBUG);
+  if (mach->locus.mu_file)
+    mu_stream_printf (mach->errstream, "\033O<%d>\033f<%u>%s\033l<%u>",
+                     MU_LOGMODE_LOCUS,
+                     strlen (mach->locus.mu_file), mach->locus.mu_file,
+                     mach->locus.mu_line);
   mu_stream_vprintf (mach->errstream, fmt, ap);
   mu_stream_write (mach->errstream, "\n", 1, NULL);
   va_end (ap);
@@ -247,6 +254,12 @@ mu_sieve_log_action (mu_sieve_machine_t mach, const char 
*action,
   if (!mach->logger)
     return;
   va_start (ap, fmt);
+  mu_stream_printf (mach->errstream, "\033s<%d>", MU_LOG_INFO);
+  if (mach->locus.mu_file)
+    mu_stream_printf (mach->errstream, "\033O<%d>\033f<%u>%s\033l<%u>",
+                     MU_LOGMODE_LOCUS,
+                     strlen (mach->locus.mu_file), mach->locus.mu_file,
+                     mach->locus.mu_line);
   mach->logger (mach->data, mach->errstream, mach->msgno, mach->msg,
                action, fmt, ap);
   va_end (ap);
diff --git a/libproto/pop/mbox.c b/libproto/pop/mbox.c
index 7c4eeb9..6160d0d 100644
--- a/libproto/pop/mbox.c
+++ b/libproto/pop/mbox.c
@@ -211,15 +211,18 @@ pop_destroy (mu_mailbox_t mbox)
     {
        size_t i;
       mu_monitor_wrlock (mbox->monitor);
-      /* Destroy the pop messages and resources associated to them.  */
-      for (i = 0; i < mpd->msg_count; i++)
+      if (mpd->msg)
        {
-         if (mpd->msg[i])
+         /* Destroy the pop messages and resources associated to them.  */
+         for (i = 0; i < mpd->msg_count; i++)
            {
-             mu_message_destroy (&mpd->msg[i]->message, mpd->msg[i]);
-             if (mpd->msg[i]->uidl)
-               free (mpd->msg[i]->uidl);
-             free (mpd->msg[i]);
+             if (mpd->msg[i])
+               {
+                 mu_message_destroy (&mpd->msg[i]->message, mpd->msg[i]);
+                 if (mpd->msg[i]->uidl)
+                   free (mpd->msg[i]->uidl);
+                 free (mpd->msg[i]);
+               }
            }
        }
       mu_pop3_destroy (&mpd->pop3);
diff --git a/mail/escape.c b/mail/escape.c
index de1c15e..8e7f109 100644
--- a/mail/escape.c
+++ b/mail/escape.c
@@ -173,7 +173,7 @@ escape_check_args (int argc, char **argv)
 int
 escape_shell (int argc, char **argv, compose_env_t *env)
 {
-  return mail_execute (1, argc - 1, argv + 1);
+  return mail_execute (1, argv[1], argc - 1, argv + 1);
 }
 
 /* ~:[mail-command] */
@@ -325,7 +325,7 @@ run_editor (char *ed, char *arg)
   argv[0] = ed;
   argv[1] = arg;
   argv[2] = NULL;
-  return mail_execute (1, 2, argv);
+  return mail_execute (1, arg, 2, argv);
 }
 
 static int
diff --git a/mail/mail.h b/mail/mail.h
index f2bb9ca..72a0440 100644
--- a/mail/mail.h
+++ b/mail/mail.h
@@ -217,7 +217,7 @@ extern int mail_save (int argc, char **argv);
 extern int mail_sendheader (int argc, char **argv);
 extern int mail_set (int argc, char **argv);
 extern int mail_shell (int argc, char **argv);
-extern int mail_execute (int shell, int argc, char **argv);
+extern int mail_execute (int shell, char *progname, int argc, char **argv);
 extern int mail_size (int argc, char **argv);
 extern int mail_source (int argc, char **argv);
 extern int mail_summary (int argc, char **argv);
diff --git a/mail/shell.c b/mail/shell.c
index 3ec5885..7f32412 100644
--- a/mail/shell.c
+++ b/mail/shell.c
@@ -18,20 +18,21 @@
 #include "mail.h"
 
 static void
-expand_bang (char **pbuf)
+expand_bang (char **pbuf, const char *arg, const char *last)
 {
-  char *last = NULL;
-  char *tmp, *p, *q;
+  char *tmp, *q;
+  const char *p;
   size_t count = 0;
   
-  mailvar_get (&last, "gnu-last-command", mailvar_type_string, 0);
-
-  for (p = *pbuf; *p; p++)
+  for (p = arg; *p; p++)
     if (*p == '!')
       count++;
 
   if (count == 0)
-    return;
+    {
+      *pbuf = xstrdup (arg);
+      return;
+    }
 
   if (!last)
     {
@@ -39,8 +40,8 @@ expand_bang (char **pbuf)
       return;
     }
 
-  tmp = xmalloc (strlen (*pbuf) + count * (strlen (last) - 1) + 1);
-  for (p = *pbuf, q = tmp; *p; )
+  tmp = xmalloc (strlen (arg) + count * (strlen (last) - 1) + 1);
+  for (p = arg, q = tmp; *p; )
     {
       if (*p == '!')
        {
@@ -49,7 +50,7 @@ expand_bang (char **pbuf)
          p++;
        }
       else
-       *p++ = *q++;
+       *q++ = *p++;
     }
   *q = 0;
   
@@ -58,12 +59,13 @@ expand_bang (char **pbuf)
 }
 
 int
-mail_execute (int shell, int argc, char **argv)
+mail_execute (int shell, char *progname, int argc, char **argv)
 {
   int xargc, i, status, rc;
   char **xargv;
   char *buf;
-
+  int expanded; /* Indicates whether argv has been bang-expanded */
+  
   if (argc == 0)
     {
       /* No arguments mean execute a copy of the user shell */
@@ -75,18 +77,27 @@ mail_execute (int shell, int argc, char **argv)
     xargc = 3;
   xargv = xcalloc (xargc + 1, sizeof (xargv[0]));
   
-  for (i = 0; i < argc; i++)
-    xargv[i] = argv[i];
-
   /* Expand arguments if required */
   if (mailvar_get (NULL, "bang", mailvar_type_boolean, 0) == 0)
     {
       int i;
-
-      for (i = 0; i < xargc; i++)
-       expand_bang (xargv + i);
+      char *last = NULL;
+      
+      mailvar_get (&last, "gnu-last-command", mailvar_type_string, 0);
+      expand_bang (xargv, progname, last);
+      for (i = 1; i < argc; i++)
+       expand_bang (xargv + i, argv[i], last);
+      expanded = 1;
     }
-
+  else
+    {
+      if (argc)
+       xargv[0] = progname;
+      for (i = 1; i < argc; i++)
+       xargv[i] = argv[i];
+      expanded = 0;
+    }
+  
   /* Reconstruct the command line and save it to gnu-last-command variable.
      Important: use argc (not xargc)!
   */
@@ -96,14 +107,25 @@ mail_execute (int shell, int argc, char **argv)
 
   if (shell)
     {
+      if (expanded)
+       {
+         for (i = 0; i < argc; i++)
+           free (xargv[i]);
+         expanded = 0;
+       }
+      
       xargv[0] = getenv ("SHELL");
       if (argc == 0)
-       xargv[1] = NULL;
+       {
+         xargv[1] = NULL;
+         xargc = 1;
+       }
       else
        {
          xargv[1] = "-c";
          xargv[2] = buf;
          xargv[3] = NULL;
+         xargc = 3;
        }
     }  
   
@@ -117,6 +139,9 @@ mail_execute (int shell, int argc, char **argv)
     mu_diag_output (MU_DIAG_NOTICE, ....
   */
   free (buf);
+  if (expanded)
+    for (i = 0; i < argc; i++)
+      free (xargv[i]);
   free (xargv);
   return rc;
 }
@@ -130,18 +155,11 @@ int
 mail_shell (int argc, char **argv)
 {
   if (argv[0][0] == '!' && strlen (argv[0]) > 1)
-    {
-      argv[0][0] = ' ';
-      return mail_execute (1, argc, argv);
-    }
+    return mail_execute (1, argv[0] + 1, argc, argv);
   else if (argc > 1)
-    {
-      return mail_execute (0, argc-1, argv+1);
-    }
+    return mail_execute (0, argv[1], argc-1, argv+1);
   else
-    {
-      return mail_execute (1, 0, NULL);
-    }
+    return mail_execute (1, NULL, 0, NULL);
   return 1;
 }
 
diff --git a/mh/Makefile.am b/mh/Makefile.am
index 4682a9b..b41b44c 100644
--- a/mh/Makefile.am
+++ b/mh/Makefile.am
@@ -95,6 +95,8 @@ MAINTAINERCLEANFILES=$(BUILT_SOURCES)
 
 EXTRA_DIST = mh_fmtgram.y pick.y mh_alias.y mh_alias.l
 
+mhlibdir = $(pkgdatadir)/mh
+
 INCLUDES = @MU_APP_COMMON_INCLUDES@ 
 AM_CPPFLAGS = -D_GNU_SOURCE -DMHLIBDIR=\"$(mhlibdir)\" -DMHBINDIR=\"$(bindir)\"
 mh_LIBS = \
diff --git a/mh/pick.y b/mh/pick.y
index b123849..399a65a 100644
--- a/mh/pick.y
+++ b/mh/pick.y
@@ -296,18 +296,24 @@ struct eval_env
 static int
 match_header (mu_message_t msg, char *comp, regex_t *regex)
 {
+  int rc;
   size_t i, count;
   mu_header_t hdr = NULL;
-  char buf[128];
+  const char *buf;
   
-  mu_message_get_header (msg, &hdr);
+  rc = mu_message_get_header (msg, &hdr);
+  if (rc)
+    {
+      mu_error (_("cannot get header: %s"), mu_strerror (rc));
+      return 0;
+    }
   mu_header_get_field_count (hdr, &count);
   for (i = 1; i <= count; i++)
     {
-      mu_header_get_field_name (hdr, i, buf, sizeof buf, NULL);
+      mu_header_sget_field_name (hdr, i, &buf);
       if (mu_c_strcasecmp (buf, comp) == 0)
        {
-         mu_header_get_field_value (hdr, i, buf, sizeof buf, NULL);
+         mu_header_sget_field_value (hdr, i, &buf);
          if (regexec (regex, buf, 0, NULL, 0) == 0)
            return 1;
        }
diff --git a/mh/repl.c b/mh/repl.c
index 93bcdaf..bbf5033 100644
--- a/mh/repl.c
+++ b/mh/repl.c
@@ -221,8 +221,9 @@ opt_handler (int key, char *arg, struct argp_state *state)
       break;
       
     case ARG_QUERY:
-      mh_opt_notimpl_warning ("-inplace");
       query_mode = is_true (arg);
+      if (query_mode)
+       mh_opt_notimpl_warning ("-query");
       break;
       
     case ARG_FILTER:
diff --git a/movemail/movemail.c b/movemail/movemail.c
index 72408d4..4dcacd5 100644
--- a/movemail/movemail.c
+++ b/movemail/movemail.c
@@ -36,7 +36,9 @@ static char args_doc[] = N_("inbox-url destfile 
[POP-password]");
 enum {
   EMACS_OPTION=256,
   IGNORE_ERRORS_OPTION,
-  PROGRAM_ID_OPTION
+  PROGRAM_ID_OPTION,
+  MAX_MESSAGES_OPTION,
+  ONERROR_OPTION
 };
 
 static struct argp_option options[] = {
@@ -53,8 +55,12 @@ static struct argp_option options[] = {
     N_("control mailbox ownership") },
   { "ignore-errors", IGNORE_ERRORS_OPTION, NULL, 0,
     N_("try to continue after errors") },
+  { "onerror", ONERROR_OPTION, N_("KW[,KW...]"), 0,
+    N_("what to do on errors") },
   { "program-id", PROGRAM_ID_OPTION, N_("FMT"), 0,
     N_("set program identifier for diagnostics (default: program name)") },
+  { "max-messages", MAX_MESSAGES_OPTION, N_("NUMBER"), 0,
+    N_("process at most NUMBER messages") },
   { NULL,      0, NULL, 0, NULL, 0 }
 };
 
@@ -65,6 +71,14 @@ static int uidl_option;
 static int verbose_option;
 static int ignore_errors;
 static char *program_id_option;
+static size_t max_messages_option;
+
+  /* These bits tell what to do when an error occurs: */
+#define ONERROR_SKIP     0x01  /* Skip to the next message */
+#define ONERROR_DELETE   0x02  /* Delete the source message */
+#define ONERROR_COUNT    0x04  /* Count it as processed */ 
+
+static int onerror_flags;  
 
 enum set_ownership_mode
   {
@@ -149,6 +163,14 @@ parse_opt (int key, char *arg, struct argp_state *state)
       mu_argp_node_list_new (lst, "ignore-errors", "yes");
       break;
 
+    case ONERROR_OPTION:
+      mu_argp_node_list_new (lst, "onerror", arg);
+      break;
+      
+    case MAX_MESSAGES_OPTION:
+      mu_argp_node_list_new (lst, "max-messages", arg);
+      break;
+      
     case PROGRAM_ID_OPTION:
       mu_argp_node_list_new (lst, "program-id", arg);
       break;
@@ -288,6 +310,49 @@ cb_mailbox_ownership (void *data, mu_config_value_t *val)
   return 0;
 }
 
+static int
+cb_onerror (void *data, mu_config_value_t *val)
+{
+  struct mu_wordsplit ws;
+  static struct mu_kwd onerror_kw[] = {
+    { "skip", ONERROR_SKIP },
+    { "delete", ONERROR_DELETE },
+    { "count", ONERROR_COUNT },
+    { NULL }
+  };
+  int i, flag;
+  
+  if (mu_cfg_assert_value_type (val, MU_CFG_STRING))
+    return 1;
+  ws.ws_delim = ",";
+  if (mu_wordsplit (val->v.string, &ws,
+                   MU_WRDSF_NOVAR | MU_WRDSF_NOCMD |
+                   MU_WRDSF_DELIM | MU_WRDSF_WS))
+    {
+      mu_error (_("cannot split argument: %s"), mu_wordsplit_strerror (&ws));
+      return 1;
+    }
+  for (i = 0; i < ws.ws_wordc; i++)
+    {
+      int clr = 0;
+      char *name = ws.ws_wordv[i];
+      
+      if (strncmp (name, "no", 2) == 0)
+       {
+         clr = 1;
+         name += 2;
+       }
+      if (mu_kwd_xlat_name (onerror_kw, name, &flag))
+       mu_error (_("unknown keyword: %s"), ws.ws_wordv[i]);
+      if (clr)
+       onerror_flags &= ~flag;
+      else
+       onerror_flags |= flag;
+    }
+  mu_wordsplit_free (&ws);
+  return 0;
+}
+  
 struct mu_cfg_param movemail_cfg_param[] = {
   { "preserve", mu_cfg_bool, &preserve_mail, 0, NULL,
     N_("Do not remove messages from the source mailbox.") },
@@ -299,8 +364,6 @@ struct mu_cfg_param movemail_cfg_param[] = {
     N_("Use UIDLs to avoid downloading the same message twice.") },
   { "verbose", mu_cfg_int, &verbose_option, 0, NULL,
     N_("Set verbosity level.") },
-  { "ignore-errors", mu_cfg_bool, &ignore_errors, 0, NULL,
-    N_("Continue after an error.") },
   { "program-id", mu_cfg_string, &program_id_option, 0, NULL,
     N_("Set program identifier string (default: program name)") },
   { "mailbox-ownership", mu_cfg_callback, NULL, 0,
@@ -312,6 +375,16 @@ struct mu_cfg_param movemail_cfg_param[] = {
        " set-id=UID[:GID] set supplied UID and GID\n"
        " set-name=USER    make destination mailbox owned by USER"),
     N_("methods: list") },
+  { "max-messages", mu_cfg_size, &max_messages_option, 0, NULL,
+    N_("Copy at most <count> messages."),
+    N_("count") },
+  { "ignore-errors", mu_cfg_bool, &ignore_errors, 0, NULL,
+    N_("Continue after an error.") },
+  { "onerror", mu_cfg_callback, NULL, 0, cb_onerror,
+    N_("What to do after an error. Argument is a comma-separated list of:\n"
+       " skip   -  skip to the next message\n"
+       " delete -  delete this one and to the next message\n"
+       " count  -  count this message as processed") },
   { NULL }
 };
 
@@ -437,7 +510,8 @@ move_message (mu_mailbox_t src, mu_mailbox_t dst, size_t 
msgno)
     {
       mu_error (_("cannot append message %lu: %s"),
                (unsigned long) msgno, mu_strerror (rc));
-      return rc;
+      if (!(onerror_flags & ONERROR_DELETE))
+       return rc;
     }
   if (!preserve_mail)
     {
@@ -770,6 +844,9 @@ main (int argc, char **argv)
       return 1;
     }
 
+  if (ignore_errors)
+    onerror_flags |= ONERROR_SKIP;
+  
   if (emacs_mode)
     {      
       /* Undo the effect of configuration options that may affect
@@ -805,10 +882,22 @@ main (int argc, char **argv)
     }
   
   if (verbose_option)
-    mu_diag_output (MU_DIAG_INFO,
-                   _("number of messages in source mailbox: %lu"),
-                   (unsigned long) total);
-
+    {
+      mu_diag_output (MU_DIAG_INFO,
+                     _("number of messages in source mailbox: %lu"),
+                     (unsigned long) total);
+      if (max_messages_option)
+       mu_diag_output (MU_DIAG_INFO,
+                       reverse_order ?
+                       ngettext ("will process last %lu message",
+                                 "will process last %lu messages",
+                                 max_messages_option) :
+                       ngettext ("will process first %lu message",
+                                 "will process first %lu messages",
+                                 max_messages_option),
+                       (unsigned long) max_messages_option);
+    }
+  
   if (uidl_option)
     {
       mu_iterator_t itr;
@@ -864,11 +953,19 @@ main (int argc, char **argv)
          mu_iterator_current (itr, (void **)&uidl);
          rc = move_message (source, dest, uidl->msgno);
          if (rc == 0)
-           msg_count++;
-         else if (!ignore_errors)
-           break;
+           {
+             ++msg_count;
+           }
+         else if (onerror_flags)
+           {
+             if (onerror_flags & ONERROR_COUNT)
+               ++msg_count;
+             errs = 1;
+           }
          else
-           errs = 1;
+           break;
+         if (max_messages_option && msg_count >= max_messages_option)
+           break;
        }
       mu_iterator_destroy (&itr);
     }
@@ -878,11 +975,19 @@ main (int argc, char **argv)
        {
          rc = move_message (source, dest, i);
          if (rc == 0)
-           msg_count++;
-         else if (!ignore_errors)
-           break;
+           {
+             ++msg_count;
+           }
+         else if (onerror_flags)
+           {
+             if (onerror_flags & ONERROR_COUNT)
+               ++msg_count;
+             errs = 1;
+           }
          else
-           errs = 1;
+           break;
+         if (max_messages_option && msg_count >= max_messages_option)
+           break;
        }
     }
   else
@@ -891,11 +996,19 @@ main (int argc, char **argv)
        {
          rc = move_message (source, dest, i);
          if (rc == 0)
-           msg_count++;
-         else if (!ignore_errors)
-           break;
+           {
+             ++msg_count;
+           }
+         else if (onerror_flags)
+           {
+             if (onerror_flags & ONERROR_COUNT)
+               ++msg_count;
+             errs = 1;
+           }
          else
-           errs = 1;
+           break;
+         if (max_messages_option && msg_count >= max_messages_option)
+           break;
        }
     }
   
@@ -903,17 +1016,18 @@ main (int argc, char **argv)
     mu_diag_output (MU_DIAG_INFO,
                    _("number of processed messages: %lu"),
                    (unsigned long) msg_count);
-  
-  if (rc)
-    return !!rc;
-  
+
+  if (errs && !(onerror_flags & (ONERROR_DELETE|ONERROR_COUNT)))
+    /* FIXME: mailboxes are not properly closed */
+    return 1;
+      
   mu_mailbox_sync (dest);
   rc = mu_mailbox_close (dest);
   mu_mailbox_destroy (&dest);
   if (rc)
     mu_error (_("cannot close destination mailbox: %s"), mu_strerror (rc));
   else if (!preserve_mail)
-    mu_mailbox_flush (source, 1);
+    mu_mailbox_expunge (source);
 
   mu_mailbox_close (source);
   mu_mailbox_destroy (&source);


hooks/post-receive
-- 
GNU Mailutils



reply via email to

[Prev in Thread] Current Thread [Next in Thread]