From f0188e998009d87511418d8bb1c4dc779e2ea7fa Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Thu, 25 Sep 2025 11:36:46 +0300 Subject: [PATCH] lib-storage: Fix subscription listing showing parent namespace prefix If e.g. shared/user/box was subscribed, LSUB "" % didn't list shared namespace prefix. --- src/lib-storage/list/mailbox-list-iter.c | 31 ++++++++++++++++++++++++ src/lib-storage/mailbox-tree.c | 5 ++++ src/lib-storage/mailbox-tree.h | 1 + 3 files changed, 37 insertions(+) diff --git a/src/lib-storage/list/mailbox-list-iter.c b/src/lib-storage/list/mailbox-list-iter.c index a65c1be54a..5385902d93 100644 --- a/src/lib-storage/list/mailbox-list-iter.c +++ b/src/lib-storage/list/mailbox-list-iter.c @@ -486,6 +486,29 @@ mailbox_ns_prefix_check_selection_criteria(struct ns_list_iterate_context *ctx) return TRUE; } +static int ns_has_child_subscriptions(struct ns_list_iterate_context *ctx, + struct mail_namespace *parent_ns) +{ + struct mail_namespace *ns; + + for (ns = ctx->namespaces; ns != NULL; ns = ns->next) { + if (ns->prefix_len > parent_ns->prefix_len && + strncmp(ns->prefix, parent_ns->prefix, + parent_ns->prefix_len) == 0) { + if (mailbox_list_iter_subscriptions_refresh(ns->list) < 0) + return -1; + + if (mailbox_tree_get_root(ns->list->subscriptions) != NULL) + return 1; + + int ret = ns_has_child_subscriptions(ctx, ns); + if (ret != 0) + return ret; + } + } + return 0; +} + static bool mailbox_list_ns_prefix_return(struct ns_list_iterate_context *ctx, struct mail_namespace *ns, bool has_children) @@ -570,6 +593,14 @@ mailbox_list_ns_prefix_return(struct ns_list_iterate_context *ctx, have a child is if one of them is subscribed */ subs_flags = MAILBOX_CHILD_SUBSCRIBED; } + if (subs_flags == 0) { + if ((ret = ns_has_child_subscriptions(ctx, ns)) < 0) { + mailbox_list_ns_iter_failed(ctx); + return FALSE; + } + if (ret > 0) + subs_flags = MAILBOX_CHILD_SUBSCRIBED; + } if (subs_flags != 0 && mailbox_list_want_subscription(ns, ctx->ns_info.flags | subs_flags)) diff --git a/src/lib-storage/mailbox-tree.c b/src/lib-storage/mailbox-tree.c index 94945aeae3..c2ea74ca3e 100644 --- a/src/lib-storage/mailbox-tree.c +++ b/src/lib-storage/mailbox-tree.c @@ -80,6 +80,11 @@ pool_t mailbox_tree_get_pool(struct mailbox_tree_context *tree) return tree->pool; } +struct mailbox_node *mailbox_tree_get_root(struct mailbox_tree_context *tree) +{ + return tree->nodes; +} + static struct mailbox_node * ATTR_NULL(2) mailbox_tree_traverse(struct mailbox_tree_context *tree, const char *path, bool create, bool *created_r) diff --git a/src/lib-storage/mailbox-tree.h b/src/lib-storage/mailbox-tree.h index aeb45c4849..b8b014a8f6 100644 --- a/src/lib-storage/mailbox-tree.h +++ b/src/lib-storage/mailbox-tree.h @@ -23,6 +23,7 @@ void mailbox_tree_set_separator(struct mailbox_tree_context *tree, void mailbox_tree_set_parents_nonexistent(struct mailbox_tree_context *tree); void mailbox_tree_clear(struct mailbox_tree_context *tree); pool_t mailbox_tree_get_pool(struct mailbox_tree_context *tree); +struct mailbox_node *mailbox_tree_get_root(struct mailbox_tree_context *tree); struct mailbox_node * mailbox_tree_get(struct mailbox_tree_context *tree, const char *path, -- 2.47.3