dovecot-2.0: dbox: Log warning if attachment file isn't the expe...

dovecot at dovecot.org dovecot at dovecot.org
Sat Oct 2 14:33:56 EEST 2010


details:   http://hg.dovecot.org/dovecot-2.0/rev/142bf0d4ae3c
changeset: 12247:142bf0d4ae3c
user:      Timo Sirainen <tss at iki.fi>
date:      Fri Aug 13 17:35:44 2010 +0100
description:
dbox: Log warning if attachment file isn't the expected size.

diffstat:

 src/lib-storage/index/Makefile.am                   |    2 +
 src/lib-storage/index/dbox-common/dbox-attachment.c |    7 +-
 src/lib-storage/index/istream-attachment.c          |  132 ++++++++++++++++++++++
 src/lib-storage/index/istream-attachment.h          |    6 +
 4 files changed, 145 insertions(+), 2 deletions(-)

diffs (196 lines):

diff -r 026148640148 -r 142bf0d4ae3c src/lib-storage/index/Makefile.am
--- a/src/lib-storage/index/Makefile.am	Fri Aug 13 17:22:31 2010 +0100
+++ b/src/lib-storage/index/Makefile.am	Fri Aug 13 17:35:44 2010 +0100
@@ -12,6 +12,7 @@
 	-I$(top_srcdir)/src/lib-storage
 
 libstorage_index_la_SOURCES = \
+	istream-attachment.c \
 	istream-mail-stats.c \
 	index-attachment.c \
 	index-fetch.c \
@@ -36,6 +37,7 @@
 libstorage_index_la_DEPENDENCIES = @LINKED_STORAGE_LIBS@
 
 headers = \
+	istream-attachment.h \
 	istream-mail-stats.h \
 	index-attachment.h \
 	index-mail.h \
diff -r 026148640148 -r 142bf0d4ae3c src/lib-storage/index/dbox-common/dbox-attachment.c
--- a/src/lib-storage/index/dbox-common/dbox-attachment.c	Fri Aug 13 17:22:31 2010 +0100
+++ b/src/lib-storage/index/dbox-common/dbox-attachment.c	Fri Aug 13 17:35:44 2010 +0100
@@ -4,6 +4,7 @@
 #include "istream.h"
 #include "istream-concat.h"
 #include "str.h"
+#include "istream-attachment.h"
 #include "dbox-file.h"
 #include "dbox-save.h"
 #include "dbox-attachment.h"
@@ -80,7 +81,7 @@
 	ARRAY_TYPE(mail_attachment_extref) extrefs_arr;
 	ARRAY_DEFINE(streams, struct istream *);
 	const struct mail_attachment_extref *extref;
-	struct istream **inputs, *input;
+	struct istream **inputs, *input, *input2;
 	const char *path;
 	uoff_t root_offset, last_voffset = 0;
 	unsigned int i;
@@ -107,7 +108,9 @@
 		}
 
 		last_voffset += extref->size;
-		input = i_stream_create_file(path, IO_BLOCK_SIZE);
+		input2 = i_stream_create_file(path, IO_BLOCK_SIZE);
+		input = i_stream_create_attachment(input2, extref->size);
+		i_stream_unref(&input2);
 		array_append(&streams, &input, 1);
 	}
 
