On Fri, 2010-11-19 at 11:45 +0200, Axel Thimm wrote:

> evolution has a bug when it comes to closing and IDLE' connection:
> 
> https://bugzilla.gnome.org/show_bug.cgi?id=628515
> 
> evolution does not send a DONE command, and dovecot properly answers
> with an error. evolution ignores this and seems to wait on another
> response.
> 
> Timo, do you think there could be a setting for tolerating missing
> DONEs? Thanks!

Well .. the attached patch should do it, but looks like a lot more code
just to fix a client..

I also tested that Cyrus at least works the same way as Dovecot.
diff -r 3a93121f652a src/imap/cmd-idle.c
--- a/src/imap/cmd-idle.c	Mon Nov 22 18:35:07 2010 +0000
+++ b/src/imap/cmd-idle.c	Mon Nov 22 18:58:15 2010 +0000
@@ -55,10 +55,27 @@
 		client_command_free(&ctx->cmd);
 }
 
+static int idle_is_done(const unsigned char *data, size_t size)
+{
+	if (i_memcasecmp(data, "DONE", I_MIN(size, 4)) != 0)
+		return -1;
+	if (size > 4) {
+		if (data[4] == '\n')
+			return 5;
+		if (data[4] != '\r')
+			return -1;
+		if (size > 5)
+			return data[5] == '\n' ? 6 : -1;
+	}
+	return 0;
+}
+
 static void idle_client_input_more(struct cmd_idle_context *ctx)
 {
 	struct client *client = ctx->client;
-	char *line;
+	const unsigned char *data;
+	size_t size;
+	int ret;
 
 	client->last_input = ioloop_time;
 	timeout_reset(client->to_idle);
@@ -82,13 +99,17 @@
 		return;
 	}
 
-	while ((line = i_stream_next_line(client->input)) != NULL) {
-		if (client->input_skip_line)
-			client->input_skip_line = FALSE;
-		else {
-			idle_finish(ctx, strcasecmp(line, "DONE") == 0, TRUE);
-			break;
-		}
+	if (client->input_skip_line) {
+		if (i_stream_next_line(client->input) == NULL)
+			return;
+		client->input_skip_line = FALSE;
+	}
+
+	data = i_stream_get_data(client->input, &size);
+	if ((ret = idle_is_done(data, size)) != 0) {
+		idle_finish(ctx, ret > 0, TRUE);
+		if (ret > 0)
+			i_stream_skip(client->input, ret);
 	}
 	if (!client->disconnected && !client->handling_input)
 		client_continue_pending_input(client);

Reply via email to