]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
imapc: Fixed mailbox deletion and some error handling. Code cleanups.
authorTimo Sirainen <tss@iki.fi>
Sun, 23 Jan 2011 21:32:52 +0000 (23:32 +0200)
committerTimo Sirainen <tss@iki.fi>
Sun, 23 Jan 2011 21:32:52 +0000 (23:32 +0200)
src/lib-storage/index/imapc/imapc-client.c
src/lib-storage/index/imapc/imapc-connection.c
src/lib-storage/index/imapc/imapc-connection.h
src/lib-storage/index/imapc/imapc-list.c
src/lib-storage/index/imapc/imapc-mailbox.c
src/lib-storage/index/imapc/imapc-storage.c
src/lib-storage/index/imapc/imapc-sync.c

index d645b6c95eff9a33405df1cbf5aff29f6d4e543d..0696a53314623fdc858b1430112c1421bfc02b61 100644 (file)
@@ -93,21 +93,13 @@ void imapc_client_stop(struct imapc_client *client)
                io_loop_stop(client->ioloop);
 }
 
-static void
-imapc_connection_state_changed(struct imapc_connection *conn,
-                              struct imapc_client *client,
-                              enum imapc_connection_state prev_state)
-{
-}
-
 static struct imapc_client_connection *
 imapc_client_add_connection(struct imapc_client *client)
 {
        struct imapc_client_connection *conn;
 
        conn = i_new(struct imapc_client_connection, 1);
-       conn->conn = imapc_connection_init(client,
-                                          imapc_connection_state_changed);
+       conn->conn = imapc_connection_init(client);
        array_append(&client->conns, &conn, 1);
        return conn;
 }
index 82cf7704b34001c46f1eab5877717d8e2b54620e..3fff92d201615733e3ec54b290c1bacc29ae3d8f 100644 (file)
@@ -55,8 +55,6 @@ struct imapc_connection {
        uint32_t cur_num;
 
        struct imapc_client_mailbox *selecting_box, *selected_box;
-
-       imapc_connection_state_change *state_callback;
        enum imapc_connection_state state;
 
        enum imapc_capability capabilities;
@@ -79,14 +77,12 @@ static void imapc_command_send_more(struct imapc_connection *conn,
                                    struct imapc_command *cmd);
 
 struct imapc_connection *
-imapc_connection_init(struct imapc_client *client,
-                     imapc_connection_state_change *state_callback)
+imapc_connection_init(struct imapc_client *client)
 {
        struct imapc_connection *conn;
 
        conn = i_new(struct imapc_connection, 1);
        conn->client = client;
-       conn->state_callback = state_callback;
        conn->fd = -1;
        conn->name = i_strdup_printf("%s:%u", client->set.host,
                                     client->set.port);
@@ -121,8 +117,6 @@ void imapc_connection_ioloop_changed(struct imapc_connection *conn)
 static void imapc_connection_set_state(struct imapc_connection *conn,
                                       enum imapc_connection_state state)
 {
-       enum imapc_connection_state prev_state = conn->state;
-
        if (state == IMAPC_CONNECTION_STATE_DISCONNECTED) {
                /* abort all pending commands */
                struct imapc_command_reply reply;
@@ -157,9 +151,7 @@ static void imapc_connection_set_state(struct imapc_connection *conn,
                        imapc_command_send_more(conn, *cmd_p);
                }
        }
-
        conn->state = state;
-       conn->state_callback(conn, conn->client, prev_state);
 }
 
 static void imapc_connection_disconnect(struct imapc_connection *conn)
index 6abc712d4e0776c45fc3e5721ffacb593936af9b..663727f39349f8a3bc1ed65e66059692181e3967 100644 (file)
@@ -17,15 +17,8 @@ enum imapc_connection_state {
        IMAPC_CONNECTION_STATE_DONE
 };
 
-/* Called when connection state changes */
-typedef void
-imapc_connection_state_change(struct imapc_connection *conn,
-                             struct imapc_client *client,
-                             enum imapc_connection_state prev_state);
-
 struct imapc_connection *
-imapc_connection_init(struct imapc_client *client,
-                     imapc_connection_state_change *state_callback);
+imapc_connection_init(struct imapc_client *client);
 void imapc_connection_deinit(struct imapc_connection **conn);
 
 void imapc_connection_connect(struct imapc_connection *conn);
index 9ca531a9d5bb90d2ec18d6e88a8775bf2c9d7495..ee8e9a6f1ed581a4b4cbd87d03b7398850c31ba2 100644 (file)
@@ -41,6 +41,20 @@ static void imapc_list_deinit(struct mailbox_list *_list)
        pool_unref(&list->list.pool);
 }
 
+static void imapc_list_simple_callback(const struct imapc_command_reply *reply,
+                                      void *context)
+{
+       struct imapc_simple_context *ctx = context;
+       const char *str;
+       enum mail_error error;
+
+       imapc_simple_callback(reply, context);
+       if (ctx->ret < 0) {
+               str = mail_storage_get_last_error(&ctx->storage->storage, &error);
+               mailbox_list_set_error(&ctx->storage->list->list, error, str);
+       }
+}
+
 static struct mailbox_node *
 imapc_list_update_tree(struct mailbox_tree_context *tree,
                       const struct imap_arg *args)
@@ -135,12 +149,14 @@ static int imapc_list_refresh(struct imapc_mailbox_list *list,
        ctx.storage = list->storage;
        if ((flags & MAILBOX_LIST_ITER_SELECT_SUBSCRIBED) == 0) {
                imapc_client_cmdf(list->storage->client,
-                                 imapc_simple_callback, &ctx, "LIST \"\" *");
+                                 imapc_list_simple_callback, &ctx,
+                                 "LIST \"\" *");
                if (list->mailboxes != NULL)
                        mailbox_tree_deinit(&list->mailboxes);
        } else {
                imapc_client_cmdf(list->storage->client,
-                                 imapc_simple_callback, &ctx, "LSUB \"\" *");
+                                 imapc_list_simple_callback, &ctx,
+                                 "LSUB \"\" *");
                if (list->subscriptions != NULL)
                        mailbox_tree_deinit(&list->subscriptions);
        }
