const struct mailbox_info *
mailbox_list_subscriptions_iter_next(struct mailbox_list_iterate_context *_ctx)
{
	struct subscriptions_mailbox_list_iterate_context *ctx =
		(struct subscriptions_mailbox_list_iterate_context *)_ctx;
	struct mailbox_list *list = _ctx->list;
	struct mailbox_node *node;
	enum mailbox_info_flags subs_flags;
	const char *vname, *storage_name, *error;
	int ret;

	node = mailbox_tree_iterate_next(ctx->iter, &vname);
	if (node == NULL)
		return NULL;

	ctx->info.vname = vname;
	subs_flags = node->flags & (MAILBOX_SUBSCRIBED |
				    MAILBOX_CHILD_SUBSCRIBED);

	if ((_ctx->flags & MAILBOX_LIST_ITER_RETURN_NO_FLAGS) != 0 &&
	    (_ctx->flags & MAILBOX_LIST_ITER_RETURN_CHILDREN) == 0) {
		/* don't care about flags, just return it */
		ctx->info.flags = subs_flags;
		return &ctx->info;
	}

	storage_name = mailbox_list_get_storage_name(list, vname);
	if (!mailbox_list_is_valid_name(list, storage_name, &error)) {
		/* broken entry in subscriptions file */
		ctx->info.flags = MAILBOX_NONEXISTENT;
	} else if (mailbox_list_mailbox(list, storage_name,
					&ctx->info.flags) < 0) {
		ctx->info.flags = 0;
		_ctx->failed = TRUE;
	} else if ((_ctx->flags & MAILBOX_LIST_ITER_RETURN_CHILDREN) != 0 &&
		   (ctx->info.flags & (MAILBOX_CHILDREN |
				       MAILBOX_NOCHILDREN)) == 0) {
		ret = mailbox_has_children(list, storage_name);
		if (ret < 0)
			_ctx->failed = TRUE;
		else if (ret == 0)
			ctx->info.flags |= MAILBOX_NOCHILDREN;
		else
			ctx->info.flags |= MAILBOX_CHILDREN;

	}

	ctx->info.flags &= ~(MAILBOX_SUBSCRIBED | MAILBOX_CHILD_SUBSCRIBED);
	ctx->info.flags |=
		node->flags & (MAILBOX_SUBSCRIBED | MAILBOX_CHILD_SUBSCRIBED);
	return &ctx->info;
}
static int
maildir_fill_inbox(struct maildir_list_iterate_context *ctx,
		   struct imap_match_glob *glob, const char *inbox_name,
		   bool update_only)
{
	struct mailbox_node *node;
	enum mailbox_info_flags flags;
	enum imap_match_result match;
	bool created;
	int ret;

	if ((ctx->ctx.flags & MAILBOX_LIST_ITER_NO_AUTO_BOXES) == 0) {
		/* always show INBOX */
	} else {
		/* INBOX may be Maildir root or completely elsewhere.
		   show it only if it has already been created */
		ret = mailbox_list_mailbox(ctx->ctx.list, "INBOX", &flags);
		if (ret < 0)
			return -1;
		if ((flags & MAILBOX_NONEXISTENT) != 0)
			update_only = TRUE;
	}

	if (update_only) {
		node = mailbox_tree_lookup(ctx->tree_ctx, inbox_name);
		if (node != NULL)
			node->flags &= ~MAILBOX_NONEXISTENT;
		return 0;
	}

	/* add the INBOX only if it matches the patterns */
	match = imap_match(glob, inbox_name);
	if (match == IMAP_MATCH_PARENT)
		maildir_fill_parents(ctx, glob, FALSE, inbox_name);
	else if (match == IMAP_MATCH_YES) {
		node = mailbox_tree_get(ctx->tree_ctx, inbox_name, &created);
		if (created)
			node->flags = MAILBOX_NOCHILDREN;
		else
			node->flags &= ~MAILBOX_NONEXISTENT;
		node->flags |= MAILBOX_MATCHED;
	}
	return 0;
}