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-450-gebbbc39


From: Sergey Poznyakoff
Subject: [SCM] GNU Mailutils branch, master, updated. release-2.2-450-gebbbc39
Date: Fri, 18 Nov 2011 19:28:01 +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=ebbbc397fba86fd32fb2cccb377a59f8e38d03e9

The branch, master has been updated
       via  ebbbc397fba86fd32fb2cccb377a59f8e38d03e9 (commit)
      from  a736b7a9a775db4b82806a6214deefc3ac7a4dd4 (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 ebbbc397fba86fd32fb2cccb377a59f8e38d03e9
Author: Sergey Poznyakoff <address@hidden>
Date:   Fri Nov 18 21:23:15 2011 +0200

    imap client: implement select/examine.
    
    * include/mailutils/imap.h (mu_imap_stat): New structs.
    (MU_IMAP_STAT_DEFINED_FLAGS,MU_IMAP_STAT_PERMANENT_FLAGS)
    (MU_IMAP_STAT_MESSAGE_COUNT,MU_IMAP_STAT_RECENT_COUNT)
    (MU_IMAP_STAT_FIRST_UNSEEN,MU_IMAP_STAT_UIDNEXT)
    (MU_IMAP_STAT_UIDVALIDITY):  New flags.
    (mu_imap_select): New proto.
    * include/mailutils/imapio.h (mu_imap_flag_to_attribute)
    (mu_imap_format_flags): New protos.
    * include/mailutils/sys/imap.h (mu_imap_client_state)
    <MU_IMAP_SELECT_RX>: New state.
    (_mu_imap) <mbox_name,mbox_writable,mbox_stat>: New members.
    * libmailutils/imapio/flags.c: New file.
    * libmailutils/imapio/Makefile.am: Add flags.c
    * libproto/imap/select.c: New file.
    * libproto/imap/Makefile.am: Add select.c
    * libproto/imap/err.c (_mu_imap_seterrstr)
    (_mu_imap_clrerrstr, mu_imap_strerror): Allow for imap==NULL.
    * libproto/imap/id.c (mu_imap_id): Set errstr on MU_ERR_BADREPLY
    * libproto/imap/login.c (mu_imap_login): Likewise.
    * libproto/imap/resplist.c (_mu_imap_list_element_is_string): New function.
    * mu/imap.c: Implement examine and select.

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

Summary of changes:
 include/mailutils/imap.h        |   28 +++++-
 include/mailutils/imapio.h      |    3 +
 include/mailutils/sys/imap.h    |    8 ++
 libmailutils/imapio/Makefile.am |    1 +
 libmailutils/imapio/flags.c     |   85 ++++++++++++++
 libproto/imap/Makefile.am       |    1 +
 libproto/imap/err.c             |    9 ++-
 libproto/imap/id.c              |    7 +-
 libproto/imap/login.c           |    9 ++-
 libproto/imap/resplist.c        |   10 ++
 libproto/imap/select.c          |  230 +++++++++++++++++++++++++++++++++++++++
 mu/imap.c                       |   72 ++++++++++++
 12 files changed, 458 insertions(+), 5 deletions(-)
 create mode 100644 libmailutils/imapio/flags.c
 create mode 100644 libproto/imap/select.c

diff --git a/include/mailutils/imap.h b/include/mailutils/imap.h
index 3e04391..e8369cb 100644
--- a/include/mailutils/imap.h
+++ b/include/mailutils/imap.h
@@ -37,7 +37,7 @@ enum mu_imap_state
     MU_IMAP_STATE_NONAUTH,  /* Non-Authenticated State */
     MU_IMAP_STATE_AUTH,     /* Authenticated State */
     MU_IMAP_STATE_SELECTED, /* Selected State */
-    MU_IMAP_STATE_LOGOUT    /* Logout State */
+    MU_IMAP_STATE_LOGOUT,   /* Logout State */
   };
   
 int mu_imap_create (mu_imap_t *pimap);
@@ -70,7 +70,31 @@ int mu_imap_state (mu_imap_t imap, int *pstate);
 int mu_imap_state_str (int state, const char **pstr);
 
 int mu_imap_tag (mu_imap_t imap, const char **pseq);
