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-703-geea2c4a


From: Sergey Poznyakoff
Subject: [SCM] GNU Mailutils branch, master, updated. release-2.2-703-geea2c4a
Date: Mon, 04 May 2015 13:19:52 +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=eea2c4aa6f4383f3288ddc0c9e5084e36d31d9ac

The branch, master has been updated
       via  eea2c4aa6f4383f3288ddc0c9e5084e36d31d9ac (commit)
      from  be9580f6db6b710e0cd67ca326cac794742a112c (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 eea2c4aa6f4383f3288ddc0c9e5084e36d31d9ac
Author: Sergey Poznyakoff <address@hidden>
Date:   Mon May 4 16:11:53 2015 +0300

    mail: the "copy" command operates on files by default.
    
    Last argument is treated as a mailbox only if it begins with
    a mailbox scheme (mbox://, maildir://, etc).
    
    * mail/copy.c (append_to_mailbox)
    (append_to_file): New functions.
    (mail_copy0): Depending on whether mailbox scheme is specified,
    call one of the above functions.
    * doc/texinfo/programs.texi (mail): Fix documentation of the copy
    command.
    * mail/testsuite/mail/write.exp: Update line/character counts for
    [Ss]ave commands.

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

Summary of changes:
 doc/texinfo/programs.texi     |   17 ++-
 mail/copy.c                   |  235 ++++++++++++++++++++++++++++++++--------
 mail/testsuite/mail/write.exp |    4 +-
 3 files changed, 202 insertions(+), 54 deletions(-)

diff --git a/doc/texinfo/programs.texi b/doc/texinfo/programs.texi
index c7d10e5..ee90ef0 100644
--- a/doc/texinfo/programs.texi
+++ b/doc/texinfo/programs.texi
@@ -3236,11 +3236,18 @@ prints the message, immediately following last deleted 
one.
 @table @samp
 @item save address@hidden @var{file}]
 @itemx s address@hidden @var{file}]
-Takes a message list and a file name and appends each message in turn to
-the end of the file.  The name of file and number of characters appended
-to it is echoed on the terminal.  Each saved message is marked for
-deletion as if with @code{delete} command, unless the variable
address@hidden is set.
+Takes a message list and a file name or mailbox URL and appends each
+message in turn to the end of that file or mailbox.  Mailbox URLs
+begin with mailbox type specifier, such as @samp{mbox://},
address@hidden://}, etc.  The name of file or mailbox and number of
+lines and characters appended to it is echoed on the terminal.  When
+writing to file, the numbers represent exact number of lines and
+characters appended to the file.  When @var{file} specifies a mailbox,
+these numbers may differ by the amount of lines/characters needed to
+represent message envelope for that specific mailbox type.
+
+Each saved message is marked for deletion as if with @code{delete}
+command, unless the variable @code{keepsave} is set.
 @item Save address@hidden
 @itemx S address@hidden
 Like @code{save}, but the file to append messages to is named after the
diff --git a/mail/copy.c b/mail/copy.c
index ccbef62..5d35af6 100644
--- a/mail/copy.c
+++ b/mail/copy.c
@@ -16,6 +16,7 @@
    along with GNU Mailutils.  If not, see <http://www.gnu.org/licenses/>. */
 
 #include "mail.h"
+#include <mailutils/locker.h>
 
 /*
  * c[opy] [file]
@@ -23,59 +24,33 @@
  * C[opy] [msglist]
  */
 
-/*
- * mail_copy0() is shared between mail_copy() and mail_save().
- * argc, argv -- argument count & vector
- * mark -- whether we should mark the message as saved.
- */
-int
-mail_copy0 (int argc, char **argv, int mark)
+struct append_stat
 {
-  mu_message_t msg;
-  mu_mailbox_t mbx;
-  char *filename = NULL;
-  msgset_t *msglist = NULL, *mp;
-  int sender = 0;
-  size_t total_size = 0, total_lines = 0, size;
-  int status;
-
-  if (mu_isupper (argv[0][0]))
-    sender = 1;
-  else if (argc >= 2)
-    filename = mail_expand_name (argv[--argc]);
-  else
-    filename = mu_strdup ("mbox");
-
-  if (msgset_parse (argc, argv, MSG_NODELETED|MSG_SILENT, &msglist))
-    {
-      if (filename)
-       free (filename);
-      return 1;
-    }
-
-  if (sender)
-    filename = util_outfolder_name (util_get_sender (msglist->msg_part[0], 1));
-
-  if (!filename)
-    {
-      msgset_free (msglist);
-      return 1;
-    }
+  size_t size;
+  size_t lines;
+};
 
+static int
+append_to_mailbox (char const *filename, msgset_t *msglist, int mark,
+                  struct append_stat *totals)
+{
+  int status;
+  mu_mailbox_t mbx;
+  msgset_t *mp;
+  size_t size;
+  mu_message_t msg;
+  
   if ((status = mu_mailbox_create_default (&mbx, filename)) != 0)
     {
       mu_error (_("Cannot create mailbox %s: %s"), filename, 
                    mu_strerror (status));
-      free (filename);
-      msgset_free (msglist);
       return 1;
     }
   if ((status = mu_mailbox_open (mbx, MU_STREAM_WRITE | MU_STREAM_CREAT)) != 0)
     {
       mu_error (_("Cannot open mailbox %s: %s"), filename, 
                    mu_strerror (status));
-      free (filename);
-      msgset_free (msglist);
+      mu_mailbox_destroy (&mbx);
       return 1;
     }
 
@@ -93,9 +68,9 @@ mail_copy0 (int argc, char **argv, int mark)
        }
       
       mu_message_size (msg, &size);
-      total_size += size;
+      totals->size += size;
       mu_message_lines (msg, &size);
-      total_lines += size;
+      totals->lines += size;
 
       if (mark)
        {
@@ -104,13 +79,179 @@ mail_copy0 (int argc, char **argv, int mark)
          mu_attribute_set_userflag (attr, MAIL_ATTRIBUTE_SAVED);
        }
     }
