virtual-save.c revision 31a574fda352ef4f71dbff9c30e15e4744e132c0
02c335c23bf5fa225a467c19f2c063fb0dc7b8c3Timo Sirainen/* Copyright (c) 2009-2012 Dovecot authors, see the included COPYING file */
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk#include "lib.h"
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk#include "array.h"
bdd36cfdba3ff66d25570a9ff568d69e1eb543cfTimo Sirainen#include "virtual-transaction.h"
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk#include "virtual-storage.h"
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volkstruct virtual_save_context {
633a1bf10559b9a8d85bfab662fa2a7ba97d45baAki Tuomi struct mail_save_context ctx;
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk struct mail_save_context *backend_save_ctx;
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk struct mailbox *backend_box;
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk struct mail_keywords *backend_keywords;
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk};
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volkstruct mail_save_context *
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volkvirtual_save_alloc(struct mailbox_transaction_context *_t)
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk{
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk struct virtual_transaction_context *t =
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk (struct virtual_transaction_context *)_t;
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk struct virtual_mailbox *mbox = (struct virtual_mailbox *)_t->box;
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk struct mailbox_transaction_context *backend_trans;
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk struct virtual_save_context *ctx;
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainen if (_t->save_ctx == NULL) {
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk ctx = i_new(struct virtual_save_context, 1);
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk ctx->ctx.transaction = &t->t;
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk _t->save_ctx = &ctx->ctx;
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk } else {
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk ctx = (struct virtual_save_context *)_t->save_ctx;
a75d470c9223a75801418fcdda258885c36317e0Timo Sirainen }
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainen if (mbox->save_bbox != NULL) {
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk i_assert(ctx->backend_save_ctx == NULL);
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk backend_trans =
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk virtual_transaction_get(_t, mbox->save_bbox->box);
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk ctx->backend_save_ctx = mailbox_save_alloc(backend_trans);
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk }
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk return _t->save_ctx;
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk}
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volkstatic struct mail_keywords *
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volkvirtual_copy_keywords(struct mailbox *src_box,
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk const struct mail_keywords *src_keywords,
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk struct mailbox *dest_box)
a75d470c9223a75801418fcdda258885c36317e0Timo Sirainen{
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk struct mailbox_status status;
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk ARRAY_TYPE(keywords) kw_strings;
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk const char *const *kwp;
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk unsigned int i;
a75d470c9223a75801418fcdda258885c36317e0Timo Sirainen
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk if (src_keywords == NULL || src_keywords->count == 0)
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk return NULL;
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk t_array_init(&kw_strings, src_keywords->count + 1);
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk mailbox_get_open_status(src_box, STATUS_KEYWORDS, &status);
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk for (i = 0; i < src_keywords->count; i++) {
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk kwp = array_idx(status.keywords, src_keywords->idx[i]);
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk array_append(&kw_strings, kwp, 1);
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk }
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk array_append_zero(&kw_strings);
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk return mailbox_keywords_create_valid(dest_box,
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk array_idx(&kw_strings, 0));
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk}
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volkint virtual_save_begin(struct mail_save_context *_ctx, struct istream *input)
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk{
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk struct virtual_save_context *ctx = (struct virtual_save_context *)_ctx;
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk struct virtual_mailbox *mbox =
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk (struct virtual_mailbox *)_ctx->transaction->box;
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk struct mail *mail;
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk if (ctx->backend_save_ctx == NULL) {
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk mail_storage_set_error(_ctx->transaction->box->storage,
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk MAIL_ERROR_NOTPOSSIBLE,
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk "Can't save messages to this virtual mailbox");
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk return -1;
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk }
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk ctx->backend_box = ctx->backend_save_ctx->transaction->box;
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk ctx->backend_keywords =
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk virtual_copy_keywords(_ctx->transaction->box, _ctx->keywords,
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk ctx->backend_box);
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk mailbox_save_set_flags(ctx->backend_save_ctx, _ctx->flags,
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk ctx->backend_keywords);
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk mailbox_save_set_received_date(ctx->backend_save_ctx,
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk _ctx->received_date,
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk _ctx->received_tz_offset);
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk mailbox_save_set_from_envelope(ctx->backend_save_ctx,
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk _ctx->from_envelope);
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk mailbox_save_set_guid(ctx->backend_save_ctx, _ctx->guid);
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk mailbox_save_set_min_modseq(ctx->backend_save_ctx, _ctx->min_modseq);
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk if (_ctx->dest_mail != NULL) {
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk mail = virtual_mail_set_backend_mail(_ctx->dest_mail,
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk mbox->save_bbox);
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk mailbox_save_set_dest_mail(ctx->backend_save_ctx, mail);
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk }
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk return mailbox_save_begin(&ctx->backend_save_ctx, input);
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk}
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volkint virtual_save_continue(struct mail_save_context *_ctx)
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk{
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk struct virtual_save_context *ctx = (struct virtual_save_context *)_ctx;
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk return mailbox_save_continue(ctx->backend_save_ctx);
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk}
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volkint virtual_save_finish(struct mail_save_context *_ctx)
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk{
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk struct virtual_save_context *ctx = (struct virtual_save_context *)_ctx;
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk return mailbox_save_finish(&ctx->backend_save_ctx);
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk}
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volkvoid virtual_save_cancel(struct mail_save_context *_ctx)
633a1bf10559b9a8d85bfab662fa2a7ba97d45baAki Tuomi{
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk struct virtual_save_context *ctx = (struct virtual_save_context *)_ctx;
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk
633a1bf10559b9a8d85bfab662fa2a7ba97d45baAki Tuomi if (ctx->backend_save_ctx != NULL)
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk mailbox_save_cancel(&ctx->backend_save_ctx);
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk}
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volkvoid virtual_save_free(struct mail_save_context *_ctx)
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk{
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk struct virtual_save_context *ctx = (struct virtual_save_context *)_ctx;
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk if (ctx->backend_keywords != NULL)
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk mailbox_keywords_unref(&ctx->backend_keywords);
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk if (ctx->backend_save_ctx != NULL)
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk mailbox_save_cancel(&ctx->backend_save_ctx);
a75d470c9223a75801418fcdda258885c36317e0Timo Sirainen i_free(ctx);
a75d470c9223a75801418fcdda258885c36317e0Timo Sirainen}
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk