From 3b694edd46a5b74e8c8e0e5853691257615a559f Mon Sep 17 00:00:00 2001 From: Stephan Bosch <stephan@rename-it.nl> Date: Mon, 14 Jul 2008 12:19:21 +0200 Subject: [PATCH] Added support for implicit side effects and adjusted imapflags extension accordingly. --- src/lib-sieve/Makefile.am | 2 + src/lib-sieve/cmd-discard.c | 6 +- src/lib-sieve/cmd-redirect.c | 10 +- src/lib-sieve/ext-reject.c | 6 +- src/lib-sieve/plugins/body/ext-body-common.c | 1 + src/lib-sieve/plugins/copy/ext-copy.c | 17 +-- .../plugins/imapflags/ext-imapflags-common.c | 64 +++++---- .../plugins/imapflags/ext-imapflags-common.h | 8 ++ .../plugins/imapflags/ext-imapflags.c | 29 +++-- src/lib-sieve/plugins/imapflags/tag-flags.c | 102 ++++----------- .../plugins/include/ext-include-common.c | 11 +- .../plugins/include/ext-include-common.h | 2 +- src/lib-sieve/plugins/include/ext-include.c | 9 +- src/lib-sieve/plugins/include/include.sieve | 1 + src/lib-sieve/plugins/vacation/cmd-vacation.c | 7 +- .../plugins/variables/ext-variables.c | 11 +- src/lib-sieve/sieve-actions.c | 15 +-- src/lib-sieve/sieve-actions.h | 5 +- src/lib-sieve/sieve-common.h | 3 + src/lib-sieve/sieve-extensions.c | 2 +- src/lib-sieve/sieve-extensions.h | 2 +- src/lib-sieve/sieve-interpreter.c | 110 ++++------------ src/lib-sieve/sieve-interpreter.h | 11 -- src/lib-sieve/sieve-message.c | 75 +++++++++++ src/lib-sieve/sieve-message.h | 19 +++ src/lib-sieve/sieve-result.c | 122 +++++++++++++++++- src/lib-sieve/sieve-result.h | 9 ++ 27 files changed, 389 insertions(+), 270 deletions(-) create mode 100644 src/lib-sieve/sieve-message.c create mode 100644 src/lib-sieve/sieve-message.h diff --git a/src/lib-sieve/Makefile.am b/src/lib-sieve/Makefile.am index a15a5cdc1..8323ccee3 100644 --- a/src/lib-sieve/Makefile.am +++ b/src/lib-sieve/Makefile.am @@ -52,6 +52,7 @@ libsieve_la_DEPENDENCIES = $(plugins) libsieve_la_LIBADD = $(plugins) libsieve_la_SOURCES = \ + sieve-message.c \ sieve-lexer.c \ sieve-script.c \ sieve-ast.c \ @@ -79,6 +80,7 @@ libsieve_la_SOURCES = \ sieve.c noinst_HEADERS = \ + sieve-message.h \ sieve-lexer.h \ sieve-script.h \ sieve-script-private.h \ diff --git a/src/lib-sieve/cmd-discard.c b/src/lib-sieve/cmd-discard.c index feff4843a..42af9c156 100644 --- a/src/lib-sieve/cmd-discard.c +++ b/src/lib-sieve/cmd-discard.c @@ -46,7 +46,8 @@ const struct sieve_operation cmd_discard_operation = { /* discard action */ static void act_discard_print - (const struct sieve_action *action, void *context, bool *keep); + (const struct sieve_action *action, struct sieve_result *result, + void *context, bool *keep); static bool act_discard_commit (const struct sieve_action *action, const struct sieve_action_exec_env *aenv, void *tr_context, bool *keep); @@ -94,7 +95,8 @@ static bool cmd_discard_operation_execute */ static void act_discard_print -(const struct sieve_action *action ATTR_UNUSED, void *context ATTR_UNUSED, +(const struct sieve_action *action ATTR_UNUSED, + struct sieve_result *result ATTR_UNUSED, void *context ATTR_UNUSED, bool *keep) { printf("* discard\n"); diff --git a/src/lib-sieve/cmd-redirect.c b/src/lib-sieve/cmd-redirect.c index ce228c0d7..342bb87a4 100644 --- a/src/lib-sieve/cmd-redirect.c +++ b/src/lib-sieve/cmd-redirect.c @@ -67,10 +67,11 @@ static int act_redirect_check_duplicate (const struct sieve_runtime_env *renv, const struct sieve_action *action1, void *context1, void *context2); static void act_redirect_print - (const struct sieve_action *action, void *context, bool *keep); + (const struct sieve_action *action, struct sieve_result *result, + void *context, bool *keep); static bool act_redirect_commit -(const struct sieve_action *action ATTR_UNUSED, - const struct sieve_action_exec_env *aenv, void *tr_context, bool *keep); + (const struct sieve_action *action ATTR_UNUSED, + const struct sieve_action_exec_env *aenv, void *tr_context, bool *keep); struct act_redirect_context { const char *to_address; @@ -208,7 +209,8 @@ static int act_redirect_check_duplicate } static void act_redirect_print -(const struct sieve_action *action ATTR_UNUSED, void *context, bool *keep) +(const struct sieve_action *action ATTR_UNUSED, + struct sieve_result *result ATTR_UNUSED, void *context, bool *keep) { struct act_redirect_context *ctx = (struct act_redirect_context *) context; diff --git a/src/lib-sieve/ext-reject.c b/src/lib-sieve/ext-reject.c index 69497e52e..f64c992fe 100644 --- a/src/lib-sieve/ext-reject.c +++ b/src/lib-sieve/ext-reject.c @@ -99,7 +99,8 @@ int act_reject_check_conflict (const struct sieve_runtime_env *renv, const struct sieve_action *action, const struct sieve_action *other_action, void *context); static void act_reject_print - (const struct sieve_action *action, void *context, bool *keep); + (const struct sieve_action *action, struct sieve_result *result, + void *context, bool *keep); static bool act_reject_commit (const struct sieve_action *action ATTR_UNUSED, const struct sieve_action_exec_env *aenv, void *tr_context, bool *keep); @@ -254,7 +255,8 @@ int act_reject_check_conflict } static void act_reject_print -(const struct sieve_action *action ATTR_UNUSED, void *context, bool *keep) +(const struct sieve_action *action ATTR_UNUSED, + struct sieve_result *result ATTR_UNUSED, void *context, bool *keep) { struct act_reject_context *ctx = (struct act_reject_context *) context; diff --git a/src/lib-sieve/plugins/body/ext-body-common.c b/src/lib-sieve/plugins/body/ext-body-common.c index 38505a3ff..ff1690834 100644 --- a/src/lib-sieve/plugins/body/ext-body-common.c +++ b/src/lib-sieve/plugins/body/ext-body-common.c @@ -10,6 +10,7 @@ #include "message-decoder.h" #include "sieve-common.h" +#include "sieve-message.h" #include "sieve-interpreter.h" #include "ext-body-common.h" diff --git a/src/lib-sieve/plugins/copy/ext-copy.c b/src/lib-sieve/plugins/copy/ext-copy.c index 1122462dd..ce4faa81b 100644 --- a/src/lib-sieve/plugins/copy/ext-copy.c +++ b/src/lib-sieve/plugins/copy/ext-copy.c @@ -55,12 +55,12 @@ static bool ext_copy_load(int ext_id) const struct sieve_side_effect_extension ext_copy_side_effect; static void seff_copy_print - (const struct sieve_side_effect *seffect, const struct sieve_action *action, - void *se_context, bool *keep); + (const struct sieve_side_effect *seffect, const struct sieve_action *action, + struct sieve_result *result, void *se_context, bool *keep); static bool seff_copy_post_commit - (const struct sieve_side_effect *seffect, const struct sieve_action *action, - const struct sieve_action_exec_env *aenv, void *se_context, - void *tr_context, bool *keep); + (const struct sieve_side_effect *seffect, const struct sieve_action *action, + const struct sieve_action_exec_env *aenv, void *se_context, + void *tr_context, bool *keep); const struct sieve_side_effect copy_side_effect = { "copy", @@ -125,9 +125,10 @@ static const struct sieve_argument copy_tag = { /* Side effect execution */ static void seff_copy_print - (const struct sieve_side_effect *seffect ATTR_UNUSED, - const struct sieve_action *action ATTR_UNUSED, - void *se_context ATTR_UNUSED, bool *keep) +(const struct sieve_side_effect *seffect ATTR_UNUSED, + const struct sieve_action *action ATTR_UNUSED, + struct sieve_result *result ATTR_UNUSED, + void *se_context ATTR_UNUSED, bool *keep) { printf(" + preserve implicit keep\n"); diff --git a/src/lib-sieve/plugins/imapflags/ext-imapflags-common.c b/src/lib-sieve/plugins/imapflags/ext-imapflags-common.c index a64f5c43f..b448d5cea 100644 --- a/src/lib-sieve/plugins/imapflags/ext-imapflags-common.c +++ b/src/lib-sieve/plugins/imapflags/ext-imapflags-common.c @@ -6,6 +6,7 @@ #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" +#include "sieve-result.h" #include "sieve-dump.h" #include "sieve-ext-variables.h" @@ -167,47 +168,51 @@ void ext_imapflags_attach_flags_tag /* Tag specified by user */ sieve_validator_register_external_tag (valdtr, &tag_flags, command, -1); - - /* Implicit tag if none is specified */ - sieve_validator_register_persistent_tag - (valdtr, &tag_flags_implicit, command); } /* Context access */ -struct ext_imapflags_message_context { +struct ext_imapflags_result_context { string_t *internal_flags; }; -static inline struct ext_imapflags_message_context * - _get_message_context(struct sieve_message_context *msgctx) +static inline struct ext_imapflags_result_context * + _get_result_context(struct sieve_result *result) { - struct ext_imapflags_message_context *mctx = - (struct ext_imapflags_message_context *) - sieve_message_context_extension_get(msgctx, ext_imapflags_my_id); + struct ext_imapflags_result_context *rctx = + (struct ext_imapflags_result_context *) + sieve_result_extension_get_context(result, ext_imapflags_my_id); - if ( mctx == NULL ) { - pool_t pool = sieve_message_context_pool(msgctx); + if ( rctx == NULL ) { + pool_t pool = sieve_result_pool(result); - mctx =p_new(pool, struct ext_imapflags_message_context, 1); - mctx->internal_flags = str_new(pool, 32); + rctx =p_new(pool, struct ext_imapflags_result_context, 1); + rctx->internal_flags = str_new(pool, 32); - sieve_message_context_extension_set - (msgctx, ext_imapflags_my_id, mctx); + sieve_result_extension_set_context + (result, ext_imapflags_my_id, rctx); } - return mctx; + return rctx; } static string_t *_get_flags_string - (struct sieve_message_context *msgctx) + (struct sieve_result *result) { - struct ext_imapflags_message_context *ctx = - _get_message_context(msgctx); + struct ext_imapflags_result_context *ctx = + _get_result_context(result); return ctx->internal_flags; } +/* Initialization */ + +void ext_imapflags_runtime_init(const struct sieve_runtime_env *renv) +{ + sieve_result_add_implicit_side_effect + (renv->result, &act_store, &flags_side_effect, NULL); +} + /* Flag operations */ static bool flag_is_valid(const char *flag) @@ -369,7 +374,7 @@ void ext_imapflags_set_flags if ( storage != NULL ) sieve_variable_get_modifiable(storage, var_index, &cur_flags); else - cur_flags = _get_flags_string(renv->msgctx); + cur_flags = _get_flags_string(renv->result); flags_list_set_flags(cur_flags, flags); } @@ -383,7 +388,7 @@ void ext_imapflags_add_flags if ( storage != NULL ) sieve_variable_get_modifiable(storage, var_index, &cur_flags); else - cur_flags = _get_flags_string(renv->msgctx); + cur_flags = _get_flags_string(renv->result); flags_list_add_flags(cur_flags, flags); } @@ -397,7 +402,7 @@ void ext_imapflags_remove_flags if ( storage != NULL ) sieve_variable_get_modifiable(storage, var_index, &cur_flags); else - cur_flags = _get_flags_string(renv->msgctx); + cur_flags = _get_flags_string(renv->result); flags_list_remove_flags(cur_flags, flags); } @@ -411,7 +416,7 @@ const char *ext_imapflags_get_flags_string if ( storage != NULL ) sieve_variable_get_modifiable(storage, var_index, &cur_flags); else - cur_flags = _get_flags_string(renv->msgctx); + cur_flags = _get_flags_string(renv->result); return str_c(cur_flags); } @@ -425,11 +430,20 @@ void ext_imapflags_get_flags_init if ( storage != NULL ) sieve_variable_get_modifiable(storage, var_index, &cur_flags); else - cur_flags = _get_flags_string(renv->msgctx); + cur_flags = _get_flags_string(renv->result); ext_imapflags_iter_init(iter, cur_flags); } +void ext_imapflags_get_implicit_flags_init +(struct ext_imapflags_iter *iter, struct sieve_result *result) +{ + string_t *cur_flags = _get_flags_string(result); + + ext_imapflags_iter_init(iter, cur_flags); +} + + diff --git a/src/lib-sieve/plugins/imapflags/ext-imapflags-common.h b/src/lib-sieve/plugins/imapflags/ext-imapflags-common.h index 2394382c5..ca35782b6 100644 --- a/src/lib-sieve/plugins/imapflags/ext-imapflags-common.h +++ b/src/lib-sieve/plugins/imapflags/ext-imapflags-common.h @@ -7,7 +7,9 @@ #include "sieve-ext-variables.h" extern int ext_imapflags_my_id; + extern const struct sieve_extension imapflags_extension; +extern const struct sieve_side_effect flags_side_effect; enum ext_imapflags_opcode { EXT_IMAPFLAGS_OPERATION_SETFLAG, @@ -33,6 +35,10 @@ bool ext_imapflags_command_operands_read void ext_imapflags_attach_flags_tag (struct sieve_validator *valdtr, const char *command); +/* Initialization */ + +void ext_imapflags_runtime_init(const struct sieve_runtime_env *renv); + /* Flag registration */ struct ext_imapflags_iter { @@ -64,6 +70,8 @@ void ext_imapflags_remove_flags void ext_imapflags_get_flags_init (struct ext_imapflags_iter *iter, const struct sieve_runtime_env *renv, struct sieve_variable_storage *storage, unsigned int var_index); +void ext_imapflags_get_implicit_flags_init + (struct ext_imapflags_iter *iter, struct sieve_result *result); #endif /* __EXT_IMAPFLAGS_COMMON_H */ diff --git a/src/lib-sieve/plugins/imapflags/ext-imapflags.c b/src/lib-sieve/plugins/imapflags/ext-imapflags.c index e790c48d4..8dcfcd4e8 100644 --- a/src/lib-sieve/plugins/imapflags/ext-imapflags.c +++ b/src/lib-sieve/plugins/imapflags/ext-imapflags.c @@ -28,9 +28,9 @@ /* Forward declarations */ static bool ext_imapflags_load(int ext_id); -static bool ext_imapflags_validator_load(struct sieve_validator *validator); -static bool ext_imapflags_interpreter_load - (struct sieve_interpreter *interpreter); +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_binary_load(struct sieve_binary *sbin); /* Commands */ @@ -60,7 +60,7 @@ const struct sieve_extension imapflags_extension = { ext_imapflags_load, ext_imapflags_validator_load, NULL, - ext_imapflags_interpreter_load, + ext_imapflags_runtime_load, ext_imapflags_binary_load, NULL, SIEVE_EXT_DEFINE_OPERATIONS(imapflags_operations), @@ -79,16 +79,16 @@ extern const struct sieve_side_effect_extension imapflags_seffect_extension; /* Load extension into validator */ static bool ext_imapflags_validator_load - (struct sieve_validator *validator) + (struct sieve_validator *valdtr) { /* Register commands */ - sieve_validator_register_command(validator, &cmd_setflag); - sieve_validator_register_command(validator, &cmd_addflag); - sieve_validator_register_command(validator, &cmd_removeflag); - sieve_validator_register_command(validator, &tst_hasflag); + sieve_validator_register_command(valdtr, &cmd_setflag); + sieve_validator_register_command(valdtr, &cmd_addflag); + sieve_validator_register_command(valdtr, &cmd_removeflag); + sieve_validator_register_command(valdtr, &tst_hasflag); - ext_imapflags_attach_flags_tag(validator, "keep"); - ext_imapflags_attach_flags_tag(validator, "fileinto"); + ext_imapflags_attach_flags_tag(valdtr, "keep"); + ext_imapflags_attach_flags_tag(valdtr, "fileinto"); return TRUE; } @@ -109,10 +109,11 @@ static bool ext_imapflags_binary_load(struct sieve_binary *sbin) * Interpreter context */ -static bool ext_imapflags_interpreter_load - (struct sieve_interpreter *interpreter ATTR_UNUSED) +static bool ext_imapflags_runtime_load + (const struct sieve_runtime_env *renv) { - /* Will contain something when variables extension is implemented */ + ext_imapflags_runtime_init(renv); + return TRUE; } diff --git a/src/lib-sieve/plugins/imapflags/tag-flags.c b/src/lib-sieve/plugins/imapflags/tag-flags.c index 56097fb41..254e15826 100644 --- a/src/lib-sieve/plugins/imapflags/tag-flags.c +++ b/src/lib-sieve/plugins/imapflags/tag-flags.c @@ -13,8 +13,6 @@ #include "ext-imapflags-common.h" -static bool tag_flags_validate_persistent - (struct sieve_validator *validator, struct sieve_command_context *cmd); static bool tag_flags_validate (struct sieve_validator *validator, struct sieve_ast_argument **arg, struct sieve_command_context *cmd); @@ -32,14 +30,6 @@ const struct sieve_argument tag_flags = { tag_flags_generate }; -const struct sieve_argument tag_flags_implicit = { - "@flags-implicit", - NULL, - tag_flags_validate_persistent, - NULL, NULL, - tag_flags_generate -}; - /* Side effect */ extern const struct sieve_side_effect_extension imapflags_seffect_extension; @@ -51,29 +41,20 @@ static bool seff_flags_read_context (const struct sieve_side_effect *seffect, const struct sieve_runtime_env *renv, sieve_size_t *address, void **se_context); -static bool seff_flags_read_implicit_context - (const struct sieve_side_effect *seffect, - const struct sieve_runtime_env *renv, sieve_size_t *address, - void **se_context); static void seff_flags_print - (const struct sieve_side_effect *seffect, const struct sieve_action *action, - void *se_context, bool *keep); + (const struct sieve_side_effect *seffect, const struct sieve_action *action, + struct sieve_result *result, void *se_context, bool *keep); static bool seff_flags_pre_execute (const struct sieve_side_effect *seffect, const struct sieve_action *action, const struct sieve_action_exec_env *aenv, void **se_context, void *tr_context); -enum ext_imapflags_side_effect_type { - EXT_IMAPFLAGS_SEFFECT_FLAGS, - EXT_IMAPFLAGS_SEFFECT_FLAGS_IMPLICIT, -}; - const struct sieve_side_effect flags_side_effect = { "flags", &act_store, &imapflags_seffect_extension, - EXT_IMAPFLAGS_SEFFECT_FLAGS, + 0, seff_flags_dump_context, seff_flags_read_context, seff_flags_print, @@ -81,41 +62,14 @@ const struct sieve_side_effect flags_side_effect = { NULL, NULL, NULL }; -const struct sieve_side_effect flags_implicit_side_effect = { - "flags-implicit", - &act_store, - - &imapflags_seffect_extension, - EXT_IMAPFLAGS_SEFFECT_FLAGS_IMPLICIT, - NULL, - seff_flags_read_implicit_context, - seff_flags_print, - seff_flags_pre_execute, - NULL, NULL, NULL -}; - -const struct sieve_side_effect *imapflags_side_effects[] = { - &flags_side_effect, &flags_implicit_side_effect -}; - const struct sieve_side_effect_extension imapflags_seffect_extension = { &imapflags_extension, - SIEVE_EXT_DEFINE_SIDE_EFFECTS(imapflags_side_effects) + SIEVE_EXT_DEFINE_SIDE_EFFECT(flags_side_effect) }; /* Tag validation */ -static bool tag_flags_validate_persistent -(struct sieve_validator *validator ATTR_UNUSED, struct sieve_command_context *cmd) -{ - if ( sieve_command_find_argument(cmd, &tag_flags) == NULL ) { - sieve_command_add_dynamic_tag(cmd, &tag_flags_implicit, -1); - } - - return TRUE; -} - static bool tag_flags_validate (struct sieve_validator *validator, struct sieve_ast_argument **arg, struct sieve_command_context *cmd) @@ -154,19 +108,13 @@ static bool tag_flags_generate return FALSE; } - if ( arg->argument == &tag_flags ) { - sieve_opr_side_effect_emit(sbin, &flags_side_effect, ext_imapflags_my_id); - - param = arg->parameters; - - /* Call the generation function for the argument */ - if ( param->argument != NULL && param->argument->generate != NULL && - !param->argument->generate(generator, param, cmd) ) - return FALSE; - } else if ( arg->argument == &tag_flags_implicit ) { - sieve_opr_side_effect_emit - (sbin, &flags_implicit_side_effect, ext_imapflags_my_id); - } else + sieve_opr_side_effect_emit(sbin, &flags_side_effect, ext_imapflags_my_id); + + param = arg->parameters; + + /* Call the generation function for the argument */ + if ( param->argument != NULL && param->argument->generate != NULL && + !param->argument->generate(generator, param, cmd) ) return FALSE; return TRUE; @@ -244,13 +192,10 @@ static bool seff_flags_read_context return result; } -static bool seff_flags_read_implicit_context -(const struct sieve_side_effect *seffect ATTR_UNUSED, - const struct sieve_runtime_env *renv, sieve_size_t *address ATTR_UNUSED, - void **se_context) +static struct seff_flags_context *seff_flags_get_implicit_context +(struct sieve_result *result) { - bool result = TRUE; - pool_t pool = sieve_result_pool(renv->result); + pool_t pool = sieve_result_pool(result); struct seff_flags_context *ctx; const char *flag; struct ext_imapflags_iter flit; @@ -261,7 +206,7 @@ static bool seff_flags_read_implicit_context t_push(); /* Unpack */ - ext_imapflags_get_flags_init(&flit, renv, NULL, 0); + ext_imapflags_get_implicit_flags_init(&flit, result); while ( (flag=ext_imapflags_iter_get_flag(&flit)) != NULL ) { if (flag != NULL && *flag != '\\') { /* keyword */ @@ -280,23 +225,24 @@ static bool seff_flags_read_implicit_context ctx->flags |= MAIL_DRAFT; } } - - *se_context = (void *) ctx; t_pop(); - return result; + return ctx; } - static void seff_flags_print (const struct sieve_side_effect *seffect ATTR_UNUSED, const struct sieve_action *action ATTR_UNUSED, + struct sieve_result *result, void *se_context ATTR_UNUSED, bool *keep) { struct seff_flags_context *ctx = (struct seff_flags_context *) se_context; unsigned int i; + if ( ctx == NULL ) + ctx = seff_flags_get_implicit_context(result); + printf(" + add flags:"); if ( (ctx->flags & MAIL_FLAGGED) > 0 ) @@ -333,6 +279,11 @@ static bool seff_flags_pre_execute struct seff_flags_context *ctx = (struct seff_flags_context *) *se_context; struct act_store_transaction *trans = (struct act_store_transaction *) tr_context; + + if ( ctx == NULL ) { + ctx = seff_flags_get_implicit_context(aenv->result); + *se_context = (void *) ctx; + } /* Assign mail keywords for subsequent mailbox_copy() */ if ( array_count(&ctx->keywords) > 0 ) { @@ -342,10 +293,7 @@ static bool seff_flags_pre_execute } array_append_array(&trans->keywords, &ctx->keywords); - - printf("keywords: %d\n", array_count(&ctx->keywords)); } - printf("flags: %d\n", trans->flags); /* Assign mail flags for subsequent mailbox_copy() */ trans->flags |= ctx->flags; diff --git a/src/lib-sieve/plugins/include/ext-include-common.c b/src/lib-sieve/plugins/include/ext-include-common.c index 57fdc1ab9..6b1c4ccd3 100644 --- a/src/lib-sieve/plugins/include/ext-include-common.c +++ b/src/lib-sieve/plugins/include/ext-include-common.c @@ -167,19 +167,18 @@ static inline struct ext_include_interpreter_context * return ctx; } -void ext_include_register_interpreter_context -(struct sieve_interpreter *interp) +void ext_include_runtime_context_init +(const struct sieve_runtime_env *renv) { struct ext_include_interpreter_context *ctx = - ext_include_get_interpreter_context(interp); - struct sieve_script *script = sieve_interpreter_script(interp); + ext_include_get_interpreter_context(renv->interp); if ( ctx == NULL ) { ctx = ext_include_create_interpreter_context - (interp, NULL, script, SBIN_SYSBLOCK_MAIN_PROGRAM); + (renv->interp, NULL, renv->script, SBIN_SYSBLOCK_MAIN_PROGRAM); sieve_interpreter_extension_set_context - (interp, ext_include_my_id, (void *) ctx); + (renv->interp, ext_include_my_id, (void *) ctx); } } diff --git a/src/lib-sieve/plugins/include/ext-include-common.h b/src/lib-sieve/plugins/include/ext-include-common.h index ffd05a9e5..35a2b8094 100644 --- a/src/lib-sieve/plugins/include/ext-include-common.h +++ b/src/lib-sieve/plugins/include/ext-include-common.h @@ -55,7 +55,7 @@ bool ext_include_generate_include /* Interpreter */ -void ext_include_register_interpreter_context(struct sieve_interpreter *interp); +void ext_include_runtime_context_init(const struct sieve_runtime_env *renv); bool ext_include_execute_include (const struct sieve_runtime_env *renv, unsigned int block_id); diff --git a/src/lib-sieve/plugins/include/ext-include.c b/src/lib-sieve/plugins/include/ext-include.c index bae9985e0..d9eb0cfb3 100644 --- a/src/lib-sieve/plugins/include/ext-include.c +++ b/src/lib-sieve/plugins/include/ext-include.c @@ -33,7 +33,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); +static bool ext_include_runtime_load(const struct sieve_runtime_env *renv); /* Operations */ @@ -54,7 +54,7 @@ const struct sieve_extension include_extension = { ext_include_load, ext_include_validator_load, ext_include_generator_load, - ext_include_interpreter_load, + ext_include_runtime_load, ext_include_binary_load, ext_include_binary_dump, SIEVE_EXT_DEFINE_OPERATIONS(ext_include_operations), @@ -92,9 +92,10 @@ static bool ext_include_generator_load(struct sieve_generator *gentr) /* Load extension into interpreter */ -static bool ext_include_interpreter_load(struct sieve_interpreter *interp) +static bool ext_include_runtime_load +(const struct sieve_runtime_env *renv) { - ext_include_register_interpreter_context(interp); + ext_include_runtime_context_init(renv); return TRUE; } diff --git a/src/lib-sieve/plugins/include/include.sieve b/src/lib-sieve/plugins/include/include.sieve index 1b90fc329..81c3bb5ff 100644 --- a/src/lib-sieve/plugins/include/include.sieve +++ b/src/lib-sieve/plugins/include/include.sieve @@ -1,4 +1,5 @@ require "include"; +require "variables"; include "included1"; include :global "included2"; diff --git a/src/lib-sieve/plugins/vacation/cmd-vacation.c b/src/lib-sieve/plugins/vacation/cmd-vacation.c index 96fe5468e..ac7b0c30f 100644 --- a/src/lib-sieve/plugins/vacation/cmd-vacation.c +++ b/src/lib-sieve/plugins/vacation/cmd-vacation.c @@ -56,7 +56,8 @@ int act_vacation_check_conflict (const struct sieve_runtime_env *renv, const struct sieve_action *action, const struct sieve_action *other_action, void *context); static void act_vacation_print - (const struct sieve_action *action, void *context, bool *keep); + (const struct sieve_action *action, struct sieve_result *result, + void *context, bool *keep); static bool act_vacation_commit (const struct sieve_action *action, const struct sieve_action_exec_env *aenv, void *tr_context, bool *keep); @@ -468,8 +469,8 @@ int act_vacation_check_conflict } static void act_vacation_print -(const struct sieve_action *action ATTR_UNUSED, void *context, - bool *keep ATTR_UNUSED) +(const struct sieve_action *action ATTR_UNUSED, struct sieve_result *result ATTR_UNUSED, + void *context, bool *keep ATTR_UNUSED) { struct act_vacation_context *ctx = (struct act_vacation_context *) context; diff --git a/src/lib-sieve/plugins/variables/ext-variables.c b/src/lib-sieve/plugins/variables/ext-variables.c index 7d1885da2..4edfa9b6d 100644 --- a/src/lib-sieve/plugins/variables/ext-variables.c +++ b/src/lib-sieve/plugins/variables/ext-variables.c @@ -21,6 +21,7 @@ #include "sieve-extensions.h" #include "sieve-commands.h" #include "sieve-binary.h" +#include "sieve-interpreter.h" #include "sieve-validator.h" @@ -35,7 +36,7 @@ static bool ext_variables_load(int ext_id); static bool ext_variables_validator_load(struct sieve_validator *validator); static bool ext_variables_binary_load(struct sieve_binary *sbin); -static bool ext_variables_interpreter_load(struct sieve_interpreter *interp); +static bool ext_variables_runtime_load(const struct sieve_runtime_env *renv); /* Commands */ @@ -69,7 +70,7 @@ struct sieve_extension variables_extension = { ext_variables_load, ext_variables_validator_load, NULL, - ext_variables_interpreter_load, + ext_variables_runtime_load, ext_variables_binary_load, NULL, SIEVE_EXT_DEFINE_OPERATIONS(ext_variables_operations), @@ -110,10 +111,10 @@ static bool ext_variables_binary_load /* Load extension into interpreter */ -static bool ext_variables_interpreter_load - (struct sieve_interpreter *interp) +static bool ext_variables_runtime_load + (const struct sieve_runtime_env *renv) { - ext_variables_interpreter_initialize(interp); + ext_variables_interpreter_initialize(renv->interp); return TRUE; } diff --git a/src/lib-sieve/sieve-actions.c b/src/lib-sieve/sieve-actions.c index 8e9e628f6..844f9760d 100644 --- a/src/lib-sieve/sieve-actions.c +++ b/src/lib-sieve/sieve-actions.c @@ -180,11 +180,11 @@ bool sieve_opr_side_effect_dump /* Store action */ static int act_store_check_duplicate - (const struct sieve_runtime_env *renv ATTR_UNUSED, - const struct sieve_action *action1 ATTR_UNUSED, + (const struct sieve_runtime_env *renv, const struct sieve_action *action1, void *context1, void *context2); static void act_store_print - (const struct sieve_action *action ATTR_UNUSED, void *context, bool *keep); + (const struct sieve_action *action, struct sieve_result *result, + void *context, bool *keep); static bool act_store_start (const struct sieve_action *action, @@ -243,7 +243,8 @@ static int act_store_check_duplicate } static void act_store_print -(const struct sieve_action *action ATTR_UNUSED, void *context, bool *keep) +(const struct sieve_action *action ATTR_UNUSED, + struct sieve_result *result ATTR_UNUSED, void *context, bool *keep) { struct act_store_context *ctx = (struct act_store_context *) context; @@ -322,9 +323,7 @@ static bool act_store_execute if ( array_is_created(&trans->keywords) && array_count(&trans->keywords) > 0 ) { const char *const *kwds; - - printf("KEYWORDS: %d\n", array_count(&trans->keywords)); - + (void)array_append_space(&trans->keywords); kwds = array_idx(&trans->keywords, 0); @@ -336,8 +335,6 @@ static bool act_store_execute } } - printf("FLAGS: %d\n", trans->flags); - if (mailbox_copy(trans->mail_trans, aenv->msgdata->mail, trans->flags, keywords, trans->dest_mail) < 0) { act_store_get_storage_error(aenv, trans); diff --git a/src/lib-sieve/sieve-actions.h b/src/lib-sieve/sieve-actions.h index d29bc1be6..b17ffe838 100644 --- a/src/lib-sieve/sieve-actions.h +++ b/src/lib-sieve/sieve-actions.h @@ -34,7 +34,8 @@ struct sieve_action { void *context); void (*print) - (const struct sieve_action *action, void *context, bool *keep); + (const struct sieve_action *action, struct sieve_result *result, + void *context, bool *keep); bool (*start) (const struct sieve_action *action, @@ -72,7 +73,7 @@ struct sieve_side_effect { void (*print) (const struct sieve_side_effect *seffect, const struct sieve_action *action, - void *se_context, bool *keep); + struct sieve_result *result, void *se_context, bool *keep); bool (*pre_execute) (const struct sieve_side_effect *seffect, const struct sieve_action *action, diff --git a/src/lib-sieve/sieve-common.h b/src/lib-sieve/sieve-common.h index 79d41b3b7..7ce1f2360 100644 --- a/src/lib-sieve/sieve-common.h +++ b/src/lib-sieve/sieve-common.h @@ -93,6 +93,9 @@ struct sieve_side_effect; /* sieve-script.h */ struct sieve_script; +/* sieve-message.h */ +struct sieve_message_context; + /* sieve.c */ struct sieve_ast *sieve_parse (struct sieve_script *script, struct sieve_error_handler *ehandler); diff --git a/src/lib-sieve/sieve-extensions.c b/src/lib-sieve/sieve-extensions.c index 627fd7d90..c349db5dc 100644 --- a/src/lib-sieve/sieve-extensions.c +++ b/src/lib-sieve/sieve-extensions.c @@ -202,7 +202,7 @@ static bool _list_extension(const struct sieve_extension *ext) if ( *ext->name == '@' ) return FALSE; if ( ext->validator_load == NULL && ext->generator_load == NULL && - ext->binary_load == NULL && ext->interpreter_load == NULL && + ext->binary_load == NULL && ext->runtime_load == NULL && ext->load == NULL && ext->operations.count == 0 && ext->operands.count == 0 ) { return FALSE; diff --git a/src/lib-sieve/sieve-extensions.h b/src/lib-sieve/sieve-extensions.h index f8b65eb24..0f5bff415 100644 --- a/src/lib-sieve/sieve-extensions.h +++ b/src/lib-sieve/sieve-extensions.h @@ -21,7 +21,7 @@ struct sieve_extension { bool (*validator_load)(struct sieve_validator *validator); bool (*generator_load)(struct sieve_generator *generator); - bool (*interpreter_load)(struct sieve_interpreter *interpreter); + bool (*runtime_load)(const struct sieve_runtime_env *renv); bool (*binary_load)(struct sieve_binary *binary); bool (*binary_dump)(struct sieve_dumptime_env *denv); diff --git a/src/lib-sieve/sieve-interpreter.c b/src/lib-sieve/sieve-interpreter.c index 3b4accb5d..067a5b56c 100644 --- a/src/lib-sieve/sieve-interpreter.c +++ b/src/lib-sieve/sieve-interpreter.c @@ -9,6 +9,7 @@ #include "sieve-error.h" #include "sieve-extensions.h" +#include "sieve-message.h" #include "sieve-commands-private.h" #include "sieve-code.h" #include "sieve-actions.h" @@ -19,75 +20,6 @@ #include "sieve-interpreter.h" -/* - * Message context - * (might get moved to separate file) - */ - -struct sieve_message_context { - pool_t pool; - int refcount; - - /* Context data for extensions */ - ARRAY_DEFINE(ext_contexts, void *); -}; - -static struct sieve_message_context *sieve_message_context_create(void) -{ - pool_t pool; - struct sieve_message_context *msgctx; - - pool = pool_alloconly_create("sieve_message_context", 1024); - msgctx = p_new(pool, struct sieve_message_context, 1); - msgctx->pool = pool; - msgctx->refcount = 1; - - p_array_init(&msgctx->ext_contexts, pool, 4); - - return msgctx; -} - -static void sieve_message_context_ref(struct sieve_message_context *msgctx) -{ - msgctx->refcount++; -} - -static void sieve_message_context_unref(struct sieve_message_context **msgctx) -{ - i_assert((*msgctx)->refcount > 0); - - if (--(*msgctx)->refcount != 0) - return; - - pool_unref(&((*msgctx)->pool)); - - *msgctx = NULL; -} - -void sieve_message_context_extension_set - (struct sieve_message_context *msgctx, int ext_id, void *context) -{ - array_idx_set(&msgctx->ext_contexts, (unsigned int) ext_id, &context); -} - -const void *sieve_message_context_extension_get - (struct sieve_message_context *msgctx, int ext_id) -{ - void * const *ctx; - - if ( ext_id < 0 || ext_id >= (int) array_count(&msgctx->ext_contexts) ) - return NULL; - - ctx = array_idx(&msgctx->ext_contexts, (unsigned int) ext_id); - - return *ctx; -} - -pool_t sieve_message_context_pool(struct sieve_message_context *msgctx) -{ - return msgctx->pool; -} - /* * Interpreter */ @@ -116,8 +48,6 @@ struct sieve_interpreter { struct sieve_interpreter *sieve_interpreter_create (struct sieve_binary *sbin, struct sieve_error_handler *ehandler) { - unsigned int i; - int idx; pool_t pool; struct sieve_interpreter *interp; @@ -136,23 +66,6 @@ struct sieve_interpreter *sieve_interpreter_create interp->pc = 0; p_array_init(&interp->ext_contexts, pool, 4); - - /* 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->interpreter_load != NULL ) - (void)ext->interpreter_load(interp); - } - - /* 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, NULL); - - if ( ext->interpreter_load != NULL ) - ext->interpreter_load(interp); - } return interp; } @@ -416,6 +329,10 @@ 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; + interp->runenv.msgdata = msgdata; interp->runenv.result = result; interp->runenv.scriptenv = senv; @@ -427,6 +344,23 @@ int sieve_interpreter_start 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, NULL); + + if ( ext->runtime_load != NULL ) + ext->runtime_load(&interp->runenv); + } + return sieve_interpreter_continue(interp, interrupted); } diff --git a/src/lib-sieve/sieve-interpreter.h b/src/lib-sieve/sieve-interpreter.h index 15f53e8c5..cc431804e 100644 --- a/src/lib-sieve/sieve-interpreter.h +++ b/src/lib-sieve/sieve-interpreter.h @@ -11,17 +11,6 @@ /* FIXME: make execution dumps use some interpreter function */ #include <stdio.h> -/* Message context */ - -struct sieve_message_context; - -void sieve_message_context_extension_set - (struct sieve_message_context *msgctx, int ext_id, void *context); -const void *sieve_message_context_extension_get - (struct sieve_message_context *msgctx, int ext_id); -pool_t sieve_message_context_pool - (struct sieve_message_context *msgctx); - /* Interpreter */ struct sieve_interpreter; diff --git a/src/lib-sieve/sieve-message.c b/src/lib-sieve/sieve-message.c new file mode 100644 index 000000000..57bc9aa63 --- /dev/null +++ b/src/lib-sieve/sieve-message.c @@ -0,0 +1,75 @@ +#include "lib.h" +#include "mempool.h" +#include "array.h" + +#include "sieve-common.h" +#include "sieve-message.h" + +/* + * Message context + */ + +struct sieve_message_context { + pool_t pool; + int refcount; + + /* Context data for extensions */ + ARRAY_DEFINE(ext_contexts, void *); +}; + +struct sieve_message_context *sieve_message_context_create(void) +{ + pool_t pool; + struct sieve_message_context *msgctx; + + pool = pool_alloconly_create("sieve_message_context", 1024); + msgctx = p_new(pool, struct sieve_message_context, 1); + msgctx->pool = pool; + msgctx->refcount = 1; + + p_array_init(&msgctx->ext_contexts, pool, 4); + + return msgctx; +} + +void sieve_message_context_ref(struct sieve_message_context *msgctx) +{ + msgctx->refcount++; +} + +void sieve_message_context_unref(struct sieve_message_context **msgctx) +{ + i_assert((*msgctx)->refcount > 0); + + if (--(*msgctx)->refcount != 0) + return; + + pool_unref(&((*msgctx)->pool)); + + *msgctx = NULL; +} + +void sieve_message_context_extension_set + (struct sieve_message_context *msgctx, int ext_id, void *context) +{ + array_idx_set(&msgctx->ext_contexts, (unsigned int) ext_id, &context); +} + +const void *sieve_message_context_extension_get + (struct sieve_message_context *msgctx, int ext_id) +{ + void * const *ctx; + + if ( ext_id < 0 || ext_id >= (int) array_count(&msgctx->ext_contexts) ) + return NULL; + + ctx = array_idx(&msgctx->ext_contexts, (unsigned int) ext_id); + + return *ctx; +} + +pool_t sieve_message_context_pool(struct sieve_message_context *msgctx) +{ + return msgctx->pool; +} + diff --git a/src/lib-sieve/sieve-message.h b/src/lib-sieve/sieve-message.h new file mode 100644 index 000000000..33fd667d7 --- /dev/null +++ b/src/lib-sieve/sieve-message.h @@ -0,0 +1,19 @@ +#ifndef __SIEVE_MESSAGE_H +#define __SIEVE_MESSAGE_H + +/* Message context */ + +struct sieve_message_context; + +struct sieve_message_context *sieve_message_context_create(void); +void sieve_message_context_ref(struct sieve_message_context *msgctx); +void sieve_message_context_unref(struct sieve_message_context **msgctx); + +void sieve_message_context_extension_set + (struct sieve_message_context *msgctx, int ext_id, void *context); +const void *sieve_message_context_extension_get + (struct sieve_message_context *msgctx, int ext_id); +pool_t sieve_message_context_pool + (struct sieve_message_context *msgctx); + +#endif diff --git a/src/lib-sieve/sieve-result.c b/src/lib-sieve/sieve-result.c index cd2ab1916..bfdd71668 100644 --- a/src/lib-sieve/sieve-result.c +++ b/src/lib-sieve/sieve-result.c @@ -1,5 +1,6 @@ #include "lib.h" #include "mempool.h" +#include "hash.h" #include "strfuncs.h" #include "str-sanitize.h" @@ -11,6 +12,10 @@ #include <stdio.h> +/* + * + */ + struct sieve_result_action { struct sieve_result *result; const struct sieve_action *action; @@ -36,15 +41,25 @@ struct sieve_result_side_effect { struct sieve_result_side_effect *prev, *next; }; +struct sieve_result_implicit_side_effects { + const struct sieve_action *action; + struct sieve_side_effects_list *seffects; +}; + struct sieve_result { pool_t pool; int refcount; + + /* Context data for extensions */ + ARRAY_DEFINE(ext_contexts, void *); struct sieve_error_handler *ehandler; struct sieve_action_exec_env action_env; struct sieve_result_action *first_action; struct sieve_result_action *last_action; + + struct hash_table *implicit_seffects; }; struct sieve_result *sieve_result_create @@ -58,6 +73,8 @@ struct sieve_result *sieve_result_create result->refcount = 1; result->pool = pool; + p_array_init(&result->ext_contexts, pool, 4); + result->ehandler = ehandler; sieve_error_handler_ref(ehandler); @@ -66,6 +83,7 @@ struct sieve_result *sieve_result_create result->first_action = NULL; result->last_action = NULL; + result->implicit_seffects = NULL; return result; } @@ -78,14 +96,14 @@ void sieve_result_unref(struct sieve_result **result) { i_assert((*result)->refcount > 0); - if (--(*result)->refcount != 0) - return; + if (--(*result)->refcount != 0) + return; sieve_error_handler_unref(&(*result)->ehandler); - pool_unref(&(*result)->pool); + pool_unref(&(*result)->pool); - *result = NULL; + *result = NULL; } pool_t sieve_result_pool(struct sieve_result *result) @@ -93,6 +111,25 @@ pool_t sieve_result_pool(struct sieve_result *result) return result->pool; } +void sieve_result_extension_set_context + (struct sieve_result *result, int ext_id, void *context) +{ + array_idx_set(&result->ext_contexts, (unsigned int) ext_id, &context); +} + +const void *sieve_result_extension_get_context + (struct sieve_result *result, int ext_id) +{ + void * const *ctx; + + if ( ext_id < 0 || ext_id >= (int) array_count(&result->ext_contexts) ) + return NULL; + + ctx = array_idx(&result->ext_contexts, (unsigned int) ext_id); + + return *ctx; +} + /* Logging of result */ static const char *_get_location(const struct sieve_action_exec_env *aenv) @@ -123,6 +160,33 @@ void sieve_result_log /* Result composition */ +void sieve_result_add_implicit_side_effect +(struct sieve_result *result, const struct sieve_action *to_action, + const struct sieve_side_effect *seffect, void *context) +{ + struct sieve_result_implicit_side_effects *implseff = NULL; + + if ( result->implicit_seffects == NULL ) { + result->implicit_seffects = hash_create + (result->pool, result->pool, 0, NULL, NULL); + } else { + implseff = (struct sieve_result_implicit_side_effects *) + hash_lookup(result->implicit_seffects, to_action); + } + + if ( implseff == NULL ) { + implseff = p_new + (result->pool, struct sieve_result_implicit_side_effects, 1); + implseff->action = to_action; + implseff->seffects = sieve_side_effects_list_create(result); + + hash_insert(result->implicit_seffects, (void *) to_action, + (void *) implseff); + } + + sieve_side_effects_list_add(implseff->seffects, seffect, context); +} + int sieve_result_add_action (const struct sieve_runtime_env *renv, const struct sieve_action *action, struct sieve_side_effects_list *seffects, @@ -180,6 +244,50 @@ int sieve_result_add_action raction->next = NULL; } + /* Apply any implicit side effects */ + if ( result->implicit_seffects != NULL ) { + struct sieve_result_implicit_side_effects *implseff; + + /* Check for implicit side effects to this particular action */ + implseff = (struct sieve_result_implicit_side_effects *) + hash_lookup(result->implicit_seffects, action); + + if ( implseff != NULL ) { + struct sieve_result_side_effect *iseff; + + /* Iterate through all implicit side effects and add those that are + * missing. + */ + iseff = implseff->seffects->first_effect; + while ( iseff != NULL ) { + struct sieve_result_side_effect *seff; + bool exists = FALSE; + + /* Scan for presence */ + if ( seffects != NULL ) { + seff = seffects->first_effect; + while ( seff != NULL ) { + if ( seff->seffect == iseff->seffect ) { + exists = TRUE; + break; + } + + seff = seff->next; + } + } else { + raction->seffects = seffects = sieve_side_effects_list_create(result); + } + + /* If not present, add it */ + if ( !exists ) { + sieve_side_effects_list_add(seffects, iseff->seffect, iseff->context); + } + + iseff = iseff->next; + } + } + } + return 0; } @@ -197,7 +305,7 @@ bool sieve_result_print(struct sieve_result *result) if ( act->print != NULL ) { - act->print(act, rac->context, &keep); + act->print(act, result, rac->context, &keep); } else { printf("* %s\n", act->name); } @@ -208,7 +316,7 @@ bool sieve_result_print(struct sieve_result *result) sef = rsef->seffect; if ( sef->print != NULL ) sef->print - (sef, act, rsef->context, &keep); + (sef, act, result, rsef->context, &keep); rsef = rsef->next; } @@ -418,7 +526,7 @@ void sieve_side_effects_list_add { struct sieve_result_side_effect *reffect; - /* Create new action object */ + /* Create new side effect object */ reffect = p_new(list->result->pool, struct sieve_result_side_effect, 1); reffect->seffect = seffect; reffect->context = context; diff --git a/src/lib-sieve/sieve-result.h b/src/lib-sieve/sieve-result.h index 8db7ca630..f5917cc8a 100644 --- a/src/lib-sieve/sieve-result.h +++ b/src/lib-sieve/sieve-result.h @@ -13,6 +13,11 @@ void sieve_result_ref(struct sieve_result *result); void sieve_result_unref(struct sieve_result **result); pool_t sieve_result_pool(struct sieve_result *result); +void sieve_result_extension_set_context + (struct sieve_result *result, int ext_id, void *context); +const void *sieve_result_extension_get_context + (struct sieve_result *result, int ext_id); + /* Error handling */ void sieve_result_log @@ -22,6 +27,10 @@ void sieve_result_error (const struct sieve_action_exec_env *aenv, const char *fmt, ...) ATTR_FORMAT(2, 3); +void sieve_result_add_implicit_side_effect +(struct sieve_result *result, const struct sieve_action *to_action, + const struct sieve_side_effect *seffect, void *context); + int sieve_result_add_action (const struct sieve_runtime_env *renv, const struct sieve_action *action, struct sieve_side_effects_list *seffects, -- GitLab