@@ 829,7 829,21 @@ static int trash_append (CONTEXT *ctx)
return 0;
}
-/* save changes and close mailbox */
+/* save changes and close mailbox.
+ *
+ * returns 0 on success.
+ * -1 on error
+ * one of the check_mailbox enums if aborted for one of those reasons.
+ *
+ * Note: it's very important to ensure the mailbox is properly closed
+ * before free'ing the context. For selected mailboxes, IMAP
+ * will cache the context inside connection->idata until
+ * imap_close_mailbox() removes it.
+ *
+ * Readonly, dontwrite, and append mailboxes are guaranteed to call
+ * mx_fastclose_mailbox(), so for most of Mutt's code you won't see
+ * return value checks for temporary contexts.
+ */
int mx_close_mailbox (CONTEXT *ctx, int *index_hint)
{
int i, move_messages = 0, purge = 1, read_msgs = 0;
@@ 242,6 242,7 @@ int mutt_get_postponed (CONTEXT *ctx, HEADER *hdr, HEADER **cur, BUFFER *fcc)
LIST *next;
const char *p;
int opt_delete;
+ int close_rc;
if (!Postponed)
return (-1);
@@ 256,7 257,7 @@ int mutt_get_postponed (CONTEXT *ctx, HEADER *hdr, HEADER **cur, BUFFER *fcc)
if (! PostContext->msgcount)
{
PostCount = 0;
- mx_close_mailbox (PostContext, NULL);
+ mx_fastclose_mailbox (PostContext);
FREE (&PostContext);
mutt_error _("No postponed messages.");
return (-1);
@@ 269,7 270,13 @@ int mutt_get_postponed (CONTEXT *ctx, HEADER *hdr, HEADER **cur, BUFFER *fcc)
}
else if ((h = select_msg ()) == NULL)
{
- mx_close_mailbox (PostContext, NULL);
+ /* messages might have been marked for deletion.
+ * try once more on reopen before giving up. */
+ close_rc = mx_close_mailbox (PostContext, NULL);
+ if (close_rc > 0)
+ close_rc = mx_close_mailbox (PostContext, NULL);
+ if (close_rc != 0)
+ mx_fastclose_mailbox (PostContext);
FREE (&PostContext);
return (-1);
}
@@ 291,7 298,11 @@ int mutt_get_postponed (CONTEXT *ctx, HEADER *hdr, HEADER **cur, BUFFER *fcc)
/* avoid the "purge deleted messages" prompt */
opt_delete = quadoption (OPT_DELETE);
set_quadoption (OPT_DELETE, MUTT_YES);
- mx_close_mailbox (PostContext, NULL);
+ close_rc = mx_close_mailbox (PostContext, NULL);
+ if (close_rc > 0)
+ close_rc = mx_close_mailbox (PostContext, NULL);
+ if (close_rc != 0)
+ mx_fastclose_mailbox (PostContext);
set_quadoption (OPT_DELETE, opt_delete);
FREE (&PostContext);