dbox-save.c revision a825281071af96cc148e49c64ac36d8c5cf26f71
02c335c23bf5fa225a467c19f2c063fb0dc7b8c3Timo Sirainen/* Copyright (c) 2007-2017 Dovecot authors, see the included COPYING file */
ff52f5c52ee6a4c8a9c79964d32b5d0ff0ae92e6Timo Sirainenvoid dbox_save_add_to_index(struct dbox_save_context *ctx)
ff52f5c52ee6a4c8a9c79964d32b5d0ff0ae92e6Timo Sirainen struct mail_save_data *mdata = &ctx->ctx.data;
8f079b04c103e073e57fa8b85cf69b14b0260ea4Timo Sirainen if ((ctx->ctx.transaction->flags & MAILBOX_TRANSACTION_FLAG_FILL_IN_STUB) == 0)
8f079b04c103e073e57fa8b85cf69b14b0260ea4Timo Sirainen mail_index_append(ctx->trans, mdata->uid, &ctx->seq);
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen mail_index_update_flags(ctx->trans, ctx->seq, MODIFY_REPLACE,
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen mail_index_update_keywords(ctx->trans, ctx->seq,
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen mail_index_update_modseq(ctx->trans, ctx->seq,
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainenvoid dbox_save_begin(struct dbox_save_context *ctx, struct istream *input)
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen struct mail_storage *_storage = _ctx->transaction->box->storage;
c5d27aee77dad4b10d6dd915b9cb4c8757c0e988Timo Sirainen struct dbox_storage *storage = (struct dbox_storage *)_storage;
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen mail_set_seq_saving(_ctx->dest_mail, ctx->seq);
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen ctx->input = index_mail_cache_parse_init(_ctx->dest_mail, crlf_input);
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen /* write a dummy header. it'll get rewritten when we're finished */
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen if (o_stream_send(ctx->dbox_output, &dbox_msg_hdr,
98da0024e7340e036f0aa9371e9400176df18ebfTimo Sirainen sizeof(dbox_msg_hdr)) < 0) {
ff52f5c52ee6a4c8a9c79964d32b5d0ff0ae92e6Timo Sirainen mail_storage_set_critical(_storage, "write(%s) failed: %s",
98b7ea1744aecc52750f1dfb0d8ed6f9646b4605Timo Sirainen index_attachment_save_begin(_ctx, storage->attachment_fs, ctx->input);
28a311381d783cc06e56f9baf1cb9f25634cbfe4Timo Sirainenint dbox_save_continue(struct mail_save_context *_ctx)
3954326e793bdef1e94e0ad781ed6cc7e48beebbTimo Sirainen struct dbox_save_context *ctx = (struct dbox_save_context *)_ctx;
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen if (index_storage_save_continue(_ctx, ctx->input,
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainenvoid dbox_save_end(struct dbox_save_context *ctx)
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen struct mail_save_data *mdata = &ctx->ctx.data;
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen struct ostream *dbox_output = ctx->dbox_output;
ff52f5c52ee6a4c8a9c79964d32b5d0ff0ae92e6Timo Sirainen if (index_attachment_save_finish(&ctx->ctx) < 0)
3954326e793bdef1e94e0ad781ed6cc7e48beebbTimo Sirainen mail_storage_set_critical(ctx->ctx.transaction->box->storage,
1cfe369d1278a9e2e6cc2e46103db48c493e1f21Timo Sirainen "write(%s) failed: %s",
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen /* e.g. zlib plugin had changed this */
b5052fbfdbc2678cc8f12899afe55c998f43b740Timo Sirainen index_mail_cache_parse_deinit(ctx->ctx.dest_mail,
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainenvoid dbox_save_write_metadata(struct mail_save_context *_ctx,
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen struct ostream *output, uoff_t output_msg_size,
38fa43690a1cdc1917245f5f834ec40a89e83d91Timo Sirainen struct dbox_save_context *ctx = (struct dbox_save_context *)_ctx;
38fa43690a1cdc1917245f5f834ec40a89e83d91Timo Sirainen struct mail_save_data *mdata = &ctx->ctx.data;
ff52f5c52ee6a4c8a9c79964d32b5d0ff0ae92e6Timo Sirainen memcpy(metadata_hdr.magic_post, DBOX_MAGIC_POST,
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen o_stream_nsend(output, &metadata_hdr, sizeof(metadata_hdr));
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen if (output_msg_size != ctx->input->v_offset) {
4210fac11e936f7edd6f3deecd1b23466534ce6aTimo Sirainen /* a plugin changed the data written to disk, so the
4210fac11e936f7edd6f3deecd1b23466534ce6aTimo Sirainen "message size" dbox header doesn't contain the actual
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen "physical" message size. we need to save it as a
684cbcce30cc97340ee43240de5c0d236c917d29Timo Sirainen separate metadata header. */
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen str_printfa(str, "%c%llx\n", DBOX_METADATA_PHYSICAL_SIZE,
661998e2ccd772ad92a9d4a75cb712692a8c94b3Timo Sirainen str_printfa(str, "%c%lx\n", DBOX_METADATA_RECEIVED_TIME,
56558eb46c396db9c7a0cfd89413b1c50b126b7eTimo Sirainen if (mail_get_virtual_size(_ctx->dest_mail, &vsize) < 0)
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen str_printfa(str, "%c%llx\n", DBOX_METADATA_VIRTUAL_SIZE,
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen (unsigned long long)vsize);
e080054d7df103a9b6be62a476cbee18261acf6cTimo Sirainen i_assert(strchr(mdata->pop3_uidl, '\n') == NULL);
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen str_printfa(str, "%c%s\n", DBOX_METADATA_POP3_UIDL,
684cbcce30cc97340ee43240de5c0d236c917d29Timo Sirainen str_printfa(str, "%c%u\n", DBOX_METADATA_POP3_ORDER,
3954326e793bdef1e94e0ad781ed6cc7e48beebbTimo Sirainen str_printfa(str, "%c%s\n", DBOX_METADATA_GUID, guid);
3954326e793bdef1e94e0ad781ed6cc7e48beebbTimo Sirainen /* save the original mailbox name so if mailbox indexes get
3954326e793bdef1e94e0ad781ed6cc7e48beebbTimo Sirainen corrupted we can place at least some (hopefully most) of
c5d27aee77dad4b10d6dd915b9cb4c8757c0e988Timo Sirainen the messages to correct mailboxes. */
c5d27aee77dad4b10d6dd915b9cb4c8757c0e988Timo Sirainen str_printfa(str, "%c%s\n", DBOX_METADATA_ORIG_MAILBOX,
c5d27aee77dad4b10d6dd915b9cb4c8757c0e988Timo Sirainen dbox_attachment_save_write_metadata(_ctx, str);
3954326e793bdef1e94e0ad781ed6cc7e48beebbTimo Sirainen o_stream_nsend(output, str_data(str), str_len(str));
d0fa29db7def334c142f46507a7d0c0bd6c70932Timo Sirainenvoid dbox_save_update_header_flags(struct dbox_save_context *ctx,
cf1b9b686bca3e0de3dda1a95dab66ad4590d8efTimo Sirainen mail_index_get_header_ext(sync_view, ext_id, &data, &data_size);
cf1b9b686bca3e0de3dda1a95dab66ad4590d8efTimo Sirainen old_flags = *((const uint8_t *)data + flags_offset);
3954326e793bdef1e94e0ad781ed6cc7e48beebbTimo Sirainen /* grow old dbox header */
3954326e793bdef1e94e0ad781ed6cc7e48beebbTimo Sirainen mail_index_ext_resize_hdr(ctx->trans, ext_id, flags_offset+1);
98da0024e7340e036f0aa9371e9400176df18ebfTimo Sirainen flags |= DBOX_INDEX_HEADER_FLAG_HAVE_POP3_UIDLS;
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen flags |= DBOX_INDEX_HEADER_FLAG_HAVE_POP3_ORDERS;
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen /* flags changed, update them */