[dovecot-cvs] dovecot/src/lib-storage/index/maildir maildir-copy.c,1.25,1.26 maildir-storage.c,1.45,1.46 maildir-storage.h,1.15,1.16

cras at procontrol.fi cras at procontrol.fi
Wed Jul 23 04:40:52 EEST 2003


Update of /home/cvs/dovecot/src/lib-storage/index/maildir
In directory danu:/tmp/cvs-serv408/lib-storage/index/maildir

Modified Files:
	maildir-copy.c maildir-storage.c maildir-storage.h 
Log Message:
API change for copying messages.



Index: maildir-copy.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/maildir/maildir-copy.c,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -d -r1.25 -r1.26
--- maildir-copy.c	18 Jun 2003 22:20:51 -0000	1.25
+++ maildir-copy.c	23 Jul 2003 00:40:50 -0000	1.26
@@ -11,6 +11,16 @@
 #include <stdlib.h>
 #include <unistd.h>
 
+struct maildir_copy_context {
+	struct index_mailbox *ibox;
+	int hardlink;
+
+	pool_t pool;
+	struct rollback *rollbacks;
+
+	struct mail_copy_context *ctx;
+};
+
 struct rollback {
 	struct rollback *next;
 	const char *fname;
@@ -64,139 +74,122 @@
 	return 0;
 }
 
