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-644-g441dda6


From: Sergey Poznyakoff
Subject: [SCM] GNU Mailutils branch, master, updated. release-2.2-644-g441dda6
Date: Sat, 30 Mar 2013 15:15:30 +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=441dda65dd5aa0a97bc26ea7398d38de43dbee06

The branch, master has been updated
       via  441dda65dd5aa0a97bc26ea7398d38de43dbee06 (commit)
      from  b8dc1293e299380a32992baa98a773282354d459 (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 441dda65dd5aa0a97bc26ea7398d38de43dbee06
Author: Sergey Poznyakoff <address@hidden>
Date:   Sat Mar 30 16:47:38 2013 +0200

    Implement IMAP SEARCH. New function mu_mailbox_access_time.
    
    * include/mailutils/imap.h (mu_imap_search): New proto.
    * libproto/imap/search.c: New file.
    * include/mailutils/sys/imap.h (MU_IMAP_CLIENT_SEARCH_RX): New state.
    * libproto/imap/fetch.c: Fix debugging categories
    * libproto/imap/mbox.c (_imap_messages_recent)
    (_imap_message_unseen): Use search if information is not
    readily available.
    * libproto/imap/status.c (_mu_imap_status_name_table): Comment
    out UNSEEN: its semantics is entirely different from what we
    need.
    * libproto/imap/Makefile.am: Add new file.
    * mu/imap.c: Implement search.
    
    * include/mailutils/sys/mailbox.h (_mu_mailbox) <_get_atime>: New method.
    * include/mailutils/mailbox.h (mu_mailbox_access_time): New proto.
    * libproto/mbox/mbox.c (_mailbox_mbox_init): Initialize
    >_get_atime.
    * libmailutils/mailbox/mailbox.c (mu_mailbox_access_time): New function.
    
    * libmailutils/datetime/utcoff.c (mu_utc_offset): Rewrite using tzset.
    
    * mh/msgchk.c: Implement --date.
    Check for new mail using both recent and unseen messages.

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

Summary of changes:
 include/mailutils/imap.h        |    3 +
 include/mailutils/mailbox.h     |    3 +-
 include/mailutils/sys/imap.h    |    1 +
 include/mailutils/sys/mailbox.h |    2 +
 libmailutils/datetime/utcoff.c  |    9 +--
 libmailutils/mailbox/mailbox.c  |    9 +++
 libproto/imap/Makefile.am       |    1 +
 libproto/imap/fetch.c           |    4 +-
 libproto/imap/mbox.c            |   48 +++++++++++++-
 libproto/imap/search.c          |  134 +++++++++++++++++++++++++++++++++++++++
 libproto/imap/status.c          |    2 +-
 libproto/mbox/mbox.c            |   16 +++++
 mh/msgchk.c                     |   25 ++++++-
 mu/imap.c                       |   33 ++++++++++
 14 files changed, 272 insertions(+), 18 deletions(-)
 create mode 100644 libproto/imap/search.c

diff --git a/include/mailutils/imap.h b/include/mailutils/imap.h
index 300e590..c015d53 100644
--- a/include/mailutils/imap.h
+++ b/include/mailutils/imap.h
@@ -143,6 +143,9 @@ int mu_imap_session_state_str (int state, const char 
**pstr);
 
 int mu_imap_tag (mu_imap_t imap, const char **pseq);
 
+int mu_imap_search (mu_imap_t imap, int uid, const char *expr,
+                   mu_msgset_t *msgset);
+  
 
 #define MU_IMAP_STAT_DEFINED_FLAGS   0x01
 #define MU_IMAP_STAT_PERMANENT_FLAGS 0x02
diff --git a/include/mailutils/mailbox.h b/include/mailutils/mailbox.h
index f2a6ecd..fa14e3e 100644
--- a/include/mailutils/mailbox.h
+++ b/include/mailutils/mailbox.h
@@ -20,7 +20,7 @@
 #define _MAILUTILS_MAILBOX_H
 
 #include <sys/types.h>
-
+#include <time.h>
 #include <mailutils/types.h>
 
 #ifdef __cplusplus
@@ -56,6 +56,7 @@ extern int  mu_mailbox_get_folder      (mu_mailbox_t, 
mu_folder_t *);
 extern int  mu_mailbox_set_folder      (mu_mailbox_t, mu_folder_t);
 extern int  mu_mailbox_uidvalidity     (mu_mailbox_t, unsigned long *);
 extern int  mu_mailbox_uidnext         (mu_mailbox_t, size_t *);
+extern int  mu_mailbox_access_time (mu_mailbox_t mbox, time_t *return_time);
 
 /* Messages.  */
 extern int  mu_mailbox_get_message     (mu_mailbox_t, size_t msgno,
diff --git a/include/mailutils/sys/imap.h b/include/mailutils/sys/imap.h
index 41f995b..28e5036 100644
--- a/include/mailutils/sys/imap.h
+++ b/include/mailutils/sys/imap.h
@@ -71,6 +71,7 @@ enum mu_imap_client_state
     MU_IMAP_CLIENT_UNSUBSCRIBE_RX,
     MU_IMAP_CLIENT_LSUB_RX,
     MU_IMAP_CLIENT_STARTTLS_RX,
+    MU_IMAP_CLIENT_SEARCH_RX,
     MU_IMAP_CLIENT_CLOSING
   };
 
diff --git a/include/mailutils/sys/mailbox.h b/include/mailutils/sys/mailbox.h
index f1b8813..71eb1ef 100644
--- a/include/mailutils/sys/mailbox.h
+++ b/include/mailutils/sys/mailbox.h
@@ -20,6 +20,7 @@
 # define _MAILUTILS_SYS_MAILBOX_H
 
 # include <sys/types.h>
+# include <time.h>
 # include <stdio.h>
 
 # include <mailutils/monitor.h>
@@ -76,6 +77,7 @@ struct _mu_mailbox
 
   int  (*_translate) (mu_mailbox_t, int cmd, size_t, size_t *);
   int  (*_copy) (mu_mailbox_t, mu_msgset_t, const char *, int);
+  int  (*_get_atime) (mu_mailbox_t, time_t *);
 };
 
 # ifdef __cplusplus
