void mailbox_list_subscriptions_fill(struct mailbox_list_iterate_context *ctx, struct mailbox_tree_context *tree, bool default_nonexistent) { struct mailbox_list_iter_update_context update_ctx; struct mailbox_tree_iterate_context *iter; const char *name; memset(&update_ctx, 0, sizeof(update_ctx)); update_ctx.iter_ctx = ctx; update_ctx.tree_ctx = tree; update_ctx.glob = ctx->glob; update_ctx.leaf_flags = MAILBOX_SUBSCRIBED; if (default_nonexistent) update_ctx.leaf_flags |= MAILBOX_NONEXISTENT; update_ctx.parent_flags = MAILBOX_CHILD_SUBSCRIBED; update_ctx.match_parents = (ctx->flags & MAILBOX_LIST_ITER_SELECT_RECURSIVEMATCH) != 0; iter = mailbox_tree_iterate_init(ctx->list->subscriptions, NULL, MAILBOX_SUBSCRIBED); while (mailbox_tree_iterate_next(iter, &name) != NULL) mailbox_list_iter_update(&update_ctx, name); mailbox_tree_iterate_deinit(&iter); }
struct mailbox_list_iterate_context * mailbox_list_subscriptions_iter_init(struct mailbox_list *list, const char *const *patterns, enum mailbox_list_iter_flags flags) { struct subscriptions_mailbox_list_iterate_context *ctx; pool_t pool; char sep = mail_namespace_get_sep(list->ns); pool = pool_alloconly_create("mailbox list subscriptions iter", 1024); ctx = p_new(pool, struct subscriptions_mailbox_list_iterate_context, 1); ctx->ctx.pool = pool; ctx->ctx.list = list; ctx->ctx.flags = flags; ctx->ctx.glob = imap_match_init_multiple(pool, patterns, TRUE, sep); array_create(&ctx->ctx.module_contexts, pool, sizeof(void *), 5); ctx->tree = mailbox_tree_init(sep); mailbox_list_subscriptions_fill(&ctx->ctx, ctx->tree, FALSE); ctx->info.ns = list->ns; /* the tree usually has only those entries we want to iterate through, but there are also non-matching root entries (e.g. "LSUB foo/%" will include the "foo"), which we'll drop with MAILBOX_MATCHED. */ ctx->iter = mailbox_tree_iterate_init(ctx->tree, NULL, MAILBOX_MATCHED); return &ctx->ctx; }
(flags & MAILBOX_LIST_ITER_RETURN_NO_FLAGS) == 0) { /* Add/update mailbox list with flags */ bool update_only = (flags & MAILBOX_LIST_ITER_SELECT_SUBSCRIBED) != 0; T_BEGIN { ret = maildir_fill_readdir(ctx, ctx->ctx.glob, update_only); } T_END; if (ret < 0) { ctx->ctx.failed = TRUE; return &ctx->ctx; } } ctx->tree_iter = mailbox_tree_iterate_init(ctx->tree_ctx, NULL, MAILBOX_MATCHED); return &ctx->ctx; } int maildir_list_iter_deinit(struct mailbox_list_iterate_context *_ctx) { struct maildir_list_iterate_context *ctx = (struct maildir_list_iterate_context *)_ctx; int ret = _ctx->failed ? -1 : 0; if (ctx->tree_iter != NULL) mailbox_tree_iterate_deinit(&ctx->tree_iter); mailbox_tree_deinit(&ctx->tree_ctx); pool_unref(&ctx->ctx.pool); return ret; }