dovecot-2.0: imap: Some mailbox accessing commands failed with w...

dovecot at dovecot.org dovecot at dovecot.org
Tue Mar 16 16:15:06 EET 2010


details:   http://hg.dovecot.org/dovecot-2.0/rev/7443f0b5218f
changeset: 10918:7443f0b5218f
user:      Timo Sirainen <tss at iki.fi>
date:      Tue Mar 16 16:15:03 2010 +0200
description:
imap: Some mailbox accessing commands failed with wrong error message.

diffstat:

 src/imap/cmd-append.c         |   22 ++++++-
 src/imap/cmd-copy.c           |   24 ++++++-
 src/imap/cmd-create.c         |   35 +++++++----
 src/imap/cmd-delete.c         |   18 ++++-
 src/imap/cmd-rename.c         |   39 +++++++++---
 src/imap/cmd-select.c         |   20 +++++-
 src/imap/cmd-status.c         |   24 ++++++--
 src/imap/cmd-subscribe.c      |   68 +++++++++++++++-------
 src/imap/imap-commands-util.c |  111 +++++++++++++-----------------------
 src/imap/imap-commands-util.h |   28 +++------
 10 files changed, 232 insertions(+), 157 deletions(-)

diffs (truncated from 717 to 300 lines):

diff -r cc0a8b0347f9 -r 7443f0b5218f src/imap/cmd-append.c
--- a/src/imap/cmd-append.c	Tue Mar 16 15:20:15 2010 +0200
+++ b/src/imap/cmd-append.c	Tue Mar 16 16:15:03 2010 +0200
@@ -454,17 +454,31 @@
 {
 	struct mail_namespace *ns;
 	struct mailbox *box;
+	enum mailbox_name_status status;
+	const char *storage_name;
 
-	ns = client_find_namespace(cmd, &name,
-				   CLIENT_VERIFY_MAILBOX_SHOULD_EXIST_TRYCREATE);
+	ns = client_find_namespace(cmd, name, &storage_name, &status);
 	if (ns == NULL)
 		return NULL;
 
+	switch (status) {
+	case MAILBOX_NAME_EXISTS_MAILBOX:
+		break;
+	case MAILBOX_NAME_EXISTS_DIR:
+		status = MAILBOX_NAME_VALID;
+		/* fall through */
+	case MAILBOX_NAME_VALID:
+	case MAILBOX_NAME_INVALID:
+	case MAILBOX_NAME_NOINFERIORS:
+		client_fail_mailbox_name_status(cmd, name, "TRYCREATE", status);
+		return NULL;
+	}
+
 	if (cmd->client->mailbox != NULL &&
-	    mailbox_equals(cmd->client->mailbox, ns, name))
+	    mailbox_equals(cmd->client->mailbox, ns, storage_name))
 		return cmd->client->mailbox;
 
