virtual-save.c revision 3657abd8e4d63adb35a9242c47e0a53cfe010e78
89a126810703c666309310d0f3189e9834d70b5bTimo Sirainen/* Copyright (c) 2009 Dovecot authors, see the included COPYING file */
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen#include "lib.h"
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen#include "array.h"
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen#include "virtual-transaction.h"
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen#include "virtual-storage.h"
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen
a35cbba04d0a2823da98e693bd09a051addffdb2Timo Sirainenstruct virtual_save_context {
94e1adead9faddec88a623485b9999a87b1684faTimo Sirainen struct mail_save_context ctx;
94e1adead9faddec88a623485b9999a87b1684faTimo Sirainen struct mail_save_context *backend_save_ctx;
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen struct mailbox *backend_box;
503e5ef896c7b4a51cf73efb0d132860a8c747e6Timo Sirainen struct mail_keywords *backend_keywords;
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen};
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainenstruct mail_save_context *
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainenvirtual_save_alloc(struct mailbox_transaction_context *_t)
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen{
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen struct virtual_transaction_context *t =
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen (struct virtual_transaction_context *)_t;
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen struct virtual_mailbox *mbox = (struct virtual_mailbox *)_t->box;
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen struct mailbox_transaction_context *backend_trans;
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen struct virtual_save_context *ctx;
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen if (t->save_ctx != NULL)
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen return &t->save_ctx->ctx;
cb951d3282610a9a0960230865bc5f3e3347b203Timo Sirainen
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen ctx = t->save_ctx = i_new(struct virtual_save_context, 1);
cb951d3282610a9a0960230865bc5f3e3347b203Timo Sirainen ctx->ctx.transaction = &t->ictx.mailbox_ctx;
a35cbba04d0a2823da98e693bd09a051addffdb2Timo Sirainen
3fe44a0df5a0bdd80c495f79cbf0e384441d6fccTimo Sirainen if (mbox->save_bbox != NULL) {
a35cbba04d0a2823da98e693bd09a051addffdb2Timo Sirainen backend_trans =
cb951d3282610a9a0960230865bc5f3e3347b203Timo Sirainen virtual_transaction_get(_t, mbox->save_bbox->box);
a35cbba04d0a2823da98e693bd09a051addffdb2Timo Sirainen ctx->backend_save_ctx = mailbox_save_alloc(backend_trans);
cb951d3282610a9a0960230865bc5f3e3347b203Timo Sirainen }
cb951d3282610a9a0960230865bc5f3e3347b203Timo Sirainen return &ctx->ctx;
cb951d3282610a9a0960230865bc5f3e3347b203Timo Sirainen}
a35cbba04d0a2823da98e693bd09a051addffdb2Timo Sirainen
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainenstatic struct mail_keywords *
3fe44a0df5a0bdd80c495f79cbf0e384441d6fccTimo Sirainenvirtual_copy_keywords(struct mailbox *src_box,
3fe44a0df5a0bdd80c495f79cbf0e384441d6fccTimo Sirainen const struct mail_keywords *src_keywords,
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen struct mailbox *dest_box)
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen{
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen struct mailbox_status status;
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen ARRAY_TYPE(keywords) kw_strings;
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen const char *const *kwp;
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen unsigned int i;
3fe44a0df5a0bdd80c495f79cbf0e384441d6fccTimo Sirainen
fc84f8af4794f4bb6caf6e5ec3fb1f8cebd0462aTimo Sirainen if (src_keywords == NULL || src_keywords->count == 0)
91dca97b367c54a139c268b56a0c67f564bd9197Timo Sirainen return NULL;
91dca97b367c54a139c268b56a0c67f564bd9197Timo Sirainen
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen t_array_init(&kw_strings, src_keywords->count + 1);
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen mailbox_get_status(src_box, STATUS_KEYWORDS, &status);
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen for (i = 0; i < src_keywords->count; i++) {
bd7b1a9000b12349e2a99bb43b3ce8b96a18e92bTimo Sirainen kwp = array_idx(status.keywords, src_keywords->idx[i]);
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen array_append(&kw_strings, kwp, 1);
bd7b1a9000b12349e2a99bb43b3ce8b96a18e92bTimo Sirainen }
8a1c866a4c429f26c8746525f82024bc387f1407Timo Sirainen (void)array_append_space(&kw_strings);
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen return mailbox_keywords_create_valid(dest_box,
bd7b1a9000b12349e2a99bb43b3ce8b96a18e92bTimo Sirainen array_idx(&kw_strings, 0));
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen}
8a1c866a4c429f26c8746525f82024bc387f1407Timo Sirainen
8a1c866a4c429f26c8746525f82024bc387f1407Timo Sirainenint virtual_save_begin(struct mail_save_context *_ctx, struct istream *input)
8a1c866a4c429f26c8746525f82024bc387f1407Timo Sirainen{
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen struct virtual_save_context *ctx = (struct virtual_save_context *)_ctx;
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen struct virtual_mailbox *mbox =
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen (struct virtual_mailbox *)_ctx->transaction->box;
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen struct mail *mail;
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen if (ctx->backend_save_ctx == NULL) {
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen mail_storage_set_error(_ctx->transaction->box->storage,
3fe44a0df5a0bdd80c495f79cbf0e384441d6fccTimo Sirainen MAIL_ERROR_NOTPOSSIBLE,
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen "Can't save messages to this virtual mailbox");
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen return -1;
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen }
fd1f0e9ef52b3e157cfd1a01c464c2ac7458ab17Timo Sirainen
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen ctx->backend_box = ctx->backend_save_ctx->transaction->box;
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen ctx->backend_keywords =
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen virtual_copy_keywords(_ctx->transaction->box, _ctx->keywords,
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen ctx->backend_box);
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen mailbox_save_set_flags(ctx->backend_save_ctx, _ctx->flags,
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen ctx->backend_keywords);
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen mailbox_save_set_received_date(ctx->backend_save_ctx,
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen _ctx->received_date,
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen _ctx->received_tz_offset);
3fe44a0df5a0bdd80c495f79cbf0e384441d6fccTimo Sirainen mailbox_save_set_from_envelope(ctx->backend_save_ctx,
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen _ctx->from_envelope);
1795e934ebcd58175d3b5bbdd811b13c7889efa3Timo Sirainen mailbox_save_set_guid(ctx->backend_save_ctx, _ctx->guid);
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen if (_ctx->dest_mail != NULL) {
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen mail = virtual_mail_set_backend_mail(_ctx->dest_mail,
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen mbox->save_bbox);
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen mailbox_save_set_dest_mail(ctx->backend_save_ctx, mail);
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen }
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen return mailbox_save_begin(&ctx->backend_save_ctx, input);
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen}
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainenint virtual_save_continue(struct mail_save_context *_ctx)
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen{
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen struct virtual_save_context *ctx = (struct virtual_save_context *)_ctx;
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen return mailbox_save_continue(ctx->backend_save_ctx);
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen}
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainenint virtual_save_finish(struct mail_save_context *_ctx)
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen{
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen struct virtual_save_context *ctx = (struct virtual_save_context *)_ctx;
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen
3fe44a0df5a0bdd80c495f79cbf0e384441d6fccTimo Sirainen return mailbox_save_finish(&ctx->backend_save_ctx);
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen}
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainenvoid virtual_save_cancel(struct mail_save_context *_ctx)
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen{
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen struct virtual_save_context *ctx = (struct virtual_save_context *)_ctx;
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen if (ctx->backend_save_ctx != NULL)
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen mailbox_save_cancel(&ctx->backend_save_ctx);
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen}
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainenvoid virtual_save_free(struct virtual_save_context *ctx)
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen{
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen if (ctx->backend_keywords != NULL)
3ccfcf0856958cb9208a9fc51c3bdf13c58ad52aTimo Sirainen mailbox_keywords_unref(ctx->backend_box, &ctx->backend_keywords);
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen if (ctx->backend_save_ctx != NULL)
82995cc154a929f37aa486a72a6485e9f8d34a30Timo Sirainen mailbox_save_cancel(&ctx->backend_save_ctx);
91dca97b367c54a139c268b56a0c67f564bd9197Timo Sirainen i_free(ctx);
503e5ef896c7b4a51cf73efb0d132860a8c747e6Timo Sirainen}
26a8b7deb3a5b6f26f9c4d71538e1248f680e4beTimo Sirainen