From: Timo Sirainen Date: Thu, 17 Jun 2010 19:28:06 +0000 (+0100) Subject: lib-storage: Fixed listing mailbox flags for subscriptions=no namespaces. X-Git-Tag: 2.0.rc1~144 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=8e9e586f812146478bdab1098bbc1969b11d7b61;p=thirdparty%2Fdovecot%2Fcore.git lib-storage: Fixed listing mailbox flags for subscriptions=no namespaces. --HG-- branch : HEAD --- diff --git a/src/lib-storage/list/mailbox-list-fs-iter.c b/src/lib-storage/list/mailbox-list-fs-iter.c index 7903472cfa..65a36d9948 100644 --- a/src/lib-storage/list/mailbox-list-fs-iter.c +++ b/src/lib-storage/list/mailbox-list-fs-iter.c @@ -622,6 +622,7 @@ fs_list_subs(struct fs_list_iterate_context *ctx) { 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 @@ fs_list_subs(struct fs_list_iterate_context *ctx) 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; diff --git a/src/lib-storage/list/mailbox-list-maildir-iter.c b/src/lib-storage/list/mailbox-list-maildir-iter.c index 0463a6af24..549f9b35d9 100644 --- a/src/lib-storage/list/mailbox-list-maildir-iter.c +++ b/src/lib-storage/list/mailbox-list-maildir-iter.c @@ -399,6 +399,56 @@ maildir_fill_readdir(struct maildir_list_iterate_context *ctx, } } +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 @@ maildir_list_iter_init(struct mailbox_list *_list, const char *const *patterns, } } + 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