]> granicus.if.org Git - mutt/commitdiff
Fix imap expunge to match msn and fix index. (see #3942)
authorKevin McCarthy <kevin@8t8.us>
Sun, 21 May 2017 01:52:13 +0000 (18:52 -0700)
committerKevin McCarthy <kevin@8t8.us>
Sun, 21 May 2017 01:52:13 +0000 (18:52 -0700)
The expunge needs to match against the MSN now.  Since
cmd_parse_expunge() does not automatically fix h->index anymore,
change imap_expunge_mailbox() to fix up the h->index values.

imap/command.c
imap/imap.c

index 6d267463c876f1905d49795c50e019c92f830069..249326c1ec1480c8cacb8bf71199c2c1424a7312 100644 (file)
@@ -589,12 +589,13 @@ static void cmd_parse_capability (IMAP_DATA* idata, char* s)
  *   be reopened at our earliest convenience */
 static void cmd_parse_expunge (IMAP_DATA* idata, const char* s)
 {
-  int expno, cur;
+  unsigned int exp_msn;
+  int cur;
   HEADER* h;
 
   dprint (2, (debugfile, "Handling EXPUNGE\n"));
 
-  expno = atoi (s);
+  exp_msn = atoi (s);
 
   /* walk headers, zero seqno of expunged message, decrement seqno of those
    * above. Possibly we could avoid walking the whole list by resorting
@@ -604,10 +605,16 @@ static void cmd_parse_expunge (IMAP_DATA* idata, const char* s)
   {
     h = idata->ctx->hdrs[cur];
 
-    if (h->index+1 == expno)
-      h->index = -1;
-    else if (h->index+1 > expno)
-      h->index--;
+    if (HEADER_DATA(h)->msn == exp_msn)
+    {
+      /* imap_expunge_mailbox() will rewrite h->index.
+       * It needs to resort using SORT_ORDER anyway, so setting to INT_MAX
+       * makes the code simpler and possibly more efficient. */
+      h->index = INT_MAX;
+      HEADER_DATA(h)->msn = 0;
+    }
+    else if (HEADER_DATA(h)->msn > exp_msn)
+      HEADER_DATA(h)->msn--;
   }
 
   idata->reopen |= IMAP_EXPUNGE_PENDING;
index f45a516e3642a9a1c7f952fd778630983d5b7686..30001030453dd26c832a4c9e45853e3668d34989 100644 (file)
@@ -250,16 +250,21 @@ void imap_expunge_mailbox (IMAP_DATA* idata)
 {
   HEADER* h;
   int i, cacheno;
+  short old_sort;
 
 #ifdef USE_HCACHE
   idata->hcache = imap_hcache_open (idata, NULL);
 #endif
 
+  old_sort = Sort;
+  Sort = SORT_ORDER;
+  mutt_sort_headers (idata->ctx, 0);
+
   for (i = 0; i < idata->ctx->msgcount; i++)
   {
     h = idata->ctx->hdrs[i];
 
-    if (h->index == -1)
+    if (h->index == INT_MAX)
     {
       dprint (2, (debugfile, "Expunging message UID %d.\n", HEADER_DATA (h)->uid));
 
@@ -284,6 +289,8 @@ void imap_expunge_mailbox (IMAP_DATA* idata)
 
       imap_free_header_data ((IMAP_HEADER_DATA**)&h->data);
     }
+    else
+      h->index = i;
   }
 
 #if USE_HCACHE
@@ -293,6 +300,7 @@ void imap_expunge_mailbox (IMAP_DATA* idata)
   /* 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);
+  Sort = old_sort;
   mutt_sort_headers (idata->ctx, 1);
 }