dovecot-2.2: imap: FETCH API cleanup: keep fetch state in a sepa...

dovecot at dovecot.org dovecot at dovecot.org
Mon Aug 13 02:38:58 EEST 2012


details:   http://hg.dovecot.org/dovecot-2.2/rev/0c73a42c194e
changeset: 14887:0c73a42c194e
user:      Timo Sirainen <tss at iki.fi>
date:      Mon Aug 13 01:47:54 2012 +0300
description:
imap: FETCH API cleanup: keep fetch state in a separate struct.

diffstat:

 src/imap/cmd-fetch.c       |   11 +-
 src/imap/imap-fetch-body.c |   93 ++++++++++++----------
 src/imap/imap-fetch.c      |  187 ++++++++++++++++++++++----------------------
 src/imap/imap-fetch.h      |   45 ++++++----
 4 files changed, 175 insertions(+), 161 deletions(-)

diffs (truncated from 767 to 300 lines):

diff -r 42cc4c4c4891 -r 0c73a42c194e src/imap/cmd-fetch.c
--- a/src/imap/cmd-fetch.c	Mon Aug 13 01:25:12 2012 +0300
+++ b/src/imap/cmd-fetch.c	Mon Aug 13 01:47:54 2012 +0300
@@ -144,19 +144,20 @@
 	static const char *ok_message = "OK Fetch completed.";
 	const char *tagged_reply = ok_message;
 	enum mail_error error;
+	bool seen_flags_changed = ctx->state.seen_flags_changed;
 
