From e6af7659a1b1032a1d104778ca859f455189bcb2 Mon Sep 17 00:00:00 2001
From: Stephan Bosch <stephan.bosch@open-xchange.com>
Date: Fri, 9 Apr 2021 02:12:53 +0200
Subject: [PATCH] lib-sieve: sieve - Merge sieve_multiscript_tempfail() into
 sieve_multiscript_finish().

---
 src/lib-sieve/sieve.c                         | 69 ++++---------------
 src/lib-sieve/sieve.h                         |  5 +-
 .../imap-filter-sieve/imap-filter-sieve.c     |  9 ++-
 src/plugins/imapsieve/imap-sieve.c            |  9 ++-
 src/plugins/lda-sieve/lda-sieve-plugin.c      | 11 ++-
 src/sieve-tools/sieve-test.c                  |  2 +-
 src/testsuite/testsuite-script.c              |  2 +-
 7 files changed, 34 insertions(+), 73 deletions(-)

diff --git a/src/lib-sieve/sieve.c b/src/lib-sieve/sieve.c
index 4851e6980..aa730b9dc 100644
--- a/src/lib-sieve/sieve.c
+++ b/src/lib-sieve/sieve.c
@@ -878,50 +878,9 @@ int sieve_multiscript_status(struct sieve_multiscript *mscript)
 	return mscript->status;
 }
 
