dovecot-2.2-pigeonhole: Committed Timo's patch that adds a plugi...

pigeonhole at rename-it.nl pigeonhole at rename-it.nl
Sat Mar 23 00:10:12 EET 2013


details:   http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/43b09b9a2f72
changeset: 1726:43b09b9a2f72
user:      Stephan Bosch <stephan at rename-it.nl>
date:      Fri Mar 22 23:09:57 2013 +0100
description:
Committed Timo's patch that adds a plugin that provides Sieve dsync support.
http://dovecot.org/patches/2.2/doveadm-sieve-plugin.diff
Made some small modifications.
This code should not interfere with normal ManageSieve operation, so I commit this right now without much testing.
The actual doveadm sieve plugin has a few open issues that need to be resolved still.

diffstat:

 configure.ac                                     |    1 +
 src/lib-sievestorage/Makefile.am                 |    4 +-
 src/lib-sievestorage/sieve-storage.c             |   17 +
 src/lib-sievestorage/sieve-storage.h             |    3 +
 src/managesieve/Makefile.am                      |    2 +-
 src/plugins/Makefile.am                          |    2 +-
 src/plugins/doveadm-sieve/Makefile.am            |   15 +
 src/plugins/doveadm-sieve/doveadm-sieve-plugin.c |  481 +++++++++++++++++++++++
 8 files changed, 521 insertions(+), 4 deletions(-)

diffs (truncated from 586 to 300 lines):

diff -r b75b00760b86 -r 43b09b9a2f72 configure.ac
--- a/configure.ac	Mon Mar 04 22:26:15 2013 +0100
+++ b/configure.ac	Fri Mar 22 23:09:57 2013 +0100
@@ -127,6 +127,7 @@
 src/lib-sievestorage/Makefile
 src/lib-managesieve/Makefile
 src/plugins/Makefile
+src/plugins/doveadm-sieve/Makefile
 src/plugins/lda-sieve/Makefile
 src/sieve-tools/Makefile
 src/managesieve/Makefile
diff -r b75b00760b86 -r 43b09b9a2f72 src/lib-sievestorage/Makefile.am
--- a/src/lib-sievestorage/Makefile.am	Mon Mar 04 22:26:15 2013 +0100
+++ b/src/lib-sievestorage/Makefile.am	Fri Mar 22 23:09:57 2013 +0100
@@ -1,11 +1,11 @@
-noinst_LIBRARIES = libsievestorage.a
+noinst_LTLIBRARIES = libsievestorage.la
 
 INCLUDES = \
 	$(LIBDOVECOT_INCLUDE) \
 	-I$(top_srcdir) \
 	-I$(top_srcdir)/src/lib-sieve
 
-libsievestorage_a_SOURCES = \
+libsievestorage_la_SOURCES = \
 	sieve-storage-save.c \
 	sieve-storage-script.c \
 	sieve-storage-list.c \
diff -r b75b00760b86 -r 43b09b9a2f72 src/lib-sievestorage/sieve-storage.c
--- a/src/lib-sievestorage/sieve-storage.c	Mon Mar 04 22:26:15 2013 +0100
+++ b/src/lib-sievestorage/sieve-storage.c	Fri Mar 22 23:09:57 2013 +0100
@@ -586,4 +586,21 @@
 	return storage->error != NULL ? storage->error : "Unknown error";
 }
 
+int sieve_storage_get_last_change
+(struct sieve_storage *storage, time_t *last_change_r)
+{
+	struct stat st;
 
+	if (stat(storage->dir, &st) < 0) {
+		if (errno == ENOENT) {
+			*last_change_r = 0;
+			return 0;
+		}
+		sieve_storage_set_critical(storage, "stat(%s) failed: %m",
+					   storage->dir);
+		return -1;
+	}
+	*last_change_r = st.st_mtime;
+	return 0;
+}
+
diff -r b75b00760b86 -r 43b09b9a2f72 src/lib-sievestorage/sieve-storage.h
--- a/src/lib-sievestorage/sieve-storage.h	Mon Mar 04 22:26:15 2013 +0100
+++ b/src/lib-sievestorage/sieve-storage.h	Fri Mar 22 23:09:57 2013 +0100
@@ -32,4 +32,7 @@
 const char *sieve_storage_get_last_error
 	(struct sieve_storage *storage, enum sieve_error *error_r);
 
+int sieve_storage_get_last_change
+	(struct sieve_storage *storage, time_t *last_change_r);
+
 #endif
diff -r b75b00760b86 -r 43b09b9a2f72 src/managesieve/Makefile.am
--- a/src/managesieve/Makefile.am	Mon Mar 04 22:26:15 2013 +0100
+++ b/src/managesieve/Makefile.am	Fri Mar 22 23:09:57 2013 +0100
@@ -24,7 +24,7 @@
 libs = \
 	managesieve-settings.lo \
 	$(top_builddir)/src/lib-managesieve/libmanagesieve.a \