diff --git a/libmailutils/datetime/utcoff.c b/libmailutils/datetime/utcoff.c
index fbc55b7..d23fa71 100644
--- a/libmailutils/datetime/utcoff.c
+++ b/libmailutils/datetime/utcoff.c
@@ -20,13 +20,10 @@
 #endif
 #include <time.h>
 
-/* Convert time 0 at UTC to our localtime, that tells us the offset
-   of our current timezone from UTC. */
+/* Returns the offset of our timezone from UTC, in seconds. */
 int
 mu_utc_offset (void)
 {
-  time_t t = 0;
-  struct tm *tm = gmtime (&t);
-
-  return - mktime (tm);
+  tzset ();
+  return - timezone;
 }
diff --git a/libmailutils/mailbox/mailbox.c b/libmailutils/mailbox/mailbox.c
index db775b4..4b52e3c 100644
--- a/libmailutils/mailbox/mailbox.c
+++ b/libmailutils/mailbox/mailbox.c
@@ -918,3 +918,12 @@ mu_mailbox_translate (mu_mailbox_t mbox, int cmd, size_t 
from, size_t *to)
   return rc;
 }
 
+int
+mu_mailbox_access_time (mu_mailbox_t mbox, time_t *return_time)
+{
+  _MBOX_CHECK_Q (mbox, _get_atime);
+  if (!return_time)
+    return MU_ERR_OUT_PTR_NULL;
+  return mbox->_get_atime (mbox, return_time);
+}
+
diff --git a/libproto/imap/Makefile.am b/libproto/imap/Makefile.am
index 3af503b..a8c2e53 100644
--- a/libproto/imap/Makefile.am
+++ b/libproto/imap/Makefile.am
@@ -55,6 +55,7 @@ libmu_imap_la_SOURCES = \
  resplist.c\
  response.c\
  resproc.c\
+ search.c\
  select.c\
  state.c\
  status.c\
