dovecot-2.1-pigeonhole: lib-sieve: vnd.dovecot.duplicate extensi...

pigeonhole at rename-it.nl pigeonhole at rename-it.nl
Wed Oct 17 03:59:33 EEST 2012


details:   http://hg.rename-it.nl/dovecot-2.1-pigeonhole/rev/762b6a885897
changeset: 1663:762b6a885897
user:      Stephan Bosch <stephan at rename-it.nl>
date:      Wed Oct 17 02:55:07 2012 +0200
description:
lib-sieve: vnd.dovecot.duplicate extension: Only track duplicate when Sieve script executes successfully.

diffstat:

 src/lib-sieve/plugins/vnd.dovecot/duplicate/ext-duplicate-common.c |  111 ++++++++-
 src/lib-sieve/plugins/vnd.dovecot/duplicate/ext-duplicate-common.h |    2 +-
 src/lib-sieve/plugins/vnd.dovecot/duplicate/tst-duplicate.c        |    4 +-
 3 files changed, 96 insertions(+), 21 deletions(-)

diffs (221 lines):

diff -r 3a972efe012b -r 762b6a885897 src/lib-sieve/plugins/vnd.dovecot/duplicate/ext-duplicate-common.c
--- a/src/lib-sieve/plugins/vnd.dovecot/duplicate/ext-duplicate-common.c	Wed Oct 17 02:15:04 2012 +0200
+++ b/src/lib-sieve/plugins/vnd.dovecot/duplicate/ext-duplicate-common.c	Wed Oct 17 02:55:07 2012 +0200
@@ -5,6 +5,7 @@
 #include "md5.h"
 #include "ioloop.h"
 #include "str.h"
+#include "str-sanitize.h"
 #include "array.h"
 
 #include "sieve-common.h"
@@ -15,6 +16,7 @@
 #include "sieve-code.h"
 #include "sieve-runtime.h"
 #include "sieve-actions.h"
+#include "sieve-result.h"
 
 #include "ext-duplicate-common.h"
 
@@ -62,6 +64,67 @@
 }
 
 /*
+ * Duplicate_mark action
+ */
+
+struct act_duplicate_mark_data {
+	const char *handle;
+	unsigned int period;
+	unsigned char hash[MD5_RESULTLEN];
+};
+
+static void act_duplicate_mark_print
+	(const struct sieve_action *action,
+		const struct sieve_result_print_env *rpenv, bool *keep);
+static bool act_duplicate_mark_commit
+	(const struct sieve_action *action,
+		const struct sieve_action_exec_env *aenv, void *tr_context, bool *keep);
+
+static const struct sieve_action_def act_duplicate_mark = {
+	"duplicate_mark",
+	0,
+	NULL, NULL, NULL,
+	act_duplicate_mark_print,
+	NULL, NULL,
+	act_duplicate_mark_commit,
+	NULL
+};
+
+static void act_duplicate_mark_print
+(const struct sieve_action *action,
+	const struct sieve_result_print_env *rpenv, bool *keep ATTR_UNUSED)
+{
+	struct act_duplicate_mark_data *data =
+		(struct act_duplicate_mark_data *) action->context;
+
+	if (data->handle != NULL) {
+		sieve_result_action_printf(rpenv, "track duplicate with handle: %s",
+			str_sanitize(data->handle, 128));
+	} else {
+		sieve_result_action_printf(rpenv, "track duplicate");		
+	}
+}
+
+static bool act_duplicate_mark_commit
+(const struct sieve_action *action,
+	const struct sieve_action_exec_env *aenv,
+	void *tr_context ATTR_UNUSED, bool *keep ATTR_UNUSED)
+{
+	const struct sieve_script_env *senv = aenv->scriptenv;
+	struct act_duplicate_mark_data *data =
+		(struct act_duplicate_mark_data *) action->context;
+
+	/* Message was handled successfully until now, so track duplicate for this
+	 * message.
+	 */
+	sieve_action_duplicate_mark
+		(senv, data->hash, sizeof(data->hash), ioloop_time + data->period);
+	
+	return TRUE;
+}
+
+
+/*
  * Duplicate checking
  */
 
@@ -77,7 +140,7 @@
 	unsigned int nohandle_checked:1;
 };
 
