From e56488197faaf942fdc21db41572513388634d53 Mon Sep 17 00:00:00 2001
From: Stephan Bosch <stephan@rename-it.nl>
Date: Sat, 23 May 2009 13:11:17 +0200
Subject: [PATCH] Migrated Dovecot Sieve to Dovecot v2.0.

---
 .hgignore                                     |   1 +
 src/lib-sieve-tool/Makefile.am                |   2 +
 src/lib-sieve-tool/mail-raw.c                 |  54 +++--
 src/lib-sieve-tool/mail-raw.h                 |   7 +-
 src/lib-sieve-tool/sieve-tool.c               |  41 ++--
 src/lib-sieve-tool/sieve-tool.h               |   2 +-
 src/lib-sieve/Makefile.am                     |   2 +
 src/lib-sieve/cmd-redirect.c                  |  11 +-
 src/lib-sieve/ext-reject.c                    |   7 +-
 src/lib-sieve/plugins/enotify/ntfy-mailto.c   |   8 +-
 src/lib-sieve/plugins/vacation/cmd-vacation.c |  15 +-
 src/lib-sieve/sieve-actions.c                 |  29 +++
 src/lib-sieve/sieve-actions.h                 |  14 +-
 src/lib-sieve/sieve-smtp.c                    |  32 +++
 src/lib-sieve/sieve-smtp.h                    |  20 ++
 src/lib-sieve/sieve-types.h                   |  12 +-
 src/plugins/lda-sieve/Makefile.am             |   3 +-
 src/plugins/lda-sieve/lda-sieve-plugin.c      |  55 +++--
 src/sieve-tools/Makefile.am                   |  40 ++--
 src/sieve-tools/sieve-test.c                  | 215 ++++++++++--------
 src/sieve-tools/sievec.c                      |   2 +-
 src/sieve-tools/sieved.c                      |   2 +-
 src/testsuite/Makefile.am                     |  24 +-
 src/testsuite/testsuite-message.c             |   6 +-
 src/testsuite/testsuite-message.h             |   6 +-
 src/testsuite/testsuite-smtp.c                |   6 +-
 src/testsuite/testsuite-smtp.h                |   6 +-
 src/testsuite/testsuite.c                     | 118 +++++++---
 28 files changed, 486 insertions(+), 254 deletions(-)
 create mode 100644 src/lib-sieve/sieve-smtp.c
 create mode 100644 src/lib-sieve/sieve-smtp.h

diff --git a/.hgignore b/.hgignore
index 724452b3b..87d0fafa5 100644
--- a/.hgignore
+++ b/.hgignore
@@ -47,6 +47,7 @@ Makefile.in
 *.svbin
 **/Makefile
 **/Makefile.in
+**/.libs
 
 src/sieve-tools/sievec
 src/sieve-tools/sieved
diff --git a/src/lib-sieve-tool/Makefile.am b/src/lib-sieve-tool/Makefile.am
index ab965c5a5..575cffd6b 100644
--- a/src/lib-sieve-tool/Makefile.am
+++ b/src/lib-sieve-tool/Makefile.am
@@ -5,6 +5,8 @@ AM_CPPFLAGS = \
 	-I$(dovecot_incdir) \
 	-I$(dovecot_incdir)/src/lib \
 	-I$(dovecot_incdir)/src/lib-mail \
+	-I$(dovecot_incdir)/src/lib-master \
+	-I$(dovecot_incdir)/src/lib-settings \
 	-I$(dovecot_incdir)/src/lib-index \
 	-I$(dovecot_incdir)/src/lib-storage \
 	-I$(dovecot_incdir)/src/lib-storage/index \
diff --git a/src/lib-sieve-tool/mail-raw.c b/src/lib-sieve-tool/mail-raw.c
index 7098eb160..a46bd6fb9 100644
--- a/src/lib-sieve-tool/mail-raw.c
+++ b/src/lib-sieve-tool/mail-raw.c
@@ -17,7 +17,9 @@
 #include "mbox-from.h"
 #include "raw-storage.h"
 #include "mail-namespace.h"
-
+#include "master-service.h"
+#include "master-service-settings.h"
+#include "settings-parser.h"
 #include "mail-raw.h"
 
 #include <stdio.h>
@@ -46,20 +48,23 @@ static const char *wanted_headers[] = {
  */
 
 static struct mail_namespace *raw_ns;
+static struct mail_namespace_settings raw_ns_set;
 static struct mail_user *raw_mail_user;
 
+char *raw_tmp_prefix;
+
 /*
  * Raw mail implementation
  */
 
 static struct istream *create_raw_stream
-	(int fd, time_t *mtime_r, const char **sender)
+(int fd, time_t *mtime_r, const char **sender)
 {
 	struct istream *input, *input2, *input_list[2];
 	const unsigned char *data;
 	size_t i, size;
 	int ret, tz;
-	char *env_sender;
+	char *env_sender = NULL;
 
 	*mtime_r = (time_t)-1;
 	fd_set_nonblock(fd, FALSE);
@@ -85,7 +90,7 @@ static struct istream *create_raw_stream
 		}
 	}
 
-	if (sender != NULL) {
+	if (env_sender != NULL && sender != NULL) {
 		*sender = t_strdup(env_sender);
 	}
 	i_free(env_sender);
@@ -99,8 +104,8 @@ static struct istream *create_raw_stream
 	i_stream_unref(&input);
 
 	input_list[0] = input2; input_list[1] = NULL;
-	input = i_stream_create_seekable(input_list, MAIL_MAX_MEMORY_BUFFER,
-					 "/tmp/dovecot.sieve-tool.");
+	input = i_stream_create_seekable
+		(input_list, MAIL_MAX_MEMORY_BUFFER, raw_tmp_prefix);
 	i_stream_unref(&input2);
 	return input;
 }
@@ -109,28 +114,41 @@ static struct istream *create_raw_stream
  * Init/Deinit
  */
 
-void mail_raw_init(const char *user) 
+void mail_raw_init
+(struct master_service *service, const char *user,
+	struct mail_user *mail_user) 
 {
-	const char *error;
+	const char *errstr;
+	void **sets;
+	
+	sets = master_service_settings_get_others(service);
+
+	raw_mail_user = mail_user_alloc(user, sets[0]); 
+	mail_user_set_home(raw_mail_user, "/");
+   
+	if (mail_user_init(raw_mail_user, &errstr) < 0)
+		i_fatal("Raw user initialization failed: %s", errstr);
+
+	memset(&raw_ns_set, 0, sizeof(raw_ns_set));
+	raw_ns_set.location = "/tmp";
 
-	raw_mail_user = mail_user_init(user);
-	mail_user_set_home(raw_mail_user, NULL);
 	raw_ns = mail_namespaces_init_empty(raw_mail_user);
 	raw_ns->flags |= NAMESPACE_FLAG_INTERNAL;
-	
-	if ( mail_storage_create(raw_ns, "raw", "/tmp",
-		MAIL_STORAGE_FLAG_FULL_FS_ACCESS,
-		FILE_LOCK_METHOD_FCNTL, &error) < 0 ) {
- 		i_fatal("Couldn't create internal raw storage: %s", error);
-	}
+	raw_ns->set = &raw_ns_set;
+    
+	if (mail_storage_create(raw_ns, "raw", 0, &errstr) < 0)
+		i_fatal("Couldn't create internal raw storage: %s", errstr);
+
+	raw_tmp_prefix = i_strdup(mail_user_get_temp_prefix(mail_user));
 }
 
 void mail_raw_deinit(void)
 {
+	i_free(raw_tmp_prefix);
+
 	mail_user_unref(&raw_mail_user);
 }
 
-
 /*
  * Open raw mail data
  */
