diff --git a/src/lib-sieve/plugins/imapflags/ext-imapflags-common.c b/src/lib-sieve/plugins/imapflags/ext-imapflags-common.c index 2f8d498aeded05b33d74ccf5920bc8817d4e406f..6ed55b5013780292a3ea4fa0892a6bc80db8e364 100644 --- a/src/lib-sieve/plugins/imapflags/ext-imapflags-common.c +++ b/src/lib-sieve/plugins/imapflags/ext-imapflags-common.c @@ -254,12 +254,19 @@ static string_t *_get_flags_string /* Initialization */ -void ext_imapflags_runtime_init(const struct sieve_runtime_env *renv) +static void ext_imapflags_runtime_init + (const struct sieve_runtime_env *renv, void *context ATTR_UNUSED) { sieve_result_add_implicit_side_effect (renv->result, &act_store, &flags_side_effect, NULL); } +struct sieve_interpreter_extension imapflags_interpreter_extension = { + &imapflags_extension, + ext_imapflags_runtime_init, + NULL, +}; + /* Flag operations */ /* FIXME: This currently accepts a potentially unlimited number of diff --git a/src/lib-sieve/plugins/imapflags/ext-imapflags-common.h b/src/lib-sieve/plugins/imapflags/ext-imapflags-common.h index b50d7fb82669526fd0fbaeae40a9b47f9187d59d..ed820ea6374b20abbb69bd00a30b217485b67f03 100644 --- a/src/lib-sieve/plugins/imapflags/ext-imapflags-common.h +++ b/src/lib-sieve/plugins/imapflags/ext-imapflags-common.h @@ -45,10 +45,6 @@ void ext_imapflags_attach_flags_tag const struct sieve_operand flags_side_effect_operand; -/* Initialization */ - -void ext_imapflags_runtime_init(const struct sieve_runtime_env *renv); - /* Flag registration */ struct ext_imapflags_iter { diff --git a/src/lib-sieve/plugins/imapflags/ext-imapflags.c b/src/lib-sieve/plugins/imapflags/ext-imapflags.c index 273c7f98765050e5b9f5e01154975a18e1d6e3bf..259949838a80144e45a56877cf60f91196c10b43 100644 --- a/src/lib-sieve/plugins/imapflags/ext-imapflags.c +++ b/src/lib-sieve/plugins/imapflags/ext-imapflags.c @@ -25,14 +25,17 @@ #include "ext-imapflags-common.h" -/* Forward declarations */ +/* + * Forward declarations + */ static bool ext_imapflags_load(int ext_id); static bool ext_imapflags_validator_load(struct sieve_validator *valdtr); -static bool ext_imapflags_runtime_load - (const struct sieve_runtime_env *renv); +static bool ext_imapflags_interpreter_load(struct sieve_interpreter *interp); -/* Operations */ +/* + * Operations + */ extern const struct sieve_operation setflag_operation; extern const struct sieve_operation addflag_operation; @@ -42,12 +45,17 @@ extern const struct sieve_operation hasflag_operation; const struct sieve_operation *imapflags_operations[] = { &setflag_operation, &addflag_operation, &removeflag_operation, &hasflag_operation }; -/* Operands */ +/* + * Operands + */ -const struct sieve_operand flags_side_effect_operand; +extern const struct sieve_operand flags_side_effect_operand; /* Extension definitions */ +extern const struct sieve_interpreter_extension + imapflags_interpreter_extension; + int ext_imapflags_my_id; const struct sieve_extension imapflags_extension = { @@ -55,9 +63,9 @@ const struct sieve_extension imapflags_extension = { &ext_imapflags_my_id, ext_imapflags_load, ext_imapflags_validator_load, - NULL, NULL, - ext_imapflags_runtime_load, - NULL, NULL, + NULL, + ext_imapflags_interpreter_load, + NULL, NULL, NULL, SIEVE_EXT_DEFINE_OPERATIONS(imapflags_operations), SIEVE_EXT_DEFINE_OPERAND(flags_side_effect_operand) }; @@ -92,11 +100,12 @@ static bool ext_imapflags_validator_load * Interpreter context */ -static bool ext_imapflags_runtime_load - (const struct sieve_runtime_env *renv) +static bool ext_imapflags_interpreter_load +(struct sieve_interpreter *interp) { - ext_imapflags_runtime_init(renv); - + sieve_interpreter_extension_register + (interp, &imapflags_interpreter_extension, NULL); + return TRUE; } diff --git a/src/lib-sieve/plugins/include/ext-include-common.c b/src/lib-sieve/plugins/include/ext-include-common.c index e191b8796f2e0f17f35f9f03554f77f55a8bb8cf..e097080e3d2e9f2eaec893655d7ab51beed667c8 100644 --- a/src/lib-sieve/plugins/include/ext-include-common.c +++ b/src/lib-sieve/plugins/include/ext-include-common.c @@ -44,6 +44,8 @@ struct ext_include_interpreter_context { unsigned int inc_block_id; bool returned; struct ext_include_interpreter_context *parent; + + struct sieve_variable_storage *global_variables; }; /* @@ -218,8 +220,24 @@ void ext_include_register_generator_context * Interpreter context management */ +static void ext_include_runtime_init + (const struct sieve_runtime_env *renv, void *context) +{ + struct ext_include_interpreter_context *ctx = + (struct ext_include_interpreter_context *) context; + + sieve_ext_variables_set_storage + (renv->interp, ctx->global_variables, &include_extension); +} + +static struct sieve_interpreter_extension include_interpreter_extension = { + &include_extension, + ext_include_runtime_init, + NULL, +}; + static struct ext_include_interpreter_context * - ext_include_create_interpreter_context + ext_include_interpreter_context_create (struct sieve_interpreter *interp, struct ext_include_interpreter_context *parent, struct sieve_script *script, unsigned int block_id) @@ -232,11 +250,15 @@ static struct ext_include_interpreter_context * ctx->interp = interp; ctx->script = script; ctx->block_id = block_id; - if ( parent == NULL ) + + if ( parent == NULL ) { ctx->nesting_level = 0; - else + ctx->global_variables = sieve_variable_storage_create(pool, NULL); + } else { ctx->nesting_level = parent->nesting_level + 1; - + ctx->global_variables = parent->global_variables; + } + return ctx; } @@ -249,15 +271,16 @@ static inline struct ext_include_interpreter_context * } static inline struct ext_include_interpreter_context * - ext_include_initialize_interpreter_context + ext_include_interpreter_context_init_child (struct sieve_interpreter *interp, struct ext_include_interpreter_context *parent, struct sieve_script *script, unsigned int block_id) { struct ext_include_interpreter_context *ctx = - ext_include_create_interpreter_context(interp, parent, script, block_id); + ext_include_interpreter_context_create(interp, parent, script, block_id); - sieve_interpreter_extension_set_context(interp, &include_extension, ctx); + sieve_interpreter_extension_register + (interp, &include_interpreter_extension, ctx); return ctx; } @@ -267,14 +290,18 @@ void ext_include_interpreter_context_init { struct ext_include_interpreter_context *ctx = ext_include_get_interpreter_context(interp); - struct sieve_script *script = sieve_interpreter_script(interp); - + + /* Is this is the top-level interpreter ? */ if ( ctx == NULL ) { - ctx = ext_include_create_interpreter_context + struct sieve_script *script; + + /* Initialize top context */ + script = sieve_interpreter_script(interp); + ctx = ext_include_interpreter_context_create (interp, NULL, script, SBIN_SYSBLOCK_MAIN_PROGRAM); - sieve_interpreter_extension_set_context - (interp, &include_extension, (void *) ctx); + sieve_interpreter_extension_register + (interp, &include_interpreter_extension, (void *) ctx); } } @@ -431,7 +458,6 @@ bool ext_include_execute_include struct sieve_error_handler *ehandler = sieve_interpreter_get_error_handler(renv->interp); struct sieve_interpreter *subinterp; - struct sieve_variable_storage *varstrg; unsigned int this_block_id; bool interrupted = FALSE; @@ -441,13 +467,9 @@ bool ext_include_execute_include */ subinterp = sieve_interpreter_create (renv->sbin, ehandler, renv->trace_stream); - curctx = ext_include_initialize_interpreter_context + curctx = ext_include_interpreter_context_init_child (subinterp, ctx, NULL, block_id); - - /* Create variable storage for global variables */ - varstrg = sieve_ext_variables_get_storage(renv->interp, &include_extension); - sieve_ext_variables_set_storage(subinterp, varstrg, &include_extension); - + /* Activate and start the top-level included script */ if ( sieve_binary_block_set_active(renv->sbin, block_id, &this_block_id) ) result = ( sieve_interpreter_start @@ -496,7 +518,7 @@ bool ext_include_execute_include /* Create sub-interpreter */ subinterp = sieve_interpreter_create (renv->sbin, ehandler, renv->trace_stream); - curctx = ext_include_initialize_interpreter_context + curctx = ext_include_interpreter_context_init_child (subinterp, curctx, NULL, curctx->inc_block_id); /* Activate the sub-include's block */ diff --git a/src/lib-sieve/plugins/variables/ext-variables-common.c b/src/lib-sieve/plugins/variables/ext-variables-common.c index dafdec1d85a0c63dd6bb9f86d324d98ac2927adc..10d1f520003a04d8a4388315d39772fc7e0bb9db 100644 --- a/src/lib-sieve/plugins/variables/ext-variables-common.c +++ b/src/lib-sieve/plugins/variables/ext-variables-common.c @@ -214,15 +214,18 @@ struct sieve_variable * const *sieve_variable_scope_get_variables struct sieve_variable_storage { pool_t pool; + struct sieve_variable_scope *scope; ARRAY_DEFINE(var_values, string_t *); }; -struct sieve_variable_storage *sieve_variable_storage_create(pool_t pool) +struct sieve_variable_storage *sieve_variable_storage_create +(pool_t pool, struct sieve_variable_scope *scope) { struct sieve_variable_storage *storage; storage = p_new(pool, struct sieve_variable_storage, 1); storage->pool = pool; + storage->scope = scope; p_array_init(&storage->var_values, pool, 4); @@ -374,7 +377,7 @@ ext_variables_interpreter_context_create(struct sieve_interpreter *interp) struct ext_variables_interpreter_context *ctx; ctx = p_new(pool, struct ext_variables_interpreter_context, 1); - ctx->local_storage = sieve_variable_storage_create(pool); + ctx->local_storage = sieve_variable_storage_create(pool, NULL); p_array_init(&ctx->ext_storages, pool, sieve_extensions_get_count()); sieve_interpreter_extension_set_context @@ -402,7 +405,8 @@ ext_variables_interpreter_context_get(struct sieve_interpreter *interp) } struct sieve_variable_storage *sieve_ext_variables_get_storage - (struct sieve_interpreter *interp, const struct sieve_extension *ext) +(struct sieve_interpreter *interp, const struct sieve_extension *ext, + bool create) { struct ext_variables_interpreter_context *ctx = ext_variables_interpreter_context_get(interp); @@ -420,12 +424,17 @@ struct sieve_variable_storage *sieve_ext_variables_get_storage } if ( storage == NULL || *storage == NULL ) { - pool_t pool = sieve_interpreter_pool(interp); - struct sieve_variable_storage *strg = sieve_variable_storage_create(pool); + if ( create ) { + pool_t pool = sieve_interpreter_pool(interp); + struct sieve_variable_storage *strg = + sieve_variable_storage_create(pool, NULL); - array_idx_set(&ctx->ext_storages, (unsigned int) ext_id, &strg); + array_idx_set(&ctx->ext_storages, (unsigned int) ext_id, &strg); - return strg; + return strg; + } + + return NULL; } return *storage; diff --git a/src/lib-sieve/plugins/variables/ext-variables-operands.c b/src/lib-sieve/plugins/variables/ext-variables-operands.c index 1d95e57130753c9f0bbbe0b9a5164e1e30ded8ae..c50ee0e57e8089a477af22009c1eba83df6f21e6 100644 --- a/src/lib-sieve/plugins/variables/ext-variables-operands.c +++ b/src/lib-sieve/plugins/variables/ext-variables-operands.c @@ -88,7 +88,7 @@ static bool opr_variable_read_value if ( !sieve_binary_read_extension(renv->sbin, address, &code, &ext) ) return FALSE; - storage = sieve_ext_variables_get_storage(renv->interp, ext); + storage = sieve_ext_variables_get_storage(renv->interp, ext, FALSE); if ( storage == NULL ) return FALSE; @@ -123,7 +123,7 @@ bool sieve_variable_operand_read_data if ( !sieve_binary_read_extension(renv->sbin, address, &code, &ext) ) return FALSE; - *storage = sieve_ext_variables_get_storage(renv->interp, ext); + *storage = sieve_ext_variables_get_storage(renv->interp, ext, FALSE); if ( *storage == NULL ) return FALSE; diff --git a/src/lib-sieve/plugins/variables/sieve-ext-variables.h b/src/lib-sieve/plugins/variables/sieve-ext-variables.h index c4540d909140e331d2a4dcf1a6468829c85a0560..d93e602e21ea6ff1257fa42e0c24b7c58ed45ae4 100644 --- a/src/lib-sieve/plugins/variables/sieve-ext-variables.h +++ b/src/lib-sieve/plugins/variables/sieve-ext-variables.h @@ -71,7 +71,8 @@ struct sieve_variable * const *sieve_variable_scope_get_variables struct sieve_variable_storage; -struct sieve_variable_storage *sieve_variable_storage_create(pool_t pool); +struct sieve_variable_storage *sieve_variable_storage_create + (pool_t pool, struct sieve_variable_scope *scope); void sieve_variable_get (struct sieve_variable_storage *storage, unsigned int index, string_t **value); @@ -92,7 +93,8 @@ struct sieve_variable_scope *sieve_ext_variables_get_main_scope (struct sieve_validator *validator); struct sieve_variable_storage *sieve_ext_variables_get_storage - (struct sieve_interpreter *interp, const struct sieve_extension *ext); + (struct sieve_interpreter *interp, const struct sieve_extension *ext, + bool create); void sieve_ext_variables_set_storage (struct sieve_interpreter *interp, struct sieve_variable_storage *storage, const struct sieve_extension *ext); diff --git a/src/lib-sieve/sieve-interpreter.c b/src/lib-sieve/sieve-interpreter.c index e5de43fa7ed40e5e72f86ae0852d4a5e1173da03..2d6df31714e14b862efd861a90b056a856a5588c 100644 --- a/src/lib-sieve/sieve-interpreter.c +++ b/src/lib-sieve/sieve-interpreter.c @@ -113,7 +113,7 @@ void sieve_interpreter_free(struct sieve_interpreter **interp) sieve_error_handler_unref(&(*interp)->ehandler); - /* Signal registered extensions that the validator is being destroyed */ + /* Signal registered extensions that the interpreter is being destroyed */ extrs = array_get(&(*interp)->extensions, &ext_count); for ( i = 0; i < ext_count; i++ ) { if ( extrs[i].int_ext != NULL && extrs[i].int_ext->free != NULL ) @@ -431,9 +431,8 @@ int sieve_interpreter_start const struct sieve_script_env *senv, struct sieve_message_context *msgctx, struct sieve_result *result, bool *interrupted) { - struct sieve_binary *sbin = interp->runenv.sbin; - unsigned int i; - int idx; + const struct sieve_interpreter_extension_reg *extrs; + unsigned int ext_count, i; interp->runenv.msgdata = msgdata; interp->runenv.result = result; @@ -445,23 +444,13 @@ int sieve_interpreter_start interp->runenv.msgctx = msgctx; sieve_message_context_ref(msgctx); } - - /* Pre-load core language features implemented as 'extensions' */ - for ( i = 0; i < sieve_preloaded_extensions_count; i++ ) { - const struct sieve_extension *ext = sieve_preloaded_extensions[i]; - - if ( ext->runtime_load != NULL ) - (void)ext->runtime_load(&interp->runenv); - } - /* Load other extensions listed in the binary */ - for ( idx = 0; idx < sieve_binary_extensions_count(sbin); idx++ ) { - const struct sieve_extension *ext = - sieve_binary_extension_get_by_index(sbin, idx); - - if ( ext->runtime_load != NULL ) - ext->runtime_load(&interp->runenv); - } + /* Signal registered extensions that the interpreter is being run */ + extrs = array_get(&interp->extensions, &ext_count); + for ( i = 0; i < ext_count; i++ ) { + if ( extrs[i].int_ext != NULL && extrs[i].int_ext->run != NULL ) + extrs[i].int_ext->run(&interp->runenv, extrs[i].context); + } return sieve_interpreter_continue(interp, interrupted); } diff --git a/src/lib-sieve/sieve-interpreter.h b/src/lib-sieve/sieve-interpreter.h index eae9bdd17903f0dc4b6ff5f72aa8463b357aaa8f..e68e1aaa9ea5c9fd5cdd2ed4f55c5559e52a87f1 100644 --- a/src/lib-sieve/sieve-interpreter.h +++ b/src/lib-sieve/sieve-interpreter.h @@ -100,6 +100,7 @@ void _sieve_runtime_trace_error struct sieve_interpreter_extension { const struct sieve_extension *ext; + void (*run)(const struct sieve_runtime_env *renv, void *context); void (*free)(struct sieve_interpreter *interp, void *context); }; diff --git a/src/lib-sieve/sieve-match-types.c b/src/lib-sieve/sieve-match-types.c index 287fc61589da77e22f9800639e03f53e465b9c94..4ccdfde5c81cbd0e8dfa2b27e78497eeb8cbae06 100644 --- a/src/lib-sieve/sieve-match-types.c +++ b/src/lib-sieve/sieve-match-types.c @@ -132,6 +132,7 @@ static void mtch_interpreter_free struct sieve_interpreter_extension mtch_interpreter_extension = { &match_type_extension, + NULL, mtch_interpreter_free };