dovecot-2.2: imap: Changed internal FETCH command handling API.

dovecot at dovecot.org dovecot at dovecot.org
Thu Mar 1 09:31:51 EET 2012


details:   http://hg.dovecot.org/dovecot-2.2/rev/d8a88e53f1e6
changeset: 14228:d8a88e53f1e6
user:      Timo Sirainen <tss at iki.fi>
date:      Thu Mar 01 09:31:40 2012 +0200
description:
imap: Changed internal FETCH command handling API.

diffstat:

 src/imap/cmd-fetch.c       |   53 ++++++-----
 src/imap/cmd-select.c      |   15 +-
 src/imap/imap-fetch-body.c |  155 +++++++++++++++-----------------
 src/imap/imap-fetch.c      |  208 +++++++++++++++++++++++---------------------
 src/imap/imap-fetch.h      |   59 ++++++++----
 5 files changed, 253 insertions(+), 237 deletions(-)

diffs (truncated from 1071 to 300 lines):

diff -r df631445f150 -r d8a88e53f1e6 src/imap/cmd-fetch.c
--- a/src/imap/cmd-fetch.c	Tue Feb 28 05:27:03 2012 +0200
+++ b/src/imap/cmd-fetch.c	Thu Mar 01 09:31:40 2012 +0200
@@ -21,13 +21,14 @@
 };
 
 static bool
