From 6eb224c4e8d02113fa20524c1597995197d811fb Mon Sep 17 00:00:00 2001
From: Stephan Bosch <stephan@rename-it.nl>
Date: Sat, 4 Sep 2010 14:51:35 +0200
Subject: [PATCH] Made global system error handler state part of Sieve
 instance.

---
 src/lib-sieve-tool/sieve-tool.c               |  16 +-
 .../plugins/include/ext-include-binary.c      |  16 +-
 .../plugins/include/ext-include-common.c      |   4 +-
 .../plugins/include/ext-include-variables.c   |   3 +-
 .../spamvirustest/ext-spamvirustest-common.c  |  33 +--
 .../plugins/variables/ext-variables-common.c  |  21 +-
 .../plugins/variables/sieve-ext-variables.h   |   4 +-
 src/lib-sieve/sieve-binary-file.c             | 134 +++++++------
 src/lib-sieve/sieve-binary-private.h          |   4 +-
 src/lib-sieve/sieve-common.h                  |   3 +
 src/lib-sieve/sieve-error-private.h           |  12 +-
 src/lib-sieve/sieve-error.c                   | 188 ++++++++++++------
 src/lib-sieve/sieve-error.h                   |  28 +--
 src/lib-sieve/sieve-extensions.c              |  11 +-
 src/lib-sieve/sieve-message.c                 |  22 +-
 src/lib-sieve/sieve-script.c                  |   4 +-
 src/lib-sieve/sieve-settings.c                |  10 +-
 src/lib-sieve/sieve.c                         |  38 ++--
 src/lib-sieve/sieve.h                         |   2 +-
 src/lib-sieve/tst-size.c                      |   2 +-
 src/lib-sievestorage/sieve-storage.c          |   2 +-
 src/managesieve/cmd-putscript.c               |   4 +-
 src/plugins/lda-sieve/lda-sieve-log.c         |   5 +-
 src/plugins/lda-sieve/lda-sieve-log.h         |   3 +-
 src/plugins/lda-sieve/lda-sieve-plugin.c      | 132 ++++++------
 src/sieve-tools/sieve-test.c                  |   9 +-
 src/testsuite/cmd-test-binary.c               |   6 +-
 src/testsuite/testsuite-log.c                 |  29 ++-
 src/testsuite/testsuite-mailstore.c           |   6 +-
 29 files changed, 450 insertions(+), 301 deletions(-)

diff --git a/src/lib-sieve-tool/sieve-tool.c b/src/lib-sieve-tool/sieve-tool.c
index 35827436b..80dca2e6c 100644
--- a/src/lib-sieve-tool/sieve-tool.c
+++ b/src/lib-sieve-tool/sieve-tool.c
@@ -41,7 +41,7 @@ struct sieve_tool {
 
 	char *username;
 	char *homedir;
-	
+
 	char *sieve_extensions;
 	ARRAY_TYPE(const_string) sieve_plugins;
 
@@ -515,8 +515,8 @@ struct sieve_binary *sieve_tool_script_compile
 {
 	struct sieve_error_handler *ehandler;
 	struct sieve_binary *sbin;
-	
-	ehandler = sieve_stderr_ehandler_create(0);
+
+	ehandler = sieve_stderr_ehandler_create(svinst, 0);
 	sieve_error_handler_accept_infolog(ehandler, TRUE);
 
 	if ( (sbin = sieve_compile(svinst, filename, name, ehandler, NULL)) == NULL )
@@ -526,14 +526,14 @@ struct sieve_binary *sieve_tool_script_compile
 
 	return sbin;
 }
-	
+
 struct sieve_binary *sieve_tool_script_open
 (struct sieve_instance *svinst, const char *filename)
 {
 	struct sieve_error_handler *ehandler;
 	struct sieve_binary *sbin;
-	
-	ehandler = sieve_stderr_ehandler_create(0);
+
+	ehandler = sieve_stderr_ehandler_create(svinst, 0);
 	sieve_error_handler_accept_infolog(ehandler, TRUE);
 
 	if ( (sbin = sieve_open(svinst, filename, NULL, ehandler, NULL)) == NULL ) {
@@ -542,7 +542,7 @@ struct sieve_binary *sieve_tool_script_open
 	}
 
 	sieve_error_handler_unref(&ehandler);
-		
+
 	sieve_save(sbin, NULL, FALSE, NULL);
 	return sbin;
 }
@@ -561,7 +561,7 @@ void sieve_tool_dump_binary_to(struct sieve_binary *sbin, const char *filename)
 		i_fatal("Failed to create stream for sieve code dump.");
 	}
 }
-	
+
 /*
  * Commandline option parsing
  */
