]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
imapc: Fixed mailbox_exists() to actually work.
authorTimo Sirainen <tss@iki.fi>
Mon, 12 Sep 2011 10:14:26 +0000 (13:14 +0300)
committerTimo Sirainen <tss@iki.fi>
Mon, 12 Sep 2011 10:14:26 +0000 (13:14 +0300)
This fixes problems with subscribing to mailboxes.

src/lib-storage/index/imapc/imapc-list.c
src/lib-storage/index/imapc/imapc-list.h
src/lib-storage/index/imapc/imapc-storage.c

index ab71dbf648e0e34508ca4da8fc3a941c05519759..58633262132496bf298b9c25330c58ad6ddfa167 100644 (file)
@@ -31,6 +31,8 @@ static struct mailbox_list *imapc_list_alloc(void)
        list = p_new(pool, struct imapc_mailbox_list, 1);
        list->list = imapc_mailbox_list;
        list->list.pool = pool;
+       /* separator is set when storage is created */
+       list->mailboxes = mailbox_tree_init('\0');
        return &list->list;
 }
 
@@ -38,8 +40,7 @@ static void imapc_list_deinit(struct mailbox_list *_list)
 {
        struct imapc_mailbox_list *list = (struct imapc_mailbox_list *)_list;
 
-       if (list->mailboxes != NULL)
-               mailbox_tree_deinit(&list->mailboxes);
+       mailbox_tree_deinit(&list->mailboxes);
        if (list->tmp_subscriptions != NULL)
                mailbox_tree_deinit(&list->tmp_subscriptions);
        pool_unref(&list->list.pool);
@@ -118,8 +119,7 @@ static void imapc_untagged_list(const struct imapc_untagged_reply *reply,
 
                /* we can't handle NIL separator yet */
                list->sep = sep == NULL ? '/' : sep[0];
-               if (list->mailboxes != NULL)
-                       mailbox_tree_set_separator(list->mailboxes, list->sep);
+               mailbox_tree_set_separator(list->mailboxes, list->sep);
        } else {
                (void)imapc_list_update_tree(list, list->mailboxes, args);
        }
@@ -273,17 +273,15 @@ static int imapc_list_refresh(struct imapc_mailbox_list *list)
 {
        struct imapc_simple_context ctx;
 
+       i_assert(list->sep != '\0');
+
        if (list->refreshed_mailboxes)
                return 0;
 
-       if (list->sep == '\0')
-               (void)mailbox_list_get_hierarchy_sep(&list->list);
-
        imapc_simple_context_init(&ctx, list->storage);
        imapc_client_cmdf(list->storage->client,
                          imapc_list_simple_callback, &ctx, "LIST \"\" *");
-       if (list->mailboxes != NULL)
-               mailbox_tree_deinit(&list->mailboxes);
+       mailbox_tree_deinit(&list->mailboxes);
        list->mailboxes = mailbox_tree_init(list->sep);
 
        imapc_simple_run(&ctx);
@@ -557,6 +555,37 @@ imapc_list_rename_mailbox(struct mailbox_list *oldlist, const char *oldname,
        return ctx.ret;
 }
 
+int imapc_list_get_mailbox_flags(struct mailbox_list *_list, const char *name,
+                                enum mailbox_info_flags *flags_r)
+{
+       struct imapc_mailbox_list *list = (struct imapc_mailbox_list *)_list;
+       struct imapc_simple_context sctx;
+       struct mailbox_node *node;
+       const char *vname;
+
+       i_assert(list->sep != '\0');
+
+       vname = mailbox_list_default_get_vname(_list, name);
+       node = mailbox_tree_lookup(list->mailboxes, vname);
+       if (node != NULL)
+               node->flags |= MAILBOX_NONEXISTENT;
+
+       /* refresh the mailbox flags */
+       imapc_simple_context_init(&sctx, list->storage);
+       imapc_client_cmdf(list->storage->client, imapc_simple_callback,
+                         &sctx, "LIST \"\" %s", name);
+       imapc_simple_run(&sctx);
+       if (sctx.ret < 0)
+               return -1;
+
+       node = mailbox_tree_lookup(list->mailboxes, vname);
+       if (node == NULL)
+               *flags_r = MAILBOX_NONEXISTENT;
+       else
+               *flags_r = node->flags;
+       return 0;
+}
+
 struct mailbox_list imapc_mailbox_list = {
        .name = MAILBOX_LIST_NAME_IMAPC,
        .props = MAILBOX_LIST_PROP_NO_ROOT,
index 98f0792e21a23bbf72089798a39db1b69c781c83..a764f212050f5761d7f29c11972cb74bab1c44af 100644 (file)
@@ -22,6 +22,9 @@ struct imapc_mailbox_list {
        unsigned int index_list_failed:1;
 };
 
+int imapc_list_get_mailbox_flags(struct mailbox_list *list, const char *name,
+                                enum mailbox_info_flags *flags_r);
+
 void imapc_list_register_callbacks(struct imapc_mailbox_list *list);
 
 #endif
index adb04a3a4bfc929c98aacd4ca5abc273d0b02717..7b4d448fd6e4d13eea50ec679c82324bfac34752 100644 (file)
@@ -5,6 +5,7 @@
 #include "str.h"
 #include "imap-arg.h"
 #include "imap-resp-code.h"
+#include "mailbox-tree.h"
 #include "imapc-mail.h"
 #include "imapc-client-private.h"
 #include "imapc-connection.h"
@@ -341,6 +342,23 @@ imapc_mailbox_alloc(struct mail_storage *storage, struct mailbox_list *list,
        return &mbox->box;
 }
 
+static int
+imapc_mailbox_exists(struct mailbox *box, bool auto_boxes ATTR_UNUSED,
+                    enum mailbox_existence *existence_r)
+{
+       enum mailbox_info_flags flags;
+
+       if (imapc_list_get_mailbox_flags(box->list, box->name, &flags) < 0)
+               return -1;
+       if ((flags & MAILBOX_NONEXISTENT) != 0)
+               *existence_r = MAILBOX_EXISTENCE_NONE;
+       else if ((flags & MAILBOX_NOSELECT) != 0)
+               *existence_r = MAILBOX_EXISTENCE_NOSELECT;
+       else
+               *existence_r = MAILBOX_EXISTENCE_SELECT;
+       return 0;
+}
+
 static void
 imapc_mailbox_open_callback(const struct imapc_command_reply *reply,
                            void *context)
@@ -647,7 +665,7 @@ struct mailbox imapc_mailbox = {
        .v = {
                index_storage_is_readonly,
                index_storage_mailbox_enable,
-               index_storage_mailbox_exists,
+               imapc_mailbox_exists,
                imapc_mailbox_open,
                imapc_mailbox_close,
                index_storage_mailbox_free,