]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Fixed creating mailboxes over \noselect mailboxes.
authorTimo Sirainen <tss@iki.fi>
Mon, 15 Feb 2010 00:08:02 +0000 (02:08 +0200)
committerTimo Sirainen <tss@iki.fi>
Mon, 15 Feb 2010 00:08:02 +0000 (02:08 +0200)
--HG--
branch : HEAD

src/imap/cmd-rename.c
src/imap/imap-commands-util.c
src/imap/imap-commands-util.h
src/lib-storage/list/mailbox-list-fs.c

index 567e3df05523ec1a0c1cc022181b3cd88c40c5c7..fddbf62dc2bf0b495142e6409b291503ae134c9b 100644 (file)
@@ -21,7 +21,7 @@ bool cmd_rename(struct client_command_context *cmd)
                return TRUE;
 
        new_ns = client_find_namespace(cmd, &newname,
-                                      CLIENT_VERIFY_MAILBOX_SHOULD_NOT_EXIST);
+                               CLIENT_VERIFY_MAILBOX_DIR_SHOULD_NOT_EXIST);
        if (new_ns == NULL)
                return TRUE;
 
index a7a5940109846b2df3bee564f15c15197ebcc379..7bdc63c2a1b6257459ecfd3637157d71ed7bd98f 100644 (file)
@@ -91,14 +91,22 @@ client_find_namespace(struct client_command_context *cmd, const char **mailboxp,
 
        switch (mailbox_status) {
        case MAILBOX_NAME_EXISTS_MAILBOX:
+       case MAILBOX_NAME_EXISTS_DIR:
                switch (mode) {
+               case CLIENT_VERIFY_MAILBOX_SHOULD_EXIST:
+               case CLIENT_VERIFY_MAILBOX_SHOULD_EXIST_TRYCREATE:
+                       if (mailbox_status == MAILBOX_NAME_EXISTS_DIR)
+                               break;
+                       return ns;
                case CLIENT_VERIFY_MAILBOX_NONE:
                case CLIENT_VERIFY_MAILBOX_NAME:
-               case CLIENT_VERIFY_MAILBOX_SHOULD_EXIST:
                case CLIENT_VERIFY_MAILBOX_DIR_SHOULD_EXIST:
-               case CLIENT_VERIFY_MAILBOX_SHOULD_EXIST_TRYCREATE:
                        return ns;
                case CLIENT_VERIFY_MAILBOX_SHOULD_NOT_EXIST:
+                       if (mailbox_status == MAILBOX_NAME_EXISTS_DIR)
+                               return ns;
+                       break;
+               case CLIENT_VERIFY_MAILBOX_DIR_SHOULD_NOT_EXIST:
                        break;
                }
 
@@ -108,11 +116,11 @@ client_find_namespace(struct client_command_context *cmd, const char **mailboxp,
                break;
 
        case MAILBOX_NAME_VALID:
-       case MAILBOX_NAME_EXISTS_DIR:
                resp_code = "";
                switch (mode) {
                case CLIENT_VERIFY_MAILBOX_NAME:
                case CLIENT_VERIFY_MAILBOX_SHOULD_NOT_EXIST:
+               case CLIENT_VERIFY_MAILBOX_DIR_SHOULD_NOT_EXIST:
                case CLIENT_VERIFY_MAILBOX_DIR_SHOULD_EXIST:
                        return ns;
                case CLIENT_VERIFY_MAILBOX_SHOULD_EXIST:
index 8c4abab953ea3d817b64d313e72fe934d9d35981..078bea5d7c0add739222ad2cba61062fa7179cb9 100644 (file)
@@ -13,7 +13,9 @@ enum client_verify_mailbox_mode {
        /* 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
+       CLIENT_VERIFY_MAILBOX_SHOULD_NOT_EXIST,
+       /* If dir/mailbox exists, fail with [ALREADYEXISTS] resp code */
+       CLIENT_VERIFY_MAILBOX_DIR_SHOULD_NOT_EXIST
 };
 
 struct msgset_generator_context {
index 5c328577efef819628e614771a19803ae991320c..33763b8092047beb9f220fea384d3253930d11ee 100644 (file)
@@ -317,6 +317,16 @@ static int fs_list_set_subscribed(struct mailbox_list *_list,
                                       name, set);
 }
 
+static int mailbox_is_selectable(struct mailbox_list *list, const char *name)
+{
+       enum mailbox_info_flags flags;
+
+       if (mailbox_list_mailbox(list, name, &flags) < 0)
+               return -1;
+
+       return (flags & (MAILBOX_NOSELECT | MAILBOX_NONEXISTENT)) == 0 ? 1 : 0;
+}
+
 static int
 fs_list_create_mailbox_dir(struct mailbox_list *list, const char *name,
                           bool directory)
@@ -326,6 +336,7 @@ fs_list_create_mailbox_dir(struct mailbox_list *list, const char *name,
        mode_t mode;
        gid_t gid;
        bool create_parent_dir;
+       int ret;
 
        /* make sure the alt path doesn't exist yet. it shouldn't (except with
           race conditions with RENAME/DELETE), but if something crashed and
@@ -361,6 +372,10 @@ fs_list_create_mailbox_dir(struct mailbox_list *list, const char *name,
        else if (errno == EEXIST) {
                if (create_parent_dir)
                        return 0;
+               if (!directory && *list->set.mailbox_dir_name == '\0') {
+                       if ((ret = mailbox_is_selectable(list, name)) <= 0)
+                               return ret;
+               }
                mailbox_list_set_error(list, MAIL_ERROR_EXISTS,
                                       "Mailbox already exists");
        } else if (errno == ENOTDIR) {