]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-storage: Removed INBOX auto-creating from backend code. Added bool box->inbox.
authorTimo Sirainen <tss@iki.fi>
Mon, 15 Feb 2010 01:07:19 +0000 (03:07 +0200)
committerTimo Sirainen <tss@iki.fi>
Mon, 15 Feb 2010 01:07:19 +0000 (03:07 +0200)
--HG--
branch : HEAD

src/lib-storage/index/cydir/cydir-storage.c
src/lib-storage/index/dbox-common/dbox-storage.c
src/lib-storage/index/index-storage.c
src/lib-storage/index/maildir/maildir-storage.c
src/lib-storage/index/mbox/mbox-lock.c
src/lib-storage/index/mbox/mbox-storage.c
src/lib-storage/list/mailbox-list-maildir.c
src/lib-storage/mail-storage-private.h
src/lib-storage/mail-storage.c

index e2a94c5af1bca2b24d59860480ba7904e27d7e28..0b04be426b0ea74717d8387addf997e5c6888789 100644 (file)
@@ -73,11 +73,6 @@ static int cydir_mailbox_open(struct mailbox *box)
 
        if (stat(box->path, &st) == 0) {
                /* exists, open it */
-       } else if (errno == ENOENT && strcmp(box->name, "INBOX") == 0) {
-               /* INBOX always exists, create it */
-               if (box->list->v.create_mailbox_dir(box->list,
-                                                   box->name, FALSE) < 0)
-                       return -1;
        } else if (errno == ENOENT) {
                mail_storage_set_error(box->storage, MAIL_ERROR_NOTFOUND,
                        T_MAIL_ERR_MAILBOX_NOT_FOUND(box->name));
index 1b10d48c988aef717d192afe26ad7f444e4e28d0..8905bf984cc0bebd2457dac201491eb3302b32f0 100644 (file)
@@ -71,45 +71,11 @@ dbox_cleanup_if_exists(struct mailbox_list *list, const char *path)
        return TRUE;
 }
 
