dovecot-2.2-pigeonhole: doveadm-sieve: Prevented Sieve storage f...

pigeonhole at rename-it.nl pigeonhole at rename-it.nl
Fri Apr 19 23:26:39 EEST 2013


details:   http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/9f14740cc1c0
changeset: 1755:9f14740cc1c0
user:      Stephan Bosch <stephan at rename-it.nl>
date:      Fri Apr 19 22:26:32 2013 +0200
description:
doveadm-sieve: Prevented Sieve storage from logging useless while synchronizing.
Added flag to prevent warnings about non-link active scripts and disable critical error logging.
A rather fundamental synchronization problem remains to be solved.

diffstat:

 src/lib-sievestorage/sieve-storage-private.h     |   9 ---
 src/lib-sievestorage/sieve-storage-script.c      |  15 +++--
 src/lib-sievestorage/sieve-storage.c             |  56 +++++++++++++----------
 src/lib-sievestorage/sieve-storage.h             |  12 +++-
 src/managesieve/managesieve-client.c             |   6 ++-
 src/plugins/doveadm-sieve/doveadm-sieve-plugin.c |  54 +++++++++++++++++-----
 6 files changed, 95 insertions(+), 57 deletions(-)

diffs (truncated from 358 to 300 lines):

diff -r 5fa5e2dfbb57 -r 9f14740cc1c0 src/lib-sievestorage/sieve-storage-private.h
--- a/src/lib-sievestorage/sieve-storage-private.h	Fri Apr 19 09:46:49 2013 +0200
+++ b/src/lib-sievestorage/sieve-storage-private.h	Fri Apr 19 22:26:32 2013 +0200
@@ -9,14 +9,6 @@
 
 #include "sieve-storage.h"
 
-
-enum sieve_storage_flags {
-	/* Print debugging information while initializing the storage */
-	SIEVE_STORAGE_FLAG_DEBUG     = 0x01,
-	/* Use CRLF linefeeds when saving mails. */
-	SIEVE_STORAGE_FLAG_SAVE_CRLF   = 0x02,
-};
-
 #define SIEVE_READ_BLOCK_SIZE (1024*8)
 
 /* How often to scan tmp/ directory for old files (based on dir's atime) */
@@ -38,7 +30,6 @@
 
 	char *name;
 	char *dir;
-	bool debug;
 
 	/* Private */
 	char *active_path;
