From c031d4bdf3bca086ba2975c0958a35b87f2824da Mon Sep 17 00:00:00 2001
From: Stephan Bosch <stephan.bosch@open-xchange.com>
Date: Tue, 27 Aug 2024 01:13:23 +0200
Subject: [PATCH] lib-sieve: vnd.dovecot.report extension: Migrate settings to
 new config structure

---
 .../plugins/vnd.dovecot/report/Makefile.am    |  2 +
 .../plugins/vnd.dovecot/report/cmd-report.c   |  2 +-
 .../report/ext-vnd-report-common.c            | 24 ++++++--
 .../report/ext-vnd-report-common.h            |  5 +-
 .../report/ext-vnd-report-settings.c          | 57 +++++++++++++++++++
 .../report/ext-vnd-report-settings.h          | 18 ++++++
 .../vnd.dovecot/report/ext-vnd-report.c       |  1 +
 src/lib-sieve/sieve-address-source.h          |  5 +-
 8 files changed, 106 insertions(+), 8 deletions(-)
 create mode 100644 src/lib-sieve/plugins/vnd.dovecot/report/ext-vnd-report-settings.c
 create mode 100644 src/lib-sieve/plugins/vnd.dovecot/report/ext-vnd-report-settings.h

diff --git a/src/lib-sieve/plugins/vnd.dovecot/report/Makefile.am b/src/lib-sieve/plugins/vnd.dovecot/report/Makefile.am
index 599765f0a..c473aa097 100644
--- a/src/lib-sieve/plugins/vnd.dovecot/report/Makefile.am
+++ b/src/lib-sieve/plugins/vnd.dovecot/report/Makefile.am
@@ -10,8 +10,10 @@ commands = \
 
 libsieve_ext_vnd_report_la_SOURCES = \
 	ext-vnd-report.c \
+	ext-vnd-report-settings.c \
 	ext-vnd-report-common.c \
 	$(commands)
 
 noinst_HEADERS = \
