]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Maildir: CONTROL=<dir> in MAIL environment now specifies where to save
authorTimo Sirainen <tss@iki.fi>
Sat, 17 May 2003 13:09:54 +0000 (16:09 +0300)
committerTimo Sirainen <tss@iki.fi>
Sat, 17 May 2003 13:09:54 +0000 (16:09 +0300)
.customflags and dovecot-uidlist files. This can be useful if the main
mail directory is under hard quota.

--HG--
branch : HEAD

src/lib-index/mail-custom-flags.c
src/lib-index/mail-index.c
src/lib-index/mail-index.h
src/lib-index/maildir/maildir-index.c
src/lib-index/maildir/maildir-index.h
src/lib-index/maildir/maildir-uidlist.c
src/lib-index/mbox/mbox-index.c
src/lib-index/mbox/mbox-index.h
src/lib-storage/index/maildir/maildir-storage.c
src/lib-storage/index/mbox/mbox-storage.c
src/lib-storage/mail-storage.h

index e89dbf5e2d9068d56ccc629c2ac811a09502e1dd..9b2b52328fa57f1b24c452acb8c251cbe0726c17 100644 (file)
@@ -238,7 +238,7 @@ int mail_custom_flags_open_or_create(struct mail_index *index)
        const char *path;
        int fd;
 
-       path = t_strconcat(index->custom_flags_dir, "/",
+       path = t_strconcat(index->control_dir, "/",
                           CUSTOM_FLAGS_FILE_NAME, NULL);
        if (path == NULL)
                fd = -1;
index 32430fd72e0a0f05d8d1aafa6f3b9c5566d42a25..60059e673004c701b213deb2b86dc33016344549 100644 (file)
@@ -170,9 +170,9 @@ void mail_index_close(struct mail_index *index)
                 index->custom_flags = NULL;
        }
 
