]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
dbox: Allow plugins to change output stream while saving messages.
authorTimo Sirainen <tss@iki.fi>
Fri, 19 Feb 2010 04:13:23 +0000 (06:13 +0200)
committerTimo Sirainen <tss@iki.fi>
Fri, 19 Feb 2010 04:13:23 +0000 (06:13 +0200)
--HG--
branch : HEAD

src/lib-storage/index/dbox-common/dbox-save.c
src/lib-storage/index/dbox-common/dbox-save.h
src/lib-storage/index/dbox-multi/mdbox-save.c
src/lib-storage/index/dbox-single/sdbox-save.c

index 4aa2b6ad53c899c439d7722c547a8d7ada3d5e90..bab4c0b26904ad820229cfc2c320a240f17a6c5b 100644 (file)
@@ -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,
index 2734b3e027128c8d01b4747015dd615c42624135..ac7712a2385b395eb998cda92f59c4b54d80250d 100644 (file)
@@ -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,
index e7868a321d30e0365fb3d1a086906409b10fa492..c58bca0ca7e6fdcd1bc5172616c14fabc03c6340 100644 (file)
@@ -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);
 
index d9dcb338de62b1d2858be87ed7f9d622459cfe71..eaf59fe37e0d2268be229f813c940af1f3e7e3ef 100644 (file)
@@ -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;
 }