dbox-save.c revision 9865d9e7c5713e41db939222ed9c0225a11fb99e
76b43e4417bab52e913da39b5f5bc2a130d3f149Timo Sirainen/* Copyright (c) 2007-2013 Dovecot authors, see the included COPYING file */
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen#include "lib.h"
0fd246126fece57712566c725d6353f255f5fcfaTimo Sirainen#include "istream.h"
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen#include "istream-crlf.h"
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen#include "ostream.h"
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen#include "str.h"
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen#include "hex-binary.h"
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen#include "index-mail.h"
b8835b8a21c617ceb82ddc5a176243faf36aa8f7Timo Sirainen#include "dbox-attachment.h"
c4b376dd6e0c423006d7ac83a39253bcaf8e7c47Timo Sirainen#include "dbox-file.h"
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen#include "dbox-save.h"
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainenvoid dbox_save_add_to_index(struct dbox_save_context *ctx)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen{
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen struct mail_save_data *mdata = &ctx->ctx.data;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen enum mail_flags save_flags;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen save_flags = mdata->flags & ~MAIL_RECENT;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen mail_index_append(ctx->trans, mdata->uid, &ctx->seq);
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen mail_index_update_flags(ctx->trans, ctx->seq, MODIFY_REPLACE,
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen save_flags);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen if (mdata->keywords != NULL) {
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen mail_index_update_keywords(ctx->trans, ctx->seq,
0fd246126fece57712566c725d6353f255f5fcfaTimo Sirainen MODIFY_REPLACE, mdata->keywords);
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen }
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen if (mdata->min_modseq != 0) {
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen mail_index_update_modseq(ctx->trans, ctx->seq,
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen mdata->min_modseq);
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen }
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen}
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainenvoid dbox_save_begin(struct dbox_save_context *ctx, struct istream *input)
c4b376dd6e0c423006d7ac83a39253bcaf8e7c47Timo Sirainen{
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen struct mail_save_context *_ctx = &ctx->ctx;
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen struct mail_storage *_storage = _ctx->transaction->box->storage;
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen struct dbox_storage *storage = (struct dbox_storage *)_storage;
0fd246126fece57712566c725d6353f255f5fcfaTimo Sirainen struct dbox_message_header dbox_msg_hdr;
0fd246126fece57712566c725d6353f255f5fcfaTimo Sirainen struct istream *crlf_input;
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen dbox_save_add_to_index(ctx);
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen if (_ctx->dest_mail == NULL) {
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen if (ctx->mail == NULL)
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen ctx->mail = mail_alloc(_ctx->transaction, 0, NULL);
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen _ctx->dest_mail = ctx->mail;
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen }
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen mail_set_seq_saving(_ctx->dest_mail, ctx->seq);
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen crlf_input = i_stream_create_lf(input);
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen ctx->input = index_mail_cache_parse_init(_ctx->dest_mail, crlf_input);
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen i_stream_unref(&crlf_input);
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen /* write a dummy header. it'll get rewritten when we're finished */
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen memset(&dbox_msg_hdr, 0, sizeof(dbox_msg_hdr));
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen o_stream_cork(ctx->dbox_output);
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen if (o_stream_send(ctx->dbox_output, &dbox_msg_hdr,
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen sizeof(dbox_msg_hdr)) < 0) {
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen mail_storage_set_critical(_storage, "write(%s) failed: %m",
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen o_stream_get_name(ctx->dbox_output));
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen ctx->failed = TRUE;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen }
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen _ctx->data.output = ctx->dbox_output;
94f90df2cfb7587bb5af432b2ba065d1c364e1f7Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen if (_ctx->data.received_date == (time_t)-1)
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen _ctx->data.received_date = ioloop_time;
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen index_attachment_save_begin(_ctx, storage->attachment_fs, ctx->input);
eb0ede66120bb63c0212bad69e67efca1eb47324Timo Sirainen}
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainenint dbox_save_continue(struct mail_save_context *_ctx)
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen{
94f90df2cfb7587bb5af432b2ba065d1c364e1f7Timo Sirainen struct dbox_save_context *ctx = (struct dbox_save_context *)_ctx;
94f90df2cfb7587bb5af432b2ba065d1c364e1f7Timo Sirainen struct mail_storage *storage = _ctx->transaction->box->storage;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen if (ctx->failed)
c37e5edd83ff696d396131f7147ef971cf678911Timo Sirainen return -1;
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen if (_ctx->data.attach != NULL)
38a4c09de37bc2ebdc38427a2b958c46dfdcffb1Timo Sirainen return index_attachment_save_continue(_ctx);
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen do {
c37e5edd83ff696d396131f7147ef971cf678911Timo Sirainen if (o_stream_send_istream(_ctx->data.output, ctx->input) < 0) {
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen if (!mail_storage_set_error_from_errno(storage)) {
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen mail_storage_set_critical(storage,
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen "write(%s) failed: %m",
38a4c09de37bc2ebdc38427a2b958c46dfdcffb1Timo Sirainen o_stream_get_name(_ctx->data.output));
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen }
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen ctx->failed = TRUE;
38a4c09de37bc2ebdc38427a2b958c46dfdcffb1Timo Sirainen return -1;
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen }
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen index_mail_cache_parse_continue(_ctx->dest_mail);
38a4c09de37bc2ebdc38427a2b958c46dfdcffb1Timo Sirainen
38a4c09de37bc2ebdc38427a2b958c46dfdcffb1Timo Sirainen /* both tee input readers may consume data from our primary
38a4c09de37bc2ebdc38427a2b958c46dfdcffb1Timo Sirainen input stream. we'll have to make sure we don't return with
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen one of the streams still having data in them. */
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen } while (i_stream_read(ctx->input) > 0);
38a4c09de37bc2ebdc38427a2b958c46dfdcffb1Timo Sirainen return 0;
38a4c09de37bc2ebdc38427a2b958c46dfdcffb1Timo Sirainen}
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainenvoid dbox_save_end(struct dbox_save_context *ctx)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen{
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen struct mail_save_data *mdata = &ctx->ctx.data;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen struct ostream *dbox_output = ctx->dbox_output;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen if (mdata->attach != NULL && !ctx->failed) {
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen if (index_attachment_save_finish(&ctx->ctx) < 0)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen ctx->failed = TRUE;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen }
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen if (o_stream_nfinish(mdata->output) < 0) {
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen mail_storage_set_critical(ctx->ctx.transaction->box->storage,
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen "write(%s) failed: %m",
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen o_stream_get_name(mdata->output));
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen ctx->failed = TRUE;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen }
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen if (mdata->output != dbox_output) {
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen if (mdata->output != NULL) {
992118a50af940482b6cf884a89be56d7015580aTimo Sirainen /* e.g. zlib plugin had changed this */
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen o_stream_ref(dbox_output);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen o_stream_destroy(&mdata->output);
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen mdata->output = dbox_output;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen } else {
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen i_assert(ctx->failed);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen }
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen }
38a4c09de37bc2ebdc38427a2b958c46dfdcffb1Timo Sirainen index_mail_cache_parse_deinit(ctx->ctx.dest_mail,
043c8a96a035379bcba04f487d58457beefdfcaaTimo Sirainen ctx->ctx.data.received_date,
043c8a96a035379bcba04f487d58457beefdfcaaTimo Sirainen !ctx->failed);
043c8a96a035379bcba04f487d58457beefdfcaaTimo Sirainen}
e1b83f64e62cc3e8967c75fcc3f9b5dbb243d3b3Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainenvoid dbox_save_write_metadata(struct mail_save_context *_ctx,
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen struct ostream *output, uoff_t output_msg_size,
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen const char *orig_mailbox_name,
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen guid_128_t guid_128)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen{
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen struct dbox_save_context *ctx = (struct dbox_save_context *)_ctx;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen struct mail_save_data *mdata = &ctx->ctx.data;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen struct dbox_metadata_header metadata_hdr;
38a4c09de37bc2ebdc38427a2b958c46dfdcffb1Timo Sirainen const char *guid;
38a4c09de37bc2ebdc38427a2b958c46dfdcffb1Timo Sirainen string_t *str;
38a4c09de37bc2ebdc38427a2b958c46dfdcffb1Timo Sirainen uoff_t vsize;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
38a4c09de37bc2ebdc38427a2b958c46dfdcffb1Timo Sirainen memset(&metadata_hdr, 0, sizeof(metadata_hdr));
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen memcpy(metadata_hdr.magic_post, DBOX_MAGIC_POST,
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen sizeof(metadata_hdr.magic_post));
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen o_stream_nsend(output, &metadata_hdr, sizeof(metadata_hdr));
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen str = t_str_new(256);
38a4c09de37bc2ebdc38427a2b958c46dfdcffb1Timo Sirainen if (output_msg_size != ctx->input->v_offset) {
38a4c09de37bc2ebdc38427a2b958c46dfdcffb1Timo Sirainen /* a plugin changed the data written to disk, so the
38a4c09de37bc2ebdc38427a2b958c46dfdcffb1Timo Sirainen "message size" dbox header doesn't contain the actual
38a4c09de37bc2ebdc38427a2b958c46dfdcffb1Timo Sirainen "physical" message size. we need to save it as a
c37e5edd83ff696d396131f7147ef971cf678911Timo Sirainen separate metadata header. */
0f55802e8fdd95ae4290da6da077819209b71f70Timo Sirainen str_printfa(str, "%c%llx\n", DBOX_METADATA_PHYSICAL_SIZE,
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen (unsigned long long)ctx->input->v_offset);
20b136f04257b0ba338e49f31a999c0d4b243647Timo Sirainen }
20b136f04257b0ba338e49f31a999c0d4b243647Timo Sirainen str_printfa(str, "%c%lx\n", DBOX_METADATA_RECEIVED_TIME,
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen (unsigned long)mdata->received_date);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen if (mail_get_virtual_size(_ctx->dest_mail, &vsize) < 0)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen i_unreached();
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen str_printfa(str, "%c%llx\n", DBOX_METADATA_VIRTUAL_SIZE,
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen (unsigned long long)vsize);
992118a50af940482b6cf884a89be56d7015580aTimo Sirainen if (mdata->pop3_uidl != NULL) {
992118a50af940482b6cf884a89be56d7015580aTimo Sirainen i_assert(strchr(mdata->pop3_uidl, '\n') == NULL);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen str_printfa(str, "%c%s\n", DBOX_METADATA_POP3_UIDL,
c37e5edd83ff696d396131f7147ef971cf678911Timo Sirainen mdata->pop3_uidl);
c37e5edd83ff696d396131f7147ef971cf678911Timo Sirainen ctx->have_pop3_uidls = TRUE;
c37e5edd83ff696d396131f7147ef971cf678911Timo Sirainen }
c37e5edd83ff696d396131f7147ef971cf678911Timo Sirainen if (mdata->pop3_order != 0) {
c37e5edd83ff696d396131f7147ef971cf678911Timo Sirainen str_printfa(str, "%c%u\n", DBOX_METADATA_POP3_ORDER,
c37e5edd83ff696d396131f7147ef971cf678911Timo Sirainen mdata->pop3_order);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen ctx->have_pop3_orders = TRUE;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen }
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen guid = mdata->guid;
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen if (guid != NULL)
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen mail_generate_guid_128_hash(guid, guid_128);
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen else {
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen guid_128_generate(guid_128);
c4b376dd6e0c423006d7ac83a39253bcaf8e7c47Timo Sirainen guid = guid_128_to_string(guid_128);
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen }
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen str_printfa(str, "%c%s\n", DBOX_METADATA_GUID, guid);
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen
f210ec6b25f80d06419921e9231465bb114ee971Timo Sirainen if (orig_mailbox_name != NULL &&
e22b857e838fe118de3f78513aad6a3c6f4306b3Timo Sirainen strchr(orig_mailbox_name, '\r') == NULL &&
e22b857e838fe118de3f78513aad6a3c6f4306b3Timo Sirainen strchr(orig_mailbox_name, '\n') == NULL) {
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen /* save the original mailbox name so if mailbox indexes get
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen corrupted we can place at least some (hopefully most) of
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen the messages to correct mailboxes. */
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen str_printfa(str, "%c%s\n", DBOX_METADATA_ORIG_MAILBOX,
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen orig_mailbox_name);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen }
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen dbox_attachment_save_write_metadata(_ctx, str);
48566ca412a7cf3b42512fd0ec112744778e5da0Timo Sirainen
c06cd6539a3dbd68eb546464076187be6bc4290fTimo Sirainen str_append_c(str, '\n');
c06cd6539a3dbd68eb546464076187be6bc4290fTimo Sirainen o_stream_nsend(output, str_data(str), str_len(str));
5afa8e2edf4f313cd56e5909f92f39c3b5b7b4d3Timo Sirainen}
5afa8e2edf4f313cd56e5909f92f39c3b5b7b4d3Timo Sirainen
1176124297af5c56e932c0863c6637ff21d8a0efTimo Sirainenvoid dbox_save_update_header_flags(struct dbox_save_context *ctx,
c06cd6539a3dbd68eb546464076187be6bc4290fTimo Sirainen struct mail_index_view *sync_view,
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen uint32_t ext_id,
c06cd6539a3dbd68eb546464076187be6bc4290fTimo Sirainen unsigned int flags_offset)
c06cd6539a3dbd68eb546464076187be6bc4290fTimo Sirainen{
c06cd6539a3dbd68eb546464076187be6bc4290fTimo Sirainen const void *data;
c06cd6539a3dbd68eb546464076187be6bc4290fTimo Sirainen size_t data_size;
c4b376dd6e0c423006d7ac83a39253bcaf8e7c47Timo Sirainen uint8_t old_flags = 0, flags;
c4b376dd6e0c423006d7ac83a39253bcaf8e7c47Timo Sirainen
c4b376dd6e0c423006d7ac83a39253bcaf8e7c47Timo Sirainen mail_index_get_header_ext(sync_view, ext_id, &data, &data_size);
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen if (flags_offset < data_size)
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen old_flags = *((const uint8_t *)data + flags_offset);
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen else {
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen /* grow old dbox header */
c4b376dd6e0c423006d7ac83a39253bcaf8e7c47Timo Sirainen mail_index_ext_resize_hdr(ctx->trans, ext_id, flags_offset+1);
d54ab8987e482a8df250615b44f41fa040c38741Timo Sirainen }
c4b376dd6e0c423006d7ac83a39253bcaf8e7c47Timo Sirainen
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen flags = old_flags;
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen if (ctx->have_pop3_uidls)
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen flags |= DBOX_INDEX_HEADER_FLAG_HAVE_POP3_UIDLS;
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen if (ctx->have_pop3_orders)
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen flags |= DBOX_INDEX_HEADER_FLAG_HAVE_POP3_ORDERS;
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen if (flags != old_flags) {
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen /* flags changed, update them */
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen mail_index_update_header_ext(ctx->trans, ext_id,
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen flags_offset, &flags, 1);
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen }
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen}
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen