dbox-save.c revision efe78d3ba24fc866af1c79b9223dc0809ba26cad
02c335c23bf5fa225a467c19f2c063fb0dc7b8c3Timo Sirainen/* Copyright (c) 2007-2016 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;
e42e27fcc497c7b4a5cc0b6ff304abca5ccfcb4fTimo Sirainen if ((ctx->ctx.transaction->flags & MAILBOX_TRANSACTION_FLAG_FILL_IN_STUB) == 0)
e42e27fcc497c7b4a5cc0b6ff304abca5ccfcb4fTimo 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 */
e6440616c02bb1404dc35debf45d9741260c7831Timo Sirainen if (o_stream_send(ctx->dbox_output, &dbox_msg_hdr,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen sizeof(dbox_msg_hdr)) < 0) {
8acb8deef145fc0225095ed3974b2685fdaf959eTimo Sirainen mail_storage_set_critical(_storage, "write(%s) failed: %s",
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;
c68f28e2cf5f9621511bece0414335e551dc82c6Timo Sirainen if (index_storage_save_continue(_ctx, ctx->input,
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,
8acb8deef145fc0225095ed3974b2685fdaf959eTimo Sirainen "write(%s) failed: %s",
3177b410680f3915549719f84a4acbffd4f9c561Timo 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 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);
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainen o_stream_nsend(output, str_data(str), str_len(str));
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainenvoid dbox_save_update_header_flags(struct dbox_save_context *ctx,
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainen mail_index_get_header_ext(sync_view, ext_id, &data, &data_size);
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainen old_flags = *((const uint8_t *)data + flags_offset);
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainen /* grow old dbox header */
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainen mail_index_ext_resize_hdr(ctx->trans, ext_id, flags_offset+1);
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainen flags |= DBOX_INDEX_HEADER_FLAG_HAVE_POP3_UIDLS;
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainen flags |= DBOX_INDEX_HEADER_FLAG_HAVE_POP3_ORDERS;
9865d9e7c5713e41db939222ed9c0225a11fb99eTimo Sirainen /* flags changed, update them */