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-503-gaa0debf


From: Sergey Poznyakoff
Subject: [SCM] GNU Mailutils branch, master, updated. release-2.2-503-gaa0debf
Date: Wed, 07 Dec 2011 17:25:50 +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=aa0debf5d7f45684db96fe2a5be171ad870975ab

The branch, master has been updated
       via  aa0debf5d7f45684db96fe2a5be171ad870975ab (commit)
       via  b12c4638805b9528800f319283536b3e0bb2fb13 (commit)
      from  ea8772cd3bb401e2a3e2f992a1ae570d3b99abdb (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 aa0debf5d7f45684db96fe2a5be171ad870975ab
Author: Sergey Poznyakoff <address@hidden>
Date:   Wed Dec 7 13:48:44 2011 +0200

    imap client: implement STORE, DELETE, RENAME, CHECK, EXPUNGE, COPY, CLOSE 
and UNSELECT.
    
    * include/mailutils/imap.h (imap_command): New struct.
    (mu_imap_gencom): New function.
    (mu_imap_store,mu_imap_delete)
    (mu_imap_rename,mu_imap_mailbox_close,mu_imap_close)
    (mu_imap_check): New functions.
    (_mu_close_handler): New function.
    * include/mailutils/sys/imap.h (mu_imap_client_state): Add new states.
    * libproto/imap/gencom.c: New file.
    * libproto/imap/close.c: New file.
    * libproto/imap/delete.c: New file.
    * libproto/imap/rename.c: New file.
    * libproto/imap/store.c: New file.
    * libproto/imap/unselect.c: New file.
    * libproto/imap/check.c: New file.
    * libproto/imap/expunge.c: New file.
    * libproto/imap/copy.c: New file.
    * libproto/imap/Makefile.am (libmu_imap_la_SOURCES): Add new files.
    
    * mu/imap.c: Implement new commands.
    * mu/shell.c (execute_line): Treat backslash as escape only before
    another backslash or double-quote.

commit b12c4638805b9528800f319283536b3e0bb2fb13
Author: Sergey Poznyakoff <address@hidden>
Date:   Wed Dec 7 13:42:28 2011 +0200

    imap4d: CLOSE should not send EXPUNGE responses. Fix error checking in 
STORE.
    
    * imap4d/imap4d.h (silent_expunge): New global.
    * imap4d/sync.c (silent_expunge): New variable.
    (action): Suppress EXPUNGE responses if silent_expunge is set.
    * imap4d/close.c (imap4d_close0): Set silent_expunge before calling
    mu_mailbox_flush.
    
    * imap4d/tests/close-expunge.at: New test.
    * imap4d/tests/testsuite.at: Include close-expunge.at.
    * imap4d/tests/Makefile.am (TESTSUITE_AT): Add close-expunge.at.
    
    * imap4d/fetch.c (fetch_thunk): Emit BAD response if failed to parse
    message set.
    * imap4d/store.c (store_thunk): Emit BAD response if failed to parse
    flags.

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

Summary of changes:
 imap4d/close.c                                 |   10 ++-
 imap4d/fetch.c                                 |    5 +-
 imap4d/imap4d.h                                |    3 +-
 imap4d/store.c                                 |   14 ++--
 imap4d/sync.c                                  |   15 ++-
 imap4d/tests/Makefile.am                       |    1 +
 imap4d/tests/{expunge.at => close-expunge.at}  |   21 +++--
 imap4d/tests/testsuite.at                      |    1 +
 include/mailutils/imap.h                       |   33 +++++++-
 include/mailutils/sys/imap.h                   |   10 ++
 libmailutils/tests/.gitignore                  |    1 +
 libproto/imap/Makefile.am                      |   11 ++-
 libmu_dbm/delete.c => libproto/imap/check.c    |   25 +++--
 {libmu_dbm => libproto/imap}/close.c           |   32 +++++--
 libmu_dbm/delete.c => libproto/imap/copy.c     |   28 ++++--
 libmu_dbm/create.c => libproto/imap/delete.c   |   39 +++++----
 libmu_dbm/delete.c => libproto/imap/expunge.c  |   25 +++--
 libproto/imap/fetch.c                          |   57 +++---------
 libproto/imap/{noop.c => gencom.c}             |   52 +++++++++---
 libproto/imap/logout.c                         |    2 +-
 libproto/imap/noop.c                           |   56 +++----------
 libmu_dbm/delete.c => libproto/imap/rename.c   |   29 +++++--
 libmu_dbm/create.c => libproto/imap/store.c    |   40 +++++----
 libmu_dbm/delete.c => libproto/imap/unselect.c |   25 +++--
 mu/imap.c                                      |  109 +++++++++++++++++++++---
 mu/mu.h                                        |    4 +-
 mu/shell.c                                     |    3 +-
 27 files changed, 411 insertions(+), 240 deletions(-)
 copy imap4d/tests/{expunge.at => close-expunge.at} (73%)
 copy libmu_dbm/delete.c => libproto/imap/check.c (72%)
 copy {libmu_dbm => libproto/imap}/close.c (64%)
 copy libmu_dbm/delete.c => libproto/imap/copy.c (64%)
 copy libmu_dbm/create.c => libproto/imap/delete.c (66%)
 copy libmu_dbm/delete.c => libproto/imap/expunge.c (71%)
 copy libproto/imap/{noop.c => gencom.c} (61%)
 copy libmu_dbm/delete.c => libproto/imap/rename.c (64%)
 copy libmu_dbm/create.c => libproto/imap/store.c (63%)
 copy libmu_dbm/delete.c => libproto/imap/unselect.c (70%)

diff --git a/imap4d/close.c b/imap4d/close.c
index 352de98..a1535dd 100644
--- a/imap4d/close.c
+++ b/imap4d/close.c
@@ -30,9 +30,11 @@ imap4d_close0 (struct imap4d_command *command, 
imap4d_tokbuf_t tok,
   mu_mailbox_get_flags (mbox, &flags);
   if (flags & MU_STREAM_WRITE)
     {
+      silent_expunge = expunge;
       imap4d_enter_critical ();
       status = mu_mailbox_flush (mbox, expunge);
       imap4d_leave_critical ();
+      silent_expunge = 0;
       if (status)
        {
          mu_diag_funcall (MU_DIAG_ERROR, "mu_mailbox_flush", NULL, status);
@@ -69,9 +71,11 @@ imap4d_close0 (struct imap4d_command *command, 
imap4d_tokbuf_t tok,
                NO - close failure: no mailbox selected
                BAD - command unknown or arguments invalid
 
-   The CLOSE command permanently removes from the currently selected
-   mailbox all messages that have the \\Deleted flag set, and returns
-   to authenticated state from selected state.  */
+      The CLOSE command permanently removes all messages that have the
+      \Deleted flag set from the currently selected mailbox, and returns
+      to the authenticated state from the selected state.  No untagged
+      EXPUNGE responses are sent. */
+
 int
 imap4d_close (struct imap4d_command *command, imap4d_tokbuf_t tok)
 {
diff --git a/imap4d/fetch.c b/imap4d/fetch.c
index cd7baa6..40a963e 100644
--- a/imap4d/fetch.c
+++ b/imap4d/fetch.c
@@ -1778,13 +1778,10 @@ fetch_thunk (imap4d_parsebuf_t pb)
         FIXME: This code also causes imap4d to silently ignore erroneous
         msgset specifications (e.g. FETCH foobar (FLAGS)), which should
         be fixed.  */
-      
-      pb->err_text = "Completed";
       return RESP_OK;
 
     default:
-      pb->err_text = "Failed to parse message set";
-      return RESP_NO;
+      imap4d_parsebuf_exit (pb, "Failed to parse message set");
     }
 
   /* Compile the expression */
diff --git a/imap4d/imap4d.h b/imap4d/imap4d.h
index b2290a1..f74eba3 100644
--- a/imap4d/imap4d.h
+++ b/imap4d/imap4d.h
@@ -205,7 +205,8 @@ extern char **imap4d_argv;
 extern jmp_buf child_jmp;
 
 extern int test_mode;
-  
+extern int silent_expunge;
+
 /* Input functions */
 extern mu_stream_t iostream;
 extern int  io_untagged_response (int, const char *, ...) MU_PRINTFLIKE(2,3);
diff --git a/imap4d/store.c b/imap4d/store.c
index b4e5cbe..7e9d9ad 100644
--- a/imap4d/store.c
+++ b/imap4d/store.c
@@ -79,12 +79,10 @@ store_thunk (imap4d_parsebuf_t p)
     case EINVAL:
       /* See RFC 3501, section 6.4.8, and a comment to the equivalent code
         in fetch.c */
-      p->err_text = "Completed";
       return RESP_OK;
 
     default:
-      p->err_text = "Failed to parse message set";
-      return RESP_NO;
+      imap4d_parsebuf_exit (p, "Failed to parse message set");
     }      
 
   if (p->token[0] != '(')
@@ -94,7 +92,9 @@ store_thunk (imap4d_parsebuf_t p)
   do
     {
       int t;
-      if (!util_attribute_to_type (p->token, &t))
+      if (util_attribute_to_type (p->token, &t))
+       imap4d_parsebuf_exit (p, "Failed to parse flags");
+      else
        pclos->type |= t;
     }
   while (imap4d_parsebuf_next (p, 1) && p->token[0] != ')');
@@ -163,7 +163,7 @@ imap4d_store0 (imap4d_tokbuf_t tok, int isuid, char **ptext)
 
       *ptext = "Completed";
     }
-
+  
   free (pclos.set);
   
   return rc;
@@ -173,9 +173,9 @@ int
 imap4d_store (struct imap4d_command *command, imap4d_tokbuf_t tok)
 {
   int rc;
-  char *err_text;
+  char *err_text = NULL;
   
   rc = imap4d_store0 (tok, 0, &err_text);
-  return io_completion_response (command, rc, "%s", err_text);
+  return io_completion_response (command, rc, "%s", err_text ? err_text : "");
 }
 
diff --git a/imap4d/sync.c b/imap4d/sync.c
index 4033ec0..1a5d0c5 100644
--- a/imap4d/sync.c
+++ b/imap4d/sync.c
@@ -136,7 +136,11 @@ imap4d_sync_flags (size_t msgno)
   return 0;
 }
 
+int silent_expunge;
+/* When true, non-tagged EXPUNGE responses are suppressed. */
+
 static int mailbox_corrupt;
+/* When true, mailbox has been altered by another party. */
 
 static int
 action (mu_observer_t observer, size_t type, void *data, void *action_data)
@@ -158,11 +162,12 @@ action (mu_observer_t observer, size_t type, void *data, 
void *action_data)
         immediately decremented by 1, and this decrement is reflected in
         message sequence numbers in subsequent responses (including other
         untagged EXPUNGE responses). */
-      {
-       size_t *exp = data;
-       io_untagged_response (RESP_NONE, "%lu EXPUNGED",
-                             (unsigned long) (exp[0] - exp[1]));
-      }
+      if (!silent_expunge)
+       {
+         size_t *exp = data;
+         io_untagged_response (RESP_NONE, "%lu EXPUNGED",
+                               (unsigned long) (exp[0] - exp[1]));
+       }
     }
   return 0;
 }
