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-526-g7e78c6a


From: Sergey Poznyakoff
Subject: [SCM] GNU Mailutils branch, master, updated. release-2.2-526-g7e78c6a
Date: Tue, 13 Dec 2011 21:02:10 +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=7e78c6af4aa397ff422db07489850d40a9360a8c

The branch, master has been updated
       via  7e78c6af4aa397ff422db07489850d40a9360a8c (commit)
      from  85c5f9a8decef2583674bc957caef1818e9628a9 (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 7e78c6af4aa397ff422db07489850d40a9360a8c
Author: Sergey Poznyakoff <address@hidden>
Date:   Tue Dec 13 22:56:32 2011 +0200

    Imap client: implement list.
    
    * libmailutils/stdstream/basestr.c (mu_strout): Bugfix: initialize
    destroy function.
    * include/mailutils/imap.h (imap_command)
    (mu_imap_gencom): Move to sys/imap.h
    (mu_imap_list,mu_imap_list_new): New protos.
    * include/mailutils/sys/imap.h (imap_command): New struct (from ../imap.h).
    <handler>: Rename to tagged_handler.
    (untagged_handler,untagged_handler_data): New members. All uses changed.
    (mu_imap_gencom): New proto.
    
    * libproto/imap/list.c: New file.
    * libproto/imap/Makefile.am: Add list.c
    * libproto/imap/gencom.c: Use supplied untagged_handler to
    analize untagged response.
    
    * mu/imap.c: Implement list command.

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

Summary of changes:
 include/mailutils/imap.h         |   18 +---
 include/mailutils/sys/imap.h     |   22 ++++-
 libmailutils/stdstream/basestr.c |    1 +
 libproto/imap/Makefile.am        |    1 +
 libproto/imap/copy.c             |    3 +-
 libproto/imap/delete.c           |    3 +-
 libproto/imap/fetch.c            |    3 +-
 libproto/imap/gencom.c           |    7 +-
 libproto/imap/list.c             |  172 ++++++++++++++++++++++++++++++++++++++
 libproto/imap/mbcreate.c         |    3 +-
 libproto/imap/rename.c           |    3 +-
 libproto/imap/store.c            |    3 +-
 mu/imap.c                        |   41 +++++++++
 13 files changed, 255 insertions(+), 25 deletions(-)
 create mode 100644 libproto/imap/list.c

diff --git a/include/mailutils/imap.h b/include/mailutils/imap.h
index b247676..bdce14c 100644
--- a/include/mailutils/imap.h
+++ b/include/mailutils/imap.h
@@ -44,19 +44,6 @@ enum mu_imap_session_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);
 
@@ -100,6 +87,11 @@ int mu_imap_append_message (mu_imap_t imap, const char 
*mailbox, int flags,
                            struct tm *tm, struct mu_timezone *tz,
                            mu_message_t msg);
   
+int mu_imap_list (mu_imap_t imap, const char *refname, const char *mboxname,
+                 mu_list_t retlist);
+int mu_imap_list_new (mu_imap_t imap, const char *refname, const char 
*mboxname,
+                     mu_list_t *plist);
+  
 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 05ec9db..9c50e84 100644
--- a/include/mailutils/sys/imap.h
+++ b/include/mailutils/sys/imap.h
@@ -66,6 +66,7 @@ enum mu_imap_client_state
     MU_IMAP_CLIENT_COPY_RX,
     MU_IMAP_CLIENT_EXPUNGE_RX,
     MU_IMAP_CLIENT_APPEND_RX,
+    MU_IMAP_CLIENT_LIST_RX,
     MU_IMAP_CLIENT_CLOSING
   };
 
@@ -135,6 +136,24 @@ int _mu_imap_trace_enable (mu_imap_t imap);
 int _mu_imap_trace_disable (mu_imap_t imap);
 int _mu_imap_xscript_level (mu_imap_t imap, int xlev);
 
+typedef void (*mu_imap_response_action_t) (mu_imap_t imap, mu_list_t resp,
+                                          void *data);
+
+struct imap_command
+{
+  int session_state;
+  char *capa;
+  int rx_state;
+  int uid;
+  int argc;
+  char const **argv;
+  void (*tagged_handler) (mu_imap_t);
+  mu_imap_response_action_t untagged_handler;
+  void *untagged_handler_data;
+};
+
+int mu_imap_gencom (mu_imap_t imap, struct imap_command *cmd);
+  
 /* If status indicates an error, return.
   */
 #define MU_IMAP_CHECK_ERROR(imap, status)                      \
