bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2006-2018 Dovecot authors, see the included COPYING file */
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen#include "lib.h"
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen#include "str.h"
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen#include "imap-match.h"
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen#include "mail-storage.h"
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen#include "mailbox-list-subscriptions.h"
d823c19df414cac96c7f50a6f78a13fd03bcb27eTimo Sirainen#include "mailbox-list-iter-private.h"
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen#include "mailbox-list-index.h"
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen
d186a2391d98a3efa3fe1078879ef2798e169c29Timo Sirainenstatic bool iter_use_index(struct mailbox_list *list,
d186a2391d98a3efa3fe1078879ef2798e169c29Timo Sirainen enum mailbox_list_iter_flags flags)
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen{
43ce61b1d755832186f12b9739d18212b4744d14Aki Tuomi struct mailbox_list_index *ilist = INDEX_LIST_CONTEXT_REQUIRE(list);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
d186a2391d98a3efa3fe1078879ef2798e169c29Timo Sirainen if ((flags & MAILBOX_LIST_ITER_SELECT_SUBSCRIBED) != 0) {
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen /* for now we don't use indexes when listing subscriptions,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen because it needs to list also the nonexistent subscribed
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen mailboxes, which don't exist in the index. */
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen return FALSE;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen }
d186a2391d98a3efa3fe1078879ef2798e169c29Timo Sirainen if ((flags & MAILBOX_LIST_ITER_RAW_LIST) != 0 &&
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen ilist->has_backing_store) {
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen /* no indexing wanted with raw lists */
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen return FALSE;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen }
d186a2391d98a3efa3fe1078879ef2798e169c29Timo Sirainen if (mailbox_list_index_refresh(list) < 0 &&
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen ilist->has_backing_store) {
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen /* refresh failed */
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen return FALSE;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen }
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen return TRUE;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen}
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainenstruct mailbox_list_iterate_context *
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainenmailbox_list_index_iter_init(struct mailbox_list *list,
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen const char *const *patterns,
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen enum mailbox_list_iter_flags flags)
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen{
43ce61b1d755832186f12b9739d18212b4744d14Aki Tuomi struct mailbox_list_index *ilist = INDEX_LIST_CONTEXT_REQUIRE(list);
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen struct mailbox_list_index_iterate_context *ctx;
7ff6268cc35102675d73d44d680bed13d0709f7bTimo Sirainen pool_t pool;
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen char ns_sep = mail_namespace_get_sep(list->ns);
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen
f8a67af9b7bde79c186e6b82ea200d7fcf85571bTimo Sirainen if (!iter_use_index(list, flags)) {
f8a67af9b7bde79c186e6b82ea200d7fcf85571bTimo Sirainen /* no indexing */
f8a67af9b7bde79c186e6b82ea200d7fcf85571bTimo Sirainen return ilist->module_ctx.super.iter_init(list, patterns, flags);
f8a67af9b7bde79c186e6b82ea200d7fcf85571bTimo Sirainen }
f8a67af9b7bde79c186e6b82ea200d7fcf85571bTimo Sirainen
29543188462c9348f365ec29115d777ffe4769d3Timo Sirainen pool = pool_alloconly_create("mailbox list index iter", 2048);
7ff6268cc35102675d73d44d680bed13d0709f7bTimo Sirainen ctx = p_new(pool, struct mailbox_list_index_iterate_context, 1);
7ff6268cc35102675d73d44d680bed13d0709f7bTimo Sirainen ctx->ctx.pool = pool;
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen ctx->ctx.list = list;
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen ctx->ctx.flags = flags;
7ff6268cc35102675d73d44d680bed13d0709f7bTimo Sirainen ctx->ctx.glob = imap_match_init_multiple(pool, patterns, TRUE, ns_sep);
7ff6268cc35102675d73d44d680bed13d0709f7bTimo Sirainen array_create(&ctx->ctx.module_contexts, pool, sizeof(void *), 5);
0f97c2b6ec76e7f600e983cb952cf265a6189114Timo Sirainen ctx->info_pool = pool_alloconly_create("mailbox list index iter info", 128);
f8a67af9b7bde79c186e6b82ea200d7fcf85571bTimo Sirainen ctx->ctx.index_iteration = TRUE;
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen
f8a67af9b7bde79c186e6b82ea200d7fcf85571bTimo Sirainen /* listing mailboxes from index */
f8a67af9b7bde79c186e6b82ea200d7fcf85571bTimo Sirainen ctx->info.ns = list->ns;
f8a67af9b7bde79c186e6b82ea200d7fcf85571bTimo Sirainen ctx->path = str_new(pool, 128);
f8a67af9b7bde79c186e6b82ea200d7fcf85571bTimo Sirainen ctx->next_node = ilist->mailbox_tree;
f8a67af9b7bde79c186e6b82ea200d7fcf85571bTimo Sirainen ctx->mailbox_pool = ilist->mailbox_pool;
f8a67af9b7bde79c186e6b82ea200d7fcf85571bTimo Sirainen pool_ref(ctx->mailbox_pool);
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen return &ctx->ctx;
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen}
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainenstatic void
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainenmailbox_list_index_update_info(struct mailbox_list_index_iterate_context *ctx)
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen{
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen struct mailbox_list_index_node *node = ctx->next_node;
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen struct mailbox *box;
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen
0f97c2b6ec76e7f600e983cb952cf265a6189114Timo Sirainen p_clear(ctx->info_pool);
0f97c2b6ec76e7f600e983cb952cf265a6189114Timo Sirainen
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen str_truncate(ctx->path, ctx->parent_len);
2848ed04730e9f2ed91829d41312ebc3132b5613Timo Sirainen /* the root directory may have an empty name. in that case we'll still
2848ed04730e9f2ed91829d41312ebc3132b5613Timo Sirainen want to insert the separator, so check for non-NULL parent rather
2848ed04730e9f2ed91829d41312ebc3132b5613Timo Sirainen than non-empty path. */
2848ed04730e9f2ed91829d41312ebc3132b5613Timo Sirainen if (node->parent != NULL) {
cf05592015b99607095f970bf914f5d069bf0666Timo Sirainen str_append_c(ctx->path,
cf05592015b99607095f970bf914f5d069bf0666Timo Sirainen mailbox_list_get_hierarchy_sep(ctx->ctx.list));
cf05592015b99607095f970bf914f5d069bf0666Timo Sirainen }
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen str_append(ctx->path, node->name);
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen
402e999a878e0cc41a0afb830fea0a93afc75f0dTimo Sirainen ctx->info.vname = mailbox_list_get_vname(ctx->ctx.list, str_c(ctx->path));
f7dd04ec9ac41fda62fdc082e33debf3fccb0159Timo Sirainen ctx->info.flags = node->children != NULL ?
f7dd04ec9ac41fda62fdc082e33debf3fccb0159Timo Sirainen MAILBOX_CHILDREN : MAILBOX_NOCHILDREN;
f7dd04ec9ac41fda62fdc082e33debf3fccb0159Timo Sirainen if (strcmp(ctx->info.vname, "INBOX") != 0) {
f7dd04ec9ac41fda62fdc082e33debf3fccb0159Timo Sirainen /* non-INBOX */
f7dd04ec9ac41fda62fdc082e33debf3fccb0159Timo Sirainen ctx->info.vname = p_strdup(ctx->info_pool, ctx->info.vname);
65492363f4a0114c0706ee3fd212e429515f5a73Timo Sirainen } else if (!ctx->prefix_inbox_list) {
f7dd04ec9ac41fda62fdc082e33debf3fccb0159Timo Sirainen /* listing INBOX itself */
f7dd04ec9ac41fda62fdc082e33debf3fccb0159Timo Sirainen ctx->info.vname = "INBOX";
f7dd04ec9ac41fda62fdc082e33debf3fccb0159Timo Sirainen if (mail_namespace_is_inbox_noinferiors(ctx->info.ns)) {
f7dd04ec9ac41fda62fdc082e33debf3fccb0159Timo Sirainen ctx->info.flags &= ~(MAILBOX_CHILDREN|MAILBOX_NOCHILDREN);
f7dd04ec9ac41fda62fdc082e33debf3fccb0159Timo Sirainen ctx->info.flags |= MAILBOX_NOINFERIORS;
f7dd04ec9ac41fda62fdc082e33debf3fccb0159Timo Sirainen }
65492363f4a0114c0706ee3fd212e429515f5a73Timo Sirainen } else {
65492363f4a0114c0706ee3fd212e429515f5a73Timo Sirainen /* listing INBOX/INBOX */
65492363f4a0114c0706ee3fd212e429515f5a73Timo Sirainen ctx->info.vname = p_strconcat(ctx->info_pool,
65492363f4a0114c0706ee3fd212e429515f5a73Timo Sirainen ctx->ctx.list->ns->prefix, "INBOX", NULL);
65492363f4a0114c0706ee3fd212e429515f5a73Timo Sirainen ctx->info.flags |= MAILBOX_NONEXISTENT;
f7dd04ec9ac41fda62fdc082e33debf3fccb0159Timo Sirainen }
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen if ((node->flags & MAILBOX_LIST_INDEX_FLAG_NONEXISTENT) != 0)
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen ctx->info.flags |= MAILBOX_NONEXISTENT;
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen else if ((node->flags & MAILBOX_LIST_INDEX_FLAG_NOSELECT) != 0)
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen ctx->info.flags |= MAILBOX_NOSELECT;
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen if ((node->flags & MAILBOX_LIST_INDEX_FLAG_NOINFERIORS) != 0)
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen ctx->info.flags |= MAILBOX_NOINFERIORS;
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen if ((ctx->ctx.flags & (MAILBOX_LIST_ITER_SELECT_SUBSCRIBED |
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen MAILBOX_LIST_ITER_RETURN_SUBSCRIBED)) != 0) {
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen mailbox_list_set_subscription_flags(ctx->ctx.list,
402e999a878e0cc41a0afb830fea0a93afc75f0dTimo Sirainen ctx->info.vname,
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen &ctx->info.flags);
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen }
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen
85c9cf2c39903ecb102d701e8b19a7cf364dce83Timo Sirainen if ((ctx->ctx.flags & MAILBOX_LIST_ITER_RETURN_NO_FLAGS) == 0) {
85c9cf2c39903ecb102d701e8b19a7cf364dce83Timo Sirainen box = mailbox_alloc(ctx->ctx.list, ctx->info.vname, 0);
85c9cf2c39903ecb102d701e8b19a7cf364dce83Timo Sirainen mailbox_list_index_status_set_info_flags(box, node->uid,
85c9cf2c39903ecb102d701e8b19a7cf364dce83Timo Sirainen &ctx->info.flags);
85c9cf2c39903ecb102d701e8b19a7cf364dce83Timo Sirainen mailbox_free(&box);
85c9cf2c39903ecb102d701e8b19a7cf364dce83Timo Sirainen }
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen}
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainenstatic void
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainenmailbox_list_index_update_next(struct mailbox_list_index_iterate_context *ctx,
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen bool follow_children)
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen{
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen struct mailbox_list_index_node *node = ctx->next_node;
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen
65492363f4a0114c0706ee3fd212e429515f5a73Timo Sirainen if (!ctx->prefix_inbox_list && ctx->ctx.list->ns->prefix_len > 0 &&
65492363f4a0114c0706ee3fd212e429515f5a73Timo Sirainen strcmp(node->name, "INBOX") == 0 && node->parent == NULL &&
65492363f4a0114c0706ee3fd212e429515f5a73Timo Sirainen node->children != NULL) {
65492363f4a0114c0706ee3fd212e429515f5a73Timo Sirainen /* prefix/INBOX has children */
65492363f4a0114c0706ee3fd212e429515f5a73Timo Sirainen ctx->prefix_inbox_list = TRUE;
65492363f4a0114c0706ee3fd212e429515f5a73Timo Sirainen return;
65492363f4a0114c0706ee3fd212e429515f5a73Timo Sirainen }
65492363f4a0114c0706ee3fd212e429515f5a73Timo Sirainen
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen if (node->children != NULL && follow_children) {
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen ctx->parent_len = str_len(ctx->path);
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen ctx->next_node = node->children;
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen } else {
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen while (node->next == NULL) {
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen node = node->parent;
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen if (node != NULL) {
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen ctx->parent_len -= strlen(node->name);
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen if (node->parent != NULL)
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen ctx->parent_len--;
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen }
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen if (node == NULL) {
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen /* last one */
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen ctx->next_node = NULL;
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen return;
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen }
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen }
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen ctx->next_node = node->next;
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen }
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen}
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainenstatic bool
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Siraineniter_subscriptions_ok(struct mailbox_list_index_iterate_context *ctx)
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen{
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen if ((ctx->ctx.flags & MAILBOX_LIST_ITER_SELECT_SUBSCRIBED) == 0)
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen return TRUE;
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen if ((ctx->info.flags & MAILBOX_SUBSCRIBED) != 0)
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen return TRUE;
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen if ((ctx->ctx.flags & MAILBOX_LIST_ITER_SELECT_RECURSIVEMATCH) != 0 &&
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen (ctx->info.flags & MAILBOX_CHILD_SUBSCRIBED) != 0)
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen return TRUE;
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen return FALSE;
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen}
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainenconst struct mailbox_info *
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainenmailbox_list_index_iter_next(struct mailbox_list_iterate_context *_ctx)
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen{
43ce61b1d755832186f12b9739d18212b4744d14Aki Tuomi struct mailbox_list_index *ilist = INDEX_LIST_CONTEXT_REQUIRE(_ctx->list);
f8a67af9b7bde79c186e6b82ea200d7fcf85571bTimo Sirainen if (!_ctx->index_iteration) {
f8a67af9b7bde79c186e6b82ea200d7fcf85571bTimo Sirainen /* index isn't being used */
f8a67af9b7bde79c186e6b82ea200d7fcf85571bTimo Sirainen return ilist->module_ctx.super.iter_next(_ctx);
f8a67af9b7bde79c186e6b82ea200d7fcf85571bTimo Sirainen }
f8a67af9b7bde79c186e6b82ea200d7fcf85571bTimo Sirainen
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen struct mailbox_list_index_iterate_context *ctx =
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen (struct mailbox_list_index_iterate_context *)_ctx;
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen bool follow_children;
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen enum imap_match_result match;
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen /* listing mailboxes from index */
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen while (ctx->next_node != NULL) {
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen mailbox_list_index_update_info(ctx);
402e999a878e0cc41a0afb830fea0a93afc75f0dTimo Sirainen match = imap_match(_ctx->glob, ctx->info.vname);
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen follow_children = (match & (IMAP_MATCH_YES |
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen IMAP_MATCH_CHILDREN)) != 0;
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen if (match == IMAP_MATCH_YES && iter_subscriptions_ok(ctx)) {
d823c19df414cac96c7f50a6f78a13fd03bcb27eTimo Sirainen /* If this is a) \NoSelect leaf, b) not LAYOUT=index
d823c19df414cac96c7f50a6f78a13fd03bcb27eTimo Sirainen and c) NO-NOSELECT is set, try to rmdir the leaf
d823c19df414cac96c7f50a6f78a13fd03bcb27eTimo Sirainen directores from filesystem. (With LAYOUT=index the
d823c19df414cac96c7f50a6f78a13fd03bcb27eTimo Sirainen \NoSelect mailboxes aren't on the filesystem.) */
d823c19df414cac96c7f50a6f78a13fd03bcb27eTimo Sirainen if (ilist->has_backing_store &&
d823c19df414cac96c7f50a6f78a13fd03bcb27eTimo Sirainen mailbox_list_iter_try_delete_noselect(_ctx, &ctx->info,
d823c19df414cac96c7f50a6f78a13fd03bcb27eTimo Sirainen str_c(ctx->path))) {
d823c19df414cac96c7f50a6f78a13fd03bcb27eTimo Sirainen /* Deleted \NoSelect leaf. Refresh the index
d823c19df414cac96c7f50a6f78a13fd03bcb27eTimo Sirainen later on so it gets removed from the index
d823c19df414cac96c7f50a6f78a13fd03bcb27eTimo Sirainen as well. */
d823c19df414cac96c7f50a6f78a13fd03bcb27eTimo Sirainen mailbox_list_index_refresh_later(_ctx->list);
d823c19df414cac96c7f50a6f78a13fd03bcb27eTimo Sirainen } else {
d823c19df414cac96c7f50a6f78a13fd03bcb27eTimo Sirainen mailbox_list_index_update_next(ctx, TRUE);
d823c19df414cac96c7f50a6f78a13fd03bcb27eTimo Sirainen return &ctx->info;
d823c19df414cac96c7f50a6f78a13fd03bcb27eTimo Sirainen }
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen } else if ((_ctx->flags & MAILBOX_LIST_ITER_SELECT_SUBSCRIBED) != 0 &&
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen (ctx->info.flags & MAILBOX_CHILD_SUBSCRIBED) == 0) {
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen /* listing only subscriptions, but there are no
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen subscribed children. */
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen follow_children = FALSE;
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen }
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen mailbox_list_index_update_next(ctx, follow_children);
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen }
34b724d1d7e50b1ab24267a3b6fc089b1147c1abAki Tuomi return mailbox_list_iter_default_next(_ctx);
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen}
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainenint mailbox_list_index_iter_deinit(struct mailbox_list_iterate_context *_ctx)
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen{
43ce61b1d755832186f12b9739d18212b4744d14Aki Tuomi struct mailbox_list_index *ilist = INDEX_LIST_CONTEXT_REQUIRE(_ctx->list);
f8a67af9b7bde79c186e6b82ea200d7fcf85571bTimo Sirainen if (!_ctx->index_iteration)
f8a67af9b7bde79c186e6b82ea200d7fcf85571bTimo Sirainen return ilist->module_ctx.super.iter_deinit(_ctx);
f8a67af9b7bde79c186e6b82ea200d7fcf85571bTimo Sirainen
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen struct mailbox_list_index_iterate_context *ctx =
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen (struct mailbox_list_index_iterate_context *)_ctx;
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen int ret = ctx->failed ? -1 : 0;
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen
f8a67af9b7bde79c186e6b82ea200d7fcf85571bTimo Sirainen pool_unref(&ctx->mailbox_pool);
0f97c2b6ec76e7f600e983cb952cf265a6189114Timo Sirainen pool_unref(&ctx->info_pool);
7ff6268cc35102675d73d44d680bed13d0709f7bTimo Sirainen pool_unref(&_ctx->pool);
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen return ret;
66e1cf5014bec1cf1a8339be6fccc9be5ad3c793Timo Sirainen}