[dovecot-cvs] dovecot/src/imap cmd-append.c, 1.97, 1.98 cmd-copy.c, 1.36, 1.37

tss at dovecot.org tss at dovecot.org
Tue Apr 17 20:19:44 EEST 2007


Update of /var/lib/cvs/dovecot/src/imap
In directory talvi:/tmp/cvs-serv1757/src/imap

Modified Files:
	cmd-append.c cmd-copy.c 
Log Message:
Implemented UIDPLUS extension.



Index: cmd-append.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/imap/cmd-append.c,v
retrieving revision 1.97
retrieving revision 1.98
diff -u -d -r1.97 -r1.98
--- cmd-append.c	25 Mar 2007 21:53:11 -0000	1.97
+++ cmd-append.c	17 Apr 2007 17:19:40 -0000	1.98
@@ -25,6 +25,7 @@
 	struct imap_parser *save_parser;
 	struct mail_save_context *save_ctx;
 	struct mailbox_keywords old_keywords;
+	unsigned int count;
 
 	unsigned int message_input:1;
 	unsigned int failed:1;
@@ -231,6 +232,9 @@
 	if (args->type == IMAP_ARG_EOL) {
 		/* last message */
 		enum mailbox_sync_flags sync_flags;
+		struct mailbox_status status;
+		uint32_t uid1, uid2;
+		const char *msg;
 
 		/* eat away the trailing CRLF */
 		client->input_skip_line = TRUE;
@@ -241,18 +245,37 @@
 			return TRUE;
 		}
 
-		ret = mailbox_transaction_commit(&ctx->t, 0);
+		if (mailbox_get_status(ctx->box, STATUS_UIDVALIDITY,
+				       &status) < 0) {
+			client_send_storage_error(cmd, ctx->storage);
+			cmd_append_finish(ctx);
+			return TRUE;
+		}
+
+		ret = mailbox_transaction_commit_get_uids(&ctx->t, 0,
+							  &uid1, &uid2);
 		if (ret < 0) {
 			client_send_storage_error(cmd, ctx->storage);
 			cmd_append_finish(ctx);
 			return TRUE;
 		}
+		i_assert(ctx->count == uid2 - uid1 + 1);
+
+		if (uid1 == uid2) {
+			msg = t_strdup_printf("OK [APPENDUID %u %u] "
+					      "Append completed.",
+					      status.uidvalidity, uid1);
+		} else {
+			msg = t_strdup_printf("OK [APPENDUID %u %u:%u] "
+					      "Append completed.",
+					      status.uidvalidity, uid1, uid2);
+		}
 
 		sync_flags = ctx->box == cmd->client->mailbox ?
 			0 : MAILBOX_SYNC_FLAG_FAST;
 
 		cmd_append_finish(ctx);
-		return cmd_sync(cmd, sync_flags, 0, "OK Append completed.");
+		return cmd_sync(cmd, sync_flags, 0, msg);
 	}
 
 	if (!validate_args(args, &flags_list, &internal_date_str,
@@ -321,6 +344,7 @@
 		o_stream_uncork(client->output);
 	}
 
+	ctx->count++;
 	ctx->message_input = TRUE;
 	cmd->func = cmd_append_continue_message;
 	return cmd_append_continue_message(cmd);
@@ -473,7 +497,8 @@
 			ctx->failed = TRUE;
 		} else {
 			ctx->t = mailbox_transaction_begin(ctx->box,
-					MAILBOX_TRANSACTION_FLAG_EXTERNAL);
+					MAILBOX_TRANSACTION_FLAG_EXTERNAL |
+					MAILBOX_TRANSACTION_FLAG_ASSIGN_UIDS);
 		}
 	}
 

