[dovecot-cvs] dovecot/src/imap cmd-append.c, 1.35, 1.36 cmd-close.c, 1.12, 1.13 cmd-copy.c, 1.18, 1.19 cmd-expunge.c, 1.6, 1.7 cmd-select.c, 1.26, 1.27 cmd-status.c, 1.16, 1.17 commands-util.c, 1.31, 1.32 commands-util.h, 1.14, 1.15 commands.c, 1.12, 1.13 commands.h, 1.13, 1.14 imap-expunge.c, 1.2, 1.3 imap-expunge.h, 1.2, 1.3

cras at procontrol.fi cras at procontrol.fi
Sun Jun 20 06:25:35 EEST 2004


Update of /home/cvs/dovecot/src/imap
In directory talvi:/tmp/cvs-serv336/src/imap

Modified Files:
	cmd-append.c cmd-close.c cmd-copy.c cmd-expunge.c cmd-select.c 
	cmd-status.c commands-util.c commands-util.h commands.c 
	commands.h imap-expunge.c imap-expunge.h 
Log Message:
mailbox_save() and mailbox_copy() functions can now return the saved mail so
it can be immediately queried. Implemented UIDPLUS extension using it.
Maildir implementation missing, so it crashes with it for now.. APPEND with
mbox now doesn't require resyncing the mailbox since it updates indexes
directly.



Index: cmd-append.c
===================================================================
RCS file: /home/cvs/dovecot/src/imap/cmd-append.c,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -d -r1.35 -r1.36
--- cmd-append.c	2 May 2004 20:32:15 -0000	1.35
+++ cmd-append.c	20 Jun 2004 03:25:33 -0000	1.36
@@ -4,6 +4,7 @@
 #include "ioloop.h"
 #include "istream.h"
 #include "ostream.h"
+#include "str.h"
 #include "commands.h"
 #include "imap-parser.h"
 #include "imap-date.h"
@@ -55,9 +56,12 @@
         struct mailbox_keywords old_flags;
 	struct mail_full_flags flags;
 	struct istream *input;
+	struct mail *mail;
 	time_t internal_date;
 	const char *mailbox, *internal_date_str;
 	uoff_t msg_size;
+	string_t *reply;
+        struct msgset_generator_context msgset_ctx;
 	unsigned int count;
 	int ret, failed, timezone_offset, nonsync;
 
@@ -72,13 +76,19 @@
 	if (storage == NULL)
 		return TRUE;
 
-	box = mailbox_open(storage, mailbox, MAILBOX_OPEN_FAST);
-	if (box == NULL) {
-		client_send_storage_error(client, storage);
-		return TRUE;
+	if (client->mailbox != NULL &&
+	    mailbox_name_equals(mailbox_get_name(client->mailbox), mailbox))
+		box = client->mailbox;
+	else {
+		box = mailbox_open(storage, mailbox, MAILBOX_OPEN_FAST);
+		if (box == NULL) {
+			client_send_storage_error(client, storage);
+			return TRUE;
+		}
 	}
 
-	if (mailbox_get_status(box, STATUS_KEYWORDS, &status) < 0) {
+	if (mailbox_get_status(box, STATUS_KEYWORDS | STATUS_UIDVALIDITY,
+			       &status) < 0) {
 		client_send_storage_error(client, storage);
 		mailbox_close(box);
 		return TRUE;
@@ -93,6 +103,10 @@
 	/* if error occurs, the CRLF is already read. */
 	client->input_skip_line = FALSE;
 
+	reply = str_new(default_pool, 256);
+	str_printfa(reply, "OK [APPENDUID %u ", status.uidvalidity);
+
+	msgset_generator_init(&msgset_ctx, reply);
 	count = 0;
 	failed = TRUE;
 	save_parser = imap_parser_create(client->input, client->output,
@@ -180,13 +194,15 @@
 					      client->input->v_offset,
 					      msg_size);
 		if (mailbox_save(t, &flags, internal_date, timezone_offset,
-				 NULL, input) < 0) {
+				 NULL, input, &mail) < 0) {
 			i_stream_unref(input);
 			client_send_storage_error(client, storage);
 			break;
 		}
 		i_stream_unref(input);
 
+		msgset_generator_next(&msgset_ctx, mail->uid);
+
 		if (client->input->closed)
 			break;
 
@@ -194,6 +210,8 @@
 	}
         imap_parser_destroy(save_parser);
 
+	msgset_generator_finish(&msgset_ctx);
+
 	if (failed)
 		mailbox_transaction_rollback(t);
 	else {
@@ -203,11 +221,15 @@
 		}
 	}
 