diff --git a/imap4d/tests/Makefile.am b/imap4d/tests/Makefile.am
index 6d471c5..ecde2b6 100644
--- a/imap4d/tests/Makefile.am
+++ b/imap4d/tests/Makefile.am
@@ -42,6 +42,7 @@ TESTSUITE_AT = \
  anystate.at\
  append00.at\
  append01.at\
+ close-expunge.at\
  create01.at\
  create02.at\
  examine.at\
diff --git a/imap4d/tests/expunge.at b/imap4d/tests/close-expunge.at
similarity index 73%
copy from imap4d/tests/expunge.at
copy to imap4d/tests/close-expunge.at
index fe01f79..714ecc8 100644
--- a/imap4d/tests/expunge.at
+++ b/imap4d/tests/close-expunge.at
@@ -14,14 +14,19 @@
 # You should have received a copy of the GNU General Public License
 # along with GNU Mailutils.  If not, see <http://www.gnu.org/licenses/>.
 
-AT_SETUP([expunge])
+AT_SETUP([Close with expunge])
+AT_KEYWORDS([close close-expunge])
+
+# According to RFC3501, CLOSE command should not send untagged EXPUNGE
+# responses even if expunge actually took place.
 
 IMAP4D_CHECK([
 MUT_MBCOPY($abs_top_srcdir/testsuite/spool/search.mbox,temp)
 sed 's/^\(Status: .*\)/\1D/' temp > INBOX
 ],
 [1 SELECT INBOX
-2 EXPUNGE
+2 CLOSE
+3 EXAMINE INBOX
 X LOGOUT
 ],
 [* PREAUTH IMAP4rev1 Test mode
@@ -32,12 +37,14 @@ X LOGOUT
 * FLAGS (\Answered \Flagged \Deleted \Seen \Draft)
 * OK [[PERMANENTFLAGS (\Answered \Flagged \Deleted \Seen \Draft)]] Permanent 
flags
 1 OK [[READ-WRITE]] SELECT Completed
-* 1 EXPUNGED
-* 1 EXPUNGED
-* 1 EXPUNGED
+2 OK CLOSE Completed
 * 5 EXISTS
-* 5 RECENT
-2 OK EXPUNGE Completed
+* 0 RECENT
+* OK [[UIDNEXT 9]] Predicted next uid
+* OK [[UNSEEN 1]] first unseen messsage
+* FLAGS (\Answered \Flagged \Deleted \Seen \Draft)
+* OK [[PERMANENTFLAGS ()]] No permanent flags
+3 OK [[READ-ONLY]] EXAMINE Completed
 * BYE Session terminating.
 X OK LOGOUT Completed
 ])
