changeset 2580:a86d97c69e8f HEAD

When using cached message_parts, update the header size with mbox since it may change. Fixes BODY[1] etc. fetches giving corrupted replies.
author Timo Sirainen <tss@iki.fi>
date Fri, 10 Sep 2004 14:25:33 +0300
parents b0ab37ee418a
children b88b34d95c7b
files src/lib-mail/message-part-serialize.c src/lib-mail/message-part-serialize.h src/lib-storage/index/index-mail.c
diffstat 3 files changed, 53 insertions(+), 57 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-mail/message-part-serialize.c	Fri Sep 10 13:49:09 2004 +0300
+++ b/src/lib-mail/message-part-serialize.c	Fri Sep 10 14:25:33 2004 +0300
@@ -240,11 +240,26 @@
 	return TRUE;
 }
 
-struct message_part *message_part_deserialize(pool_t pool, const void *data,
-					      size_t size, const char **error)
+static void
+message_parts_update_physical_pos(struct message_part *parent, off_t diff)
+{
+	struct message_part *part;
+
+	for (part = parent->children; part != NULL; part = part->next) {
+		part->physical_pos += diff;
+		if (part->children != NULL)
+			message_parts_update_physical_pos(part, diff);
+	}
+}
+
+struct message_part *
+message_part_deserialize(pool_t pool, const void *data, size_t size,
+			 const struct message_size *new_hdr_size,
+			 const char **error_r)
 {
 	struct deserialize_context ctx;
         struct message_part *part;
+	off_t diff;
 
 	memset(&ctx, 0, sizeof(ctx));
 	ctx.pool = pool;
@@ -252,58 +267,29 @@
 	ctx.end = ctx.data + size;
 
 	if (!message_part_deserialize_part(&ctx, NULL, 1, &part)) {
-		*error = ctx.error;
+		*error_r = ctx.error;
 		return NULL;
 	}
 
 	if (ctx.data != ctx.end) {
-		*error = "Too much data";
+		*error_r = "Too much data";
 		return NULL;
 	}
 
+	if (new_hdr_size != NULL) {
+		if (new_hdr_size->virtual_size !=
+		    part->header_size.virtual_size) {
+			part->header_size.virtual_size =
+				new_hdr_size->virtual_size;
+		}
+		if (new_hdr_size->physical_size !=
+		    part->header_size.physical_size) {
+			diff = new_hdr_size->physical_size -
+				part->header_size.physical_size;
+                        part->header_size.physical_size += diff;
+			message_parts_update_physical_pos(part, diff);
+		}
+	}
+
 	return part;
 }
-
-int message_part_deserialize_size(const void *data, size_t size,
-				  struct message_size *hdr_size,
-				  struct message_size *body_size)
-{
-	const unsigned char *buf = data;
-	unsigned int flags;
-
-	/* make sure it looks valid */
-	if (size < MINIMUM_SERIALIZED_SIZE)
-		return FALSE;
-
-	memcpy(&flags, buf, sizeof(flags));
-	buf += sizeof(flags);
-
-	if (hdr_size == NULL)
-		buf += sizeof(uoff_t) * 2;
-	else {
-		memcpy(&hdr_size->physical_size, buf, sizeof(uoff_t));
-		buf += sizeof(uoff_t);
-		memcpy(&hdr_size->virtual_size, buf, sizeof(uoff_t));
-		buf += sizeof(uoff_t);
-		hdr_size->lines = 0;
-	}
-
-	if (body_size != NULL) {
-		memcpy(&body_size->physical_size, buf, sizeof(uoff_t));
-		buf += sizeof(uoff_t);
-		memcpy(&body_size->virtual_size, buf, sizeof(uoff_t));
-		buf += sizeof(uoff_t);
-
-		if ((flags & (MESSAGE_PART_FLAG_TEXT |
-			      MESSAGE_PART_FLAG_MESSAGE_RFC822)) == 0)
-			body_size->lines = 0;
-		else {
-			if (size < MINIMUM_SERIALIZED_SIZE +
-			    sizeof(unsigned int))
-				return FALSE;
-			memcpy(&body_size->lines, buf, sizeof(unsigned int));
-		}
-	}
-
-	return TRUE;
-}
--- a/src/lib-mail/message-part-serialize.h	Fri Sep 10 13:49:09 2004 +0300
+++ b/src/lib-mail/message-part-serialize.h	Fri Sep 10 14:25:33 2004 +0300
@@ -8,13 +8,11 @@
 void message_part_serialize(struct message_part *part, buffer_t *dest);
 
 /* Generate struct message_part from serialized data. Returns NULL and sets
-   error if any problems are detected. */
-struct message_part *message_part_deserialize(pool_t pool, const void *data,
-					      size_t size, const char **error);
-
-/* Get message size from serialized struct message_part data. */
-int message_part_deserialize_size(const void *data, size_t size,
-				  struct message_size *hdr_size,
-				  struct message_size *body_size);
+   error if any problems are detected. If cache header size is unreliable
+   (eg. with mbox), you can give a new header size which will be used. */
+struct message_part *
+message_part_deserialize(pool_t pool, const void *data, size_t size,
+			 const struct message_size *new_hdr_size,
+			 const char **error_r);
 
 #endif
--- a/src/lib-storage/index/index-mail.c	Fri Sep 10 13:49:09 2004 +0300
+++ b/src/lib-storage/index/index-mail.c	Fri Sep 10 14:25:33 2004 +0300
@@ -36,6 +36,7 @@
 {
 	struct mail_cache_field *cache_fields = mail->ibox->cache_fields;
 	struct message_part *part;
+	const struct message_size *new_hdr_size;
 	buffer_t *part_buf;
 	const char *error;
 
@@ -49,10 +50,21 @@
 		return NULL;
 	}
 
+	if (!mail->ibox->unreliable_headers)
+		new_hdr_size = NULL;
+	else {
+		if (!mail->data.hdr_size_set) {
+			if (index_mail_parse_headers(mail, NULL) < 0)
+				return NULL;
+		}
+
+		new_hdr_size = &mail->data.hdr_size;
+	}
+
 	part = message_part_deserialize(mail->pool,
 					buffer_get_data(part_buf, NULL),
 					buffer_get_used_size(part_buf),
-					&error);
+					new_hdr_size, &error);
 	t_pop();
 
 	if (part == NULL) {