-	mailbox_close(box);
+	if (box != client->mailbox)
+		mailbox_close(box);
 
 	if (!failed) {
 		client_sync_full(client);
-		client_send_tagline(client, "OK Append completed.");
+		str_append(reply, "] Append completed.");
+		client_send_tagline(client, str_c(reply));
 	}
+	str_free(reply);
+
 	return TRUE;
 }

Index: cmd-close.c
===================================================================
RCS file: /home/cvs/dovecot/src/imap/cmd-close.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -r1.12 -r1.13
--- cmd-close.c	27 Apr 2004 20:25:52 -0000	1.12
+++ cmd-close.c	20 Jun 2004 03:25:33 -0000	1.13
@@ -15,7 +15,7 @@
 	client->mailbox = NULL;
 
 	if (!mailbox_is_readonly(mailbox)) {
-		if (!imap_expunge(mailbox))
+		if (!imap_expunge(mailbox, NULL))
 			client_send_untagged_storage_error(client, storage);
 	}
 

Index: cmd-copy.c
===================================================================
RCS file: /home/cvs/dovecot/src/imap/cmd-copy.c,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -d -r1.18 -r1.19
--- cmd-copy.c	28 Apr 2004 00:21:00 -0000	1.18
+++ cmd-copy.c	20 Jun 2004 03:25:33 -0000	1.19
@@ -1,16 +1,20 @@
 /* Copyright (C) 2002 Timo Sirainen */
 
 #include "common.h"
+#include "str.h"
 #include "commands.h"
 #include "imap-search.h"
 
 static int fetch_and_copy(struct mailbox_transaction_context *t,
 			  struct mailbox *srcbox,
-			  struct mail_search_arg *search_args)
+			  struct mail_search_arg *search_args,
+			  string_t *reply)
 {
 	struct mail_search_context *search_ctx;
         struct mailbox_transaction_context *src_trans;
-	struct mail *mail;
+	struct mail *mail, *dest_mail;
+        struct msgset_generator_context srcset_ctx, destset_ctx;
+	string_t *dest_str;
 	int ret;
 
 	src_trans = mailbox_transaction_begin(srcbox, FALSE);
@@ -22,16 +26,35 @@
 		return -1;
 	}
 