diff --git a/imap4d/tests/testsuite.at b/imap4d/tests/testsuite.at
index 0a18641..fc8fcae 100644
--- a/imap4d/tests/testsuite.at
+++ b/imap4d/tests/testsuite.at
@@ -70,6 +70,7 @@ m4_include([select.at])
 m4_include([examine.at])
 m4_include([status.at])
 m4_include([expunge.at])
+m4_include([close-expunge.at])
 m4_include([create01.at])
 m4_include([create02.at])
 
diff --git a/include/mailutils/imap.h b/include/mailutils/imap.h
index 86e365c..7a77ac3 100644
--- a/include/mailutils/imap.h
+++ b/include/mailutils/imap.h
@@ -38,13 +38,25 @@ enum mu_imap_session_state
     MU_IMAP_SESSION_INIT,     /* Initial state (disconnected) */
     MU_IMAP_SESSION_NONAUTH,  /* Non-Authenticated State */
     MU_IMAP_SESSION_AUTH,     /* Authenticated State */
-    MU_IMAP_SESSION_SELECTED, /* Selected State */
-    MU_IMAP_SESSION_LOGOUT,   /* Logout State */
+    MU_IMAP_SESSION_SELECTED  /* Selected State */
   };
   
 int mu_imap_create (mu_imap_t *pimap);
 void mu_imap_destroy (mu_imap_t *pimap);
 
+struct imap_command
+{
+  int session_state;
+  char *capa;
+  int rx_state;
+  int uid;
+  int argc;
+  char const **argv;
+  void (*handler) (mu_imap_t);
+};
+
+int mu_imap_gencom (mu_imap_t imap, struct imap_command *cmd);
+  
 int mu_imap_connect (mu_imap_t imap);
 int mu_imap_disconnect (mu_imap_t imap);
 
@@ -58,8 +70,23 @@ int mu_imap_logout (mu_imap_t imap);
 int mu_imap_id (mu_imap_t imap, char **idenv, mu_assoc_t *passoc);
 
 int mu_imap_noop (mu_imap_t imap);
+int mu_imap_check (mu_imap_t imap);
+
+int mu_imap_fetch (mu_imap_t imap, int uid, const char *msgset,
+                  const char *items);
+int mu_imap_store (mu_imap_t imap, int uid, const char *msgset,
+                  const char *items);
+
+int mu_imap_delete (mu_imap_t imap, const char *mailbox);
+int mu_imap_rename (mu_imap_t imap, const char *mailbox,
+                   const char *new_mailbox);
+int mu_imap_copy (mu_imap_t imap, int uid, const char *msgset,
+                 const char *mailbox);
+
+int mu_imap_close (mu_imap_t imap);
+int mu_imap_unselect (mu_imap_t imap);
 
-int mu_imap_fetch (mu_imap_t imap, const char *msgset, const char *items);
+int mu_imap_expunge (mu_imap_t imap);
   
 int mu_imap_set_carrier (mu_imap_t imap, mu_stream_t carrier);
 int mu_imap_get_carrier (mu_imap_t imap, mu_stream_t *pcarrier);
diff --git a/include/mailutils/sys/imap.h b/include/mailutils/sys/imap.h
index 02deead..adb258b 100644
--- a/include/mailutils/sys/imap.h
+++ b/include/mailutils/sys/imap.h
@@ -57,6 +57,14 @@ enum mu_imap_client_state
     MU_IMAP_CLIENT_STATUS_RX,
     MU_IMAP_CLIENT_NOOP_RX,
     MU_IMAP_CLIENT_FETCH_RX,
+    MU_IMAP_CLIENT_STORE_RX,
+    MU_IMAP_CLIENT_DELETE_RX,
+    MU_IMAP_CLIENT_RENAME_RX,
+    MU_IMAP_CLIENT_CLOSE_RX,
+    MU_IMAP_CLIENT_UNSELECT_RX,
+    MU_IMAP_CLIENT_CHECK_RX,
+    MU_IMAP_CLIENT_COPY_RX,
+    MU_IMAP_CLIENT_EXPUNGE_RX,
     MU_IMAP_CLIENT_CLOSING
   };
 
