changeset 9135:39c234ab0b21 HEAD

IMAP: Send [ALREADYEXISTS], [NONEXISTENT] and [TRYCREATE] resp-codes correctly.
author Timo Sirainen <tss@iki.fi>
date Mon, 15 Jun 2009 21:43:37 -0400
parents 67fe18c3f8dd
children ef7c0c3b1976
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/commands-util.c src/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:43:37 2009 -0400
@@ -455,7 +455,8 @@
 	struct mail_storage *storage;
 	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;
 
 	storage = client_find_storage(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:43:37 2009 -0400
@@ -112,7 +112,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:43:37 2009 -0400
@@ -35,7 +35,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;
 
 	if (mail_storage_mailbox_create(ns->storage, mailbox, directory) < 0)
--- a/src/imap/cmd-rename.c	Mon Jun 15 21:22:30 2009 -0400
+++ b/src/imap/cmd-rename.c	Mon Jun 15 21:43:37 2009 -0400
@@ -16,9 +16,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_storage = client_find_storage(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:43:37 2009 -0400
@@ -70,9 +70,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/commands-util.c	Mon Jun 15 21:22:30 2009 -0400
+++ b/src/imap/commands-util.c	Mon Jun 15 21:43:37 2009 -0400
@@ -43,12 +43,12 @@
 
 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;
 	struct mailbox_list *list;
 	enum mailbox_name_status mailbox_status;
-	const char *orig_mailbox, *p;
+	const char *orig_mailbox, *p, *resp_code;
 
 	orig_mailbox = mailbox;
 	ns = client_find_namespace(cmd, &mailbox);
@@ -99,18 +99,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/commands-util.h	Mon Jun 15 21:22:30 2009 -0400
+++ b/src/imap/commands-util.h	Mon Jun 15 21:43:37 2009 -0400
@@ -1,6 +1,17 @@
 #ifndef COMMANDS_UTIL_H
 #define 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;
@@ -18,15 +29,11 @@
 struct mail_storage *
 client_find_storage(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. */