]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
snarf: Added mbox_snarf setting to enable snarfing only optionally.
authorTimo Sirainen <tss@iki.fi>
Thu, 18 Nov 2010 19:32:50 +0000 (19:32 +0000)
committerTimo Sirainen <tss@iki.fi>
Thu, 18 Nov 2010 19:32:50 +0000 (19:32 +0000)
src/plugins/snarf/Makefile.am
src/plugins/snarf/snarf-plugin.c

index 55bab6b0fe1e1d3c302b4024ca7ac2528569c1ba..054bb821869fc4becb1edd5bda1240bc7b97835b 100644 (file)
@@ -4,12 +4,12 @@ AM_CPPFLAGS = \
        -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 = \
index 28bb032095458c8cba667b3c758a0031f10ed534..7d2253054142e08f8b07ff76a7d309ed353221d9 100644 (file)
 #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 @@ static void snarf_mailbox_free(struct mailbox *box)
        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 @@ static void snarf_mailbox_allocated(struct mailbox *box)
        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)