-int sieve_multiscript_tempfail(struct sieve_multiscript **_mscript,
-			       struct sieve_error_handler *action_ehandler,
-			       enum sieve_execute_flags flags)
-{
-	struct sieve_multiscript *mscript = *_mscript;
-
-	if (mscript == NULL)
-		return SIEVE_EXEC_OK;
-	*_mscript = NULL;
-
-	struct sieve_result *result = mscript->result;
-	int ret = mscript->status;
-
-	mscript->exec_env.flags = flags;
-	sieve_result_set_keep_action(mscript->result, NULL, &act_store);
-
-	if (mscript->active) {
-		ret = SIEVE_EXEC_TEMP_FAILURE;
-
-		if (mscript->teststream == NULL &&
-		    sieve_result_executed(result)) {
-			/* Part of the result is already executed, need to fall
-			   back to to implicit keep (FIXME)
-			 */
-			switch (sieve_result_implicit_keep(
-				result, action_ehandler, FALSE)) {
-			case SIEVE_EXEC_OK:
-				ret = SIEVE_EXEC_FAILURE;
-				break;
-			default:
-				ret = SIEVE_EXEC_KEEP_FAILED;
-			}
-		}
-	}
-
-	/* Cleanup */
-	sieve_multiscript_destroy(&mscript);
-
-	return ret;
-}
-
 int sieve_multiscript_finish(struct sieve_multiscript **_mscript,
 			     struct sieve_error_handler *action_ehandler,
-			     enum sieve_execute_flags flags)
+			     enum sieve_execute_flags flags, int status)
 {
 	struct sieve_multiscript *mscript = *_mscript;
 
@@ -929,39 +888,41 @@ int sieve_multiscript_finish(struct sieve_multiscript **_mscript,
 		return SIEVE_EXEC_OK;
 	*_mscript = NULL;
 
-	struct sieve_result *result = mscript->result;
-	int ret = mscript->status;
-
 	mscript->exec_env.flags = flags;
 	sieve_result_set_keep_action(mscript->result, NULL, &act_store);
 
 	if (mscript->active) {
-		if (mscript->teststream != NULL)
-			mscript->keep = TRUE;
-		else {
+		if (mscript->teststream != NULL) {
+			if (status != SIEVE_EXEC_TEMP_FAILURE)
+				mscript->keep = TRUE;
+		} else if (status != SIEVE_EXEC_TEMP_FAILURE ||
+			   sieve_result_executed(mscript->result)) {
 			switch (sieve_result_implicit_keep(
-				result, action_ehandler, TRUE)) {
+				mscript->result, action_ehandler, TRUE)) {
 			case SIEVE_EXEC_OK:
 				mscript->keep = TRUE;
 				break;
 			case SIEVE_EXEC_TEMP_FAILURE:
-				if (!sieve_result_executed(result)) {
-					ret = SIEVE_EXEC_TEMP_FAILURE;
+				if (!sieve_result_executed(mscript->result)) {
+					status = SIEVE_EXEC_TEMP_FAILURE;
 					break;
 				}
 				/* fall through */
 			default:
-				ret = SIEVE_EXEC_KEEP_FAILED;
+				status = SIEVE_EXEC_KEEP_FAILED;
 			}
 		}
 	}
 
-	sieve_result_finish(result, action_ehandler, (ret == SIEVE_EXEC_OK));
+	if (status != SIEVE_EXEC_TEMP_FAILURE) {
+		sieve_result_finish(mscript->result, action_ehandler,
+				    (status == SIEVE_EXEC_OK));
+	}
 
 	/* Cleanup */
 	sieve_multiscript_destroy(&mscript);
 
-	return ret;
+	return status;
 }
 
 /*
diff --git a/src/lib-sieve/sieve.h b/src/lib-sieve/sieve.h
index f4acafe91..3c47e2041 100644
--- a/src/lib-sieve/sieve.h
+++ b/src/lib-sieve/sieve.h
@@ -182,12 +182,9 @@ void sieve_multiscript_run_discard(struct sieve_multiscript *mscript,
 
 int sieve_multiscript_status(struct sieve_multiscript *mscript);
 
-int sieve_multiscript_tempfail(struct sieve_multiscript **_mscript,
-			       struct sieve_error_handler *action_ehandler,
-			       enum sieve_execute_flags flags);
 int sieve_multiscript_finish(struct sieve_multiscript **_mscript,
 			     struct sieve_error_handler *action_ehandler,
-			     enum sieve_execute_flags flags);
+			     enum sieve_execute_flags flags, int status);
 
 /*
  * Configured limits
diff --git a/src/plugins/imap-filter-sieve/imap-filter-sieve.c b/src/plugins/imap-filter-sieve/imap-filter-sieve.c
index eb68057d4..fe6e4a81e 100644
--- a/src/plugins/imap-filter-sieve/imap-filter-sieve.c
+++ b/src/plugins/imap-filter-sieve/imap-filter-sieve.c
@@ -872,15 +872,18 @@ imap_sieve_filter_run_scripts(struct imap_filter_sieve_context *sctx,
 	ehandler = (user_ehandler != NULL ?
 		user_ehandler : ifsuser->master_ehandler);
 	if (compile_error == SIEVE_ERROR_TEMP_FAILURE) {
-		ret = sieve_multiscript_tempfail(&mscript, ehandler, exflags);
+		ret = sieve_multiscript_finish(&mscript, ehandler, exflags,
+					       SIEVE_EXEC_TEMP_FAILURE);
 	} else if (rusage_exceeded) {
 		i_assert(last_script != NULL);
-		(void)sieve_multiscript_tempfail(&mscript, ehandler, exflags);
+		(void)sieve_multiscript_finish(&mscript, ehandler, exflags,
+					       SIEVE_EXEC_TEMP_FAILURE);
 		sieve_error(ehandler, sieve_script_name(last_script),
 			    "cumulative resource usage limit exceeded");
 		ret = SIEVE_EXEC_RESOURCE_LIMIT;
 	} else {
-		ret = sieve_multiscript_finish(&mscript, ehandler, exflags);
+		ret = sieve_multiscript_finish(&mscript, ehandler, exflags,
+					       SIEVE_EXEC_OK);
 	}
 
 	/* Don't log additional messages about compile failure */
diff --git a/src/plugins/imapsieve/imap-sieve.c b/src/plugins/imapsieve/imap-sieve.c
index 480d3847b..e5b08947b 100644
--- a/src/plugins/imapsieve/imap-sieve.c
+++ b/src/plugins/imapsieve/imap-sieve.c
@@ -793,15 +793,18 @@ imap_sieve_run_scripts(struct imap_sieve_run *isrun,
 	ehandler = (isrun->user_ehandler != NULL ?
 		    isrun->user_ehandler : isieve->master_ehandler);
 	if (compile_error == SIEVE_ERROR_TEMP_FAILURE) {
-		ret = sieve_multiscript_tempfail(&mscript, ehandler, exflags);
+		ret = sieve_multiscript_finish(&mscript, ehandler, exflags,
+					       SIEVE_EXEC_TEMP_FAILURE);
 	} else if (rusage_exceeded) {
 		i_assert(last_script != NULL);
-		(void)sieve_multiscript_tempfail(&mscript, ehandler, exflags);
+		(void)sieve_multiscript_finish(&mscript, ehandler, exflags,
+					       SIEVE_EXEC_TEMP_FAILURE);
 		sieve_error(ehandler, sieve_script_name(last_script),
 			    "cumulative resource usage limit exceeded");
 		ret = SIEVE_EXEC_RESOURCE_LIMIT;
 	} else {
-		ret = sieve_multiscript_finish(&mscript, ehandler, exflags);
+		ret = sieve_multiscript_finish(&mscript, ehandler, exflags,
+					       SIEVE_EXEC_OK);
 	}
 
 	/* Don't log additional messages about compile failure */
diff --git a/src/plugins/lda-sieve/lda-sieve-plugin.c b/src/plugins/lda-sieve/lda-sieve-plugin.c
index 98b5b2f2e..60b3b1885 100644
--- a/src/plugins/lda-sieve/lda-sieve-plugin.c
+++ b/src/plugins/lda-sieve/lda-sieve-plugin.c
@@ -663,13 +663,10 @@ static int lda_sieve_execute_scripts(struct lda_sieve_run_context *srctx)
 	/* Finish execution */
 	exec_ehandler = (srctx->user_ehandler != NULL ?
 			 srctx->user_ehandler : srctx->master_ehandler);
-	if (error == SIEVE_ERROR_TEMP_FAILURE) {
-		ret = sieve_multiscript_tempfail(&mscript, exec_ehandler,
-						 exflags);
-	} else {
-		ret = sieve_multiscript_finish(&mscript, exec_ehandler,
-					       exflags);
-	}
+	ret = sieve_multiscript_finish(&mscript, exec_ehandler, exflags,
+				       (error == SIEVE_ERROR_TEMP_FAILURE ?
+					SIEVE_EXEC_TEMP_FAILURE :
+					SIEVE_EXEC_OK));
 
 	/* Don't log additional messages about compile failure */
 	if (error != SIEVE_ERROR_NONE && ret == SIEVE_EXEC_FAILURE) {
diff --git a/src/sieve-tools/sieve-test.c b/src/sieve-tools/sieve-test.c
index c5d7523d2..08059cb7c 100644
--- a/src/sieve-tools/sieve-test.c
+++ b/src/sieve-tools/sieve-test.c
@@ -441,7 +441,7 @@ int main(int argc, char **argv)
 			}
 
 			result = sieve_multiscript_finish(
-				&mscript, ehandler, exflags);
+				&mscript, ehandler, exflags, ret);
 
 			ret = (ret > 0 ? result : ret);
 		}
diff --git a/src/testsuite/testsuite-script.c b/src/testsuite/testsuite-script.c
index 3cfaafab0..7c89ecd24 100644
--- a/src/testsuite/testsuite-script.c
+++ b/src/testsuite/testsuite-script.c
@@ -251,5 +251,5 @@ bool testsuite_script_multiscript(const struct sieve_runtime_env *renv,
 	}
 
 	return (sieve_multiscript_finish(&mscript, testsuite_log_ehandler,
-					 0) > 0 && result);
+					 0, SIEVE_EXEC_OK) > 0 && result);
 }
-- 
GitLab