]> granicus.if.org Git - mutt/commitdiff
The attached patch:
authorThomas Roessler <roessler@does-not-exist.org>
Wed, 8 Sep 1999 06:05:51 +0000 (06:05 +0000)
committerThomas Roessler <roessler@does-not-exist.org>
Wed, 8 Sep 1999 06:05:51 +0000 (06:05 +0000)
* gets Mutt to properly log off the IMAP server when quitting. Clients
  don't care, but it's polite and proper.
* further updates the flags changes from yesterday
* uses CLOSE instead of EXPUNGE when closing a mailbox and purging
  messages, for some slight speed gain.
* purges all messages marked for deletion in one command (if purging),
  making for very cool speed gains switching mailboxes if you're on,
  say, a few high volume mailing lists. Yeah, baby! (I personally love
  this one).

(From Brendan Cully <brendan@kublai.com>)

curs_main.c
imap/imap.c
imap/imap.h
imap/imap_private.h
mx.c

index c873e597cb53f6a1c303d0a3ffde3e9a067326d0..285f96b71d891524d089b36644a590e464ac15ab 100644 (file)
 #include "sort.h"
 #include "buffy.h"
 
+#ifdef USE_IMAP
+#include "mx.h"
+#include "imap.h"
+#endif
+
 
 
 #ifdef _PGPPATH
