dovecot-2.2: imap: Implemented MOVE extension.

dovecot at dovecot.org dovecot at dovecot.org
Wed Jun 20 06:22:14 EEST 2012


details:   http://hg.dovecot.org/dovecot-2.2/rev/3a53a2f7927a
changeset: 14616:3a53a2f7927a
user:      Timo Sirainen <tss at iki.fi>
date:      Wed Jun 20 06:21:17 2012 +0300
description:
imap: Implemented MOVE extension.

diffstat:

 src/imap/cmd-copy.c      |  47 +++++++++++++++++++++++++++++++++++++----------
 src/imap/imap-commands.c |   2 ++
 src/imap/imap-commands.h |   1 +
 3 files changed, 40 insertions(+), 10 deletions(-)

diffs (128 lines):

diff -r 0a2126680120 -r 3a53a2f7927a src/imap/cmd-copy.c
--- a/src/imap/cmd-copy.c	Wed Jun 20 06:17:40 2012 +0300
+++ b/src/imap/cmd-copy.c	Wed Jun 20 06:21:17 2012 +0300
@@ -28,7 +28,7 @@
 	}
 }
 
-static int fetch_and_copy(struct client *client,
+static int fetch_and_copy(struct client *client, bool move,
 			  struct mailbox_transaction_context *t,
 			  struct mail_search_args *search_args,
 			  const char **src_uidset_r,
@@ -62,8 +62,15 @@
 		save_ctx = mailbox_save_alloc(t);
 		mailbox_save_copy_flags(save_ctx, mail);
 
-		if (mailbox_copy(&save_ctx, mail) < 0)
-			ret = mail->expunged ? 0 : -1;
+		if (move) {
+			if (mailbox_move(&save_ctx, mail) < 0)
+				ret = -1;
+		} else {
+			if (mailbox_copy(&save_ctx, mail) < 0)
+				ret = -1;
+		}
+		if (ret < 0 && mail->expunged)
+			ret = 0;
 
 		msgset_generator_next(&srcset_ctx, mail->uid);
 	}
@@ -72,15 +79,20 @@
 	if (mailbox_search_deinit(&search_ctx) < 0)
 		ret = -1;
 
-	if (mailbox_transaction_commit(&src_trans) < 0)
-		ret = -1;
+	if (ret <= 0 && move) {
+		/* move failed, don't expunge anything */
+		mailbox_transaction_rollback(&src_trans);
+	} else {
+		if (mailbox_transaction_commit(&src_trans) < 0)
+			ret = -1;
+	}
 
 	*src_uidset_r = str_c(src_uidset);
 	*copy_count_r = copy_count;
 	return ret;
 }
 
-bool cmd_copy(struct client_command_context *cmd)
+static bool cmd_copy_full(struct client_command_context *cmd, bool move)
 {
 	struct client *client = cmd->client;
 	struct mail_storage *dest_storage;
@@ -114,7 +126,8 @@
 	t = mailbox_transaction_begin(destbox,
 				      MAILBOX_TRANSACTION_FLAG_EXTERNAL |
 				      MAILBOX_TRANSACTION_FLAG_ASSIGN_UIDS);
-	ret = fetch_and_copy(client, t, search_args, &src_uidset, &copy_count);
+	ret = fetch_and_copy(client, move, t, search_args,
+			     &src_uidset, &copy_count);
 	mail_search_args_unref(&search_args);
 
 	msg = t_str_new(256);
@@ -123,11 +136,12 @@
 	else if (mailbox_transaction_commit_get_changes(&t, &changes) < 0)
 		ret = -1;
 	else if (copy_count == 0) {
-		str_append(msg, "OK No messages copied.");
+		str_append(msg, "OK No messages found.");
 		pool_unref(&changes.pool);
 	} else if (seq_range_count(&changes.saved_uids) == 0) {
 		/* not supported by backend (virtual) */
-		str_append(msg, "OK Copy completed.");
+		str_append(msg, move ? "OK Move completed." :
+			   "OK Copy completed.");
 		pool_unref(&changes.pool);
 	} else {
 		i_assert(copy_count == seq_range_count(&changes.saved_uids));
@@ -135,7 +149,10 @@
 		str_printfa(msg, "OK [COPYUID %u %s ", changes.uid_validity,
 			    src_uidset);
 		imap_write_seq_range(msg, &changes.saved_uids);
-		str_append(msg, "] Copy completed.");
+		if (move)
+			str_append(msg, "] Move completed.");
+		else
+			str_append(msg, "] Copy completed.");
 		pool_unref(&changes.pool);
 	}
 
@@ -158,3 +175,13 @@
 		return TRUE;
 	}
 }
+
+bool cmd_copy(struct client_command_context *cmd)
+{
+	return cmd_copy_full(cmd, FALSE);
+}
+
+bool cmd_uid_move(struct client_command_context *cmd)
+{
+	return cmd_copy_full(cmd, TRUE);
+}
diff -r 0a2126680120 -r 3a53a2f7927a src/imap/imap-commands.c
--- a/src/imap/imap-commands.c	Wed Jun 20 06:17:40 2012 +0300
+++ b/src/imap/imap-commands.c	Wed Jun 20 06:21:17 2012 +0300
@@ -56,6 +56,8 @@
 	{ "SORT",		cmd_sort,        COMMAND_FLAG_USES_SEQS },
 	{ "THREAD",		cmd_thread,      COMMAND_FLAG_USES_SEQS },
 	{ "UID EXPUNGE",	cmd_uid_expunge, COMMAND_FLAG_BREAKS_SEQS },
+	{ "UID MOVE",		cmd_uid_move,    COMMAND_FLAG_USES_SEQS |
+						 COMMAND_FLAG_BREAKS_SEQS },
 	{ "UID SORT",		cmd_sort,        COMMAND_FLAG_BREAKS_SEQS },
 	{ "UID THREAD",		cmd_thread,      COMMAND_FLAG_BREAKS_SEQS },
 	{ "UNSELECT",		cmd_unselect,    COMMAND_FLAG_BREAKS_MAILBOX },
diff -r 0a2126680120 -r 3a53a2f7927a src/imap/imap-commands.h
--- a/src/imap/imap-commands.h	Wed Jun 20 06:17:40 2012 +0300
+++ b/src/imap/imap-commands.h	Wed Jun 20 06:21:17 2012 +0300
@@ -110,6 +110,7 @@
 bool cmd_sort(struct client_command_context *cmd);
 bool cmd_thread(struct client_command_context *cmd);
 bool cmd_uid_expunge(struct client_command_context *cmd);
+bool cmd_uid_move(struct client_command_context *cmd);
 bool cmd_unselect(struct client_command_context *cmd);
 bool cmd_x_cancel(struct client_command_context *cmd);
 


More information about the dovecot-cvs mailing list