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