changeset 1861:e42d97a85653 HEAD

Added istream->eof. istream->v_size is now set to 0 with files.
author Timo Sirainen <tss@iki.fi>
date Wed, 05 Nov 2003 10:42:12 +0200
parents 8da9b7748bd4
children 3b25ea70b500
files src/lib-index/mbox/mbox-append.c src/lib-index/mbox/mbox-index.c src/lib-index/mbox/mbox-rewrite.c src/lib-index/mbox/mbox-sync-full.c src/lib-mail/message-send.c src/lib-storage/index/mbox/mbox-expunge.c src/lib/istream-file.c src/lib/istream-mmap.c src/lib/istream.c src/lib/istream.h src/lib/ostream-file.c
diffstat 11 files changed, 66 insertions(+), 43 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-index/mbox/mbox-append.c	Wed Nov 05 00:26:16 2003 +0200
+++ b/src/lib-index/mbox/mbox-append.c	Wed Nov 05 10:42:12 2003 +0200
@@ -35,6 +35,9 @@
 			break;
 	}
 
+	if (size == 0)
+		return -1;
+
 	if (pos == size || size <= 5 ||
 	    strncmp((const char *) data, "From ", 5) != 0) {
 		/* a) no \n found, or line too long
@@ -164,7 +167,7 @@
 	uoff_t offset;
 	int ret;
 
-	if (input->v_offset == input->v_size) {
+	if (input->eof) {
 		/* no new data */
 		return TRUE;
 	}
@@ -192,15 +195,15 @@
 			}
 		}
 