+	dest_str = t_str_new(128);
+	msgset_generator_init(&srcset_ctx, reply);
+	msgset_generator_init(&destset_ctx, dest_str);
+
 	ret = 1;
 	while ((mail = mailbox_search_next(search_ctx)) != NULL) {
 		if (mail->expunged) {
 			ret = 0;
 			break;
 		}
-		if (mailbox_copy(t, mail) < 0) {
+		if (mailbox_copy(t, mail, &dest_mail) < 0) {
 			ret = -1;
 			break;
 		}
+
+		msgset_generator_next(&srcset_ctx, mail->uid);
+		msgset_generator_next(&destset_ctx, dest_mail->uid);
+
+	}
+
+	msgset_generator_finish(&srcset_ctx);
+	msgset_generator_finish(&destset_ctx);
+
+	if (str_len(dest_str) == 0)
+		str_truncate(reply, 0);
+	else {
+		str_append_c(reply, ' ');
+		str_append_str(reply, dest_str);
+		str_append(reply, "] Copy completed.");
 	}
 
 	if (mailbox_search_deinit(search_ctx) < 0)
@@ -49,7 +72,9 @@
 	struct mailbox *destbox;
 	struct mailbox_transaction_context *t;
         struct mail_search_arg *search_arg;
+	struct mailbox_status status;
 	const char *messageset, *mailbox;
+	string_t *reply;
 	int ret;
 
 	/* <message set> <mailbox> */
@@ -74,14 +99,28 @@
 	if (storage == NULL)
 		return TRUE;
 
-	destbox = mailbox_open(storage, mailbox, MAILBOX_OPEN_FAST);
-	if (destbox == NULL) {
+	if (mailbox_name_equals(mailbox_get_name(client->mailbox), mailbox))
+		destbox = client->mailbox;
+	else {
+		destbox = mailbox_open(storage, mailbox, MAILBOX_OPEN_FAST);
+		if (destbox == NULL) {
+			client_send_storage_error(client, storage);
+			return TRUE;
+		}
+	}
+
+	if (mailbox_get_status(destbox, STATUS_UIDVALIDITY, &status) < 0) {
 		client_send_storage_error(client, storage);
+		if (destbox != client->mailbox)
+			mailbox_close(destbox);
 		return TRUE;
 	}
 
+	reply = str_new(default_pool, 512);
+	str_printfa(reply, "OK [COPYUID %u ", status.uidvalidity);
+
 	t = mailbox_transaction_begin(destbox, FALSE);
-	ret = fetch_and_copy(t, client->mailbox, search_arg);
+	ret = fetch_and_copy(t, client->mailbox, search_arg, reply);
 
 	if (ret <= 0)
 		mailbox_transaction_rollback(t);
@@ -102,9 +141,15 @@
 			client_sync_full(client);
 		else
 			client_sync_full_fast(client);
-		client_send_tagline(client, "OK Copy completed.");
+		if (str_len(reply) > 0)
+			client_send_tagline(client, str_c(reply));
+		else {
+			client_send_tagline(client,
+				"OK Copy completed, no messages found.");
+		}
 	}
 
-	mailbox_close(destbox);
+	if (destbox != client->mailbox)
+		mailbox_close(destbox);
 	return TRUE;
 }

Index: cmd-expunge.c
===================================================================
RCS file: /home/cvs/dovecot/src/imap/cmd-expunge.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- cmd-expunge.c	27 Apr 2004 20:25:52 -0000	1.6
+++ cmd-expunge.c	20 Jun 2004 03:25:33 -0000	1.7
@@ -2,14 +2,48 @@
 
 #include "common.h"
 #include "commands.h"
+#include "imap-search.h"
 #include "imap-expunge.h"
 
