From: Timo Sirainen Date: Fri, 6 Feb 2009 17:49:46 +0000 (-0500) Subject: Mail copying API changed to be based on save API. This allows extending it easily... X-Git-Tag: 1.2.beta1~17 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=bd4d0a1a7c0626452b8d82f37e3ec07267ac9896;p=thirdparty%2Fdovecot%2Fcore.git Mail copying API changed to be based on save API. This allows extending it easily in future. --HG-- branch : HEAD --- diff --git a/src/deliver/deliver.c b/src/deliver/deliver.c index 9bde35885b..042c3ac31a 100644 --- a/src/deliver/deliver.c +++ b/src/deliver/deliver.c @@ -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); diff --git a/src/imap/cmd-copy.c b/src/imap/cmd-copy.c index 49553008a9..1180e132ab 100644 --- a/src/imap/cmd-copy.c +++ b/src/imap/cmd-copy.c @@ -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); diff --git a/src/lib-storage/index/maildir/maildir-copy.c b/src/lib-storage/index/maildir/maildir-copy.c index b3bc7a8d4c..e5033d2fd2 100644 --- a/src/lib-storage/index/maildir/maildir-copy.c +++ b/src/lib-storage/index/maildir/maildir-copy.c @@ -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); } diff --git a/src/lib-storage/index/maildir/maildir-storage.h b/src/lib-storage/index/maildir/maildir-storage.h index ed1ecd5e5f..7f5c63c65d 100644 --- a/src/lib-storage/index/maildir/maildir-storage.h +++ b/src/lib-storage/index/maildir/maildir-storage.h @@ -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); diff --git a/src/lib-storage/mail-copy.c b/src/lib-storage/mail-copy.c index 8e5d7e9247..888d175e9c 100644 --- a/src/lib-storage/mail-copy.c +++ b/src/lib-storage/mail-copy.c @@ -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; diff --git a/src/lib-storage/mail-copy.h b/src/lib-storage/mail-copy.h index 89478689a9..c769082db2 100644 --- a/src/lib-storage/mail-copy.h +++ b/src/lib-storage/mail-copy.h @@ -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 diff --git a/src/lib-storage/mail-storage-private.h b/src/lib-storage/mail-storage-private.h index 2f56a6b753..3901346f97 100644 --- a/src/lib-storage/mail-storage-private.h +++ b/src/lib-storage/mail-storage-private.h @@ -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); }; diff --git a/src/lib-storage/mail-storage.c b/src/lib-storage/mail-storage.c index 647e520276..efe5282d83 100644 --- a/src/lib-storage/mail-storage.c +++ b/src/lib-storage/mail-storage.c @@ -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) diff --git a/src/lib-storage/mail-storage.h b/src/lib-storage/mail-storage.h index ac210cc413..2275f1d6b2 100644 --- a/src/lib-storage/mail-storage.h +++ b/src/lib-storage/mail-storage.h @@ -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 diff --git a/src/plugins/acl/acl-mailbox.c b/src/plugins/acl/acl-mailbox.c index 9dbd166810..ab42e53842 100644 --- a/src/plugins/acl/acl-mailbox.c +++ b/src/plugins/acl/acl-mailbox.c @@ -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 diff --git a/src/plugins/convert/convert-storage.c b/src/plugins/convert/convert-storage.c index 9471b2a5ce..a63128b5f5 100644 --- a/src/plugins/convert/convert-storage.c +++ b/src/plugins/convert/convert-storage.c @@ -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); diff --git a/src/plugins/expire/expire-plugin.c b/src/plugins/expire/expire-plugin.c index 74fe2ba2a6..459b754122 100644 --- a/src/plugins/expire/expire-plugin.c +++ b/src/plugins/expire/expire-plugin.c @@ -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 diff --git a/src/plugins/mail-log/mail-log-plugin.c b/src/plugins/mail-log/mail-log-plugin.c index bde0b277f6..0fba83e69d 100644 --- a/src/plugins/mail-log/mail-log-plugin.c +++ b/src/plugins/mail-log/mail-log-plugin.c @@ -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; } diff --git a/src/plugins/mbox-snarf/mbox-snarf-plugin.c b/src/plugins/mbox-snarf/mbox-snarf-plugin.c index 1e2901da06..c9b21cbfcf 100644 --- a/src/plugins/mbox-snarf/mbox-snarf-plugin.c +++ b/src/plugins/mbox-snarf/mbox-snarf-plugin.c @@ -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 diff --git a/src/plugins/quota/quota-storage.c b/src/plugins/quota/quota-storage.c index 413eb1c53c..fa68242c35 100644 --- a/src/plugins/quota/quota-storage.c +++ b/src/plugins/quota/quota-storage.c @@ -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