]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Mail copying API changed to be based on save API. This allows extending it easily...
authorTimo Sirainen <tss@iki.fi>
Fri, 6 Feb 2009 17:49:46 +0000 (12:49 -0500)
committerTimo Sirainen <tss@iki.fi>
Fri, 6 Feb 2009 17:49:46 +0000 (12:49 -0500)
--HG--
branch : HEAD

15 files changed:
src/deliver/deliver.c
src/imap/cmd-copy.c
src/lib-storage/index/maildir/maildir-copy.c
src/lib-storage/index/maildir/maildir-storage.h
src/lib-storage/mail-copy.c
src/lib-storage/mail-copy.h
src/lib-storage/mail-storage-private.h
src/lib-storage/mail-storage.c
src/lib-storage/mail-storage.h
src/plugins/acl/acl-mailbox.c
src/plugins/convert/convert-storage.c
src/plugins/expire/expire-plugin.c
src/plugins/mail-log/mail-log-plugin.c
src/plugins/mbox-snarf/mbox-snarf-plugin.c
src/plugins/quota/quota-storage.c

index 9bde35885b64f6e1d668dede144193819b17faea..042c3ac31a7e7db3130e95aa3a8044105dd2bd7b 100644 (file)
@@ -204,6 +204,7 @@ int deliver_save(struct mail_namespace *namespaces,
 {
        struct mailbox *box;
        struct mailbox_transaction_context *t;
+       struct mail_save_context *save_ctx;
        struct mail_keywords *kw;
        enum mail_error error;
        const char *mailbox_name;
@@ -237,7 +238,9 @@ int deliver_save(struct mail_namespace *namespaces,
 
        kw = str_array_length(keywords) == 0 ? NULL :
                mailbox_keywords_create_valid(box, keywords);
-       if (mailbox_copy(t, mail, flags, kw, NULL) < 0)
+       save_ctx = mailbox_save_alloc(t);
+       mailbox_save_set_flags(save_ctx, flags, kw);
+       if (mailbox_copy(&save_ctx, mail) < 0)
                ret = -1;
        mailbox_keywords_free(box, &kw);
 
index 49553008a9bdc3eb235b18a20a8ef18cb4f94cf6..1180e132ab8d761f40d676946b1e9c48241be506 100644 (file)
@@ -35,6 +35,7 @@ static int fetch_and_copy(struct client *client, struct mailbox *destbox,
 {
        struct mail_search_context *search_ctx;
         struct mailbox_transaction_context *src_trans;
+       struct mail_save_context *save_ctx;
        struct mail_keywords *keywords;
        const char *const *keywords_list;
        struct mail *mail;
@@ -64,8 +65,12 @@ static int fetch_and_copy(struct client *client, struct mailbox *destbox,
                keywords_list = mail_get_keywords(mail);
                keywords = str_array_length(keywords_list) == 0 ? NULL :
                        mailbox_keywords_create_valid(destbox, keywords_list);
-               if (mailbox_copy(t, mail, mail_get_flags(mail),
-                                keywords, NULL) < 0)
+
+               save_ctx = mailbox_save_alloc(t);
+               mailbox_save_set_flags(save_ctx, mail_get_flags(mail),
+                                      keywords);
+
+               if (mailbox_copy(&save_ctx, mail) < 0)
                        ret = mail->expunged ? 0 : -1;
                mailbox_keywords_free(destbox, &keywords);
 
index b3bc7a8d4c0089ba5d387ecc4435b006e835c149..e5033d2fd20aa81fa334bdda4694b7e7e5a7f09d 100644 (file)
@@ -259,29 +259,28 @@ maildir_compatible_file_modes(struct mailbox *box1, struct mailbox *box2)
                box1->file_create_gid == box2->file_create_gid;
 }
 
-int maildir_copy(struct mailbox_transaction_context *_t, struct mail *mail,
-                enum mail_flags flags, struct mail_keywords *keywords,
-                struct mail *dest_mail)
+int maildir_copy(struct mail_save_context *ctx, struct mail *mail)
 {
        struct maildir_transaction_context *t =
-               (struct maildir_transaction_context *)_t;
+               (struct maildir_transaction_context *)ctx->transaction;
        struct maildir_mailbox *mbox = (struct maildir_mailbox *)t->ictx.ibox;
        int ret;
 
        if (mbox->storage->copy_with_hardlinks &&
            maildir_compatible_file_modes(&mbox->ibox.box, mail->box)) {
                T_BEGIN {
-                       ret = maildir_copy_hardlink(t, mail, flags,
-                                                   keywords, dest_mail);
+                       ret = maildir_copy_hardlink(t, mail, ctx->flags,
+                                                   ctx->keywords,
+                                                   ctx->dest_mail);
                } T_END;
 
-               if (ret > 0)
-                       return 0;
-               if (ret < 0)
-                       return -1;
+               if (ret != 0) {
+                       index_save_context_free(ctx);
+                       return ret > 0 ? 0 : -1;
+               }
 
                /* non-fatal hardlinking failure, try the slow way */
        }
 
-       return mail_storage_copy(_t, mail, flags, keywords, dest_mail);
+       return mail_storage_copy(ctx, mail);
 }
index ed1ecd5e5fac16d8a9d9236d718313b97933d680..7f5c63c65d6b51e126a47830192303ff179621e7 100644 (file)
@@ -148,9 +148,7 @@ int maildir_transaction_save_commit_pre(struct maildir_save_context *ctx);
 void maildir_transaction_save_commit_post(struct maildir_save_context *ctx);
 void maildir_transaction_save_rollback(struct maildir_save_context *ctx);
 
-int maildir_copy(struct mailbox_transaction_context *t, struct mail *mail,
-                enum mail_flags flags, struct mail_keywords *keywords,
-                struct mail *dest_mail);
+int maildir_copy(struct mail_save_context *ctx, struct mail *mail);
 int maildir_transaction_copy_commit(struct maildir_copy_context *ctx);
 void maildir_transaction_copy_rollback(struct maildir_copy_context *ctx);
 
index 8e5d7e92477644b16aa928fdb5f858f308de4e1c..888d175e9c60d8b515bac356a3637a64672a7511 100644 (file)
@@ -5,33 +5,33 @@
 #include "mail-storage-private.h"
 #include "mail-copy.h"
 
-int mail_storage_copy(struct mailbox_transaction_context *t, struct mail *mail,
-                     enum mail_flags flags, struct mail_keywords *keywords,
-                     struct mail *dest_mail)
+int mail_storage_copy(struct mail_save_context *ctx, struct mail *mail)
 {
-       struct mail_save_context *ctx;
        struct istream *input;
        const char *from_envelope, *guid;
        time_t received_date;
 
        if (mail_get_stream(mail, NULL, NULL, &input) < 0)
                return -1;
-       if (mail_get_received_date(mail, &received_date) < 0)
-               return -1;
-       if (mail_get_special(mail, MAIL_FETCH_FROM_ENVELOPE,
-                            &from_envelope) < 0)
-               return -1;
-       if (mail_get_special(mail, MAIL_FETCH_GUID, &guid) < 0)
-               return -1;
 
-       ctx = mailbox_save_alloc(t);
-       mailbox_save_set_flags(ctx, flags, keywords);
-       mailbox_save_set_received_date(ctx, received_date, 0);
-       if (*from_envelope != '\0')
-               mailbox_save_set_from_envelope(ctx, from_envelope);
-       if (*guid != '\0')
-               mailbox_save_set_guid(ctx, guid);
-       mailbox_save_set_dest_mail(ctx, dest_mail);
+       if (ctx->received_date == (time_t)-1) {
+               if (mail_get_received_date(mail, &received_date) < 0)
+                       return -1;
+               mailbox_save_set_received_date(ctx, received_date, 0);
+       }
+       if (ctx->from_envelope == NULL) {
+               if (mail_get_special(mail, MAIL_FETCH_FROM_ENVELOPE,
+                                    &from_envelope) < 0)
+                       return -1;
+               if (*from_envelope != '\0')
+                       mailbox_save_set_from_envelope(ctx, from_envelope);
+       }
+       if (ctx->guid == NULL) {
+               if (mail_get_special(mail, MAIL_FETCH_GUID, &guid) < 0)
+                       return -1;
+               if (*guid != '\0')
+                       mailbox_save_set_guid(ctx, guid);
+       }
 
        if (mailbox_save_begin(&ctx, input) < 0)
                return -1;
@@ -42,7 +42,7 @@ int mail_storage_copy(struct mailbox_transaction_context *t, struct mail *mail,
        } while (i_stream_read(input) != -1);
 
        if (input->stream_errno != 0) {
-               mail_storage_set_critical(t->box->storage,
+               mail_storage_set_critical(ctx->transaction->box->storage,
                                          "copy: i_stream_read() failed: %m");
                mailbox_save_cancel(&ctx);
                return -1;
index 89478689a93b24d174dc633585b4d8ce5ee5424a..c769082db2413e63b3eb8e126db52fbe635afd30 100644 (file)
@@ -1,8 +1,6 @@
 #ifndef MAIL_COPY_H
 #define MAIL_COPY_H
 
-int mail_storage_copy(struct mailbox_transaction_context *t, struct mail *mail,
-                     enum mail_flags flags, struct mail_keywords *keywords,
-                     struct mail *dest_mail);
+int mail_storage_copy(struct mail_save_context *ctx, struct mail *mail);
 
 #endif
index 2f56a6b7534aecced920bc736edc20a6a2031dba..3901346f971c41dc88e5a21955e7c0dff76dc489 100644 (file)
@@ -176,10 +176,7 @@ struct mailbox_vfuncs {
        int (*save_continue)(struct mail_save_context *ctx);
        int (*save_finish)(struct mail_save_context *ctx);
        void (*save_cancel)(struct mail_save_context *ctx);
-
-       int (*copy)(struct mailbox_transaction_context *t, struct mail *mail,
-                   enum mail_flags flags, struct mail_keywords *keywords,
-                   struct mail *dest_mail);
+       int (*copy)(struct mail_save_context *ctx, struct mail *mail);
 
        bool (*is_inconsistent)(struct mailbox *box);
 };
index 647e520276297a853fe71385edeb6c28d750f174..efe5282d838a48021c2306a42b12a44ddee4ad81 100644 (file)
@@ -915,11 +915,12 @@ void mailbox_save_cancel(struct mail_save_context **_ctx)
        ctx->transaction->box->v.save_cancel(ctx);
 }
 
-int mailbox_copy(struct mailbox_transaction_context *t, struct mail *mail,
-                enum mail_flags flags, struct mail_keywords *keywords,
-                struct mail *dest_mail)
+int mailbox_copy(struct mail_save_context **_ctx, struct mail *mail)
 {
-       return t->box->v.copy(t, mail, flags, keywords, dest_mail);
+       struct mail_save_context *ctx = *_ctx;
+
+       *_ctx = NULL;
+       return ctx->transaction->box->v.copy(ctx, mail);
 }
 
 bool mailbox_is_inconsistent(struct mailbox *box)
index ac210cc41383e0fce1a0ac234ec6959e20954885..2275f1d6b27f06533d90f2dba5fa78a799a75be2 100644 (file)
@@ -527,12 +527,9 @@ int mailbox_save_continue(struct mail_save_context *ctx);
 int mailbox_save_finish(struct mail_save_context **ctx);
 void mailbox_save_cancel(struct mail_save_context **ctx);
 
-/* Copy given message. If dest_mail is non-NULL, the copied message can be
-   accessed using it. Note that setting it non-NULL may require mailbox
-   syncing, so don't give give it unless you need it. */
-int mailbox_copy(struct mailbox_transaction_context *t, struct mail *mail,
-                enum mail_flags flags, struct mail_keywords *keywords,
-                struct mail *dest_mail);
+/* Copy the given message. You'll need to specify the flags etc. using the
+   mailbox_save_*() functions. */
+int mailbox_copy(struct mail_save_context **ctx, struct mail *mail);
 
 /* Returns TRUE if mailbox is now in inconsistent state, meaning that
    the message IDs etc. may have changed - only way to recover this
index 9dbd166810e2fdf6b753aa30fb68b472e63c712a..ab42e53842cb3321ae32ab04a5cc9be0b2eb4818 100644 (file)
@@ -287,10 +287,9 @@ acl_save_begin(struct mail_save_context *ctx, struct istream *input)
 }
 
 static int
-acl_copy(struct mailbox_transaction_context *t, struct mail *mail,
-        enum mail_flags flags, struct mail_keywords *keywords,
-        struct mail *dest_mail)
+acl_copy(struct mail_save_context *ctx, struct mail *mail)
 {
+       struct mailbox_transaction_context *t = ctx->transaction;
        struct acl_mailbox *abox = ACL_CONTEXT(t->box);
        enum acl_storage_rights save_right;
 
@@ -298,10 +297,10 @@ acl_copy(struct mailbox_transaction_context *t, struct mail *mail,
                ACL_STORAGE_RIGHT_POST : ACL_STORAGE_RIGHT_INSERT;
        if (acl_mailbox_right_lookup(t->box, save_right) <= 0)
                return -1;
-       if (acl_save_get_flags(t->box, &flags, &keywords) < 0)
+       if (acl_save_get_flags(t->box, &ctx->flags, &ctx->keywords) < 0)
                return -1;
 
-       return abox->module_ctx.super.copy(t, mail, flags, keywords, dest_mail);
+       return abox->module_ctx.super.copy(ctx, mail);
 }
 
 static int
index 9471b2a5ce891106a37f23c4a49b359d6fd1428b..a63128b5f530dab3b1a50bacf2027c66e4b5cb4a 100644 (file)
@@ -34,6 +34,7 @@ static int mailbox_copy_mails(struct mailbox *srcbox, struct mailbox *destbox,
 {
        struct mail_search_context *ctx;
        struct mailbox_transaction_context *src_trans, *dest_trans;
+       struct mail_save_context *save_ctx;
        struct mail *mail;
        struct mail_search_args *search_args;
        int ret = 0;
@@ -72,8 +73,10 @@ static int mailbox_copy_mails(struct mailbox *srcbox, struct mailbox *destbox,
                keywords = str_array_length(keywords_list) == 0 ? NULL :
                        mailbox_keywords_create_valid(destbox, keywords_list);
 
-               ret = mailbox_copy(dest_trans, mail, mail_get_flags(mail),
-                                  keywords, NULL);
+               save_ctx = mailbox_save_alloc(dest_trans);
+               mailbox_save_set_flags(save_ctx, mail_get_flags(mail),
+                                      keywords);
+               ret = mailbox_copy(&save_ctx, mail);
                mailbox_keywords_free(destbox, &keywords);
                if (ret < 0) {
                        *error_r = storage_error(destbox->storage);
index 74fe2ba2a60a4011decc27a4524c68c295bf80aa..459b754122607f106bdd13e9d83a486ec39dc67f 100644 (file)
@@ -213,16 +213,14 @@ static int expire_save_finish(struct mail_save_context *ctx)
 }
 
 static int
-expire_copy(struct mailbox_transaction_context *t, struct mail *mail,
-           enum mail_flags flags, struct mail_keywords *keywords,
-           struct mail *dest_mail)
+expire_copy(struct mail_save_context *ctx, struct mail *mail)
 {
-       struct expire_transaction_context *xt = EXPIRE_CONTEXT(t);
-       struct expire_mailbox *xpr_box = EXPIRE_CONTEXT(t->box);
+       struct expire_transaction_context *xt =
+               EXPIRE_CONTEXT(ctx->transaction);
+       struct expire_mailbox *xpr_box = EXPIRE_CONTEXT(ctx->transaction->box);
 
        xt->saves = TRUE;
-       return xpr_box->module_ctx.super.
-               copy(t, mail, flags, keywords, dest_mail);
+       return xpr_box->module_ctx.super.copy(ctx, mail);
 }
 
 static void
index bde0b277f62bf06a5dfec6b02232ba9776d6e1aa..0fba83e69d75467cf7f9bbb1097df15fc470c445 100644 (file)
@@ -433,20 +433,20 @@ mail_log_mail_alloc(struct mailbox_transaction_context *t,
 }
 
 static int
-mail_log_copy(struct mailbox_transaction_context *t, struct mail *mail,
-             enum mail_flags flags, struct mail_keywords *keywords,
-             struct mail *dest_mail)
+mail_log_copy(struct mail_save_context *ctx, struct mail *mail)
 {
-       union mailbox_module_context *lbox = MAIL_LOG_CONTEXT(t->box);
+       union mailbox_module_context *lbox =
+               MAIL_LOG_CONTEXT(ctx->transaction->box);
        const char *name;
 
-       if (lbox->super.copy(t, mail, flags, keywords, dest_mail) < 0)
+       if (lbox->super.copy(ctx, mail) < 0)
                return -1;
 
        T_BEGIN {
-               name = str_sanitize(mailbox_get_name(t->box),
+               name = str_sanitize(mailbox_get_name(ctx->transaction->box),
                                    MAILBOX_NAME_LOG_LEN);
-               mail_log_action(t, mail, MAIL_LOG_EVENT_COPY, name);
+               mail_log_action(ctx->transaction, mail,
+                               MAIL_LOG_EVENT_COPY, name);
        } T_END;
        return 0;
 }
index 1e2901da067cf161ed9b671448ef0ec7838ca99f..c9b21cbfcf09edb386bea2591e1a55f41a33fab0 100644 (file)
@@ -40,6 +40,7 @@ static int mbox_snarf(struct mailbox *srcbox, struct mailbox *destbox)
        struct mail_search_args *search_args;
        struct mail_search_context *search_ctx;
         struct mailbox_transaction_context *src_trans, *dest_trans;
+       struct mail_save_context *save_ctx;
        struct mail *mail;
        enum mail_error error;
        int ret;
@@ -62,8 +63,8 @@ static int mbox_snarf(struct mailbox *srcbox, struct mailbox *destbox)
                if (mail->expunged)
                        continue;
 
-               if (mailbox_copy(dest_trans, mail, 0, NULL, NULL) < 0 &&
-                   !mail->expunged) {
+               save_ctx = mailbox_save_alloc(dest_trans);
+               if (mailbox_copy(&save_ctx, mail) < 0 && !mail->expunged) {
                        (void)mail_storage_get_last_error(destbox->storage,
                                                          &error);
                        /* if we failed because of out of disk space, just
index 413eb1c53c156f58e077b29d84fcfb5958c487c8..fa68242c35604bbd226de0b8d8b971eed259c89b 100644 (file)
@@ -170,30 +170,28 @@ static int quota_check(struct mailbox_transaction_context *t, struct mail *mail)
 }
 
 static int
-quota_copy(struct mailbox_transaction_context *t, struct mail *mail,
-          enum mail_flags flags, struct mail_keywords *keywords,
-          struct mail *dest_mail)
+quota_copy(struct mail_save_context *ctx, struct mail *mail)
 {
+       struct mailbox_transaction_context *t = ctx->transaction;
        struct quota_transaction_context *qt = QUOTA_CONTEXT(t);
        struct quota_mailbox *qbox = QUOTA_CONTEXT(t->box);
 
-       if (dest_mail == NULL) {
+       if (ctx->dest_mail == NULL) {
                /* we always want to know the mail size */
                if (qt->tmp_mail == NULL) {
                        qt->tmp_mail = mail_alloc(t, MAIL_FETCH_PHYSICAL_SIZE,
                                                  NULL);
                }
-               dest_mail = qt->tmp_mail;
+               ctx->dest_mail = qt->tmp_mail;
        }
 
        qbox->save_hack = FALSE;
-       if (qbox->module_ctx.super.copy(t, mail, flags, keywords,
-                                       dest_mail) < 0)
+       if (qbox->module_ctx.super.copy(ctx, mail) < 0)
                return -1;
 
        /* if copying used saving internally, we already checked the quota
           and set qbox->save_hack = TRUE. */
-       return qbox->save_hack ? 0 : quota_check(t, dest_mail);
+       return qbox->save_hack ? 0 : quota_check(t, ctx->dest_mail);
 }
 
 static int