@@ -175,8 +193,6 @@ static struct mail_raw *mail_raw_create
 	}
 
 	if ( mailbox_sync(mailr->box, 0, 0, NULL ) < 0) {
-		enum mail_error error;
-
 		i_fatal("Can't sync delivery mail: %s",
 			mail_storage_get_last_error(raw_ns->storage, &error));
 	}
diff --git a/src/lib-sieve-tool/mail-raw.h b/src/lib-sieve-tool/mail-raw.h
index 693433720..0f2c23e86 100644
--- a/src/lib-sieve-tool/mail-raw.h
+++ b/src/lib-sieve-tool/mail-raw.h
@@ -4,6 +4,9 @@
 #ifndef __MAIL_RAW_H
 #define __MAIL_RAW_H
 
+#include "lib.h"
+#include "master-service.h"
+
 struct mail_raw {
 	pool_t pool;
 	struct mail *mail;
@@ -13,7 +16,9 @@ struct mail_raw {
 	struct mailbox_transaction_context *trans;
 };
 
-void mail_raw_init(const char *user);
+void mail_raw_init
+(struct master_service *service, const char *user, 
+	struct mail_user *mail_user);
 void mail_raw_deinit(void);
 
 struct mail_raw *mail_raw_open_file(const char *path);
diff --git a/src/lib-sieve-tool/sieve-tool.c b/src/lib-sieve-tool/sieve-tool.c
index e02054593..bb4596fc1 100644
--- a/src/lib-sieve-tool/sieve-tool.c
+++ b/src/lib-sieve-tool/sieve-tool.c
@@ -32,31 +32,38 @@ static void sig_die(const siginfo_t *si, void *context ATTR_UNUSED)
 	/* warn about being killed because of some signal, except SIGINT (^C)
 	 * which is too common at least while testing :) 
 	 */
-        if (si->si_signo != SIGINT) {
-		/* FIMXE: strange error for a command line tool */
+	if (si->si_signo != SIGINT) {
+		/* FIXME: strange error for a command line tool */
 		i_warning("Killed with signal %d (by pid=%s uid=%s code=%s)",
  			si->si_signo, dec2str(si->si_pid),
 			dec2str(si->si_uid),
 			lib_signal_code_to_str(si->si_signo, si->si_code));
-        }
-        io_loop_stop(current_ioloop);
+	}
+	io_loop_stop(current_ioloop);
 }
 
 /*
  * Initialization
  */
 
