From: Timo Sirainen Date: Fri, 19 Feb 2010 04:13:23 +0000 (+0200) Subject: dbox: Allow plugins to change output stream while saving messages. X-Git-Tag: 2.0.beta3~35 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=e6440616c02bb1404dc35debf45d9741260c7831;p=thirdparty%2Fdovecot%2Fcore.git dbox: Allow plugins to change output stream while saving messages. --HG-- branch : HEAD --- diff --git a/src/lib-storage/index/dbox-common/dbox-save.c b/src/lib-storage/index/dbox-common/dbox-save.c index 4aa2b6ad53..bab4c0b269 100644 --- a/src/lib-storage/index/dbox-common/dbox-save.c +++ b/src/lib-storage/index/dbox-common/dbox-save.c @@ -49,14 +49,15 @@ void dbox_save_begin(struct dbox_save_context *ctx, struct istream *input) /* write a dummy header. it'll get rewritten when we're finished */ memset(&dbox_msg_hdr, 0, sizeof(dbox_msg_hdr)); - o_stream_cork(ctx->cur_output); - if (o_stream_send(ctx->cur_output, &dbox_msg_hdr, + o_stream_cork(ctx->dbox_output); + if (o_stream_send(ctx->dbox_output, &dbox_msg_hdr, sizeof(dbox_msg_hdr)) < 0) { mail_storage_set_critical(_ctx->transaction->box->storage, "o_stream_send(%s) failed: %m", ctx->cur_file->cur_path); ctx->failed = TRUE; } + _ctx->output = ctx->dbox_output; if (_ctx->received_date == (time_t)-1) _ctx->received_date = ioloop_time; @@ -71,7 +72,7 @@ int dbox_save_continue(struct mail_save_context *_ctx) return -1; do { - if (o_stream_send_istream(ctx->cur_output, ctx->input) < 0) { + if (o_stream_send_istream(_ctx->output, ctx->input) < 0) { if (!mail_storage_set_error_from_errno(storage)) { mail_storage_set_critical(storage, "o_stream_send_istream(%s) failed: %m", @@ -89,6 +90,18 @@ int dbox_save_continue(struct mail_save_context *_ctx) return 0; } +void dbox_save_end(struct dbox_save_context *ctx) +{ + struct ostream *dbox_output = ctx->dbox_output; + + if (ctx->ctx.output != dbox_output) { + /* e.g. zlib plugin had changed this */ + o_stream_ref(dbox_output); + o_stream_destroy(&ctx->ctx.output); + ctx->ctx.output = dbox_output; + } +} + void dbox_save_write_metadata(struct mail_save_context *ctx, struct ostream *output, const char *orig_mailbox_name, diff --git a/src/lib-storage/index/dbox-common/dbox-save.h b/src/lib-storage/index/dbox-common/dbox-save.h index 2734b3e027..ac7712a238 100644 --- a/src/lib-storage/index/dbox-common/dbox-save.h +++ b/src/lib-storage/index/dbox-common/dbox-save.h @@ -11,7 +11,7 @@ struct dbox_save_context { struct mail *mail; struct dbox_file *cur_file; - struct ostream *cur_output; + struct ostream *dbox_output; unsigned int failed:1; unsigned int finished:1; @@ -19,6 +19,7 @@ struct dbox_save_context { void dbox_save_begin(struct dbox_save_context *ctx, struct istream *input); int dbox_save_continue(struct mail_save_context *_ctx); +void dbox_save_end(struct dbox_save_context *ctx); void dbox_save_write_metadata(struct mail_save_context *ctx, struct ostream *output, diff --git a/src/lib-storage/index/dbox-multi/mdbox-save.c b/src/lib-storage/index/dbox-multi/mdbox-save.c index e7868a321d..c58bca0ca7 100644 --- a/src/lib-storage/index/dbox-multi/mdbox-save.c +++ b/src/lib-storage/index/dbox-multi/mdbox-save.c @@ -110,12 +110,12 @@ int mdbox_save_begin(struct mail_save_context *_ctx, struct istream *input) } if (dbox_map_append_next(ctx->append_ctx, mail_size, &ctx->cur_file_append, - &ctx->ctx.cur_output) < 0) { + &ctx->ctx.dbox_output) < 0) { ctx->ctx.failed = TRUE; return -1; } - i_assert(ctx->ctx.cur_output->offset <= (uint32_t)-1); - append_offset = ctx->ctx.cur_output->offset; + i_assert(ctx->ctx.dbox_output->offset <= (uint32_t)-1); + append_offset = ctx->ctx.dbox_output->offset; ctx->ctx.cur_file = ctx->cur_file_append->file; dbox_save_begin(&ctx->ctx, input); @@ -137,10 +137,10 @@ static int mdbox_save_mail_write_metadata(struct mdbox_save_context *ctx, i_assert(file->msg_header_size == sizeof(dbox_msg_hdr)); - message_size = ctx->ctx.cur_output->offset - + message_size = ctx->ctx.dbox_output->offset - mail->append_offset - mail->file_append->file->msg_header_size; - dbox_save_write_metadata(&ctx->ctx.ctx, ctx->ctx.cur_output, + dbox_save_write_metadata(&ctx->ctx.ctx, ctx->ctx.dbox_output, ctx->mbox->box.name, guid_128); /* save the 128bit GUID to index so if the map index gets corrupted we can still find the message */ @@ -148,7 +148,7 @@ static int mdbox_save_mail_write_metadata(struct mdbox_save_context *ctx, ctx->mbox->guid_ext_id, guid_128, NULL); dbox_msg_header_fill(&dbox_msg_hdr, message_size); - if (o_stream_pwrite(ctx->ctx.cur_output, &dbox_msg_hdr, + if (o_stream_pwrite(ctx->ctx.dbox_output, &dbox_msg_hdr, sizeof(dbox_msg_hdr), mail->append_offset) < 0) { dbox_file_set_syscall_error(file, "pwrite()"); return -1; @@ -162,9 +162,10 @@ static int mdbox_save_finish_write(struct mail_save_context *_ctx) struct dbox_save_mail *mails; ctx->ctx.finished = TRUE; - if (ctx->ctx.cur_output == NULL) + if (ctx->ctx.dbox_output == NULL) return -1; + dbox_save_end(&ctx->ctx); index_mail_cache_parse_deinit(_ctx->dest_mail, _ctx->received_date, !ctx->ctx.failed); diff --git a/src/lib-storage/index/dbox-single/sdbox-save.c b/src/lib-storage/index/dbox-single/sdbox-save.c index d9dcb338de..eaf59fe37e 100644 --- a/src/lib-storage/index/dbox-single/sdbox-save.c +++ b/src/lib-storage/index/dbox-single/sdbox-save.c @@ -81,7 +81,7 @@ int sdbox_save_begin(struct mail_save_context *_ctx, struct istream *input) file = sdbox_file_init(ctx->mbox, 0); ctx->append_ctx = dbox_file_append_init(file); ret = dbox_file_get_append_stream(ctx->append_ctx, - &ctx->ctx.cur_output); + &ctx->ctx.dbox_output); if (ret <= 0) { i_assert(ret != 0); dbox_file_append_rollback(&ctx->append_ctx); @@ -108,12 +108,12 @@ static int dbox_save_mail_write_metadata(struct dbox_save_context *ctx, i_assert(file->msg_header_size == sizeof(dbox_msg_hdr)); - message_size = ctx->cur_output->offset - + message_size = ctx->dbox_output->offset - file->msg_header_size - file->file_header_size; - dbox_save_write_metadata(&ctx->ctx, ctx->cur_output, NULL, guid_128); + dbox_save_write_metadata(&ctx->ctx, ctx->dbox_output, NULL, guid_128); dbox_msg_header_fill(&dbox_msg_hdr, message_size); - if (o_stream_pwrite(ctx->cur_output, &dbox_msg_hdr, + if (o_stream_pwrite(ctx->dbox_output, &dbox_msg_hdr, sizeof(dbox_msg_hdr), file->file_header_size) < 0) { dbox_file_set_syscall_error(file, "pwrite()"); @@ -128,7 +128,7 @@ static int dbox_save_finish_write(struct mail_save_context *_ctx) struct dbox_file *const *files; ctx->ctx.finished = TRUE; - if (ctx->ctx.cur_output == NULL) + if (ctx->ctx.dbox_output == NULL) return -1; index_mail_cache_parse_deinit(_ctx->dest_mail, @@ -136,6 +136,7 @@ static int dbox_save_finish_write(struct mail_save_context *_ctx) files = array_idx_modifiable(&ctx->files, array_count(&ctx->files) - 1); + dbox_save_end(&ctx->ctx); if (!ctx->ctx.failed) T_BEGIN { if (dbox_save_mail_write_metadata(&ctx->ctx, *files) < 0) ctx->ctx.failed = TRUE; @@ -148,7 +149,7 @@ static int dbox_save_finish_write(struct mail_save_context *_ctx) i_stream_unref(&ctx->ctx.input); dbox_file_close(*files); - ctx->ctx.cur_output = NULL; + ctx->ctx.dbox_output = NULL; return ctx->ctx.failed ? -1 : 0; }