dovecot-2.0: Allow namespace prefix to be opened as mailbox, if ...

dovecot at dovecot.org dovecot at dovecot.org
Mon Aug 3 06:22:26 EEST 2009


details:   http://hg.dovecot.org/dovecot-2.0/rev/1ba2a0637719
changeset: 9713:1ba2a0637719
user:      Timo Sirainen <tss at iki.fi>
date:      Sun Aug 02 23:21:43 2009 -0400
description:
Allow namespace prefix to be opened as mailbox, if it already exists.

diffstat:

18 files changed, 130 insertions(+), 98 deletions(-)
src/imap/cmd-append.c                           |    7 --
src/imap/cmd-copy.c                             |    9 +--
src/imap/cmd-create.c                           |   12 +++-
src/imap/cmd-delete.c                           |    3 -
src/imap/cmd-list.c                             |    2 
src/imap/cmd-rename.c                           |   13 +----
src/imap/cmd-select.c                           |    3 -
src/imap/cmd-status.c                           |    3 -
src/imap/cmd-subscribe.c                        |   11 ++--
src/imap/imap-commands-util.c                   |   57 ++++++++++-------------
src/imap/imap-commands-util.h                   |   15 ++----
src/lib-storage/index/maildir/maildir-storage.c |    4 -
src/lib-storage/list/mailbox-list-maildir.c     |    9 ---
src/lib-storage/mail-namespace.c                |   42 ++++++++++++----
src/lib-storage/mailbox-list.c                  |   27 ++++++++++
src/lib-storage/mailbox-list.h                  |    4 +
src/plugins/imap-acl/imap-acl-plugin.c          |    5 +-
src/plugins/imap-quota/imap-quota-plugin.c      |    2 

diffs (truncated from 585 to 300 lines):