-	if (ctx->skipped_expunged_msgs) {
+	if (ctx->state.skipped_expunged_msgs) {
 		tagged_reply = "OK ["IMAP_RESP_CODE_EXPUNGEISSUED"] "
 			"Some messages were already expunged.";
 	}
 
 	if (imap_fetch_deinit(ctx) < 0)
-		ctx->failed = TRUE;
+		ctx->state.failed = TRUE;
 
-	if (ctx->failed) {
+	if (ctx->state.failed) {
 		const char *errstr;
 
-		if (ctx->client->output->closed) {
+		if (cmd->client->output->closed) {
 			client_disconnect(cmd->client, "Disconnected");
 			return TRUE;
 		}
@@ -175,7 +176,7 @@
 	}
 
 	return cmd_sync(cmd,
-			(ctx->seen_flags_changed ? 0 : MAILBOX_SYNC_FLAG_FAST) |
+			(seen_flags_changed ? 0 : MAILBOX_SYNC_FLAG_FAST) |
 			(cmd->uid ? 0 : MAILBOX_SYNC_FLAG_NO_EXPUNGES), 0,
 			tagged_reply);
 }
diff -r 42cc4c4c4891 -r 0c73a42c194e src/imap/imap-fetch-body.c
--- a/src/imap/imap-fetch-body.c	Mon Aug 13 01:25:12 2012 +0300
+++ b/src/imap/imap-fetch-body.c	Mon Aug 13 01:47:54 2012 +0300
@@ -30,11 +30,13 @@
 
 static void fetch_read_error(struct imap_fetch_context *ctx)
 {
-	errno = ctx->cur_input->stream_errno;
+	struct imap_fetch_state *state = &ctx->state;
+
+	errno = state->cur_input->stream_errno;
 	mail_storage_set_critical(ctx->box->storage,
 		"read(%s) failed: %m (FETCH for mailbox %s UID %u)",
-		i_stream_get_name(ctx->cur_input),
-		mailbox_get_vname(ctx->cur_mail->box), ctx->cur_mail->uid);
+		i_stream_get_name(state->cur_input),
+		mailbox_get_vname(state->cur_mail->box), state->cur_mail->uid);
 }
 
 static const char *get_body_name(const struct imap_fetch_body_data *body)
@@ -63,8 +65,8 @@
 	string_t *str;
 
 	str = t_str_new(128);
-	if (ctx->first)
-		ctx->first = FALSE;
+	if (ctx->state.cur_first)
+		ctx->state.cur_first = FALSE;
 	else
 		str_append_c(str, ' ');
 
@@ -81,31 +83,34 @@
 
 static int fetch_stream_continue(struct imap_fetch_context *ctx)
 {
+	struct imap_fetch_state *state = &ctx->state;
 	off_t ret;
 
 	o_stream_set_max_buffer_size(ctx->client->output, 0);
-	ret = o_stream_send_istream(ctx->client->output, ctx->cur_input);
+	ret = o_stream_send_istream(ctx->client->output, state->cur_input);
 	o_stream_set_max_buffer_size(ctx->client->output, (size_t)-1);
 
 	if (ret > 0)
-		ctx->cur_offset += ret;
+		state->cur_offset += ret;
 
-	if (ctx->cur_offset != ctx->cur_size) {
+	if (state->cur_offset != state->cur_size) {
 		/* unfinished */
-		if (ctx->cur_input->stream_errno != 0) {
+		if (state->cur_input->stream_errno != 0) {
 			fetch_read_error(ctx);
 			client_disconnect(ctx->client, "FETCH failed");
 			return -1;
 		}
-		if (!i_stream_have_bytes_left(ctx->cur_input)) {
+		if (!i_stream_have_bytes_left(state->cur_input)) {
 			/* Input stream gave less data than expected */
 			i_error("FETCH %s for mailbox %s UID %u "
 				"got too little data: "
 				"%"PRIuUOFF_T" vs %"PRIuUOFF_T,
-				ctx->cur_name, mailbox_get_vname(ctx->cur_mail->box),
-				ctx->cur_mail->uid, ctx->cur_offset, ctx->cur_size);
-			mail_set_cache_corrupted(ctx->cur_mail,
-						 ctx->cur_size_field);
+				state->cur_human_name,
+				mailbox_get_vname(state->cur_mail->box),
+				state->cur_mail->uid,
+				state->cur_offset, state->cur_size);
+			mail_set_cache_corrupted(state->cur_mail,
+						 state->cur_size_field);
 			client_disconnect(ctx->client, "FETCH failed");
 			return -1;
 		}
@@ -128,17 +133,18 @@
 
 	if (imap_msgpart_open(mail, body->msgpart, &result) < 0)
 		return -1;
-	ctx->cur_input = result.input;
-	ctx->cur_size = result.size;
-	ctx->cur_size_field = result.size_field;
-	ctx->cur_name = p_strconcat(ctx->pool, "[", body->section, "]", NULL);
+	ctx->state.cur_input = result.input;
+	ctx->state.cur_size = result.size;
+	ctx->state.cur_size_field = result.size_field;
+	ctx->state.cur_human_name =
+		p_strconcat(ctx->pool, "[", body->section, "]", NULL);
 
-	str = get_prefix(ctx, body, ctx->cur_size,
+	str = get_prefix(ctx, body, ctx->state.cur_size,
 			 result.binary_decoded_input_has_nuls);
 	o_stream_nsend(ctx->client->output, str_data(str), str_len(str));
 
-	ctx->cont_handler = fetch_stream_continue;
-	return ctx->cont_handler(ctx);
+	ctx->state.cont_handler = fetch_stream_continue;
+	return ctx->state.cont_handler(ctx);
 }
 
 static int fetch_binary_size(struct imap_fetch_context *ctx, struct mail *mail,
@@ -151,8 +157,8 @@
 		return -1;
 
 	str = t_str_new(128);
-	if (ctx->first)
-		ctx->first = FALSE;
+	if (ctx->state.cur_first)
+		ctx->state.cur_first = FALSE;
 	else
 		str_append_c(str, ' ');
 	str_printfa(str, "%s %"PRIuUOFF_T, get_body_name(body), size);
@@ -412,7 +418,7 @@
 	if (mail_get_virtual_size(mail, &size) < 0)
 		return -1;
 
-	str_printfa(ctx->cur_str, "RFC822.SIZE %"PRIuUOFF_T" ", size);
+	str_printfa(ctx->state.cur_str, "RFC822.SIZE %"PRIuUOFF_T" ", size);
 	return 1;
 }
 
@@ -427,10 +433,10 @@
 	imap_msgpart_free(_msgpart);
 	if (ret < 0)
 		return -1;
-	ctx->cur_input = result.input;
-	ctx->cur_size = result.size;
-	ctx->cur_size_field = result.size_field;
-	ctx->cont_handler = fetch_stream_continue;
+	ctx->state.cur_input = result.input;
+	ctx->state.cur_size = result.size;
+	ctx->state.cur_size_field = result.size_field;
+	ctx->state.cont_handler = fetch_stream_continue;
 	return 0;
 }
 
@@ -445,14 +451,15 @@
 	if (fetch_and_free_msgpart(ctx, mail, &msgpart) < 0)
 		return -1;
 
-	str = t_strdup_printf(" RFC822 {%"PRIuUOFF_T"}\r\n", ctx->cur_size);
-	if (ctx->first) {
-		str++; ctx->first = FALSE;
+	str = t_strdup_printf(" RFC822 {%"PRIuUOFF_T"}\r\n",
+			      ctx->state.cur_size);
+	if (ctx->state.cur_first) {
+		str++; ctx->state.cur_first = FALSE;
 	}
 	o_stream_nsend_str(ctx->client->output, str);
 
-	ctx->cur_name = "RFC822";
-	return ctx->cont_handler(ctx);
+	ctx->state.cur_human_name = "RFC822";
+	return ctx->state.cont_handler(ctx);
 }
 
 static int ATTR_NULL(3)
@@ -467,14 +474,14 @@
 		return -1;
 
 	str = t_strdup_printf(" RFC822.HEADER {%"PRIuUOFF_T"}\r\n",
-			      ctx->cur_size);
-	if (ctx->first) {
-		str++; ctx->first = FALSE;
+			      ctx->state.cur_size);
+	if (ctx->state.cur_first) {
+		str++; ctx->state.cur_first = FALSE;
 	}
 	o_stream_nsend_str(ctx->client->output, str);
 
-	ctx->cur_name = "RFC822.HEADER";
-	return ctx->cont_handler(ctx);
+	ctx->state.cur_human_name = "RFC822.HEADER";
+	return ctx->state.cont_handler(ctx);
 }
 
 static int ATTR_NULL(3)
@@ -489,14 +496,14 @@
 		return -1;
 
 	str = t_strdup_printf(" RFC822.TEXT {%"PRIuUOFF_T"}\r\n",
-			      ctx->cur_size);
-	if (ctx->first) {
-		str++; ctx->first = FALSE;
+			      ctx->state.cur_size);
+	if (ctx->state.cur_first) {
+		str++; ctx->state.cur_first = FALSE;
 	}
 	o_stream_nsend_str(ctx->client->output, str);
 
-	ctx->cur_name = "RFC822.TEXT";
-	return ctx->cont_handler(ctx);
+	ctx->state.cur_human_name = "RFC822.TEXT";
+	return ctx->state.cont_handler(ctx);
 }
 
 bool imap_fetch_rfc822_init(struct imap_fetch_init_context *ctx)
diff -r 42cc4c4c4891 -r 0c73a42c194e src/imap/imap-fetch.c
--- a/src/imap/imap-fetch.c	Mon Aug 13 01:25:12 2012 +0300
+++ b/src/imap/imap-fetch.c	Mon Aug 13 01:47:54 2012 +0300
@@ -105,12 +105,12 @@
 	ctx->pool = cmd->pool;
 	ctx->box = box;
 
-	ctx->cur_str = str_new(default_pool, 8192);
+	ctx->state.cur_str = str_new(default_pool, 8192);
 	p_array_init(&ctx->all_headers, cmd->pool, 64);
 	p_array_init(&ctx->handlers, cmd->pool, 16);
 	p_array_init(&ctx->tmp_keywords, cmd->pool,
 		     client->keywords.announce_count + 8);
-	ctx->line_finished = TRUE;
+	ctx->state.line_finished = TRUE;
 	return ctx;
 }
 
@@ -140,8 +140,8 @@
 	/* partially because of broken clients, but also partially because
 	   it potentially can make client implementations faster, we have a
 	   buffered parameter which basically means that the handler promises
-	   to write the output in fetch_ctx->cur_str. The cur_str is then sent
-	   to client before calling any non-buffered handlers.
+	   to write the output in fetch_ctx->state.cur_str. The cur_str is then
+	   sent to client before calling any non-buffered handlers.
 
 	   We try to keep the handler registration order the same as the
 	   client requested them. This is especially useful to get UID
@@ -327,11 +327,12 @@
 
 int imap_fetch_begin(struct imap_fetch_context *ctx)
 {
+	struct mailbox_header_lookup_ctx *wanted_headers = NULL;
 	const void *data;
 
 	if (ctx->send_vanished) {
 		if (imap_fetch_send_vanished(ctx) < 0) {
-			ctx->failed = TRUE;
+			ctx->state.failed = TRUE;
 			return -1;
 		}
 	}
@@ -351,24 +352,25 @@
 		array_append_zero(&ctx->all_headers);
 
 		data = array_idx(&ctx->all_headers, 0);
-		ctx->all_headers_ctx =
-			mailbox_header_lookup_init(ctx->box, data);
+		wanted_headers = mailbox_header_lookup_init(ctx->box, data);
 	}
 
 	if ((ctx->fetch_data &
 	     (MAIL_FETCH_STREAM_HEADER | MAIL_FETCH_STREAM_BODY)) != 0)
 		ctx->fetch_data |= MAIL_FETCH_NUL_STATE;
 
-	ctx->trans = mailbox_transaction_begin(ctx->box,
+	ctx->state.trans = mailbox_transaction_begin(ctx->box,
 		MAILBOX_TRANSACTION_FLAG_HIDE |
 		MAILBOX_TRANSACTION_FLAG_REFRESH);
 
 	/* Delayed uidset -> seqset conversion. VANISHED needs the uidset. */
 	mail_search_args_init(ctx->search_args, ctx->box, TRUE,
 			      &ctx->client->search_saved_uidset);
-	ctx->search_ctx =
-		mailbox_search_init(ctx->trans, ctx->search_args, NULL,


More information about the dovecot-cvs mailing list