Mercurial > dovecot > original-hg > dovecot-1.2
diff src/lib-storage/mailbox-list.c @ 6639:e1fde9940f7e HEAD
Fixes to handling namespace prefixes and real!=virtual separator. Added a
new MAILBOX_LIST_ITER_VIRTUAL_NAMES which specifies if mailbox listing
should be using virtual or real mailbox names.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sun, 28 Oct 2007 01:53:32 +0300 |
parents | 7b745fb85975 |
children | 4a3cc2968040 |
line wrap: on
line diff
--- a/src/lib-storage/mailbox-list.c Sun Oct 28 01:52:00 2007 +0300 +++ b/src/lib-storage/mailbox-list.c Sun Oct 28 01:53:32 2007 +0300 @@ -6,6 +6,8 @@ #include "home-expand.h" #include "mkdir-parents.h" #include "unlink-directory.h" +#include "imap-match.h" +#include "mailbox-tree.h" #include "mailbox-list-private.h" #include <time.h> @@ -441,6 +443,80 @@ return 0; } +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; + } +} + +void mailbox_list_iter_update(struct mailbox_list_iterate_context *ctx, + struct mailbox_tree_context *tree_ctx, + struct imap_match_glob *glob, bool update_only, + bool match_parents, const char *name) +{ + struct mail_namespace *ns = 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 = (update_only || + (ctx->flags & MAILBOX_LIST_ITER_RETURN_NO_FLAGS) == 0) ? + (MAILBOX_NONEXISTENT | MAILBOX_NOCHILDREN) : 0; + always_flags = MAILBOX_SUBSCRIBED; + add_matched = TRUE; + + 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 && 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 (!match_parents) + break; + + /* see if parent matches */ + p = strrchr(name, ns->sep); + if (p == NULL) + break; + + name = t_strdup_until(name, p); + create_flags &= ~MAILBOX_NOCHILDREN; + always_flags = MAILBOX_CHILDREN | MAILBOX_CHILD_SUBSCRIBED; + } + t_pop(); +} + bool mailbox_list_name_is_too_large(const char *name, char sep) { unsigned int levels = 1, level_len = 0;