+	ext-vnd-report-settings.h \
 	ext-vnd-report-common.h
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 11a09bb05..b56eeb875 100644
--- a/src/lib-sieve/plugins/vnd.dovecot/report/cmd-report.c
+++ b/src/lib-sieve/plugins/vnd.dovecot/report/cmd-report.c
@@ -453,7 +453,7 @@ act_report_send(const struct sieve_action_exec_env *aenv,
 	struct sieve_message_context *msgctx = aenv->msgctx;
 	const struct sieve_script_env *senv = eenv->scriptenv;
 	const struct sieve_message_data *msgdata = eenv->msgdata;
-	struct sieve_address_source report_from = extctx->report_from;
+	struct sieve_address_source report_from = extctx->set->parsed.from;
 	const struct smtp_address *sender, *user;
 	struct sieve_smtp_context *sctx;
 	struct istream *input;
diff --git a/src/lib-sieve/plugins/vnd.dovecot/report/ext-vnd-report-common.c b/src/lib-sieve/plugins/vnd.dovecot/report/ext-vnd-report-common.c
index 543b5c6b8..47947ba97 100644
--- a/src/lib-sieve/plugins/vnd.dovecot/report/ext-vnd-report-common.c
+++ b/src/lib-sieve/plugins/vnd.dovecot/report/ext-vnd-report-common.c
@@ -3,6 +3,7 @@
 
 #include "lib.h"
 #include "str.h"
+#include "settings.h"
 #include "rfc822-parser.h"
 
 #include "sieve-common.h"
@@ -14,17 +15,32 @@ int ext_report_load(const struct sieve_extension *ext, void **context_r)
 {
 	struct sieve_instance *svinst = ext->svinst;
 	struct ext_report_context *extctx;
+	const struct ext_report_settings *set;
+	const char *error;
 
-	extctx = p_new(svinst->pool, struct ext_report_context, 1);
+	if (settings_get(svinst->event, &ext_report_setting_parser_info, 0,
+			 &set, &error) < 0) {
+		e_error(svinst->event, "%s", error);
+		return -1;
+	}
 
-	(void)sieve_address_source_parse_from_setting(
-		svinst, svinst->pool, "sieve_report_from",
-		&extctx->report_from);
+	extctx = i_new(struct ext_report_context, 1);
+	extctx->set = set;
 
 	*context_r = extctx;
 	return 0;
 }
 
+void ext_report_unload(const struct sieve_extension *ext)
+{
+	struct ext_report_context *extctx = ext->context;
+
+	if (extctx == NULL)
+		return;
+	settings_free(extctx->set);
+	i_free(extctx);
+}
+
 const char *ext_vnd_report_parse_feedback_type(const char *feedback_type)
 {
 	struct rfc822_parser_context parser;
diff --git a/src/lib-sieve/plugins/vnd.dovecot/report/ext-vnd-report-common.h b/src/lib-sieve/plugins/vnd.dovecot/report/ext-vnd-report-common.h
index 6302a7e75..1e45d1f32 100644
--- a/src/lib-sieve/plugins/vnd.dovecot/report/ext-vnd-report-common.h
+++ b/src/lib-sieve/plugins/vnd.dovecot/report/ext-vnd-report-common.h
@@ -1,12 +1,14 @@
 #ifndef EXT_REPORT_COMMON_H
 #define EXT_REPORT_COMMON_H
 
+#include "ext-vnd-report-settings.h"
+
 /*
  * Extension configuration
  */
 
 struct ext_report_context {
-	struct sieve_address_source report_from;
+	const struct ext_report_settings *set;
 };
 
 /*
@@ -16,6 +18,7 @@ struct ext_report_context {
 extern const struct sieve_extension_def vnd_report_extension;
 
 int ext_report_load(const struct sieve_extension *ext, void **context_r);
+void ext_report_unload(const struct sieve_extension *ext);
 
 /*
  * Commands
diff --git a/src/lib-sieve/plugins/vnd.dovecot/report/ext-vnd-report-settings.c b/src/lib-sieve/plugins/vnd.dovecot/report/ext-vnd-report-settings.c
new file mode 100644
index 000000000..89b93d771
--- /dev/null
+++ b/src/lib-sieve/plugins/vnd.dovecot/report/ext-vnd-report-settings.c
@@ -0,0 +1,57 @@
+/* Copyright (c) 2024 Pigeonhole authors, see the included COPYING file
+ */
+
+#include "lib.h"
+#include "array.h"
+#include "settings.h"
+#include "settings-parser.h"
+
+#include "ext-vnd-report-settings.h"
+
+static bool
+ext_report_settings_check(void *_set, pool_t pool, const char **error_r);
+
+#undef DEF
+#define DEF(type, name) \
+	SETTING_DEFINE_STRUCT_##type("sieve_report_"#name, name, \
+				     struct ext_report_settings)
+
+static const struct setting_define ext_report_setting_defines[] = {
+	DEF(STR, from),
+
+	SETTING_DEFINE_LIST_END,
+};
+
+static const struct ext_report_settings ext_report_default_settings = {
+	.from = "",
+};
+
+const struct setting_parser_info ext_report_setting_parser_info = {
+	.name = "sieve_report",
+
+	.defines = ext_report_setting_defines,
+	.defaults = &ext_report_default_settings,
+
+	.struct_size = sizeof(struct ext_report_settings),
+
+	.check_func = ext_report_settings_check,
+
+	.pool_offset1 = 1 + offsetof(struct ext_report_settings, pool),
+};
+
+/* <settings checks> */
+static bool
+ext_report_settings_check(void *_set, pool_t pool, const char **error_r)
+{
+	struct ext_report_settings *set = _set;
+
+	if (!sieve_address_source_parse(pool, set->from, &set->parsed.from)) {
+		*error_r = t_strdup_printf("sieve_report_from: "
+					   "Invalid address source '%s'",
+					   set->from);
+		return FALSE;
+	}
+
+	return TRUE;
+}
+/* </settings checks> */
diff --git a/src/lib-sieve/plugins/vnd.dovecot/report/ext-vnd-report-settings.h b/src/lib-sieve/plugins/vnd.dovecot/report/ext-vnd-report-settings.h
new file mode 100644
index 000000000..d71f4c4d4
--- /dev/null
+++ b/src/lib-sieve/plugins/vnd.dovecot/report/ext-vnd-report-settings.h
@@ -0,0 +1,18 @@
+#ifndef EXT_REPORT_SETTINGS_H
+#define EXT_REPORT_SETTINGS_H
+
+#include "sieve-address-source.h"
+
+struct ext_report_settings {
+	pool_t pool;
+
+	const char *from;
+
+	struct {
+		struct sieve_address_source from;
+	} parsed;
+};
+
+extern const struct setting_parser_info ext_report_setting_parser_info;
+
+#endif
diff --git a/src/lib-sieve/plugins/vnd.dovecot/report/ext-vnd-report.c b/src/lib-sieve/plugins/vnd.dovecot/report/ext-vnd-report.c
index f1cc7ce0d..90c8aaab0 100644
--- a/src/lib-sieve/plugins/vnd.dovecot/report/ext-vnd-report.c
+++ b/src/lib-sieve/plugins/vnd.dovecot/report/ext-vnd-report.c
@@ -35,6 +35,7 @@ ext_report_validator_load(const struct sieve_extension *ext,
 const struct sieve_extension_def vnd_report_extension = {
 	.name = "vnd.dovecot.report",
 	.load = ext_report_load,
+	.unload = ext_report_unload,
 	.validator_load = ext_report_validator_load,
 	SIEVE_EXT_DEFINE_OPERATION(report_operation),
 };
diff --git a/src/lib-sieve/sieve-address-source.h b/src/lib-sieve/sieve-address-source.h
index 5a300ff7a..5bfd5ff7d 100644
--- a/src/lib-sieve/sieve-address-source.h
+++ b/src/lib-sieve/sieve-address-source.h
@@ -1,9 +1,10 @@
 #ifndef SIEVE_ADDRESS_SOURCE_H
 #define SIEVE_ADDRESS_SOURCE_H
 
-#include "sieve-common.h"
-
+struct sieve_instance;
+struct sieve_script_env;
 struct sieve_message_context;
+enum sieve_execute_flags;
 
 enum sieve_address_source_type {
 	SIEVE_ADDRESS_SOURCE_DEFAULT = 0,
-- 
GitLab