dbox-save.c revision c25dfa96bc32e8841c9a8cf5ba02fffba4290160
5f5870385cff47efd2f58e7892f251cf13761528Timo Sirainen/* Copyright (c) 2007-2012 Dovecot authors, see the included COPYING file */
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainenvoid dbox_save_add_to_index(struct dbox_save_context *ctx)
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen struct mail_save_data *mdata = &ctx->ctx.data;
f7539a17ea306191b53b8f5e752e228937df9ec3Timo Sirainen mail_index_append(ctx->trans, mdata->uid, &ctx->seq);
f7539a17ea306191b53b8f5e752e228937df9ec3Timo Sirainen mail_index_update_flags(ctx->trans, ctx->seq, MODIFY_REPLACE,
f7539a17ea306191b53b8f5e752e228937df9ec3Timo Sirainen mail_index_update_keywords(ctx->trans, ctx->seq,
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen mail_index_update_modseq(ctx->trans, ctx->seq,
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainenvoid dbox_save_begin(struct dbox_save_context *ctx, struct istream *input)
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen struct mail_storage *_storage = _ctx->transaction->box->storage;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen struct dbox_storage *storage = (struct dbox_storage *)_storage;
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen ctx->mail = mail_alloc(_ctx->transaction, 0, NULL);
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen mail_set_seq_saving(_ctx->dest_mail, ctx->seq);
d22301419109ed4a38351715e6760011421dadecTimo Sirainen ctx->input = index_mail_cache_parse_init(_ctx->dest_mail, crlf_input);
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen /* write a dummy header. it'll get rewritten when we're finished */
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen memset(&dbox_msg_hdr, 0, sizeof(dbox_msg_hdr));
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen if (o_stream_send(ctx->dbox_output, &dbox_msg_hdr,
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen sizeof(dbox_msg_hdr)) < 0) {
d22301419109ed4a38351715e6760011421dadecTimo Sirainen mail_storage_set_critical(_storage, "write(%s) failed: %m",
ca98892a6b8a30ffc1fe26fcf02c7d59e3204e7eTimo Sirainen index_attachment_save_begin(_ctx, storage->attachment_fs, ctx->input);
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainenint dbox_save_continue(struct mail_save_context *_ctx)
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen struct dbox_save_context *ctx = (struct dbox_save_context *)_ctx;
b42697a5749b85659a24316d97f1c208d469e4e8Timo Sirainen struct mail_storage *storage = _ctx->transaction->box->storage;
df00412606a00714a6e85383fa87fbdc7cc1fb5bTimo Sirainen if (o_stream_send_istream(_ctx->data.output, ctx->input) < 0) {
df00412606a00714a6e85383fa87fbdc7cc1fb5bTimo Sirainen if (!mail_storage_set_error_from_errno(storage)) {
df00412606a00714a6e85383fa87fbdc7cc1fb5bTimo Sirainen "write(%s) failed: %m",
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainen index_mail_cache_parse_continue(_ctx->dest_mail);
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainen /* both tee input readers may consume data from our primary
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen input stream. we'll have to make sure we don't return with
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen one of the streams still having data in them. */
9ffdc9d18870acef2e4dde99715d8528ff4b080dTimo Sirainenvoid dbox_save_end(struct dbox_save_context *ctx)
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen struct mail_save_data *mdata = &ctx->ctx.data;
f81f4bc282cd1944cec187bae89c0701a416ed2aTimo Sirainen struct ostream *dbox_output = ctx->dbox_output;
ca98892a6b8a30ffc1fe26fcf02c7d59e3204e7eTimo Sirainen if (index_attachment_save_finish(&ctx->ctx) < 0)
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen mail_storage_set_critical(ctx->ctx.transaction->box->storage,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen "write(%s) failed: %m",
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen /* e.g. zlib plugin had changed this */
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen index_mail_cache_parse_deinit(ctx->ctx.dest_mail,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainenvoid dbox_save_write_metadata(struct mail_save_context *_ctx,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen struct ostream *output, uoff_t output_msg_size,
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen struct dbox_save_context *ctx = (struct dbox_save_context *)_ctx;
306cfd77100131c08b243de10f6d40500f4c27c6Timo Sirainen struct mail_save_data *mdata = &ctx->ctx.data;
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen memset(&metadata_hdr, 0, sizeof(metadata_hdr));
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen memcpy(metadata_hdr.magic_post, DBOX_MAGIC_POST,
d3442384ca53d4b18a493db7dd0b000f470419cfTimo Sirainen o_stream_nsend(output, &metadata_hdr, sizeof(metadata_hdr));
c0d069950af1dbc6a4e5c3de3bf2e437796e3ae0Timo Sirainen if (output_msg_size != ctx->input->v_offset) {
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen /* a plugin changed the data written to disk, so the
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen "message size" dbox header doesn't contain the actual
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen "physical" message size. we need to save it as a
5137d2d80255938a0f5fb8f3c1a21b34cf11ada3Timo Sirainen separate metadata header. */
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen str_printfa(str, "%c%llx\n", DBOX_METADATA_PHYSICAL_SIZE,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen str_printfa(str, "%c%lx\n", DBOX_METADATA_RECEIVED_TIME,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen if (mail_get_virtual_size(_ctx->dest_mail, &vsize) < 0)
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen str_printfa(str, "%c%llx\n", DBOX_METADATA_VIRTUAL_SIZE,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen (unsigned long long)vsize);
e3aeeb634245e80d4f643f8d2eea11d6b72336d8Timo Sirainen i_assert(strchr(mdata->pop3_uidl, '\n') == NULL);