dovecot-2.0: cydir: Fixed crashing when saving was aborted early...
dovecot at dovecot.org
dovecot at dovecot.org
Fri Aug 6 17:12:11 EEST 2010
details: http://hg.dovecot.org/dovecot-2.0/rev/b38708f38e6c
changeset: 11951:b38708f38e6c
user: Timo Sirainen <tss at iki.fi>
date: Fri Aug 06 15:10:52 2010 +0100
description:
cydir: Fixed crashing when saving was aborted early (e.g. by out of quota)
diffstat:
src/lib-storage/index/cydir/cydir-save.c | 47 +++++++++++++++--------
1 files changed, 30 insertions(+), 17 deletions(-)
diffs (110 lines):
diff -r a30a30d1e25a -r b38708f38e6c src/lib-storage/index/cydir/cydir-save.c
--- a/src/lib-storage/index/cydir/cydir-save.c Fri Aug 06 03:12:28 2010 +0100
+++ b/src/lib-storage/index/cydir/cydir-save.c Fri Aug 06 15:10:52 2010 +0100
@@ -69,6 +69,7 @@
ctx->mbox = mbox;
ctx->trans = t->itrans;
ctx->tmp_basename = cydir_generate_tmp_filename();
+ ctx->fd = -1;
t->save_ctx = &ctx->ctx;
}
return t->save_ctx;
@@ -156,69 +157,81 @@
return 0;
}
-int cydir_save_finish(struct mail_save_context *_ctx)
+static int cydir_save_flush(struct cydir_save_context *ctx, const char *path)
{
- struct cydir_save_context *ctx = (struct cydir_save_context *)_ctx;
struct mail_storage *storage = &ctx->mbox->storage->storage;
- const char *path = cydir_get_save_path(ctx, ctx->mail_count);
struct stat st;
+ int ret = 0;
- ctx->finished = TRUE;
-
- if (o_stream_flush(_ctx->output) < 0) {
+ if (o_stream_flush(ctx->ctx.output) < 0) {
mail_storage_set_critical(storage,
"o_stream_flush(%s) failed: %m", path);
- ctx->failed = TRUE;
+ ret = -1;
}
if (storage->set->parsed_fsync_mode != FSYNC_MODE_NEVER) {
if (fsync(ctx->fd) < 0) {
mail_storage_set_critical(storage,
"fsync(%s) failed: %m", path);
- ctx->failed = TRUE;
+ ret = -1;
}
}
- if (_ctx->received_date == (time_t)-1) {
+ if (ctx->ctx.received_date == (time_t)-1) {
if (fstat(ctx->fd, &st) == 0)
- _ctx->received_date = st.st_mtime;
+ ctx->ctx.received_date = st.st_mtime;
else {
mail_storage_set_critical(storage,
"fstat(%s) failed: %m", path);
- ctx->failed = TRUE;
+ ret = -1;
}
} else {
struct utimbuf ut;
ut.actime = ioloop_time;
- ut.modtime = _ctx->received_date;
+ ut.modtime = ctx->ctx.received_date;
if (utime(path, &ut) < 0) {
mail_storage_set_critical(storage,
"utime(%s) failed: %m", path);
- ctx->failed = TRUE;
+ ret = -1;
}
}
- o_stream_destroy(&_ctx->output);
+ o_stream_destroy(&ctx->ctx.output);
if (close(ctx->fd) < 0) {
mail_storage_set_critical(storage,
"close(%s) failed: %m", path);
- ctx->failed = TRUE;
+ ret = -1;
}
ctx->fd = -1;
+ return ret;
+}
+
+int cydir_save_finish(struct mail_save_context *_ctx)
+{
+ struct cydir_save_context *ctx = (struct cydir_save_context *)_ctx;
+ const char *path = cydir_get_save_path(ctx, ctx->mail_count);
+
+ ctx->finished = TRUE;
+
+ if (ctx->fd != -1) {
+ if (cydir_save_flush(ctx, path) < 0)
+ ctx->failed = TRUE;
+ }
if (!ctx->failed)
ctx->mail_count++;
else {
if (unlink(path) < 0) {
- mail_storage_set_critical(storage,
+ mail_storage_set_critical(&ctx->mbox->storage->storage,
"unlink(%s) failed: %m", path);
}
}
index_mail_cache_parse_deinit(_ctx->dest_mail,
_ctx->received_date, !ctx->failed);
- i_stream_unref(&ctx->input);
+ if (ctx->input != NULL)
+ i_stream_unref(&ctx->input);
index_save_context_free(_ctx);
return ctx->failed ? -1 : 0;
More information about the dovecot-cvs
mailing list