+  
+  mu_mailbox_close (mbx);
+  mu_mailbox_destroy (&mbx);
+  return 0;
+}
+
+static int
+append_to_file (char const *filename, msgset_t *msglist, int mark,
+               struct append_stat *totals)
+{
+  int status;
+  msgset_t *mp;
+  mu_stream_t ostr, mstr;
+  mu_off_t size;
+  size_t lines;
+  mu_message_t msg;
+  mu_locker_t locker;
+  
+  status = mu_file_stream_create (&ostr, filename,
+                                 MU_STREAM_CREAT|MU_STREAM_APPEND);
+  if (status)
+    {
+      mu_error (_("Cannot open output file %s: %s"),
+               filename, mu_strerror (status));
+      return 1;
+    }
+  
+  status = mu_locker_create (&locker, filename,
+                            MU_LOCKER_KERNEL|MU_LOCKER_RETRY);
+  if (status)
+    {
+      mu_error (_("Cannot create locker %s: %s"),
+               filename, mu_strerror (status));
+      mu_stream_unref (ostr);
+      return 1;
+    }
+  mu_locker_lock_mode (locker, mu_lck_exc);
+
+  status = mu_locker_lock (locker);
+  if (status)
+    {
+      mu_error (_("Cannot lock %s: %s"),
+               filename, mu_strerror (status));
+      mu_locker_destroy (&locker);
+      mu_stream_unref (ostr);
+      return 1;
+    }
+  
+  for (mp = msglist; mp; mp = mp->next)
+    {
+      mu_envelope_t env;
+      const char *s, *d;
+      int n;
+      
+      status = util_get_message (mbox, mp->msg_part[0], &msg);
+      if (status)
+        break;
 
+      status = mu_message_get_envelope (msg, &env);
+      if (status)
+       {
+         mu_error (_("Cannot get envelope: %s"), mu_strerror (status));
+         break;
+       }
+
+      status = mu_envelope_sget_sender (env, &s);
+      if (status)
+       {
+         mu_error (_("Cannot get envelope sender: %s"), mu_strerror (status));
+         break;
+       }
+      
+      status = mu_envelope_sget_date (env, &d);
+      if (status)
+       {
+         mu_error (_("Cannot get envelope date: %s"), mu_strerror (status));
+         break;
+       }
+      
+      status = mu_stream_printf (ostr, "From %s %s\n%n", s, d, &n);
+      if (status)
+       {
+         mu_error (_("Write error: %s"), mu_strerror (status));
+         break;
+       }
+      
+      totals->lines++;
+      totals->size += n;
+      
+      status = mu_message_get_streamref (msg, &mstr);
+      if (status)
+       {
+         mu_error (_("Cannot get message: %s"), mu_strerror (status));
+         break;
+       }
+
+      status = mu_stream_copy (ostr, mstr, 0, &size);
+      if (status)
+       {
+         mu_error (_("Cannot append message: %s"), mu_strerror (status));
+         break;
+       }
+      
+      mu_stream_unref (mstr);
+
+      mu_stream_write (ostr, "\n", 1, NULL);
+      
+      totals->size += size + 1;
+      mu_message_lines (msg, &lines);
+      totals->lines += lines + 1;
+
+      if (mark)
+       {
+         mu_attribute_t attr;
+         mu_message_get_attribute (msg, &attr);
+         mu_attribute_set_userflag (attr, MAIL_ATTRIBUTE_SAVED);
+       }
+    }
+
+  mu_stream_close (ostr);
+  mu_stream_unref (ostr);
+
+  mu_locker_unlock (locker);
+  mu_locker_destroy (&locker);
+  
+  return 0;
+}
+
+/*
+ * mail_copy0() is shared between mail_copy() and mail_save().
+ * argc, argv -- argument count & vector
+ * mark -- whether we should mark the message as saved.
+ */
+int
+mail_copy0 (int argc, char **argv, int mark)
+{
+  char *filename = NULL;
+  msgset_t *msglist = NULL;
+  int sender = 0;
+  struct append_stat totals = { 0, 0 };
+  int status;
+
+  if (mu_isupper (argv[0][0]))
+    sender = 1;
+  else if (argc >= 2)
+    filename = mail_expand_name (argv[--argc]);
+  else
+    filename = mu_strdup ("mbox");
+
+  if (msgset_parse (argc, argv, MSG_NODELETED|MSG_SILENT, &msglist))
+    {
+      if (filename)
+       free (filename);
+      return 1;
+    }
+
+  if (sender)
+    filename = util_outfolder_name (util_get_sender (msglist->msg_part[0], 1));
+
+  if (!filename)
+    {
+      msgset_free (msglist);
+      return 1;
+    }
+
+  if (mu_is_proto (filename))
+    status = append_to_mailbox (filename, msglist, mark, &totals);
+  else
+    status = append_to_file (filename, msglist, mark, &totals);
+  
   if (status == 0)
     mu_printf ("\"%s\" %3lu/%-5lu\n", filename,
-            (unsigned long) total_lines, (unsigned long) total_size);
-
-  mu_mailbox_close (mbx);
-  mu_mailbox_destroy (&mbx);
+            (unsigned long) totals.lines, (unsigned long) totals.size);
 
   free (filename);
   msgset_free (msglist);
