bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2007-2018 Dovecot authors, see the included COPYING file */
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen#include "lib.h"
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen#include "array.h"
636f017be100bce67d66fd3ae1544a47681efd33Timo Sirainen#include "unichar.h"
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen#include "mail-namespace.h"
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen#include "mail-search-build.h"
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen#include "mail-storage-private.h"
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen#include "snarf-plugin.h"
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen#define SNARF_CONTEXT(obj) \
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen MODULE_CONTEXT(obj, snarf_storage_module)
ff9fabd3e38f5dd5e5982d33cd216da7560a99f4Aki Tuomi#define SNARF_CONTEXT_REQUIRE(obj) \
ff9fabd3e38f5dd5e5982d33cd216da7560a99f4Aki Tuomi MODULE_CONTEXT_REQUIRE(obj, snarf_storage_module)
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainenstruct snarf_mail_storage {
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen union mail_storage_module_context module_ctx;
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen const char *snarf_path;
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen bool snarfing_disabled;
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen};
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainenstruct snarf_mailbox {
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen union mailbox_module_context module_ctx;
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen struct mailbox *snarf_box;
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen};
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen
bd63b5b860658b01b1f46f26d406e1e4a9dc019aTimo Sirainenconst char *snarf_plugin_version = DOVECOT_ABI_VERSION;
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainenstatic MODULE_CONTEXT_DEFINE_INIT(snarf_storage_module,
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen &mail_storage_module_register);
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainenstatic int snarf(struct mailbox *srcbox, struct mailbox *destbox)
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen{
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen struct mail_search_args *search_args;
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen struct mail_search_context *search_ctx;
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen struct mailbox_transaction_context *src_trans, *dest_trans;
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen struct mail_save_context *save_ctx;
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen struct mail *mail;
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen enum mail_error error;
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen int ret;
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen
4abfd8fcb814730b17cede56d8bd10fa7529361fTimo Sirainen /* make sure the destination mailbox has been opened.
4abfd8fcb814730b17cede56d8bd10fa7529361fTimo Sirainen note that this locks the mailbox. */
c14ceb2cabfd4934243d09ff2dfbc24791ef4eb2Timo Sirainen if (mailbox_open(destbox) < 0)
c14ceb2cabfd4934243d09ff2dfbc24791ef4eb2Timo Sirainen return -1;
c14ceb2cabfd4934243d09ff2dfbc24791ef4eb2Timo Sirainen
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen if (mailbox_sync(srcbox, MAILBOX_SYNC_FLAG_FULL_READ) < 0)
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen return -1;
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen
0dab9cb35a976c49b28a11e28d5570f5191f1a7aMartti Rannanjärvi src_trans = mailbox_transaction_begin(srcbox, 0, "snarf src_trans");
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen dest_trans = mailbox_transaction_begin(destbox,
0dab9cb35a976c49b28a11e28d5570f5191f1a7aMartti Rannanjärvi MAILBOX_TRANSACTION_FLAG_EXTERNAL,
0dab9cb35a976c49b28a11e28d5570f5191f1a7aMartti Rannanjärvi "snarf dest_trans");
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen search_args = mail_search_build_init();
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen mail_search_build_add_all(search_args);
eef4ba0cc3e78f8c26804c1c9251a76580a41f0cTimo Sirainen search_ctx = mailbox_search_init(src_trans, search_args, NULL,
eef4ba0cc3e78f8c26804c1c9251a76580a41f0cTimo Sirainen MAIL_FETCH_STREAM_HEADER |
eef4ba0cc3e78f8c26804c1c9251a76580a41f0cTimo Sirainen MAIL_FETCH_STREAM_BODY, NULL);
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen mail_search_args_unref(&search_args);
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen ret = 0;
eef4ba0cc3e78f8c26804c1c9251a76580a41f0cTimo Sirainen while (mailbox_search_next(search_ctx, &mail)) {
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen if (mail->expunged)
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen continue;
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen save_ctx = mailbox_save_alloc(dest_trans);
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen if (mailbox_copy(&save_ctx, mail) < 0 && !mail->expunged) {
11352dc3e4b29f3d2763c82f8ea4f99e8daf4fa3Timo Sirainen error = mailbox_get_last_mail_error(destbox);
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen /* if we failed because of out of disk space, just
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen move those messages we managed to move so far. */
2ed2459dbd183bb371da4a0aecb2d2b74ae7c815Timo Sirainen if (error != MAIL_ERROR_NOQUOTA)
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen ret = -1;
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen break;
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen }
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen mail_expunge(mail);
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen }
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen if (mailbox_search_deinit(&search_ctx) < 0)
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen ret = -1;
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen /* commit the copied messages to the destination mailbox. if we crash
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen between that and between expunging the messages from the source
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen mailbox, we're left with duplicates. */
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen if (ret < 0)
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen mailbox_transaction_rollback(&dest_trans);
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen else if (mailbox_transaction_commit(&dest_trans) < 0)
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen ret = -1;
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen if (ret < 0)
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen mailbox_transaction_rollback(&src_trans);
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen else {
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen if (mailbox_transaction_commit(&src_trans) < 0)
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen ret = -1;
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen }
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen if (ret == 0) {
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen if (mailbox_sync(srcbox, 0) < 0)
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen ret = -1;
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen }
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen return ret;
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen}
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainenstatic struct mailbox_sync_context *
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainensnarf_sync_init(struct mailbox *box, enum mailbox_sync_flags flags)
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen{
ff9fabd3e38f5dd5e5982d33cd216da7560a99f4Aki Tuomi struct snarf_mailbox *sbox = SNARF_CONTEXT_REQUIRE(box);
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen (void)snarf(sbox->snarf_box, box);
4abfd8fcb814730b17cede56d8bd10fa7529361fTimo Sirainen /* close the mailbox so that we don't have to keep it locked */
4abfd8fcb814730b17cede56d8bd10fa7529361fTimo Sirainen (void)mailbox_close(sbox->snarf_box);
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen return sbox->module_ctx.super.sync_init(box, flags);
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen}
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainenstatic void snarf_mailbox_free(struct mailbox *box)
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen{
ff9fabd3e38f5dd5e5982d33cd216da7560a99f4Aki Tuomi struct snarf_mailbox *sbox = SNARF_CONTEXT_REQUIRE(box);
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen mailbox_free(&sbox->snarf_box);
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen sbox->module_ctx.super.free(box);
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen}
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainenstatic bool
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainensnarf_box_find(struct mail_user *user, struct mailbox_list **list_r,
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen const char **name_r)
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen{
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen struct mail_namespace *snarf_ns;
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen const char *snarf_name;
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen snarf_name = mail_user_plugin_getenv(user, "snarf");
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen if (snarf_name == NULL)
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen return FALSE;
636f017be100bce67d66fd3ae1544a47681efd33Timo Sirainen if (!uni_utf8_str_is_valid(snarf_name)) {
636f017be100bce67d66fd3ae1544a47681efd33Timo Sirainen i_error("snarf: Mailbox name not UTF-8: %s", snarf_name);
636f017be100bce67d66fd3ae1544a47681efd33Timo Sirainen return FALSE;
636f017be100bce67d66fd3ae1544a47681efd33Timo Sirainen }
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen snarf_ns = mail_namespace_find(user->namespaces, snarf_name);
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen *list_r = snarf_ns->list;
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen *name_r = snarf_name;
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen return TRUE;
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen}
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainenstatic void snarf_mailbox_allocated(struct mailbox *box)
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen{
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen struct snarf_mail_storage *sstorage = SNARF_CONTEXT(box->storage);
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen struct mailbox_vfuncs *v = box->vlast;
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen struct snarf_mailbox *sbox;
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen struct mailbox_list *snarf_list;
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen const char *snarf_name;
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen if (!box->inbox_user)
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen return;
040b26a36509e180a02acaf1cbc9db5d8c153c82Aki Tuomi if (sstorage == NULL || sstorage->snarfing_disabled)
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen return;
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen if (!snarf_box_find(box->storage->user, &snarf_list, &snarf_name))
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen return;
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen sbox = p_new(box->pool, struct snarf_mailbox, 1);
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen sbox->module_ctx.super = *v;
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen box->vlast = &sbox->module_ctx.super;
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen
4abfd8fcb814730b17cede56d8bd10fa7529361fTimo Sirainen sbox->snarf_box = mailbox_alloc(snarf_list, snarf_name,
4abfd8fcb814730b17cede56d8bd10fa7529361fTimo Sirainen MAILBOX_FLAG_KEEP_LOCKED);
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen v->sync_init = snarf_sync_init;
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen v->free = snarf_mailbox_free;
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen MODULE_CONTEXT_SET(box, snarf_storage_module, sbox);
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen}
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainenstatic struct mailbox *
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainensnarf_mailbox_alloc(struct mail_storage *storage,
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen struct mailbox_list *list,
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen const char *vname, enum mailbox_flags flags)
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen{
ff9fabd3e38f5dd5e5982d33cd216da7560a99f4Aki Tuomi struct snarf_mail_storage *sstorage = SNARF_CONTEXT_REQUIRE(storage);
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen struct mail_namespace *ns = mailbox_list_get_namespace(list);
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen struct mailbox *box;
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen struct mailbox_list *snarf_list;
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen const char *snarf_name;
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen struct stat st;
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen if (strcmp(vname, "INBOX") == 0 &&
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen (ns->flags & NAMESPACE_FLAG_INBOX_USER) != 0) {
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen if (stat(sstorage->snarf_path, &st) == 0)
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen sstorage->snarfing_disabled = FALSE;
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen else {
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen if (errno != ENOENT) {
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen mail_storage_set_critical(storage,
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen "stat(%s) failed: %m",
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen sstorage->snarf_path);
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen }
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen sstorage->snarfing_disabled = TRUE;
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen /* use the snarf box as our real INBOX */
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen if (snarf_box_find(storage->user, &snarf_list,
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen &snarf_name)) {
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen list = snarf_list;
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen vname = snarf_name;
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen }
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen }
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen }
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen box = sstorage->module_ctx.super.
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen mailbox_alloc(storage, list, vname, flags);
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen if (sstorage->snarfing_disabled) {
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen box->inbox_user = TRUE;
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen box->inbox_any = TRUE;
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen }
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen return box;
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen}
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainenstatic void
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainensnarf_mail_storage_create(struct mail_storage *storage, const char *path)
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen{
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen struct snarf_mail_storage *mstorage;
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen struct mail_storage_vfuncs *v = storage->vlast;
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen path = mail_user_home_expand(storage->user, path);
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen mstorage = p_new(storage->pool, struct snarf_mail_storage, 1);
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen mstorage->snarf_path = p_strdup(storage->pool, path);
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen mstorage->module_ctx.super = *v;
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen storage->vlast = &mstorage->module_ctx.super;
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen v->mailbox_alloc = snarf_mailbox_alloc;
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen MODULE_CONTEXT_SET(storage, snarf_storage_module, mstorage);
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen}
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainenstatic void snarf_mail_storage_created(struct mail_storage *storage)
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen{
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen const char *path;
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen /* snarfing is optional: do it only if the path specified
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen by mbox_snarf exists */
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen path = mail_user_plugin_getenv(storage->user, "mbox_snarf");
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen if (path != NULL)
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen snarf_mail_storage_create(storage, path);
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen}
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainenstatic struct mail_storage_hooks snarf_mail_storage_hooks = {
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen .mailbox_allocated = snarf_mailbox_allocated,
9bd607718368ffb39bcfbc82010073364901c5a2Timo Sirainen .mail_storage_created = snarf_mail_storage_created
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen};
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainenvoid snarf_plugin_init(struct module *module)
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen{
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen mail_storage_hooks_add(module, &snarf_mail_storage_hooks);
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen}
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainenvoid snarf_plugin_deinit(void)
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen{
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen mail_storage_hooks_remove(&snarf_mail_storage_hooks);
a6e79dffa06db28bcfad9c1e5fc819c48172d5deTimo Sirainen}