dbox-save.c revision 147a788fea2a88f7125b27226451271d55cf5b01
5a580c3a38ced62d4bcc95b8ac7c4f2935b5d294Timo Sirainen/* Copyright (c) 2007-2013 Dovecot authors, see the included COPYING file */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenvoid dbox_save_add_to_index(struct dbox_save_context *ctx)
99695d99930b35c2bac85d52e976b44cf8485d83Timo Sirainen struct mail_save_data *mdata = &ctx->ctx.data;
99695d99930b35c2bac85d52e976b44cf8485d83Timo Sirainen mail_index_append(ctx->trans, mdata->uid, &ctx->seq);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mail_index_update_flags(ctx->trans, ctx->seq, MODIFY_REPLACE,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mail_index_update_keywords(ctx->trans, ctx->seq,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mail_index_update_modseq(ctx->trans, ctx->seq,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenvoid dbox_save_begin(struct dbox_save_context *ctx, struct istream *input)
b9f564d00b7a115f465ffd6840341c7b8f9bfc8aTimo Sirainen struct mail_storage *_storage = _ctx->transaction->box->storage;
b9f564d00b7a115f465ffd6840341c7b8f9bfc8aTimo Sirainen struct dbox_storage *storage = (struct dbox_storage *)_storage;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen ctx->mail = mail_alloc(_ctx->transaction, 0, NULL);
7631f16156aca373004953fe6b01a7f343fb47e0Timo Sirainen mail_set_seq_saving(_ctx->dest_mail, ctx->seq);
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 */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen 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) {
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainen mail_storage_set_critical(_storage, "write(%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)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct dbox_save_context *ctx = (struct dbox_save_context *)_ctx;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct mail_storage *storage = _ctx->transaction->box->storage;
99695d99930b35c2bac85d52e976b44cf8485d83Timo Sirainen if (o_stream_send_istream(_ctx->data.output, ctx->input) < 0) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (!mail_storage_set_error_from_errno(storage)) {
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainen "write(%s) failed: %m",
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen index_mail_cache_parse_continue(_ctx->dest_mail);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen /* both tee input readers may consume data from our primary
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen input stream. we'll have to make sure we don't return with
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen one of the streams still having data in them. */
e6440616c02bb1404dc35debf45d9741260c7831Timo Sirainenvoid dbox_save_end(struct dbox_save_context *ctx)
99695d99930b35c2bac85d52e976b44cf8485d83Timo Sirainen struct mail_save_data *mdata = &ctx->ctx.data;
e6440616c02bb1404dc35debf45d9741260c7831Timo Sirainen struct ostream *dbox_output = ctx->dbox_output;
b9f564d00b7a115f465ffd6840341c7b8f9bfc8aTimo Sirainen if (index_attachment_save_finish(&ctx->ctx) < 0)
efb83f10b2a557d7427c311da52d768fb91e1b47Timo Sirainen mail_storage_set_critical(ctx->ctx.transaction->box->storage,
efb83f10b2a557d7427c311da52d768fb91e1b47Timo Sirainen "write(%s) failed: %m",
dcf4259a9de2a5c86cea67e5bb1321ff5222746dTimo Sirainen /* e.g. zlib plugin had changed this */
c3d9da3955043aef88c17b71f2081e894186aa6bTimo Sirainen index_mail_cache_parse_deinit(ctx->ctx.dest_mail,
1f19649986397419d014febd1337c6eb7b530f26Timo Sirainenvoid dbox_save_write_metadata(struct mail_save_context *_ctx,
1f19649986397419d014febd1337c6eb7b530f26Timo Sirainen struct ostream *output, uoff_t output_msg_size,
1f19649986397419d014febd1337c6eb7b530f26Timo Sirainen struct dbox_save_context *ctx = (struct dbox_save_context *)_ctx;
99695d99930b35c2bac85d52e976b44cf8485d83Timo Sirainen struct mail_save_data *mdata = &ctx->ctx.data;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen memset(&metadata_hdr, 0, sizeof(metadata_hdr));
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen memcpy(metadata_hdr.magic_post, DBOX_MAGIC_POST,
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainen o_stream_nsend(output, &metadata_hdr, sizeof(metadata_hdr));
1f19649986397419d014febd1337c6eb7b530f26Timo Sirainen if (output_msg_size != ctx->input->v_offset) {
1f19649986397419d014febd1337c6eb7b530f26Timo Sirainen /* a plugin changed the data written to disk, so the
1f19649986397419d014febd1337c6eb7b530f26Timo Sirainen "message size" dbox header doesn't contain the actual
1f19649986397419d014febd1337c6eb7b530f26Timo Sirainen "physical" message size. we need to save it as a
1f19649986397419d014febd1337c6eb7b530f26Timo Sirainen separate metadata header. */
b58aafbd21b365117538f73f306d22f75acd91f1Timo 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)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen str_printfa(str, "%c%llx\n", DBOX_METADATA_VIRTUAL_SIZE,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen (unsigned long long)vsize);
99695d99930b35c2bac85d52e976b44cf8485d83Timo Sirainen i_assert(strchr(mdata->pop3_uidl, '\n') == NULL);
a8bc64d2ec8babb5109fa23aa3c90383de61cd69Timo Sirainen str_printfa(str, "%c%s\n", DBOX_METADATA_POP3_UIDL,
147a788fea2a88f7125b27226451271d55cf5b01Timo Sirainen str_printfa(str, "%c%u\n", DBOX_METADATA_POP3_ORDER,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen str_printfa(str, "%c%s\n", DBOX_METADATA_GUID, guid);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen /* save the original mailbox name so if mailbox indexes get
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen corrupted we can place at least some (hopefully most) of
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen the messages to correct mailboxes. */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen str_printfa(str, "%c%s\n", DBOX_METADATA_ORIG_MAILBOX,
b9f564d00b7a115f465ffd6840341c7b8f9bfc8aTimo Sirainen dbox_attachment_save_write_metadata(_ctx, str);