return mail_set_aborted(_mail);
do {
- if (mail->open_file == NULL) {
+ if (mail->open_file != NULL) {
+ /* already open */
+ } else if (_mail->uid != 0) {
if (dbox_mail_lookup(mbox, mbox->ibox.view, _mail->seq,
&mail->map_uid) < 0)
return -1;
if (dbox_mail_open_init(mail) < 0)
return -1;
+ } else {
+ /* mail is being saved in this transaction */
+ mail->open_file =
+ dbox_save_file_get_file(_mail->transaction,
+ _mail->seq,
+ &mail->offset);
+ mail->open_file->refcount++;
+ break;
}
if (!dbox_file_is_open(mail->open_file))
unsigned int finished:1;
};
+struct dbox_file *
+dbox_save_file_get_file(struct mailbox_transaction_context *t,
+ uint32_t seq, uoff_t *offset_r)
+{
+ struct dbox_save_context *ctx = (struct dbox_save_context *)t->save_ctx;
+ const struct dbox_save_mail *mails, *mail;
+ unsigned int count;
+
+ mails = array_get(&ctx->mails, &count);
+ i_assert(count > 0);
+ i_assert(seq >= mails[0].seq);
+
+ mail = &mails[mails[0].seq - seq];
+ i_assert(mail->seq == seq);
+
+ if (o_stream_flush(mail->file->output) < 0) {
+ dbox_file_set_syscall_error(mail->file, "write()");
+ ctx->failed = TRUE;
+ }
+
+ *offset_r = mail->append_offset;
+ return mail->file;
+}
+
struct mail_save_context *
dbox_save_alloc(struct mailbox_transaction_context *t)
{
ctx->failed = TRUE;
} T_END;
+ if (o_stream_flush(ctx->cur_output) < 0) {
+ dbox_file_set_syscall_error(save_mail->file, "write()");
+ ctx->failed = TRUE;
+ }
+
o_stream_unref(&ctx->cur_output);
i_stream_unref(&ctx->input);
int dbox_save_finish(struct mail_save_context *ctx);
void dbox_save_cancel(struct mail_save_context *ctx);
+struct dbox_file *
+dbox_save_file_get_file(struct mailbox_transaction_context *t,
+ uint32_t seq, uoff_t *offset_r);
+
int dbox_transaction_save_commit_pre(struct mail_save_context *ctx);
void dbox_transaction_save_commit_post(struct mail_save_context *ctx);
void dbox_transaction_save_rollback(struct mail_save_context *ctx);