]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
fs layout: Kludge to show INBOX/INBOX mailbox when necessary.
authorTimo Sirainen <tss@iki.fi>
Tue, 14 Aug 2012 00:03:26 +0000 (03:03 +0300)
committerTimo Sirainen <tss@iki.fi>
Tue, 14 Aug 2012 00:03:26 +0000 (03:03 +0300)
This happens with one prefix="" namespace and another prefix=INBOX/
namespace when the INBOX mailbox itself has children.

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

index c2949caa760e82a2d2ff1ab57b4a97cc63789479..7d9332b743bf0c4d19970087a2b59c5f59cc428b 100644 (file)
@@ -49,6 +49,7 @@ struct fs_list_iterate_context {
        struct list_dir_context *dir;
 
        unsigned int inbox_found:1;
+       unsigned int list_inbox_inbox:1;
 };
 
 static int
@@ -526,7 +527,8 @@ int fs_list_iter_deinit(struct mailbox_list_iterate_context *_ctx)
        return ret;
 }
 
-static void inbox_flags_set(struct fs_list_iterate_context *ctx)
+static void inbox_flags_set(struct fs_list_iterate_context *ctx,
+                           enum imap_match_result child_dir_match)
 {
        struct mail_namespace *ns = ctx->ctx.list->ns;
 
@@ -541,8 +543,19 @@ static void inbox_flags_set(struct fs_list_iterate_context *ctx)
                   with INBOX = /var/inbox/%u/Maildir, root = ~/Maildir:
                   ~/Maildir/INBOX/foo/ shows up as <prefix>/INBOX/foo and
                   INBOX can't directly have any children. */
-               ctx->info.flags &= ~MAILBOX_CHILDREN;
-               ctx->info.flags |= MAILBOX_NOINFERIORS;
+               if (ns->prefix_len == 6 &&
+                   strncasecmp(ns->prefix, "INBOX", ns->prefix_len-1) == 0 &&
+                   (ctx->info.flags & MAILBOX_CHILDREN) != 0 &&
+                   (child_dir_match & IMAP_MATCH_CHILDREN) != 0) {
+                       /* except, INBOX/ prefix is once again a special case.
+                          we're now listing both the namespace prefix and the
+                          INBOX. we're now doing a LIST INBOX/%, so we'll need
+                          to create a fake \NoSelect INBOX/INBOX */
+                       ctx->list_inbox_inbox = TRUE;
+               } else {
+                       ctx->info.flags &= ~MAILBOX_CHILDREN;
+                       ctx->info.flags |= MAILBOX_NOINFERIORS;
+               }
        }
 }
 
@@ -570,7 +583,7 @@ list_file_unfound_inbox(struct fs_list_iterate_context *ctx)
            (ctx->info.flags & MAILBOX_NONEXISTENT) != 0)
                return FALSE;
 
-       inbox_flags_set(ctx);
+       inbox_flags_set(ctx, 0);
        /* we got here because we didn't see INBOX among other mailboxes,
           which means it has no children. */
        ctx->info.flags |= MAILBOX_NOCHILDREN;
@@ -645,7 +658,7 @@ fs_list_entry(struct fs_list_iterate_context *ctx,
                        }
                        return 0;
                }
-               inbox_flags_set(ctx);
+               inbox_flags_set(ctx, child_dir_match);
                ctx->inbox_found = TRUE;
        } else if (strcmp(storage_name, "INBOX") == 0 &&
                   (ns->flags & NAMESPACE_FLAG_INBOX_USER) != 0) {
@@ -704,6 +717,15 @@ fs_list_next(struct fs_list_iterate_context *ctx)
                        fs_list_next_root(ctx);
        }
 
+       if (ctx->list_inbox_inbox) {
+               ctx->info.flags = MAILBOX_CHILDREN | MAILBOX_NOSELECT;
+               ctx->info.name =
+                       p_strconcat(ctx->info_pool,
+                                   ctx->ctx.list->ns->prefix, "INBOX", NULL);
+               ctx->list_inbox_inbox = FALSE;
+               if (imap_match(ctx->ctx.glob, ctx->info.name) == IMAP_MATCH_YES)
+                       return 1;
+       }
        if (!ctx->inbox_found && ctx->ctx.glob != NULL &&
            (ctx->ctx.list->ns->flags & NAMESPACE_FLAG_INBOX_ANY) != 0 &&
            imap_match(ctx->ctx.glob,