]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-storage: Fixed listing mailbox flags for subscriptions=no namespaces.
authorTimo Sirainen <tss@iki.fi>
Thu, 17 Jun 2010 19:28:06 +0000 (20:28 +0100)
committerTimo Sirainen <tss@iki.fi>
Thu, 17 Jun 2010 19:28:06 +0000 (20:28 +0100)
--HG--
branch : HEAD

src/lib-storage/list/mailbox-list-fs-iter.c
src/lib-storage/list/mailbox-list-maildir-iter.c

index 7903472cfadd1cdc22156314af20653e3177bdbd..65a36d99487013445573306f22d8921e39348788 100644 (file)
@@ -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;
index 0463a6af24b94321a2b12b354d0126130a80c575..549f9b35d9991fa57e7a6f4a8633244787111d78 100644 (file)
@@ -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