# HG changeset patch # User Timo Sirainen # Date 1290108770 0 # Node ID 8adacd9c03b28ea67cc5c672bfef8e062abccc31 # Parent 7446b066fc75278468d673b24d750b3e770eedde snarf: Added mbox_snarf setting to enable snarfing only optionally. diff -r 7446b066fc75 -r 8adacd9c03b2 src/plugins/snarf/Makefile.am --- a/src/plugins/snarf/Makefile.am Thu Nov 18 18:58:33 2010 +0000 +++ b/src/plugins/snarf/Makefile.am Thu Nov 18 19:32:50 2010 +0000 @@ -4,12 +4,12 @@ -I$(top_srcdir)/src/lib-index \ -I$(top_srcdir)/src/lib-storage -lib20_snarf_plugin_la_LDFLAGS = -module -avoid-version +lib05_snarf_plugin_la_LDFLAGS = -module -avoid-version module_LTLIBRARIES = \ - lib20_snarf_plugin.la + lib05_snarf_plugin.la -lib20_snarf_plugin_la_SOURCES = \ +lib05_snarf_plugin_la_SOURCES = \ snarf-plugin.c noinst_HEADERS = \ diff -r 7446b066fc75 -r 8adacd9c03b2 src/plugins/snarf/snarf-plugin.c --- a/src/plugins/snarf/snarf-plugin.c Thu Nov 18 18:58:33 2010 +0000 +++ b/src/plugins/snarf/snarf-plugin.c Thu Nov 18 19:32:50 2010 +0000 @@ -10,6 +10,13 @@ #define SNARF_CONTEXT(obj) \ MODULE_CONTEXT(obj, snarf_storage_module) +struct snarf_mail_storage { + union mail_storage_module_context module_ctx; + + const char *snarf_path; + bool snarfing_disabled; +}; + struct snarf_mailbox { union mailbox_module_context module_ctx; struct mailbox *snarf_box; @@ -104,33 +111,49 @@ sbox->module_ctx.super.free(box); } +static bool +snarf_box_find(struct mail_user *user, struct mailbox_list **list_r, + const char **name_r) +{ + struct mail_namespace *snarf_ns; + const char *snarf_name; + + snarf_name = mail_user_plugin_getenv(user, "snarf"); + if (snarf_name == NULL) + return FALSE; + + snarf_ns = mail_namespace_find(user->namespaces, &snarf_name); + if (snarf_ns == NULL) { + i_error("snarf: Namespace not found for mailbox: %s", + snarf_name); + return FALSE; + } + *list_r = snarf_ns->list; + *name_r = snarf_name; + return TRUE; +} + static void snarf_mailbox_allocated(struct mailbox *box) { + struct snarf_mail_storage *sstorage = SNARF_CONTEXT(box->storage); struct mailbox_vfuncs *v = box->vlast; struct snarf_mailbox *sbox; - struct mail_namespace *snarf_ns; + struct mailbox_list *snarf_list; const char *snarf_name; if (!box->inbox_user) return; - - snarf_name = mail_user_plugin_getenv(box->storage->user, "snarf"); - if (snarf_name == NULL) + if (sstorage != NULL && sstorage->snarfing_disabled) 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); + if (!snarf_box_find(box->storage->user, &snarf_list, &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, + sbox->snarf_box = mailbox_alloc(snarf_list, snarf_name, MAILBOX_FLAG_KEEP_RECENT); v->sync_init = snarf_sync_init; @@ -138,8 +161,77 @@ MODULE_CONTEXT_SET(box, snarf_storage_module, sbox); } +static struct mailbox * +snarf_mailbox_alloc(struct mail_storage *storage, + struct mailbox_list *list, const char *name, + enum mailbox_flags flags) +{ + struct snarf_mail_storage *sstorage = SNARF_CONTEXT(storage); + struct mail_namespace *ns = mailbox_list_get_namespace(list); + struct mailbox *box; + struct mailbox_list *snarf_list; + const char *snarf_name; + struct stat st; + + if (strcmp(name, "INBOX") == 0 && + (ns->flags & NAMESPACE_FLAG_INBOX_USER) != 0) { + if (stat(sstorage->snarf_path, &st) == 0) + sstorage->snarfing_disabled = FALSE; + else { + if (errno != ENOENT) { + mail_storage_set_critical(storage, + "stat(%s) failed: %m", + sstorage->snarf_path); + } + sstorage->snarfing_disabled = TRUE; + /* use the snarf box as our real INBOX */ + if (snarf_box_find(storage->user, &snarf_list, + &snarf_name)) { + list = snarf_list; + name = snarf_name; + } + } + } + + box = sstorage->module_ctx.super. + mailbox_alloc(storage, list, name, flags); + if (sstorage->snarfing_disabled) { + box->inbox_user = TRUE; + box->inbox_any = TRUE; + } + return box; +} + +static void +snarf_mail_storage_create(struct mail_storage *storage, const char *path) +{ + struct 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 snarf_mail_storage, 1); + mstorage->snarf_path = p_strdup(storage->pool, path); + mstorage->module_ctx.super = *v; + storage->vlast = &mstorage->module_ctx.super; + v->mailbox_alloc = snarf_mailbox_alloc; + + MODULE_CONTEXT_SET(storage, snarf_storage_module, mstorage); +} + +static void snarf_mail_storage_created(struct mail_storage *storage) +{ + const char *path; + + /* snarfing is optional: do it only if the path specified + by mbox_snarf exists */ + path = mail_user_plugin_getenv(storage->user, "mbox_snarf"); + if (path != NULL) + snarf_mail_storage_create(storage, path); +} + static struct mail_storage_hooks snarf_mail_storage_hooks = { - .mailbox_allocated = snarf_mailbox_allocated + .mailbox_allocated = snarf_mailbox_allocated, + .mail_storage_created = snarf_mail_storage_created }; void snarf_plugin_init(struct module *module)