@@ -182,9 +201,6 @@ int _mu_imap_tag_next (mu_imap_t imap);
 int _mu_imap_tag_clr (mu_imap_t imap);
 
 
-typedef void (*mu_imap_response_action_t) (mu_imap_t imap, mu_list_t resp,
-                                          void *data);
-
 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,
diff --git a/libmailutils/stdstream/basestr.c b/libmailutils/stdstream/basestr.c
index ec9ae29..1e6df45 100644
--- a/libmailutils/stdstream/basestr.c
+++ b/libmailutils/stdstream/basestr.c
@@ -128,6 +128,7 @@ static struct _mu_file_stream stdstream[2] = {
   { { ref_count: 1,
       buftype: mu_buffer_none,
       flags: MU_STREAM_WRITE,
+      destroy: bootstrap_destroy,
       event_cb: std_bootstrap,
       event_mask: _MU_STR_EVMASK (_MU_STR_EVENT_BOOTSTRAP)
     }, fd: MU_STDOUT_FD, filename: "<stdout>",
diff --git a/libproto/imap/Makefile.am b/libproto/imap/Makefile.am
index 41d023d..dfed78c 100644
--- a/libproto/imap/Makefile.am
+++ b/libproto/imap/Makefile.am
@@ -48,6 +48,7 @@ libmu_imap_la_SOURCES = \
  err.c\
  expunge.c\
  id.c\
+ list.c\
  login.c\
  logout.c\
  mbcreate.c\
diff --git a/libproto/imap/copy.c b/libproto/imap/copy.c
index 5a11a1c..507b701 100644
--- a/libproto/imap/copy.c
+++ b/libproto/imap/copy.c
@@ -39,7 +39,8 @@ mu_imap_copy (mu_imap_t imap, int uid, const char *msgset, 
const char *mailbox)
   com.uid = 0;
   com.argc = 3;
   com.argv = argv;
-  com.handler = NULL;
+  com.tagged_handler = NULL;
+  com.untagged_handler = NULL;
 
   return mu_imap_gencom (imap, &com);
 }
diff --git a/libproto/imap/delete.c b/libproto/imap/delete.c
index e29f028..6f986e9 100644
--- a/libproto/imap/delete.c
+++ b/libproto/imap/delete.c
@@ -40,7 +40,8 @@ mu_imap_delete (mu_imap_t imap, const char *mailbox)
   com.uid = 0;
   com.argc = 2;
   com.argv = argv;
-  com.handler = NULL;
+  com.tagged_handler = NULL;
+  com.untagged_handler = NULL;
 
   return mu_imap_gencom (imap, &com);
 }
diff --git a/libproto/imap/fetch.c b/libproto/imap/fetch.c
index 1d7c0f2..cecf794 100644
--- a/libproto/imap/fetch.c
+++ b/libproto/imap/fetch.c
@@ -44,7 +44,8 @@ mu_imap_fetch (mu_imap_t imap, int uid, const char *msgset, 
const char *items)
   com.uid = uid;
   com.argc = 3;
   com.argv = argv;
-  com.handler = NULL;
+  com.tagged_handler = NULL;
+  com.untagged_handler = NULL;
 
   return mu_imap_gencom (imap, &com);
 }
