dovecot: More fixes to handling mail saving.

dovecot at dovecot.org dovecot at dovecot.org
Sat Oct 20 19:17:05 EEST 2007


details:   http://hg.dovecot.org/dovecot/rev/8917cf7fa8ba
changeset: 6562:8917cf7fa8ba
user:      Timo Sirainen <tss at iki.fi>
date:      Sat Oct 20 19:17:00 2007 +0300
description:
More fixes to handling mail saving.

diffstat:

1 file changed, 71 insertions(+), 47 deletions(-)
src/lib-storage/index/mbox/mbox-save.c |  118 +++++++++++++++++++-------------

diffs (182 lines):

diff -r 026f67ecd858 -r 8917cf7fa8ba src/lib-storage/index/mbox/mbox-save.c
--- a/src/lib-storage/index/mbox/mbox-save.c	Sat Oct 20 19:16:25 2007 +0300
+++ b/src/lib-storage/index/mbox/mbox-save.c	Sat Oct 20 19:17:00 2007 +0300
@@ -12,6 +12,7 @@
 #include "write-full.h"
 #include "istream-header-filter.h"
 #include "istream-crlf.h"
+#include "istream-concat.h"
 #include "message-parser.h"
 #include "index-mail.h"
 #include "mbox-storage.h"
@@ -51,7 +52,7 @@ struct mbox_save_context {
 	char last_char;
 
 	struct mbox_md5_context *mbox_md5_ctx;
-	unsigned int x_delivery_id_pos;
+	char *x_delivery_id_header;
 
 	unsigned int synced:1;
 	unsigned int failed:1;
@@ -350,6 +351,7 @@ static void mbox_save_x_delivery_id(stru
 {
 	unsigned char md5_result[MD5_RESULTLEN];
 	buffer_t *buf;
+	string_t *str;
 	void *randbuf;
 
 	t_push();
@@ -363,11 +365,59 @@ static void mbox_save_x_delivery_id(stru
 
 	md5_get_digest(buf->data, buf->used, md5_result);
 
-	str_append(ctx->headers, "X-Delivery-ID: ");
-	ctx->x_delivery_id_pos = str_len(ctx->headers);
-	base64_encode(md5_result, sizeof(md5_result), ctx->headers);
-	str_append_c(ctx->headers, '\n');
+	str = t_str_new(128);
+	str_append(str, "X-Delivery-ID: ");
+	base64_encode(md5_result, sizeof(md5_result), str);
+	str_append_c(str, '\n');
+
+	ctx->x_delivery_id_header = i_strdup(str_c(str));
 	t_pop();
+}
+
+static struct istream *
+mbox_save_get_input_stream(struct mbox_save_context *ctx, struct istream *input)
+{
+	struct istream *filter, *ret, *cache_input, *streams[3];
+
+	/* filter out unwanted headers and keep track of headers' MD5 sum */
+	filter = i_stream_create_header_filter(input, HEADER_FILTER_EXCLUDE |
+					       HEADER_FILTER_NO_CR,
+					       mbox_save_drop_headers,
+					       mbox_save_drop_headers_count,
+					       save_header_callback, ctx);
+
+	if ((ctx->mbox->storage->storage.flags &
+	     MAIL_STORAGE_FLAG_KEEP_HEADER_MD5) != 0) {
+		/* we're using MD5 sums to generate POP3 UIDLs.
+		   clients don't like it much if there are duplicates,
+		   so make sure that there can't be any by appending
+		   our own X-Delivery-ID header. */
+		const char *hdr;
+
+		mbox_save_x_delivery_id(ctx);
+		hdr = ctx->x_delivery_id_header;
+
+		streams[0] = i_stream_create_from_data(hdr, strlen(hdr));
+		streams[1] = filter;
+		streams[2] = NULL;
+		ret = i_stream_create_concat(streams);
+		i_stream_unref(&filter);
+		filter = ret;
+	}
+
+	/* convert linefeeds to wanted format */
+	ret = (ctx->mbox->storage->storage.flags &
+	       MAIL_STORAGE_FLAG_SAVE_CRLF) != 0 ?
+		i_stream_create_crlf(filter) : i_stream_create_lf(filter);
+	i_stream_unref(&filter);
+
+	if (ctx->mail != NULL) {
+		/* caching creates a tee stream */
+		cache_input = index_mail_cache_parse_init(ctx->mail, ret);
+		i_stream_unref(&ret);
+		ret = cache_input;
+	}
+	return ret;
 }
 
 int mbox_save_init(struct mailbox_transaction_context *_t,
@@ -417,14 +467,6 @@ int mbox_save_init(struct mailbox_transa
 			str_printfa(ctx->headers, "X-IMAPbase: %u %010u\n",
 				    ctx->uid_validity, ctx->next_uid);
 		}
-		if ((mbox->storage->storage.flags &
-		     MAIL_STORAGE_FLAG_KEEP_HEADER_MD5) != 0) {
-			/* we're using MD5 sums to generate POP3 UIDLs.
-			   clients don't like it much if there are duplicates,
-			   so make sure that there can't be any by appending
-			   our own X-Delivery-ID header. */
-			mbox_save_x_delivery_id(ctx);
-		}
 		str_printfa(ctx->headers, "X-UID: %u\n", ctx->next_uid);
 		if (!mbox->ibox.keep_recent)
 			save_flags &= ~MAIL_RECENT;
@@ -464,26 +506,8 @@ int mbox_save_init(struct mailbox_transa
 
 	if (write_from_line(ctx, received_date, from_envelope) < 0)
 		ctx->failed = TRUE;
-	else {
-		input = i_stream_create_header_filter(input,
-						HEADER_FILTER_EXCLUDE |
-						HEADER_FILTER_NO_CR,
-						mbox_save_drop_headers,
-						mbox_save_drop_headers_count,
-						save_header_callback, ctx);
-		ctx->input = (mbox->storage->storage.flags &
-			      MAIL_STORAGE_FLAG_SAVE_CRLF) != 0 ?
-			i_stream_create_crlf(input) :
-			i_stream_create_lf(input);
-		i_stream_unref(&input);
-
-		if (ctx->mail != NULL) {
-			input = index_mail_cache_parse_init(ctx->mail,
-							    ctx->input);
-			i_stream_unref(&ctx->input);
-			ctx->input = input;
-		}
-	}
+	else
+		ctx->input = mbox_save_get_input_stream(ctx, input);
 
 	*ctx_r = &ctx->ctx;
 	return ctx->failed ? -1 : 0;
@@ -495,10 +519,12 @@ static int mbox_save_body_input(struct m
 	size_t size;
 
 	data = i_stream_get_data(ctx->input, &size);
-	if (o_stream_send(ctx->output, data, size) < 0)
-		return write_error(ctx);
-	ctx->last_char = data[size-1];
-	i_stream_skip(ctx->input, size);
+	if (size > 0) {
+		if (o_stream_send(ctx->output, data, size) < 0)
+			return write_error(ctx);
+		ctx->last_char = data[size-1];
+		i_stream_skip(ctx->input, size);
+	}
 	return 0;
 }
 
@@ -589,20 +615,18 @@ int mbox_save_continue(struct mail_save_
 	if (ctx->mbox_md5_ctx) {
 		unsigned char hdr_md5_sum[16];
 
-		if (ctx->x_delivery_id_pos != 0) {
+		if (ctx->x_delivery_id_header != NULL) {
 			struct message_header_line hdr;
-			const unsigned char *p;
 
 			memset(&hdr, 0, sizeof(hdr));
-			hdr.name = "X-Delivery-ID";
-			hdr.name_len = strlen(hdr.name);
-			hdr.middle = (const unsigned char *)": ";
+			hdr.name = ctx->x_delivery_id_header;
+			hdr.name_len = sizeof("X-Delivery-ID")-1;
+			hdr.middle = (const unsigned char *)hdr.name +
+				hdr.name_len;
 			hdr.middle_len = 2;
-			hdr.value = hdr.full_value = str_data(ctx->headers) +
-				ctx->x_delivery_id_pos;
-
-			for (p = hdr.value; *p != '\n'; p++) ;
-			hdr.value_len = hdr.full_value_len = p - hdr.value;
+			hdr.value = hdr.full_value =
+				hdr.middle + hdr.middle_len;
+			hdr.value_len = strlen((const char *)hdr.value);
 			mbox_md5_continue(ctx->mbox_md5_ctx, &hdr);
 		}
 		mbox_md5_finish(ctx->mbox_md5_ctx, hdr_md5_sum);


More information about the dovecot-cvs mailing list