-	$(top_builddir)/src/lib-sievestorage/libsievestorage.a \
+	$(top_builddir)/src/lib-sievestorage/libsievestorage.la \
 	$(top_builddir)/src/lib-sieve/libdovecot-sieve.la
 
 managesieve_LDADD = $(libs) $(LIBDOVECOT_STORAGE) $(LIBDOVECOT_LDA) $(LIBDOVECOT)
diff -r b75b00760b86 -r 43b09b9a2f72 src/plugins/Makefile.am
--- a/src/plugins/Makefile.am	Mon Mar 04 22:26:15 2013 +0100
+++ b/src/plugins/Makefile.am	Fri Mar 22 23:09:57 2013 +0100
@@ -1,1 +1,1 @@
-SUBDIRS = lda-sieve
+SUBDIRS = doveadm-sieve lda-sieve
diff -r b75b00760b86 -r 43b09b9a2f72 src/plugins/doveadm-sieve/Makefile.am
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/plugins/doveadm-sieve/Makefile.am	Fri Mar 22 23:09:57 2013 +0100
@@ -0,0 +1,15 @@
+AM_CPPFLAGS = \
+	-I$(top_srcdir)/src/lib-sieve \
+	-I$(top_srcdir)/src/lib-sievestorage \
+	$(LIBDOVECOT_INCLUDE)
+
+doveadm_moduledir = $(dovecot_moduledir)/doveadm
+lib10_doveadm_sieve_plugin_la_LDFLAGS = -module -avoid-version
+
+doveadm_module_LTLIBRARIES = lib10_doveadm_sieve_plugin.la
+
+lib10_doveadm_sieve_plugin_la_SOURCES = \
+	doveadm-sieve-plugin.c
+lib10_doveadm_sieve_plugin_la_LIBADD = \
+	$(top_builddir)/src/lib-sieve/libdovecot-sieve.la \
+	$(top_builddir)/src/lib-sievestorage/libsievestorage.la
diff -r b75b00760b86 -r 43b09b9a2f72 src/plugins/doveadm-sieve/doveadm-sieve-plugin.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/plugins/doveadm-sieve/doveadm-sieve-plugin.c	Fri Mar 22 23:09:57 2013 +0100
@@ -0,0 +1,481 @@
+/* Copyright (c) 2013 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "istream.h"
+#include "sieve-storage.h"
+#include "sieve-storage-list.h"
+#include "sieve-storage-save.h"
+#include "sieve-storage-script.h"
+#include "mail-storage-private.h"
+
+#define SIEVE_MAIL_CONTEXT(obj) \
+	MODULE_CONTEXT(obj, sieve_storage_module)
+#define SIEVE_USER_CONTEXT(obj) \
+	MODULE_CONTEXT(obj, sieve_user_module)
+
+#define MAILBOX_ATTRIBUTE_PREFIX_SIEVE \
+	MAILBOX_ATTRIBUTE_PREFIX_DOVECOT_PVT"sieve/"
+#define MAILBOX_ATTRIBUTE_PREFIX_SIEVE_FILES \
+	MAILBOX_ATTRIBUTE_PREFIX_SIEVE"files/"
+#define MAILBOX_ATTRIBUTE_SIEVE_ACTIVE \
+	MAILBOX_ATTRIBUTE_PREFIX_SIEVE"active"
+
+struct sieve_mail_user {
+	union mail_user_module_context module_ctx;
+
+	struct sieve_instance *svinst;
+	struct sieve_storage *sstorage;
+};
+
+struct sieve_mailbox_attribute_iter {
+	struct mailbox_attribute_iter iter;
+	struct mailbox_attribute_iter *super;
+
+	struct sieve_list_context *sieve_list;
+	string_t *name;
+
+	bool failed;
+	bool have_active;
+};
+
+void doveadm_sieve_plugin_init(struct module *module);
+void doveadm_sieve_plugin_deinit(void);
+
+static MODULE_CONTEXT_DEFINE_INIT(sieve_storage_module,
+				  &mail_storage_module_register);
+static MODULE_CONTEXT_DEFINE_INIT(sieve_user_module,
+				  &mail_user_module_register);
+
+const char *doveadm_sieve_plugin_version = DOVECOT_ABI_VERSION;
+
+static const char *
+mail_sieve_get_setting(void *context, const char *identifier)
+{
+	struct mail_user *mail_user = context;
+
+	return mail_user_plugin_getenv(mail_user, identifier);
+}
+
+static const struct sieve_callbacks mail_sieve_callbacks = {
+	NULL,
+	mail_sieve_get_setting
+};
+
+static void mail_sieve_user_deinit(struct mail_user *user)
+{
+	struct sieve_mail_user *suser = SIEVE_USER_CONTEXT(user);
+
+	sieve_storage_free(suser->sstorage);
+	sieve_deinit(&suser->svinst);
+
+	suser->module_ctx.super.deinit(user);
+}
+
+static int
+mail_sieve_user_init(struct mail_user *user, struct sieve_storage **sstorage_r)
+{
+	/* delayed initialization of sieve storage until it's actually needed */
+	struct mail_user_vfuncs *v = user->vlast;
+	struct sieve_environment svenv;
+	struct sieve_mail_user *suser;
+
+	memset(&svenv, 0, sizeof(svenv));
+	svenv.username = user->username;
+	(void)mail_user_get_home(user, &svenv.home_dir);
+	svenv.base_dir = user->set->base_dir;
+	svenv.flags = SIEVE_FLAG_HOME_RELATIVE;
+
+	suser = p_new(user->pool, struct sieve_mail_user, 1);
+	suser->module_ctx.super = *v;
+	user->vlast = &suser->module_ctx.super;
+	v->deinit = mail_sieve_user_deinit;
+
+	suser->svinst = sieve_init(&svenv, &mail_sieve_callbacks,
+				   user, user->mail_debug);
+	suser->sstorage = sieve_storage_create(suser->svinst, user->username,
+					       svenv.home_dir, user->mail_debug);
+
+	MODULE_CONTEXT_SET(user, sieve_user_module, suser);
+	*sstorage_r = suser->sstorage;
+	return 0;
+}
+
+static int sieve_attribute_unset_script(struct mail_storage *storage,
+					struct sieve_storage *sstorage,
+					const char *scriptname)
+{
+	struct sieve_script *script;
+	const char *errstr;
+	enum sieve_error error;
+	int ret = 0;
+
+	script = sieve_storage_script_init(sstorage, scriptname);
+	ret = script == NULL ? -1 :
+		sieve_storage_script_delete(&script);
+	if (ret < 0) {
+		errstr = sieve_storage_get_last_error(sstorage, &error);
+		if (error == SIEVE_ERROR_NOT_FOUND) {
+			/* already deleted, ignore */
+			return 0;
+		}
+		mail_storage_set_critical(storage,
+			"Failed to delete sieve script '%s': %s", scriptname,
+			errstr);
+		return -1;
+	}
+	return 0;
+}
+
+static int
+sieve_attribute_set_active(struct mail_storage *storage,
+			   struct sieve_storage *sstorage,
+			   const struct mail_attribute_value *value)
+{
+	const char *scriptname;
+	struct sieve_script *script;
+	int ret;
+
+	if (mailbox_attribute_value_to_string(storage, value, &scriptname) < 0)
+		return -1;
+	if (scriptname == NULL) {
+		/* deactivate current script */
+		if (sieve_storage_deactivate(sstorage) < 0) {
+			mail_storage_set_critical(storage,
+				"Failed to deactivate sieve: %s",
+				sieve_storage_get_last_error(sstorage, NULL));
+			return -1;
+		}
+		return 0;
+	}
+
+	/* activate specified script */
+	script = sieve_storage_script_init(sstorage, scriptname);
+	ret = script == NULL ? -1 :
+		sieve_storage_script_activate(script);
+	if (ret < 0) {
+		mail_storage_set_critical(storage,
+			"Failed to activate sieve script '%s': %s", scriptname,
+			sieve_storage_get_last_error(sstorage, NULL));
+	}
+	if (script != NULL)
+		sieve_script_unref(&script);
+	return ret;
+}
+
+static int
+sieve_attribute_set_sieve(struct mail_storage *storage,
+			  const char *key,
+			  const struct mail_attribute_value *value)
+{
+	struct sieve_storage *sstorage;
+	struct sieve_save_context *save_ctx;
+	struct istream *input;
+	const char *scriptname;
+	int ret = 0;
+
+	if (mail_sieve_user_init(storage->user, &sstorage) < 0)
+		return -1;
+
+	if (strcmp(key, MAILBOX_ATTRIBUTE_SIEVE_ACTIVE) == 0)
+		return sieve_attribute_set_active(storage, sstorage, value);
+	if (strncmp(key, MAILBOX_ATTRIBUTE_PREFIX_SIEVE_FILES,
+		    strlen(MAILBOX_ATTRIBUTE_PREFIX_SIEVE_FILES)) != 0) {
+		mail_storage_set_error(storage, MAIL_ERROR_NOTFOUND,
+				       "Nonexistent sieve attribute");
+		return -1;
+	}
+	scriptname = key + strlen(MAILBOX_ATTRIBUTE_PREFIX_SIEVE_FILES);
+
+	if (value->value != NULL) {
+		input = i_stream_create_from_data(value->value,
+						  strlen(value->value));
+		save_ctx = sieve_storage_save_init(sstorage, scriptname, input);
+		i_stream_unref(&input);
+	} else if (value->value_stream != NULL) {
+		input = value->value_stream;


More information about the dovecot-cvs mailing list