mail-deliver.c revision 92e6bb6497f8c9d57bff334a5c9f31bc2f040394
e59faf65ce864fe95dc00f5d52b8323cdbd0608aTimo Sirainen/* Copyright (c) 2005-2010 Dovecot authors, see the included COPYING file */
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen#include "lib.h"
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen#include "ioloop.h"
96308127e006bb3b1108093bcf4cc1fd9481cb7aTimo Sirainen#include "array.h"
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen#include "str.h"
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen#include "str-sanitize.h"
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen#include "var-expand.h"
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen#include "message-address.h"
ed51404d355ae65d762cee68aefdbf900903a658Timo Sirainen#include "imap-utf7.h"
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen#include "lda-settings.h"
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen#include "mail-storage.h"
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen#include "mail-namespace.h"
4afaedfcbd43896befbe1fd5c10eba42246f3fdeTimo Sirainen#include "duplicate.h"
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen#include "mail-deliver.h"
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainendeliver_mail_func_t *deliver_mail = NULL;
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen
16d8197506b63d2ca7e38447df9faf1612c1f288Timo Sirainenconst char *mail_deliver_get_address(struct mail *mail, const char *header)
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen{
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen struct message_address *addr;
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen const char *str;
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen
16d8197506b63d2ca7e38447df9faf1612c1f288Timo Sirainen if (mail_get_first_header(mail, header, &str) <= 0)
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen return NULL;
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen addr = message_address_parse(pool_datastack_create(),
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen (const unsigned char *)str,
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen strlen(str), 1, FALSE);
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen return addr == NULL || addr->mailbox == NULL || addr->domain == NULL ||
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen *addr->mailbox == '\0' || *addr->domain == '\0' ?
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen NULL : t_strconcat(addr->mailbox, "@", addr->domain, NULL);
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen}
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen
16d8197506b63d2ca7e38447df9faf1612c1f288Timo Sirainenconst struct var_expand_table *
16d8197506b63d2ca7e38447df9faf1612c1f288Timo Sirainenmail_deliver_get_log_var_expand_table(struct mail *mail, const char *message)
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen{
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen static struct var_expand_table static_tab[] = {
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen { '$', NULL, NULL },
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen { 'm', NULL, "msgid" },
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen { 's', NULL, "subject" },
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen { 'f', NULL, "from" },
1695984ac979204fffb3458ae7f8499ad36339ccTimo Sirainen { 'p', NULL, "size" },
1695984ac979204fffb3458ae7f8499ad36339ccTimo Sirainen { 'w', NULL, "vsize" },
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen { '\0', NULL, NULL }
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen };
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen struct var_expand_table *tab;
1695984ac979204fffb3458ae7f8499ad36339ccTimo Sirainen uoff_t size;
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen tab = t_malloc(sizeof(static_tab));
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen memcpy(tab, static_tab, sizeof(static_tab));
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen tab[0].value = message;
16d8197506b63d2ca7e38447df9faf1612c1f288Timo Sirainen (void)mail_get_first_header(mail, "Message-ID", &tab[1].value);
16d8197506b63d2ca7e38447df9faf1612c1f288Timo Sirainen tab[1].value = tab[1].value == NULL ? "unspecified" :
16d8197506b63d2ca7e38447df9faf1612c1f288Timo Sirainen str_sanitize(tab[1].value, 200);
82727bef77e1e3abf7ae1b46290503b7899d8d92Timo Sirainen
16d8197506b63d2ca7e38447df9faf1612c1f288Timo Sirainen (void)mail_get_first_header_utf8(mail, "Subject", &tab[2].value);
82727bef77e1e3abf7ae1b46290503b7899d8d92Timo Sirainen tab[2].value = str_sanitize(tab[2].value, 80);
16d8197506b63d2ca7e38447df9faf1612c1f288Timo Sirainen tab[3].value = str_sanitize(mail_deliver_get_address(mail, "From"), 80);
82727bef77e1e3abf7ae1b46290503b7899d8d92Timo Sirainen
16d8197506b63d2ca7e38447df9faf1612c1f288Timo Sirainen if (mail_get_physical_size(mail, &size) == 0)
1695984ac979204fffb3458ae7f8499ad36339ccTimo Sirainen tab[4].value = dec2str(size);
16d8197506b63d2ca7e38447df9faf1612c1f288Timo Sirainen if (mail_get_virtual_size(mail, &size) == 0)
1695984ac979204fffb3458ae7f8499ad36339ccTimo Sirainen tab[5].value = dec2str(size);
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen return tab;
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen}
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainenvoid mail_deliver_log(struct mail_deliver_context *ctx, const char *fmt, ...)
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen{
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen va_list args;
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen string_t *str;
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen const char *msg;
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen va_start(args, fmt);
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen msg = t_strdup_vprintf(fmt, args);
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen str = t_str_new(256);
eed03830015b7138b9d4522e72bef650aa24b45fTimo Sirainen if (ctx->session_id != NULL)
eed03830015b7138b9d4522e72bef650aa24b45fTimo Sirainen str_printfa(str, "%s: ", ctx->session_id);
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen var_expand(str, ctx->set->deliver_log_format,
16d8197506b63d2ca7e38447df9faf1612c1f288Timo Sirainen mail_deliver_get_log_var_expand_table(ctx->src_mail, msg));
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen i_info("%s", str_c(str));
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen va_end(args);
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen}
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen
f9db221d0793f05c4631885e71f98145428a7e1bTimo Sirainenstatic const char *mailbox_name_to_mutf7(const char *mailbox_utf8)
f9db221d0793f05c4631885e71f98145428a7e1bTimo Sirainen{
f9db221d0793f05c4631885e71f98145428a7e1bTimo Sirainen string_t *str = t_str_new(128);
f9db221d0793f05c4631885e71f98145428a7e1bTimo Sirainen
f9db221d0793f05c4631885e71f98145428a7e1bTimo Sirainen if (imap_utf8_to_utf7(mailbox_utf8, str) < 0)
f9db221d0793f05c4631885e71f98145428a7e1bTimo Sirainen return mailbox_utf8;
f9db221d0793f05c4631885e71f98145428a7e1bTimo Sirainen else
f9db221d0793f05c4631885e71f98145428a7e1bTimo Sirainen return str_c(str);
f9db221d0793f05c4631885e71f98145428a7e1bTimo Sirainen}
f9db221d0793f05c4631885e71f98145428a7e1bTimo Sirainen
f9db221d0793f05c4631885e71f98145428a7e1bTimo Sirainenint mail_deliver_save_open(struct mail_deliver_save_open_context *ctx,
f9db221d0793f05c4631885e71f98145428a7e1bTimo Sirainen const char *name, struct mailbox **box_r,
258adfa09081ea8600a39759d486e678b5aa5f60Timo Sirainen enum mail_error *error_r, const char **error_str_r)
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen{
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen struct mail_namespace *ns;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen struct mail_storage *storage;
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen struct mailbox *box;
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen enum mailbox_flags flags =
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen MAILBOX_FLAG_KEEP_RECENT | MAILBOX_FLAG_SAVEONLY |
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen MAILBOX_FLAG_POST_SESSION;
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen
f9db221d0793f05c4631885e71f98145428a7e1bTimo Sirainen *box_r = NULL;
258adfa09081ea8600a39759d486e678b5aa5f60Timo Sirainen *error_r = MAIL_ERROR_NONE;
258adfa09081ea8600a39759d486e678b5aa5f60Timo Sirainen *error_str_r = NULL;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen
f9db221d0793f05c4631885e71f98145428a7e1bTimo Sirainen name = mailbox_name_to_mutf7(name);
f9db221d0793f05c4631885e71f98145428a7e1bTimo Sirainen ns = mail_namespace_find(ctx->user->namespaces, &name);
f9db221d0793f05c4631885e71f98145428a7e1bTimo Sirainen if (ns == NULL) {
258adfa09081ea8600a39759d486e678b5aa5f60Timo Sirainen *error_str_r = "Unknown namespace";
258adfa09081ea8600a39759d486e678b5aa5f60Timo Sirainen *error_r = MAIL_ERROR_PARAMS;
f9db221d0793f05c4631885e71f98145428a7e1bTimo Sirainen return -1;
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen }
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen
eb64c3586d854cddd693f0b811d897399076a441Timo Sirainen if (*name == '\0' && (ns->flags & NAMESPACE_FLAG_INBOX_USER) != 0) {
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen /* delivering to a namespace prefix means we actually want to
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen deliver to the INBOX instead */
f9db221d0793f05c4631885e71f98145428a7e1bTimo Sirainen name = "INBOX";
f9db221d0793f05c4631885e71f98145428a7e1bTimo Sirainen ns = mail_namespace_find_inbox(ctx->user->namespaces);
f9db221d0793f05c4631885e71f98145428a7e1bTimo Sirainen }
f9db221d0793f05c4631885e71f98145428a7e1bTimo Sirainen
f9db221d0793f05c4631885e71f98145428a7e1bTimo Sirainen if (strcasecmp(name, "INBOX") == 0) {
f9db221d0793f05c4631885e71f98145428a7e1bTimo Sirainen /* deliveries to INBOX must always succeed,
f9db221d0793f05c4631885e71f98145428a7e1bTimo Sirainen regardless of ACLs */
f9db221d0793f05c4631885e71f98145428a7e1bTimo Sirainen flags |= MAILBOX_FLAG_IGNORE_ACLS;
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen }
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen
f9db221d0793f05c4631885e71f98145428a7e1bTimo Sirainen *box_r = box = mailbox_alloc(ns->list, name, flags);
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen if (mailbox_open(box) == 0)
f9db221d0793f05c4631885e71f98145428a7e1bTimo Sirainen return 0;
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen storage = mailbox_get_storage(box);
258adfa09081ea8600a39759d486e678b5aa5f60Timo Sirainen *error_str_r = mail_storage_get_last_error(storage, error_r);
258adfa09081ea8600a39759d486e678b5aa5f60Timo Sirainen if (!ctx->lda_mailbox_autocreate || *error_r != MAIL_ERROR_NOTFOUND)
f9db221d0793f05c4631885e71f98145428a7e1bTimo Sirainen return -1;
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen /* try creating it. */
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainen if (mailbox_create(box, NULL, FALSE) < 0) {
258adfa09081ea8600a39759d486e678b5aa5f60Timo Sirainen *error_str_r = mail_storage_get_last_error(storage, error_r);
258adfa09081ea8600a39759d486e678b5aa5f60Timo Sirainen if (*error_r != MAIL_ERROR_EXISTS)
f9db221d0793f05c4631885e71f98145428a7e1bTimo Sirainen return -1;
014863702b55990240e2b64754b439b3e2f907dcTimo Sirainen /* someone else just created it */
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen }
f9db221d0793f05c4631885e71f98145428a7e1bTimo Sirainen if (ctx->lda_mailbox_autosubscribe) {
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen /* (try to) subscribe to it */
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen (void)mailbox_list_set_subscribed(ns->list, name, TRUE);
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen }
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen /* and try opening again */
2584e86cc2d8c31ba30a4109cf4ba09d1e37e28aTimo Sirainen if (mailbox_sync(box, 0) < 0) {
258adfa09081ea8600a39759d486e678b5aa5f60Timo Sirainen *error_str_r = mail_storage_get_last_error(storage, error_r);
f9db221d0793f05c4631885e71f98145428a7e1bTimo Sirainen return -1;
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen }
f9db221d0793f05c4631885e71f98145428a7e1bTimo Sirainen return 0;
ed51404d355ae65d762cee68aefdbf900903a658Timo Sirainen}
ed51404d355ae65d762cee68aefdbf900903a658Timo Sirainen
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainenint mail_deliver_save(struct mail_deliver_context *ctx, const char *mailbox,
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen enum mail_flags flags, const char *const *keywords,
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen struct mail_storage **storage_r)
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen{
f9db221d0793f05c4631885e71f98145428a7e1bTimo Sirainen struct mail_deliver_save_open_context open_ctx;
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen struct mailbox *box;
2ef5254ab6b446b93ce7733bc96eeefa6f731ee4Timo Sirainen enum mailbox_transaction_flags trans_flags;
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen struct mailbox_transaction_context *t;
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen struct mail_save_context *save_ctx;
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen struct mail_keywords *kw;
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen enum mail_error error;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen const char *mailbox_name, *errstr;
96308127e006bb3b1108093bcf4cc1fd9481cb7aTimo Sirainen struct mail_transaction_commit_changes changes;
96308127e006bb3b1108093bcf4cc1fd9481cb7aTimo Sirainen const struct seq_range *range;
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen bool default_save;
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen int ret = 0;
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen
f4704cef6ccb64d390198d0e0fddb9f2235a4d0bTimo Sirainen i_assert(ctx->dest_mail == NULL);
f4704cef6ccb64d390198d0e0fddb9f2235a4d0bTimo Sirainen
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen default_save = strcmp(mailbox, ctx->dest_mailbox_name) == 0;
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen if (default_save)
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen ctx->tried_default_save = TRUE;
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen
f9db221d0793f05c4631885e71f98145428a7e1bTimo Sirainen memset(&open_ctx, 0, sizeof(open_ctx));
f9db221d0793f05c4631885e71f98145428a7e1bTimo Sirainen open_ctx.user = ctx->dest_user;
f9db221d0793f05c4631885e71f98145428a7e1bTimo Sirainen open_ctx.lda_mailbox_autocreate = ctx->set->lda_mailbox_autocreate;
f9db221d0793f05c4631885e71f98145428a7e1bTimo Sirainen open_ctx.lda_mailbox_autosubscribe = ctx->set->lda_mailbox_autosubscribe;
f9db221d0793f05c4631885e71f98145428a7e1bTimo Sirainen
f185133819c115c8cbc1c7e96804f237e23d255cTimo Sirainen mailbox_name = str_sanitize(mailbox, 80);
258adfa09081ea8600a39759d486e678b5aa5f60Timo Sirainen if (mail_deliver_save_open(&open_ctx, mailbox, &box,
258adfa09081ea8600a39759d486e678b5aa5f60Timo Sirainen &error, &errstr) < 0) {
f9db221d0793f05c4631885e71f98145428a7e1bTimo Sirainen if (box != NULL)
f9db221d0793f05c4631885e71f98145428a7e1bTimo Sirainen mailbox_free(&box);
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen mail_deliver_log(ctx, "save failed to %s: %s",
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen mailbox_name, errstr);
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen return -1;
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen }
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen *storage_r = mailbox_get_storage(box);
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen
2ef5254ab6b446b93ce7733bc96eeefa6f731ee4Timo Sirainen trans_flags = MAILBOX_TRANSACTION_FLAG_EXTERNAL;
2ef5254ab6b446b93ce7733bc96eeefa6f731ee4Timo Sirainen if (ctx->save_dest_mail)
2ef5254ab6b446b93ce7733bc96eeefa6f731ee4Timo Sirainen trans_flags |= MAILBOX_TRANSACTION_FLAG_ASSIGN_UIDS;
2ef5254ab6b446b93ce7733bc96eeefa6f731ee4Timo Sirainen t = mailbox_transaction_begin(box, trans_flags);
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen kw = str_array_length(keywords) == 0 ? NULL :
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen mailbox_keywords_create_valid(box, keywords);
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen save_ctx = mailbox_save_alloc(t);
4c20874a726f2a88e133a7fb1fb07ea66a0b5a7cTimo Sirainen if (ctx->src_envelope_sender != NULL)
4c20874a726f2a88e133a7fb1fb07ea66a0b5a7cTimo Sirainen mailbox_save_set_from_envelope(save_ctx, ctx->src_envelope_sender);
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen mailbox_save_set_flags(save_ctx, flags, kw);
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen if (mailbox_copy(&save_ctx, ctx->src_mail) < 0)
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen ret = -1;
84ed9f8f3d0e5ed47607ef417618e49e4f865557Timo Sirainen if (kw != NULL)
84ed9f8f3d0e5ed47607ef417618e49e4f865557Timo Sirainen mailbox_keywords_unref(box, &kw);
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen if (ret < 0)
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen mailbox_transaction_rollback(&t);
96308127e006bb3b1108093bcf4cc1fd9481cb7aTimo Sirainen else
96308127e006bb3b1108093bcf4cc1fd9481cb7aTimo Sirainen ret = mailbox_transaction_commit_get_changes(&t, &changes);
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen if (ret == 0) {
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen ctx->saved_mail = TRUE;
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen mail_deliver_log(ctx, "saved mail to %s", mailbox_name);
2ef5254ab6b446b93ce7733bc96eeefa6f731ee4Timo Sirainen
2584e86cc2d8c31ba30a4109cf4ba09d1e37e28aTimo Sirainen if (ctx->save_dest_mail && mailbox_sync(box, 0) == 0) {
96308127e006bb3b1108093bcf4cc1fd9481cb7aTimo Sirainen range = array_idx(&changes.saved_uids, 0);
96308127e006bb3b1108093bcf4cc1fd9481cb7aTimo Sirainen i_assert(range[0].seq1 == range[0].seq2);
2ef5254ab6b446b93ce7733bc96eeefa6f731ee4Timo Sirainen
2ef5254ab6b446b93ce7733bc96eeefa6f731ee4Timo Sirainen t = mailbox_transaction_begin(box, 0);
2ef5254ab6b446b93ce7733bc96eeefa6f731ee4Timo Sirainen ctx->dest_mail = mail_alloc(t, MAIL_FETCH_STREAM_BODY,
2ef5254ab6b446b93ce7733bc96eeefa6f731ee4Timo Sirainen NULL);
96308127e006bb3b1108093bcf4cc1fd9481cb7aTimo Sirainen if (mail_set_uid(ctx->dest_mail, range[0].seq1) < 0) {
2ef5254ab6b446b93ce7733bc96eeefa6f731ee4Timo Sirainen mail_free(&ctx->dest_mail);
2ef5254ab6b446b93ce7733bc96eeefa6f731ee4Timo Sirainen mailbox_transaction_rollback(&t);
2ef5254ab6b446b93ce7733bc96eeefa6f731ee4Timo Sirainen }
2ef5254ab6b446b93ce7733bc96eeefa6f731ee4Timo Sirainen }
96308127e006bb3b1108093bcf4cc1fd9481cb7aTimo Sirainen pool_unref(&changes.pool);
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen } else {
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen mail_deliver_log(ctx, "save failed to %s: %s", mailbox_name,
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen mail_storage_get_last_error(*storage_r, &error));
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen }
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen
2ef5254ab6b446b93ce7733bc96eeefa6f731ee4Timo Sirainen if (ctx->dest_mail == NULL)
e10d8b1291090c26b9ef499637e6e632485ca5beTimo Sirainen mailbox_free(&box);
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen return ret;
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen}
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainenconst char *mail_deliver_get_return_address(struct mail_deliver_context *ctx)
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen{
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen if (ctx->src_envelope_sender != NULL)
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen return ctx->src_envelope_sender;
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen
16d8197506b63d2ca7e38447df9faf1612c1f288Timo Sirainen return mail_deliver_get_address(ctx->src_mail, "Return-Path");
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen}
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainenconst char *mail_deliver_get_new_message_id(struct mail_deliver_context *ctx)
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen{
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen static int count = 0;
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen return t_strdup_printf("<dovecot-%s-%s-%d@%s>",
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen dec2str(ioloop_timeval.tv_sec),
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen dec2str(ioloop_timeval.tv_usec),
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen count++, ctx->set->hostname);
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen}
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainenint mail_deliver(struct mail_deliver_context *ctx,
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen struct mail_storage **storage_r)
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen{
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen int ret;
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen *storage_r = NULL;
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen if (deliver_mail == NULL)
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen ret = -1;
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen else {
4afaedfcbd43896befbe1fd5c10eba42246f3fdeTimo Sirainen ctx->dup_ctx = duplicate_init(ctx->dest_user);
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen if (deliver_mail(ctx, storage_r) <= 0) {
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen /* if message was saved, don't bounce it even though
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen the script failed later. */
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen ret = ctx->saved_mail ? 0 : -1;
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen } else {
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen /* success. message may or may not have been saved. */
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen ret = 0;
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen }
4afaedfcbd43896befbe1fd5c10eba42246f3fdeTimo Sirainen duplicate_deinit(&ctx->dup_ctx);
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen }
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen if (ret < 0 && !ctx->tried_default_save) {
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen /* plugins didn't handle this. save into the default mailbox. */
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen ret = mail_deliver_save(ctx, ctx->dest_mailbox_name, 0, NULL,
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen storage_r);
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen }
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen if (ret < 0 && strcasecmp(ctx->dest_mailbox_name, "INBOX") != 0) {
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen /* still didn't work. try once more to save it
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen to INBOX. */
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen ret = mail_deliver_save(ctx, "INBOX", 0, NULL, storage_r);
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen }
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen return ret;
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen}
92e6bb6497f8c9d57bff334a5c9f31bc2f040394Timo Sirainen
92e6bb6497f8c9d57bff334a5c9f31bc2f040394Timo Sirainendeliver_mail_func_t *mail_deliver_hook_set(deliver_mail_func_t *new_hook)
92e6bb6497f8c9d57bff334a5c9f31bc2f040394Timo Sirainen{
92e6bb6497f8c9d57bff334a5c9f31bc2f040394Timo Sirainen deliver_mail_func_t *old_hook = deliver_mail;
92e6bb6497f8c9d57bff334a5c9f31bc2f040394Timo Sirainen
92e6bb6497f8c9d57bff334a5c9f31bc2f040394Timo Sirainen deliver_mail = new_hook;
92e6bb6497f8c9d57bff334a5c9f31bc2f040394Timo Sirainen return old_hook;
92e6bb6497f8c9d57bff334a5c9f31bc2f040394Timo Sirainen}