@@ -194,6 +202,8 @@ int _mu_imap_collect_flags (struct imap_list_element *arg, 
int *res);
 struct imap_list_element *_mu_imap_list_at (mu_list_t list, int idx);
   
 int _mu_imap_parse_fetch_response (mu_list_t resp, mu_list_t *result_list);
+
+void _mu_close_handler (mu_imap_t imap);
   
 # ifdef __cplusplus
 }
diff --git a/libmailutils/tests/.gitignore b/libmailutils/tests/.gitignore
index ca22f53..aa5a1f3 100644
--- a/libmailutils/tests/.gitignore
+++ b/libmailutils/tests/.gitignore
@@ -16,6 +16,7 @@ imapio
 listop
 mailcap
 prop
+scantime
 strftime
 url-comp
 url-parse
diff --git a/libproto/imap/Makefile.am b/libproto/imap/Makefile.am
index fbd14bd..224dc26 100644
--- a/libproto/imap/Makefile.am
+++ b/libproto/imap/Makefile.am
@@ -29,25 +29,34 @@ libmu_imap_la_LIBADD = ${MU_LIB_AUTH} ${MU_LIB_MAILUTILS} 
@INTLLIBS@
 libmu_imap_la_SOURCES = \
  fake-folder.c\
  fetch.c\
+ gencom.c\
  callback.c\
  capability.c\
  capatst.c\
  carrier.c\
+ check.c\
+ close.c\
  connect.c\
+ copy.c\
  create.c\
+ delete.c\
  destroy.c\
  disconnect.c\
  err.c\
+ expunge.c\
  id.c\
  login.c\
  logout.c\
  noop.c\
+ rename.c\
  resplist.c\
  response.c\
  resproc.c\
  select.c\
  state.c\
  status.c\
+ store.c\
  tag.c\
- trace.c
+ trace.c\
+ unselect.c
 
diff --git a/libmu_dbm/delete.c b/libproto/imap/check.c
similarity index 72%
copy from libmu_dbm/delete.c
copy to libproto/imap/check.c
index f36f875..0346906 100644
--- a/libmu_dbm/delete.c
+++ b/libproto/imap/check.c
@@ -19,17 +19,22 @@
 # include <config.h>
 #endif
 
-#include <mailutils/types.h>
-#include <mailutils/dbm.h>
-#include <mailutils/errno.h>
-#include "mudbm.h"
+#include <mailutils/imap.h>
+#include <mailutils/sys/imap.h>
 
 int
-mu_dbm_delete (mu_dbm_file_t db, struct mu_dbm_datum const *key)
+mu_imap_check (mu_imap_t imap)
 {
-  DBMSYSCK (db, _dbm_delete);
-  if (!db->db_descr)
-    return EINVAL;
-  return db->db_sys->_dbm_delete (db, key);
+  static char const *command = "CHECK";
+  static struct imap_command com = {
+    MU_IMAP_SESSION_SELECTED,
+    NULL,
+    MU_IMAP_CLIENT_CHECK_RX,
+    0,
+    1,
+    &command,
+    NULL
+  };
+  return mu_imap_gencom (imap, &com);
 }
-
+      
diff --git a/libmu_dbm/close.c b/libproto/imap/close.c
similarity index 64%
copy from libmu_dbm/close.c
copy to libproto/imap/close.c
index a84574a..a92d598 100644
--- a/libmu_dbm/close.c
+++ b/libproto/imap/close.c
@@ -19,17 +19,29 @@
 # include <config.h>
 #endif
 
-#include <mailutils/types.h>
-#include <mailutils/dbm.h>
-#include <mailutils/errno.h>
-#include "mudbm.h"
+#include <mailutils/imap.h>
+#include <mailutils/sys/imap.h>
 
-int
-mu_dbm_close (mu_dbm_file_t db)
+void
+_mu_close_handler (mu_imap_t imap)
 {
-  DBMSYSCK (db, _dbm_close);
-  if (!db->db_descr)
-    return 0;
-  return db->db_sys->_dbm_close (db);
+  if (imap->resp_code == MU_IMAP_OK)
+    imap->session_state = MU_IMAP_SESSION_AUTH;
 }
 
+int
+mu_imap_close (mu_imap_t imap)
+{
+  static char const *command = "CLOSE";
+  static struct imap_command com = {
+    MU_IMAP_SESSION_SELECTED,
+    NULL,
+    MU_IMAP_CLIENT_CLOSE_RX,
+    0,
+    1,
+    &command,
+    _mu_close_handler
+  };
+  return mu_imap_gencom (imap, &com);
+}
+      
diff --git a/libmu_dbm/delete.c b/libproto/imap/copy.c
similarity index 64%
copy from libmu_dbm/delete.c
copy to libproto/imap/copy.c
index f36f875..5a11a1c 100644
--- a/libmu_dbm/delete.c
+++ b/libproto/imap/copy.c
@@ -19,17 +19,27 @@
 # include <config.h>
 #endif
 
-#include <mailutils/types.h>
-#include <mailutils/dbm.h>
 #include <mailutils/errno.h>
-#include "mudbm.h"
+#include <mailutils/imap.h>
+#include <mailutils/sys/imap.h>
 
 int
-mu_dbm_delete (mu_dbm_file_t db, struct mu_dbm_datum const *key)
+mu_imap_copy (mu_imap_t imap, int uid, const char *msgset, const char *mailbox)
 {
-  DBMSYSCK (db, _dbm_delete);
-  if (!db->db_descr)
-    return EINVAL;
-  return db->db_sys->_dbm_delete (db, key);
-}
+  char const *argv[3];
+  static struct imap_command com;
+
+  argv[0] = "COPY";
+  argv[1] = msgset;
+  argv[2] = mailbox;
 