+int cmd_uid_expunge(struct client *client)
+{
+	struct imap_arg *args;
+	struct mail_search_arg *search_arg;
+	const char *uidset;
+
+	if (!client_read_args(client, 1, 0, &args))
+		return FALSE;
+
+	if (!client_verify_open_mailbox(client))
+		return TRUE;
+
+	uidset = imap_arg_string(&args[0]);
+	if (uidset == NULL) {
+		client_send_command_error(client, "Invalid arguments.");
+		return TRUE;
+	}
+
+	search_arg = imap_search_get_arg(client, uidset, TRUE);
+	if (search_arg == NULL)
+		return TRUE;
+
+	if (imap_expunge(client->mailbox, search_arg)) {
+		client_sync_full(client);
+		client_send_tagline(client, "OK Expunge completed.");
+	} else {
+		client_send_storage_error(client,
+					  mailbox_get_storage(client->mailbox));
+	}
+
+	return TRUE;
+}
+
 int cmd_expunge(struct client *client)
 {
 	if (!client_verify_open_mailbox(client))
 		return TRUE;
 
-	if (imap_expunge(client->mailbox)) {
+	if (imap_expunge(client->mailbox, NULL)) {
 		client_sync_full(client);
 		client_send_tagline(client, "OK Expunge completed.");
 	} else {

Index: cmd-select.c
===================================================================
RCS file: /home/cvs/dovecot/src/imap/cmd-select.c,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -d -r1.26 -r1.27
--- cmd-select.c	2 May 2004 20:32:15 -0000	1.26
+++ cmd-select.c	20 Jun 2004 03:25:33 -0000	1.27
@@ -27,8 +27,8 @@
 	if (storage == NULL)
 		return TRUE;
 
-	box = mailbox_open(storage, mailbox,
-			   readonly ? MAILBOX_OPEN_READONLY : 0);
+	box = mailbox_open(storage, mailbox, !readonly ? 0 :
+			   (MAILBOX_OPEN_READONLY | MAILBOX_OPEN_KEEP_RECENT));
 	if (box == NULL) {
 		client_send_storage_error(client, storage);
 		return TRUE;

Index: cmd-status.c
===================================================================
RCS file: /home/cvs/dovecot/src/imap/cmd-status.c,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -d -r1.16 -r1.17
--- cmd-status.c	28 Apr 2004 00:21:00 -0000	1.16
+++ cmd-status.c	20 Jun 2004 03:25:33 -0000	1.17
@@ -43,14 +43,6 @@
 	return items;
 }
 
-static int mailbox_name_equals(const char *box1, const char *box2)
-{
-	if (strcmp(box1, box2) == 0)
-		return TRUE;
-
-	return strcasecmp(box1, "INBOX") == 0 && strcasecmp(box2, "INBOX") == 0;
-}
-
 static int get_mailbox_status(struct client *client,
 			      struct mail_storage *storage, const char *mailbox,
 			      enum mailbox_status_items items,
@@ -66,7 +58,8 @@
 	} else {
 		/* open the mailbox */
 		box = mailbox_open(storage, mailbox, MAILBOX_OPEN_FAST |
-				   MAILBOX_OPEN_READONLY);
+				   MAILBOX_OPEN_READONLY |
+				   MAILBOX_OPEN_KEEP_RECENT);
 		if (box == NULL)
 			return FALSE;
 	}

Index: commands-util.c
===================================================================
RCS file: /home/cvs/dovecot/src/imap/commands-util.c,v
retrieving revision 1.31
retrieving revision 1.32
diff -u -d -r1.31 -r1.32
--- commands-util.c	2 May 2004 20:32:15 -0000	1.31
+++ commands-util.c	20 Jun 2004 03:25:33 -0000	1.32
@@ -339,3 +339,42 @@
 	for (i = 0; i < keywords_count; i++)
 		dest->keywords[i] = p_strdup(dest->pool, keywords[i]);
 }
+
+int mailbox_name_equals(const char *box1, const char *box2)
+{
+	if (strcmp(box1, box2) == 0)
+		return TRUE;
+
+	return strcasecmp(box1, "INBOX") == 0 && strcasecmp(box2, "INBOX") == 0;
+}
+
+void msgset_generator_init(struct msgset_generator_context *ctx, string_t *str)
+{
+	memset(ctx, 0, sizeof(*ctx));
+	ctx->str = str;
+	ctx->last_uid = (uint32_t)-1;
+}
+
+void msgset_generator_next(struct msgset_generator_context *ctx, uint32_t uid)
+{
+	if (uid != ctx->last_uid+1) {
+		if (ctx->first_uid == 0)
+			;
+		else if (ctx->first_uid == ctx->last_uid)
+			str_printfa(ctx->str, "%u,", ctx->first_uid);
+		else {
+			str_printfa(ctx->str, "%u:%u,",
+				    ctx->first_uid, ctx->last_uid);
+		}
+		ctx->first_uid = uid;
+	}
+	ctx->last_uid = uid;
+}
+
+void msgset_generator_finish(struct msgset_generator_context *ctx)
+{
+	if (ctx->first_uid == ctx->last_uid)
+		str_printfa(ctx->str, "%u", ctx->first_uid);
+	else
+		str_printfa(ctx->str, "%u:%u", ctx->first_uid, ctx->last_uid);
+}

Index: commands-util.h
===================================================================
RCS file: /home/cvs/dovecot/src/imap/commands-util.h,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -d -r1.14 -r1.15
--- commands-util.h	2 May 2004 20:32:15 -0000	1.14
+++ commands-util.h	20 Jun 2004 03:25:33 -0000	1.15
@@ -1,6 +1,11 @@
 #ifndef __COMMANDS_UTIL_H
 #define __COMMANDS_UTIL_H
 
+struct msgset_generator_context {
+	string_t *str;
+	uint32_t first_uid, last_uid;
+};
+
 struct mail_full_flags;
 
 /* Finds mail storage for given mailbox from namespaces. If not found,
@@ -54,4 +59,10 @@
 void client_save_keywords(struct mailbox_keywords *dest,
 			  const char *keywords[], unsigned int keywords_count);
 
+int mailbox_name_equals(const char *box1, const char *box2);
+
+void msgset_generator_init(struct msgset_generator_context *ctx, string_t *str);
+void msgset_generator_next(struct msgset_generator_context *ctx, uint32_t uid);
+void msgset_generator_finish(struct msgset_generator_context *ctx);
+
 #endif

Index: commands.c
===================================================================
RCS file: /home/cvs/dovecot/src/imap/commands.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -r1.12 -r1.13
--- commands.c	27 Jul 2003 04:48:32 -0000	1.12
+++ commands.c	20 Jun 2004 03:25:33 -0000	1.13
@@ -46,6 +46,7 @@
 	{ "NAMESPACE",		cmd_namespace },
 	{ "SORT",		cmd_sort },
 	{ "THREAD",		cmd_thread },
+	{ "UID EXPUNGE",	cmd_uid_expunge },
 	{ "UID SORT",		cmd_sort },
 	{ "UID THREAD",		cmd_thread },
 	{ "UNSELECT",		cmd_unselect }

Index: commands.h
===================================================================
RCS file: /home/cvs/dovecot/src/imap/commands.h,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- commands.h	27 Jul 2003 04:48:32 -0000	1.13
+++ commands.h	20 Jun 2004 03:25:33 -0000	1.14
@@ -66,6 +66,7 @@
 int cmd_namespace(struct client *client);
 int cmd_sort(struct client *client);
 int cmd_thread(struct client *client);
+int cmd_uid_expunge(struct client *client);
 int cmd_unselect(struct client *client);
 
 /* private: */

Index: imap-expunge.c
===================================================================
RCS file: /home/cvs/dovecot/src/imap/imap-expunge.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- imap-expunge.c	27 Apr 2004 20:25:52 -0000	1.2
+++ imap-expunge.c	20 Jun 2004 03:25:33 -0000	1.3
@@ -5,7 +5,7 @@
 #include "mail-search.h"
 #include "imap-expunge.h"
 
-int imap_expunge(struct mailbox *box)
+int imap_expunge(struct mailbox *box, struct mail_search_arg *next_search_arg)
 {
 	struct mail_search_context *ctx;
         struct mailbox_transaction_context *t;
@@ -15,6 +15,7 @@
 
 	memset(&search_arg, 0, sizeof(search_arg));
 	search_arg.type = SEARCH_DELETED;
+	search_arg.next = next_search_arg;
 
 	t = mailbox_transaction_begin(box, FALSE);
 	ctx = mailbox_search_init(t, NULL, &search_arg, NULL, 0, NULL);
@@ -41,4 +42,3 @@
 
 	return !failed;
 }
-

Index: imap-expunge.h
===================================================================
RCS file: /home/cvs/dovecot/src/imap/imap-expunge.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- imap-expunge.h	27 Apr 2004 20:25:52 -0000	1.2
+++ imap-expunge.h	20 Jun 2004 03:25:33 -0000	1.3
@@ -1,6 +1,6 @@
 #ifndef __IMAP_EXPUNGE_H
 #define __IMAP_EXPUNGE_H
 
-int imap_expunge(struct mailbox *box);
+int imap_expunge(struct mailbox *box, struct mail_search_arg *next_search_arg);
 
 #endif



More information about the dovecot-cvs mailing list