From: Timo Sirainen Date: Thu, 19 Sep 2013 19:20:56 +0000 (+0300) Subject: imapc: Abort pending commands before any deinitialization to avoid crashes. X-Git-Tag: 2.2.6~55 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9a7f22e2c14b507e6044e5534df978a0c3b638d0;p=thirdparty%2Fdovecot%2Fcore.git imapc: Abort pending commands before any deinitialization to avoid crashes. --- diff --git a/src/lib-imap-client/imapc-client.c b/src/lib-imap-client/imapc-client.c index b2829908cf..6469303f82 100644 --- a/src/lib-imap-client/imapc-client.c +++ b/src/lib-imap-client/imapc-client.c @@ -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); } diff --git a/src/lib-imap-client/imapc-client.h b/src/lib-imap-client/imapc-client.h index e099c93a61..456c76059d 100644 --- a/src/lib-imap-client/imapc-client.h +++ b/src/lib-imap-client/imapc-client.h @@ -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). */ diff --git a/src/lib-storage/index/imapc/imapc-list.c b/src/lib-storage/index/imapc/imapc-list.c index be755f3329..983fd20ce4 100644 --- a/src/lib-storage/index/imapc/imapc-list.c +++ b/src/lib-storage/index/imapc/imapc-list.c @@ -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); } diff --git a/src/lib-storage/index/imapc/imapc-storage.c b/src/lib-storage/index/imapc/imapc-storage.c index 08611f1b3f..2e9d7d8458 100644 --- a/src/lib-storage/index/imapc/imapc-storage.c +++ b/src/lib-storage/index/imapc/imapc-storage.c @@ -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); }