From df1bb2870b9e9e6f800ca3a4ff21befbfa6d9ca3 Mon Sep 17 00:00:00 2001 From: Stephan Bosch <stephan@rename-it.nl> Date: Thu, 6 Dec 2007 02:26:57 +0100 Subject: [PATCH] Implemented implicit keep to execute when not canceled or when the preceeding action execution fails. --- src/lib-sieve/ext-fileinto.c | 2 +- src/lib-sieve/sieve-interpreter.c | 2 +- src/lib-sieve/sieve-result.c | 51 ++++++++++++++++++++++++++++--- src/sieve-bin/bin-common.c | 1 + src/sieve-bin/sieve-exec.c | 6 +++- 5 files changed, 55 insertions(+), 7 deletions(-) diff --git a/src/lib-sieve/ext-fileinto.c b/src/lib-sieve/ext-fileinto.c index 5fd761797..365247b3d 100644 --- a/src/lib-sieve/ext-fileinto.c +++ b/src/lib-sieve/ext-fileinto.c @@ -157,7 +157,7 @@ static bool ext_fileinto_opcode_execute return FALSE; t_push(); - + if ( !sieve_opr_string_read(renv->sbin, address, &folder) ) { t_pop(); return FALSE; diff --git a/src/lib-sieve/sieve-interpreter.c b/src/lib-sieve/sieve-interpreter.c index 18cfe5ba9..7978d8e5f 100644 --- a/src/lib-sieve/sieve-interpreter.c +++ b/src/lib-sieve/sieve-interpreter.c @@ -214,7 +214,7 @@ bool sieve_interpreter_handle_optional_operands (const struct sieve_runtime_env *renv, sieve_size_t *address, struct sieve_side_effects_list **list) { - int opt_code; + int opt_code = -1; if ( sieve_operand_optional_present(renv->sbin, address) ) { while ( opt_code != 0 ) { diff --git a/src/lib-sieve/sieve-result.c b/src/lib-sieve/sieve-result.c index 356d97d53..2d7dad57a 100644 --- a/src/lib-sieve/sieve-result.c +++ b/src/lib-sieve/sieve-result.c @@ -211,6 +211,33 @@ bool sieve_result_print(struct sieve_result *result) return TRUE; } +static bool sieve_result_implicit_keep(struct sieve_result *result) +{ + bool success = TRUE; + bool dummy = TRUE; + struct act_store_context ctx; + void *tr_context; + + ctx.folder = result->action_env.mailenv->inbox; + + /* FIXME: Handle persistent side-effects for the (implicit) keep action */ + + success = act_store.start + (&act_store, &result->action_env, (void *) &ctx, &tr_context); + + success = success && act_store.execute + (&act_store, &result->action_env, tr_context); + + if ( success ) { + return act_store.commit + (&act_store, &result->action_env, tr_context, &dummy); + } + + act_store.rollback(&act_store, &result->action_env, tr_context, success); + + return FALSE; +} + bool sieve_result_execute (struct sieve_result *result, const struct sieve_message_data *msgdata, const struct sieve_mail_environment *menv) @@ -225,7 +252,7 @@ bool sieve_result_execute /* Transaction start */ - printf("\nTransaction start:\n"); + printf("\nTransaction start:\n"); /* REMOVEME */ rac = result->first_action; while ( success && rac != NULL ) { @@ -241,7 +268,7 @@ bool sieve_result_execute /* Transaction execute */ - printf("\nTransaction execute:\n"); + printf("\nTransaction execute:\n"); /* REMOVEME */ last_attempted = rac; rac = result->first_action; @@ -282,7 +309,7 @@ bool sieve_result_execute } /* Transaction commit/rollback */ - if ( success ) + if ( success ) /* REMOVEME */ printf("\nTransaction commit:\n"); else printf("\nTransaction rollback:\n"); @@ -334,9 +361,25 @@ bool sieve_result_execute rac = rac->next; } + /* REMOVEME */ printf("\nTransaction result: %s\n", commit_ok ? "success" : "failed"); + + /* Return value indicates whether the caller should attempt an implicit keep + * of its own. So, if the above transaction fails, but the implicit keep below + * succeeds, the return value is still true. An error is/should be logged + * though. + */ - return commit_ok; + /* Execute implicit keep if the transaction failed or when the implicit keep + * was not canceled during transaction. + */ + if ( !commit_ok || implicit_keep ) { + printf("Executing implicit keep\n"); + return sieve_result_implicit_keep(result); + } + + /* Unconditional success */ + return TRUE; } /* diff --git a/src/sieve-bin/bin-common.c b/src/sieve-bin/bin-common.c index 31415cf49..dbac28110 100644 --- a/src/sieve-bin/bin-common.c +++ b/src/sieve-bin/bin-common.c @@ -72,6 +72,7 @@ struct sieve_binary *bin_compile_sieve_script(const char *filename) struct sieve_binary *sbin; ehandler = sieve_stderr_ehandler_create(); + sieve_error_handler_accept_infolog(ehandler, TRUE); if ( (sbin = sieve_compile(filename, ehandler)) == NULL ) { sieve_error_handler_free(&ehandler); diff --git a/src/sieve-bin/sieve-exec.c b/src/sieve-bin/sieve-exec.c index 172d81907..82a7fcee2 100644 --- a/src/sieve-bin/sieve-exec.c +++ b/src/sieve-bin/sieve-exec.c @@ -186,9 +186,13 @@ int main(int argc, char **argv) mailenv.duplicate_check = duplicate_check; ehandler = sieve_stderr_ehandler_create(); + sieve_error_handler_accept_infolog(ehandler, TRUE); /* Run */ - sieve_execute(sbin, &msgdata, &mailenv, ehandler); + if ( sieve_execute(sbin, &msgdata, &mailenv, ehandler) ) + i_info("Final result: success\n"); + else + i_info("Final result: failed (caller please handle implicit keep!)\n"); sieve_error_handler_free(&ehandler); -- GitLab