-static int hardlink_messageset(struct messageset_context *ctx,
-			       struct index_mailbox *src,
-			       struct index_mailbox *dest)
+static int maildir_copy_hardlink(struct mail *mail,
+				 struct maildir_copy_context *ctx)
 {
-	struct mail_index *index = src->index;
-	pool_t pool;
-        struct rollback *rollbacks, *rb;
-        const struct messageset_mail *mail;
-	enum mail_flags flags;
-	const char **custom_flags;
+	struct index_mail *imail = (struct index_mail *) mail;
+        struct rollback *rb;
 	const char *fname, *dest_fname, *dest_path;
-	int ret, i, found;
+	enum mail_flags flags;
+	int i, ret, found;
 
-	pool = pool_alloconly_create("hard copy rollbacks", 2048);
-	rollbacks = NULL;
+	flags = mail->get_flags(mail)->flags;
 
-	custom_flags = mail_custom_flags_list_get(index->custom_flags);
+	/* link the file */
+	dest_fname = maildir_generate_tmp_filename(&ioloop_timeval);
+	dest_fname = maildir_filename_set_flags(dest_fname, flags);
+	dest_path = t_strconcat(ctx->ibox->index->mailbox_path, "/new/",
+				dest_fname, NULL);
 
-	ret = 1;
-	while (ret > 0 && (mail = index_messageset_next(ctx)) != NULL) {
-		flags = mail->rec->msg_flags;
-		if (!index_mailbox_fix_custom_flags(dest, &flags,
-						    custom_flags,
-						    MAIL_CUSTOM_FLAGS_COUNT)) {
-			ret = -1;
+	for (i = 0;; i++) {
+		ret = maildir_hardlink_file(imail->ibox->index, imail->data.rec,
+					    &fname, dest_path);
+		if (ret != 0)
 			break;
-		}
-
-		/* link the file */
-		t_push();
 
-		dest_fname = maildir_generate_tmp_filename(&ioloop_timeval);
-		dest_fname = maildir_filename_set_flags(dest_fname, flags);
-		dest_path = t_strconcat(dest->index->mailbox_path, "/new/",
-					dest_fname, NULL);
-
-		for (i = 0;; i++) {
-			ret = maildir_hardlink_file(index, mail->rec, &fname,
-						    dest_path);
-			if (ret > 0) {
-				rb = p_new(pool, struct rollback, 1);
-				rb->fname = p_strdup(pool, dest_fname);
-				rb->next = rollbacks;
-				rollbacks = rb;
-				break;
-			}
-			if (ret < 0)
-				break;
-
-			if (i == 10) {
-                                mail_storage_set_error(src->box.storage,
-					"File name keeps changing, "
-					"copy failed");
-				break;
-			}
-
-			if (!maildir_index_sync_readonly(index, fname, &found))
-				break;
+		if (i == 10) {
+			mail_storage_set_error(mail->box->storage,
+				"File name keeps changing, copy failed");
+			break;
+		}
 
-			if (!found)
-				break;
+		if (!maildir_index_sync_readonly(imail->ibox->index, fname,
+						 &found)) {
+			ret = -1;
+			break;
 		}
-		t_pop();
+
+		if (!found)
+			break;
 	}
 
-	if (ret <= 0) {
-		for (rb = rollbacks; rb != NULL; rb = rb->next) {
-			t_push();
-			(void)unlink(t_strconcat(dest->index->mailbox_path,
-						 "new/", rb->fname, NULL));
-			t_pop();
+	if (ret > 0) {
+		if (ctx->pool == NULL) {
+			ctx->pool = pool_alloconly_create("hard copy rollbacks",
+							  2048);
 		}
+
+		rb = p_new(ctx->pool, struct rollback, 1);
+		rb->fname = p_strdup(ctx->pool, dest_fname);
+		rb->next = ctx->rollbacks;
+		ctx->rollbacks = rb;
 	}
 
-	pool_unref(pool);
 	return ret;
 }
 
-static int copy_with_hardlinks(struct index_mailbox *src,
-			       struct index_mailbox *dest,
-			       const char *messageset, int uidset)
+struct mail_copy_context *maildir_storage_copy_init(struct mailbox *box)
 {
-        struct messageset_context *ctx;
-	int exdev, ret, ret2;
+	struct index_mailbox *ibox = (struct index_mailbox *) box;
+	struct maildir_copy_context *ctx;
 
-	if (!src->index->set_lock(src->index, MAIL_LOCK_SHARED))
-		return -1;
+	if (box->readonly) {
+		mail_storage_set_error(box->storage,
+				       "Destination mailbox is read-only");
+		return NULL;
+	}
 
-	ctx = index_messageset_init(src, messageset, uidset, FALSE);
-	ret = hardlink_messageset(ctx, src, dest);
-	exdev = ret < 0 && errno == EXDEV;
-	ret2 = index_messageset_deinit(ctx);
+	ctx = i_new(struct maildir_copy_context, 1);
+	ctx->hardlink = getenv("MAILDIR_COPY_WITH_HARDLINKS") != NULL;
+	ctx->ibox = ibox;
+	return (struct mail_copy_context *) ctx;
+}
 
-	if (ret2 < 0)
-		ret = -1;
+int maildir_storage_copy_deinit(struct mail_copy_context *_ctx, int rollback)
+{
+	struct maildir_copy_context *ctx = (struct maildir_copy_context *) _ctx;
+        struct rollback *rb;
+	int ret = TRUE;
 
-	if (ret == 0 || ret2 == 0) {
-		mail_storage_set_error(src->box.storage,
-			"Some of the requested messages no longer exist.");
-		ret = -1;
+	if (ctx->ctx != NULL)
+		ret = index_storage_copy_deinit(ctx->ctx, rollback);
+
+	if (rollback) {
+		for (rb = ctx->rollbacks; rb != NULL; rb = rb->next) {
+			t_push();
+			(void)unlink(t_strconcat(ctx->ibox->index->mailbox_path,
+						 "/new/", rb->fname, NULL));
+			t_pop();
+		}
 	}
 
-	(void)index_storage_lock(src, MAIL_LOCK_UNLOCK);
+	if (ctx->pool != NULL)
+		pool_unref(ctx->pool);
 
-	return exdev ? 0 : ret;
+	i_free(ctx);
+	return ret;
 }
 
-int maildir_storage_copy(struct mailbox *box, struct mailbox *destbox,
-			 const char *messageset, int uidset)
+int maildir_storage_copy(struct mail *mail, struct mail_copy_context *_ctx)
 {
-	struct index_mailbox *ibox = (struct index_mailbox *) box;
+	struct maildir_copy_context *ctx = (struct maildir_copy_context *) _ctx;
+	int ret;
 
-	if (destbox->readonly) {
-		mail_storage_set_error(box->storage,
-				       "Destination mailbox is read-only");
-		return FALSE;
-	}
+	if (ctx->hardlink && mail->box->storage == ctx->ibox->box.storage) {
+		t_push();
+		ret = maildir_copy_hardlink(mail, ctx);
+		t_pop();
 
-	if (getenv("MAILDIR_COPY_WITH_HARDLINKS") != NULL &&
-	    destbox->storage == box->storage) {
-		/* both source and destination mailbox are in maildirs and
-		   copy_with_hardlinks option is on, do it */
-		switch (copy_with_hardlinks(ibox,
-			(struct index_mailbox *) destbox, messageset, uidset)) {
-		case 1:
+		if (ret > 0)
 			return TRUE;
-		case 0:
-			/* non-fatal hardlinking failure, try the slow way */
-			break;
-		default:
+		if (ret < 0)
 			return FALSE;
-		}
+
+		/* non-fatal hardlinking failure, try the slow way */
 	}
 
-	return index_storage_copy(box, destbox, messageset, uidset);
+	if (ctx->ctx == NULL)
+		ctx->ctx = index_storage_copy_init(&ctx->ibox->box);
+
+	return index_storage_copy(mail, ctx->ctx);
 }

Index: maildir-storage.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/maildir/maildir-storage.c,v
retrieving revision 1.45
retrieving revision 1.46
diff -u -d -r1.45 -r1.46
--- maildir-storage.c	15 Jul 2003 18:26:43 -0000	1.45
+++ maildir-storage.c	23 Jul 2003 00:40:50 -0000	1.46
@@ -319,6 +319,11 @@
 		create_control_dir(storage, "INBOX");
 }
 
+static void maildir_mail_init(struct index_mail *mail)
+{
+	mail->mail.copy = maildir_storage_copy;
+}
+
 static struct mailbox *
 maildir_open(struct mail_storage *storage, const char *name,
 	     enum mailbox_open_flags flags)
@@ -339,8 +344,10 @@
 
 	ibox = index_storage_mailbox_init(storage, &maildir_mailbox,
 					  index, name, flags);
-	if (ibox != NULL)
+	if (ibox != NULL) {
 		ibox->expunge_locked = maildir_expunge_locked;
+		ibox->mail_init = maildir_mail_init;
+	}
 	return (struct mailbox *) ibox;
 }
 
@@ -739,7 +746,6 @@
 	maildir_storage_auto_sync,
 	index_storage_expunge,
 	index_storage_update_flags,
-	maildir_storage_copy,
 	index_storage_fetch_init,
 	index_storage_fetch_deinit,
 	index_storage_fetch_next,
@@ -752,6 +758,8 @@
 	maildir_storage_save_init,
 	maildir_storage_save_deinit,
 	maildir_storage_save_next,
+	maildir_storage_copy_init,
+	maildir_storage_copy_deinit,
 	mail_storage_is_inconsistency_error,
 
 	FALSE,

Index: maildir-storage.h
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/maildir/maildir-storage.h,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -d -r1.15 -r1.16
--- maildir-storage.h	9 Apr 2003 20:10:02 -0000	1.15
+++ maildir-storage.h	23 Jul 2003 00:40:50 -0000	1.16
@@ -3,8 +3,9 @@
 
 #include "index-storage.h"
 
-int maildir_storage_copy(struct mailbox *box, struct mailbox *destbox,
-			 const char *messageset, int uidset);
+struct mail_copy_context *maildir_storage_copy_init(struct mailbox *box);
+int maildir_storage_copy_deinit(struct mail_copy_context *ctx, int rollback);
+int maildir_storage_copy(struct mail *mail, struct mail_copy_context *ctx);
 
 struct mail_save_context *
 maildir_storage_save_init(struct mailbox *box, int transaction);



More information about the dovecot-cvs mailing list