From a584bec08821f8e06dc44a8b8a2ce8f3cf71218a Mon Sep 17 00:00:00 2001
From: Stephan Bosch <stephan@rename-it.nl>
Date: Sat, 25 Jul 2009 01:42:50 +0200
Subject: [PATCH] Added means to get keep status from sieve execution through
 main Sieve library API.

---
 src/lib-sieve/sieve.c                    | 78 +++++++++++++++---------
 src/lib-sieve/sieve.h                    |  8 ++-
 src/plugins/lda-sieve/lda-sieve-plugin.c |  6 +-
 src/sieve-tools/sieve-filter.c           |  2 +-
 src/sieve-tools/sieve-test.c             |  8 ++-
 5 files changed, 64 insertions(+), 38 deletions(-)

diff --git a/src/lib-sieve/sieve.c b/src/lib-sieve/sieve.c
index 63089a5ff..8ce37650d 100644
--- a/src/lib-sieve/sieve.c
+++ b/src/lib-sieve/sieve.c
@@ -285,17 +285,22 @@ void sieve_dump(struct sieve_binary *sbin, struct ostream *stream)
 int sieve_test
 (struct sieve_binary *sbin, const struct sieve_message_data *msgdata,
 	const struct sieve_script_env *senv, struct sieve_error_handler *ehandler,
-	struct ostream *stream) 	
+	struct ostream *stream, bool *keep) 	
 {
 	struct sieve_result *result = NULL;
 	int ret;
+
+	if ( keep != NULL ) *keep = FALSE;
 	
 	/* Run the script */
 	ret = sieve_run(sbin, &result, msgdata, senv, ehandler);
 				
 	/* Print result if successful */
-	if ( ret > 0 ) 
-		ret = sieve_result_print(result, senv, stream, NULL);
+	if ( ret > 0 ) {
+		ret = sieve_result_print(result, senv, stream, keep);
+	} else if ( ret == 0 ) {
+		if ( keep != NULL ) *keep = TRUE;
+	}
 	
 	/* Cleanup */
 	sieve_result_unref(&result);
@@ -309,10 +314,13 @@ int sieve_test
 
 int sieve_execute
 (struct sieve_binary *sbin, const struct sieve_message_data *msgdata,
-	const struct sieve_script_env *senv, struct sieve_error_handler *ehandler)
+	const struct sieve_script_env *senv, struct sieve_error_handler *ehandler,
+	bool *keep)
 {
 	struct sieve_result *result = NULL;
 	int ret;
+
+	if ( keep != NULL ) *keep = FALSE;
 	
 	/* Run the script */
 	ret = sieve_run(sbin, &result, msgdata, senv, ehandler);
@@ -322,14 +330,15 @@ int sieve_execute
 	 *   In that case no implicit keep is attempted, because the situation may be 
 	 *   resolved.
 	 */
-	if ( ret >= 0 ) {
-		if ( ret > 0 ) 
-			/* Execute result */
-			ret = sieve_result_execute(result, NULL);
-		else {
-			/* Perform implicit keep if script failed with a normal runtime error */
-			if ( !sieve_result_implicit_keep(result) )
-				ret = SIEVE_EXEC_KEEP_FAILED;
+	if ( ret > 0 ) {
+		/* Execute result */
+		ret = sieve_result_execute(result, keep);
+	} else if ( ret == 0 ) {
+		/* Perform implicit keep if script failed with a normal runtime error */
+		if ( !sieve_result_implicit_keep(result) ) {
+			ret = SIEVE_EXEC_KEEP_FAILED;
+		} else {
+			if ( keep != NULL ) *keep = TRUE;
 		}
 	}
 	
@@ -351,6 +360,7 @@ struct sieve_multiscript {
 	int status;
 	bool active;
 	bool ended;
+	bool keep;
 
 	struct ostream *teststream;
 };
@@ -373,6 +383,7 @@ struct sieve_multiscript *sieve_multiscript_start_execute
 	mscript->scriptenv = senv;
 	mscript->status = SIEVE_EXEC_OK;
 	mscript->active = TRUE;
+	mscript->keep = TRUE;
 	
 	return mscript;
 }
@@ -390,35 +401,39 @@ struct sieve_multiscript *sieve_multiscript_start_test
 }
 
 static void sieve_multiscript_test
-(struct sieve_multiscript *mscript, struct sieve_error_handler *ehandler)
+(struct sieve_multiscript *mscript, struct sieve_error_handler *ehandler,
+	bool *keep)
 {						
-	bool keep = FALSE;
-
 	sieve_result_set_error_handler(mscript->result, ehandler);
 
-	mscript->status = sieve_result_print
-		(mscript->result, mscript->scriptenv, mscript->teststream, &keep);
+	if ( mscript->status > 0 ) {
+		mscript->status = sieve_result_print
+			(mscript->result, mscript->scriptenv, mscript->teststream, keep);
+	} else {
+		if ( keep != NULL ) *keep = TRUE;
+	}
 		
-	mscript->active = ( mscript->active && keep );
+	mscript->active = ( mscript->active && *keep );
 
 	sieve_result_mark_executed(mscript->result);
 }
 
 static void sieve_multiscript_execute
-(struct sieve_multiscript *mscript, struct sieve_error_handler *ehandler)
+(struct sieve_multiscript *mscript, struct sieve_error_handler *ehandler,
+	bool *keep)
 {
-	bool keep = FALSE;
-			
 	sieve_result_set_error_handler(mscript->result, ehandler);
 
-	if ( mscript->status > 0 )
-		mscript->status = sieve_result_execute(mscript->result, &keep);
-	else {
+	if ( mscript->status > 0 ) {
+		mscript->status = sieve_result_execute(mscript->result, keep);
+	} else {
 		if ( !sieve_result_implicit_keep(mscript->result) )
 			mscript->status = SIEVE_EXEC_KEEP_FAILED;
+		else
+			if ( keep != NULL ) *keep = TRUE;			
 	}
 	
-	mscript->active = ( mscript->active && keep );
+	mscript->active = ( mscript->active && *keep );
 }
 
 bool sieve_multiscript_run
@@ -435,10 +450,12 @@ bool sieve_multiscript_run
 		mscript->scriptenv, ehandler);
 
 	if ( mscript->status >= 0 ) {
+		mscript->keep = FALSE;
+
 		if ( mscript->teststream != NULL ) 
-			sieve_multiscript_test(mscript, ehandler);
+			sieve_multiscript_test(mscript, ehandler, &mscript->keep);
 		else
-			sieve_multiscript_execute(mscript, ehandler);
+			sieve_multiscript_execute(mscript, ehandler, &mscript->keep);
 
 		if ( final ) mscript->active = FALSE;
 	}	
@@ -455,7 +472,7 @@ int sieve_multiscript_status(struct sieve_multiscript *mscript)
 }
 
 int sieve_multiscript_finish(struct sieve_multiscript **mscript, 
-	struct sieve_error_handler *ehandler)
+	struct sieve_error_handler *ehandler, bool *keep)
 {
 	struct sieve_result *result = (*mscript)->result;
 	int ret = (*mscript)->status;
@@ -467,11 +484,16 @@ int sieve_multiscript_finish(struct sieve_multiscript **mscript,
 		ret = SIEVE_EXEC_FAILURE;
 
 		if ( (*mscript)->teststream ) {
+			(*mscript)->keep = TRUE;
 		} else {
 			if ( !sieve_result_implicit_keep((*mscript)->result) )
 				ret = SIEVE_EXEC_KEEP_FAILED;
+			else
+				(*mscript)->keep = TRUE;
 		}
 	}
+
+	if ( keep != NULL ) *keep = (*mscript)->keep;
 	
 	/* Cleanup */
 	sieve_result_unref(&result);
diff --git a/src/lib-sieve/sieve.h b/src/lib-sieve/sieve.h
index 7648e8262..a8d09ed3f 100644
--- a/src/lib-sieve/sieve.h
+++ b/src/lib-sieve/sieve.h
@@ -100,7 +100,7 @@ void sieve_dump(struct sieve_binary *sbin, struct ostream *stream);
 int sieve_test
 	(struct sieve_binary *sbin, const struct sieve_message_data *msgdata, 
 		const struct sieve_script_env *senv, struct sieve_error_handler *ehandler, 
-		struct ostream *stream);
+		struct ostream *stream, bool *keep);
 
 /*
  * Script execution
@@ -112,7 +112,8 @@ int sieve_test
  */
 int sieve_execute
 	(struct sieve_binary *sbin, const struct sieve_message_data *msgdata,
-		const struct sieve_script_env *senv, struct sieve_error_handler *ehandler);
+		const struct sieve_script_env *senv, struct sieve_error_handler *ehandler,
+		bool *keep);
 		
 /*
  * Multiscript support
@@ -133,7 +134,8 @@ bool sieve_multiscript_run
 int sieve_multiscript_status(struct sieve_multiscript *mscript);
 
 int sieve_multiscript_finish
-	(struct sieve_multiscript **mscript, struct sieve_error_handler *ehandler);
+	(struct sieve_multiscript **mscript, struct sieve_error_handler *ehandler,
+		bool *keep);
 
 /*
  * Script directory
diff --git a/src/plugins/lda-sieve/lda-sieve-plugin.c b/src/plugins/lda-sieve/lda-sieve-plugin.c
index 1dd3904d7..0ea73f8d0 100644
--- a/src/plugins/lda-sieve/lda-sieve-plugin.c
+++ b/src/plugins/lda-sieve/lda-sieve-plugin.c
@@ -310,7 +310,7 @@ static int lda_sieve_singlescript_execute
 		ehandler = srctx->master_ehandler;
 	}
 
-	ret = sieve_execute(sbin, srctx->msgdata, srctx->scriptenv, ehandler);
+	ret = sieve_execute(sbin, srctx->msgdata, srctx->scriptenv, ehandler, NULL);
 
 	sieve_error_handler_copy_masterlog(ehandler, FALSE);	
 
@@ -332,7 +332,7 @@ static int lda_sieve_singlescript_execute
 		if ( user_script )
         	sieve_error_handler_copy_masterlog(ehandler, TRUE);
 
-		ret = sieve_execute(sbin, srctx->msgdata, srctx->scriptenv, ehandler);
+		ret = sieve_execute(sbin, srctx->msgdata, srctx->scriptenv, ehandler, NULL);
 
 		sieve_error_handler_copy_masterlog(ehandler, FALSE);
 
@@ -433,7 +433,7 @@ static int lda_sieve_multiscript_execute
 	if ( user_script )	
 		sieve_error_handler_copy_masterlog(ehandler, TRUE);
 
-	ret = sieve_multiscript_finish(&mscript, ehandler);
+	ret = sieve_multiscript_finish(&mscript, ehandler, NULL);
 
 	sieve_error_handler_copy_masterlog(ehandler, FALSE);
 
diff --git a/src/sieve-tools/sieve-filter.c b/src/sieve-tools/sieve-filter.c
index 9ff267634..8c41ce5f3 100644
--- a/src/sieve-tools/sieve-filter.c
+++ b/src/sieve-tools/sieve-filter.c
@@ -60,7 +60,7 @@ static int filter_message
 	main_sbin = NULL;
 
 	/* Execute script */
