mail-deliver.c revision 92e6bb6497f8c9d57bff334a5c9f31bc2f040394
e59faf65ce864fe95dc00f5d52b8323cdbd0608aTimo Sirainen/* Copyright (c) 2005-2010 Dovecot authors, see the included COPYING file */
16d8197506b63d2ca7e38447df9faf1612c1f288Timo Sirainenconst char *mail_deliver_get_address(struct mail *mail, const char *header)
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen const char *str;
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' ?
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen NULL : t_strconcat(addr->mailbox, "@", addr->domain, NULL);
16d8197506b63d2ca7e38447df9faf1612c1f288Timo Sirainenmail_deliver_get_log_var_expand_table(struct mail *mail, const char *message)
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen static struct var_expand_table static_tab[] = {
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 (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);
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainenvoid mail_deliver_log(struct mail_deliver_context *ctx, const char *fmt, ...)
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen const char *msg;
16d8197506b63d2ca7e38447df9faf1612c1f288Timo Sirainen mail_deliver_get_log_var_expand_table(ctx->src_mail, msg));
f9db221d0793f05c4631885e71f98145428a7e1bTimo Sirainenstatic const char *mailbox_name_to_mutf7(const char *mailbox_utf8)
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)
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen MAILBOX_FLAG_KEEP_RECENT | MAILBOX_FLAG_SAVEONLY |
f9db221d0793f05c4631885e71f98145428a7e1bTimo Sirainen ns = mail_namespace_find(ctx->user->namespaces, &name);
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 ns = mail_namespace_find_inbox(ctx->user->namespaces);
f9db221d0793f05c4631885e71f98145428a7e1bTimo Sirainen /* deliveries to INBOX must always succeed,
f9db221d0793f05c4631885e71f98145428a7e1bTimo Sirainen regardless of ACLs */
f9db221d0793f05c4631885e71f98145428a7e1bTimo Sirainen *box_r = box = mailbox_alloc(ns->list, name, flags);
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)
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen /* try creating it. */
258adfa09081ea8600a39759d486e678b5aa5f60Timo Sirainen *error_str_r = mail_storage_get_last_error(storage, error_r);
014863702b55990240e2b64754b439b3e2f907dcTimo Sirainen /* someone else just created it */
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen /* (try to) subscribe to it */
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen (void)mailbox_list_set_subscribed(ns->list, name, TRUE);
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen /* and try opening again */
258adfa09081ea8600a39759d486e678b5aa5f60Timo Sirainen *error_str_r = mail_storage_get_last_error(storage, error_r);
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;
96308127e006bb3b1108093bcf4cc1fd9481cb7aTimo Sirainen struct mail_transaction_commit_changes changes;
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen default_save = strcmp(mailbox, ctx->dest_mailbox_name) == 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,
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen mail_deliver_log(ctx, "save failed to %s: %s",
2ef5254ab6b446b93ce7733bc96eeefa6f731ee4Timo Sirainen trans_flags = MAILBOX_TRANSACTION_FLAG_EXTERNAL;
2ef5254ab6b446b93ce7733bc96eeefa6f731ee4Timo Sirainen trans_flags |= MAILBOX_TRANSACTION_FLAG_ASSIGN_UIDS;
2ef5254ab6b446b93ce7733bc96eeefa6f731ee4Timo Sirainen t = mailbox_transaction_begin(box, trans_flags);
4c20874a726f2a88e133a7fb1fb07ea66a0b5a7cTimo Sirainen mailbox_save_set_from_envelope(save_ctx, ctx->src_envelope_sender);
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen if (mailbox_copy(&save_ctx, ctx->src_mail) < 0)
96308127e006bb3b1108093bcf4cc1fd9481cb7aTimo Sirainen ret = mailbox_transaction_commit_get_changes(&t, &changes);
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen mail_deliver_log(ctx, "saved mail to %s", mailbox_name);
2584e86cc2d8c31ba30a4109cf4ba09d1e37e28aTimo Sirainen if (ctx->save_dest_mail && mailbox_sync(box, 0) == 0) {
2ef5254ab6b446b93ce7733bc96eeefa6f731ee4Timo Sirainen ctx->dest_mail = mail_alloc(t, MAIL_FETCH_STREAM_BODY,
96308127e006bb3b1108093bcf4cc1fd9481cb7aTimo Sirainen if (mail_set_uid(ctx->dest_mail, range[0].seq1) < 0) {
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen mail_deliver_log(ctx, "save failed to %s: %s", mailbox_name,
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen mail_storage_get_last_error(*storage_r, &error));
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainenconst char *mail_deliver_get_return_address(struct mail_deliver_context *ctx)
16d8197506b63d2ca7e38447df9faf1612c1f288Timo Sirainen return mail_deliver_get_address(ctx->src_mail, "Return-Path");
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainenconst char *mail_deliver_get_new_message_id(struct mail_deliver_context *ctx)
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen static int count = 0;
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainen return t_strdup_printf("<dovecot-%s-%s-%d@%s>",
58c61ac5650583d21c891e61e051c614290d31fbTimo Sirainenint mail_deliver(struct mail_deliver_context *ctx,
4afaedfcbd43896befbe1fd5c10eba42246f3fdeTimo Sirainen ctx->dup_ctx = duplicate_init(ctx->dest_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. */
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 if (ret < 0 && strcasecmp(ctx->dest_mailbox_name, "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);