]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-storage: Moved mailbox list iteration functions to a separate file.
authorTimo Sirainen <tss@iki.fi>
Fri, 2 Dec 2011 12:23:47 +0000 (14:23 +0200)
committerTimo Sirainen <tss@iki.fi>
Fri, 2 Dec 2011 12:23:47 +0000 (14:23 +0200)
src/lib-storage/Makefile.am
src/lib-storage/mailbox-list-iter.c [new file with mode: 0644]
src/lib-storage/mailbox-list.c

index 55a04838aff8c3b206c77a76bcbdc38ee2ef4bc3..a17301b963c294344184fe8785ed96629f398e31 100644 (file)
@@ -40,6 +40,7 @@ libstorage_la_SOURCES = \
        mailbox-header.c \
        mailbox-keywords.c \
        mailbox-list.c \
+       mailbox-list-iter.c \
        mailbox-search-result.c \
        mailbox-tree.c \
        mailbox-uidvalidity.c
diff --git a/src/lib-storage/mailbox-list-iter.c b/src/lib-storage/mailbox-list-iter.c
new file mode 100644 (file)
index 0000000..75bb3e8
--- /dev/null
@@ -0,0 +1,396 @@
+/* Copyright (c) 2006-2011 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "imap-match.h"
+#include "mailbox-tree.h"
+#include "mailbox-list-private.h"
+
+struct ns_list_iterate_context {
+       struct mailbox_list_iterate_context ctx;
+       struct mailbox_list_iterate_context *backend_ctx;
+       struct mail_namespace *namespaces;
+       pool_t pool;
+       const char **patterns, **patterns_ns_match;
+       enum namespace_type type_mask;
+};
+
+struct mailbox_list_iterate_context *
+mailbox_list_iter_init(struct mailbox_list *list, const char *pattern,
+                      enum mailbox_list_iter_flags flags)
+{
+       const char *patterns[2];
+
+       patterns[0] = pattern;
+       patterns[1] = NULL;
+       return mailbox_list_iter_init_multiple(list, patterns, flags);
+}
+
+static int mailbox_list_subscriptions_refresh(struct mailbox_list *list)
+{
+       struct mail_namespace *ns = list->ns;
+
+       if ((ns->flags & NAMESPACE_FLAG_SUBSCRIPTIONS) == 0) {
+               /* no subscriptions in this namespace. find where they are. */
+               ns = mail_namespace_find_subscribable(ns->user->namespaces,
+                                                     ns->prefix);
+               if (ns == NULL) {
+                       /* no subscriptions */
+                       return 0;
+               }
+       }
+       return ns->list->v.subscriptions_refresh(ns->list, list);
+}
+
+struct mailbox_list_iterate_context *
+mailbox_list_iter_init_multiple(struct mailbox_list *list,
+                               const char *const *patterns,
+                               enum mailbox_list_iter_flags flags)
+{
+       struct mailbox_list_iterate_context *ctx;
+       int ret = 0;
+
+       i_assert(*patterns != NULL);
+
+       if ((flags & (MAILBOX_LIST_ITER_SELECT_SUBSCRIBED |
+                     MAILBOX_LIST_ITER_RETURN_SUBSCRIBED)) != 0)
+               ret = mailbox_list_subscriptions_refresh(list);
+
+       ctx = list->v.iter_init(list, patterns, flags);
+       if (ret < 0)
+               ctx->failed = TRUE;
+       return ctx;
+}
+
+static bool
+ns_match_simple(struct ns_list_iterate_context *ctx, struct mail_namespace *ns)
+{
+       if ((ctx->type_mask & ns->type) == 0)
+               return FALSE;
+
+       if ((ctx->ctx.flags & MAILBOX_LIST_ITER_SKIP_ALIASES) != 0) {
+               if (ns->alias_for != NULL)
+                       return FALSE;
+       }
+       return TRUE;
+}
+
+static bool
+ns_match_inbox(struct mail_namespace *ns, const char *pattern)
+{
+       struct imap_match_glob *glob;
+
+       if ((ns->flags & NAMESPACE_FLAG_INBOX_USER) == 0)
+               return FALSE;
+
+       glob = imap_match_init(pool_datastack_create(), pattern,
+                              TRUE, mail_namespace_get_sep(ns));
+       return imap_match(glob, "INBOX") == IMAP_MATCH_YES;
+}
+
+static bool
+ns_match_next(struct ns_list_iterate_context *ctx, struct mail_namespace *ns,
+             const char *pattern)
+{
+       struct imap_match_glob *glob;
+       enum imap_match_result result;
+       const char *prefix_without_sep;
+       unsigned int len;
+
+       len = ns->prefix_len;
+       if (len > 0 && ns->prefix[len-1] == mail_namespace_get_sep(ns))
+               len--;
+
+       if ((ns->flags & (NAMESPACE_FLAG_LIST_PREFIX |
+                         NAMESPACE_FLAG_LIST_CHILDREN)) == 0) {
+               /* non-listable namespace matches only with exact prefix */
+               if (strncmp(ns->prefix, pattern, ns->prefix_len) != 0)
+                       return FALSE;
+       }
+
+       prefix_without_sep = t_strndup(ns->prefix, len);
+       if (*prefix_without_sep == '\0')
+               result = IMAP_MATCH_CHILDREN;
+       else {
+               glob = imap_match_init(pool_datastack_create(), pattern,
+                                      TRUE, mail_namespace_get_sep(ns));
+               result = imap_match(glob, prefix_without_sep);
+       }
+
+       if ((ctx->ctx.flags & MAILBOX_LIST_ITER_STAR_WITHIN_NS) == 0) {
+               switch (result) {
+               case IMAP_MATCH_YES:
+               case IMAP_MATCH_CHILDREN:
+                       return TRUE;
+               case IMAP_MATCH_NO:
+               case IMAP_MATCH_PARENT:
+                       break;
+               }
+               return FALSE;
+       }
+
+       switch (result) {
+       case IMAP_MATCH_YES:
+               /* allow matching prefix only when it's done without
+                  wildcards */
+               if (strcmp(prefix_without_sep, pattern) == 0)
+                       return TRUE;
+               break;
+       case IMAP_MATCH_CHILDREN: {
+               /* allow this only if there isn't another namespace
+                  with longer prefix that matches this pattern
+                  (namespaces are sorted by prefix length) */
+               struct mail_namespace *tmp;
+
+               T_BEGIN {
+                       for (tmp = ns->next; tmp != NULL; tmp = tmp->next) {
+                               if (ns_match_simple(ctx, tmp) &&
+                                   ns_match_next(ctx, tmp, pattern))
+                                       break;
+                       }
+               } T_END;
+               if (tmp == NULL)
+                       return TRUE;
+               break;
+       }
+       case IMAP_MATCH_NO:
+       case IMAP_MATCH_PARENT:
+               break;
+       }
+       return FALSE;
+}
+
+static bool
+ns_match(struct ns_list_iterate_context *ctx, struct mail_namespace *ns)
+{
+       unsigned int i;
+
+       if (!ns_match_simple(ctx, ns))
+               return FALSE;
+
+       /* filter out namespaces whose prefix doesn't match. this same code
+          handles both with and without STAR_WITHIN_NS, so the "without" case
+          is slower than necessary, but this shouldn't matter much */
+       T_BEGIN {
+               for (i = 0; ctx->patterns_ns_match[i] != NULL; i++) {
+                       if (ns_match_inbox(ns, ctx->patterns_ns_match[i]))
+                               break;
+                       if (ns_match_next(ctx, ns, ctx->patterns_ns_match[i]))
+                               break;
+               }
+       } T_END;
+
+       return ctx->patterns_ns_match[i] != NULL;
+}
+
+static struct mail_namespace *
+ns_next(struct ns_list_iterate_context *ctx, struct mail_namespace *ns)
+{
+       for (; ns != NULL; ns = ns->next) {
+               if (ns_match(ctx, ns))
+                       break;
+       }
+       return ns;
+}
+
+static const struct mailbox_info *
+mailbox_list_ns_iter_next(struct mailbox_list_iterate_context *_ctx)
+{
+       struct ns_list_iterate_context *ctx =
+               (struct ns_list_iterate_context *)_ctx;
+       const struct mailbox_info *info;
+
+       info = ctx->backend_ctx == NULL ? NULL :
+               mailbox_list_iter_next(ctx->backend_ctx);
+       if (info == NULL && ctx->namespaces != NULL) {
+               /* go to the next namespace */
+               if (mailbox_list_iter_deinit(&ctx->backend_ctx) < 0)
+                       _ctx->failed = TRUE;
+               ctx->ctx.list->ns = ctx->namespaces;
+               ctx->backend_ctx =
+                       mailbox_list_iter_init_multiple(ctx->namespaces->list,
+                                                       ctx->patterns,
+                                                       _ctx->flags);
+               ctx->namespaces = ns_next(ctx, ctx->namespaces->next);
+               return mailbox_list_ns_iter_next(_ctx);
+       }
+       return info;
+}
+
+static int
+mailbox_list_ns_iter_deinit(struct mailbox_list_iterate_context *_ctx)
+{
+       struct ns_list_iterate_context *ctx =
+               (struct ns_list_iterate_context *)_ctx;
+       int ret;
+
+       if (ctx->backend_ctx != NULL) {
+               if (mailbox_list_iter_deinit(&ctx->backend_ctx) < 0)
+                       _ctx->failed = TRUE;
+       }
+       ret = _ctx->failed ? -1 : 0;
+       pool_unref(&ctx->pool);
+       return ret;
+}
+
+static const char **
+dup_patterns_without_stars(pool_t pool, const char *const *patterns,
+                          unsigned int count)
+{
+       const char **dup;
+       unsigned int i;
+
+       dup = p_new(pool, const char *, count + 1);
+       for (i = 0; i < count; i++) {
+               char *p = p_strdup(pool, patterns[i]);
+               dup[i] = p;
+
+               for (; *p != '\0'; p++) {
+                       if (*p == '*')
+                               *p = '%';
+               }
+       }
+       return dup;
+}
+
+struct mailbox_list_iterate_context *
+mailbox_list_iter_init_namespaces(struct mail_namespace *namespaces,
+                                 const char *const *patterns,
+                                 enum namespace_type type_mask,
+                                 enum mailbox_list_iter_flags flags)
+{
+       struct ns_list_iterate_context *ctx;
+       unsigned int i, count;
+       pool_t pool;
+
+       i_assert(namespaces != NULL);
+
+       pool = pool_alloconly_create("mailbox list namespaces", 1024);
+       ctx = p_new(pool, struct ns_list_iterate_context, 1);
+       ctx->pool = pool;
+       ctx->type_mask = type_mask;
+       ctx->ctx.flags = flags;
+       ctx->ctx.list = p_new(pool, struct mailbox_list, 1);
+       ctx->ctx.list->v.iter_next = mailbox_list_ns_iter_next;
+       ctx->ctx.list->v.iter_deinit = mailbox_list_ns_iter_deinit;
+
+       count = str_array_length(patterns);
+       ctx->patterns = p_new(pool, const char *, count + 1);
+       for (i = 0; i < count; i++)
+               ctx->patterns[i] = p_strdup(pool, patterns[i]);
+
+       if ((flags & MAILBOX_LIST_ITER_STAR_WITHIN_NS) != 0) {
+               /* create copies of patterns with '*' wildcard changed to '%' */
+               ctx->patterns_ns_match =
+                       dup_patterns_without_stars(pool, ctx->patterns, count);
+       } else {
+               ctx->patterns_ns_match = ctx->patterns;
+       }
+
+       namespaces = ns_next(ctx, namespaces);
+       ctx->ctx.list->ns = namespaces;
+       if (namespaces != NULL) {
+               ctx->backend_ctx =
+                       mailbox_list_iter_init_multiple(namespaces->list,
+                                                       patterns, flags);
+               ctx->namespaces = ns_next(ctx, namespaces->next);
+       }
+       return &ctx->ctx;
+}
+
+const struct mailbox_info *
+mailbox_list_iter_next(struct mailbox_list_iterate_context *ctx)
+{
+       const struct mailbox_info *info;
+
+       info = ctx->list->v.iter_next(ctx);
+       if (info != NULL)
+               ctx->list->ns->flags |= NAMESPACE_FLAG_USABLE;
+       return info;
+}
+
+int mailbox_list_iter_deinit(struct mailbox_list_iterate_context **_ctx)
+{
+       struct mailbox_list_iterate_context *ctx = *_ctx;
+
+       *_ctx = NULL;
+
+       return ctx->list->v.iter_deinit(ctx);
+}
+
+static void node_fix_parents(struct mailbox_node *node)
+{
+       /* If we happened to create any of the parents, we need to mark them
+          nonexistent. */
+       node = node->parent;
+       for (; node != NULL; node = node->parent) {
+               if ((node->flags & MAILBOX_MATCHED) == 0)
+                       node->flags |= MAILBOX_NONEXISTENT;
+       }
+}
+
+static void
+mailbox_list_iter_update_real(struct mailbox_list_iter_update_context *ctx,
+                             const char *name)
+{
+       struct mail_namespace *ns = ctx->iter_ctx->list->ns;
+       struct mailbox_node *node;
+       enum mailbox_info_flags create_flags, always_flags;
+       enum imap_match_result match;
+       const char *p;
+       bool created, add_matched;
+
+       create_flags = MAILBOX_NOCHILDREN;
+       always_flags = ctx->leaf_flags;
+       add_matched = TRUE;
+
+       for (;;) {
+               created = FALSE;
+               match = imap_match(ctx->glob, name);
+               if (match == IMAP_MATCH_YES) {
+                       node = ctx->update_only ?
+                               mailbox_tree_lookup(ctx->tree_ctx, name) :
+                               mailbox_tree_get(ctx->tree_ctx, name, &created);
+                       if (created) {
+                               node->flags = create_flags;
+                               if (create_flags != 0)
+                                       node_fix_parents(node);
+                       }
+                       if (node != NULL) {
+                               if (!ctx->update_only && add_matched)
+                                       node->flags |= MAILBOX_MATCHED;
+                               node->flags |= always_flags;
+                       }
+                       /* We don't want to show the parent mailboxes unless
+                          something else matches them, but if they are matched
+                          we want to show them having child subscriptions */
+                       add_matched = FALSE;
+               } else {
+                       if ((match & IMAP_MATCH_PARENT) == 0)
+                               break;
+                       /* We've a (possibly) non-subscribed parent mailbox
+                          which has a subscribed child mailbox. Make sure we
+                          return the parent mailbox. */
+               }
+
+               if (!ctx->match_parents)
+                       break;
+
+               /* see if parent matches */
+               p = strrchr(name, mail_namespace_get_sep(ns));
+               if (p == NULL)
+                       break;
+
+               name = t_strdup_until(name, p);
+               create_flags |= MAILBOX_NONEXISTENT;
+               create_flags &= ~MAILBOX_NOCHILDREN;
+               always_flags = MAILBOX_CHILDREN | ctx->parent_flags;
+       }
+}
+
+void mailbox_list_iter_update(struct mailbox_list_iter_update_context *ctx,
+                             const char *name)
+{
+       T_BEGIN {
+               mailbox_list_iter_update_real(ctx, name);
+       } T_END;
+}
index 22fd45586ef89b0de79bdfcafe735ec24b8df2c8..d3f242d383d2a537f34e182cfec363147a854047 100644 (file)
@@ -8,19 +8,13 @@
 #include "sha1.h"
 #include "hash.h"
 #include "home-expand.h"
