sdbox-save.c revision 9a790c932a9e5d52939c5d9e56e8b0ef02166d43
5a580c3a38ced62d4bcc95b8ac7c4f2935b5d294Timo Sirainen/* Copyright (c) 2007-2012 Dovecot authors, see the included COPYING file */
0001f76bf725c5cf403bade8556f142dd43144eeTimo Sirainensdbox_save_file_get_file(struct mailbox_transaction_context *t, uint32_t seq)
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen unsigned int count;
e237ebeb97f42950eef3efd0d3db85590160d5fbTimo Sirainensdbox_save_alloc(struct mailbox_transaction_context *t)
e237ebeb97f42950eef3efd0d3db85590160d5fbTimo Sirainen struct sdbox_mailbox *mbox = (struct sdbox_mailbox *)t->box;
e237ebeb97f42950eef3efd0d3db85590160d5fbTimo Sirainen i_assert((t->flags & MAILBOX_TRANSACTION_FLAG_EXTERNAL) != 0);
c18ff860dc22960fd37c272d929f889c7939a2c8Timo Sirainen /* use the existing allocated structure */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenvoid sdbox_save_add_file(struct mail_save_context *_ctx, struct dbox_file *file)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct sdbox_save_context *ctx = (struct sdbox_save_context *)_ctx;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen unsigned int count;
e237ebeb97f42950eef3efd0d3db85590160d5fbTimo Sirainen /* a plugin may leave a previously saved file open.
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen we'll close it here to avoid eating too many fds. */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenint sdbox_save_begin(struct mail_save_context *_ctx, struct istream *input)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct sdbox_save_context *ctx = (struct sdbox_save_context *)_ctx;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen ctx->append_ctx = dbox_file_append_init(file);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen ret = dbox_file_get_append_stream(ctx->append_ctx,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstatic int dbox_save_mail_write_metadata(struct dbox_save_context *ctx,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct sdbox_file *sfile = (struct sdbox_file *)file;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen const ARRAY_TYPE(mail_attachment_extref) *extrefs_arr;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen unsigned int i, count;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen i_assert(file->msg_header_size == sizeof(dbox_msg_hdr));
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen file->msg_header_size - file->file_header_size;
5e702db5540b2303e25554dee21bbf35a4813381Timo Sirainen dbox_save_write_metadata(&ctx->ctx, ctx->dbox_output,
5e702db5540b2303e25554dee21bbf35a4813381Timo Sirainen dbox_msg_header_fill(&dbox_msg_hdr, message_size);
5e702db5540b2303e25554dee21bbf35a4813381Timo Sirainen if (o_stream_pwrite(ctx->dbox_output, &dbox_msg_hdr,
5e702db5540b2303e25554dee21bbf35a4813381Timo Sirainen dbox_file_set_syscall_error(file, "pwrite()");
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen /* remember the attachment paths until commit time */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen extrefs_arr = index_attachment_save_get_extrefs(&ctx->ctx);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen pool_alloconly_create("sdbox attachment paths", 512);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen for (i = 0; i < count; i++) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen const char *path = p_strdup(sfile->attachment_pool,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen array_append(&sfile->attachment_paths, &path, 1);
de62ce819d59a529530da4b57be1b8d6dad13d6bTimo Sirainenstatic int dbox_save_finish_write(struct mail_save_context *_ctx)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct sdbox_save_context *ctx = (struct sdbox_save_context *)_ctx;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen /* we can't change ctime, but we can add the date to cache */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct index_mail *mail = (struct index_mail *)_ctx->dest_mail;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen index_mail_cache_add(mail, MAIL_CACHE_SAVE_DATE, &t, sizeof(t));
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen files = array_idx_modifiable(&ctx->files, array_count(&ctx->files) - 1);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (dbox_save_mail_write_metadata(&ctx->ctx, *files) < 0)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mail_index_expunge(ctx->ctx.trans, ctx->ctx.seq);
e6440616c02bb1404dc35debf45d9741260c7831Timo Sirainen array_delete(&ctx->files, array_count(&ctx->files) - 1, 1);
e6440616c02bb1404dc35debf45d9741260c7831Timo Sirainen if (dbox_file_append_commit(&ctx->append_ctx) < 0)
06eb8c1371aa06478d8840b1373cab7c2752d5edTimo Sirainenint sdbox_save_finish(struct mail_save_context *ctx)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenvoid sdbox_save_cancel(struct mail_save_context *_ctx)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct dbox_save_context *ctx = (struct dbox_save_context *)_ctx;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstatic int dbox_save_assign_uids(struct sdbox_save_context *ctx,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen unsigned int i, count, n = 0;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen for (i = 0; i < count; i++) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct sdbox_file *sfile = (struct sdbox_file *)files[i];
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen ret = seq_range_array_iter_nth(&iter, n++, &uid);
5833a4972491fdb7b78eac2280f31dc4b9fa2bb7Timo Sirainen i_assert(!seq_range_array_iter_nth(&iter, n, &uid));
5833a4972491fdb7b78eac2280f31dc4b9fa2bb7Timo Sirainenstatic void dbox_save_unref_files(struct sdbox_save_context *ctx)
5833a4972491fdb7b78eac2280f31dc4b9fa2bb7Timo Sirainen unsigned int i, count;
5833a4972491fdb7b78eac2280f31dc4b9fa2bb7Timo Sirainen files = array_get_modifiable(&ctx->files, &count);
5833a4972491fdb7b78eac2280f31dc4b9fa2bb7Timo Sirainen for (i = 0; i < count; i++) {
5833a4972491fdb7b78eac2280f31dc4b9fa2bb7Timo Sirainenint sdbox_transaction_save_commit_pre(struct mail_save_context *_ctx)
5833a4972491fdb7b78eac2280f31dc4b9fa2bb7Timo Sirainen struct sdbox_save_context *ctx = (struct sdbox_save_context *)_ctx;
5833a4972491fdb7b78eac2280f31dc4b9fa2bb7Timo Sirainen struct mailbox_transaction_context *_t = _ctx->transaction;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen /* the mail must be freed in the commit_pre() */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (sdbox_sync_begin(ctx->mbox, SDBOX_SYNC_FLAG_FORCE |
ddedc8b77c5bccc8d224ab5f8716d9874f5d8512Timo Sirainen /* assign UIDs for new messages */
ddedc8b77c5bccc8d224ab5f8716d9874f5d8512Timo Sirainen hdr = mail_index_get_header(ctx->sync_ctx->sync_view);
ddedc8b77c5bccc8d224ab5f8716d9874f5d8512Timo Sirainen mail_index_append_finish_uids(ctx->ctx.trans, hdr->next_uid,
56aa9083e1742d0083885aaf0c5b8581577731aeTimo Sirainen if (dbox_save_assign_uids(ctx, &_t->changes->saved_uids) < 0) {
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen _t->changes->uid_validity = hdr->uid_validity;
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainenvoid sdbox_transaction_save_commit_post(struct mail_save_context *_ctx,
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen struct mail_index_transaction_commit_result *result)
08a8b3de61139ba02371afc8240ac85be0e8b17cTimo Sirainen struct sdbox_save_context *ctx = (struct sdbox_save_context *)_ctx;
3c40cf45bb10548bf434aea0fca32b99acc99a35Timo Sirainen struct mail_storage *storage = _ctx->transaction->box->storage;
3c40cf45bb10548bf434aea0fca32b99acc99a35Timo Sirainen _ctx->transaction = NULL; /* transaction is already freed */
3c40cf45bb10548bf434aea0fca32b99acc99a35Timo Sirainen mail_index_sync_set_commit_result(ctx->sync_ctx->index_sync_ctx,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (sdbox_sync_finish(&ctx->sync_ctx, TRUE) < 0)
fb5efc6ed69da679d9da31ef62daa7024de18212Timo Sirainen if (storage->set->parsed_fsync_mode != FSYNC_MODE_NEVER) {
5833a4972491fdb7b78eac2280f31dc4b9fa2bb7Timo Sirainen const char *box_path = mailbox_get_path(&ctx->mbox->box);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenvoid sdbox_transaction_save_rollback(struct mail_save_context *_ctx)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen struct sdbox_save_context *ctx = (struct sdbox_save_context *)_ctx;