]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
LIST: Fixes to handling subscriptions
authorTimo Sirainen <tss@iki.fi>
Tue, 4 Sep 2012 13:06:29 +0000 (16:06 +0300)
committerTimo Sirainen <tss@iki.fi>
Tue, 4 Sep 2012 13:06:29 +0000 (16:06 +0300)
src/imap/cmd-list.c
src/lib-storage/list/mailbox-list-iter.c

index e3ab6e6e5f7e14d2d9335d716065e038945735bb..4bcfd39379527385b37502ed0d01efc50bbec86d 100644 (file)
@@ -41,14 +41,12 @@ mailbox_flags2str(struct cmd_list_context *ctx, string_t *str,
        if ((ctx->list_flags & MAILBOX_LIST_ITER_RETURN_CHILDREN) == 0)
                flags &= ~(MAILBOX_CHILDREN|MAILBOX_NOCHILDREN);
 
-       if ((ctx->list_flags & MAILBOX_LIST_ITER_RETURN_SUBSCRIBED) == 0)
-               flags &= ~MAILBOX_SUBSCRIBED;
-
        if ((flags & MAILBOX_CHILD_SUBSCRIBED) != 0 &&
            (flags & MAILBOX_SUBSCRIBED) == 0 && !ctx->used_listext) {
                /* LSUB uses \Noselect for this */
                flags |= MAILBOX_NOSELECT;
-       }
+       } else if ((ctx->list_flags & MAILBOX_LIST_ITER_RETURN_SUBSCRIBED) == 0)
+               flags &= ~MAILBOX_SUBSCRIBED;
        imap_mailbox_flags2str(str, flags);
 
        if ((ctx->list_flags & MAILBOX_LIST_ITER_RETURN_SPECIALUSE) != 0 &&
@@ -69,6 +67,9 @@ mailbox_childinfo2str(struct cmd_list_context *ctx, string_t *str,
        if ((flags & MAILBOX_CHILD_SUBSCRIBED) != 0 &&
            (ctx->list_flags & MAILBOX_LIST_ITER_SELECT_RECURSIVEMATCH) != 0)
                str_append(str, " (CHILDINFO (\"SUBSCRIBED\"))");
+       if ((flags & MAILBOX_CHILD_SPECIALUSE) != 0 &&
+           (ctx->list_flags & MAILBOX_LIST_ITER_SELECT_RECURSIVEMATCH) != 0)
+               str_append(str, " (CHILDINFO (\"SPECIAL-USE\"))");
 }
 
 static bool
index 170c719941b43bde90f3bbc00c363eca980d9afd..b953a0aa8eb02cade63599de9d9f4cee9d43b2d8 100644 (file)
@@ -5,6 +5,7 @@
 #include "imap-match.h"
 #include "mail-storage.h"
 #include "mailbox-tree.h"
+#include "mailbox-list-subscriptions.h"
 #include "mailbox-list-private.h"
 
 enum autocreate_match_result {
@@ -67,7 +68,7 @@ mailbox_list_iter_init(struct mailbox_list *list, const char *pattern,
        return mailbox_list_iter_init_multiple(list, patterns, flags);
 }
 
-static int mailbox_list_subscriptions_refresh(struct mailbox_list *list)
+static int mailbox_list_iter_subscriptions_refresh(struct mailbox_list *list)
 {
        struct mail_namespace *ns = list->ns;
 
@@ -162,7 +163,7 @@ mailbox_list_iter_init_multiple(struct mailbox_list *list,
 
        if ((flags & (MAILBOX_LIST_ITER_SELECT_SUBSCRIBED |
                      MAILBOX_LIST_ITER_RETURN_SUBSCRIBED)) != 0)
-               ret = mailbox_list_subscriptions_refresh(list);
+               ret = mailbox_list_iter_subscriptions_refresh(list);
 
        ctx = list->v.iter_init(list, patterns, flags);
        if (ret < 0)
@@ -406,10 +407,25 @@ mailbox_list_match_anything(struct ns_list_iterate_context *ctx,
        return ret;
 }
 
+static bool
+mailbox_ns_prefix_check_selection_criteria(struct ns_list_iterate_context *ctx)
+{
+       if ((ctx->ctx.flags & MAILBOX_LIST_ITER_SELECT_SUBSCRIBED) != 0) {
+               if ((ctx->ns_info.flags & MAILBOX_SUBSCRIBED) != 0)
+                       return TRUE;
+               if ((ctx->ctx.flags & MAILBOX_LIST_ITER_SELECT_RECURSIVEMATCH) != 0 &&
+                   (ctx->ns_info.flags & MAILBOX_CHILD_SUBSCRIBED) != 0)
+                       return TRUE;
+               return FALSE;
+       }
+       return TRUE;
+}
+
 static bool
 mailbox_list_ns_prefix_return(struct ns_list_iterate_context *ctx,
                              struct mail_namespace *ns, bool has_children)
 {
+       struct mail_namespace *subs_ns;
        struct mailbox *box;
        enum mailbox_existence existence;
        int ret;
@@ -435,6 +451,19 @@ mailbox_list_ns_prefix_return(struct ns_list_iterate_context *ctx,
                ctx->ns_info.flags |= ctx->inbox_info.flags | MAILBOX_SELECT;
        }
 
+       if ((ctx->ctx.flags & (MAILBOX_LIST_ITER_RETURN_SUBSCRIBED |
+                              MAILBOX_LIST_ITER_SELECT_SUBSCRIBED)) != 0) {
+               subs_ns = mail_namespace_find_subscribable(ctx->namespaces,
+                                                          ns->prefix);
+               if (subs_ns != NULL) {
+                       mailbox_list_set_subscription_flags(subs_ns->list,
+                                                           ctx->ns_info.vname,
+                                                           &ctx->ns_info.flags);
+               }
+       }
+       if (!mailbox_ns_prefix_check_selection_criteria(ctx))
+               return FALSE;
+
        /* see if the namespace has children */
        if (has_children)
                ctx->ns_info.flags |= MAILBOX_CHILDREN;
@@ -878,7 +907,8 @@ static bool autocreate_iter_autobox(struct mailbox_list_iterate_context *ctx,
                        p = strrchr(actx->new_info.vname, sep);
                        i_assert(p != NULL);
                        actx->new_info.vname =
-                               t_strdup_until(actx->new_info.vname, p);
+                               p_strdup_until(ctx->pool,
+                                              actx->new_info.vname, p);
                        match = imap_match(ctx->glob, actx->new_info.vname);
                } while (match != IMAP_MATCH_YES);
                return TRUE;