From a2f1ad80472d29b90774d8ce8895cf49dc256586 Mon Sep 17 00:00:00 2001 From: Stephan Bosch <stephan@rename-it.nl> Date: Thu, 29 Nov 2007 14:20:10 +0100 Subject: [PATCH] Added basic execution support to copy extension. Not completely functional yet. --- src/lib-sieve/cmd-keep.c | 8 ++- src/lib-sieve/cmd-redirect.c | 9 ++- src/lib-sieve/ext-fileinto.c | 9 ++- src/lib-sieve/plugins/copy/ext-copy.c | 34 +++++++++- src/lib-sieve/sieve-actions.c | 5 +- src/lib-sieve/sieve-actions.h | 3 +- src/lib-sieve/sieve-binary.c | 17 +++++ src/lib-sieve/sieve-binary.h | 2 + src/lib-sieve/sieve-code.c | 18 +----- src/lib-sieve/sieve-common.h | 1 + src/lib-sieve/sieve-interpreter.c | 31 +++++++++ src/lib-sieve/sieve-interpreter.h | 5 ++ src/lib-sieve/sieve-result.c | 91 +++++++++++++++++---------- src/lib-sieve/sieve-result.h | 14 +++-- 14 files changed, 185 insertions(+), 62 deletions(-) diff --git a/src/lib-sieve/cmd-keep.c b/src/lib-sieve/cmd-keep.c index 7a59bc212..7c5930908 100644 --- a/src/lib-sieve/cmd-keep.c +++ b/src/lib-sieve/cmd-keep.c @@ -65,14 +65,18 @@ static bool opc_keep_execute const struct sieve_runtime_env *renv ATTR_UNUSED, sieve_size_t *address ATTR_UNUSED) { + struct sieve_side_effects_list *slist = NULL; bool added = FALSE; printf(">> KEEP\n"); + if ( !sieve_interpreter_handle_optional_operands(renv, address, &slist) ) + return FALSE; + if ( renv->mailenv != NULL && renv->mailenv->inbox != NULL ) - added = sieve_act_store_add_to_result(renv, renv->mailenv->inbox); + added = sieve_act_store_add_to_result(renv, slist, renv->mailenv->inbox); else - added = sieve_act_store_add_to_result(renv, "INBOX"); + added = sieve_act_store_add_to_result(renv, slist, "INBOX"); if ( added ) sieve_result_cancel_implicit_keep(renv->result); diff --git a/src/lib-sieve/cmd-redirect.c b/src/lib-sieve/cmd-redirect.c index e6c802fae..9325e8305 100644 --- a/src/lib-sieve/cmd-redirect.c +++ b/src/lib-sieve/cmd-redirect.c @@ -117,6 +117,9 @@ static bool cmd_redirect_opcode_dump { printf("REDIRECT\n"); + if ( !sieve_interpreter_handle_optional_operands(renv, address, NULL) ) + return FALSE; + return sieve_opr_string_dump(renv->sbin, address); } @@ -129,10 +132,14 @@ static bool cmd_redirect_opcode_execute (const struct sieve_opcode *opcode ATTR_UNUSED, const struct sieve_runtime_env *renv, sieve_size_t *address) { + struct sieve_side_effects_list *slist = NULL; struct act_redirect_context *act; string_t *redirect; pool_t pool; + if ( !sieve_interpreter_handle_optional_operands(renv, address, &slist) ) + return FALSE; + t_push(); if ( !sieve_opr_string_read(renv->sbin, address, &redirect) ) { @@ -147,7 +154,7 @@ static bool cmd_redirect_opcode_execute act = p_new(pool, struct act_redirect_context, 1); act->to_address = p_strdup(pool, str_c(redirect)); - if ( sieve_result_add_action(renv, &act_redirect, (void *) act) ) + if ( sieve_result_add_action(renv, &act_redirect, slist, (void *) act) ) sieve_result_cancel_implicit_keep(renv->result); t_pop(); diff --git a/src/lib-sieve/ext-fileinto.c b/src/lib-sieve/ext-fileinto.c index 2f9433679..1789151a8 100644 --- a/src/lib-sieve/ext-fileinto.c +++ b/src/lib-sieve/ext-fileinto.c @@ -132,6 +132,9 @@ static bool ext_fileinto_opcode_dump { printf("FILEINTO\n"); + if ( !sieve_interpreter_handle_optional_operands(renv, address, NULL) ) + return FALSE; + return sieve_opr_string_dump(renv->sbin, address); } @@ -144,7 +147,11 @@ static bool ext_fileinto_opcode_execute (const struct sieve_opcode *opcode ATTR_UNUSED, const struct sieve_runtime_env *renv, sieve_size_t *address) { + struct sieve_side_effects_list *slist = NULL; string_t *folder; + + if ( !sieve_interpreter_handle_optional_operands(renv, address, &slist) ) + return FALSE; t_push(); @@ -155,7 +162,7 @@ static bool ext_fileinto_opcode_execute printf(">> FILEINTO \"%s\"\n", str_c(folder)); - if ( sieve_act_store_add_to_result(renv, str_c(folder)) ) + if ( sieve_act_store_add_to_result(renv, slist, str_c(folder)) ) sieve_result_cancel_implicit_keep(renv->result); t_pop(); diff --git a/src/lib-sieve/plugins/copy/ext-copy.c b/src/lib-sieve/plugins/copy/ext-copy.c index 1655ae9c9..11c21d738 100644 --- a/src/lib-sieve/plugins/copy/ext-copy.c +++ b/src/lib-sieve/plugins/copy/ext-copy.c @@ -52,13 +52,25 @@ static bool ext_copy_load(int ext_id) const struct sieve_side_effect_extension ext_copy_side_effect; +bool seff_copy_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); +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); + const struct sieve_side_effect copy_side_effect = { "copy", &act_store, &ext_copy_side_effect, 0, - NULL, NULL, NULL, NULL + seff_copy_pre_execute, + NULL, + seff_copy_post_commit, + NULL }; const struct sieve_side_effect_extension ext_copy_side_effect = { @@ -108,6 +120,26 @@ static const struct sieve_argument copy_tag = { tag_copy_generate }; +/* Side effect execution */ + +bool seff_copy_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) +{ + printf(" + implicit keep preserved\n"); + return TRUE; +} + +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) +{ + printf(" + implicit keep restored\n"); + return TRUE; +} + /* Load extension into validator */ static bool ext_copy_validator_load(struct sieve_validator *validator) { diff --git a/src/lib-sieve/sieve-actions.c b/src/lib-sieve/sieve-actions.c index 6a00bf1f3..1d41439d6 100644 --- a/src/lib-sieve/sieve-actions.c +++ b/src/lib-sieve/sieve-actions.c @@ -153,7 +153,8 @@ const struct sieve_action act_store = { }; bool sieve_act_store_add_to_result -(const struct sieve_runtime_env *renv, const char *folder) +(const struct sieve_runtime_env *renv, + struct sieve_side_effects_list *seffects, const char *folder) { pool_t pool; struct act_store_context *act; @@ -163,7 +164,7 @@ bool sieve_act_store_add_to_result act = p_new(pool, struct act_store_context, 1); act->folder = p_strdup(pool, folder); - return sieve_result_add_action(renv, &act_store, (void *) act); + return sieve_result_add_action(renv, &act_store, seffects, (void *) act); } /* Store action implementation */ diff --git a/src/lib-sieve/sieve-actions.h b/src/lib-sieve/sieve-actions.h index cdf12ff7a..75058cf4c 100644 --- a/src/lib-sieve/sieve-actions.h +++ b/src/lib-sieve/sieve-actions.h @@ -115,7 +115,8 @@ struct act_store_transaction { }; bool sieve_act_store_add_to_result - (const struct sieve_runtime_env *renv, const char *folder); + (const struct sieve_runtime_env *renv, + struct sieve_side_effects_list *seffects, const char *folder); #endif /* __SIEVE_ACTIONS_H */ diff --git a/src/lib-sieve/sieve-binary.c b/src/lib-sieve/sieve-binary.c index ea47008f6..e27c5e6c4 100644 --- a/src/lib-sieve/sieve-binary.c +++ b/src/lib-sieve/sieve-binary.c @@ -289,9 +289,26 @@ bool sieve_binary_read_byte return TRUE; } + *byte_val = 0; return FALSE; } +bool sieve_binary_read_code + (struct sieve_binary *binary, sieve_size_t *address, int *code) +{ + if ( ADDR_BYTES_LEFT(binary, address) >= 1 ) { + if ( code != NULL ) + *code = ADDR_CODE_AT(binary, address); + ADDR_JUMP(address, 1); + + return TRUE; + } + + *code = 0; + return FALSE; +} + + bool sieve_binary_read_offset (struct sieve_binary *binary, sieve_size_t *address, int *offset) { diff --git a/src/lib-sieve/sieve-binary.h b/src/lib-sieve/sieve-binary.h index 8f2fafc2f..cd1a6f043 100644 --- a/src/lib-sieve/sieve-binary.h +++ b/src/lib-sieve/sieve-binary.h @@ -71,6 +71,8 @@ sieve_size_t sieve_binary_emit_ext_opcode_id /* Literals */ bool sieve_binary_read_byte (struct sieve_binary *binary, sieve_size_t *address, unsigned int *byte_val); +bool sieve_binary_read_code + (struct sieve_binary *binary, sieve_size_t *address, int *code); bool sieve_binary_read_offset (struct sieve_binary *binary, sieve_size_t *address, int *offset); bool sieve_binary_read_integer diff --git a/src/lib-sieve/sieve-code.c b/src/lib-sieve/sieve-code.c index 371d4fb6c..5714624f6 100644 --- a/src/lib-sieve/sieve-code.c +++ b/src/lib-sieve/sieve-code.c @@ -140,22 +140,8 @@ bool sieve_operand_optional_present(struct sieve_binary *sbin, sieve_size_t *add bool sieve_operand_optional_read(struct sieve_binary *sbin, sieve_size_t *address, int *id_code) { - unsigned int id; - - while ( sieve_binary_read_byte(sbin, address, &id) ) { - *id_code = (int) id; - - if ( *id_code == SIEVE_OPT_SIDE_EFFECT ) { - const struct sieve_side_effect *seffect = - sieve_opr_side_effect_read(sbin, address); - - printf("SIDE_EFFECT!!!\n"); - if ( seffect == NULL ) return FALSE; - - printf(" : SIDE_EFFECT: %s\n", seffect->name); - } else - return TRUE; - } + if ( sieve_binary_read_code(sbin, address, id_code) ) + return TRUE; *id_code = 0; diff --git a/src/lib-sieve/sieve-common.h b/src/lib-sieve/sieve-common.h index 92bba80e7..e717a566a 100644 --- a/src/lib-sieve/sieve-common.h +++ b/src/lib-sieve/sieve-common.h @@ -73,6 +73,7 @@ struct sieve_address_part; /* sieve-result.h */ struct sieve_result; +struct sieve_side_effects_list; /* sieve-actions.h */ struct sieve_action_exec_env; diff --git a/src/lib-sieve/sieve-interpreter.c b/src/lib-sieve/sieve-interpreter.c index 691fb7f4c..3e4af48f3 100644 --- a/src/lib-sieve/sieve-interpreter.c +++ b/src/lib-sieve/sieve-interpreter.c @@ -9,6 +9,7 @@ #include "sieve-extensions.h" #include "sieve-commands-private.h" +#include "sieve-actions.h" #include "sieve-generator.h" #include "sieve-binary.h" #include "sieve-result.h" @@ -166,6 +167,36 @@ bool sieve_interpreter_read_offset_operand { return sieve_binary_read_offset(interp->runenv.sbin, &(interp->pc), offset); } + +bool sieve_interpreter_handle_optional_operands + (const struct sieve_runtime_env *renv, sieve_size_t *address, + struct sieve_side_effects_list **list) +{ + int opt_code; + + if ( sieve_operand_optional_present(renv->sbin, address) ) { + while ( opt_code != 0 ) { + if ( !sieve_operand_optional_read(renv->sbin, address, &opt_code) ) + return FALSE; + + if ( opt_code == SIEVE_OPT_SIDE_EFFECT ) { + if ( list != NULL && *list == NULL ) + *list = sieve_side_effects_list_create(renv->result); + + const struct sieve_side_effect *seffect = + sieve_opr_side_effect_read(renv->sbin, address); + + if ( seffect == NULL ) return FALSE; + + printf(" : SIDE_EFFECT: %s\n", seffect->name); + + if ( list != NULL ) + sieve_side_effects_list_add(*list, seffect, NULL); + } + } + } + return TRUE; +} /* Code Dump */ diff --git a/src/lib-sieve/sieve-interpreter.h b/src/lib-sieve/sieve-interpreter.h index 5d4e0a5f8..8f37fb63b 100644 --- a/src/lib-sieve/sieve-interpreter.h +++ b/src/lib-sieve/sieve-interpreter.h @@ -50,6 +50,11 @@ inline const void *sieve_interpreter_extension_get_context bool sieve_interpreter_read_offset_operand (struct sieve_interpreter *interp, int *offset); + +struct sieve_result_action; +bool sieve_interpreter_handle_optional_operands + (const struct sieve_runtime_env *renv, sieve_size_t *address, + struct sieve_side_effects_list **list); /* Code dump (debugging purposes) */ diff --git a/src/lib-sieve/sieve-result.c b/src/lib-sieve/sieve-result.c index 2e1dabadc..ae5d8043e 100644 --- a/src/lib-sieve/sieve-result.c +++ b/src/lib-sieve/sieve-result.c @@ -7,14 +7,20 @@ #include "sieve-result.h" #include <stdio.h> - struct sieve_result_action { struct sieve_result *result; const struct sieve_action *action; void *context; void *tr_context; bool success; + + struct sieve_side_effects_list *seffects; + struct sieve_result_action *prev, *next; +}; + +struct sieve_side_effects_list { + struct sieve_result *result; struct sieve_result_side_effect *first_effect; struct sieve_result_side_effect *last_effect; @@ -81,7 +87,8 @@ void sieve_result_cancel_implicit_keep(struct sieve_result *result) bool sieve_result_add_action (const struct sieve_runtime_env *renv, - const struct sieve_action *action, void *context) + const struct sieve_action *action, struct sieve_side_effects_list *seffects, + void *context) { struct sieve_result *result = renv->result; struct sieve_result_action *raction; @@ -119,6 +126,7 @@ bool sieve_result_add_action raction->context = context; raction->tr_context = NULL; raction->success = FALSE; + raction->seffects = seffects; /* Add */ if ( result->first_action == NULL ) { @@ -136,33 +144,6 @@ bool sieve_result_add_action return TRUE; } -bool sieve_result_add_side_effect -(struct sieve_result_action *raction, const struct sieve_side_effect *seffect, - void *context) -{ - struct sieve_result_side_effect *reffect; - - /* Create new action object */ - reffect = p_new(raction->result->pool, struct sieve_result_side_effect, 1); - reffect->seffect = seffect; - reffect->context = context; - - /* Add */ - if ( raction->first_effect == NULL ) { - raction->first_effect = reffect; - raction->last_effect = reffect; - reffect->prev = NULL; - reffect->next = NULL; - } else { - raction->last_effect->next = reffect; - reffect->prev = raction->last_effect; - raction->last_effect = reffect; - reffect->next = NULL; - } - - return TRUE; -} - bool sieve_result_print(struct sieve_result *result) { struct sieve_result_action *rac = result->first_action; @@ -225,7 +206,7 @@ bool sieve_result_execute rac->context : rac->tr_context; /* Execute pre-execute event of side effects */ - rsef = rac->first_effect; + rsef = rac->seffects != NULL ? rac->seffects->first_effect : NULL; while ( rsef != NULL ) { sef = rsef->seffect; if ( sef->pre_execute != NULL ) @@ -241,7 +222,7 @@ bool sieve_result_execute } /* Execute pre-execute event of side effects */ - rsef = rac->first_effect; + rsef = rac->seffects != NULL ? rac->seffects->first_effect : NULL; while ( rsef != NULL ) { sef = rsef->seffect; if ( sef->post_execute != NULL ) @@ -273,7 +254,7 @@ bool sieve_result_execute commit_ok = act->commit(act, &result->action_env, context) && commit_ok; /* Execute post_commit event of side effects */ - rsef = rac->first_effect; + rsef = rac->seffects != NULL ? rac->seffects->first_effect : NULL; while ( rsef != NULL ) { sef = rsef->seffect; if ( sef->post_commit != NULL ) @@ -286,7 +267,7 @@ bool sieve_result_execute act->rollback(act, &result->action_env, context, rac->success); /* Rollback side effects */ - rsef = rac->first_effect; + rsef = rac->seffects != NULL ? rac->seffects->first_effect : NULL; while ( rsef != NULL ) { sef = rsef->seffect; if ( sef->rollback != NULL ) @@ -303,3 +284,47 @@ bool sieve_result_execute return commit_ok; } + +/* + * Side effects list + */ +struct sieve_side_effects_list *sieve_side_effects_list_create + (struct sieve_result *result) +{ + struct sieve_side_effects_list *list = + p_new(result->pool, struct sieve_side_effects_list, 1); + + list->result = result; + list->first_effect = NULL; + list->last_effect = NULL; + + return list; +}; + +void sieve_side_effects_list_add +(struct sieve_side_effects_list *list, const struct sieve_side_effect *seffect, + void *context) +{ + struct sieve_result_side_effect *reffect; + + /* Create new action object */ + reffect = p_new(list->result->pool, struct sieve_result_side_effect, 1); + reffect->seffect = seffect; + reffect->context = context; + + /* Add */ + if ( list->first_effect == NULL ) { + list->first_effect = reffect; + list->last_effect = reffect; + reffect->prev = NULL; + reffect->next = NULL; + } else { + list->last_effect->next = reffect; + reffect->prev = list->last_effect; + list->last_effect = reffect; + reffect->next = NULL; + } +} + + + diff --git a/src/lib-sieve/sieve-result.h b/src/lib-sieve/sieve-result.h index f32266846..8927048e1 100644 --- a/src/lib-sieve/sieve-result.h +++ b/src/lib-sieve/sieve-result.h @@ -4,8 +4,8 @@ #include "sieve-common.h" struct sieve_result; - struct sieve_result_action; +struct sieve_side_effects_list; struct sieve_result *sieve_result_create(void); void sieve_result_ref(struct sieve_result *result); @@ -13,10 +13,8 @@ void sieve_result_unref(struct sieve_result **result); inline pool_t sieve_result_pool(struct sieve_result *result); bool sieve_result_add_action -(const struct sieve_runtime_env *renv, const struct sieve_action *action, - void *context); -bool sieve_result_add_side_effect -(struct sieve_result_action *raction, const struct sieve_side_effect *seffect, +(const struct sieve_runtime_env *renv, + const struct sieve_action *action, struct sieve_side_effects_list *seffects, void *context); bool sieve_result_print(struct sieve_result *result); @@ -26,5 +24,11 @@ void sieve_result_cancel_implicit_keep(struct sieve_result *result); bool sieve_result_execute (struct sieve_result *result, const struct sieve_message_data *msgdata, const struct sieve_mail_environment *menv); + +struct sieve_side_effects_list *sieve_side_effects_list_create + (struct sieve_result *result); +void sieve_side_effects_list_add +(struct sieve_side_effects_list *list, const struct sieve_side_effect *seffect, + void *context); #endif -- GitLab