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-591-ge6ae285


From: Sergey Poznyakoff
Subject: [SCM] GNU Mailutils branch, master, updated. release-2.2-591-ge6ae285
Date: Sun, 29 Apr 2012 19:56:49 +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=e6ae2852edb142fcf84dc489715f8984843dfe0c

The branch, master has been updated
       via  e6ae2852edb142fcf84dc489715f8984843dfe0c (commit)
      from  1cf13b32d876b2f7ef0faf8f074142c376aeba1d (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 e6ae2852edb142fcf84dc489715f8984843dfe0c
Author: Sergey Poznyakoff <address@hidden>
Date:   Sun Apr 29 22:06:49 2012 +0300

    Implement a copy method in mailbox.
    
    This method copies given messages (ificated by their sequence or UID
    numbers) to the given mailbox. So far this is implemented only in
    IMAP[S] folders.
    
    The mh/inc utility uses this method to optionally move incorporated
    messages to other folder (mailbox) instead of simply deleting them.
    
    * include/mailutils/imap.h (mu_imap_response)
    (mu_imap_response_code): New protos.
    (MU_IMAP_CB_TAGGED_OK,MU_IMAP_CB_TAGGED_NO)
    (MU_IMAP_CB_TAGGED_BAD): New callback codes.
    * include/mailutils/mailbox.h (MU_MAILBOX_COPY_UID)
    (MU_MAILBOX_COPY_CREAT): New constants.
    (mu_mailbox_msgset_copy)
    (mu_mailbox_message_copy): New protos.
    * include/mailutils/sys/imap.h (resp_code): Rename to
    response to avoid confusion. All uses updated.
    (response_code): New member.
    (_mu_imap_process_tagged_response): New proto.
    * include/mailutils/sys/mailbox.h (_mu_mailbox) <_copy>: New member.
    * libmailutils/mailbox/Makefile.am (libmailbox_la_SOURCES): Add copy.c
    * libmailutils/mailbox/copy.c: New file.
    * libproto/imap/err.c (mu_imap_response): New function.
    (mu_imap_response_code): New function.
    * libproto/imap/mbox.c (_imap_copy_to_mailbox)
    (_mu_imap_mailbox_init): Implement _copy method.
    * libproto/imap/resplist.c (IS_LBRACE,IS_RBRACE): Fix macros.
    * libproto/imap/response.c (_mu_imap_response): Call
    _mu_imap_process_tagged_response to process tagged responses.
    * libproto/imap/resproc.c (parse_response_code): Bugfix: expected
    ']' was set off by one.
    (resptab)<code>: New member.
    (_mu_imap_process_tagged_response): New function.
    
    * mh/inc.c (options, mh_option, opt_handler): New option --moveto.
    (move_to_mailbox): New variable.
    (main): If move_to_mailbox is set, move messages to that mailbox
    instead of deleting them.
    * mh/mh_getopt.h (mh_arg)<ARG_MOVETO>: New constant.
    
    * NEWS: Update.
    
    * include/mailutils/folder.h: Add a comment.
    * libmailutils/mailbox/folder.c: Minor formatting change.

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

Summary of changes:
 NEWS                                               |   19 +++++-
 include/mailutils/folder.h                         |    3 +-
 include/mailutils/imap.h                           |   23 ++++--
 include/mailutils/mailbox.h                        |   10 +++-
 include/mailutils/sys/imap.h                       |    7 ++-
 include/mailutils/sys/mailbox.h                    |    1 +
 libmailutils/mailbox/Makefile.am                   |    1 +
 .../imap/appstr.c => libmailutils/mailbox/copy.c   |   50 +++++++++-----
 libmailutils/mailbox/folder.c                      |   13 ++--
 libproto/imap/appstrsiz.c                          |    2 +-
 libproto/imap/capability.c                         |    2 +-
 libproto/imap/close.c                              |    2 +-
 libproto/imap/err.c                                |   18 +++++
 libproto/imap/gencom.c                             |    2 +-
 libproto/imap/id.c                                 |    2 +-
 libproto/imap/login.c                              |    2 +-
 libproto/imap/mbox.c                               |   36 +++++++++
 libproto/imap/resplist.c                           |    4 +-
 libproto/imap/response.c                           |   37 +++-------
 libproto/imap/resproc.c                            |   75 +++++++++++++++++++-
 libproto/imap/select.c                             |    2 +-
 libproto/imap/starttls.c                           |    2 +-
 libproto/imap/status.c                             |    2 +-
 libproto/imap/storeflg.c                           |    2 +-
 mh/inc.c                                           |   38 ++++++++++-
 mh/mh_getopt.h                                     |    3 +-
 26 files changed, 278 insertions(+), 80 deletions(-)
 copy libproto/imap/appstr.c => libmailutils/mailbox/copy.c (51%)

diff --git a/NEWS b/NEWS
index 90f0446..02291b4 100644
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,4 @@
-GNU mailutils NEWS -- history of user-visible changes. 2012-02-26
+GNU mailutils NEWS -- history of user-visible changes. 2012-04-29
 Copyright (C) 2002-2012 Free Software Foundation, Inc.
 See the end of file for copying conditions.
 
@@ -116,6 +116,16 @@ See <http://mailutils.org/wiki/Timestamp_(Sieve_test)>.
 
 ** MH: improved compatibility with other implementations
 
+** MH inc: new option --moveto
+
+This option instructs the utility to move incorporated messages into
+another folder instead of deleting them. It is implemented only for
+input folders of type IMAP or IMAPS. A sample usage is:
+
+ inc -truncate -moveto Read -file imaps://imap.gmail.com
+
+Note the `-truncate' option. 
+
 ** mailutils-config is deprecated.
 
 Use `mu cflags' and `mu ldflags' instead.  The mailutils-config is
@@ -202,6 +212,13 @@ transaction.
 
 ** Support for Maildir and MH formats considerably improved.
 
+** The mailbox object contains a `copy' method.
+
+This method copies the requested set of messages into another
+mailbox. It is accessed using the `mu_mailbox_msgset_copy' or
+`mu_mailbox_message_copy' functions.  So far it is implememented
+only for IMAP and IMAPS mailboxes.
+
 ** MIME support improved.
 
 ** Debugging support considerably improved.
diff --git a/include/mailutils/folder.h b/include/mailutils/folder.h
index bbaafed..9036249 100644
--- a/include/mailutils/folder.h
+++ b/include/mailutils/folder.h
@@ -61,7 +61,8 @@ extern int  mu_folder_enumerate      (mu_folder_t, const char 
*,
 extern int  mu_folder_lsub           (mu_folder_t, const char *, const char *,
                                      mu_list_t *);
 
-/* Stream settings.  */
+/* Stream settings. Don't use these functions.
+   FIXME: To be removed. */
 extern int  mu_folder_get_stream     (mu_folder_t, mu_stream_t *)
                                        __attribute__ ((deprecated));
 extern int  mu_folder_get_streamref  (mu_folder_t, mu_stream_t *);
diff --git a/include/mailutils/imap.h b/include/mailutils/imap.h
index af47c05..300e590 100644
--- a/include/mailutils/imap.h
+++ b/include/mailutils/imap.h
@@ -133,6 +133,9 @@ int mu_imap_get_carrier (mu_imap_t imap, mu_stream_t 
*pcarrier);
 int mu_imap_trace (mu_imap_t imap, int op);
 int mu_imap_trace_mask (mu_imap_t imap, int op, int lev);
 
+enum mu_imap_response mu_imap_response (mu_imap_t imap);
+int mu_imap_response_code (mu_imap_t imap);
+  
 int mu_imap_strerror (mu_imap_t imap, const char **pstr);
 
 int mu_imap_session_state (mu_imap_t imap);
@@ -178,21 +181,27 @@ extern struct mu_kwd _mu_imap_status_name_table[];
 #define MU_IMAP_CB_UIDNEXT          4 
 #define MU_IMAP_CB_UIDVALIDITY      5
 
-  /* The following callbacks correspond to server responses and take two
-     arguments: a response code (see MU_IMAP_RESPONSE, below) in SDAT, and
-     human-readable text string as returned by the server in PDAT.  The
-     latter can be NULL. */
+  /* The following callbacks correspond to unsolicited server responses and
+     take two arguments: a response code (see MU_IMAP_RESPONSE, below) in
+     SDAT, and human-readable text string as returned by the server in PDAT.
+     The latter can be NULL. */
 #define MU_IMAP_CB_OK               6
 #define MU_IMAP_CB_NO               7
 #define MU_IMAP_CB_BAD              8
 #define MU_IMAP_CB_BYE              9
 #define MU_IMAP_CB_PREAUTH         10
 
+  /* These corresponde to the tagged server responses.  The calling convention
+     is the same as above. */
+#define MU_IMAP_CB_TAGGED_OK       11  
+#define MU_IMAP_CB_TAGGED_NO       12
+#define MU_IMAP_CB_TAGGED_BAD      13
+  
   /* FETCH callback.  Arguments: SDAT - message sequence number, PDAT - a
      list (mu_list_t) of union mu_imap_fetch_response (see below). */
-#define MU_IMAP_CB_FETCH           11
+#define MU_IMAP_CB_FETCH           14
 
-#define _MU_IMAP_CB_MAX            12
+#define _MU_IMAP_CB_MAX            15
 
 typedef void (*mu_imap_callback_t) (void *, int code, size_t sdat, void *pdat);
   
@@ -202,8 +211,6 @@ void mu_imap_register_callback_function (mu_imap_t imap, 
int code,
                                         mu_imap_callback_t callback,
                                         void *data);
 
-#define MU_IMAP_RESPONSE_TAGGED           0x10
-
 #define MU_IMAP_RESPONSE_UNKNOWN           0 
 #define MU_IMAP_RESPONSE_ALERT             1
 #define MU_IMAP_RESPONSE_BADCHARSET        2
diff --git a/include/mailutils/mailbox.h b/include/mailutils/mailbox.h
index 1468244..4a2d8c2 100644
--- a/include/mailutils/mailbox.h
+++ b/include/mailutils/mailbox.h
@@ -42,7 +42,7 @@ extern int  mu_mailbox_create_from_url (mu_mailbox_t *, 
mu_url_t);
 extern int  mu_mailbox_create_from_record (mu_mailbox_t *pmbox,
                                           mu_record_t record,
                                           const char *name);
-extern int  mu_mailbox_create_default  (mu_mailbox_t *, const char *);
+extern int mu_mailbox_create_default  (mu_mailbox_t *, const char *);
 extern int mu_mailbox_create_at (mu_mailbox_t *pmbox, mu_folder_t folder,
                                 const char *name);
 
@@ -119,6 +119,14 @@ extern int mu_mailbox_get_iterator (mu_mailbox_t mbx,
 #define MU_MAILBOX_MSGNO_TO_UID 1
 
 extern int mu_mailbox_translate (mu_mailbox_t, int, size_t, size_t *);  
+
+/* Copy message into a folder */  
+#define MU_MAILBOX_COPY_UID   0x01
+#define MU_MAILBOX_COPY_CREAT 0x02
+  
+extern int mu_mailbox_msgset_copy (mu_mailbox_t, mu_msgset_t, const char *,
+                                  int);
+extern int mu_mailbox_message_copy (mu_mailbox_t, size_t, const char *, int);
   
 #ifdef __cplusplus
 }
diff --git a/include/mailutils/sys/imap.h b/include/mailutils/sys/imap.h
index e8bc9a2..41f995b 100644
--- a/include/mailutils/sys/imap.h
+++ b/include/mailutils/sys/imap.h
@@ -85,8 +85,10 @@ struct _mu_imap
   {
     int flags;
 
-    /* Holds the recect response code */
-    enum mu_imap_response resp_code;
+    /* Holds the recent response */
+    enum mu_imap_response response;
+    /* The recent response code */
+    int response_code;
     
     /* Error string (if any) */
     char *errstr;
@@ -210,6 +212,7 @@ int _mu_imap_untagged_response_to_list (mu_imap_t imap, 
mu_list_t *plist);
 int _mu_imap_process_untagged_response (mu_imap_t imap, mu_list_t list,
                                        mu_imap_response_action_t fun,
                                        void *data);
+int _mu_imap_process_tagged_response (mu_imap_t imap, mu_list_t resp);
  
 int _mu_imap_response (mu_imap_t imap, mu_imap_response_action_t fun,
                       void *data);
diff --git a/include/mailutils/sys/mailbox.h b/include/mailutils/sys/mailbox.h
index ebae207..f1b8813 100644
--- a/include/mailutils/sys/mailbox.h
+++ b/include/mailutils/sys/mailbox.h
@@ -75,6 +75,7 @@ struct _mu_mailbox
   int  (*_get_uidls) (mu_mailbox_t, mu_list_t);
 
   int  (*_translate) (mu_mailbox_t, int cmd, size_t, size_t *);
+  int  (*_copy) (mu_mailbox_t, mu_msgset_t, const char *, int);
 };
 
 # ifdef __cplusplus
diff --git a/libmailutils/mailbox/Makefile.am b/libmailutils/mailbox/Makefile.am
index dee4aa0..f2144e6 100644
--- a/libmailutils/mailbox/Makefile.am
+++ b/libmailutils/mailbox/Makefile.am
@@ -24,6 +24,7 @@ libmailbox_la_SOURCES =  \
  attribute.c\
  body.c\
  bodystruct.c\
+ copy.c\
  envelope.c\
  folder.c\
  fsfolder.c\
diff --git a/libproto/imap/appstr.c b/libmailutils/mailbox/copy.c
similarity index 51%
copy from libproto/imap/appstr.c
copy to libmailutils/mailbox/copy.c
index ace7142..2c884c3 100644
--- a/libproto/imap/appstr.c
+++ b/libmailutils/mailbox/copy.c
@@ -1,5 +1,6 @@
 /* GNU Mailutils -- a suite of utilities for electronic mail
-   Copyright (C) 2011-2012 Free Software Foundation, Inc.
+   Copyright (C) 1999-2001, 2004-2005, 2007, 2009-2012 Free Software
+   Foundation, Inc.
 
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
@@ -18,29 +19,44 @@
 #ifdef HAVE_CONFIG_H
 # include <config.h>
 #endif
-
-#include <stdlib.h>
 #include <mailutils/types.h>
+#include <mailutils/mailbox.h>
 #include <mailutils/stream.h>
 #include <mailutils/errno.h>
-#include <mailutils/imap.h>
-#include <mailutils/sys/imap.h>
+#include <mailutils/msgset.h>
+#include <mailutils/sys/mailbox.h>
 
 int
-mu_imap_append_stream (mu_imap_t imap, const char *mailbox, int flags,
-                      struct tm *tm, struct mu_timezone *tz,
-                      mu_stream_t stream)
+mu_mailbox_msgset_copy (mu_mailbox_t mbox, mu_msgset_t msgset,
+                       const char *dest, int flags)
 {
-  mu_off_t size;
-  int rc;
+  if (!mbox)
+    return EINVAL;
+  if (!mbox->_copy)
+    return ENOSYS;
+  return mbox->_copy (mbox, msgset, dest, flags);
+}
 
-  rc = mu_stream_size (stream, &size);
+int
+mu_mailbox_message_copy (mu_mailbox_t mbox, size_t msgno,
+                        const char *dest, int flags)
+{
+  int rc;
+  mu_msgset_t msgset;
+  int mode;
+  
+  if (!mbox)
+    return EINVAL;
+  if (!mbox->_copy)
+    return ENOSYS;
+
+  mode = flags & MU_MAILBOX_COPY_UID ? MU_MSGSET_UID : MU_MSGSET_NUM;
+  rc = mu_msgset_create (&msgset, mbox, mode);
+  if (rc)
+    return rc;
+  rc = mu_msgset_add_range (msgset, 1, 1, mode);
   if (rc == 0)
-    rc = mu_imap_append_stream_size (imap, mailbox, flags, tm, tz, stream,
-                                    size);
+    rc = mbox->_copy (mbox, msgset, dest, flags);
+  mu_msgset_destroy (&msgset);
   return rc;
 }
-
-      
-      
-
diff --git a/libmailutils/mailbox/folder.c b/libmailutils/mailbox/folder.c
index b6e86f4..a3fdb54 100644
--- a/libmailutils/mailbox/folder.c
+++ b/libmailutils/mailbox/folder.c
@@ -475,12 +475,13 @@ mu_folder_delete (mu_folder_t folder, const char *name)
         mailbox and call mailbox delete (remove) method.  This is necessary
         because certain types of mailboxes share a common folder (e.g. mbox,
         maildir and mh all use filesystem folder), but have a different
-        internal structure.  Supplying mu_folder_t with a knowledge of mailbox
-        internals will harm separation of concerns.  On the other hand,
-        removing something without looking into it may well yield undesired
-        results.  For example, a MH mailbox can hold another mailboxes, i.e.
-        be a folder itself.  Removing it blindly would result in removing
-        these mailboxes as well, which is clearly not indended.
+        internal structure.  Supplying mu_folder_t with knowledge about
+        mailbox internals will harm separation of concerns.  On the other 
+        hand, removing something without looking into it may well yield 
+        undesired results.  For example, a MH mailbox can hold another
+        mailboxes, i.e. be a folder itself.  Removing it blindly would 
+        result in removing these mailboxes as well, which is clearly not 
+        indended.
 
         To solve this folder and mailbox delete methods are tightly paired,
         but without looking into each-others internal mechanisms. */
diff --git a/libproto/imap/appstrsiz.c b/libproto/imap/appstrsiz.c
index f9887f2..ee59dce 100644
--- a/libproto/imap/appstrsiz.c
+++ b/libproto/imap/appstrsiz.c
@@ -121,7 +121,7 @@ mu_imap_append_stream_size (mu_imap_t imap, const char 
*mailbox, int flags,
     case MU_IMAP_CLIENT_APPEND_RX:
       status = _mu_imap_response (imap, NULL, NULL);
       MU_IMAP_CHECK_EAGAIN (imap, status);
-      switch (imap->resp_code)
+      switch (imap->response)
        {
        case MU_IMAP_OK:
          status = 0;
diff --git a/libproto/imap/capability.c b/libproto/imap/capability.c
index c301a6d..ce1c46b 100644
--- a/libproto/imap/capability.c
+++ b/libproto/imap/capability.c
@@ -113,7 +113,7 @@ mu_imap_capability (mu_imap_t imap, int reread, 
mu_iterator_t *piter)
                                  NULL);
       imap->client_state = MU_IMAP_CLIENT_READY;
       MU_IMAP_CHECK_EAGAIN (imap, status);
-      if (imap->resp_code != MU_IMAP_OK)
+      if (imap->response != MU_IMAP_OK)
        return MU_ERR_REPLY;
       else
        {
diff --git a/libproto/imap/close.c b/libproto/imap/close.c
index a006f10..d2156b4 100644
--- a/libproto/imap/close.c
+++ b/libproto/imap/close.c
@@ -25,7 +25,7 @@
 void
 _mu_close_handler (mu_imap_t imap)
 {
-  if (imap->resp_code == MU_IMAP_OK)
+  if (imap->response == MU_IMAP_OK)
     imap->session_state = MU_IMAP_SESSION_AUTH;
 }
 
diff --git a/libproto/imap/err.c b/libproto/imap/err.c
index b0db47a..f28da51 100644
--- a/libproto/imap/err.c
+++ b/libproto/imap/err.c
@@ -71,3 +71,21 @@ mu_imap_strerror (mu_imap_t imap, const char **pstr)
   *pstr = "(no recent reply)";
   return MU_ERR_NOENT;
 }
+
+enum mu_imap_response
+mu_imap_response (mu_imap_t imap)
+{
+  if (!imap)
+    return MU_IMAP_BAD;
+  return imap->response;
+}
+
+int
+mu_imap_response_code (mu_imap_t imap)
+{
+  if (!imap)
+    return -1;
+  return imap->response_code;
+}
+
+
diff --git a/libproto/imap/gencom.c b/libproto/imap/gencom.c
index 119a53c..908f033 100644
--- a/libproto/imap/gencom.c
+++ b/libproto/imap/gencom.c
@@ -71,7 +71,7 @@ mu_imap_gencom (mu_imap_t imap, struct imap_command *cmd)
       MU_IMAP_CHECK_EAGAIN (imap, status);
       if (cmd->tagged_handler)
          cmd->tagged_handler (imap);
-      switch (imap->resp_code)
+      switch (imap->response)
        {
        case MU_IMAP_OK:
          status = 0;
diff --git a/libproto/imap/id.c b/libproto/imap/id.c
index a2769a0..4132813 100644
--- a/libproto/imap/id.c
+++ b/libproto/imap/id.c
@@ -126,7 +126,7 @@ mu_imap_id (mu_imap_t imap, char **idenv, mu_assoc_t 
*passoc)
     case MU_IMAP_CLIENT_ID_RX:
       status = _mu_imap_response (imap, parse_id_reply, passoc);
       MU_IMAP_CHECK_EAGAIN (imap, status);
-      switch (imap->resp_code)
+      switch (imap->response)
        {
        case MU_IMAP_OK:
          status = 0;
diff --git a/libproto/imap/login.c b/libproto/imap/login.c
index 9a3a7fa..60a2d4f 100644
--- a/libproto/imap/login.c
+++ b/libproto/imap/login.c
@@ -56,7 +56,7 @@ mu_imap_login (mu_imap_t imap, const char *user, const char 
*pass)
       status = _mu_imap_response (imap, NULL, NULL);
       imap->client_state = MU_IMAP_CLIENT_READY;
       MU_IMAP_CHECK_EAGAIN (imap, status);
-      switch (imap->resp_code)
+      switch (imap->response)
        {
        case MU_IMAP_OK:
          imap->session_state = MU_IMAP_SESSION_AUTH;
diff --git a/libproto/imap/mbox.c b/libproto/imap/mbox.c
index ed53c5f..a7fd302 100644
--- a/libproto/imap/mbox.c
+++ b/libproto/imap/mbox.c
@@ -1252,6 +1252,41 @@ _imap_mbx_is_updated (mu_mailbox_t mbox)
   return imbx->flags & _MU_IMAP_MBX_UPTODATE;
 }
 
+static int
+_imap_copy_to_mailbox (mu_mailbox_t mbox, mu_msgset_t msgset,
+                      const char *mailbox, int flags)
+{
+  struct _mu_imap_mailbox *imbx = mbox->data;
+  mu_folder_t folder = mbox->folder;
+  mu_imap_t imap = folder->data;
+  int rc;
+  
+  mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_TRACE1,
+           (_("copying messages to mailbox %s"), mailbox));
+  _imap_mbx_clrerr (imbx);
+
+  rc = mu_imap_copy (imap, flags & MU_MAILBOX_COPY_UID, msgset, mailbox);
+  if (rc)
+    {
+      mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_ERROR,
+               (_("mu_imap_copy: %s"), mu_strerror (rc)));
+      if (rc)
+       {
+         if (mu_imap_response_code (imap) == MU_IMAP_RESPONSE_TRYCREATE)
+           {
+             mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_TRACE1,
+                       (_("creating mailbox %s"), mailbox));
+             rc = mu_imap_mailbox_create (imap, mailbox);
+             if (rc == 0)
+               rc = mu_imap_copy (imap, flags & MU_MAILBOX_COPY_UID,
+                                  msgset, mailbox);
+           }
+       }
+      imbx->last_error = rc;
+    }
+  return rc;
+}
+
 int
 _mu_imap_mailbox_init (mu_mailbox_t mailbox)
 {
@@ -1279,6 +1314,7 @@ _mu_imap_mailbox_init (mu_mailbox_t mailbox)
   mailbox->_sync = _imap_mbx_sync;
   
   mailbox->_append_message = _imap_mbx_append_message;
+  mailbox->_copy = _imap_copy_to_mailbox;
   
   return 0;
 }
diff --git a/libproto/imap/resplist.c b/libproto/imap/resplist.c
index d2d06b2..43f64c5 100644
--- a/libproto/imap/resplist.c
+++ b/libproto/imap/resplist.c
@@ -55,8 +55,8 @@ _mu_imap_response_list_create (mu_imap_t imap, mu_list_t 
*plist)
   return 0;
 }
 
-#define IS_LBRACE(p) ((p)[0] == '(')
-#define IS_RBRACE(p) ((p)[0] == ')')
+#define IS_LBRACE(p) ((p)[0] == '(' && !(p)[1])
+#define IS_RBRACE(p) ((p)[0] == ')' && !(p)[1])
 #define IS_NIL(p) (strcmp (p, "NIL") == 0)
 
 static struct imap_list_element *
diff --git a/libproto/imap/response.c b/libproto/imap/response.c
index 00d9f8d..5b92485 100644
--- a/libproto/imap/response.c
+++ b/libproto/imap/response.c
@@ -27,13 +27,6 @@
 #include <mailutils/errno.h>
 #include <mailutils/sys/imap.h>
 
-static void
-response_to_errstr (mu_imap_t imap, size_t argc, char **argv)
-{
-  if (argc && strcmp (argv[argc-1], "]"))
-    _mu_imap_seterrstrz (imap, argv[argc-1]);
-}
-
 int
 _mu_imap_response (mu_imap_t imap, mu_imap_response_action_t fun,
                   void *data)
@@ -83,29 +76,17 @@ _mu_imap_response (mu_imap_t imap, 
mu_imap_response_action_t fun,
                  /*imap->client_state = MU_IMAP_CLIENT_ERROR;*/
                  status = MU_ERR_BADREPLY;
                }
-             else if (strcmp (wv[1], "OK") == 0)
-               {
-                 imap->resp_code = MU_IMAP_OK;
-                 response_to_errstr (imap, wc, wv);
-               }
-             else if (strcmp (wv[1], "NO") == 0)
-               {
-                 imap->resp_code = MU_IMAP_NO;
-                 response_to_errstr (imap, wc, wv);
-               }
-             else if (strcmp (wv[1], "BAD") == 0)
+             else
                {
-                 imap->resp_code = MU_IMAP_BAD;
-                 response_to_errstr (imap, wc, wv);
-                 /* This may be so important that CB_BAD callback is
-                  * overloaded to handle this case as well.
-                  */
-                 mu_imap_callback (imap, MU_IMAP_CB_BAD,
-                                   MU_IMAP_RESPONSE_TAGGED,
-                                   wc >= 1 ? wv[wc-1] : NULL);
+                 mu_list_t list;
+                 status = _mu_imap_untagged_response_to_list (imap, &list);
+                 if (status == 0)
+                   {
+                     if (_mu_imap_process_tagged_response (imap, list))
+                       status = MU_ERR_BADREPLY;
+                     mu_list_destroy (&list);
+                   }
                }
-             else
-               status = MU_ERR_BADREPLY;
              MU_IMAP_FSET (imap, MU_IMAP_RESP);
            }
          else
diff --git a/libproto/imap/resproc.c b/libproto/imap/resproc.c
index b1bc43c..7f6e184 100644
--- a/libproto/imap/resproc.c
+++ b/libproto/imap/resproc.c
@@ -72,7 +72,7 @@ parse_response_code (mu_imap_t imap, mu_list_t resp)
       if (mu_kwd_xlat_name (mu_imap_response_codes, arg->v.string, &rcode))
        return -1;
       
-      arg = _mu_imap_list_at (resp, 4);
+      arg = _mu_imap_list_at (resp, 3);
       if (!arg || !_mu_imap_list_element_is_string (arg, "]"))
        return -1;
     }
@@ -217,6 +217,7 @@ struct resptab
 {
   char *name;
   mu_imap_response_action_t action;
+  int code;
 };
 
 static struct resptab resptab[] = {
@@ -350,5 +351,75 @@ _mu_imap_process_untagged_response (mu_imap_t imap, 
mu_list_t list,
     }
   return 0;
 }
+
+static void
+default_tagged_response (mu_imap_t imap, int code, mu_list_t resp, void *data)
+{
+  struct imap_list_element *arg;
+
+  if (mu_list_tail (resp, (void*) &arg) == 0 &&
+      arg->type == imap_eltype_string)
+    _mu_imap_seterrstrz (imap, arg->v.string);
+  imap->response_code = parse_response_code (imap, resp);
+  mu_imap_callback (imap, code, imap->response_code,
+                   arg ? arg->v.string : NULL);
+}
+
+static void
+ok_tagged_response (mu_imap_t imap, mu_list_t resp, void *data)
+{
+  default_tagged_response (imap, MU_IMAP_CB_TAGGED_OK, resp, data);
+}
+
+static void
+no_tagged_response (mu_imap_t imap, mu_list_t resp, void *data)
+{
+  default_tagged_response (imap, MU_IMAP_CB_TAGGED_NO, resp, data);
+}
+
+static void
+bad_tagged_response (mu_imap_t imap, mu_list_t resp, void *data)
+{
+  default_tagged_response (imap, MU_IMAP_CB_TAGGED_BAD, resp, data);
+}
+
+static struct resptab tagged_resptab[] = {
+  { "OK", ok_tagged_response, MU_IMAP_OK },
+  { "NO", no_tagged_response, MU_IMAP_NO },
+  { "BAD", bad_tagged_response, MU_IMAP_BAD },
+  { NULL }
+};
+
+static int
+_std_tagged_response (mu_imap_t imap, size_t count, mu_list_t resp)
+{
+  struct resptab *rp;
+  struct imap_list_element *arg = _mu_imap_list_at (resp, 0);
+
+  if (!arg)
+    return 1;
+
+  if (arg->type == imap_eltype_string)
+    for (rp = tagged_resptab; rp->name; rp++)
+      {
+       if (mu_c_strcasecmp (rp->name, arg->v.string) == 0)
+         {
+           imap->response = rp->code;
+           rp->action (imap, resp, NULL);
+           return 0;
+         }
+      }
+  return 1;
+}
+
+int
+_mu_imap_process_tagged_response (mu_imap_t imap, mu_list_t resp)
+{
+  size_t count;
+  
+  if (mu_list_count (resp, &count))
+    return 1;
+
+  return _std_tagged_response (imap, count, resp);
+}
 
-                         
diff --git a/libproto/imap/select.c b/libproto/imap/select.c
index 72af1a7..6debee7 100644
--- a/libproto/imap/select.c
+++ b/libproto/imap/select.c
@@ -113,7 +113,7 @@ mu_imap_select (mu_imap_t imap, const char *mbox, int 
writable,
       memset (&imap->mbox_stat, 0, sizeof (imap->mbox_stat));
       status = _mu_imap_response (imap, _select_response_action, NULL);
       MU_IMAP_CHECK_EAGAIN (imap, status);
-      switch (imap->resp_code)
+      switch (imap->response)
        {
        case MU_IMAP_OK:
          imap->session_state = MU_IMAP_SESSION_SELECTED;
diff --git a/libproto/imap/starttls.c b/libproto/imap/starttls.c
index 08cbce9..45498de 100644
--- a/libproto/imap/starttls.c
+++ b/libproto/imap/starttls.c
@@ -60,7 +60,7 @@ mu_imap_starttls (mu_imap_t imap)
     case MU_IMAP_CLIENT_STARTTLS_RX:
       status = _mu_imap_response (imap, NULL, NULL);
       MU_IMAP_CHECK_EAGAIN (imap, status);
-      switch (imap->resp_code)
+      switch (imap->response)
        {
        case MU_IMAP_OK:
          status = mu_imapio_get_streams (imap->io, streams);
diff --git a/libproto/imap/status.c b/libproto/imap/status.c
index 32dd9f1..915225a 100644
--- a/libproto/imap/status.c
+++ b/libproto/imap/status.c
@@ -185,7 +185,7 @@ mu_imap_status (mu_imap_t imap, const char *mboxname, 
struct mu_imap_stat *ps)
 
        status = _mu_imap_response (imap, _status_response_action, &sd);
        MU_IMAP_CHECK_EAGAIN (imap, status);
-       switch (imap->resp_code)
+       switch (imap->response)
          {
          case MU_IMAP_OK:
            break;
diff --git a/libproto/imap/storeflg.c b/libproto/imap/storeflg.c
index 9eb7536..e265d15 100644
--- a/libproto/imap/storeflg.c
+++ b/libproto/imap/storeflg.c
@@ -67,7 +67,7 @@ mu_imap_store_flags (mu_imap_t imap, int uid, mu_msgset_t 
msgset,
       /* FIXME: Handle unsolicited responses */
       status = _mu_imap_response (imap, NULL, NULL);
       MU_IMAP_CHECK_EAGAIN (imap, status);
-      switch (imap->resp_code)
+      switch (imap->response)
        {
        case MU_IMAP_OK:
          status = 0;
diff --git a/mh/inc.c b/mh/inc.c
index a51511b..790d5cf 100644
--- a/mh/inc.c
+++ b/mh/inc.c
@@ -42,6 +42,8 @@ static struct argp_option options[] = {
   {"truncate", ARG_TRUNCATE, N_("BOOL"), OPTION_ARG_OPTIONAL,
    N_("truncate source mailbox after incorporating (default)")},
   {"notruncate", ARG_NOTRUNCATE, NULL, OPTION_HIDDEN, ""},
+  {"moveto",  ARG_MOVETO, N_("MAILBOX"), 0,
+   N_("move incorporated messages to MAILBOX instead of deleting them") },
   {"width",   ARG_WIDTH, N_("NUMBER"), 0,
    N_("set output width")},
   {"quiet",   ARG_QUIET, 0,        0,
@@ -58,6 +60,7 @@ struct mh_option mh_option[] = {
   { "form",      MH_OPT_ARG, "format-file" },
   { "format",    MH_OPT_ARG, "string" },
   { "truncate",  MH_OPT_BOOL },
+  { "moveto",    MH_OPT_ARG, "folder" },
   { "width",     MH_OPT_ARG, "number" },
   { "quiet" },
   { NULL }
@@ -72,6 +75,7 @@ static int changecur = -1;
 static int truncate_source = -1;
 static int quiet = 0;
 static const char *append_folder;
+static const char *move_to_mailbox;
 
 static error_t
 opt_handler (int key, char *arg, struct argp_state *state)
@@ -122,6 +126,10 @@ opt_handler (int key, char *arg, struct argp_state *state)
     case ARG_NOTRUNCATE:
       truncate_source = 0;
       break;
+
+    case ARG_MOVETO:
+      move_to_mailbox = arg;
+      break;
       
     case ARG_WIDTH:
       width = strtoul (arg, NULL, 0);
@@ -143,7 +151,8 @@ opt_handler (int key, char *arg, struct argp_state *state)
 }
 
 void
-list_message (mh_format_t *format, mu_mailbox_t mbox, size_t msgno, size_t 
width)
+list_message (mh_format_t *format, mu_mailbox_t mbox, size_t msgno,
+             size_t width)
 {
   mu_message_t msg;
   char *buf = NULL;
@@ -275,6 +284,33 @@ main (int argc, char **argv)
        }
     }
 
+  if (truncate_source && move_to_mailbox)
+    {
+      mu_msgset_t msgset;
+      
+      rc = mu_msgset_create (&msgset, input, MU_MSGSET_NUM);
+      if (rc)
+       mu_diag_funcall (MU_DIAG_ERROR, "mu_msgset_create", NULL, rc);
+      else
+       {
+         rc = mu_msgset_add_range (msgset, 1, total, MU_MSGSET_NUM);
+         if (rc)
+           mu_diag_funcall (MU_DIAG_ERROR, "mu_msgset_add_range", NULL, rc);
+         else
+           {
+             rc = mu_mailbox_msgset_copy (input, msgset, move_to_mailbox,
+                                          MU_MAILBOX_COPY_CREAT);
+             if (rc)
+               {
+                 mu_error (_("failed to move messages to %s: %s"),
+                           move_to_mailbox, mu_strerror (rc));
+                 truncate_source = 0;
+               }
+           }
+         mu_msgset_destroy (&msgset);
+       }
+    }
+  
   if (!changecur)
     {
       mu_property_t prop = mh_mailbox_get_property (output);
diff --git a/mh/mh_getopt.h b/mh/mh_getopt.h
index e552103..a0fb7c8 100644
--- a/mh/mh_getopt.h
+++ b/mh/mh_getopt.h
@@ -91,7 +91,8 @@ enum mh_arg {
   ARG_LINK,            
   ARG_LIST,            
   ARG_MIME,            
-  ARG_MOREPROC,                
+  ARG_MOREPROC,
+  ARG_MOVETO,
   ARG_MSGID,           
   ARG_NOALIAS,            
   ARG_NOAUDIT,         


hooks/post-receive
-- 
GNU Mailutils



reply via email to

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