+  com.session_state = MU_IMAP_SESSION_SELECTED;
+  com.capa = NULL;
+  com.rx_state = MU_IMAP_CLIENT_COPY_RX;
+  com.uid = 0;
+  com.argc = 3;
+  com.argv = argv;
+  com.handler = NULL;
+
+  return mu_imap_gencom (imap, &com);
+}
diff --git a/libmu_dbm/create.c b/libproto/imap/delete.c
similarity index 66%
copy from libmu_dbm/create.c
copy to libproto/imap/delete.c
index 44c161d..e29f028 100644
--- a/libmu_dbm/create.c
+++ b/libproto/imap/delete.c
@@ -18,27 +18,30 @@
 #ifdef HAVE_CONFIG_H
 # include <config.h>
 #endif
-#include <unistd.h>
+
 #include <stdlib.h>
-#include <mailutils/types.h>
-#include <mailutils/list.h>
-#include <mailutils/url.h>
-#include <mailutils/dbm.h>
+#include <string.h>
 #include <mailutils/errno.h>
-#include <mailutils/util.h>
-#include "mudbm.h"
+#include <mailutils/imap.h>
+#include <mailutils/sys/imap.h>
 
 int
-mu_dbm_create (char *name, mu_dbm_file_t *db, int defsafety)
+mu_imap_delete (mu_imap_t imap, const char *mailbox)
 {
-  int rc;
-  mu_url_t url;
-
-  mu_dbm_init ();
-  rc = mu_url_create_hint (&url, name, 0, mu_dbm_hint);
-  if (rc)
-    return rc;
-  rc = mu_dbm_create_from_url (url, db, defsafety);
-  mu_url_destroy (&url);
-  return rc;
+  char const *argv[2];
+  static struct imap_command com;
+
+  argv[0] = "DELETE";
+  argv[1] = mailbox;
+
+  com.session_state = MU_IMAP_SESSION_AUTH;
+  com.capa = NULL;
+  com.rx_state = MU_IMAP_CLIENT_DELETE_RX;
+  com.uid = 0;
+  com.argc = 2;
+  com.argv = argv;
+  com.handler = NULL;
+
+  return mu_imap_gencom (imap, &com);
 }
+      
diff --git a/libmu_dbm/delete.c b/libproto/imap/expunge.c
similarity index 71%
copy from libmu_dbm/delete.c
copy to libproto/imap/expunge.c
index f36f875..376ee4b 100644
--- a/libmu_dbm/delete.c
+++ b/libproto/imap/expunge.c
@@ -19,17 +19,22 @@
 # include <config.h>
 #endif
 
-#include <mailutils/types.h>
-#include <mailutils/dbm.h>
-#include <mailutils/errno.h>
-#include "mudbm.h"
+#include <mailutils/imap.h>
+#include <mailutils/sys/imap.h>
 
 int
-mu_dbm_delete (mu_dbm_file_t db, struct mu_dbm_datum const *key)
+mu_imap_expunge (mu_imap_t imap)
 {
-  DBMSYSCK (db, _dbm_delete);
-  if (!db->db_descr)
-    return EINVAL;
-  return db->db_sys->_dbm_delete (db, key);
+  static char const *command = "EXPUNGE";
+  static struct imap_command com = {
+    MU_IMAP_SESSION_SELECTED,
+    NULL,
+    MU_IMAP_CLIENT_EXPUNGE_RX,
+    0,
+    1,
+    &command,
+    NULL
+  };
+  return mu_imap_gencom (imap, &com);
 }
-
+      
diff --git a/libproto/imap/fetch.c b/libproto/imap/fetch.c
index e15fc1d..1d7c0f2 100644
--- a/libproto/imap/fetch.c
+++ b/libproto/imap/fetch.c
@@ -29,53 +29,24 @@
 #include <mailutils/sys/imap.h>
 
 int
-mu_imap_fetch (mu_imap_t imap, const char *msgset, const char *items)
+mu_imap_fetch (mu_imap_t imap, int uid, const char *msgset, const char *items)
 {
-  int status;
-  
-  if (imap == NULL)
-    return EINVAL;
-  if (!imap->io)
-    return MU_ERR_NO_TRANSPORT;
+  char const *argv[3];
+  static struct imap_command com;
 
-  if (imap->session_state != MU_IMAP_SESSION_SELECTED)
-    return MU_ERR_SEQ;
+  argv[0] = "FETCH";
+  argv[1] = msgset;
+  argv[2] = items;
   
-  switch (imap->client_state)
-    {
-    case MU_IMAP_CLIENT_READY:
-      status = _mu_imap_tag_next (imap);
-      MU_IMAP_CHECK_EAGAIN (imap, status);
-      status = mu_imapio_printf (imap->io, "%s FETCH %s %s\r\n",
-                                imap->tag_str, msgset, items);
-      MU_IMAP_CHECK_ERROR (imap, status);
-      MU_IMAP_FCLR (imap, MU_IMAP_RESP);
-      imap->client_state = MU_IMAP_CLIENT_FETCH_RX;
-
-    case MU_IMAP_CLIENT_FETCH_RX:
-      status = _mu_imap_response (imap, NULL, NULL);
-      MU_IMAP_CHECK_EAGAIN (imap, status);
-      switch (imap->resp_code)
-       {
-       case MU_IMAP_OK:
-         status = 0;
-         break;
-
-       case MU_IMAP_NO:
-         status = MU_ERR_FAILURE;
-         break;
-
-       case MU_IMAP_BAD:
-         status = MU_ERR_BADREPLY;
-         break;
-       }
-      imap->client_state = MU_IMAP_CLIENT_READY;
-      break;
-
-    default:
-      status = EINPROGRESS;
-    }
-  return status;
+  com.session_state = MU_IMAP_SESSION_SELECTED;
+  com.capa = NULL;
+  com.rx_state = MU_IMAP_CLIENT_FETCH_RX;
+  com.uid = uid;
+  com.argc = 3;
+  com.argv = argv;
+  com.handler = NULL;
+
+  return mu_imap_gencom (imap, &com);
 }
 
 static void