@@ -746,6 +751,11 @@ int mutt_index_menu (void)
 
        if (query_quadoption (OPT_QUIT, _("Quit Mutt?")) == M_YES)
        { 
+#ifdef USE_IMAP
+          /* logout gracefully from the IMAP server */
+          if (Context->magic == M_IMAP)
+            imap_set_logout (Context);
+#endif
          if (!Context || mx_close_mailbox (Context) == 0)
            done = 1;
          else
@@ -987,6 +997,10 @@ int mutt_index_menu (void)
        {
          if (Context)
          {
+#ifdef USE_IMAP
+            if (Context->magic == M_IMAP)
+              imap_set_logout (Context);
+#endif
            mx_fastclose_mailbox (Context);
            safe_free ((void **) &Context);
          }
index b577de91dc40e1428bbe4fdced0757f9abae569e..c15404515d266765733d5ce8df4db6518819bc20 100644 (file)
@@ -54,6 +54,17 @@ static int imap_check_acl (IMAP_DATA *idata);
 static int imap_check_capabilities (IMAP_DATA *idata);
 static int imap_create_mailbox (IMAP_DATA *idata, char *mailbox);
 
+void imap_error (const char *where, const char *msg)
+{
+  mutt_error (_("imap_error(): unexpected response in %s: %s\n"), where, msg);
+}
+
+void imap_set_logout (CONTEXT *ctx)
+{
+  if (CTX_DATA)
+    CTX_DATA->status = IMAP_LOGOUT;
+}
+
 void imap_make_sequence (char *buf, size_t buflen)
 {
   static int sequence = 0;
@@ -64,11 +75,6 @@ void imap_make_sequence (char *buf, size_t buflen)
     sequence = 0;
 }
 
-void imap_error (const char *where, const char *msg)
-{
-  mutt_error (_("imap_error(): unexpected response in %s: %s\n"), where, msg);
-}
-
 /* imap_parse_date: date is of the form: DD-MMM-YYYY HH:MM:SS +ZZzz */
 time_t imap_parse_date (char *s)
 {
@@ -354,7 +360,7 @@ int imap_handle_untagged (IMAP_DATA *idata, char *s)
   }
   else
   {
-    dprint (1, (debugfile, "imap_unhandle_untagged(): unhandled request: %s\n",
+    dprint (1, (debugfile, "imap_handle_untagged(): unhandled request: %s\n",
                s));
   }
 
@@ -1277,7 +1283,64 @@ int imap_sync_mailbox (CONTEXT *ctx, int expunge)
   char seq[8];
   char buf[LONG_STRING];
   char flags[LONG_STRING];
+  char tmp[LONG_STRING];
   int n;
+  int setstart = 0;
+
+  if (CTX_DATA->state != IMAP_SELECTED)
+  {
+    dprint (2, (debugfile, "imap_sync_mailbox: no mailbox selected\n"));
+    return -1;
+  }
+  
+  /* if we are expunging anyway, we can do deleted messages very quickly... */
+  if (expunge && mutt_bit_isset (CTX_DATA->rights, IMAP_ACL_DELETE))
+  {
+    buf[0] = '\0';
+    for (n = 0; n < ctx->msgcount; n++)
+    {
+      if (ctx->hdrs[n]->changed && ctx->hdrs[n]->deleted)
+      {
+        if (setstart == 0)
+        {
+          setstart = n+1;
+          if (!buf[0])
+            snprintf (buf, sizeof (buf), "%u", n+1);
+          else
+          {
+            strncpy (tmp, buf, sizeof (tmp));
+            snprintf (buf, sizeof (buf), "%s,%u", tmp, n+1);
+          }
+        }
+        /* tie up if the last message is also deleted */
+        else if (n == ctx->msgcount-1)
+        {
+          strncpy (tmp, buf, sizeof (tmp));
+          snprintf (buf, sizeof (buf), "%s:%u", tmp, n+1);
+        }
+        /* the normal flag update can skip this message */
+        ctx->hdrs[n]->changed = 0;
+      }
+      else if (setstart && (n > setstart))
+      {
+        setstart = 0;
+        strncpy (tmp, buf, sizeof (tmp));
+        snprintf (buf, sizeof (buf), "%s:%u", tmp, n);
+      }
+    }
+    /* if we have a message set, then let's delete */
+    if (buf[0])
+    {
+      snprintf (tmp, sizeof (tmp), _("Marking %d messages for deletion..."), ctx->deleted);
+      mutt_message (tmp);
+      imap_make_sequence (seq, sizeof (seq));
+      snprintf (tmp, sizeof (tmp), "%s STORE %s +FLAGS.SILENT (\\Deleted)\r\n",
+        seq, buf);
+      if (imap_exec (buf, sizeof (buf), CTX_DATA, seq, tmp, 0) != 0)
+        /* continue, let regular store try before giving up */
+        dprint(2, (debugfile, "imap_sync_mailbox: fast delete failed\n"));
+    }
+  }
 
   /* save status changes */
   for (n = 0; n < ctx->msgcount; n++)
@@ -1337,7 +1400,20 @@ int imap_sync_mailbox (CONTEXT *ctx, int expunge)
 
   if (expunge == 1)
   {
-    if (mutt_bit_isset(CTX_DATA->rights, IMAP_ACL_DELETE))
+    /* expunge is implicit if closing */
+    if (ctx->closing)
+    {
+      mutt_message _("Closing mailbox...");
+      imap_make_sequence (seq, sizeof (seq));
+      snprintf (buf, sizeof (buf), "%s CLOSE\r\n", seq);
+      if (imap_exec (buf, sizeof (buf), CTX_DATA, seq, buf, 0) != 0)
+      {
+        imap_error ("imap_sync_mailbox()", buf);
+        return -1;
+      }
+      CTX_DATA->state = IMAP_AUTHENTICATED;
+    }
+    else if (mutt_bit_isset(CTX_DATA->rights, IMAP_ACL_DELETE))
     {
       mutt_message _("Expunging messages from server...");
       CTX_DATA->status = IMAP_EXPUNGE;
@@ -1346,7 +1422,7 @@ int imap_sync_mailbox (CONTEXT *ctx, int expunge)
       if (imap_exec (buf, sizeof (buf), CTX_DATA, seq, buf, 0) != 0)
       {
         imap_error ("imap_sync_mailbox()", buf);
-        return (-1);
+        return -1;
       }
       CTX_DATA->status = 0;
     }
@@ -1387,7 +1463,8 @@ void imap_fastclose_mailbox (CONTEXT *ctx)
       safe_free ((void **) &CTX_DATA->cache[i].path);
     }
   }
-  if (CTX_DATA->status == IMAP_BYE || CTX_DATA->status == IMAP_FATAL)
+  if (CTX_DATA->status == IMAP_BYE || CTX_DATA->status == IMAP_FATAL ||
+    CTX_DATA->status == IMAP_LOGOUT)
   {
     imap_close_connection (ctx);
     CTX_DATA->conn->data = NULL;
index 52e71adab202bd1bf806ecd7070f0e2058f57c04..15395f019e5f47e49270ba6ce49d809a182f0e2a 100644 (file)
 #include "mailbox.h"
 
 int imap_check_mailbox (CONTEXT *ctx, int *index_hint);
+int imap_close_connection (CONTEXT *ctx);
 int imap_open_mailbox (CONTEXT *ctx);
 int imap_open_mailbox_append (CONTEXT *ctx);
 int imap_parse_path (char *path, char *host, size_t hlen, int *port,
   char **mbox);
 int imap_select_mailbox (CONTEXT *ctx, const char* path);
+void imap_set_logout (CONTEXT *ctx);
 int imap_sync_mailbox (CONTEXT *ctx, int expunge);
 void imap_fastclose_mailbox (CONTEXT *ctx);
 int imap_buffy_check (char *path);
index 3fcfbc0d3618da271b44d02fd4f3310f2ba6006d..618f9d4b079a70de09306d3eb70faa18a0502758 100644 (file)
@@ -37,7 +37,8 @@ enum
   IMAP_EXPUNGE,
   IMAP_BYE,
   IMAP_OK_FAIL,
-  IMAP_REOPENED
+  IMAP_REOPENED,
+  IMAP_LOGOUT
 };
 
 enum
diff --git a/mx.c b/mx.c
index b1ec0fd27475c0063431ff6354eaa7b7a146208c..056a13dd150920f00d924f68b04144d0de38af24 100644 (file)
--- a/mx.c
+++ b/mx.c
@@ -868,37 +868,37 @@ int mx_close_mailbox (CONTEXT *ctx)
   {
     if (imap_sync_mailbox (ctx, purge) == -1)
       return -1;
+    if (ctx->magic == M_IMAP && !purge)
+      mutt_message (_("%d kept."), ctx->msgcount);
   }
+  else
 #endif
-  if (!purge)
   {
-    for (i = 0; i < ctx->msgcount; i++)
-      ctx->hdrs[i]->deleted = 0;
-    ctx->deleted = 0;
-  }
+    if (!purge)
+    {
+      for (i = 0; i < ctx->msgcount; i++)
+        ctx->hdrs[i]->deleted = 0;
+      ctx->deleted = 0;
+    }
 
-  if (ctx->changed || ctx->deleted)
-  {
-    if (sync_mailbox (ctx) == -1)
-      return (-1);
-  }
+    if (ctx->changed || ctx->deleted)
+    {
+      if (sync_mailbox (ctx) == -1)
+        return -1;
+    }
 
-#ifdef USE_IMAP
-  if (ctx->magic == M_IMAP && !purge)
-    mutt_message (_("%d kept."), ctx->msgcount);
-  else
-#endif
-  if (move_messages)
-    mutt_message (_("%d kept, %d moved, %d deleted."),
-                 ctx->msgcount - ctx->deleted, read_msgs, ctx->deleted);
-  else
-    mutt_message (_("%d kept, %d deleted."),
-                 ctx->msgcount - ctx->deleted, ctx->deleted);
+    if (move_messages)
+      mutt_message (_("%d kept, %d moved, %d deleted."),
+        ctx->msgcount - ctx->deleted, read_msgs, ctx->deleted);
+    else
+      mutt_message (_("%d kept, %d deleted."),
+        ctx->msgcount - ctx->deleted, ctx->deleted);
 
-  if (ctx->msgcount == ctx->deleted &&
-      (ctx->magic == M_MMDF || ctx->magic == M_MBOX) &&
-      !mutt_is_spool(ctx->path) && !option (OPTSAVEEMPTY))
-    mx_unlink_empty (ctx->path);
+    if (ctx->msgcount == ctx->deleted &&
+        (ctx->magic == M_MMDF || ctx->magic == M_MBOX) &&
+        !mutt_is_spool(ctx->path) && !option (OPTSAVEEMPTY))
+      mx_unlink_empty (ctx->path);
+  }
 
   mx_fastclose_mailbox (ctx);