Mercurial > dovecot > core-2.2
changeset 11574:7330bb240c75 HEAD
lib-storage: Fixed listing mailbox flags for subscriptions=no namespaces.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Thu, 17 Jun 2010 20:28:06 +0100 |
parents | 3128f592ef5c |
children | 6d0b4dfc0829 |
files | src/lib-storage/list/mailbox-list-fs-iter.c src/lib-storage/list/mailbox-list-maildir-iter.c |
diffstat | 2 files changed, 78 insertions(+), 8 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-storage/list/mailbox-list-fs-iter.c Thu Jun 17 19:50:44 2010 +0100 +++ b/src/lib-storage/list/mailbox-list-fs-iter.c Thu Jun 17 20:28:06 2010 +0100 @@ -622,6 +622,7 @@ { struct mailbox_node *node; enum mailbox_info_flags flags; + struct mail_namespace *ns; const char *path, *dir, *fname, *storage_name; unsigned int len; struct stat st; @@ -639,21 +640,29 @@ return &ctx->info; } - storage_name = (ctx->ctx.flags & MAILBOX_LIST_ITER_VIRTUAL_NAMES) == 0 ? - ctx->info.name : - mail_namespace_get_storage_name(ctx->info.ns, ctx->info.name); + /* see if this is for another subscriptions=no namespace */ + storage_name = ctx->info.name; + ns = mail_namespace_find_unsubscribable(ctx->info.ns->user->namespaces, + &storage_name); + if (ns == NULL) { + ns = ctx->info.ns; + if ((ctx->ctx.flags & MAILBOX_LIST_ITER_VIRTUAL_NAMES) != 0) + storage_name = mail_namespace_get_storage_name(ns, storage_name); + else + storage_name = ctx->info.name; + } /* if name ends with hierarchy separator, drop the separator */ len = strlen(storage_name); - if (len > 0 && storage_name[len-1] == ctx->info.ns->real_sep) + if (len > 0 && storage_name[len-1] == ns->real_sep) storage_name = t_strndup(storage_name, len-1); - path = mailbox_list_get_path(ctx->ctx.list, storage_name, + path = mailbox_list_get_path(ns->list, storage_name, MAILBOX_LIST_PATH_TYPE_DIR); path_split(path, &dir, &fname); - if (ctx->ctx.list->v.get_mailbox_flags(ctx->ctx.list, dir, fname, - MAILBOX_LIST_FILE_TYPE_UNKNOWN, - &st, &ctx->info.flags) < 0) + if (ns->list->v.get_mailbox_flags(ns->list, dir, fname, + MAILBOX_LIST_FILE_TYPE_UNKNOWN, + &st, &ctx->info.flags) < 0) ctx->ctx.failed = TRUE; ctx->info.flags |= flags;
--- a/src/lib-storage/list/mailbox-list-maildir-iter.c Thu Jun 17 19:50:44 2010 +0100 +++ b/src/lib-storage/list/mailbox-list-maildir-iter.c Thu Jun 17 20:28:06 2010 +0100 @@ -399,6 +399,56 @@ } } +static int +maildir_fill_other_ns_subscriptions(struct maildir_list_iterate_context *ctx, + struct mail_namespace *ns) +{ + struct mailbox_list_iterate_context *iter; + const struct mailbox_info *info; + struct mailbox_node *node; + + iter = mailbox_list_iter_init(ns->list, "*", + MAILBOX_LIST_ITER_VIRTUAL_NAMES | + MAILBOX_LIST_ITER_RETURN_CHILDREN); + while ((info = mailbox_list_iter_next(iter)) != NULL) { + node = mailbox_tree_lookup(ctx->tree_ctx, info->name); + if (node != NULL) { + node->flags &= ~MAILBOX_NONEXISTENT; + node->flags |= info->flags; + } + } + if (mailbox_list_iter_deinit(&iter) < 0) { + enum mail_error error; + const char *errstr; + + errstr = mailbox_list_get_last_error(ns->list, &error); + mailbox_list_set_error(ctx->ctx.list, error, errstr); + return -1; + } + return 0; +} + +static int +maildir_fill_other_subscriptions(struct maildir_list_iterate_context *ctx) +{ + struct mail_namespace *ns; + const char *path; + + ns = ctx->ctx.list->ns->user->namespaces; + for (; ns != NULL; ns = ns->next) { + if ((ns->flags & NAMESPACE_FLAG_SUBSCRIPTIONS) != 0 || + ns->prefix_len == 0) + continue; + + path = t_strndup(ns->prefix, ns->prefix_len-1); + if (mailbox_tree_lookup(ctx->tree_ctx, path) != NULL) { + if (maildir_fill_other_ns_subscriptions(ctx, ns) < 0) + return -1; + } + } + return 0; +} + struct mailbox_list_iterate_context * maildir_list_iter_init(struct mailbox_list *_list, const char *const *patterns, enum mailbox_list_iter_flags flags) @@ -451,6 +501,17 @@ } } + if ((flags & MAILBOX_LIST_ITER_SELECT_SUBSCRIBED) != 0 && + (flags & MAILBOX_LIST_ITER_RETURN_NO_FLAGS) == 0) { + /* if there are subscriptions=no namespaces, we may have some + of their subscriptions whose flags need to be filled */ + ret = maildir_fill_other_subscriptions(ctx); + if (ret < 0) { + ctx->ctx.failed = TRUE; + return &ctx->ctx; + } + } + if ((flags & MAILBOX_LIST_ITER_RETURN_SUBSCRIBED) != 0 && (flags & MAILBOX_LIST_ITER_SELECT_SUBSCRIBED) == 0) { /* we're listing all mailboxes but we want to know