]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-storage: Fix subscription listing showing parent namespace prefix
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Thu, 25 Sep 2025 08:36:46 +0000 (11:36 +0300)
committeraki.tuomi <aki.tuomi@open-xchange.com>
Tue, 30 Sep 2025 05:48:46 +0000 (05:48 +0000)
If e.g. shared/user/box was subscribed, LSUB "" % didn't list shared
namespace prefix.

src/lib-storage/list/mailbox-list-iter.c
src/lib-storage/mailbox-tree.c
src/lib-storage/mailbox-tree.h

index a65c1be54aa57cda56c6f1894ebd20f91701b048..5385902d93487a33abe54f56d2c5362c119f2f2c 100644 (file)
@@ -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))
index 94945aeae33c561cc13abfe526fcb86342336cc9..c2ea74ca3eae97480033eecfc9c0c45085147a23 100644 (file)
@@ -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)
index aeb45c4849481967b10609893e5fdc32ed0a0b30..b8b014a8f63787353dc4b477c6c2c2915b4bac23 100644 (file)
@@ -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,