From: Timo Sirainen Date: Thu, 17 Jun 2004 23:08:48 +0000 (+0300) Subject: fixes X-Git-Tag: 1.1.alpha1~3951 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=02b79f9c2636da1829eee5b92753602bba8b67ed;p=thirdparty%2Fdovecot%2Fcore.git fixes --HG-- branch : HEAD --- diff --git a/src/lib-storage/index/mbox/istream-raw-mbox.c b/src/lib-storage/index/mbox/istream-raw-mbox.c index d072997383..5cb9a57198 100644 --- a/src/lib-storage/index/mbox/istream-raw-mbox.c +++ b/src/lib-storage/index/mbox/istream-raw-mbox.c @@ -103,6 +103,22 @@ static int mbox_read_from_line(struct raw_mbox_istream *rstream) return 0; } +static void handle_end_of_mail(struct raw_mbox_istream *rstream, size_t pos) +{ + rstream->mail_size = rstream->istream.istream.v_offset + pos - + rstream->hdr_offset; + + if (rstream->body_offset != (uoff_t)-1 && + rstream->hdr_offset + rstream->mail_size < rstream->body_offset) { + /* "headers\n\nFrom ..", the second \n belongs to next + message which we didn't know at the time yet. */ + i_assert(rstream->body_offset == + rstream->hdr_offset + rstream->mail_size + 1); + rstream->body_offset = + rstream->hdr_offset + rstream->mail_size; + } +} + static ssize_t _read(struct _istream *stream) { static const char *mbox_from = "\nFrom "; @@ -114,6 +130,8 @@ static ssize_t _read(struct _istream *stream) size_t i, pos, new_pos, from_start_pos; ssize_t ret = 0; + i_assert(stream->istream.v_offset >= rstream->from_offset); + if (rstream->eom) { if (rstream->body_offset == (uoff_t)-1) { /* missing \n from headers */ @@ -134,8 +152,9 @@ static ssize_t _read(struct _istream *stream) do { ret = i_stream_read(rstream->input); buf = i_stream_get_data(rstream->input, &pos); - } while (ret > 0 && - stream->istream.v_offset + pos <= rstream->input_peak_offset); + } while (ret > 0 && (pos == 1 || + stream->istream.v_offset + pos <= + rstream->input_peak_offset)); if (ret < 0) { if (ret == -2) @@ -155,8 +174,7 @@ static ssize_t _read(struct _istream *stream) rstream->eom = TRUE; rstream->next_eof = TRUE; - rstream->mail_size = stream->istream.v_offset + pos - - rstream->hdr_offset; + handle_end_of_mail(rstream, pos); return ret < 0 ? _read(stream) : ret; } @@ -211,10 +229,8 @@ static ssize_t _read(struct _istream *stream) /* rewind "\nFrom " */ from_start_pos -= 6; - rstream->mail_size = - stream->istream.v_offset + - from_start_pos - - rstream->hdr_offset; + handle_end_of_mail(rstream, + from_start_pos); break; } from_start_pos = 0; diff --git a/src/lib-storage/index/mbox/mbox-sync-private.h b/src/lib-storage/index/mbox/mbox-sync-private.h index 0dbdd63b19..c852e690e4 100644 --- a/src/lib-storage/index/mbox/mbox-sync-private.h +++ b/src/lib-storage/index/mbox/mbox-sync-private.h @@ -108,6 +108,7 @@ int mbox_sync_try_rewrite(struct mbox_sync_mail_context *ctx, off_t move_diff); int mbox_sync_rewrite(struct mbox_sync_context *sync_ctx, uint32_t first_seq, uint32_t last_seq, off_t extra_space); +int mbox_sync_seek(struct mbox_sync_context *sync_ctx, uoff_t from_offset); int mbox_move(struct mbox_sync_context *sync_ctx, uoff_t dest, uoff_t source, uoff_t size); diff --git a/src/lib-storage/index/mbox/mbox-sync-rewrite.c b/src/lib-storage/index/mbox/mbox-sync-rewrite.c index 6fe1846c62..3fe3218930 100644 --- a/src/lib-storage/index/mbox/mbox-sync-rewrite.c +++ b/src/lib-storage/index/mbox/mbox-sync-rewrite.c @@ -263,7 +263,8 @@ static int mbox_sync_read_and_move(struct mbox_sync_context *sync_ctx, uint32_t old_prev_msg_uid; uoff_t offset; - i_stream_seek(sync_ctx->input, mails[idx].offset); + if (mbox_sync_seek(sync_ctx, mails[idx].from_offset) < 0) + return -1; memset(&mail_ctx, 0, sizeof(mail_ctx)); mail_ctx.sync_ctx = sync_ctx; @@ -338,6 +339,7 @@ static int mbox_sync_fill_leftover(struct mbox_sync_context *sync_ctx, uint32_t old_prev_msg_uid; i_assert(start_offset < end_offset); + i_stream_seek(sync_ctx->input, mails[idx].offset); memset(&mail_ctx, 0, sizeof(mail_ctx)); @@ -368,7 +370,9 @@ static int mbox_sync_fill_leftover(struct mbox_sync_context *sync_ctx, return -1; } + /* just a cleanup - shouldn't be needed anymore */ mails[idx].offset = start_offset; + mails[idx].space = 0; return 0; } @@ -463,7 +467,6 @@ int mbox_sync_rewrite(struct mbox_sync_context *sync_ctx, } /* now parse it again and give it more space */ - mails[idx].space = extra_per_mail; mails[idx+1].space = 0; /* from_offset doesn't move.. */ if (mbox_sync_fill_leftover(sync_ctx, mails, first_seq + idx, idx, diff --git a/src/lib-storage/index/mbox/mbox-sync.c b/src/lib-storage/index/mbox/mbox-sync.c index 7c2e29553d..15f475c932 100644 --- a/src/lib-storage/index/mbox/mbox-sync.c +++ b/src/lib-storage/index/mbox/mbox-sync.c @@ -125,6 +125,18 @@ static int mbox_sync_lock(struct mbox_sync_context *sync_ctx, int lock_type) return 1; } +int mbox_sync_seek(struct mbox_sync_context *sync_ctx, uoff_t from_offset) +{ + if (istream_raw_mbox_seek(sync_ctx->input, from_offset) < 0) { + mail_storage_set_critical(sync_ctx->ibox->box.storage, + "Unexpectedly lost From-line at offset %"PRIuUOFF_T + " from mbox file %s", from_offset, + sync_ctx->ibox->path); + return -1; + } + return 0; +} + static int mbox_sync_grow_file(struct mbox_sync_context *sync_ctx, struct mbox_sync_mail_context *mail_ctx, uoff_t grow_size) @@ -200,6 +212,7 @@ mbox_sync_read_next_mail(struct mbox_sync_context *sync_ctx, mail_ctx->mail.body_size = istream_raw_mbox_get_body_size(sync_ctx->input, mail_ctx->content_length); + i_assert(mail_ctx->mail.body_size < OFF_T_MAX); /* save the offset permanently with recent flag state */ mail_ctx->mail.from_offset = mail_ctx->from_offset; @@ -714,7 +727,8 @@ static int mbox_sync_loop(struct mbox_sync_context *sync_ctx, if (sync_ctx->need_space_seq != 0) { if (mbox_sync_handle_missing_space(mail_ctx) < 0) return -1; - i_stream_seek(sync_ctx->input, offset); + if (mbox_sync_seek(sync_ctx, offset) < 0) + return -1; } else if (sync_ctx->expunged_space > 0) { if (!expunged) { /* move the body */ @@ -724,7 +738,8 @@ static int mbox_sync_loop(struct mbox_sync_context *sync_ctx, mail_ctx->body_offset, mail_ctx->mail.body_size) < 0) return -1; - i_stream_seek(sync_ctx->input, offset); + if (mbox_sync_seek(sync_ctx, offset) < 0) + return -1; } } else if (sync_ctx->seq >= min_message_count) { mbox_sync_buffer_delete_old(sync_ctx->syncs, uid+1); @@ -775,7 +790,10 @@ static int mbox_sync_handle_eof_updates(struct mbox_sync_context *sync_ctx, sync_ctx->space_diff -= extra_space; sync_ctx->space_diff += sync_ctx->expunged_space; - sync_ctx->expunged_space -= -sync_ctx->space_diff; + if (sync_ctx->expunged_space <= -sync_ctx->space_diff) + sync_ctx->expunged_space = 0; + else + sync_ctx->expunged_space -= -sync_ctx->space_diff; if (mail_ctx->have_eoh && !mail_ctx->updated) str_append_c(mail_ctx->header, '\n'); @@ -958,14 +976,8 @@ static int mbox_sync_update_imap_base(struct mbox_sync_context *sync_ctx) { struct mbox_sync_mail_context mail_ctx; - if (istream_raw_mbox_seek(sync_ctx->input, 0) < 0) { - /* doesn't begin with a From-line, which is weird because it - just did. */ - mail_storage_set_critical(sync_ctx->ibox->box.storage, - "Unexpectedly lost From-header line from mbox file %s", - sync_ctx->ibox->path); + if (mbox_sync_seek(sync_ctx, 0) < 0) return -1; - } sync_ctx->t = mail_index_transaction_begin(sync_ctx->sync_view, FALSE); sync_ctx->update_base_uid_last = sync_ctx->next_uid-1;