sdbox-save.c revision 9a02317c852face76737763fa6ec43b444688de5
02c335c23bf5fa225a467c19f2c063fb0dc7b8c3Timo Sirainen/* Copyright (c) 2007-2009 Dovecot authors, see the included COPYING file */
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen#include "lib.h"
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen#include "array.h"
735259c24eda6f272c8e21eab0f4d0c6bb022fd6Timo Sirainen#include "fdatasync-path.h"
735259c24eda6f272c8e21eab0f4d0c6bb022fd6Timo Sirainen#include "hex-binary.h"
735259c24eda6f272c8e21eab0f4d0c6bb022fd6Timo Sirainen#include "hex-dec.h"
735259c24eda6f272c8e21eab0f4d0c6bb022fd6Timo Sirainen#include "str.h"
fd16501d913e6e61a5cb9ae8f05b1fa7c19a1faeBaofeng Wang#include "istream.h"
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen#include "istream-crlf.h"
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen#include "ostream.h"
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen#include "write-full.h"
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen#include "index-mail.h"
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainen#include "mail-copy.h"
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen#include "dbox-save.h"
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen#include "sdbox-storage.h"
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen#include "sdbox-file.h"
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen#include "sdbox-sync.h"
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen#include <stdlib.h>
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainenstruct sdbox_save_context {
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen struct dbox_save_context ctx;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen struct sdbox_mailbox *mbox;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct sdbox_sync_context *sync_ctx;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct dbox_file_append_context *append_ctx;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
735259c24eda6f272c8e21eab0f4d0c6bb022fd6Timo Sirainen uint32_t first_saved_seq;
735259c24eda6f272c8e21eab0f4d0c6bb022fd6Timo Sirainen ARRAY_DEFINE(files, struct dbox_file *);
735259c24eda6f272c8e21eab0f4d0c6bb022fd6Timo Sirainen};
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenstruct dbox_file *
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainensdbox_save_file_get_file(struct mailbox_transaction_context *t, uint32_t seq)
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen{
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen struct sdbox_save_context *ctx =
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen (struct sdbox_save_context *)t->save_ctx;
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen struct dbox_file *const *files;
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen unsigned int count;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen i_assert(seq >= ctx->first_saved_seq);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
fd16501d913e6e61a5cb9ae8f05b1fa7c19a1faeBaofeng Wang files = array_get(&ctx->files, &count);
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen i_assert(count > 0);
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen return files[seq - ctx->first_saved_seq];
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen}
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenstruct mail_save_context *
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainensdbox_save_alloc(struct mailbox_transaction_context *t)
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen{
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen struct index_transaction_context *it =
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen (struct index_transaction_context *)t;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen struct sdbox_mailbox *mbox = (struct sdbox_mailbox *)t->box;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen struct sdbox_save_context *ctx =
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen (struct sdbox_save_context *)t->save_ctx;
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen i_assert((t->flags & MAILBOX_TRANSACTION_FLAG_EXTERNAL) != 0);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (ctx != NULL) {
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen /* use the existing allocated structure */
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen ctx->ctx.finished = FALSE;
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen return &ctx->ctx.ctx;
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen }
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen ctx = i_new(struct sdbox_save_context, 1);
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen ctx->ctx.ctx.transaction = t;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen ctx->ctx.trans = it->trans;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen ctx->mbox = mbox;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen i_array_init(&ctx->files, 32);
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen t->save_ctx = &ctx->ctx.ctx;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen return t->save_ctx;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen}
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainenint sdbox_save_begin(struct mail_save_context *_ctx, struct istream *input)
e7f8009c974ed6a6a5a0e88633d98fff2867fa92Timo Sirainen{
e7f8009c974ed6a6a5a0e88633d98fff2867fa92Timo Sirainen struct sdbox_save_context *ctx = (struct sdbox_save_context *)_ctx;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen struct dbox_file *file;
e7f8009c974ed6a6a5a0e88633d98fff2867fa92Timo Sirainen int ret;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen file = sdbox_file_init(ctx->mbox, 0);
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen ctx->append_ctx = dbox_file_append_init(file);
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen ret = dbox_file_get_append_stream(ctx->append_ctx,
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen &ctx->ctx.cur_output);
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen if (ret <= 0) {
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen i_assert(ret != 0);
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen dbox_file_append_rollback(&ctx->append_ctx);
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen dbox_file_unref(&file);
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen ctx->ctx.failed = TRUE;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen return -1;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen }
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen ctx->ctx.cur_file = file;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen dbox_save_begin(&ctx->ctx, input);
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen if (ctx->first_saved_seq == 0)
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen ctx->first_saved_seq = ctx->ctx.seq;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen array_append(&ctx->files, &file, 1);
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen return ctx->ctx.failed ? -1 : 0;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen}
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainenstatic int dbox_save_mail_write_metadata(struct dbox_save_context *ctx,
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen struct dbox_file *file)
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen{
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen struct dbox_message_header dbox_msg_hdr;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen uoff_t message_size;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen uint8_t guid_128[MAIL_GUID_128_SIZE];
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen i_assert(file->msg_header_size == sizeof(dbox_msg_hdr));
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen message_size = ctx->cur_output->offset -
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen file->msg_header_size - file->file_header_size;
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen dbox_save_write_metadata(&ctx->ctx, ctx->cur_output, NULL, guid_128);
0fd246126fece57712566c725d6353f255f5fcfaTimo Sirainen dbox_msg_header_fill(&dbox_msg_hdr, message_size);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (o_stream_pwrite(ctx->cur_output, &dbox_msg_hdr,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen sizeof(dbox_msg_hdr),
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen file->file_header_size) < 0) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen dbox_file_set_syscall_error(file, "pwrite()");
d0ef8bc2b961a68dd0f75662c2160bd296b9476bTimo Sirainen return -1;
f4616f1875297fb2f583d913c0f01b075bdecd5bTimo Sirainen }
f4616f1875297fb2f583d913c0f01b075bdecd5bTimo Sirainen return 0;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen}
f4616f1875297fb2f583d913c0f01b075bdecd5bTimo Sirainen
bc93929cdd9000ca560a5f42a27f50ab307f1efbTimo Sirainenstatic int dbox_save_finish_write(struct mail_save_context *_ctx)
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainen{
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainen struct sdbox_save_context *ctx = (struct sdbox_save_context *)_ctx;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen struct dbox_file *const *files;
bc93929cdd9000ca560a5f42a27f50ab307f1efbTimo Sirainen
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainen ctx->ctx.finished = TRUE;
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainen if (ctx->ctx.cur_output == NULL)
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainen return -1;
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainen
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainen index_mail_cache_parse_deinit(_ctx->dest_mail,
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainen _ctx->received_date, !ctx->ctx.failed);
bc93929cdd9000ca560a5f42a27f50ab307f1efbTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen files = array_idx_modifiable(&ctx->files, array_count(&ctx->files) - 1);
1537d20b852cbbf0d6971790b84e0cce5ca61307Timo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (!ctx->ctx.failed) T_BEGIN {
d54ab8987e482a8df250615b44f41fa040c38741Timo Sirainen if (dbox_save_mail_write_metadata(&ctx->ctx, *files) < 0)
bc93929cdd9000ca560a5f42a27f50ab307f1efbTimo Sirainen ctx->ctx.failed = TRUE;
bc93929cdd9000ca560a5f42a27f50ab307f1efbTimo Sirainen } T_END;
bc93929cdd9000ca560a5f42a27f50ab307f1efbTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (ctx->ctx.failed)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen dbox_file_append_rollback(&ctx->append_ctx);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen else if (dbox_file_append_commit(&ctx->append_ctx) < 0)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen ctx->ctx.failed = TRUE;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen i_stream_unref(&ctx->ctx.input);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen dbox_file_close(*files);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen ctx->ctx.cur_output = NULL;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return ctx->ctx.failed ? -1 : 0;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen}
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenint sdbox_save_finish(struct mail_save_context *ctx)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen{
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen int ret;
cbc8f9d71483a2cf71610f7e7e1f2dc9884bd556Baofeng Wang
cbc8f9d71483a2cf71610f7e7e1f2dc9884bd556Baofeng Wang ret = dbox_save_finish_write(ctx);
cbc8f9d71483a2cf71610f7e7e1f2dc9884bd556Baofeng Wang index_save_context_free(ctx);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return ret;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen}
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenvoid sdbox_save_cancel(struct mail_save_context *_ctx)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen{
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct dbox_save_context *ctx = (struct dbox_save_context *)_ctx;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
a693adf01b5f9256b273bee0b38efb69bc2b0182Timo Sirainen ctx->failed = TRUE;
a693adf01b5f9256b273bee0b38efb69bc2b0182Timo Sirainen (void)sdbox_save_finish(_ctx);
a693adf01b5f9256b273bee0b38efb69bc2b0182Timo Sirainen}
a693adf01b5f9256b273bee0b38efb69bc2b0182Timo Sirainen
a693adf01b5f9256b273bee0b38efb69bc2b0182Timo Sirainenstatic int dbox_save_assign_uids(struct sdbox_save_context *ctx,
a693adf01b5f9256b273bee0b38efb69bc2b0182Timo Sirainen const ARRAY_TYPE(seq_range) *uids)
a693adf01b5f9256b273bee0b38efb69bc2b0182Timo Sirainen{
a693adf01b5f9256b273bee0b38efb69bc2b0182Timo Sirainen struct dbox_file *const *files;
a693adf01b5f9256b273bee0b38efb69bc2b0182Timo Sirainen struct seq_range_iter iter;
a693adf01b5f9256b273bee0b38efb69bc2b0182Timo Sirainen unsigned int i, count, n = 0;
a693adf01b5f9256b273bee0b38efb69bc2b0182Timo Sirainen uint32_t uid;
a693adf01b5f9256b273bee0b38efb69bc2b0182Timo Sirainen bool ret;
a693adf01b5f9256b273bee0b38efb69bc2b0182Timo Sirainen
a693adf01b5f9256b273bee0b38efb69bc2b0182Timo Sirainen seq_range_array_iter_init(&iter, uids);
a693adf01b5f9256b273bee0b38efb69bc2b0182Timo Sirainen files = array_get(&ctx->files, &count);
a693adf01b5f9256b273bee0b38efb69bc2b0182Timo Sirainen for (i = 0; i < count; i++) {
a693adf01b5f9256b273bee0b38efb69bc2b0182Timo Sirainen struct sdbox_file *sfile = (struct sdbox_file *)files[i];
a693adf01b5f9256b273bee0b38efb69bc2b0182Timo Sirainen
a693adf01b5f9256b273bee0b38efb69bc2b0182Timo Sirainen ret = seq_range_array_iter_nth(&iter, n++, &uid);
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen i_assert(ret);
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen if (sdbox_file_assign_uid(sfile, uid) < 0)
c4b376dd6e0c423006d7ac83a39253bcaf8e7c47Timo Sirainen return -1;
eef4ba0cc3e78f8c26804c1c9251a76580a41f0cTimo Sirainen }
eef4ba0cc3e78f8c26804c1c9251a76580a41f0cTimo Sirainen i_assert(!seq_range_array_iter_nth(&iter, n, &uid));
eef4ba0cc3e78f8c26804c1c9251a76580a41f0cTimo Sirainen return 0;
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen}
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainenstatic void dbox_save_unref_files(struct sdbox_save_context *ctx)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen{
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen struct mail_storage *storage = &ctx->mbox->storage->storage.storage;
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen struct dbox_file **files;
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen unsigned int i, count;
eef4ba0cc3e78f8c26804c1c9251a76580a41f0cTimo Sirainen
eef4ba0cc3e78f8c26804c1c9251a76580a41f0cTimo Sirainen files = array_get_modifiable(&ctx->files, &count);
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen for (i = 0; i < count; i++) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (ctx->ctx.failed) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (unlink(files[i]->cur_path) < 0) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen mail_storage_set_critical(storage,
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen "unlink(%s) failed: %m",
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen files[i]->cur_path);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen }
bc93929cdd9000ca560a5f42a27f50ab307f1efbTimo Sirainen }
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen dbox_file_unref(&files[i]);
a5e89374cb2fb2cad575fee6c3b33a9487ab9b3aTimo Sirainen }
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen array_free(&ctx->files);
aa41b2e17912d6cad3151babea6a85dd88539d28Timo Sirainen}
0211537cbf53ad17348408103fdb0c06de56ed5eTimo Sirainen
71748cca1bacd74451fd228db5536828bdfeb190Baofeng Wangint sdbox_transaction_save_commit_pre(struct mail_save_context *_ctx)
71748cca1bacd74451fd228db5536828bdfeb190Baofeng Wang{
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct sdbox_save_context *ctx = (struct sdbox_save_context *)_ctx;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct mailbox_transaction_context *_t = _ctx->transaction;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen const struct mail_index_header *hdr;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen i_assert(ctx->ctx.finished);
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen
a693adf01b5f9256b273bee0b38efb69bc2b0182Timo Sirainen if (array_count(&ctx->files) == 0)
a693adf01b5f9256b273bee0b38efb69bc2b0182Timo Sirainen return 0;
a693adf01b5f9256b273bee0b38efb69bc2b0182Timo Sirainen
71748cca1bacd74451fd228db5536828bdfeb190Baofeng Wang if (sdbox_sync_begin(ctx->mbox, SDBOX_SYNC_FLAG_FORCE |
71748cca1bacd74451fd228db5536828bdfeb190Baofeng Wang SDBOX_SYNC_FLAG_FSYNC, &ctx->sync_ctx) < 0) {
117fb8c00336dc54bab9cfa547249df7a4970611Timo Sirainen sdbox_transaction_save_rollback(_ctx);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return -1;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen }
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen /* assign UIDs for new messages */
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen hdr = mail_index_get_header(ctx->sync_ctx->sync_view);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen mail_index_append_finish_uids(ctx->ctx.trans, hdr->next_uid,
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen &_t->changes->saved_uids);
0211537cbf53ad17348408103fdb0c06de56ed5eTimo Sirainen if (dbox_save_assign_uids(ctx, &_t->changes->saved_uids) < 0) {
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen sdbox_transaction_save_rollback(_ctx);
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen return -1;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen }
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen if (ctx->ctx.mail != NULL)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen mail_free(&ctx->ctx.mail);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen _t->changes->uid_validity = hdr->uid_validity;
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen return 0;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen}
bc93929cdd9000ca560a5f42a27f50ab307f1efbTimo Sirainen
6f368f8571092c5ad94357752cfea34f69ef66d7Timo Sirainenvoid sdbox_transaction_save_commit_post(struct mail_save_context *_ctx)
6f368f8571092c5ad94357752cfea34f69ef66d7Timo Sirainen{
6f368f8571092c5ad94357752cfea34f69ef66d7Timo Sirainen struct sdbox_save_context *ctx = (struct sdbox_save_context *)_ctx;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
6f368f8571092c5ad94357752cfea34f69ef66d7Timo Sirainen _ctx->transaction = NULL; /* transaction is already freed */
6f368f8571092c5ad94357752cfea34f69ef66d7Timo Sirainen
6f368f8571092c5ad94357752cfea34f69ef66d7Timo Sirainen if (array_count(&ctx->files) == 0) {
6f368f8571092c5ad94357752cfea34f69ef66d7Timo Sirainen sdbox_transaction_save_rollback(_ctx);
6f368f8571092c5ad94357752cfea34f69ef66d7Timo Sirainen return;
6f368f8571092c5ad94357752cfea34f69ef66d7Timo Sirainen }
6f368f8571092c5ad94357752cfea34f69ef66d7Timo Sirainen
6f368f8571092c5ad94357752cfea34f69ef66d7Timo Sirainen if (sdbox_sync_finish(&ctx->sync_ctx, TRUE) < 0)
6f368f8571092c5ad94357752cfea34f69ef66d7Timo Sirainen ctx->ctx.failed = TRUE;
6f368f8571092c5ad94357752cfea34f69ef66d7Timo Sirainen
6f368f8571092c5ad94357752cfea34f69ef66d7Timo Sirainen if (!ctx->mbox->storage->storage.storage.set->fsync_disable) {
6f368f8571092c5ad94357752cfea34f69ef66d7Timo Sirainen if (fdatasync_path(ctx->mbox->ibox.box.path) < 0) {
6f368f8571092c5ad94357752cfea34f69ef66d7Timo Sirainen i_error("fdatasync_path(%s) failed: %m",
6f368f8571092c5ad94357752cfea34f69ef66d7Timo Sirainen ctx->mbox->ibox.box.path);
b66d803de86bfb411165b3465b0d9ef64ecfe2a1Timo Sirainen }
b66d803de86bfb411165b3465b0d9ef64ecfe2a1Timo Sirainen }
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen sdbox_transaction_save_rollback(_ctx);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen}
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainenvoid sdbox_transaction_save_rollback(struct mail_save_context *_ctx)
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen{
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen struct sdbox_save_context *ctx = (struct sdbox_save_context *)_ctx;
437a8b0fe254057b0c1f1723d689bafa91cae2abTimo Sirainen
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen if (!ctx->ctx.finished)
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen sdbox_save_cancel(_ctx);
6d41944c73171cdb64b0a00bff368d212452e924Timo Sirainen dbox_save_unref_files(ctx);
04f70d9dc154761eb262f485415f27ed0345ece4Timo Sirainen
04f70d9dc154761eb262f485415f27ed0345ece4Timo Sirainen if (ctx->sync_ctx != NULL)
04f70d9dc154761eb262f485415f27ed0345ece4Timo Sirainen (void)sdbox_sync_finish(&ctx->sync_ctx, FALSE);
04f70d9dc154761eb262f485415f27ed0345ece4Timo Sirainen
04f70d9dc154761eb262f485415f27ed0345ece4Timo Sirainen if (ctx->ctx.mail != NULL)
04f70d9dc154761eb262f485415f27ed0345ece4Timo Sirainen mail_free(&ctx->ctx.mail);
04f70d9dc154761eb262f485415f27ed0345ece4Timo Sirainen i_free(ctx);
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen}
2e5170d1dce33cf055cfc2f6fa4b4a61df35d1c5Timo Sirainen
6f368f8571092c5ad94357752cfea34f69ef66d7Timo Sirainenint sdbox_copy(struct mail_save_context *_ctx, struct mail *mail)
6f368f8571092c5ad94357752cfea34f69ef66d7Timo Sirainen{
6f368f8571092c5ad94357752cfea34f69ef66d7Timo Sirainen struct dbox_save_context *ctx = (struct dbox_save_context *)_ctx;
6f368f8571092c5ad94357752cfea34f69ef66d7Timo Sirainen
6f368f8571092c5ad94357752cfea34f69ef66d7Timo Sirainen /* FIXME: use hard linking */
6f368f8571092c5ad94357752cfea34f69ef66d7Timo Sirainen
6f368f8571092c5ad94357752cfea34f69ef66d7Timo Sirainen ctx->finished = TRUE;
6f368f8571092c5ad94357752cfea34f69ef66d7Timo Sirainen return mail_storage_copy(_ctx, mail);
6f368f8571092c5ad94357752cfea34f69ef66d7Timo Sirainen}
6d41944c73171cdb64b0a00bff368d212452e924Timo Sirainen