snarf-plugin.c revision 636f017be100bce67d66fd3ae1544a47681efd33
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen/* Copyright (c) 2007-2010 Dovecot authors, see the included COPYING file */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenconst char *snarf_plugin_version = DOVECOT_VERSION;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenstatic MODULE_CONTEXT_DEFINE_INIT(snarf_storage_module,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenstatic int snarf(struct mailbox *srcbox, struct mailbox *destbox)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen struct mailbox_transaction_context *src_trans, *dest_trans;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen /* make sure the destination mailbox has been opened */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (mailbox_sync(srcbox, MAILBOX_SYNC_FLAG_FULL_READ) < 0)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen src_trans = mailbox_transaction_begin(srcbox, 0);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen dest_trans = mailbox_transaction_begin(destbox,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen search_ctx = mailbox_search_init(src_trans, search_args, NULL);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen mail = mail_alloc(src_trans, MAIL_FETCH_STREAM_HEADER |
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen while (mailbox_search_next(search_ctx, mail)) {
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (mailbox_copy(&save_ctx, mail) < 0 && !mail->expunged) {
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen /* if we failed because of out of disk space, just
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen move those messages we managed to move so far. */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen /* commit the copied messages to the destination mailbox. if we crash
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen between that and between expunging the messages from the source
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen mailbox, we're left with duplicates. */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen else if (mailbox_transaction_commit(&dest_trans) < 0)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (mailbox_transaction_commit(&src_trans) < 0)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainensnarf_sync_init(struct mailbox *box, enum mailbox_sync_flags flags)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen struct snarf_mailbox *sbox = SNARF_CONTEXT(box);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen return sbox->module_ctx.super.sync_init(box, flags);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenstatic void snarf_mailbox_free(struct mailbox *box)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen struct snarf_mailbox *sbox = SNARF_CONTEXT(box);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainensnarf_box_find(struct mail_user *user, struct mailbox_list **list_r,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen const char **name_r)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen snarf_name = mail_user_plugin_getenv(user, "snarf");
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen i_error("snarf: Mailbox name not UTF-8: %s", snarf_name);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen snarf_ns = mail_namespace_find(user->namespaces, snarf_name);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen i_error("snarf: Namespace not found for mailbox: %s",
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenstatic void snarf_mailbox_allocated(struct mailbox *box)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen struct snarf_mail_storage *sstorage = SNARF_CONTEXT(box->storage);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (sstorage != NULL && sstorage->snarfing_disabled)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (!snarf_box_find(box->storage->user, &snarf_list, &snarf_name))
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen sbox = p_new(box->pool, struct snarf_mailbox, 1);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen sbox->snarf_box = mailbox_alloc(snarf_list, snarf_name,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen MODULE_CONTEXT_SET(box, snarf_storage_module, sbox);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenstatic struct mailbox *
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainensnarf_mailbox_alloc(struct mail_storage *storage,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen struct snarf_mail_storage *sstorage = SNARF_CONTEXT(storage);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen struct mail_namespace *ns = mailbox_list_get_namespace(list);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen (ns->flags & NAMESPACE_FLAG_INBOX_USER) != 0) {
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen "stat(%s) failed: %m",
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen /* use the snarf box as our real INBOX */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (snarf_box_find(storage->user, &snarf_list,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainensnarf_mail_storage_create(struct mail_storage *storage, const char *path)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen struct mail_storage_vfuncs *v = storage->vlast;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen path = mail_user_home_expand(storage->user, path);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen mstorage = p_new(storage->pool, struct snarf_mail_storage, 1);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen mstorage->snarf_path = p_strdup(storage->pool, path);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen MODULE_CONTEXT_SET(storage, snarf_storage_module, mstorage);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenstatic void snarf_mail_storage_created(struct mail_storage *storage)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen /* snarfing is optional: do it only if the path specified
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen by mbox_snarf exists */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen path = mail_user_plugin_getenv(storage->user, "mbox_snarf");
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenstatic struct mail_storage_hooks snarf_mail_storage_hooks = {
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen .mail_storage_created = snarf_mail_storage_created
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen mail_storage_hooks_add(module, &snarf_mail_storage_hooks);