-       if (index->custom_flags_dir != NULL) {
-               i_free(index->custom_flags_dir);
-                index->custom_flags_dir = NULL;
+       if (index->control_dir != NULL) {
+               i_free(index->control_dir);
+                index->control_dir = NULL;
        }
 
        if (index->error != NULL) {
index 21cb3b7df0ebb0f825e55e95aa6317d78b046ddc..21ef3efc43b9b6ec573d456dc4d097a7ec711062 100644 (file)
@@ -370,7 +370,7 @@ struct mail_index {
        char *dir; /* directory where to place the index files */
        char *filepath; /* index file path */
        char *mailbox_path; /* file/directory for mailbox location */
-       char *custom_flags_dir; /* destination for .customflags file */
+       char *control_dir; /* destination for control files */
        enum mail_data_field default_cache_fields, never_cache_fields;
        unsigned int indexid;
        unsigned int sync_id;
index 876062959f9eb09717a5a2d882f219cd47f52951..cf39f3e70895162d1a1a4282b00aa7082e867723 100644 (file)
@@ -205,7 +205,9 @@ const char *maildir_filename_set_flags(const char *fname, enum mail_flags flags)
        return str_c(flags_str);
 }
 
-struct mail_index *maildir_index_alloc(const char *dir, const char *maildir)
+struct mail_index *
+maildir_index_alloc(const char *maildir, const char *index_dir,
+                   const char *control_dir)
 {
        struct mail_index *index;
 
@@ -216,7 +218,8 @@ struct mail_index *maildir_index_alloc(const char *dir, const char *maildir)
 
        index->maildir_lock_fd = -1;
        index->mailbox_path = i_strdup(maildir);
-       mail_index_init(index, dir);
+       index->control_dir = i_strdup(control_dir);
+       mail_index_init(index, index_dir);
        return index;
 }
 
index a5b02da49991cb09e1d4e837c2e9ca0c47e0349a..cce7b7127f5f5048c97dec53faa45b34d0b67ecb 100644 (file)
@@ -8,7 +8,9 @@
 /* ":2,DFRST" - leave the 2 extra for other clients' additions */
 #define MAILDIR_LOCATION_EXTRA_SPACE 10
 
-struct mail_index *maildir_index_alloc(const char *dir, const char *maildir);
+struct mail_index *
+maildir_index_alloc(const char *maildir, const char *index_dir,
+                   const char *control_dir);
 
 /* Return new filename base to save into tmp/ */
 const char *maildir_generate_tmp_filename(const struct timeval *tv);
index 2bb8547a9a60f80eda804e18241662a8941137ed..29a66db5121e20b26d29aec6e63b02c11be4ff88 100644 (file)
@@ -25,7 +25,7 @@ int maildir_uidlist_try_lock(struct mail_index *index)
 
        i_assert(!INDEX_IS_UIDLIST_LOCKED(index));
 
-       path = t_strconcat(index->mailbox_path,
+       path = t_strconcat(index->control_dir,
                           "/" MAILDIR_UIDLIST_NAME ".lock", NULL);
        for (i = 0; i < 2; i++) {
                fd = open(path, O_WRONLY | O_CREAT | O_EXCL, 0644);
@@ -70,7 +70,7 @@ void maildir_uidlist_unlock(struct mail_index *index)
        if (!INDEX_IS_UIDLIST_LOCKED(index))
                return;
 
-       path = t_strconcat(index->mailbox_path,
+       path = t_strconcat(index->control_dir,
                           "/" MAILDIR_UIDLIST_NAME ".lock", NULL);
        if (unlink(path) < 0 && errno != ENOENT)
                index_file_set_syscall_error(index, path, "unlink()");
@@ -87,7 +87,7 @@ struct maildir_uidlist *maildir_uidlist_open(struct mail_index *index)
        unsigned int version;
        int fd;
 
-       path = t_strconcat(index->mailbox_path, "/" MAILDIR_UIDLIST_NAME, NULL);
+       path = t_strconcat(index->control_dir, "/" MAILDIR_UIDLIST_NAME, NULL);
        fd = open(path, O_RDONLY);
        if (fd == -1) {
                if (errno != ENOENT)
@@ -243,7 +243,7 @@ int maildir_uidlist_rewrite(struct mail_index *index, time_t *mtime)
                        return FALSE;
        }
 
-       temp_path = t_strconcat(index->mailbox_path,
+       temp_path = t_strconcat(index->control_dir,
                                "/" MAILDIR_UIDLIST_NAME ".lock", NULL);
 
        failed = !maildir_uidlist_rewrite_fd(index, temp_path, mtime);
@@ -254,7 +254,7 @@ int maildir_uidlist_rewrite(struct mail_index *index, time_t *mtime)
         index->maildir_lock_fd = -1;
 
        if (!failed) {
-               db_path = t_strconcat(index->mailbox_path,
+               db_path = t_strconcat(index->control_dir,
                                      "/" MAILDIR_UIDLIST_NAME, NULL);
 
                if (rename(temp_path, db_path) < 0) {
index 0184a68eee62e46e73631b5218cff092c4d5451e..e6b8b8f0b84ed76fa7a7811bf1aca082737de233 100644 (file)
@@ -744,7 +744,9 @@ int mbox_mail_get_location(struct mail_index *index,
        return TRUE;
 }
 
-struct mail_index *mbox_index_alloc(const char *dir, const char *mbox_path)
+struct mail_index *
+mbox_index_alloc(const char *mbox_path, const char *index_dir,
+                const char *control_dir)
 {
        struct mail_index *index;
 
@@ -758,7 +760,8 @@ struct mail_index *mbox_index_alloc(const char *dir, const char *mbox_path)
        index->mailbox_readonly = access(mbox_path, W_OK) < 0;
 
        index->mailbox_path = i_strdup(mbox_path);
-       mail_index_init(index, dir);
+       index->control_dir = i_strdup(control_dir);
+       mail_index_init(index, index_dir);
        return index;
 }
 
index 8be223dc332edf59a9d3a344dac6748669babad4..4d9b44bc85594c2a847b5bf6889b01c02e6c927e 100644 (file)
@@ -52,7 +52,9 @@ int mbox_mail_get_location(struct mail_index *index,
                           struct mail_index_record *rec,
                           uoff_t *offset, uoff_t *hdr_size, uoff_t *body_size);
 
-struct mail_index *mbox_index_alloc(const char *dir, const char *mbox_path);
+struct mail_index *
+mbox_index_alloc(const char *mbox_path, const char *index_dir,
+                const char *control_dir);
 int mbox_index_rebuild(struct mail_index *index);
 int mbox_index_sync(struct mail_index *index,
                    enum mail_lock_type lock_type, int *changes);
index 8d1ab894ba841b7ee6e3611347c437982d3442c6..957ced5d99c6ef61fae11c821305f93a6509fa52 100644 (file)
@@ -28,9 +28,9 @@ static const char *maildirs[] = { "cur", "new", "tmp", NULL  };
 static struct mail_storage *maildir_create(const char *data, const char *user)
 {
        struct mail_storage *storage;
-       const char *home, *path, *root_dir, *index_dir, *p;
+       const char *home, *path, *root_dir, *index_dir, *control_dir, *p;
 
-       root_dir = index_dir = NULL;
+       root_dir = index_dir = control_dir = NULL;
 
        if (data == NULL || *data == '\0') {
                /* we'll need to figure out the maildir location ourself.
@@ -47,16 +47,21 @@ static struct mail_storage *maildir_create(const char *data, const char *user)
                        }
                }
        } else {
-               /* <Maildir> [:INDEX=<dir>] */
+               /* <Maildir> [:INDEX=<dir>] [:CONTROL=<dir>] */
                p = strchr(data, ':');
                if (p == NULL)
                        root_dir = data;
                else {
                        root_dir = t_strdup_until(data, p);
 
-                       p++;
-                       if (strncmp(p, "INDEX=", 6) == 0)
-                               index_dir = t_strcut(p+6, ':');
+                       do {
+                               p++;
+                               if (strncmp(p, "INDEX=", 6) == 0)
+                                       index_dir = t_strcut(p+6, ':');
+                               else if (strncmp(p, "CONTROL=", 8) == 0)
+                                       control_dir = t_strcut(p+8, ':');
+                               p = strchr(p, ':');
+                       } while (p != NULL);
                }
        }
 
@@ -73,6 +78,7 @@ static struct mail_storage *maildir_create(const char *data, const char *user)
 
        storage->dir = i_strdup(root_dir);
        storage->index_dir = i_strdup(index_dir);
+       storage->control_dir = i_strdup(control_dir);
        storage->user = i_strdup(user);
        storage->callbacks = i_new(struct mail_storage_callbacks, 1);
        return storage;
@@ -82,6 +88,7 @@ static void maildir_free(struct mail_storage *storage)
 {
        i_free(storage->dir);
        i_free(storage->index_dir);
+       i_free(storage->control_dir);
        i_free(storage->user);
        i_free(storage->error);
        i_free(storage->callbacks);
@@ -160,20 +167,43 @@ static const char *maildir_get_index_path(struct mail_storage *storage,
        return t_strconcat(storage->index_dir, "/.", name, NULL);
 }
 
+static const char *maildir_get_control_path(struct mail_storage *storage,
+                                           const char *name)
+{
+       if (storage->control_dir == NULL)
+               return maildir_get_path(storage, name);
+
+       if (full_filesystem_access && (*name == '/' || *name == '~'))
+               return maildir_get_absolute_path(name);
+
+       return t_strconcat(storage->control_dir, "/.", name, NULL);
+}
+
 /* create or fix maildir, ignore if it already exists */
-static int create_maildir(const char *dir, int verify)
+static int create_maildir(struct mail_storage *storage,
+                         const char *dir, int verify)
 {
        const char **tmp, *path;
 
-       if (mkdir(dir, CREATE_MODE) == -1 && (errno != EEXIST || !verify))
+       if (mkdir(dir, CREATE_MODE) < 0 && (errno != EEXIST || !verify)) {
+               if (errno != EEXIST) {
+                       mail_storage_set_critical(storage,
+                                                 "mkdir(%s) failed: %m", dir);
+               }
                return FALSE;
+       }
 
        for (tmp = maildirs; *tmp != NULL; tmp++) {
                path = t_strconcat(dir, "/", *tmp, NULL);
 
-               if (mkdir(path, CREATE_MODE) == -1 &&
-                   (errno != EEXIST || !verify))
+               if (mkdir(path, CREATE_MODE) < 0 &&
+                   (errno != EEXIST || !verify)) {
+                       if (errno != EEXIST) {
+                               mail_storage_set_critical(storage,
+                                       "mkdir(%s) failed: %m", dir);
+                       }
                        return FALSE;
+               }
        }
 
        return TRUE;
@@ -191,8 +221,23 @@ static int create_index_dir(struct mail_storage *storage, const char *name)
 
        dir = t_strconcat(storage->index_dir, "/.", name, NULL);
        if (mkdir(dir, CREATE_MODE) == -1 && errno != EEXIST) {
-               mail_storage_set_critical(storage,
-                                         "Can't create directory %s: %m", dir);
+               mail_storage_set_critical(storage, "mkdir(%s) failed: %m", dir);
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
+static int create_control_dir(struct mail_storage *storage, const char *name)
+{
+       const char *dir;
+
+       if (storage->control_dir == NULL)
+               return TRUE;
+
+       dir = t_strconcat(storage->control_dir, "/.", name, NULL);
+       if (mkdir(dir, CREATE_MODE) < 0 && errno != EEXIST) {
+               mail_storage_set_critical(storage, "mkdir(%s) failed: %m", dir);
                return FALSE;
        }
 
@@ -204,18 +249,20 @@ static int verify_inbox(struct mail_storage *storage)
        const char *inbox;
 
        /* first make sure the cur/ new/ and tmp/ dirs exist in root dir */
-       (void)create_maildir(storage->dir, TRUE);
+       if (!create_maildir(storage, storage->dir, TRUE))
+               return FALSE;
 
        /* create the .INBOX directory */
        inbox = t_strconcat(storage->dir, "/.INBOX", NULL);
-       if (mkdir(inbox, CREATE_MODE) == -1 && errno != EEXIST) {
-               mail_storage_set_critical(storage, "Can't create directory "
-                                         "%s: %m", inbox);
+       if (mkdir(inbox, CREATE_MODE) < 0 && errno != EEXIST) {
+               mail_storage_set_critical(storage, "mkdir(%s) failed: %m",
+                                         inbox);
                return FALSE;
        }
 
        /* make sure the index directories exist */
-       return create_index_dir(storage, "INBOX");
+       return create_index_dir(storage, "INBOX") &&
+               create_control_dir(storage, "INBOX");
 }
 
 static struct mailbox *
@@ -224,15 +271,15 @@ maildir_open(struct mail_storage *storage, const char *name,
 {
        struct index_mailbox *ibox;
        struct mail_index *index;
-       const char *path, *index_dir;
+       const char *path, *index_dir, *control_dir;
 
        path = maildir_get_path(storage, name);
        index_dir = maildir_get_index_path(storage, name);
+       control_dir = maildir_get_control_path(storage, name);
 
        index = index_storage_lookup_ref(index_dir);
        if (index == NULL) {
-               index = maildir_index_alloc(index_dir, path);
-               index->custom_flags_dir = i_strdup(path);
+               index = maildir_index_alloc(path, index_dir, control_dir);
                index_storage_add(index);
        }
 
@@ -280,10 +327,10 @@ maildir_open_mailbox(struct mail_storage *storage,
        path = maildir_get_path(storage, name);
        if (stat(path, &st) == 0) {
                /* exists - make sure the required directories are also there */
-               (void)create_maildir(path, TRUE);
-
-               /* make sure the index directories exist */
-               (void)create_index_dir(storage, name);
+               if (!create_maildir(storage, path, TRUE) ||
+                   !create_index_dir(storage, name) ||
+                   !create_control_dir(storage, name))
+                       return FALSE;
 
                return maildir_open(storage, name, readonly, fast);
        } else if (errno == ENOENT) {
@@ -291,8 +338,7 @@ maildir_open_mailbox(struct mail_storage *storage,
                                       name);
                return NULL;
        } else {
-               mail_storage_set_critical(storage, "Can't open mailbox %s: %m",
-                                         name);
+               mail_storage_set_critical(storage, "stat(%s) failed: %m", path);
                return NULL;
        }
 }
@@ -316,16 +362,15 @@ static int maildir_create_mailbox(struct mail_storage *storage,
        }
 
        path = maildir_get_path(storage, name);
-       if (create_maildir(path, FALSE))
-               return TRUE;
-       else if (errno == EEXIST) {
-               mail_storage_set_error(storage, "Mailbox already exists");
-               return FALSE;
-       } else {
-               mail_storage_set_critical(storage, "Can't create mailbox "
-                                         "%s: %m", name);
+       if (!create_maildir(storage, path, FALSE)) {
+               if (errno == EEXIST) {
+                       mail_storage_set_error(storage,
+                                              "Mailbox already exists");
+               }
                return FALSE;
        }
+
+       return TRUE;
 }
 
 static int maildir_delete_mailbox(struct mail_storage *storage,
@@ -458,7 +503,8 @@ static int rename_subfolders(struct mail_storage *storage,
                    errno == EEXIST || errno == ENOTEMPTY)
                        ret = 1;
                else {
-                       mail_storage_set_critical(storage, "rename(%s, %s) failed: %m",
+                       mail_storage_set_critical(storage,
+                                                 "rename(%s, %s) failed: %m",
                                                  oldpath, newpath);
                        ret = -1;
                        t_pop();
@@ -502,8 +548,7 @@ static int maildir_rename_mailbox(struct mail_storage *storage,
 
        ret = rename(oldpath, newpath);
        if (ret == 0 || errno == ENOENT) {
-               if (!rename_indexes(storage, oldname, newname))
-                       return FALSE;
+               (void)rename_indexes(storage, oldname, newname);
 
                found = ret == 0;
                ret = rename_subfolders(storage, oldname, newname);
@@ -559,8 +604,7 @@ static int maildir_get_mailbox_name_status(struct mail_storage *storage,
                *status = MAILBOX_NAME_VALID;
                return TRUE;
        } else {
-               mail_storage_set_critical(storage, "mailbox name status: "
-                                         "stat(%s) failed: %m", path);
+               mail_storage_set_critical(storage, "stat(%s) failed: %m", path);
                return FALSE;
        }
 }
@@ -609,7 +653,7 @@ struct mail_storage maildir_storage = {
        NULL,
        NULL,
        NULL,
-       NULL, NULL,
+       NULL, NULL, NULL,
 
        0
 };
index c5939a7d910283f6a15d13a0f2c0ef15a2ac517a..81cd577de0ce60544cc645c506d9f0b2b0aa06ca 100644 (file)
@@ -358,8 +358,7 @@ static struct mailbox *mbox_open(struct mail_storage *storage, const char *name,
 
        index = index_storage_lookup_ref(index_dir);
        if (index == NULL) {
-               index = mbox_index_alloc(index_dir, path);
-               index->custom_flags_dir = i_strdup(index_dir);
+               index = mbox_index_alloc(path, index_dir, index_dir);
                index_storage_add(index);
        }
 
@@ -724,7 +723,7 @@ struct mail_storage mbox_storage = {
        NULL,
        NULL,
        NULL,
-       NULL, NULL,
+       NULL, NULL, NULL,
 
        0
 };
index e82596e2a70048a20c10c3181de005565f0690b1..b816d5398792a685752d862657275f2e936506c8 100644 (file)
@@ -201,6 +201,7 @@ struct mail_storage {
        char *dir; /* root directory */
        char *inbox_file; /* INBOX file for mbox */
        char *index_dir;
+       char *control_dir;
 
        char *user; /* name of user accessing the storage */
        char *error;