diff --git a/libproto/imap/noop.c b/libproto/imap/gencom.c
similarity index 61%
copy from libproto/imap/noop.c
copy to libproto/imap/gencom.c
index a4b22e7..5786a2b 100644
--- a/libproto/imap/noop.c
+++ b/libproto/imap/gencom.c
@@ -25,30 +25,59 @@
 #include <mailutils/sys/imap.h>
 
 int
-mu_imap_noop (mu_imap_t imap)
+mu_imap_gencom (mu_imap_t imap, struct imap_command *cmd)
 {
   int status;
+  int i;
   
-  if (imap == NULL)
+  if (imap == NULL || !cmd || cmd->argc < 1)
     return EINVAL;
   if (!imap->io)
     return MU_ERR_NO_TRANSPORT;
-  if (imap->session_state == MU_IMAP_SESSION_INIT)
+  if (imap->session_state < cmd->session_state)
     return MU_ERR_SEQ;
 
-  switch (imap->client_state)
+  if (cmd->capa)
+    {
+      status = mu_imap_capability_test (imap, cmd->capa, NULL);
+      switch (status)
+       {
+       case 0:
+         break;
+
+       case MU_ERR_NOENT:
+         return ENOSYS;
+
+       default:
+         return status;
+       }
+    }
+  
+  if (imap->client_state == MU_IMAP_CLIENT_READY)
     {
-    case MU_IMAP_CLIENT_READY:
       status = _mu_imap_tag_next (imap);
       MU_IMAP_CHECK_EAGAIN (imap, status);
-      status = mu_imapio_printf (imap->io, "%s NOOP\r\n", imap->tag_str);
+      status = mu_imapio_printf (imap->io, "%s", imap->tag_str);
+      if (status == 0 && cmd->uid)
+       status = mu_imapio_printf (imap->io, " UID");
+      MU_IMAP_CHECK_ERROR (imap, status);
+      for (i = 0; i < cmd->argc; i++)
+       {
+         status = mu_imapio_printf (imap->io, " %s", cmd->argv[i]);
+         MU_IMAP_CHECK_ERROR (imap, status);
+       }
+      status = mu_imapio_send (imap->io, "\r\n", 2);
       MU_IMAP_CHECK_ERROR (imap, status);
       MU_IMAP_FCLR (imap, MU_IMAP_RESP);
-      imap->client_state = MU_IMAP_CLIENT_NOOP_RX;
+      imap->client_state = cmd->rx_state;
+    }
 
-    case MU_IMAP_CLIENT_NOOP_RX:
+  if (imap->client_state == cmd->rx_state)
+    {
       status = _mu_imap_response (imap, NULL, NULL);
       MU_IMAP_CHECK_EAGAIN (imap, status);
+      if (cmd->handler)
+         cmd->handler (imap);
       switch (imap->resp_code)
        {
        case MU_IMAP_OK:
@@ -64,11 +93,10 @@ mu_imap_noop (mu_imap_t imap)
          break;
        }
       imap->client_state = MU_IMAP_CLIENT_READY;
-      break;
-
-    default:
-      status = EINPROGRESS;
     }
+  else
+    status = EINPROGRESS;
+
   return status;
 }
       
diff --git a/libproto/imap/logout.c b/libproto/imap/logout.c
index e91e1ce..9b39b39 100644
--- a/libproto/imap/logout.c
+++ b/libproto/imap/logout.c
@@ -51,7 +51,7 @@ mu_imap_logout (mu_imap_t imap)
       status = _mu_imap_response (imap, NULL, NULL);
       MU_IMAP_CHECK_EAGAIN (imap, status);
       imap->client_state = MU_IMAP_CLIENT_READY;
-      imap->session_state = MU_IMAP_SESSION_LOGOUT;
+      imap->session_state = MU_IMAP_SESSION_INIT;
       break;
 
     default:
diff --git a/libproto/imap/noop.c b/libproto/imap/noop.c
index a4b22e7..62d5035 100644
--- a/libproto/imap/noop.c
+++ b/libproto/imap/noop.c
@@ -19,56 +19,22 @@
 # include <config.h>
 #endif
 
-#include <stdlib.h>
-#include <mailutils/errno.h>
 #include <mailutils/imap.h>
 #include <mailutils/sys/imap.h>
 
 int
 mu_imap_noop (mu_imap_t imap)
 {
-  int status;
-  
-  if (imap == NULL)
-    return EINVAL;
-  if (!imap->io)
-    return MU_ERR_NO_TRANSPORT;
-  if (imap->session_state == MU_IMAP_SESSION_INIT)
-    return MU_ERR_SEQ;
-
-  switch (imap->client_state)
-    {
-    case MU_IMAP_CLIENT_READY:
-      status = _mu_imap_tag_next (imap);
-      MU_IMAP_CHECK_EAGAIN (imap, status);
-      status = mu_imapio_printf (imap->io, "%s NOOP\r\n", imap->tag_str);
-      MU_IMAP_CHECK_ERROR (imap, status);
-      MU_IMAP_FCLR (imap, MU_IMAP_RESP);
-      imap->client_state = MU_IMAP_CLIENT_NOOP_RX;
-
-    case MU_IMAP_CLIENT_NOOP_RX:
-      status = _mu_imap_response (imap, NULL, NULL);
-      MU_IMAP_CHECK_EAGAIN (imap, status);
-      switch (imap->resp_code)
-       {
-       case MU_IMAP_OK:
-         status = 0;
-         break;
-
-       case MU_IMAP_NO:
-         status = MU_ERR_FAILURE;
-         break;
-
-       case MU_IMAP_BAD:
-         status = MU_ERR_BADREPLY;
-         break;
-       }
-      imap->client_state = MU_IMAP_CLIENT_READY;
-      break;
-
-    default:
-      status = EINPROGRESS;
-    }
-  return status;
+  static char const *command = "NOOP";
+  static struct imap_command com = {
+    MU_IMAP_SESSION_INIT,
+    NULL,
+    MU_IMAP_CLIENT_NOOP_RX,
+    0,
+    1,
+    &command,
+    NULL
+  };
+  return mu_imap_gencom (imap, &com);
 }
       