-	box = mailbox_alloc(ns->list, name, MAILBOX_FLAG_SAVEONLY |
+	box = mailbox_alloc(ns->list, storage_name, MAILBOX_FLAG_SAVEONLY |
 			    MAILBOX_FLAG_KEEP_RECENT);
 	if (mailbox_open(box) < 0) {
 		client_send_storage_error(cmd, mailbox_get_storage(box));
diff -r cc0a8b0347f9 -r 7443f0b5218f src/imap/cmd-copy.c
--- a/src/imap/cmd-copy.c	Tue Mar 16 15:20:15 2010 +0200
+++ b/src/imap/cmd-copy.c	Tue Mar 16 16:15:03 2010 +0200
@@ -90,7 +90,8 @@
 	struct mailbox *destbox;
 	struct mailbox_transaction_context *t;
         struct mail_search_args *search_args;
-	const char *messageset, *mailbox, *src_uidset;
+	const char *messageset, *mailbox, *storage_name, *src_uidset;
+	enum mailbox_name_status status;
 	enum mailbox_sync_flags sync_flags = 0;
 	enum imap_sync_flags imap_flags = 0;
 	struct mail_transaction_commit_changes changes;
@@ -110,15 +111,28 @@
 		return ret < 0;
 
 	/* open the destination mailbox */
-	dest_ns = client_find_namespace(cmd, &mailbox,
-				CLIENT_VERIFY_MAILBOX_SHOULD_EXIST_TRYCREATE);
+	dest_ns = client_find_namespace(cmd, mailbox, &storage_name, &status);
 	if (dest_ns == NULL)
 		return TRUE;
 
-	if (mailbox_equals(client->mailbox, dest_ns, mailbox))
+	switch (status) {
+	case MAILBOX_NAME_EXISTS_MAILBOX:
+		break;
+	case MAILBOX_NAME_EXISTS_DIR:
+		status = MAILBOX_NAME_VALID;
+		/* fall through */
+	case MAILBOX_NAME_VALID:
+	case MAILBOX_NAME_INVALID:
+	case MAILBOX_NAME_NOINFERIORS:
+		client_fail_mailbox_name_status(cmd, mailbox,
+						"TRYCREATE", status);
+		return NULL;
+	}
+
+	if (mailbox_equals(client->mailbox, dest_ns, storage_name))
 		destbox = client->mailbox;
 	else {
-		destbox = mailbox_alloc(dest_ns->list, mailbox,
+		destbox = mailbox_alloc(dest_ns->list, storage_name,
 					MAILBOX_FLAG_SAVEONLY |
 					MAILBOX_FLAG_KEEP_RECENT);
 		if (mailbox_open(destbox) < 0) {
diff -r cc0a8b0347f9 -r 7443f0b5218f src/imap/cmd-create.c
--- a/src/imap/cmd-create.c	Tue Mar 16 15:20:15 2010 +0200
+++ b/src/imap/cmd-create.c	Tue Mar 16 16:15:03 2010 +0200
@@ -7,8 +7,9 @@
 
 bool cmd_create(struct client_command_context *cmd)
 {
+	enum mailbox_name_status status;
 	struct mail_namespace *ns;
-	const char *mailbox, *full_mailbox;
+	const char *mailbox, *storage_name;
 	struct mailbox *box;
 	bool directory;
 	size_t len;
@@ -16,16 +17,15 @@
 	/* <mailbox> */
 	if (!client_read_string_args(cmd, 1, &mailbox))
 		return FALSE;
-	full_mailbox = mailbox;
 
-	ns = client_find_namespace(cmd, &mailbox, CLIENT_VERIFY_MAILBOX_NONE);
+	ns = client_find_namespace(cmd, mailbox, &storage_name, NULL);
 	if (ns == NULL)
 		return TRUE;
 
-	len = strlen(full_mailbox);
-	if (len == 0 || full_mailbox[len-1] != ns->sep)
+	len = strlen(mailbox);
+	if (len == 0 || mailbox[len-1] != ns->sep)
 		directory = FALSE;
-	else if (*mailbox == '\0') {
+	else if (*storage_name == '\0') {
 		client_send_tagline(cmd, "NO ["IMAP_RESP_CODE_ALREADYEXISTS
 				    "] Namespace already exists.");
 		return TRUE;
@@ -34,17 +34,28 @@
 		   informing us that it wants to create children under this
 		   mailbox. */
                 directory = TRUE;
-		mailbox = t_strndup(mailbox, strlen(mailbox)-1);
-		full_mailbox = t_strndup(full_mailbox, len-1);
+		storage_name = t_strndup(storage_name, strlen(storage_name)-1);
+		mailbox = t_strndup(mailbox, len-1);
 	}
 
-	mailbox = full_mailbox;
-	ns = client_find_namespace(cmd, &mailbox,
-				   CLIENT_VERIFY_MAILBOX_SHOULD_NOT_EXIST);
+	ns = client_find_namespace(cmd, mailbox, &storage_name, &status);
 	if (ns == NULL)
 		return TRUE;
+	switch (status) {
+	case MAILBOX_NAME_VALID:
+		break;
+	case MAILBOX_NAME_EXISTS_DIR:
+		if (!directory)
+			break;
+		/* fall through */
+	case MAILBOX_NAME_EXISTS_MAILBOX:
+	case MAILBOX_NAME_INVALID:
+	case MAILBOX_NAME_NOINFERIORS:
+		client_fail_mailbox_name_status(cmd, mailbox, NULL, status);
+		return TRUE;
+	}
 
-	box = mailbox_alloc(ns->list, mailbox, 0);
+	box = mailbox_alloc(ns->list, storage_name, 0);
 	if (mailbox_create(box, NULL, directory) < 0)
 		client_send_storage_error(cmd, mailbox_get_storage(box));
 	else
diff -r cc0a8b0347f9 -r 7443f0b5218f src/imap/cmd-delete.c
--- a/src/imap/cmd-delete.c	Tue Mar 16 15:20:15 2010 +0200
+++ b/src/imap/cmd-delete.c	Tue Mar 16 16:15:03 2010 +0200
@@ -6,9 +6,10 @@
 bool cmd_delete(struct client_command_context *cmd)
 {
 	struct client *client = cmd->client;
+	enum mailbox_name_status status;
 	struct mail_namespace *ns;
 	struct mailbox *box;
-	const char *name;
+	const char *name, *storage_name;
 
 	/* <mailbox> */
 	if (!client_read_string_args(cmd, 1, &name))
@@ -20,12 +21,21 @@
 		return TRUE;
 	}
 
-	ns = client_find_namespace(cmd, &name,
-				   CLIENT_VERIFY_MAILBOX_DIR_SHOULD_EXIST);
+	ns = client_find_namespace(cmd, name, &storage_name, &status);
 	if (ns == NULL)
 		return TRUE;
+	switch (status) {
+	case MAILBOX_NAME_EXISTS_MAILBOX:
+	case MAILBOX_NAME_EXISTS_DIR:
+		break;
+	case MAILBOX_NAME_VALID:
+	case MAILBOX_NAME_INVALID:
+	case MAILBOX_NAME_NOINFERIORS:
+		client_fail_mailbox_name_status(cmd, name, NULL, status);
+		return TRUE;
+	}
 
-	box = mailbox_alloc(ns->list, name, 0);
+	box = mailbox_alloc(ns->list, storage_name, 0);
 	if (client->mailbox != NULL &&
 	    mailbox_backends_equal(box, client->mailbox)) {
 		/* deleting selected mailbox. close it first */
diff -r cc0a8b0347f9 -r 7443f0b5218f src/imap/cmd-rename.c
--- a/src/imap/cmd-rename.c	Tue Mar 16 15:20:15 2010 +0200
+++ b/src/imap/cmd-rename.c	Tue Mar 16 16:15:03 2010 +0200
@@ -6,40 +6,59 @@
 
 bool cmd_rename(struct client_command_context *cmd)
 {
+	enum mailbox_name_status status;
 	struct mail_namespace *old_ns, *new_ns;
 	struct mailbox *old_box, *new_box;
-	const char *oldname, *newname;
+	const char *oldname, *newname, *storage_oldname, *storage_newname;
 	unsigned int oldlen;
 
 	/* <old name> <new name> */
 	if (!client_read_string_args(cmd, 2, &oldname, &newname))
 		return FALSE;
 
-	old_ns = client_find_namespace(cmd, &oldname,
-				       CLIENT_VERIFY_MAILBOX_DIR_SHOULD_EXIST);
+	old_ns = client_find_namespace(cmd, oldname, &storage_oldname, &status);
 	if (old_ns == NULL)
 		return TRUE;
+	switch (status) {
+	case MAILBOX_NAME_EXISTS_MAILBOX:
+	case MAILBOX_NAME_EXISTS_DIR:
+		break;
+	case MAILBOX_NAME_VALID:
+	case MAILBOX_NAME_INVALID:
+	case MAILBOX_NAME_NOINFERIORS:
+		client_fail_mailbox_name_status(cmd, oldname, NULL, status);
+		return TRUE;
+	}
 
-	new_ns = client_find_namespace(cmd, &newname,
-				CLIENT_VERIFY_MAILBOX_DIR_SHOULD_NOT_EXIST);
+	new_ns = client_find_namespace(cmd, newname, &storage_newname, &status);
 	if (new_ns == NULL)
 		return TRUE;
+	switch (status) {
+	case MAILBOX_NAME_VALID:
+		break;
+	case MAILBOX_NAME_EXISTS_MAILBOX:
+	case MAILBOX_NAME_EXISTS_DIR:
+	case MAILBOX_NAME_INVALID:
+	case MAILBOX_NAME_NOINFERIORS:
+		client_fail_mailbox_name_status(cmd, newname, NULL, status);
+		return TRUE;
+	}
 
 	if (old_ns == new_ns) {
 		/* disallow box -> box/child, because it may break clients and
 		   there's really no point in doing it anyway. */
 		old_ns = mailbox_list_get_namespace(old_ns->list);
-		oldlen = strlen(oldname);
-		if (strncmp(oldname, newname, oldlen) == 0 &&
-		    newname[oldlen] == old_ns->real_sep) {
+		oldlen = strlen(storage_oldname);
+		if (strncmp(storage_oldname, storage_newname, oldlen) == 0 &&
+		    storage_newname[oldlen] == old_ns->real_sep) {
 			client_send_tagline(cmd,
 				"NO Can't rename mailbox under its own child.");
 			return TRUE;
 		}
 	}
 
-	old_box = mailbox_alloc(old_ns->list, oldname, 0);
-	new_box = mailbox_alloc(new_ns->list, newname, 0);
+	old_box = mailbox_alloc(old_ns->list, storage_oldname, 0);
+	new_box = mailbox_alloc(new_ns->list, storage_newname, 0);
 	if (mailbox_rename(old_box, new_box, TRUE) < 0)
 		client_send_storage_error(cmd, mailbox_get_storage(old_box));
 	else
diff -r cc0a8b0347f9 -r 7443f0b5218f src/imap/cmd-select.c
--- a/src/imap/cmd-select.c	Tue Mar 16 15:20:15 2010 +0200
+++ b/src/imap/cmd-select.c	Tue Mar 16 16:15:03 2010 +0200
@@ -342,7 +342,8 @@
 	struct mailbox *box;
 	struct imap_select_context *ctx;
 	const struct imap_arg *args;
-	const char *mailbox;
+	enum mailbox_name_status status;
+	const char *mailbox, *storage_name;
 	int ret;
 
 	/* <mailbox> [(optional parameters)] */
@@ -357,10 +358,21 @@
 
 	ctx = p_new(cmd->pool, struct imap_select_context, 1);
 	ctx->cmd = cmd;
-	ctx->ns = client_find_namespace(cmd, &mailbox,
-					CLIENT_VERIFY_MAILBOX_SHOULD_EXIST);
+	ctx->ns = client_find_namespace(cmd, mailbox, &storage_name, &status);
 	if (ctx->ns == NULL)
 		return TRUE;
+	switch (status) {
+	case MAILBOX_NAME_EXISTS_MAILBOX:
+		break;
+	case MAILBOX_NAME_EXISTS_DIR:
+		status = MAILBOX_NAME_VALID;
+		/* fall through */
+	case MAILBOX_NAME_VALID:
+	case MAILBOX_NAME_INVALID:
+	case MAILBOX_NAME_NOINFERIORS:
+		client_fail_mailbox_name_status(cmd, mailbox, NULL, status);


More information about the dovecot-cvs mailing list