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;
}
Example #2
0
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);
}