diff --git a/libproto/imap/fetch.c b/libproto/imap/fetch.c
index fbad10c..f1ec865 100644
--- a/libproto/imap/fetch.c
+++ b/libproto/imap/fetch.c
@@ -1004,7 +1004,7 @@ _fetch_fold (void *item, void *data)
 
        if (!mt->name)
          {
-           mu_debug (MU_DEBCAT_MAILER, MU_DEBUG_TRACE9,
+           mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_TRACE9,
                      ("ignoring unknown FETCH item '%s'", kw));
            env->state = resp_skip;
            return 0;
@@ -1112,7 +1112,7 @@ _mu_imap_parse_fetch_response (mu_list_t input, mu_list_t 
*result_list)
   status = mu_list_create (&result);
   if (status)
     {
-      mu_debug (MU_DEBCAT_MAILER, MU_DEBUG_ERROR,
+      mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_ERROR,
                ("mu_list_create: %s", mu_strerror (status)));
       return 1;
     }
diff --git a/libproto/imap/mbox.c b/libproto/imap/mbox.c
index 538c04b..d181cbc 100644
--- a/libproto/imap/mbox.c
+++ b/libproto/imap/mbox.c
@@ -812,7 +812,7 @@ _imap_messages_count (mu_mailbox_t mbox, size_t *pcount)
     return MU_ERR_INFO_UNAVAILABLE;
   return 0;
 }
-  
+
 static int
 _imap_messages_recent (mu_mailbox_t mbox, size_t *pcount)
 {
@@ -820,7 +820,20 @@ _imap_messages_recent (mu_mailbox_t mbox, size_t *pcount)
   if (imbx->stats.flags & MU_IMAP_STAT_RECENT_COUNT)
     *pcount = imbx->stats.recent_count;
   else
-    return MU_ERR_INFO_UNAVAILABLE;
+    {
+      int rc;
+      mu_folder_t folder = mbox->folder;
+      mu_imap_t imap = folder->data;
+      mu_msgset_t msgset;
+  
+      rc = mu_imap_search (imap, 0, "RECENT", &msgset);
+      if (rc)
+       return rc;
+
+      rc = mu_msgset_count (msgset, pcount);
+      mu_msgset_free (msgset);
+      return rc;
+    }
   return 0;
 }
 
@@ -840,9 +853,36 @@ _imap_message_unseen (mu_mailbox_t mbox, size_t *pn)
 {
   struct _mu_imap_mailbox *imbx = mbox->data;
   if (imbx->stats.flags & MU_IMAP_STAT_FIRST_UNSEEN)
-    *pn = imbx->stats.uidnext;
+    *pn = imbx->stats.first_unseen;
   else
-    return MU_ERR_INFO_UNAVAILABLE;
+    {
+      int rc;
+      mu_folder_t folder = mbox->folder;
+      mu_imap_t imap = folder->data;
+      mu_msgset_t msgset;
+      mu_list_t list;
+  
+      rc = mu_imap_search (imap, 0, "UNSEEN", &msgset);
+      if (rc)
+       return rc;
+
+      if (mu_msgset_is_empty (msgset))
+       {
+         mu_msgset_free (msgset);
+         return MU_ERR_NOENT;
+       }
+
+      rc = mu_msgset_get_list (msgset, &list);
+      if (rc == 0)
+       {
+         struct mu_msgrange r;
+         rc = mu_list_head (list, (void **) &r);
+         if (rc == 0)
+           *pn = r.msg_beg;
+       }
+      mu_msgset_free (msgset);
+      return rc;
+    }
   return 0;
 }
 
