From 88c1edae6591dc592d35e38a665bc50906206d31 Mon Sep 17 00:00:00 2001
From: Stephan Bosch <stephan@rename-it.nl>
Date: Mon, 26 Nov 2007 17:09:54 +0100
Subject: [PATCH] Added support for avoiding duplicate actions in the sieve
 result.

---
 sieve/tests/redirect.sieve   |  1 +
 src/lib-sieve/cmd-keep.c     |  4 ++--
 src/lib-sieve/cmd-redirect.c | 19 ++++++++++++++++++-
 src/lib-sieve/sieve-result.c | 23 ++++++++++++++++++++++-
 src/lib-sieve/sieve-result.h |  5 ++++-
 5 files changed, 47 insertions(+), 5 deletions(-)

diff --git a/sieve/tests/redirect.sieve b/sieve/tests/redirect.sieve
index 57ced4ae3..6d02c6edc 100644
--- a/sieve/tests/redirect.sieve
+++ b/sieve/tests/redirect.sieve
@@ -1,5 +1,6 @@
 if address :contains "to" "vestingbar" {
 	redirect "stephan@example.com";
+	keep;
 }
 
 redirect "stephan@rename-it.nl";
diff --git a/src/lib-sieve/cmd-keep.c b/src/lib-sieve/cmd-keep.c
index 99838fb74..6335f3eff 100644
--- a/src/lib-sieve/cmd-keep.c
+++ b/src/lib-sieve/cmd-keep.c
@@ -51,7 +51,7 @@ static int act_keep_execute
 		
 const struct sieve_action act_keep = {
 	"keep",
-	NULL,
+	NULL, NULL,
 	act_keep_execute
 };
 
@@ -88,7 +88,7 @@ static bool opc_keep_execute
 /*
  * Action
  */
-
+ 
 static int act_keep_execute
 (const struct sieve_action *action ATTR_UNUSED, 
 	const struct sieve_action_exec_env *aenv, void *context)
diff --git a/src/lib-sieve/cmd-redirect.c b/src/lib-sieve/cmd-redirect.c
index 31de529ac..d8f1eff42 100644
--- a/src/lib-sieve/cmd-redirect.c
+++ b/src/lib-sieve/cmd-redirect.c
@@ -50,6 +50,9 @@ const struct sieve_opcode cmd_redirect_opcode = {
 
 /* Redirect action */
 
+static bool act_redirect_check_duplicate
+	(const struct sieve_action *action1 ATTR_UNUSED, void *context1, 
+		void *context2);
 static void act_redirect_print
 	(const struct sieve_action *action, void *context);	
 static int act_redirect_execute
@@ -62,6 +65,7 @@ struct act_redirect_context {
 
 const struct sieve_action act_redirect = {
 	"redirect",
+	act_redirect_check_duplicate, 
 	act_redirect_print,
 	act_redirect_execute
 };
@@ -146,8 +150,21 @@ static bool cmd_redirect_opcode_execute
 }
 
 /*
- * Action
+ * Actionstatic bool act_redirect_check_duplicate
+(const struct sieve_action *action1 ATTR_UNUSED, void *context1, void *context2)
  */
+ 
+static bool act_redirect_check_duplicate
+(const struct sieve_action *action1 ATTR_UNUSED, void *context1, void *context2)
+{
+	struct act_redirect_context *ctx1 = (struct act_redirect_context *) context1;
+	struct act_redirect_context *ctx2 = (struct act_redirect_context *) context2;
+	
+	if ( strcmp(ctx1->to_address, ctx2->to_address) == 0 ) 
+		return TRUE;
+		
+	return FALSE;
+}
 
 static void act_redirect_print
 (const struct sieve_action *action ATTR_UNUSED, void *context)	
diff --git a/src/lib-sieve/sieve-result.c b/src/lib-sieve/sieve-result.c
index 30e49dc6c..cd1bc4f03 100644
--- a/src/lib-sieve/sieve-result.c
+++ b/src/lib-sieve/sieve-result.c
@@ -59,11 +59,30 @@ inline pool_t sieve_result_pool(struct sieve_result *result)
 	return result->pool;
 }
 
-void sieve_result_add_action
+bool sieve_result_add_action
 (struct sieve_result *result, const struct sieve_action *action, void *context)		
 {
 	struct sieve_result_action *raction;
 	
+	/* First, check for duplicates */
+	raction = result->first_action;
+	while ( raction != NULL ) {
+		if ( raction->action == action ) {
+			const struct sieve_action *oact = raction->action;
+			
+			if ( oact->check_duplicate != NULL ) {
+				if ( oact->check_duplicate(action, raction->context, context) )
+					return FALSE;
+			} else 
+				return FALSE; 
+		}
+		raction = raction->next;
+	}
+	
+	/* Check for conflicts */
+	
+	/* FIXME: Unimplemented */
+	
 	/* Create new action object */
 	raction = p_new(result->pool, struct sieve_result_action, 1);
 	raction->action = action;
@@ -81,6 +100,8 @@ void sieve_result_add_action
 		result->last_action = raction;
 		raction->next = NULL;
 	}	
+	
+	return TRUE;
 }	
 
 bool sieve_result_print(struct sieve_result *result)
diff --git a/src/lib-sieve/sieve-result.h b/src/lib-sieve/sieve-result.h
index 6790cad49..4165171c1 100644
--- a/src/lib-sieve/sieve-result.h
+++ b/src/lib-sieve/sieve-result.h
@@ -13,6 +13,9 @@ struct sieve_action_exec_env {
 struct sieve_action {
 	const char *name;
 
+	bool (*check_duplicate)	
+		(const struct sieve_action *action1, void *context1, void *context2);	
+
 	void (*print)
 		(const struct sieve_action *action, void *context);	
 	int (*execute)
@@ -25,7 +28,7 @@ void sieve_result_ref(struct sieve_result *result);
 void sieve_result_unref(struct sieve_result **result); 
 inline pool_t sieve_result_pool(struct sieve_result *result);
 
-void sieve_result_add_action
+bool sieve_result_add_action
 	(struct sieve_result *result, const struct sieve_action *action, 
 		void *context);		
 
-- 
GitLab