dovecot-2.0: snarf: Added mbox_snarf setting to enable snarfing ...

dovecot at dovecot.org dovecot at dovecot.org
Thu Nov 18 21:32:54 EET 2010


details:   http://hg.dovecot.org/dovecot-2.0/rev/8adacd9c03b2
changeset: 12447:8adacd9c03b2
user:      Timo Sirainen <tss at iki.fi>
date:      Thu Nov 18 19:32:50 2010 +0000
description:
snarf: Added mbox_snarf setting to enable snarfing only optionally.

diffstat:

 src/plugins/snarf/Makefile.am    |    6 +-
 src/plugins/snarf/snarf-plugin.c |  116 ++++++++++++++++++++++++++++++++++----
 2 files changed, 107 insertions(+), 15 deletions(-)

diffs (176 lines):

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)


More information about the dovecot-cvs mailing list