dovecot-2.2-pigeonhole: doveadm-sieve: Fix ping-pong problem in ...

pigeonhole at rename-it.nl pigeonhole at rename-it.nl
Mon May 6 23:49:03 EEST 2013


details:   http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/e2e1ecc75a72
changeset: 1759:e2e1ecc75a72
user:      Stephan Bosch <stephan at rename-it.nl>
date:      Mon May 06 22:48:59 2013 +0200
description:
doveadm-sieve: Fix ping-pong problem in active Sieve script synchronization.
Patch by Timo Sirainen.

diffstat:

 src/lib-sievestorage/sieve-storage.c             |    6 +-
 src/plugins/doveadm-sieve/doveadm-sieve-plugin.c |  122 ++++++++++++++++------
 2 files changed, 91 insertions(+), 37 deletions(-)

diffs (252 lines):

diff -r 5892c2ab9b0d -r e2e1ecc75a72 src/lib-sievestorage/sieve-storage.c
--- a/src/lib-sievestorage/sieve-storage.c	Tue Apr 23 22:55:03 2013 +0200
+++ b/src/lib-sievestorage/sieve-storage.c	Mon May 06 22:48:59 2013 +0200
@@ -504,15 +504,19 @@
 void sieve_storage_set_modified
 (struct sieve_storage *storage, time_t mtime)
 {
-	struct utimbuf times = { .actime = mtime, .modtime = mtime };
+	struct utimbuf times;
 	time_t cur_mtime;
 
 	if ( mtime != (time_t)-1 ) {
 		if ( sieve_storage_get_last_change(storage, &cur_mtime) >= 0 &&
 			cur_mtime > mtime )
 			return;
+	} else {
+		mtime = ioloop_time;
 	}
 
+	times.actime = mtime;
+	times.modtime = mtime;
 	if ( utime(storage->dir, &times) < 0 ) {
 		switch ( errno ) {
 		case ENOENT:
diff -r 5892c2ab9b0d -r e2e1ecc75a72 src/plugins/doveadm-sieve/doveadm-sieve-plugin.c
--- a/src/plugins/doveadm-sieve/doveadm-sieve-plugin.c	Tue Apr 23 22:55:03 2013 +0200
+++ b/src/plugins/doveadm-sieve/doveadm-sieve-plugin.c	Mon May 06 22:48:59 2013 +0200
@@ -4,6 +4,7 @@
 #include "lib.h"
 #include "ioloop.h"
 #include "istream.h"
+#include "istream-concat.h"
 #include "sieve-script.h"
 #include "sieve-script-file.h"
 #include "sieve-storage.h"
@@ -21,10 +22,11 @@
 	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"
-#define MAILBOX_ATTRIBUTE_SIEVE_SCRIPT \
-	MAILBOX_ATTRIBUTE_PREFIX_SIEVE"script"
+#define MAILBOX_ATTRIBUTE_SIEVE_DEFAULT \
+	MAILBOX_ATTRIBUTE_PREFIX_SIEVE"default"
+
+#define MAILBOX_ATTRIBUTE_SIEVE_DEFAULT_LINK 'L'
+#define MAILBOX_ATTRIBUTE_SIEVE_DEFAULT_SCRIPT 'S'
 
 struct sieve_mail_user {
 	union mail_user_module_context module_ctx;
@@ -153,6 +155,9 @@
 
 	if (mailbox_attribute_value_to_string(storage, value, &scriptname) < 0)
 		return -1;
+	i_assert(scriptname[0] == MAILBOX_ATTRIBUTE_SIEVE_DEFAULT_LINK);
+	scriptname++;
+
 	if (scriptname == NULL) {
 		/* don't affect non-link active script */
 		if ((ret=sieve_storage_active_script_is_no_link(svstorage)) != 0) {
@@ -224,6 +229,8 @@
 	} else {
 		return sieve_attribute_unset_active_script(storage, svstorage, value->last_change);
 	}
+	/* skip over the 'S' type */
+	i_stream_skip(input, 1);
 
 	if (sieve_storage_save_as_active_script
 		(svstorage, input, value->last_change) < 0) {
@@ -240,6 +247,37 @@
 }
 
 static int
+sieve_attribute_set_default(struct mail_storage *storage,
+			    struct sieve_storage *svstorage,
+			    const struct mail_attribute_value *value)
+{
+	const unsigned char *data;
+	size_t size;
+	ssize_t ret;
+	char type;
+
+	if (value->value != NULL) {
+		type = value->value[0];
+	} else {
+		ret = i_stream_read_data(value->value_stream, &data, &size, 0);
+		if (ret == -1) {
+			mail_storage_set_critical(storage, "read(%s) failed: %m",
+				i_stream_get_name(value->value_stream));
+			return -1;
+		}
+		i_assert(ret > 0);
+		type = data[0];
+	}
+	if (type == MAILBOX_ATTRIBUTE_SIEVE_DEFAULT_LINK)
+		return sieve_attribute_set_active(storage, svstorage, value);
+	if (type == MAILBOX_ATTRIBUTE_SIEVE_DEFAULT_SCRIPT)
+		return sieve_attribute_set_active_script(storage, svstorage, value);
+	mail_storage_set_error(storage, MAIL_ERROR_PARAMS,
+			       "Invalid value for default sieve attribute");
+	return -1;
+}
+
+static int
 sieve_attribute_set_sieve(struct mail_storage *storage,
 			  const char *key,
 			  const struct mail_attribute_value *value)
@@ -253,10 +291,8 @@
 	if (mail_sieve_user_init(storage->user, &svstorage) < 0)
 		return -1;
 
-	if (strcmp(key, MAILBOX_ATTRIBUTE_SIEVE_ACTIVE) == 0)
-		return sieve_attribute_set_active(storage, svstorage, value);
-	if (strcmp(key, MAILBOX_ATTRIBUTE_SIEVE_SCRIPT) == 0)
-		return sieve_attribute_set_active_script(storage, svstorage, value);
+	if (strcmp(key, MAILBOX_ATTRIBUTE_SIEVE_DEFAULT) == 0)
+		return sieve_attribute_set_default(storage, svstorage, value);
 	if (strncmp(key, MAILBOX_ATTRIBUTE_PREFIX_SIEVE_FILES,
 		    strlen(MAILBOX_ATTRIBUTE_PREFIX_SIEVE_FILES)) != 0) {
 		mail_storage_set_error(storage, MAIL_ERROR_NOTFOUND,
@@ -349,28 +385,13 @@
 }
 
 static int
-sieve_attribute_get_active(struct mail_storage *storage,
-			   struct sieve_storage *svstorage,
-			   struct mail_attribute_value *value_r)
-{
-	int ret;
-
-	ret = sieve_storage_active_script_get_name(svstorage, &value_r->value);
-	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);
-	return ret;
-}
-
-static int
 sieve_attribute_retrieve_script(struct mail_storage *storage,
 			   struct sieve_storage *svstorage, struct sieve_script *script,
+			   bool add_type_prefix,
 			   struct mail_attribute_value *value_r, const char **errorstr_r)
 {
-	struct istream *input;
+	char type = MAILBOX_ATTRIBUTE_SIEVE_DEFAULT_SCRIPT;
+	struct istream *input, *inputs[3];
 	const struct stat *st;
 	enum sieve_error error;
 
@@ -389,14 +410,21 @@
 		*errorstr_r = sieve_storage_get_last_error(svstorage, &error);
 		return -1;
 	}
-	i_stream_ref(input);
-	value_r->value_stream = input;
 	if (i_stream_stat(input, FALSE, &st) < 0) {
 		mail_storage_set_critical(storage,
 			"stat(%s) failed: %m", i_stream_get_name(input));
 	} else {
 		value_r->last_change = st->st_mtime;
 	}
+	if (!add_type_prefix) {
+		i_stream_ref(input);
+		value_r->value_stream = input;
+	} else {
+		inputs[0] = i_stream_create_from_data(&type, 1);
+		inputs[1] = input;
+		inputs[2] = NULL;
+		value_r->value_stream = i_stream_create_concat(inputs);
+	}
 	sieve_script_unref(&script);
 	return 1;
 }
@@ -423,7 +451,7 @@
 	if ((script=sieve_storage_active_script_get(svstorage)) == NULL)
 		return 0;
 	if ((ret=sieve_attribute_retrieve_script
-		(storage, svstorage, script, value_r, &errstr)) < 0) {
+		(storage, svstorage, script, TRUE, value_r, &errstr)) < 0) {
 		mail_storage_set_critical(storage,
 			"Failed to access active sieve script: %s", errstr);
 	}
@@ -431,6 +459,30 @@
 }
 
 static int
+sieve_attribute_get_default(struct mail_storage *storage,
+			    struct sieve_storage *svstorage,
+			    struct mail_attribute_value *value_r)
+{
+	const char *scriptname;
+	int ret;
+
+	ret = sieve_storage_active_script_get_name(svstorage, &scriptname);
+	if (ret == 0)
+		return sieve_attribute_get_active_script(storage, svstorage, value_r);
+
+	if (ret > 0) {
+		value_r->value = t_strdup_printf("%c%s",
+			MAILBOX_ATTRIBUTE_SIEVE_DEFAULT_LINK, scriptname);
+		if (sieve_storage_active_script_get_last_change
+				(svstorage, &value_r->last_change) < 0)
+			ret = -1;
+	}
+	if (ret < 0)
+		mail_storage_set_internal_error(storage);
+	return ret;
+}
+
+static int
 sieve_attribute_get_sieve(struct mail_storage *storage, const char *key,
 			  struct mail_attribute_value *value_r)
 {
@@ -442,10 +494,8 @@
 	if (mail_sieve_user_init(storage->user, &svstorage) < 0)
 		return -1;
 
-	if (strcmp(key, MAILBOX_ATTRIBUTE_SIEVE_ACTIVE) == 0)
-		return sieve_attribute_get_active(storage, svstorage, value_r);
-	if (strcmp(key, MAILBOX_ATTRIBUTE_SIEVE_SCRIPT) == 0)
-		return sieve_attribute_get_active_script(storage, svstorage, value_r);
+	if (strcmp(key, MAILBOX_ATTRIBUTE_SIEVE_DEFAULT) == 0)
+		return sieve_attribute_get_default(storage, svstorage, value_r);
 	if (strncmp(key, MAILBOX_ATTRIBUTE_PREFIX_SIEVE_FILES,
 		    strlen(MAILBOX_ATTRIBUTE_PREFIX_SIEVE_FILES)) != 0)
 		return 0;
@@ -457,7 +507,7 @@
 	scriptname = key + strlen(MAILBOX_ATTRIBUTE_PREFIX_SIEVE_FILES);
 	script = sieve_storage_script_init(svstorage, scriptname);
 	if ((ret=sieve_attribute_retrieve_script
-		(storage, svstorage, script, value_r, &errstr)) < 0) {
+		(storage, svstorage, script, FALSE, value_r, &errstr)) < 0) {
 		mail_storage_set_critical(storage,
 			"Failed to access sieve script '%s': %s",
 			scriptname, errstr);
@@ -584,10 +634,10 @@
 
 	/* Regular file */
 	if (ret > 0)
-		return MAILBOX_ATTRIBUTE_SIEVE_SCRIPT	;	
+		return MAILBOX_ATTRIBUTE_SIEVE_DEFAULT;
 
 	/* Symlink or none active */
-	return siter->have_active ? MAILBOX_ATTRIBUTE_SIEVE_ACTIVE : NULL;
+	return siter->have_active ? MAILBOX_ATTRIBUTE_SIEVE_DEFAULT : NULL;
 }
 
 static const char *


More information about the dovecot-cvs mailing list