-#include "close-keep-errno.h"
-#include "eacces-error.h"
-#include "read-full.h"
-#include "write-full.h"
-#include "safe-mkstemp.h"
-#include "unlink-directory.h"
 #include "unichar.h"
 #include "settings-parser.h"
-#include "imap-match.h"
 #include "imap-utf7.h"
 #include "mailbox-log.h"
 #include "mailbox-tree.h"
-#include "mail-storage-private.h"
+#include "mail-storage.h"
+#include "mail-storage-hooks.h"
 #include "mailbox-list-private.h"
 
 #include <time.h>
 #define MAILBOX_MAX_HIERARCHY_LEVELS 20
 #define MAILBOX_MAX_HIERARCHY_NAME_LENGTH 200
 
-struct ns_list_iterate_context {
-       struct mailbox_list_iterate_context ctx;
-       struct mailbox_list_iterate_context *backend_ctx;
-       struct mail_namespace *namespaces;
-       pool_t pool;
-       const char **patterns, **patterns_ns_match;
-       enum namespace_type type_mask;
-};
-
 struct mailbox_list_module_register mailbox_list_module_register = { 0 };
 
 static ARRAY_DEFINE(mailbox_list_drivers, const struct mailbox_list *);
@@ -971,309 +956,6 @@ const char *mailbox_list_join_refpattern(struct mailbox_list *list,
        return pattern;
 }
 
