summaryrefslogtreecommitdiffstats
path: root/pigeonhole/src/lib-sieve/sieve-execute.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 17:36:47 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 17:36:47 +0000
commit0441d265f2bb9da249c7abf333f0f771fadb4ab5 (patch)
tree3f3789daa2f6db22da6e55e92bee0062a7d613fe /pigeonhole/src/lib-sieve/sieve-execute.c
parentInitial commit. (diff)
downloaddovecot-0441d265f2bb9da249c7abf333f0f771fadb4ab5.tar.xz
dovecot-0441d265f2bb9da249c7abf333f0f771fadb4ab5.zip
Adding upstream version 1:2.3.21+dfsg1.upstream/1%2.3.21+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'pigeonhole/src/lib-sieve/sieve-execute.c')
-rw-r--r--pigeonhole/src/lib-sieve/sieve-execute.c162
1 files changed, 162 insertions, 0 deletions
diff --git a/pigeonhole/src/lib-sieve/sieve-execute.c b/pigeonhole/src/lib-sieve/sieve-execute.c
new file mode 100644
index 0000000..a395cc6
--- /dev/null
+++ b/pigeonhole/src/lib-sieve/sieve-execute.c
@@ -0,0 +1,162 @@
+/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file
+ */
+
+#include "lib.h"
+
+#include "sieve-execute.h"
+
+struct sieve_execute_state {
+ void *dup_trans;
+};
+
+struct event_category event_category_sieve_execute = {
+ .parent = &event_category_sieve,
+ .name = "sieve-execute",
+};
+
+static struct sieve_execute_state *
+sieve_execute_state_create(struct sieve_execute_env *eenv)
+{
+ return p_new(eenv->pool, struct sieve_execute_state, 1);
+}
+
+static void
+sieve_execute_state_free(struct sieve_execute_state **_estate,
+ struct sieve_execute_env *eenv)
+{
+ struct sieve_execute_state *estate = *_estate;
+ const struct sieve_script_env *senv = eenv->scriptenv;
+
+ *_estate = NULL;
+
+ if (senv->duplicate_transaction_rollback != NULL)
+ senv->duplicate_transaction_rollback(&estate->dup_trans);
+}
+
+void sieve_execute_init(struct sieve_execute_env *eenv,
+ struct sieve_instance *svinst, pool_t pool,
+ const struct sieve_message_data *msgdata,
+ const struct sieve_script_env *senv,
+ enum sieve_execute_flags flags)
+{
+ i_zero(eenv);
+ eenv->svinst = svinst;
+ eenv->pool = pool;
+ eenv->flags = flags;
+ eenv->msgdata = msgdata;
+ eenv->scriptenv = senv;
+
+ pool_ref(pool);
+ eenv->event = event_create(svinst->event);
+ event_add_category(eenv->event, &event_category_sieve_execute);
+ event_add_str(eenv->event, "message_id", msgdata->id);
+ if ((flags & SIEVE_EXECUTE_FLAG_NO_ENVELOPE) == 0) {
+ /* Make sure important envelope fields are available */
+ event_add_str(eenv->event, "mail_from",
+ smtp_address_encode(msgdata->envelope.mail_from));
+ event_add_str(eenv->event, "rcpt_to",
+ smtp_address_encode(msgdata->envelope.rcpt_to));
+ }
+
+ eenv->state = sieve_execute_state_create(eenv);
+
+ eenv->exec_status = senv->exec_status;
+ if (eenv->exec_status == NULL)
+ eenv->exec_status = p_new(pool, struct sieve_exec_status, 1);
+ else
+ i_zero(eenv->exec_status);
+}
+
+void sieve_execute_finish(struct sieve_execute_env *eenv, int status)
+{
+ const struct sieve_script_env *senv = eenv->scriptenv;
+
+ if (status == SIEVE_EXEC_OK) {
+ if (senv->duplicate_transaction_commit != NULL) {
+ senv->duplicate_transaction_commit(
+ &eenv->state->dup_trans);
+ }
+ } else {
+ if (senv->duplicate_transaction_rollback != NULL) {
+ senv->duplicate_transaction_rollback(
+ &eenv->state->dup_trans);
+ }
+ }
+}
+
+void sieve_execute_deinit(struct sieve_execute_env *eenv)
+{
+ sieve_execute_state_free(&eenv->state, eenv);
+ event_unref(&eenv->event);
+ pool_unref(&eenv->pool);
+}
+
+/*
+ * Checking for duplicates
+ */
+
+static void *
+sieve_execute_get_dup_transaction(const struct sieve_execute_env *eenv)
+{
+ const struct sieve_script_env *senv = eenv->scriptenv;
+
+ if (senv->duplicate_transaction_begin == NULL)
+ return NULL;
+ if (eenv->state->dup_trans == NULL) {
+ eenv->state->dup_trans =
+ senv->duplicate_transaction_begin(senv);
+ }
+ return eenv->state->dup_trans;
+}
+
+bool sieve_execute_duplicate_check_available(
+ const struct sieve_execute_env *eenv)
+{
+ const struct sieve_script_env *senv = eenv->scriptenv;
+
+ return (senv->duplicate_transaction_begin != NULL);
+}
+
+int sieve_execute_duplicate_check(const struct sieve_execute_env *eenv,
+ const void *id, size_t id_size,
+ bool *duplicate_r)
+{
+ const struct sieve_script_env *senv = eenv->scriptenv;
+ void *dup_trans = sieve_execute_get_dup_transaction(eenv);
+ int ret;
+
+ *duplicate_r = FALSE;
+
+ if (senv->duplicate_check == NULL)
+ return SIEVE_EXEC_OK;
+
+ e_debug(eenv->svinst->event, "Check duplicate ID");
+
+ ret = senv->duplicate_check(dup_trans, senv, id, id_size);
+ switch (ret) {
+ case SIEVE_DUPLICATE_CHECK_RESULT_EXISTS:
+ *duplicate_r = TRUE;
+ break;
+ case SIEVE_DUPLICATE_CHECK_RESULT_NOT_FOUND:
+ break;
+ case SIEVE_DUPLICATE_CHECK_RESULT_FAILURE:
+ return SIEVE_EXEC_FAILURE;
+ case SIEVE_DUPLICATE_CHECK_RESULT_TEMP_FAILURE:
+ return SIEVE_EXEC_TEMP_FAILURE;
+ }
+ return SIEVE_EXEC_OK;
+}
+
+void sieve_execute_duplicate_mark(const struct sieve_execute_env *eenv,
+ const void *id, size_t id_size, time_t time)
+{
+ const struct sieve_script_env *senv = eenv->scriptenv;
+ void *dup_trans = sieve_execute_get_dup_transaction(eenv);
+
+ if (senv->duplicate_mark == NULL)
+ return;
+
+ e_debug(eenv->svinst->event, "Mark ID as duplicate");
+
+ senv->duplicate_mark(dup_trans, senv, id, id_size, time);
+}