From 94f8e03af24b222d931f26b7ae3a783c88616d75 Mon Sep 17 00:00:00 2001 From: Stephan Bosch <stephan.bosch@dovecot.fi> Date: Sun, 1 Oct 2017 20:57:38 +0200 Subject: [PATCH] lib-sieve: sieve-result - Sort action side effects based on precedence value. This way, the execution order can be made explicit. --- src/lib-sieve/plugins/imap4flags/tag-flags.c | 14 +++--- .../plugins/mailbox/tag-mailbox-create.c | 1 + src/lib-sieve/sieve-actions.h | 4 ++ src/lib-sieve/sieve-result.c | 43 +++++++++++++------ 4 files changed, 42 insertions(+), 20 deletions(-) diff --git a/src/lib-sieve/plugins/imap4flags/tag-flags.c b/src/lib-sieve/plugins/imap4flags/tag-flags.c index bd85baabf..0536b829f 100644 --- a/src/lib-sieve/plugins/imap4flags/tag-flags.c +++ b/src/lib-sieve/plugins/imap4flags/tag-flags.c @@ -74,14 +74,12 @@ seff_flags_pre_execute(const struct sieve_side_effect *seffect, const struct sieve_side_effect_def flags_side_effect = { SIEVE_OBJECT("flags", &flags_side_effect_operand, 0), - &act_store, - - seff_flags_dump_context, - seff_flags_read_context, - seff_flags_merge, - seff_flags_print, - seff_flags_pre_execute, - NULL, NULL, NULL + .to_action = &act_store, + .dump_context = seff_flags_dump_context, + .read_context = seff_flags_read_context, + .merge = seff_flags_merge, + .print = seff_flags_print, + .pre_execute = seff_flags_pre_execute }; /* diff --git a/src/lib-sieve/plugins/mailbox/tag-mailbox-create.c b/src/lib-sieve/plugins/mailbox/tag-mailbox-create.c index 026c697bf..04977d9a5 100644 --- a/src/lib-sieve/plugins/mailbox/tag-mailbox-create.c +++ b/src/lib-sieve/plugins/mailbox/tag-mailbox-create.c @@ -50,6 +50,7 @@ seff_mailbox_create_pre_execute(const struct sieve_side_effect *seffect, const struct sieve_side_effect_def mailbox_create_side_effect = { SIEVE_OBJECT("create", &mailbox_create_operand, 0), + .precedence = 100, .to_action = &act_store, .print = seff_mailbox_create_print, .pre_execute = seff_mailbox_create_pre_execute diff --git a/src/lib-sieve/sieve-actions.h b/src/lib-sieve/sieve-actions.h index e86c688c8..4c9017ec6 100644 --- a/src/lib-sieve/sieve-actions.h +++ b/src/lib-sieve/sieve-actions.h @@ -103,6 +103,10 @@ struct sieve_action { struct sieve_side_effect_def { struct sieve_object_def obj_def; + /* Precedence (side effects with higher value are executed first) */ + + unsigned int precedence; + /* The action it is supposed to link to */ const struct sieve_action_def *to_action; diff --git a/src/lib-sieve/sieve-result.c b/src/lib-sieve/sieve-result.c index dcb9e21c1..9a90d903b 100644 --- a/src/lib-sieve/sieve-result.c +++ b/src/lib-sieve/sieve-result.c @@ -1604,13 +1604,24 @@ 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) { - struct sieve_result_side_effect *reffect; + struct sieve_result_side_effect *reffect, *reffect_pos; /* Prevent duplicates */ reffect = list->first_effect; + reffect_pos = NULL; while (reffect != NULL) { - if (reffect->seffect.def == seffect->def) + const struct sieve_side_effect_def *ref_def = reffect->seffect.def; + const struct sieve_side_effect_def *sef_def = seffect->def; + + if (sef_def == ref_def) { + /* already listed */ + i_assert(reffect_pos == NULL); return; + } + if (sef_def->precedence > ref_def->precedence) { + /* insert it before this position */ + reffect_pos = reffect; + } reffect = reffect->next; } @@ -1619,17 +1630,25 @@ void sieve_side_effects_list_add(struct sieve_side_effects_list *list, reffect = p_new(list->result->pool, struct sieve_result_side_effect, 1); reffect->seffect = *seffect; - /* Add */ - if (list->first_effect == NULL) { - list->first_effect = reffect; - list->last_effect = reffect; - reffect->prev = NULL; - reffect->next = NULL; + if (reffect_pos != NULL) { + /* Insert */ + reffect->next = reffect_pos; + reffect_pos->prev = reffect; + if (list->first_effect == reffect_pos) + list->first_effect = reffect; } else { - list->last_effect->next = reffect; - reffect->prev = list->last_effect; - list->last_effect = reffect; - reffect->next = NULL; + /* 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; + } } } -- GitLab