-  
+
+
+#define MU_IMAP_STAT_DEFINED_FLAGS   0x01
+#define MU_IMAP_STAT_PERMANENT_FLAGS 0x02
+#define MU_IMAP_STAT_MESSAGE_COUNT   0x04
+#define MU_IMAP_STAT_RECENT_COUNT    0x08
+#define MU_IMAP_STAT_FIRST_UNSEEN    0x10
+#define MU_IMAP_STAT_UIDNEXT         0x20
+#define MU_IMAP_STAT_UIDVALIDITY     0x40
+
+struct mu_imap_stat
+{
+  int flags;                 /* Bitmap of what fields are filled */
+  int defined_flags;         /* Flags defined for this mailbox */
+  int permanent_flags;       /* Flags that can be changed permanently */
+  size_t message_count;      /* Number of messages */
+  size_t recent_count;       /* Number of recent messages */
+  size_t first_unseen;       /* Sequence number of the first unseen message */
+  size_t uidnext;            /* The next unique identifier value. */
+  unsigned long uidvalidity; /* The unique identifier validity value. */
+};
+
+int mu_imap_select (mu_imap_t imap, const char *mbox, int writable,
+                   struct mu_imap_stat *ps);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/include/mailutils/imapio.h b/include/mailutils/imapio.h
index 9b92622..f5ebb70 100644
--- a/include/mailutils/imapio.h
+++ b/include/mailutils/imapio.h
@@ -45,6 +45,9 @@ int mu_imapio_get_trace (mu_imapio_t io);
 int mu_imapio_getbuf (mu_imapio_t io, char **pptr, size_t *psize);
 
 int mu_imapio_reply_string (struct _mu_imapio *io, size_t start, char **pbuf);
+
+int mu_imap_flag_to_attribute (const char *item, int *attr);
+int mu_imap_format_flags (mu_stream_t str, int flags);
   
 #ifdef __cplusplus
 }
diff --git a/include/mailutils/sys/imap.h b/include/mailutils/sys/imap.h
index 17a0095..89ff4db 100644
--- a/include/mailutils/sys/imap.h
+++ b/include/mailutils/sys/imap.h
@@ -44,6 +44,7 @@ enum mu_imap_client_state
     MU_IMAP_LOGIN_RX,
     MU_IMAP_LOGOUT_RX,
     MU_IMAP_ID_RX,
+    MU_IMAP_SELECT_RX
   };
 
 enum mu_imap_response
@@ -77,6 +78,10 @@ struct _mu_imap
     
     mu_list_t capa;
     mu_imapio_t io;
+
+    char *mbox_name;  /* Name of the currently opened mailbox */
+    int mbox_writable:1; /* Is it open read/write? */
+    struct mu_imap_stat mbox_stat;  /* Stats obtained from it */
 };
 
 enum imap_eltype
@@ -151,6 +156,9 @@ int _mu_imap_response (mu_imap_t imap);
 
 int _mu_imap_untagged_response_clear (mu_imap_t imap);
 int _mu_imap_untagged_response_add (mu_imap_t imap);
+
+int _mu_imap_list_element_is_string (struct imap_list_element *elt,
+                                    const char *str);
   
 # ifdef __cplusplus
 }
diff --git a/libmailutils/imapio/Makefile.am b/libmailutils/imapio/Makefile.am
index 20c0784..c856d9d 100644
--- a/libmailutils/imapio/Makefile.am
+++ b/libmailutils/imapio/Makefile.am
@@ -19,6 +19,7 @@ noinst_LTLIBRARIES = libimapio.la
 
 libimapio_la_SOURCES = \
  create.c\
+ flags.c\
  getline.c\
  literal.c\
  printf.c\
