[dovecot-cvs] dovecot/src/pop3 client.c, 1.37, 1.38 client.h, 1.7, 1.8 commands.c, 1.29, 1.30

cras at dovecot.org cras at dovecot.org
Fri Oct 8 23:25:03 EEST 2004


Update of /var/lib/cvs/dovecot/src/pop3
In directory talvi:/tmp/cvs-serv12850

Modified Files:
	client.c client.h commands.c 
Log Message:
Delay writing seen flags to mailbox.



Index: client.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/pop3/client.c,v
retrieving revision 1.37
retrieving revision 1.38
diff -u -d -r1.37 -r1.38
--- client.c	5 Oct 2004 22:50:47 -0000	1.37
+++ client.c	8 Oct 2004 20:25:00 -0000	1.38
@@ -130,6 +130,63 @@
 	return FALSE;
 }
 
+int client_update_mailbox(struct client *client, struct mailbox *box,
+			  int delete_mails)
+{
+	struct mail_search_arg search_arg;
+        struct mailbox_transaction_context *t;
+	struct mail_search_context *ctx;
+	struct mail *mail;
+	struct mail_full_flags seen_flag;
+	uint32_t i, bitmask;
+	int failed = FALSE;
+
+	if (delete_mails && client->deleted_bitmask == NULL)
+                delete_mails = FALSE;
+
+	memset(&search_arg, 0, sizeof(search_arg));
+	search_arg.type = SEARCH_ALL;
+
+	t = mailbox_transaction_begin(box, FALSE);
+	ctx = mailbox_search_init(t, NULL, &search_arg, NULL, 0, NULL);
+	if (ctx == NULL) {
+		mailbox_transaction_rollback(t);
+		return FALSE;
+	}
+
+	memset(&seen_flag, 0, sizeof(seen_flag));
+	seen_flag.flags = MAIL_SEEN;
+
+	while ((mail = mailbox_search_next(ctx)) != NULL) {
+		i = mail->seq-1;
+
+		bitmask = 1 << (i % CHAR_BIT);
+		if (delete_mails &&
+		    (client->deleted_bitmask[i/CHAR_BIT] & bitmask) != 0) {
+			if (mail->expunge(mail) < 0) {
+				failed = TRUE;
+				break;
+			}
+		} else if (client->seen_bitmask != NULL &&
+			   (client->seen_bitmask[i/CHAR_BIT] & bitmask) != 0) {
+			if (mail->update_flags(mail, &seen_flag,
+					       MODIFY_ADD) < 0) {
+				failed = TRUE;
+				break;
+			}
+		}
+	}
+
+	if (mailbox_search_deinit(ctx) < 0 || failed) {
+		mailbox_transaction_rollback(t);
+		return FALSE;
+	}
+
+	mailbox_transaction_commit(t, MAILBOX_SYNC_FLAG_FULL_READ |
+				   MAILBOX_SYNC_FLAG_FULL_WRITE);
+	return TRUE;
+}
+
 struct client *client_create(int hin, int hout, struct mail_storage *storage)
 {
 	struct client *client;
@@ -187,12 +244,18 @@
 		client->cmd(client);
 		i_assert(client->cmd == NULL);
 	}
-	if (client->mailbox != NULL)
+	if (client->mailbox != NULL) {
+		if (client->seen_bitmask != NULL) {
+			(void)client_update_mailbox(client, client->mailbox,
+						    FALSE);
+		}
 		mailbox_close(client->mailbox);
+	}
 	mail_storage_destroy(client->storage);
 
 	i_free(client->message_sizes);
 	i_free(client->deleted_bitmask);
+	i_free(client->seen_bitmask);
 
 	if (client->io != NULL)
 		io_remove(client->io);

Index: client.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/pop3/client.h,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- client.h	12 Sep 2004 14:26:58 -0000	1.7
+++ client.h	8 Oct 2004 20:25:00 -0000	1.8
@@ -29,6 +29,7 @@
 	uint32_t last_seen;
 
 	unsigned char *deleted_bitmask;
+	unsigned char *seen_bitmask;
 
 	unsigned int deleted:1;
 	unsigned int waiting_input:1;
