bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2005-2018 Dovecot authors, see the included COPYING file */
79c7e806276f4eab6a48ec5dcd5e7c1378aae246Aki Tuomi MODULE_CONTEXT_REQUIRE(obj, mail_deliver_user_module)
79c7e806276f4eab6a48ec5dcd5e7c1378aae246Aki Tuomi MODULE_CONTEXT_REQUIRE(obj, mail_deliver_storage_module)
87dae9ffcd43023361019ca803709dbf5b8119bcTimo Sirainen union mailbox_transaction_module_context module_ctx;
291f1e54dcb8c7f38e5b78afc1eaf518e3756692Timo Sirainenstatic const char *lda_log_wanted_headers[] = {
291f1e54dcb8c7f38e5b78afc1eaf518e3756692Timo Sirainenstatic enum mail_fetch_field lda_log_wanted_fetch_fields =
291f1e54dcb8c7f38e5b78afc1eaf518e3756692Timo Sirainen MAIL_FETCH_PHYSICAL_SIZE | MAIL_FETCH_VIRTUAL_SIZE;
eed56fe22f1fc61f2003d5e66373d03dacbc9aaaTimo Sirainenstatic MODULE_CONTEXT_DEFINE_INIT(mail_deliver_user_module,
eed56fe22f1fc61f2003d5e66373d03dacbc9aaaTimo Sirainenstatic MODULE_CONTEXT_DEFINE_INIT(mail_deliver_storage_module,
3d7828efd92ecc0d08049f727d9be0154d1d681bStephan Boschmail_deliver_get_address(struct mail *mail, const char *header)
16d8197506b63d2ca7e38447df9faf1612c1f288Timo Sirainen if (mail_get_first_header(mail, header, &str) <= 0)
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen addr = message_address_parse(pool_datastack_create(),
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen (const unsigned char *)str,
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen return addr == NULL || addr->mailbox == NULL || addr->domain == NULL ||
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen *addr->mailbox == '\0' || *addr->domain == '\0' ?
3d7828efd92ecc0d08049f727d9be0154d1d681bStephan Bosch NULL : smtp_address_create_from_msg_temp(addr);
d609c2ffca2b61556980b46e1de2303c662ad0f7Timo Sirainenstatic void update_cache(pool_t pool, const char **old_str, const char *new_str)
12e28ffc2655b6d0efce628eb7d93fa74fbd345bTimo Sirainen else if (*old_str == NULL || strcmp(*old_str, new_str) != 0)
d609c2ffca2b61556980b46e1de2303c662ad0f7Timo Sirainenmail_deliver_log_update_cache(struct mail_deliver_cache *cache, pool_t pool,
12e28ffc2655b6d0efce628eb7d93fa74fbd345bTimo Sirainen const char *message_id = NULL, *subject = NULL, *from_envelope = NULL;
12e28ffc2655b6d0efce628eb7d93fa74fbd345bTimo Sirainen if (mail_get_first_header(mail, "Message-ID", &message_id) > 0)
d609c2ffca2b61556980b46e1de2303c662ad0f7Timo Sirainen update_cache(pool, &cache->message_id, message_id);
acfda38b75d0f0e899ef692fef01593bd56ed85eTimo Sirainen if (mail_get_first_header_utf8(mail, "Subject", &subject) > 0)
3d7828efd92ecc0d08049f727d9be0154d1d681bStephan Bosch from = smtp_address_encode(mail_deliver_get_address(mail, "From"));
acfda38b75d0f0e899ef692fef01593bd56ed85eTimo Sirainen if (mail_get_special(mail, MAIL_FETCH_FROM_ENVELOPE, &from_envelope) > 0)
acfda38b75d0f0e899ef692fef01593bd56ed85eTimo Sirainen from_envelope = str_sanitize(from_envelope, 80);
d609c2ffca2b61556980b46e1de2303c662ad0f7Timo Sirainen update_cache(pool, &cache->from_envelope, from_envelope);
d609c2ffca2b61556980b46e1de2303c662ad0f7Timo Sirainen if (mail_get_physical_size(mail, &cache->psize) < 0)
d609c2ffca2b61556980b46e1de2303c662ad0f7Timo Sirainen if (mail_get_virtual_size(mail, &cache->vsize) < 0)
6b6011c2242e470b41316f92512b282b5e306dacTimo Sirainenmail_deliver_ctx_get_log_var_expand_table(struct mail_deliver_context *ctx,
2a494f93f48424d391552a419ad8872fbc771eb5Timo Sirainen /* If a mail was saved/copied, the cache is already filled and the
2a494f93f48424d391552a419ad8872fbc771eb5Timo Sirainen following call is ignored. Otherwise, only the source mail exists. */
d609c2ffca2b61556980b46e1de2303c662ad0f7Timo Sirainen ctx->cache = p_new(ctx->pool, struct mail_deliver_cache, 1);
d609c2ffca2b61556980b46e1de2303c662ad0f7Timo Sirainen mail_deliver_log_update_cache(ctx->cache, ctx->pool, ctx->src_mail);
12e28ffc2655b6d0efce628eb7d93fa74fbd345bTimo Sirainen /* This call finishes a mail delivery. With Sieve there may be multiple
12e28ffc2655b6d0efce628eb7d93fa74fbd345bTimo Sirainen mail deliveries. */
12e28ffc2655b6d0efce628eb7d93fa74fbd345bTimo Sirainen delivery_time_msecs = timeval_diff_msecs(&ioloop_timeval,
12e28ffc2655b6d0efce628eb7d93fa74fbd345bTimo Sirainen ctx->cache->message_id : "unspecified", "msgid" },
12e28ffc2655b6d0efce628eb7d93fa74fbd345bTimo Sirainen { 'e', ctx->cache->from_envelope, "from_envelope" },
12e28ffc2655b6d0efce628eb7d93fa74fbd345bTimo Sirainen { '\0', dec2str(delivery_time_msecs), "delivery_time" },
12e28ffc2655b6d0efce628eb7d93fa74fbd345bTimo Sirainen { '\0', dec2str(ctx->session_time_msecs), "session_time" },
de0971aff3009fe6906c3631e8322908658a5e93Stephan Bosch { '\0', smtp_address_encode(ctx->rcpt_params.orcpt.addr), "to_envelope" },
12e28ffc2655b6d0efce628eb7d93fa74fbd345bTimo Sirainen { '\0', ctx->cache->storage_id, "storage_id" },
12e28ffc2655b6d0efce628eb7d93fa74fbd345bTimo Sirainen return p_memdup(unsafe_data_stack_pool, stack_tab, sizeof(stack_tab));
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainenvoid mail_deliver_log(struct mail_deliver_context *ctx, const char *fmt, ...)
12e28ffc2655b6d0efce628eb7d93fa74fbd345bTimo Sirainen tab = mail_deliver_ctx_get_log_var_expand_table(ctx, msg);
12e28ffc2655b6d0efce628eb7d93fa74fbd345bTimo Sirainen if (var_expand(str, ctx->set->deliver_log_format, tab, &error) <= 0) {
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen i_error("Failed to expand deliver_log_format=%s: %s",
44f3f472a49078312432b785fddcfe7b95928391Timo Sirainenstruct mail_deliver_session *mail_deliver_session_init(void)
44f3f472a49078312432b785fddcfe7b95928391Timo Sirainen pool = pool_alloconly_create("mail deliver session", 1024);
44f3f472a49078312432b785fddcfe7b95928391Timo Sirainen session = p_new(pool, struct mail_deliver_session, 1);
44f3f472a49078312432b785fddcfe7b95928391Timo Sirainenvoid mail_deliver_session_deinit(struct mail_deliver_session **_session)
44f3f472a49078312432b785fddcfe7b95928391Timo Sirainen struct mail_deliver_session *session = *_session;
f9db221d0793f05c4631885e71f98145428a7e1bTimo Sirainenint mail_deliver_save_open(struct mail_deliver_save_open_context *ctx,
258adfa09081ea8600a39759d486e678b5aa5f60Timo Sirainen enum mail_error *error_r, const char **error_str_r)
636f017be100bce67d66fd3ae1544a47681efd33Timo Sirainen *error_str_r = "Mailbox name not valid UTF-8";
fe6a2885e07818ae9145ab5dbfb36a9c1b6bd54aStephan Bosch *box_r = box = mailbox_alloc_delivery(ctx->user, name, flags);
bf7dc750b95039981c0e9d728f313d50cf38a156Martti Rannanjärvi *error_str_r = mailbox_get_last_internal_error(box, error_r);
44f3f472a49078312432b785fddcfe7b95928391Timo Sirainenstatic bool mail_deliver_check_duplicate(struct mail_deliver_session *session,
4dd0cbd517dc5d1210956a7c3e9e1ae714451dd8Timo Sirainen if (mailbox_get_metadata(box, MAILBOX_METADATA_GUID, &metadata) < 0) {
dbffb9e8b87b771851700a1acc353aa62b5ab7d7Timo Sirainen /* just play it safe and assume a duplicate */
44f3f472a49078312432b785fddcfe7b95928391Timo Sirainen /* there shouldn't be all that many recipients,
44f3f472a49078312432b785fddcfe7b95928391Timo Sirainen so just do a linear search */
dbffb9e8b87b771851700a1acc353aa62b5ab7d7Timo Sirainen p_array_init(&session->inbox_guids, session->pool, 8);
de62ce819d59a529530da4b57be1b8d6dad13d6bTimo Sirainen if (memcmp(metadata.guid, *guid, sizeof(metadata.guid)) == 0)
4dd0cbd517dc5d1210956a7c3e9e1ae714451dd8Timo Sirainen array_append(&session->inbox_guids, &metadata.guid, 1);
21fdf5394fbc307673b6c4b33f2497751a9ca1feTimo Sirainenvoid mail_deliver_deduplicate_guid_if_needed(struct mail_deliver_session *session,
21fdf5394fbc307673b6c4b33f2497751a9ca1feTimo Sirainen struct mailbox *box = mailbox_transaction_get_mailbox(trans);
21fdf5394fbc307673b6c4b33f2497751a9ca1feTimo Sirainen if (strcmp(mailbox_get_name(box), "INBOX") != 0)
44f3f472a49078312432b785fddcfe7b95928391Timo Sirainen /* avoid storing duplicate GUIDs to delivered mails to INBOX. this
44f3f472a49078312432b785fddcfe7b95928391Timo Sirainen happens if mail is delivered to same user multiple times within a
44f3f472a49078312432b785fddcfe7b95928391Timo Sirainen session. the problem with this is that if GUIDs are used as POP3
44f3f472a49078312432b785fddcfe7b95928391Timo Sirainen UIDLs, some clients can't handle the duplicates well. */
dbffb9e8b87b771851700a1acc353aa62b5ab7d7Timo Sirainen if (mail_deliver_check_duplicate(session, box)) {
de62ce819d59a529530da4b57be1b8d6dad13d6bTimo Sirainen mailbox_save_set_guid(save_ctx, guid_128_to_string(guid));
6f3244c59907273651b775d7fa00c8e3166a96c2Timo Sirainenstatic struct mail *
a9791113953195d1ed52d9b5bf63f1869758742dTimo Sirainenmail_deliver_open_mail(struct mailbox *box, uint32_t uid,
6f3244c59907273651b775d7fa00c8e3166a96c2Timo Sirainen if (mailbox_sync(box, MAILBOX_SYNC_FLAG_FAST) < 0)
0dab9cb35a976c49b28a11e28d5570f5191f1a7aMartti Rannanjärvi t = mailbox_transaction_begin(box, 0, __func__);
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainenint mail_deliver_save(struct mail_deliver_context *ctx, const char *mailbox,
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen enum mail_flags flags, const char *const *keywords,
f9db221d0793f05c4631885e71f98145428a7e1bTimo Sirainen struct mail_deliver_save_open_context open_ctx;
291f1e54dcb8c7f38e5b78afc1eaf518e3756692Timo Sirainen struct mailbox_header_lookup_ctx *headers_ctx;
96308127e006bb3b1108093bcf4cc1fd9481cb7aTimo Sirainen struct mail_transaction_commit_changes changes;
a77f136d3603a36f6cdd2e3685a5b18dd3712d79Stephan Bosch default_save = strcmp(mailbox, ctx->rcpt_default_mailbox) == 0;
f9db221d0793f05c4631885e71f98145428a7e1bTimo Sirainen open_ctx.lda_mailbox_autocreate = ctx->set->lda_mailbox_autocreate;
f9db221d0793f05c4631885e71f98145428a7e1bTimo Sirainen open_ctx.lda_mailbox_autosubscribe = ctx->set->lda_mailbox_autosubscribe;
258adfa09081ea8600a39759d486e678b5aa5f60Timo Sirainen if (mail_deliver_save_open(&open_ctx, mailbox, &box,
2f0c5d4567351c0752ec9dd809c8f0cdfe7f0e73Timo Sirainen mail_deliver_log(ctx, "save failed to open mailbox %s: %s",
2ef5254ab6b446b93ce7733bc96eeefa6f731ee4Timo Sirainen trans_flags = MAILBOX_TRANSACTION_FLAG_EXTERNAL;
2ef5254ab6b446b93ce7733bc96eeefa6f731ee4Timo Sirainen trans_flags |= MAILBOX_TRANSACTION_FLAG_ASSIGN_UIDS;
0dab9cb35a976c49b28a11e28d5570f5191f1a7aMartti Rannanjärvi t = mailbox_transaction_begin(box, trans_flags, __func__);
291f1e54dcb8c7f38e5b78afc1eaf518e3756692Timo Sirainen headers_ctx = mailbox_header_lookup_init(box, lda_log_wanted_headers);
04ca05320ecb84008aa1886e27020a4423b246c0Timo Sirainen dest_mail = mailbox_save_get_dest_mail(save_ctx);
04ca05320ecb84008aa1886e27020a4423b246c0Timo Sirainen mail_add_temp_wanted_fields(dest_mail, lda_log_wanted_fetch_fields, NULL);
21fdf5394fbc307673b6c4b33f2497751a9ca1feTimo Sirainen mail_deliver_deduplicate_guid_if_needed(ctx->session, save_ctx);
4f9b0e8c6ae16b23cfd33c0b762353442d7cfbc0Timo Sirainen if (mailbox_save_using_mail(&save_ctx, ctx->src_mail) < 0)
96308127e006bb3b1108093bcf4cc1fd9481cb7aTimo Sirainen ret = mailbox_transaction_commit_get_changes(&t, &changes);
9c550becf78b542a514fcf62ab7da0ff2a3d78f6Timo Sirainen /* copying needs the message body. with maildir we also
9c550becf78b542a514fcf62ab7da0ff2a3d78f6Timo Sirainen need to get the GUID in case the message gets
9562831b85e433ae92edd3ea42294578239eff98Timo Sirainen expunged. get these early so the copying won't fail
a9791113953195d1ed52d9b5bf63f1869758742dTimo Sirainen i_assert(array_count(&changes.saved_uids) == 1);
a9791113953195d1ed52d9b5bf63f1869758742dTimo Sirainen ctx->dest_mail = mail_deliver_open_mail(box, range->seq1,
6f3244c59907273651b775d7fa00c8e3166a96c2Timo Sirainen MAIL_FETCH_STREAM_BODY | MAIL_FETCH_GUID, &t);
9562831b85e433ae92edd3ea42294578239eff98Timo Sirainen } else if (mail_get_special(ctx->dest_mail, MAIL_FETCH_GUID, &guid) < 0) {
85b6e401b7461a833e94c1ab54161f8696e090b5Timo Sirainen mail_deliver_log(ctx, "saved mail to %s", mailbox_name);
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen mail_deliver_log(ctx, "save failed to %s: %s", mailbox_name,
bf7dc750b95039981c0e9d728f313d50cf38a156Martti Rannanjärvi mail_storage_get_last_internal_error(*storage_r, &error));
3d7828efd92ecc0d08049f727d9be0154d1d681bStephan Boschmail_deliver_get_return_address(struct mail_deliver_context *ctx)
3d7828efd92ecc0d08049f727d9be0154d1d681bStephan Bosch i_warning("Failed read return-path header: %s",
9d606eb5019bc237cf4add562d54e2345b756f50Stephan Bosch if (message_address_parse_path(pool_datastack_create(),
9d606eb5019bc237cf4add562d54e2345b756f50Stephan Bosch (const unsigned char *)path,
9d606eb5019bc237cf4add562d54e2345b756f50Stephan Bosch i_warning("Failed to parse return-path header");
9d606eb5019bc237cf4add562d54e2345b756f50Stephan Bosch return smtp_address_create_from_msg(ctx->pool, addr);
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainenconst char *mail_deliver_get_new_message_id(struct mail_deliver_context *ctx)
a9f821804fb50da03c454cd136ed9fe445a4d1d2Stephan Bosch const struct mail_storage_settings *mail_set =
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen return t_strdup_printf("<dovecot-%s-%s-%d@%s>",
b9dce659b9135c87c7708b2bb0f14e8742db7e15Timo Sirainenstatic bool mail_deliver_is_tempfailed(struct mail_deliver_context *ctx,
b9dce659b9135c87c7708b2bb0f14e8742db7e15Timo Sirainen (void)mail_storage_get_last_error(storage, &error);
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainenint mail_deliver(struct mail_deliver_context *ctx,
b3523787a7c3b9e82fd9dfe9d1b4687a3b0000b0Timo Sirainen var_has_key(ctx->set->deliver_log_format, '\0', "storage_id");
a77f136d3603a36f6cdd2e3685a5b18dd3712d79Stephan Bosch ctx->dup_db = mail_duplicate_db_init(ctx->rcpt_user,
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen /* if message was saved, don't bounce it even though
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen the script failed later. */
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen /* success. message may or may not have been saved. */
eed56fe22f1fc61f2003d5e66373d03dacbc9aaaTimo Sirainen if (ret < 0 && mail_deliver_is_tempfailed(ctx, *storage_r)) {
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen /* plugins didn't handle this. save into the default mailbox. */
a77f136d3603a36f6cdd2e3685a5b18dd3712d79Stephan Bosch ret = mail_deliver_save(ctx, ctx->rcpt_default_mailbox, 0, NULL,
eed56fe22f1fc61f2003d5e66373d03dacbc9aaaTimo Sirainen if (ret < 0 && mail_deliver_is_tempfailed(ctx, *storage_r)) {
a77f136d3603a36f6cdd2e3685a5b18dd3712d79Stephan Bosch if (ret < 0 && strcasecmp(ctx->rcpt_default_mailbox, "INBOX") != 0) {
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen /* still didn't work. try once more to save it
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen ret = mail_deliver_save(ctx, "INBOX", 0, NULL, storage_r);
92e6bb6497f8c9d57bff334a5c9f31bc2f040394Timo Sirainendeliver_mail_func_t *mail_deliver_hook_set(deliver_mail_func_t *new_hook)
eed56fe22f1fc61f2003d5e66373d03dacbc9aaaTimo Sirainenstatic int mail_deliver_save_finish(struct mail_save_context *ctx)
2e35ede0f3afa8b4528cc530a6efba239d77a022Timo Sirainen struct mail_deliver_mailbox *mbox = MAIL_DELIVER_STORAGE_CONTEXT(box);
eed56fe22f1fc61f2003d5e66373d03dacbc9aaaTimo Sirainen MAIL_DELIVER_USER_CONTEXT(box->storage->user);
87dae9ffcd43023361019ca803709dbf5b8119bcTimo Sirainen MAIL_DELIVER_STORAGE_CONTEXT(ctx->transaction);
2e35ede0f3afa8b4528cc530a6efba239d77a022Timo Sirainen if (mbox->module_ctx.super.save_finish(ctx) < 0)
eed56fe22f1fc61f2003d5e66373d03dacbc9aaaTimo Sirainen /* initialize most of the fields from dest_mail */
87dae9ffcd43023361019ca803709dbf5b8119bcTimo Sirainen mail_deliver_log_update_cache(&dt->cache, muser->deliver_ctx->pool,
eed56fe22f1fc61f2003d5e66373d03dacbc9aaaTimo Sirainenstatic int mail_deliver_copy(struct mail_save_context *ctx, struct mail *mail)
2e35ede0f3afa8b4528cc530a6efba239d77a022Timo Sirainen struct mail_deliver_mailbox *mbox = MAIL_DELIVER_STORAGE_CONTEXT(box);
eed56fe22f1fc61f2003d5e66373d03dacbc9aaaTimo Sirainen MAIL_DELIVER_USER_CONTEXT(box->storage->user);
87dae9ffcd43023361019ca803709dbf5b8119bcTimo Sirainen MAIL_DELIVER_STORAGE_CONTEXT(ctx->transaction);
2e35ede0f3afa8b4528cc530a6efba239d77a022Timo Sirainen if (mbox->module_ctx.super.copy(ctx, mail) < 0)
eed56fe22f1fc61f2003d5e66373d03dacbc9aaaTimo Sirainen /* initialize most of the fields from dest_mail */
87dae9ffcd43023361019ca803709dbf5b8119bcTimo Sirainen mail_deliver_log_update_cache(&dt->cache, muser->deliver_ctx->pool,
b3523787a7c3b9e82fd9dfe9d1b4687a3b0000b0Timo Sirainenmail_deliver_cache_update_post_commit(struct mailbox *orig_box, uint32_t uid)
b3523787a7c3b9e82fd9dfe9d1b4687a3b0000b0Timo Sirainen MAIL_DELIVER_USER_CONTEXT(orig_box->storage->user);
b3523787a7c3b9e82fd9dfe9d1b4687a3b0000b0Timo Sirainen /* getting storage_id requires a whole new mailbox view that is
b3523787a7c3b9e82fd9dfe9d1b4687a3b0000b0Timo Sirainen synced, so it'll contain the newly written mail. this is racy, so
b3523787a7c3b9e82fd9dfe9d1b4687a3b0000b0Timo Sirainen it's possible another process has already deleted the mail. */
b3523787a7c3b9e82fd9dfe9d1b4687a3b0000b0Timo Sirainen box = mailbox_alloc(orig_box->list, orig_box->vname, 0);
61cf001f1944d92eb25f113ba4c08985d6e30d53Timo Sirainen mailbox_set_reason(box, "lib-lda storage-id");
b3523787a7c3b9e82fd9dfe9d1b4687a3b0000b0Timo Sirainen mail = mail_deliver_open_mail(box, uid, MAIL_FETCH_STORAGE_ID, &t);
b3523787a7c3b9e82fd9dfe9d1b4687a3b0000b0Timo Sirainen if (mail_get_special(mail, MAIL_FETCH_STORAGE_ID, &storage_id) < 0 ||
b3523787a7c3b9e82fd9dfe9d1b4687a3b0000b0Timo Sirainen p_strdup(muser->deliver_ctx->pool, storage_id);
87dae9ffcd43023361019ca803709dbf5b8119bcTimo Sirainenmail_deliver_transaction_begin(struct mailbox *box,
87dae9ffcd43023361019ca803709dbf5b8119bcTimo Sirainen struct mail_deliver_mailbox *mbox = MAIL_DELIVER_STORAGE_CONTEXT(box);
87dae9ffcd43023361019ca803709dbf5b8119bcTimo Sirainen MAIL_DELIVER_USER_CONTEXT(box->storage->user);
c6ce2e251ac75fa650c7fbfa52150eae69386293Martti Rannanjärvi t = mbox->module_ctx.super.transaction_begin(box, flags, reason);
87dae9ffcd43023361019ca803709dbf5b8119bcTimo Sirainen dt = p_new(muser->deliver_ctx->pool, struct mail_deliver_transaction, 1);
87dae9ffcd43023361019ca803709dbf5b8119bcTimo Sirainen MODULE_CONTEXT_SET(t, mail_deliver_storage_module, dt);
b3523787a7c3b9e82fd9dfe9d1b4687a3b0000b0Timo Sirainenmail_deliver_transaction_commit(struct mailbox_transaction_context *ctx,
b3523787a7c3b9e82fd9dfe9d1b4687a3b0000b0Timo Sirainen struct mail_transaction_commit_changes *changes_r)
87dae9ffcd43023361019ca803709dbf5b8119bcTimo Sirainen struct mail_deliver_mailbox *mbox = MAIL_DELIVER_STORAGE_CONTEXT(box);
87dae9ffcd43023361019ca803709dbf5b8119bcTimo Sirainen struct mail_deliver_transaction *dt = MAIL_DELIVER_STORAGE_CONTEXT(ctx);
87dae9ffcd43023361019ca803709dbf5b8119bcTimo Sirainen MAIL_DELIVER_USER_CONTEXT(box->storage->user);
87dae9ffcd43023361019ca803709dbf5b8119bcTimo Sirainen /* sieve creates multiple transactions, saves the mails and
87dae9ffcd43023361019ca803709dbf5b8119bcTimo Sirainen then commits all of them at the end. we'll need to keep
87dae9ffcd43023361019ca803709dbf5b8119bcTimo Sirainen switching the deliver_ctx->cache for each commit.
87dae9ffcd43023361019ca803709dbf5b8119bcTimo Sirainen we also want to do this only for commits generated by sieve.
87dae9ffcd43023361019ca803709dbf5b8119bcTimo Sirainen other plugins or storage backends may be creating transactions as
87dae9ffcd43023361019ca803709dbf5b8119bcTimo Sirainen well, which we need to ignore. */
fe6a2885e07818ae9145ab5dbfb36a9c1b6bd54aStephan Bosch if ((box->flags & MAILBOX_FLAG_POST_SESSION) != 0)
87dae9ffcd43023361019ca803709dbf5b8119bcTimo Sirainen if (mbox->module_ctx.super.transaction_commit(ctx, changes_r) < 0)
b3523787a7c3b9e82fd9dfe9d1b4687a3b0000b0Timo Sirainen if (array_count(&changes_r->saved_uids) > 0) {
b3523787a7c3b9e82fd9dfe9d1b4687a3b0000b0Timo Sirainen mail_deliver_cache_update_post_commit(box, range->seq1);
eed56fe22f1fc61f2003d5e66373d03dacbc9aaaTimo Sirainenstatic void mail_deliver_mail_user_created(struct mail_user *user)
eed56fe22f1fc61f2003d5e66373d03dacbc9aaaTimo Sirainen muser = p_new(user->pool, struct mail_deliver_user, 1);
eed56fe22f1fc61f2003d5e66373d03dacbc9aaaTimo Sirainen MODULE_CONTEXT_SET(user, mail_deliver_user_module, muser);
eed56fe22f1fc61f2003d5e66373d03dacbc9aaaTimo Sirainenstatic void mail_deliver_mailbox_allocated(struct mailbox *box)
23070cb7c58e32af755dae0426493608a28a4209Aki Tuomi /* we are doing something other than lda/lmtp delivery
23070cb7c58e32af755dae0426493608a28a4209Aki Tuomi and should not be involved */
fe6a2885e07818ae9145ab5dbfb36a9c1b6bd54aStephan Bosch if ((box->flags & MAILBOX_FLAG_POST_SESSION) != 0)
2e35ede0f3afa8b4528cc530a6efba239d77a022Timo Sirainen mbox = p_new(box->pool, struct mail_deliver_mailbox, 1);
87dae9ffcd43023361019ca803709dbf5b8119bcTimo Sirainen v->transaction_begin = mail_deliver_transaction_begin;
b3523787a7c3b9e82fd9dfe9d1b4687a3b0000b0Timo Sirainen v->transaction_commit = mail_deliver_transaction_commit;
2e35ede0f3afa8b4528cc530a6efba239d77a022Timo Sirainen MODULE_CONTEXT_SET(box, mail_deliver_storage_module, mbox);
eed56fe22f1fc61f2003d5e66373d03dacbc9aaaTimo Sirainenstatic struct mail_storage_hooks mail_deliver_hooks = {
eed56fe22f1fc61f2003d5e66373d03dacbc9aaaTimo Sirainen .mail_user_created = mail_deliver_mail_user_created,
eed56fe22f1fc61f2003d5e66373d03dacbc9aaaTimo Sirainen .mailbox_allocated = mail_deliver_mailbox_allocated