[dovecot-cvs] dovecot/src/imap client.c, 1.75, 1.76 client.h, 1.40, 1.41 cmd-append.c, 1.87, 1.88 cmd-idle.c, 1.35, 1.36 cmd-search.c, 1.30, 1.31

tss at dovecot.org tss at dovecot.org
Tue Feb 6 12:56:15 UTC 2007


Update of /var/lib/cvs/dovecot/src/imap
In directory talvi:/tmp/cvs-serv23869

Modified Files:
	client.c client.h cmd-append.c cmd-idle.c cmd-search.c 
Log Message:
Command handling fixes.



Index: client.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/imap/client.c,v
retrieving revision 1.75
retrieving revision 1.76
diff -u -d -r1.75 -r1.76
--- client.c	5 Jan 2007 18:48:55 -0000	1.75
+++ client.c	6 Feb 2007 12:56:12 -0000	1.76
@@ -351,7 +351,6 @@
 void client_command_free(struct client_command_context *cmd)
 {
 	struct client *client = cmd->client;
-	size_t size;
 
 	/* reset input idle time because command output might have taken a
 	   long time and we don't want to disconnect client immediately then */
@@ -396,24 +395,38 @@
 		/* no commands left in the queue, we can clear the pool */
 		p_clear(client->command_pool);
 	}
+}
 
-	if (!client->disconnected &&
-	    (client->input_lock == NULL ||
-	     (client->input_lock->waiting_unambiguity &&
-	      !client_command_check_ambiguity(client->input_lock)))) {
-		if (client->io == NULL) {
-			i_assert(i_stream_get_fd(client->input) >= 0);
-			client->io = io_add(i_stream_get_fd(client->input),
-					    IO_READ, _client_input, client);
-		}
+void client_continue_pending_input(struct client *client)
+{
+	size_t size;
 
-		/* if there's unread data in buffer, handle it. */
-		if (!client->handling_input) {
-			(void)i_stream_get_data(client->input, &size);
-			if (size > 0 && !client->destroyed)
-				_client_input(client);
-		}
+	i_assert(!client->handling_input);
+
+	if (client->disconnected)
+		return;
+
+	if (client->input_lock != NULL) {
+		/* there's a command that has locked the input */
+		if (!client->input_lock->waiting_unambiguity)
+			return;
+
+		/* the command is waiting for existing ambiguity causing
+		   commands to finish. */
+		if (client_command_check_ambiguity(client->input_lock))
+			return;
+	}
+
+	if (client->io == NULL) {
+		i_assert(i_stream_get_fd(client->input) >= 0);
+		client->io = io_add(i_stream_get_fd(client->input),
+				    IO_READ, _client_input, client);
 	}
+
+	/* if there's unread data in buffer, handle it. */
+	(void)i_stream_get_data(client->input, &size);
+	if (size > 0)
+		_client_input(client);
 }
 
 /* Skip incoming data until newline is found,
@@ -573,6 +586,8 @@
 
 	if (client->output->closed)
 		client_destroy(client, NULL);
+	else
+		client_continue_pending_input(client);
 }
 
 static void client_output_cmd(struct client_command_context *cmd)
@@ -597,6 +612,8 @@
 	struct client_command_context *cmd;
 	int ret;
 
+	i_assert(!client->destroyed);
+
 	client->last_output = ioloop_time;
 
 	if ((ret = o_stream_flush(client->output)) < 0) {
@@ -616,6 +633,13 @@
 		}
 	}
 	o_stream_uncork(client->output);
+
+	if (client->output->closed) {
+		client_destroy(client, NULL);
+		return 1;
+	} else {
+		client_continue_pending_input(client);
+	}
 	return ret;
 }
 

Index: client.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/imap/client.h,v
retrieving revision 1.40
retrieving revision 1.41
diff -u -d -r1.40 -r1.41
--- client.h	20 Dec 2006 20:47:02 -0000	1.40
+++ client.h	6 Feb 2007 12:56:13 -0000	1.41
@@ -106,6 +106,8 @@
 void client_command_cancel(struct client_command_context *cmd);
 void client_command_free(struct client_command_context *cmd);
 
+void client_continue_pending_input(struct client *client);
+
 void _client_input(struct client *client);
 int _client_output(struct client *client);
 

Index: cmd-append.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/imap/cmd-append.c,v
retrieving revision 1.87
retrieving revision 1.88
diff -u -d -r1.87 -r1.88
--- cmd-append.c	21 Dec 2006 16:13:17 -0000	1.87
+++ cmd-append.c	6 Feb 2007 12:56:13 -0000	1.88
@@ -36,6 +36,8 @@
 	struct cmd_append_context *ctx = cmd->context;
 	struct client *client = cmd->client;
 
+	i_assert(!client->destroyed);
+
 	client->last_input = ioloop_time;
 
 	switch (i_stream_read(client->input)) {
@@ -66,8 +68,10 @@
 		return;
 	}
 
-	if (cmd->func(cmd))
+	if (cmd->func(cmd)) {
 		client_command_free(cmd);
+		client_continue_pending_input(client);
+	}
 }
 
 /* Returns -1 = error, 0 = need more data, 1 = successful. flags and
@@ -106,7 +110,7 @@
 
 static void cmd_append_finish(struct cmd_append_context *ctx)
 {
-        imap_parser_destroy(&ctx->save_parser);
+	imap_parser_destroy(&ctx->save_parser);
 
 	i_assert(ctx->client->input_lock == ctx->cmd);
 
@@ -303,6 +307,7 @@
 	struct cmd_append_context *ctx = cmd->context;
 	size_t size;
 	bool failed;
+	int ret;
 
 	if (cmd->cancel) {
 		cmd_append_finish(ctx);
@@ -310,10 +315,15 @@
 	}
 
 	if (ctx->save_ctx != NULL) {
-		if (mailbox_save_continue(ctx->save_ctx) < 0) {
-			/* we still have to finish reading the message
-			   from client */
-			mailbox_save_cancel(&ctx->save_ctx);
+		while (ctx->input->v_offset != ctx->msg_size) {
+			ret = i_stream_read(ctx->input);
+			if (mailbox_save_continue(ctx->save_ctx) < 0) {
+				/* we still have to finish reading the message
+				   from client */
+				mailbox_save_cancel(&ctx->save_ctx);
+			}
+			if (ret == -1)
+				break;
 		}
 	}
 
