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; }
struct mailbox_list_iterate_context * mailbox_list_index_iter_init(struct mailbox_list *list, const char *const *patterns, enum mailbox_list_iter_flags flags) { struct mailbox_list_index *ilist = INDEX_LIST_CONTEXT(list); struct mailbox_list_index_iterate_context *ctx; pool_t pool; char ns_sep = mail_namespace_get_sep(list->ns); pool = pool_alloconly_create("mailbox list index iter", 2048); ctx = p_new(pool, struct mailbox_list_index_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, ns_sep); array_create(&ctx->ctx.module_contexts, pool, sizeof(void *), 5); ctx->info_pool = pool_alloconly_create("mailbox list index iter info", 128); if (!iter_use_index(ctx)) { /* no indexing */ ctx->backend_ctx = ilist->module_ctx.super. iter_init(list, patterns, flags); } else { /* listing mailboxes from index */ ctx->info.ns = list->ns; ctx->path = str_new(pool, 128); ctx->next_node = ilist->mailbox_tree; ctx->mailbox_pool = ilist->mailbox_pool; pool_ref(ctx->mailbox_pool); } return &ctx->ctx; }
struct imap_match_glob * imap_match_init(pool_t pool, const char *pattern, bool inboxcase, char separator) { const char *patterns[2]; patterns[0] = pattern; patterns[1] = NULL; return imap_match_init_multiple(pool, patterns, inboxcase, separator); }
static struct mailbox_list_iterate_context * acl_mailbox_list_iter_init(struct mailbox_list *list, const char *const *patterns, enum mailbox_list_iter_flags flags) { struct acl_mailbox_list *alist = ACL_LIST_CONTEXT(list); struct acl_mailbox_list_iterate_context *ctx; pool_t pool; const char *p; unsigned int i; bool inboxcase; pool = pool_alloconly_create("mailbox list acl iter", 1024); ctx = p_new(pool, struct acl_mailbox_list_iterate_context, 1); ctx->ctx.pool = pool; ctx->ctx.list = list; ctx->ctx.flags = flags; if (list->ns->type != MAIL_NAMESPACE_TYPE_PRIVATE && (list->ns->flags & NAMESPACE_FLAG_SUBSCRIPTIONS) != 0) { /* non-private namespace with subscriptions=yes. this could be a site-global subscriptions file, so hide subscriptions for mailboxes the user doesn't see. */ ctx->hide_nonlistable_subscriptions = TRUE; } inboxcase = (list->ns->flags & NAMESPACE_FLAG_INBOX_USER) != 0; ctx->sep = mail_namespace_get_sep(list->ns); ctx->ctx.glob = imap_match_init_multiple(pool, patterns, inboxcase, ctx->sep); /* see if all patterns have only a single '*' and it's at the end. we can use it to do some optimizations. */ ctx->simple_star_glob = TRUE; for (i = 0; patterns[i] != NULL; i++) { p = strchr(patterns[i], '*'); if (p == NULL || p[1] != '\0') { ctx->simple_star_glob = FALSE; break; } } /* Try to avoid reading ACLs from all mailboxes by getting a smaller list of mailboxes that have even potential to be visible. If we couldn't get such a list, we'll go through all mailboxes. */ T_BEGIN { acl_mailbox_try_list_fast(ctx); } T_END; ctx->super_ctx = alist->module_ctx.super. iter_init(list, patterns, flags); return &ctx->ctx; }
struct mailbox_list_iterate_context * maildir_list_iter_init(struct mailbox_list *_list, const char *const *patterns, enum mailbox_list_iter_flags flags) { struct maildir_mailbox_list *list = (struct maildir_mailbox_list *)_list; struct maildir_list_iterate_context *ctx; pool_t pool; char ns_sep = mail_namespace_get_sep(_list->ns); int ret; pool = pool_alloconly_create("mailbox list maildir iter", 1024); ctx = p_new(pool, struct maildir_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, ns_sep); array_create(&ctx->ctx.module_contexts, pool, sizeof(void *), 5); ctx->tree_ctx = mailbox_tree_init(ns_sep); ctx->info.ns = _list->ns; ctx->prefix_char = strcmp(_list->name, MAILBOX_LIST_NAME_IMAPDIR) == 0 ? '\0' : list->sep; ctx->dir = _list->set.root_dir; if ((flags & MAILBOX_LIST_ITER_SELECT_SUBSCRIBED) != 0) { /* Listing only subscribed mailboxes. Flags are set later if needed. */ bool default_nonexistent = (flags & MAILBOX_LIST_ITER_RETURN_NO_FLAGS) == 0; mailbox_list_subscriptions_fill(&ctx->ctx, ctx->tree_ctx, default_nonexistent); } if ((flags & MAILBOX_LIST_ITER_SELECT_SUBSCRIBED) == 0 || (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; } }