diff --git a/libmailutils/imapio/flags.c b/libmailutils/imapio/flags.c
new file mode 100644
index 0000000..5d07297
--- /dev/null
+++ b/libmailutils/imapio/flags.c
@@ -0,0 +1,85 @@
+/* GNU Mailutils -- a suite of utilities for electronic mail
+   Copyright (C) 2011 Free Software Foundation, Inc.
+
+   GNU Mailutils is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3, or (at your option)
+   any later version.
+
+   GNU Mailutils 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 General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GNU Mailutils.  If not, see <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+#include <mailutils/types.h>
+#include <mailutils/imapio.h>
+#include <mailutils/attribute.h>
+#include <mailutils/stream.h>
+#include <mailutils/errno.h>
+#include <mailutils/cstr.h>
+#include <mailutils/sys/imapio.h>
+
+static struct
+{
+  char *name;
+  int flag;
+}
+_imap4_attrlist[] =
+{
+  { "\\Answered", MU_ATTRIBUTE_ANSWERED },
+  { "\\Flagged", MU_ATTRIBUTE_FLAGGED },
+  { "\\Deleted", MU_ATTRIBUTE_DELETED },
+  { "\\Draft", MU_ATTRIBUTE_DRAFT },
+  { "\\Seen", MU_ATTRIBUTE_SEEN|MU_ATTRIBUTE_READ },
+};
+
+static int _imap4_nattr = MU_ARRAY_SIZE (_imap4_attrlist);
+
+int
+mu_imap_flag_to_attribute (const char *item, int *attr)
+{
+  int i;
+
+  if (mu_c_strcasecmp (item, "\\Recent") == 0)
+    {
+      *attr |= MU_ATTRIBUTE_RECENT;
+      return 0;
+    }
+  
+  for (i = 0; i < _imap4_nattr; i++)
+    if (mu_c_strcasecmp (item, _imap4_attrlist[i].name) == 0)
+      {
+       *attr |= _imap4_attrlist[i].flag;
+       return 0;
+      }
+  return MU_ERR_NOENT;
+}
+
+int
+mu_imap_format_flags (mu_stream_t str, int flags)
+{
+  int i;
+  int delim = 0;
+  
+  for (i = 0; i < _imap4_nattr; i++)
+    if ((flags & _imap4_attrlist[i].flag) == _imap4_attrlist[i].flag)
+      {
+       if (delim)
+         mu_stream_printf (str, " ");
+       mu_stream_printf (str, "%s", _imap4_attrlist[i].name);
+       delim = 1;
+      }
+
+  if (MU_ATTRIBUTE_IS_UNSEEN (flags))
+    {
+      if (delim)
+       mu_stream_printf (str, " ");
+      mu_stream_printf (str, "\\Recent");
+    }
+  
+  return 0;
+}
diff --git a/libproto/imap/Makefile.am b/libproto/imap/Makefile.am
index 2f54f70..cf8dcbe 100644
--- a/libproto/imap/Makefile.am
+++ b/libproto/imap/Makefile.am
@@ -41,6 +41,7 @@ libmu_imap_la_SOURCES = \
  logout.c\
  resplist.c\
  response.c\
+ select.c\
  state.c\
  tag.c\
  trace.c
diff --git a/libproto/imap/err.c b/libproto/imap/err.c
index 4e77362..29e275d 100644
--- a/libproto/imap/err.c
+++ b/libproto/imap/err.c
@@ -26,6 +26,8 @@
 int
 _mu_imap_seterrstr (mu_imap_t imap, const char *str, size_t len)
 {
+  if (!imap)
+    return EINVAL;
   if (len + 1 > imap->errsize)
     {
       char *p = realloc (imap->errstr, len + 1);
@@ -42,13 +44,18 @@ _mu_imap_seterrstr (mu_imap_t imap, const char *str, size_t 
len)
 void
 _mu_imap_clrerrstr (mu_imap_t imap)
 {
-  if (imap->errstr)
+  if (imap && imap->errstr)
     imap->errstr[0] = 0;
 }
     
 int
 mu_imap_strerror (mu_imap_t imap, const char **pstr)
 {
+  if (!imap)
+    {
+      *pstr = "(imap not initialized)";
+      return EINVAL;
+    }
   if (imap->errstr)
     {
       *pstr = imap->errstr;
diff --git a/libproto/imap/id.c b/libproto/imap/id.c
index a6e6254..4e03c5d 100644
--- a/libproto/imap/id.c
+++ b/libproto/imap/id.c
@@ -105,11 +105,11 @@ parse_id_reply (mu_imap_t imap, mu_assoc_t *passoc)
   return st.ret;
 }
   
-  
 int
 mu_imap_id (mu_imap_t imap, char **idenv, mu_assoc_t *passoc)
 {
   int status;
+  char *p;
   
   if (imap == NULL)
     return EINVAL;
@@ -171,6 +171,11 @@ mu_imap_id (mu_imap_t imap, char **idenv, mu_assoc_t 
*passoc)
 
        case MU_IMAP_BAD:
          status = MU_ERR_BADREPLY;
+         if (mu_imapio_reply_string (imap->io, 2, &p) == 0)
+           {
+             _mu_imap_seterrstr (imap, p, strlen (p));
+             free (p);
+           }
          break;
        }
       imap->state = MU_IMAP_CONNECTED;
diff --git a/libproto/imap/login.c b/libproto/imap/login.c
index fe0af0c..b1f840f 100644
--- a/libproto/imap/login.c
+++ b/libproto/imap/login.c
@@ -18,7 +18,8 @@
 #ifdef HAVE_CONFIG_H
 # include <config.h>
 #endif
-
+#include <stdlib.h>
+#include <string.h>
 #include <mailutils/errno.h>
 #include <mailutils/stream.h>
 #include <mailutils/sys/imap.h>
@@ -27,6 +28,7 @@ int
 mu_imap_login (mu_imap_t imap, const char *user, const char *pass)
 {
   int status;
+  char *p;
   
   if (imap == NULL)
     return EINVAL;
@@ -67,6 +69,11 @@ mu_imap_login (mu_imap_t imap, const char *user, const char 
*pass)
 
        case MU_IMAP_BAD:
          status = MU_ERR_BADREPLY;
+         if (mu_imapio_reply_string (imap->io, 2, &p) == 0)
+           {
+             _mu_imap_seterrstr (imap, p, strlen (p));
+             free (p);
+           }
          break;
        }
       imap->state = MU_IMAP_CONNECTED;
diff --git a/libproto/imap/resplist.c b/libproto/imap/resplist.c
index 3031fee..f46417c 100644
--- a/libproto/imap/resplist.c
+++ b/libproto/imap/resplist.c
@@ -254,3 +254,13 @@ _mu_imap_untagged_response_add (mu_imap_t imap)
   mu_list_append (imap->untagged_resp, elt);
   return 0;
 }
+
+int
+_mu_imap_list_element_is_string (struct imap_list_element *elt,
+                                const char *str)
+{
+  if (elt->type != imap_eltype_string)
+    return 0;
+  return strcmp (elt->v.string, str) == 0;
+}
+
diff --git a/libproto/imap/select.c b/libproto/imap/select.c
new file mode 100644
index 0000000..130bb8d
--- /dev/null
+++ b/libproto/imap/select.c
@@ -0,0 +1,230 @@
+/* GNU Mailutils -- a suite of utilities for electronic mail
+   Copyright (C) 2010, 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/assoc.h>
+#include <mailutils/stream.h>
+#include <mailutils/imap.h>
+#include <mailutils/sys/imap.h>
+
+static int
+_collect_flags (void *item, void *data)
+{
+  struct imap_list_element *elt = item;
+  int *args = data;
+
+  if (elt->type == imap_eltype_string)
+    mu_imap_flag_to_attribute (elt->v.string, args);
+  return 0;
+}
+
+static int
+_parse_stat (void *item, void *data)
+{
+  struct imap_list_element *response = item;
+  mu_imap_t imap = data;
+  struct imap_list_element *elt;
+  size_t count;
+  int rc;
+  char *p;
+  
+  if (response->type != imap_eltype_list)
+    return 0;
+
+  mu_list_count (response->v.list, &count);
+  
+  rc = mu_list_get (response->v.list, 0, (void*) &elt);
+  if (rc)
+    return rc;
+  
+  if (_mu_imap_list_element_is_string (elt, "OK"))
+    {
+      struct imap_list_element *arg;
+      
+      if (count < 3)
+       return 0; /* ignore the line */
+      rc = mu_list_get (response->v.list, 1, (void*) &elt);
+      if (rc)
+       return rc;
+      rc = mu_list_get (response->v.list, 2, (void*) &arg);
+      if (rc)
+       return rc;
+      
+      if (_mu_imap_list_element_is_string (elt, "[UIDVALIDITY"))
+       {
+         if (arg->type != imap_eltype_string)
+           return 0;
+         imap->mbox_stat.uidvalidity = strtoul (arg->v.string, &p, 10);
+         if (*p == ']')
+           imap->mbox_stat.flags |= MU_IMAP_STAT_UIDVALIDITY;
+       }
+      else if (_mu_imap_list_element_is_string (elt, "[UIDNEXT"))
+       {
+         if (arg->type != imap_eltype_string)
+           return 0;
+         imap->mbox_stat.uidnext = strtoul (arg->v.string, &p, 10);
+         if (*p == ']')
+           imap->mbox_stat.flags |= MU_IMAP_STAT_UIDNEXT;
+       }
+      else if (_mu_imap_list_element_is_string (elt, "[UNSEEN"))
+       {
+         if (arg->type != imap_eltype_string)
+           return 0;
+         imap->mbox_stat.first_unseen = strtoul (arg->v.string, &p, 10);
+         if (*p == ']')
+           imap->mbox_stat.flags |= MU_IMAP_STAT_FIRST_UNSEEN;
+       }
+      else if (_mu_imap_list_element_is_string (elt, "[PERMANENTFLAGS"))
+       {
+         if (arg->type != imap_eltype_list)
+           return 0;
+         mu_list_do (arg->v.list, _collect_flags,
+                     &imap->mbox_stat.permanent_flags);
+         imap->mbox_stat.flags |= MU_IMAP_STAT_PERMANENT_FLAGS;
+       }
+    }
+  else if (_mu_imap_list_element_is_string (elt, "FLAGS"))
+    {
+      struct imap_list_element *arg;
+      rc = mu_list_get (response->v.list, 1, (void*) &arg);
+      if (rc)
+       return 0;
+      if (arg->type != imap_eltype_list)
+       return 0;
+      mu_list_do (arg->v.list, _collect_flags, &imap->mbox_stat.defined_flags);
+      imap->mbox_stat.flags |= MU_IMAP_STAT_DEFINED_FLAGS;
+    }
+  else if (count == 2)
+    {
+      struct imap_list_element *arg;
+      rc = mu_list_get (response->v.list, 1, (void*) &arg);
+      if (rc)
+       return rc;
+      if (_mu_imap_list_element_is_string (arg, "EXISTS"))
+       {
+         imap->mbox_stat.message_count = strtoul (elt->v.string, &p, 10);
+         if (*p == 0)
+           imap->mbox_stat.flags |= MU_IMAP_STAT_MESSAGE_COUNT;
+       }
+      else if (_mu_imap_list_element_is_string (arg, "RECENT"))
+       {
+         imap->mbox_stat.recent_count = strtoul (elt->v.string, &p, 10);
+         if (*p == 0)
+           imap->mbox_stat.flags |= MU_IMAP_STAT_RECENT_COUNT;
+       }
+    }
+  
+  return 0;
+}
+
+int
+mu_imap_select (mu_imap_t imap, const char *mbox, int writable,
+               struct mu_imap_stat *ps)
+{
+  int status;
+  char *p;
+  
+  if (imap == NULL)
+    return EINVAL;
+  if (!imap->io)
+    return MU_ERR_NO_TRANSPORT;
+  if (imap->state != MU_IMAP_CONNECTED)
+    return MU_ERR_SEQ;
+  if (imap->imap_state != MU_IMAP_STATE_AUTH &&
+      imap->imap_state != MU_IMAP_STATE_SELECTED)
+    return MU_ERR_SEQ;
+
+  if (!mbox)
+    {
+      if (imap->imap_state == MU_IMAP_STATE_SELECTED)
+       {
+         if (ps)
+           *ps = imap->mbox_stat;
+         return 0;
+       }
+      return MU_ERR_INFO_UNAVAILABLE;
+    }
+  
+  if (imap->mbox_name && strcmp (imap->mbox_name, mbox) == 0
+      && writable == imap->mbox_writable)
+    {
+      if (ps)
+       *ps = imap->mbox_stat;
+      return 0;
+    }
+  
+  switch (imap->state)
+    {
+    case MU_IMAP_CONNECTED:
+      status = _mu_imap_tag_next (imap);
+      MU_IMAP_CHECK_EAGAIN (imap, status);
+      status = mu_imapio_printf (imap->io, "%s %s %s\r\n",
+                                imap->tag_str,
+                                writable ? "SELECT" : "EXAMINE",
+                                mbox);
+      MU_IMAP_CHECK_ERROR (imap, status);
+      MU_IMAP_FCLR (imap, MU_IMAP_RESP);
+      imap->state = MU_IMAP_SELECT_RX;
+
+    case MU_IMAP_SELECT_RX:
+      status = _mu_imap_response (imap);
+      MU_IMAP_CHECK_EAGAIN (imap, status);
+      switch (imap->resp_code)
+       {
+       case MU_IMAP_OK:
+         imap->imap_state = MU_IMAP_STATE_SELECTED;
+         free (imap->mbox_name);
+         imap->mbox_name = strdup (mbox);
+         if (!imap->mbox_name)
+           {
+             imap->state = MU_IMAP_ERROR;
+             return errno;
+           }
+         imap->mbox_writable = writable;
+         memset (&imap->mbox_stat, 0, sizeof (imap->mbox_stat));
+         mu_list_do (imap->untagged_resp, _parse_stat, imap);
+         if (ps)
+           *ps = imap->mbox_stat;
+         break;
+
+       case MU_IMAP_NO:
+         status = EACCES;
+         break;
+
+       case MU_IMAP_BAD:
+         status = MU_ERR_BADREPLY;
+         if (mu_imapio_reply_string (imap->io, 2, &p) == 0)
+           {
+             _mu_imap_seterrstr (imap, p, strlen (p));
+             free (p);
+           }
+         break;
+       }
+      imap->state = MU_IMAP_CONNECTED;
+      break;
+
+    default:
+      status = EINPROGRESS;
+    }
+  return status;
+}
diff --git a/mu/imap.c b/mu/imap.c
index e6fa2d1..156fdf3 100644
--- a/mu/imap.c
+++ b/mu/imap.c
@@ -25,6 +25,7 @@
 #include <netinet/in.h>
 #include <mailutils/mailutils.h>
 #include <mailutils/imap.h>