@@ -324,9 +334,9 @@
 	}
 
 	if (ctx->input->eof || client->input->closed) {
-		/* finished */
 		bool all_written = ctx->input->v_offset == ctx->msg_size;
 
+		/* finished */
 		i_stream_unref(&ctx->input);
 		ctx->input = NULL;
 

Index: cmd-idle.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/imap/cmd-idle.c,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -d -r1.35 -r1.36
--- cmd-idle.c	20 Dec 2006 19:23:46 -0000	1.35
+++ cmd-idle.c	6 Feb 2007 12:56:13 -0000	1.36
@@ -63,6 +63,7 @@
 
 	o_stream_uncork(client->output);
 	client_command_free(ctx->cmd);
+	client_continue_pending_input(client);
 }
 
 static void idle_client_input(struct cmd_idle_context *ctx)

Index: cmd-search.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/imap/cmd-search.c,v
retrieving revision 1.30
retrieving revision 1.31
diff -u -d -r1.30 -r1.31
--- cmd-search.c	20 Dec 2006 19:23:46 -0000	1.30
+++ cmd-search.c	6 Feb 2007 12:56:13 -0000	1.31
@@ -104,11 +104,14 @@
 
 static void cmd_search_more_callback(struct client_command_context *cmd)
 {
-	if (cmd_search_more(cmd))
+	struct client *client = cmd->client;
+
+	if (cmd_search_more(cmd)) {
 		client_command_free(cmd);
-	else {
+		client_continue_pending_input(client);
+	} else {
 		if (cmd->output_pending)
-			o_stream_set_flush_pending(cmd->client->output, TRUE);
+			o_stream_set_flush_pending(client->output, TRUE);
 	}
 }
 



More information about the dovecot-cvs mailing list