-		if (input->v_offset == input->v_size) {
+		t_push();
+		ret = mbox_index_append_next(index, trans_ctx, input);
+		t_pop();
+
+		if (input->eof) {
 			ret = 1;
 			break;
 		}
 
-		t_push();
-		ret = mbox_index_append_next(index, trans_ctx, input);
-		t_pop();
-
 		if (ret == 0) {
 			/* we want to rescan this message with exclusive
 			   locking */
--- a/src/lib-index/mbox/mbox-index.c	Wed Nov 05 00:26:16 2003 +0200
+++ b/src/lib-index/mbox/mbox-index.c	Wed Nov 05 10:42:12 2003 +0200
@@ -649,23 +649,18 @@
 	const unsigned char *data;
 	size_t size;
 
-	if (end_offset > input->v_size) {
-		/* missing data */
-		return FALSE;
-	}
-
 	i_stream_seek(input, end_offset);
 
-	if (input->v_offset == input->v_size) {
+	/* read forward a bit */
+	if (i_stream_read_data(input, &data, &size, 6) < 0)
+		return FALSE;
+
+	if (input->eof) {
 		/* end of file. a bit unexpected though,
 		   since \n is missing. */
 		return TRUE;
 	}
 
-	/* read forward a bit */
-	if (i_stream_read_data(input, &data, &size, 6) < 0)
-		return FALSE;
-
 	/* either there should be the next From-line,
 	   or [\r]\n at end of file */
 	if (size > 0 && data[0] == '\r') {
--- a/src/lib-index/mbox/mbox-rewrite.c	Wed Nov 05 00:26:16 2003 +0200
+++ b/src/lib-index/mbox/mbox-rewrite.c	Wed Nov 05 10:42:12 2003 +0200
@@ -692,13 +692,6 @@
 				break;
 			}
 
-			if (offset + body_size > input->v_size) {
-				mail_cache_set_corrupted(index->cache,
-					"Invalid message size");
-				failed = TRUE;
-				break;
-			}
-
 			if (!dirty_found) {
 				/* first dirty message */
 				dirty_found = TRUE;
--- a/src/lib-index/mbox/mbox-sync-full.c	Wed Nov 05 00:26:16 2003 +0200
+++ b/src/lib-index/mbox/mbox-sync-full.c	Wed Nov 05 10:42:12 2003 +0200
@@ -18,8 +18,9 @@
 {
 	const unsigned char *msg;
 	size_t i, size;
+	int ret;
 
-	while (i_stream_read_data(input, &msg, &size, 0) > 0) {
+	while ((ret = i_stream_read_data(input, &msg, &size, 0)) > 0) {
 		for (i = 0; i < size; i++) {
 			if (msg[i] == '\n') {
 				i_stream_skip(input, i+1);
@@ -90,6 +91,8 @@
 
 	/* skip the From-line */
 	skip_line(input);
+	if (input->eof)
+		return -1;
 	header_offset = input->v_offset;
 
 	first_rec = last_rec = NULL;
@@ -248,12 +251,12 @@
 			}
 		}
 
-		if (input->v_offset == input->v_size)
-			break;
-
 		ret = match_next_record(index, rec, &seq, input, &rec, &dirty);
-		if (ret < 0)
+		if (ret < 0) {
+			if (input->eof)
+				break;
 			return FALSE;
+		}
 
 		if (ret == 0) {
 			/* Get back to line before From */
@@ -274,8 +277,7 @@
 		index->header->flags &= ~MAIL_INDEX_HDR_FLAG_DIRTY_MESSAGES;
 	}
 
-	if (input->v_offset == input->v_size ||
-	    (index->set_flags & MAIL_INDEX_HDR_FLAG_REBUILD))
+	if (input->eof || (index->set_flags & MAIL_INDEX_HDR_FLAG_REBUILD))
 		return TRUE;
 	else
 		return mbox_index_append_stream(index, input);
@@ -300,7 +302,7 @@
 		failed = TRUE;
 	} else {
 		failed = !mbox_sync_from_stream(index, input);
-		continue_offset = failed || input->v_offset == input->v_size ||
+		continue_offset = failed || input->eof ||
 			(index->set_flags & MAIL_INDEX_HDR_FLAG_REBUILD) ?
 			(uoff_t)-1 : input->v_offset;
 		i_stream_unref(input);
--- a/src/lib-mail/message-send.c	Wed Nov 05 00:26:16 2003 +0200
+++ b/src/lib-mail/message-send.c	Wed Nov 05 10:42:12 2003 +0200
@@ -36,7 +36,7 @@
 		old_limit = input->v_limit;
 		limit = input->v_offset + max_virtual_size;
 		i_stream_set_read_limit(input, I_MIN(limit, old_limit));
-		ret = o_stream_send_istream(output, input) > 0;
+		ret = o_stream_send_istream(output, input);
 		i_stream_set_read_limit(input, old_limit);
 
 		return ret;
--- a/src/lib-storage/index/mbox/mbox-expunge.c	Wed Nov 05 00:26:16 2003 +0200
+++ b/src/lib-storage/index/mbox/mbox-expunge.c	Wed Nov 05 10:42:12 2003 +0200
@@ -81,7 +81,8 @@
 	failed = o_stream_send_istream(ctx->output, ctx->input) < 0;
 	i_stream_set_read_limit(ctx->input, old_limit);
 
-	if (failed || ctx->input->v_offset != ctx->from_offset)
+	if (failed || (ctx->input->v_offset != ctx->from_offset &&
+		       ctx->from_offset != 0))
 		return FALSE;
 	return TRUE;
 }
--- a/src/lib/istream-file.c	Wed Nov 05 00:26:16 2003 +0200
+++ b/src/lib/istream-file.c	Wed Nov 05 10:42:12 2003 +0200
@@ -137,6 +137,7 @@
 			stream->istream.v_offset + fstream->skip_left;
 		if (read_limit <= stream->pos - stream->skip) {
 			/* virtual limit reached == EOF */
+			stream->istream.eof = TRUE;
 			return -1;
 		}
 
@@ -170,6 +171,7 @@
 		if (ret == 0) {
 			/* EOF */
 			stream->istream.stream_errno = 0;
+			stream->istream.eof = TRUE;
 			return -1;
 		}
 
@@ -177,6 +179,7 @@
 			if (errno == ECONNRESET || errno == ETIMEDOUT) {
 				/* treat as disconnection */
 				stream->istream.stream_errno = 0;
+				stream->istream.eof = TRUE;
 				return -1;
 			}
 
@@ -252,11 +255,8 @@
 	fstream->istream.seek = _seek;
 
 	/* get size of fd if it's a file */
-	if (fstat(fd, &st) < 0 || !S_ISREG(st.st_mode))
-		st.st_size = 0;
-	else
+	if (fstat(fd, &st) == 0 && S_ISREG(st.st_mode))
 		fstream->file = TRUE;
 
-	return _i_stream_create(&fstream->istream, pool, fd, 0,
-				(uoff_t)st.st_size);
+	return _i_stream_create(&fstream->istream, pool, fd, 0, 0);
 }
--- a/src/lib/istream-mmap.c	Wed Nov 05 00:26:16 2003 +0200
+++ b/src/lib/istream-mmap.c	Wed Nov 05 10:42:12 2003 +0200
@@ -100,6 +100,7 @@
 	    (uoff_t)mstream->mmap_offset + stream->pos) {
 		/* end of file */
 		stream->istream.stream_errno = 0;
+		stream->istream.eof = TRUE;
 		return -1;
 	}
 
--- a/src/lib/istream.c	Wed Nov 05 00:26:16 2003 +0200
+++ b/src/lib/istream.c	Wed Nov 05 10:42:12 2003 +0200
@@ -69,6 +69,7 @@
 
 	i_assert(stream->v_size == 0 || v_offset <= stream->v_size);
 
+	stream->eof = FALSE;
 	if (_stream->high_pos != 0) {
 		_stream->pos = _stream->high_pos;
 		_stream->high_pos = 0;
@@ -100,6 +101,7 @@
 		return -1;
 	}
 
+	stream->eof = FALSE;
 	return _stream->read(_stream);
 }
 
@@ -136,11 +138,12 @@
 {
 	struct _istream *_stream = stream->real_stream;
 
-	i_assert(v_offset <= stream->v_size);
+	i_assert(stream->v_size == 0 || v_offset <= stream->v_size);
 
 	if (stream->closed)
 		return;
 
+	stream->eof = FALSE;
 	_stream->high_pos = 0;
 	_stream->seek(_stream, v_offset);
 }
--- a/src/lib/istream.h	Wed Nov 05 00:26:16 2003 +0200
+++ b/src/lib/istream.h	Wed Nov 05 10:42:12 2003 +0200
@@ -8,6 +8,7 @@
 	int stream_errno;
 	unsigned int mmaped:1; /* be careful when copying data */
 	unsigned int closed:1;
+	unsigned int eof:1;
 
 	struct _istream *real_stream;
 };
--- a/src/lib/ostream-file.c	Wed Nov 05 00:26:16 2003 +0200
+++ b/src/lib/ostream-file.c	Wed Nov 05 10:42:12 2003 +0200
@@ -689,7 +689,8 @@
 	out_offset = outstream->ostream.offset +
 		(instream->v_limit - instream->v_offset);
 
-	i_assert(out_offset <= instream->start_offset + instream->v_size);
+	i_assert(instream->v_size == 0 ||
+		 out_offset <= instream->start_offset + instream->v_size);
 
 	while (in_offset > in_start_offset) {
 		if (in_offset - in_start_offset <= buffer_size)
@@ -756,12 +757,13 @@
 	return (off_t) (instream->v_limit - in_start_offset);
 }
 
-static off_t _send_istream(struct _ostream *outstream, struct istream *instream)
+static off_t send_istream_fd(struct _ostream *outstream,
+			     struct istream *instream, int in_fd)
 {
 	struct file_ostream *foutstream = (struct file_ostream *) outstream;
 	uoff_t old_limit;
 	off_t ret;
-	int in_fd, overlapping;
+	int overlapping;
 
 	i_assert(instream->v_limit <= OFF_T_MAX);
 	i_assert(instream->v_offset <= instream->v_limit);
@@ -771,7 +773,6 @@
 	if (instream->v_offset == instream->v_limit)
 		return 0;
 
-	in_fd = i_stream_get_fd(instream);
 	if (in_fd != foutstream->fd)
 		overlapping = 0;
 	else {
@@ -812,6 +813,29 @@
 	}
 }
 
+static off_t _send_istream(struct _ostream *outstream, struct istream *instream)
+{
+	struct stat st;
+	int in_fd, ret;
+
+	in_fd = i_stream_get_fd(instream);
+	if (fstat(in_fd, &st) < 0) {
+		outstream->ostream.stream_errno = errno;
+		return -1;
+	}
+
+	if (instream->v_limit != 0)
+		return send_istream_fd(outstream, instream, in_fd);
+	else {
+		/* easier this way so we know exactly how much data we're
+		   moving */
+		i_stream_set_read_limit(instream, st.st_size);
+		ret = send_istream_fd(outstream, instream, in_fd);
+		i_stream_set_read_limit(instream, 0);
+		return ret;
+	}
+}
+
 struct ostream *
 o_stream_create_file(int fd, pool_t pool, size_t max_buffer_size,
 		     int autoclose_fd)