void dbox_save_begin(struct dbox_save_context *ctx, struct istream *input) { struct mail_save_context *_ctx = &ctx->ctx; struct mail_storage *_storage = _ctx->transaction->box->storage; struct dbox_storage *storage = (struct dbox_storage *)_storage; struct dbox_message_header dbox_msg_hdr; struct istream *crlf_input; dbox_save_add_to_index(ctx); if (_ctx->dest_mail == NULL) { if (ctx->mail == NULL) ctx->mail = mail_alloc(_ctx->transaction, 0, NULL); _ctx->dest_mail = ctx->mail; } mail_set_seq_saving(_ctx->dest_mail, ctx->seq); crlf_input = i_stream_create_lf(input); ctx->input = index_mail_cache_parse_init(_ctx->dest_mail, crlf_input); i_stream_unref(&crlf_input); /* write a dummy header. it'll get rewritten when we're finished */ memset(&dbox_msg_hdr, 0, sizeof(dbox_msg_hdr)); o_stream_cork(ctx->dbox_output); if (o_stream_send(ctx->dbox_output, &dbox_msg_hdr, sizeof(dbox_msg_hdr)) < 0) { mail_storage_set_critical(_storage, "write(%s) failed: %m", o_stream_get_name(ctx->dbox_output)); ctx->failed = TRUE; } _ctx->data.output = ctx->dbox_output; if (_ctx->data.received_date == (time_t)-1) _ctx->data.received_date = ioloop_time; index_attachment_save_begin(_ctx, storage->attachment_fs, ctx->input); }
struct maildir_filename * maildir_save_add(struct mail_save_context *_ctx, const char *tmp_fname, struct mail *src_mail) { struct maildir_save_context *ctx = (struct maildir_save_context *)_ctx; struct mail_save_data *mdata = &_ctx->data; struct maildir_filename *mf; struct istream *input; unsigned int keyword_count; i_assert(*tmp_fname != '\0'); /* allow caller to specify recent flag only when uid is specified (we're replicating, converting, etc.). */ if (mdata->uid == 0) mdata->flags |= MAIL_RECENT; else if ((mdata->flags & MAIL_RECENT) == 0 && ctx->last_nonrecent_uid < mdata->uid) ctx->last_nonrecent_uid = mdata->uid; /* now, we want to be able to rollback the whole append session, so we'll just store the name of this temp file and move it later into new/ or cur/. */ /* @UNSAFE */ keyword_count = mdata->keywords == NULL ? 0 : mdata->keywords->count; mf = p_malloc(ctx->pool, sizeof(*mf) + sizeof(unsigned int) * keyword_count); mf->tmp_name = mf->dest_basename = p_strdup(ctx->pool, tmp_fname); mf->flags = mdata->flags; mf->size = (uoff_t)-1; mf->vsize = (uoff_t)-1; ctx->file_last = mf; i_assert(*ctx->files_tail == NULL); *ctx->files_tail = mf; ctx->files_tail = &mf->next; ctx->files_count++; if (mdata->keywords != NULL) { /* @UNSAFE */ mf->keywords_count = keyword_count; memcpy(mf + 1, mdata->keywords->idx, sizeof(unsigned int) * keyword_count); ctx->have_keywords = TRUE; } if (mdata->pop3_uidl != NULL) mf->pop3_uidl = p_strdup(ctx->pool, mdata->pop3_uidl); mf->pop3_order = mdata->pop3_order; /* insert into index */ mail_index_append(ctx->trans, mdata->uid, &ctx->seq); mail_index_update_flags(ctx->trans, ctx->seq, MODIFY_REPLACE, mdata->flags & ~MAIL_RECENT); if (mdata->keywords != NULL) { mail_index_update_keywords(ctx->trans, ctx->seq, MODIFY_REPLACE, mdata->keywords); } if (mdata->min_modseq != 0) { mail_index_update_modseq(ctx->trans, ctx->seq, mdata->min_modseq); } if (ctx->first_seq == 0) { ctx->first_seq = ctx->seq; i_assert(ctx->files->next == NULL); } if (_ctx->dest_mail == NULL) { if (ctx->mail == NULL) ctx->mail = mail_alloc(_ctx->transaction, 0, NULL); _ctx->dest_mail = ctx->mail; } mail_set_seq_saving(_ctx->dest_mail, ctx->seq); if (ctx->input == NULL) { /* copying with hardlinking. */ i_assert(src_mail != NULL); index_copy_cache_fields(_ctx, src_mail, ctx->seq); ctx->cur_dest_mail = NULL; } else { input = index_mail_cache_parse_init(_ctx->dest_mail, ctx->input); i_stream_unref(&ctx->input); ctx->input = input; ctx->cur_dest_mail = _ctx->dest_mail; } return mf; }