diff --git a/libproto/imap/gencom.c b/libproto/imap/gencom.c
index 5786a2b..ce4b350 100644
--- a/libproto/imap/gencom.c
+++ b/libproto/imap/gencom.c
@@ -74,10 +74,11 @@ mu_imap_gencom (mu_imap_t imap, struct imap_command *cmd)
 
   if (imap->client_state == cmd->rx_state)
     {
-      status = _mu_imap_response (imap, NULL, NULL);
+      status = _mu_imap_response (imap, cmd->untagged_handler,
+                                 cmd->untagged_handler_data);
       MU_IMAP_CHECK_EAGAIN (imap, status);
-      if (cmd->handler)
-         cmd->handler (imap);
+      if (cmd->tagged_handler)
+         cmd->tagged_handler (imap);
       switch (imap->resp_code)
        {
        case MU_IMAP_OK:
diff --git a/libproto/imap/list.c b/libproto/imap/list.c
new file mode 100644
index 0000000..9fb9696
--- /dev/null
+++ b/libproto/imap/list.c
@@ -0,0 +1,172 @@
+/* GNU Mailutils -- a suite of utilities for electronic mail
+   Copyright (C) 2011 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
+   License as published by the Free Software Foundation; either
+   version 3 of the License, or (at your option) any later version.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General
+   Public License along with this library.  If not, see
+   <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <mailutils/errno.h>
+#include <mailutils/address.h>
+#include <mailutils/cstr.h>
+#include <mailutils/cctype.h>
+#include <mailutils/list.h>
+#include <mailutils/imap.h>
+#include <mailutils/sys/imap.h>
+
+struct list_closure
+{
+  int error_code;
+  mu_list_t retlist;
+};
+
+static int
+count_level (const char *name, int delim)
+{
+  int level = 0;
+
+  while (*name)
+    if (*name++ == delim)
+      level++;
+  return level;
+}
+
+static int
+list_attr_conv (void *item, void *data)
+{
+  struct imap_list_element *elt = item;
+  struct mu_list_response *rp = data;
+  
+  if (elt->type != imap_eltype_string)
+    return 0;
+  if (mu_c_strcasecmp (elt->v.string, "\\Noinferiors"))
+    rp->type |= MU_FOLDER_ATTRIBUTE_DIRECTORY;
+  if (mu_c_strcasecmp (elt->v.string, "\\Noselect"))
+    rp->type |= MU_FOLDER_ATTRIBUTE_FILE;
+  /* FIXME: \Marked nad \Unmarked have no correspondence in flags. */
+  return 0;
+}
+  
+static void
+list_untagged_handler (mu_imap_t imap, mu_list_t resp, void *data)
+{
+  struct list_closure *clos = data;
+  struct imap_list_element *elt;
+  size_t count;
+  
+  if (clos->error_code)
+    return;
+
+  mu_list_count (resp, &count);
+  if (count == 4 &&
+      _mu_imap_list_nth_element_is_string (resp, 0, "LIST"))
+    {
+      struct mu_list_response *rp;
+
+      rp = calloc (1, sizeof (*rp));
+      if (!rp)
+       {
+         clos->error_code = ENOMEM;
+         return;
+       }
+         
+      elt = _mu_imap_list_at (resp, 1);
+      if (!(elt && elt->type == imap_eltype_list))
+       return;
+      rp->type = 0;
+      mu_list_foreach (elt->v.list, list_attr_conv, rp);
+
+      elt = _mu_imap_list_at (resp, 3);
+      if (!(elt && elt->type == imap_eltype_string))
+       return;
+      rp->name = strdup (elt->v.string);
+      if (!rp->name)
+       {
+         free (rp);
+         clos->error_code = ENOMEM;
+         return;
+       }
+
+      elt = _mu_imap_list_at (resp, 2);
+      if (!(elt && elt->type == imap_eltype_string))
+       return;
+      if (mu_c_strcasecmp (elt->v.string, "NIL") == 0)
+       {
+         rp->separator = 0;
+         rp->level = 0;
+       }
+      else
+       {
+         rp->separator = elt->v.string[0];
+         rp->level = count_level (rp->name, rp->separator);
+       }
+      if ((clos->error_code = mu_list_append (clos->retlist, rp)))
+       mu_list_response_free (rp);
+    }
+}
+  
+int
+mu_imap_list (mu_imap_t imap, const char *refname, const char *mboxname,
+             mu_list_t retlist)
+{
+  char const *argv[3];
+  static struct imap_command com;
+  struct list_closure clos;
+  int rc;
+
+  argv[0] = "LIST";
+  argv[1] = refname;
+  argv[2] = mboxname;
+
+  clos.error_code = 0;
+  clos.retlist = retlist;
+  
+  com.session_state = MU_IMAP_SESSION_AUTH;
+  com.capa = NULL;
+  com.rx_state = MU_IMAP_CLIENT_LIST_RX;
+  com.uid = 0;
+  com.argc = 3;
+  com.argv = argv;
+  com.tagged_handler = NULL;
+  com.untagged_handler = list_untagged_handler;
+  com.untagged_handler_data = &clos;
+
+  rc = mu_imap_gencom (imap, &com);
+  if (rc == 0)
+    rc = clos.error_code;
+
+  return rc;
+}
+
+int
+mu_imap_list_new (mu_imap_t imap, const char *refname, const char *mboxname,
+                 mu_list_t *plist)
+{
+  mu_list_t list;
+  int rc = mu_list_create (&list);
+  if (rc == 0)
+    {
+      mu_list_set_destroy_item (list, mu_list_response_free);
+      rc = mu_imap_list (imap, refname, mboxname, list);
+      if (rc)
+       mu_list_destroy (&list);
+      else
+       *plist = list;
+    }
+  return rc;
+}
diff --git a/libproto/imap/mbcreate.c b/libproto/imap/mbcreate.c
index 845d1ba..b7b9063 100644
--- a/libproto/imap/mbcreate.c
+++ b/libproto/imap/mbcreate.c
@@ -40,7 +40,8 @@ mu_imap_mailbox_create (mu_imap_t imap, const char *mailbox)
   com.uid = 0;
   com.argc = 2;
   com.argv = argv;
-  com.handler = NULL;
+  com.tagged_handler = NULL;
+  com.untagged_handler = NULL;
 
   return mu_imap_gencom (imap, &com);
 }
