dovecot-2.0: lmtp: Use dot istream for reading DATA input.

dovecot at dovecot.org dovecot at dovecot.org
Wed Jun 24 01:35:34 EEST 2009


details:   http://hg.dovecot.org/dovecot-2.0/rev/70b96df05e9a
changeset: 9515:70b96df05e9a
user:      Timo Sirainen <tss at iki.fi>
date:      Tue Jun 23 17:30:42 2009 -0400
description:
lmtp: Use dot istream for reading DATA input.

diffstat:

2 files changed, 22 insertions(+), 50 deletions(-)
src/lmtp/client.h   |    1 
src/lmtp/commands.c |   71 +++++++++++++++------------------------------------

diffs (116 lines):

diff -r f068c8a19013 -r 70b96df05e9a src/lmtp/client.h
--- a/src/lmtp/client.h	Tue Jun 23 17:30:16 2009 -0400
+++ b/src/lmtp/client.h	Tue Jun 23 17:30:42 2009 -0400
@@ -50,6 +50,7 @@ struct client {
 
 	pool_t state_pool;
 	struct client_state state;
+	struct istream *dot_input;
 
 	unsigned int disconnected:1;
 };
diff -r f068c8a19013 -r 70b96df05e9a src/lmtp/commands.c
--- a/src/lmtp/commands.c	Tue Jun 23 17:30:16 2009 -0400
+++ b/src/lmtp/commands.c	Tue Jun 23 17:30:42 2009 -0400
@@ -6,6 +6,7 @@
 #include "str.h"
 #include "istream.h"
 #include "ostream.h"
+#include "istream-dot.h"
 #include "safe-mkstemp.h"
 #include "mail-storage-service.h"
 #include "index/raw/raw-storage.h"
@@ -318,6 +319,7 @@ static void client_input_data_finish(str
 {
 	struct mail *src_mail;
 
+	i_stream_destroy(&client->dot_input);
 	io_remove(&client->io);
 	client->io = io_add(client->fd_in, IO_READ, client_input, client);
 
@@ -405,59 +407,26 @@ client_input_add(struct client *client, 
 
 static void client_input_data_handle(struct client *client)
 {
-#define DATA_DOT_NEXT_POS 3
-#define DATA_END_SIZE 5
-	static const char *data_end = "\r\n.\r\n";
 	const unsigned char *data;
-	size_t i, size, start, skip;
-	unsigned int rewind;
-
-	data = i_stream_get_data(client->input, &size);
-	skip = 0;
-	for (i = start = 0; i < size; i++) {
-		if (data[i] == data_end[client->state.data_end_idx]) {
-			if (++client->state.data_end_idx == DATA_END_SIZE) {
-				/* found the ending. drop the "." line out. */
-				skip = i + 1;
-				i -= DATA_END_SIZE - DATA_DOT_NEXT_POS;
-				client->state.data_end_idx = 0;
-				break;
-			}
-		} else if (client->state.data_end_idx == DATA_DOT_NEXT_POS) {
-			/* saw a dot at the beginning of line. drop it. */
-			if (client_input_add(client, data + start,
-					     i - start - 1) < 0) {
-				client_destroy(client, "451 4.3.0",
-					       "Temporary internal failure");
-				return;
-			}
-			start = i;
-			client->state.data_end_idx =
-				data[i] == data_end[0] ? 1 : 0;
-		} else {
-			client->state.data_end_idx =
-				data[i] == data_end[0] ? 1 : 0;
+	size_t size;
+	ssize_t ret;
+
+	while ((ret = i_stream_read(client->dot_input)) > 0 || ret == -2) {
+		data = i_stream_get_data(client->dot_input, &size);
+		if (client_input_add(client, data, size) < 0) {
+			client_destroy(client, "451 4.3.0",
+				       "Temporary internal failure");
+			return;
 		}
-	}
-	if (client->state.data_end_idx >= DATA_DOT_NEXT_POS) {
-		/* we might not want to write the dot, so keep it in buffer
-		   until we're sure what to do about it. */
-		rewind = client->state.data_end_idx - DATA_DOT_NEXT_POS + 1;
-		i -= rewind; size -= rewind;
-	}
-	if (client_input_add(client, data + start, i-start) < 0) {
-		client_destroy(client, "451 4.3.0",
-			       "Temporary internal failure");
+		i_stream_skip(client->dot_input, size);
+	}
+	if (ret == 0)
 		return;
-	}
-	i_stream_skip(client->input, skip == 0 ? i : skip);
-
-	if (i < size) {
-		client_input_data_finish(client);
-		client_state_reset(client);
-		if (i_stream_have_bytes_left(client->input))
-			client_input_handle(client);
-	}
+
+	client_input_data_finish(client);
+	client_state_reset(client);
+	if (i_stream_have_bytes_left(client->input))
+		client_input_handle(client);
 }
 
 static void client_input_data(struct client *client)
@@ -482,6 +451,8 @@ int cmd_data(struct client *client, cons
 	i_assert(client->state.mail_data == NULL);
 	client->state.mail_data = buffer_create_dynamic(default_pool, 1024*64);
 
+	i_assert(client->dot_input == NULL);
+	client->dot_input = i_stream_create_dot(client->input, TRUE);
 	io_remove(&client->io);
 	client->io = io_add(client->fd_in, IO_READ, client_input_data, client);
 	client_send_line(client, "354 OK");


More information about the dovecot-cvs mailing list