+#include <mailutils/imapio.h>
 #include "mu.h"
 #include "argp.h"
 #include "xalloc.h"
@@ -454,6 +455,71 @@ com_id (int argc, char **argv)
     }
   return status;
 }
+
+static void
+print_imap_stats (struct mu_imap_stat *st)
+{
+  if (st->flags & MU_IMAP_STAT_DEFINED_FLAGS)
+    {
+      mu_printf (_("Flags defined: "));
+      mu_imap_format_flags (mu_strout, st->defined_flags);
+      mu_printf ("\n");
+    }
+  if (st->flags & MU_IMAP_STAT_PERMANENT_FLAGS)
+    {
+      mu_printf (_("Flags permanent: "));
+      mu_imap_format_flags (mu_strout, st->permanent_flags);
+      mu_printf ("\n");
+    }
+
+  if (st->flags & MU_IMAP_STAT_MESSAGE_COUNT)
+    mu_printf (_("Total messages: %lu\n"), (unsigned long) st->message_count);
+  if (st->flags & MU_IMAP_STAT_RECENT_COUNT)
+    mu_printf (_("Recent messages: %lu\n"), (unsigned long) st->recent_count);
+  if (st->flags & MU_IMAP_STAT_FIRST_UNSEEN)
+    mu_printf (_("First unseen message: %lu\n"),
+              (unsigned long) st->first_unseen);
+  if (st->flags & MU_IMAP_STAT_UIDNEXT)
+    mu_printf (_("Next UID: %lu\n"), (unsigned long) st->uidnext);
+  if (st->flags & MU_IMAP_STAT_UIDVALIDITY)
+    mu_printf (_("UID validity: %lu\n"), st->uidvalidity);
+}
+
+
+static int
+select_mbox (int argc, char **argv, int writable)
+{
+  int status;
+  struct mu_imap_stat st;
+
+  status = mu_imap_select (imap, argv[1], writable, &st);
+  if (status == 0)
+    {
+      print_imap_stats (&st);
+      imap_prompt_env ();
+    }
+  else
+    {
+      const char *str;
+      
+      mu_error ("select failed: %s", mu_strerror (status));
+      if (mu_imap_strerror (imap, &str) == 0)
+       mu_error ("server reply: %s", str);
+    }
+  return 0;
+}
+
+static int
+com_select (int argc, char **argv)
+{
+  return select_mbox (argc, argv, 1);
+}
+
+static int
+com_examine (int argc, char **argv)
+{
+  return select_mbox (argc, argv, 0);
+}
 
 
 struct mutool_command imap_comtab[] = {
@@ -481,6 +547,12 @@ struct mutool_command imap_comtab[] = {
   { "id",           1, -1, com_id,
     N_("[-test KW] [ARG [ARG...]]"),
     N_("send ID command") },
+  { "select",       1, 2, com_select,
+    N_("MBOX"),
+    N_("select a mailbox") },
+  { "examine",       1, 2, com_examine,
+    N_("MBOX"),
+    N_("examine a mailbox") },  
   { "quit",         1, 1, com_logout,
     NULL,
     N_("same as `logout'") },


hooks/post-receive
-- 
GNU Mailutils



reply via email to

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