From: Timo Sirainen Date: Sun, 23 Jan 2011 21:32:52 +0000 (+0200) Subject: imapc: Fixed mailbox deletion and some error handling. Code cleanups. X-Git-Tag: 2.1.alpha1~410 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=51130f00bbd1e119ec042d63c148a78ac06ab85e;p=thirdparty%2Fdovecot%2Fcore.git imapc: Fixed mailbox deletion and some error handling. Code cleanups. --- diff --git a/src/lib-storage/index/imapc/imapc-client.c b/src/lib-storage/index/imapc/imapc-client.c index d645b6c95e..0696a53314 100644 --- a/src/lib-storage/index/imapc/imapc-client.c +++ b/src/lib-storage/index/imapc/imapc-client.c @@ -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; } diff --git a/src/lib-storage/index/imapc/imapc-connection.c b/src/lib-storage/index/imapc/imapc-connection.c index 82cf7704b3..3fff92d201 100644 --- a/src/lib-storage/index/imapc/imapc-connection.c +++ b/src/lib-storage/index/imapc/imapc-connection.c @@ -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) diff --git a/src/lib-storage/index/imapc/imapc-connection.h b/src/lib-storage/index/imapc/imapc-connection.h index 6abc712d4e..663727f393 100644 --- a/src/lib-storage/index/imapc/imapc-connection.h +++ b/src/lib-storage/index/imapc/imapc-connection.h @@ -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); diff --git a/src/lib-storage/index/imapc/imapc-list.c b/src/lib-storage/index/imapc/imapc-list.c index 9ca531a9d5..ee8e9a6f1e 100644 --- a/src/lib-storage/index/imapc/imapc-list.c +++ b/src/lib-storage/index/imapc/imapc-list.c @@ -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; diff --git a/src/lib-storage/index/imapc/imapc-mailbox.c b/src/lib-storage/index/imapc/imapc-mailbox.c index ce4fd75fbd..8874d48046 100644 --- a/src/lib-storage/index/imapc/imapc-mailbox.c +++ b/src/lib-storage/index/imapc/imapc-mailbox.c @@ -10,6 +10,18 @@ #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) diff --git a/src/lib-storage/index/imapc/imapc-storage.c b/src/lib-storage/index/imapc/imapc-storage.c index 57b39daf2a..bdc4f04f0e 100644 --- a/src/lib-storage/index/imapc/imapc-storage.c +++ b/src/lib-storage/index/imapc/imapc-storage.c @@ -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); diff --git a/src/lib-storage/index/imapc/imapc-sync.c b/src/lib-storage/index/imapc/imapc-sync.c index 000d572555..84a1d29768 100644 --- a/src/lib-storage/index/imapc/imapc-sync.c +++ b/src/lib-storage/index/imapc/imapc-sync.c @@ -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);