From: Timo Sirainen Date: Wed, 5 Nov 2003 08:42:12 +0000 (+0200) Subject: Added istream->eof. istream->v_size is now set to 0 with files. X-Git-Tag: 1.1.alpha1~4245 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6449bd276af37b3e0b81a9c47ecd01f39a2cba53;p=thirdparty%2Fdovecot%2Fcore.git Added istream->eof. istream->v_size is now set to 0 with files. --HG-- branch : HEAD --- diff --git a/src/lib-index/mbox/mbox-append.c b/src/lib-index/mbox/mbox-append.c index 0f0e213d0c..a2b5e39be9 100644 --- a/src/lib-index/mbox/mbox-append.c +++ b/src/lib-index/mbox/mbox-append.c @@ -35,6 +35,9 @@ static int mbox_index_append_next(struct mail_index *index, 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 @@ int mbox_index_append_stream(struct mail_index *index, struct istream *input) uoff_t offset; int ret; - if (input->v_offset == input->v_size) { + if (input->eof) { /* no new data */ return TRUE; } @@ -192,15 +195,15 @@ int mbox_index_append_stream(struct mail_index *index, struct istream *input) } } - if (input->v_offset == input->v_size) { - ret = 1; - break; - } - t_push(); ret = mbox_index_append_next(index, trans_ctx, input); t_pop(); + if (input->eof) { + ret = 1; + break; + } + if (ret == 0) { /* we want to rescan this message with exclusive locking */ diff --git a/src/lib-index/mbox/mbox-index.c b/src/lib-index/mbox/mbox-index.c index d2d6541450..6b45f4644c 100644 --- a/src/lib-index/mbox/mbox-index.c +++ b/src/lib-index/mbox/mbox-index.c @@ -649,23 +649,18 @@ int mbox_verify_end_of_body(struct istream *input, uoff_t end_offset) 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') { diff --git a/src/lib-index/mbox/mbox-rewrite.c b/src/lib-index/mbox/mbox-rewrite.c index 9d66141928..eb091a59a8 100644 --- a/src/lib-index/mbox/mbox-rewrite.c +++ b/src/lib-index/mbox/mbox-rewrite.c @@ -692,13 +692,6 @@ int mbox_index_rewrite(struct mail_index *index) 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; diff --git a/src/lib-index/mbox/mbox-sync-full.c b/src/lib-index/mbox/mbox-sync-full.c index c290d58338..2a25f1a992 100644 --- a/src/lib-index/mbox/mbox-sync-full.c +++ b/src/lib-index/mbox/mbox-sync-full.c @@ -18,8 +18,9 @@ static void skip_line(struct istream *input) { 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 @@ static int match_next_record(struct mail_index *index, /* 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 @@ static int mbox_sync_from_stream(struct mail_index *index, } } - 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 @@ static int mbox_sync_from_stream(struct mail_index *index, 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 @@ int mbox_sync_full(struct mail_index *index) 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); diff --git a/src/lib-mail/message-send.c b/src/lib-mail/message-send.c index e3566c3fe6..8179bea773 100644 --- a/src/lib-mail/message-send.c +++ b/src/lib-mail/message-send.c @@ -36,7 +36,7 @@ off_t message_send(struct ostream *output, struct istream *input, 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; diff --git a/src/lib-storage/index/mbox/mbox-expunge.c b/src/lib-storage/index/mbox/mbox-expunge.c index ab7bc1d997..cf7b92e777 100644 --- a/src/lib-storage/index/mbox/mbox-expunge.c +++ b/src/lib-storage/index/mbox/mbox-expunge.c @@ -81,7 +81,8 @@ static int mbox_move_data(struct mbox_expunge_context *ctx) 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; } diff --git a/src/lib/istream-file.c b/src/lib/istream-file.c index 5c8e6da621..a18ba7f6b3 100644 --- a/src/lib/istream-file.c +++ b/src/lib/istream-file.c @@ -137,6 +137,7 @@ static ssize_t _read(struct _istream *stream) 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 @@ static ssize_t _read(struct _istream *stream) if (ret == 0) { /* EOF */ stream->istream.stream_errno = 0; + stream->istream.eof = TRUE; return -1; } @@ -177,6 +179,7 @@ static ssize_t _read(struct _istream *stream) if (errno == ECONNRESET || errno == ETIMEDOUT) { /* treat as disconnection */ stream->istream.stream_errno = 0; + stream->istream.eof = TRUE; return -1; } @@ -252,11 +255,8 @@ struct istream *i_stream_create_file(int fd, pool_t pool, 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); } diff --git a/src/lib/istream-mmap.c b/src/lib/istream-mmap.c index 68bbd76a57..eae9c0febc 100644 --- a/src/lib/istream-mmap.c +++ b/src/lib/istream-mmap.c @@ -100,6 +100,7 @@ static ssize_t _read(struct _istream *stream) (uoff_t)mstream->mmap_offset + stream->pos) { /* end of file */ stream->istream.stream_errno = 0; + stream->istream.eof = TRUE; return -1; } diff --git a/src/lib/istream.c b/src/lib/istream.c index 90ab1dd11a..4fd314a6c5 100644 --- a/src/lib/istream.c +++ b/src/lib/istream.c @@ -69,6 +69,7 @@ void i_stream_set_read_limit(struct istream *stream, uoff_t v_offset) 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 @@ ssize_t i_stream_read(struct istream *stream) return -1; } + stream->eof = FALSE; return _stream->read(_stream); } @@ -136,11 +138,12 @@ void i_stream_seek(struct istream *stream, uoff_t v_offset) { 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); } diff --git a/src/lib/istream.h b/src/lib/istream.h index 37b0add4a6..5b15167851 100644 --- a/src/lib/istream.h +++ b/src/lib/istream.h @@ -8,6 +8,7 @@ struct istream { int stream_errno; unsigned int mmaped:1; /* be careful when copying data */ unsigned int closed:1; + unsigned int eof:1; struct _istream *real_stream; }; diff --git a/src/lib/ostream-file.c b/src/lib/ostream-file.c index 5e48ec8293..40beb64730 100644 --- a/src/lib/ostream-file.c +++ b/src/lib/ostream-file.c @@ -689,7 +689,8 @@ static off_t io_stream_copy_backwards(struct _ostream *outstream, 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 @@ static off_t io_stream_copy_backwards(struct _ostream *outstream, 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 @@ static off_t _send_istream(struct _ostream *outstream, struct istream *instream) 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) } } +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)