diff --git a/libproto/imap/rename.c b/libproto/imap/rename.c
index 79b3778..44d0773 100644
--- a/libproto/imap/rename.c
+++ b/libproto/imap/rename.c
@@ -39,7 +39,8 @@ mu_imap_rename (mu_imap_t imap, const char *mailbox, const 
char *new_mailbox)
   com.uid = 0;
   com.argc = 3;
   com.argv = argv;
-  com.handler = NULL;
+  com.tagged_handler = NULL;
+  com.untagged_handler = NULL;
 
   return mu_imap_gencom (imap, &com);
 }
diff --git a/libproto/imap/store.c b/libproto/imap/store.c
index be0d728..8faecac 100644
--- a/libproto/imap/store.c
+++ b/libproto/imap/store.c
@@ -41,7 +41,8 @@ mu_imap_store (mu_imap_t imap, int uid, const char *msgset, 
const char *items)
   com.uid = uid;
   com.argc = 3;
   com.argv = argv;
-  com.handler = NULL;
+  com.tagged_handler = NULL;
+  com.untagged_handler = NULL;
 
   return mu_imap_gencom (imap, &com);
 }
diff --git a/mu/imap.c b/mu/imap.c
index 26a3401..699e270 100644
--- a/mu/imap.c
+++ b/mu/imap.c
@@ -895,6 +895,43 @@ com_append (int argc, char **argv)
   return 0;
 }
 
+static int
+print_list_item (void *item, void *data)
+{
+  struct mu_list_response *resp = item;
+  mu_stream_t out = data;
+
+  mu_stream_printf (out,
+                   "%c%c %c %4d %s\n",
+                   (resp->type & MU_FOLDER_ATTRIBUTE_DIRECTORY) ? 'd' : '-',
+                   (resp->type & MU_FOLDER_ATTRIBUTE_FILE) ? 'f' : '-',
+                   resp->separator,
+                   resp->level,
+                   resp->name);
+  return 0;
+}
+
+static int
+com_list (int argc, char **argv)
+{
+  mu_list_t list;
+  int rc;
+  mu_stream_t out;
+  
+  rc = mu_imap_list_new (imap, argv[1], argv[2], &list);
+  if (rc)
+    {
+      report_failure ("list", rc);
+      return 0;
+    }
+
+  out = mutool_open_pager ();
+  mu_list_foreach (list, print_list_item, out);
+  mu_stream_unref (out);
+  return 0;
+}
+
+
 struct mutool_command imap_comtab[] = {
   { "capability",   1, -1, 0,
     com_capability,
@@ -982,6 +1019,10 @@ struct mutool_command imap_comtab[] = {
     com_append,
     N_("[-time DATETIME] [-flag FLAG] MAILBOX FILE"),
     N_("append message text from FILE to MAILBOX") },
+  { "list",         3, 3, 0,
+    com_list,
+    N_("REF MBOX"),
+    N_("List matching mailboxes") },
   { "quit",         1, 1, 0,
     com_logout,
     NULL,


hooks/post-receive
-- 
GNU Mailutils



reply via email to

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