]> granicus.if.org Git - mutt/commitdiff
* handles expunged messages better. Previously mutt's state was only
authorThomas Roessler <roessler@does-not-exist.org>
Tue, 8 Aug 2000 18:17:27 +0000 (18:17 +0000)
committerThomas Roessler <roessler@does-not-exist.org>
Tue, 8 Aug 2000 18:17:27 +0000 (18:17 +0000)
  updated when syncing the mailbox. This was the reason for Bob Bell's
  segfault when manipulating mailboxes with multiple simultaneous
  clients.
* makes a small adjustment for Sam's weird Courier server, which
  returns an OK FETCH completed response even when FETCH fails. I
  should probably report that behaviour to him as a bug, though.
* renames IMAP_REOPEN_PENDING to IMAP_EXPUNGE_PENDING
* gets rid of the _("Closing mailbox...") message, which was obscuring
  the status updates.
* clears some spurious mutt_clear_error calls in imap_cmd_finish.
* makes socket reads and writes check that they have an open
  connection. Shouldn't be necessary (and such calls are logged), but
  can happen currently.
* Some SASL vs regular authenticator tweaks in the imap Makefile.

(From Brendan Cully.)

imap/Makefile.am
imap/command.c
imap/imap.c
imap/imap_private.h
imap/message.c
init.c
mutt_socket.c
mx.c

index efb97def1bb4aee025ce22e395285fc2fc3a5ca3..9f4a3f386b8c736878c1b6e048518f79a5f3124e 100644 (file)
@@ -9,9 +9,9 @@ GSSSOURCES = auth_gss.c
 endif
 
 if USE_SASL
-SASLSOURCES = auth_sasl.c
+AUTHENTICATORS = auth_sasl.c $(GSSSOURCES)
 else
-CRAMSOURCES = auth_cram.c md5c.c
+AUTHENTICATORS = auth_anon.c auth_cram.c md5c.c $(GSSSOURCES)
 endif
 
 if USE_SSL
@@ -26,6 +26,6 @@ INCLUDES = -I$(top_srcdir) -I../intl
 noinst_LIBRARIES = libimap.a
 noinst_HEADERS = auth.h imap_private.h md5.h message.h $(SSLHEADERS)
 
-libimap_a_SOURCES = auth.c auth_anon.c auth_login.c browse.c \
-       command.c imap.c imap.h message.c utf7.c \
-       util.c $(GSSSOURCES) $(SASLSOURCES) $(CRAMSOURCES) $(SSLSOURCES)
+libimap_a_SOURCES = auth.c auth_login.c browse.c command.c imap.c imap.h \
+       message.c utf7.c util.c $(AUTHENTICATORS) $(SSLSOURCES)
+
index 8d6282963f5d24944138831f1c88a66b03550128..609f04e666640fd97031da4a0f541b82458d90e7 100644 (file)
@@ -85,7 +85,10 @@ int imap_cmd_resp (IMAP_DATA* idata)
     if ((c = mutt_socket_readln (idata->buf + len, idata->blen - len,
       idata->conn)) < 0)
     {
-      dprint (1, (debugfile, "imap_cmd_resp: Error while reading server response.\n"));
+      dprint (1, (debugfile, "imap_cmd_resp: Error while reading server response, closing connection.\n"));
+      mutt_socket_close (idata->conn);
+      idata->state = IMAP_DISCONNECTED;
+      idata->status = IMAP_FATAL;
       return IMAP_CMD_FAIL;
     }
 
