[dovecot-cvs] dovecot/src/imap cmd-namespace.c,NONE,1.1 namespace.c,NONE,1.1 namespace.h,NONE,1.1 Makefile.am,1.22,1.23 client.c,1.33,1.34 client.h,1.16,1.17 cmd-append.c,1.28,1.29 cmd-close.c,1.10,1.11 cmd-copy.c,1.11,1.12 cmd-create.c,1.5,1.6 cmd-delete.c,1.4,1.5 cmd-expunge.c,1.4,1.5 cmd-fetch.c,1.17,1.18 cmd-idle.c,1.6,1.7 cmd-list.c,1.26,1.27 cmd-rename.c,1.3,1.4 cmd-search.c,1.16,1.17 cmd-select.c,1.21,1.22 cmd-sort.c,1.11,1.12 cmd-status.c,1.13,1.14 cmd-store.c,1.16,1.17 cmd-subscribe.c,1.5,1.6 cmd-thread.c,1.4,1.5 cmd-unselect.c,1.2,1.3 commands-util.c,1.27,1.28 commands-util.h,1.12,1.13 commands.c,1.11,1.12 commands.h,1.12,1.13 main.c,1.41,1.42

cras at procontrol.fi cras at procontrol.fi
Sun Jul 27 08:48:35 EEST 2003


Update of /home/cvs/dovecot/src/imap
In directory danu:/tmp/cvs-serv12588

Modified Files:
	Makefile.am client.c client.h cmd-append.c cmd-close.c 
	cmd-copy.c cmd-create.c cmd-delete.c cmd-expunge.c cmd-fetch.c 
	cmd-idle.c cmd-list.c cmd-rename.c cmd-search.c cmd-select.c 
	cmd-sort.c cmd-status.c cmd-store.c cmd-subscribe.c 
	cmd-thread.c cmd-unselect.c commands-util.c commands-util.h 
	commands.c commands.h main.c 
Added Files:
	cmd-namespace.c namespace.c namespace.h 
Log Message:
Getting ready for namespaces. LIST is still broken with them.



--- NEW FILE: cmd-namespace.c ---
/* Copyright (C) 2003 Timo Sirainen */

#include "common.h"
#include "str.h"
#include "imap-quote.h"
#include "commands.h"
#include "namespace.h"

static void list_namespaces(struct namespace *ns, enum namespace_type type,
			    string_t *str)
{
	int found = FALSE;

	while (ns != NULL) {
		if (ns->type == type) {
			if (!found) {
				str_append_c(str, '(');
				found = TRUE;
			}
			str_append_c(str, '(');
			imap_quote_append_string(str, ns->prefix, FALSE);
			str_append(str, " \"");
			if (ns->hierarchy_sep == '"' ||
			    ns->hierarchy_sep == '\\')
				str_append_c(str, '\\');
			str_append_c(str, ns->hierarchy_sep);
			str_append(str, "\")");
		}

		ns = ns->next;
	}

	if (found)
		str_append_c(str, ')');
	else
		str_append(str, "NIL");
}

int cmd_namespace(struct client *client)
{
	string_t *str;

	str = t_str_new(256);
	str_append(str, "* NAMESPACE ");

        list_namespaces(client->namespaces, NAMESPACE_PRIVATE, str);
	str_append_c(str, ' ');
	list_namespaces(client->namespaces, NAMESPACE_SHARED, str);
	str_append_c(str, ' ');
        list_namespaces(client->namespaces, NAMESPACE_PUBLIC, str);

	client_send_line(client, str_c(str));
	client_send_tagline(client, "OK Namespace completed.");
	return TRUE;
}

--- NEW FILE: namespace.c ---
/* Copyright (C) 2003 Timo Sirainen */

#include "common.h"
#include "commands.h"
#include "namespace.h"

#include <stdlib.h>

static struct namespace *
namespace_add_env(pool_t pool, const char *data, unsigned int num,
		  const char *user)
{
        struct namespace *ns;
        const char *sep, *type, *prefix;

	ns = p_new(pool, struct namespace, 1);

	sep = getenv(t_strdup_printf("NAMESPACE_%u_SEP", num));
	type = getenv(t_strdup_printf("NAMESPACE_%u_TYPE", num));
	prefix = getenv(t_strdup_printf("NAMESPACE_%u_PREFIX", num));

	if (type == NULL || *type == '\0' || strncmp(type, "private", 7) == 0)
		ns->type = NAMESPACE_PRIVATE;
	else if (strncmp(type, "shared", 6) == 0)
		ns->type = NAMESPACE_SHARED;
	else if (strncmp(type, "public", 6) == 0)
		ns->type = NAMESPACE_PUBLIC;
	else
		i_fatal("Unknown namespace type: %s", type);

	if (prefix == NULL)
		prefix = "";

	ns->prefix = p_strdup(pool, prefix);
	ns->storage = mail_storage_create_with_data(data, user, ns->prefix,
						    sep != NULL ? *sep : '\0');
	if (ns->storage == NULL) {
		i_fatal("Failed to create storage for '%s' with data: %s",
			ns->prefix, data);
	}

	if (hook_mail_storage_created != NULL)
		hook_mail_storage_created(&ns->storage);

	ns->hierarchy_sep = ns->storage->hierarchy_sep;
	return ns;
}

struct namespace *namespace_init(pool_t pool, const char *user)
{
	struct namespace *namespaces, *ns, **ns_p;
	const char *mail, *data;
	unsigned int i;

        namespaces = NULL; ns_p = &namespaces;

