[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