-fetch_parse_args(struct imap_fetch_context *ctx, const struct imap_arg *arg,
-		 const struct imap_arg **next_arg_r)
+fetch_parse_args(struct imap_fetch_context *ctx,
+		 struct client_command_context *cmd,
+		 const struct imap_arg *arg, const struct imap_arg **next_arg_r)
 {
 	const char *str, *const *macro;
 
-	if (ctx->cmd->uid) {
-		if (!imap_fetch_init_handler(ctx, "UID", &arg))
+	if (cmd->uid) {
+		if (!imap_fetch_cmd_init_handler(ctx, cmd, "UID", &arg))
 			return FALSE;
 	}
 	if (imap_arg_get_atom(arg, &str)) {
@@ -43,12 +44,12 @@
 			macro = full_macro;
 		else {
 			macro = NULL;
-			if (!imap_fetch_init_handler(ctx, str, &arg))
+			if (!imap_fetch_cmd_init_handler(ctx, cmd, str, &arg))
 				return FALSE;
 		}
 		if (macro != NULL) {
 			while (*macro != NULL) {
-				if (!imap_fetch_init_handler(ctx, *macro, &arg))
+				if (!imap_fetch_cmd_init_handler(ctx, cmd, *macro, &arg))
 					return FALSE;
 				macro++;
 			}
@@ -60,11 +61,11 @@
 		while (imap_arg_get_atom(arg, &str)) {
 			str = t_str_ucase(str);
 			arg++;
-			if (!imap_fetch_init_handler(ctx, str, &arg))
+			if (!imap_fetch_cmd_init_handler(ctx, cmd, str, &arg))
 				return FALSE;
 		}
 		if (!IMAP_ARG_IS_EOL(arg)) {
-			client_send_command_error(ctx->cmd,
+			client_send_command_error(cmd,
 				"FETCH list contains non-atoms.");
 			return FALSE;
 		}
@@ -74,6 +75,7 @@
 
 static bool
 fetch_parse_modifier(struct imap_fetch_context *ctx,
+		     struct client_command_context *cmd,
 		     const char *name, const struct imap_arg **args)
 {
 	const char *str;
@@ -82,58 +84,59 @@
 	if (strcmp(name, "CHANGEDSINCE") == 0) {
 		if (!imap_arg_get_atom(*args, &str) ||
 		    str_to_uint64(str, &modseq) < 0) {
-			client_send_command_error(ctx->cmd,
+			client_send_command_error(cmd,
 				"Invalid CHANGEDSINCE modseq.");
 			return FALSE;
 		}
 		*args += 1;
-		return imap_fetch_add_changed_since(ctx, modseq);
+		imap_fetch_add_changed_since(ctx, modseq);
+		return TRUE;
 	}
-	if (strcmp(name, "VANISHED") == 0 && ctx->cmd->uid) {
+	if (strcmp(name, "VANISHED") == 0 && cmd->uid) {
 		if ((ctx->client->enabled_features &
 		     MAILBOX_FEATURE_QRESYNC) == 0) {
-			client_send_command_error(ctx->cmd,
-						  "QRESYNC not enabled");
+			client_send_command_error(cmd, "QRESYNC not enabled");
 			return FALSE;
 		}
 		ctx->send_vanished = TRUE;
 		return TRUE;
 	}
 
-	client_send_command_error(ctx->cmd, "Unknown FETCH modifier");
+	client_send_command_error(cmd, "Unknown FETCH modifier");
 	return FALSE;
 }
 
 static bool
 fetch_parse_modifiers(struct imap_fetch_context *ctx,
+		      struct client_command_context *cmd,
 		      const struct imap_arg *args)
 {
 	const char *name;
 
 	while (!IMAP_ARG_IS_EOL(args)) {
 		if (!imap_arg_get_atom(args, &name)) {
-			client_send_command_error(ctx->cmd,
+			client_send_command_error(cmd,
 				"FETCH modifiers contain non-atoms.");
 			return FALSE;
 		}
 		args++;
-		if (!fetch_parse_modifier(ctx, t_str_ucase(name), &args))
+		if (!fetch_parse_modifier(ctx, cmd, t_str_ucase(name), &args))
 			return FALSE;
 	}
 	if (ctx->send_vanished &&
 	    (ctx->search_args->args->next == NULL ||
 	     ctx->search_args->args->next->type != SEARCH_MODSEQ)) {
-		client_send_command_error(ctx->cmd,
+		client_send_command_error(cmd,
 			"VANISHED used without CHANGEDSINCE");
 		return FALSE;
 	}
 	return TRUE;
 }
 
-static bool cmd_fetch_finish(struct imap_fetch_context *ctx)
+static bool cmd_fetch_finish(struct imap_fetch_context *ctx,
+			     struct client_command_context *cmd)
 {
 	static const char *ok_message = "OK Fetch completed.";
-	struct client_command_context *cmd = ctx->cmd;
 	const char *tagged_reply = ok_message;
 
 	if (ctx->partial_fetch) {
@@ -170,11 +173,11 @@
 {
         struct imap_fetch_context *ctx = cmd->context;
 
-	if (imap_fetch_more(ctx) == 0) {
+	if (imap_fetch_more(ctx, cmd) == 0) {
 		/* unfinished */
 		return FALSE;
 	}
-	return cmd_fetch_finish(ctx);
+	return cmd_fetch_finish(ctx, cmd);
 }
 
 bool cmd_fetch(struct client_command_context *cmd)
@@ -213,15 +216,15 @@
 	}
 	ctx->search_args = search_args;
 
-	if (!fetch_parse_args(ctx, &args[1], &next_arg) ||
+	if (!fetch_parse_args(ctx, cmd, &args[1], &next_arg) ||
 	    (imap_arg_get_list(next_arg, &list_arg) &&
-	     !fetch_parse_modifiers(ctx, list_arg))) {
+	     !fetch_parse_modifiers(ctx, cmd, list_arg))) {
 		imap_fetch_deinit(ctx);
 		return TRUE;
 	}
 
 	if (imap_fetch_begin(ctx) == 0) {
-		if (imap_fetch_more(ctx) == 0) {
+		if (imap_fetch_more(ctx, cmd) == 0) {
 			/* unfinished */
 			cmd->state = CLIENT_COMMAND_STATE_WAIT_OUTPUT;
 
@@ -230,5 +233,5 @@
 			return FALSE;
 		}
 	}
-	return cmd_fetch_finish(ctx);
+	return cmd_fetch_finish(ctx, cmd);
 }
diff -r df631445f150 -r d8a88e53f1e6 src/imap/cmd-select.c
--- a/src/imap/cmd-select.c	Tue Feb 28 05:27:03 2012 +0200
+++ b/src/imap/cmd-select.c	Thu Mar 01 09:31:40 2012 +0200
@@ -214,7 +214,7 @@
         struct imap_select_context *ctx = cmd->context;
 	int ret;
 
-	if (imap_fetch_more(ctx->fetch_ctx) == 0) {
+	if (imap_fetch_more(ctx->fetch_ctx, cmd) == 0) {
 		/* unfinished */
 		return FALSE;
 	}
@@ -247,16 +247,13 @@
 	fetch_ctx->qresync_sample_seqset = &ctx->qresync_sample_seqset;
 	fetch_ctx->qresync_sample_uidset = &ctx->qresync_sample_uidset;
 
-	if (!imap_fetch_add_changed_since(fetch_ctx, ctx->qresync_modseq) ||
-	    !imap_fetch_init_handler(fetch_ctx, "UID", NULL) ||
-	    !imap_fetch_init_handler(fetch_ctx, "FLAGS", NULL) ||
-	    !imap_fetch_init_handler(fetch_ctx, "MODSEQ", NULL)) {
-		(void)imap_fetch_deinit(fetch_ctx);
-		return -1;
-	}
+	imap_fetch_add_changed_since(fetch_ctx, ctx->qresync_modseq);
+	imap_fetch_init_nofail_handler(fetch_ctx, imap_fetch_uid_init);
+	imap_fetch_init_nofail_handler(fetch_ctx, imap_fetch_flags_init);
+	imap_fetch_init_nofail_handler(fetch_ctx, imap_fetch_modseq_init);
 
 	if (imap_fetch_begin(fetch_ctx) == 0) {
-		if (imap_fetch_more(fetch_ctx) == 0) {
+		if (imap_fetch_more(fetch_ctx, ctx->cmd) == 0) {
 			/* unfinished */
 			ctx->fetch_ctx = fetch_ctx;
 			ctx->cmd->state = CLIENT_COMMAND_STATE_WAIT_OUTPUT;
diff -r df631445f150 -r d8a88e53f1e6 src/imap/imap-fetch-body.c
--- a/src/imap/imap-fetch-body.c	Tue Feb 28 05:27:03 2012 +0200
+++ b/src/imap/imap-fetch-body.c	Thu Mar 01 09:31:40 2012 +0200
@@ -305,7 +305,7 @@
 {
 	string_t *str;
 
-	ctx->cur_name = p_strconcat(ctx->cmd->pool,
+	ctx->cur_name = p_strconcat(ctx->pool,
 				    "[", body->section, "]", NULL);
 	ctx->cur_size = get_send_size(body, size->virtual_size);
 
@@ -607,63 +607,60 @@
 	return TRUE;
 }
 
-static bool fetch_body_header_fields_init(struct imap_fetch_context *ctx,
+static bool fetch_body_header_fields_init(struct imap_fetch_init_context *ctx,
 					  struct imap_fetch_body_data *body,
 					  const char *section)
 {
-	const char *const *arr, *name;
+	const char *const *arr;
 
 	if (!fetch_body_header_fields_check(section))
 		return FALSE;
 
-	name = get_body_name(body);
-	if ((ctx->fetch_data & (MAIL_FETCH_STREAM_HEADER |
-				MAIL_FETCH_STREAM_BODY)) != 0) {
+	if ((ctx->fetch_ctx->fetch_data & (MAIL_FETCH_STREAM_HEADER |
+					   MAIL_FETCH_STREAM_BODY)) != 0) {
 		/* we'll need to open the file anyway, don't try to get the
 		   headers from cache. */
-		imap_fetch_add_handler(ctx, FALSE, FALSE, name, "NIL",
+		imap_fetch_add_handler(ctx, 0, "NIL",
 				       fetch_body_header_partial, body);
 		return TRUE;
 	}
 
 	for (arr = body->fields; *arr != NULL; arr++) {
-		const char *hdr = p_strdup(ctx->cmd->pool, *arr);
-		array_append(&ctx->all_headers, &hdr, 1);
+		const char *hdr = p_strdup(ctx->fetch_ctx->pool, *arr);
+		array_append(&ctx->fetch_ctx->all_headers, &hdr, 1);
 	}
 
-	body->header_ctx = mailbox_header_lookup_init(ctx->box, body->fields);
-	imap_fetch_add_handler(ctx, FALSE, TRUE, name, "NIL",
+	body->header_ctx = mailbox_header_lookup_init(ctx->fetch_ctx->box,
+						      body->fields);
+	imap_fetch_add_handler(ctx, IMAP_FETCH_HANDLER_FLAG_WANT_DEINIT, "NIL",
 			       fetch_body_header_fields, body);
 	return TRUE;
 }
 
-static bool fetch_body_section_name_init(struct imap_fetch_context *ctx,
-					 struct imap_fetch_body_data *body)
+static bool
+fetch_body_section_name_init(struct imap_fetch_init_context *ctx,
+			     struct imap_fetch_body_data *body)
 {
-	const char *name, *section = body->section;
+	const char *section = body->section;
 
-	name = get_body_name(body);
 	if (*section == '\0') {
-		ctx->fetch_data |= MAIL_FETCH_STREAM_HEADER |
+		ctx->fetch_ctx->fetch_data |= MAIL_FETCH_STREAM_HEADER |
 			MAIL_FETCH_STREAM_BODY;
-		imap_fetch_add_handler(ctx, FALSE, FALSE, name, "NIL",
-				       fetch_body, body);
+		imap_fetch_add_handler(ctx, 0, "NIL", fetch_body, body);
 		return TRUE;
 	}
 
 	if (strcmp(section, "TEXT") == 0) {
-		ctx->fetch_data |= MAIL_FETCH_STREAM_BODY;
-		imap_fetch_add_handler(ctx, FALSE, FALSE, name, "NIL",
-				       fetch_body, body);
+		ctx->fetch_ctx->fetch_data |= MAIL_FETCH_STREAM_BODY;
+		imap_fetch_add_handler(ctx, 0, "NIL", fetch_body, body);
 		return TRUE;
 	}
 
 	if (strncmp(section, "HEADER", 6) == 0) {
 		/* exact header matches could be cached */
 		if (section[6] == '\0') {
-			ctx->fetch_data |= MAIL_FETCH_STREAM_HEADER;
-			imap_fetch_add_handler(ctx, FALSE, FALSE, name, "NIL",
-					       fetch_body, body);
+			ctx->fetch_ctx->fetch_data |= MAIL_FETCH_STREAM_HEADER;
+			imap_fetch_add_handler(ctx, 0, "NIL", fetch_body, body);
 			return TRUE;
 		}
 


More information about the dovecot-cvs mailing list