From: Josef 'Jeff' Sipek Date: Tue, 4 Feb 2020 17:10:45 +0000 (-0500) Subject: imap: expunge: Collect all \Deleted mails' seqs and then expunge them X-Git-Tag: 2.3.10~33 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=81ddb0070028a6b6b8acab914b8e70c540bad2ea;p=thirdparty%2Fdovecot%2Fcore.git imap: expunge: Collect all \Deleted mails' seqs and then expunge them This makes the following commit much more understandable. --- diff --git a/src/imap/imap-expunge.c b/src/imap/imap-expunge.c index dde00ff59e..20b48b29c9 100644 --- a/src/imap/imap-expunge.c +++ b/src/imap/imap-expunge.c @@ -5,6 +5,44 @@ #include "mail-search-build.h" #include "imap-expunge.h" +/* get a seqset of all the mails with \Deleted */ +static int imap_expunge_get_seqset(struct mailbox *box, + struct mail_search_arg *next_search_arg, + ARRAY_TYPE(seq_range) *seqset) +{ + struct mailbox_transaction_context *t; + struct mail_search_args *search_args; + struct mail_search_context *ctx; + struct mail *mail; + int ret; + + search_args = mail_search_build_init(); + search_args->args = p_new(search_args->pool, struct mail_search_arg, 1); + search_args->args->type = SEARCH_FLAGS; + search_args->args->value.flags = MAIL_DELETED; + search_args->args->next = next_search_arg; + + /* Refresh the flags so we'll expunge all messages marked as \Deleted + by any session. */ + t = mailbox_transaction_begin(box, MAILBOX_TRANSACTION_FLAG_REFRESH, + "EXPUNGE"); + ctx = mailbox_search_init(t, search_args, NULL, 0, NULL); + + /* collect the seqs into a seqset */ + while (mailbox_search_next(ctx, &mail)) + seq_range_array_add(seqset, mail->seq); + + ret = mailbox_search_deinit(&ctx); + /* commit in case a plugin made changes - failures should not abort the expunge */ + (void) mailbox_transaction_commit(&t); + mail_search_args_unref(&search_args); + + if (ret < 0) + array_free(seqset); + + return ret; +} + int imap_expunge(struct mailbox *box, struct mail_search_arg *next_search_arg, unsigned int *expunged_count) { @@ -21,14 +59,16 @@ int imap_expunge(struct mailbox *box, struct mail_search_arg *next_search_arg, search_args = mail_search_build_init(); search_args->args = p_new(search_args->pool, struct mail_search_arg, 1); - search_args->args->type = SEARCH_FLAGS; - search_args->args->value.flags = MAIL_DELETED; - search_args->args->next = next_search_arg; + search_args->args->type = SEARCH_SEQSET; + p_array_init(&search_args->args->value.seqset, search_args->pool, 16); - /* Refresh the flags so we'll expunge all messages marked as \Deleted - by any session. */ - t = mailbox_transaction_begin(box, MAILBOX_TRANSACTION_FLAG_REFRESH, - "EXPUNGE"); + if (imap_expunge_get_seqset(box, next_search_arg, + &search_args->args->value.seqset) < 0) { + mail_search_args_unref(&search_args); + return -1; + } + + t = mailbox_transaction_begin(box, 0, "EXPUNGE"); ctx = mailbox_search_init(t, search_args, NULL, 0, NULL); mail_search_args_unref(&search_args);