From ef4b920a1c7ef8a2a7b48ed1fc8b36e537595e84 Mon Sep 17 00:00:00 2001
From: Stephan Bosch <stephan.bosch@open-xchange.com>
Date: Wed, 16 Oct 2024 05:10:05 +0200
Subject: [PATCH] lib-sieve: sieve-extensions - Handle reload in the central
 load function

Was handled in each extension before, which is useless.
---
 .../plugins/duplicate/ext-duplicate-common.c  |  9 ++----
 .../plugins/duplicate/ext-duplicate-common.h  |  2 +-
 .../editheader/ext-editheader-common.c        |  9 ++----
 .../editheader/ext-editheader-common.h        |  2 +-
 src/lib-sieve/plugins/enotify/ext-enotify.c   | 13 ++++-----
 .../plugins/imap4flags/ext-imap4flags.c       | 11 ++------
 .../plugins/include/ext-include-common.c      |  9 ++----
 .../plugins/include/ext-include-common.h      |  2 +-
 src/lib-sieve/plugins/mime/ext-extracttext.c  | 11 ++------
 .../spamvirustest/ext-spamvirustest-common.c  | 28 ++++++++-----------
 .../spamvirustest/ext-spamvirustest-common.h  |  2 +-
 .../plugins/subaddress/ext-subaddress.c       |  9 ++----
 .../plugins/variables/ext-variables-common.c  |  9 ++----
 .../plugins/variables/ext-variables-common.h  |  2 +-
 .../environment/ext-vnd-environment.c         | 11 ++------
 .../report/ext-vnd-report-common.c            |  4 +--
 .../report/ext-vnd-report-common.h            |  2 +-
 src/lib-sieve/sieve-extensions.c              |  6 ++++
 src/lib-sieve/sieve-extensions.h              |  2 +-
 src/plugins/imapsieve/ext-imapsieve.c         | 22 ++++-----------
 .../sieve-extprograms-common.c                |  9 ++----
 .../sieve-extprograms-common.h                |  2 +-
 22 files changed, 59 insertions(+), 117 deletions(-)

diff --git a/src/lib-sieve/plugins/duplicate/ext-duplicate-common.c b/src/lib-sieve/plugins/duplicate/ext-duplicate-common.c
index 48e244b71..41262233b 100644
--- a/src/lib-sieve/plugins/duplicate/ext-duplicate-common.c
+++ b/src/lib-sieve/plugins/duplicate/ext-duplicate-common.c
@@ -28,17 +28,12 @@
 #define EXT_DUPLICATE_DEFAULT_PERIOD (12*60*60)
 #define EXT_DUPLICATE_DEFAULT_MAX_PERIOD (2*24*60*60)
 
-int ext_duplicate_load(const struct sieve_extension *ext, void **context)
+int ext_duplicate_load(const struct sieve_extension *ext, void **context_r)
 {
 	struct sieve_instance *svinst = ext->svinst;
 	struct ext_duplicate_context *extctx;
 	sieve_number_t default_period, max_period;
 
-	if (*context != NULL) {
-		ext_duplicate_unload(ext);
-		*context = NULL;
-	}
-
 	if (!sieve_setting_get_duration_value(
 		svinst, "sieve_duplicate_default_period", &default_period))
 		default_period = EXT_DUPLICATE_DEFAULT_PERIOD;
@@ -51,7 +46,7 @@ int ext_duplicate_load(const struct sieve_extension *ext, void **context)
 	extctx->default_period = default_period;
 	extctx->max_period = max_period;
 
-	*context = extctx;
+	*context_r = extctx;
 	return 0;
 }
 
diff --git a/src/lib-sieve/plugins/duplicate/ext-duplicate-common.h b/src/lib-sieve/plugins/duplicate/ext-duplicate-common.h
index a5181f2c8..3ad0b7907 100644
--- a/src/lib-sieve/plugins/duplicate/ext-duplicate-common.h
+++ b/src/lib-sieve/plugins/duplicate/ext-duplicate-common.h
@@ -12,7 +12,7 @@ struct ext_duplicate_context {
 	unsigned int max_period;
 };
 
-int ext_duplicate_load(const struct sieve_extension *ext, void **context);
+int ext_duplicate_load(const struct sieve_extension *ext, void **context_r);
 void ext_duplicate_unload(const struct sieve_extension *ext);
 
 extern const struct sieve_extension_def duplicate_extension;
