dbox-save.c revision a825281071af96cc148e49c64ac36d8c5cf26f71
02c335c23bf5fa225a467c19f2c063fb0dc7b8c3Timo Sirainen/* Copyright (c) 2007-2017 Dovecot authors, see the included COPYING file */
ff52f5c52ee6a4c8a9c79964d32b5d0ff0ae92e6Timo Sirainen
ff52f5c52ee6a4c8a9c79964d32b5d0ff0ae92e6Timo Sirainen#include "lib.h"
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen#include "istream.h"
3954326e793bdef1e94e0ad781ed6cc7e48beebbTimo Sirainen#include "istream-crlf.h"
ff52f5c52ee6a4c8a9c79964d32b5d0ff0ae92e6Timo Sirainen#include "ostream.h"
cbe2d47fda811fc56ba59cb2811c3fc26033b03cTimo Sirainen#include "str.h"
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen#include "hex-binary.h"
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen#include "index-mail.h"
ff52f5c52ee6a4c8a9c79964d32b5d0ff0ae92e6Timo Sirainen#include "index-storage.h"
87e603100685f9eb7faf995d2600edd0a578dd0cTimo Sirainen#include "dbox-attachment.h"
ff52f5c52ee6a4c8a9c79964d32b5d0ff0ae92e6Timo Sirainen#include "dbox-file.h"
ff52f5c52ee6a4c8a9c79964d32b5d0ff0ae92e6Timo Sirainen#include "dbox-save.h"
ff52f5c52ee6a4c8a9c79964d32b5d0ff0ae92e6Timo Sirainen
ff52f5c52ee6a4c8a9c79964d32b5d0ff0ae92e6Timo Sirainenvoid dbox_save_add_to_index(struct dbox_save_context *ctx)
ff52f5c52ee6a4c8a9c79964d32b5d0ff0ae92e6Timo Sirainen{
ff52f5c52ee6a4c8a9c79964d32b5d0ff0ae92e6Timo Sirainen struct mail_save_data *mdata = &ctx->ctx.data;
28a311381d783cc06e56f9baf1cb9f25634cbfe4Timo Sirainen enum mail_flags save_flags;
8f079b04c103e073e57fa8b85cf69b14b0260ea4Timo Sirainen
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);
8f079b04c103e073e57fa8b85cf69b14b0260ea4Timo Sirainen else
09cd60cebc01b2b25ada824f3d9f877d5efd8272Timo Sirainen ctx->seq = mdata->stub_seq;
28a311381d783cc06e56f9baf1cb9f25634cbfe4Timo Sirainen
98da0024e7340e036f0aa9371e9400176df18ebfTimo Sirainen save_flags = mdata->flags & ~MAIL_RECENT;
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen mail_index_update_flags(ctx->trans, ctx->seq, MODIFY_REPLACE,
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen save_flags);
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen if (mdata->keywords != NULL) {
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen mail_index_update_keywords(ctx->trans, ctx->seq,
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen MODIFY_REPLACE, mdata->keywords);
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen }
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen if (mdata->min_modseq != 0) {
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen mail_index_update_modseq(ctx->trans, ctx->seq,
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen mdata->min_modseq);
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen }
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen}
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainenvoid dbox_save_begin(struct dbox_save_context *ctx, struct istream *input)
701eb90460d6c57845dc4e0bf595a5d0b90b01c1Timo Sirainen{
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen struct mail_save_context *_ctx = &ctx->ctx;
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen struct mail_storage *_storage = _ctx->transaction->box->storage;
c5d27aee77dad4b10d6dd915b9cb4c8757c0e988Timo Sirainen struct dbox_storage *storage = (struct dbox_storage *)_storage;
c5d27aee77dad4b10d6dd915b9cb4c8757c0e988Timo Sirainen struct dbox_message_header dbox_msg_hdr;
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen struct istream *crlf_input;
56558eb46c396db9c7a0cfd89413b1c50b126b7eTimo Sirainen
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen dbox_save_add_to_index(ctx);
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen mail_set_seq_saving(_ctx->dest_mail, ctx->seq);
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen crlf_input = i_stream_create_lf(input);
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen ctx->input = index_mail_cache_parse_init(_ctx->dest_mail, crlf_input);
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen i_stream_unref(&crlf_input);
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen /* write a dummy header. it'll get rewritten when we're finished */
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen i_zero(&dbox_msg_hdr);
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen o_stream_cork(ctx->dbox_output);
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",
ff52f5c52ee6a4c8a9c79964d32b5d0ff0ae92e6Timo Sirainen o_stream_get_name(ctx->dbox_output),
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen o_stream_get_error(ctx->dbox_output));
ff52f5c52ee6a4c8a9c79964d32b5d0ff0ae92e6Timo Sirainen ctx->failed = TRUE;
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen }
92d1458b00f4f236c4cec96a696253d3bbf8b05aTimo Sirainen _ctx->data.output = ctx->dbox_output;
ff52f5c52ee6a4c8a9c79964d32b5d0ff0ae92e6Timo Sirainen
fc0c06ee7b1e5c29a3faabd05f40fa0d26785dffTimo Sirainen if (_ctx->data.received_date == (time_t)-1)
98b7ea1744aecc52750f1dfb0d8ed6f9646b4605Timo Sirainen _ctx->data.received_date = ioloop_time;
98b7ea1744aecc52750f1dfb0d8ed6f9646b4605Timo Sirainen index_attachment_save_begin(_ctx, storage->attachment_fs, ctx->input);
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen}
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen
28a311381d783cc06e56f9baf1cb9f25634cbfe4Timo Sirainenint dbox_save_continue(struct mail_save_context *_ctx)
09cd60cebc01b2b25ada824f3d9f877d5efd8272Timo Sirainen{
3954326e793bdef1e94e0ad781ed6cc7e48beebbTimo Sirainen struct dbox_save_context *ctx = (struct dbox_save_context *)_ctx;
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen
3954326e793bdef1e94e0ad781ed6cc7e48beebbTimo Sirainen if (ctx->failed)
ff52f5c52ee6a4c8a9c79964d32b5d0ff0ae92e6Timo Sirainen return -1;
ff52f5c52ee6a4c8a9c79964d32b5d0ff0ae92e6Timo Sirainen
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen if (_ctx->data.attach != NULL)
ff52f5c52ee6a4c8a9c79964d32b5d0ff0ae92e6Timo Sirainen return index_attachment_save_continue(_ctx);
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen if (index_storage_save_continue(_ctx, ctx->input,
ff52f5c52ee6a4c8a9c79964d32b5d0ff0ae92e6Timo Sirainen _ctx->dest_mail) < 0) {
ff52f5c52ee6a4c8a9c79964d32b5d0ff0ae92e6Timo Sirainen ctx->failed = TRUE;
ff52f5c52ee6a4c8a9c79964d32b5d0ff0ae92e6Timo Sirainen return -1;
ff52f5c52ee6a4c8a9c79964d32b5d0ff0ae92e6Timo Sirainen }
055389c58fa3915e12fb4e72ec86782ce77c5c72Timo Sirainen return 0;
ff52f5c52ee6a4c8a9c79964d32b5d0ff0ae92e6Timo Sirainen}
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainenvoid dbox_save_end(struct dbox_save_context *ctx)
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen{
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen struct mail_save_data *mdata = &ctx->ctx.data;
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen struct ostream *dbox_output = ctx->dbox_output;
8604a0675d3fa7986b872233fc7eb68068e9b80aTimo Sirainen
9e7a30991415f714b609f650105596371a58216dTimo Sirainen i_assert(mdata->output != NULL);
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen
ff52f5c52ee6a4c8a9c79964d32b5d0ff0ae92e6Timo Sirainen if (mdata->attach != NULL && !ctx->failed) {
ff52f5c52ee6a4c8a9c79964d32b5d0ff0ae92e6Timo Sirainen if (index_attachment_save_finish(&ctx->ctx) < 0)
ff52f5c52ee6a4c8a9c79964d32b5d0ff0ae92e6Timo Sirainen ctx->failed = TRUE;
ff52f5c52ee6a4c8a9c79964d32b5d0ff0ae92e6Timo Sirainen }
3954326e793bdef1e94e0ad781ed6cc7e48beebbTimo Sirainen if (o_stream_nfinish(mdata->output) < 0) {
3954326e793bdef1e94e0ad781ed6cc7e48beebbTimo Sirainen mail_storage_set_critical(ctx->ctx.transaction->box->storage,
1cfe369d1278a9e2e6cc2e46103db48c493e1f21Timo Sirainen "write(%s) failed: %s",
661998e2ccd772ad92a9d4a75cb712692a8c94b3Timo Sirainen o_stream_get_name(mdata->output),
661998e2ccd772ad92a9d4a75cb712692a8c94b3Timo Sirainen o_stream_get_error(mdata->output));
ff52f5c52ee6a4c8a9c79964d32b5d0ff0ae92e6Timo Sirainen ctx->failed = TRUE;
1cfe369d1278a9e2e6cc2e46103db48c493e1f21Timo Sirainen }
ff52f5c52ee6a4c8a9c79964d32b5d0ff0ae92e6Timo Sirainen if (mdata->output != dbox_output) {
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen /* e.g. zlib plugin had changed this */
ff52f5c52ee6a4c8a9c79964d32b5d0ff0ae92e6Timo Sirainen o_stream_ref(dbox_output);
ff52f5c52ee6a4c8a9c79964d32b5d0ff0ae92e6Timo Sirainen o_stream_destroy(&mdata->output);
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen mdata->output = dbox_output;
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen }
b5052fbfdbc2678cc8f12899afe55c998f43b740Timo Sirainen index_mail_cache_parse_deinit(ctx->ctx.dest_mail,
8604a0675d3fa7986b872233fc7eb68068e9b80aTimo Sirainen ctx->ctx.data.received_date,
8604a0675d3fa7986b872233fc7eb68068e9b80aTimo Sirainen !ctx->failed);
661998e2ccd772ad92a9d4a75cb712692a8c94b3Timo Sirainen}
ff52f5c52ee6a4c8a9c79964d32b5d0ff0ae92e6Timo Sirainen
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainenvoid dbox_save_write_metadata(struct mail_save_context *_ctx,
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen struct ostream *output, uoff_t output_msg_size,
ff52f5c52ee6a4c8a9c79964d32b5d0ff0ae92e6Timo Sirainen const char *orig_mailbox_name,
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen guid_128_t guid_128)
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen{
38fa43690a1cdc1917245f5f834ec40a89e83d91Timo Sirainen struct dbox_save_context *ctx = (struct dbox_save_context *)_ctx;
38fa43690a1cdc1917245f5f834ec40a89e83d91Timo Sirainen struct mail_save_data *mdata = &ctx->ctx.data;
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen struct dbox_metadata_header metadata_hdr;
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen const char *guid;
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen string_t *str;
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen uoff_t vsize;
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen i_zero(&metadata_hdr);
ff52f5c52ee6a4c8a9c79964d32b5d0ff0ae92e6Timo Sirainen memcpy(metadata_hdr.magic_post, DBOX_MAGIC_POST,
ff52f5c52ee6a4c8a9c79964d32b5d0ff0ae92e6Timo Sirainen sizeof(metadata_hdr.magic_post));
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen o_stream_nsend(output, &metadata_hdr, sizeof(metadata_hdr));
4210fac11e936f7edd6f3deecd1b23466534ce6aTimo Sirainen
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen str = t_str_new(256);
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,
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen (unsigned long long)ctx->input->v_offset);
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen }
661998e2ccd772ad92a9d4a75cb712692a8c94b3Timo Sirainen str_printfa(str, "%c%lx\n", DBOX_METADATA_RECEIVED_TIME,
56558eb46c396db9c7a0cfd89413b1c50b126b7eTimo Sirainen (unsigned long)mdata->received_date);
56558eb46c396db9c7a0cfd89413b1c50b126b7eTimo Sirainen if (mail_get_virtual_size(_ctx->dest_mail, &vsize) < 0)
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen i_unreached();
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen str_printfa(str, "%c%llx\n", DBOX_METADATA_VIRTUAL_SIZE,
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen (unsigned long long)vsize);
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen if (mdata->pop3_uidl != NULL) {
e080054d7df103a9b6be62a476cbee18261acf6cTimo Sirainen i_assert(strchr(mdata->pop3_uidl, '\n') == NULL);
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen str_printfa(str, "%c%s\n", DBOX_METADATA_POP3_UIDL,
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen mdata->pop3_uidl);
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen ctx->have_pop3_uidls = TRUE;
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen ctx->highest_pop3_uidl_seq =
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen I_MAX(ctx->highest_pop3_uidl_seq, ctx->seq);
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen }
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen if (mdata->pop3_order != 0) {
684cbcce30cc97340ee43240de5c0d236c917d29Timo Sirainen str_printfa(str, "%c%u\n", DBOX_METADATA_POP3_ORDER,
684cbcce30cc97340ee43240de5c0d236c917d29Timo Sirainen mdata->pop3_order);
684cbcce30cc97340ee43240de5c0d236c917d29Timo Sirainen ctx->have_pop3_orders = TRUE;
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen ctx->highest_pop3_uidl_seq =
661998e2ccd772ad92a9d4a75cb712692a8c94b3Timo Sirainen I_MAX(ctx->highest_pop3_uidl_seq, ctx->seq);
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen }
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen guid = mdata->guid;
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen if (guid != NULL)
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen mail_generate_guid_128_hash(guid, guid_128);
661998e2ccd772ad92a9d4a75cb712692a8c94b3Timo Sirainen else {
661998e2ccd772ad92a9d4a75cb712692a8c94b3Timo Sirainen guid_128_generate(guid_128);
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen guid = guid_128_to_string(guid_128);
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen }
3954326e793bdef1e94e0ad781ed6cc7e48beebbTimo Sirainen str_printfa(str, "%c%s\n", DBOX_METADATA_GUID, guid);
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen
c5d27aee77dad4b10d6dd915b9cb4c8757c0e988Timo Sirainen if (orig_mailbox_name != NULL &&
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen strchr(orig_mailbox_name, '\r') == NULL &&
3954326e793bdef1e94e0ad781ed6cc7e48beebbTimo Sirainen strchr(orig_mailbox_name, '\n') == NULL) {
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,
3954326e793bdef1e94e0ad781ed6cc7e48beebbTimo Sirainen orig_mailbox_name);
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen }
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen
c5d27aee77dad4b10d6dd915b9cb4c8757c0e988Timo Sirainen dbox_attachment_save_write_metadata(_ctx, str);
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen str_append_c(str, '\n');
3954326e793bdef1e94e0ad781ed6cc7e48beebbTimo Sirainen o_stream_nsend(output, str_data(str), str_len(str));
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen}
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen
d0fa29db7def334c142f46507a7d0c0bd6c70932Timo Sirainenvoid dbox_save_update_header_flags(struct dbox_save_context *ctx,
d0fa29db7def334c142f46507a7d0c0bd6c70932Timo Sirainen struct mail_index_view *sync_view,
8604a0675d3fa7986b872233fc7eb68068e9b80aTimo Sirainen uint32_t ext_id,
79b0f6ec3e5fde8f878bd85f4a1c3d669af66ebeTimo Sirainen unsigned int flags_offset)
d0fa29db7def334c142f46507a7d0c0bd6c70932Timo Sirainen{
d0fa29db7def334c142f46507a7d0c0bd6c70932Timo Sirainen const void *data;
d0fa29db7def334c142f46507a7d0c0bd6c70932Timo Sirainen size_t data_size;
d0fa29db7def334c142f46507a7d0c0bd6c70932Timo Sirainen uint8_t old_flags = 0, flags;
8604a0675d3fa7986b872233fc7eb68068e9b80aTimo Sirainen
cf1b9b686bca3e0de3dda1a95dab66ad4590d8efTimo Sirainen mail_index_get_header_ext(sync_view, ext_id, &data, &data_size);
d0fa29db7def334c142f46507a7d0c0bd6c70932Timo Sirainen if (flags_offset < data_size)
cf1b9b686bca3e0de3dda1a95dab66ad4590d8efTimo Sirainen old_flags = *((const uint8_t *)data + flags_offset);
8604a0675d3fa7986b872233fc7eb68068e9b80aTimo Sirainen else {
3954326e793bdef1e94e0ad781ed6cc7e48beebbTimo Sirainen /* grow old dbox header */
3954326e793bdef1e94e0ad781ed6cc7e48beebbTimo Sirainen mail_index_ext_resize_hdr(ctx->trans, ext_id, flags_offset+1);
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen }
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen
98da0024e7340e036f0aa9371e9400176df18ebfTimo Sirainen flags = old_flags;
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen if (ctx->have_pop3_uidls)
98da0024e7340e036f0aa9371e9400176df18ebfTimo Sirainen flags |= DBOX_INDEX_HEADER_FLAG_HAVE_POP3_UIDLS;
98da0024e7340e036f0aa9371e9400176df18ebfTimo Sirainen if (ctx->have_pop3_orders)
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen flags |= DBOX_INDEX_HEADER_FLAG_HAVE_POP3_ORDERS;
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen if (flags != old_flags) {
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen /* flags changed, update them */
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen mail_index_update_header_ext(ctx->trans, ext_id,
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen flags_offset, &flags, 1);
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen }
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen}
a7e46c05358b059aad2b90f01e271ba6732c5eeeTimo Sirainen