@@ -150,19 +166,22 @@ static int imapc_list_refresh(struct imapc_mailbox_list *list,
 }
 
 static bool
-imapc_is_valid_pattern(struct mailbox_list *list, const char *pattern)
+imapc_is_valid_pattern(struct mailbox_list *list ATTR_UNUSED,
+                      const char *pattern ATTR_UNUSED)
 {
        return TRUE;
 }
 
 static bool
-imapc_is_valid_existing_name(struct mailbox_list *list, const char *name)
+imapc_is_valid_existing_name(struct mailbox_list *list ATTR_UNUSED,
+                            const char *name ATTR_UNUSED)
 {
        return TRUE;
 }
 
 static bool
-imapc_is_valid_create_name(struct mailbox_list *list, const char *name)
+imapc_is_valid_create_name(struct mailbox_list *list ATTR_UNUSED,
+                          const char *name ATTR_UNUSED)
 {
        return TRUE;
 }
@@ -175,7 +194,7 @@ static char imapc_list_get_hierarchy_sep(struct mailbox_list *_list)
        if (list->sep == '\0') {
                ctx.storage = list->storage;
                imapc_client_cmdf(list->storage->client,
-                                 imapc_simple_callback, &ctx,
+                                 imapc_list_simple_callback, &ctx,
                                  "LIST \"\" \"\"");
                imapc_client_run(list->storage->client);
                if (ctx.ret < 0) {
@@ -187,7 +206,8 @@ static char imapc_list_get_hierarchy_sep(struct mailbox_list *_list)
 }
 
 static const char *
-imapc_list_get_path(struct mailbox_list *list, const char *name,
+imapc_list_get_path(struct mailbox_list *list ATTR_UNUSED,
+                   const char *name ATTR_UNUSED,
                    enum mailbox_list_path_type type)
 {
        if (type == MAILBOX_LIST_PATH_TYPE_INDEX)
@@ -284,7 +304,7 @@ static int imapc_list_set_subscribed(struct mailbox_list *_list,
 
        ctx.storage = list->storage;
        imapc_client_cmdf(list->storage->client,
-                         imapc_simple_callback, &ctx,
+                         imapc_list_simple_callback, &ctx,
                          set ? "SUBSCRIBE %s" : "UNSUBSCRIBE %s", name);
        imapc_client_run(list->storage->client);
        return ctx.ret;
@@ -301,15 +321,23 @@ imapc_list_create_mailbox_dir(struct mailbox_list *list ATTR_UNUSED,
 }
 
 static int
-imapc_list_delete_mailbox(struct mailbox_list *list, const char *name)
+imapc_list_delete_mailbox(struct mailbox_list *_list, const char *name)
 {
-       return -1;
+       struct imapc_mailbox_list *list = (struct imapc_mailbox_list *)_list;
+       struct imapc_simple_context ctx;
+
+       ctx.storage = list->storage;
+       imapc_client_cmdf(list->storage->client,
+                         imapc_list_simple_callback, &ctx, "DELETE %s", name);
+       imapc_client_run(list->storage->client);
+       return ctx.ret;
 }
 
 static int
-imapc_list_delete_dir(struct mailbox_list *list, const char *name)
+imapc_list_delete_dir(struct mailbox_list *list ATTR_UNUSED,
+                     const char *name ATTR_UNUSED)
 {
-       return -1;
+       return 0;
 }
 
 static int
@@ -334,7 +362,7 @@ imapc_list_rename_mailbox(struct mailbox_list *oldlist, const char *oldname,
 
        ctx.storage = list->storage;
        imapc_client_cmdf(list->storage->client,
-                         imapc_simple_callback, &ctx,
+                         imapc_list_simple_callback, &ctx,
                          "RENAME %s %s", oldname, newname);
        imapc_client_run(list->storage->client);
        return ctx.ret;
index ce4fd75fbd7b06f48f1935208f98ad2d377cd59e..8874d480465504a65a3cf7cb38e0f09213c6f265 100644 (file)
 
 #define NOTIFY_DELAY_MSECS 500
 
+static void imapc_mailbox_init_delayed_trans(struct imapc_mailbox *mbox)
+{
+       if (mbox->delayed_sync_trans != NULL)
+               return;
+
+       mbox->delayed_sync_trans =
+               mail_index_transaction_begin(mbox->box.view,
+                                       MAIL_INDEX_TRANSACTION_FLAG_EXTERNAL);
+       mbox->delayed_sync_view =
+               mail_index_transaction_open_updated_view(mbox->delayed_sync_trans);
+}
+
 static void imapc_untagged_exists(const struct imapc_untagged_reply *reply,
                                  struct imapc_mailbox *mbox)
 {
@@ -98,6 +110,7 @@ static void imapc_untagged_fetch(const struct imapc_untagged_reply *reply,
                imapc_fetch_mail_update(mbox->cur_fetch_mail, list);
        }
 
+       imapc_mailbox_init_delayed_trans(mbox);
        old_count = mail_index_view_get_messages_count(mbox->delayed_sync_view);
        if (seq > old_count) {
                if (uid == 0)
@@ -124,9 +137,11 @@ static void imapc_untagged_expunge(const struct imapc_untagged_reply *reply,
 
        seqmap = imapc_client_mailbox_get_seqmap(mbox->client_box);
        lseq = imapc_seqmap_rseq_to_lseq(seqmap, rseq);
-       mail_index_expunge(mbox->delayed_sync_trans, lseq);
        imapc_seqmap_expunge(seqmap, rseq);
 
+       imapc_mailbox_init_delayed_trans(mbox);
+       mail_index_expunge(mbox->delayed_sync_trans, lseq);
+
        imapc_mailbox_idle_notify(mbox);
 }
 
@@ -140,6 +155,7 @@ imapc_resp_text_uidvalidity(const struct imapc_untagged_reply *reply,
            str_to_uint32(reply->resp_text_value, &uid_validity) < 0)
                return;
 
+       imapc_mailbox_init_delayed_trans(mbox);
        mail_index_update_header(mbox->delayed_sync_trans,
                offsetof(struct mail_index_header, uid_validity),
                &uid_validity, sizeof(uid_validity), TRUE);
@@ -155,12 +171,12 @@ imapc_resp_text_uidnext(const struct imapc_untagged_reply *reply,
            str_to_uint32(reply->resp_text_value, &uid_next) < 0)
                return;
 
+       imapc_mailbox_init_delayed_trans(mbox);
        mail_index_update_header(mbox->delayed_sync_trans,
                                 offsetof(struct mail_index_header, next_uid),
                                 &uid_next, sizeof(uid_next), FALSE);
 }
 
-
 void imapc_mailbox_register_untagged(struct imapc_mailbox *mbox,
                                     const char *key,
                                     imapc_mailbox_callback_t *callback)
index 57b39daf2ae56d7aeef8094ee0dac5f7a28a0eec..bdc4f04f0e53101e2430fb69267eaf0cffbaef61 100644 (file)
@@ -279,11 +279,10 @@ static int imapc_mailbox_open(struct mailbox *box)
        if (index_storage_mailbox_open(box, FALSE) < 0)
                return -1;
 
-       mbox->delayed_sync_trans =
-               mail_index_transaction_begin(box->view,
-                                       MAIL_INDEX_TRANSACTION_FLAG_EXTERNAL);
-       mbox->delayed_sync_view =
-               mail_index_transaction_open_updated_view(mbox->delayed_sync_trans);
+       if (box->deleting) {
+               /* We don't actually want to SELECT the mailbox. */
+               return 0;
+       }
 
        ctx.mbox = mbox;
        ctx.ret = -1;
@@ -303,10 +302,14 @@ static void imapc_mailbox_close(struct mailbox *box)
 {
        struct imapc_mailbox *mbox = (struct imapc_mailbox *)box;
 
-       imapc_client_mailbox_close(&mbox->client_box);
-       mail_index_view_close(&mbox->delayed_sync_view);
-       if (mail_index_transaction_commit(&mbox->delayed_sync_trans) < 0)
-               mail_storage_set_index_error(&mbox->box);
+       if (mbox->client_box != NULL)
+               imapc_client_mailbox_close(&mbox->client_box);
+       if (mbox->delayed_sync_view != NULL)
+               mail_index_view_close(&mbox->delayed_sync_view);
+       if (mbox->delayed_sync_trans != NULL) {
+               if (mail_index_transaction_commit(&mbox->delayed_sync_trans) < 0)
+                       mail_storage_set_index_error(&mbox->box);
+       }
        if (mbox->to_idle != NULL)
                timeout_remove(&mbox->to_idle);
        return index_storage_mailbox_close(box);
index 000d5725550ce85dc3ebfe8d4edbbf8f4ef30486..84a1d297685b404b2a3f723b4ee022bedecfb59c 100644 (file)
@@ -125,11 +125,14 @@ imapc_mailbox_sync_init(struct mailbox *box, enum mailbox_sync_flags flags)
                imapc_client_run(mbox->storage->client);
        }
 
-       mail_index_view_close(&mbox->delayed_sync_view);
-       if (mail_index_transaction_commit(&mbox->delayed_sync_trans) < 0) {
-               // FIXME: mark inconsistent
-               mail_storage_set_index_error(&mbox->box);
-               ret = -1;
+       if (mbox->delayed_sync_view != NULL)
+               mail_index_view_close(&mbox->delayed_sync_view);
+       if (mbox->delayed_sync_trans != NULL) {
+               if (mail_index_transaction_commit(&mbox->delayed_sync_trans) < 0) {
+                       // FIXME: mark inconsistent
+                       mail_storage_set_index_error(&mbox->box);
+                       ret = -1;
+               }
        }
 
        if (index_mailbox_want_full_sync(&mbox->box, flags) && ret == 0)
@@ -148,12 +151,8 @@ int imapc_mailbox_sync_deinit(struct mailbox_sync_context *ctx,
        int ret;
 
        ret = index_mailbox_sync_deinit(ctx, status_r);
-
-       mbox->delayed_sync_trans =
-               mail_index_transaction_begin(mbox->box.view,
-                                       MAIL_INDEX_TRANSACTION_FLAG_EXTERNAL);
-       mbox->delayed_sync_view =
-               mail_index_transaction_open_updated_view(mbox->delayed_sync_trans);
+       if (mbox->client_box == NULL)
+               return ret;
 
        if ((ictx->flags & MAILBOX_SYNC_FLAG_NO_EXPUNGES) == 0 && ret == 0) {
                seqmap = imapc_client_mailbox_get_seqmap(mbox->client_box);