From b7f741e76411bf3559e3f66cffc1e06ae1f525f6 Mon Sep 17 00:00:00 2001
From: Stephan Bosch <stephan@rename-it.nl>
Date: Tue, 27 Nov 2007 03:38:49 +0100
Subject: [PATCH] Almost finished implementing the store action. But, I still
 get strange errors when the mail transaction commits. Mail is stored though.

---
 sieve/tests/actions.sieve     |  14 ++---
 src/lib-sieve/sieve-actions.c | 112 ++++++++++++++++++++++++++++++++--
 src/lib-sieve/sieve-actions.h |  16 ++++-
 src/lib-sieve/sieve-result.c  |  22 +++++--
 src/lib-sieve/sieve.h         |   1 +
 src/sieve-bin/Makefile.am     |   6 ++
 src/sieve-bin/mail-raw.c      |  39 +-----------
 src/sieve-bin/mail-raw.h      |   2 +-
 src/sieve-bin/namespaces.c    |  64 +++++++++++++++++++
 src/sieve-bin/namespaces.h    |   7 +++
 src/sieve-bin/sieve-exec.c    |  35 ++++++++++-
 src/sieve-bin/sieve-test.c    |  26 ++++++--
 12 files changed, 281 insertions(+), 63 deletions(-)
 create mode 100644 src/sieve-bin/namespaces.c
 create mode 100644 src/sieve-bin/namespaces.h

diff --git a/sieve/tests/actions.sieve b/sieve/tests/actions.sieve
index 0b3dd6f25..eeb7b7668 100644
--- a/sieve/tests/actions.sieve
+++ b/sieve/tests/actions.sieve
@@ -1,18 +1,18 @@
 require "fileinto";
 
 if address :contains "to" "vestingbar" {
-	redirect "stephan@example.com";
-	fileinto "INBOX.vestingbar";
+#	redirect "stephan@example.com";
+#	fileinto "INBOX.vestingbar";
 	keep;
 } else {
 	discard;
 }
 
-redirect "stephan@rename-it.nl";
-redirect "nico@example.nl";
-redirect "stephan@example.com";
+#redirect "stephan@rename-it.nl";
+#redirect "nico@example.nl";
+#redirect "stephan@example.com";
 
-fileinto "INBOX.frop";
-fileinto "INBOX";
+#fileinto "INBOX.frop";
+#fileinto "INBOX";
 keep;
 discard;
diff --git a/src/lib-sieve/sieve-actions.c b/src/lib-sieve/sieve-actions.c
index a62ce74b6..e20ba4982 100644
--- a/src/lib-sieve/sieve-actions.c
+++ b/src/lib-sieve/sieve-actions.c
@@ -1,3 +1,8 @@
+#include "lib.h"
+#include "str-sanitize.h"
+#include "mail-storage.h"
+#include "mail-namespace.h"
+
 #include "sieve-interpreter.h"
 #include "sieve-result.h"
 #include "sieve-actions.h"