diff --git a/libproto/imap/search.c b/libproto/imap/search.c
new file mode 100644
index 0000000..fa8cbe9
--- /dev/null
+++ b/libproto/imap/search.c
@@ -0,0 +1,134 @@
+/* GNU Mailutils -- a suite of utilities for electronic mail
+   Copyright (C) 2011-2013 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/>. */
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <string.h>
+#include <mailutils/errno.h>
+#include <mailutils/msgset.h>
+#include <mailutils/nls.h>
+#include <mailutils/imap.h>
+#include <mailutils/sys/imap.h>
+
+struct search_closure
+{
+  mu_msgset_t msgset;
+  int retcode;
+};
+
+static int
+add_msgno (void *item, void *data)
+{
+  int rc;
+  struct imap_list_element *elt = item;
+  struct search_closure *scp = data;
+  char *p;
+  unsigned long num;
+  
+  if (elt->type != imap_eltype_string)
+    {
+      mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_ERROR,
+               (_("unexpected list element in untagged response from 
SEARCH")));
+      scp->retcode = MU_ERR_BADREPLY;
+      return 1;
+    }
+
+  if (!scp->msgset)
+    {
+      /* First element (SEARCH): create the message set and return */
+      rc = mu_msgset_create (&scp->msgset, NULL, MU_MSGSET_NUM);
+      if (rc)
+       {
+         mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_ERROR,
+                   (_("cannot create msgset: %s"),
+                    mu_strerror (rc)));
+         scp->retcode = rc;
+         return rc;
+       }
+      return 0;
+    }
+  
+  num = strtoul (elt->v.string, &p, 10);
+  if (*p)
+    {
+      mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_ERROR,
+               (_("not a number in untagged response from SEARCH: %s"),
+                elt->v.string));
+      scp->retcode = MU_ERR_BADREPLY;
+      return 1;
+    }
+  
+  rc = mu_msgset_add_range (scp->msgset, num, num, MU_MSGSET_NUM);
+  if (rc)
+    {
+      mu_debug (MU_DEBCAT_MAILBOX, MU_DEBUG_ERROR,
+               ("mu_msgset_add_range: %s", mu_strerror (rc)));
+      scp->retcode = rc;
+      return 1;
+    }
+  return 0;
+}
+
+static void
+search_handler (mu_imap_t imap, mu_list_t resp, void *data)
+{
+  mu_list_foreach (resp, add_msgno, data);
+}
+
+int
+mu_imap_search (mu_imap_t imap, int uid, const char *expr, mu_msgset_t *msgset)
+{
+  char const *argv[3];
+  int i, rc;
+  static struct imap_command com;
+  struct search_closure clos;
+
+  if (!expr)
+    return EINVAL;
+  if (!msgset)
+    return MU_ERR_OUT_PTR_NULL;
+  i = 0;
+  if (uid)
+    argv[i++] = "UID";
+  argv[i++] = "SEARCH";
+
+  clos.msgset = NULL;
+  clos.retcode = 0;
+  
+  com.session_state = MU_IMAP_SESSION_SELECTED;
+  com.capa = NULL;
+  com.rx_state = MU_IMAP_CLIENT_SEARCH_RX;
+  com.argc = i;
+  com.argv = argv;
+  com.extra = expr;
+  com.msgset = NULL;
+  com.tagged_handler = NULL;
+  com.untagged_handler = search_handler;
+  com.untagged_handler_data = &clos;
+  rc = mu_imap_gencom (imap, &com);
+  if (rc)
+      mu_msgset_free (clos.msgset);
+  else if (clos.retcode)
+    {
+      mu_msgset_free (clos.msgset);
+      rc = clos.retcode;
+    }
+  else
+    *msgset = clos.msgset;
+  return rc;
+}
diff --git a/libproto/imap/status.c b/libproto/imap/status.c
index 915225a..af92298 100644
--- a/libproto/imap/status.c
+++ b/libproto/imap/status.c
@@ -39,7 +39,7 @@ struct mu_kwd _mu_imap_status_name_table[] = {
   { "RECENT",      MU_IMAP_STAT_RECENT_COUNT  },
   { "UIDNEXT",     MU_IMAP_STAT_UIDNEXT       },
   { "UIDVALIDITY", MU_IMAP_STAT_UIDVALIDITY   },
-  { "UNSEEN",      MU_IMAP_STAT_FIRST_UNSEEN  },
+  /*  { "UNSEEN",      MU_IMAP_STAT_NUM_UNSEEN  }, */
   { NULL }
 };
 
diff --git a/libproto/mbox/mbox.c b/libproto/mbox/mbox.c
index 3ab0b95..bce7d14 100644
--- a/libproto/mbox/mbox.c
+++ b/libproto/mbox/mbox.c
@@ -1436,6 +1436,20 @@ mbox_expunge0 (mu_mailbox_t mailbox, int remove_deleted)
   return status;
 }
 
