bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2013-2018 Dovecot authors, see the included COPYING file */
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen#include "lib.h"
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen#include "str.h"
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen#include "mail-index.h"
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen#include "mail-storage.h"
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen#include "mailbox-list-private.h"
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen#include "mailbox-list-index.h"
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen#include "mailbox-list-notify-tree.h"
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainenstruct mailbox_list_notify_tree {
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen struct mailbox_list *list;
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen struct mailbox_tree_context *mailboxes;
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen struct mail_index_view *view;
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen bool failed;
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen};
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainenstatic void
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainenmailbox_list_notify_node_get_status(struct mailbox_list_notify_tree *tree,
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen struct mailbox_notify_node *nnode)
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen{
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen struct mailbox_status status;
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen uint32_t seq;
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen if (!mail_index_lookup_seq(tree->view, nnode->index_uid, &seq))
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen return;
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen
efe78d3ba24fc866af1c79b9223dc0809ba26cadStephan Bosch i_zero(&status);
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen (void)mailbox_list_index_status(tree->list, tree->view, seq,
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen STATUS_UIDVALIDITY | STATUS_UIDNEXT | STATUS_MESSAGES |
e048e63fec8d21d4af0fd9d27dd3fe5dcedf18e6Timo Sirainen STATUS_UNSEEN | STATUS_HIGHESTMODSEQ, &status, nnode->guid, NULL);
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen nnode->uidvalidity = status.uidvalidity;
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen nnode->uidnext = status.uidnext;
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen nnode->messages = status.messages;
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen nnode->unseen = status.unseen;
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen nnode->highest_modseq = status.highest_modseq;
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen}
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainenstatic void
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainenmailbox_list_notify_node_build(struct mailbox_list_notify_tree *tree,
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen struct mailbox_list_index_node *index_node,
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen string_t *path)
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen{
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen struct mailbox_node *node;
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen struct mailbox_notify_node *nnode;
2ac5f36aa7c2e7a07ba8815d43a6d7483f62e74cTimo Sirainen size_t prefix_len;
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen bool created;
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen str_append(path, index_node->name);
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen node = mailbox_tree_get(tree->mailboxes, str_c(path), &created);
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen nnode = (struct mailbox_notify_node *)node;
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen nnode->index_uid = index_node->uid;
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen if ((index_node->flags & MAILBOX_LIST_INDEX_FLAG_NONEXISTENT) != 0)
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen node->flags = MAILBOX_NONEXISTENT;
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen else if ((index_node->flags & MAILBOX_LIST_INDEX_FLAG_NOSELECT) != 0)
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen node->flags = MAILBOX_NOSELECT;
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen else {
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen node->flags = 0;
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen mailbox_list_notify_node_get_status(tree, nnode);
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen }
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen if ((index_node->flags & MAILBOX_LIST_INDEX_FLAG_NOINFERIORS) != 0)
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen node->flags |= MAILBOX_NOINFERIORS;
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen if (index_node->children != NULL) {
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen str_append_c(path, mailbox_list_get_hierarchy_sep(tree->list));
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen prefix_len = str_len(path);
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen index_node = index_node->children;
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen for (; index_node != NULL; index_node = index_node->next) {
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen str_truncate(path, prefix_len);
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen mailbox_list_notify_node_build(tree, index_node, path);
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen }
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen }
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen}
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainenstatic void
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainenmailbox_list_notify_tree_build(struct mailbox_list_notify_tree *tree)
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen{
43ce61b1d755832186f12b9739d18212b4744d14Aki Tuomi struct mailbox_list_index *ilist = INDEX_LIST_CONTEXT_REQUIRE(tree->list);
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen struct mailbox_list_index_node *index_node;
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen string_t *path = t_str_new(128);
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen if (mailbox_list_index_refresh(tree->list) < 0)
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen tree->failed = TRUE;
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen tree->view = mail_index_view_open(ilist->index);
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen index_node = ilist->mailbox_tree;
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen for (; index_node != NULL; index_node = index_node->next) {
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen str_truncate(path, 0);
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen mailbox_list_notify_node_build(tree, index_node, path);
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen }
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen mail_index_view_close(&tree->view);
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen}
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainenstruct mailbox_list_notify_tree *
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainenmailbox_list_notify_tree_init(struct mailbox_list *list)
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen{
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen struct mailbox_list_notify_tree *tree;
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen tree = i_new(struct mailbox_list_notify_tree, 1);
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen tree->list = list;
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen tree->mailboxes =
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen mailbox_tree_init_size(mailbox_list_get_hierarchy_sep(list),
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen sizeof(struct mailbox_notify_node));
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen mailbox_list_notify_tree_build(tree);
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen return tree;
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen}
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainenvoid mailbox_list_notify_tree_deinit(struct mailbox_list_notify_tree **_tree)
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen{
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen struct mailbox_list_notify_tree *tree = *_tree;
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen *_tree = NULL;
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen mailbox_tree_deinit(&tree->mailboxes);
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen i_free(tree);
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen}
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainenstruct mailbox_notify_node *
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainenmailbox_list_notify_tree_lookup(struct mailbox_list_notify_tree *tree,
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen const char *storage_name)
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen{
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen struct mailbox_node *node;
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen node = mailbox_tree_lookup(tree->mailboxes, storage_name);
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen return (struct mailbox_notify_node *)node;
8854395cdd21ca521b37ce669f3acb8445792b20Timo Sirainen}