diff -r d48c8c0c1d29 -r 1ba2a0637719 src/imap/cmd-append.c
--- a/src/imap/cmd-append.c	Sun Aug 02 13:53:32 2009 -0400
+++ b/src/imap/cmd-append.c	Sun Aug 02 23:21:43 2009 -0400
@@ -455,11 +455,8 @@ get_mailbox(struct client_command_contex
 	struct mail_namespace *ns;
 	struct mailbox *box;
 
-	if (!client_verify_mailbox_name(cmd, name,
-				CLIENT_VERIFY_MAILBOX_SHOULD_EXIST_TRYCREATE))
-		return NULL;
-
-	ns = client_find_namespace(cmd, &name);
+	ns = client_find_namespace(cmd, &name,
+				   CLIENT_VERIFY_MAILBOX_SHOULD_EXIST_TRYCREATE);
 	if (ns == NULL)
 		return NULL;
 
diff -r d48c8c0c1d29 -r 1ba2a0637719 src/imap/cmd-copy.c
--- a/src/imap/cmd-copy.c	Sun Aug 02 13:53:32 2009 -0400
+++ b/src/imap/cmd-copy.c	Sun Aug 02 23:21:43 2009 -0400
@@ -106,16 +106,13 @@ bool cmd_copy(struct client_command_cont
 	if (!client_verify_open_mailbox(cmd))
 		return TRUE;
 
-	/* open the destination mailbox */
-	if (!client_verify_mailbox_name(cmd, mailbox,
-				CLIENT_VERIFY_MAILBOX_SHOULD_EXIST_TRYCREATE))
-		return TRUE;
-
 	ret = imap_search_get_seqset(cmd, messageset, cmd->uid, &search_args);
 	if (ret <= 0)
 		return ret < 0;
 
-	dest_ns = client_find_namespace(cmd, &mailbox);
+	/* open the destination mailbox */
+	dest_ns = client_find_namespace(cmd, &mailbox,
+				CLIENT_VERIFY_MAILBOX_SHOULD_EXIST_TRYCREATE);
 	if (dest_ns == NULL)
 		return TRUE;
 
diff -r d48c8c0c1d29 -r 1ba2a0637719 src/imap/cmd-create.c
--- a/src/imap/cmd-create.c	Sun Aug 02 13:53:32 2009 -0400
+++ b/src/imap/cmd-create.c	Sun Aug 02 23:21:43 2009 -0400
@@ -1,6 +1,7 @@
 /* Copyright (c) 2002-2009 Dovecot authors, see the included COPYING file */
 
 #include "imap-common.h"
+#include "imap-resp-code.h"
 #include "mail-namespace.h"
 #include "imap-commands.h"
 
@@ -17,7 +18,7 @@ bool cmd_create(struct client_command_co
 		return FALSE;
 	full_mailbox = mailbox;
 
-	ns = client_find_namespace(cmd, &mailbox);
+	ns = client_find_namespace(cmd, &mailbox, CLIENT_VERIFY_MAILBOX_NONE);
 	if (ns == NULL)
 		return TRUE;
 
@@ -25,7 +26,8 @@ bool cmd_create(struct client_command_co
 	if (len == 0 || full_mailbox[len-1] != ns->sep)
 		directory = FALSE;
 	else if (*mailbox == '\0') {
-		client_send_tagline(cmd, "NO Namespace already exists.");
+		client_send_tagline(cmd, "NO ["IMAP_RESP_CODE_ALREADYEXISTS
+				    "] Namespace already exists.");
 		return TRUE;
 	} else {
 		/* name ends with hierarchy separator - client is just
@@ -36,8 +38,10 @@ bool cmd_create(struct client_command_co
 		full_mailbox = t_strndup(full_mailbox, len-1);
 	}
 
-	if (!client_verify_mailbox_name(cmd, full_mailbox,
-					CLIENT_VERIFY_MAILBOX_SHOULD_NOT_EXIST))
+	mailbox = full_mailbox;
+	ns = client_find_namespace(cmd, &mailbox,
+				   CLIENT_VERIFY_MAILBOX_SHOULD_NOT_EXIST);
+	if (ns == NULL)
 		return TRUE;
 
 	box = mailbox_alloc(ns->list, mailbox, NULL, 0);
diff -r d48c8c0c1d29 -r 1ba2a0637719 src/imap/cmd-delete.c
--- a/src/imap/cmd-delete.c	Sun Aug 02 13:53:32 2009 -0400
+++ b/src/imap/cmd-delete.c	Sun Aug 02 23:21:43 2009 -0400
@@ -20,7 +20,8 @@ bool cmd_delete(struct client_command_co
 		return TRUE;
 	}
 
-	ns = client_find_namespace(cmd, &name);
+	ns = client_find_namespace(cmd, &name,
+				   CLIENT_VERIFY_MAILBOX_SHOULD_EXIST);
 	if (ns == NULL)
 		return TRUE;
 
diff -r d48c8c0c1d29 -r 1ba2a0637719 src/imap/cmd-list.c
--- a/src/imap/cmd-list.c	Sun Aug 02 13:53:32 2009 -0400
+++ b/src/imap/cmd-list.c	Sun Aug 02 23:21:43 2009 -0400
@@ -269,6 +269,8 @@ list_namespace_send_prefix(struct cmd_li
 
 		ctx->inbox_found = TRUE;
 		flags = list_get_inbox_flags(ctx);
+	} else if (mailbox_list_mailbox(ctx->ns->list, "", &flags) > 0) {
+		/* mailbox with namespace prefix exists */
 	} else {
 		flags = MAILBOX_NONEXISTENT;
 	}
diff -r d48c8c0c1d29 -r 1ba2a0637719 src/imap/cmd-rename.c
--- a/src/imap/cmd-rename.c	Sun Aug 02 13:53:32 2009 -0400
+++ b/src/imap/cmd-rename.c	Sun Aug 02 23:21:43 2009 -0400
@@ -14,18 +14,13 @@ bool cmd_rename(struct client_command_co
 	if (!client_read_string_args(cmd, 2, &oldname, &newname))
 		return FALSE;
 
-	if (!client_verify_mailbox_name(cmd, oldname,
-					CLIENT_VERIFY_MAILBOX_SHOULD_EXIST))
-		return TRUE;
-	if (!client_verify_mailbox_name(cmd, newname,
-					CLIENT_VERIFY_MAILBOX_SHOULD_NOT_EXIST))
-		return TRUE;
-
-	old_ns = client_find_namespace(cmd, &oldname);
+	old_ns = client_find_namespace(cmd, &oldname,
+				       CLIENT_VERIFY_MAILBOX_SHOULD_EXIST);
 	if (old_ns == NULL)
 		return TRUE;
 
-	new_ns = client_find_namespace(cmd, &newname);
+	new_ns = client_find_namespace(cmd, &newname,
+				       CLIENT_VERIFY_MAILBOX_SHOULD_NOT_EXIST);
 	if (new_ns == NULL)
 		return TRUE;
 
diff -r d48c8c0c1d29 -r 1ba2a0637719 src/imap/cmd-select.c
--- a/src/imap/cmd-select.c	Sun Aug 02 13:53:32 2009 -0400
+++ b/src/imap/cmd-select.c	Sun Aug 02 23:21:43 2009 -0400
@@ -357,7 +357,8 @@ bool cmd_select_full(struct client_comma
 
 	ctx = p_new(cmd->pool, struct imap_select_context, 1);
 	ctx->cmd = cmd;
-	ctx->ns = client_find_namespace(cmd, &mailbox);
+	ctx->ns = client_find_namespace(cmd, &mailbox,
+					CLIENT_VERIFY_MAILBOX_SHOULD_EXIST);
 	if (ctx->ns == NULL)
 		return TRUE;
 
diff -r d48c8c0c1d29 -r 1ba2a0637719 src/imap/cmd-status.c
--- a/src/imap/cmd-status.c	Sun Aug 02 13:53:32 2009 -0400
+++ b/src/imap/cmd-status.c	Sun Aug 02 23:21:43 2009 -0400
@@ -31,7 +31,8 @@ bool cmd_status(struct client_command_co
 				    &items) < 0)
 		return TRUE;
 
-	ns = client_find_namespace(cmd, &real_mailbox);
+	ns = client_find_namespace(cmd, &real_mailbox,
+				   CLIENT_VERIFY_MAILBOX_SHOULD_EXIST);
 	if (ns == NULL)
 		return TRUE;
 
diff -r d48c8c0c1d29 -r 1ba2a0637719 src/imap/cmd-subscribe.c
--- a/src/imap/cmd-subscribe.c	Sun Aug 02 13:53:32 2009 -0400
+++ b/src/imap/cmd-subscribe.c	Sun Aug 02 23:21:43 2009 -0400
@@ -37,7 +37,8 @@ bool cmd_subscribe_full(struct client_co
 	verify_name = mailbox;
 
 	real_name = mailbox;
-	real_ns = client_find_namespace(cmd, &real_name);
+	real_ns = client_find_namespace(cmd, &real_name,
+					CLIENT_VERIFY_MAILBOX_NONE);
 	if (real_ns == NULL)
 		return TRUE;
 
@@ -69,12 +70,12 @@ bool cmd_subscribe_full(struct client_co
 					   verify_name)) {
 		/* subscribing to a listable namespace prefix, allow it. */
 	} else if (subscribe) {
-		if (!client_verify_mailbox_name(cmd, verify_name,
-					CLIENT_VERIFY_MAILBOX_SHOULD_EXIST))
+		if (client_find_namespace(cmd, &verify_name,
+				CLIENT_VERIFY_MAILBOX_SHOULD_EXIST) == NULL)
 			return TRUE;
 	} else {
-		if (!client_verify_mailbox_name(cmd, verify_name,
-						CLIENT_VERIFY_MAILBOX_NAME))
+		if (client_find_namespace(cmd, &verify_name,
+				CLIENT_VERIFY_MAILBOX_NAME) == NULL)
 			return TRUE;
 	}
 
diff -r d48c8c0c1d29 -r 1ba2a0637719 src/imap/imap-commands-util.c
--- a/src/imap/imap-commands-util.c	Sun Aug 02 13:53:32 2009 -0400
+++ b/src/imap/imap-commands-util.c	Sun Aug 02 23:21:43 2009 -0400
@@ -20,35 +20,28 @@
 #define MAILBOX_MAX_NAME_LEN 512
 
 struct mail_namespace *
-client_find_namespace(struct client_command_context *cmd, const char **mailbox)
-{
-	struct mail_namespace *ns;
-
-	ns = mail_namespace_find(cmd->client->user->namespaces, mailbox);
-	if (ns != NULL)
-		return ns;
-
-	client_send_tagline(cmd, "NO Unknown namespace.");
-	return NULL;
-}
-
-bool client_verify_mailbox_name(struct client_command_context *cmd,
-				const char *mailbox,
-				enum client_verify_mailbox_mode mode)
+client_find_namespace(struct client_command_context *cmd, const char **mailboxp,
+		      enum client_verify_mailbox_mode mode)
 {
 	struct mail_namespace *ns;
 	enum mailbox_name_status mailbox_status;
-	const char *orig_mailbox, *p, *resp_code = NULL;
-
-	orig_mailbox = mailbox;
-	ns = client_find_namespace(cmd, &mailbox);
-	if (ns == NULL)
-		return FALSE;
+	const char *orig_mailbox, *mailbox, *p, *resp_code = NULL;
+
+	orig_mailbox = *mailboxp;
+	ns = mail_namespace_find(cmd->client->user->namespaces, mailboxp);
+	if (ns == NULL) {
+		client_send_tagline(cmd, "NO Unknown namespace.");
+		return NULL;
+	}
+	mailbox = *mailboxp;
+
+	if (mode == CLIENT_VERIFY_MAILBOX_NONE)
+		return ns;
 
 	/* make sure it even looks valid */
-	if (*mailbox == '\0') {
+	if (*mailbox == '\0' && !(*orig_mailbox != '\0' && ns->list)) {
 		client_send_tagline(cmd, "NO Empty mailbox name.");
-		return FALSE;
+		return NULL;
 	}
 
 	if (ns->real_sep != ns->sep && ns->prefix_len < strlen(orig_mailbox)) {
@@ -61,7 +54,7 @@ bool client_verify_mailbox_name(struct c
 					"NO Character not allowed "
 					"in mailbox name: '%c'",
 					ns->real_sep));
-				return FALSE;
+				return NULL;
 			}
 		}
 	}
@@ -70,36 +63,37 @@ bool client_verify_mailbox_name(struct c
 	for (p = mailbox+1; *p != '\0'; p++) {
 		if (p[0] == ns->real_sep && p[-1] == ns->real_sep) {
 			client_send_tagline(cmd, "NO Invalid mailbox name.");
-			return FALSE;
+			return NULL;
 		}
 	}
 
 	if (strlen(mailbox) > MAILBOX_MAX_NAME_LEN) {
 		client_send_tagline(cmd, "NO Mailbox name too long.");
-		return FALSE;
+		return NULL;
 	}
 
 	/* check what our storage thinks of it */
 	if (mailbox_list_get_mailbox_name_status(ns->list, mailbox,
 						 &mailbox_status) < 0) {
 		client_send_list_error(cmd, ns->list);
-		return FALSE;
+		return NULL;
 	}
 
 	switch (mailbox_status) {
 	case MAILBOX_NAME_EXISTS:
 		switch (mode) {
+		case CLIENT_VERIFY_MAILBOX_NONE:
 		case CLIENT_VERIFY_MAILBOX_NAME:
 		case CLIENT_VERIFY_MAILBOX_SHOULD_EXIST:
 		case CLIENT_VERIFY_MAILBOX_SHOULD_EXIST_TRYCREATE:
-			return TRUE;
+			return ns;
 		case CLIENT_VERIFY_MAILBOX_SHOULD_NOT_EXIST:
 			break;
 		}
 
 		if (mode == CLIENT_VERIFY_MAILBOX_NAME ||
 		    mode == CLIENT_VERIFY_MAILBOX_SHOULD_EXIST)
-			return TRUE;
+			return ns;
 
 		client_send_tagline(cmd, t_strconcat(
 			"NO [", IMAP_RESP_CODE_ALREADYEXISTS,
@@ -110,7 +104,7 @@ bool client_verify_mailbox_name(struct c
 		switch (mode) {
 		case CLIENT_VERIFY_MAILBOX_NAME:


More information about the dovecot-cvs mailing list