diff --git a/mail/testsuite/mail/write.exp b/mail/testsuite/mail/write.exp
index 68923cf..92447a0 100644
--- a/mail/testsuite/mail/write.exp
+++ b/mail/testsuite/mail/write.exp
@@ -66,7 +66,7 @@ mail_test "headers" \
 # Save messages to the third mailbox
 mail_command "set folder=\"$MU_FOLDER_DIR\""
 mail_test "save 1 2 +three" \
-       "\"$MU_FOLDER_DIR/three\"  28/968"
+       "\"$MU_FOLDER_DIR/three\"  32/1067"
 
 mail_test "headers" \
        ">*   1 Sergey Poznyakoff  Tue Jul 16 12:11  12/390   MBOX"\
@@ -84,7 +84,7 @@ mail_test "headers" \
 # Test uppercase commands (Save and Copy)
 mail_command "set outfolder=\"$MU_FOLDER_DIR\""
 mail_test "Save" \
-       "\"$MU_FOLDER_DIR/gray\"  12/390"
+       "\"$MU_FOLDER_DIR/gray\"  14/438"
 
 mail_test "file \"$MU_FOLDER_DIR/gray\"" \
        "Held 2 messages in $MU_FOLDER_DIR/three"


hooks/post-receive
-- 
GNU Mailutils



reply via email to

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