changeset 8726:68db63cc32b3 HEAD

Mail copying API changed to be based on save API. This allows extending it easily in future.
author Timo Sirainen <tss@iki.fi>
date Fri, 06 Feb 2009 12:49:46 -0500
parents c7142c9ac3c1
children d2c357625ef2
files 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
diffstat 15 files changed, 82 insertions(+), 85 deletions(-) [+]
line wrap: on
line diff
--- a/src/deliver/deliver.c	Fri Feb 06 12:48:38 2009 -0500
+++ b/src/deliver/deliver.c	Fri Feb 06 12:49:46 2009 -0500
@@ -204,6 +204,7 @@
 {
 	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 @@
 
 	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);
 
--- a/src/imap/cmd-copy.c	Fri Feb 06 12:48:38 2009 -0500
+++ b/src/imap/cmd-copy.c	Fri Feb 06 12:49:46 2009 -0500
@@ -35,6 +35,7 @@
 {
 	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 @@
 		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);
 
--- a/src/lib-storage/index/maildir/maildir-copy.c	Fri Feb 06 12:48:38 2009 -0500
+++ b/src/lib-storage/index/maildir/maildir-copy.c	Fri Feb 06 12:49:46 2009 -0500
@@ -259,29 +259,28 @@
 		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);
 }
--- a/src/lib-storage/index/maildir/maildir-storage.h	Fri Feb 06 12:48:38 2009 -0500
+++ b/src/lib-storage/index/maildir/maildir-storage.h	Fri Feb 06 12:49:46 2009 -0500
@@ -148,9 +148,7 @@
 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);
 
--- a/src/lib-storage/mail-copy.c	Fri Feb 06 12:48:38 2009 -0500
+++ b/src/lib-storage/mail-copy.c	Fri Feb 06 12:49:46 2009 -0500
@@ -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 @@
 	} 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;
--- a/src/lib-storage/mail-copy.h	Fri Feb 06 12:48:38 2009 -0500
+++ b/src/lib-storage/mail-copy.h	Fri Feb 06 12:49:46 2009 -0500
@@ -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
--- a/src/lib-storage/mail-storage-private.h	Fri Feb 06 12:48:38 2009 -0500
+++ b/src/lib-storage/mail-storage-private.h	Fri Feb 06 12:49:46 2009 -0500
@@ -176,10 +176,7 @@
 	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);
 };
--- a/src/lib-storage/mail-storage.c	Fri Feb 06 12:48:38 2009 -0500
+++ b/src/lib-storage/mail-storage.c	Fri Feb 06 12:49:46 2009 -0500
@@ -915,11 +915,12 @@
 	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)
--- a/src/lib-storage/mail-storage.h	Fri Feb 06 12:48:38 2009 -0500
+++ b/src/lib-storage/mail-storage.h	Fri Feb 06 12:49:46 2009 -0500
@@ -527,12 +527,9 @@
 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
--- a/src/plugins/acl/acl-mailbox.c	Fri Feb 06 12:48:38 2009 -0500
+++ b/src/plugins/acl/acl-mailbox.c	Fri Feb 06 12:49:46 2009 -0500
@@ -287,10 +287,9 @@
 }
 
 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_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
--- a/src/plugins/convert/convert-storage.c	Fri Feb 06 12:48:38 2009 -0500
+++ b/src/plugins/convert/convert-storage.c	Fri Feb 06 12:49:46 2009 -0500
@@ -34,6 +34,7 @@
 {
 	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 @@
 		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);
--- a/src/plugins/expire/expire-plugin.c	Fri Feb 06 12:48:38 2009 -0500
+++ b/src/plugins/expire/expire-plugin.c	Fri Feb 06 12:49:46 2009 -0500
@@ -213,16 +213,14 @@
 }
 
 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
--- a/src/plugins/mail-log/mail-log-plugin.c	Fri Feb 06 12:48:38 2009 -0500
+++ b/src/plugins/mail-log/mail-log-plugin.c	Fri Feb 06 12:49:46 2009 -0500
@@ -433,20 +433,20 @@
 }
 
 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;
 }
--- a/src/plugins/mbox-snarf/mbox-snarf-plugin.c	Fri Feb 06 12:48:38 2009 -0500
+++ b/src/plugins/mbox-snarf/mbox-snarf-plugin.c	Fri Feb 06 12:49:46 2009 -0500
@@ -40,6 +40,7 @@
 	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 @@
 		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
--- a/src/plugins/quota/quota-storage.c	Fri Feb 06 12:48:38 2009 -0500
+++ b/src/plugins/quota/quota-storage.c	Fri Feb 06 12:49:46 2009 -0500
@@ -170,30 +170,28 @@
 }
 
 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