Mercurial > dovecot > core-2.2
changeset 12446:7446b066fc75
Replaced broken mbox-snarf plugin with a more generic snarf plugin.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Thu, 18 Nov 2010 18:58:33 +0000 |
parents | 9c96b54c8a76 |
children | 8adacd9c03b2 |
files | configure.in src/plugins/Makefile.am src/plugins/mbox-snarf/Makefile.am src/plugins/mbox-snarf/mbox-snarf-plugin.c src/plugins/mbox-snarf/mbox-snarf-plugin.h src/plugins/snarf/Makefile.am src/plugins/snarf/snarf-plugin.c src/plugins/snarf/snarf-plugin.h |
diffstat | 8 files changed, 178 insertions(+), 230 deletions(-) [+] |
line wrap: on
line diff
--- a/configure.in Thu Nov 18 18:57:18 2010 +0000 +++ b/configure.in Thu Nov 18 18:58:33 2010 +0000 @@ -2707,10 +2707,10 @@ src/plugins/lazy-expunge/Makefile src/plugins/listescape/Makefile src/plugins/mail-log/Makefile -src/plugins/mbox-snarf/Makefile src/plugins/notify/Makefile src/plugins/quota/Makefile src/plugins/imap-quota/Makefile +src/plugins/snarf/Makefile src/plugins/trash/Makefile src/plugins/virtual/Makefile src/plugins/zlib/Makefile
--- a/src/plugins/Makefile.am Thu Nov 18 18:57:18 2010 +0000 +++ b/src/plugins/Makefile.am Thu Nov 18 18:58:33 2010 +0000 @@ -19,11 +19,11 @@ fts-squat \ lazy-expunge \ listescape \ - mbox-snarf \ notify \ mail-log \ quota \ imap-quota \ + snarf \ trash \ virtual \ $(ZLIB) \
--- a/src/plugins/mbox-snarf/Makefile.am Thu Nov 18 18:57:18 2010 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,16 +0,0 @@ -AM_CPPFLAGS = \ - -I$(top_srcdir)/src/lib \ - -I$(top_srcdir)/src/lib-mail \ - -I$(top_srcdir)/src/lib-index \ - -I$(top_srcdir)/src/lib-storage - -lib20_mbox_snarf_plugin_la_LDFLAGS = -module -avoid-version - -module_LTLIBRARIES = \ - lib20_mbox_snarf_plugin.la - -lib20_mbox_snarf_plugin_la_SOURCES = \ - mbox-snarf-plugin.c - -noinst_HEADERS = \ - mbox-snarf-plugin.h
--- a/src/plugins/mbox-snarf/mbox-snarf-plugin.c Thu Nov 18 18:57:18 2010 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,205 +0,0 @@ -/* Copyright (c) 2007-2010 Dovecot authors, see the included COPYING file */ - -#include "lib.h" -#include "array.h" -#include "home-expand.h" -#include "mail-search-build.h" -#include "mail-storage-private.h" -#include "mailbox-list-private.h" -#include "mail-user.h" -#include "mbox-snarf-plugin.h" - -#include <stdlib.h> -#include <sys/stat.h> - -#define MBOX_SNARF_CONTEXT(obj) \ - MODULE_CONTEXT(obj, mbox_snarf_storage_module) - -struct mbox_snarf_mail_storage { - union mail_storage_module_context module_ctx; - - const char *snarf_inbox_path; - bool open_spool_inbox; -}; - -struct mbox_snarf_mailbox { - union mailbox_module_context module_ctx; -}; - -const char *mbox_snarf_plugin_version = DOVECOT_VERSION; - -static MODULE_CONTEXT_DEFINE_INIT(mbox_snarf_storage_module, - &mail_storage_module_register); - -static int mbox_snarf(struct mailbox *srcbox, struct mailbox *destbox) -{ - struct mail_search_args *search_args; - struct mail_search_context *search_ctx; - struct mailbox_transaction_context *src_trans, *dest_trans; - struct mail_save_context *save_ctx; - struct mail *mail; - enum mail_error error; - int ret; - - if (mailbox_sync(srcbox, MAILBOX_SYNC_FLAG_FULL_READ) < 0) - return -1; - - src_trans = mailbox_transaction_begin(srcbox, 0); - dest_trans = mailbox_transaction_begin(destbox, - MAILBOX_TRANSACTION_FLAG_EXTERNAL); - - search_args = mail_search_build_init(); - mail_search_build_add_all(search_args); - search_ctx = mailbox_search_init(src_trans, search_args, NULL); - mail_search_args_unref(&search_args); - - ret = 0; - mail = mail_alloc(src_trans, MAIL_FETCH_STREAM_HEADER | - MAIL_FETCH_STREAM_BODY, NULL); - while (mailbox_search_next(search_ctx, mail)) { - if (mail->expunged) - continue; - - save_ctx = mailbox_save_alloc(dest_trans); - if (mailbox_copy(&save_ctx, mail) < 0 && !mail->expunged) { - (void)mail_storage_get_last_error(destbox->storage, - &error); - /* if we failed because of out of disk space, just - move those messages we managed to move so far. */ - if (error != MAIL_ERROR_NOSPACE) - ret = -1; - break; - } - mail_expunge(mail); - } - mail_free(&mail); - - if (mailbox_search_deinit(&search_ctx) < 0) - ret = -1; - - /* commit the copied messages to the destination mailbox. if we crash - between that and between expunging the messages from the source - mailbox, we're left with duplicates. */ - if (ret < 0) - mailbox_transaction_rollback(&dest_trans); - else if (mailbox_transaction_commit(&dest_trans) < 0) - ret = -1; - - if (ret < 0) - mailbox_transaction_rollback(&src_trans); - else { - if (mailbox_transaction_commit(&src_trans) < 0) - ret = -1; - } - if (ret == 0) { - if (mailbox_sync(srcbox, 0) < 0) - ret = -1; - } - return ret; -} - -static struct mailbox_sync_context * -mbox_snarf_sync_init(struct mailbox *box, enum mailbox_sync_flags flags) -{ - struct mbox_snarf_mail_storage *mstorage = - MBOX_SNARF_CONTEXT(box->storage); - struct mbox_snarf_mailbox *mbox = MBOX_SNARF_CONTEXT(box); - struct mailbox *spool_mbox; - struct mailbox_sync_context *ctx; - - /* try to open the spool mbox */ - mstorage->open_spool_inbox = TRUE; - spool_mbox = mailbox_alloc(box->list, "INBOX", - MAILBOX_FLAG_KEEP_RECENT | - MAILBOX_FLAG_NO_INDEX_FILES); - mstorage->open_spool_inbox = FALSE; - (void)mbox_snarf(spool_mbox, box); - - ctx = mbox->module_ctx.super.sync_init(box, flags); - mailbox_free(&spool_mbox); - return ctx; -} - -static struct mailbox * -mbox_snarf_mailbox_alloc(struct mail_storage *storage, - struct mailbox_list *list, - const char *name, enum mailbox_flags flags) -{ - struct mbox_snarf_mail_storage *mstorage = - MBOX_SNARF_CONTEXT(storage); - struct mailbox *box; - struct mbox_snarf_mailbox *mbox; - struct stat st; - enum mail_storage_flags old_flags = storage->flags; - enum mailbox_list_flags old_list_flags; - bool use_snarfing = FALSE; - - old_list_flags = list->flags; - - if (strcasecmp(name, "INBOX") == 0 && !mstorage->open_spool_inbox) { - if (stat(mstorage->snarf_inbox_path, &st) == 0) { - /* use ~/mbox as the INBOX */ - name = mstorage->snarf_inbox_path; - use_snarfing = TRUE; - //FIXME:storage->set->mail_full_filesystem_access = TRUE; - } else if (errno != ENOENT) { - mail_storage_set_critical(storage, - "stat(%s) failed: %m", - mstorage->snarf_inbox_path); - } - } - - box = mstorage->module_ctx.super. - mailbox_alloc(storage, list, name, flags); - storage->flags = old_flags; - list->flags = old_list_flags; - - if (box == NULL || !use_snarfing) - return box; - - mbox = p_new(box->pool, struct mbox_snarf_mailbox, 1); - mbox->module_ctx.super = box->v; - - box->v.sync_init = mbox_snarf_sync_init; - MODULE_CONTEXT_SET(box, mbox_snarf_storage_module, mbox); - return box; -} - -static void -mbox_snarf_mail_storage_create(struct mail_storage *storage, const char *path) -{ - struct mbox_snarf_mail_storage *mstorage; - struct mail_storage_vfuncs *v = storage->vlast; - - path = mail_user_home_expand(storage->user, path); - mstorage = p_new(storage->pool, struct mbox_snarf_mail_storage, 1); - mstorage->snarf_inbox_path = p_strdup(storage->pool, path); - mstorage->module_ctx.super = *v; - storage->vlast = &mstorage->module_ctx.super; - v->mailbox_alloc = mbox_snarf_mailbox_alloc; - - MODULE_CONTEXT_SET(storage, mbox_snarf_storage_module, mstorage); -} - -static void mbox_snarf_mail_storage_created(struct mail_storage *storage) -{ - const char *path; - - path = mail_user_plugin_getenv(storage->user, "mbox_snarf"); - if (path != NULL) - mbox_snarf_mail_storage_create(storage, path); -} - -static struct mail_storage_hooks mbox_snarf_mail_storage_hooks = { - .mail_storage_created = mbox_snarf_mail_storage_created -}; - -void mbox_snarf_plugin_init(struct module *module) -{ - mail_storage_hooks_add(module, &mbox_snarf_mail_storage_hooks); -} - -void mbox_snarf_plugin_deinit(void) -{ - mail_storage_hooks_remove(&mbox_snarf_mail_storage_hooks); -}
--- a/src/plugins/mbox-snarf/mbox-snarf-plugin.h Thu Nov 18 18:57:18 2010 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,7 +0,0 @@ -#ifndef MBOX_SNARF_PLUGIN_H -#define MBOX_SNARF_PLUGIN_H - -void mbox_snarf_plugin_init(struct module *module); -void mbox_snarf_plugin_deinit(void); - -#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/plugins/snarf/Makefile.am Thu Nov 18 18:58:33 2010 +0000 @@ -0,0 +1,16 @@ +AM_CPPFLAGS = \ + -I$(top_srcdir)/src/lib \ + -I$(top_srcdir)/src/lib-mail \ + -I$(top_srcdir)/src/lib-index \ + -I$(top_srcdir)/src/lib-storage + +lib20_snarf_plugin_la_LDFLAGS = -module -avoid-version + +module_LTLIBRARIES = \ + lib20_snarf_plugin.la + +lib20_snarf_plugin_la_SOURCES = \ + snarf-plugin.c + +noinst_HEADERS = \ + snarf-plugin.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/plugins/snarf/snarf-plugin.c Thu Nov 18 18:58:33 2010 +0000 @@ -0,0 +1,153 @@ +/* Copyright (c) 2007-2010 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "array.h" +#include "mail-namespace.h" +#include "mail-search-build.h" +#include "mail-storage-private.h" +#include "snarf-plugin.h" + +#define SNARF_CONTEXT(obj) \ + MODULE_CONTEXT(obj, snarf_storage_module) + +struct snarf_mailbox { + union mailbox_module_context module_ctx; + struct mailbox *snarf_box; +}; + +const char *snarf_plugin_version = DOVECOT_VERSION; + +static MODULE_CONTEXT_DEFINE_INIT(snarf_storage_module, + &mail_storage_module_register); + +static int snarf(struct mailbox *srcbox, struct mailbox *destbox) +{ + struct mail_search_args *search_args; + struct mail_search_context *search_ctx; + struct mailbox_transaction_context *src_trans, *dest_trans; + struct mail_save_context *save_ctx; + struct mail *mail; + enum mail_error error; + int ret; + + if (mailbox_sync(srcbox, MAILBOX_SYNC_FLAG_FULL_READ) < 0) + return -1; + + src_trans = mailbox_transaction_begin(srcbox, 0); + dest_trans = mailbox_transaction_begin(destbox, + MAILBOX_TRANSACTION_FLAG_EXTERNAL); + + search_args = mail_search_build_init(); + mail_search_build_add_all(search_args); + search_ctx = mailbox_search_init(src_trans, search_args, NULL); + mail_search_args_unref(&search_args); + + ret = 0; + mail = mail_alloc(src_trans, MAIL_FETCH_STREAM_HEADER | + MAIL_FETCH_STREAM_BODY, NULL); + while (mailbox_search_next(search_ctx, mail)) { + if (mail->expunged) + continue; + + save_ctx = mailbox_save_alloc(dest_trans); + if (mailbox_copy(&save_ctx, mail) < 0 && !mail->expunged) { + (void)mail_storage_get_last_error(destbox->storage, + &error); + /* if we failed because of out of disk space, just + move those messages we managed to move so far. */ + if (error != MAIL_ERROR_NOSPACE) + ret = -1; + break; + } + mail_expunge(mail); + } + mail_free(&mail); + + if (mailbox_search_deinit(&search_ctx) < 0) + ret = -1; + + /* commit the copied messages to the destination mailbox. if we crash + between that and between expunging the messages from the source + mailbox, we're left with duplicates. */ + if (ret < 0) + mailbox_transaction_rollback(&dest_trans); + else if (mailbox_transaction_commit(&dest_trans) < 0) + ret = -1; + + if (ret < 0) + mailbox_transaction_rollback(&src_trans); + else { + if (mailbox_transaction_commit(&src_trans) < 0) + ret = -1; + } + if (ret == 0) { + if (mailbox_sync(srcbox, 0) < 0) + ret = -1; + } + return ret; +} + +static struct mailbox_sync_context * +snarf_sync_init(struct mailbox *box, enum mailbox_sync_flags flags) +{ + struct snarf_mailbox *sbox = SNARF_CONTEXT(box); + + (void)snarf(sbox->snarf_box, box); + return sbox->module_ctx.super.sync_init(box, flags); +} + +static void snarf_mailbox_free(struct mailbox *box) +{ + struct snarf_mailbox *sbox = SNARF_CONTEXT(box); + + mailbox_free(&sbox->snarf_box); + sbox->module_ctx.super.free(box); +} + +static void snarf_mailbox_allocated(struct mailbox *box) +{ + struct mailbox_vfuncs *v = box->vlast; + struct snarf_mailbox *sbox; + struct mail_namespace *snarf_ns; + const char *snarf_name; + + if (!box->inbox_user) + return; + + snarf_name = mail_user_plugin_getenv(box->storage->user, "snarf"); + if (snarf_name == NULL) + return; + + snarf_ns = mail_namespace_find(box->storage->user->namespaces, + &snarf_name); + if (snarf_ns == NULL) { + i_error("snarf: Namespace not found for mailbox: %s", + snarf_name); + return; + } + + sbox = p_new(box->pool, struct snarf_mailbox, 1); + sbox->module_ctx.super = *v; + box->vlast = &sbox->module_ctx.super; + + sbox->snarf_box = mailbox_alloc(snarf_ns->list, snarf_name, + MAILBOX_FLAG_KEEP_RECENT); + + v->sync_init = snarf_sync_init; + v->free = snarf_mailbox_free; + MODULE_CONTEXT_SET(box, snarf_storage_module, sbox); +} + +static struct mail_storage_hooks snarf_mail_storage_hooks = { + .mailbox_allocated = snarf_mailbox_allocated +}; + +void snarf_plugin_init(struct module *module) +{ + mail_storage_hooks_add(module, &snarf_mail_storage_hooks); +} + +void snarf_plugin_deinit(void) +{ + mail_storage_hooks_remove(&snarf_mail_storage_hooks); +}