+static int
+mbox_get_atime (mu_mailbox_t mailbox, time_t *return_time)
+{
+  mbox_data_t mud = mailbox->data;
+  struct stat st;
+  
+  if (mud == NULL)
+    return EINVAL;
+  if (stat (mud->name, &st))
+    return errno;
+  *return_time = st.st_atime;
+  return 0;
+}
+
 
 /* Allocate the mbox_data_t struct(concrete mailbox), but don't do any
    parsing on the name or even test for existence.  However we do strip any
@@ -1498,6 +1512,8 @@ _mailbox_mbox_init (mu_mailbox_t mailbox)
 
   mailbox->_get_size = mbox_get_size;
 
+  mailbox->_get_atime = mbox_get_atime;
+  
   /* Set our properties.  */
   {
     mu_property_t property = NULL;
diff --git a/mh/msgchk.c b/mh/msgchk.c
index 36f40ea..d41259b 100644
--- a/mh/msgchk.c
+++ b/mh/msgchk.c
@@ -18,6 +18,7 @@
 #include "mailutils/kwd.h"
 #include "mailutils/folder.h"
 #include "mailutils/auth.h"
+#include "mailutils/datetime.h"
 #include <pwd.h>
 
 static char doc[] = N_("GNU MH msgchk")"\v"
@@ -295,11 +296,20 @@ checkmail (const char *username, int personal)
        {
          mu_off_t mbsiz = 0;
          
-         rc = mu_mailbox_messages_recent (mbox, &recent);
+         rc = mu_mailbox_message_unseen (mbox, &recent);
          if (rc)
            {
-             mu_diag_funcall (MU_DIAG_ERROR, "mu_mailbox_messages_recent",
-                              mu_url_to_string (url), rc);
+             if (rc != ENOSYS && rc != MU_ERR_INFO_UNAVAILABLE)
+               mu_diag_funcall (MU_DIAG_ERROR, "mu_mailbox_messages_unseen",
+                                mu_url_to_string (url), rc);
+             rc = mu_mailbox_messages_recent (mbox, &recent);
+           }
+
+         if (rc)
+           {
+             if (rc != ENOSYS && rc != MU_ERR_INFO_UNAVAILABLE)
+               mu_diag_funcall (MU_DIAG_ERROR, "mu_mailbox_messages_recent",
+                                mu_url_to_string (url), rc);
 
              mu_mailbox_get_size (mbox, &mbsiz);
              if (personal)
@@ -327,7 +337,14 @@ checkmail (const char *username, int personal)
            }
 
          if (date_option)
-           /*FIXME*/;
+           {
+             time_t t;
+
+             if (mu_mailbox_access_time (mbox, &t) == 0)
+               mu_c_streamftime (mu_strout,
+                                 _("; last read on %a, %d %b %Y %H:%M:%S %z"),
+                                 localtime (&t), NULL);
+           }
              
          mu_printf ("\n");
        }
diff --git a/mu/imap.c b/mu/imap.c
index 98890aa..bde1b5f 100644
--- a/mu/imap.c
+++ b/mu/imap.c
@@ -1122,6 +1122,35 @@ com_copy (int argc, char **argv)
 }
 
 static int
+com_search (int argc, char **argv)
+{
+  mu_msgset_t mset;
+  size_t count;
+  int rc;
+  
+  rc = mu_imap_search (imap, uid_mode, argv[1], &mset);
+  if (rc)
+    {
+      report_failure ("search", rc);
+      return 0;
+    }
+       
+  rc = mu_msgset_count (mset, &count);
+  if (rc == EINVAL || count == 0)
+    {
+      mu_printf (_("no matches"));
+      return 0;
+    }
+  mu_printf ("%lu matches:", (unsigned long) count);
+  mu_msgset_print (mu_strout, mset);
+  mu_printf ("\n");
+  mu_msgset_free (mset);
+  
+  return 0;
+}
+
+
+static int
 print_list_item (void *item, void *data)
 {
   struct mu_list_response *resp = item;
@@ -1293,6 +1322,10 @@ struct mutool_command imap_comtab[] = {
     com_uid,
     N_("[on|off]"),
     N_("control UID mode") },
+  { "search",       2, 2, CMD_COALESCE_EXTRA_ARGS,
+    com_search,
+    N_("args..."),
+    N_("search the mailbox") },
   { "quit",         1, 1, 0,
     com_logout,
     NULL,


hooks/post-receive
-- 
GNU Mailutils



reply via email to

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