diff --git a/libmu_dbm/delete.c b/libproto/imap/rename.c
similarity index 64%
copy from libmu_dbm/delete.c
copy to libproto/imap/rename.c
index f36f875..79b3778 100644
--- a/libmu_dbm/delete.c
+++ b/libproto/imap/rename.c
@@ -19,17 +19,28 @@
 # include <config.h>
 #endif
 
-#include <mailutils/types.h>
-#include <mailutils/dbm.h>
 #include <mailutils/errno.h>
-#include "mudbm.h"
+#include <mailutils/imap.h>
+#include <mailutils/sys/imap.h>
 
 int
-mu_dbm_delete (mu_dbm_file_t db, struct mu_dbm_datum const *key)
+mu_imap_rename (mu_imap_t imap, const char *mailbox, const char *new_mailbox)
 {
-  DBMSYSCK (db, _dbm_delete);
-  if (!db->db_descr)
-    return EINVAL;
-  return db->db_sys->_dbm_delete (db, key);
-}
+  char const *argv[3];
+  static struct imap_command com;
+
+  argv[0] = "RENAME";
+  argv[1] = mailbox;
+  argv[2] = new_mailbox;
 
+  com.session_state = MU_IMAP_SESSION_AUTH;
+  com.capa = NULL;
+  com.rx_state = MU_IMAP_CLIENT_DELETE_RX;
+  com.uid = 0;
+  com.argc = 3;
+  com.argv = argv;
+  com.handler = NULL;
+
+  return mu_imap_gencom (imap, &com);
+}
+      
diff --git a/libmu_dbm/create.c b/libproto/imap/store.c
similarity index 63%
copy from libmu_dbm/create.c
copy to libproto/imap/store.c
index 44c161d..be0d728 100644
--- a/libmu_dbm/create.c
+++ b/libproto/imap/store.c
@@ -18,27 +18,31 @@
 #ifdef HAVE_CONFIG_H
 # include <config.h>
 #endif
-#include <unistd.h>
+
 #include <stdlib.h>
-#include <mailutils/types.h>
-#include <mailutils/list.h>
-#include <mailutils/url.h>
-#include <mailutils/dbm.h>
+#include <string.h>
 #include <mailutils/errno.h>
-#include <mailutils/util.h>
-#include "mudbm.h"
+#include <mailutils/imap.h>
+#include <mailutils/sys/imap.h>
 
 int
-mu_dbm_create (char *name, mu_dbm_file_t *db, int defsafety)
+mu_imap_store (mu_imap_t imap, int uid, const char *msgset, const char *items)
 {
-  int rc;
-  mu_url_t url;
-
-  mu_dbm_init ();
-  rc = mu_url_create_hint (&url, name, 0, mu_dbm_hint);
-  if (rc)
-    return rc;
-  rc = mu_dbm_create_from_url (url, db, defsafety);
-  mu_url_destroy (&url);
-  return rc;
+  char const *argv[3];
+  static struct imap_command com;
+
+  argv[0] = "STORE";
+  argv[1] = msgset;
+  argv[2] = items;
+  
+  com.session_state = MU_IMAP_SESSION_SELECTED;
+  com.capa = NULL;
+  com.rx_state = MU_IMAP_CLIENT_STORE_RX;
+  com.uid = uid;
+  com.argc = 3;
+  com.argv = argv;
+  com.handler = NULL;
+
+  return mu_imap_gencom (imap, &com);
 }
+      
diff --git a/libmu_dbm/delete.c b/libproto/imap/unselect.c
similarity index 70%
copy from libmu_dbm/delete.c
copy to libproto/imap/unselect.c
index f36f875..f45c4aa 100644
--- a/libmu_dbm/delete.c
+++ b/libproto/imap/unselect.c
@@ -19,17 +19,22 @@
 # include <config.h>
 #endif
 
-#include <mailutils/types.h>
-#include <mailutils/dbm.h>
-#include <mailutils/errno.h>
-#include "mudbm.h"
+#include <mailutils/imap.h>
+#include <mailutils/sys/imap.h>
 
 int
-mu_dbm_delete (mu_dbm_file_t db, struct mu_dbm_datum const *key)
+mu_imap_unselect (mu_imap_t imap)
 {
-  DBMSYSCK (db, _dbm_delete);
-  if (!db->db_descr)
-    return EINVAL;
-  return db->db_sys->_dbm_delete (db, key);
+  static char const *command = "UNSELECT";
+  static struct imap_command com = {
+    MU_IMAP_SESSION_SELECTED,
+    NULL,
+    MU_IMAP_CLIENT_UNSELECT_RX,
+    0,
+    1,
+    &command,
+    _mu_close_handler
+  };
+  return mu_imap_gencom (imap, &com);
 }
-
+      
diff --git a/mu/imap.c b/mu/imap.c
index 8132b27..5468058 100644
--- a/mu/imap.c
+++ b/mu/imap.c
@@ -69,11 +69,7 @@ current_imap_state ()
   if (imap == NULL)
     state = MU_IMAP_SESSION_INIT;
   else
-    {
-      mu_imap_state (imap, &state);
-      if (state == MU_IMAP_SESSION_LOGOUT)
-       state = MU_IMAP_SESSION_INIT;
-    }
+    mu_imap_state (imap, &state);
   return state;
 }
 
@@ -731,6 +727,15 @@ com_noop (int argc MU_ARG_UNUSED, char **argv 
MU_ARG_UNUSED)
 }
 
 static int