@@ -42,6 +43,9 @@
 /* Disconnect client connection */
 void client_disconnect(struct client *client);
 
+int client_update_mailbox(struct client *client, struct mailbox *box,
+			  int delete_mails);
+
 /* Send a line of data to client */
 int client_send_line(struct client *client, const char *fmt, ...)
 	__attr_format__(2, 3);

Index: commands.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/pop3/commands.c,v
retrieving revision 1.29
retrieving revision 1.30
diff -u -d -r1.29 -r1.30
--- commands.c	5 Oct 2004 22:47:32 -0000	1.29
+++ commands.c	8 Oct 2004 20:25:00 -0000	1.30
@@ -178,55 +178,24 @@
 	return TRUE;
 }
 
-static int expunge_mails(struct client *client, struct mailbox *box)
+static int cmd_quit(struct client *client, const char *args __attr_unused__)
 {
-	struct mail_search_arg search_arg;
-        struct mailbox_transaction_context *t;
-	struct mail_search_context *ctx;
-	struct mail *mail;
-	uint32_t i;
-	int failed = FALSE;
-
-	memset(&search_arg, 0, sizeof(search_arg));
-	search_arg.type = SEARCH_ALL;
-
-	t = mailbox_transaction_begin(box, FALSE);
-	ctx = mailbox_search_init(t, NULL, &search_arg, NULL,
-				  MAIL_FETCH_VIRTUAL_SIZE, NULL);
-	if (ctx == NULL) {
-		mailbox_transaction_rollback(t);
-		return FALSE;
-	}
-
-	while ((mail = mailbox_search_next(ctx)) != NULL) {
-		i = mail->seq-1;
-		if ((client->deleted_bitmask[i / CHAR_BIT] &
-		     (1 << (i % CHAR_BIT))) != 0) {
-			if (mail->expunge(mail) < 0) {
-				failed = TRUE;
-				break;
-			}
+	if (client->deleted) {
+		if (!client_update_mailbox(client, client->mailbox, TRUE)) {
+			client_send_storage_error(client);
+			client_disconnect(client);
+			return TRUE;
 		}
-	}
 
-	if (mailbox_search_deinit(ctx) < 0 || failed) {
-		mailbox_transaction_rollback(t);
-		return FALSE;
+		/* don't sync them again at client_destroy() */
+		i_free(client->seen_bitmask);
+                client->seen_bitmask = NULL;
 	}
 
-	mailbox_transaction_commit(t, MAILBOX_SYNC_FLAG_FULL_READ |
-				   MAILBOX_SYNC_FLAG_FULL_WRITE);
-	return TRUE;
-}
-
-static int cmd_quit(struct client *client, const char *args __attr_unused__)
-{
 	if (!client->deleted)
 		client_send_line(client, "+OK Logging out.");
-	else if (expunge_mails(client, client->mailbox))
-		client_send_line(client, "+OK Logging out, messages deleted.");
 	else
-		client_send_storage_error(client);
+		client_send_line(client, "+OK Logging out, messages deleted.");
 
 	client_disconnect(client);
 	return TRUE;
@@ -344,7 +313,6 @@
 {
         struct fetch_context *ctx;
 	struct mail *mail;
-	struct mail_full_flags seen_flag;
 
 	ctx = i_new(struct fetch_context, 1);
 
@@ -366,9 +334,12 @@
 
 	if (body_lines == (uoff_t)-1) {
 		/* mark the message seen with RETR command */
-		memset(&seen_flag, 0, sizeof(seen_flag));
-		seen_flag.flags = MAIL_SEEN;
-		(void)mail->update_flags(mail, &seen_flag, MODIFY_ADD);
+		if (client->seen_bitmask == NULL) {
+			client->seen_bitmask =
+				i_malloc(MSGS_BITMASK_SIZE(client));
+		}
+		client->seen_bitmask[msgnum / CHAR_BIT] |=
+			1 << (msgnum % CHAR_BIT);
 	}
 
 	ctx->body_lines = body_lines;



More information about the dovecot-cvs mailing list