]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Added istream->eof. istream->v_size is now set to 0 with files.
authorTimo Sirainen <tss@iki.fi>
Wed, 5 Nov 2003 08:42:12 +0000 (10:42 +0200)
committerTimo Sirainen <tss@iki.fi>
Wed, 5 Nov 2003 08:42:12 +0000 (10:42 +0200)
--HG--
branch : HEAD

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

index 0f0e213d0c0efc72cb56c4d28efc91c95dfd0238..a2b5e39be98e6bc7647f1483847e7ad32c02b48a 100644 (file)
@@ -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 */
index d2d6541450bb6e7edd2aa23b92a4260bfd4dedc8..6b45f4644cd1277ebc71518903ddfe668dc4a924 100644 (file)
@@ -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') {
index 9d66141928a2a01b68fe6c8751a64790845cb19b..eb091a59a8302bc40a60c3306e9ed985c7ed3f30 100644 (file)
@@ -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;
index c290d58338f5ea5a26b3870f42f2f1b664589962..2a25f1a99281e0a3c505c6521f5dc706e28c0c0e 100644 (file)
@@ -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);
index e3566c3fe6b2a93593e1da746ac0056bf5eea175..8179bea773a169677a0249e84920a68d76f1f569 100644 (file)
@@ -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;
index ab7bc1d9972cad5ba2d275baff0f36017d645086..cf7b92e777dd58d98e3a82f46cf8d57cbf762c4b 100644 (file)
@@ -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;
 }
index 5c8e6da621684efec72c87fa61a0eab9335b160f..a18ba7f6b32dee4ccfabb1c63c0cfdf3af6a7e1f 100644 (file)
@@ -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);
 }
index 68bbd76a5788a9297ca06c1a7545d8bc1f6c486a..eae9c0febced8cc5ddd1cfa1ba3f836db6a6f5f0 100644 (file)
@@ -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;
        }
 
index 90ab1dd11aba419d2cd34abe0f42ca5f19682024..4fd314a6c564fdb00010c20bcdf6390c57ee8215 100644 (file)
@@ -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);
 }
index 37b0add4a6a8c799adb5c553e78d30946af6a515..5b151678514067413bb5258662705d8199504862 100644 (file)
@@ -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;
 };
index 5e48ec8293bb0832972c88c9bca4bd3cd6c08756..40beb64730366fc041ca209183d98aa781c6e2a6 100644 (file)
@@ -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)