+com_check (int argc MU_ARG_UNUSED, char **argv MU_ARG_UNUSED)
+{
+  int status = mu_imap_check (imap);
+  if (status)
+    report_failure ("check", status);
+  return 0;
+}
+
+static int
 com_fetch (int argc, char **argv)
 {
   int status;
@@ -739,7 +744,7 @@ com_fetch (int argc, char **argv)
   mu_imap_register_callback_function (imap, MU_IMAP_CB_FETCH,
                                      imap_fetch_callback,
                                      out);
-  status = mu_imap_fetch (imap, argv[1], argv[2]);
+  status = mu_imap_fetch (imap, 0, argv[1], argv[2]);
   mu_stream_destroy (&out);
   mu_imap_register_callback_function (imap, MU_IMAP_CB_FETCH,
                                      imap_fetch_callback,
@@ -749,22 +754,76 @@ com_fetch (int argc, char **argv)
   return 0;  
 }
 
+static int
+com_store (int argc, char **argv)
+{
+  int status = mu_imap_store (imap, 0, argv[1], argv[2]);
+  if (status)
+    report_failure ("store", status);
+  return 0;
+}
+
+static int
+com_close (int argc MU_ARG_UNUSED, char **argv MU_ARG_UNUSED)
+{
+  int status = mu_imap_close (imap);
+  if (status)
+    report_failure ("close", status);
+  return 0;
+}
+
+static int
+com_unselect (int argc MU_ARG_UNUSED, char **argv MU_ARG_UNUSED)
+{
+  int status = mu_imap_noop (imap);
+  if (status)
+    report_failure ("unselect", status);
+  return 0;
+}
+
+static int
+com_delete (int argc, char **argv)
+{
+  int status = mu_imap_delete (imap, argv[1]);
+  if (status)
+    report_failure ("delete", status);
+  return 0;
+}
+
+static int
+com_rename (int argc, char **argv)
+{
+  int status = mu_imap_rename (imap, argv[1], argv[2]);
+  if (status)
+    report_failure ("rename", status);
+  return 0;
+}
+
+static int
+com_expunge (int argc MU_ARG_UNUSED, char **argv MU_ARG_UNUSED)
+{
+  int status = mu_imap_expunge (imap);
+  if (status)
+    report_failure ("expunge", status);
+  return 0;
+}
+
 struct mutool_command imap_comtab[] = {
-  { "capability", 1, -1, 0,
+  { "capability",   1, -1, 0,
     com_capability,
     /* TRANSLATORS: -reread is a keyword; do not translate. */
     N_("[-reread] [NAME...]"),
     N_("list server capabilities") },
-  { "verbose",    1, 4, 0,
+  { "verbose",      1, 4, 0,
     com_verbose,
     "[on|off|mask|unmask] [secure [payload]]",
     N_("control the protocol tracing") },
-  { "connect",    1, 4, 0,
+  { "connect",      1, 4, 0,
     com_connect,
-    /* TRANSLATORS: --tls is a keyword. */
+    /* TRANSLATORS: -tls is a keyword. */
     N_("[-tls] HOSTNAME [PORT]"),
     N_("open connection") },
-  { "disconnect", 1, 1, 0,
+  { "disconnect",   1, 1, 0,
     com_disconnect,
     NULL,
     N_("close connection") },
@@ -784,6 +843,10 @@ struct mutool_command imap_comtab[] = {
     com_noop,
     NULL,
     N_("no operation (keepalive)") },
+  { "check",        1, 1, 0,
+    com_check,
+    NULL,
+    N_("request a server checkpoint") },
   { "select",       1, 2, 0,
     com_select,
     N_("[MBOX]"),
@@ -800,6 +863,30 @@ struct mutool_command imap_comtab[] = {
     com_fetch,
     N_("MSGSET ITEMS"),
     N_("fetch message data") },
+  { "store",        3, 3, CMD_COALESCE_EXTRA_ARGS,
+    com_store,
+    N_("MSGSET ITEMS"),
+    N_("alter mailbox data") },
+  { "close",        1, 1, 0,
+    com_close,
+    NULL,
+    N_("close the mailbox (with expunge)") },
+  { "unselect",     1, 1, 0,
+    com_unselect,
+    NULL,
+    N_("close the mailbox (without expunge)") },
+  { "delete",       2, 2, 0,
+    com_delete,
+    N_("MAILBOX"),
+    N_("delete the mailbox") },
+  { "rename",       3, 3, 0,
+    com_rename,
+    N_("OLD-NAME NEW-NAME"),
+    N_("rename existing mailbox") },
+  { "expunge",      1, 1, 0,
+    com_expunge,
+    NULL,
+    N_("permanently remove messages marked for deletion") },
   { "quit",         1, 1, 0,
     com_logout,
     NULL,
diff --git a/mu/mu.h b/mu/mu.h
index 74544b5..76bdb3a 100644
--- a/mu/mu.h
+++ b/mu/mu.h
@@ -23,13 +23,13 @@ typedef int (*mutool_action_t) (int argc, char **argv);
 struct mutool_command
 {
   const char *name;    /* User printable name of the function. */
-  int argmin;           /* Min. acceptable number of arguments (> 1) */ 
+  int argmin;           /* Min. acceptable number of arguments (>= 1) */ 
   int argmax;           /* Max. allowed number of arguments (-1 means not
                           limited */
   int flags;
   mutool_action_t func;        /* Function to call to do the job. */
   const char *argdoc;   /* Documentation for the arguments */
-  const char *docstring;/* Documentation for this function.  */
+  const char *docstring;/* Documentation for this function. */
 };
 
 extern char *mutool_shell_prompt;
diff --git a/mu/shell.c b/mu/shell.c
index 0426788..891b08b 100644
--- a/mu/shell.c
+++ b/mu/shell.c
@@ -521,8 +521,9 @@ execute_line (char *line)
   int status = 0;
   
   ws.ws_comment = "#";
+  ws.ws_escape = "\\\"";
   rc = mu_wordsplit (line, &ws,
-                    MU_WRDSF_DEFFLAGS|MU_WRDSF_COMMENT|
+                    MU_WRDSF_DEFFLAGS|MU_WRDSF_COMMENT|MU_WRDSF_ESCAPE|
                     MU_WRDSF_INCREMENTAL|MU_WRDSF_APPEND);
   if (rc == MU_WRDSE_NOINPUT)
     {


hooks/post-receive
-- 
GNU Mailutils



reply via email to

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