diff --git a/src/lib-sieve/plugins/include/ext-include-binary.c b/src/lib-sieve/plugins/include/ext-include-binary.c
index 45e9e7a78..02d90f29b 100644
--- a/src/lib-sieve/plugins/include/ext-include-binary.c
+++ b/src/lib-sieve/plugins/include/ext-include-binary.c
@@ -233,6 +233,7 @@ static bool ext_include_binary_save
 static bool ext_include_binary_open
 (const struct sieve_extension *ext, struct sieve_binary *sbin, void *context)
 {
+	struct sieve_instance *svinst = ext->svinst;
 	struct ext_include_binary_context *binctx = 
 		(struct ext_include_binary_context *) context;
 	struct sieve_binary_block *sblock;
@@ -245,7 +246,8 @@ static bool ext_include_binary_open
 	offset = 0;	
 		
 	if ( !sieve_binary_read_unsigned(sblock, &offset, &depcount) ) {
-		sieve_sys_error("include: failed to read include count "
+		sieve_sys_error(svinst, 
+			"include: failed to read include count "
 			"for dependency block %d of binary %s", block_id, 
 			sieve_binary_path(sbin));
 		return FALSE;
@@ -253,7 +255,8 @@ static bool ext_include_binary_open
 	
 	/* Check include limit */	
 	if ( depcount > EXT_INCLUDE_MAX_INCLUDES ) {
-		sieve_sys_error("include: binary %s includes too many scripts (%u > %u)",
+		sieve_sys_error(svinst,
+			"include: binary %s includes too many scripts (%u > %u)",
 			sieve_binary_path(sbin), depcount, EXT_INCLUDE_MAX_INCLUDES); 
 		return FALSE;
 	}
@@ -272,14 +275,16 @@ static bool ext_include_binary_open
 			!sieve_binary_read_byte(sblock, &offset, &location) ||
 			!sieve_binary_read_string(sblock, &offset, &script_name) ) {
 			/* Binary is corrupt, recompile */
-			sieve_sys_error("include: failed to read included script "
+			sieve_sys_error(svinst,
+				"include: failed to read included script "
 				"from dependency block %d of binary %s", block_id, 
 				sieve_binary_path(sbin)); 
 			return FALSE;
 		}
 
 		if ( (inc_block=sieve_binary_block_get(sbin, inc_block_id)) == NULL ) {
-			sieve_sys_error("include: failed to find block %d for included script "
+			sieve_sys_error(svinst,
+				"include: failed to find block %d for included script "
 				"from dependency block %d of binary %s", inc_block_id, block_id, 
 				sieve_binary_path(sbin)); 
 
@@ -288,7 +293,8 @@ static bool ext_include_binary_open
 		
 		if ( location >= EXT_INCLUDE_LOCATION_INVALID ) {
 			/* Binary is corrupt, recompile */
-			sieve_sys_error("include: dependency block %d of binary %s "
+			sieve_sys_error(svinst,
+				"include: dependency block %d of binary %s "
 				"reports invalid script location (id %d)", 
 				block_id, sieve_binary_path(sbin), location); 
 			return FALSE;
diff --git a/src/lib-sieve/plugins/include/ext-include-common.c b/src/lib-sieve/plugins/include/ext-include-common.c
index 8e94fde8c..5d4fb6579 100644
--- a/src/lib-sieve/plugins/include/ext-include-common.c
+++ b/src/lib-sieve/plugins/include/ext-include-common.c
@@ -84,7 +84,7 @@ const char *ext_include_get_script_directory
 
 		if ( sieve_dir == NULL ) {
 			if ( home == NULL )	{		
-				sieve_sys_error(
+				sieve_sys_error(svinst,
 					"include: sieve_dir and home not set for :personal script include "	
 					"(wanted script '%s')", str_sanitize(script_name, 80));
 				return NULL;
@@ -101,7 +101,7 @@ const char *ext_include_get_script_directory
 		sieve_dir = sieve_setting_get(svinst, "sieve_global_dir");
 
 		if (sieve_dir == NULL) {
-			sieve_sys_error(
+			sieve_sys_error(svinst,
 				"include: sieve_global_dir not set for :global script include "	
 				"(wanted script '%s')", str_sanitize(script_name, 80));
 			return NULL;
diff --git a/src/lib-sieve/plugins/include/ext-include-variables.c b/src/lib-sieve/plugins/include/ext-include-variables.c
index 093eb19fc..85eb93818 100644
--- a/src/lib-sieve/plugins/include/ext-include-variables.c
+++ b/src/lib-sieve/plugins/include/ext-include-variables.c
@@ -104,7 +104,8 @@ bool ext_include_variables_load
 	/* Sanity assert */
 	i_assert( *global_vars_r == NULL );
 
-	*global_vars_r = sieve_variable_scope_binary_read(this_ext, sblock, offset);
+	*global_vars_r = sieve_variable_scope_binary_read
+		(this_ext->svinst, this_ext, sblock, offset);
 
 	return ( *global_vars_r != NULL );
 }
diff --git a/src/lib-sieve/plugins/spamvirustest/ext-spamvirustest-common.c b/src/lib-sieve/plugins/spamvirustest/ext-spamvirustest-common.c
index 139f161d7..5ac75d316 100644
--- a/src/lib-sieve/plugins/spamvirustest/ext-spamvirustest-common.c
+++ b/src/lib-sieve/plugins/spamvirustest/ext-spamvirustest-common.c
@@ -248,8 +248,8 @@ bool ext_spamvirustest_load
 (const struct sieve_extension *ext, void **context)
 {
 	struct ext_spamvirustest_data *ext_data =
-        (struct ext_spamvirustest_data *) *context;
-    struct sieve_instance *svinst = ext->svinst;
+		(struct ext_spamvirustest_data *) *context;
+	struct sieve_instance *svinst = ext->svinst;
 	const char *ext_name, *status_header, *max_header, *status_type, 
 		*max_value;
 	enum ext_spamvirustest_status_type type;
@@ -300,7 +300,8 @@ bool ext_spamvirustest_load
 	} else if ( strcmp(status_type, "text") == 0 ) {
 		type = EXT_SPAMVIRUSTEST_STATUS_TYPE_TEXT;
 	} else {
-		sieve_sys_error("%s: invalid status type '%s'", ext_name, status_type);
+		sieve_sys_error(svinst, 
+			"%s: invalid status type '%s'", ext_name, status_type);
 		return FALSE;
 	}
 
@@ -309,24 +310,28 @@ bool ext_spamvirustest_load
 	if ( type != EXT_SPAMVIRUSTEST_STATUS_TYPE_TEXT ) {
 
 		if ( max_header != NULL && max_value != NULL ) {
-			sieve_sys_error("%s: sieve_%s_max_header and sieve_%s_max_value "
+			sieve_sys_error(svinst,
+				"%s: sieve_%s_max_header and sieve_%s_max_value "
 				"cannot both be configured", ext_name, ext_name, ext_name);
 			return TRUE;
 		}
 
 		if ( max_header == NULL && max_value == NULL ) {
-			sieve_sys_error("%s: none of sieve_%s_max_header or sieve_%s_max_value "
+			sieve_sys_error(svinst,
+				"%s: none of sieve_%s_max_header or sieve_%s_max_value "
 				"is configured", ext_name, ext_name, ext_name);
 			return TRUE;
 		}
 	} else {
 		if ( max_header != NULL ) {
-			sieve_sys_warning("%s: setting sieve_%s_max_header has no meaning "
+			sieve_sys_warning(svinst,
+				"%s: setting sieve_%s_max_header has no meaning "
 				"for sieve_%s_status_type=text", ext_name, ext_name, ext_name);
 		}
 
 		if ( max_value != NULL ) {
-			sieve_sys_warning("%s: setting sieve_%s_max_value has no meaning "
+			sieve_sys_warning(svinst,
+				"%s: setting sieve_%s_max_value has no meaning "
 				"for sieve_%s_status_type=text", ext_name, ext_name, ext_name);
 		}	
 	}
@@ -339,7 +344,8 @@ bool ext_spamvirustest_load
 
 	if ( !ext_spamvirustest_header_spec_parse
 		(&ext_data->status_header, ext_data->pool, status_header, &error) ) {
-		sieve_sys_error("%s: invalid status header specification "
+		sieve_sys_error(svinst,
+			"%s: invalid status header specification "
 			"'%s': %s", ext_name, status_header, error);
 		result = FALSE;
 	}
@@ -350,7 +356,8 @@ bool ext_spamvirustest_load
 
 			if ( max_header != NULL && !ext_spamvirustest_header_spec_parse
 				(&ext_data->max_header, ext_data->pool, max_header, &error) ) {
-				sieve_sys_error("%s: invalid max header specification "
+				sieve_sys_error(svinst,
+					"%s: invalid max header specification "
 					"'%s': %s", ext_name, max_header, error);
 				result = FALSE;
 			}
@@ -360,7 +367,8 @@ bool ext_spamvirustest_load
 			if ( result && max_value != NULL ) {
 				if ( !ext_spamvirustest_parse_decimal_value
 					(max_value, &ext_data->max_value, &error) ) {
-					sieve_sys_error("%s: invalid max value specification "
+					sieve_sys_error(svinst,
+						"%s: invalid max value specification "
 						"'%s': %s", ext_name, max_value, error);
 					result = FALSE;
 				}
@@ -387,8 +395,9 @@ bool ext_spamvirustest_load
 	if ( result ) {
 		*context = (void *) ext_data;
 	} else {
-		sieve_sys_warning("%s: extension not configured, "
-			"tests will always match against \"0\"", ext_name);
+		sieve_sys_warning(svinst, 
+			"%s: extension not configured, tests will always match against \"0\"",
+			ext_name);
 		ext_spamvirustest_unload(ext);
 		*context = NULL;
 	}
diff --git a/src/lib-sieve/plugins/variables/ext-variables-common.c b/src/lib-sieve/plugins/variables/ext-variables-common.c
index d184162a3..1bfab81ce 100644
--- a/src/lib-sieve/plugins/variables/ext-variables-common.c
+++ b/src/lib-sieve/plugins/variables/ext-variables-common.c
@@ -301,8 +301,8 @@ void sieve_variable_scope_binary_unref
 }
 
 struct sieve_variable_scope_binary *sieve_variable_scope_binary_read
-(const struct sieve_extension *ext, struct sieve_binary_block *sblock,
-	sieve_size_t *address)
+(struct sieve_instance *svinst, const struct sieve_extension *ext,
+	struct sieve_binary_block *sblock, sieve_size_t *address)
 {
 	struct sieve_variable_scope *scope;
 	struct sieve_variable_scope_binary *scpbin;
@@ -314,13 +314,15 @@ struct sieve_variable_scope_binary *sieve_variable_scope_binary_read
 
 	/* Read scope size */	
 	if ( !sieve_binary_read_unsigned(sblock, address, &scope_size) ) {
-		sieve_sys_error("%s: variable scope: failed to read size", ext_name);
+		sieve_sys_error
+			(svinst, "%s: variable scope: failed to read size", ext_name);
 		return NULL;
 	}
 
 	/* Check size limit */
 	if ( scope_size > EXT_VARIABLES_MAX_SCOPE_SIZE ) {
-		sieve_sys_error("%s: variable scope: size exceeds the limit (%u > %u)", 
+		sieve_sys_error(svinst,
+			"%s: variable scope: size exceeds the limit (%u > %u)", 
 			ext_name, scope_size, EXT_VARIABLES_MAX_SCOPE_SIZE );
 		return NULL;
 	}
@@ -328,7 +330,8 @@ struct sieve_variable_scope_binary *sieve_variable_scope_binary_read
 	/* Read offset */
 	pc = *address;	
 	if ( !sieve_binary_read_offset(sblock, address, &end_offset) ) {
-		sieve_sys_error("%s: variable scope: failed to read end offset", ext_name);
+		sieve_sys_error(svinst,
+			"%s: variable scope: failed to read end offset", ext_name);
 		return NULL;
 	}
 	
@@ -349,6 +352,7 @@ struct sieve_variable_scope *sieve_variable_scope_binary_get
 (struct sieve_variable_scope_binary *scpbin)
 {
 	const struct sieve_extension *ext = scpbin->scope->ext;
+	struct sieve_instance *svinst = ext->svinst;
 	const char *ext_name = 
 		( ext == NULL ? "variables" : sieve_extension_name(ext) );
 	unsigned int i;
@@ -362,8 +366,8 @@ struct sieve_variable_scope *sieve_variable_scope_binary_get
 			string_t *identifier;
 
 			if (!sieve_binary_read_string(scpbin->sblock, address, &identifier) ) {
-				sieve_sys_error
-					("%s: variable scope: failed to read variable name", ext_name);
+				sieve_sys_error(svinst,
+					"%s: variable scope: failed to read variable name", ext_name);
 				return NULL;
 			}
 		
@@ -714,7 +718,8 @@ bool ext_variables_interpreter_load
 	struct ext_variables_interpreter_context *ctx;
 	struct sieve_variable_scope_binary *scpbin;
 
-	scpbin = sieve_variable_scope_binary_read(NULL, renv->sblock, address);
+	scpbin = sieve_variable_scope_binary_read
+		(renv->svinst, NULL, renv->sblock, address);
 	if ( scpbin == NULL )
 		return FALSE;
 	
diff --git a/src/lib-sieve/plugins/variables/sieve-ext-variables.h b/src/lib-sieve/plugins/variables/sieve-ext-variables.h
index 6540ef6d5..40ba9e5f0 100644
--- a/src/lib-sieve/plugins/variables/sieve-ext-variables.h
+++ b/src/lib-sieve/plugins/variables/sieve-ext-variables.h
@@ -92,8 +92,8 @@ struct sieve_variable_scope *sieve_variable_scope_binary_dump
 	(const struct sieve_extension *ext, 
 		const struct sieve_dumptime_env *denv, sieve_size_t *address);
 struct sieve_variable_scope_binary *sieve_variable_scope_binary_read
-	(const struct sieve_extension *ext, struct sieve_binary_block *sblock,
-		sieve_size_t *address);
+	(struct sieve_instance *svinst, const struct sieve_extension *ext,
+		struct sieve_binary_block *sblock, sieve_size_t *address);
 
 struct sieve_variable_scope *sieve_variable_scope_binary_get
 	(struct sieve_variable_scope_binary *scpbin);
diff --git a/src/lib-sieve/sieve-binary-file.c b/src/lib-sieve/sieve-binary-file.c
index ea6306dd4..01013aa3c 100644
--- a/src/lib-sieve/sieve-binary-file.c
+++ b/src/lib-sieve/sieve-binary-file.c
@@ -64,10 +64,12 @@ struct sieve_binary_block_header {
  * Saving the binary to a file. 
  */
 
-static inline bool _save_skip(struct ostream *stream, size_t size)
+static inline bool _save_skip
+(struct sieve_binary *sbin, struct ostream *stream, size_t size)
 {	
 	if ( (o_stream_seek(stream, stream->offset + size)) <= 0 ) {
-		sieve_sys_error("binary save: failed to skip output stream "
+		sieve_sys_error(sbin->svinst,
+			"binary save: failed to skip output stream "
 			"to position %"PRIuUOFF_T": %s", stream->offset + size,
 			strerror(stream->stream_errno));
 		return FALSE;
@@ -77,12 +79,13 @@ static inline bool _save_skip(struct ostream *stream, size_t size)
 }
 
 static inline bool _save_skip_aligned
-(struct ostream *stream, size_t size, uoff_t *offset)
+(struct sieve_binary *sbin, struct ostream *stream, size_t size, 
+	uoff_t *offset)
 {
 	uoff_t aligned_offset = SIEVE_BINARY_ALIGN(stream->offset);
 	
 	if ( (o_stream_seek(stream, aligned_offset + size)) <= 0 ) {
-		sieve_sys_error("binary save: failed to skip output stream "
+		sieve_sys_error(sbin->svinst, "binary save: failed to skip output stream "
 			"to position %"PRIuUOFF_T": %s", aligned_offset + size,
 			strerror(stream->stream_errno));
 		return FALSE;
@@ -95,7 +98,8 @@ static inline bool _save_skip_aligned
 }
 
 /* FIXME: Is this even necessary for a file? */
-static bool _save_full(struct ostream *stream, const void *data, size_t size)
+static bool _save_full
+(struct sieve_binary *sbin, struct ostream *stream, const void *data, size_t size)
 {
 	size_t bytes_left = size;
 	const void *pdata = data;
@@ -104,7 +108,8 @@ static bool _save_full(struct ostream *stream, const void *data, size_t size)
 		ssize_t ret;
 		
 		if ( (ret=o_stream_send(stream, pdata, bytes_left)) <= 0 ) {
-			sieve_sys_error("binary save: failed to write %"PRIuSIZE_T" bytes "
+			sieve_sys_error(sbin->svinst,
+				"binary save: failed to write %"PRIuSIZE_T" bytes "
 				"to output stream: %s", bytes_left, strerror(stream->stream_errno));
 			return FALSE;
 		}
@@ -117,7 +122,8 @@ static bool _save_full(struct ostream *stream, const void *data, size_t size)
 }
 
 static bool _save_aligned
-(struct ostream *stream, const void *data, size_t size, uoff_t *offset)
+(struct sieve_binary *sbin, struct ostream *stream, const void *data,
+	size_t size, uoff_t *offset)
 {	
 	uoff_t aligned_offset = SIEVE_BINARY_ALIGN(stream->offset);
 
@@ -125,11 +131,11 @@ static bool _save_aligned
 	
 	/* Align the data by adding zeroes to the output stream */
 	if ( stream->offset < aligned_offset ) {
-		if ( !_save_skip(stream, aligned_offset - stream->offset) ) 
+		if ( !_save_skip(sbin, stream, aligned_offset - stream->offset) ) 
 			return FALSE;
 	}
 	
-	if ( !_save_full(stream, data, size) )
+	if ( !_save_full(sbin, stream, data, size) )
 		return FALSE;
 	
 	o_stream_uncork(stream); 
@@ -157,11 +163,11 @@ static bool _save_block
 	block_header.id = id;
 	block_header.size = size;
 	
-	if ( !_save_aligned(stream, &block_header,
+	if ( !_save_aligned(sbin, stream, &block_header,
 		sizeof(block_header), &block->offset) )
 		return FALSE;
 	
-	return _save_aligned(stream, data, size, NULL);
+	return _save_aligned(sbin, stream, data, size, NULL);
 }
 
 static bool _save_block_index_record
@@ -179,8 +185,9 @@ static bool _save_block_index_record
 	header.ext_id = block->ext_index;
 	header.offset = block->offset;
 	
-	if ( !_save_full(stream, &header, sizeof(header)) ) {
-		sieve_sys_error("binary save: failed to save block index header %d", id);
+	if ( !_save_full(sbin, stream, &header, sizeof(header)) ) {
+		sieve_sys_error(sbin->svinst,
+			"binary save: failed to save block index header %d", id);
 		return FALSE;
 	}
 	
@@ -215,14 +222,14 @@ static bool _sieve_binary_save
 	header.version_minor = SIEVE_BINARY_VERSION_MINOR;
 	header.blocks = blk_count;
 
-	if ( !_save_aligned(stream, &header, sizeof(header), NULL) ) {
-		sieve_sys_error("binary save: failed to save header");
+	if ( !_save_aligned(sbin, stream, &header, sizeof(header), NULL) ) {
+		sieve_sys_error(sbin->svinst, "binary save: failed to save header");
 		return FALSE;
 	} 
 	
 	/* Skip block index for now */
 	
-	if ( !_save_skip_aligned(stream, 
+	if ( !_save_skip_aligned(sbin, stream, 
 		sizeof(struct sieve_binary_block_index) * blk_count, &block_index) )
 		return FALSE;
 	
@@ -277,7 +284,8 @@ int sieve_binary_save
 	/* Use default path if none is specified */
 	if ( path == NULL ) {
 		if ( sbin->script == NULL ) {
-			sieve_sys_error("binary save: cannot determine default path "
+			sieve_sys_error(sbin->svinst, 
+				"binary save: cannot determine default path "
 				"with missing script object");
 			if ( error_r != NULL )
 				*error_r = SIEVE_ERROR_NOT_POSSIBLE;
@@ -289,7 +297,7 @@ int sieve_binary_save
 	/* Check whether saving is necessary */
 	if ( !update && sbin->path != NULL && strcmp(sbin->path, path) == 0 ) {
 		if ( sbin->svinst->debug ) {
-			sieve_sys_debug("binary save: not saving binary %s, "
+			sieve_sys_debug(sbin->svinst, "binary save: not saving binary %s, "
 				"because it is already stored", path);
 		}		
 		return 0;
@@ -302,13 +310,15 @@ int sieve_binary_save
 	fd = safe_mkstemp_hostpid(temp_path, save_mode, (uid_t)-1, (gid_t)-1);
 	if ( fd < 0 ) {
 		if ( errno == EACCES ) {
-			sieve_sys_error("binary save: failed to create temporary file: %s",
+			sieve_sys_error(sbin->svinst,
+				"binary save: failed to create temporary file: %s",
 				eacces_error_get_creating("open", str_c(temp_path)));
 			if ( error_r != NULL )
 				*error_r = SIEVE_ERROR_NO_PERM;
 		} else {
-			sieve_sys_error("binary save: failed to create temporary file: "
-				"open(%s) failed: %m", str_c(temp_path));
+			sieve_sys_error(sbin->svinst,
+				"binary save: failed to create temporary file: open(%s) failed: %m",
+				str_c(temp_path));
 			if ( error_r != NULL )
 				*error_r = SIEVE_ERROR_TEMP_FAIL;
 		}
@@ -327,19 +337,20 @@ int sieve_binary_save
 
 	/* Close saved binary */ 
 	if ( close(fd) < 0 ) {
-		sieve_sys_error("binary save: failed to close temporary file: "
+		sieve_sys_error(sbin->svinst,
+			"binary save: failed to close temporary file: "
 			"close(fd=%s) failed: %m", str_c(temp_path));
 	}
 
 	/* Replace any original binary atomically */
 	if ( result && (rename(str_c(temp_path), path) < 0) ) {
 		if ( errno == EACCES ) {
-			sieve_sys_error("binary save: failed to save binary: %s", 
+			sieve_sys_error(sbin->svinst, "binary save: failed to save binary: %s", 
 				eacces_error_get_creating("rename", path));
 			if ( error_r != NULL )
 				*error_r = SIEVE_ERROR_NO_PERM;
 		} else { 		
-			sieve_sys_error("binary save: failed to save binary: "
+			sieve_sys_error(sbin->svinst, "binary save: failed to save binary: "
 				"rename(%s, %s) failed: %m", str_c(temp_path), path);
 			if ( error_r != NULL )
 				*error_r = SIEVE_ERROR_TEMP_FAIL;
@@ -350,8 +361,9 @@ int sieve_binary_save
 	if ( result < 0 ) {
 		/* Get rid of temp output (if any) */
 		if ( unlink(str_c(temp_path)) < 0 && errno != ENOENT ) {
-			sieve_sys_error("binary save: failed to clean up after error: "
-				"unlink(%s) failed: %m", str_c(temp_path));
+			sieve_sys_error(sbin->svinst, 
+				"binary save: failed to clean up after error: unlink(%s) failed: %m",
+				str_c(temp_path));
 		}
 	} else {
 		if ( sbin->path == NULL ) {
@@ -367,7 +379,8 @@ int sieve_binary_save
  */
 
 bool sieve_binary_file_open
-(struct sieve_binary_file *file, const char *path, enum sieve_error *error_r)
+(struct sieve_binary_file *file, 
+	struct sieve_instance *svinst, const char *path, enum sieve_error *error_r)
 {
 	int fd;
 	bool result = TRUE;
@@ -383,13 +396,13 @@ bool sieve_binary_file_open
 				*error_r = SIEVE_ERROR_NOT_FOUND;
 			break;
 		case EACCES:
-			sieve_sys_error("binary open: failed to open: %s", 
+			sieve_sys_error(svinst, "binary open: failed to open: %s", 
 				eacces_error_get("open", path));
 			if ( error_r != NULL )
 				*error_r = SIEVE_ERROR_NO_PERM;
 			break;
 		default:
-			sieve_sys_error("binary open: failed to open: "
+			sieve_sys_error(svinst, "binary open: failed to open: "
 				"open(%s) failed: %m", path);
 			if ( error_r != NULL )
 				*error_r = SIEVE_ERROR_TEMP_FAIL;
@@ -400,24 +413,27 @@ bool sieve_binary_file_open
 
 	if ( fstat(fd, &st) < 0 ) {
 		if ( errno != ENOENT ) {
-			sieve_sys_error("binary open: fstat(fd=%s) failed: %m", path);
+			sieve_sys_error(svinst,
+				"binary open: fstat(fd=%s) failed: %m", path);
 		}
 		result = FALSE;
 	}
 
 	if ( result && !S_ISREG(st.st_mode) ) {
-		sieve_sys_error("binary open: %s is not a regular file", path);
+		sieve_sys_error(svinst, 
+			"binary open: %s is not a regular file", path);
 		result = FALSE;		
 	}
 	
 	if ( !result )	{
 		if ( close(fd) < 0 ) {
-			sieve_sys_error("binary open: close(fd=%s) failed after error: %m",
-				path);
+			sieve_sys_error(svinst,
+				"binary open: close(fd=%s) failed after error: %m", path);
 		}
 		return FALSE;
 	}
 
+	file->svinst = svinst;
 	file->fd = fd;
 	file->st = st;
 
@@ -428,8 +444,9 @@ void sieve_binary_file_close(struct sieve_binary_file **file)
 {
 	if ( (*file)->fd != -1 ) {
 		if ( close((*file)->fd) < 0 ) {
-			sieve_sys_error("binary close: failed to close: "
-				"close(fd=%s) failed: %m", (*file)->path);
+			sieve_sys_error((*file)->svinst, 
+				"binary close: failed to close: close(fd=%s) failed: %m",
+				(*file)->path);
 		}
 	}
 
@@ -557,6 +574,7 @@ static struct sieve_binary_file *_file_memory_open(const char *path)
 static bool _file_lazy_read
 (struct sieve_binary_file *file, off_t *offset, void *buffer, size_t size)
 {
+	struct sieve_instance *svinst = file->svinst;
 	int ret;
 	void *indata = buffer;
 	size_t insize = size;
@@ -566,7 +584,7 @@ static bool _file_lazy_read
 	/* Seek to the correct position */ 
 	if ( *offset != file->offset && 
 		lseek(file->fd, *offset, SEEK_SET) == (off_t) -1 ) {
-		sieve_sys_error("binary read:"
+		sieve_sys_error(svinst, "binary read:"
 			"failed to seek(fd, %lld, SEEK_SET) in binary %s: %m", 
 			(long long) *offset, file->path);
 		return FALSE;
@@ -576,11 +594,11 @@ static bool _file_lazy_read
 	while (insize > 0) {
 		if ( (ret=read(file->fd, indata, insize)) <= 0 ) {
 			if ( ret == 0 ) 
-				sieve_sys_error(
+				sieve_sys_error(svinst, 
 					"binary read: binary %s is truncated (more data expected)", 
 					file->path);
 			else
-				sieve_sys_error(
+				sieve_sys_error(svinst,
 					"binary read: failed to read from binary %s: %m", file->path);
 			break;
 		}
@@ -626,7 +644,7 @@ static buffer_t *_file_lazy_load_buffer
 }
 
 static struct sieve_binary_file *_file_lazy_open
-(const char *path, enum sieve_error *error_r)
+(struct sieve_instance *svinst, const char *path, enum sieve_error *error_r)
 {
 	pool_t pool;
 	struct sieve_binary_file *file;
@@ -638,7 +656,7 @@ static struct sieve_binary_file *_file_lazy_open
 	file->load_data = _file_lazy_load_data;
 	file->load_buffer = _file_lazy_load_buffer;
 	
-	if ( !sieve_binary_file_open(file, path, error_r) ) {
+	if ( !sieve_binary_file_open(file, svinst, path, error_r) ) {
 		pool_unref(&pool);
 		return NULL;
 	}
@@ -663,14 +681,14 @@ bool sieve_binary_load_block
 		LOAD_HEADER(sbin, &offset, const struct sieve_binary_block_header);
 		
 	if ( header == NULL ) {
-		sieve_sys_error(
+		sieve_sys_error(sbin->svinst,
 			"binary load: binary %s is corrupt: "
 			"failed to read header of block %d", sbin->path, id);
 		return FALSE;
 	}
 	
 	if ( header->id != id ) {
-		sieve_sys_error(
+		sieve_sys_error(sbin->svinst,
 			"binary load: binary %s is corrupt: "
 			"header of block %d has non-matching id %d",
 			sbin->path, id, header->id);
@@ -679,7 +697,7 @@ bool sieve_binary_load_block
 	
 	sblock->data = sbin->file->load_buffer(sbin->file, &offset, header->size);
 	if ( sblock->data == NULL ) {
-		sieve_sys_error(
+		sieve_sys_error(sbin->svinst,
 			"binary load: failed to read block %d of binary %s (size=%d)",
 			id, sbin->path, header->size);
 		return FALSE;
@@ -696,14 +714,14 @@ static bool _read_block_index_record
 	struct sieve_binary_block *block;
 	
 	if ( record == NULL ) {
-		sieve_sys_error(
+		sieve_sys_error(sbin->svinst,
 			"binary open: binary %s is corrupt: "
 			"failed to load block index record %d", sbin->path, id);
 		return FALSE;
 	}
 	
 	if ( record->id != id ) {
-		sieve_sys_error(
+		sieve_sys_error(sbin->svinst,
 			"binary open: binary %s is corrupt: "
 			"block index record %d has unexpected id %d", sbin->path, id, record->id);
 		return FALSE;
@@ -735,7 +753,7 @@ static bool _read_extensions(struct sieve_binary_block *sblock)
 				ext = sieve_extension_get_by_name(sbin->svinst, str_c(extension));	
 			
 				if ( ext == NULL ) { 
-					sieve_sys_error(
+					sieve_sys_error(sbin->svinst,
 						"binary open: binary %s requires unknown extension '%s'", 
 						sbin->path, str_sanitize(str_c(extension), 128));
 					result = FALSE;					
@@ -768,18 +786,20 @@ static bool _sieve_binary_open(struct sieve_binary *sbin)
 		header = LOAD_HEADER(sbin, &offset, const struct sieve_binary_header);
 		/* Check header presence */
 		if ( header == NULL ) {
-			sieve_sys_error("binary_open: file %s is not large enough "
-				"to contain the header.", sbin->path);
+			sieve_sys_error(sbin->svinst,
+				"binary_open: file %s is not large enough to contain the header.",
+				sbin->path);
 			result = FALSE;
 
 		/* Check header validity */
 		} else if ( header->magic != SIEVE_BINARY_MAGIC ) {
 			if ( header->magic != SIEVE_BINARY_MAGIC_OTHER_ENDIAN ) 
-				sieve_sys_error("binary_open: binary %s has corrupted header "
+				sieve_sys_error(sbin->svinst, 
+					"binary_open: binary %s has corrupted header "
 					"(0x%08x) or it is not a Sieve binary", sbin->path, header->magic);
 			else if ( sbin->svinst->debug )
-				sieve_sys_debug("binary open: binary %s stored "
-					"with in different endian format "
+				sieve_sys_debug(sbin->svinst,
+					"binary open: binary %s stored with in different endian format "
 					"(automatically fixed when re-compiled)",
 					sbin->path);
 			result = FALSE;
@@ -792,8 +812,8 @@ static bool _sieve_binary_open(struct sieve_binary *sbin)
 			/* Binary is of different version. Caller will have to recompile */
 			
 			if ( sbin->svinst->debug ) {
-				sieve_sys_debug("binary open: binary %s stored "
-					"with different binary version %d.%d "
+				sieve_sys_debug(sbin->svinst,
+					"binary open: binary %s stored with different binary version %d.%d "
 					"(!= %d.%d; automatically fixed when re-compiled)", sbin->path,
 					(int) header->version_major, header->version_minor,
 					SIEVE_BINARY_VERSION_MAJOR, SIEVE_BINARY_VERSION_MINOR);
@@ -802,7 +822,7 @@ static bool _sieve_binary_open(struct sieve_binary *sbin)
 
 		/* Check block content */
 		} else if ( result && header->blocks == 0 ) {
-			sieve_sys_error(
+			sieve_sys_error(sbin->svinst,
 				"binary open: binary %s is corrupt: it contains no blocks",
 				sbin->path);
 			result = FALSE; 
@@ -835,8 +855,8 @@ static bool _sieve_binary_open(struct sieve_binary *sbin)
 			result = FALSE;
 		} else {
 			if ( !_read_extensions(ext_block) ) {
-				sieve_sys_error("binary open: binary %s is corrupt: "
-					"failed to load extension block", 
+				sieve_sys_error(sbin->svinst,
+					"binary open: binary %s is corrupt: failed to load extension block", 
 					sbin->path);
 				result = FALSE;
 			}
@@ -858,7 +878,7 @@ struct sieve_binary *sieve_binary_open
 	i_assert( script == NULL || sieve_script_svinst(script) == svinst );
 	
 	//file = _file_memory_open(path);	
-	if ( (file=_file_lazy_open(path, error_r)) == NULL ) 
+	if ( (file=_file_lazy_open(svinst, path, error_r)) == NULL ) 
 		return NULL;
 		
 	/* Create binary object */
diff --git a/src/lib-sieve/sieve-binary-private.h b/src/lib-sieve/sieve-binary-private.h
index e241247df..4c38265be 100644
--- a/src/lib-sieve/sieve-binary-private.h
+++ b/src/lib-sieve/sieve-binary-private.h
@@ -17,6 +17,7 @@
 struct sieve_binary_file {
 	pool_t pool;
 	const char *path;
+	struct sieve_instance *svinst;
 	
 	struct stat st;
 	int fd;
@@ -29,7 +30,8 @@ struct sieve_binary_file {
 };
 
 bool sieve_binary_file_open
-	(struct sieve_binary_file *file, const char *path, enum sieve_error *error_r);
+	(struct sieve_binary_file *file, struct sieve_instance *svinst,
+		const char *path, enum sieve_error *error_r);
 void sieve_binary_file_close(struct sieve_binary_file **file);
 
 /* 
diff --git a/src/lib-sieve/sieve-common.h b/src/lib-sieve/sieve-common.h
index 5c03e0871..086c082bb 100644
--- a/src/lib-sieve/sieve-common.h
+++ b/src/lib-sieve/sieve-common.h
@@ -165,6 +165,9 @@ struct sieve_instance {
 	/* Extension registry */
 	struct sieve_extension_registry *ext_reg;
 
+	/* System error handler */
+	struct sieve_error_handler *system_ehandler;
+
 	/* Plugin modules */
 	struct sieve_plugin *plugins;
 
diff --git a/src/lib-sieve/sieve-error-private.h b/src/lib-sieve/sieve-error-private.h
index 62368f1d6..d4f844b12 100644
--- a/src/lib-sieve/sieve-error-private.h
+++ b/src/lib-sieve/sieve-error-private.h
@@ -6,6 +6,13 @@
 
 #include "sieve-error.h"
 
+/*
+ * Initialization
+ */
+
+void sieve_errors_init(struct sieve_instance *svinst);
+void sieve_errors_deinit(struct sieve_instance *svinst);
+
 /*
  * Error handler object
  */
@@ -14,6 +21,8 @@ struct sieve_error_handler {
 	pool_t pool;
 	int refcount;
 
+	struct sieve_instance *svinst;
+
 	struct sieve_error_handler *parent;
 
 	unsigned int max_errors;
@@ -40,7 +49,8 @@ struct sieve_error_handler {
 };
 
 void sieve_error_handler_init
-	(struct sieve_error_handler *ehandler, pool_t pool, unsigned int max_errors);
+	(struct sieve_error_handler *ehandler, struct sieve_instance *svinst, 
+		pool_t pool, unsigned int max_errors);
 
 void sieve_error_handler_init_from_parent
 	(struct sieve_error_handler *ehandler, pool_t pool, 
diff --git a/src/lib-sieve/sieve-error.c b/src/lib-sieve/sieve-error.c
index e3a526143..f13f1c5c0 100644
--- a/src/lib-sieve/sieve-error.c
+++ b/src/lib-sieve/sieve-error.c
@@ -47,20 +47,95 @@ const char *sieve_error_script_location
 	return t_strdup_printf("%s: line %d", sname, source_line);
 }
 
+/*
+ * Initialization
+ */
+
+void sieve_errors_init(struct sieve_instance *svinst)
+{
+	svinst->system_ehandler = sieve_master_ehandler_create(svinst, 0);
+}
+ 
+void sieve_errors_deinit(struct sieve_instance *svinst)
+{
+	sieve_error_handler_unref(&svinst->system_ehandler);
+}
+
+/*
+ * System errors
+ */
+
+void sieve_sys_error(struct sieve_instance *svinst, const char *fmt, ...)
+{
+	va_list args;
+	va_start(args, fmt);
+	
+	T_BEGIN { 
+		sieve_verror(svinst->system_ehandler, NULL, fmt, args);
+	} T_END;
+	
+	va_end(args);
+}
+
+void sieve_sys_warning(struct sieve_instance *svinst, const char *fmt, ...)
+{
+	va_list args;
+	va_start(args, fmt);
+	
+	T_BEGIN {
+		sieve_vwarning(svinst->system_ehandler, NULL, fmt, args);
+	} T_END;
+	
+	va_end(args);
+}
+
+void sieve_sys_info(struct sieve_instance *svinst, const char *fmt, ...)
+{
+	va_list args;
+	va_start(args, fmt);
+	
+	T_BEGIN {
+		sieve_vinfo(svinst->system_ehandler, NULL, fmt, args);
+	} T_END;
+	
+	va_end(args);
+}
+
+void sieve_sys_debug(struct sieve_instance *svinst, const char *fmt, ...)
+{
+	va_list args;
+	va_start(args, fmt);
+	
+	T_BEGIN {
+		sieve_vdebug(svinst->system_ehandler, NULL, fmt, args);
+	} T_END;
+	
+	va_end(args);
+}
+
+void sieve_system_ehandler_set
+(struct sieve_error_handler *ehandler)
+{
+	struct sieve_instance *svinst = ehandler->svinst;
+
+	sieve_error_handler_unref(&svinst->system_ehandler);
+	svinst->system_ehandler = ehandler;
+	sieve_error_handler_ref(ehandler);
+}
 
 /*
  * Main error functions
  */
 
 static void sieve_vcopy_master
-(const char *location, sieve_error_vfunc_t error_vfunc, 
-	const char *fmt, va_list args)
+(struct sieve_instance *svinst, const char *location,
+	sieve_error_vfunc_t error_vfunc, const char *fmt, va_list args)
 {
 	va_list args_copy;
 
 	VA_COPY(args_copy, args);
 
-	error_vfunc(_sieve_system_ehandler, location, fmt, args_copy);
+	error_vfunc(svinst->system_ehandler, location, fmt, args_copy);
 }
 
 void sieve_verror
@@ -70,7 +145,7 @@ void sieve_verror
 	if ( ehandler == NULL ) return;
 	
 	if ( ehandler->parent == NULL && ehandler->log_master )
-		sieve_vcopy_master(location, sieve_verror, fmt, args);
+		sieve_vcopy_master(ehandler->svinst, location, sieve_verror, fmt, args);
 
 	sieve_direct_verror(ehandler, location, fmt, args);
 }
@@ -82,7 +157,7 @@ void sieve_vwarning
 	if ( ehandler == NULL ) return;
 
 	if ( ehandler->parent == NULL && ehandler->log_master )
-		sieve_vcopy_master(location, sieve_vwarning, fmt, args);
+		sieve_vcopy_master(ehandler->svinst, location, sieve_vwarning, fmt, args);
 
 	sieve_direct_vwarning(ehandler, location, fmt, args);
 }
@@ -94,7 +169,7 @@ void sieve_vinfo
 	if ( ehandler == NULL ) return;
 
 	if ( ehandler->parent == NULL && ehandler->log_master )
-		sieve_vcopy_master(location, sieve_vinfo, fmt, args);
+		sieve_vcopy_master(ehandler->svinst, location, sieve_vinfo, fmt, args);
 
 	sieve_direct_vinfo(ehandler, location, fmt, args);
 }
@@ -106,7 +181,7 @@ void sieve_vdebug
 	if ( ehandler == NULL ) return;
 
 	if ( ehandler->parent == NULL && ehandler->log_master )
-		sieve_vcopy_master(location, sieve_vdebug, fmt, args);
+		sieve_vcopy_master(ehandler->svinst, location, sieve_vdebug, fmt, args);
 
 	sieve_direct_vdebug(ehandler, location, fmt, args);
 }
@@ -120,11 +195,14 @@ void sieve_vcritical
 	
 	tm = localtime(&ioloop_time);
 	
-	if ( location == NULL || *location == '\0' )
-		sieve_sys_error("%s", t_strdup_vprintf(fmt, args));
-	else
-		sieve_sys_error("%s: %s", location, t_strdup_vprintf(fmt, args));
-		
+	if ( location == NULL || *location == '\0' ) {
+		sieve_sys_error
+			(ehandler->svinst, "%s", t_strdup_vprintf(fmt, args));
+	} else {
+		sieve_sys_error
+			(ehandler->svinst, "%s: %s", location, t_strdup_vprintf(fmt, args));
+	}
+
 	if ( ehandler == NULL ) return;
 	
 	sieve_error(ehandler, location, "%s", 
@@ -254,9 +332,11 @@ void sieve_error_handler_copy_masterlog
  */
 
 void sieve_error_handler_init
-(struct sieve_error_handler *ehandler, pool_t pool, unsigned int max_errors)
+(struct sieve_error_handler *ehandler, struct sieve_instance *svinst,
+	pool_t pool, unsigned int max_errors)
 {
 	ehandler->pool = pool;
+	ehandler->svinst = svinst;
 	ehandler->refcount = 1;
 	ehandler->max_errors = max_errors;
 	
@@ -269,7 +349,7 @@ void sieve_error_handler_init_from_parent
 {
 	i_assert( parent != NULL );
 
-	sieve_error_handler_init(ehandler, pool, parent->max_errors);
+	sieve_error_handler_init(ehandler, parent->svinst, pool, parent->max_errors);
 
 	ehandler->parent = parent;
 	sieve_error_handler_ref(parent);
@@ -369,7 +449,7 @@ static void sieve_master_vdebug
 }
 
 struct sieve_error_handler *sieve_master_ehandler_create
-(unsigned int max_errors) 
+(struct sieve_instance *svinst, unsigned int max_errors) 
 {
 	pool_t pool;
 	struct sieve_error_handler *ehandler;
@@ -380,7 +460,7 @@ struct sieve_error_handler *sieve_master_ehandler_create
 	pool = pool_alloconly_create
 		("master_error_handler", sizeof(struct sieve_error_handler));
 	ehandler = p_new(pool, struct sieve_error_handler, 1);
-	sieve_error_handler_init(ehandler, pool, max_errors);
+	sieve_error_handler_init(ehandler, svinst, pool, max_errors);
 
 	ehandler->verror = sieve_master_verror;
 	ehandler->vwarning = sieve_master_vwarning;
@@ -390,33 +470,6 @@ struct sieve_error_handler *sieve_master_ehandler_create
 	return ehandler;
 }
 
-struct sieve_error_handler _sieve_system_ehandler_object = {
-	NULL, 0, NULL, 0, 0, 0,
-	FALSE,
-	TRUE,
-	TRUE,
-	sieve_master_verror,
-	sieve_master_vwarning,
-	sieve_master_vinfo,
-	sieve_master_vdebug,
-	NULL
-};
-
-struct sieve_error_handler *_sieve_system_ehandler = &_sieve_system_ehandler_object;
-
-void sieve_system_ehandler_set(struct sieve_error_handler *ehandler)
-{
-	sieve_error_handler_unref(&_sieve_system_ehandler);
-	_sieve_system_ehandler = ehandler;
-	sieve_error_handler_ref(_sieve_system_ehandler);
-}
-
-void sieve_system_ehandler_reset(void)
-{
-	sieve_error_handler_unref(&_sieve_system_ehandler);
-	_sieve_system_ehandler = &_sieve_system_ehandler_object;	
-}
-
 /* 
  * STDERR error handler
  *
@@ -462,7 +515,7 @@ static void sieve_stderr_vdebug
 }
 
 struct sieve_error_handler *sieve_stderr_ehandler_create
-(unsigned int max_errors)
+(struct sieve_instance *svinst, unsigned int max_errors)
 {
 	pool_t pool;
 	struct sieve_error_handler *ehandler;
@@ -473,7 +526,7 @@ struct sieve_error_handler *sieve_stderr_ehandler_create
 	pool = pool_alloconly_create
 		("stderr_error_handler", sizeof(struct sieve_error_handler));
 	ehandler = p_new(pool, struct sieve_error_handler, 1);
-	sieve_error_handler_init(ehandler, pool, max_errors);
+	sieve_error_handler_init(ehandler, svinst, pool, max_errors);
 
 	ehandler->verror = sieve_stderr_verror;
 	ehandler->vwarning = sieve_stderr_vwarning;
@@ -542,7 +595,8 @@ static void sieve_strbuf_vdebug
 }
 
 struct sieve_error_handler *sieve_strbuf_ehandler_create
-(string_t *strbuf, bool crlf, unsigned int max_errors)
+(struct sieve_instance *svinst, string_t *strbuf, bool crlf,
+	unsigned int max_errors)
 {
 	pool_t pool;
 	struct sieve_strbuf_ehandler *ehandler;
@@ -551,7 +605,7 @@ struct sieve_error_handler *sieve_strbuf_ehandler_create
 	ehandler = p_new(pool, struct sieve_strbuf_ehandler, 1);
 	ehandler->errors = strbuf;
 
-	sieve_error_handler_init(&ehandler->handler, pool, max_errors);
+	sieve_error_handler_init(&ehandler->handler, svinst, pool, max_errors);
 
 	ehandler->handler.verror = sieve_strbuf_verror;
 	ehandler->handler.vwarning = sieve_strbuf_vwarning;
@@ -609,14 +663,14 @@ static void sieve_logfile_vprintf
 	} T_END;
 
 	if ( ret < 0 ) {
-		sieve_sys_error(
+		sieve_sys_error(ehandler->handler.svinst,
 			"o_stream_send() failed on logfile %s: %m", ehandler->logfile);		
 	}
 }
 
 inline static void sieve_logfile_printf
-(struct sieve_logfile_ehandler *ehandler, const char *location, const char *prefix,
-	const char *fmt, ...) 
+(struct sieve_logfile_ehandler *ehandler, const char *location,
+	const char *prefix, const char *fmt, ...) 
 {
 	va_list args;
 	va_start(args, fmt);
@@ -628,22 +682,23 @@ inline static void sieve_logfile_printf
 
 static void sieve_logfile_start(struct sieve_logfile_ehandler *ehandler)
 {
-	int fd;
+	struct sieve_instance *svinst = ehandler->handler.svinst;
 	struct ostream *ostream = NULL;
 	struct stat st;
 	struct tm *tm;
 	char buf[256];
 	time_t now;
+	int fd;
 
 	/* Open the logfile */
 
 	fd = open(ehandler->logfile, O_CREAT | O_APPEND | O_WRONLY, 0600);
 	if (fd == -1) {
 		if ( errno == EACCES ) {
-			sieve_sys_error("failed to open logfile (LOGGING TO STDERR): %s",
+			sieve_sys_error(svinst, "failed to open logfile (LOGGING TO STDERR): %s",
 				eacces_error_get_creating("open", ehandler->logfile));
 		} else {
-			sieve_sys_error("failed to open logfile (LOGGING TO STDERR): "
+			sieve_sys_error(svinst, "failed to open logfile (LOGGING TO STDERR): "
 				"open(%s) failed: %m", ehandler->logfile);
 		}
 		fd = STDERR_FILENO;
@@ -652,11 +707,11 @@ static void sieve_logfile_start(struct sieve_logfile_ehandler *ehandler)
 
 		/* Stat the log file to obtain size information */
 		if ( fstat(fd, &st) != 0 ) {
-			sieve_sys_error("failed to stat logfile (logging to STDERR): "
+			sieve_sys_error(svinst, "failed to stat logfile (logging to STDERR): "
 				"fstat(fd=%s) failed: %m", ehandler->logfile);
 			
 			if ( close(fd) < 0 ) {
-				sieve_sys_error("failed to close logfile after error: "
+				sieve_sys_error(svinst, "failed to close logfile after error: "
 					"close(fd=%s) failed: %m", ehandler->logfile);
 			}
 
@@ -669,14 +724,15 @@ static void sieve_logfile_start(struct sieve_logfile_ehandler *ehandler)
 			
 			/* Close open file */
 			if ( close(fd) < 0 ) {
-				sieve_sys_error("failed to close logfile: close(fd=%s) failed: %m",
-					ehandler->logfile);
+				sieve_sys_error(svinst, 
+					"failed to close logfile: close(fd=%s) failed: %m", ehandler->logfile);
 			}
 			
 			/* Rotate logfile */
 			rotated = t_strconcat(ehandler->logfile, ".0", NULL);
 			if ( rename(ehandler->logfile, rotated) < 0 ) {
-				sieve_sys_error("failed to rotate logfile: rename(%s, %s) failed: %m", 
+				sieve_sys_error(svinst,
+					"failed to rotate logfile: rename(%s, %s) failed: %m", 
 					ehandler->logfile, rotated);
 			}
 			
@@ -684,11 +740,13 @@ static void sieve_logfile_start(struct sieve_logfile_ehandler *ehandler)
 			fd = open(ehandler->logfile, O_CREAT | O_WRONLY | O_TRUNC, 0600);
 			if (fd == -1) {
 				if ( errno == EACCES ) {
-					sieve_sys_error("failed to open logfile (LOGGING TO STDERR): %s",
+					sieve_sys_error(svinst,
+						"failed to open logfile (LOGGING TO STDERR): %s",
 						eacces_error_get_creating("open", ehandler->logfile));
 				} else {
-					sieve_sys_error("failed to open logfile (LOGGING TO STDERR): "
-						"open(%s) failed: %m", ehandler->logfile);
+					sieve_sys_error(svinst,
+						"failed to open logfile (LOGGING TO STDERR): open(%s) failed: %m", 
+						ehandler->logfile);
 				}
 				fd = STDERR_FILENO;
 			}
@@ -698,7 +756,7 @@ static void sieve_logfile_start(struct sieve_logfile_ehandler *ehandler)
 	ostream = o_stream_create_fd(fd, 0, FALSE);
 	if ( ostream == NULL ) {
 		/* Can't we do anything else in this most awkward situation? */
-		sieve_sys_error("failed to open log stream on open file: "
+		sieve_sys_error(svinst, "failed to open log stream on open file: "
 			"o_stream_create_fd(fd=%s) failed "
 			"(non-critical messages are not logged!)", ehandler->logfile);
 	} 
@@ -776,7 +834,7 @@ static void sieve_logfile_free
 		o_stream_destroy(&(handler->stream));
 		if ( handler->fd != STDERR_FILENO ){
 			if ( close(handler->fd) < 0 ) {
-				sieve_sys_error("failed to close logfile: "
+				sieve_sys_error(ehandler->svinst, "failed to close logfile: "
 					"close(fd=%s) failed: %m", handler->logfile);
 			}
 		}
@@ -784,14 +842,14 @@ static void sieve_logfile_free
 }
 
 struct sieve_error_handler *sieve_logfile_ehandler_create
-(const char *logfile, unsigned int max_errors)
+(struct sieve_instance *svinst, const char *logfile, unsigned int max_errors)
 {
 	pool_t pool;
 	struct sieve_logfile_ehandler *ehandler;
 
 	pool = pool_alloconly_create("logfile_error_handler", 512);
 	ehandler = p_new(pool, struct sieve_logfile_ehandler, 1);
-	sieve_error_handler_init(&ehandler->handler, pool, max_errors);
+	sieve_error_handler_init(&ehandler->handler, svinst, pool, max_errors);
 
 	ehandler->handler.verror = sieve_logfile_verror;
 	ehandler->handler.vwarning = sieve_logfile_vwarning;
diff --git a/src/lib-sieve/sieve-error.h b/src/lib-sieve/sieve-error.h
index fd7d743b2..5fb8c8f44 100644
--- a/src/lib-sieve/sieve-error.h
+++ b/src/lib-sieve/sieve-error.h
@@ -15,6 +15,7 @@
 
 struct var_expand_table;
 
+struct sieve_instance;
 struct sieve_script;
 struct sieve_error_handler;
 
@@ -33,15 +34,17 @@ typedef void (*sieve_error_func_t)
  * System errors
  */
 
-extern struct sieve_error_handler *_sieve_system_ehandler;
+void sieve_sys_error
+	(struct sieve_instance *svinst, const char *fmt, ...) ATTR_FORMAT(2, 3);
+void sieve_sys_warning
+	(struct sieve_instance *svinst, const char *fmt, ...) ATTR_FORMAT(2, 3);
+void sieve_sys_info
+	(struct sieve_instance *svinst, const char *fmt, ...) ATTR_FORMAT(2, 3);
+void sieve_sys_debug
+	(struct sieve_instance *svinst, const char *fmt, ...) ATTR_FORMAT(2, 3);
 
-#define sieve_sys_error(...) sieve_error(_sieve_system_ehandler, NULL, __VA_ARGS__ )
-#define sieve_sys_warning(...) sieve_warning(_sieve_system_ehandler, NULL, __VA_ARGS__ )
-#define sieve_sys_info(...) sieve_info(_sieve_system_ehandler, NULL, __VA_ARGS__ )
-#define sieve_sys_debug(...) sieve_debug(_sieve_system_ehandler, NULL, __VA_ARGS__ )
-
-void sieve_system_ehandler_set(struct sieve_error_handler *ehandler);
-void sieve_system_ehandler_reset(void);
+void sieve_system_ehandler_set
+	(struct sieve_error_handler *ehandler);
 
 /*
  * Main error functions
@@ -121,19 +124,20 @@ void sieve_error_handler_reset(struct sieve_error_handler *ehandler);
 
 /* Write errors to dovecot master log */
 struct sieve_error_handler *sieve_master_ehandler_create
-	(unsigned int max_errors);
+	(struct sieve_instance *svinst, unsigned int max_errors);
 
 /* Write errors to stderr */
 struct sieve_error_handler *sieve_stderr_ehandler_create
-	(unsigned int max_errors);
+	(struct sieve_instance *svinst, unsigned int max_errors);
 
 /* Write errors into a string buffer */
 struct sieve_error_handler *sieve_strbuf_ehandler_create
-	(string_t *strbuf, bool crlf, unsigned int max_errors);
+	(struct sieve_instance *svinst, string_t *strbuf, bool crlf,
+		unsigned int max_errors);
 
 /* Write errors to a logfile */
 struct sieve_error_handler *sieve_logfile_ehandler_create
-	(const char *logfile, unsigned int max_errors);  
+	(struct sieve_instance *svinst, const char *logfile, unsigned int max_errors);  
 
 /* Wrapper: prefix all log messages */
 struct sieve_error_handler *sieve_prefix_ehandler_create
diff --git a/src/lib-sieve/sieve-extensions.c b/src/lib-sieve/sieve-extensions.c
index c4ac848d0..9086264a7 100644
--- a/src/lib-sieve/sieve-extensions.c
+++ b/src/lib-sieve/sieve-extensions.c
@@ -268,7 +268,8 @@ static bool _sieve_extension_load(struct sieve_extension *ext)
 	/* Call load handler */
 	if ( ext->def != NULL && ext->def->load != NULL && 
 		!ext->def->load(ext, &ext->context) ) {
-		sieve_sys_error("failed to load '%s' extension support.", ext->def->name);
+		sieve_sys_error(ext->svinst,
+			"failed to load '%s' extension support.", ext->def->name);
 		return FALSE;
 	}
 
@@ -277,9 +278,9 @@ static bool _sieve_extension_load(struct sieve_extension *ext)
 
 static void _sieve_extension_unload(struct sieve_extension *ext)
 {
-    /* Call unload handler */
-    if ( ext->def != NULL && ext->def->unload != NULL )
-        ext->def->unload(ext);
+	/* Call unload handler */
+	if ( ext->def != NULL && ext->def->unload != NULL )
+		ext->def->unload(ext);
 }
 
 static void sieve_extension_registry_init(struct sieve_instance *svinst)
@@ -544,7 +545,7 @@ void sieve_extensions_set_string
 						hash_table_lookup(ext_reg->extension_index, name);
 	
 				if ( ext == NULL || ext->def == NULL ) {
-					sieve_sys_warning(
+					sieve_sys_warning(ext->svinst,
 						"ignored unknown extension '%s' while configuring "
 						"available extensions", name);
 					continue;
diff --git a/src/lib-sieve/sieve-message.c b/src/lib-sieve/sieve-message.c
index 005dadc8c..1ff42a197 100644
--- a/src/lib-sieve/sieve-message.c
+++ b/src/lib-sieve/sieve-message.c
@@ -142,21 +142,31 @@ const void *sieve_message_context_extension_get
 
 static void sieve_message_envelope_parse(struct sieve_message_context *msgctx)
 {
+	struct sieve_instance *svinst = msgctx->svinst;
+
 	/* FIXME: log parse problems properly; logs only 'failure' now */
 
 	msgctx->envelope_recipient = sieve_address_parse_envelope_path
 		(msgctx->pool, msgctx->msgdata->to_address);	
 
-	if ( msgctx->envelope_recipient == NULL )
-		sieve_sys_error("envelope recipient address '%s' is unparsable", msgctx->msgdata->to_address); 
-	else if ( msgctx->envelope_recipient->local_part == NULL )
-		sieve_sys_error("envelope recipient address '%s' is a null path", msgctx->msgdata->to_address); 
+	if ( msgctx->envelope_recipient == NULL ) {
+		sieve_sys_error(svinst,
+			"envelope recipient address '%s' is unparsable",
+			msgctx->msgdata->to_address); 
+	} else if ( msgctx->envelope_recipient->local_part == NULL ) {
+		sieve_sys_error(svinst,
+			"envelope recipient address '%s' is a null path",
+			msgctx->msgdata->to_address);
+	} 
 
 	msgctx->envelope_sender = sieve_address_parse_envelope_path
 		(msgctx->pool, msgctx->msgdata->return_path);	
 
-	if ( msgctx->envelope_sender == NULL )
-		sieve_sys_error("envelope sender address '%s' is unparsable", msgctx->msgdata->return_path); 
+	if ( msgctx->envelope_sender == NULL ) {
+		sieve_sys_error(svinst, 
+			"envelope sender address '%s' is unparsable", 
+			msgctx->msgdata->return_path);
+	}
 
 	msgctx->envelope_parsed = TRUE;
 }
diff --git a/src/lib-sieve/sieve-script.c b/src/lib-sieve/sieve-script.c
index e0010b2a8..9f8765a53 100644
--- a/src/lib-sieve/sieve-script.c
+++ b/src/lib-sieve/sieve-script.c
@@ -142,7 +142,7 @@ static void sieve_script_handle_file_error
 			sieve_error(ehandler, name, "sieve script does not exist");
 		else {
 			if ( svinst->debug )
-				sieve_sys_debug("script file %s not found", t_abspath(path));
+				sieve_sys_debug(svinst, "script file %s not found", t_abspath(path));
 			*error_r = SIEVE_ERROR_NOT_FOUND;
 		}
 		break;
@@ -403,7 +403,7 @@ struct istream *sieve_script_open
 	if ( result == NULL ) {
 		/* Something went wrong, close the fd */
 		if ( close(fd) != 0 ) {
-			sieve_sys_error(
+			sieve_sys_error(script->svinst, 
 				"failed to close sieve script: close(fd=%s) failed: %m", 
 				script->path);
 		}
diff --git a/src/lib-sieve/sieve-settings.c b/src/lib-sieve/sieve-settings.c
index 9c318b214..cd0ed8e1c 100644
--- a/src/lib-sieve/sieve-settings.c
+++ b/src/lib-sieve/sieve-settings.c
@@ -25,7 +25,8 @@ bool sieve_setting_get_uint_value
 	*value_r = strtoull(str_value, &endp, 10);
 
 	if ( *endp != '\0' ) {
-		sieve_sys_warning("invalid unsigned integer value for setting '%s': '%s'",
+		sieve_sys_warning(svinst,
+			"invalid unsigned integer value for setting '%s': '%s'",
 			setting, str_value);
 		return FALSE;
 	}
@@ -48,7 +49,7 @@ bool sieve_setting_get_int_value
 	*value_r = strtoll(str_value, &endp, 10);
 
 	if ( *endp != '\0' ) {
-		sieve_sys_warning("invalid integer value for setting '%s': '%s'",
+		sieve_sys_warning(svinst, "invalid integer value for setting '%s': '%s'",
 			setting, str_value);
 
 		return FALSE;
@@ -92,7 +93,8 @@ bool sieve_setting_get_size_value
 		multiply = 1024ULL*1024*1024*1024;
 		break;
 	default:
-		sieve_sys_warning("invalid unsigned integer value for setting '%s': '%s'",
+		sieve_sys_warning(svinst,
+			"invalid unsigned integer value for setting '%s': '%s'",
 			setting, str_value);
 		return FALSE;
 	}
@@ -124,7 +126,7 @@ bool sieve_setting_get_bool_value
 		return TRUE;
 	}
 
-	sieve_sys_warning("invalid boolean value for setting '%s': '%s'",
+	sieve_sys_warning(svinst, "invalid boolean value for setting '%s': '%s'",
 		setting, str_value);
 	return FALSE;
 }
diff --git a/src/lib-sieve/sieve.c b/src/lib-sieve/sieve.c
index fd1e98a9c..3c0caef11 100644
--- a/src/lib-sieve/sieve.c
+++ b/src/lib-sieve/sieve.c
@@ -26,6 +26,7 @@
 
 #include "sieve.h"
 #include "sieve-common.h"
+#include "sieve-error-private.h"
 
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -55,6 +56,8 @@ struct sieve_instance *sieve_init
 	svinst->context = context;
 	svinst->debug = debug;
 
+	sieve_errors_init(svinst);
+
 	/* Read limits from configuration */
 
 	svinst->max_script_size = SIEVE_DEFAULT_MAX_SCRIPT_SIZE;
@@ -93,6 +96,8 @@ void sieve_deinit(struct sieve_instance **svinst)
 
 	sieve_extensions_deinit(*svinst);
 
+	sieve_errors_deinit(*svinst);
+
 	pool_unref(&(*svinst)->pool);
 
 	*svinst = NULL;
@@ -247,7 +252,8 @@ struct sieve_binary *sieve_compile
 	sieve_script_unref(&script);
 
 	if ( svinst->debug && sbin != NULL ) {
-		sieve_sys_debug("script file %s successfully compiled", script_path);
+		sieve_sys_debug(svinst, "script file %s successfully compiled",
+			script_path);
 	}
 	
 	return sbin;
@@ -329,7 +335,8 @@ struct sieve_binary *sieve_open
 			if ( !sieve_binary_up_to_date(sbin) ) {
 				/* Not up to date */
 				if ( svinst->debug )
-					sieve_sys_debug("script binary %s is not up-to-date", bin_path);
+					sieve_sys_debug(svinst, "script binary %s is not up-to-date",
+						bin_path);
 
 				sieve_binary_unref(&sbin);
 				sbin = NULL;
@@ -341,7 +348,8 @@ struct sieve_binary *sieve_open
 		 */
 		if ( sbin != NULL ) {
 			if ( svinst->debug )
-				sieve_sys_debug("script binary %s successfully loaded", bin_path);
+				sieve_sys_debug(svinst, "script binary %s successfully loaded",
+					bin_path);
 			
 		} else {	
 			sbin = sieve_compile_script(script, ehandler, error_r);
@@ -349,7 +357,8 @@ struct sieve_binary *sieve_open
 			/* Save the binary if compile was successful */
 			if ( sbin != NULL ) {
 				if ( svinst->debug )
-					sieve_sys_debug("script %s successfully compiled", script_path);
+					sieve_sys_debug(svinst, "script %s successfully compiled", 
+						script_path);
 			}
 		}
 	} T_END;
@@ -640,13 +649,14 @@ size_t sieve_max_script_size(struct sieve_instance *svinst)
  */
 
 struct sieve_directory {
+		struct sieve_instance *svinst;
 		DIR *dirp;
 
 		const char *path;
 };
 
 struct sieve_directory *sieve_directory_open
-(const char *path, enum sieve_error *error_r)
+(struct sieve_instance *svinst, const char *path, enum sieve_error *error_r)
 { 
 	struct sieve_directory *sdir = NULL;
 	DIR *dirp;
@@ -663,14 +673,14 @@ struct sieve_directory *sieve_directory_open
 				*error_r = SIEVE_ERROR_NOT_FOUND;
 			break;
 		case EACCES:
-			sieve_sys_error("failed to open sieve dir: %s",
+			sieve_sys_error(svinst, "failed to open sieve dir: %s",
 				eacces_error_get("stat", path));
 			if ( error_r != NULL )
 				*error_r = SIEVE_ERROR_NO_PERM;
 			break;
 		default:
-			sieve_sys_error("failed to open sieve dir: "
-				"stat(%s) failed: %m", path);
+			sieve_sys_error(svinst, "failed to open sieve dir: stat(%s) failed: %m",
+				path);
 			if ( error_r != NULL )
 				*error_r = SIEVE_ERROR_TEMP_FAIL;
 			break;
@@ -688,14 +698,14 @@ struct sieve_directory *sieve_directory_open
 					*error_r = SIEVE_ERROR_NOT_FOUND;
 				break;
 			case EACCES:
-				sieve_sys_error("failed to open sieve dir: %s",
+				sieve_sys_error(svinst, "failed to open sieve dir: %s",
 					eacces_error_get("opendir", path));
 				if ( error_r != NULL )
 					*error_r = SIEVE_ERROR_NO_PERM;
 				break;
 			default:
-				sieve_sys_error("failed to open sieve dir: "
-					"opendir(%s) failed: %m", path);
+				sieve_sys_error(svinst, "failed to open sieve dir: opendir(%s) failed: "
+					"%m", path);
 				if ( error_r != NULL )
 					*error_r = SIEVE_ERROR_TEMP_FAIL;
 				break;
@@ -713,6 +723,8 @@ struct sieve_directory *sieve_directory_open
 		sdir->dirp = NULL;
 	}
 
+	sdir->svinst = svinst;
+
 	return sdir;
 }
 
@@ -729,7 +741,7 @@ const char *sieve_directory_get_scriptfile(struct sieve_directory *sdir)
 			errno = 0;
 			if ( (dp = readdir(sdir->dirp)) == NULL ) {
 				if ( errno != 0 ) {
-					sieve_sys_error("failed to read sieve dir: "
+					sieve_sys_error(sdir->svinst, "failed to read sieve dir: "
 						"readdir(%s) failed: %m", sdir->path);
 				}
 
@@ -761,7 +773,7 @@ void sieve_directory_close(struct sieve_directory **sdir)
 {
 	/* Close the directory */
 	if ( (*sdir)->dirp != NULL && closedir((*sdir)->dirp) < 0 ) 
-		sieve_sys_error("failed to close sieve dir: "
+		sieve_sys_error((*sdir)->svinst, "failed to close sieve dir: "
 			"closedir(%s) failed: %m", (*sdir)->path);
 		
 	*sdir = NULL;
diff --git a/src/lib-sieve/sieve.h b/src/lib-sieve/sieve.h
index 082e95acc..ac58cf77b 100644
--- a/src/lib-sieve/sieve.h
+++ b/src/lib-sieve/sieve.h
@@ -181,7 +181,7 @@ size_t sieve_max_script_size(struct sieve_instance *svinst);
 struct sieve_directory;
 
 struct sieve_directory *sieve_directory_open
-	(const char *path, enum sieve_error *error_r);
+	(struct sieve_instance *svinst, const char *path, enum sieve_error *error_r);
 const char *sieve_directory_get_scriptfile(struct sieve_directory *sdir);
 void sieve_directory_close(struct sieve_directory **sdir);
 
diff --git a/src/lib-sieve/tst-size.c b/src/lib-sieve/tst-size.c
index c4759decf..2e3aa19d7 100644
--- a/src/lib-sieve/tst-size.c
+++ b/src/lib-sieve/tst-size.c
@@ -263,7 +263,7 @@ static int tst_size_operation_execute
 	/* Get the size of the message */
 	if ( !tst_size_get(renv, &mail_size) ) {
 		/* FIXME: improve this error */
-		sieve_sys_error("failed to assess message size");
+		sieve_sys_error(renv->svinst, "failed to assess message size");
 		return SIEVE_EXEC_FAILURE;
 	}
 	
diff --git a/src/lib-sievestorage/sieve-storage.c b/src/lib-sievestorage/sieve-storage.c
index 2e0a1c791..e5478835e 100644
--- a/src/lib-sievestorage/sieve-storage.c
+++ b/src/lib-sievestorage/sieve-storage.c
@@ -399,7 +399,7 @@ struct sieve_error_handler *sieve_storage_get_error_handler
 	if ( storage->ehandler == NULL ) {
 		pool_t pool = pool_alloconly_create("sieve_storage_ehandler", 512);
 		ehandler = p_new(pool, struct sieve_storage_ehandler,1);
-		sieve_error_handler_init(&ehandler->handler, pool, 1);
+		sieve_error_handler_init(&ehandler->handler, storage->svinst, pool, 1);
 
 		ehandler->handler.verror = sieve_storage_verror;
 		ehandler->storage = storage;
diff --git a/src/managesieve/cmd-putscript.c b/src/managesieve/cmd-putscript.c
index 10d4f31a1..a52d88257 100644
--- a/src/managesieve/cmd-putscript.c
+++ b/src/managesieve/cmd-putscript.c
@@ -199,8 +199,8 @@ static bool cmd_putscript_finish_parsing(struct client_command_context *cmd)
 
 			/* Prepare error handler */
 			errors = str_new(default_pool, 1024);
-			ehandler = sieve_strbuf_ehandler_create
-				(errors, TRUE, client->set->managesieve_max_compile_errors);
+			ehandler = sieve_strbuf_ehandler_create(client->svinst, errors, TRUE, 
+				client->set->managesieve_max_compile_errors);
 
 			/* Compile */
 			if ( (sbin=sieve_compile_script(script, ehandler, NULL)) == NULL ) {
diff --git a/src/plugins/lda-sieve/lda-sieve-log.c b/src/plugins/lda-sieve/lda-sieve-log.c
index 4d9d545c5..1b12809c7 100644
--- a/src/plugins/lda-sieve/lda-sieve-log.c
+++ b/src/plugins/lda-sieve/lda-sieve-log.c
@@ -76,7 +76,8 @@ static void lda_sieve_log_vdebug
 }
 
 struct sieve_error_handler *lda_sieve_log_ehandler_create
-(struct mail_deliver_context *mdctx, unsigned int max_errors)
+(struct sieve_instance *svinst, struct mail_deliver_context *mdctx,
+	unsigned int max_errors)
 {
 	pool_t pool;
 	struct lda_sieve_log_ehandler *ehandler;
@@ -85,7 +86,7 @@ struct sieve_error_handler *lda_sieve_log_ehandler_create
 	ehandler = p_new(pool, struct lda_sieve_log_ehandler, 1);
 	ehandler->mdctx = mdctx;
 
-	sieve_error_handler_init(&ehandler->handler, pool, max_errors);
+	sieve_error_handler_init(&ehandler->handler, svinst, pool, max_errors);
 
 	ehandler->handler.verror = lda_sieve_log_verror;
 	ehandler->handler.vwarning = lda_sieve_log_vwarning;
diff --git a/src/plugins/lda-sieve/lda-sieve-log.h b/src/plugins/lda-sieve/lda-sieve-log.h
index 1c549ac83..4523b82f6 100644
--- a/src/plugins/lda-sieve/lda-sieve-log.h
+++ b/src/plugins/lda-sieve/lda-sieve-log.h
@@ -8,6 +8,7 @@
 #include "mail-deliver.h"
 
 struct sieve_error_handler *lda_sieve_log_ehandler_create
-	(struct mail_deliver_context *mdctx, unsigned int max_errors);
+	(struct sieve_instance *svinst, struct mail_deliver_context *mdctx,
+		unsigned int max_errors);
 
 #endif /* __LDA_SIEVE_LOG */
diff --git a/src/plugins/lda-sieve/lda-sieve-plugin.c b/src/plugins/lda-sieve/lda-sieve-plugin.c
index 44ea0f9ae..3fa7a9d8d 100644
--- a/src/plugins/lda-sieve/lda-sieve-plugin.c
+++ b/src/plugins/lda-sieve/lda-sieve-plugin.c
@@ -136,7 +136,8 @@ struct lda_sieve_run_context {
 	const char *userlog;
 };
 
-static const char *lda_sieve_get_personal_path(struct mail_user *user)
+static const char *lda_sieve_get_personal_path
+(struct sieve_instance *svinst, struct mail_user *user)
 {
 	const char *script_path, *home;
 
@@ -150,7 +151,7 @@ static const char *lda_sieve_get_personal_path(struct mail_user *user)
 		if (*script_path == '\0') {
 			/* disabled */
 			if ( user->mail_debug )
-				sieve_sys_debug("empty script path, disabled");
+				sieve_sys_debug(svinst, "empty script path, disabled");
 			return NULL;
 		}
 
@@ -161,7 +162,7 @@ static const char *lda_sieve_get_personal_path(struct mail_user *user)
 
 			if ( home == NULL || *home == '\0' ) {
 				if ( user->mail_debug )
-					sieve_sys_debug("relative script path, but empty home dir");
+					sieve_sys_debug(svinst, "relative script path, but empty home dir");
 				return NULL;
 			}
 
@@ -169,7 +170,7 @@ static const char *lda_sieve_get_personal_path(struct mail_user *user)
 		}
 	} else {
 		if ( home == NULL || *home == '\0' ) {
-			sieve_sys_error(
+			sieve_sys_error(svinst, 
 				"path to user's main active personal script is unknown. "
 				"See http://wiki.dovecot.org/LDA/Sieve/Dovecot#configuration");
 			return NULL;
@@ -181,7 +182,8 @@ static const char *lda_sieve_get_personal_path(struct mail_user *user)
 	return script_path;
 }
 
-static const char *lda_sieve_get_default_path(struct mail_user *user)
+static const char *lda_sieve_get_default_path
+(struct mail_user *user)
 {
 	const char *script_path;
 
@@ -196,13 +198,14 @@ static const char *lda_sieve_get_default_path(struct mail_user *user)
 }
 
 static int lda_sieve_multiscript_get_scriptfiles
-(const char *script_path, ARRAY_TYPE(const_string) *scriptfiles)
+(struct sieve_instance *svinst, const char *script_path,
+	ARRAY_TYPE(const_string) *scriptfiles)
 {
 	struct sieve_directory *sdir;
 	enum sieve_error error;
 	const char *file;
 
-	if ( (sdir=sieve_directory_open(script_path, &error)) == NULL )
+	if ( (sdir=sieve_directory_open(svinst, script_path, &error)) == NULL )
 		return ( error == SIEVE_ERROR_NOT_FOUND ? 0 : -1 );
 
 	while ( (file=sieve_directory_get_scriptfile(sdir)) != NULL ) {
@@ -238,7 +241,7 @@ static void lda_sieve_binary_save
 	if ( sieve_save(sbin, NULL, FALSE, &error) < 0 &&
 		error == SIEVE_ERROR_NO_PERM  && script_path != srctx->user_script ) {
 		/* Cannot save binary for global script */
-		sieve_sys_error(
+		sieve_sys_error(srctx->svinst,
 			"the lda sieve plugin does not have permission "
 			"to save global sieve script binaries; "
 			"global sieve scripts like %s need to be "
@@ -264,26 +267,25 @@ static struct sieve_binary *lda_sieve_open
 		ehandler = srctx->master_ehandler;
 
 	if ( debug )
-		sieve_sys_debug("opening script %s", script_path);
+		sieve_sys_debug(svinst, "opening script %s", script_path);
 
 	sieve_error_handler_reset(ehandler);
 
 	/* Open the sieve script */
-	if ( (sbin=sieve_open(svinst, script_path, script_name, ehandler, error_r)) 
+	if ( (sbin=sieve_open(svinst, script_path, script_name, ehandler, error_r))
 		== NULL ) {
 		if ( *error_r == SIEVE_ERROR_NOT_FOUND ) {
 			if ( debug )
-				sieve_sys_debug("script file %s is missing", script_path);
+				sieve_sys_debug(svinst, "script file %s is missing", script_path);
 		} else {
 			if ( script_path == srctx->user_script && srctx->userlog != NULL ) {
-				sieve_sys_error
-					("failed to open script %s "
-						"(view logfile %s for more information)", 
-						script_path, srctx->userlog);
+				sieve_sys_error(svinst,
+					"failed to open script %s "
+					"(view logfile %s for more information)",
+					script_path, srctx->userlog);
 			} else {
-				sieve_sys_error
-					("failed to open script %s", 
-						script_path);
+				sieve_sys_error(svinst,
+					"failed to open script %s", script_path);
 			}
 		}
 
@@ -307,10 +309,10 @@ static struct sieve_binary *lda_sieve_recompile
 
 	/* Warn */
 
-	sieve_sys_warning("encountered corrupt binary: re-compiling script %s", 
+	sieve_sys_warning(svinst, "encountered corrupt binary: re-compiling script %s",
 		script_path);
 
-	/* Recompile */	
+	/* Recompile */
 
 	if ( script_path == srctx->user_script )
 		ehandler = srctx->user_ehandler;
@@ -321,13 +323,13 @@ static struct sieve_binary *lda_sieve_recompile
 		(svinst, script_path, script_name, ehandler, error_r)) == NULL ) {
 
 		if ( script_path == srctx->user_script && srctx->userlog != NULL ) {
-			sieve_sys_error
-				("failed to re-compile script %s "
-					"(view logfile %s for more information)",
-					script_path, srctx->userlog);
+			sieve_sys_error(svinst,
+				"failed to re-compile script %s "
+				"(view logfile %s for more information)",
+				script_path, srctx->userlog);
 		} else {
-			sieve_sys_error
-				("failed to re-compile script %s", script_path);
+			sieve_sys_error(svinst,
+				"failed to re-compile script %s", script_path);
 		}
 
 		return NULL;
@@ -336,27 +338,29 @@ static struct sieve_binary *lda_sieve_recompile
 	return sbin;
 }
 
-static int lda_sieve_handle_exec_status(const char *script_path, int status)
+static int lda_sieve_handle_exec_status
+(struct lda_sieve_run_context *srctx, const char *script_path, int status)
 {
+	struct sieve_instance *svinst = srctx->svinst;
 	int ret;
 
 	switch ( status ) {
 	case SIEVE_EXEC_FAILURE:
-		sieve_sys_error
-			("execution of script %s failed, but implicit keep was successful", 
+		sieve_sys_error(svinst,
+			"execution of script %s failed, but implicit keep was successful", 
 				script_path);
 		ret = 1;
 		break;
 	case SIEVE_EXEC_BIN_CORRUPT:
-		sieve_sys_error
-			("!!BUG!!: binary compiled from %s is still corrupt; "
+		sieve_sys_error(svinst,
+			"!!BUG!!: binary compiled from %s is still corrupt; "
 				"bailing out and reverting to default delivery", 
 				script_path);
 		ret = -1;
 		break;
 	case SIEVE_EXEC_KEEP_FAILED:
-		sieve_sys_error
-			("script %s failed with unsuccessful implicit keep", script_path);
+		sieve_sys_error(svinst,
+			"script %s failed with unsuccessful implicit keep", script_path);
 		ret = -1;
 		break;
 	default:
@@ -370,6 +374,7 @@ static int lda_sieve_handle_exec_status(const char *script_path, int status)
 static int lda_sieve_singlescript_execute
 (struct lda_sieve_run_context *srctx)
 {
+	struct sieve_instance *svinst = srctx->svinst;
 	const char *script_file = srctx->script_files[0];
 	bool user_script = ( script_file == srctx->user_script );
 	struct sieve_error_handler *ehandler;
@@ -386,18 +391,18 @@ static int lda_sieve_singlescript_execute
 	/* Execute */
 
 	if ( debug )
-		sieve_sys_debug("executing script from %s", sieve_get_source(sbin));
+		sieve_sys_debug(svinst, "executing script from %s", sieve_get_source(sbin));
 
 	if ( user_script ) {
 		ehandler = srctx->user_ehandler;
-		sieve_error_handler_copy_masterlog(ehandler, TRUE);	
+		sieve_error_handler_copy_masterlog(ehandler, TRUE);
 	} else {
 		ehandler = srctx->master_ehandler;
 	}
 
 	ret = sieve_execute(sbin, srctx->msgdata, srctx->scriptenv, ehandler, NULL);
 
-	sieve_error_handler_copy_masterlog(ehandler, FALSE);	
+	sieve_error_handler_copy_masterlog(ehandler, FALSE);
 
 	/* Recompile if corrupt binary */
 
@@ -414,7 +419,7 @@ static int lda_sieve_singlescript_execute
 		/* Execute again */
 
 		if ( debug )
-			sieve_sys_debug("executing script from %s", sieve_get_source(sbin));
+			sieve_sys_debug(svinst, "executing script from %s", sieve_get_source(sbin));
 
 		if ( user_script )
         	sieve_error_handler_copy_masterlog(ehandler, TRUE);
@@ -432,7 +437,7 @@ static int lda_sieve_singlescript_execute
 	sieve_close(&sbin);
 
 	/* Report status */
-	return lda_sieve_handle_exec_status(script_file, ret);
+	return lda_sieve_handle_exec_status(srctx, script_file, ret);
 }
 
 static int lda_sieve_multiscript_execute
@@ -484,7 +489,7 @@ static int lda_sieve_multiscript_execute
 			sieve_error_handler_copy_masterlog(ehandler, TRUE);
 
 		if ( debug )
-			sieve_sys_debug("executing script from %s", sieve_get_source(sbin));
+			sieve_sys_debug(svinst, "executing script from %s", sieve_get_source(sbin));
 
 		more = sieve_multiscript_run(mscript, sbin, ehandler, final);
 
@@ -533,30 +538,25 @@ static int lda_sieve_multiscript_execute
 
 	sieve_error_handler_copy_masterlog(ehandler, FALSE);
 
-	return lda_sieve_handle_exec_status(last_script, ret);
+	return lda_sieve_handle_exec_status(srctx, last_script, ret);
 }
 
 static int lda_sieve_run
-(struct mail_deliver_context *mdctx, 
+(struct mail_deliver_context *mdctx, struct sieve_instance *svinst,
 	const char *user_script, const char *default_script,
 	const ARRAY_TYPE (const_string) *scripts_before,
 	const ARRAY_TYPE (const_string) *scripts_after,
 	struct mail_storage **storage_r)
 {
-	struct sieve_instance *svinst;
 	ARRAY_TYPE (const_string) scripts;
 	struct lda_sieve_run_context srctx;
 	struct sieve_message_data msgdata;
 	struct sieve_script_env scriptenv;
 	struct sieve_exec_status estatus;
-	bool debug = mdctx->dest_user->mail_debug;
 	int ret = 0;
 
 	*storage_r = NULL;
 
-	/* Initialize Sieve engine */
-	svinst = sieve_init(&lda_sieve_env, mdctx->dest_user, debug);
-
 	/* Initialize */
 
 	memset(&srctx, 0, sizeof(srctx));
@@ -589,11 +589,11 @@ static int lda_sieve_run
 	if ( user_script != NULL ) {
 		srctx.userlog = t_strconcat(user_script, ".log", NULL);
 		srctx.user_ehandler = sieve_logfile_ehandler_create
-			(srctx.userlog, LDA_SIEVE_MAX_USER_ERRORS);
+			(svinst, srctx.userlog, LDA_SIEVE_MAX_USER_ERRORS);
 	}
 
 	srctx.master_ehandler = lda_sieve_log_ehandler_create
-		(mdctx, LDA_SIEVE_MAX_SYSTEM_ERRORS);
+		(svinst, mdctx, LDA_SIEVE_MAX_SYSTEM_ERRORS);
 	sieve_system_ehandler_set(srctx.master_ehandler);
 
 	sieve_error_handler_accept_infolog(srctx.master_ehandler, TRUE);
@@ -653,7 +653,6 @@ static int lda_sieve_run
 	if ( srctx.user_ehandler != NULL )
 		sieve_error_handler_unref(&srctx.user_ehandler);
 
-	sieve_system_ehandler_reset();
 	sieve_error_handler_unref(&srctx.master_ehandler);
 
 	/* Deinitialize Sieve engine */
@@ -665,12 +664,17 @@ static int lda_sieve_run
 static int lda_sieve_deliver_mail
 (struct mail_deliver_context *mdctx, struct mail_storage **storage_r)
 {
+	struct sieve_instance *svinst;
 	const char *user_script, *default_script, *sieve_before, *sieve_after;
 	ARRAY_TYPE (const_string) scripts_before;
 	ARRAY_TYPE (const_string) scripts_after;
 	bool debug = mdctx->dest_user->mail_debug;
 	int ret = 0;
 
+	/* Initialize Sieve engine */
+
+	svinst = sieve_init(&lda_sieve_env, mdctx->dest_user, debug);
+
 	*storage_r = NULL;
 
 	T_BEGIN { 
@@ -678,7 +682,7 @@ static int lda_sieve_deliver_mail
 
 		/* Find the personal script to execute */
 
-		user_script = lda_sieve_get_personal_path(mdctx->dest_user);
+		user_script = lda_sieve_get_personal_path(svinst, mdctx->dest_user);
 		default_script = lda_sieve_get_default_path(mdctx->dest_user);
 
 		if ( user_script != NULL && stat(user_script, &st) < 0 ) {
@@ -686,16 +690,16 @@ static int lda_sieve_deliver_mail
 			switch ( errno ) {
 			case ENOENT:
 				if ( debug )
-					sieve_sys_debug("user's script path %s doesn't exist "
+					sieve_sys_debug(svinst, "user's script path %s doesn't exist "
 						"(using global script path in stead)", user_script);
 				break;
 			case EACCES:
-				sieve_sys_error("failed to stat user's sieve script: %s "
+				sieve_sys_error(svinst, "failed to stat user's sieve script: %s "
 					"(using global script path in stead)",
 					eacces_error_get("stat", user_script));
 				break;
 			default:
-				sieve_sys_error("failed to stat user's sieve script: "
+				sieve_sys_error(svinst, "failed to stat user's sieve script: "
 					"stat(%s) failed: %m (using global script path in stead)",
 					user_script);
 				break;
@@ -708,9 +712,9 @@ static int lda_sieve_deliver_mail
 			const char *script = user_script == NULL ? default_script : user_script;
 
 			if ( script == NULL )
-				sieve_sys_debug("user has no valid personal script");
+				sieve_sys_debug(svinst, "user has no valid personal script");
 			else
-				sieve_sys_debug("using sieve path for user's script: %s", script);
+				sieve_sys_debug(svinst, "using sieve path for user's script: %s", script);
 		}
 
 		/* Check for multiscript */
@@ -723,15 +727,15 @@ static int lda_sieve_deliver_mail
 
 		if ( sieve_before != NULL && *sieve_before != '\0' ) {
 			if ( lda_sieve_multiscript_get_scriptfiles
-				(sieve_before, &scripts_before) == 0 && debug ) {
-				sieve_sys_debug("sieve_before path not found: %s", sieve_before);
+				(svinst, sieve_before, &scripts_before) == 0 && debug ) {
+				sieve_sys_debug(svinst, "sieve_before path not found: %s", sieve_before);
 			}
 		}
 
 		if ( sieve_after != NULL && *sieve_after != '\0' ) {
 			if ( lda_sieve_multiscript_get_scriptfiles
-				(sieve_after, &scripts_after) == 0 && debug ) {
-				sieve_sys_debug("sieve_after path not found: %s", sieve_after);
+				(svinst, sieve_after, &scripts_after) == 0 && debug ) {
+				sieve_sys_debug(svinst, "sieve_after path not found: %s", sieve_after);
 			}
 		}
 
@@ -741,13 +745,13 @@ static int lda_sieve_deliver_mail
 
 			scriptfiles = array_get(&scripts_before, &count);
 			for ( i = 0; i < count; i ++ ) {
-				sieve_sys_debug("executed before user's script(%d): %s",
+				sieve_sys_debug(svinst, "executed before user's script(%d): %s",
 					i+1, scriptfiles[i]);
 			}
 
 			scriptfiles = array_get(&scripts_after, &count);
 			for ( i = 0; i < count; i ++ ) {
-				sieve_sys_debug("executed after user's script(%d): %s",
+				sieve_sys_debug(svinst, "executed after user's script(%d): %s",
 					i+1, scriptfiles[i]);
 			}
 		}
@@ -757,7 +761,7 @@ static int lda_sieve_deliver_mail
 		if ( array_count(&scripts_before) == 0 && array_count(&scripts_after) == 0 &&
 			user_script == NULL && default_script == NULL ) {
 			if ( debug )
-				sieve_sys_debug("no scripts to execute: reverting to default delivery.");
+				sieve_sys_debug(svinst, "no scripts to execute: reverting to default delivery.");
 
 			/* No error, but no delivery by this plugin either. A return value of <= 0 for a 
 			 * deliver plugin is is considered a failure. In deliver itself, saved_mail and 
@@ -769,8 +773,8 @@ static int lda_sieve_deliver_mail
 			/* Run the script(s) */
 
 			ret = lda_sieve_run
-				(mdctx, user_script, default_script, &scripts_before, &scripts_after, 
-					storage_r);
+				(mdctx, svinst, user_script, default_script, &scripts_before,
+					&scripts_after, storage_r);
 		}
 
 	} T_END;
diff --git a/src/sieve-tools/sieve-test.c b/src/sieve-tools/sieve-test.c
index 87739e0ad..fdf8a8975 100644
--- a/src/sieve-tools/sieve-test.c
+++ b/src/sieve-tools/sieve-test.c
@@ -207,7 +207,7 @@ int main(int argc, char **argv)
 	(void) sieve_extension_register(svinst, &debug_extension, TRUE);
 
 	/* Create error handler */
-	ehandler = sieve_stderr_ehandler_create(0);
+	ehandler = sieve_stderr_ehandler_create(svinst, 0);
 	sieve_system_ehandler_set(ehandler);
 	sieve_error_handler_accept_infolog(ehandler, TRUE);
 
@@ -225,7 +225,7 @@ int main(int argc, char **argv)
 	} else {
 		/* Dump script */
 		sieve_tool_dump_binary_to(main_sbin, dumpfile);
-	
+
 		/* Obtain mail namespaces from -l argument */
 		if ( mailloc != NULL ) {
 			sieve_tool_init_mail_user(sieve_tool, mailloc);
@@ -380,12 +380,11 @@ int main(int argc, char **argv)
 		if ( main_sbin != NULL ) 
 			sieve_close(&main_sbin);
 	}
-	
+
 	/* Cleanup error handler */
 	sieve_error_handler_unref(&ehandler);
-	sieve_system_ehandler_reset();
 
 	sieve_tool_deinit(&sieve_tool);
-	
+
 	return exit_status;
 }
diff --git a/src/testsuite/cmd-test-binary.c b/src/testsuite/cmd-test-binary.c
index 7bb076ca3..349b9f295 100644
--- a/src/testsuite/cmd-test-binary.c
+++ b/src/testsuite/cmd-test-binary.c
@@ -178,7 +178,8 @@ static int cmd_test_binary_operation_execute
 
 			sieve_binary_unref(&sbin);
 		} else {
-			sieve_sys_error("failed to load binary %s", str_c(binary_name));
+			sieve_sys_error(testsuite_sieve_instance,
+				"failed to load binary %s", str_c(binary_name));
 			return SIEVE_EXEC_FAILURE;
 		}
 
@@ -194,7 +195,8 @@ static int cmd_test_binary_operation_execute
 		if ( sbin != NULL ) 
 			testsuite_binary_save(sbin, str_c(binary_name));
 		else {
-			sieve_sys_error("no compiled binary to save as %s", str_c(binary_name));
+			sieve_sys_error(testsuite_sieve_instance,
+				"no compiled binary to save as %s", str_c(binary_name));
 			return SIEVE_EXEC_FAILURE;
 		}
 	} else {
diff --git a/src/testsuite/testsuite-log.c b/src/testsuite/testsuite-log.c
index b43a30de9..d713d49c8 100644
--- a/src/testsuite/testsuite-log.c
+++ b/src/testsuite/testsuite-log.c
@@ -9,6 +9,7 @@
 #include "sieve-stringlist.h"
 #include "sieve-error-private.h"
 
+#include "testsuite-common.h"
 #include "testsuite-log.h"
 
 /*
@@ -40,8 +41,7 @@ static void _testsuite_log_verror
 	pool_t pool = _testsuite_logmsg_pool;
 	struct _testsuite_log_message msg;
 
-	if ( _testsuite_log_stdout ) 	
-	{
+	if ( _testsuite_log_stdout ) {
 		va_list args_copy;
 		VA_COPY(args_copy, args);
 
@@ -52,7 +52,7 @@ static void _testsuite_log_verror
 			fprintf(stdout,
 				"LOG: error: %s: %s.\n", location, t_strdup_vprintf(fmt, args_copy));
 	}
-	
+
 	msg.location = p_strdup(pool, location);
 	msg.message = p_strdup_vprintf(pool, fmt, args);
 
@@ -78,8 +78,7 @@ static void _testsuite_log_vwarning
 	pool_t pool = _testsuite_logmsg_pool;
 	struct _testsuite_log_message msg;
 
-	if ( _testsuite_log_stdout ) 	
-	{
+	if ( _testsuite_log_stdout ) {
 		va_list args_copy;
 		VA_COPY(args_copy, args);
 
@@ -90,11 +89,11 @@ static void _testsuite_log_vwarning
 			fprintf(stdout,
 				"LOG: warning: %s: %s.\n", location, t_strdup_vprintf(fmt, args_copy));
 	}
-	
+
 	msg.location = p_strdup(pool, location);
 	msg.message = p_strdup_vprintf(pool, fmt, args);
 
-	array_append(&_testsuite_log_warnings, &msg, 1);	
+	array_append(&_testsuite_log_warnings, &msg, 1);
 }
 
 static struct sieve_error_handler *_testsuite_log_ehandler_create(void)
@@ -105,7 +104,7 @@ static struct sieve_error_handler *_testsuite_log_ehandler_create(void)
 	pool = pool_alloconly_create
 		("testsuite_log_ehandler", sizeof(struct sieve_error_handler));
 	ehandler = p_new(pool, struct sieve_error_handler, 1);
-	sieve_error_handler_init(ehandler, pool, 0);
+	sieve_error_handler_init(ehandler, testsuite_sieve_instance, pool, 0);
 
 	ehandler->verror = _testsuite_log_verror;
 	ehandler->vwarning = _testsuite_log_vwarning;
@@ -121,7 +120,7 @@ static struct sieve_error_handler *_testsuite_log_main_ehandler_create(void)
 	pool = pool_alloconly_create
 		("testsuite_log_main_ehandler", sizeof(struct sieve_error_handler));
 	ehandler = p_new(pool, struct sieve_error_handler, 1);
-	sieve_error_handler_init(ehandler, pool, 0);
+	sieve_error_handler_init(ehandler, testsuite_sieve_instance, pool, 0);
 
 	ehandler->verror = _testsuite_log_main_verror;
 	ehandler->vwarning = _testsuite_log_vwarning;
@@ -143,9 +142,9 @@ void testsuite_log_clear_messages(void)
 
 	_testsuite_logmsg_pool = pool_alloconly_create
 		("testsuite_log_messages", 8192);
-	
-	p_array_init(&_testsuite_log_errors, _testsuite_logmsg_pool, 128);	
-	p_array_init(&_testsuite_log_warnings, _testsuite_logmsg_pool, 128);	
+
+	p_array_init(&_testsuite_log_errors, _testsuite_logmsg_pool, 128);
+	p_array_init(&_testsuite_log_warnings, _testsuite_logmsg_pool, 128);
 
 	sieve_error_handler_reset(testsuite_log_ehandler);
 }
@@ -158,10 +157,10 @@ void testsuite_log_init(bool log_stdout)
 {
 	_testsuite_log_stdout = log_stdout;
 
-	testsuite_log_ehandler = _testsuite_log_ehandler_create(); 	
+	testsuite_log_ehandler = _testsuite_log_ehandler_create(); 
 	sieve_error_handler_accept_infolog(testsuite_log_ehandler, TRUE);
 
-	testsuite_log_main_ehandler = _testsuite_log_main_ehandler_create(); 	
+	testsuite_log_main_ehandler = _testsuite_log_main_ehandler_create(); 
 
 	sieve_system_ehandler_set(testsuite_log_ehandler);
 
@@ -170,8 +169,6 @@ void testsuite_log_init(bool log_stdout)
 
 void testsuite_log_deinit(void)
 {
-	sieve_system_ehandler_reset();
-
 	sieve_error_handler_unref(&testsuite_log_ehandler);
 	sieve_error_handler_unref(&testsuite_log_main_ehandler);
 
diff --git a/src/testsuite/testsuite-mailstore.c b/src/testsuite/testsuite-mailstore.c
index c298d0f5e..49d423cda 100644
--- a/src/testsuite/testsuite-mailstore.c
+++ b/src/testsuite/testsuite-mailstore.c
@@ -134,7 +134,8 @@ static struct mail *testsuite_mailstore_open(const char *folder)
 
 	box = mailbox_alloc(ns->list, folder, flags);
 	if ( mailbox_open(box) < 0 ) {
-		sieve_sys_error("testsuite: failed to open mailbox '%s'", folder);
+		sieve_sys_error(testsuite_sieve_instance,
+			"testsuite: failed to open mailbox '%s'", folder);
 		mailbox_free(&box);
 		return NULL;	
 	}
@@ -142,7 +143,8 @@ static struct mail *testsuite_mailstore_open(const char *folder)
 	/* Sync mailbox */
 
 	if ( mailbox_sync(box, MAILBOX_SYNC_FLAG_FULL_READ) < 0 ) {
-		sieve_sys_error("testsuite: failed to sync mailbox '%s'", folder);
+		sieve_sys_error(testsuite_sieve_instance,
+			"testsuite: failed to sync mailbox '%s'", folder);
 		mailbox_free(&box);
 		return NULL;
 	}
-- 
GitLab