]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
mail_deliver(): Support returning a destination mail.
authorTimo Sirainen <tss@iki.fi>
Thu, 16 Apr 2009 22:10:30 +0000 (18:10 -0400)
committerTimo Sirainen <tss@iki.fi>
Thu, 16 Apr 2009 22:10:30 +0000 (18:10 -0400)
--HG--
branch : HEAD

src/lib-lda/mail-deliver.c
src/lib-lda/mail-deliver.h

index e431be36777f92bdea6d100ef919e8d57553af70..9e040ade0f7ba3d5819d2fa8a795e4d7dbfae165 100644 (file)
@@ -135,11 +135,13 @@ int mail_deliver_save(struct mail_deliver_context *ctx, const char *mailbox,
 {
        struct mail_namespace *ns;
        struct mailbox *box;
+       enum mailbox_transaction_flags trans_flags;
        struct mailbox_transaction_context *t;
        struct mail_save_context *save_ctx;
        struct mail_keywords *kw;
        enum mail_error error;
        const char *mailbox_name;
+       uint32_t uid_validity, uid1 = 0, uid2 = 0;
        bool default_save;
        int ret = 0;
 
@@ -166,7 +168,10 @@ int mail_deliver_save(struct mail_deliver_context *ctx, const char *mailbox,
                return -1;
        }
 
-       t = mailbox_transaction_begin(box, MAILBOX_TRANSACTION_FLAG_EXTERNAL);
+       trans_flags = MAILBOX_TRANSACTION_FLAG_EXTERNAL;
+       if (ctx->save_dest_mail)
+               trans_flags |= MAILBOX_TRANSACTION_FLAG_ASSIGN_UIDS;
+       t = mailbox_transaction_begin(box, trans_flags);
 
        kw = str_array_length(keywords) == 0 ? NULL :
                mailbox_keywords_create_valid(box, keywords);
@@ -178,18 +183,33 @@ int mail_deliver_save(struct mail_deliver_context *ctx, const char *mailbox,
 
        if (ret < 0)
                mailbox_transaction_rollback(&t);
-       else
-               ret = mailbox_transaction_commit(&t);
+       else {
+               ret = mailbox_transaction_commit_get_uids(&t, &uid_validity,
+                                                         &uid1, &uid2);
+       }
 
        if (ret == 0) {
                ctx->saved_mail = TRUE;
                mail_deliver_log(ctx, "saved mail to %s", mailbox_name);
+
+               if (ctx->save_dest_mail && mailbox_sync(box, 0, 0, NULL) == 0) {
+                       i_assert(uid1 == uid2);
+
+                       t = mailbox_transaction_begin(box, 0);
+                       ctx->dest_mail = mail_alloc(t, MAIL_FETCH_STREAM_BODY,
+                                                   NULL);
+                       if (mail_set_uid(ctx->dest_mail, uid1) < 0) {
+                               mail_free(&ctx->dest_mail);
+                               mailbox_transaction_rollback(&t);
+                       }
+               }
        } else {
                mail_deliver_log(ctx, "save failed to %s: %s", mailbox_name,
                                 mail_storage_get_last_error(*storage_r, &error));
        }
 
-       mailbox_close(&box);
+       if (ctx->dest_mail == NULL)
+               mailbox_close(&box);
        return ret;
 }
 
index b622108944541dbb8a38a7f6ce463a64f19cde20..64df09a2e0c0715a696cd586c66d62e0f5137aba 100644 (file)
@@ -21,8 +21,14 @@ struct mail_deliver_context {
           something to it. */
        const char *dest_mailbox_name;
 
+       /* Filled with destination mail, if save_dest_mail=TRUE.
+          The caller must free the mail, its transaction and close
+          the mailbox. */
+       struct mail *dest_mail;
+
        bool tried_default_save;
        bool saved_mail;
+       bool save_dest_mail;
 };
 
 typedef int deliver_mail_func_t(struct mail_deliver_context *ctx,