changeset 9480:8741d62d6b74 HEAD

IMAP: Send [ALREADYEXISTS], [NONEXISTENT] and [TRYCREATE] resp-codes correctly.
author Timo Sirainen <tss@iki.fi>
date Mon, 15 Jun 2009 21:45:35 -0400
parents 9291253df6de
children 25ad27f699f6
files src/imap/cmd-append.c src/imap/cmd-copy.c src/imap/cmd-create.c src/imap/cmd-rename.c src/imap/cmd-subscribe.c src/imap/imap-commands-util.c src/imap/imap-commands-util.h
diffstat 7 files changed, 56 insertions(+), 19 deletions(-) [+]
line wrap: on
line diff
--- a/src/imap/cmd-append.c	Mon Jun 15 21:22:30 2009 -0400
+++ b/src/imap/cmd-append.c	Mon Jun 15 21:45:35 2009 -0400
@@ -454,7 +454,8 @@
 	struct mail_namespace *ns;
 	struct mailbox *box;
 
-	if (!client_verify_mailbox_name(cmd, name, TRUE, FALSE))
+	if (!client_verify_mailbox_name(cmd, name,
+				CLIENT_VERIFY_MAILBOX_SHOULD_EXIST_TRYCREATE))
 		return NULL;
 
 	ns = client_find_namespace(cmd, &name);
--- a/src/imap/cmd-copy.c	Mon Jun 15 21:22:30 2009 -0400
+++ b/src/imap/cmd-copy.c	Mon Jun 15 21:45:35 2009 -0400
@@ -113,7 +113,8 @@
 		return TRUE;
 
 	/* open the destination mailbox */
-	if (!client_verify_mailbox_name(cmd, mailbox, TRUE, FALSE))
+	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);
--- a/src/imap/cmd-create.c	Mon Jun 15 21:22:30 2009 -0400
+++ b/src/imap/cmd-create.c	Mon Jun 15 21:45:35 2009 -0400
@@ -36,7 +36,8 @@
 		full_mailbox = t_strndup(full_mailbox, len-1);
 	}
 
-	if (!client_verify_mailbox_name(cmd, full_mailbox, FALSE, TRUE))
+	if (!client_verify_mailbox_name(cmd, full_mailbox,
+					CLIENT_VERIFY_MAILBOX_SHOULD_NOT_EXIST))
 		return TRUE;
 
 	storage = mail_namespace_get_default_storage(ns);
--- a/src/imap/cmd-rename.c	Mon Jun 15 21:22:30 2009 -0400
+++ b/src/imap/cmd-rename.c	Mon Jun 15 21:45:35 2009 -0400
@@ -14,9 +14,11 @@
 	if (!client_read_string_args(cmd, 2, &oldname, &newname))
 		return FALSE;
 
-	if (!client_verify_mailbox_name(cmd, oldname, TRUE, FALSE))
+	if (!client_verify_mailbox_name(cmd, oldname,
+					CLIENT_VERIFY_MAILBOX_SHOULD_EXIST))
 		return TRUE;
-	if (!client_verify_mailbox_name(cmd, newname, FALSE, TRUE))
+	if (!client_verify_mailbox_name(cmd, newname,
+					CLIENT_VERIFY_MAILBOX_SHOULD_NOT_EXIST))
 		return TRUE;
 
 	old_ns = client_find_namespace(cmd, &oldname);
--- a/src/imap/cmd-subscribe.c	Mon Jun 15 21:22:30 2009 -0400
+++ b/src/imap/cmd-subscribe.c	Mon Jun 15 21:45:35 2009 -0400
@@ -68,9 +68,13 @@
 	if (have_listable_namespace_prefix(cmd->client->user->namespaces,
 					   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))
+			return TRUE;
 	} else {
 		if (!client_verify_mailbox_name(cmd, verify_name,
-						subscribe, FALSE))
+						CLIENT_VERIFY_MAILBOX_NAME))
 			return TRUE;
 	}
 
