Mercurial > dovecot > original-hg > dovecot-1.2
changeset 6010:ed6c07975ccb HEAD
Fixes to returning mailboxes
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sun, 15 Jul 2007 06:46:00 +0300 |
parents | 62f92a68fc72 |
children | 91c229e00772 |
files | src/lib-storage/list/mailbox-list-maildir-iter.c src/lib-storage/list/mailbox-list-subscriptions.c |
diffstat | 2 files changed, 126 insertions(+), 117 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-storage/list/mailbox-list-maildir-iter.c Sun Jul 15 06:45:36 2007 +0300 +++ b/src/lib-storage/list/mailbox-list-maildir-iter.c Sun Jul 15 06:46:00 2007 +0300 @@ -22,13 +22,66 @@ struct mailbox_info info; }; +static void node_fix_parents(struct mailbox_node *node) +{ + /* Fix parent nodes' children states. also 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; + + node->flags |= MAILBOX_CHILDREN; + node->flags &= ~MAILBOX_NOCHILDREN; + } +} + +static void maildir_fill_parents(struct maildir_list_iterate_context *ctx, + struct imap_match_glob *glob, bool update_only, + string_t *mailbox, const char *mailbox_c, + enum mailbox_info_flags flags) +{ + struct mailbox_node *node; + const char *p; + char hierarchy_sep; + bool created; + + hierarchy_sep = ctx->ctx.list->hierarchy_sep; + + t_push(); + while ((p = strrchr(mailbox_c, hierarchy_sep)) != NULL) { + str_truncate(mailbox, (size_t) (p-mailbox_c)); + mailbox_c = str_c(mailbox); + if (imap_match(glob, mailbox_c) == IMAP_MATCH_YES) { + created = FALSE; + node = update_only ? + mailbox_tree_lookup(ctx->tree_ctx, mailbox_c) : + mailbox_tree_get(ctx->tree_ctx, + mailbox_c, &created); + if (node != NULL) { + if (created) { + /* we haven't yet seen this mailbox, + but we might see it later */ + node->flags = MAILBOX_NONEXISTENT; + } + if (!update_only) + node->flags |= MAILBOX_MATCHED; + node->flags |= MAILBOX_CHILDREN | flags; + node->flags &= ~MAILBOX_NOCHILDREN; + node_fix_parents(node); + } + } + } + t_pop(); +} + static int maildir_fill_readdir(struct maildir_list_iterate_context *ctx, struct imap_match_glob *glob, bool update_only) { DIR *dirp; struct dirent *d; - const char *p, *mailbox_c; + const char *mailbox_c; string_t *mailbox; enum mailbox_info_flags flags; enum imap_match_result match; @@ -84,37 +137,14 @@ if (ret == 0) continue; - if ((match & IMAP_MATCH_PARENT) != 0) { - /* get the name of the parent mailbox that matches */ - t_push(); - while ((p = strrchr(mailbox_c, - hierarchy_sep)) != NULL) { - str_truncate(mailbox, (size_t) (p-mailbox_c)); - mailbox_c = str_c(mailbox); - if (imap_match(glob, mailbox_c) == - IMAP_MATCH_YES) - break; - } - i_assert(p != NULL); + /* we know the children flags ourself, so ignore if any of + them were set. */ + flags &= ~(MAILBOX_NOINFERIORS | + MAILBOX_CHILDREN | MAILBOX_NOCHILDREN); - created = FALSE; - node = update_only ? - mailbox_tree_lookup(ctx->tree_ctx, mailbox_c) : - mailbox_tree_get(ctx->tree_ctx, - mailbox_c, &created); - if (node != NULL) { - if (created) { - /* we haven't yet seen this mailbox, - but we might see it later */ - node->flags = MAILBOX_NONEXISTENT; - } - if (!update_only) - node->flags |= MAILBOX_MATCHED; - node->flags |= MAILBOX_CHILDREN; - node->flags &= ~MAILBOX_NOCHILDREN; - } - - t_pop(); + if ((match & IMAP_MATCH_PARENT) != 0) { + maildir_fill_parents(ctx, glob, update_only, + mailbox, mailbox_c, flags); } else { created = FALSE; node = update_only ? @@ -129,25 +159,8 @@ node->flags &= ~MAILBOX_NONEXISTENT; if (!update_only) node->flags |= MAILBOX_MATCHED; - } - } - if (node != NULL) { - /* apply flags given by storage. we know the children - flags ourself, so ignore if any of them were set. */ - node->flags |= flags & ~(MAILBOX_NOINFERIORS | - MAILBOX_CHILDREN | - MAILBOX_NOCHILDREN); - - /* Fix parent nodes' children states. also 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; - - node->flags |= MAILBOX_CHILDREN; - node->flags &= ~MAILBOX_NOCHILDREN; + node->flags |= flags; + node_fix_parents(node); } } }
--- a/src/lib-storage/list/mailbox-list-subscriptions.c Sun Jul 15 06:45:36 2007 +0300 +++ b/src/lib-storage/list/mailbox-list-subscriptions.c Sun Jul 15 06:46:00 2007 +0300 @@ -7,15 +7,68 @@ #include "mailbox-list-private.h" #include "mailbox-list-subscriptions.h" -static void nodes_add_child_subscribed(struct mailbox_node *node) +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_subscription_add(struct mailbox_list_iterate_context *ctx, + struct mailbox_tree_context *tree_ctx, + struct imap_match_glob *glob, + bool update_only, const char *name) { - while (node != NULL) { - if (node->children != NULL) { - node->flags |= MAILBOX_MATCHED | - MAILBOX_CHILD_SUBSCRIBED; - } - node = node->next; + struct mailbox_node *node; + enum mailbox_info_flags create_flags, always_flags; + enum imap_match_result match; + const char *p; + bool created; + + create_flags = (update_only || + (ctx->flags & MAILBOX_LIST_ITER_RETURN_NO_FLAGS) == 0) ? + (MAILBOX_NONEXISTENT | MAILBOX_NOCHILDREN) : 0; + always_flags = MAILBOX_SUBSCRIBED; + + t_push(); + for (;;) { + created = FALSE; + match = imap_match(glob, name); + if (match == IMAP_MATCH_YES) { + node = update_only ? + mailbox_tree_lookup(tree_ctx, name) : + mailbox_tree_get(tree_ctx, name, &created); + if (created) { + node->flags = create_flags; + if (create_flags != 0) + node_fix_parents(node); + } + if (node != NULL) { + if (!update_only) + node->flags |= MAILBOX_MATCHED; + node->flags |= always_flags; + } + } else if ((match & IMAP_MATCH_PARENT) == 0) + break; + + if ((ctx->flags & MAILBOX_LIST_ITER_SELECT_RECURSIVEMATCH) == 0) + break; + + /* see if parent matches */ + p = strrchr(name, ctx->list->hierarchy_sep); + if (p == NULL) + break; + + name = t_strdup_until(name, p); + create_flags &= ~MAILBOX_NOCHILDREN; + always_flags = MAILBOX_CHILDREN | MAILBOX_CHILD_SUBSCRIBED; } + t_pop(); } int mailbox_list_subscriptions_fill(struct mailbox_list_iterate_context *ctx, @@ -24,13 +77,7 @@ bool update_only) { struct subsfile_list_context *subsfile_ctx; - const char *path, *name, *p; - struct mailbox_node *node; - char hierarchy_sep; - bool created, add_flags; - - add_flags = update_only || - (ctx->flags & MAILBOX_LIST_ITER_RETURN_NO_FLAGS) == 0; + const char *path, *name; path = t_strconcat(ctx->list->set.control_dir != NULL ? ctx->list->set.control_dir : @@ -38,61 +85,10 @@ "/", ctx->list->set.subscription_fname, NULL); subsfile_ctx = subsfile_list_init(ctx->list, path); - hierarchy_sep = ctx->list->hierarchy_sep; while ((name = subsfile_list_next(subsfile_ctx)) != NULL) { - created = FALSE; - switch (imap_match(glob, name)) { - case IMAP_MATCH_YES: - node = update_only ? - mailbox_tree_lookup(tree_ctx, name) : - mailbox_tree_get(tree_ctx, name, &created); - if (created && add_flags) { - node->flags = MAILBOX_NONEXISTENT | - MAILBOX_NOCHILDREN; - } - if (node != NULL) { - if (!update_only) - node->flags |= MAILBOX_MATCHED; - node->flags |= MAILBOX_SUBSCRIBED; - } - break; - case IMAP_MATCH_PARENT: - /* child matched */ - if ((ctx->flags & - MAILBOX_LIST_ITER_SELECT_RECURSIVEMATCH) == 0) - break; - - while ((p = strrchr(name, hierarchy_sep)) != NULL) { - name = t_strdup_until(name, p); - if (imap_match(glob, name) == IMAP_MATCH_YES) - break; - } - i_assert(p != NULL); - - node = update_only ? - mailbox_tree_lookup(tree_ctx, name) : - mailbox_tree_get(tree_ctx, name, &created); - if (created && add_flags) - node->flags = MAILBOX_NONEXISTENT; - if (node != NULL) { - if (!update_only) - node->flags |= MAILBOX_MATCHED; - node->flags |= MAILBOX_CHILDREN | - MAILBOX_CHILD_SUBSCRIBED; - node->flags &= ~MAILBOX_NOCHILDREN; - } - break; - default: - break; - } + mailbox_list_subscription_add(ctx, tree_ctx, glob, update_only, + name); } - if ((ctx->flags & MAILBOX_LIST_ITER_SELECT_SUBSCRIBED) != 0 && - (ctx->flags & MAILBOX_LIST_ITER_SELECT_RECURSIVEMATCH) != 0) { - struct mailbox_node *nodes = - mailbox_tree_get(tree_ctx, NULL, NULL); - - nodes_add_child_subscribed(nodes); - } return subsfile_list_deinit(subsfile_ctx); }