From: Stephan Bosch Date: Tue, 13 Nov 2018 21:24:10 +0000 (+0100) Subject: lib-storage: Add support for replacing mail using mailbox_save_begin_replace() X-Git-Tag: 2.4.1~128 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f3936059b0170229cc9315c0c1c9f28259d89075;p=thirdparty%2Fdovecot%2Fcore.git lib-storage: Add support for replacing mail using mailbox_save_begin_replace() The indicated expunged mail is expunged once saving the new mail finishes successfully. The expunged mail is available in the mailbox save context for plugins (like quota) that need to be able to obtain information about the mail being replaced. The source mail for mailbox_move() is also recorded in the context as such. This way, quota handling can be implemented identically for moving and replacing a message. --- diff --git a/src/lib-storage/mail-storage-private.h b/src/lib-storage/mail-storage-private.h index 6732bd80e4..f93f9204c8 100644 --- a/src/lib-storage/mail-storage-private.h +++ b/src/lib-storage/mail-storage-private.h @@ -742,6 +742,11 @@ struct mail_save_context { implemented via save, and the save_*() methods want to access the source mail. */ struct mail *copy_src_mail; + /* Set during mailbox_move() and mailbox_save_begin_replace(). This + is made available for the quota plugin to allow accounting for the + size of the mail that is being expunged as part of the MOVE and + REPLACE commands, respectively. */ + struct mail *expunged_mail; /* data that changes for each saved mail */ struct mail_save_data data; diff --git a/src/lib-storage/mail-storage.c b/src/lib-storage/mail-storage.c index e126b33663..fdae32c0e3 100644 --- a/src/lib-storage/mail-storage.c +++ b/src/lib-storage/mail-storage.c @@ -3005,6 +3005,14 @@ int mailbox_save_begin(struct mail_save_context **ctx, struct istream *input) return 0; } +int mailbox_save_begin_replace(struct mail_save_context **ctx, + struct istream *input, + struct mail *replaced) +{ + (*ctx)->expunged_mail = replaced; + return mailbox_save_begin(ctx, input); +} + int mailbox_save_continue(struct mail_save_context *ctx) { int ret; @@ -3079,6 +3087,8 @@ int mailbox_save_finish(struct mail_save_context **_ctx) if (pvt_flags != 0) mailbox_save_add_pvt_flags(t, pvt_flags); t->save_count++; + if (ctx->expunged_mail != NULL) + mail_expunge(ctx->expunged_mail); } mailbox_save_context_reset(ctx, TRUE); @@ -3178,6 +3188,7 @@ int mailbox_move(struct mail_save_context **_ctx, struct mail *mail) i_assert(!ctx->moving); ctx->moving = TRUE; + ctx->expunged_mail = mail; T_BEGIN { if ((ret = mailbox_copy_int(_ctx, mail)) == 0) mail_expunge(mail); diff --git a/src/lib-storage/mail-storage.h b/src/lib-storage/mail-storage.h index ed5d80e6b9..b821ef5502 100644 --- a/src/lib-storage/mail-storage.h +++ b/src/lib-storage/mail-storage.h @@ -875,6 +875,13 @@ struct mail *mailbox_save_get_dest_mail(struct mail_save_context *ctx); i_stream_read() and calling mailbox_save_continue() as long as there's more input. */ int mailbox_save_begin(struct mail_save_context **ctx, struct istream *input); +/* Begin saving the message that replaces the provided mail (which may reside + in another mailbox altogether). The replaced mail is expunged implicitly + when saving the message succeeds at mailbox_save_finish(). In all other + respects this function behaves the same as mailbox_save_begin(). */ +int mailbox_save_begin_replace(struct mail_save_context **ctx, + struct istream *input, + struct mail *replaced); int mailbox_save_continue(struct mail_save_context *ctx); int mailbox_save_finish(struct mail_save_context **ctx); void mailbox_save_cancel(struct mail_save_context **ctx);