-static int dbox_mailbox_create_indexes(struct mailbox *box,
-                                      const struct mailbox_update *update)
-{
-       struct dbox_storage *storage = (struct dbox_storage *)box->storage;
-       const char *origin;
-       mode_t mode;
-       gid_t gid;
-
-       mailbox_list_get_dir_permissions(box->list, NULL, &mode, &gid, &origin);
-       if (mkdir_parents_chgrp(box->path, mode, gid, origin) == 0) {
-               /* create indexes immediately with the dbox header */
-               if (index_storage_mailbox_open(box, FALSE) < 0)
-                       return -1;
-               if (storage->v.mailbox_create_indexes(box, update) < 0)
-                       return -1;
-       } else if (errno != EEXIST) {
-               if (!mail_storage_set_error_from_errno(box->storage)) {
-                       mail_storage_set_critical(box->storage,
-                               "mkdir(%s) failed: %m", box->path);
-               }
-               return -1;
-       }
-       return 0;
-}
-
 int dbox_mailbox_open(struct mailbox *box)
 {
        if (dbox_cleanup_if_exists(box->list, box->path)) {
                return index_storage_mailbox_open(box, FALSE);
        } else if (errno == ENOENT) {
-               if (strcmp(box->name, "INBOX") == 0 &&
-                   (box->list->ns->flags & NAMESPACE_FLAG_INBOX) != 0) {
-                       /* INBOX always exists, create it */
-                       if (dbox_mailbox_create_indexes(box, NULL) < 0)
-                               return -1;
-                       return box->opened ? 0 :
-                               index_storage_mailbox_open(box, FALSE);
-               }
-
                mail_storage_set_error(box->storage, MAIL_ERROR_NOTFOUND,
                        T_MAIL_ERR_MAILBOX_NOT_FOUND(box->name));
                return -1;
index 016465f669faedc4731ebd4fc99daad42cd4e1f5..f06f997644550db6091be0de8609d9e723253d59 100644 (file)
@@ -285,6 +285,8 @@ void index_storage_mailbox_alloc(struct mailbox *box, const char *name,
                                     MAILBOX_LIST_PATH_TYPE_MAILBOX);
        box->path = p_strdup(box->pool, path);
        box->index = index_storage_alloc(box->list, name, flags, index_prefix);
+       box->inbox = strcmp(name, "INBOX") == 0 &&
+               (box->list->ns->flags & NAMESPACE_FLAG_INBOX) != 0;
        if (box->file_create_mode == 0)
                mailbox_refresh_permissions(box);
        mail_index_set_permissions(box->index, box->file_create_mode,
index d3692a45df90e37932ddb7732a625eb8647ab694..de127ec75c2b43844d8c9ec3eda5dce232fc5db8 100644 (file)
@@ -322,12 +322,9 @@ static int maildir_mailbox_open_existing(struct mailbox *box)
 
 static int maildir_mailbox_open(struct mailbox *box)
 {
+       const char *root_dir;
        struct stat st;
        int ret;
-       bool inbox;
-
-       inbox = strcmp(box->name, "INBOX") == 0 &&
-               (box->list->ns->flags & NAMESPACE_FLAG_INBOX) != 0;
 
        /* begin by checking if tmp/ directory exists and if it should be
           cleaned up. */
@@ -340,13 +337,20 @@ static int maildir_mailbox_open(struct mailbox *box)
                return -1;
 
        /* tmp/ directory doesn't exist. does the maildir? */
-       if (inbox || (*box->name != '\0' && stat(box->path, &st) == 0)) {
+       root_dir = mailbox_list_get_path(box->list, NULL,
+                                        MAILBOX_LIST_PATH_TYPE_MAILBOX);
+       if (strcmp(box->path, root_dir) == 0) {
+               /* root directory. either INBOX or some other namespace root */
+               errno = ENOENT;
+       } else if (stat(box->path, &st) == 0) {
                /* yes, we'll need to create the missing dirs */
                if (create_maildir(box, TRUE) < 0)
                        return -1;
 
                return maildir_mailbox_open_existing(box);
-       } else if (*box->name == '\0' || errno == ENOENT) {
+       }
+
+       if (errno == ENOENT) {
                mail_storage_set_error(box->storage, MAIL_ERROR_NOTFOUND,
                        T_MAIL_ERR_MAILBOX_NOT_FOUND(box->name));
                return -1;
index 899dd02d1f0dd0cc136fc8ace63897769a5569dd..3adf0bffca093a997f2cc07d7f02bd545ca2a0af 100644 (file)
@@ -348,7 +348,7 @@ mbox_dotlock_log_eacces_error(struct mbox_mailbox *mbox, const char *path)
        errmsg = eacces_error_get_creating("file_dotlock_create", path);
        dir = strrchr(path, '/');
        dir = dir == NULL ? "." : t_strdup_until(path, dir);
-       if (strcmp(mbox->box.name, "INBOX") != 0) {
+       if (!mbox->box.inbox) {
                mail_storage_set_critical(&mbox->storage->storage,
                        "%s (not INBOX -> no privileged locking)", errmsg);
        } else if (!mbox->mbox_privileged_locking) {
index 3bd6e5da28e40119f6f2290aab6874e13290d985..f22f2db62cc89a719fdeea8879c6f01b41633cbd 100644 (file)
@@ -364,44 +364,42 @@ mbox_mailbox_alloc(struct mail_storage *storage, struct mailbox_list *list,
        return &mbox->box;
 }
 
-static int verify_inbox(struct mailbox_list *list)
+static int create_inbox(struct mailbox *box)
 {
        const char *inbox_path, *rootdir;
        int fd;
 
-       inbox_path = mailbox_list_get_path(list, "INBOX",
+       inbox_path = mailbox_list_get_path(box->list, "INBOX",
                                           MAILBOX_LIST_PATH_TYPE_MAILBOX);
-       rootdir = mailbox_list_get_path(list, NULL,
+       rootdir = mailbox_list_get_path(box->list, NULL,
                                        MAILBOX_LIST_PATH_TYPE_DIR);
 
-       /* make sure inbox file itself exists */
-       fd = open(inbox_path, O_RDWR | O_CREAT | O_EXCL, 0660);
+       fd = open(inbox_path, O_RDWR | O_CREAT, 0660);
        if (fd == -1 && errno == EACCES) {
                /* try again with increased privileges */
                (void)restrict_access_use_priv_gid();
                fd = open(inbox_path, O_RDWR | O_CREAT | O_EXCL, 0660);
                restrict_access_drop_priv_gid();
        }
-       if (fd != -1)
+       if (fd != -1) {
                (void)close(fd);
-       else if (errno == ENOTDIR &&
+               return 0;
+       } else if (errno == ENOTDIR &&
                 strncmp(inbox_path, rootdir, strlen(rootdir)) == 0) {
-               mailbox_list_set_critical(list,
+               mail_storage_set_critical(box->storage,
                        "mbox root directory can't be a file: %s "
                        "(http://wiki.dovecot.org/MailLocation/Mbox)",
                        rootdir);
                return -1;
        } else if (errno == EACCES) {
-               mailbox_list_set_critical(list, "%s",
+               mail_storage_set_critical(box->storage,"%s",
                        mail_error_create_eacces_msg("open", inbox_path));
                return -1;
-       } else if (errno != EEXIST) {
-               mailbox_list_set_critical(list,
+       } else {
+               mail_storage_set_critical(box->storage,
                        "open(%s, O_CREAT) failed: %m", inbox_path);
                return -1;
        }
-
-       return 0;
 }
 
 static void mbox_lock_touch_timeout(struct mbox_mailbox *mbox)
@@ -424,7 +422,7 @@ static int mbox_mailbox_open_existing(struct mbox_mailbox *mbox)
        }
        move_to_memory = want_memory_indexes(mbox->storage, box->path);
 
-       if (strcmp(box->name, "INBOX") == 0) {
+       if (box->inbox) {
                /* if INBOX isn't under the root directory, it's probably in
                   /var/mail and we want to allow privileged dotlocking */
                rootdir = mailbox_list_get_path(box->list, NULL,
@@ -459,14 +457,6 @@ static int mbox_mailbox_open(struct mailbox *box)
                return index_storage_mailbox_open(box, FALSE);
        }
 
-       if (strcmp(box->name, "INBOX") == 0 &&
-           (box->list->ns->flags & NAMESPACE_FLAG_INBOX) != 0) {
-               /* make sure INBOX exists */
-               if (verify_inbox(box->list) < 0)
-                       return -1;
-               return mbox_mailbox_open_existing(mbox);
-       }
-
        if ((ret = stat(box->path, &st)) == 0 && !S_ISDIR(st.st_mode))
                return mbox_mailbox_open_existing(mbox);
        else if (ret == 0) {
@@ -514,16 +504,22 @@ mbox_mailbox_create(struct mailbox *box, const struct mailbox_update *update,
            (box->list->props & MAILBOX_LIST_PROP_NO_NOSELECT) == 0)
                return 0;
 
-       /* create the mbox file */
-       ret = mailbox_create_fd(box, box->path, O_RDWR | O_CREAT | O_EXCL, &fd);
-       if (ret <= 0) {
+       if (box->inbox) {
+               if (create_inbox(box) < 0)
+                       return -1;
+       } else {
+               /* create the mbox file */
+               ret = mailbox_create_fd(box, box->path,
+                                       O_RDWR | O_CREAT | O_EXCL, &fd);
+               if (ret < 0)
+                       return -1;
                if (ret == 0) {
                        mail_storage_set_error(box->storage, MAIL_ERROR_EXISTS,
                                               "Mailbox already exists");
+                       return -1;
                }
-               return -1;
+               (void)close(fd);
        }
-       (void)close(fd);
        return update == NULL ? 0 : mbox_mailbox_update(box, update);
 }
 
index 3744cd61473948db2d874d615e29976672ef95b6..8f3b6cacbdd7b81bb169bc26cff8c7703ca5bf29 100644 (file)
@@ -338,7 +338,7 @@ static int
 maildir_list_create_mailbox_dir(struct mailbox_list *list, const char *name,
                                bool directory ATTR_UNUSED)
 {
-       const char *path, *gid_origin, *p;
+       const char *path, *root_dir, *gid_origin, *p;
        mode_t mode;
        gid_t gid;
        bool create_parent_dir;
@@ -355,23 +355,33 @@ maildir_list_create_mailbox_dir(struct mailbox_list *list, const char *name,
                path = t_strdup_until(path, p);
        }
 
+       root_dir = mailbox_list_get_path(list, NULL,
+                                        MAILBOX_LIST_PATH_TYPE_MAILBOX);
        mailbox_list_get_dir_permissions(list, NULL, &mode,
                                         &gid, &gid_origin);
        if (mkdir_parents_chgrp(path, mode, gid, gid_origin) == 0) {
                /* ok */
        } else if (errno == EEXIST) {
-               if (!create_parent_dir) {
-                       mailbox_list_set_error(list, MAIL_ERROR_EXISTS,
-                                              "Mailbox already exists");
-                       return -1;
+               if (create_parent_dir)
+                       return 0;
+               if (!directory) {
+                       if (strcmp(path, root_dir) == 0) {
+                               /* even though the root directory exists,
+                                  the mailbox might not */
+                               return 0;
+                       }
                }
+
+               mailbox_list_set_error(list, MAIL_ERROR_EXISTS,
+                                      "Mailbox already exists");
+               return -1;
        } else if (mailbox_list_set_error_from_errno(list)) {
                return -1;
        } else {
                mailbox_list_set_critical(list, "mkdir(%s) failed: %m", path);
                return -1;
        }
-       return create_parent_dir ? 0 :
+       return create_parent_dir || strcmp(path, root_dir) == 0 ? 0 :
                maildir_list_create_maildirfolder_file(list, path);
 }
 
index 112c96856598141a86faa76621dafb13cb388e67..5ed1cc0584d6bc918509af346955ededbd749888 100644 (file)
@@ -263,6 +263,8 @@ struct mailbox {
        unsigned int backend_readonly:1;
        /* Mailbox is being deleted */
        unsigned int deleting:1;
+       /* TRUE if this is the INBOX */
+       unsigned int inbox:1;
 };
 
 struct mail_vfuncs {
index c6618b2f9867ef7d2fc4ac199d6243f27fbca61f..f5895512214da4895708f2d564b580055d271263 100644 (file)
@@ -526,6 +526,14 @@ static int mailbox_open_full(struct mailbox *box, struct istream *input)
                ret = box->v.open(box);
        } T_END;
 
+       if (ret < 0 && box->storage->error == MAIL_ERROR_NOTFOUND &&
+           box->input == NULL && box->inbox) T_BEGIN {
+               /* INBOX should always exist. try to create it and retry. */
+               (void)mailbox_create(box, NULL, FALSE);
+               mailbox_close(box);
+               ret = box->v.open(box);
+       } T_END;
+
        if (ret < 0) {
                if (box->input != NULL)
                        i_stream_unref(&box->input);
@@ -635,8 +643,7 @@ int mailbox_delete(struct mailbox *box)
                                       "Storage root can't be deleted");
                return -1;
        }
-       if (strcmp(box->name, "INBOX") == 0 &&
-           (box->list->ns->flags & NAMESPACE_FLAG_INBOX) != 0) {
+       if (box->inbox) {
                mail_storage_set_error(box->storage, MAIL_ERROR_NOTPOSSIBLE,
                                       "INBOX can't be deleted.");
                return -1;