const struct mailbox_info * mailbox_list_index_iter_next(struct mailbox_list_iterate_context *_ctx) { struct mailbox_list_index_iterate_context *ctx = (struct mailbox_list_index_iterate_context *)_ctx; struct mailbox_list_index *ilist = INDEX_LIST_CONTEXT(_ctx->list); bool follow_children; enum imap_match_result match; if (ctx->backend_ctx != NULL) { /* index isn't being used */ return ilist->module_ctx.super.iter_next(ctx->backend_ctx); } /* listing mailboxes from index */ while (ctx->next_node != NULL) { mailbox_list_index_update_info(ctx); match = imap_match(_ctx->glob, ctx->info.vname); follow_children = (match & (IMAP_MATCH_YES | IMAP_MATCH_CHILDREN)) != 0; if (match == IMAP_MATCH_YES && iter_subscriptions_ok(ctx)) { mailbox_list_index_update_next(ctx, TRUE); return &ctx->info; } else if ((_ctx->flags & MAILBOX_LIST_ITER_SELECT_SUBSCRIBED) != 0 && (ctx->info.flags & MAILBOX_CHILD_SUBSCRIBED) == 0) { /* listing only subscriptions, but there are no subscribed children. */ follow_children = FALSE; } mailbox_list_index_update_next(ctx, follow_children); } return NULL; }
const struct mailbox_info * mailbox_list_index_iter_next(struct mailbox_list_iterate_context *_ctx) { struct mailbox_list_index *ilist = INDEX_LIST_CONTEXT_REQUIRE(_ctx->list); if (!_ctx->index_iteration) { /* index isn't being used */ return ilist->module_ctx.super.iter_next(_ctx); } struct mailbox_list_index_iterate_context *ctx = (struct mailbox_list_index_iterate_context *)_ctx; bool follow_children; enum imap_match_result match; /* listing mailboxes from index */ while (ctx->next_node != NULL) { mailbox_list_index_update_info(ctx); match = imap_match(_ctx->glob, ctx->info.vname); follow_children = (match & (IMAP_MATCH_YES | IMAP_MATCH_CHILDREN)) != 0; if (match == IMAP_MATCH_YES && iter_subscriptions_ok(ctx)) { /* If this is a) \NoSelect leaf, b) not LAYOUT=index and c) NO-NOSELECT is set, try to rmdir the leaf directores from filesystem. (With LAYOUT=index the \NoSelect mailboxes aren't on the filesystem.) */ if (ilist->has_backing_store && mailbox_list_iter_try_delete_noselect(_ctx, &ctx->info, str_c(ctx->path))) { /* Deleted \NoSelect leaf. Refresh the index later on so it gets removed from the index as well. */ mailbox_list_index_refresh_later(_ctx->list); } else { mailbox_list_index_update_next(ctx, TRUE); return &ctx->info; } } else if ((_ctx->flags & MAILBOX_LIST_ITER_SELECT_SUBSCRIBED) != 0 && (ctx->info.flags & MAILBOX_CHILD_SUBSCRIBED) == 0) { /* listing only subscriptions, but there are no subscribed children. */ follow_children = FALSE; } mailbox_list_index_update_next(ctx, follow_children); } return mailbox_list_iter_default_next(_ctx); }