diff --git a/sieve/tests/redirect.sieve b/sieve/tests/redirect.sieve index 57ced4ae3a0118a12555e20f12ad4ec9cabff8d3..6d02c6edca32384f62c8f60792277d505b289735 100644 --- a/sieve/tests/redirect.sieve +++ b/sieve/tests/redirect.sieve @@ -1,5 +1,6 @@ if address :contains "to" "vestingbar" { redirect "stephan@example.com"; + keep; } redirect "stephan@rename-it.nl"; diff --git a/src/lib-sieve/cmd-keep.c b/src/lib-sieve/cmd-keep.c index 99838fb74b0c6401474e61e1e3f883b843bbd7b2..6335f3effadd7c7dcc7f6b09c55b1a596fa78846 100644 --- a/src/lib-sieve/cmd-keep.c +++ b/src/lib-sieve/cmd-keep.c @@ -51,7 +51,7 @@ static int act_keep_execute const struct sieve_action act_keep = { "keep", - NULL, + NULL, NULL, act_keep_execute }; @@ -88,7 +88,7 @@ static bool opc_keep_execute /* * Action */ - + static int act_keep_execute (const struct sieve_action *action ATTR_UNUSED, const struct sieve_action_exec_env *aenv, void *context) diff --git a/src/lib-sieve/cmd-redirect.c b/src/lib-sieve/cmd-redirect.c index 31de529ac410e35840e2db5ae5a549bc0d12c79c..d8f1eff42e0b25ce7bacdd588a941ae50af574d0 100644 --- a/src/lib-sieve/cmd-redirect.c +++ b/src/lib-sieve/cmd-redirect.c @@ -50,6 +50,9 @@ const struct sieve_opcode cmd_redirect_opcode = { /* Redirect action */ +static bool act_redirect_check_duplicate + (const struct sieve_action *action1 ATTR_UNUSED, void *context1, + void *context2); static void act_redirect_print (const struct sieve_action *action, void *context); static int act_redirect_execute @@ -62,6 +65,7 @@ struct act_redirect_context { const struct sieve_action act_redirect = { "redirect", + act_redirect_check_duplicate, act_redirect_print, act_redirect_execute }; @@ -146,8 +150,21 @@ static bool cmd_redirect_opcode_execute } /* - * Action + * Actionstatic bool act_redirect_check_duplicate +(const struct sieve_action *action1 ATTR_UNUSED, void *context1, void *context2) */ + +static bool act_redirect_check_duplicate +(const struct sieve_action *action1 ATTR_UNUSED, void *context1, void *context2) +{ + struct act_redirect_context *ctx1 = (struct act_redirect_context *) context1; + struct act_redirect_context *ctx2 = (struct act_redirect_context *) context2; + + if ( strcmp(ctx1->to_address, ctx2->to_address) == 0 ) + return TRUE; + + return FALSE; +} static void act_redirect_print (const struct sieve_action *action ATTR_UNUSED, void *context) diff --git a/src/lib-sieve/sieve-result.c b/src/lib-sieve/sieve-result.c index 30e49dc6ce228829faa6e24ccf8b432a4a9fe194..cd1bc4f0374f91ef088e794936ff0504d359626c 100644 --- a/src/lib-sieve/sieve-result.c +++ b/src/lib-sieve/sieve-result.c @@ -59,11 +59,30 @@ inline pool_t sieve_result_pool(struct sieve_result *result) return result->pool; } -void sieve_result_add_action +bool sieve_result_add_action (struct sieve_result *result, const struct sieve_action *action, void *context) { struct sieve_result_action *raction; + /* First, check for duplicates */ + raction = result->first_action; + while ( raction != NULL ) { + if ( raction->action == action ) { + const struct sieve_action *oact = raction->action; + + if ( oact->check_duplicate != NULL ) { + if ( oact->check_duplicate(action, raction->context, context) ) + return FALSE; + } else + return FALSE; + } + raction = raction->next; + } + + /* Check for conflicts */ + + /* FIXME: Unimplemented */ + /* Create new action object */ raction = p_new(result->pool, struct sieve_result_action, 1); raction->action = action; @@ -81,6 +100,8 @@ void sieve_result_add_action result->last_action = raction; raction->next = NULL; } + + return TRUE; } bool sieve_result_print(struct sieve_result *result) diff --git a/src/lib-sieve/sieve-result.h b/src/lib-sieve/sieve-result.h index 6790cad49570abad2f3c0e9fee185e08e3caa831..4165171c1f131a22042cb7abc7bac927a0330b85 100644 --- a/src/lib-sieve/sieve-result.h +++ b/src/lib-sieve/sieve-result.h @@ -13,6 +13,9 @@ struct sieve_action_exec_env { struct sieve_action { const char *name; + bool (*check_duplicate) + (const struct sieve_action *action1, void *context1, void *context2); + void (*print) (const struct sieve_action *action, void *context); int (*execute) @@ -25,7 +28,7 @@ void sieve_result_ref(struct sieve_result *result); void sieve_result_unref(struct sieve_result **result); inline pool_t sieve_result_pool(struct sieve_result *result); -void sieve_result_add_action +bool sieve_result_add_action (struct sieve_result *result, const struct sieve_action *action, void *context);