From: Timo Sirainen Date: Wed, 25 Feb 2009 02:13:29 +0000 (-0500) Subject: Added i_stream_get_size(). Use it instead of i_stream_stat() where possible. X-Git-Tag: 2.0.alpha1~1038^2~78 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=4b9f99761df5014c659cd87fddaf6854af428cfc;p=thirdparty%2Fdovecot%2Fcore.git Added i_stream_get_size(). Use it instead of i_stream_stat() where possible. --HG-- branch : HEAD --- diff --git a/src/lib-storage/index/mbox/mbox-sync.c b/src/lib-storage/index/mbox/mbox-sync.c index 4ae5c99657..7781e9ec22 100644 --- a/src/lib-storage/index/mbox/mbox-sync.c +++ b/src/lib-storage/index/mbox/mbox-sync.c @@ -866,22 +866,24 @@ mbox_sync_seek_to_uid(struct mbox_sync_context *sync_ctx, uint32_t uid) { struct mail_index_view *sync_view = sync_ctx->sync_view; uint32_t seq1, seq2; - const struct stat *st; + uoff_t size; + int ret; i_assert(!sync_ctx->index_reset); if (!mail_index_lookup_seq_range(sync_view, uid, (uint32_t)-1, &seq1, &seq2)) { /* doesn't exist anymore, seek to end of file */ - st = i_stream_stat(sync_ctx->file_input, TRUE); - if (st == NULL) { + ret = i_stream_get_size(sync_ctx->file_input, TRUE, &size); + if (ret < 0) { mbox_set_syscall_error(sync_ctx->mbox, - "i_stream_stat()"); + "i_stream_get_size()"); return -1; } + i_assert(ret != 0); if (istream_raw_mbox_seek(sync_ctx->mbox->mbox_stream, - st->st_size) < 0) { + size) < 0) { mbox_sync_set_critical(sync_ctx, "Error seeking to end of mbox file %s", sync_ctx->mbox->path); @@ -1218,8 +1220,8 @@ static int mbox_write_pseudo(struct mbox_sync_context *sync_ctx) static int mbox_sync_handle_eof_updates(struct mbox_sync_context *sync_ctx, struct mbox_sync_mail_context *mail_ctx) { - const struct stat *st; uoff_t file_size, offset, padding, trailer_size; + int ret; if (!istream_raw_mbox_is_eof(sync_ctx->input)) { i_assert(sync_ctx->need_space_seq == 0); @@ -1227,17 +1229,16 @@ static int mbox_sync_handle_eof_updates(struct mbox_sync_context *sync_ctx, return 0; } - st = i_stream_stat(sync_ctx->file_input, TRUE); - if (st == NULL) { - mbox_set_syscall_error(sync_ctx->mbox, "i_stream_stat()"); + ret = i_stream_get_size(sync_ctx->file_input, TRUE, &file_size); + if (ret < 0) { + mbox_set_syscall_error(sync_ctx->mbox, "i_stream_get_size()"); return -1; } - if (st->st_size < 0) { + if (ret == 0) { /* Not a file - allow anyway */ return 0; } - file_size = st->st_size; if (file_size < sync_ctx->file_input->v_offset) { mbox_sync_set_critical(sync_ctx, "file size unexpectedly shrank in mbox file %s " diff --git a/src/lib/istream-internal.h b/src/lib/istream-internal.h index e075debc81..f5f27aa41f 100644 --- a/src/lib/istream-internal.h +++ b/src/lib/istream-internal.h @@ -16,6 +16,7 @@ struct istream_private { uoff_t v_offset, bool mark); void (*sync)(struct istream_private *stream); const struct stat *(*stat)(struct istream_private *stream, bool exact); + int (*get_size)(struct istream_private *stream, bool exact, uoff_t *size_r); /* data: */ struct istream istream; diff --git a/src/lib/istream-limit.c b/src/lib/istream-limit.c index 4544467267..cc59e0f8f7 100644 --- a/src/lib/istream-limit.c +++ b/src/lib/istream-limit.c @@ -112,6 +112,27 @@ i_stream_limit_stat(struct istream_private *stream, bool exact) return &stream->statbuf; } +static int i_stream_limit_get_size(struct istream_private *stream, + bool exact, uoff_t *size_r) +{ + struct limit_istream *lstream = (struct limit_istream *) stream; + const struct stat *st; + + if (lstream->v_size != (uoff_t)-1) { + *size_r = lstream->v_size; + return 1; + } + + st = i_stream_stat(&stream->istream, exact); + if (st == NULL) + return -1; + if (st->st_size == -1) + return 0; + + *size_r = st->st_size; + return 1; +} + struct istream *i_stream_create_limit(struct istream *input, uoff_t v_size) { struct limit_istream *lstream; @@ -130,6 +151,7 @@ struct istream *i_stream_create_limit(struct istream *input, uoff_t v_size) lstream->istream.read = i_stream_limit_read; lstream->istream.seek = i_stream_limit_seek; lstream->istream.stat = i_stream_limit_stat; + lstream->istream.get_size = i_stream_limit_get_size; lstream->istream.istream.blocking = input->blocking; lstream->istream.istream.seekable = input->seekable; diff --git a/src/lib/istream.c b/src/lib/istream.c index cf8b7a0cd3..413cae1be3 100644 --- a/src/lib/istream.c +++ b/src/lib/istream.c @@ -191,6 +191,16 @@ const struct stat *i_stream_stat(struct istream *stream, bool exact) return _stream->stat(_stream, exact); } +int i_stream_get_size(struct istream *stream, bool exact, uoff_t *size_r) +{ + struct istream_private *_stream = stream->real_stream; + + if (unlikely(stream->closed)) + return -1; + + return _stream->get_size(_stream, exact, size_r); +} + bool i_stream_have_bytes_left(const struct istream *stream) { const struct istream_private *_stream = stream->real_stream; @@ -429,6 +439,22 @@ i_stream_default_stat(struct istream_private *stream, bool exact ATTR_UNUSED) return &stream->statbuf; } +static int +i_stream_default_get_size(struct istream_private *stream, + bool exact, uoff_t *size_r) +{ + const struct stat *st; + + st = stream->stat(stream, exact); + if (st == NULL) + return -1; + if (st->st_size == -1) + return 0; + + *size_r = st->st_size; + return 1; +} + struct istream * i_stream_create(struct istream_private *_stream, struct istream *parent, int fd) { @@ -443,6 +469,8 @@ i_stream_create(struct istream_private *_stream, struct istream *parent, int fd) if (_stream->stat == NULL) _stream->stat = i_stream_default_stat; + if (_stream->get_size == NULL) + _stream->get_size = i_stream_default_get_size; if (_stream->iostream.set_max_buffer_size == NULL) { _stream->iostream.set_max_buffer_size = i_stream_default_set_max_buffer_size; diff --git a/src/lib/istream.h b/src/lib/istream.h index a48de15fba..607ebf0169 100644 --- a/src/lib/istream.h +++ b/src/lib/istream.h @@ -82,6 +82,9 @@ void i_stream_seek_mark(struct istream *stream, uoff_t v_offset); returned values can be compared to see if anything had changed (eg. in compressed stream st_size could be compressed size) */ const struct stat *i_stream_stat(struct istream *stream, bool exact); +/* Similar to i_stream_stat() call. Returns 1 if size was successfully + set, 0 if size is unknown, -1 if error. */ +int i_stream_get_size(struct istream *stream, bool exact, uoff_t *size_r); /* Returns TRUE if there are any bytes left to be read or in buffer. */ bool i_stream_have_bytes_left(const struct istream *stream) ATTR_PURE; diff --git a/src/plugins/quota/quota-storage.c b/src/plugins/quota/quota-storage.c index fa68242c35..3a57691781 100644 --- a/src/plugins/quota/quota-storage.c +++ b/src/plugins/quota/quota-storage.c @@ -200,11 +200,10 @@ quota_save_begin(struct mail_save_context *ctx, struct istream *input) struct mailbox_transaction_context *t = ctx->transaction; struct quota_transaction_context *qt = QUOTA_CONTEXT(t); struct quota_mailbox *qbox = QUOTA_CONTEXT(t->box); - const struct stat *st; + uoff_t size; int ret; - st = i_stream_stat(input, TRUE); - if (st != NULL && st->st_size != -1) { + if (i_stream_get_size(input, TRUE, &size) > 0) { /* Input size is known, check for quota immediately. This check isn't perfect, especially because input stream's linefeeds may contain CR+LFs while physical message would @@ -216,7 +215,7 @@ quota_save_begin(struct mail_save_context *ctx, struct istream *input) full mail. */ bool too_large; - ret = quota_test_alloc(qt, st->st_size, &too_large); + ret = quota_test_alloc(qt, size, &too_large); if (ret == 0) { mail_storage_set_error(t->box->storage, MAIL_ERROR_NOSPACE,