changeset 12595:5d97dfa9d86c

imapc: Fixed mailbox deletion and some error handling. Code cleanups.
author Timo Sirainen <tss@iki.fi>
date Sun, 23 Jan 2011 23:32:52 +0200
parents f7e4d46e980f
children d75d4841c890
files 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
diffstat 7 files changed, 84 insertions(+), 61 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-storage/index/imapc/imapc-client.c	Sun Jan 23 23:32:34 2011 +0200
+++ b/src/lib-storage/index/imapc/imapc-client.c	Sun Jan 23 23:32:52 2011 +0200
@@ -93,21 +93,13 @@
 		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;
 }
--- a/src/lib-storage/index/imapc/imapc-connection.c	Sun Jan 23 23:32:34 2011 +0200
+++ b/src/lib-storage/index/imapc/imapc-connection.c	Sun Jan 23 23:32:52 2011 +0200
@@ -55,8 +55,6 @@
 	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 @@
 				    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 @@
 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 @@
 			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)
--- a/src/lib-storage/index/imapc/imapc-connection.h	Sun Jan 23 23:32:34 2011 +0200
+++ b/src/lib-storage/index/imapc/imapc-connection.h	Sun Jan 23 23:32:52 2011 +0200
@@ -17,15 +17,8 @@
 	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);
--- a/src/lib-storage/index/imapc/imapc-list.c	Sun Jan 23 23:32:34 2011 +0200
+++ b/src/lib-storage/index/imapc/imapc-list.c	Sun Jan 23 23:32:52 2011 +0200
@@ -41,6 +41,20 @@
 	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 @@
 	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 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 @@
 	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 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 @@
 
 	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 @@
 }
 
 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 @@
 
 	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;
--- a/src/lib-storage/index/imapc/imapc-mailbox.c	Sun Jan 23 23:32:34 2011 +0200
+++ b/src/lib-storage/index/imapc/imapc-mailbox.c	Sun Jan 23 23:32:52 2011 +0200
@@ -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 @@
 		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,8 +137,10 @@
 
 	seqmap = imapc_client_mailbox_get_seqmap(mbox->client_box);
 	lseq = imapc_seqmap_rseq_to_lseq(seqmap, rseq);
+	imapc_seqmap_expunge(seqmap, rseq);
+
+	imapc_mailbox_init_delayed_trans(mbox);
 	mail_index_expunge(mbox->delayed_sync_trans, lseq);
-	imapc_seqmap_expunge(seqmap, rseq);
 
 	imapc_mailbox_idle_notify(mbox);
 }
@@ -140,6 +155,7 @@
 	    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 @@
 	    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)
--- a/src/lib-storage/index/imapc/imapc-storage.c	Sun Jan 23 23:32:34 2011 +0200
+++ b/src/lib-storage/index/imapc/imapc-storage.c	Sun Jan 23 23:32:52 2011 +0200
@@ -279,11 +279,10 @@
 	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 @@
 {
 	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);
--- a/src/lib-storage/index/imapc/imapc-sync.c	Sun Jan 23 23:32:34 2011 +0200
+++ b/src/lib-storage/index/imapc/imapc-sync.c	Sun Jan 23 23:32:52 2011 +0200
@@ -125,11 +125,14 @@
 		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 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);