-void sieve_tool_init(void) 
+/* HACK */
+static bool _init_lib = FALSE;
+
+void sieve_tool_init(bool init_lib) 
 {
-	lib_init();
+	_init_lib = init_lib;
 
-	ioloop = io_loop_create();
+	if ( _init_lib ) {
+		lib_init();
 
-	lib_signals_init();
-	lib_signals_set_handler(SIGINT, TRUE, sig_die, NULL);
-	lib_signals_set_handler(SIGTERM, TRUE, sig_die, NULL);
-	lib_signals_ignore(SIGPIPE, TRUE);
-	lib_signals_ignore(SIGALRM, FALSE);
+		ioloop = io_loop_create();
+
+		lib_signals_init();
+		lib_signals_set_handler(SIGINT, TRUE, sig_die, NULL);
+		lib_signals_set_handler(SIGTERM, TRUE, sig_die, NULL);
+		lib_signals_ignore(SIGPIPE, TRUE);
+		lib_signals_ignore(SIGALRM, FALSE);
+	}
 
 	if ( !sieve_init() ) 
 		i_fatal("failed to initialize sieve implementation\n");
@@ -65,13 +72,17 @@ void sieve_tool_init(void)
 void sieve_tool_deinit(void)
 {
 	sieve_deinit();
+
+	if ( _init_lib ) {
+		lib_signals_deinit();
 	
-	lib_signals_deinit();
+		io_loop_destroy(&ioloop);
 
-	io_loop_destroy(&ioloop);
-	lib_deinit();
+		lib_deinit();
+	}
 }
 
+
 /*
  * Commonly needed functionality
  */
diff --git a/src/lib-sieve-tool/sieve-tool.h b/src/lib-sieve-tool/sieve-tool.h
index fbcef9269..4c7dbd43e 100644
--- a/src/lib-sieve-tool/sieve-tool.h
+++ b/src/lib-sieve-tool/sieve-tool.h
@@ -10,7 +10,7 @@
  * Initialization
  */
 
-void sieve_tool_init(void);
+void sieve_tool_init(bool init_lib);
 void sieve_tool_deinit(void);
 
 /*
diff --git a/src/lib-sieve/Makefile.am b/src/lib-sieve/Makefile.am
index b7c2b210f..366cf2910 100644
--- a/src/lib-sieve/Makefile.am
+++ b/src/lib-sieve/Makefile.am
@@ -64,6 +64,7 @@ libsieve_la_SOURCES = \
 	rfc2822.c \
 	sieve-limits.c \
 	sieve-message.c \
+	sieve-smtp.c \
 	sieve-lexer.c \
 	sieve-script.c \
 	sieve-ast.c \
@@ -100,6 +101,7 @@ noinst_HEADERS = \
 	sieve-common.h \
 	sieve-limits.h \
 	sieve-message.h \
+	sieve-smtp.h \
 	sieve-lexer.h \
 	sieve-script.h \
 	sieve-script-private.h \
diff --git a/src/lib-sieve/cmd-redirect.c b/src/lib-sieve/cmd-redirect.c
index 1efff576c..bbb412aa0 100644
--- a/src/lib-sieve/cmd-redirect.c
+++ b/src/lib-sieve/cmd-redirect.c
@@ -21,6 +21,7 @@
 #include "sieve-interpreter.h"
 #include "sieve-code-dumper.h"
 #include "sieve-result.h"
+#include "sieve-smtp.h"
 
 #include <stdio.h>
 
@@ -292,7 +293,7 @@ static bool act_redirect_send
 	int ret;
 	
 	/* Just to be sure */
-	if ( senv->smtp_open == NULL || senv->smtp_close == NULL ) {
+	if ( !sieve_smtp_available(senv) ) {
 		sieve_result_warning(aenv, "redirect action has no means to send mail.");
 		return TRUE;
 	}
@@ -301,7 +302,7 @@ static bool act_redirect_send
 		return FALSE;
 		
 	/* Open SMTP transport */
-	smtp_handle = senv->smtp_open(ctx->to_address, msgdata->return_path, &f);
+	smtp_handle = sieve_smtp_open(senv, ctx->to_address, msgdata->return_path, &f);
 
 	/* Remove unwanted headers */
 	input = i_stream_create_header_filter
@@ -325,7 +326,7 @@ static bool act_redirect_send
 	i_stream_unref(&input);
 
 	/* Close SMTP transport */
-	if ( !senv->smtp_close(smtp_handle) ) {
+	if ( !sieve_smtp_close(senv, smtp_handle) ) {
 		sieve_result_error(aenv, 
 			"failed to redirect message to <%s> "
 			"(refer to server log for more information)",
@@ -350,7 +351,7 @@ static bool act_redirect_commit
 		NULL : t_strdup_printf("%s-%s", msgdata->id, ctx->to_address);
 	if (dupeid != NULL) {
 		/* Check whether we've seen this message before */
-		if (senv->duplicate_check(dupeid, strlen(dupeid), senv->username)) {
+		if (sieve_action_duplicate_check(senv, dupeid, strlen(dupeid))) {
 			sieve_result_log(aenv, "discarded duplicate forward to <%s>",
 				str_sanitize(ctx->to_address, 128));
 			return TRUE;
@@ -362,7 +363,7 @@ static bool act_redirect_commit
 	
 		/* Mark this message id as forwarded to the specified destination */
 		if (dupeid != NULL) {
-			senv->duplicate_mark(dupeid, strlen(dupeid), senv->username,
+			sieve_action_duplicate_mark(senv, dupeid, strlen(dupeid),
 				ioloop_time + CMD_REDIRECT_DUPLICATE_KEEP);
 		}
 	
diff --git a/src/lib-sieve/ext-reject.c b/src/lib-sieve/ext-reject.c
index 62e351a6e..cbaf09075 100644
--- a/src/lib-sieve/ext-reject.c
+++ b/src/lib-sieve/ext-reject.c
@@ -34,6 +34,7 @@
 #include "sieve-dump.h"
 #include "sieve-result.h"
 #include "sieve-message.h"
+#include "sieve-smtp.h"
 
 /* 
  * Forward declarations 
@@ -329,12 +330,12 @@ static bool act_reject_send
 	int ret;
 
 	/* Just to be sure */
-	if ( senv->smtp_open == NULL || senv->smtp_close == NULL ) {
+	if ( !sieve_smtp_available(senv) ) {
 		sieve_result_warning(aenv, "reject action has no means to send mail");
 		return TRUE;
 	}
 
-	smtp_handle = senv->smtp_open(msgdata->return_path, NULL, &f);
+	smtp_handle = sieve_smtp_open(senv, msgdata->return_path, NULL, &f);
 
 	new_msgid = sieve_message_get_new_id(senv);
 	boundary = t_strdup_printf("%s/%s", my_pid, senv->hostname);
@@ -410,7 +411,7 @@ static bool act_reject_send
 
 	fprintf(f, "\r\n\r\n--%s--\r\n", boundary);
 
-	if ( !senv->smtp_close(smtp_handle) ) {
+	if ( !sieve_smtp_close(senv, smtp_handle) ) {
 		sieve_result_error(aenv, 
 			"failed to send rejection message to <%s> "
 			"(refer to server log for more information)",
diff --git a/src/lib-sieve/plugins/enotify/ntfy-mailto.c b/src/lib-sieve/plugins/enotify/ntfy-mailto.c
index aeb556095..36ed896da 100644
--- a/src/lib-sieve/plugins/enotify/ntfy-mailto.c
+++ b/src/lib-sieve/plugins/enotify/ntfy-mailto.c
@@ -31,6 +31,7 @@
 #include "sieve-ext-enotify.h"
 #include "sieve-address.h"
 #include "sieve-message.h"
+#include "sieve-smtp.h"
 
 /*
  * Configuration
@@ -919,7 +920,7 @@ static bool ntfy_mailto_send
 	}
 
 	/* Just to be sure */
-	if ( senv->smtp_open == NULL || senv->smtp_close == NULL ) {
+	if ( !sieve_smtp_available(senv) ) {
 		sieve_enotify_warning(nlog, 
 			"notify mailto method has no means to send mail");
 		return TRUE;
@@ -985,7 +986,8 @@ static bool ntfy_mailto_send
 		const struct ntfy_mailto_header_field *headers;
 		unsigned int h, hcount;
 
-		smtp_handle = senv->smtp_open(recipients[i].normalized, from_smtp, &f);
+		smtp_handle = sieve_smtp_open
+			(senv, recipients[i].normalized, from_smtp, &f);
 		outmsgid = sieve_message_get_new_id(senv);
 	
 		rfc2822_header_field_write(f, "X-Sieve", SIEVE_IMPLEMENTATION);
@@ -1048,7 +1050,7 @@ static bool ntfy_mailto_send
 			fprintf(f, "Notification of new message.\r\n");
 		}
 	
-		if ( senv->smtp_close(smtp_handle) ) {
+		if ( sieve_smtp_close(senv, smtp_handle) ) {
 			sieve_enotify_log(nlog, 
 				"sent mail notification to <%s>", 
 				str_sanitize(recipients[i].normalized, 80));
diff --git a/src/lib-sieve/plugins/vacation/cmd-vacation.c b/src/lib-sieve/plugins/vacation/cmd-vacation.c
index 3b98abac9..81b5161eb 100644
--- a/src/lib-sieve/plugins/vacation/cmd-vacation.c
+++ b/src/lib-sieve/plugins/vacation/cmd-vacation.c
@@ -25,6 +25,7 @@
 #include "sieve-dump.h"
 #include "sieve-result.h"
 #include "sieve-message.h"
+#include "sieve-smtp.h"
 
 #include "ext-vacation-common.h"
 
@@ -869,14 +870,14 @@ static bool act_vacation_send
 
 	/* Check smpt functions just to be sure */
 
-	if ( senv->smtp_open == NULL || senv->smtp_close == NULL ) {
+	if ( !sieve_smtp_available(senv) ) {
 		sieve_result_warning(aenv, "vacation action has no means to send mail");
 		return TRUE;
 	}
 
 	/* Open smtp session */
 
-	smtp_handle = senv->smtp_open(msgdata->return_path, NULL, &f);
+	smtp_handle = sieve_smtp_open(senv, msgdata->return_path, NULL, &f);
 	outmsgid = sieve_message_get_new_id(senv);
 
 	/* Produce a proper reply */
@@ -929,7 +930,7 @@ static bool act_vacation_send
 	fprintf(f, "%s\r\n", ctx->reason);
 
 	/* Close smtp session */    
-	if ( !senv->smtp_close(smtp_handle) ) {
+	if ( !sieve_smtp_close(senv, smtp_handle) ) {
 		sieve_result_error(aenv, 
 			"failed to send vacation response to <%s> "
 			"(refer to server log for more information)", 
@@ -985,10 +986,10 @@ static bool act_vacation_commit
 	}
 	
 	/* Did whe respond to this user before? */
-	if ( senv->duplicate_check != NULL ) {
+	if ( sieve_action_duplicate_check_available(senv) ) {
 		act_vacation_hash(msgdata, ctx, dupl_hash);
 	
-		if ( senv->duplicate_check(dupl_hash, sizeof(dupl_hash), senv->username) ) 
+		if ( sieve_action_duplicate_check(senv, dupl_hash, sizeof(dupl_hash)) ) 
 		{
 			sieve_result_log(aenv, "discarded duplicate vacation response to <%s>",
 				str_sanitize(msgdata->return_path, 128));
@@ -1103,8 +1104,8 @@ static bool act_vacation_commit
 			str_sanitize(msgdata->return_path, 128));	
 
 		/* Mark as replied */
-		if ( senv->duplicate_mark != NULL )
-			senv->duplicate_mark(dupl_hash, sizeof(dupl_hash), senv->username,
+		sieve_action_duplicate_mark
+			(senv, dupl_hash, sizeof(dupl_hash),
 				ioloop_time + ctx->days * (24 * 60 * 60));
 
 		return TRUE;
diff --git a/src/lib-sieve/sieve-actions.c b/src/lib-sieve/sieve-actions.c
index 2c5d141ce..bcb537427 100644
--- a/src/lib-sieve/sieve-actions.c
+++ b/src/lib-sieve/sieve-actions.c
@@ -457,6 +457,35 @@ static void act_store_rollback
 		mailbox_close(&trans->box);
 }
 
+/*
+ * Action utility functions
+ */
+
+bool sieve_action_duplicate_check_available
+(const struct sieve_script_env *senv)
+{
+	return ( senv->duplicate_check != NULL && senv->duplicate_mark != NULL );
+}
+
+int sieve_action_duplicate_check
+(const struct sieve_script_env *senv, const void *id, size_t id_size)
+{
+	if ( senv->duplicate_check == NULL || senv->duplicate_mark == NULL)
+		return 0;
+
+	return senv->duplicate_check
+		(id, id_size, senv->username); 
+}
 
+void sieve_action_duplicate_mark
+(const struct sieve_script_env *senv, const void *id, size_t id_size,
+	time_t time)
+{
+	if ( senv->duplicate_check == NULL || senv->duplicate_mark == NULL)
+		return;
 
+	senv->duplicate_mark
+		(id, id_size, senv->username, time);
+}
+	
 
diff --git a/src/lib-sieve/sieve-actions.h b/src/lib-sieve/sieve-actions.h
index c088ab58c..ef82f090f 100644
--- a/src/lib-sieve/sieve-actions.h
+++ b/src/lib-sieve/sieve-actions.h
@@ -205,5 +205,17 @@ int sieve_act_store_add_to_result
 	(const struct sieve_runtime_env *renv, 
 		struct sieve_side_effects_list *seffects, const char *folder,
 		unsigned int source_line);
-		
+
+/*		
+ * Action utility functions
+ */
+
+bool sieve_action_duplicate_check_available
+	(const struct sieve_script_env *senv);
+int sieve_action_duplicate_check
+	(const struct sieve_script_env *senv, const void *id, size_t id_size);
+void sieve_action_duplicate_mark
+	(const struct sieve_script_env *senv, const void *id, size_t id_size,
+		time_t time);
+
 #endif /* __SIEVE_ACTIONS_H */
diff --git a/src/lib-sieve/sieve-smtp.c b/src/lib-sieve/sieve-smtp.c
new file mode 100644
index 000000000..073f45dfc
--- /dev/null
+++ b/src/lib-sieve/sieve-smtp.c
@@ -0,0 +1,32 @@
+#include "lib.h"
+
+#include "sieve-common.h"
+#include "sieve-smtp.h"
+
+
+bool sieve_smtp_available
+(const struct sieve_script_env *senv)
+{
+    return ( senv->smtp_open != NULL && senv->smtp_close != NULL );
+}
+
+void *sieve_smtp_open
+(const struct sieve_script_env *senv, const char *destination,
+    const char *return_path, FILE **file_r)
+{
+    if ( senv->smtp_open == NULL || senv->smtp_close == NULL )
+        return NULL;
+
+    return senv->smtp_open
+        (senv->script_context, destination, return_path, file_r);
+}
+
+bool sieve_smtp_close
+(const struct sieve_script_env *senv, void *handle)
+{
+    if ( senv->smtp_open == NULL || senv->smtp_close == NULL )
+        return NULL;
+
+    return senv->smtp_close(senv->script_context, handle);
+}
+
diff --git a/src/lib-sieve/sieve-smtp.h b/src/lib-sieve/sieve-smtp.h
new file mode 100644
index 000000000..283167eda
--- /dev/null
+++ b/src/lib-sieve/sieve-smtp.h
@@ -0,0 +1,20 @@
+/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
+ */
+
+
+#ifndef __SIEVE_SMTP_H
+#define __SIEVE_SMTP_H
+
+#include "sieve-common.h"
+
+bool sieve_smtp_available
+	(const struct sieve_script_env *senv);
+
+void *sieve_smtp_open
+	(const struct sieve_script_env *senv, const char *destination,
+    	const char *return_path, FILE **file_r);
+
+bool sieve_smtp_close
+	(const struct sieve_script_env *senv, void *handle);
+
+#endif /* __SIEVE_SMTP_H */
diff --git a/src/lib-sieve/sieve-types.h b/src/lib-sieve/sieve-types.h
index 28c4abe76..eebeabf4a 100644
--- a/src/lib-sieve/sieve-types.h
+++ b/src/lib-sieve/sieve-types.h
@@ -50,18 +50,24 @@ struct sieve_script_env {
 	const char *hostname;
 	const char *postmaster_address;
 		
+	/* External context data */
+
+	void *script_context;
+
 	/* Callbacks */
 	
 	/* Interface for sending mail */
 	void *(*smtp_open)
-		(const char *destination, const char *return_path, FILE **file_r);
-	bool (*smtp_close)(void *handle);
+		(void *script_ctx, const char *destination, 
+			const char *return_path, FILE **file_r);
+	bool (*smtp_close)(void *script_ctx, void *handle);
 	
 	/* Interface for marking and checking duplicates */
 	int (*duplicate_check)
 		(const void *id, size_t id_size, const char *user);
 	void (*duplicate_mark)
-		(const void *id, size_t id_size, const char *user, time_t time);
+		(const void *id, size_t id_size, const char *user, 
+			time_t time);
 	
 	/* Execution status record */	
 	struct sieve_exec_status *exec_status;
diff --git a/src/plugins/lda-sieve/Makefile.am b/src/plugins/lda-sieve/Makefile.am
index 994aafbe3..1c8a6418c 100644
--- a/src/plugins/lda-sieve/Makefile.am
+++ b/src/plugins/lda-sieve/Makefile.am
@@ -5,7 +5,8 @@ AM_CPPFLAGS = \
 	-I$(dovecot_incdir)/src/lib-dict \
 	-I$(dovecot_incdir)/src/lib-mail \
 	-I$(dovecot_incdir)/src/lib-storage \
-	-I$(dovecot_incdir)/src/deliver
+	-I$(dovecot_incdir)/src/lib-lda \
+	-I$(dovecot_incdir)/src/lda
 
 lda_moduledir = $(moduledir)/lda
 
diff --git a/src/plugins/lda-sieve/lda-sieve-plugin.c b/src/plugins/lda-sieve/lda-sieve-plugin.c
index 565262857..7fdaf8e60 100644
--- a/src/plugins/lda-sieve/lda-sieve-plugin.c
+++ b/src/plugins/lda-sieve/lda-sieve-plugin.c
@@ -4,9 +4,12 @@
 #include "lib.h"
 #include "array.h"
 #include "home-expand.h"
-#include "deliver.h"
+#include "mail-storage.h"
+#include "mail-deliver.h"
+#include "mail-user.h"
 #include "duplicate.h"
 #include "smtp-client.h"
+#include "lda-settings.h"
 
 #include "sieve.h"
 
@@ -37,13 +40,17 @@ static bool lda_sieve_debug = FALSE;
  * Mail transmission
  */
 
-static void *lda_sieve_smtp_open(const char *destination,
+static void *lda_sieve_smtp_open
+(void *script_ctx, const char *destination,
 	const char *return_path, FILE **file_r)
 {
-	return (void *) smtp_client_open(destination, return_path, file_r);
+	return (void *) smtp_client_open
+		((struct mail_deliver_context *) script_ctx, destination, 
+			return_path, file_r);
 }
 
-static bool lda_sieve_smtp_close(void *handle)
+static bool lda_sieve_smtp_close
+(void *script_ctx ATTR_UNUSED, void *handle)
 {
 	struct smtp_client *smtp_client = (struct smtp_client *) handle;
 
@@ -425,10 +432,9 @@ static int lda_sieve_multiscript_execute
 }
 
 static int lda_sieve_run
-(struct mail_namespace *namespaces, struct mail *mail, const char *user_script,
-	const ARRAY_TYPE (const_string) *scripts_before, 
-	const ARRAY_TYPE (const_string) *scripts_after, 
-	const char *destaddr, const char *username, const char *mailbox, 
+(struct mail_deliver_context *mdctx, const char *user_script,
+	const ARRAY_TYPE (const_string) *scripts_before,
+	const ARRAY_TYPE (const_string) *scripts_after,
 	struct mail_storage **storage_r)
 {
 	ARRAY_TYPE (const_string) scripts;
@@ -471,11 +477,11 @@ static int lda_sieve_run
 
 	memset(&msgdata, 0, sizeof(msgdata));
 
-	msgdata.mail = mail;
-	msgdata.return_path = deliver_get_return_address(mail);
-	msgdata.to_address = destaddr;
-	msgdata.auth_user = username;
-	(void)mail_get_first_header(mail, "Message-ID", &msgdata.id);
+	msgdata.mail = mdctx->src_mail;
+	msgdata.return_path = mail_deliver_get_return_address(mdctx);
+    msgdata.to_address = mdctx->dest_addr;
+	msgdata.auth_user = mdctx->dest_user->username;
+	(void)mail_get_first_header(msgdata.mail, "Message-ID", &msgdata.id);
 
 	srctx.msgdata = &msgdata;
 
@@ -483,17 +489,18 @@ static int lda_sieve_run
 
 	memset(&scriptenv, 0, sizeof(scriptenv));
 
-	scriptenv.default_mailbox = mailbox;
-	scriptenv.mailbox_autocreate = deliver_set->mailbox_autocreate;
-	scriptenv.mailbox_autosubscribe = deliver_set->mailbox_autosubscribe;
-	scriptenv.namespaces = namespaces;
-	scriptenv.username = username;
-	scriptenv.hostname = deliver_set->hostname;
-	scriptenv.postmaster_address = deliver_set->postmaster_address;
+	scriptenv.default_mailbox = mdctx->dest_mailbox_name;
+	scriptenv.mailbox_autocreate = mdctx->set->lda_mailbox_autocreate;
+	scriptenv.mailbox_autosubscribe = mdctx->set->lda_mailbox_autosubscribe;
+	scriptenv.namespaces = mdctx->dest_user->namespaces;
+	scriptenv.username = mdctx->dest_user->username;
+	scriptenv.hostname = mdctx->set->hostname;
+	scriptenv.postmaster_address = mdctx->set->postmaster_address;
 	scriptenv.smtp_open = lda_sieve_smtp_open;
 	scriptenv.smtp_close = lda_sieve_smtp_close;
 	scriptenv.duplicate_mark = duplicate_mark;
 	scriptenv.duplicate_check = duplicate_check;
+	scriptenv.script_context = (void *) mdctx;
 	scriptenv.exec_status = &estatus;
 
 	srctx.scriptenv = &scriptenv;
@@ -511,7 +518,7 @@ static int lda_sieve_run
 
 	/* Record status */
 
-	tried_default_save = estatus.tried_default_save;
+	mdctx->tried_default_save = estatus.tried_default_save;
 	*storage_r = estatus.last_storage;
 
 	/* Clean up */
@@ -524,8 +531,7 @@ static int lda_sieve_run
 }
 
 static int lda_sieve_deliver_mail
-(struct mail_namespace *namespaces, struct mail_storage **storage_r, 
-	struct mail *mail, const char *destaddr, const char *mailbox)
+(struct mail_deliver_context *mdctx, struct mail_storage **storage_r)
 {
 	const char *user_script, *sieve_before, *sieve_after;
 	ARRAY_TYPE (const_string) scripts_before;
@@ -593,8 +599,7 @@ static int lda_sieve_deliver_mail
 			/* Run the script(s) */
 				
 			ret = lda_sieve_run
-				(namespaces, mail, user_script, &scripts_before, &scripts_after, destaddr,
-					getenv("USER"), mailbox, storage_r);
+                (mdctx, user_script, &scripts_before, &scripts_after, storage_r);
 		}
 
 	} T_END;
diff --git a/src/sieve-tools/Makefile.am b/src/sieve-tools/Makefile.am
index ead0f8d3d..67f49be0c 100644
--- a/src/sieve-tools/Makefile.am
+++ b/src/sieve-tools/Makefile.am
@@ -2,7 +2,7 @@ pkglibexecdir = $(libexecdir)/dovecot
 
 SUBDIRS = debug
 
-bin_PROGRAMS = sievec sieved sieve-test sieve-filter
+bin_PROGRAMS = sievec sieved sieve-test # sieve-filter
 
 AM_CPPFLAGS = \
 	-I$(top_srcdir)/src/lib-sieve \
@@ -10,39 +10,37 @@ AM_CPPFLAGS = \
 	-I./debug \
 	-I$(dovecot_incdir) \
 	-I$(dovecot_incdir)/src/lib \
+	-I$(dovecot_incdir)/src/lib-settings \
 	-I$(dovecot_incdir)/src/lib-mail \
+	-I$(dovecot_incdir)/src/lib-imap \
 	-I$(dovecot_incdir)/src/lib-index \
+	-I$(dovecot_incdir)/src/lib-master \
 	-I$(dovecot_incdir)/src/lib-storage \
-	-I$(dovecot_incdir)/src/deliver
+	-I$(dovecot_incdir)/src/lib-storage/index \
+	-I$(dovecot_incdir)/src/lib-storage/index/raw
 
 sievec_LDFLAGS = -export-dynamic 
 sieved_LDFLAGS = -export-dynamic 
 sieve_test_LDFLAGS = -export-dynamic
-sieve_filter_LDFLAGS = -export-dynamic
+# sieve_filter_LDFLAGS = -export-dynamic
 
 libs = \
 	$(top_srcdir)/src/lib-sieve/libsieve.la \
 	$(top_srcdir)/src/lib-sieve-tool/libsieve-tool.la \
-	$(dovecot_incdir)/src/lib-storage/list/libstorage_list.a \
-	$(dovecot_incdir)/src/lib-storage/register/libstorage-register.a \
-	./debug/libsieve_ext_debug.la \
-	$(STORAGE_LIBS) 
-
-ldadd = \
-	$(libs) \
- 	$(LIBICONV) \
-	$(RAND_LIBS) \
-	$(MODULE_LIBS)
-
-sievec_LDADD = $(ldadd)
-sieved_LDADD = $(ldadd)
-sieve_test_LDADD = $(ldadd)
-sieve_filter_LDADD = $(ldadd)
+	$(dovecot_incdir)/src/lib-storage/libdovecot-storage.la \
+	$(dovecot_incdir)/src/lib-dovecot/libdovecot.la \
+	./debug/libsieve_ext_debug.la
+
+
+sievec_LDADD = $(libs)
+sieved_LDADD = $(libs)
+sieve_test_LDADD = $(libs)
+# sieve_filter_LDADD = $(libs)
 
 sievec_DEPENDENCIES = $(libs)
 sieved_DEPENDENCIES = $(libs)
 sieve_test_DEPENDENCIES = $(libs)
-sieve_filter_DEPENDENCIES = $(libs)
+# sieve_filter_DEPENDENCIES = $(libs)
 
 sievec_SOURCES = \
 	sievec.c 
@@ -53,7 +51,7 @@ sieved_SOURCES = \
 sieve_test_SOURCES = \
 	sieve-test.c 
 
-sieve_filter_SOURCES = \
-	sieve-filter.c 
+# sieve_filter_SOURCES = \
+# 	sieve-filter.c 
 
 noinst_HEADERS =
diff --git a/src/sieve-tools/sieve-test.c b/src/sieve-tools/sieve-test.c
index 08083d907..98c3d97d3 100644
--- a/src/sieve-tools/sieve-test.c
+++ b/src/sieve-tools/sieve-test.c
@@ -2,11 +2,17 @@
  */
 
 #include "lib.h"
+#include "lib-signals.h"
+#include "ioloop.h"
+#include "env-util.h"
+#include "str.h"
 #include "ostream.h"
 #include "array.h"
 #include "mail-namespace.h"
 #include "mail-storage.h"
-#include "env-util.h"
+#include "master-service.h"
+#include "master-service-settings.h"
+#include "mail-storage-service.h"
 
 #include "sieve.h"
 #include "sieve-binary.h"
@@ -22,6 +28,8 @@
 #include <unistd.h>
 #include <fcntl.h>
 #include <pwd.h>
+#include <sysexits.h>
+
 
 /* 
  * Configuration
@@ -53,7 +61,8 @@ static void print_help(void)
  * Dummy SMTP session
  */
 
-static void *sieve_smtp_open(const char *destination,
+static void *sieve_smtp_open
+(void *script_ctx ATTR_UNUSED, const char *destination,
 	const char *return_path, FILE **file_r)
 {
 	i_info("sending message from <%s> to <%s>:",
@@ -66,7 +75,8 @@ static void *sieve_smtp_open(const char *destination,
 	return NULL;	
 }
 
-static bool sieve_smtp_close(void *handle ATTR_UNUSED)
+static bool sieve_smtp_close
+(void *script_ctx ATTR_UNUSED, void *handle ATTR_UNUSED)
 {
 	printf("END MESSAGE\n\n");
 	return TRUE;
@@ -96,14 +106,17 @@ static void duplicate_mark
 
 int main(int argc, char **argv) 
 {
+	enum mail_storage_service_flags service_flags = 0;
+    struct master_service *service;
+    const char *getopt_str;
+    int c;
 	ARRAY_DEFINE(scriptfiles, const char *);
 	const char *scriptfile, *recipient, *sender, *mailbox, *dumpfile, *mailfile, 
 		*mailloc, *extensions; 
 	const char *user, *home;
-	int i;
 	struct mail_raw *mailr;
+	struct mail_namespace_settings ns_set;
 	struct mail_namespace *ns = NULL;
-	struct mail_user *mail_user = NULL;
 	struct sieve_binary *main_sbin, *sbin = NULL;
 	struct sieve_message_data msgdata;
 	struct sieve_script_env scriptenv;
@@ -114,89 +127,93 @@ int main(int argc, char **argv)
 	bool trace = FALSE;
 	int ret;
 
-	sieve_tool_init();
-	
+	service = master_service_init("sieve-test",
+                      MASTER_SERVICE_FLAG_STANDALONE,
+                      argc, argv);
+
+	sieve_tool_init(FALSE);
+
 	t_array_init(&scriptfiles, 16);
 
+    user = getenv("USER");
+	
 	/* Parse arguments */
 	scriptfile = recipient = sender = mailbox = dumpfile = mailfile = mailloc = 
 		extensions = NULL;
-	for (i = 1; i < argc; i++) {
-		if (strcmp(argv[i], "-r") == 0) {
-			/* recipient address */
-			i++;
-			if (i == argc)
-				i_fatal("Missing -r argument");
-			recipient = argv[i];
-		} else if (strcmp(argv[i], "-f") == 0) {
-			/* envelope sender */
-			i++;
-			if (i == argc)
-				i_fatal("Missing -f argument");
-			sender = argv[i];
-		} else if (strcmp(argv[i], "-m") == 0) {
+	getopt_str = t_strconcat("r:f:m:d:l:x:s:ect",
+                 master_service_getopt_string(), NULL);
+	while ((c = getopt(argc, argv, getopt_str)) > 0) {
+		switch (c) {
+		case 'r':
+			/* destination address */
+			recipient = optarg;
+			break;
+		case 'f':
+			/* envelope sender address */
+			sender = optarg;
+			break;
+		case 'm':
 			/* default mailbox (keep box) */
-			i++;
-			if (i == argc) 
-				i_fatal("Missing -m argument");
-			mailbox = argv[i];
-		} else if (strcmp(argv[i], "-d") == 0) {
+			mailbox = optarg;
+			break;
+		case 'd':
 			/* dump file */
-			i++;
-			if (i == argc)
-				i_fatal("Missing -d argument");
-			dumpfile = argv[i];
-		} else if (strcmp(argv[i], "-l") == 0) {
+			dumpfile = optarg;
+			break;
+        case 'l':
 			/* mail location */
-			i++;
-			if (i == argc)
-				i_fatal("Missing -l argument");
-			mailloc = argv[i];
-		} else if (strcmp(argv[i], "-x") == 0) {
-			/* extensions */
-			i++;
-			if (i == argc)
-				i_fatal("Missing -x argument");
-			extensions = argv[i];
-		} else if (strcmp(argv[i], "-s") == 0) {
-			const char *file;
-			
+			mailloc = optarg;
+			break;
+        case 'x':
+			/* mail location */
+			extensions = optarg;
+			break;
+        case 's': 
 			/* scriptfile executed before main script */
-			i++;
-			if (i == argc)
-				i_fatal("Missing -s argument");
-				
-			file = t_strdup(argv[i]);
-			array_append(&scriptfiles, &file, 1);
-		} else if (strcmp(argv[i], "-c") == 0) {
-			/* force compile */
-			force_compile = TRUE;
-		} else if (strcmp(argv[i], "-e") == 0) {
-			/* execute */
-			execute = TRUE;
-#ifdef SIEVE_RUNTIME_TRACE
-		} else if (strcmp(argv[i], "-t") == 0) {
-			/* runtime trace */
-			trace = TRUE;
-#endif
-		} else if ( scriptfile == NULL ) {
-			scriptfile = argv[i];
-		} else if ( mailfile == NULL ) {
-			mailfile = argv[i];
-		} else {
-			print_help();
-			i_fatal("Unknown argument: %s", argv[i]);
-		}
+			{
+				const char *file;			
+
+				file = t_strdup(optarg);
+				array_append(&scriptfiles, &file, 1);
+			}
+            break;
+
+        case 'e':
+            execute = TRUE;
+            break;
+        case 'c':
+            force_compile = TRUE;
+            break;
+        case 't':
+            trace = TRUE;
+            break;
+        default:
+            if (!master_service_parse_option(service, c, optarg)) {
+                print_help();
+                i_fatal_status(EX_USAGE,
+                           "Unknown argument: %c", c);
+            }
+            break;
+        }
+    }
+
+	if ( optind < argc ) {
+		scriptfile = t_strdup(argv[optind++]);
+	} else { 
+		print_help();
+		i_fatal_status(EX_USAGE, "Missing <scriptfile> argument");
 	}
 	
-	if ( scriptfile == NULL ) {
+	if ( optind < argc ) {
+		mailfile = t_strdup(argv[optind++]);
+	} else { 
 		print_help();
-		i_fatal("Missing <scriptfile> argument");
+		i_fatal_status(EX_USAGE, "Missing <mailfile> argument");
 	}
 	
-	if ( mailfile == NULL ) {
+	if (optind != argc) {
 		print_help();
-		i_fatal("Missing <mailfile> argument");
+		i_fatal_status(EX_USAGE, "Unknown argument: %s", argv[optind]);
 	}
 
 	if ( extensions != NULL ) {
@@ -220,6 +237,10 @@ int main(int argc, char **argv)
 	}
 
 	if ( main_sbin != NULL ) {
+		struct mail_user *mail_user_dovecot = NULL;
+		struct mail_user *mail_user = NULL;
+		struct mail_storage_service_input input;
+
 		/* Dump script */
 		sieve_tool_dump_binary_to(main_sbin, dumpfile);
 	
@@ -227,29 +248,38 @@ int main(int argc, char **argv)
 		home = getenv("HOME");
 
 		/* Initialize mail storages */
-		mail_users_init(getenv("AUTH_SOCKET_PATH"), getenv("DEBUG") != NULL);
-		mail_storage_init();
-		mail_storage_register_all();
-		mailbox_list_register_all();
+		//env_remove("HOME");
+		env_put("DOVECONF_ENV=1");
+		env_put(t_strdup_printf("MAIL=maildir:/tmp/dovecot-test-%s", user));
+
+		memset(&input, 0, sizeof(input));
+		input.username = user;
+		mail_user_dovecot = mail_storage_service_init_user(service, &input,
+                NULL, service_flags);
 	
 		/* Obtain mail namespaces from -l argument */
 		if ( mailloc != NULL ) {
-			env_put(t_strdup_printf("NAMESPACE_1=%s", mailloc));
-			env_put("NAMESPACE_1_INBOX=1");
-			env_put("NAMESPACE_1_LIST=1");
-			env_put("NAMESPACE_1_SEP=.");
-			env_put("NAMESPACE_1_SUBSCRIPTIONS=1");
+			const char *errstr;
 
-			mail_user = mail_user_init(user);
+			mail_user = mail_user_alloc(user, mail_user_dovecot->unexpanded_set);
 			mail_user_set_home(mail_user, home);
-			if (mail_namespaces_init(mail_user) < 0)
-				i_fatal("Namespace initialization failed");	
 
-			ns = mail_user->namespaces;
+			if (mail_user_init(mail_user, &errstr) < 0)
+        		i_fatal("Test user initialization failed: %s", errstr);
+
+			memset(&ns_set, 0, sizeof(ns_set));
+    		ns_set.location = mailloc;
+
+    		ns = mail_namespaces_init_empty(mail_user);
+    		ns->flags |= NAMESPACE_FLAG_INTERNAL;
+    		ns->set = &ns_set;
 		}
 
+		if (master_service_set(service, "mail_full_filesystem_access=yes") < 0)
+			i_unreached(); 
+
 		/* Initialize raw mail object */
-		mail_raw_init(user);
+		mail_raw_init(service, user, mail_user_dovecot);
 		mailr = mail_raw_open_file(mailfile);
 
 		sieve_tool_get_envelope_data(mailr->mail, &recipient, &sender);
@@ -388,13 +418,14 @@ int main(int argc, char **argv)
 		mail_raw_close(mailr);
 		mail_raw_deinit();
 
-		/* De-initialize mail user object */
+		/* De-initialize mail user objects */
 		if ( mail_user != NULL )
 			mail_user_unref(&mail_user);
 
-		/* De-initialize mail storages */
-		mail_storage_deinit();
-		mail_users_deinit();
+		if ( mail_user_dovecot != NULL )
+			mail_user_unref(&mail_user_dovecot);
+	
+		mail_storage_service_deinit_user();
 	}
 
 	/* Cleanup error handler */
@@ -402,6 +433,8 @@ int main(int argc, char **argv)
 	sieve_system_ehandler_reset();
 
 	sieve_tool_deinit();
+
+    master_service_deinit(&service);
 	
 	return 0;
 }
diff --git a/src/sieve-tools/sievec.c b/src/sieve-tools/sievec.c
index 9ba488ec2..b6bf4d1c8 100644
--- a/src/sieve-tools/sievec.c
+++ b/src/sieve-tools/sievec.c
@@ -41,7 +41,7 @@ int main(int argc, char **argv) {
 	bool dump = FALSE;
 	const char *scriptfile, *outfile, *extensions;
 		
-	sieve_tool_init();	
+	sieve_tool_init(TRUE);	
 		
 	scriptfile = outfile = extensions = NULL;
 	for (i = 1; i < argc; i++) {
diff --git a/src/sieve-tools/sieved.c b/src/sieve-tools/sieved.c
index 331667979..61d740275 100644
--- a/src/sieve-tools/sieved.c
+++ b/src/sieve-tools/sieved.c
@@ -38,7 +38,7 @@ int main(int argc, char **argv) {
 	struct sieve_binary *sbin;
 	const char *binfile, *outfile, *extensions;
 	
-	sieve_tool_init();
+	sieve_tool_init(TRUE);
 	
 	binfile = outfile = extensions = NULL;
 	for (i = 1; i < argc; i++) {
diff --git a/src/testsuite/Makefile.am b/src/testsuite/Makefile.am
index 66050b5ab..c8bd6f500 100644
--- a/src/testsuite/Makefile.am
+++ b/src/testsuite/Makefile.am
@@ -1,30 +1,28 @@
 noinst_PROGRAMS = testsuite
 
 AM_CPPFLAGS = \
-	-I../lib-sieve \
-	-I../lib-sieve-tool \
+	-I$(top_srcdir)/src/lib-sieve \
+	-I$(top_srcdir)/src/lib-sieve-tool \
 	-I$(dovecot_incdir) \
 	-I$(dovecot_incdir)/src/lib \
+	-I$(dovecot_incdir)/src/lib-settings \
 	-I$(dovecot_incdir)/src/lib-mail \
+	-I$(dovecot_incdir)/src/lib-imap \
 	-I$(dovecot_incdir)/src/lib-index \
-	-I$(dovecot_incdir)/src/lib-storage
+	-I$(dovecot_incdir)/src/lib-master \
+	-I$(dovecot_incdir)/src/lib-storage \
+	-I$(dovecot_incdir)/src/lib-storage/index \
+	-I$(dovecot_incdir)/src/lib-storage/index/raw
 
 testsuite_LDFLAGS = -export-dynamic
 
 libs = \
 	$(top_srcdir)/src/lib-sieve/libsieve.la \
 	$(top_srcdir)/src/lib-sieve-tool/libsieve-tool.la \
-	$(dovecot_incdir)/src/lib-storage/list/libstorage_list.a \
-	$(dovecot_incdir)/src/lib-storage/register/libstorage-register.a \
-	$(STORAGE_LIBS)
+	$(dovecot_incdir)/src/lib-storage/libdovecot-storage.la \
+	$(dovecot_incdir)/src/lib-dovecot/libdovecot.la
 
-ldadd = \
-	$(libs) \
- 	$(LIBICONV) \
-	$(RAND_LIBS) \
-	$(MODULE_LIBS)
-
-testsuite_LDADD = $(ldadd)
+testsuite_LDADD = $(libs)
 testsuite_DEPENDENCIES = $(libs)
 
 commands = \
diff --git a/src/testsuite/testsuite-message.c b/src/testsuite/testsuite-message.c
index 26a4cad69..9488222dd 100644
--- a/src/testsuite/testsuite-message.c
+++ b/src/testsuite/testsuite-message.c
@@ -4,6 +4,7 @@
 #include "lib.h"
 #include "str.h"
 #include "mail-storage.h"
+#include "master-service.h"
 
 #include "mail-raw.h"
 
@@ -69,7 +70,8 @@ static void _testsuite_message_set_data(struct mail *mail)
 	(void)mail_get_first_header(mail, "Message-ID", &testsuite_msgdata.id);
 }
 
-void testsuite_message_init(const char *user)
+void testsuite_message_init
+(struct master_service *service, const char *user, struct mail_user *mail_user)
 {		
 	message_pool = pool_alloconly_create("testsuite_message", 6096);
 
@@ -77,7 +79,7 @@ void testsuite_message_init(const char *user)
 	str_append(default_message, _default_message_data);
 
 	testsuite_user = user;
-	mail_raw_init(user);
+	mail_raw_init(service, user, mail_user);
 	_raw_message = mail_raw_open_data(default_message);
 	_testsuite_message_set_data(_raw_message->mail);
 
diff --git a/src/testsuite/testsuite-message.h b/src/testsuite/testsuite-message.h
index 526c35389..ca869c75e 100644
--- a/src/testsuite/testsuite-message.h
+++ b/src/testsuite/testsuite-message.h
@@ -4,11 +4,15 @@
 #ifndef __TESTSUITE_MESSAGE_H
 #define __TESTSUITE_MESSAGE_H
 
+#include "lib.h"
+#include "master-service.h"
+
 #include "sieve-common.h"
 
 extern struct sieve_message_data testsuite_msgdata;
 
-void testsuite_message_init(const char *user);
+void testsuite_message_init
+(struct master_service *service, const char *user, struct mail_user *mail_user);
 void testsuite_message_deinit(void);
 
 void testsuite_message_set_string
diff --git a/src/testsuite/testsuite-smtp.c b/src/testsuite/testsuite-smtp.c
index 0f26c62ba..18eff1ca8 100644
--- a/src/testsuite/testsuite-smtp.c
+++ b/src/testsuite/testsuite-smtp.c
@@ -72,7 +72,8 @@ struct testsuite_smtp {
 };
  
 void *testsuite_smtp_open
-	(const char *destination, const char *return_path, FILE **file_r)
+(void *script_ctx ATTR_UNUSED, const char *destination, 
+	const char *return_path, FILE **file_r)
 {	
 	struct testsuite_smtp_message smtp_msg;
 	struct testsuite_smtp *smtp;
@@ -97,7 +98,8 @@ void *testsuite_smtp_open
 	return (void *) smtp;	
 }
 
-bool testsuite_smtp_close(void *handle)
+bool testsuite_smtp_close
+(void *script_ctx ATTR_UNUSED, void *handle)
 {
 	struct testsuite_smtp *smtp = (struct testsuite_smtp *) handle;
 
diff --git a/src/testsuite/testsuite-smtp.h b/src/testsuite/testsuite-smtp.h
index f1e7f38a1..9315c0ec7 100644
--- a/src/testsuite/testsuite-smtp.h
+++ b/src/testsuite/testsuite-smtp.h
@@ -13,8 +13,10 @@ void testsuite_smtp_reset(void);
  */
  
 void *testsuite_smtp_open
-	(const char *destination, const char *return_path, FILE **file_r);
-bool testsuite_smtp_close(void *handle);
+	(void *script_ctx, const char *destination, const char *return_path, 
+		FILE **file_r);
+bool testsuite_smtp_close
+	(void *script_ctx, void *handle);
 
 /*
  * Access
diff --git a/src/testsuite/testsuite.c b/src/testsuite/testsuite.c
index 933399fe1..c923d116f 100644
--- a/src/testsuite/testsuite.c
+++ b/src/testsuite/testsuite.c
@@ -4,11 +4,14 @@
 #include "lib.h"
 #include "lib-signals.h"
 #include "ioloop.h"
+#include "env-util.h"
 #include "ostream.h"
 #include "hostpid.h"
 #include "mail-storage.h"
 #include "mail-namespace.h"
-#include "env-util.h"
+#include "master-service.h"
+#include "master-service-settings.h"
+#include "mail-storage-service.h"
 
 #include "sieve.h"
 #include "sieve-extensions.h"
@@ -30,6 +33,7 @@
 #include <unistd.h>
 #include <fcntl.h>
 #include <pwd.h>
+#include <sysexits.h>
 
 /*
  * Configuration
@@ -44,7 +48,7 @@
 
 static void testsuite_tool_init(void) 
 {
-	sieve_tool_init();
+	sieve_tool_init(FALSE);
 
 	sieve_extensions_set_string(NULL);
 
@@ -99,47 +103,77 @@ static int testsuite_run
 	return ret;
 }
 
+/* IEW.. YUCK.. and so forth.. */
+static const char *_get_cwd(void)
+{
+	static char cwd[PATH_MAX];
+	const char *result;
+
+	result = t_strdup(getcwd(cwd, sizeof(cwd)));
+
+	return result;
+}
+
 int main(int argc, char **argv) 
 {
+	enum mail_storage_service_flags service_flags = 0;
+	struct master_service *service;
+	const char *getopt_str;
+	int c;
 	const char *scriptfile, *dumpfile; 
 	const char *user;
-	int i, ret;
 	struct sieve_binary *sbin;
 	const char *sieve_dir;
 	bool trace = FALSE;
+	int ret;
+
+	service = master_service_init("testsuite",
+                      MASTER_SERVICE_FLAG_STANDALONE,
+                      argc, argv);
+
+	/* Initialize testsuite */
+	testsuite_tool_init();
+
+    user = getenv("USER");
 
 	/* Parse arguments */
 	scriptfile = dumpfile =  NULL;
-	for (i = 1; i < argc; i++) {
-		if (strcmp(argv[i], "-d") == 0) {
-			/* dump file */
-			i++;
-			if (i == argc)
-				i_fatal("Missing -d argument");
-			dumpfile = argv[i];
-#ifdef SIEVE_RUNTIME_TRACE
-		} else if (strcmp(argv[i], "-t") == 0) {
-			/* runtime trace */
+
+	getopt_str = t_strconcat("d:t",
+                 master_service_getopt_string(), NULL);
+	while ((c = getopt(argc, argv, getopt_str)) > 0) {
+		switch (c) {
+		case 'd':
+			/* destination address */
+			dumpfile = optarg;
+			break;
+		case 't':
 			trace = TRUE;
-#endif
-		} else if ( scriptfile == NULL ) {
-			scriptfile = argv[i];
-		} else {
-			print_help();
-			i_fatal("Unknown argument: %s", argv[i]);
+			break;
+		default:
+			if (!master_service_parse_option(service, c, optarg)) {
+				print_help();
+				i_fatal_status(EX_USAGE,
+					"Unknown argument: %c", c);
+			}
+			break;
 		}
 	}
-	
-	if ( scriptfile == NULL ) {
+
+	if ( optind < argc ) {
+		scriptfile = t_strdup(argv[optind++]);
+	} else {
 		print_help();
-		i_fatal("Missing <scriptfile> argument");
+		i_fatal_status(EX_USAGE, "Missing <scriptfile> argument");
 	}
+	
+	if (optind != argc) {
+        print_help();
+        i_fatal_status(EX_USAGE, "Unknown argument: %s", argv[optind]);
+    }
 
 	printf("Test case: %s:\n\n", scriptfile);
 
-	/* Initialize testsuite */
-	testsuite_tool_init();
-
 	/* Initialize environment */
 	sieve_dir = strrchr(scriptfile, '/');
 	if ( sieve_dir == NULL )
@@ -153,21 +187,29 @@ int main(int argc, char **argv)
 	
 	/* Compile sieve script */
 	if ( (sbin = sieve_tool_script_compile(scriptfile, NULL)) != NULL ) {
+	    struct mail_storage_service_input input;
 		struct sieve_script_env scriptenv;
 		struct sieve_error_handler *ehandler;
+		struct mail_user *mail_user;
 
 		/* Dump script */
 		sieve_tool_dump_binary_to(sbin, dumpfile);
 	
-		/* Initialize mail storages */
-		mail_users_init(getenv("AUTH_SOCKET_PATH"), getenv("DEBUG") != NULL);
-		mail_storage_init();
-		mail_storage_register_all();
-		mailbox_list_register_all();
-
-		/* Initialize message environment */
+		/* Initialize mail user */
 		user = sieve_tool_get_user();
-		testsuite_message_init(user);
+		env_put("DOVECONF_ENV=1");
+		env_put(t_strdup_printf("HOME=%s", _get_cwd()));
+		env_put(t_strdup_printf("MAIL=maildir:/tmp/dovecot-test-%s", user));
+
+	    memset(&input, 0, sizeof(input));
+	    input.username = user;
+		mail_user = mail_storage_service_init_user
+			(service, &input, NULL, service_flags);
+
+		if (master_service_set(service, "mail_full_filesystem_access=yes") < 0)
+			i_unreached(); 
+
+		testsuite_message_init(service, user, mail_user);
 
 		memset(&scriptenv, 0, sizeof(scriptenv));
 		scriptenv.default_mailbox = "INBOX";
@@ -204,9 +246,11 @@ int main(int argc, char **argv)
 		/* De-initialize message environment */
 		testsuite_message_deinit();
 
-		/* De-initialize mail storages */
-		mail_storage_deinit();
-		mail_users_deinit();
+		/* De-initialize mail user */
+		if ( mail_user != NULL )
+            mail_user_unref(&mail_user);
+
+        mail_storage_service_deinit_user();
 	} else {
 		testsuite_testcase_fail("failed to compile testcase script");
 	}
@@ -214,5 +258,7 @@ int main(int argc, char **argv)
 	/* De-initialize testsuite */
 	testsuite_tool_deinit();  
 
+	master_service_deinit(&service);
+
 	return testsuite_testcase_result();
 }
-- 
GitLab