From 6cdfe4f4cdd92cd68f1a34c013fe1aa2c8cab123 Mon Sep 17 00:00:00 2001
From: Stephan Bosch <stephan@rename-it.nl>
Date: Thu, 1 Jan 2009 19:37:26 +0100
Subject: [PATCH] Multiscript: resolved inter-script action conflict
 situations.

---
 src/lib-sieve/ext-reject.c                    | 34 +++++++++++++------
 src/lib-sieve/plugins/vacation/cmd-vacation.c | 28 ++++++++++-----
 src/lib-sieve/sieve-result.c                  | 11 +++++-
 3 files changed, 52 insertions(+), 21 deletions(-)

diff --git a/src/lib-sieve/ext-reject.c b/src/lib-sieve/ext-reject.c
index a45cb8ee8..8f05591ab 100644
--- a/src/lib-sieve/ext-reject.c
+++ b/src/lib-sieve/ext-reject.c
@@ -253,10 +253,14 @@ static int act_reject_check_duplicate
 	const struct sieve_action_data *act, 
 	const struct sieve_action_data *act_other)
 {
-	sieve_runtime_error(renv, act->location, 
-		"duplicate reject action not allowed "
-		"(previously triggered one was here: %s)", act_other->location);	
-	return -1;
+	if ( !act_other->executed ) {
+		sieve_runtime_error(renv, act->location, 
+			"duplicate reject action not allowed "
+			"(previously triggered one was here: %s)", act_other->location);	
+		return -1;
+	}
+	
+	return 1;
 }
  
 int act_reject_check_conflict
@@ -265,19 +269,27 @@ int act_reject_check_conflict
 	const struct sieve_action_data *act_other)
 {
 	if ( (act_other->action->flags & SIEVE_ACTFLAG_TRIES_DELIVER) > 0 ) {
-		sieve_runtime_error(renv, act->location, 
+		if ( !act_other->executed ) {
+			sieve_runtime_error(renv, act->location, 
 			"reject action conflicts with earlier triggered action: "
 			"the %s action (%s) tries to deliver the message",
 			act_other->action->name, act_other->location);	
-		return -1;
+			return -1;
+		}
+		
+		return 1;
 	}
 
 	if ( (act_other->action->flags & SIEVE_ACTFLAG_SENDS_RESPONSE) > 0 ) {
-		sieve_runtime_error(renv, act->location, 
-			"reject action conflicts with earlier triggered action: "
-			"the %s action (%s) also sends a response to the sender",
-			act_other->action->name, act_other->location);	
-		return -1;
+		if ( !act_other->executed ) {
+			sieve_runtime_error(renv, act->location, 
+				"reject action conflicts with earlier triggered action: "
+				"the %s action (%s) also sends a response to the sender",
+				act_other->action->name, act_other->location);	
+			return -1;
+		}
+		
+		return 1;
 	}
 	
 	return 0;
diff --git a/src/lib-sieve/plugins/vacation/cmd-vacation.c b/src/lib-sieve/plugins/vacation/cmd-vacation.c
index 22020ea28..85e271a49 100644
--- a/src/lib-sieve/plugins/vacation/cmd-vacation.c
+++ b/src/lib-sieve/plugins/vacation/cmd-vacation.c
@@ -685,10 +685,15 @@ static int act_vacation_check_duplicate
 	const struct sieve_action_data *act, 
 	const struct sieve_action_data *act_other)
 {
-	sieve_runtime_error(renv, act->location, 
-		"duplicate vacation action not allowed "
-		"(previously triggered one was here: %s)", act_other->location);
-	return -1;
+	if ( !act_other->executed ) {
+		sieve_runtime_error(renv, act->location, 
+			"duplicate vacation action not allowed "
+			"(previously triggered one was here: %s)", act_other->location);
+		return -1;
+	}
+
+	/* Not an error if executed in preceeding script */
+	return 1;
 }
 
 int act_vacation_check_conflict
@@ -697,11 +702,16 @@ int act_vacation_check_conflict
 	const struct sieve_action_data *act_other)
 {
 	if ( (act_other->action->flags & SIEVE_ACTFLAG_SENDS_RESPONSE) > 0 ) {
-		sieve_runtime_error(renv, act->location, 
-			"vacation action conflicts with earlier triggered action: "
-			"the %s action (%s) also sends a response back to the sender",	
-			act_other->action->name, act_other->location);
-		return -1;
+		if ( !act_other->executed ) {
+			sieve_runtime_error(renv, act->location, 
+				"vacation action conflicts with earlier triggered action: "
+				"the %s action (%s) also sends a response back to the sender",	
+				act_other->action->name, act_other->location);
+			return -1;
+		} else {
+			/* Not an error if executed in preceeding script */
+			return 1;
+		}
 	}
 
 	return 0;
diff --git a/src/lib-sieve/sieve-result.c b/src/lib-sieve/sieve-result.c
index c0dda7670..4a9535226 100644
--- a/src/lib-sieve/sieve-result.c
+++ b/src/lib-sieve/sieve-result.c
@@ -335,7 +335,11 @@ static int _sieve_result_add_action
 		const struct sieve_action *oact = raction->data.action;
 		
 		if ( keep && raction->keep ) {
+		
+			/* Duplicate keep */
 			if ( raction->data.executed ) {
+				/* Keep action from preceeding execution */
+			
 				kaction = raction;
 			
 				/* Detach existing keep action */
@@ -352,7 +356,10 @@ static int _sieve_result_add_action
 						(renv, action, seffects, kaction->seffects)) <= 0 )	 
 						return ret;
 				}
+				
 			} else {
+				/* True duplicate */
+				
 				return sieve_result_side_effects_merge
 					(renv, action, raction->seffects, seffects);
 			}
@@ -374,11 +381,13 @@ static int _sieve_result_add_action
 						 * into a keep.
 						 */
 						if ( (ret=sieve_result_side_effects_merge
-							(renv, action, raction->seffects, seffects)) <= 0 ) 
+							(renv, action, raction->seffects, seffects)) < 0 ) 
 							return ret;
 						raction->keep = TRUE;
 						raction->data.context = NULL;
 						raction->data.location = p_strdup(result->pool, act_data.location);
+						
+						return 1;
 					} else {
 						/* Merge side-effects, but don't add new action */
 						return sieve_result_side_effects_merge
-- 
GitLab