dbox-save.c revision 7cd7bd65aba6d84f4e4f5066d248437eaa4e5e54
bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2007-2010 Dovecot authors, see the included COPYING file */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenvoid dbox_save_add_to_index(struct dbox_save_context *ctx)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mail_index_append(ctx->trans, ctx->ctx.uid, &ctx->seq);
e42e27fcc497c7b4a5cc0b6ff304abca5ccfcb4fTimo Sirainen mail_index_update_flags(ctx->trans, ctx->seq, MODIFY_REPLACE,
e42e27fcc497c7b4a5cc0b6ff304abca5ccfcb4fTimo Sirainen mail_index_update_keywords(ctx->trans, ctx->seq,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mail_index_update_modseq(ctx->trans, ctx->seq,
99695d99930b35c2bac85d52e976b44cf8485d83Timo Sirainenvoid dbox_save_begin(struct dbox_save_context *ctx, struct istream *input)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct mail_storage *_storage = _ctx->transaction->box->storage;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct dbox_storage *storage = (struct dbox_storage *)_storage;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen ctx->mail = mail_alloc(_ctx->transaction, 0, NULL);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen ctx->input = index_mail_cache_parse_init(_ctx->dest_mail, crlf_input);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen /* write a dummy header. it'll get rewritten when we're finished */
efe78d3ba24fc866af1c79b9223dc0809ba26cadStephan Bosch memset(&dbox_msg_hdr, 0, sizeof(dbox_msg_hdr));
e6440616c02bb1404dc35debf45d9741260c7831Timo Sirainen if (o_stream_send(ctx->dbox_output, &dbox_msg_hdr,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen sizeof(dbox_msg_hdr)) < 0) {
d4002fe1f64d25a792f76fb102ef7dc519cd4e24Martti Rannanjärvi "o_stream_send(%s) failed: %m",
b9f564d00b7a115f465ffd6840341c7b8f9bfc8aTimo Sirainen index_attachment_save_begin(_ctx, storage->attachment_fs, ctx->input);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenint dbox_save_continue(struct mail_save_context *_ctx)
804fa3f03bd9170272168a5ad214053bbe3160c7Josef 'Jeff' Sipek struct dbox_save_context *ctx = (struct dbox_save_context *)_ctx;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct mail_storage *storage = _ctx->transaction->box->storage;
c68f28e2cf5f9621511bece0414335e551dc82c6Timo Sirainen if (o_stream_send_istream(_ctx->output, ctx->input) < 0) {
c68f28e2cf5f9621511bece0414335e551dc82c6Timo Sirainen if (!mail_storage_set_error_from_errno(storage)) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen "o_stream_send_istream(%s) failed: %m",
e6440616c02bb1404dc35debf45d9741260c7831Timo Sirainen index_mail_cache_parse_continue(_ctx->dest_mail);
e6440616c02bb1404dc35debf45d9741260c7831Timo Sirainen /* both tee input readers may consume data from our primary
48325adac125d7ff275ec69b05b7a92be9637630Timo Sirainen input stream. we'll have to make sure we don't return with
48325adac125d7ff275ec69b05b7a92be9637630Timo Sirainen one of the streams still having data in them. */
ad9afb64630511d5e25bc5bc11c5304986156928Timo Sirainenvoid dbox_save_end(struct dbox_save_context *ctx)
ad9afb64630511d5e25bc5bc11c5304986156928Timo Sirainen struct ostream *dbox_output = ctx->dbox_output;
ad9afb64630511d5e25bc5bc11c5304986156928Timo Sirainen if (index_attachment_save_finish(&ctx->ctx) < 0)
d4002fe1f64d25a792f76fb102ef7dc519cd4e24Martti Rannanjärvi /* e.g. zlib plugin had changed this */
3177b410680f3915549719f84a4acbffd4f9c561Timo Sirainenvoid dbox_save_write_metadata(struct mail_save_context *_ctx,
3177b410680f3915549719f84a4acbffd4f9c561Timo Sirainen struct ostream *output, uoff_t output_msg_size,
c25dfa96bc32e8841c9a8cf5ba02fffba4290160Timo Sirainen struct dbox_save_context *ctx = (struct dbox_save_context *)_ctx;
de62ce819d59a529530da4b57be1b8d6dad13d6bTimo Sirainen memset(&metadata_hdr, 0, sizeof(metadata_hdr));
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen memcpy(metadata_hdr.magic_post, DBOX_MAGIC_POST,
99695d99930b35c2bac85d52e976b44cf8485d83Timo Sirainen o_stream_send(output, &metadata_hdr, sizeof(metadata_hdr));
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (output_msg_size != ctx->input->v_offset) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen /* a plugin changed the data written to disk, so the
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen "message size" dbox header doesn't contain the actual
efe78d3ba24fc866af1c79b9223dc0809ba26cadStephan Bosch "physical" message size. we need to save it as a
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen separate metadata header. */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen str_printfa(str, "%c%llx\n", DBOX_METADATA_PHYSICAL_SIZE,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen str_printfa(str, "%c%lx\n", DBOX_METADATA_RECEIVED_TIME,
1f19649986397419d014febd1337c6eb7b530f26Timo Sirainen if (mail_get_virtual_size(_ctx->dest_mail, &vsize) < 0)
1f19649986397419d014febd1337c6eb7b530f26Timo Sirainen str_printfa(str, "%c%llx\n", DBOX_METADATA_VIRTUAL_SIZE,
1f19649986397419d014febd1337c6eb7b530f26Timo Sirainen (unsigned long long)vsize);
1f19649986397419d014febd1337c6eb7b530f26Timo Sirainen i_assert(strchr(_ctx->pop3_uidl, '\n') == NULL);
b58aafbd21b365117538f73f306d22f75acd91f1Timo Sirainen str_printfa(str, "%c%s\n", DBOX_METADATA_POP3_UIDL,
a8bc64d2ec8babb5109fa23aa3c90383de61cd69Timo Sirainen guid = binary_to_hex(guid_128, MAIL_GUID_128_SIZE);
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainen str_printfa(str, "%c%s\n", DBOX_METADATA_GUID, guid);
147a788fea2a88f7125b27226451271d55cf5b01Timo Sirainen /* save the original mailbox name so if mailbox indexes get
147a788fea2a88f7125b27226451271d55cf5b01Timo Sirainen corrupted we can place at least some (hopefully most) of
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainen the messages to correct mailboxes. */
2b9dbb270ad82e58d5f3581436e6f143176d5819Timo Sirainen str_printfa(str, "%c%s\n", DBOX_METADATA_ORIG_MAILBOX,
99695d99930b35c2bac85d52e976b44cf8485d83Timo Sirainen dbox_attachment_save_write_metadata(_ctx, str);