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