From: Timo Sirainen Date: Mon, 4 Sep 2017 14:48:52 +0000 (+0300) Subject: lib-storage: Fix INBOX notifications to set correct events X-Git-Tag: 2.3.0.rc1~1110 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=838a76b0f4e65e98eeca3c134b8c290bc94eb849;p=thirdparty%2Fdovecot%2Fcore.git 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. --- diff --git a/src/lib-storage/list/mailbox-list-index-notify.c b/src/lib-storage/list/mailbox-list-index-notify.c index 48a4366a5b..64b0123e1c 100644 --- a/src/lib-storage/list/mailbox-list-index-notify.c +++ b/src/lib-storage/list/mailbox-list-index-notify.c @@ -60,12 +60,17 @@ struct mailbox_list_notify_index { char *list_log_path, *inbox_log_path; struct stat list_last_st, inbox_last_st; + struct mailbox *inbox; bool initialized:1; bool read_failed:1; bool 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 @@ mailbox_notify_node_update_status(struct mailbox_notify_node *nnode, 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 @@ int mailbox_list_index_notify_init(struct mailbox_list *list, &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 @@ void mailbox_list_index_notify_deinit(struct mailbox_list_notify *notify) (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 @@ static bool 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 @@ mailbox_list_index_notify_try_next(struct mailbox_list_notify_index *inotify) 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 @@ int mailbox_list_index_notify_next(struct mailbox_list_notify *notify, 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; }