summaryrefslogtreecommitdiffstats
path: root/pigeonhole/src/lib-sieve/cmd-discard.c
diff options
context:
space:
mode:
Diffstat (limited to 'pigeonhole/src/lib-sieve/cmd-discard.c')
-rw-r--r--pigeonhole/src/lib-sieve/cmd-discard.c173
1 files changed, 173 insertions, 0 deletions
diff --git a/pigeonhole/src/lib-sieve/cmd-discard.c b/pigeonhole/src/lib-sieve/cmd-discard.c
new file mode 100644
index 0000000..de460ae
--- /dev/null
+++ b/pigeonhole/src/lib-sieve/cmd-discard.c
@@ -0,0 +1,173 @@
+/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file
+ */
+
+#include "lib.h"
+#include "str-sanitize.h"
+
+#include "sieve-common.h"
+#include "sieve-commands.h"
+#include "sieve-code.h"
+#include "sieve-dump.h"
+#include "sieve-actions.h"
+#include "sieve-validator.h"
+#include "sieve-generator.h"
+#include "sieve-interpreter.h"
+#include "sieve-result.h"
+
+/*
+ * Discard command
+ *
+ * Syntax
+ * discard
+ */
+
+static bool
+cmd_discard_generate(const struct sieve_codegen_env *cgenv,
+ struct sieve_command *ctx ATTR_UNUSED);
+
+const struct sieve_command_def cmd_discard = {
+ .identifier = "discard",
+ .type = SCT_COMMAND,
+ .positional_args = 0,
+ .subtests = 0,
+ .block_allowed = FALSE,
+ .block_required = FALSE,
+ .generate = cmd_discard_generate
+};
+
+/*
+ * Discard operation
+ */
+
+static bool
+cmd_discard_operation_dump(const struct sieve_dumptime_env *denv,
+ sieve_size_t *address);
+static int
+cmd_discard_operation_execute(const struct sieve_runtime_env *renv,
+ sieve_size_t *address);
+
+const struct sieve_operation_def cmd_discard_operation = {
+ .mnemonic = "DISCARD",
+ .code = SIEVE_OPERATION_DISCARD,
+ .dump = cmd_discard_operation_dump,
+ .execute = cmd_discard_operation_execute
+};
+
+/*
+ * Discard actions
+ */
+
+static bool
+act_discard_equals(const struct sieve_script_env *senv,
+ const struct sieve_action *act1,
+ const struct sieve_action *act2);
+static int
+act_discard_check_duplicate(const struct sieve_runtime_env *renv,
+ const struct sieve_action *act,
+ const struct sieve_action *act_other);
+static void
+act_discard_print(const struct sieve_action *action,
+ const struct sieve_result_print_env *rpenv, bool *keep);
+static int
+act_discard_execute(const struct sieve_action_exec_env *aenv, void *tr_context,
+ bool *keep);
+
+const struct sieve_action_def act_discard = {
+ .name = "discard",
+ .equals = act_discard_equals,
+ .check_duplicate = act_discard_check_duplicate,
+ .print = act_discard_print,
+ .execute = act_discard_execute,
+};
+
+/*
+ * Code generation
+ */
+
+static bool
+cmd_discard_generate(const struct sieve_codegen_env *cgenv,
+ struct sieve_command *cmd ATTR_UNUSED)
+{
+ sieve_operation_emit(cgenv->sblock, NULL, &cmd_discard_operation);
+
+ return TRUE;
+}
+
+/*
+ * Code dump
+ */
+
+static bool
+cmd_discard_operation_dump(const struct sieve_dumptime_env *denv,
+ sieve_size_t *address)
+{
+ sieve_code_dumpf(denv, "DISCARD");
+ sieve_code_descend(denv);
+
+ return (sieve_action_opr_optional_dump(denv, address, NULL) == 0);
+}
+
+/*
+ * Interpretation
+ */
+
+static int
+cmd_discard_operation_execute(const struct sieve_runtime_env *renv ATTR_UNUSED,
+ sieve_size_t *address ATTR_UNUSED)
+{
+ sieve_runtime_trace(renv, SIEVE_TRLVL_ACTIONS,
+ "discard action; cancel implicit keep");
+
+ if (sieve_result_add_action(renv, NULL, "discard", &act_discard,
+ NULL, NULL, 0, FALSE) < 0)
+ return SIEVE_EXEC_FAILURE;
+ return SIEVE_EXEC_OK;
+}
+
+/*
+ * Action implementation
+ */
+
+static bool
+act_discard_equals(const struct sieve_script_env *senv ATTR_UNUSED,
+ const struct sieve_action *act1 ATTR_UNUSED,
+ const struct sieve_action *act2 ATTR_UNUSED)
+{
+ return TRUE;
+}
+
+static int
+act_discard_check_duplicate(const struct sieve_runtime_env *renv ATTR_UNUSED,
+ const struct sieve_action *act ATTR_UNUSED,
+ const struct sieve_action *act_other ATTR_UNUSED)
+{
+ return 1;
+}
+
+static void
+act_discard_print(const struct sieve_action *action ATTR_UNUSED,
+ const struct sieve_result_print_env *rpenv, bool *keep)
+{
+ sieve_result_action_printf(rpenv, "discard");
+
+ *keep = FALSE;
+}
+
+static int
+act_discard_execute(const struct sieve_action_exec_env *aenv,
+ void *tr_context ATTR_UNUSED, bool *keep)
+{
+ const struct sieve_execute_env *eenv = aenv->exec_env;
+
+ eenv->exec_status->significant_action_executed = TRUE;
+
+ struct event_passthrough *e = sieve_action_create_finish_event(aenv);
+
+ sieve_result_event_log(aenv, e->event(),
+ "Marked message to be discarded if not explicitly delivered "
+ "(discard action)");
+ *keep = FALSE;
+
+ return SIEVE_EXEC_OK;
+}
+