]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
imapc: Abort pending commands before any deinitialization to avoid crashes.
authorTimo Sirainen <tss@iki.fi>
Thu, 19 Sep 2013 19:20:56 +0000 (22:20 +0300)
committerTimo Sirainen <tss@iki.fi>
Thu, 19 Sep 2013 19:20:56 +0000 (22:20 +0300)
src/lib-imap-client/imapc-client.c
src/lib-imap-client/imapc-client.h
src/lib-storage/index/imapc/imapc-list.c
src/lib-storage/index/imapc/imapc-storage.c

index b2829908cf6a091761109acd5bf9c1271b5fe2a9..6469303f82ea953503fbdeb725677220442259ab 100644 (file)
@@ -110,17 +110,27 @@ void imapc_client_unref(struct imapc_client **_client)
        pool_unref(&client->pool);
 }
 
+void imapc_client_disconnect(struct imapc_client *client)
+{
+       struct imapc_client_connection *const *conns, *conn;
+       unsigned int i, count;
+
+       conns = array_get(&client->conns, &count);
+       for (i = count; i > 0; i--) {
+               conn = conns[i-1];
+               array_delete(&client->conns, i-1, 1);
+
+               i_assert(imapc_connection_get_mailbox(conn->conn) == NULL);
+               imapc_connection_deinit(&conn->conn);
+               i_free(conn);
+       }
+}
+
 void imapc_client_deinit(struct imapc_client **_client)
 {
        struct imapc_client *client = *_client;
-       struct imapc_client_connection **connp;
 
-       array_foreach_modifiable(&client->conns, connp) {
-               i_assert(imapc_connection_get_mailbox((*connp)->conn) == NULL);
-               imapc_connection_deinit(&(*connp)->conn);
-               i_free(*connp);
-       }
-       array_clear(&client->conns);
+       imapc_client_disconnect(client);
        imapc_client_unref(_client);
 }
 
index e099c93a61370d1c5b016ceb2fd2d15bad060795..456c76059dd6c2c5aa464e571ce8877df8077cd1 100644 (file)
@@ -134,6 +134,7 @@ typedef void imapc_untagged_callback_t(const struct imapc_untagged_reply *reply,
 
 struct imapc_client *
 imapc_client_init(const struct imapc_client_settings *set);
+void imapc_client_disconnect(struct imapc_client *client);
 void imapc_client_deinit(struct imapc_client **client);
 
 /* Explicitly login to server (also done automatically). */
index be755f3329b3b097256f7304798e5202d769bb0b..983fd20ce43ca2e34b6de7fc2c458bdb0f11a39e 100644 (file)
@@ -98,12 +98,16 @@ static void imapc_list_deinit(struct mailbox_list *_list)
 {
        struct imapc_mailbox_list *list = (struct imapc_mailbox_list *)_list;
 
+       /* make sure all pending commands are aborted before anything is
+          deinitialized */
+       imapc_client_disconnect(list->client->client);
+
+       imapc_storage_client_unref(&list->client);
        if (list->index_list != NULL)
                mailbox_list_destroy(&list->index_list);
        mailbox_tree_deinit(&list->mailboxes);
        if (list->tmp_subscriptions != NULL)
                mailbox_tree_deinit(&list->tmp_subscriptions);
-       imapc_storage_client_unref(&list->client);
        pool_unref(&list->list.pool);
 }
 
index 08611f1b3fad49f25d7103be5954e6fab981e10d..2e9d7d8458fd6d0393788f08ccfd7341578aaa3f 100644 (file)
@@ -295,6 +295,10 @@ static void imapc_storage_destroy(struct mail_storage *_storage)
 {
        struct imapc_storage *storage = (struct imapc_storage *)_storage;
 
+       /* make sure all pending commands are aborted before anything is
+          deinitialized */
+       imapc_client_disconnect(storage->client->client);
+
        imapc_storage_client_unref(&storage->client);
        index_storage_destroy(_storage);
 }