diff -r 026148640148 -r 142bf0d4ae3c src/lib-storage/index/istream-attachment.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib-storage/index/istream-attachment.c	Fri Aug 13 17:35:44 2010 +0100
@@ -0,0 +1,132 @@
+/* Copyright (c) 2003-2010 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "istream-internal.h"
+#include "istream-attachment.h"
+
+struct attachment_istream {
+	struct istream_private istream;
+
+	uoff_t size;
+};
+
+static void i_stream_attachment_destroy(struct iostream_private *stream)
+{
+	struct attachment_istream *astream =
+		(struct attachment_istream *)stream;
+
+	i_stream_unref(&astream->istream.parent);
+}
+
+static ssize_t i_stream_attachment_read(struct istream_private *stream)
+{
+	struct attachment_istream *astream =
+		(struct attachment_istream *)stream;
+	uoff_t left;
+	ssize_t ret;
+	size_t pos;
+
+	if (stream->istream.v_offset +
+	    (stream->pos - stream->skip) >= astream->size) {
+		stream->istream.eof = TRUE;
+		return -1;
+	}
+
+	i_stream_seek(stream->parent, astream->istream.parent_start_offset +
+		      stream->istream.v_offset);
+
+	stream->pos -= stream->skip;
+	stream->skip = 0;
+
+	stream->buffer = i_stream_get_data(stream->parent, &pos);
+	if (pos > stream->pos)
+		ret = 0;
+	else do {
+		if ((ret = i_stream_read(stream->parent)) == -2)
+			return -2;
+
+		stream->istream.stream_errno = stream->parent->stream_errno;
+		stream->istream.eof = stream->parent->eof;
+		stream->buffer = i_stream_get_data(stream->parent, &pos);
+	} while (pos <= stream->pos && ret > 0);
+
+	left = astream->size - stream->istream.v_offset;
+	if (pos == left)
+		stream->istream.eof = TRUE;
+	else if (pos > left) {
+		i_error("Attachment file %s larger than expected "
+			"(%"PRIuUOFF_T")", i_stream_get_name(stream->parent),
+			astream->size);
+		pos = left;
+		stream->istream.eof = TRUE;
+	} else if (!stream->istream.eof) {
+		/* still more to read */
+	} else {
+		i_error("Attachment file %s smaller than expected "
+			"(%"PRIuUOFF_T")", i_stream_get_name(stream->parent),
+			astream->size);
+	}
+
+	ret = pos > stream->pos ? (ssize_t)(pos - stream->pos) :
+		(ret == 0 ? 0 : -1);
+	stream->pos = pos;
+	i_assert(ret != -1 || stream->istream.eof ||
+		 stream->istream.stream_errno != 0);
+	return ret;
+}
+
+static void
+i_stream_attachment_seek(struct istream_private *stream,
+			 uoff_t v_offset, bool mark ATTR_UNUSED)
+{
+	struct attachment_istream *astream =
+		(struct attachment_istream *)stream;
+
+	i_assert(v_offset <= astream->size);
+
+	stream->istream.v_offset = v_offset;
+	stream->skip = stream->pos = 0;
+}
+
+static const struct stat *
+i_stream_attachment_stat(struct istream_private *stream, bool exact)
+{
+	struct attachment_istream *astream =
+		(struct attachment_istream *)stream;
+	const struct stat *st;
+
+	st = i_stream_stat(stream->parent, exact);
+	if (st == NULL)
+		return NULL;
+
+	stream->statbuf = *st;
+	stream->statbuf.st_size = astream->size;
+	if (st->st_size != 0 && (uoff_t)st->st_size != astream->size) {
+		i_error("Attachment file %s size mismatch: "
+			"%"PRIuUOFF_T" != %"PRIuUOFF_T,
+			i_stream_get_name(stream->parent),
+			st->st_size, astream->size);
+	}
+	return &stream->statbuf;
+}
+
+struct istream *i_stream_create_attachment(struct istream *input, uoff_t size)
+{
+	struct attachment_istream *astream;
+
+	astream = i_new(struct attachment_istream, 1);
+	astream->size = size;
+	astream->istream.max_buffer_size = input->real_stream->max_buffer_size;
+
+	astream->istream.iostream.destroy = i_stream_attachment_destroy;
+	astream->istream.parent = input;
+	astream->istream.read = i_stream_attachment_read;
+	astream->istream.seek = i_stream_attachment_seek;
+	astream->istream.stat = i_stream_attachment_stat;
+
+	astream->istream.istream.readable_fd = input->readable_fd;
+	astream->istream.istream.blocking = input->blocking;
+	astream->istream.istream.seekable = input->seekable;
+	return i_stream_create(&astream->istream, input,
+			       i_stream_get_fd(input));
+}
diff -r 026148640148 -r 142bf0d4ae3c src/lib-storage/index/istream-attachment.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib-storage/index/istream-attachment.h	Fri Aug 13 17:35:44 2010 +0100
@@ -0,0 +1,6 @@
+#ifndef ISTREAM_ATTACHMENT_H
+#define ISTREAM_ATTACHMENT_H
+
+struct istream *i_stream_create_attachment(struct istream *input, uoff_t size);
+
+#endif


More information about the dovecot-cvs mailing list