From 176c337e2a0b73b70da5dbbc1036aa1aec336443 Mon Sep 17 00:00:00 2001 From: Timo Sirainen <timo.sirainen@open-xchange.com> Date: Mon, 29 Apr 2019 14:57:56 +0300 Subject: [PATCH] lib-sieve: Add sieve_exec_status.significant_action_executed --- src/lib-sieve/cmd-discard.c | 1 + src/lib-sieve/cmd-redirect.c | 1 + src/lib-sieve/ext-reject.c | 1 + .../plugins/duplicate/ext-duplicate-common.c | 1 + src/lib-sieve/plugins/enotify/cmd-notify.c | 2 + src/lib-sieve/plugins/notify/cmd-notify.c | 5 ++- src/lib-sieve/plugins/vacation/cmd-vacation.c | 2 + .../plugins/vnd.dovecot/report/cmd-report.c | 1 + src/lib-sieve/sieve-actions.c | 43 +++++++++++++++++-- src/lib-sieve/sieve-types.h | 1 + 10 files changed, 54 insertions(+), 4 deletions(-) diff --git a/src/lib-sieve/cmd-discard.c b/src/lib-sieve/cmd-discard.c index 92c710951..a5ed06677 100644 --- a/src/lib-sieve/cmd-discard.c +++ b/src/lib-sieve/cmd-discard.c @@ -154,6 +154,7 @@ static int act_discard_commit const struct sieve_action_exec_env *aenv, void *tr_context ATTR_UNUSED, bool *keep) { + aenv->exec_status->significant_action_executed = TRUE; sieve_result_global_log(aenv, "marked message to be discarded if not explicitly delivered " "(discard action)"); diff --git a/src/lib-sieve/cmd-redirect.c b/src/lib-sieve/cmd-redirect.c index 0647ce11d..af405b412 100644 --- a/src/lib-sieve/cmd-redirect.c +++ b/src/lib-sieve/cmd-redirect.c @@ -576,6 +576,7 @@ act_redirect_commit(const struct sieve_action *action, sieve_action_duplicate_mark(senv, dupeid, strlen(dupeid), ioloop_time + svinst->redirect_duplicate_period); + aenv->exec_status->significant_action_executed = TRUE; sieve_result_global_log( aenv, "redirect action: forwarded to <%s>", smtp_address_encode(ctx->to_address)); diff --git a/src/lib-sieve/ext-reject.c b/src/lib-sieve/ext-reject.c index 9519f4118..def2b8604 100644 --- a/src/lib-sieve/ext-reject.c +++ b/src/lib-sieve/ext-reject.c @@ -519,6 +519,7 @@ static int act_reject_commit (aenv, recipient, rj_ctx->reason)) <= 0 ) return ret; + aenv->exec_status->significant_action_executed = TRUE; sieve_result_global_log(aenv, "rejected message from <%s> (%s)", smtp_address_encode(sender), diff --git a/src/lib-sieve/plugins/duplicate/ext-duplicate-common.c b/src/lib-sieve/plugins/duplicate/ext-duplicate-common.c index 62e0bbd29..73afea044 100644 --- a/src/lib-sieve/plugins/duplicate/ext-duplicate-common.c +++ b/src/lib-sieve/plugins/duplicate/ext-duplicate-common.c @@ -118,6 +118,7 @@ static void act_duplicate_mark_finish /* Message was handled successfully, so track duplicate for this * message. */ + aenv->exec_status->significant_action_executed = TRUE; sieve_action_duplicate_mark (senv, data->hash, sizeof(data->hash), ioloop_time + data->period); } diff --git a/src/lib-sieve/plugins/enotify/cmd-notify.c b/src/lib-sieve/plugins/enotify/cmd-notify.c index e69cbc240..52ef15e20 100644 --- a/src/lib-sieve/plugins/enotify/cmd-notify.c +++ b/src/lib-sieve/plugins/enotify/cmd-notify.c @@ -578,6 +578,8 @@ static int act_notify_commit (aenv->ehandler, NULL, "notify action"); ret = method->def->action_execute(&nenv, act); + if (ret >= 0) + aenv->exec_status->significant_action_executed = TRUE; sieve_error_handler_unref(&nenv.ehandler); } diff --git a/src/lib-sieve/plugins/notify/cmd-notify.c b/src/lib-sieve/plugins/notify/cmd-notify.c index 3019eb999..9ee5322ca 100644 --- a/src/lib-sieve/plugins/notify/cmd-notify.c +++ b/src/lib-sieve/plugins/notify/cmd-notify.c @@ -838,7 +838,10 @@ static int act_notify_commit result = act_notify_send(aenv, act); } T_END; - return ( result ? SIEVE_EXEC_OK : SIEVE_EXEC_FAILURE ); + if (!result) + return SIEVE_EXEC_FAILURE; + aenv->exec_status->significant_action_executed = TRUE; + return SIEVE_EXEC_OK; } diff --git a/src/lib-sieve/plugins/vacation/cmd-vacation.c b/src/lib-sieve/plugins/vacation/cmd-vacation.c index 2f6806f27..d7af93e2e 100644 --- a/src/lib-sieve/plugins/vacation/cmd-vacation.c +++ b/src/lib-sieve/plugins/vacation/cmd-vacation.c @@ -1134,6 +1134,7 @@ static int act_vacation_send return SIEVE_EXEC_FAILURE; } + aenv->exec_status->significant_action_executed = TRUE; return SIEVE_EXEC_OK; } @@ -1459,6 +1460,7 @@ static int act_vacation_commit if ( ret == SIEVE_EXEC_OK ) { sieve_number_t seconds; + aenv->exec_status->significant_action_executed = TRUE; sieve_result_global_log(aenv, "sent vacation response to <%s>", smtp_address_encode(sender)); diff --git a/src/lib-sieve/plugins/vnd.dovecot/report/cmd-report.c b/src/lib-sieve/plugins/vnd.dovecot/report/cmd-report.c index 4ec2514f4..15caf1ff3 100644 --- a/src/lib-sieve/plugins/vnd.dovecot/report/cmd-report.c +++ b/src/lib-sieve/plugins/vnd.dovecot/report/cmd-report.c @@ -650,6 +650,7 @@ static int act_report_send str_sanitize(error, 512)); } } else { + aenv->exec_status->significant_action_executed = TRUE; sieve_result_global_log(aenv, "sent `%s' report to <%s>", str_sanitize(act->feedback_type, 32), diff --git a/src/lib-sieve/sieve-actions.c b/src/lib-sieve/sieve-actions.c index b71b48371..c32b7fd41 100644 --- a/src/lib-sieve/sieve-actions.c +++ b/src/lib-sieve/sieve-actions.c @@ -482,6 +482,32 @@ static struct mail_keywords *act_store_keywords_create return box_keywords; } +static bool +have_equal_keywords(struct mail *mail, struct mail_keywords *new_kw) +{ + const ARRAY_TYPE(keyword_indexes) *old_kw_arr = + mail_get_keyword_indexes(mail); + const unsigned int *old_kw; + unsigned int i, j; + + if (array_count(old_kw_arr) != new_kw->count) + return FALSE; + if (new_kw->count == 0) + return TRUE; + + old_kw = array_front(old_kw_arr); + for (i = 0; i < new_kw->count; i++) { + /* new_kw->count equals old_kw's count and it's easier to use */ + for (j = 0; j < new_kw->count; j++) { + if (old_kw[j] == new_kw->idx[i]) + break; + } + if (j == new_kw->count) + return FALSE; + } + return TRUE; +} + static int act_store_execute (const struct sieve_action *action, const struct sieve_action_exec_env *aenv, void *tr_context) @@ -538,11 +564,17 @@ static int act_store_execute (aenv, &trans->keywords, mail->box, TRUE); if ( keywords != NULL ) { - mail_update_keywords(mail, MODIFY_REPLACE, keywords); + if (!have_equal_keywords(mail, keywords)) { + aenv->exec_status->significant_action_executed = TRUE; + mail_update_keywords(mail, MODIFY_REPLACE, keywords); + } mailbox_keywords_unref(&keywords); } - mail_update_flags(mail, MODIFY_REPLACE, trans->flags); + if ((mail_get_flags(mail) & MAIL_FLAGS_NONRECENT) != trans->flags) { + aenv->exec_status->significant_action_executed = TRUE; + mail_update_flags(mail, MODIFY_REPLACE, trans->flags); + } } return SIEVE_EXEC_OK; @@ -581,7 +613,10 @@ static int act_store_execute if ( trans->flags_altered ) { keywords = act_store_keywords_create(aenv, &trans->keywords, trans->box, FALSE); - mailbox_save_set_flags(save_ctx, trans->flags, keywords); + if (trans->flags != 0 || keywords != NULL) { + aenv->exec_status->significant_action_executed = TRUE; + mailbox_save_set_flags(save_ctx, trans->flags, keywords); + } } else { mailbox_save_copy_flags(save_ctx, mail); } @@ -590,6 +625,8 @@ static int act_store_execute sieve_act_store_get_storage_error(aenv, trans); status = ( trans->error_code == MAIL_ERROR_TEMP ? SIEVE_EXEC_TEMP_FAILURE : SIEVE_EXEC_FAILURE ); + } else { + aenv->exec_status->significant_action_executed = TRUE; } /* Deallocate keywords */ diff --git a/src/lib-sieve/sieve-types.h b/src/lib-sieve/sieve-types.h index 6b93dd203..dce10d542 100644 --- a/src/lib-sieve/sieve-types.h +++ b/src/lib-sieve/sieve-types.h @@ -260,6 +260,7 @@ struct sieve_exec_status { bool tried_default_save:1; bool keep_original:1; bool store_failed:1; + bool significant_action_executed:1; }; /* -- GitLab