-	return sieve_execute(sbin, &msgdata, senv, ehandler);
+	return sieve_execute(sbin, &msgdata, senv, ehandler, NULL);
 }
 
 static int filter_mailbox
diff --git a/src/sieve-tools/sieve-test.c b/src/sieve-tools/sieve-test.c
index e042c654e..7365f25c2 100644
--- a/src/sieve-tools/sieve-test.c
+++ b/src/sieve-tools/sieve-test.c
@@ -316,9 +316,11 @@ int main(int argc, char **argv)
 	
 			/* Execute/Test script */
 			if ( execute )
-				ret = sieve_execute(sbin, &msgdata, &scriptenv, ehandler);
+				ret = sieve_execute
+					(sbin, &msgdata, &scriptenv, ehandler, NULL);
 			else
-				ret = sieve_test(sbin, &msgdata, &scriptenv, ehandler, teststream);				
+				ret = sieve_test
+					(sbin, &msgdata, &scriptenv, ehandler, teststream, NULL);				
 		} else {
 			/* Multiple scripts */
 			const char *const *sfiles;
@@ -378,7 +380,7 @@ int main(int argc, char **argv)
 				sieve_multiscript_run(mscript, sbin, ehandler, TRUE);
 			}
 			
-			result = sieve_multiscript_finish(&mscript, ehandler);
+			result = sieve_multiscript_finish(&mscript, ehandler, NULL);
 			
 			ret = ret > 0 ? result : ret;
 		}
-- 
GitLab