changeset 633:3814fc4f4135 HEAD

COPYing inside same mailbox works now with mbox. Also fixed SAVE leaving From-line written to mbox file if it was aborted.
author Timo Sirainen <tss@iki.fi>
date Wed, 20 Nov 2002 20:31:15 +0200
parents 8efd9f63e333
children 339c176aba1e
files src/lib-storage/index/index-copy.c src/lib-storage/index/index-storage.h src/lib-storage/index/mbox/mbox-save.c
diffstat 3 files changed, 36 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-storage/index/index-copy.c	Wed Nov 20 20:28:15 2002 +0200
+++ b/src/lib-storage/index/index-copy.c	Wed Nov 20 20:31:15 2002 +0200
@@ -11,6 +11,7 @@
 typedef struct {
 	Mailbox *dest;
 	const char **custom_flags;
+	int copy_inside_mailbox;
 } CopyContext;
 
 static int copy_func(MailIndex *index, MailIndexRecord *rec,
@@ -18,6 +19,7 @@
 		     unsigned int idx_seq __attr_unused__, void *context)
 {
 	CopyContext *ctx = context;
+	IndexMailbox *dest_ibox = NULL;
 	IBuffer *inbuf;
 	time_t internal_date;
 	int failed, deleted;
@@ -26,10 +28,19 @@
 	if (inbuf == NULL)
 		return FALSE;
 
+	if (ctx->copy_inside_mailbox) {
+                /* kludgy.. */
+		dest_ibox = (IndexMailbox *) ctx->dest;
+		dest_ibox->delay_save_unlocking = TRUE;
+	}
+
 	/* save it in destination mailbox */
 	failed = !ctx->dest->save(ctx->dest, rec->msg_flags,
 				  ctx->custom_flags, internal_date, 0,
-				  inbuf, inbuf->v_size);
+				  inbuf, inbuf->v_limit);
+
+	if (ctx->copy_inside_mailbox)
+		dest_ibox->delay_save_unlocking = FALSE;
 
 	i_buffer_unref(inbuf);
 	return !failed;
@@ -49,9 +60,19 @@
 		return FALSE;
 	}
 
-	lock_type = destbox->storage == box->storage &&
-		strcmp(destbox->name, box->name) == 0 ?
-		MAIL_LOCK_EXCLUSIVE : MAIL_LOCK_SHARED;
+	ctx.copy_inside_mailbox =
+		destbox->storage == box->storage &&
+		strcmp(destbox->name, box->name) == 0;
+
+	if (ctx.copy_inside_mailbox) {
+		/* copying inside same mailbox */
+		if (!ibox->index->set_lock(ibox->index, MAIL_LOCK_EXCLUSIVE))
+			return mail_storage_set_index_error(ibox);
+
+		lock_type = MAIL_LOCK_EXCLUSIVE;
+	} else {
+		lock_type = MAIL_LOCK_SHARED;
+	}
 
 	if (!index_storage_sync_and_lock(ibox, TRUE, lock_type))
 		return FALSE;
--- a/src/lib-storage/index/index-storage.h	Wed Nov 20 20:28:15 2002 +0200
+++ b/src/lib-storage/index/index-storage.h	Wed Nov 20 20:31:15 2002 +0200
@@ -28,6 +28,7 @@
 	unsigned int synced_messages_count;
 
 	unsigned int sent_diskspace_warning:1;
+	unsigned int delay_save_unlocking:1; /* For COPYing inside mailbox */
 };
 
 extern ImapMessageCacheIface index_msgcache_iface;
--- a/src/lib-storage/index/mbox/mbox-save.c	Wed Nov 20 20:28:15 2002 +0200
+++ b/src/lib-storage/index/mbox/mbox-save.c	Wed Nov 20 20:31:15 2002 +0200
@@ -176,7 +176,7 @@
 		return FALSE;
 	}
 
-	/* we don't need the real flags, easier to keep using our own.
+	/* we don't need the real flag positions, easier to keep using our own.
 	   they need to be checked/added though. */
 	real_flags = flags;
 	if (!index_mailbox_fix_custom_flags(ibox, &real_flags, custom_flags))
@@ -205,7 +205,10 @@
 		    !index_storage_save(box->storage, mbox_path,
 					data, outbuf, data_size) ||
 		    !mbox_append_lf(box->storage, outbuf, mbox_path)) {
-			/* failed, truncate file back to original size */
+			/* failed, truncate file back to original size.
+			   output buffer needs to be flushed before truncating
+			   so unref() won't write anything. */
+			o_buffer_flush(outbuf);
 			(void)ftruncate(index->mbox_fd, pos);
 			failed = TRUE;
 		}
@@ -213,8 +216,11 @@
 		t_pop();
 	}
 
-	if (!ibox->index->set_lock(ibox->index, MAIL_LOCK_UNLOCK))
-		return mail_storage_set_index_error(ibox);
+	/* kludgy.. for copying inside same mailbox. */
+	if (!ibox->delay_save_unlocking) {
+		if (!ibox->index->set_lock(ibox->index, MAIL_LOCK_UNLOCK))
+			return mail_storage_set_index_error(ibox);
+	}
 
 	return !failed;
 }