diff --git a/src/lib-sieve/sieve-result.c b/src/lib-sieve/sieve-result.c index 614fc5f21f72ce5da81cb0d31271b5facbc3527e..baffba9051873140f15c0ad85380d5d61c1d5360 100644 --- a/src/lib-sieve/sieve-result.c +++ b/src/lib-sieve/sieve-result.c @@ -1402,22 +1402,6 @@ sieve_result_implicit_keep_finalize(struct sieve_result_execution *rexec, return rexec->keep_status; } -int sieve_result_implicit_keep(struct sieve_result_execution *rexec, - struct sieve_error_handler *ehandler, - bool success) -{ - int ret; - - rexec->ehandler = ehandler; - - sieve_result_implicit_keep_execute(rexec, success); - ret = sieve_result_implicit_keep_finalize(rexec, success); - - sieve_action_execution_post(rexec); - - return ret; -} - bool sieve_result_executed(struct sieve_result *result) { return result->executed; @@ -1539,15 +1523,38 @@ sieve_result_transaction_finish(struct sieve_result_execution *rexec, bool last, sieve_action_execution_post(rexec); } -int sieve_result_execute(struct sieve_result_execution *rexec, +static void +sieve_result_execute_update_status(struct sieve_result_execution *rexec, + int status) +{ + switch (status) { + case SIEVE_EXEC_OK: + break; + case SIEVE_EXEC_TEMP_FAILURE: + rexec->status = status; + break; + case SIEVE_EXEC_BIN_CORRUPT: + i_unreached(); + case SIEVE_EXEC_FAILURE: + case SIEVE_EXEC_KEEP_FAILED: + if (rexec->status == SIEVE_EXEC_OK) + rexec->status = status; + break; + case SIEVE_EXEC_RESOURCE_LIMIT: + if (rexec->status != SIEVE_EXEC_TEMP_FAILURE) + rexec->status = status; + break; + } +} + +int sieve_result_execute(struct sieve_result_execution *rexec, int status, bool last, struct sieve_error_handler *ehandler, bool *keep_r) { const struct sieve_action_exec_env *aenv = &rexec->action_env; struct sieve_result *result = aenv->result; - int status = SIEVE_EXEC_OK, result_status; struct sieve_result_action *actions_head, *actions_tail; - int ret; + int result_status, ret; if (keep_r != NULL) *keep_r = FALSE; @@ -1562,24 +1569,31 @@ int sieve_result_execute(struct sieve_result_execution *rexec, actions_head = (result->last_attempted_action == NULL ? result->actions_head : result->last_attempted_action->next); + actions_tail = actions_head; result->last_attempted_action = result->actions_tail; - /* Transaction start */ + if (status != SIEVE_EXEC_OK) { + sieve_result_execute_update_status(rexec, status); + } else if (rexec->status == SIEVE_EXEC_OK) { + /* Transaction start */ - status = sieve_result_transaction_start(rexec, actions_head, - &actions_tail); + status = sieve_result_transaction_start(rexec, actions_head, + &actions_tail); - /* Transaction execute */ + /* Transaction execute */ - if (status == SIEVE_EXEC_OK) - status = sieve_result_transaction_execute(rexec, actions_head); - rexec->status = status; + if (status == SIEVE_EXEC_OK) { + status = sieve_result_transaction_execute(rexec, + actions_head); + } + sieve_result_execute_update_status(rexec, status); + } /* Transaction commit/rollback */ status = sieve_result_transaction_commit_or_rollback( rexec, status, actions_head, actions_tail); - rexec->status = status; + sieve_result_execute_update_status(rexec, status); /* Perform implicit keep if necessary */ @@ -1621,6 +1635,8 @@ int sieve_result_execute(struct sieve_result_execution *rexec, sieve_action_execution_post(rexec); rexec->ehandler = NULL; + rexec->status = result_status; + /* Merge explicit keep status into implicit keep for the next execution round. */ diff --git a/src/lib-sieve/sieve-result.h b/src/lib-sieve/sieve-result.h index 390b7613121a7dccef66d66c7c3ebab87365afd6..fa856e7977e6bda61b741ca2bd9fb5958943fc84 100644 --- a/src/lib-sieve/sieve-result.h +++ b/src/lib-sieve/sieve-result.h @@ -110,11 +110,7 @@ struct sieve_result_execution * sieve_result_execution_create(struct sieve_result *result, pool_t pool); void sieve_result_execution_destroy(struct sieve_result_execution **_rexec); -int sieve_result_implicit_keep(struct sieve_result_execution *rexec, - struct sieve_error_handler *ehandler, - bool success); - -int sieve_result_execute(struct sieve_result_execution *rexec, +int sieve_result_execute(struct sieve_result_execution *rexec, int status, bool last, struct sieve_error_handler *ehandler, bool *keep_r); diff --git a/src/lib-sieve/sieve.c b/src/lib-sieve/sieve.c index dde0d4bfd6a50c729a826fb5670a1df16a2e93f5..38a7f5bd26fec24f38399502d571fc7c1faf7c58 100644 --- a/src/lib-sieve/sieve.c +++ b/src/lib-sieve/sieve.c @@ -664,24 +664,7 @@ int sieve_execute(struct sieve_binary *sbin, caller. In that case no implicit keep is attempted, because the situation may be resolved. */ - if (ret > 0) { - /* Execute result */ - ret = sieve_result_execute(rexec, TRUE, action_ehandler, NULL); - } else if (ret == SIEVE_EXEC_FAILURE) { - /* Perform implicit keep if script failed with a normal runtime - error - */ - switch (sieve_result_implicit_keep(rexec, action_ehandler, - FALSE)) { - case SIEVE_EXEC_OK: - break; - case SIEVE_EXEC_TEMP_FAILURE: - ret = SIEVE_EXEC_TEMP_FAILURE; - break; - default: - ret = SIEVE_EXEC_KEEP_FAILED; - } - } + ret = sieve_result_execute(rexec, ret, TRUE, action_ehandler, NULL); sieve_result_execution_destroy(&rexec); @@ -794,15 +777,10 @@ sieve_multiscript_execute(struct sieve_multiscript *mscript, mscript->exec_env.flags = flags; if (mscript->status > 0) { - mscript->status = sieve_result_execute(mscript->rexec, FALSE, + mscript->status = sieve_result_execute(mscript->rexec, + SIEVE_EXEC_OK, FALSE, ehandler, &mscript->keep); - } else { - if (sieve_result_implicit_keep(mscript->rexec, ehandler, - FALSE) <= 0) - mscript->status = SIEVE_EXEC_KEEP_FAILED; - else - mscript->keep = TRUE; } } @@ -897,35 +875,31 @@ int sieve_multiscript_finish(struct sieve_multiscript **_mscript, return SIEVE_EXEC_OK; *_mscript = NULL; + switch (status) { + case SIEVE_EXEC_OK: + status = mscript->status; + break; + case SIEVE_EXEC_TEMP_FAILURE: + break; + case SIEVE_EXEC_BIN_CORRUPT: + case SIEVE_EXEC_FAILURE: + case SIEVE_EXEC_KEEP_FAILED: + case SIEVE_EXEC_RESOURCE_LIMIT: + if (mscript->status == SIEVE_EXEC_TEMP_FAILURE) + status = mscript->status; + break; + } + mscript->exec_env.flags = flags; sieve_result_set_keep_action(mscript->result, NULL, &act_store); - if (mscript->active) { - 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( - mscript->rexec, action_ehandler, TRUE)) { - case SIEVE_EXEC_OK: - mscript->keep = TRUE; - break; - case SIEVE_EXEC_TEMP_FAILURE: - if (!sieve_result_executed(mscript->result)) { - status = SIEVE_EXEC_TEMP_FAILURE; - break; - } - /* fall through */ - default: - status = SIEVE_EXEC_KEEP_FAILED; - } - } - } - - if (status != SIEVE_EXEC_TEMP_FAILURE) { - sieve_result_finish(mscript->rexec, action_ehandler, - (status == SIEVE_EXEC_OK)); + mscript->keep = FALSE; + if (mscript->teststream != NULL) + mscript->keep = TRUE; + else { + status = sieve_result_execute( + mscript->rexec, status, TRUE, action_ehandler, + &mscript->keep); } /* Cleanup */ diff --git a/src/sieve-tools/sieve-test.c b/src/sieve-tools/sieve-test.c index 08059cb7c1f9ec7d4f70d19a9dd69f6bcb1c93e7..5a4235c099a9861643b3a8a94fd4ff569a246a04 100644 --- a/src/sieve-tools/sieve-test.c +++ b/src/sieve-tools/sieve-test.c @@ -374,7 +374,6 @@ int main(int argc, char **argv) unsigned int i, count; struct sieve_multiscript *mscript; bool more = TRUE; - int result; if (execute) mscript = sieve_multiscript_start_execute( @@ -440,10 +439,8 @@ int main(int argc, char **argv) exflags); } - result = sieve_multiscript_finish( - &mscript, ehandler, exflags, ret); - - ret = (ret > 0 ? result : ret); + ret = sieve_multiscript_finish(&mscript, ehandler, + exflags, ret); } /* Run */ diff --git a/src/testsuite/testsuite-result.c b/src/testsuite/testsuite-result.c index 927b88492c92fcff1cc2e86fc3f3d5f5ce0b62ca..51be3ff35fb06e6623221d82ed41d8fdd82a9b77 100644 --- a/src/testsuite/testsuite-result.c +++ b/src/testsuite/testsuite-result.c @@ -100,7 +100,7 @@ bool testsuite_result_execute(const struct sieve_runtime_env *renv) } /* Execute the result */ - ret = sieve_result_execute(_testsuite_rexec, TRUE, + ret = sieve_result_execute(_testsuite_rexec, SIEVE_EXEC_OK, TRUE, testsuite_log_ehandler, NULL); return (ret > 0);