Mercurial > dovecot > core-2.2
changeset 22457:5de2bae83c93
lib-storage: Fix INBOX notifications to set correct events
This fixes IMAP NOTIFY so it doesn't send STATUS notifications to INBOX when
it doesn't have to.
author | Timo Sirainen <timo.sirainen@dovecot.fi> |
---|---|
date | Mon, 04 Sep 2017 17:48:52 +0300 |
parents | d1658f4cb079 |
children | 83f93173dadb |
files | src/lib-storage/list/mailbox-list-index-notify.c |
diffstat | 1 files changed, 41 insertions(+), 13 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-storage/list/mailbox-list-index-notify.c Mon Sep 04 17:37:05 2017 +0300 +++ b/src/lib-storage/list/mailbox-list-index-notify.c Mon Sep 04 17:48:52 2017 +0300 @@ -60,12 +60,17 @@ char *list_log_path, *inbox_log_path; struct stat list_last_st, inbox_last_st; + struct mailbox *inbox; unsigned int initialized:1; unsigned int read_failed:1; unsigned int inbox_event_pending:1; }; +static const enum mailbox_status_items notify_status_items = + STATUS_UIDVALIDITY | STATUS_UIDNEXT | STATUS_MESSAGES | + STATUS_UNSEEN | STATUS_HIGHESTMODSEQ; + static enum mailbox_list_notify_event mailbox_list_index_get_changed_events(const struct mailbox_notify_node *nnode, const struct mailbox_status *status) @@ -101,6 +106,17 @@ nnode->highest_modseq = status->highest_modseq; } +static void +mailbox_list_index_notify_init_inbox(struct mailbox_list_notify_index *inotify) +{ + inotify->inbox = mailbox_alloc(inotify->notify.list, "INBOX", + MAILBOX_FLAG_READONLY); + if (mailbox_open(inotify->inbox) < 0) + mailbox_free(&inotify->inbox); + inotify->inbox_log_path = + i_strconcat(inotify->inbox->index->filepath, ".log", NULL); +} + int mailbox_list_index_notify_init(struct mailbox_list *list, enum mailbox_list_notify_event mask, struct mailbox_list_notify **notify_r) @@ -146,9 +162,7 @@ &index_dir) <= 0) { /* no indexes for INBOX? can't handle it */ } else { - /* FIXME: annoyingly hardcoded filename. */ - inotify->inbox_log_path = i_strdup_printf( - "%s/"MAIL_INDEX_PREFIX".log", index_dir); + mailbox_list_index_notify_init_inbox(inotify); } *notify_r = &inotify->notify; @@ -161,6 +175,8 @@ (struct mailbox_list_notify_index *)notify; bool b; + if (inotify->inbox != NULL) + mailbox_free(&inotify->inbox); if (inotify->subscriptions != NULL) mailbox_tree_deinit(&inotify->subscriptions); if (inotify->io_wait != NULL) @@ -724,15 +740,13 @@ mailbox_list_index_notify_change(struct mailbox_list_notify_index *inotify, uint32_t uid) { - const enum mailbox_status_items status_items = - STATUS_UIDVALIDITY | STATUS_UIDNEXT | STATUS_MESSAGES | - STATUS_UNSEEN | STATUS_HIGHESTMODSEQ; struct mailbox_list_notify_rec *rec; struct mailbox_notify_node *nnode, empty_node; struct mailbox_status status; if (!mailbox_list_index_notify_lookup(inotify, inotify->view, - uid, status_items, &status, &rec)) + uid, notify_status_items, + &status, &rec)) i_unreached(); /* get the old status */ @@ -789,6 +803,24 @@ return FALSE; } +static enum mailbox_list_notify_event +mailbox_list_notify_inbox_get_events(struct mailbox_list_notify_index *inotify) +{ + struct mailbox_status old_status, new_status; + struct mailbox_notify_node old_nnode; + + mailbox_get_open_status(inotify->inbox, notify_status_items, &old_status); + if (mailbox_sync(inotify->inbox, MAILBOX_SYNC_FLAG_FAST) < 0) { + i_error("Mailbox list index notify: Failed to sync INBOX: %s", + mailbox_get_last_internal_error(inotify->inbox, NULL)); + return 0; + } + mailbox_get_open_status(inotify->inbox, notify_status_items, &new_status); + + mailbox_notify_node_update_status(&old_nnode, &old_status); + return mailbox_list_index_get_changed_events(&old_nnode, &new_status); +} + int mailbox_list_index_notify_next(struct mailbox_list_notify *notify, const struct mailbox_list_notify_rec **rec_r) { @@ -813,12 +845,8 @@ i_zero(&inotify->notify_rec); inotify->notify_rec.vname = "INBOX"; inotify->notify_rec.storage_name = "INBOX"; - /* Don't bother trying to figure out which event exactly this - is. Just send them all and let the caller handle it. */ - inotify->notify_rec.events = MAILBOX_LIST_NOTIFY_APPENDS | - MAILBOX_LIST_NOTIFY_EXPUNGES | - MAILBOX_LIST_NOTIFY_SEEN_CHANGES | - MAILBOX_LIST_NOTIFY_MODSEQ_CHANGES; + inotify->notify_rec.events = + mailbox_list_notify_inbox_get_events(inotify); *rec_r = &inotify->notify_rec; return 1; }