--- a/src/imap/imap-commands-util.c	Mon Jun 15 21:22:30 2009 -0400
+++ b/src/imap/imap-commands-util.c	Mon Jun 15 21:45:35 2009 -0400
@@ -34,11 +34,11 @@
 
 bool client_verify_mailbox_name(struct client_command_context *cmd,
 				const char *mailbox,
-				bool should_exist, bool should_not_exist)
+				enum client_verify_mailbox_mode mode)
 {
 	struct mail_namespace *ns;
 	enum mailbox_name_status mailbox_status;
-	const char *orig_mailbox, *p;
+	const char *orig_mailbox, *p, *resp_code = NULL;
 
 	orig_mailbox = mailbox;
 	ns = client_find_namespace(cmd, &mailbox);
@@ -88,18 +88,39 @@
 
 	switch (mailbox_status) {
 	case MAILBOX_NAME_EXISTS:
-		if (should_exist || !should_not_exist)
+		switch (mode) {
+		case CLIENT_VERIFY_MAILBOX_NAME:
+		case CLIENT_VERIFY_MAILBOX_SHOULD_EXIST:
+		case CLIENT_VERIFY_MAILBOX_SHOULD_EXIST_TRYCREATE:
+			return TRUE;
+		case CLIENT_VERIFY_MAILBOX_SHOULD_NOT_EXIST:
+			break;
+		}
+
+		if (mode == CLIENT_VERIFY_MAILBOX_NAME ||
+		    mode == CLIENT_VERIFY_MAILBOX_SHOULD_EXIST)
 			return TRUE;
 
-		client_send_tagline(cmd, "NO Mailbox exists.");
+		client_send_tagline(cmd, t_strconcat(
+			"NO [", IMAP_RESP_CODE_ALREADYEXISTS,
+			"] Mailbox exists.", NULL));
 		break;
 
 	case MAILBOX_NAME_VALID:
-		if (!should_exist)
+		switch (mode) {
+		case CLIENT_VERIFY_MAILBOX_NAME:
+		case CLIENT_VERIFY_MAILBOX_SHOULD_NOT_EXIST:
 			return TRUE;
+		case CLIENT_VERIFY_MAILBOX_SHOULD_EXIST:
+			resp_code = IMAP_RESP_CODE_NONEXISTENT;
+			break;
+		case CLIENT_VERIFY_MAILBOX_SHOULD_EXIST_TRYCREATE:
+			resp_code = "TRYCREATE";
+			break;
+		}
 
 		client_send_tagline(cmd, t_strconcat(
-			"NO [TRYCREATE] Mailbox doesn't exist: ",
+			"NO [", resp_code, "] Mailbox doesn't exist: ",
 			str_sanitize(orig_mailbox, MAILBOX_MAX_NAME_LEN),
 			NULL));
 		break;
--- a/src/imap/imap-commands-util.h	Mon Jun 15 21:22:30 2009 -0400
+++ b/src/imap/imap-commands-util.h	Mon Jun 15 21:45:35 2009 -0400
@@ -1,6 +1,17 @@
 #ifndef IMAP_COMMANDS_UTIL_H
 #define IMAP_COMMANDS_UTIL_H
 
+enum client_verify_mailbox_mode {
+	/* Verify only that the mailbox name is valid */
+	CLIENT_VERIFY_MAILBOX_NAME,
+	/* If mailbox doesn't exist, fail with [NONEXISTENT] resp code */
+	CLIENT_VERIFY_MAILBOX_SHOULD_EXIST,
+	/* If mailbox doesn't exist, fail with [TRYCREATE] resp code */
+	CLIENT_VERIFY_MAILBOX_SHOULD_EXIST_TRYCREATE,
+	/* If mailbox exists, fail with [ALREADYEXISTS] resp code */
+	CLIENT_VERIFY_MAILBOX_SHOULD_NOT_EXIST
+};
+
 struct msgset_generator_context {
 	string_t *str;
 	uint32_t first_uid, last_uid;
@@ -14,15 +25,11 @@
 struct mail_namespace *
 client_find_namespace(struct client_command_context *cmd, 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].
-
-   If should_exist is FALSE, the should_not_exist specifies if we should
-   return TRUE or FALSE if mailbox doesn't exist. */
+/* Returns TRUE if verifications succeeds. If it fails, a tagged NO is sent to
+   client. */
 bool client_verify_mailbox_name(struct client_command_context *cmd,
 				const char *mailbox,
-				bool should_exist, bool should_not_exist);
+				enum client_verify_mailbox_mode mode);
 
 /* Returns TRUE if mailbox is selected. If not, sends "No mailbox selected"
    error message to client. */