@@ -136,12 +139,12 @@ void imap_cmd_finish (IMAP_DATA* idata)
   }
   
   if ((idata->status == IMAP_NEW_MAIL || 
-       (idata->reopen & (IMAP_REOPEN_PENDING|IMAP_NEWMAIL_PENDING)))
+       (idata->reopen & (IMAP_EXPUNGE_PENDING|IMAP_NEWMAIL_PENDING)))
       && (idata->reopen & IMAP_REOPEN_ALLOW))
   {
     int count = idata->newMailCount;
 
-    if (!(idata->reopen & IMAP_REOPEN_PENDING) &&
+    if (!(idata->reopen & IMAP_EXPUNGE_PENDING) &&
        ((idata->status == IMAP_NEW_MAIL) || (idata->reopen & IMAP_NEWMAIL_PENDING))  
        && count > idata->ctx->msgcount)
     {
@@ -156,7 +159,7 @@ void imap_cmd_finish (IMAP_DATA* idata)
     {
       imap_expunge_mailbox (idata);
       idata->check_status = IMAP_REOPENED;
-      idata->reopen &= ~(IMAP_REOPEN_PENDING|IMAP_NEWMAIL_PENDING);
+      idata->reopen &= ~(IMAP_EXPUNGE_PENDING|IMAP_NEWMAIL_PENDING);
     }
 
   }
@@ -252,7 +255,7 @@ int imap_handle_untagged (IMAP_DATA* idata, char* s)
       /* new mail arrived */
       count = atoi (pn);
 
-      if ( !(idata->reopen & IMAP_REOPEN_PENDING) &&
+      if ( !(idata->reopen & IMAP_EXPUNGE_PENDING) &&
           count < idata->ctx->msgcount)
       {
        /* something is wrong because the server reported fewer messages
@@ -270,7 +273,7 @@ int imap_handle_untagged (IMAP_DATA* idata, char* s)
           "imap_handle_untagged: superfluous EXISTS message.\n"));
       else
       {
-       if (!(idata->reopen & IMAP_REOPEN_PENDING))
+       if (!(idata->reopen & IMAP_EXPUNGE_PENDING))
         {
           dprint (2, (debugfile,
             "imap_handle_untagged: New mail in %s - %d messages total.\n",
@@ -378,7 +381,7 @@ static void cmd_parse_expunge (IMAP_DATA* idata, char* s)
       HEADER_DATA (h)->sid--;
   }
 
-  idata->reopen |= IMAP_REOPEN_PENDING;
+  idata->reopen |= IMAP_EXPUNGE_PENDING;
 }
 
 /* cmd_parse_myrights: set rights bits according to MYRIGHTS response */
index 102b9820feea63cc2ceb838dac332650c3f5c0ad..86ec6511364283f0e701bfb15604f960e997dea4 100644 (file)
@@ -196,8 +196,7 @@ int imap_read_literal (FILE* fp, IMAP_DATA* idata, long bytes)
 
 /* imap_expunge_mailbox: Purge IMAP portion of expunged messages from the
  *   context. Must not be done while something has a handle on any headers
- *   (eg inside pager or editor). mx_update_tables and mutt_sort_headers
- *   must be called afterwards. */
+ *   (eg inside pager or editor). That is, check IMAP_REOPEN_ALLOW. */
 void imap_expunge_mailbox (IMAP_DATA* idata)
 {
   HEADER* h;
@@ -225,6 +224,11 @@ void imap_expunge_mailbox (IMAP_DATA* idata)
       imap_free_header_data (&h->data);
     }
   }
+
+  /* We may be called on to expunge at any time. We can't rely on the caller
+   * to always know to rethread */
+  mx_update_tables (idata->ctx, 0);
+  mutt_sort_headers (idata->ctx, 1);
 }
 
 #if 0
@@ -1124,7 +1128,8 @@ int imap_sync_mailbox (CONTEXT* ctx, int expunge, int* index_hint)
       if (*flags && (imap_exec (idata, buf, 0) != 0) &&
         (err_continue != M_YES))
       {
-        err_continue = imap_continue ("imap_sync_mailbox: STORE failed", buf);
+        err_continue = imap_continue ("imap_sync_mailbox: STORE failed",
+          idata->buf);
         if (err_continue != M_YES)
           return -1;
       }
@@ -1141,7 +1146,7 @@ int imap_sync_mailbox (CONTEXT* ctx, int expunge, int* index_hint)
     mutt_message _("Expunging messages from server...");
     if (imap_exec (idata, "EXPUNGE", 0) != 0)
     {
-      imap_error ("imap_sync_mailbox: EXPUNGE failed", buf);
+      imap_error ("imap_sync_mailbox: EXPUNGE failed", idata->buf);
       return -1;
     }
   }
@@ -1164,12 +1169,8 @@ void imap_close_mailbox (CONTEXT* ctx)
 
   if ((idata->state == IMAP_SELECTED) && (ctx == idata->ctx))
   {
-    if (!(idata->noclose))
-    {
-      mutt_message _("Closing mailbox...");
-      if (imap_exec (idata, "CLOSE", 0) != 0)
-        imap_error ("CLOSE failed", idata->buf);
-    }
+    if (!(idata->noclose) && imap_exec (idata, "CLOSE", 0))
+      imap_error ("CLOSE failed", idata->buf);
     
     idata->state = IMAP_AUTHENTICATED;
     FREE (&(idata->mailbox));
index fe197a644f0e97dd3ad6f701350505aab86595f6..412e9521c5566e299e7c2cbfbeb1ff3ffa3cb7d4 100644 (file)
@@ -44,7 +44,7 @@
 #define SEQLEN 5
 
 #define IMAP_REOPEN_ALLOW    (1<<0)
-#define IMAP_REOPEN_PENDING  (1<<1)
+#define IMAP_EXPUNGE_PENDING  (1<<1)
 #define IMAP_NEWMAIL_PENDING (1<<2)
 
 /* imap_exec flags (see imap_exec) */
index a5e5fccd25add026d97afc3ccd7d5c0ce720065b..74c4da858f1fc25e1b9b93d46786ec334f1aa450 100644 (file)
@@ -199,6 +199,9 @@ int imap_fetch_message (MESSAGE *msg, CONTEXT *ctx, int msgno)
   int uid;
   int cacheno;
   IMAP_CACHE *cache;
+  /* Sam's weird courier server returns an OK response even when FETCH
+   * fails. Thanks Sam. */
+  short fetched = 0;
   int rc;
 
   idata = (IMAP_DATA*) ctx->data;
@@ -245,11 +248,12 @@ int imap_fetch_message (MESSAGE *msg, CONTEXT *ctx, int msgno)
   do
   {
     if ((rc = imap_cmd_resp (idata)) != IMAP_CMD_CONTINUE)
-      continue;
+      break;
 
     pc = idata->buf;
     pc = imap_next_word (pc);
     pc = imap_next_word (pc);
+
     if (!mutt_strncasecmp ("FETCH", pc, 5))
     {
       while (*pc)
@@ -278,6 +282,8 @@ int imap_fetch_message (MESSAGE *msg, CONTEXT *ctx, int msgno)
          if ((rc = imap_cmd_resp (idata)) != IMAP_CMD_CONTINUE)
            goto bail;
          pc = idata->buf;
+
+         fetched = 1;
        }
        /* UW-IMAP will provide a FLAGS update here if the FETCH causes a
         * change (eg from \Unseen to \Seen).
@@ -336,7 +342,7 @@ int imap_fetch_message (MESSAGE *msg, CONTEXT *ctx, int msgno)
   if (rc != IMAP_CMD_DONE)
     goto bail;
 
-  if (!imap_code (idata->buf))
+  if (!fetched || !imap_code (idata->buf))
     goto bail;
     
   /* Update the header information.  Previously, we only downloaded a
diff --git a/init.c b/init.c
index 533f8b71a6cab57f03d47c148195006890d3118a..7d26ea6c63f540bfd1033f4580a0765e953af688 100644 (file)
--- a/init.c
+++ b/init.c
@@ -1836,6 +1836,10 @@ void mutt_init (int skip_sys_rc, LIST *commands)
     set_option (OPTLOCALES);
 #endif
 
+  /* Unset suspend by default if we're the session leader */
+  if (getsid(0) == getpid())
+    unset_option (OPTSUSPEND);
+  
   mutt_init_history ();
 
   
index 1470450879c6b57bfbb5c48208de4d2af50df5bf..bc39fdf6d95f6fe5ed66b39e602031ab1feb1601 100644 (file)
@@ -63,6 +63,12 @@ int mutt_socket_write_d (CONNECTION *conn, const char *buf, int dbg)
 
   dprint (dbg, (debugfile,"> %s", buf));
 
+  if (conn->fd < 0)
+  {
+    dprint (1, (debugfile, "mutt_socket_write: attempt to write to closed connection\n"));
+    return -1;
+  }
+
   if ((rc = conn->write (conn, buf, mutt_strlen (buf))) < 0)
   {
     dprint (1, (debugfile, "mutt_socket_write: error writing, closing socket\n"));
@@ -79,7 +85,13 @@ int mutt_socket_readchar (CONNECTION *conn, char *c)
 {
   if (conn->bufpos >= conn->available)
   {
-    conn->available = conn->read (conn);
+    if (conn->fd >= 0)
+      conn->available = conn->read (conn);
+    else
+    {
+      dprint (1, (debugfile, "mutt_socket_readchar: attempt to read closed from connection.\n"));
+      return -1;
+    }
     conn->bufpos = 0;
     if (conn->available <= 0)
       return conn->available; /* returns 0 for EOF or -1 for other error */
@@ -98,9 +110,7 @@ int mutt_socket_readln_d (char* buf, size_t buflen, CONNECTION* conn, int dbg)
   {
     if (mutt_socket_readchar (conn, &ch) != 1)
     {
-      dprint (1, (debugfile, "mutt_socket_readln_d: read error, closing socket"));
       buf[i] = '\0';
-      mutt_socket_close (conn);
       return -1;
     }
     if (ch == '\n')
diff --git a/mx.c b/mx.c
index 4f50560df9225e2b72ddf65611c9f0267d83cb3e..8106137ba9c10b0b1d381ce3082b48438461a1ce 100644 (file)
--- a/mx.c
+++ b/mx.c
@@ -1118,15 +1118,13 @@ int mx_sync_mailbox (CONTEXT *ctx, int *index_hint)
     if (purge)
     {
 #ifdef USE_IMAP
-      /* IMAP uses the active flag, since deleted messages may remain after
-       * a sync */
-      if (ctx->magic == M_IMAP)
-       mx_update_tables (ctx, 0);
-      else
+      /* IMAP does this automatically after handling EXPUNGE */
+      if (ctx->magic != M_IMAP)
 #endif
+      {
        mx_update_tables (ctx, 1);
-
-      mutt_sort_headers (ctx, 1); /* rethread from scratch */
+       mutt_sort_headers (ctx, 1); /* rethread from scratch */
+      }
     }
   }