-struct mailbox_list_iterate_context *
-mailbox_list_iter_init(struct mailbox_list *list, const char *pattern,
-                      enum mailbox_list_iter_flags flags)
-{
-       const char *patterns[2];
-
-       patterns[0] = pattern;
-       patterns[1] = NULL;
-       return mailbox_list_iter_init_multiple(list, patterns, flags);
-}
-
-static int mailbox_list_subscriptions_refresh(struct mailbox_list *list)
-{
-       struct mail_namespace *ns = list->ns;
-
-       if ((ns->flags & NAMESPACE_FLAG_SUBSCRIPTIONS) == 0) {
-               /* no subscriptions in this namespace. find where they are. */
-               ns = mail_namespace_find_subscribable(ns->user->namespaces,
-                                                     ns->prefix);
-               if (ns == NULL) {
-                       /* no subscriptions */
-                       return 0;
-               }
-       }
-       return ns->list->v.subscriptions_refresh(ns->list, list);
-}
-
-struct mailbox_list_iterate_context *
-mailbox_list_iter_init_multiple(struct mailbox_list *list,
-                               const char *const *patterns,
-                               enum mailbox_list_iter_flags flags)
-{
-       struct mailbox_list_iterate_context *ctx;
-       int ret = 0;
-
-       i_assert(*patterns != NULL);
-
-       if ((flags & (MAILBOX_LIST_ITER_SELECT_SUBSCRIBED |
-                     MAILBOX_LIST_ITER_RETURN_SUBSCRIBED)) != 0)
-               ret = mailbox_list_subscriptions_refresh(list);
-
-       ctx = list->v.iter_init(list, patterns, flags);
-       if (ret < 0)
-               ctx->failed = TRUE;
-       return ctx;
-}
-
-static bool
-ns_match_simple(struct ns_list_iterate_context *ctx, struct mail_namespace *ns)
-{
-       if ((ctx->type_mask & ns->type) == 0)
-               return FALSE;
-
-       if ((ctx->ctx.flags & MAILBOX_LIST_ITER_SKIP_ALIASES) != 0) {
-               if (ns->alias_for != NULL)
-                       return FALSE;
-       }
-       return TRUE;
-}
-
-static bool
-ns_match_inbox(struct mail_namespace *ns, const char *pattern)
-{
-       struct imap_match_glob *glob;
-
-       if ((ns->flags & NAMESPACE_FLAG_INBOX_USER) == 0)
-               return FALSE;
-
-       glob = imap_match_init(pool_datastack_create(), pattern,
-                              TRUE, mail_namespace_get_sep(ns));
-       return imap_match(glob, "INBOX") == IMAP_MATCH_YES;
-}
-
-static bool
-ns_match_next(struct ns_list_iterate_context *ctx, struct mail_namespace *ns,
-             const char *pattern)
-{
-       struct imap_match_glob *glob;
-       enum imap_match_result result;
-       const char *prefix_without_sep;
-       unsigned int len;
-
-       len = ns->prefix_len;
-       if (len > 0 && ns->prefix[len-1] == mail_namespace_get_sep(ns))
-               len--;
-
-       if ((ns->flags & (NAMESPACE_FLAG_LIST_PREFIX |
-                         NAMESPACE_FLAG_LIST_CHILDREN)) == 0) {
-               /* non-listable namespace matches only with exact prefix */
-               if (strncmp(ns->prefix, pattern, ns->prefix_len) != 0)
-                       return FALSE;
-       }
-
-       prefix_without_sep = t_strndup(ns->prefix, len);
-       if (*prefix_without_sep == '\0')
-               result = IMAP_MATCH_CHILDREN;
-       else {
-               glob = imap_match_init(pool_datastack_create(), pattern,
-                                      TRUE, mail_namespace_get_sep(ns));
-               result = imap_match(glob, prefix_without_sep);
-       }
-
-       if ((ctx->ctx.flags & MAILBOX_LIST_ITER_STAR_WITHIN_NS) == 0) {
-               switch (result) {
-               case IMAP_MATCH_YES:
-               case IMAP_MATCH_CHILDREN:
-                       return TRUE;
-               case IMAP_MATCH_NO:
-               case IMAP_MATCH_PARENT:
-                       break;
-               }
-               return FALSE;
-       }
-
-       switch (result) {
-       case IMAP_MATCH_YES:
-               /* allow matching prefix only when it's done without
-                  wildcards */
-               if (strcmp(prefix_without_sep, pattern) == 0)
-                       return TRUE;
-               break;
-       case IMAP_MATCH_CHILDREN: {
-               /* allow this only if there isn't another namespace
-                  with longer prefix that matches this pattern
-                  (namespaces are sorted by prefix length) */
-               struct mail_namespace *tmp;
-
-               T_BEGIN {
-                       for (tmp = ns->next; tmp != NULL; tmp = tmp->next) {
-                               if (ns_match_simple(ctx, tmp) &&
-                                   ns_match_next(ctx, tmp, pattern))
-                                       break;
-                       }
-               } T_END;
-               if (tmp == NULL)
-                       return TRUE;
-               break;
-       }
-       case IMAP_MATCH_NO:
-       case IMAP_MATCH_PARENT:
-               break;
-       }
-       return FALSE;
-}
-
-static bool
-ns_match(struct ns_list_iterate_context *ctx, struct mail_namespace *ns)
-{
-       unsigned int i;
-
-       if (!ns_match_simple(ctx, ns))
-               return FALSE;
-
-       /* filter out namespaces whose prefix doesn't match. this same code
-          handles both with and without STAR_WITHIN_NS, so the "without" case
-          is slower than necessary, but this shouldn't matter much */
-       T_BEGIN {
-               for (i = 0; ctx->patterns_ns_match[i] != NULL; i++) {
-                       if (ns_match_inbox(ns, ctx->patterns_ns_match[i]))
-                               break;
-                       if (ns_match_next(ctx, ns, ctx->patterns_ns_match[i]))
-                               break;
-               }
-       } T_END;
-
-       return ctx->patterns_ns_match[i] != NULL;
-}
-
-static struct mail_namespace *
-ns_next(struct ns_list_iterate_context *ctx, struct mail_namespace *ns)
-{
-       for (; ns != NULL; ns = ns->next) {
-               if (ns_match(ctx, ns))
-                       break;
-       }
-       return ns;
-}
-
-static const struct mailbox_info *
-mailbox_list_ns_iter_next(struct mailbox_list_iterate_context *_ctx)
-{
-       struct ns_list_iterate_context *ctx =
-               (struct ns_list_iterate_context *)_ctx;
-       const struct mailbox_info *info;
-
-       info = ctx->backend_ctx == NULL ? NULL :
-               mailbox_list_iter_next(ctx->backend_ctx);
-       if (info == NULL && ctx->namespaces != NULL) {
-               /* go to the next namespace */
-               if (mailbox_list_iter_deinit(&ctx->backend_ctx) < 0)
-                       _ctx->failed = TRUE;
-               ctx->ctx.list->ns = ctx->namespaces;
-               ctx->backend_ctx =
-                       mailbox_list_iter_init_multiple(ctx->namespaces->list,
-                                                       ctx->patterns,
-                                                       _ctx->flags);
-               ctx->namespaces = ns_next(ctx, ctx->namespaces->next);
-               return mailbox_list_ns_iter_next(_ctx);
-       }
-       return info;
-}
-
-static int
-mailbox_list_ns_iter_deinit(struct mailbox_list_iterate_context *_ctx)
-{
-       struct ns_list_iterate_context *ctx =
-               (struct ns_list_iterate_context *)_ctx;
-       int ret;
-
-       if (ctx->backend_ctx != NULL) {
-               if (mailbox_list_iter_deinit(&ctx->backend_ctx) < 0)
-                       _ctx->failed = TRUE;
-       }
-       ret = _ctx->failed ? -1 : 0;
-       pool_unref(&ctx->pool);
-       return ret;
-}
-
-static const char **
-dup_patterns_without_stars(pool_t pool, const char *const *patterns,
-                          unsigned int count)
-{
-       const char **dup;
-       unsigned int i;
-
-       dup = p_new(pool, const char *, count + 1);
-       for (i = 0; i < count; i++) {
-               char *p = p_strdup(pool, patterns[i]);
-               dup[i] = p;
-
-               for (; *p != '\0'; p++) {
-                       if (*p == '*')
-                               *p = '%';
-               }
-       }
-       return dup;
-}
-
-struct mailbox_list_iterate_context *
-mailbox_list_iter_init_namespaces(struct mail_namespace *namespaces,
-                                 const char *const *patterns,
-                                 enum namespace_type type_mask,
-                                 enum mailbox_list_iter_flags flags)
-{
-       struct ns_list_iterate_context *ctx;
-       unsigned int i, count;
-       pool_t pool;
-
-       i_assert(namespaces != NULL);
-
-       pool = pool_alloconly_create("mailbox list namespaces", 1024);
-       ctx = p_new(pool, struct ns_list_iterate_context, 1);
-       ctx->pool = pool;
-       ctx->type_mask = type_mask;
-       ctx->ctx.flags = flags;
-       ctx->ctx.list = p_new(pool, struct mailbox_list, 1);
-       ctx->ctx.list->v.iter_next = mailbox_list_ns_iter_next;
-       ctx->ctx.list->v.iter_deinit = mailbox_list_ns_iter_deinit;
-
-       count = str_array_length(patterns);
-       ctx->patterns = p_new(pool, const char *, count + 1);
-       for (i = 0; i < count; i++)
-               ctx->patterns[i] = p_strdup(pool, patterns[i]);
-
-       if ((flags & MAILBOX_LIST_ITER_STAR_WITHIN_NS) != 0) {
-               /* create copies of patterns with '*' wildcard changed to '%' */
-               ctx->patterns_ns_match =
-                       dup_patterns_without_stars(pool, ctx->patterns, count);
-       } else {
-               ctx->patterns_ns_match = ctx->patterns;
-       }
-
-       namespaces = ns_next(ctx, namespaces);
-       ctx->ctx.list->ns = namespaces;
-       if (namespaces != NULL) {
-               ctx->backend_ctx =
-                       mailbox_list_iter_init_multiple(namespaces->list,
-                                                       patterns, flags);
-               ctx->namespaces = ns_next(ctx, namespaces->next);
-       }
-       return &ctx->ctx;
-}
-
-const struct mailbox_info *
-mailbox_list_iter_next(struct mailbox_list_iterate_context *ctx)
-{
-       const struct mailbox_info *info;
-
-       info = ctx->list->v.iter_next(ctx);
-       if (info != NULL)
-               ctx->list->ns->flags |= NAMESPACE_FLAG_USABLE;
-       return info;
-}
-
-int mailbox_list_iter_deinit(struct mailbox_list_iterate_context **_ctx)
-{
-       struct mailbox_list_iterate_context *ctx = *_ctx;
-
-       *_ctx = NULL;
-
-       return ctx->list->v.iter_deinit(ctx);
-}
-
 int mailbox_has_children(struct mailbox_list *list, const char *name)
 {
        struct mailbox_list_iterate_context *iter;
@@ -1508,84 +1190,6 @@ void mailbox_list_set_changelog_timestamp(struct mailbox_list *list,
        list->changelog_timestamp = stamp;
 }
 
-static void node_fix_parents(struct mailbox_node *node)
-{
-       /* If we happened to create any of the parents, we need to mark them
-          nonexistent. */
-       node = node->parent;
-       for (; node != NULL; node = node->parent) {
-               if ((node->flags & MAILBOX_MATCHED) == 0)
-                       node->flags |= MAILBOX_NONEXISTENT;
-       }
-}
-
-static void
-mailbox_list_iter_update_real(struct mailbox_list_iter_update_context *ctx,
-                             const char *name)
-{
-       struct mail_namespace *ns = ctx->iter_ctx->list->ns;
-       struct mailbox_node *node;
-       enum mailbox_info_flags create_flags, always_flags;
-       enum imap_match_result match;
-       const char *p;
-       bool created, add_matched;
-
-       create_flags = MAILBOX_NOCHILDREN;
-       always_flags = ctx->leaf_flags;
-       add_matched = TRUE;
-
-       for (;;) {
-               created = FALSE;
-               match = imap_match(ctx->glob, name);
-               if (match == IMAP_MATCH_YES) {
-                       node = ctx->update_only ?
-                               mailbox_tree_lookup(ctx->tree_ctx, name) :
-                               mailbox_tree_get(ctx->tree_ctx, name, &created);
-                       if (created) {
-                               node->flags = create_flags;
-                               if (create_flags != 0)
-                                       node_fix_parents(node);
-                       }
-                       if (node != NULL) {
-                               if (!ctx->update_only && add_matched)
-                                       node->flags |= MAILBOX_MATCHED;
-                               node->flags |= always_flags;
-                       }
-                       /* We don't want to show the parent mailboxes unless
-                          something else matches them, but if they are matched
-                          we want to show them having child subscriptions */
-                       add_matched = FALSE;
-               } else {
-                       if ((match & IMAP_MATCH_PARENT) == 0)
-                               break;
-                       /* We've a (possibly) non-subscribed parent mailbox
-                          which has a subscribed child mailbox. Make sure we
-                          return the parent mailbox. */
-               }
-
-               if (!ctx->match_parents)
-                       break;
-
-               /* see if parent matches */
-               p = strrchr(name, mail_namespace_get_sep(ns));
-               if (p == NULL)
-                       break;
-
-               name = t_strdup_until(name, p);
-               create_flags |= MAILBOX_NONEXISTENT;
-               create_flags &= ~MAILBOX_NOCHILDREN;
-               always_flags = MAILBOX_CHILDREN | ctx->parent_flags;
-       }
-}
-
-void mailbox_list_iter_update(struct mailbox_list_iter_update_context *ctx,
-                             const char *name)
-{
-       T_BEGIN {
-               mailbox_list_iter_update_real(ctx, name);
-       } T_END;
-}
-
 bool mailbox_list_name_is_too_large(const char *name, char sep)
 {
        unsigned int levels = 1, level_len = 0;