@@ -26,7 +31,7 @@ static bool act_store_commit
 		const struct sieve_action_exec_env *aenv, void *tr_context);
 static void act_store_rollback
 	(const struct sieve_action *action ATTR_UNUSED, 
-		const struct sieve_action_exec_env *aenv, void *tr_context);
+		const struct sieve_action_exec_env *aenv, void *tr_context, bool success);
 		
 const struct sieve_action act_store = {
 	"store",
@@ -79,31 +84,128 @@ static void act_store_print
 
 /* Store transaction */
 
+static void act_store_get_storage_error
+(const struct sieve_action_exec_env *aenv, struct act_store_transaction *trans)
+{
+	enum mail_error error;
+	pool_t pool = sieve_result_pool(aenv->result);
+	
+	trans->error = p_strdup(pool, 
+		mail_storage_get_last_error(trans->namespace->storage, &error));
+}
+
 static bool act_store_start
 (const struct sieve_action *action ATTR_UNUSED, 
 	const struct sieve_action_exec_env *aenv, void *context, void **tr_context)
 {  
+	struct act_store_context *ctx = (struct act_store_context *) context;
+	struct act_store_transaction *trans;
+	struct mail_namespace *ns;
+	struct mailbox *box;
+	pool_t pool;
+
+	ns = mail_namespace_find(aenv->mailenv->namespaces, &ctx->folder);
+	if (ns == NULL) 
+		return FALSE;
+		
+	box = mailbox_open(ns->storage, ctx->folder, NULL, MAILBOX_OPEN_FAST |
+		MAILBOX_OPEN_KEEP_RECENT);
+						
+	pool = sieve_result_pool(aenv->result);
+	trans = p_new(pool, struct act_store_transaction, 1);
+	trans->context = ctx;
+	trans->namespace = ns;
+	trans->box = box;
+	
+	if ( box == NULL ) {
+		printf("Open failed\n");
+		act_store_get_storage_error(aenv, trans);
+	}	
+	
+	*tr_context = (void *)trans;
+
 	return TRUE;
 }
 
 static bool act_store_execute
 (const struct sieve_action *action ATTR_UNUSED, 
 	const struct sieve_action_exec_env *aenv, void *tr_context)
-{  
+{   
+	struct act_store_transaction *trans = 
+		(struct act_store_transaction *) tr_context;
+			
+	if ( trans->box == NULL ) return FALSE;
+	
+	trans->mail_trans = mailbox_transaction_begin
+		(trans->box, MAILBOX_TRANSACTION_FLAG_EXTERNAL);
+
+  if (mailbox_copy(trans->mail_trans, aenv->msgdata->mail, 0, NULL, NULL) < 0) {
+  	printf("Copy failed\n");
+  	act_store_get_storage_error(aenv, trans);
+ 		return FALSE;
+ 	}
+ 		 	
 	return TRUE;
 }
 
+static void act_store_log_status
+(struct act_store_transaction *trans, 
+	const struct sieve_message_data *msgdata, bool rolled_back, bool status )
+{
+	const char *msgid, *mailbox_name;
+	
+	if (mail_get_first_header(msgdata->mail, "Message-ID", &msgid) <= 0)
+		msgid = "";
+	else
+		msgid = str_sanitize(msgid, 80);
+
+	if ( trans->box == NULL )
+		mailbox_name = str_sanitize(trans->context->folder, 80);
+	else
+		mailbox_name = str_sanitize(mailbox_get_name(trans->box), 80);
+
+	if (!rolled_back && status) {
+		i_info("msgid=%s: saved mail to %s", msgid, mailbox_name);
+	} else {
+		const char *errstr;
+		enum mail_error error;
+		
+		if ( trans->error != NULL )
+			errstr = trans->error;
+		else
+			errstr = mail_storage_get_last_error(trans->namespace->storage, &error);
+
+		if ( status )
+			i_info("msgid=%s: save to %s aborted.", msgid, mailbox_name);
+		else
+			i_info("msgid=%s: save failed to %s: %s", msgid, mailbox_name, errstr);
+	}
+}
+
 static bool act_store_commit
 (const struct sieve_action *action ATTR_UNUSED, 
 	const struct sieve_action_exec_env *aenv, void *tr_context)
 {  
-	return TRUE;
+	struct act_store_transaction *trans = 
+		(struct act_store_transaction *) tr_context;
+	bool status = mailbox_transaction_commit(&trans->mail_trans);
+	
+	act_store_log_status(trans, aenv->msgdata, FALSE, status);
+	
+	return status;
 }
 
 static void act_store_rollback
 (const struct sieve_action *action ATTR_UNUSED, 
-	const struct sieve_action_exec_env *aenv, void *tr_context)
-{  
+	const struct sieve_action_exec_env *aenv, void *tr_context, bool success)
+{
+	struct act_store_transaction *trans = 
+		(struct act_store_transaction *) tr_context;
+
+	if ( trans->mail_trans != NULL )
+	  mailbox_transaction_rollback(&trans->mail_trans);
+  
+  act_store_log_status(trans, aenv->msgdata, TRUE, success);
 }
 
 
diff --git a/src/lib-sieve/sieve-actions.h b/src/lib-sieve/sieve-actions.h
index 64b298fea..f7dd0cde9 100644
--- a/src/lib-sieve/sieve-actions.h
+++ b/src/lib-sieve/sieve-actions.h
@@ -1,9 +1,13 @@
 #ifndef __SIEVE_ACTIONS_H
 #define __SIEVE_ACTIONS_H
 
+#include "lib.h"
+#include "mail-storage.h"
+
 #include "sieve-common.h"
 
-struct sieve_action_exec_env {
+struct sieve_action_exec_env { 
+	struct sieve_result *result;
 	const struct sieve_message_data *msgdata;
 	const struct sieve_mail_environment *mailenv;
 };
@@ -34,7 +38,7 @@ struct sieve_action {
 			const struct sieve_action_exec_env *aenv, void *tr_context);
 	void (*rollback)
 		(const struct sieve_action *action, 
-			const struct sieve_action_exec_env *aenv, void *tr_context);
+			const struct sieve_action_exec_env *aenv, void *tr_context, bool success);
 };
 
 /* Actions common to multiple commands */
@@ -45,6 +49,14 @@ struct act_store_context {
 	const char *folder;
 };
 
+struct act_store_transaction {
+	struct act_store_context *context;
+	struct mail_namespace *namespace;
+	struct mailbox *box;
+	struct mailbox_transaction_context *mail_trans;
+	const char *error;
+};
+
 bool sieve_act_store_add_to_result
 	(const struct sieve_runtime_env *renv, const char *folder);
 
diff --git a/src/lib-sieve/sieve-result.c b/src/lib-sieve/sieve-result.c
index e2b4f71bf..66c3e45ad 100644
--- a/src/lib-sieve/sieve-result.c
+++ b/src/lib-sieve/sieve-result.c
@@ -12,6 +12,7 @@ struct sieve_result_action {
 	const struct sieve_action *action;
 	void *context;
 	void *tr_context;
+	bool success;
 	struct sieve_result_action *prev, *next; 
 };
 
@@ -33,6 +34,7 @@ struct sieve_result *sieve_result_create(void)
 	pool = pool_alloconly_create("sieve_result", 4096);	
 	result = p_new(pool, struct sieve_result, 1);
 	result->pool = pool;
+	result->action_env.result = result;
 		
 	result->first_action = NULL;
 	result->last_action = NULL;
@@ -73,7 +75,7 @@ bool sieve_result_add_action
 {
 	struct sieve_result *result = renv->result;
 	struct sieve_result_action *raction;
-	
+		
 	/* First, check for duplicates or conflicts */
 	raction = result->first_action;
 	while ( raction != NULL ) {
@@ -105,6 +107,7 @@ bool sieve_result_add_action
 	raction->action = action;
 	raction->context = context;
 	raction->tr_context = NULL;
+	raction->success = FALSE;
 	
 	/* Add */
 	if ( result->first_action == NULL ) {
@@ -149,6 +152,8 @@ bool sieve_result_execute
 { 
 	bool success = TRUE, commit_ok;
 	struct sieve_result_action *rac;
+	struct sieve_result_action *last_attempted;
+
 	
 	result->action_env.msgdata = msgdata;
 	result->action_env.mailenv = menv;
@@ -162,8 +167,9 @@ bool sieve_result_execute
 		const struct sieve_action *act = rac->action;
 	
 		if ( act->start != NULL ) {
-			success = success && act->start(act, &result->action_env, rac->context, 
+			rac->success = act->start(act, &result->action_env, rac->context, 
 				&rac->tr_context);
+			success = success && rac->success;
 		} 
 		rac = rac->next;	
 	}
@@ -172,7 +178,9 @@ bool sieve_result_execute
 	
 	printf("\nTransaction execute:\n");
 	
-	rac = result->first_action;
+	if ( success )
+		rac = result->first_action;
+	
 	while ( success && rac != NULL ) {
 		const struct sieve_action *act = rac->action;
 	
@@ -180,7 +188,8 @@ bool sieve_result_execute
 			void *context = rac->tr_context == NULL ? 
 				rac->context : rac->tr_context;
 				
-			success = success && act->execute(act, &result->action_env, context);
+			rac->success = act->execute(act, &result->action_env, context);
+			success = success && rac->success;
 		} 
 		rac = rac->next;	
 	}
@@ -192,8 +201,9 @@ bool sieve_result_execute
 		printf("\nTransaction rollback:\n");
 
 	commit_ok = success;
+	last_attempted = rac;
 	rac = result->first_action;
-	while ( rac != NULL ) {
+	while ( rac != NULL && rac != last_attempted ) {
 		const struct sieve_action *act = rac->action;
 		void *context = rac->tr_context == NULL ? 
 				rac->context : rac->tr_context;
@@ -203,7 +213,7 @@ bool sieve_result_execute
 				commit_ok = act->commit(act, &result->action_env, context) && commit_ok;
 		} else {
 			if ( act->rollback != NULL ) 
-				act->rollback(act, &result->action_env, context);
+				act->rollback(act, &result->action_env, context, rac->success);
 		}
 		rac = rac->next;	
 	}
diff --git a/src/lib-sieve/sieve.h b/src/lib-sieve/sieve.h
index ffb807881..97dd8e51a 100644
--- a/src/lib-sieve/sieve.h
+++ b/src/lib-sieve/sieve.h
@@ -16,6 +16,7 @@ struct sieve_message_data {
 
 struct sieve_mail_environment {
 	const char *inbox;
+	struct mail_namespace *namespaces;
 	
 	/* Interface for sending mail (callbacks if you like) */
 	int (*send_rejection)
diff --git a/src/sieve-bin/Makefile.am b/src/sieve-bin/Makefile.am
index daed7c645..c677cdd4d 100644
--- a/src/sieve-bin/Makefile.am
+++ b/src/sieve-bin/Makefile.am
@@ -9,6 +9,8 @@ AM_CPPFLAGS = \
 	-I$(dovecot_incdir)/src/lib-storage \
 	-I$(dovecot_incdir)/src/lib-storage/index \
 	-I$(dovecot_incdir)/src/lib-storage/index/raw \
+	-I$(dovecot_incdir)/src/lib-storage/index/mbox \
+	-I$(dovecot_incdir)/src/lib-storage/index/maildir \
 	-I$(dovecot_incdir)/src/deliver
 
 sievec_LDFLAGS = -export-dynamic -Wl,--start-group 
@@ -19,6 +21,8 @@ libs = \
 	$(top_srcdir)/src/lib-sieve/libsieve.la \
 	$(dovecot_incdir)/src/lib-storage/list/libstorage_list.a \
 	$(dovecot_incdir)/src/lib-storage/index/raw/libstorage_raw.a \
+	$(dovecot_incdir)/src/lib-storage/index/maildir/libstorage_maildir.a \
+	$(dovecot_incdir)/src/lib-storage/index/mbox/libstorage_mbox.a \
     $(dovecot_incdir)/src/lib-storage/index/libstorage_index.a \
     $(dovecot_incdir)/src/lib-storage/libstorage.a \
     $(dovecot_incdir)/src/lib-index/libindex.a \
@@ -43,6 +47,7 @@ sieve_exec_DEPENDENCIES = $(libs)
 
 common_sources = \
 	bin-common.c \
+	namespaces.c \
 	mail-raw.c
 
 sievec_SOURCES = \
@@ -58,4 +63,5 @@ sieve_exec_SOURCES = \
 
 noinst_HEADERS = \
 	bin-common.h \
+	namespaces.h \
 	mail-raw.h
diff --git a/src/sieve-bin/mail-raw.c b/src/sieve-bin/mail-raw.c
index a426eb19c..fb314c156 100644
--- a/src/sieve-bin/mail-raw.c
+++ b/src/sieve-bin/mail-raw.c
@@ -28,20 +28,6 @@
 
 #define DEFAULT_ENVELOPE_SENDER "MAILER-DAEMON"
 
-/* Hideous .... */
-
-extern struct mail_storage raw_storage;
-void mail_storage_register_all(void) {
-	mail_storage_class_register(&raw_storage);
-}
-
-extern struct mailbox_list fs_mailbox_list;
-void index_mailbox_list_init(void);
-void mailbox_list_register_all(void) {
-	mailbox_list_register(&fs_mailbox_list);
-	index_mailbox_list_init();
-}
-
 /* After buffer grows larger than this, create a temporary file to /tmp
    where to read the mail. */
 #define MAIL_MAX_MEMORY_BUFFER (1024*128)
@@ -91,29 +77,11 @@ static struct istream *create_raw_stream(int fd)
 	return input;
 }
 
-static pool_t namespaces_pool;
 static struct mail_namespace *raw_ns;
 
-void mail_raw_init(void) 
+void mail_raw_init(pool_t namespaces_pool, const char *user) 
 {
-	const char *user, *error;
-	struct passwd *pw;
-	uid_t process_euid;
-
-	mail_storage_init();
-	mail_storage_register_all();
-	mailbox_list_register_all();
-
-	process_euid = geteuid();
-	pw = getpwuid(process_euid);
-	if (pw != NULL) {
-		user = t_strdup(pw->pw_name);
- 	} else {
-		i_fatal("Couldn't lookup our username (uid=%s)",
-			dec2str(process_euid));
-    }
-
-	namespaces_pool = pool_alloconly_create("namespaces", 1024);
+	const char *error;
 
 	raw_ns = mail_namespaces_init_empty(namespaces_pool);
 	raw_ns->flags |= NAMESPACE_FLAG_INTERNAL;
@@ -173,8 +141,5 @@ void mail_raw_close(struct mail_raw *mailr)
 void mail_raw_deinit(void)
 {
 	mail_namespaces_deinit(&raw_ns);
-	mail_storage_deinit();
-
-	pool_unref(&namespaces_pool);
 }
 
diff --git a/src/sieve-bin/mail-raw.h b/src/sieve-bin/mail-raw.h
index 3848cc1e4..f54372e8e 100644
--- a/src/sieve-bin/mail-raw.h
+++ b/src/sieve-bin/mail-raw.h
@@ -10,7 +10,7 @@ struct mail_raw {
     struct mailbox_transaction_context *trans;
 };
 
-void mail_raw_init(void);
+void mail_raw_init(pool_t namespaces_pool, const char *user);
 struct mail_raw *mail_raw_open(int fd);
 void mail_raw_close(struct mail_raw *mailr);
 void mail_raw_deinit(void);
diff --git a/src/sieve-bin/namespaces.c b/src/sieve-bin/namespaces.c
new file mode 100644
index 000000000..cc1378953
--- /dev/null
+++ b/src/sieve-bin/namespaces.c
@@ -0,0 +1,64 @@
+/* Copyright (c) 2005-2007 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "istream.h"
+#include "istream-seekable.h"
+#include "fd-set-nonblock.h"
+#include "str.h"
+#include "str-sanitize.h"
+#include "strescape.h"
+#include "message-address.h"
+#include "raw-storage.h"
+#include "mbox-storage.h"
+#include "maildir-storage.h"
+#include "mail-namespace.h"
+
+#include "namespaces.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <pwd.h>
+
+#define DEFAULT_ENVELOPE_SENDER "MAILER-DAEMON"
+
+/* Hideous .... */
+
+extern struct mail_storage raw_storage;
+extern struct mail_storage maildir_storage;
+extern struct mail_storage mbox_storage;
+void mail_storage_register_all(void) {
+	mail_storage_class_register(&raw_storage);
+	mail_storage_class_register(&mbox_storage);
+	mail_storage_class_register(&maildir_storage);
+}
+
+extern struct mailbox_list maildir_mailbox_list;
+extern struct mailbox_list fs_mailbox_list;
+void index_mailbox_list_init(void);
+void mailbox_list_register_all(void) {
+mailbox_list_register(&maildir_mailbox_list);
+mailbox_list_register(&fs_mailbox_list);
+index_mailbox_list_init();
+}
+
+static pool_t namespaces_pool;
+
+pool_t namespaces_init(void) 
+{
+	mail_storage_init();
+	mail_storage_register_all();
+	mailbox_list_register_all();
+
+	namespaces_pool = pool_alloconly_create("namespaces", 1024);
+
+	return namespaces_pool;
+}	
+	
+void namespaces_deinit(void)
+{
+	mail_storage_deinit();
+	pool_unref(&namespaces_pool);
+}
+
diff --git a/src/sieve-bin/namespaces.h b/src/sieve-bin/namespaces.h
new file mode 100644
index 000000000..5f542d3f6
--- /dev/null
+++ b/src/sieve-bin/namespaces.h
@@ -0,0 +1,7 @@
+#ifndef __NAMESPACES_H
+#define __NAMESPACES_H
+
+pool_t namespaces_init(void);
+void namespaces_deinit(void);
+
+#endif /* __MAIL_RAW_H */
diff --git a/src/sieve-bin/sieve-exec.c b/src/sieve-bin/sieve-exec.c
index 1088480bc..b52939b6e 100644
--- a/src/sieve-bin/sieve-exec.c
+++ b/src/sieve-bin/sieve-exec.c
@@ -1,13 +1,20 @@
 /* Copyright (c) 2005-2007 Dovecot authors, see the included COPYING file */
 
 #include "lib.h"
+#include "mail-storage.h"
+#include "mail-namespace.h"
 
 #include "bin-common.h"
 #include "mail-raw.h"
+#include "namespaces.h"
 #include "sieve.h"
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <pwd.h>
+
 
 #define DEFAULT_SENDMAIL_PATH "/usr/lib/sendmail"
 #define DEFAULT_ENVELOPE_SENDER "MAILER-DAEMON"
@@ -31,7 +38,12 @@ static int sieve_send_forward
 
 int main(int argc, char **argv) 
 {
+	const char *user;
+    struct passwd *pw;
+    uid_t process_euid;
 	int sfd, mfd;
+	pool_t namespaces_pool;
+	struct mail_namespace *ns;
 	struct mail_raw *mailr;
 	struct sieve_binary *sbin;
 	struct sieve_message_data msgdata;
@@ -84,8 +96,26 @@ int main(int argc, char **argv)
 
  	close(sfd);
 
-	mail_raw_init();
+    process_euid = geteuid();
+    pw = getpwuid(process_euid);
+    if (pw != NULL) {
+        user = t_strdup(pw->pw_name);
+    } else {
+        i_fatal("Couldn't lookup our username (uid=%s)",
+            dec2str(process_euid));
+    }
+
+	env_put(t_strdup_printf("NAMESPACE_1=%s", "maildir:/home/stephan/Maildir"));
+	env_put("NAMESPACE_1_PREFIX=INBOX.");
+	env_put("NAMESPACE_1_LIST=yes");
+	env_put("NAMESPACE_1_SUBSCRIPTIONS=yes");
+
+	namespaces_pool = namespaces_init();
+	
+	if (mail_namespaces_init(namespaces_pool, user, &ns) < 0)
+        i_fatal("Namespace initialization failed");
 
+	mail_raw_init(namespaces_pool, user);
 	mailr = mail_raw_open(mfd);
 
 	/* Collect necessary message data */
@@ -98,6 +128,7 @@ int main(int argc, char **argv)
 	
 	memset(&mailenv, 0, sizeof(mailenv));
 	mailenv.inbox = "INBOX";
+	mailenv.namespaces = ns;
 	mailenv.send_forward = sieve_send_forward;
 	mailenv.send_rejection = sieve_send_rejection;
 	
@@ -110,6 +141,8 @@ int main(int argc, char **argv)
 	close(mfd);
 
 	mail_raw_deinit();
+	mail_namespaces_deinit(&ns);
+	namespaces_deinit();
 	bin_deinit();  
 	return 0;
 }
diff --git a/src/sieve-bin/sieve-test.c b/src/sieve-bin/sieve-test.c
index fd623c3fc..3a60aaa09 100644
--- a/src/sieve-bin/sieve-test.c
+++ b/src/sieve-bin/sieve-test.c
@@ -4,17 +4,26 @@
 
 #include "bin-common.h"
 #include "mail-raw.h"
+#include "namespaces.h"
 #include "sieve.h"
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <pwd.h>
+
 
 #define DEFAULT_SENDMAIL_PATH "/usr/lib/sendmail"
 #define DEFAULT_ENVELOPE_SENDER "MAILER-DAEMON"
 
 int main(int argc, char **argv) 
 {
+	const char *user;
+    struct passwd *pw;
+    uid_t process_euid;
 	int sfd, mfd;
+	pool_t namespaces_pool;
 	struct mail_raw *mailr;
 	struct sieve_binary *sbin;
 	struct sieve_message_data msgdata;
@@ -64,8 +73,18 @@ int main(int argc, char **argv)
 	(void) sieve_dump(sbin);
 
  	close(sfd);
-
-	mail_raw_init();
+	
+    process_euid = geteuid();
+    pw = getpwuid(process_euid);
+    if (pw != NULL) {
+        user = t_strdup(pw->pw_name);
+    } else {
+        i_fatal("Couldn't lookup our username (uid=%s)",
+            dec2str(process_euid));
+    }
+
+	namespaces_pool = namespaces_init();
+	mail_raw_init(namespaces_pool, user);
 
 	mailr = mail_raw_open(mfd);
 
@@ -79,8 +98,6 @@ int main(int argc, char **argv)
 
 	memset(&mailenv, 0, sizeof(mailenv));
     mailenv.inbox = "INBOX";
-    mailenv.send_forward = NULL;
-    mailenv.send_rejection = NULL;
 	
 	/* Run the test */
 	(void) sieve_test(sbin, &msgdata, &mailenv);
@@ -92,6 +109,7 @@ int main(int argc, char **argv)
 		close(mfd);
 
 	mail_raw_deinit();
+	namespaces_deinit();
 	bin_deinit();  
 	return 0;
 }
-- 
GitLab