Mercurial > dovecot > original-hg > dovecot-1.2
view src/lib-storage/list/mailbox-list-subscriptions.c @ 6043:d9abe04fc9ae HEAD
List non-subscribed mailboxes only if at least one child mailbox isn't
listed.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Tue, 17 Jul 2007 21:48:42 +0300 |
parents | 92fabfda82f9 |
children | 65c69a53a7be |
line wrap: on
line source
/* Copyright (C) 2002-2007 Timo Sirainen */ #include "lib.h" #include "imap-match.h" #include "mailbox-tree.h" #include "subscription-file.h" #include "mailbox-list-private.h" #include "mailbox-list-subscriptions.h" 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) { struct mailbox_node *node; enum mailbox_info_flags create_flags, always_flags; enum imap_match_result match; const char *p; bool created, add_matched; if ((ctx->list->ns->flags & NAMESPACE_FLAG_INBOX) == 0 || strcasecmp(name, "INBOX") != 0) { /* add namespace prefix to all but INBOX */ name = t_strconcat(ctx->list->ns->prefix, name, NULL); } 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 ((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, struct mailbox_tree_context *tree_ctx, struct imap_match_glob *glob, bool update_only) { struct subsfile_list_context *subsfile_ctx; const char *path, *name; path = t_strconcat(ctx->list->set.control_dir != NULL ? ctx->list->set.control_dir : ctx->list->set.root_dir, "/", ctx->list->set.subscription_fname, NULL); subsfile_ctx = subsfile_list_init(ctx->list, path); while ((name = subsfile_list_next(subsfile_ctx)) != NULL) { t_push(); mailbox_list_subscription_add(ctx, tree_ctx, glob, update_only, name); t_pop(); } return subsfile_list_deinit(subsfile_ctx); }