]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
IMAP: Send [ALREADYEXISTS], [NONEXISTENT] and [TRYCREATE] resp-codes correctly.
authorTimo Sirainen <tss@iki.fi>
Tue, 16 Jun 2009 01:45:35 +0000 (21:45 -0400)
committerTimo Sirainen <tss@iki.fi>
Tue, 16 Jun 2009 01:45:35 +0000 (21:45 -0400)
--HG--
branch : HEAD

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

index a1e9bf2376df6f2038a8fc3dcd2204310b165d73..a76aae9271e365a4c65c3d12a260cf38a6a6baff 100644 (file)
@@ -454,7 +454,8 @@ get_mailbox(struct client_command_context *cmd, const char *name)
        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);
index 9e6e91ee5c9ffe3801bfa5df62b95eeaa62c560b..7969de2a240fa59c3362bc4c6bbc20b8692f6ddb 100644 (file)
@@ -113,7 +113,8 @@ bool cmd_copy(struct client_command_context *cmd)
                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);
index d4561bf9aadd0a3cd10eb9909bb0e018f025ba26..50335f295161783ba16a3d97addb2c72b7e26e95 100644 (file)
@@ -36,7 +36,8 @@ bool cmd_create(struct client_command_context *cmd)
                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);
index 77f1154f2225bc9601b5403721050af7cecf10c2..6bb7b449b25cf65eecebbc7d4dcdb25a79f06886 100644 (file)
@@ -14,9 +14,11 @@ bool cmd_rename(struct client_command_context *cmd)
        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);
index c920d3b16ea2146106e044f0f0065b2eec735e43..a682f2b8977ea6702fe852054a43de8aa636c4d5 100644 (file)
@@ -68,9 +68,13 @@ bool cmd_subscribe_full(struct client_command_context *cmd, bool subscribe)
        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;
        }
 
index 53d77bc5177f848e139af342ae7112152760d369..eca0631ed56d720c4abae5eed7f30fe1ad2290d1 100644 (file)
@@ -34,11 +34,11 @@ client_find_namespace(struct client_command_context *cmd, const char **mailbox)
 
 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 @@ bool client_verify_mailbox_name(struct client_command_context *cmd,
 
        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;
index 07205b8c62f3c1a524ad54b209d913a29f54acfe..ae59c7da6b6ef96d315d40a0fa7d8c66114da8a8 100644 (file)
@@ -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 mailbox_keywords;
 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. */