From c061f3896cccb46fa3b4e471810eda49a11a288b Mon Sep 17 00:00:00 2001 From: Stephan Bosch <stephan@rename-it.nl> Date: Thu, 13 Dec 2007 22:59:24 +0100 Subject: [PATCH] First successful (single level) execution of four consecutive includes. --- src/lib-sieve/plugins/include/cmd-include.c | 9 +- .../plugins/include/ext-include-common.c | 94 +++++++++++++++++++ .../plugins/include/ext-include-common.h | 7 ++ src/lib-sieve/plugins/include/ext-include.c | 16 +++- src/lib-sieve/sieve-interpreter.c | 28 ++++-- src/lib-sieve/sieve-interpreter.h | 14 ++- src/lib-sieve/sieve.c | 4 +- 7 files changed, 158 insertions(+), 14 deletions(-) diff --git a/src/lib-sieve/plugins/include/cmd-include.c b/src/lib-sieve/plugins/include/cmd-include.c index b5e6186b4..c128e79d3 100644 --- a/src/lib-sieve/plugins/include/cmd-include.c +++ b/src/lib-sieve/plugins/include/cmd-include.c @@ -240,8 +240,13 @@ static bool opc_include_dump static bool opc_include_execute (const struct sieve_opcode *opcode ATTR_UNUSED, const struct sieve_runtime_env *renv, sieve_size_t *address) -{ - return TRUE; +{ + int block; + + if ( !sieve_binary_read_offset(renv->sbin, address, &block) ) + return FALSE; + + return ext_include_execute_include(renv, (unsigned int) block); } diff --git a/src/lib-sieve/plugins/include/ext-include-common.c b/src/lib-sieve/plugins/include/ext-include-common.c index be669d741..4f188b462 100644 --- a/src/lib-sieve/plugins/include/ext-include-common.c +++ b/src/lib-sieve/plugins/include/ext-include-common.c @@ -5,6 +5,7 @@ #include "sieve-binary.h" #include "sieve-commands.h" #include "sieve-generator.h" +#include "sieve-interpreter.h" #include "ext-include-common.h" @@ -28,6 +29,16 @@ struct ext_include_binary_context { struct hash_table *included_scripts; }; +/* Interpreter context */ + +struct ext_include_interpreter_context { + struct sieve_interpreter *interp; + unsigned int nesting_level; + struct sieve_script *script; + unsigned int block_id; + struct ext_include_interpreter_context *parent; +}; + /* Main context management */ static struct ext_include_main_context *ext_include_create_main_context @@ -187,6 +198,62 @@ static bool ext_include_script_is_included return TRUE; } +/* Interpreter context management */ + +static struct ext_include_interpreter_context * + ext_include_create_interpreter_context +(struct sieve_interpreter *interp, + struct ext_include_interpreter_context *parent, + struct sieve_script *script, unsigned int block_id) +{ + struct ext_include_interpreter_context *ctx; + + pool_t pool = sieve_interpreter_pool(interp); + ctx = p_new(pool, struct ext_include_interpreter_context, 1); + ctx->parent = parent; + ctx->script = script; + ctx->block_id = block_id; + if ( parent == NULL ) + ctx->nesting_level = 0; + else + ctx->nesting_level = parent->nesting_level + 1; + + return ctx; +} + +static inline struct ext_include_interpreter_context * + ext_include_get_interpreter_context +(struct sieve_interpreter *interp) +{ + return (struct ext_include_interpreter_context *) + sieve_interpreter_extension_get_context(interp, ext_include_my_id); +} + +static inline void ext_include_initialize_interpreter_context +(struct sieve_interpreter *interp, + struct ext_include_interpreter_context *parent, + struct sieve_script *script, unsigned int block_id) +{ + sieve_interpreter_extension_set_context(interp, ext_include_my_id, + ext_include_create_interpreter_context(interp, parent, script, block_id)); +} + +void ext_include_register_interpreter_context +(struct sieve_interpreter *interp) +{ + struct ext_include_interpreter_context *ctx = + ext_include_get_interpreter_context(interp); + struct sieve_script *script = sieve_interpreter_script(interp); + + if ( ctx == NULL ) { + ctx = ext_include_create_interpreter_context + (interp, NULL, script, SBIN_SYSBLOCK_MAIN_PROGRAM); + + sieve_interpreter_extension_set_context + (interp, ext_include_my_id, (void *) ctx); + } +} + /* Including a script during generation */ bool ext_include_generate_include @@ -296,3 +363,30 @@ bool ext_include_generate_include return result; } +/* Executing an included script during interpretation */ + +bool ext_include_execute_include + (const struct sieve_runtime_env *renv, unsigned int block_id) +{ + int result = TRUE; + struct ext_include_interpreter_context *ctx = + ext_include_get_interpreter_context(renv->interp); + struct sieve_error_handler *ehandler = + sieve_interpreter_get_error_handler(renv->interp); + struct sieve_interpreter *subinterp; + unsigned int this_block_id; + bool interrupted; + + this_block_id = sieve_binary_block_set_active(renv->sbin, block_id); + subinterp = sieve_interpreter_create(renv->sbin, ehandler); + ext_include_initialize_interpreter_context(subinterp, ctx, NULL, block_id); + + result = ( sieve_interpreter_start + (subinterp, renv->msgdata, renv->scriptenv, renv->result, &interrupted) + == 1 ); + + (void) sieve_binary_block_set_active(renv->sbin, this_block_id); + sieve_interpreter_free(&subinterp); + + return result; +} diff --git a/src/lib-sieve/plugins/include/ext-include-common.h b/src/lib-sieve/plugins/include/ext-include-common.h index 2401a229a..54e228f93 100644 --- a/src/lib-sieve/plugins/include/ext-include-common.h +++ b/src/lib-sieve/plugins/include/ext-include-common.h @@ -30,4 +30,11 @@ bool ext_include_generate_include void ext_include_binary_free(struct sieve_binary *sbin); +/* Interpreter */ + +void ext_include_register_interpreter_context + (struct sieve_interpreter *interp); +bool ext_include_execute_include + (const struct sieve_runtime_env *renv, unsigned int block_id); + #endif /* __EXT_INCLUDE_COMMON_H */ diff --git a/src/lib-sieve/plugins/include/ext-include.c b/src/lib-sieve/plugins/include/ext-include.c index d1d426be2..29373bd8f 100644 --- a/src/lib-sieve/plugins/include/ext-include.c +++ b/src/lib-sieve/plugins/include/ext-include.c @@ -35,6 +35,7 @@ static bool ext_include_load(int ext_id); static bool ext_include_validator_load(struct sieve_validator *validator); static bool ext_include_generator_load(struct sieve_generator *gentr); static bool ext_include_binary_load(struct sieve_binary *sbin); +static bool ext_include_interpreter_load(struct sieve_interpreter *interp); /* Commands */ @@ -58,7 +59,8 @@ const struct sieve_extension include_extension = { ext_include_load, ext_include_validator_load, ext_include_generator_load, - ext_include_binary_load, NULL, + ext_include_binary_load, + ext_include_interpreter_load, SIEVE_EXT_DEFINE_OPCODES(ext_include_opcodes), NULL }; @@ -96,6 +98,8 @@ static bool ext_include_generator_load(struct sieve_generator *gentr) return TRUE; } +/* Load extension into binary */ + static bool ext_include_binary_load(struct sieve_binary *sbin) { sieve_binary_extension_set(sbin, ext_include_my_id, &include_binary_ext); @@ -103,3 +107,13 @@ static bool ext_include_binary_load(struct sieve_binary *sbin) return TRUE; } +/* Load extension into interpreter */ + +static bool ext_include_interpreter_load(struct sieve_interpreter *interp) +{ + ext_include_register_interpreter_context(interp); + + return TRUE; +} + + diff --git a/src/lib-sieve/sieve-interpreter.c b/src/lib-sieve/sieve-interpreter.c index 5aba90f7a..926ec1fce 100644 --- a/src/lib-sieve/sieve-interpreter.c +++ b/src/lib-sieve/sieve-interpreter.c @@ -54,6 +54,7 @@ struct sieve_interpreter *sieve_interpreter_create interp->runenv.interp = interp; interp->runenv.sbin = sbin; + interp->runenv.script = sieve_binary_script(sbin); sieve_binary_ref(sbin); interp->pc = 0; @@ -80,10 +81,13 @@ struct sieve_interpreter *sieve_interpreter_create return interp; } -void sieve_interpreter_free(struct sieve_interpreter *interp) +void sieve_interpreter_free(struct sieve_interpreter **interp) { - sieve_binary_unref(&interp->runenv.sbin); - pool_unref(&(interp->pool)); + sieve_binary_unref(&(*interp)->runenv.sbin); + + pool_unref(&((*interp)->pool)); + + *interp = NULL; } inline pool_t sieve_interpreter_pool(struct sieve_interpreter *interp) @@ -91,6 +95,18 @@ inline pool_t sieve_interpreter_pool(struct sieve_interpreter *interp) return interp->pool; } +inline struct sieve_script *sieve_interpreter_script + (struct sieve_interpreter *interp) +{ + return interp->runenv.script; +} + +inline struct sieve_error_handler *sieve_interpreter_get_error_handler + (struct sieve_interpreter *interp) +{ + return interp->ehandler; +} + /* Error handling */ /* This is not particularly user friendly, so we might want to consider storing @@ -304,11 +320,11 @@ int sieve_interpreter_continue int sieve_interpreter_start (struct sieve_interpreter *interp, const struct sieve_message_data *msgdata, - const struct sieve_script_env *senv, struct sieve_result **result, + const struct sieve_script_env *senv, struct sieve_result *result, bool *interrupted) { interp->runenv.msgdata = msgdata; - interp->runenv.result = *result; + interp->runenv.result = result; interp->runenv.scriptenv = senv; return sieve_interpreter_continue(interp, interrupted); @@ -328,7 +344,7 @@ int sieve_interpreter_run sieve_result_ref(*result); } - ret = sieve_interpreter_start(interp, msgdata, senv, result, NULL); + ret = sieve_interpreter_start(interp, msgdata, senv, *result, NULL); if ( ret >= 0 && is_topmost ) { ret = sieve_result_execute(*result, msgdata, senv); diff --git a/src/lib-sieve/sieve-interpreter.h b/src/lib-sieve/sieve-interpreter.h index 972d315d4..4c7c4c29c 100644 --- a/src/lib-sieve/sieve-interpreter.h +++ b/src/lib-sieve/sieve-interpreter.h @@ -15,7 +15,9 @@ struct sieve_interpreter; struct sieve_runtime_env { struct sieve_interpreter *interp; + struct sieve_script *script; struct sieve_binary *sbin; + const struct sieve_message_data *msgdata; const struct sieve_script_env *scriptenv; struct sieve_result *result; @@ -23,8 +25,14 @@ struct sieve_runtime_env { struct sieve_interpreter *sieve_interpreter_create (struct sieve_binary *sbin, struct sieve_error_handler *ehandler); -void sieve_interpreter_free(struct sieve_interpreter *interp); -inline pool_t sieve_interpreter_pool(struct sieve_interpreter *interp); +void sieve_interpreter_free(struct sieve_interpreter **interp); + +inline pool_t sieve_interpreter_pool + (struct sieve_interpreter *interp); +inline struct sieve_script *sieve_interpreter_script + (struct sieve_interpreter *interp); +inline struct sieve_error_handler *sieve_interpreter_get_error_handler + (struct sieve_interpreter *interp); inline void sieve_interpreter_reset (struct sieve_interpreter *interp); @@ -73,7 +81,7 @@ int sieve_interpreter_continue (struct sieve_interpreter *interp, bool *interrupted); int sieve_interpreter_start (struct sieve_interpreter *interp, const struct sieve_message_data *msgdata, - const struct sieve_script_env *senv, struct sieve_result **result, + const struct sieve_script_env *senv, struct sieve_result *result, bool *interrupted); int sieve_interpreter_run (struct sieve_interpreter *interp, const struct sieve_message_data *msgdata, diff --git a/src/lib-sieve/sieve.c b/src/lib-sieve/sieve.c index 2dd1732b5..185aeab23 100644 --- a/src/lib-sieve/sieve.c +++ b/src/lib-sieve/sieve.c @@ -184,7 +184,7 @@ int sieve_test if ( ret > 0 ) ret = sieve_result_print(sres); - sieve_interpreter_free(interp); + sieve_interpreter_free(&interp); sieve_result_unref(&sres); return ret; } @@ -201,7 +201,7 @@ int sieve_execute ret = sieve_interpreter_run(interp, msgdata, senv, &sres); - sieve_interpreter_free(interp); + sieve_interpreter_free(&interp); sieve_result_unref(&sres); return ret; } -- GitLab