Mercurial > dovecot > core-2.2
changeset 21551:8351a4c497cc
lib-lda: Fix deliver_log_format variables with Sieve
With Sieve it was using src_mail for getting the values, which weren't
correct especially if Sieve had modified the mail.
author | Timo Sirainen <timo.sirainen@dovecot.fi> |
---|---|
date | Mon, 13 Feb 2017 20:47:51 +0200 |
parents | 0a4e672c70a1 |
children | f48743eb38c6 |
files | src/lda/main.c src/lib-lda/Makefile.am src/lib-lda/mail-deliver.c src/lib-lda/mail-deliver.h src/lmtp/main.c |
diffstat | 5 files changed, 101 insertions(+), 11 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lda/main.c Mon Feb 13 20:46:16 2017 +0200 +++ b/src/lda/main.c Mon Feb 13 20:47:51 2017 +0200 @@ -408,6 +408,7 @@ MAIL_STORAGE_SERVICE_FLAG_USE_SYSEXITS; storage_service = mail_storage_service_init(master_service, set_roots, service_flags); + mail_deliver_hooks_init(); /* set before looking up the user (or ideally we'd do this between _lookup() and _next(), but don't bother) */ ctx.delivery_time_started = ioloop_timeval;
--- a/src/lib-lda/Makefile.am Mon Feb 13 20:46:16 2017 +0200 +++ b/src/lib-lda/Makefile.am Mon Feb 13 20:47:51 2017 +0200 @@ -6,6 +6,7 @@ -I$(top_srcdir)/src/lib-master \ -I$(top_srcdir)/src/lib-dns \ -I$(top_srcdir)/src/lib-smtp \ + -I$(top_srcdir)/src/lib-index \ -I$(top_srcdir)/src/lib-imap \ -I$(top_srcdir)/src/lib-mail \ -I$(top_srcdir)/src/lib-storage
--- a/src/lib-lda/mail-deliver.c Mon Feb 13 20:46:16 2017 +0200 +++ b/src/lib-lda/mail-deliver.c Mon Feb 13 20:47:51 2017 +0200 @@ -12,9 +12,20 @@ #include "lda-settings.h" #include "mail-storage.h" #include "mail-namespace.h" +#include "mail-storage-private.h" #include "duplicate.h" #include "mail-deliver.h" +#define MAIL_DELIVER_USER_CONTEXT(obj) \ + MODULE_CONTEXT(obj, mail_deliver_user_module) +#define MAIL_DELIVER_STORAGE_CONTEXT(obj) \ + MODULE_CONTEXT(obj, mail_deliver_storage_module) + +struct mail_deliver_user { + union mail_user_module_context module_ctx; + struct mail_deliver_context *deliver_ctx; +}; + deliver_mail_func_t *deliver_mail = NULL; struct mail_deliver_cache { @@ -35,6 +46,10 @@ }; static enum mail_fetch_field lda_log_wanted_fetch_fields = MAIL_FETCH_PHYSICAL_SIZE | MAIL_FETCH_VIRTUAL_SIZE; +static MODULE_CONTEXT_DEFINE_INIT(mail_deliver_user_module, + &mail_user_module_register); +static MODULE_CONTEXT_DEFINE_INIT(mail_deliver_storage_module, + &mail_storage_module_register); const char *mail_deliver_get_address(struct mail *mail, const char *header) { @@ -61,9 +76,9 @@ } static void -mail_deliver_log_update_cache(struct mail_deliver_context *ctx) +mail_deliver_log_update_cache(struct mail_deliver_context *ctx, + struct mail *mail) { - struct mail *mail; const char *message_id = NULL, *subject = NULL, *from_envelope = NULL; const char *from; @@ -73,8 +88,6 @@ return; ctx->cache->filled = TRUE; - mail = ctx->dest_mail != NULL ? ctx->dest_mail : ctx->src_mail; - if (mail_get_first_header(mail, "Message-ID", &message_id) > 0) message_id = str_sanitize(message_id, 200); update_cache(ctx, &ctx->cache->message_id, message_id); @@ -100,9 +113,11 @@ mail_deliver_ctx_get_log_var_expand_table(struct mail_deliver_context *ctx, const char *message) { + struct mail *mail = ctx->dest_mail != NULL ? + ctx->dest_mail : ctx->src_mail; unsigned int delivery_time_msecs; - mail_deliver_log_update_cache(ctx); + mail_deliver_log_update_cache(ctx, mail); /* This call finishes a mail delivery. With Sieve there may be multiple mail deliveries. */ ctx->cache->filled = FALSE; @@ -360,10 +375,6 @@ if (mailbox_save_using_mail(&save_ctx, ctx->src_mail) < 0) ret = -1; - else { - /* fill the cache while we still have dest_mail */ - mail_deliver_log_update_cache(ctx); - } if (kw != NULL) mailbox_keywords_unref(&kw); @@ -436,8 +447,13 @@ int mail_deliver(struct mail_deliver_context *ctx, struct mail_storage **storage_r) { + struct mail_deliver_user *muser = + MAIL_DELIVER_USER_CONTEXT(ctx->dest_user); int ret; + i_assert(muser->deliver_ctx == NULL); + + muser->deliver_ctx = ctx; *storage_r = NULL; if (deliver_mail == NULL) ret = -1; @@ -452,22 +468,27 @@ ret = 0; } duplicate_deinit(&ctx->dup_ctx); - if (ret < 0 && mail_deliver_is_tempfailed(ctx, *storage_r)) + if (ret < 0 && mail_deliver_is_tempfailed(ctx, *storage_r)) { + muser->deliver_ctx = NULL; return -1; + } } if (ret < 0 && !ctx->tried_default_save) { /* plugins didn't handle this. save into the default mailbox. */ ret = mail_deliver_save(ctx, ctx->dest_mailbox_name, 0, NULL, storage_r); - if (ret < 0 && mail_deliver_is_tempfailed(ctx, *storage_r)) + if (ret < 0 && mail_deliver_is_tempfailed(ctx, *storage_r)) { + muser->deliver_ctx = NULL; return -1; + } } if (ret < 0 && strcasecmp(ctx->dest_mailbox_name, "INBOX") != 0) { /* still didn't work. try once more to save it to INBOX. */ ret = mail_deliver_save(ctx, "INBOX", 0, NULL, storage_r); } + muser->deliver_ctx = NULL; return ret; } @@ -478,3 +499,65 @@ deliver_mail = new_hook; return old_hook; } + +static int mail_deliver_save_finish(struct mail_save_context *ctx) +{ + struct mailbox *box = ctx->transaction->box; + union mailbox_module_context *mbox = MAIL_DELIVER_STORAGE_CONTEXT(box); + struct mail_deliver_user *muser = + MAIL_DELIVER_USER_CONTEXT(box->storage->user); + + if (mbox->super.save_finish(ctx) < 0) + return -1; + + /* initialize most of the fields from dest_mail */ + mail_deliver_log_update_cache(muser->deliver_ctx, ctx->dest_mail); + return 0; +} + +static int mail_deliver_copy(struct mail_save_context *ctx, struct mail *mail) +{ + struct mailbox *box = ctx->transaction->box; + union mailbox_module_context *mbox = MAIL_DELIVER_STORAGE_CONTEXT(box); + struct mail_deliver_user *muser = + MAIL_DELIVER_USER_CONTEXT(box->storage->user); + + if (mbox->super.copy(ctx, mail) < 0) + return -1; + + /* initialize most of the fields from dest_mail */ + mail_deliver_log_update_cache(muser->deliver_ctx, ctx->dest_mail); + return 0; +} + +static void mail_deliver_mail_user_created(struct mail_user *user) +{ + struct mail_deliver_user *muser; + + muser = p_new(user->pool, struct mail_deliver_user, 1); + MODULE_CONTEXT_SET(user, mail_deliver_user_module, muser); +} + +static void mail_deliver_mailbox_allocated(struct mailbox *box) +{ + struct mailbox_vfuncs *v = box->vlast; + union mailbox_module_context *mbox; + + mbox = p_new(box->pool, union mailbox_module_context, 1); + mbox->super = *v; + box->vlast = &mbox->super; + v->save_finish = mail_deliver_save_finish; + v->copy = mail_deliver_copy; + + MODULE_CONTEXT_SET_SELF(box, mail_deliver_storage_module, mbox); + } + +static struct mail_storage_hooks mail_deliver_hooks = { + .mail_user_created = mail_deliver_mail_user_created, + .mailbox_allocated = mail_deliver_mailbox_allocated +}; + +void mail_deliver_hooks_init(void) +{ + mail_storage_hooks_add_internal(&mail_deliver_hooks); +}
--- a/src/lib-lda/mail-deliver.h Mon Feb 13 20:46:16 2017 +0200 +++ b/src/lib-lda/mail-deliver.h Mon Feb 13 20:47:51 2017 +0200 @@ -113,4 +113,7 @@ which the new_hook should call if it's non-NULL. */ deliver_mail_func_t *mail_deliver_hook_set(deliver_mail_func_t *new_hook); +/* Must be called before any storage is created. */ +void mail_deliver_hooks_init(void); + #endif
--- a/src/lmtp/main.c Mon Feb 13 20:46:16 2017 +0200 +++ b/src/lmtp/main.c Mon Feb 13 20:47:51 2017 +0200 @@ -11,6 +11,7 @@ #include "master-service.h" #include "master-service-settings.h" #include "master-interface.h" +#include "mail-deliver.h" #include "mail-storage-service.h" #include "lda-settings.h" #include "lmtp-settings.h" @@ -63,6 +64,7 @@ (void)client_create(STDIN_FILENO, STDOUT_FILENO, &conn); } dns_client_socket_path = t_abspath(DNS_CLIENT_SOCKET_PATH); + mail_deliver_hooks_init(); } static void main_deinit(void)