Index: cmd-copy.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/imap/cmd-copy.c,v
retrieving revision 1.36
retrieving revision 1.37
diff -u -d -r1.36 -r1.37
--- cmd-copy.c	21 Mar 2007 19:19:52 -0000	1.36
+++ cmd-copy.c	17 Apr 2007 17:19:40 -0000	1.37
@@ -27,7 +27,9 @@
 
 static int fetch_and_copy(struct client *client,
 			  struct mailbox_transaction_context *t,
-			  struct mail_search_arg *search_args)
+			  struct mail_search_arg *search_args,
+			  const char **src_uidset_r,
+			  unsigned int *copy_count_r)
 {
 	struct mail_search_context *search_ctx;
         struct mailbox_transaction_context *src_trans;
@@ -35,8 +37,13 @@
 	const char *const *keywords_list;
 	struct mail *mail;
 	unsigned int copy_count = 0;
+	struct msgset_generator_context srcset_ctx;
+	string_t *src_uidset;
 	int ret;
 
+	src_uidset = t_str_new(256);
+	msgset_generator_init(&srcset_ctx, src_uidset);
+
 	src_trans = mailbox_transaction_begin(client->mailbox, 0);
 	search_ctx = mailbox_search_init(src_trans, NULL, search_args, NULL);
 
@@ -59,8 +66,11 @@
 				 keywords, NULL) < 0)
 			ret = mail->expunged ? 0 : -1;
 		mailbox_keywords_free(t, &keywords);
+
+		msgset_generator_next(&srcset_ctx, mail->uid);
 	}
 	mail_free(&mail);
+	msgset_generator_finish(&srcset_ctx);
 
 	if (mailbox_search_deinit(&search_ctx) < 0)
 		ret = -1;
@@ -68,6 +78,8 @@
 	if (mailbox_transaction_commit(&src_trans, 0) < 0)
 		ret = -1;
 
+	*src_uidset_r = str_c(src_uidset);
+	*copy_count_r = copy_count;
 	return ret;
 }
 
@@ -78,8 +90,11 @@
 	struct mailbox *destbox;
 	struct mailbox_transaction_context *t;
         struct mail_search_arg *search_arg;
-	const char *messageset, *mailbox;
+	struct mailbox_status status;
+	const char *messageset, *mailbox, *src_uidset, *msg = NULL;
         enum mailbox_sync_flags sync_flags = 0;
+	unsigned int copy_count;
+	uint32_t uid1, uid2;
 	int ret;
 
 	/* <message set> <mailbox> */
@@ -115,14 +130,34 @@
 	}
 
 	t = mailbox_transaction_begin(destbox,
-				      MAILBOX_TRANSACTION_FLAG_EXTERNAL);
-	ret = fetch_and_copy(client, t, search_arg);
+				      MAILBOX_TRANSACTION_FLAG_EXTERNAL |
+				      MAILBOX_TRANSACTION_FLAG_ASSIGN_UIDS);
+	ret = fetch_and_copy(client, t, search_arg, &src_uidset, &copy_count);
+
+	if (ret > 0 &&
+	    mailbox_get_status(destbox, STATUS_UIDVALIDITY, &status) < 0) {
+		client_send_storage_error(cmd, storage);
+		ret = -1;
+	}
 
 	if (ret <= 0)
 		mailbox_transaction_rollback(&t);
+	else if (mailbox_transaction_commit_get_uids(&t, 0, &uid1, &uid2) < 0)
+		ret = -1;
 	else {
-		if (mailbox_transaction_commit(&t, 0) < 0)
-			ret = -1;
+		i_assert(copy_count == uid2 - uid1 + 1);
+
+		if (uid1 == uid2) {
+			msg = t_strdup_printf("OK [COPYUID %u %s %u] "
+					      "Copy completed.",
+					      status.uidvalidity,
+					      src_uidset, uid1);
+		} else {
+			msg = t_strdup_printf("OK [COPYUID %u %s %u:%u] "
+					      "Copy completed.",
+					      status.uidvalidity,
+					      src_uidset, uid1, uid2);
+		}
 	}
 
 	if (destbox != client->mailbox) {
@@ -131,7 +166,7 @@
 	}
 
 	if (ret > 0)
-		return cmd_sync(cmd, sync_flags, 0, "OK Copy completed.");
+		return cmd_sync(cmd, sync_flags, 0, msg);
 	else if (ret == 0) {
 		/* some messages were expunged, sync them */
 		return cmd_sync(cmd, 0, 0,



More information about the dovecot-cvs mailing list