summaryrefslogtreecommitdiffstats
path: root/pigeonhole/src/managesieve/cmd-setactive.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 09:51:24 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 09:51:24 +0000
commitf7548d6d28c313cf80e6f3ef89aed16a19815df1 (patch)
treea3f6f2a3f247293bee59ecd28e8cd8ceb6ca064a /pigeonhole/src/managesieve/cmd-setactive.c
parentInitial commit. (diff)
downloaddovecot-f7548d6d28c313cf80e6f3ef89aed16a19815df1.tar.xz
dovecot-f7548d6d28c313cf80e6f3ef89aed16a19815df1.zip
Adding upstream version 1:2.3.19.1+dfsg1.upstream/1%2.3.19.1+dfsg1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'pigeonhole/src/managesieve/cmd-setactive.c')
-rw-r--r--pigeonhole/src/managesieve/cmd-setactive.c165
1 files changed, 165 insertions, 0 deletions
diff --git a/pigeonhole/src/managesieve/cmd-setactive.c b/pigeonhole/src/managesieve/cmd-setactive.c
new file mode 100644
index 0000000..07844c5
--- /dev/null
+++ b/pigeonhole/src/managesieve/cmd-setactive.c
@@ -0,0 +1,165 @@
+/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file
+ */
+
+#include "lib.h"
+#include "str.h"
+
+#include "sieve.h"
+#include "sieve-script.h"
+#include "sieve-storage.h"
+
+#include "managesieve-common.h"
+#include "managesieve-commands.h"
+
+static void
+cmd_setactive_activate(struct client_command_context *cmd,
+ const char *scriptname)
+{
+ struct client *client = cmd->client;
+ struct sieve_storage *storage = client->storage;
+ struct sieve_script *script;
+ string_t *errors = NULL;
+ const char *errormsg = NULL;
+ unsigned int warning_count = 0, error_count = 0;
+ bool success = TRUE;
+ int ret;
+
+ event_add_str(cmd->event, "script_name", scriptname);
+
+ script = sieve_storage_open_script(storage, scriptname, NULL);
+ if (script == NULL) {
+ client_command_storage_error(
+ cmd, "Failed to open script `%s' for activation",
+ scriptname);
+ return;
+ }
+
+ if (sieve_script_is_active(script) <= 0) T_BEGIN {
+ /* Script is first being activated; compile it again without the
+ UPLOAD flag. */
+ struct sieve_error_handler *ehandler;
+ enum sieve_compile_flags cpflags =
+ SIEVE_COMPILE_FLAG_NOGLOBAL |
+ SIEVE_COMPILE_FLAG_ACTIVATED;
+ struct sieve_binary *sbin;
+ enum sieve_error error;
+
+ /* Prepare error handler */
+ errors = str_new(default_pool, 1024);
+ ehandler = sieve_strbuf_ehandler_create(
+ client->svinst, errors, TRUE,
+ client->set->managesieve_max_compile_errors);
+
+ /* Compile */
+ sbin = sieve_compile_script(script, ehandler, cpflags, &error);
+ if (sbin == NULL) {
+ if (error != SIEVE_ERROR_NOT_VALID) {
+ errormsg = sieve_script_get_last_error(
+ script, &error);
+ if (error == SIEVE_ERROR_NONE)
+ errormsg = NULL;
+ }
+ success = FALSE;
+ } else {
+ sieve_close(&sbin);
+ }
+
+ warning_count = sieve_get_warnings(ehandler);
+ error_count = sieve_get_errors(ehandler);
+ sieve_error_handler_unref(&ehandler);
+ } T_END;
+
+ /* Activate only when script is valid (or already active) */
+ if (success) {
+ /* Refresh activation no matter what; this can also
+ resolve some erroneous situations. */
+ ret = sieve_script_activate(script, (time_t)-1);
+ if (ret < 0) {
+ client_command_storage_error(
+ cmd, "Failed to activate script `%s'",
+ scriptname);
+ } else {
+ struct event_passthrough *e =
+ client_command_create_finish_event(cmd)->
+ add_int("compile_warnings", warning_count);
+ e_debug(e->event(), "Activated script `%s' "
+ " (%u warnings%s)",
+ scriptname, warning_count,
+ (ret == 0 ? ", redundant" : ""));
+
+ if (warning_count > 0) {
+ client_send_okresp(
+ client, "WARNINGS",
+ str_c(errors));
+ } else {
+ client_send_ok(client,
+ (ret > 0 ?
+ "Setactive completed." :
+ "Script is already active."));
+ }
+ }
+ } else if (errormsg == NULL) {
+ struct event_passthrough *e =
+ client_command_create_finish_event(cmd)->
+ add_str("error", "Compilation failed")->
+ add_int("compile_errors", error_count)->
+ add_int("compile_warnings", warning_count);
+ e_debug(e->event(), "Failed to activate script `%s': "
+ "Compilation failed (%u errors, %u warnings)",
+ scriptname, error_count, warning_count);
+
+ client_send_no(client, str_c(errors));
+ } else {
+ struct event_passthrough *e =
+ client_command_create_finish_event(cmd)->
+ add_str("error", errormsg);
+ e_debug(e->event(), "Failed to activate script `%s': %s",
+ scriptname, errormsg);
+
+ client_send_no(client, errormsg);
+ }
+
+ if (errors != NULL)
+ str_free(&errors);
+ sieve_script_unref(&script);
+}
+
+static void
+cmd_setactive_deactivate(struct client_command_context *cmd)
+{
+ struct client *client = cmd->client;
+ struct sieve_storage *storage = client->storage;
+ int ret;
+
+ ret = sieve_storage_deactivate(storage, (time_t)-1);
+ if (ret < 0) {
+ client_command_storage_error(
+ cmd, "Failed to deactivate script");
+ return;
+ }
+
+ struct event_passthrough *e =
+ client_command_create_finish_event(cmd);
+ e_debug(e->event(), "Deactivated script");
+
+ client_send_ok(client, (ret > 0 ?
+ "Active script is now deactivated." :
+ "No scripts currently active."));
+}
+
+bool cmd_setactive(struct client_command_context *cmd)
+{
+ const char *scriptname;
+
+ /* <scriptname> */
+ if (!client_read_string_args(cmd, TRUE, 1, &scriptname))
+ return FALSE;
+
+ /* Activate, or deactivate */
+ if (*scriptname != '\0')
+ cmd_setactive_activate(cmd, scriptname);
+ else
+ cmd_setactive_deactivate(cmd);
+
+ return TRUE;
+}