diff --git a/src/lib-sieve/plugins/editheader/ext-editheader-common.c b/src/lib-sieve/plugins/editheader/ext-editheader-common.c
index a28d25d19..58a9cb517 100644
--- a/src/lib-sieve/plugins/editheader/ext-editheader-common.c
+++ b/src/lib-sieve/plugins/editheader/ext-editheader-common.c
@@ -93,18 +93,13 @@ ext_editheader_config_headers(struct sieve_instance *svinst,
 	}
 }
 
-int ext_editheader_load(const struct sieve_extension *ext, void **context)
+int ext_editheader_load(const struct sieve_extension *ext, void **context_r)
 {
 	struct ext_editheader_context *extctx;
 	struct sieve_instance *svinst = ext->svinst;
 	size_t max_header_size;
 	pool_t pool;
 
-	if (*context != NULL) {
-		ext_editheader_unload(ext);
-		*context = NULL;
-	}
-
 	T_BEGIN {
 		pool = pool_alloconly_create("editheader_config", 1024);
 		extctx = p_new(pool, struct ext_editheader_context, 1);
@@ -139,7 +134,7 @@ int ext_editheader_load(const struct sieve_extension *ext, void **context)
 		}
 	} T_END;
 
-	*context = extctx;
+	*context_r = extctx;
 	return 0;
 }
 
diff --git a/src/lib-sieve/plugins/editheader/ext-editheader-common.h b/src/lib-sieve/plugins/editheader/ext-editheader-common.h
index 161d03998..646db1abd 100644
--- a/src/lib-sieve/plugins/editheader/ext-editheader-common.h
+++ b/src/lib-sieve/plugins/editheader/ext-editheader-common.h
@@ -26,7 +26,7 @@ extern const struct sieve_operation_def deleteheader_operation;
 
 extern const struct sieve_extension_def editheader_extension;
 
-int ext_editheader_load(const struct sieve_extension *ext, void **context);
+int ext_editheader_load(const struct sieve_extension *ext, void **context_r);
 void ext_editheader_unload(const struct sieve_extension *ext);
 
 /*
diff --git a/src/lib-sieve/plugins/enotify/ext-enotify.c b/src/lib-sieve/plugins/enotify/ext-enotify.c
index c2fa3c5d5..d00b12dd2 100644
--- a/src/lib-sieve/plugins/enotify/ext-enotify.c
+++ b/src/lib-sieve/plugins/enotify/ext-enotify.c
@@ -40,7 +40,8 @@ const struct sieve_operation_def *ext_enotify_operations[] = {
  * Extension
  */
 