	/* first try NAMESPACE_* environments */
	for (i = 1; ; i++) {
		t_push();
		data = getenv(t_strdup_printf("NAMESPACE_%u", i));
		t_pop();

		if (data == NULL)
			break;

		t_push();
		*ns_p = namespace_add_env(pool, data, i, user);
		t_pop();

		ns_p = &(*ns_p)->next;
	}

	if (namespaces != NULL)
		return namespaces;

	/* fallback to MAIL */
	mail = getenv("MAIL");
	if (mail == NULL) {
		/* support also maildir-specific environment */
		mail = getenv("MAILDIR");
		if (mail != NULL)
			mail = t_strconcat("maildir:", mail, NULL);
	}

	ns = p_new(pool, struct namespace, 1);
	ns->storage = mail_storage_create_with_data(mail, user, NULL, '\0');
	if (ns->storage == NULL) {
		if (mail != NULL && *mail != '\0')
			i_fatal("Failed to create storage with data: %s", mail);
		else {
			const char *home;

			home = getenv("HOME");
			if (home == NULL) home = "not set";

			i_fatal("MAIL environment missing and "
				"autodetection failed (home %s)", home);
		}
	}

	ns->type = NAMESPACE_PRIVATE;
	ns->prefix = p_strdup(pool, "");
	ns->hierarchy_sep = ns->storage->hierarchy_sep;
	if (hook_mail_storage_created != NULL)
		hook_mail_storage_created(&ns->storage);

	return ns;
}

void namespace_deinit(struct namespace *namespaces)
{
	while (namespaces != NULL) {
		mail_storage_destroy(namespaces->storage);
		namespaces = namespaces->next;
	}
}

struct namespace *
namespace_find(struct namespace *namespaces, const char *mailbox)
{
	struct namespace *best = NULL;
	size_t len, best_len = 0;
	int inbox;

	inbox = strncasecmp(mailbox, "INBOX", 5) == 0;

	while (namespaces != NULL) {
		len = namespaces->prefix == NULL ? 0 :
			strlen(namespaces->prefix);
		if (len >= best_len &&
		    (strncmp(namespaces->prefix, mailbox, len) == 0 ||
		     (inbox && strncmp(namespaces->prefix, "INBOX", 5) == 0 &&
		      mailbox[5] == namespaces->hierarchy_sep &&
		      namespaces->prefix[5] == namespaces->hierarchy_sep &&
		      strncmp(namespaces->prefix+6, mailbox+6, len-6) == 0))) {
			best = namespaces;
			best_len = len;
		}
		namespaces = namespaces->next;
	}

	return best;
}

--- NEW FILE: namespace.h ---
#ifndef __NAMESPACE_H
#define __NAMESPACE_H

enum namespace_type {
	NAMESPACE_PRIVATE,
	NAMESPACE_SHARED,
	NAMESPACE_PUBLIC
};

struct namespace {
	struct namespace *next;

        enum namespace_type type;
	char hierarchy_sep;
	char *prefix;
	struct mail_storage *storage;
};

struct namespace *namespace_init(pool_t pool, const char *user);
void namespace_deinit(struct namespace *namespaces);

struct namespace *
namespace_find(struct namespace *namespaces, const char *mailbox);

#endif

Index: Makefile.am
===================================================================
RCS file: /home/cvs/dovecot/src/imap/Makefile.am,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -d -r1.22 -r1.23
--- Makefile.am	26 Jul 2003 16:33:21 -0000	1.22
+++ Makefile.am	27 Jul 2003 04:48:32 -0000	1.23
@@ -43,6 +43,7 @@
 	cmd-login.c \
 	cmd-logout.c \
 	cmd-lsub.c \
+	cmd-namespace.c \
 	cmd-noop.c \
 	cmd-rename.c \
 	cmd-search.c \
@@ -69,6 +70,7 @@
 	imap-thread.c \
 	mail-storage-callbacks.c \
 	main.c \
+	namespace.c \
 	rawlog.c
 
 
@@ -82,4 +84,5 @@
 	imap-search.h \
 	imap-sort.h \
 	imap-thread.h \
+	namespace.h \
 	rawlog.h

Index: client.c
===================================================================
RCS file: /home/cvs/dovecot/src/imap/client.c,v
retrieving revision 1.33
retrieving revision 1.34
diff -u -d -r1.33 -r1.34
--- client.c	26 Jul 2003 18:22:44 -0000	1.33
+++ client.c	27 Jul 2003 04:48:32 -0000	1.34
@@ -6,6 +6,7 @@
 #include "istream.h"
 #include "ostream.h"
 #include "commands.h"
+#include "namespace.h"
 
 #include <stdlib.h>
 
@@ -40,7 +41,7 @@
 		"Disconnected for inactivity while waiting for command data.");
 }
 
