Mercurial > dovecot > core-2.2
changeset 2322:aae574ed7f4c HEAD
Broke mailbox_sync() into iterator.
line wrap: on
line diff
--- a/src/imap/Makefile.am Mon Jul 12 14:31:34 2004 +0300 +++ b/src/imap/Makefile.am Mon Jul 12 14:35:50 2004 +0300 @@ -68,6 +68,7 @@ imap-messageset.c \ imap-search.c \ imap-sort.c \ + imap-sync.c \ imap-thread.c \ mail-storage-callbacks.c \ main.c \ @@ -84,5 +85,6 @@ imap-messageset.h \ imap-search.h \ imap-sort.h \ + imap-sync.h \ imap-thread.h \ namespace.h
--- a/src/imap/client.h Mon Jul 12 14:31:34 2004 +0300 +++ b/src/imap/client.h Mon Jul 12 14:35:50 2004 +0300 @@ -25,6 +25,7 @@ struct mailbox *mailbox; struct mailbox_keywords keywords; unsigned int select_counter; /* increased when mailbox is changed */ + uint32_t messages_count, recent_count; time_t last_input; unsigned int bad_counter;
--- a/src/imap/cmd-idle.c Mon Jul 12 14:31:34 2004 +0300 +++ b/src/imap/cmd-idle.c Mon Jul 12 14:35:50 2004 +0300 @@ -5,6 +5,7 @@ #include "istream.h" #include "ostream.h" #include "commands.h" +#include "imap-sync.h" #include <stdlib.h> @@ -19,7 +20,7 @@ o_stream_cork(client->output); - if (client->idle_expunge) { + if (client->idle_expunge != 0) { client_send_line(client, t_strdup_printf("* %u EXPUNGE", client->idle_expunge)); } @@ -28,12 +29,8 @@ client->io = io_add(i_stream_get_fd(client->input), IO_READ, _client_input, client); - if (client->mailbox != NULL) { - mailbox_auto_sync(client->mailbox, mailbox_check_interval != 0 ? - MAILBOX_SYNC_FLAG_NO_EXPUNGES : - MAILBOX_SYNC_AUTO_STOP, - mailbox_check_interval); - } + if (client->mailbox != NULL) + mailbox_notify_changes(client->mailbox, 0, NULL, NULL); client_sync_full(client); if (done_ok) @@ -78,21 +75,28 @@ static void idle_timeout(void *context) { struct client *client = context; - struct mailbox_status status; + + /* outlook workaround - it hasn't sent anything for a long time and + we're about to disconnect unless it does something. send a fake + EXISTS to see if it responds. it's expunged later. */ timeout_remove(client->idle_to); client->idle_to = NULL; - if (mailbox_get_status(client->mailbox, STATUS_MESSAGES, &status) < 0) { + client->idle_expunge = client->messages_count+1; + client_send_line(client, + t_strdup_printf("* %u EXISTS", client->idle_expunge)); + mailbox_notify_changes(client->mailbox, 0, NULL, NULL); +} + +static void idle_callback(struct mailbox *box, void *context) +{ + struct client *client = context; + + if (imap_sync(client, box, 0) < 0) { client_send_untagged_storage_error(client, mailbox_get_storage(client->mailbox)); - idle_finish(client, TRUE); - } else { - client->idle_expunge = status.messages+1; - client_send_line(client, - t_strdup_printf("* %u EXISTS", client->idle_expunge)); - - mailbox_auto_sync(client->mailbox, MAILBOX_SYNC_AUTO_STOP, 0); + mailbox_notify_changes(client->mailbox, 0, NULL, NULL); } } @@ -113,9 +117,10 @@ if (interval == 0) interval = DEFAULT_IDLE_CHECK_INTERVAL; - if (client->mailbox != NULL) - mailbox_auto_sync(client->mailbox, 0, interval); - + if (client->mailbox != NULL) { + mailbox_notify_changes(client->mailbox, interval, + idle_callback, client); + } client_send_line(client, "+ idling"); io_remove(client->io);
--- a/src/imap/cmd-select.c Mon Jul 12 14:31:34 2004 +0300 +++ b/src/imap/cmd-select.c Mon Jul 12 14:35:50 2004 +0300 @@ -2,6 +2,7 @@ #include "common.h" #include "commands.h" +#include "imap-sync.h" int _cmd_select_full(struct client *client, int readonly) { @@ -34,6 +35,12 @@ return TRUE; } + if (imap_sync(client, box, 0) < 0) { + client_send_storage_error(client, storage); + mailbox_close(box); + return TRUE; + } + if (mailbox_get_status(box, STATUS_MESSAGES | STATUS_RECENT | STATUS_FIRST_UNSEEN_SEQ | STATUS_UIDVALIDITY | STATUS_UIDNEXT | STATUS_KEYWORDS, @@ -45,6 +52,8 @@ client_save_keywords(&client->keywords, status.keywords, status.keywords_count); + client->messages_count = status.messages; + client->recent_count = status.recent; /* set client's mailbox only after getting status to make sure we're not sending any expunge/exists replies too early to client */ @@ -81,12 +90,6 @@ client_send_tagline(client, mailbox_is_readonly(box) ? "OK [READ-ONLY] Select completed." : "OK [READ-WRITE] Select completed."); - - if (mailbox_check_interval != 0) { - mailbox_auto_sync(box, MAILBOX_SYNC_FLAG_NO_EXPUNGES, - mailbox_check_interval); - } - return TRUE; }
--- a/src/imap/cmd-status.c Mon Jul 12 14:31:34 2004 +0300 +++ b/src/imap/cmd-status.c Mon Jul 12 14:35:50 2004 +0300 @@ -4,6 +4,7 @@ #include "str.h" #include "imap-quote.h" #include "commands.h" +#include "imap-sync.h" /* Returns status items, or -1 if error */ static enum mailbox_status_items @@ -64,7 +65,10 @@ return FALSE; } - failed = mailbox_get_status(box, items, status) < 0; + if (imap_sync(client, box, 0) < 0) + failed = TRUE; + else + failed = mailbox_get_status(box, items, status) < 0; if (box != client->mailbox) mailbox_close(box);
--- a/src/imap/cmd-store.c Mon Jul 12 14:31:34 2004 +0300 +++ b/src/imap/cmd-store.c Mon Jul 12 14:35:50 2004 +0300 @@ -1,6 +1,7 @@ /* Copyright (C) 2002 Timo Sirainen */ #include "common.h" +#include "str.h" #include "commands.h" #include "imap-search.h" #include "imap-util.h" @@ -37,19 +38,21 @@ static int mail_send_flags(struct client *client, struct mail *mail) { const struct mail_full_flags *flags; - const char *str; + string_t *str; flags = mail->get_flags(mail); if (flags == NULL) return FALSE; t_push(); - str = imap_write_flags(flags); - str = t_strdup_printf(client->cmd_uid ? - "* %u FETCH (FLAGS (%s) UID %u)" : - "* %u FETCH (FLAGS (%s))", - mail->seq, str, mail->uid); - client_send_line(client, str); + str = t_str_new(128); + str_printfa(str, "* %u FETCH (FLAGS (", mail->seq); + imap_write_flags(str, flags); + if (client->cmd_uid) + str_printfa(str, ") UID %u)", mail->uid); + else + str_append(str, "))"); + client_send_line(client, str_c(str)); t_pop(); return TRUE;
--- a/src/imap/commands-util.c Mon Jul 12 14:31:34 2004 +0300 +++ b/src/imap/commands-util.c Mon Jul 12 14:35:50 2004 +0300 @@ -7,6 +7,7 @@ #include "imap-util.h" #include "mail-storage.h" #include "imap-parser.h" +#include "imap-sync.h" #include "namespace.h" /* Maximum length for mailbox name, including it's path. This isn't fully @@ -116,7 +117,7 @@ if (client->mailbox == NULL) return; - if (mailbox_sync(client->mailbox, 0) < 0) { + if (imap_sync(client, client->mailbox, 0) < 0) { client_send_untagged_storage_error(client, mailbox_get_storage(client->mailbox)); } @@ -127,7 +128,7 @@ if (client->mailbox == NULL) return; - if (mailbox_sync(client->mailbox, MAILBOX_SYNC_FLAG_FAST) < 0) { + if (imap_sync(client, client->mailbox, MAILBOX_SYNC_FLAG_FAST) < 0) { client_send_untagged_storage_error(client, mailbox_get_storage(client->mailbox)); } @@ -138,8 +139,8 @@ if (client->mailbox == NULL) return; - if (mailbox_sync(client->mailbox, MAILBOX_SYNC_FLAG_FAST | - MAILBOX_SYNC_FLAG_NO_EXPUNGES) < 0) { + if (imap_sync(client, client->mailbox, MAILBOX_SYNC_FLAG_FAST | + MAILBOX_SYNC_FLAG_NO_EXPUNGES) < 0) { client_send_untagged_storage_error(client, mailbox_get_storage(client->mailbox)); }
--- a/src/imap/imap-fetch.c Mon Jul 12 14:31:34 2004 +0300 +++ b/src/imap/imap-fetch.c Mon Jul 12 14:35:50 2004 +0300 @@ -58,7 +58,9 @@ flags = &full_flags; } - str_printfa(ctx->str, "FLAGS (%s) ", imap_write_flags(flags)); + str_append(ctx->str, "FLAGS ("); + imap_write_flags(ctx->str, flags); + str_append(ctx->str, ") "); return TRUE; }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/imap/imap-sync.c Mon Jul 12 14:35:50 2004 +0300 @@ -0,0 +1,88 @@ +/* Copyright (C) 2002 Timo Sirainen */ + +#include "common.h" +#include "str.h" +#include "imap-util.h" +#include "mail-storage.h" +#include "imap-sync.h" + +int imap_sync(struct client *client, struct mailbox *box, + enum mailbox_sync_flags flags) +{ + struct mailbox_transaction_context *t; + struct mailbox_sync_context *ctx; + struct mailbox_sync_rec sync_rec; + struct mailbox_status status; + struct mail *mail; + const struct mail_full_flags *mail_flags; + string_t *str; + uint32_t seq; + + if (client->mailbox != box) { + /* mailbox isn't selected - we only wish to sync the mailbox + without sending anything to client */ + ctx = mailbox_sync_init(box, flags); + while (mailbox_sync_next(ctx, &sync_rec) > 0) + ; + return mailbox_sync_deinit(ctx, &status); + } + + t_push(); + str = t_str_new(256); + + t = mailbox_transaction_begin(box, FALSE); + ctx = mailbox_sync_init(box, flags); + while (mailbox_sync_next(ctx, &sync_rec) > 0) { + switch (sync_rec.type) { + case MAILBOX_SYNC_TYPE_FLAGS: + for (seq = sync_rec.seq1; seq <= sync_rec.seq2; seq++) { + mail = mailbox_fetch(t, seq, MAIL_FETCH_FLAGS); + + mail_flags = mail->get_flags(mail); + if (mail_flags == NULL) + continue; + + str_truncate(str, 0); + str_printfa(str, "* %u FETCH (FLAGS (", seq); + imap_write_flags(str, mail_flags); + str_append(str, "))"); + client_send_line(client, str_c(str)); + } + break; + case MAILBOX_SYNC_TYPE_EXPUNGE: + for (seq = sync_rec.seq2; seq >= sync_rec.seq1; seq--) { + str_truncate(str, 0); + str_printfa(str, "* %u EXPUNGE", seq); + client_send_line(client, str_c(str)); + } + break; + } + } + + if (mailbox_sync_deinit(ctx, &status) < 0) { + mailbox_transaction_rollback(t); + t_pop(); + return -1; + } + + mailbox_transaction_commit(t); + + if (status.messages != client->messages_count) { + client->messages_count = status.messages; + str_truncate(str, 0); + str_printfa(str, "* %u EXISTS", status.messages); + client_send_line(client, str_c(str)); + } + if (status.recent != client->recent_count) { + client->recent_count = status.recent; + str_truncate(str, 0); + str_printfa(str, "* %u RECENT", status.recent); + client_send_line(client, str_c(str)); + } + + /*FIXME:client_save_keywords(&client->keywords, keywords, keywords_count); + client_send_mailbox_flags(client, mailbox, keywords, keywords_count);*/ + + t_pop(); + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/imap/imap-sync.h Mon Jul 12 14:35:50 2004 +0300 @@ -0,0 +1,7 @@ +#ifndef __IMAP_SYNC_H +#define __IMAP_SYNC_H + +int imap_sync(struct client *client, struct mailbox *box, + enum mailbox_sync_flags flags); + +#endif
--- a/src/imap/mail-storage-callbacks.c Mon Jul 12 14:31:34 2004 +0300 +++ b/src/imap/mail-storage-callbacks.c Mon Jul 12 14:35:50 2004 +0300 @@ -33,79 +33,8 @@ o_stream_flush(client->output); } -static void expunge(struct mailbox *mailbox, unsigned int seq, void *context) -{ - struct client *client = context; - char str[MAX_INT_STRLEN+20]; - - if (client->mailbox != mailbox) - return; - - i_snprintf(str, sizeof(str), "* %u EXPUNGE", seq); - client_send_line(client, str); -} - -static void update_flags(struct mailbox *mailbox, unsigned int seq, - const struct mail_full_flags *flags, void *context) -{ - struct client *client = context; - const char *str; - - if (client->mailbox != mailbox) - return; - - t_push(); - str = imap_write_flags(flags); - str = t_strdup_printf("* %u FETCH (FLAGS (%s))", seq, str); - client_send_line(client, str); - t_pop(); -} - -static void message_count_changed(struct mailbox *mailbox, unsigned int count, - void *context) -{ - struct client *client = context; - char str[MAX_INT_STRLEN+20]; - - if (client->mailbox != mailbox) - return; - - i_snprintf(str, sizeof(str), "* %u EXISTS", count); - client_send_line(client, str); -} - -static void recent_count_changed(struct mailbox *mailbox, unsigned int count, - void *context) -{ - struct client *client = context; - char str[MAX_INT_STRLEN+20]; - - if (client->mailbox != mailbox) - return; - - i_snprintf(str, sizeof(str), "* %u RECENT", count); - client_send_line(client, str); -} - -static void new_keywords(struct mailbox *mailbox, const char *keywords[], - unsigned int keywords_count, void *context) -{ - struct client *client = context; - - if (client->mailbox != mailbox) - return; - - client_save_keywords(&client->keywords, keywords, keywords_count); - client_send_mailbox_flags(client, mailbox, keywords, keywords_count); -} - struct mail_storage_callbacks mail_storage_callbacks = { alert_no_diskspace, notify_ok, - notify_no, - expunge, - update_flags, - message_count_changed, - recent_count_changed, - new_keywords + notify_no };
--- a/src/lib-imap/imap-util.c Mon Jul 12 14:31:34 2004 +0300 +++ b/src/lib-imap/imap-util.c Mon Jul 12 14:35:50 2004 +0300 @@ -5,38 +5,33 @@ #include "mail-types.h" #include "imap-util.h" -const char *imap_write_flags(const struct mail_full_flags *flags) +void imap_write_flags(string_t *dest, const struct mail_full_flags *flags) { - string_t *str; - const char *sysflags; unsigned int i; - - if (flags == 0) - return ""; - - sysflags = t_strconcat( - (flags->flags & MAIL_ANSWERED) ? " \\Answered" : "", - (flags->flags & MAIL_FLAGGED) ? " \\Flagged" : "", - (flags->flags & MAIL_DELETED) ? " \\Deleted" : "", - (flags->flags & MAIL_SEEN) ? " \\Seen" : "", - (flags->flags & MAIL_DRAFT) ? " \\Draft" : "", - (flags->flags & MAIL_RECENT) ? " \\Recent" : "", - NULL); + size_t size; - if (*sysflags != '\0') - sysflags++; - - if (flags->keywords_count == 0) - return sysflags; + size = str_len(dest); + if ((flags->flags & MAIL_ANSWERED) != 0) + str_append(dest, "\\Answered "); + if ((flags->flags & MAIL_FLAGGED) != 0) + str_append(dest, "\\Flagged "); + if ((flags->flags & MAIL_DELETED) != 0) + str_append(dest, "\\Deleted "); + if ((flags->flags & MAIL_SEEN) != 0) + str_append(dest, "\\Seen "); + if ((flags->flags & MAIL_DRAFT) != 0) + str_append(dest, "\\Draft "); + if ((flags->flags & MAIL_RECENT) != 0) + str_append(dest, "\\Recent "); - /* we have keywords too */ - str = t_str_new(256); - str_append(str, sysflags); + if (flags->keywords_count > 0) { + /* we have keywords too */ + for (i = 0; i < flags->keywords_count; i++) { + str_append(dest, flags->keywords[i]); + str_append_c(dest, ' '); + } + } - for (i = 0; i < flags->keywords_count; i++) { - if (str_len(str) > 0) - str_append_c(str, ' '); - str_append(str, flags->keywords[i]); - } - return str_c(str); + if (str_len(dest) != size) + str_truncate(dest, str_len(dest)-1); }
--- a/src/lib-imap/imap-util.h Mon Jul 12 14:31:34 2004 +0300 +++ b/src/lib-imap/imap-util.h Mon Jul 12 14:35:50 2004 +0300 @@ -4,6 +4,6 @@ struct mail_full_flags; /* Return flags as a space separated string. */ -const char *imap_write_flags(const struct mail_full_flags *flags); +void imap_write_flags(string_t *dest, const struct mail_full_flags *flags); #endif
--- a/src/lib-storage/index/index-mailbox-check.c Mon Jul 12 14:31:34 2004 +0300 +++ b/src/lib-storage/index/index-mailbox-check.c Mon Jul 12 14:35:50 2004 +0300 @@ -9,31 +9,46 @@ #include <fcntl.h> #include <sys/stat.h> +struct index_notify_file { + struct index_notify_file *next; + + char *path; + time_t last_stamp; +}; + +struct index_notify_io { + struct index_notify_io *next; + struct io *io; + int fd; +}; + static void check_timeout(void *context) { struct index_mailbox *ibox = context; - struct index_autosync_file *file; + struct index_notify_file *file; struct stat st; - int sync; + time_t last_check; + int notify; /* check changes only when we can also notify of new mail */ - if ((unsigned int) (ioloop_time - ibox->sync_last_check) < - ibox->min_newmail_notify_interval) + last_check = I_MAX(ibox->sync_last_check, ibox->notify_last_check); + if ((unsigned int)(ioloop_time - last_check) < + ibox->min_notify_interval) return; - ibox->sync_last_check = ioloop_time; + ibox->notify_last_check = ioloop_time; - sync = ibox->autosync_pending; - for (file = ibox->autosync_files; file != NULL; file = file->next) { + notify = ibox->notify_pending; + for (file = ibox->notify_files; file != NULL; file = file->next) { if (stat(file->path, &st) == 0 && file->last_stamp != st.st_mtime) file->last_stamp = st.st_mtime; } - if (sync) { - ibox->box.sync(&ibox->box, ibox->autosync_flags); - ibox->sync_last_notify = ioloop_time; - ibox->autosync_pending = FALSE; + if (notify) { + ibox->notify_last_sent = ioloop_time; + ibox->notify_pending = FALSE; + ibox->notify_callback(&ibox->box, ibox->notify_context); } } @@ -41,24 +56,24 @@ { struct index_mailbox *ibox = context; - ibox->sync_last_check = ioloop_time; - if ((unsigned int) (ioloop_time - ibox->sync_last_notify) >= - ibox->min_newmail_notify_interval) { - ibox->box.sync(&ibox->box, ibox->autosync_flags); - ibox->sync_last_notify = ioloop_time; - ibox->autosync_pending = FALSE; + ibox->notify_last_check = ioloop_time; + if ((unsigned int)(ioloop_time - ibox->notify_last_sent) >= + ibox->min_notify_interval) { + ibox->notify_last_sent = ioloop_time; + ibox->notify_pending = FALSE; + ibox->notify_callback(&ibox->box, ibox->notify_context); } else { - ibox->autosync_pending = TRUE; + ibox->notify_pending = TRUE; } } void index_mailbox_check_add(struct index_mailbox *ibox, const char *path, int dir) { - struct index_autosync_file *file; + struct index_notify_file *file; struct stat st; struct io *io; - struct index_autosync_io *aio; + struct index_notify_io *aio; int fd; fd = open(path, O_RDONLY); @@ -66,56 +81,56 @@ io = io_add(fd, dir ? IO_DIR_NOTIFY : IO_FILE_NOTIFY, notify_callback, ibox); if (io != NULL) { - aio = i_new(struct index_autosync_io, 1); + aio = i_new(struct index_notify_io, 1); aio->io = io; aio->fd = fd; - aio->next = ibox->autosync_ios; - ibox->autosync_ios = aio; + aio->next = ibox->notify_ios; + ibox->notify_ios = aio; } } - file = i_new(struct index_autosync_file, 1); + file = i_new(struct index_notify_file, 1); file->path = i_strdup(path); if (fd < 0) file->last_stamp = stat(path, &st) < 0 ? 0 : st.st_mtime; else file->last_stamp = fstat(fd, &st) < 0 ? 0 : st.st_mtime; - file->next = ibox->autosync_files; - ibox->autosync_files = file; + file->next = ibox->notify_files; + ibox->notify_files = file; - if (ibox->autosync_to == NULL) - ibox->autosync_to = timeout_add(1000, check_timeout, ibox); + if (ibox->notify_to == NULL) + ibox->notify_to = timeout_add(1000, check_timeout, ibox); } void index_mailbox_check_remove_all(struct index_mailbox *ibox) { - struct index_autosync_file *file; - struct index_autosync_io *aio; + struct index_notify_file *file; + struct index_notify_io *aio; /* reset notify stamp */ - ibox->sync_last_notify = 0; + ibox->notify_last_sent = 0; - while (ibox->autosync_files != NULL) { - file = ibox->autosync_files; - ibox->autosync_files = file->next; + while (ibox->notify_files != NULL) { + file = ibox->notify_files; + ibox->notify_files = file->next; i_free(file->path); i_free(file); } - while (ibox->autosync_ios != NULL) { - aio = ibox->autosync_ios; - ibox->autosync_ios = aio->next; + while (ibox->notify_ios != NULL) { + aio = ibox->notify_ios; + ibox->notify_ios = aio->next; io_remove(aio->io); if (close(aio->fd) < 0) - i_error("close(autosync_io) failed: %m"); + i_error("close(notify_io) failed: %m"); i_free(aio); } - if (ibox->autosync_to != NULL) { - timeout_remove(ibox->autosync_to); - ibox->autosync_to = NULL; + if (ibox->notify_to != NULL) { + timeout_remove(ibox->notify_to); + ibox->notify_to = NULL; } }
--- a/src/lib-storage/index/index-status.c Mon Jul 12 14:31:34 2004 +0300 +++ b/src/lib-storage/index/index-status.c Mon Jul 12 14:35:50 2004 +0300 @@ -3,10 +3,6 @@ #include "lib.h" #include "index-storage.h" -#define STATUS_MESSAGE_COUNTS \ - (STATUS_MESSAGES | STATUS_RECENT | STATUS_UIDNEXT | \ - STATUS_UIDVALIDITY | STATUS_UNSEEN | STATUS_FIRST_UNSEEN_SEQ) - /*static void get_keywords(struct mail_keywords *mcf, struct mailbox_status *status) { @@ -21,44 +17,47 @@ status->keywords[i] = t_strdup(flags[i]); }*/ -int index_storage_get_status(struct mailbox *box, - enum mailbox_status_items items, - struct mailbox_status *status) +int index_storage_get_status_locked(struct index_mailbox *ibox, + enum mailbox_status_items items, + struct mailbox_status *status_r) { - struct index_mailbox *ibox = (struct index_mailbox *) box; const struct mail_index_header *hdr; - memset(status, 0, sizeof(struct mailbox_status)); - - if ((items & STATUS_MESSAGE_COUNTS) != 0) { - /* sync mailbox to update message counts */ - if (mailbox_sync(box, 0) < 0) - return -1; - } + memset(status_r, 0, sizeof(struct mailbox_status)); /* we can get most of the status items without any trouble */ if (mail_index_get_header(ibox->view, &hdr) < 0) return -1; - if ((items & STATUS_MESSAGE_COUNTS) != 0) { - status->messages = hdr->messages_count; - status->recent = ibox->synced_recent_count; - status->unseen = hdr->messages_count - hdr->seen_messages_count; - status->uidvalidity = hdr->uid_validity; - status->uidnext = hdr->next_uid; - } - //FIXME:status->diskspace_full = ibox->nodiskspace; + + status_r->messages = hdr->messages_count; + status_r->recent = ibox->synced_recent_count; + status_r->unseen = + hdr->messages_count - hdr->seen_messages_count; + status_r->uidvalidity = hdr->uid_validity; + status_r->uidnext = hdr->next_uid; + //FIXME:status_r->diskspace_full = ibox->nodiskspace; if (items & STATUS_FIRST_UNSEEN_SEQ) { if (mail_index_lookup_first(ibox->view, 0, MAIL_SEEN, - &status->first_unseen_seq) < 0) { + &status_r->first_unseen_seq) < 0) { mail_storage_set_index_error(ibox); return -1; } } /*FIXME:if (items & STATUS_KEYWORDS) - get_keywords(ibox, status);*/ - - mail_index_view_unlock(ibox->view); + get_keywords(ibox, status_r);*/ return 0; } + +int index_storage_get_status(struct mailbox *box, + enum mailbox_status_items items, + struct mailbox_status *status) +{ + struct index_mailbox *ibox = (struct index_mailbox *)box; + int ret; + + ret = index_storage_get_status_locked(ibox, items, status); + mail_index_view_unlock(ibox->view); + return ret; +}
--- a/src/lib-storage/index/index-storage.h Mon Jul 12 14:31:34 2004 +0300 +++ b/src/lib-storage/index/index-storage.h Mon Jul 12 14:35:50 2004 +0300 @@ -22,19 +22,6 @@ MAILBOX_LOCK_NOTIFY_MAILBOX_OVERRIDE }; -struct index_autosync_file { - struct index_autosync_file *next; - - char *path; - time_t last_stamp; -}; - -struct index_autosync_io { - struct index_autosync_io *next; - struct io *io; - int fd; -}; - struct index_storage { struct mail_storage storage; @@ -63,12 +50,13 @@ void (*mail_deinit)(struct index_mail *mail); int (*is_recent)(struct index_mailbox *ibox, uint32_t uid); - struct timeout *autosync_to; - struct index_autosync_file *autosync_files; - struct index_autosync_io *autosync_ios; - enum mailbox_sync_flags autosync_flags; - time_t sync_last_check, sync_last_notify; - unsigned int min_newmail_notify_interval; + struct timeout *notify_to; + struct index_notify_file *notify_files; + struct index_notify_io *notify_ios; + time_t notify_last_check, notify_last_sent; + unsigned int min_notify_interval; + mailbox_notify_callback_t *notify_callback; + void *notify_context; time_t next_lock_notify; /* temporary */ enum mailbox_lock_notify_type last_notify_type; @@ -78,7 +66,8 @@ buffer_t *recent_flags; uint32_t recent_flags_start_seq, recent_flags_count; - unsigned int synced_recent_count; + uint32_t synced_recent_count; + time_t sync_last_check; /* mbox: */ int mbox_fd; @@ -106,7 +95,7 @@ unsigned int recent_flags_synced:1; unsigned int sent_diskspace_warning:1; unsigned int sent_readonly_flags_warning:1; - unsigned int autosync_pending:1; + unsigned int notify_pending:1; unsigned int mail_read_mmaped:1; unsigned int syncing_commit:1; }; @@ -164,6 +153,14 @@ const char *path, int dir); void index_mailbox_check_remove_all(struct index_mailbox *ibox); +struct mailbox_sync_context * +index_mailbox_sync_init(struct mailbox *box, enum mailbox_sync_flags flags, + int failed); +int index_mailbox_sync_next(struct mailbox_sync_context *ctx, + struct mailbox_sync_rec *sync_rec_r); +int index_mailbox_sync_deinit(struct mailbox_sync_context *ctx, + struct mailbox_status *status_r); + int index_storage_sync(struct mailbox *box, enum mailbox_sync_flags flags); void index_storage_set_callbacks(struct mail_storage *storage, @@ -174,6 +171,9 @@ int index_storage_get_status(struct mailbox *box, enum mailbox_status_items items, struct mailbox_status *status); +int index_storage_get_status_locked(struct index_mailbox *ibox, + enum mailbox_status_items items, + struct mailbox_status *status_r); struct mail * index_storage_fetch(struct mailbox_transaction_context *t, uint32_t seq,
--- a/src/lib-storage/index/index-sync.c Mon Jul 12 14:31:34 2004 +0300 +++ b/src/lib-storage/index/index-sync.c Mon Jul 12 14:35:50 2004 +0300 @@ -4,6 +4,17 @@ #include "buffer.h" #include "index-storage.h" +struct index_mailbox_sync_context { + struct mailbox_sync_context ctx; + struct index_mailbox *ibox; + struct mail_index_view_sync_ctx *sync_ctx; + uint32_t messages_count; + + const uint32_t *expunges; + size_t expunges_count; + int failed; +}; + void index_mailbox_set_recent(struct index_mailbox *ibox, uint32_t seq) { unsigned char *p; @@ -97,124 +108,142 @@ return 0; } -int index_storage_sync(struct mailbox *box, enum mailbox_sync_flags flags) +struct mailbox_sync_context * +index_mailbox_sync_init(struct mailbox *box, enum mailbox_sync_flags flags, + int failed) { struct index_mailbox *ibox = (struct index_mailbox *)box; - struct mail_index_view_sync_ctx *ctx; - struct mail_full_flags full_flags; - const struct mail_index_record *rec; - struct mail_index_sync_rec sync; - struct mail_storage_callbacks *sc; - const uint32_t *expunges; - size_t i, expunges_count; - void *sc_context; + struct index_mailbox_sync_context *ctx; enum mail_index_sync_type sync_mask; - uint32_t seq, seq1, seq2; - uint32_t messages_count, last_messages_count; - int ret; + + ctx = i_new(struct index_mailbox_sync_context, 1); + ctx->ctx.box = box; + ctx->ibox = ibox; + + if (failed) { + ctx->failed = TRUE; + return &ctx->ctx; + } + + ctx->messages_count = mail_index_view_get_message_count(ibox->view); sync_mask = MAIL_INDEX_SYNC_MASK_ALL; if ((flags & MAILBOX_SYNC_FLAG_NO_EXPUNGES) != 0) sync_mask &= ~MAIL_INDEX_SYNC_TYPE_EXPUNGE; - if (mail_index_view_sync_begin(ibox->view, sync_mask, &ctx) < 0) { - mail_storage_set_index_error(ibox); - return -1; + if (mail_index_view_sync_begin(ibox->view, sync_mask, + &ctx->sync_ctx) < 0) { + mail_storage_set_index_error(ibox); + ctx->failed = TRUE; + return &ctx->ctx; } - last_messages_count = mail_index_view_get_message_count(ibox->view); - if (!ibox->recent_flags_synced) { ibox->recent_flags_synced = TRUE; - index_mailbox_update_recent(ibox, 1, last_messages_count); + index_mailbox_update_recent(ibox, 1, ctx->messages_count); } - if ((flags & MAILBOX_SYNC_FLAG_NO_EXPUNGES) != 0) { - expunges_count = 0; - expunges = NULL; - } else { - expunges = - mail_index_view_sync_get_expunges(ctx, &expunges_count); + if ((flags & MAILBOX_SYNC_FLAG_NO_EXPUNGES) == 0) { + ctx->expunges = + mail_index_view_sync_get_expunges(ctx->sync_ctx, + &ctx->expunges_count); } + return &ctx->ctx; +} - sc = ibox->storage->callbacks; - sc_context = ibox->storage->callback_context; +int index_mailbox_sync_next(struct mailbox_sync_context *_ctx, + struct mailbox_sync_rec *sync_rec_r) +{ + struct index_mailbox_sync_context *ctx = + (struct index_mailbox_sync_context *)_ctx; + struct mail_index_sync_rec sync; + int ret; - memset(&full_flags, 0, sizeof(full_flags)); - while ((ret = mail_index_view_sync_next(ctx, &sync)) > 0) { + if (ctx->failed) + return -1; + + while ((ret = mail_index_view_sync_next(ctx->sync_ctx, &sync)) > 0) { switch (sync.type) { case MAIL_INDEX_SYNC_TYPE_APPEND: + /* not interested */ break; case MAIL_INDEX_SYNC_TYPE_EXPUNGE: /* later */ break; case MAIL_INDEX_SYNC_TYPE_FLAGS: - if (sc->update_flags == NULL) - break; - /* FIXME: hide the flag updates for expunged messages */ - - if (mail_index_lookup_uid_range(ibox->view, - sync.uid1, sync.uid2, - &seq1, &seq2) < 0) { - ret = -1; - break; + if (mail_index_lookup_uid_range(ctx->ibox->view, + sync.uid1, sync.uid2, + &sync_rec_r->seq1, + &sync_rec_r->seq2) < 0) { + ctx->failed = TRUE; + return -1; } - if (seq1 == 0) + if (sync_rec_r->seq1 == 0) break; - for (seq = seq1; seq <= seq2; seq++) { - if (mail_index_lookup(ibox->view, - seq, &rec) < 0) { - ret = -1; - break; - } - full_flags.flags = rec->flags; // FIXME - if (index_mailbox_is_recent(ibox, seq)) - full_flags.flags |= MAIL_RECENT; - sc->update_flags(&ibox->box, seq, - &full_flags, sc_context); - } - break; + sync_rec_r->type = MAILBOX_SYNC_TYPE_FLAGS; + return 1; } } + if (ret == 0 && ctx->expunges_count > 0) { + /* expunges[] is a sorted array of sequences. it's easiest for + us to print them from end to beginning. */ + sync_rec_r->seq1 = ctx->expunges[ctx->expunges_count*2-2]; + sync_rec_r->seq2 = ctx->expunges[ctx->expunges_count*2-1]; + index_mailbox_expunge_recent(ctx->ibox, sync_rec_r->seq1, + sync_rec_r->seq2); + + if (sync_rec_r->seq2 > ctx->messages_count) + sync_rec_r->seq2 = ctx->messages_count; + + ctx->messages_count -= sync_rec_r->seq2 - sync_rec_r->seq1 + 1; + ctx->expunges_count--; + + sync_rec_r->type = MAILBOX_SYNC_TYPE_EXPUNGE; + return 1; + } + if (ret < 0) - mail_storage_set_index_error(ibox); + mail_storage_set_index_error(ctx->ibox); + return ret; +} + +#define SYNC_STATUS_FLAGS \ + (STATUS_MESSAGES | STATUS_RECENT | STATUS_UIDNEXT | \ + STATUS_UIDVALIDITY | STATUS_UNSEEN | STATUS_KEYWORDS) - if (sc->expunge != NULL) { - /* expunges[] is a sorted array of sequences. it's easiest for - us to print them from end to beginning. */ +int index_mailbox_sync_deinit(struct mailbox_sync_context *_ctx, + struct mailbox_status *status_r) +{ + struct index_mailbox_sync_context *ctx = + (struct index_mailbox_sync_context *)_ctx; + struct index_mailbox *ibox = ctx->ibox; + uint32_t messages_count; + int ret = ctx->failed ? -1 : 0; + + if (ctx->sync_ctx != NULL) + mail_index_view_sync_end(ctx->sync_ctx); + + if (ret == 0) { messages_count = mail_index_view_get_message_count(ibox->view); - for (i = expunges_count*2; i > 0; i -= 2) { - seq = expunges[i-1]; - index_mailbox_expunge_recent(ibox, expunges[i-2], seq); - if (seq > messages_count) - seq = messages_count; - for (; seq >= expunges[i-2]; seq--) { - sc->expunge(&ibox->box, seq, sc_context); - last_messages_count--; - } + if (messages_count != ctx->messages_count) { + index_mailbox_update_recent(ibox, + ctx->messages_count+1, + messages_count); } + + if (ibox->recent_flags_count != ibox->synced_recent_count) + ibox->synced_recent_count = ibox->recent_flags_count; + + ret = index_storage_get_status_locked(ctx->ibox, + SYNC_STATUS_FLAGS, + status_r); } - mail_index_view_sync_end(ctx); - - messages_count = mail_index_view_get_message_count(ibox->view); - if (messages_count != last_messages_count) { - index_mailbox_update_recent(ibox, last_messages_count+1, - messages_count); - sc->message_count_changed(&ibox->box, messages_count, - sc_context); - } - - if (ibox->recent_flags_count != ibox->synced_recent_count) { - ibox->synced_recent_count = ibox->recent_flags_count; - sc->recent_count_changed(&ibox->box, ibox->synced_recent_count, - sc_context); - } - - mail_index_view_unlock(ibox->view); + mail_index_view_unlock(ctx->ibox->view); + i_free(ctx); return ret; }
--- a/src/lib-storage/index/maildir/maildir-storage.c Mon Jul 12 14:31:34 2004 +0300 +++ b/src/lib-storage/index/maildir/maildir-storage.c Mon Jul 12 14:35:50 2004 +0300 @@ -798,22 +798,17 @@ return ret; } -static void maildir_storage_auto_sync(struct mailbox *box, - enum mailbox_sync_flags flags, - unsigned int min_newmail_notify_interval) +static void +maildir_notify_changes(struct mailbox *box, unsigned int min_interval, + mailbox_notify_callback_t *callback, void *context) { struct index_mailbox *ibox = (struct index_mailbox *)box; - ibox->min_newmail_notify_interval = min_newmail_notify_interval; + ibox->min_notify_interval = min_interval; + ibox->notify_callback = callback; + ibox->notify_context = context; - if ((ibox->autosync_flags == 0 && flags == 0) || - (ibox->autosync_flags != 0 && flags != 0)) { - /* flags or interval just changed. or nothing. */ - ibox->autosync_flags = flags; - } - ibox->autosync_flags = flags; - - if (flags == 0) { + if (callback == NULL) { index_mailbox_check_remove_all(ibox); return; } @@ -857,8 +852,10 @@ index_storage_allow_new_keywords, maildir_storage_close, index_storage_get_status, - maildir_storage_sync, - maildir_storage_auto_sync, + maildir_storage_sync_init, + index_mailbox_sync_next, + index_mailbox_sync_deinit, + maildir_notify_changes, maildir_transaction_begin, maildir_transaction_commit, maildir_transaction_rollback,
--- a/src/lib-storage/index/maildir/maildir-storage.h Mon Jul 12 14:31:34 2004 +0300 +++ b/src/lib-storage/index/maildir/maildir-storage.h Mon Jul 12 14:35:50 2004 +0300 @@ -38,7 +38,8 @@ struct mailbox_list * maildir_mailbox_list_next(struct mailbox_list_context *ctx); -int maildir_storage_sync(struct mailbox *box, enum mailbox_sync_flags flags); +struct mailbox_sync_context * +maildir_storage_sync_init(struct mailbox *box, enum mailbox_sync_flags flags); int maildir_storage_sync_force(struct index_mailbox *ibox); struct mailbox_transaction_context *
--- a/src/lib-storage/index/maildir/maildir-sync.c Mon Jul 12 14:31:34 2004 +0300 +++ b/src/lib-storage/index/maildir/maildir-sync.c Mon Jul 12 14:35:50 2004 +0300 @@ -913,11 +913,12 @@ return ret; } -int maildir_storage_sync(struct mailbox *box, enum mailbox_sync_flags flags) +struct mailbox_sync_context * +maildir_storage_sync_init(struct mailbox *box, enum mailbox_sync_flags flags) { struct index_mailbox *ibox = (struct index_mailbox *)box; struct maildir_sync_context *ctx; - int ret; + int ret = 0; if ((flags & MAILBOX_SYNC_FLAG_FAST) == 0 || ibox->sync_last_check + MAILBOX_FULL_SYNC_INTERVAL <= ioloop_time) { @@ -926,10 +927,7 @@ ctx = maildir_sync_context_new(ibox); ret = maildir_sync_context(ctx, FALSE); maildir_sync_deinit(ctx); - - if (ret < 0) - return -1; } - return index_storage_sync(box, flags); + return index_mailbox_sync_init(box, flags, ret < 0); }
--- a/src/lib-storage/index/mbox/mbox-storage.c Mon Jul 12 14:31:34 2004 +0300 +++ b/src/lib-storage/index/mbox/mbox-storage.c Mon Jul 12 14:35:50 2004 +0300 @@ -831,22 +831,17 @@ return 0; } -static void mbox_storage_auto_sync(struct mailbox *box, - enum mailbox_sync_flags flags, - unsigned int min_newmail_notify_interval) +static void +mbox_notify_changes(struct mailbox *box, unsigned int min_interval, + mailbox_notify_callback_t *callback, void *context) { struct index_mailbox *ibox = (struct index_mailbox *)box; - ibox->min_newmail_notify_interval = min_newmail_notify_interval; + ibox->min_notify_interval = min_interval; + ibox->notify_callback = callback; + ibox->notify_context = context; - if ((ibox->autosync_flags == 0 && flags == 0) || - (ibox->autosync_flags != 0 && flags != 0)) { - /* flags or interval just changed. or nothing. */ - ibox->autosync_flags = flags; - } - ibox->autosync_flags = flags; - - if (flags == 0) + if (callback == NULL) index_mailbox_check_remove_all(ibox); else index_mailbox_check_add(ibox, ibox->path, FALSE); @@ -885,8 +880,10 @@ index_storage_allow_new_keywords, mbox_storage_close, index_storage_get_status, - mbox_storage_sync, - mbox_storage_auto_sync, + mbox_storage_sync_init, + index_mailbox_sync_next, + index_mailbox_sync_deinit, + mbox_notify_changes, mbox_transaction_begin, mbox_transaction_commit, mbox_transaction_rollback,
--- a/src/lib-storage/index/mbox/mbox-storage.h Mon Jul 12 14:31:34 2004 +0300 +++ b/src/lib-storage/index/mbox/mbox-storage.h Mon Jul 12 14:35:50 2004 +0300 @@ -34,7 +34,8 @@ int mbox_transaction_commit(struct mailbox_transaction_context *t); void mbox_transaction_rollback(struct mailbox_transaction_context *t); -int mbox_storage_sync(struct mailbox *box, enum mailbox_sync_flags flags); +struct mailbox_sync_context * +mbox_storage_sync_init(struct mailbox *box, enum mailbox_sync_flags flags); int mbox_save(struct mailbox_transaction_context *t, const struct mail_full_flags *flags,
--- a/src/lib-storage/index/mbox/mbox-sync.c Mon Jul 12 14:31:34 2004 +0300 +++ b/src/lib-storage/index/mbox/mbox-sync.c Mon Jul 12 14:35:50 2004 +0300 @@ -1320,17 +1320,18 @@ return ret; } -int mbox_storage_sync(struct mailbox *box, enum mailbox_sync_flags flags) +struct mailbox_sync_context * +mbox_storage_sync_init(struct mailbox *box, enum mailbox_sync_flags flags) { struct index_mailbox *ibox = (struct index_mailbox *)box; + int ret = 0; if ((flags & MAILBOX_SYNC_FLAG_FAST) == 0 || ibox->sync_last_check + MAILBOX_FULL_SYNC_INTERVAL <= ioloop_time) { ibox->sync_last_check = ioloop_time; - if (mbox_sync(ibox, FALSE, FALSE, FALSE) < 0) - return -1; + ret = mbox_sync(ibox, FALSE, FALSE, FALSE); } - return index_storage_sync(box, flags); + return index_mailbox_sync_init(box, flags, ret < 0); }
--- a/src/lib-storage/mail-storage-private.h Mon Jul 12 14:31:34 2004 +0300 +++ b/src/lib-storage/mail-storage-private.h Mon Jul 12 14:35:50 2004 +0300 @@ -66,9 +66,17 @@ int (*get_status)(struct mailbox *box, enum mailbox_status_items items, struct mailbox_status *status); - int (*sync)(struct mailbox *box, enum mailbox_sync_flags flags); - void (*auto_sync)(struct mailbox *box, enum mailbox_sync_flags flags, - unsigned int min_newmail_notify_interval); + struct mailbox_sync_context * + (*sync_init)(struct mailbox *box, + enum mailbox_sync_flags flags); + int (*sync_next)(struct mailbox_sync_context *ctx, + struct mailbox_sync_rec *sync_rec_r); + int (*sync_deinit)(struct mailbox_sync_context *ctx, + struct mailbox_status *status_r); + + void (*notify_changes)(struct mailbox *box, unsigned int min_interval, + mailbox_notify_callback_t *callback, + void *context); struct mailbox_transaction_context * (*transaction_begin)(struct mailbox *box, int hide); @@ -116,6 +124,10 @@ struct mailbox *box; }; +struct mailbox_sync_context { + struct mailbox *box; +}; + /* Set error message in storage. Critical errors are logged with i_error(), but user sees only "internal error" message. */ void mail_storage_clear_error(struct mail_storage *storage);
--- a/src/lib-storage/mail-storage.c Mon Jul 12 14:31:34 2004 +0300 +++ b/src/lib-storage/mail-storage.c Mon Jul 12 14:35:50 2004 +0300 @@ -334,15 +334,28 @@ return box->get_status(box, items, status); } -int mailbox_sync(struct mailbox *box, enum mailbox_sync_flags flags) +struct mailbox_sync_context * +mailbox_sync_init(struct mailbox *box, enum mailbox_sync_flags flags) { - return box->sync(box, flags); + return box->sync_init(box, flags); } -void mailbox_auto_sync(struct mailbox *box, enum mailbox_sync_flags flags, - unsigned int min_newmail_notify_interval) +int mailbox_sync_next(struct mailbox_sync_context *ctx, + struct mailbox_sync_rec *sync_rec_r) { - box->auto_sync(box, flags, min_newmail_notify_interval); + return ctx->box->sync_next(ctx, sync_rec_r); +} + +int mailbox_sync_deinit(struct mailbox_sync_context *ctx, + struct mailbox_status *status_r) +{ + return ctx->box->sync_deinit(ctx, status_r); +} + +void mailbox_notify_changes(struct mailbox *box, unsigned int min_interval, + mailbox_notify_callback_t *callback, void *context) +{ + box->notify_changes(box, min_interval, callback, context); } struct mail *mailbox_fetch(struct mailbox_transaction_context *t, uint32_t seq,
--- a/src/lib-storage/mail-storage.h Mon Jul 12 14:31:34 2004 +0300 +++ b/src/lib-storage/mail-storage.h Mon Jul 12 14:35:50 2004 +0300 @@ -89,6 +89,11 @@ MAILBOX_SYNC_AUTO_STOP = 0x04 }; +enum mailbox_sync_type { + MAILBOX_SYNC_TYPE_EXPUNGE = 0x01, + MAILBOX_SYNC_TYPE_FLAGS = 0x02 +}; + struct mail_storage; struct mail_storage_callbacks; struct mailbox_list; @@ -123,6 +128,11 @@ const char **keywords; }; +struct mailbox_sync_rec { + uint32_t seq1, seq2; + enum mailbox_sync_type type; +}; + struct mail_storage_callbacks { /* Alert: Not enough disk space */ void (*alert_no_diskspace)(struct mailbox *mailbox, void *context); @@ -133,26 +143,9 @@ void (*notify_no)(struct mailbox *mailbox, const char *text, void *context); - /* EXPUNGE */ - void (*expunge)(struct mailbox *mailbox, unsigned int seq, - void *context); - /* FETCH FLAGS */ - void (*update_flags)(struct mailbox *mailbox, unsigned int seq, - const struct mail_full_flags *flags, - void *context); +}; - /* EXISTS */ - void (*message_count_changed)(struct mailbox *mailbox, - unsigned int count, void *context); - /* RECENT */ - void (*recent_count_changed)(struct mailbox *mailbox, - unsigned int count, void *context); - /* FLAGS, PERMANENTFLAGS */ - void (*new_keywords)(struct mailbox *mailbox, - const char *keywords[], - unsigned int keywords_count, void *context); - -}; +typedef void mailbox_notify_callback_t(struct mailbox *box, void *context); extern int full_filesystem_access; @@ -271,12 +264,17 @@ struct mailbox_status *status); /* Synchronize the mailbox. */ -int mailbox_sync(struct mailbox *box, enum mailbox_sync_flags flags); +struct mailbox_sync_context * +mailbox_sync_init(struct mailbox *box, enum mailbox_sync_flags flags); +int mailbox_sync_next(struct mailbox_sync_context *ctx, + struct mailbox_sync_rec *sync_rec_r); +int mailbox_sync_deinit(struct mailbox_sync_context *ctx, + struct mailbox_status *status_r); -/* Synchronize mailbox in background. It's done until this function is - called with flags = MAILBOX_SYNC_AUTO_STOP. */ -void mailbox_auto_sync(struct mailbox *box, enum mailbox_sync_flags flags, - unsigned int min_newmail_notify_interval); +/* Call given callback function when something changes in the mailbox. + It's done until this function is called with callback = NULL. */ +void mailbox_notify_changes(struct mailbox *box, unsigned int min_interval, + mailbox_notify_callback_t *callback, void *context); struct mailbox_transaction_context * mailbox_transaction_begin(struct mailbox *box, int hide);
--- a/src/lib-storage/proxy-mailbox.c Mon Jul 12 14:31:34 2004 +0300 +++ b/src/lib-storage/proxy-mailbox.c Mon Jul 12 14:35:50 2004 +0300 @@ -32,19 +32,20 @@ return p->box->get_status(p->box, items, status); } -static int _sync(struct mailbox *box, enum mailbox_sync_flags flags) +static struct mailbox_sync_context * +_sync_init(struct mailbox *box, enum mailbox_sync_flags flags) { struct proxy_mailbox *p = (struct proxy_mailbox *) box; - return p->box->sync(p->box, flags); + return p->box->sync_init(p->box, flags); } -static void _auto_sync(struct mailbox *box, enum mailbox_sync_flags flags, - unsigned int min_newmail_notify_interval) +static void _notify_changes(struct mailbox *box, unsigned int min_interval, + mailbox_notify_callback_t *callback, void *context) { struct proxy_mailbox *p = (struct proxy_mailbox *) box; - p->box->auto_sync(p->box, flags, min_newmail_notify_interval); + return p->box->notify_changes(box, min_interval, callback, context); } static struct mail *_fetch(struct mailbox_transaction_context *t, uint32_t seq, @@ -150,8 +151,10 @@ pb->allow_new_keywords = _allow_new_keywords; pb->close = _close; pb->get_status = _get_status; - pb->sync = _sync; - pb->auto_sync = _auto_sync; + pb->sync_init = _sync_init; + pb->sync_next = box->sync_next; + pb->sync_deinit = box->sync_deinit; + pb->notify_changes = _notify_changes; pb->fetch = _fetch; pb->get_uids = _get_uids;
--- a/src/pop3/client.c Mon Jul 12 14:31:34 2004 +0300 +++ b/src/pop3/client.c Mon Jul 12 14:35:50 2004 +0300 @@ -38,6 +38,18 @@ o_stream_close(client->output); } +static int sync_mailbox(struct mailbox *box) +{ + struct mailbox_sync_context *ctx; + struct mailbox_sync_rec sync_rec; + struct mailbox_status status; + + ctx = mailbox_sync_init(box, 0); + while (mailbox_sync_next(ctx, &sync_rec) > 0) + ; + return mailbox_sync_deinit(ctx, &status); +} + static int init_mailbox(struct client *client) { struct mail_search_arg search_arg; @@ -51,6 +63,10 @@ search_arg.type = SEARCH_ALL; for (i = 0; i < 2; i++) { + if (sync_mailbox(client->mailbox) < 0) { + client_send_storage_error(client); + return FALSE; + } if (mailbox_get_status(client->mailbox, STATUS_MESSAGES, &status) < 0) { client_send_storage_error(client); @@ -104,10 +120,6 @@ /* well, sync and try again */ mailbox_transaction_rollback(t); - if (mailbox_sync(client->mailbox, 0) < 0) { - client_send_storage_error(client); - return FALSE; - } } client_send_line(client, "-ERR [IN-USE] Couldn't sync mailbox.");
--- a/src/pop3/mail-storage-callbacks.c Mon Jul 12 14:31:34 2004 +0300 +++ b/src/pop3/mail-storage-callbacks.c Mon Jul 12 14:35:50 2004 +0300 @@ -21,71 +21,8 @@ { } -static void expunge(struct mailbox *mailbox __attr_unused__, - unsigned int seq, void *context) -{ - struct client *client = context; - unsigned char *mask = client->deleted_bitmask; - unsigned int max, i, j; - - /* external deletes - we have to fix our internal deleted array. - this should happen only when we're doing the expunging at quit. */ - seq--; - client->messages_count--; - - if (!client->deleted) - return; - - max = client->messages_count / CHAR_BIT; - i = seq / CHAR_BIT; j = seq % CHAR_BIT; - mask[i] = (mask[i] & ((1 << j) - 1)) | - ((mask[i] >> (j+1)) << j) | - (i == max ? 0 : ((mask[i+1] & 1) << (CHAR_BIT-1))); - - if (i != max) { - for (i++; i < max-1; i++) { - mask[i] = (mask[i] >> 1) | - ((mask[i+1] & 1) << (CHAR_BIT-1)); - } - - mask[i] >>= 1; - } -} - -static void update_flags(struct mailbox *mailbox __attr_unused__, - unsigned int seq __attr_unused__, - const struct mail_full_flags *flags __attr_unused__, - void *context __attr_unused__) -{ -} - -static void message_count_changed(struct mailbox *mailbox __attr_unused__, - unsigned int count __attr_unused__, - void *context __attr_unused__) -{ -} - -static void recent_count_changed(struct mailbox *mailbox __attr_unused__, - unsigned int count __attr_unused__, - void *context __attr_unused__) -{ -} - - -static void new_keywords(struct mailbox *mailbox __attr_unused__, - const char *keywords[] __attr_unused__, - unsigned int keywords_count __attr_unused__, - void *context __attr_unused__) -{ -} - struct mail_storage_callbacks mail_storage_callbacks = { alert_no_diskspace, notify_ok, - notify_no, - expunge, - update_flags, - message_count_changed, - recent_count_changed, - new_keywords + notify_no };