diff -r 5fa5e2dfbb57 -r 9f14740cc1c0 src/lib-sievestorage/sieve-storage-script.c
--- a/src/lib-sievestorage/sieve-storage-script.c	Fri Apr 19 09:46:49 2013 +0200
+++ b/src/lib-sievestorage/sieve-storage-script.c	Fri Apr 19 22:26:32 2013 +0200
@@ -126,18 +126,20 @@
 	ret = readlink(storage->active_path, linkbuf, sizeof(linkbuf));
 
 	if ( ret < 0 ) {
-		if (errno == EINVAL) {
+		if ( errno == EINVAL ) {
 			/* Our symlink is no symlink. Report 'no active script'.
 			 * Activating a script will automatically resolve this, so
 			 * there is no need to panic on this one.
 			 */
-			i_warning
-			  ("sieve-storage: Active sieve script symlink %s is no symlink.",
-			   storage->active_path);
+			if ( (storage->flags & SIEVE_STORAGE_FLAG_SYNCHRONIZING) == 0 ) {
+				i_warning
+				  ("sieve-storage: Active sieve script symlink %s is no symlink.",
+				   storage->active_path);
+			}
 			return 0;
 		}
 
-		if (errno == ENOENT ) {
+		if ( errno == ENOENT ) {
 			/* Symlink not found */
 			return 0;
 		}
@@ -395,6 +397,7 @@
 
 static bool sieve_storage_rescue_regular_file(struct sieve_storage *storage)
 {
+	bool debug = ( (storage->flags & SIEVE_STORAGE_FLAG_DEBUG) != 0 );
 	struct stat st;
 
 	/* Stat the file */
@@ -409,7 +412,7 @@
 	}
 
 	if ( S_ISLNK( st.st_mode ) ) {
-		if ( storage->debug )
+		if ( debug )
 			i_debug( "sieve-storage: nothing to rescue %s.", storage->active_path);
 		return TRUE; /* Nothing to rescue */
 	}
diff -r 5fa5e2dfbb57 -r 9f14740cc1c0 src/lib-sievestorage/sieve-storage.c
--- a/src/lib-sievestorage/sieve-storage.c	Fri Apr 19 09:46:49 2013 +0200
+++ b/src/lib-sievestorage/sieve-storage.c	Fri Apr 19 22:26:32 2013 +0200
@@ -203,10 +203,12 @@
 }
 
 static struct sieve_storage *_sieve_storage_create
-(struct sieve_instance *svinst, const char *user, const char *home, bool debug)
+(struct sieve_instance *svinst, const char *user, const char *home,
+	enum sieve_storage_flags flags)
 {
 	pool_t pool;
 	struct sieve_storage *storage;
+	bool debug = ( (flags & SIEVE_STORAGE_FLAG_DEBUG) != 0 );
 	const char *tmp_dir, *link_path, *path;
 	const char *sieve_data, *active_path, *active_fname, *storage_dir;
 	mode_t dir_create_mode, file_create_mode;
@@ -408,7 +410,7 @@
 	pool = pool_alloconly_create("sieve-storage", 512+256);
 	storage = p_new(pool, struct sieve_storage, 1);
 	storage->svinst = svinst;
-	storage->debug = debug;
+	storage->flags = flags;
 	storage->pool = pool;
 	storage->dir = p_strdup(pool, storage_dir);
 	storage->user = p_strdup(pool, user);
@@ -461,12 +463,13 @@
 }
 
 struct sieve_storage *sieve_storage_create
-(struct sieve_instance *svinst, const char *user, const char *home, bool debug)
+(struct sieve_instance *svinst, const char *user, const char *home,
+	enum sieve_storage_flags flags)
 {
 	struct sieve_storage *storage;
 
 	T_BEGIN {
-		storage = _sieve_storage_create(svinst, user, home, debug);
+		storage = _sieve_storage_create(svinst, user, home, flags);
 	} T_END;
 
 	return storage;
@@ -574,20 +577,6 @@
 	storage->error_code = error;
 }
 
-void sieve_storage_set_internal_error(struct sieve_storage *storage)
-{
-	struct tm *tm;
-	char str[256];
-
-	tm = localtime(&ioloop_time);
-
-	i_free(storage->error);
-	storage->error_code = SIEVE_ERROR_TEMP_FAIL;
-	storage->error =
-	  strftime(str, sizeof(str), CRITICAL_MSG_STAMP, tm) > 0 ?
-	  i_strdup(str) : i_strdup(CRITICAL_MSG);
-}
-
 void sieve_storage_set_critical
 (struct sieve_storage *storage, const char *fmt, ...)
 {
@@ -595,14 +584,31 @@
 
 	sieve_storage_clear_error(storage);
 	if (fmt != NULL) {
-		va_start(va, fmt);
-		i_error("sieve-storage: %s", t_strdup_vprintf(fmt, va));
-		va_end(va);
+		i_free(storage->error);
+		storage->error_code = SIEVE_ERROR_TEMP_FAIL;
 
-		/* critical errors may contain sensitive data, so let user
-		   see only "Internal error" with a timestamp to make it
-		   easier to look from log files the actual error message. */
-		sieve_storage_set_internal_error(storage);
+		if ( (storage->flags & SIEVE_STORAGE_FLAG_SYNCHRONIZING) == 0 ) {
+			struct tm *tm;
+			char str[256];
+
+			va_start(va, fmt);
+			i_error("sieve-storage: %s", t_strdup_vprintf(fmt, va));
+			va_end(va);
+
+			/* critical errors may contain sensitive data, so let user
+			   see only "Internal error" with a timestamp to make it
+			   easier to look from log files the actual error message. */
+			tm = localtime(&ioloop_time);
+			storage->error =
+				strftime(str, sizeof(str), CRITICAL_MSG_STAMP, tm) > 0 ?
+				i_strdup(str) : i_strdup(CRITICAL_MSG);
+		} else {
+			/* no user is involved while synchronizing, so do it the
+			   normal way */
+			va_start(va, fmt);
+			storage->error = i_strdup_vprintf(fmt, va);
+			va_end(va);
+		}
 	}
 }
 
diff -r 5fa5e2dfbb57 -r 9f14740cc1c0 src/lib-sievestorage/sieve-storage.h
--- a/src/lib-sievestorage/sieve-storage.h	Fri Apr 19 09:46:49 2013 +0200
+++ b/src/lib-sievestorage/sieve-storage.h	Fri Apr 19 22:26:32 2013 +0200
@@ -9,8 +9,16 @@
 
 #include "sieve.h"
 
+enum sieve_storage_flags {
+    /* Print debugging information */
+    SIEVE_STORAGE_FLAG_DEBUG             = 0x01,
+    /* This storage is used for synchronization (and not normal ManageSieve) */
+    SIEVE_STORAGE_FLAG_SYNCHRONIZING     = 0x02
+};
+
 struct sieve_storage *sieve_storage_create
-	(struct sieve_instance *svinst, const char *user, const char *home, bool debug);
+	(struct sieve_instance *svinst, const char *user, const char *home,
+		enum sieve_storage_flags flags);
 void sieve_storage_free(struct sieve_storage *storage);
 
 struct sieve_error_handler *sieve_storage_get_error_handler
@@ -27,8 +35,6 @@
 void sieve_storage_set_critical(struct sieve_storage *storage,
 	const char *fmt, ...) ATTR_FORMAT(2, 3);
 
-void sieve_storage_set_internal_error(struct sieve_storage *storage);
-
 const char *sieve_storage_get_last_error
 	(struct sieve_storage *storage, enum sieve_error *error_r);
 
diff -r 5fa5e2dfbb57 -r 9f14740cc1c0 src/managesieve/managesieve-client.c
--- a/src/managesieve/managesieve-client.c	Fri Apr 19 09:46:49 2013 +0200
+++ b/src/managesieve/managesieve-client.c	Fri Apr 19 22:26:32 2013 +0200
@@ -62,13 +62,17 @@
 	const struct managesieve_settings *set)
 {
 	struct sieve_storage *storage;
+	enum sieve_storage_flags flags = 0;
 	const char *home;
 
 	if ( mail_user_get_home(user, &home) <= 0 )
 		home = NULL;
 
+	if ( set->mail_debug )
+		flags |= SIEVE_STORAGE_FLAG_DEBUG;
+
 	storage = sieve_storage_create
-		(svinst, user->username, home, set->mail_debug);
+		(svinst, user->username, home, flags);
 
 	if (storage == NULL) {
 		struct tm *tm;
diff -r 5fa5e2dfbb57 -r 9f14740cc1c0 src/plugins/doveadm-sieve/doveadm-sieve-plugin.c
--- a/src/plugins/doveadm-sieve/doveadm-sieve-plugin.c	Fri Apr 19 09:46:49 2013 +0200
+++ b/src/plugins/doveadm-sieve/doveadm-sieve-plugin.c	Fri Apr 19 22:26:32 2013 +0200
@@ -26,10 +26,6 @@
 #define MAILBOX_ATTRIBUTE_SIEVE_SCRIPT \
 	MAILBOX_ATTRIBUTE_PREFIX_SIEVE"script"
 
-// FIXME: Sieve has its own 'critical' error handling functionality
-//         Passing the last sieve storage error in such situations to the
-//         mail storage error handler is a bit futile.
-
 struct sieve_mail_user {
 	union mail_user_module_context module_ctx;
 
@@ -86,12 +82,13 @@
 (struct mail_user *user, struct sieve_storage **svstorage_r)
 {
 	struct sieve_mail_user *suser = SIEVE_USER_CONTEXT(user);
+	enum sieve_storage_flags storage_flags = SIEVE_STORAGE_FLAG_SYNCHRONIZING;
 	struct mail_user_vfuncs *v = user->vlast;
 	struct sieve_environment svenv;
 
 	if (suser != NULL) {
 		*svstorage_r = suser->sieve_storage;
-		return 0;	
+		return 0;
 	}
 
 	/* Delayed initialization of sieve storage until it's actually needed */
@@ -106,10 +103,13 @@
 	user->vlast = &suser->module_ctx.super;
 	v->deinit = mail_sieve_user_deinit;
 
+	if (user->mail_debug)
+		storage_flags |= SIEVE_STORAGE_FLAG_DEBUG;
+
 	suser->svinst = sieve_init(&svenv, &mail_sieve_callbacks,
 				   user, user->mail_debug);
 	suser->sieve_storage = sieve_storage_create(suser->svinst, user->username,
-					       svenv.home_dir, user->mail_debug);
+					       svenv.home_dir, storage_flags);
 
 	MODULE_CONTEXT_SET(user, sieve_user_module, suser);
 	*svstorage_r = suser->sieve_storage;
@@ -320,6 +320,7 @@
 		    enum mail_attribute_type type, const char *key,
 		    const struct mail_attribute_value *value)
 {
+	struct mail_user *user = t->box->storage->user;
 	union mailbox_module_context *sbox = SIEVE_MAIL_CONTEXT(t->box);
 	time_t ts = value->last_change != 0 ? value->last_change : ioloop_time;
 
@@ -329,6 +330,8 @@
 		    strlen(MAILBOX_ATTRIBUTE_PREFIX_SIEVE)) == 0) {
 		if (sieve_attribute_set_sieve(t->box->storage, key, value) < 0)
 			return -1;
+		if (user->mail_debug)
+			i_debug("doveadm-sieve: Assigned value for key `%s'", key);
 		/* FIXME: set value len to sieve script size / active name
 		   length */
 		if (value->value != NULL || value->value_stream != NULL)
@@ -348,9 +351,9 @@
 	int ret;
 
 	ret = sieve_storage_active_script_get_name(svstorage, &value_r->value);
-	if (ret >= 0) {
-		ret = sieve_storage_active_script_get_last_change
-			(svstorage, &value_r->last_change);
+	if (ret >= 0 && sieve_storage_active_script_get_last_change
+			(svstorage, &value_r->last_change) < 0) {
+		ret = -1;
 	}
 	if (ret < 0)
 		mail_storage_set_internal_error(storage);


More information about the dovecot-cvs mailing list