From dd105ea5c7bd001472d4bded73b68963e42a0559 Mon Sep 17 00:00:00 2001 From: Stephan Bosch <stephan@rename-it.nl> Date: Sun, 6 Apr 2008 21:57:32 +0200 Subject: [PATCH] Include: merged import and export commands into a single implementation and implemented global variable storage. --- src/lib-sieve/plugins/include/Makefile.am | 3 +- src/lib-sieve/plugins/include/cmd-export.c | 94 ------------------- src/lib-sieve/plugins/include/cmd-import.c | 36 +++++-- .../plugins/include/ext-include-common.c | 5 + .../plugins/include/ext-include-variables.c | 77 +++++++-------- .../plugins/include/ext-include-variables.h | 9 +- .../plugins/include/include-variables.sieve | 6 ++ .../plugins/include/include-variables1.sieve | 5 + .../plugins/include/include-variables2.sieve | 5 + .../plugins/include/include-variables3.sieve | 11 +++ src/lib-sieve/plugins/variables/cmd-set.c | 3 +- .../plugins/variables/ext-variables-common.c | 81 +++++++++++++--- .../plugins/variables/ext-variables-common.h | 2 +- .../variables/ext-variables-operands.c | 64 ++++++++++--- .../plugins/variables/ext-variables.c | 4 - .../plugins/variables/sieve-ext-variables.h | 23 ++++- 16 files changed, 246 insertions(+), 182 deletions(-) delete mode 100644 src/lib-sieve/plugins/include/cmd-export.c create mode 100644 src/lib-sieve/plugins/include/include-variables3.sieve diff --git a/src/lib-sieve/plugins/include/Makefile.am b/src/lib-sieve/plugins/include/Makefile.am index 4a3e840ab..44236db11 100644 --- a/src/lib-sieve/plugins/include/Makefile.am +++ b/src/lib-sieve/plugins/include/Makefile.am @@ -11,8 +11,7 @@ AM_CPPFLAGS = \ cmds = \ cmd-include.c \ cmd-return.c \ - cmd-import.c \ - cmd-export.c + cmd-import.c libsieve_ext_include_la_SOURCES = \ $(cmds) \ diff --git a/src/lib-sieve/plugins/include/cmd-export.c b/src/lib-sieve/plugins/include/cmd-export.c deleted file mode 100644 index 6865f8c1d..000000000 --- a/src/lib-sieve/plugins/include/cmd-export.c +++ /dev/null @@ -1,94 +0,0 @@ -#include "lib.h" - -#include "sieve-code.h" -#include "sieve-commands.h" -#include "sieve-commands-private.h" -#include "sieve-validator.h" -#include "sieve-generator.h" -#include "sieve-interpreter.h" -#include "sieve-ext-variables.h" - -#include "ext-include-common.h" -#include "ext-include-variables.h" - -/* Forward declarations */ - -static bool cmd_export_validate - (struct sieve_validator *validator, struct sieve_command_context *cmd); - -/* Export command - * - * Syntax - * export - */ -const struct sieve_command cmd_export = { - "export", - SCT_COMMAND, - 1, 0, FALSE, FALSE, - NULL, NULL, - cmd_export_validate, - NULL, NULL -}; - -/* - * Validation - */ - -static bool cmd_export_validate - (struct sieve_validator *validator, struct sieve_command_context *cmd) -{ - struct sieve_ast_argument *arg = cmd->first_positional; - struct sieve_command_context *prev_context = - sieve_command_prev_context(cmd); - - /* Check valid command placement */ - if ( !sieve_command_is_toplevel(cmd) || - ( !sieve_command_is_first(cmd) && prev_context != NULL && - prev_context->command != &cmd_require && - prev_context->command != &cmd_import && - prev_context->command != &cmd_export) ) - { - sieve_command_validate_error(validator, cmd, - "export commands can only be placed at top level " - "at the beginning of the file after any require or import commands"); - return FALSE; - } - - if ( !sieve_ext_variables_is_active(validator) ) { - sieve_command_validate_error(validator, cmd, - "export command requires that variables extension is active"); - return FALSE; - } - - /* Register exported variable */ - if ( sieve_ast_argument_type(arg) == SAAT_STRING ) { - /* Single string */ - const char *variable = sieve_ast_argument_strc(arg); - - if ( !ext_include_variable_export(validator, cmd, variable) ) - return FALSE; - - } else if ( sieve_ast_argument_type(arg) == SAAT_STRING_LIST ) { - /* String list */ - struct sieve_ast_argument *stritem = sieve_ast_strlist_first(arg); - - while ( stritem != NULL ) { - const char *variable = sieve_ast_argument_strc(stritem); - - if ( !ext_include_variable_export(validator, cmd, variable) ) - return FALSE; - - stritem = sieve_ast_strlist_next(stritem); - } - } else { - /* Something else */ - sieve_command_validate_error(validator, cmd, - "the export command accepts a single string or string list argument, " - "but %s was found", - sieve_ast_argument_name(arg)); - return FALSE; - } - - (void)sieve_ast_arguments_detach(arg, 1); - return TRUE; -} diff --git a/src/lib-sieve/plugins/include/cmd-import.c b/src/lib-sieve/plugins/include/cmd-import.c index 0e7c5823d..9c2afe089 100644 --- a/src/lib-sieve/plugins/include/cmd-import.c +++ b/src/lib-sieve/plugins/include/cmd-import.c @@ -30,6 +30,20 @@ const struct sieve_command cmd_import = { NULL, NULL }; +/* Export command + * + * Syntax + * export + */ +const struct sieve_command cmd_export = { + "export", + SCT_COMMAND, + 1, 0, FALSE, FALSE, + NULL, NULL, + cmd_import_validate, + NULL, NULL +}; + /* * Validation */ @@ -45,17 +59,21 @@ static bool cmd_import_validate if ( !sieve_command_is_toplevel(cmd) || ( !sieve_command_is_first(cmd) && prev_context != NULL && prev_context->command != &cmd_require && - prev_context->command != &cmd_import) ) + prev_context->command != &cmd_import && + (cmd->command != &cmd_export || prev_context->command != &cmd_export) ) ) { sieve_command_validate_error(validator, cmd, - "import commands can only be placed at top level " - "at the beginning of the file after any require commands"); + "%s commands can only be placed at top level " + "at the beginning of the file after any require %scommands", + cmd->command->identifier, cmd->command == &cmd_export ? "or import " : ""); return FALSE; } + if ( !sieve_ext_variables_is_active(validator) ) { sieve_command_validate_error(validator, cmd, - "import command requires that variables extension is active"); + "%s command requires that variables extension is active", + cmd->command->identifier); return FALSE; } @@ -64,7 +82,8 @@ static bool cmd_import_validate /* Single string */ const char *variable = sieve_ast_argument_strc(arg); - if ( !ext_include_variable_import(validator, cmd, variable) ) + if ( !ext_include_variable_import_global + (validator, cmd, variable, cmd->command == &cmd_export) ) return FALSE; } else if ( sieve_ast_argument_type(arg) == SAAT_STRING_LIST ) { @@ -74,7 +93,8 @@ static bool cmd_import_validate while ( stritem != NULL ) { const char *variable = sieve_ast_argument_strc(stritem); - if ( !ext_include_variable_import(validator, cmd, variable) ) + if ( !ext_include_variable_import_global + (validator, cmd, variable, cmd->command == &cmd_export) ) return FALSE; stritem = sieve_ast_strlist_next(stritem); @@ -82,8 +102,8 @@ static bool cmd_import_validate } else { /* Something else */ sieve_command_validate_error(validator, cmd, - "the import command accepts a single string or string list argument, " - "but %s was found", + "the %s command accepts a single string or string list argument, " + "but %s was found", cmd->command->identifier, sieve_ast_argument_name(arg)); return FALSE; } diff --git a/src/lib-sieve/plugins/include/ext-include-common.c b/src/lib-sieve/plugins/include/ext-include-common.c index d54c8dff4..57fdc1ab9 100644 --- a/src/lib-sieve/plugins/include/ext-include-common.c +++ b/src/lib-sieve/plugins/include/ext-include-common.c @@ -306,6 +306,7 @@ 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; @@ -316,6 +317,10 @@ bool ext_include_execute_include subinterp = sieve_interpreter_create(renv->sbin, ehandler); curctx = ext_include_initialize_interpreter_context (subinterp, ctx, NULL, block_id); + + /* Create variable storage for global variables */ + varstrg = sieve_ext_variables_get_storage(renv->interp, ext_include_my_id); + sieve_ext_variables_set_storage(subinterp, varstrg, ext_include_my_id); /* Activate and start the top-level included script */ if ( sieve_binary_block_set_active(renv->sbin, block_id, &this_block_id) ) diff --git a/src/lib-sieve/plugins/include/ext-include-variables.c b/src/lib-sieve/plugins/include/ext-include-variables.c index e01275950..59f66279a 100644 --- a/src/lib-sieve/plugins/include/ext-include-variables.c +++ b/src/lib-sieve/plugins/include/ext-include-variables.c @@ -31,7 +31,7 @@ struct ext_include_ast_context *ext_include_create_ast_context pool_t pool = sieve_ast_pool(ast); ctx = p_new(pool, struct ext_include_ast_context, 1); - ctx->import_vars = sieve_variable_scope_create(pool); + ctx->import_vars = sieve_variable_scope_create(pool, ext_include_my_id); if ( parent != NULL ) { struct ext_include_ast_context *parent_ctx = @@ -62,50 +62,51 @@ static inline struct ext_include_ast_context * * Variable import-export */ -bool ext_include_variable_import +bool ext_include_variable_import_global (struct sieve_validator *valdtr, struct sieve_command_context *cmd, - const char *variable) -{ - struct ext_include_ast_context *ctx = - ext_include_get_ast_context(cmd->ast_node->ast); - - if ( ctx->global_vars == NULL || - sieve_variable_scope_get_variable(ctx->global_vars, variable, FALSE) - == NULL ) - { - sieve_command_validate_error(valdtr, cmd, - "importing unknown global variable '%s'", variable); - return FALSE; - } - - printf("VAR IMPORT: %s\n", variable); - (void)sieve_variable_scope_declare(ctx->import_vars, variable); - - return TRUE; -} - -bool ext_include_variable_export -(struct sieve_validator *valdtr, struct sieve_command_context *cmd, - const char *variable) + const char *variable, bool export) { struct sieve_ast *ast = cmd->ast_node->ast; struct ext_include_ast_context *ctx = ext_include_get_ast_context(ast); + struct sieve_variable_scope *main_scope; + struct sieve_variable *var; + + if ( export ) { + if ( sieve_variable_scope_get_variable(ctx->import_vars, variable, FALSE) + != NULL ) { + sieve_command_validate_error(valdtr, cmd, + "cannot export imported variable '%s'", variable); + return FALSE; + } - if ( sieve_variable_scope_get_variable(ctx->import_vars, variable, FALSE) - != NULL ) { - sieve_command_validate_error(valdtr, cmd, - "cannot export imported variable '%s'", variable); - return FALSE; - } - - if ( ctx->global_vars == NULL ) { - pool_t pool = sieve_ast_pool(ast); - ctx->global_vars = sieve_variable_scope_create(pool); - } + if ( ctx->global_vars == NULL ) { + pool_t pool = sieve_ast_pool(ast); + ctx->global_vars = sieve_variable_scope_create(pool, ext_include_my_id); + } + + printf("VAR EXPORT: %s\n", variable); + var = sieve_variable_scope_get_variable(ctx->global_vars, variable, TRUE); - printf("VAR EXPORT: %s\n", variable); + } else { + var = NULL; - (void)sieve_variable_scope_declare(ctx->global_vars, variable); + if ( ctx->global_vars != NULL ) { + var = sieve_variable_scope_get_variable + (ctx->global_vars, variable, FALSE); + } + + if ( var == NULL ) { + sieve_command_validate_error(valdtr, cmd, + "importing unknown global variable '%s'", variable); + return FALSE; + } + + printf("VAR IMPORT: %s\n", variable); + (void)sieve_variable_scope_declare(ctx->import_vars, variable); + } + + main_scope = sieve_ext_variables_get_main_scope(valdtr); + (void)sieve_variable_scope_import(main_scope, var); return TRUE; } diff --git a/src/lib-sieve/plugins/include/ext-include-variables.h b/src/lib-sieve/plugins/include/ext-include-variables.h index 0fefff051..e5aea5d86 100644 --- a/src/lib-sieve/plugins/include/ext-include-variables.h +++ b/src/lib-sieve/plugins/include/ext-include-variables.h @@ -2,6 +2,8 @@ #define __EXT_INCLUDE_VARIABLES_H #include "sieve-common.h" +#include "sieve-ext-variables.h" + #include "ext-include-common.h" /* @@ -15,12 +17,9 @@ struct ext_include_ast_context *ext_include_create_ast_context * Variable import-export */ -bool ext_include_variable_import - (struct sieve_validator *valdtr, struct sieve_command_context *cmd, - const char *variable); -bool ext_include_variable_export +bool ext_include_variable_import_global (struct sieve_validator *valdtr, struct sieve_command_context *cmd, - const char *variable); + const char *variable, bool export); #endif /* __EXT_INCLUDE_VARIABLES_H */ diff --git a/src/lib-sieve/plugins/include/include-variables.sieve b/src/lib-sieve/plugins/include/include-variables.sieve index 996c81aa6..fe655633f 100644 --- a/src/lib-sieve/plugins/include/include-variables.sieve +++ b/src/lib-sieve/plugins/include/include-variables.sieve @@ -1,8 +1,11 @@ require "include"; require "variables"; +require "fileinto"; export ["value1", "value2"]; export ["value3", "value4"]; +export ["result1", "result2"]; +export "result"; set "value1" "Works"; set "value2" "fine."; @@ -11,3 +14,6 @@ set "value4" "it does."; include "include-variables1"; include "include-variables2"; +include "include-variables3"; + +fileinto "${result}"; diff --git a/src/lib-sieve/plugins/include/include-variables1.sieve b/src/lib-sieve/plugins/include/include-variables1.sieve index ec4cd8885..91dab0b04 100644 --- a/src/lib-sieve/plugins/include/include-variables1.sieve +++ b/src/lib-sieve/plugins/include/include-variables1.sieve @@ -3,5 +3,10 @@ require "variables"; require "fileinto"; import ["value1", "value2"]; +export ["result1"]; fileinto "${value1} ${value2}"; + +set "result1" "${value1} ${value2}"; + +fileinto "RESULT: ${result1}"; diff --git a/src/lib-sieve/plugins/include/include-variables2.sieve b/src/lib-sieve/plugins/include/include-variables2.sieve index 1736dbd78..681c39749 100644 --- a/src/lib-sieve/plugins/include/include-variables2.sieve +++ b/src/lib-sieve/plugins/include/include-variables2.sieve @@ -4,5 +4,10 @@ require "fileinto"; import "value3"; import "value4"; +export "result2"; fileinto "${value3} ${value4}"; + +set "result2" "${value3} ${value4}"; + +fileinto "RESULT: ${result2}"; diff --git a/src/lib-sieve/plugins/include/include-variables3.sieve b/src/lib-sieve/plugins/include/include-variables3.sieve new file mode 100644 index 000000000..c7625bc59 --- /dev/null +++ b/src/lib-sieve/plugins/include/include-variables3.sieve @@ -0,0 +1,11 @@ +require "include"; +require "variables"; +require "fileinto"; + +import "result1"; +import "result2"; +export "result"; + +set "result" "${result1} ${result2}"; + +fileinto "RESULT: ${result}"; diff --git a/src/lib-sieve/plugins/variables/cmd-set.c b/src/lib-sieve/plugins/variables/cmd-set.c index 69d49d7e4..e4180228b 100644 --- a/src/lib-sieve/plugins/variables/cmd-set.c +++ b/src/lib-sieve/plugins/variables/cmd-set.c @@ -353,7 +353,8 @@ static bool cmd_set_operation_execute printf(">> SET\n"); /* Read the variable identifier */ - if ( !ext_variables_opr_variable_read(renv, address, &storage, &var_index) ) + if ( !ext_variables_opr_variable_read + (renv, address, &storage, &var_index) ) return FALSE; /* Read the raw string value */ diff --git a/src/lib-sieve/plugins/variables/ext-variables-common.c b/src/lib-sieve/plugins/variables/ext-variables-common.c index 95c9beb53..96abf265c 100644 --- a/src/lib-sieve/plugins/variables/ext-variables-common.c +++ b/src/lib-sieve/plugins/variables/ext-variables-common.c @@ -61,18 +61,20 @@ void sieve_variables_extension_set struct sieve_variable_scope { pool_t pool; - const char *identifier; + int ext_id; unsigned int next_index; struct hash_table *variables; }; -struct sieve_variable_scope *sieve_variable_scope_create(pool_t pool) +struct sieve_variable_scope *sieve_variable_scope_create + (pool_t pool, int ext_id) { struct sieve_variable_scope *scope; scope = p_new(pool, struct sieve_variable_scope, 1); scope->pool = pool; + scope->ext_id = ext_id; scope->variables = hash_create (pool, pool, 0, strcase_hash, (hash_cmp_callback_t *)strcasecmp); @@ -82,13 +84,14 @@ struct sieve_variable_scope *sieve_variable_scope_create(pool_t pool) struct sieve_variable *sieve_variable_scope_declare (struct sieve_variable_scope *scope, const char *identifier) { - struct sieve_variable *var = p_new(scope->pool, struct sieve_variable, 1); - var->identifier = identifier; - var->index = scope->next_index++; + struct sieve_variable *new_var = p_new(scope->pool, struct sieve_variable, 1); + new_var->identifier = identifier; + new_var->index = scope->next_index++; + new_var->ext_id = scope->ext_id; - hash_insert(scope->variables, (void *) identifier, (void *) var); + hash_insert(scope->variables, (void *) identifier, (void *) new_var); - return var; + return new_var; } struct sieve_variable *sieve_variable_scope_get_variable @@ -103,6 +106,17 @@ struct sieve_variable *sieve_variable_scope_get_variable return var; } +struct sieve_variable *sieve_variable_scope_import +(struct sieve_variable_scope *scope, struct sieve_variable *var) +{ + struct sieve_variable *new_var = p_new(scope->pool, struct sieve_variable, 1); + memcpy(new_var, var, sizeof(struct sieve_variable)); + + hash_insert(scope->variables, (void *) new_var->identifier, (void *) new_var); + + return new_var; +} + /* Variable storage */ struct sieve_variable_storage { @@ -172,7 +186,7 @@ ext_variables_validator_context_create(struct sieve_validator *validator) ctx = p_new(pool, struct ext_variables_validator_context, 1); ctx->set_modifiers = hash_create (pool, pool, 0, str_hash, (hash_cmp_callback_t *)strcmp); - ctx->main_scope = sieve_variable_scope_create(sieve_ast_pool(ast)); + ctx->main_scope = sieve_variable_scope_create(sieve_ast_pool(ast), -1); sieve_validator_extension_set_context (validator, ext_variables_my_id, (void *) ctx); @@ -211,6 +225,15 @@ struct sieve_variable *ext_variables_validator_get_variable return sieve_variable_scope_get_variable(ctx->main_scope, variable, declare); } +struct sieve_variable_scope *sieve_ext_variables_get_main_scope +(struct sieve_validator *validator) +{ + struct ext_variables_validator_context *ctx = + ext_variables_validator_context_get(validator); + + return ctx->main_scope; +} + bool sieve_ext_variables_is_active(struct sieve_validator *valdtr) { return ( ext_variables_validator_context_get(valdtr) != NULL ); @@ -220,6 +243,7 @@ bool sieve_ext_variables_is_active(struct sieve_validator *valdtr) struct ext_variables_interpreter_context { struct sieve_variable_storage *local_storage; + ARRAY_DEFINE(ext_storages, struct sieve_variable_storage *); }; static struct ext_variables_interpreter_context * @@ -230,6 +254,7 @@ ext_variables_interpreter_context_create(struct sieve_interpreter *interp) ctx = p_new(pool, struct ext_variables_interpreter_context, 1); ctx->local_storage = sieve_variable_storage_create(pool); + p_array_init(&ctx->ext_storages, pool, sieve_extensions_get_count()); sieve_interpreter_extension_set_context (interp, ext_variables_my_id, (void *) ctx); @@ -255,13 +280,45 @@ ext_variables_interpreter_context_get(struct sieve_interpreter *interp) sieve_interpreter_extension_get_context(interp, ext_variables_my_id); } -struct sieve_variable_storage *ext_variables_interpreter_get_storage - (struct sieve_interpreter *interp) +struct sieve_variable_storage *sieve_ext_variables_get_storage + (struct sieve_interpreter *interp, int ext_id) { struct ext_variables_interpreter_context *ctx = ext_variables_interpreter_context_get(interp); + struct sieve_variable_storage * const *storage; - return ctx->local_storage; + if ( ext_id < 0 ) + return ctx->local_storage; + + if ( ext_id >= (int) array_count(&ctx->ext_storages) ) { + storage = NULL; + } else { + storage = array_idx(&ctx->ext_storages, ext_id); + } + + if ( storage == NULL || *storage == NULL ) { + pool_t pool = sieve_interpreter_pool(interp); + struct sieve_variable_storage *strg = sieve_variable_storage_create(pool); + + array_idx_set(&ctx->ext_storages, (unsigned int) ext_id, &strg); + + return strg; + } + + return *storage; +} + +void sieve_ext_variables_set_storage +(struct sieve_interpreter *interp, struct sieve_variable_storage *storage, + int ext_id) +{ + struct ext_variables_interpreter_context *ctx = + ext_variables_interpreter_context_get(interp); + + if ( ext_id < 0 || storage == NULL ) + return; + + array_idx_set(&ctx->ext_storages, (unsigned int) ext_id, &storage); } /* Set modifier registration */ @@ -276,6 +333,4 @@ const struct ext_variables_set_modifier *ext_variables_set_modifier_find hash_lookup(ctx->set_modifiers, identifier); } -/* Interpreter context */ - diff --git a/src/lib-sieve/plugins/variables/ext-variables-common.h b/src/lib-sieve/plugins/variables/ext-variables-common.h index dd8e42181..1579f0594 100644 --- a/src/lib-sieve/plugins/variables/ext-variables-common.h +++ b/src/lib-sieve/plugins/variables/ext-variables-common.h @@ -71,7 +71,7 @@ struct sieve_variable *ext_variables_validator_get_variable (struct sieve_validator *validator, const char *variable, bool declare); struct sieve_variable_storage *ext_variables_interpreter_get_storage - (struct sieve_interpreter *interp); + (struct sieve_interpreter *interp, unsigned int ext_id); /* Extensions */ diff --git a/src/lib-sieve/plugins/variables/ext-variables-operands.c b/src/lib-sieve/plugins/variables/ext-variables-operands.c index efdf06def..31a2e6446 100644 --- a/src/lib-sieve/plugins/variables/ext-variables-operands.c +++ b/src/lib-sieve/plugins/variables/ext-variables-operands.c @@ -39,42 +39,72 @@ const struct sieve_operand variable_operand = { EXT_VARIABLES_OPERAND_VARIABLE, &string_class, &variable_interface -}; +}; void ext_variables_opr_variable_emit (struct sieve_binary *sbin, struct sieve_variable *var) { + if ( var->ext_id < 0 ) { + /* Default variable storage */ + (void) sieve_operand_emit_code(sbin, &variable_operand, ext_variables_my_id); + (void) sieve_binary_emit_byte(sbin, 0); + (void) sieve_binary_emit_integer(sbin, var->index); + return; + } + (void) sieve_operand_emit_code(sbin, &variable_operand, ext_variables_my_id); + (void) sieve_binary_emit_byte(sbin, 1 + var->ext_id); (void) sieve_binary_emit_integer(sbin, var->index); } static bool opr_variable_dump (const struct sieve_dumptime_env *denv, sieve_size_t *address) { + unsigned int code; + int ext_id; sieve_size_t index = 0; + const struct sieve_extension *ext = NULL; - if (sieve_binary_read_integer(denv->sbin, address, &index) ) { - sieve_code_dumpf(denv, "VAR: %ld", (long) index); - - return TRUE; + if ( !sieve_binary_read_byte(denv->sbin, address, &code) ) { + return FALSE; + } + ext_id = code - 1; + + if ( ext_id >= 0 && (ext = sieve_extension_get_by_id(ext_id)) == NULL ) { + return FALSE; } - return FALSE; + if ( !sieve_binary_read_integer(denv->sbin, address, &index) ) { + return FALSE; + } + + if ( ext == NULL ) + sieve_code_dumpf(denv, "VAR: %ld", (long) index); + else + sieve_code_dumpf(denv, "VAR: [%d:%s] %ld", ext_id, ext->name, (long) index); + return TRUE; } static bool opr_variable_read_value (const struct sieve_runtime_env *renv, sieve_size_t *address, string_t **str) { + unsigned int code; + int ext_id; struct sieve_variable_storage *storage; sieve_size_t index = 0; - storage = ext_variables_interpreter_get_storage(renv->interp); + if ( !sieve_binary_read_byte(renv->sbin, address, &code) ) { + return FALSE; + } + ext_id = code - 1; + + storage = sieve_ext_variables_get_storage(renv->interp, ext_id); if ( storage == NULL ) return FALSE; - + if (sieve_binary_read_integer(renv->sbin, address, &index) ) { /* Parameter str can be NULL if we are requested to only skip and not * actually read the argument. - */ + */ if ( str != NULL ) { sieve_variable_get(storage, index, str); @@ -87,20 +117,28 @@ static bool opr_variable_read_value } bool ext_variables_opr_variable_read - (const struct sieve_runtime_env *renv, sieve_size_t *address, - struct sieve_variable_storage **storage, unsigned int *var_index) +(const struct sieve_runtime_env *renv, sieve_size_t *address, + struct sieve_variable_storage **storage, unsigned int *var_index) { + unsigned int code; + int ext_id; const struct sieve_operand *operand = sieve_operand_read(renv->sbin, address); sieve_size_t idx = 0; if ( operand != &variable_operand ) return FALSE; - *storage = ext_variables_interpreter_get_storage(renv->interp); - if ( *storage == NULL ) return FALSE; + if ( !sieve_binary_read_byte(renv->sbin, address, &code) ) { + return FALSE; + } + ext_id = code - 1; + + *storage = sieve_ext_variables_get_storage(renv->interp, ext_id); + if ( *storage == NULL ) return FALSE; if (sieve_binary_read_integer(renv->sbin, address, &idx) ) { *var_index = idx; + return TRUE; } diff --git a/src/lib-sieve/plugins/variables/ext-variables.c b/src/lib-sieve/plugins/variables/ext-variables.c index e66c9bc0e..a2b273f88 100644 --- a/src/lib-sieve/plugins/variables/ext-variables.c +++ b/src/lib-sieve/plugins/variables/ext-variables.c @@ -55,10 +55,6 @@ const struct sieve_operation *ext_variables_operations[] = { /* Operands */ -extern const struct sieve_operand variable_operand; -extern const struct sieve_operand match_value_operand; -extern const struct sieve_operand variable_string_operand; - const struct sieve_operand *ext_variables_operands[] = { &variable_operand, &match_value_operand, diff --git a/src/lib-sieve/plugins/variables/sieve-ext-variables.h b/src/lib-sieve/plugins/variables/sieve-ext-variables.h index d2f025d5a..f7607501e 100644 --- a/src/lib-sieve/plugins/variables/sieve-ext-variables.h +++ b/src/lib-sieve/plugins/variables/sieve-ext-variables.h @@ -8,8 +8,6 @@ #include "sieve-common.h" #include "sieve-extensions.h" -bool sieve_ext_variables_is_active(struct sieve_validator *valdtr); - /* * Variable scope */ @@ -17,13 +15,17 @@ bool sieve_ext_variables_is_active(struct sieve_validator *valdtr); struct sieve_variable { const char *identifier; unsigned int index; + int ext_id; }; struct sieve_variable_scope; -struct sieve_variable_scope *sieve_variable_scope_create(pool_t pool); +struct sieve_variable_scope *sieve_variable_scope_create + (pool_t pool, int ext_id); struct sieve_variable *sieve_variable_scope_declare (struct sieve_variable_scope *scope, const char *identifier); +struct sieve_variable *sieve_variable_scope_import + (struct sieve_variable_scope *scope, struct sieve_variable *var); struct sieve_variable *sieve_variable_scope_get_variable (struct sieve_variable_scope *scope, const char *identifier, bool create); @@ -58,4 +60,19 @@ void sieve_variables_extension_set (struct sieve_binary *sbin, int ext_id, const struct sieve_variables_extension *ext); +/* + * Variables access + */ + +bool sieve_ext_variables_is_active(struct sieve_validator *valdtr); + +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, int ext_id); +void sieve_ext_variables_set_storage + (struct sieve_interpreter *interp, struct sieve_variable_storage *storage, + int ext_id); + #endif /* __SIEVE_EXT_VARIABLES_H */ -- GitLab