changeset 7635:19327e95a787 HEAD

EXPUNGE: Send HIGHESTMODSEQ only if something was actually expunged.
author Timo Sirainen <tss@iki.fi>
date Sun, 16 Mar 2008 07:41:26 +0200
parents 3980292275ab
children 8ca66e0ac4ed
files src/imap/client.h src/imap/cmd-expunge.c src/imap/imap-sync.c
diffstat 3 files changed, 38 insertions(+), 25 deletions(-) [+]
line wrap: on
line diff
--- a/src/imap/client.h	Sun Mar 16 07:41:06 2008 +0200
+++ b/src/imap/client.h	Sun Mar 16 07:41:26 2008 +0200
@@ -88,6 +88,7 @@
 	/* syncing marks this TRUE when it sees \Deleted flags. this is by
 	   EXPUNGE for Outlook-workaround. */
 	unsigned int sync_seen_deletes:1;
+	unsigned int sync_seen_expunges:1;
 	unsigned int disconnected:1;
 	unsigned int destroyed:1;
 	unsigned int handling_input:1;
--- a/src/imap/cmd-expunge.c	Sun Mar 16 07:41:06 2008 +0200
+++ b/src/imap/cmd-expunge.c	Sun Mar 16 07:41:26 2008 +0200
@@ -7,16 +7,23 @@
 
 static bool cmd_expunge_callback(struct client_command_context *cmd)
 {
-	struct mailbox_status status;
-
 	if (cmd->client->sync_seen_deletes && !cmd->uid) {
 		/* Outlook workaround: session 1 set \Deleted flag and
 		   session 2 tried to expunge without having seen it yet.
-		   expunge again. */
+		   expunge again. MAILBOX_TRANSACTION_FLAG_REFRESH should
+		   have caught this already if index files are used. */
 		return cmd_expunge(cmd);
 	}
 
-	if ((cmd->client->enabled_features & MAILBOX_FEATURE_QRESYNC) == 0)
+	client_send_tagline(cmd, "OK Expunge completed.");
+	return TRUE;
+}
+
+static bool cmd_expunge_callback_qresync(struct client_command_context *cmd)
+{
+	struct mailbox_status status;
+
+	if (!cmd->client->sync_seen_expunges)
 		client_send_tagline(cmd, "OK Expunge completed.");
 	else {
 		mailbox_get_status(cmd->client->mailbox,
@@ -28,9 +35,30 @@
 	return TRUE;
 }
 
+static bool cmd_expunge_finish(struct client_command_context *cmd,
+			       struct mail_search_arg *search_arg)
+{
+	struct client *client = cmd->client;
+
+	if (imap_expunge(client->mailbox, search_arg) < 0) {
+		client_send_storage_error(cmd,
+					  mailbox_get_storage(client->mailbox));
+		return TRUE;
+	}
+
+	client->sync_seen_deletes = FALSE;
+	client->sync_seen_expunges = FALSE;
+	if ((client->enabled_features & MAILBOX_FEATURE_QRESYNC) != 0) {
+		return cmd_sync_callback(cmd, 0, IMAP_SYNC_FLAG_SAFE,
+					 cmd_expunge_callback_qresync);
+	} else {
+		return cmd_sync_callback(cmd, 0, IMAP_SYNC_FLAG_SAFE,
+					 cmd_expunge_callback);
+	}
+}
+
 bool cmd_uid_expunge(struct client_command_context *cmd)
 {
-	struct client *client = cmd->client;
 	const struct imap_arg *args;
 	struct mail_search_arg *search_arg;
 	const char *uidset;
@@ -48,31 +76,14 @@
 	}
 
 	search_arg = imap_search_get_seqset(cmd, uidset, TRUE);
-	if (search_arg == NULL)
-		return TRUE;
-
-	if (imap_expunge(client->mailbox, search_arg) < 0) {
-		client_send_storage_error(cmd,
-					  mailbox_get_storage(client->mailbox));
-		return TRUE;
-	}
-	return cmd_sync_callback(cmd, 0, IMAP_SYNC_FLAG_SAFE,
-				 cmd_expunge_callback);
+	return search_arg == NULL ? TRUE :
+		cmd_expunge_finish(cmd, search_arg);
 }
 
 bool cmd_expunge(struct client_command_context *cmd)
 {
-	struct client *client = cmd->client;
-
 	if (!client_verify_open_mailbox(cmd))
 		return TRUE;
 
-	cmd->client->sync_seen_deletes = FALSE;
-	if (imap_expunge(client->mailbox, NULL) < 0) {
-		client_send_storage_error(cmd,
-					  mailbox_get_storage(client->mailbox));
-		return TRUE;
-	}
-	return cmd_sync_callback(cmd, 0, IMAP_SYNC_FLAG_SAFE,
-				 cmd_expunge_callback);
+	return cmd_expunge_finish(cmd, NULL);
 }
--- a/src/imap/imap-sync.c	Sun Mar 16 07:41:06 2008 +0200
+++ b/src/imap/imap-sync.c	Sun Mar 16 07:41:26 2008 +0200
@@ -241,6 +241,7 @@
 			}
 			break;
 		case MAILBOX_SYNC_TYPE_EXPUNGE:
+			ctx->client->sync_seen_expunges = TRUE;
 			if (array_is_created(&ctx->expunges)) {
 				/* Use a single VANISHED line */
 				seq_range_array_add_range(&ctx->expunges,