-static int ext_enotify_load(const struct sieve_extension *ext, void **context);
+static int
+ext_enotify_load(const struct sieve_extension *ext, void **context_r);
 static void ext_enotify_unload(const struct sieve_extension *ext);
 static bool
 ext_enotify_validator_load(const struct sieve_extension *ext,
@@ -55,26 +56,22 @@ const struct sieve_extension_def enotify_extension = {
 	SIEVE_EXT_DEFINE_OPERAND(encodeurl_operand),
 };
 
-static int ext_enotify_load(const struct sieve_extension *ext, void **context)
+static int ext_enotify_load(const struct sieve_extension *ext, void **context_r)
 {
 	const struct sieve_extension *var_ext;
 	struct ext_enotify_context *extctx;
 
-	if (*context != NULL) {
-		ext_enotify_unload(ext);
-		*context = NULL;
-	}
-
 	if (sieve_ext_variables_get_extension(ext->svinst, &var_ext) < 0)
 		return -1;
 
 	extctx = i_new(struct ext_enotify_context, 1);
 	extctx->var_ext = var_ext;
-	*context = extctx;
 
 	ext_enotify_methods_init(ext->svinst, extctx);
 
 	sieve_extension_capabilities_register(ext, &notify_capabilities);
+
+	*context_r = extctx;
 	return 0;
 }
 
diff --git a/src/lib-sieve/plugins/imap4flags/ext-imap4flags.c b/src/lib-sieve/plugins/imap4flags/ext-imap4flags.c
index c4cea7fcc..1968129b7 100644
--- a/src/lib-sieve/plugins/imap4flags/ext-imap4flags.c
+++ b/src/lib-sieve/plugins/imap4flags/ext-imap4flags.c
@@ -43,7 +43,7 @@ const struct sieve_operation_def *imap4flags_operations[] = {
  */
 
 static int
-ext_imap4flags_load(const struct sieve_extension *ext, void **context);
+ext_imap4flags_load(const struct sieve_extension *ext, void **context_r);
 static void ext_imap4flags_unload(const struct sieve_extension *ext);
 
 static bool ext_imap4flags_validator_load
@@ -64,24 +64,19 @@ const struct sieve_extension_def imap4flags_extension = {
 };
 
 static int
-ext_imap4flags_load(const struct sieve_extension *ext, void **context)
+ext_imap4flags_load(const struct sieve_extension *ext, void **context_r)
 {
 	struct sieve_instance *svinst = ext->svinst;
 	const struct sieve_extension *var_ext;
 	struct ext_imap4flags_context *extctx;
 
-	if (*context != NULL) {
-		ext_imap4flags_unload(ext);
-		*context = NULL;
-	}
-
 	if (sieve_ext_variables_get_extension(svinst, &var_ext) < 0)
 		return -1;
 
 	extctx = i_new(struct ext_imap4flags_context, 1);
 	extctx->var_ext = var_ext;
 
-	*context = extctx;
+	*context_r = extctx;
 	return 0;
 }
 
diff --git a/src/lib-sieve/plugins/include/ext-include-common.c b/src/lib-sieve/plugins/include/ext-include-common.c
index eb271d09a..79e684f3c 100644
--- a/src/lib-sieve/plugins/include/ext-include-common.c
+++ b/src/lib-sieve/plugins/include/ext-include-common.c
@@ -73,7 +73,7 @@ struct ext_include_interpreter_context {
 
 /* Extension hooks */
 
-int ext_include_load(const struct sieve_extension *ext, void **context)
+int ext_include_load(const struct sieve_extension *ext, void **context_r)
 {
 	struct sieve_instance *svinst = ext->svinst;
 	const struct sieve_extension *var_ext;
@@ -81,11 +81,6 @@ int ext_include_load(const struct sieve_extension *ext, void **context)
 	const char *location;
 	unsigned long long int uint_setting;
 
-	if (*context != NULL) {
-		ext_include_unload(ext);
-		*context = NULL;
-	}
-
 	/* Extension dependencies */
 	if (sieve_ext_variables_get_extension(ext->svinst, &var_ext) < 0)
 		return -1;
@@ -115,7 +110,7 @@ int ext_include_load(const struct sieve_extension *ext, void **context)
 		svinst, "sieve_include_max_includes", &uint_setting))
 		extctx->max_includes = (unsigned int)uint_setting;
 
-	*context = extctx;
+	*context_r = extctx;
 	return 0;
 }
 
diff --git a/src/lib-sieve/plugins/include/ext-include-common.h b/src/lib-sieve/plugins/include/ext-include-common.h
index cc98b7763..9b9ca7c63 100644
--- a/src/lib-sieve/plugins/include/ext-include-common.h
+++ b/src/lib-sieve/plugins/include/ext-include-common.h
@@ -53,7 +53,7 @@ ext_include_script_location_name(enum ext_include_script_location location)
 extern const struct sieve_extension_def include_extension;
 extern const struct sieve_binary_extension include_binary_ext;
 
-int ext_include_load(const struct sieve_extension *ext, void **context);
+int ext_include_load(const struct sieve_extension *ext, void **context_r);
 void ext_include_unload(const struct sieve_extension *ext);
 
 /*
diff --git a/src/lib-sieve/plugins/mime/ext-extracttext.c b/src/lib-sieve/plugins/mime/ext-extracttext.c
index c2c3e218f..b62b2cc9a 100644
--- a/src/lib-sieve/plugins/mime/ext-extracttext.c
+++ b/src/lib-sieve/plugins/mime/ext-extracttext.c
@@ -31,7 +31,7 @@
  */
 
 static int
-ext_extracttext_load(const struct sieve_extension *ext, void **context);
+ext_extracttext_load(const struct sieve_extension *ext, void **context_r);
 static void
 ext_extracttext_unload(const struct sieve_extension *ext);
 static bool
@@ -47,18 +47,13 @@ const struct sieve_extension_def extracttext_extension = {
 };
 
 static int
-ext_extracttext_load(const struct sieve_extension *ext, void **context)
+ext_extracttext_load(const struct sieve_extension *ext, void **context_r)
 {
 	struct sieve_instance *svinst = ext->svinst;
 	const struct sieve_extension *var_ext;
 	const struct sieve_extension *fep_ext;
 	struct ext_extracttext_context *extctx;
 
-	if (*context != NULL) {
-		ext_extracttext_unload(ext);
-		*context = NULL;
-	}
-
 	if (sieve_ext_variables_get_extension(ext->svinst, &var_ext) < 0)
 		return -1;
 	if (sieve_extension_register(svinst, &foreverypart_extension, FALSE,
@@ -69,7 +64,7 @@ ext_extracttext_load(const struct sieve_extension *ext, void **context)
 	extctx->var_ext = var_ext;
 	extctx->fep_ext = fep_ext;
 
-	*context = extctx;
+	*context_r = extctx;
 	return 0;
 }
 
diff --git a/src/lib-sieve/plugins/spamvirustest/ext-spamvirustest-common.c b/src/lib-sieve/plugins/spamvirustest/ext-spamvirustest-common.c
index 48376fdfe..e6c43fa15 100644
--- a/src/lib-sieve/plugins/spamvirustest/ext-spamvirustest-common.c
+++ b/src/lib-sieve/plugins/spamvirustest/ext-spamvirustest-common.c
@@ -37,8 +37,7 @@ struct ext_spamvirustest_header_spec {
 
 struct ext_spamvirustest_context {
 	pool_t pool;
-
-	int reload;
+	unsigned int reload_id;
 
 	struct ext_spamvirustest_header_spec status_header;
 	struct ext_spamvirustest_header_spec max_header;
@@ -249,22 +248,17 @@ ext_spamvirustest_parse_decimal_value(const char *str_value,
  * Extension initialization
  */
 
-int ext_spamvirustest_load(const struct sieve_extension *ext, void **context)
+int ext_spamvirustest_load(const struct sieve_extension *ext, void **context_r)
 {
+	static unsigned int reload_id = 0;
 	struct sieve_instance *svinst = ext->svinst;
-	struct ext_spamvirustest_context *extctx = *context;
+	struct ext_spamvirustest_context *extctx;
 	const char *ext_name, *status_header, *max_header, *status_type,
 		*max_value;
 	enum ext_spamvirustest_status_type type;
 	const char *error;
 	pool_t pool;
-	int reload = 0, ret = 0;
-
-	if (*context != NULL) {
-		reload = extctx->reload + 1;
-		ext_spamvirustest_unload(ext);
-		*context = NULL;
-	}
+	int ret = 0;
 
 	/* FIXME: Prevent loading of both spamtest and spamtestplus:
 	   let these share contexts.
@@ -343,7 +337,7 @@ int ext_spamvirustest_load(const struct sieve_extension *ext, void **context)
 	pool = pool_alloconly_create("spamvirustest_data", 512);
 	extctx = p_new(pool, struct ext_spamvirustest_context, 1);
 	extctx->pool = pool;
-	extctx->reload = reload;
+	extctx->reload_id = ++reload_id;
 	extctx->status_type = type;
 
 	if (!ext_spamvirustest_header_spec_parse(
@@ -405,14 +399,14 @@ int ext_spamvirustest_load(const struct sieve_extension *ext, void **context)
 		}
 	}
 
-	*context = extctx;
+	*context_r = extctx;
 	if (ret < 0) {
 		e_warning(svinst->event, "%s: "
 			  "extension not configured, "
 			  "tests will always match against \"0\"",
 			  ext_name);
 		ext_spamvirustest_unload(ext);
-		*context = NULL;
+		*context_r = NULL;
 	}
 
 	return ret;
@@ -435,7 +429,7 @@ void ext_spamvirustest_unload(const struct sieve_extension *ext)
  */
 
 struct ext_spamvirustest_message_context {
-	int reload;
+	unsigned int reload_id;
 	float score_ratio;
 };
 
@@ -500,7 +494,7 @@ int ext_spamvirustest_get_value(const struct sieve_runtime_env *renv,
 		/* Create new context */
 		mctx = p_new(pool, struct ext_spamvirustest_message_context, 1);
 		sieve_message_context_extension_set(msgctx, ext, mctx);
-	} else if (mctx->reload == extctx->reload) {
+	} else if (mctx->reload_id == extctx->reload_id) {
 		/* Use cached result */
 		*value_r = ext_spamvirustest_get_score(ext, mctx->score_ratio,
 						       percent);
@@ -509,7 +503,7 @@ int ext_spamvirustest_get_value(const struct sieve_runtime_env *renv,
 		/* Extension was reloaded (probably in testsuite) */
 	}
 
-	mctx->reload = extctx->reload;
+	mctx->reload_id = extctx->reload_id;
 
 	/*
 	 * Get max status value
diff --git a/src/lib-sieve/plugins/spamvirustest/ext-spamvirustest-common.h b/src/lib-sieve/plugins/spamvirustest/ext-spamvirustest-common.h
index 87d484460..154ec3458 100644
--- a/src/lib-sieve/plugins/spamvirustest/ext-spamvirustest-common.h
+++ b/src/lib-sieve/plugins/spamvirustest/ext-spamvirustest-common.h
@@ -11,7 +11,7 @@ extern const struct sieve_extension_def spamtest_extension;
 extern const struct sieve_extension_def spamtestplus_extension;
 extern const struct sieve_extension_def virustest_extension;
 
-int ext_spamvirustest_load(const struct sieve_extension *ext, void **context);
+int ext_spamvirustest_load(const struct sieve_extension *ext, void **context_r);
 void ext_spamvirustest_unload(const struct sieve_extension *ext);
 
 /*
diff --git a/src/lib-sieve/plugins/subaddress/ext-subaddress.c b/src/lib-sieve/plugins/subaddress/ext-subaddress.c
index 34a54c1f3..85e6e9a94 100644
--- a/src/lib-sieve/plugins/subaddress/ext-subaddress.c
+++ b/src/lib-sieve/plugins/subaddress/ext-subaddress.c
@@ -64,16 +64,11 @@ const struct sieve_extension_def subaddress_extension = {
 };
 
 static int
-ext_subaddress_load(const struct sieve_extension *ext, void **context)
+ext_subaddress_load(const struct sieve_extension *ext, void **context_r)
 {
 	struct ext_subaddress_context *extctx;
 	const char *delim;
 
-	if (*context != NULL) {
-		ext_subaddress_unload(ext);
-		*context = NULL;
-	}
-
 	delim = sieve_setting_get(ext->svinst, "recipient_delimiter");
 
 	if (delim == NULL)
@@ -82,7 +77,7 @@ ext_subaddress_load(const struct sieve_extension *ext, void **context)
 	extctx = i_new(struct ext_subaddress_context, 1);
 	extctx->delimiter = i_strdup(delim);
 
-	*context = extctx;
+	*context_r = extctx;
 	return 0;
 }
 
diff --git a/src/lib-sieve/plugins/variables/ext-variables-common.c b/src/lib-sieve/plugins/variables/ext-variables-common.c
index 5aa411e82..dab91448a 100644
--- a/src/lib-sieve/plugins/variables/ext-variables-common.c
+++ b/src/lib-sieve/plugins/variables/ext-variables-common.c
@@ -52,18 +52,13 @@ size_t sieve_variables_get_max_variable_size(
  * Extension configuration
  */
 
-int ext_variables_load(const struct sieve_extension *ext, void **context)
+int ext_variables_load(const struct sieve_extension *ext, void **context_r)
 {
 	struct sieve_instance *svinst = ext->svinst;
 	struct ext_variables_context *extctx;
 	unsigned long long int uint_setting;
 	size_t size_setting;
 
-	if (*context != NULL) {
-		ext_variables_unload(ext);
-		*context = NULL;
-	}
-
 	extctx = i_new(struct ext_variables_context, 1);
 
 	/* Get limits */
@@ -97,7 +92,7 @@ int ext_variables_load(const struct sieve_extension *ext, void **context)
 		}
 	}
 
-	*context = extctx;
+	*context_r = extctx;
 	return 0;
 }
 
diff --git a/src/lib-sieve/plugins/variables/ext-variables-common.h b/src/lib-sieve/plugins/variables/ext-variables-common.h
index f0c1fef42..16c6dab9a 100644
--- a/src/lib-sieve/plugins/variables/ext-variables-common.h
+++ b/src/lib-sieve/plugins/variables/ext-variables-common.h
@@ -19,7 +19,7 @@ struct ext_variables_context {
 
 extern const struct sieve_extension_def variables_extension;
 
-int ext_variables_load(const struct sieve_extension *ext, void **context);
+int ext_variables_load(const struct sieve_extension *ext, void **context_r);
 void ext_variables_unload(const struct sieve_extension *ext);
 
 const struct ext_variables_context *
diff --git a/src/lib-sieve/plugins/vnd.dovecot/environment/ext-vnd-environment.c b/src/lib-sieve/plugins/vnd.dovecot/environment/ext-vnd-environment.c
index e3a81e932..529950eeb 100644
--- a/src/lib-sieve/plugins/vnd.dovecot/environment/ext-vnd-environment.c
+++ b/src/lib-sieve/plugins/vnd.dovecot/environment/ext-vnd-environment.c
@@ -36,7 +36,7 @@
  */
 
 static int
-ext_vnd_environment_load(const struct sieve_extension *ext, void **context);
+ext_vnd_environment_load(const struct sieve_extension *ext, void **context_r);
 static void
 ext_vnd_environment_unload(const struct sieve_extension *ext);
 static bool
@@ -57,17 +57,12 @@ const struct sieve_extension_def vnd_environment_extension = {
 };
 
 static int
-ext_vnd_environment_load(const struct sieve_extension *ext, void **context)
+ext_vnd_environment_load(const struct sieve_extension *ext, void **context_r)
 {
 	const struct sieve_extension *ext_env;
 	const struct sieve_extension *ext_var;
 	struct ext_vnd_environment_context *extctx;
 
-	if (*context != NULL) {
-		ext_vnd_environment_unload(ext);
-		*context = NULL;
-	}
-
 	if (sieve_ext_environment_require_extension(ext->svinst, &ext_env) < 0)
 		return -1;
 	if (sieve_ext_variables_get_extension(ext->svinst, &ext_var) < 0)
@@ -77,7 +72,7 @@ ext_vnd_environment_load(const struct sieve_extension *ext, void **context)
 	extctx->env_ext = ext_env;
 	extctx->var_ext = ext_var;
 
-	*context = extctx;
+	*context_r = extctx;
 	return 0;
 }
 
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 f2d7668e9..543b5c6b8 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
@@ -10,7 +10,7 @@
 
 #include "ext-vnd-report-common.h"
 
-int ext_report_load(const struct sieve_extension *ext, void **context)
+int ext_report_load(const struct sieve_extension *ext, void **context_r)
 {
 	struct sieve_instance *svinst = ext->svinst;
 	struct ext_report_context *extctx;
@@ -21,7 +21,7 @@ int ext_report_load(const struct sieve_extension *ext, void **context)
 		svinst, svinst->pool, "sieve_report_from",
 		&extctx->report_from);
 
-	*context = extctx;
+	*context_r = extctx;
 	return 0;
 }
 
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 09ea4d940..6302a7e75 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
@@ -15,7 +15,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);
+int ext_report_load(const struct sieve_extension *ext, void **context_r);
 
 /*
  * Commands
diff --git a/src/lib-sieve/sieve-extensions.c b/src/lib-sieve/sieve-extensions.c
index ac033ac48..19e175557 100644
--- a/src/lib-sieve/sieve-extensions.c
+++ b/src/lib-sieve/sieve-extensions.c
@@ -296,10 +296,16 @@ sieve_extensions_get_preloaded(struct sieve_instance *svinst,
  * Extension registry
  */
 
+static void _sieve_extension_unload(struct sieve_extension *ext);
+
 static int _sieve_extension_load(struct sieve_extension *ext)
 {
 	int ret;
 
+	/* Drop context if this is a reload */
+	if (ext->context != NULL)
+		_sieve_extension_unload(ext);
+
 	/* Call load handler */
 	if (ext->def == NULL || ext->def->load == NULL)
 		return 0;
diff --git a/src/lib-sieve/sieve-extensions.h b/src/lib-sieve/sieve-extensions.h
index fa46859a1..db6d621b5 100644
--- a/src/lib-sieve/sieve-extensions.h
+++ b/src/lib-sieve/sieve-extensions.h
@@ -24,7 +24,7 @@ struct sieve_extension_def {
 	unsigned int version;
 
 	/* Registration */
-	int (*load)(const struct sieve_extension *ext, void **context);
+	int (*load)(const struct sieve_extension *ext, void **context_r);
 	void (*unload)(const struct sieve_extension *ext);
 
 	/* Compilation */
diff --git a/src/plugins/imapsieve/ext-imapsieve.c b/src/plugins/imapsieve/ext-imapsieve.c
index a19f5ed4c..79dc59fd3 100644
--- a/src/plugins/imapsieve/ext-imapsieve.c
+++ b/src/plugins/imapsieve/ext-imapsieve.c
@@ -29,9 +29,9 @@
  */
 
 static int
-ext_imapsieve_load(const struct sieve_extension *ext, void **context);
+ext_imapsieve_load(const struct sieve_extension *ext, void **context_r);
 static int
-ext_vnd_imapsieve_load(const struct sieve_extension *ext, void **context);
+ext_vnd_imapsieve_load(const struct sieve_extension *ext, void **context_r);
 static void ext_imapsieve_unload(const struct sieve_extension *ext);
 static void ext_vnd_imapsieve_unload(const struct sieve_extension *ext);
 
@@ -72,16 +72,11 @@ const struct sieve_extension_def vnd_imapsieve_extension = {
  */
 
 static int
-ext_imapsieve_load(const struct sieve_extension *ext, void **context)
+ext_imapsieve_load(const struct sieve_extension *ext, void **context_r)
 {
 	const struct sieve_extension *ext_environment;
 	struct ext_imapsieve_context *extctx;
 
-	if (context != NULL) {
-		ext_imapsieve_unload(ext);
-		*context = NULL;
-	}
-
 	if (sieve_ext_environment_require_extension(ext->svinst,
 						    &ext_environment) < 0)
 		return -1;
@@ -89,20 +84,15 @@ ext_imapsieve_load(const struct sieve_extension *ext, void **context)
 	extctx = i_new(struct ext_imapsieve_context, 1);
 	extctx->ext_environment = ext_environment;
 
-	*context = extctx;
+	*context_r = extctx;
 	return 0;
 }
 
 static int
-ext_vnd_imapsieve_load(const struct sieve_extension *ext, void **context)
+ext_vnd_imapsieve_load(const struct sieve_extension *ext, void **context_r)
 {
 	struct ext_vnd_imapsieve_context *extctx;
 
-	if (context != NULL) {
-		ext_imapsieve_unload(ext);
-		*context = NULL;
-	}
-
 	extctx = i_new(struct ext_vnd_imapsieve_context, 1);
 #ifdef __IMAPSIEVE_DUMMY
 	if (sieve_extension_require(ext->svinst, &imapsieve_extension_dummy,
@@ -114,7 +104,7 @@ ext_vnd_imapsieve_load(const struct sieve_extension *ext, void **context)
 		return -1;
 #endif
 
-	*context = extctx;
+	*context_r = extctx;
 	return 0;
 }
 
diff --git a/src/plugins/sieve-extprograms/sieve-extprograms-common.c b/src/plugins/sieve-extprograms/sieve-extprograms-common.c
index e64e25f4d..fae2ecb31 100644
--- a/src/plugins/sieve-extprograms/sieve-extprograms-common.c
+++ b/src/plugins/sieve-extprograms/sieve-extprograms-common.c
@@ -57,7 +57,7 @@
  */
 
 int sieve_extprograms_ext_load(const struct sieve_extension *ext,
-			       void **context)
+			       void **context_r)
 {
 	struct sieve_instance *svinst = ext->svinst;
 	const struct sieve_extension *copy_ext = NULL;
@@ -67,11 +67,6 @@ int sieve_extprograms_ext_load(const struct sieve_extension *ext,
 	const char *bin_dir, *socket_dir, *input_eol;
 	sieve_number_t execute_timeout;
 
-	if (*context != NULL) {
-		sieve_extprograms_ext_unload(ext);
-		*context = NULL;
-	}
-
 	extname = strrchr(extname, '.');
 	i_assert(extname != NULL);
 	extname++;
@@ -119,7 +114,7 @@ int sieve_extprograms_ext_load(const struct sieve_extension *ext,
 		}
 	}
 
-	*context = extctx;
+	*context_r = extctx;
 	return 0;
 }
 
diff --git a/src/plugins/sieve-extprograms/sieve-extprograms-common.h b/src/plugins/sieve-extprograms/sieve-extprograms-common.h
index c7f9719f3..881b7d467 100644
--- a/src/plugins/sieve-extprograms/sieve-extprograms-common.h
+++ b/src/plugins/sieve-extprograms/sieve-extprograms-common.h
@@ -25,7 +25,7 @@ struct sieve_extprograms_ext_context {
 };
 
 int sieve_extprograms_ext_load(const struct sieve_extension *ext,
-			       void **context);
+			       void **context_r);
 void sieve_extprograms_ext_unload(const struct sieve_extension *ext);
 
 /*
-- 
GitLab