snarf-plugin.c revision 0dab9cb35a976c49b28a11e28d5570f5191f1a7a
a8c5a86d183db25a57bf193c06b41e092ec2e151Timo Sirainen/* Copyright (c) 2007-2017 Dovecot authors, see the included COPYING file */
7ace5117d5f2395bd66f20b09e77dac05492f7ceTimo Sirainenconst char *snarf_plugin_version = DOVECOT_ABI_VERSION;
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainenstatic MODULE_CONTEXT_DEFINE_INIT(snarf_storage_module,
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainenstatic int snarf(struct mailbox *srcbox, struct mailbox *destbox)
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen struct mailbox_transaction_context *src_trans, *dest_trans;
145d2eef238ed8bbff635e3b06951a83f0ee5a03Timo Sirainen /* make sure the destination mailbox has been opened.
00bde9ae9eab9e720462bf6ec9a4dd85e88c3bbfTimo Sirainen note that this locks the mailbox. */
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen if (mailbox_sync(srcbox, MAILBOX_SYNC_FLAG_FULL_READ) < 0)
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen src_trans = mailbox_transaction_begin(srcbox, 0, "snarf src_trans");
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen dest_trans = mailbox_transaction_begin(destbox,
6135260095e1704ed6edff9d00bdfc043c11429cTimo Sirainen "snarf dest_trans");
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen search_ctx = mailbox_search_init(src_trans, search_args, NULL,
6135260095e1704ed6edff9d00bdfc043c11429cTimo Sirainen while (mailbox_search_next(search_ctx, &mail)) {
24d7c5fc9fa1cb1f49402ec796654113199ba4e6Timo Sirainen if (mailbox_copy(&save_ctx, mail) < 0 && !mail->expunged) {
24d7c5fc9fa1cb1f49402ec796654113199ba4e6Timo Sirainen /* if we failed because of out of disk space, just
6135260095e1704ed6edff9d00bdfc043c11429cTimo Sirainen move those messages we managed to move so far. */
8759adc67109b5a12a7af3ed717c7040622a0a04Timo Sirainen /* commit the copied messages to the destination mailbox. if we crash
8759adc67109b5a12a7af3ed717c7040622a0a04Timo Sirainen between that and between expunging the messages from the source
24d7c5fc9fa1cb1f49402ec796654113199ba4e6Timo Sirainen mailbox, we're left with duplicates. */
24d7c5fc9fa1cb1f49402ec796654113199ba4e6Timo Sirainen else if (mailbox_transaction_commit(&dest_trans) < 0)
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen if (mailbox_transaction_commit(&src_trans) < 0)
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainensnarf_sync_init(struct mailbox *box, enum mailbox_sync_flags flags)
145d2eef238ed8bbff635e3b06951a83f0ee5a03Timo Sirainen struct snarf_mailbox *sbox = SNARF_CONTEXT(box);
6135260095e1704ed6edff9d00bdfc043c11429cTimo Sirainen /* close the mailbox so that we don't have to keep it locked */
6135260095e1704ed6edff9d00bdfc043c11429cTimo Sirainen return sbox->module_ctx.super.sync_init(box, flags);
7ace5117d5f2395bd66f20b09e77dac05492f7ceTimo Sirainenstatic void snarf_mailbox_free(struct mailbox *box)
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen struct snarf_mailbox *sbox = SNARF_CONTEXT(box);
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainensnarf_box_find(struct mail_user *user, struct mailbox_list **list_r,
3c296d819c54e21ce05c3d2eeeedc79be42ac593Timo Sirainen const char **name_r)
a3dd97fb6d92a89c3de0597fed2d4b044c7aeb84Timo Sirainen snarf_name = mail_user_plugin_getenv(user, "snarf");
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen i_error("snarf: Mailbox name not UTF-8: %s", snarf_name);
31a12066e4cd9310d64091c81b59fb8eb1986023Timo Sirainen snarf_ns = mail_namespace_find(user->namespaces, snarf_name);
31a12066e4cd9310d64091c81b59fb8eb1986023Timo Sirainenstatic void snarf_mailbox_allocated(struct mailbox *box)
31a12066e4cd9310d64091c81b59fb8eb1986023Timo Sirainen struct snarf_mail_storage *sstorage = SNARF_CONTEXT(box->storage);
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen if (sstorage != NULL && sstorage->snarfing_disabled)
dc9bfb7dc057964238e181d3d8b08751527bb08aTimo Sirainen if (!snarf_box_find(box->storage->user, &snarf_list, &snarf_name))
static struct mailbox *
const char *snarf_name;
&snarf_name)) {
return box;
const char *path;
void snarf_plugin_deinit(void)