-bool ext_duplicate_check
+int ext_duplicate_check
 (const struct sieve_runtime_env *renv, string_t *handle,
 	const char *value, size_t value_len, sieve_number_t period)
 {
@@ -85,13 +148,13 @@
 	const struct sieve_script_env *senv = renv->scriptenv;
 	struct ext_duplicate_context *rctx;
 	bool duplicate = FALSE;
-	pool_t pool = NULL;
+	pool_t msg_pool = NULL, result_pool = NULL;
 	static const char *id = "sieve duplicate";
-	unsigned char dupl_hash[MD5_RESULTLEN];
+	struct act_duplicate_mark_data *act;
 	struct md5_context ctx;
 
 	if ( !sieve_action_duplicate_check_available(senv)	|| value == NULL )
-		return FALSE;
+		return 0;
 
 	/* Get context; find out whether duplicate was checked earlier */
 	rctx = (struct ext_duplicate_context *)
@@ -99,24 +162,30 @@
 
 	if ( rctx == NULL ) {
 		/* Create context */
-		pool = sieve_message_context_pool(renv->msgctx);
-		rctx = p_new(pool, struct ext_duplicate_context, 1);
+		msg_pool = sieve_message_context_pool(renv->msgctx);
+		rctx = p_new(msg_pool, struct ext_duplicate_context, 1);
 		sieve_message_context_extension_set(renv->msgctx, this_ext, (void *)rctx);
 	} else {
 		if ( handle == NULL ) {
 			if ( rctx->nohandle_checked  ) {
 				/* Already checked for duplicate */
-				return rctx->nohandle_duplicate;
+				return ( rctx->nohandle_duplicate ? 1 : 0 );
 			}
 		} else if ( array_is_created(&rctx->handles) ) {
 			const struct ext_duplicate_handle *record;
 			array_foreach (&rctx->handles, record) {
 				if ( strcmp(record->handle, str_c(handle)) == 0 )
-					return record->duplicate;
+					return ( record->duplicate ? 1 : 0 );
 			}
 		}
 	}		
 
+	result_pool = sieve_result_pool(renv->result);
+	act = p_new(result_pool, struct act_duplicate_mark_data, 1);
+	if (handle != NULL)
+		act->handle = p_strdup(result_pool, str_c(handle));
+	act->period = period;
+
 	/* Create hash */
 	md5_init(&ctx);
 	md5_update(&ctx, id, strlen(id));
@@ -127,31 +196,35 @@
 		md5_update(&ctx, "default", 7);
 	}
 	md5_update(&ctx, value, value_len);
-	md5_final(&ctx, dupl_hash);
+	md5_final(&ctx, act->hash);
 
 	/* Check duplicate */
-	duplicate = sieve_action_duplicate_check
-		(senv, dupl_hash, sizeof(dupl_hash));
+	duplicate = sieve_action_duplicate_check(senv, act->hash, sizeof(act->hash));
 
-	/* Create/refresh entry */
-	sieve_action_duplicate_mark
-		(senv, dupl_hash, sizeof(dupl_hash), ioloop_time + period);
+	/* We may only mark the message as duplicate when Sieve script executes
+	 * successfully; therefore defer this operation until successful result
+	 * execution.
+	 */
+	if ( sieve_result_add_action
+		(renv, NULL, &act_duplicate_mark, NULL, (void *) act, 0, FALSE) < 0 )
+		return -1;
 
+	/* Cache result */
 	if ( handle == NULL ) {
 		rctx->nohandle_duplicate = duplicate;
 		rctx->nohandle_checked = TRUE;
 	} else {
 		struct ext_duplicate_handle *record;
 		
-		if ( pool == NULL )
-			pool = sieve_message_context_pool(renv->msgctx);
+		if ( msg_pool == NULL )
+			msg_pool = sieve_message_context_pool(renv->msgctx);
 		if ( !array_is_created(&rctx->handles) )
-			p_array_init(&rctx->handles, pool, 64);
+			p_array_init(&rctx->handles, msg_pool, 64);
 		record = array_append_space(&rctx->handles);
-		record->handle = p_strdup(pool, str_c(handle));
+		record->handle = p_strdup(msg_pool, str_c(handle));
 		record->duplicate = duplicate;
 	}
 
-	return duplicate;
+	return ( duplicate ? 1 : 0 );
 }
 
diff -r 3a972efe012b -r 762b6a885897 src/lib-sieve/plugins/vnd.dovecot/duplicate/ext-duplicate-common.h
--- a/src/lib-sieve/plugins/vnd.dovecot/duplicate/ext-duplicate-common.h	Wed Oct 17 02:15:04 2012 +0200
+++ b/src/lib-sieve/plugins/vnd.dovecot/duplicate/ext-duplicate-common.h	Wed Oct 17 02:55:07 2012 +0200
@@ -38,7 +38,7 @@
  * Duplicate checking
  */
 
-bool ext_duplicate_check
+int ext_duplicate_check
 	(const struct sieve_runtime_env *renv, string_t *handle,
 		const char *value, size_t value_len, sieve_number_t period);
 
diff -r 3a972efe012b -r 762b6a885897 src/lib-sieve/plugins/vnd.dovecot/duplicate/tst-duplicate.c
--- a/src/lib-sieve/plugins/vnd.dovecot/duplicate/tst-duplicate.c	Wed Oct 17 02:15:04 2012 +0200
+++ b/src/lib-sieve/plugins/vnd.dovecot/duplicate/tst-duplicate.c	Wed Oct 17 02:55:07 2012 +0200
@@ -343,7 +343,9 @@
 	if (val == NULL) {
 		duplicate = FALSE;
 	} else {	
-		duplicate = ext_duplicate_check(renv, handle, val, val_len, seconds);
+		if ((ret=ext_duplicate_check(renv, handle, val, val_len, seconds)) < 0)
+			return SIEVE_EXEC_FAILURE;
+		duplicate = ( ret > 0 );
 	}
 
 	/* Trace */


More information about the dovecot-cvs mailing list