-struct client *client_create(int hin, int hout, struct mail_storage *storage)
+struct client *client_create(int hin, int hout, struct namespace *namespaces)
 {
 	struct client *client;
 
@@ -65,8 +66,14 @@
 
 	client->mailbox_flags.pool =
 		pool_alloconly_create("mailbox_custom_flags", 512);
-	client->storage = storage;
-	storage->set_callbacks(storage, &mail_storage_callbacks, client);
+	client->namespaces = namespaces;
+
+	while (namespaces != NULL) {
+		namespaces->storage->set_callbacks(namespaces->storage,
+						   &mail_storage_callbacks,
+						   client);
+		namespaces = namespaces->next;
+	}
 
 	i_assert(my_client == NULL);
 	my_client = client;
@@ -82,7 +89,7 @@
 
 	if (client->mailbox != NULL)
 		client->mailbox->close(client->mailbox);
-	mail_storage_destroy(client->storage);
+	namespace_deinit(client->namespaces);
 
 	imap_parser_destroy(client->parser);
 	io_remove(client->io);

Index: client.h
===================================================================
RCS file: /home/cvs/dovecot/src/imap/client.h,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -d -r1.16 -r1.17
--- client.h	23 Jul 2003 01:44:16 -0000	1.16
+++ client.h	27 Jul 2003 04:48:32 -0000	1.17
@@ -21,7 +21,7 @@
 	struct istream *input;
 	struct ostream *output;
 
-	struct mail_storage *storage;
+        struct namespace *namespaces;
 	struct mailbox *mailbox;
         struct mailbox_custom_flags mailbox_flags;
 	unsigned int select_counter; /* increased when mailbox is changed */
@@ -46,7 +46,7 @@
 
 /* Create new client with specified input/output handles. socket specifies
    if the handle is a socket. */
-struct client *client_create(int hin, int hout, struct mail_storage *storage);
+struct client *client_create(int hin, int hout, struct namespace *namespaces);
 void client_destroy(struct client *client);
 
 /* Disconnect client connection */

Index: cmd-append.c
===================================================================
RCS file: /home/cvs/dovecot/src/imap/cmd-append.c,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -d -r1.28 -r1.29
--- cmd-append.c	15 Jul 2003 18:26:42 -0000	1.28
+++ cmd-append.c	27 Jul 2003 04:48:32 -0000	1.29
@@ -45,6 +45,7 @@
 
 int cmd_append(struct client *client)
 {
+	struct mail_storage *storage;
 	struct mailbox *box;
 	struct mailbox_status status;
 	struct mail_save_context *ctx;
@@ -66,16 +67,19 @@
 	if (!client_verify_mailbox_name(client, mailbox, TRUE, FALSE))
 		return TRUE;
 
-	box = client->storage->open_mailbox(client->storage,
-					    mailbox, mailbox_open_flags |
-					    MAILBOX_OPEN_FAST);
+	storage = client_find_storage(client, mailbox);
+	if (storage == NULL)
+		return TRUE;
+
+	box = storage->open_mailbox(storage, mailbox,
+				    mailbox_open_flags | MAILBOX_OPEN_FAST);
 	if (box == NULL) {
-		client_send_storage_error(client);
+		client_send_storage_error(client, storage);
 		return TRUE;
 	}
 
 	if (!box->get_status(box, STATUS_CUSTOM_FLAGS, &status)) {
-		client_send_storage_error(client);
+		client_send_storage_error(client, storage);
 		box->close(box);
 		return TRUE;
 	}
@@ -86,7 +90,7 @@
 
 	ctx = box->save_init(box, TRUE);
 	if (ctx == NULL) {
-		client_send_storage_error(client);
+		client_send_storage_error(client, storage);
 		return TRUE;
 	}
 
@@ -188,7 +192,7 @@
 					client->input->v_offset + msg_size);
 		if (!box->save_next(ctx, &flags, internal_date,
 				    timezone_offset, client->input)) {
-			client_send_storage_error(client);
+			client_send_storage_error(client, storage);
 			break;
 		}
 		i_stream_set_read_limit(client->input, 0);
@@ -202,7 +206,7 @@
 
 	if (!box->save_deinit(ctx, failed)) {
 		failed = TRUE;
-		client_send_storage_error(client);
+		client_send_storage_error(client, storage);
 	}
 
 	box->close(box);

Index: cmd-close.c
===================================================================
RCS file: /home/cvs/dovecot/src/imap/cmd-close.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- cmd-close.c	26 Jul 2003 16:55:11 -0000	1.10
+++ cmd-close.c	27 Jul 2003 04:48:32 -0000	1.11
@@ -14,12 +14,14 @@
 	client->mailbox = NULL;
 
 	if (!mailbox->is_readonly(mailbox)) {
-		if (!imap_expunge(mailbox, FALSE))
-			client_send_untagged_storage_error(client);
+		if (!imap_expunge(mailbox, FALSE)) {
+			client_send_untagged_storage_error(client,
+							   mailbox->storage);
+		}
 	}
 
 	if (!mailbox->close(mailbox))
-                client_send_untagged_storage_error(client);
+                client_send_untagged_storage_error(client, mailbox->storage);
 
 	client_send_tagline(client, "OK Close completed.");
 	return TRUE;

Index: cmd-copy.c
===================================================================
RCS file: /home/cvs/dovecot/src/imap/cmd-copy.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- cmd-copy.c	23 Jul 2003 02:55:12 -0000	1.11
+++ cmd-copy.c	27 Jul 2003 04:48:32 -0000	1.12
@@ -31,6 +31,7 @@
 
 int cmd_copy(struct client *client)
 {
+	struct mail_storage *storage;
 	struct mailbox *destbox;
         struct mail_copy_context *copy_ctx;
 	const char *messageset, *mailbox;
@@ -47,11 +48,14 @@
 	if (!client_verify_mailbox_name(client, mailbox, TRUE, FALSE))
 		return TRUE;
 
-	destbox = client->storage->open_mailbox(client->storage,
-						mailbox, mailbox_open_flags |
-						MAILBOX_OPEN_FAST);
+	storage = client_find_storage(client, mailbox);
+	if (storage == NULL)
+		return TRUE;
+
+	destbox = storage->open_mailbox(storage, mailbox,
+					mailbox_open_flags | MAILBOX_OPEN_FAST);
 	if (destbox == NULL) {
-		client_send_storage_error(client);
+		client_send_storage_error(client, storage);
 		return TRUE;
 	}
 
@@ -78,7 +82,7 @@
 	(void)destbox->lock(destbox, MAILBOX_LOCK_UNLOCK);
 
 	if (failed)
-		client_send_storage_error(client);
+		client_send_storage_error(client, storage);
 	else if (!all_found) {
 		/* some messages were expunged, sync them */
 		client_sync_full(client);

Index: cmd-create.c
===================================================================
RCS file: /home/cvs/dovecot/src/imap/cmd-create.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- cmd-create.c	9 Mar 2003 09:56:05 -0000	1.5
+++ cmd-create.c	27 Jul 2003 04:48:32 -0000	1.6
@@ -5,6 +5,7 @@
 
 int cmd_create(struct client *client)
 {
+	struct mail_storage *storage;
 	const char *mailbox;
 	int only_hiearchy;
 	size_t len;
@@ -13,8 +14,12 @@
 	if (!client_read_string_args(client, 1, &mailbox))
 		return FALSE;
 
+	storage = client_find_storage(client, mailbox);
+	if (storage == NULL)
+		return TRUE;
+
 	len = strlen(mailbox);
-	if (mailbox[len-1] != client->storage->hierarchy_sep)
+	if (mailbox[len-1] != storage->hierarchy_sep)
 		only_hiearchy = FALSE;
 	else {
 		/* name ends with hierarchy separator - client is just
@@ -27,9 +32,8 @@
 	if (!client_verify_mailbox_name(client, mailbox, FALSE, TRUE))
 		return TRUE;
 
-	if (!client->storage->create_mailbox(client->storage, mailbox,
-					     only_hiearchy)) {
-		client_send_storage_error(client);
+	if (!storage->create_mailbox(storage, mailbox, only_hiearchy)) {
+		client_send_storage_error(client, storage);
 		return TRUE;
 	}
 

Index: cmd-delete.c
===================================================================
RCS file: /home/cvs/dovecot/src/imap/cmd-delete.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- cmd-delete.c	22 Apr 2003 18:49:00 -0000	1.4
+++ cmd-delete.c	27 Jul 2003 04:48:32 -0000	1.5
@@ -5,6 +5,7 @@
 
 int cmd_delete(struct client *client)
 {
+	struct mail_storage *storage;
 	struct mailbox *mailbox;
 	const char *name;
 
@@ -21,15 +22,20 @@
 	mailbox = client->mailbox;
 	if (mailbox != NULL && strcmp(mailbox->name, name) == 0) {
 		/* deleting selected mailbox. close it first */
+		storage = mailbox->storage;
 		client->mailbox = NULL;
 
 		if (!mailbox->close(mailbox))
-			client_send_untagged_storage_error(client);
+			client_send_untagged_storage_error(client, storage);
+	} else {
+		storage = client_find_storage(client, name);
+		if (storage == NULL)
+			return TRUE;
 	}
 
-	if (client->storage->delete_mailbox(client->storage, name))
+	if (storage->delete_mailbox(storage, name))
 		client_send_tagline(client, "OK Delete completed.");
 	else
-		client_send_storage_error(client);
+		client_send_storage_error(client, storage);
 	return TRUE;
 }

Index: cmd-expunge.c
===================================================================
RCS file: /home/cvs/dovecot/src/imap/cmd-expunge.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- cmd-expunge.c	26 Jul 2003 16:33:22 -0000	1.4
+++ cmd-expunge.c	27 Jul 2003 04:48:32 -0000	1.5
@@ -12,7 +12,7 @@
 	if (imap_expunge(client->mailbox, TRUE))
 		client_send_tagline(client, "OK Expunge completed.");
 	else
-		client_send_storage_error(client);
+		client_send_storage_error(client, client->mailbox->storage);
 
 	return TRUE;
 }

Index: cmd-fetch.c
===================================================================
RCS file: /home/cvs/dovecot/src/imap/cmd-fetch.c,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -d -r1.17 -r1.18
--- cmd-fetch.c	15 Jun 2003 03:42:28 -0000	1.17
+++ cmd-fetch.c	27 Jul 2003 04:48:32 -0000	1.18
@@ -362,7 +362,7 @@
 		client_send_tagline(client, ret > 0 ? "OK Fetch completed." :
 			"NO Some of the requested messages no longer exist.");
 	} else {
-		client_send_storage_error(client);
+		client_send_storage_error(client, client->mailbox->storage);
 	}
 
 	return TRUE;

Index: cmd-idle.c
===================================================================
RCS file: /home/cvs/dovecot/src/imap/cmd-idle.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- cmd-idle.c	21 Feb 2003 14:28:45 -0000	1.6
+++ cmd-idle.c	27 Jul 2003 04:48:32 -0000	1.7
@@ -86,7 +86,8 @@
 
 	if (!client->mailbox->get_status(client->mailbox, STATUS_MESSAGES,
 					 &status)) {
-		client_send_untagged_storage_error(client);
+		client_send_untagged_storage_error(client,
+						   client->mailbox->storage);
 		idle_finish(client, TRUE);
 	} else {
                 client->idle_expunge = status.messages+1;

Index: cmd-list.c
===================================================================
RCS file: /home/cvs/dovecot/src/imap/cmd-list.c,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -d -r1.26 -r1.27
--- cmd-list.c	26 Jul 2003 23:53:05 -0000	1.26
+++ cmd-list.c	27 Jul 2003 04:48:32 -0000	1.27
@@ -34,21 +34,20 @@
 	return *str == '\0' ? "" : str+1;
 }
 
-static int mailbox_list(struct client *client, const char *mask,
-			const char *sep, const char *reply,
+static int mailbox_list(struct client *client, struct mail_storage *storage,
+			const char *mask, const char *sep, const char *reply,
 			enum mailbox_list_flags list_flags, int listext)
 {
 	struct mailbox_list_context *ctx;
 	struct mailbox_list *list;
 	string_t *str;
 
-	ctx = client->storage->list_mailbox_init(client->storage, mask,
-						 list_flags);
+	ctx = storage->list_mailbox_init(storage, mask, list_flags);
 	if (ctx == NULL)
 		return FALSE;
 
 	str = t_str_new(256);
-	while ((list = client->storage->list_mailbox_next(ctx)) != NULL) {
+	while ((list = storage->list_mailbox_next(ctx)) != NULL) {
 		str_truncate(str, 0);
 		str_printfa(str, "* %s (%s) \"%s\" ", reply,
 			    mailbox_flags2str(list->flags, listext),
@@ -60,7 +59,7 @@
 		client_send_line(client, str_c(str));
 	}
 
-	return client->storage->list_mailbox_deinit(ctx);
+	return storage->list_mailbox_deinit(ctx);
 }
 
 static int parse_list_flags(struct client *client, struct imap_arg *args,
@@ -93,14 +92,19 @@
 
 int _cmd_list_full(struct client *client, int lsub)
 {
+	struct mail_storage *storage;
 	struct imap_arg *args;
         enum mailbox_list_flags list_flags;
 	const char *ref, *mask;
 	char sep_chr, sep[3];
 	int failed, listext;
 
-	sep_chr = client->storage->hierarchy_sep;
-	if (IS_ESCAPED_CHAR(sep_chr)) {
+	storage = client_find_storage(client, "");
+	if (storage == NULL)
+		return TRUE;
+
+	sep_chr = storage->hierarchy_sep;
+	if (sep_chr == '"' || sep_chr == '\\') {
 		sep[0] = '\\';
 		sep[1] = sep_chr;
 		sep[2] = '\0';
@@ -158,13 +162,13 @@
 			}
 		}
 
-		failed = !mailbox_list(client, mask, sep,
+		failed = !mailbox_list(client, storage, mask, sep,
 				       lsub ? "LSUB" : "LIST",
 				       list_flags, listext);
 	}
 
 	if (failed)
-		client_send_storage_error(client);
+		client_send_storage_error(client, storage);
 	else {
 		client_send_tagline(client, lsub ?
 				    "OK Lsub completed." :

Index: cmd-rename.c
===================================================================
RCS file: /home/cvs/dovecot/src/imap/cmd-rename.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- cmd-rename.c	5 Jan 2003 13:09:51 -0000	1.3
+++ cmd-rename.c	27 Jul 2003 04:48:32 -0000	1.4
@@ -5,6 +5,7 @@
 
 int cmd_rename(struct client *client)
 {
+	struct mail_storage *old_storage, *new_storage;
 	const char *oldname, *newname;
 
 	/* <old name> <new name> */
@@ -14,11 +15,24 @@
 	if (!client_verify_mailbox_name(client, newname, FALSE, TRUE))
 		return TRUE;
 
-	if (client->storage->rename_mailbox(client->storage,
-					    oldname, newname))
+	old_storage = client_find_storage(client, oldname);
+	if (old_storage == NULL)
+		return TRUE;
+
+	new_storage = client_find_storage(client, newname);
+	if (new_storage == NULL)
+		return TRUE;
+
+	if (old_storage != new_storage) {
+		client_send_tagline(client,
+			"NO Can't rename mailbox to another namespace.");
+		return TRUE;
+	}
+
+	if (old_storage->rename_mailbox(old_storage, oldname, newname))
 		client_send_tagline(client, "OK Rename completed.");
 	else
-		client_send_storage_error(client);
+		client_send_storage_error(client, old_storage);
 
 	return TRUE;
 }

Index: cmd-search.c
===================================================================
RCS file: /home/cvs/dovecot/src/imap/cmd-search.c,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -d -r1.16 -r1.17
--- cmd-search.c	15 Jun 2003 03:42:28 -0000	1.16
+++ cmd-search.c	27 Jul 2003 04:48:32 -0000	1.17
@@ -97,7 +97,7 @@
 			client_sync_without_expunges(client);
 		client_send_tagline(client, "OK Search completed.");
 	} else {
-		client_send_storage_error(client);
+		client_send_storage_error(client, client->mailbox->storage);
 	}
 
 	pool_unref(pool);

Index: cmd-select.c
===================================================================
RCS file: /home/cvs/dovecot/src/imap/cmd-select.c,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -d -r1.21 -r1.22
--- cmd-select.c	26 Jul 2003 16:55:11 -0000	1.21
+++ cmd-select.c	27 Jul 2003 04:48:32 -0000	1.22
@@ -5,6 +5,7 @@
 
 int _cmd_select_full(struct client *client, int readonly)
 {
+	struct mail_storage *storage;
 	struct mailbox *box;
 	struct mailbox_status status;
 	enum mailbox_open_flags flags;
@@ -17,23 +18,29 @@
 	if (client->mailbox != NULL) {
 		box = client->mailbox;
 		client->mailbox = NULL;
-		if (!box->close(box))
-                        client_send_untagged_storage_error(client);
+		if (!box->close(box)) {
+			client_send_untagged_storage_error(client,
+							   box->storage);
+		}
 	}
 
+	storage = client_find_storage(client, mailbox);
+	if (storage == NULL)
+		return TRUE;
+
 	flags = mailbox_open_flags;
 	if (readonly)
 		flags |= MAILBOX_OPEN_READONLY;
-	box = client->storage->open_mailbox(client->storage, mailbox, flags);
+	box = storage->open_mailbox(storage, mailbox, flags);
 	if (box == NULL) {
-		client_send_storage_error(client);
+		client_send_storage_error(client, storage);
 		return TRUE;
 	}
 
 	if (!box->get_status(box, STATUS_MESSAGES | STATUS_RECENT |
 			     STATUS_FIRST_UNSEEN_SEQ | STATUS_UIDVALIDITY |
 			     STATUS_UIDNEXT | STATUS_CUSTOM_FLAGS, &status)) {
-		client_send_storage_error(client);
+		client_send_storage_error(client, storage);
 		box->close(box);
 		return TRUE;
 	}

Index: cmd-sort.c
===================================================================
RCS file: /home/cvs/dovecot/src/imap/cmd-sort.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- cmd-sort.c	15 Jun 2003 03:42:28 -0000	1.11
+++ cmd-sort.c	27 Jul 2003 04:48:32 -0000	1.12
@@ -128,7 +128,7 @@
 			client_sync_without_expunges(client);
 		client_send_tagline(client, "OK Sort completed.");
 	} else {
-		client_send_storage_error(client);
+		client_send_storage_error(client, client->mailbox->storage);
 	}
 
 	pool_unref(pool);

Index: cmd-status.c
===================================================================
RCS file: /home/cvs/dovecot/src/imap/cmd-status.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- cmd-status.c	15 Jul 2003 18:26:42 -0000	1.13
+++ cmd-status.c	27 Jul 2003 04:48:32 -0000	1.14
@@ -51,7 +51,8 @@
 	return strcasecmp(box1, "INBOX") == 0 && strcasecmp(box2, "INBOX") == 0;
 }
 
-static int get_mailbox_status(struct client *client, const char *mailbox,
+static int get_mailbox_status(struct client *client,
+			      struct mail_storage *storage, const char *mailbox,
 			      enum mailbox_status_items items,
 			      struct mailbox_status *status)
 {
@@ -64,11 +65,10 @@
 		box = client->mailbox;
 	} else {
 		/* open the mailbox */
-		box = client->storage->open_mailbox(client->storage,
-						    mailbox,
-						    mailbox_open_flags |
-						    MAILBOX_OPEN_FAST |
-						    MAILBOX_OPEN_READONLY);
+		box = storage->open_mailbox(storage, mailbox,
+					    mailbox_open_flags |
+					    MAILBOX_OPEN_FAST |
+					    MAILBOX_OPEN_READONLY);
 		if (box == NULL)
 			return FALSE;
 	}
@@ -86,6 +86,7 @@
 	struct imap_arg *args;
 	struct mailbox_status status;
 	enum mailbox_status_items items;
+	struct mail_storage *storage;
 	const char *mailbox;
 	string_t *str;
 
@@ -106,9 +107,13 @@
 		return TRUE;
 	}
 
+	storage = client_find_storage(client, mailbox);
+	if (storage == NULL)
+		return FALSE;
+
 	/* get status */
-	if (!get_mailbox_status(client, mailbox, items, &status)) {
-		client_send_storage_error(client);
+	if (!get_mailbox_status(client, storage, mailbox, items, &status)) {
+		client_send_storage_error(client, storage);
 		return TRUE;
 	}
 

Index: cmd-store.c
===================================================================
RCS file: /home/cvs/dovecot/src/imap/cmd-store.c,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -d -r1.16 -r1.17
--- cmd-store.c	23 Jul 2003 02:55:12 -0000	1.16
+++ cmd-store.c	27 Jul 2003 04:48:32 -0000	1.17
@@ -132,7 +132,7 @@
 		client_send_tagline(client, all_found ? "OK Store completed." :
 				    "NO Some of the messages no longer exist.");
 	} else {
-		client_send_storage_error(client);
+		client_send_storage_error(client, client->mailbox->storage);
 	}
 
 	return TRUE;

Index: cmd-subscribe.c
===================================================================
RCS file: /home/cvs/dovecot/src/imap/cmd-subscribe.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- cmd-subscribe.c	5 Jan 2003 13:09:51 -0000	1.5
+++ cmd-subscribe.c	27 Jul 2003 04:48:32 -0000	1.6
@@ -5,6 +5,7 @@
 
 int _cmd_subscribe_full(struct client *client, int subscribe)
 {
+        struct mail_storage *storage;
 	const char *mailbox;
 
 	/* <mailbox> */
@@ -14,13 +15,16 @@
 	if (!client_verify_mailbox_name(client, mailbox, subscribe, FALSE))
 		return TRUE;
 
-	if (client->storage->set_subscribed(client->storage,
-					    mailbox, subscribe)) {
+	storage = client_find_storage(client, mailbox);
+	if (storage == NULL)
+		return FALSE;
+
+	if (storage->set_subscribed(storage, mailbox, subscribe)) {
 		client_send_tagline(client, subscribe ?
 				    "OK Subscribe completed." :
 				    "OK Unsubscribe completed.");
 	} else {
-		client_send_storage_error(client);
+		client_send_storage_error(client, storage);
 	}
 
 	return TRUE;

Index: cmd-thread.c
===================================================================
RCS file: /home/cvs/dovecot/src/imap/cmd-thread.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- cmd-thread.c	15 Jun 2003 03:42:28 -0000	1.4
+++ cmd-thread.c	27 Jul 2003 04:48:32 -0000	1.5
@@ -70,7 +70,7 @@
 			client_sync_without_expunges(client);
 		client_send_tagline(client, "OK Search completed.");
 	} else {
-		client_send_storage_error(client);
+		client_send_storage_error(client, client->mailbox->storage);
 	}
 
 	pool_unref(pool);

Index: cmd-unselect.c
===================================================================
RCS file: /home/cvs/dovecot/src/imap/cmd-unselect.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- cmd-unselect.c	20 Feb 2003 00:46:17 -0000	1.2
+++ cmd-unselect.c	27 Jul 2003 04:48:32 -0000	1.3
@@ -13,7 +13,7 @@
 	client->mailbox = NULL;
 
 	if (!mailbox->close(mailbox))
-		client_send_untagged_storage_error(client);
+		client_send_untagged_storage_error(client, mailbox->storage);
 
 	client_send_tagline(client, "OK Unselect completed.");
 	return TRUE;

Index: commands-util.c
===================================================================
RCS file: /home/cvs/dovecot/src/imap/commands-util.c,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -d -r1.27 -r1.28
--- commands-util.c	26 Jul 2003 16:55:11 -0000	1.27
+++ commands-util.c	27 Jul 2003 04:48:32 -0000	1.28
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002 Timo Sirainen */
+/* Copyright (C) 2002-2003 Timo Sirainen */
 
 #include "common.h"
 #include "str.h"
@@ -6,6 +6,7 @@
 #include "imap-util.h"
 #include "mail-storage.h"
 #include "imap-parser.h"
+#include "namespace.h"
 
 /* Maximum length for mailbox name, including it's path. This isn't fully
    exact since the user can create folder hierarchy with small names, then
@@ -13,15 +14,33 @@
    to them, mbox/maildir currently allow paths only up to PATH_MAX. */
 #define MAILBOX_MAX_NAME_LEN 512
 
+struct mail_storage *
+client_find_storage(struct client *client, const char *mailbox)
+{
+	struct namespace *ns;
+
+	ns = namespace_find(client->namespaces, mailbox);
+	if (ns != NULL)
+		return ns->storage;
+
+	client_send_tagline(client, "NO Unknown namespace.");
+	return NULL;
+}
+
 int client_verify_mailbox_name(struct client *client, const char *mailbox,
 			       int should_exist, int should_not_exist)
 {
+	struct mail_storage *storage;
 	enum mailbox_name_status mailbox_status;
 	const char *p;
 	char sep;
 
+	storage = client_find_storage(client, mailbox);
+	if (storage == NULL)
+		return FALSE;
+
 	/* make sure it even looks valid */
-	sep = client->storage->hierarchy_sep;
+	sep = storage->hierarchy_sep;
 	if (*mailbox == '\0' || strspn(mailbox, "\r\n*%?") != 0) {
 		client_send_tagline(client, "NO Invalid mailbox name.");
 		return FALSE;
@@ -41,9 +60,9 @@
 	}
 
 	/* check what our storage thinks of it */
-	if (!client->storage->get_mailbox_name_status(client->storage, mailbox,
-						      &mailbox_status)) {
-		client_send_storage_error(client);
+	if (!storage->get_mailbox_name_status(storage, mailbox,
+					      &mailbox_status)) {
+		client_send_storage_error(client, storage);
 		return FALSE;
 	}
 
@@ -93,32 +112,40 @@
 
 void client_sync_full(struct client *client)
 {
-	if (client->mailbox != NULL) {
-		if (!client->mailbox->sync(client->mailbox, 0))
-                        client_send_untagged_storage_error(client);
+	if (client->mailbox == NULL)
+		return;
+
+	if (!client->mailbox->sync(client->mailbox, 0)) {
+		client_send_untagged_storage_error(client,
+						   client->mailbox->storage);
 	}
 }
 
 void client_sync_full_fast(struct client *client)
 {
-	if (client->mailbox != NULL) {
-		if (!client->mailbox->sync(client->mailbox,
-					   MAIL_SYNC_FLAG_FAST))
-                        client_send_untagged_storage_error(client);
+	if (client->mailbox == NULL)
+		return;
+
+	if (!client->mailbox->sync(client->mailbox, MAIL_SYNC_FLAG_FAST)) {
+		client_send_untagged_storage_error(client,
+						   client->mailbox->storage);
 	}
 }
 
 void client_sync_without_expunges(struct client *client)
 {
-	if (client->mailbox != NULL) {
-		if (!client->mailbox->sync(client->mailbox,
-                                           MAIL_SYNC_FLAG_NO_EXPUNGES |
-					   MAIL_SYNC_FLAG_FAST))
-			client_send_untagged_storage_error(client);
+	if (client->mailbox == NULL)
+		return;
+
+	if (!client->mailbox->sync(client->mailbox, MAIL_SYNC_FLAG_NO_EXPUNGES |
+				   MAIL_SYNC_FLAG_FAST)) {
+		client_send_untagged_storage_error(client,
+						   client->mailbox->storage);
 	}
 }
 
-void client_send_storage_error(struct client *client)
+void client_send_storage_error(struct client *client,
+			       struct mail_storage *storage)
 {
 	const char *error;
 	int syntax;
@@ -131,12 +158,13 @@
 		return;
 	}
 
-	error = client->storage->get_last_error(client->storage, &syntax);
+	error = storage->get_last_error(storage, &syntax);
 	client_send_tagline(client, t_strconcat(syntax ? "BAD " : "NO ",
 						error, NULL));
 }
 
-void client_send_untagged_storage_error(struct client *client)
+void client_send_untagged_storage_error(struct client *client,
+					struct mail_storage *storage)
 {
 	const char *error;
 	int syntax;
@@ -149,7 +177,7 @@
 		return;
 	}
 
-	error = client->storage->get_last_error(client->storage, &syntax);
+	error = storage->get_last_error(storage, &syntax);
 	client_send_line(client,
 			 t_strconcat(syntax ? "* BAD " : "* NO ", error, NULL));
 }

Index: commands-util.h
===================================================================
RCS file: /home/cvs/dovecot/src/imap/commands-util.h,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -r1.12 -r1.13
--- commands-util.h	15 Jun 2003 03:42:28 -0000	1.12
+++ commands-util.h	27 Jul 2003 04:48:32 -0000	1.13
@@ -3,6 +3,11 @@
 
 struct mail_full_flags;
 
+/* Finds mail storage for given mailbox from namespaces. If not found,
+   sends "Unknown namespace" error message to client. */
+struct mail_storage *
+client_find_storage(struct client *client, const char *mailbox);
+
 /* If should_exist is TRUE, this function returns TRUE if the mailbox
    exists. If it doesn't exist but would be a valid mailbox name, the
    error message is prefixed with [TRYCREATE].
@@ -27,10 +32,12 @@
 void client_sync_without_expunges(struct client *client);
 
 /* Send last mail storage error message to client. */
-void client_send_storage_error(struct client *client);
+void client_send_storage_error(struct client *client,
+			       struct mail_storage *storage);
 
 /* Send untagged error message to client. */
-void client_send_untagged_storage_error(struct client *client);
+void client_send_untagged_storage_error(struct client *client,
+					struct mail_storage *storage);
 
 /* Parse flags. Returns TRUE if successful, if not sends an error message to
    client. */

Index: commands.c
===================================================================
RCS file: /home/cvs/dovecot/src/imap/commands.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- commands.c	15 May 2003 19:22:22 -0000	1.11
+++ commands.c	27 Jul 2003 04:48:32 -0000	1.12
@@ -43,6 +43,7 @@
 
 const struct command imap_ext_commands[] = {
 	{ "IDLE",		cmd_idle },
+	{ "NAMESPACE",		cmd_namespace },
 	{ "SORT",		cmd_sort },
 	{ "THREAD",		cmd_thread },
 	{ "UID SORT",		cmd_sort },

Index: commands.h
===================================================================
RCS file: /home/cvs/dovecot/src/imap/commands.h,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -r1.12 -r1.13
--- commands.h	14 May 2003 17:23:11 -0000	1.12
+++ commands.h	27 Jul 2003 04:48:32 -0000	1.13
@@ -62,10 +62,11 @@
 int cmd_uid(struct client *client);
 
 /* IMAP extensions: */
+int cmd_idle(struct client *client);
+int cmd_namespace(struct client *client);
 int cmd_sort(struct client *client);
 int cmd_thread(struct client *client);
 int cmd_unselect(struct client *client);
-int cmd_idle(struct client *client);
 
 /* private: */
 int _cmd_list_full(struct client *client, int lsub);

Index: main.c
===================================================================
RCS file: /home/cvs/dovecot/src/imap/main.c,v
retrieving revision 1.41
retrieving revision 1.42
diff -u -d -r1.41 -r1.42
--- main.c	27 Jul 2003 03:12:13 -0000	1.41
+++ main.c	27 Jul 2003 04:48:32 -0000	1.42
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002 Timo Sirainen */
+/* Copyright (C) 2002-2003 Timo Sirainen */
 
 #include "common.h"
 #include "ioloop.h"
@@ -13,6 +13,7 @@
 #include "module-dir.h"
 #include "mail-storage.h"
 #include "commands.h"
+#include "namespace.h"
 
 #include <stdlib.h>
 #include <unistd.h>
@@ -28,6 +29,7 @@
 
 static struct module *modules;
 static char log_prefix[128]; /* syslog() needs this to be permanent */
+static pool_t namespace_pool;
 
 void (*hook_mail_storage_created)(struct mail_storage **storage) = NULL;
 void (*hook_client_created)(struct client **client) = NULL;
@@ -85,8 +87,7 @@
 static void main_init(void)
 {
 	struct client *client;
-	struct mail_storage *storage;
-	const char *user, *mail, *str;
+	const char *user, *str;
 	int hin, hout;
 
 	lib_init_signals(sig_quit);
@@ -113,33 +114,6 @@
 	modules = getenv("MODULE_DIR") == NULL ? NULL :
 		module_dir_load(getenv("MODULE_DIR"));
 
-	mail = getenv("MAIL");
-	if (mail == NULL) {
-		/* support also maildir-specific environment */
-		mail = getenv("MAILDIR");
-		if (mail != NULL)
-			mail = t_strconcat("maildir:", mail, NULL);
-	}
-
-	storage = mail_storage_create_with_data(mail, user, NULL, '\0');
-	if (storage == NULL) {
-		/* failed */
-		if (mail != NULL && *mail != '\0')
-			i_fatal("Failed to create storage with data: %s", mail);
-		else {
-			const char *home;
-
-			home = getenv("HOME");
-			if (home == NULL) home = "not set";
-
-			i_fatal("MAIL environment missing and "
-				"autodetection failed (home %s)", home);
-		}
-	}
-
-	if (hook_mail_storage_created != NULL)
-		hook_mail_storage_created(&storage);
-
 	str = getenv("IMAP_MAX_LINE_LENGTH");
 	imap_max_line_length = str != NULL ?
 		(unsigned int)strtoul(str, NULL, 10) :
@@ -157,7 +131,8 @@
 	mailbox_open_flags = getenv("MMAP_INVALIDATE") != NULL ?
 		MAILBOX_OPEN_MMAP_INVALIDATE : 0;
 
-	client = client_create(hin, hout, storage);
+	namespace_pool = pool_alloconly_create("namespaces", 1024);
+	client = client_create(hin, hout, namespace_init(namespace_pool, user));
 
         o_stream_cork(client->output);
 	if (IS_STANDALONE()) {
@@ -185,6 +160,7 @@
 	clients_deinit();
         mail_storage_deinit();
 	random_deinit();
+	pool_unref(namespace_pool);
 
 	closelog();
 }



More information about the dovecot-cvs mailing list