Mercurial > dovecot > core-2.2
changeset 890:079a620c0261 HEAD
CREATE and RENAME should create the folder hierarchy if needed. SELECTing a
folder gives now prettier error message.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Thu, 02 Jan 2003 15:01:52 +0200 |
parents | f6e6812bd872 |
children | fd754a6fa784 |
files | src/lib-storage/index/mbox/mbox-storage.c |
diffstat | 1 files changed, 70 insertions(+), 4 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-storage/index/mbox/mbox-storage.c Thu Jan 02 15:00:57 2003 +0200 +++ b/src/lib-storage/index/mbox/mbox-storage.c Thu Jan 02 15:01:52 2003 +0200 @@ -19,6 +19,35 @@ extern MailStorage mbox_storage; extern Mailbox mbox_mailbox; +static int mkdir_parents(const char *path) +{ + const char *p, *dir; + + p = path; + if (*p == '/') p++; + + do { + t_push(); + + p = strchr(p, '/'); + if (p == NULL) + dir = path; + else { + dir = t_strdup_until(path, p); + p++; + } + + if (mkdir(dir, CREATE_MODE) < 0 && errno != EEXIST) { + t_pop(); + return -1; + } + + t_pop(); + } while (p != NULL); + + return 0; +} + static int mbox_autodetect(const char *data) { const char *path; @@ -274,6 +303,12 @@ path = mbox_get_path(storage, name); if (stat(path, &st) == 0) { + if (S_ISDIR(st.st_mode)) { + mail_storage_set_error(storage, + "Mailbox isn't selectable: %s", name); + return NULL; + } + /* exists - make sure the required directories are also there */ (void)create_mbox_index_dirs(storage, name, TRUE); @@ -291,7 +326,7 @@ static int mbox_create_mailbox(MailStorage *storage, const char *name) { - const char *path; + const char *path, *p; struct stat st; int fd; @@ -312,12 +347,29 @@ return FALSE; } + if (errno == ENOTDIR) { + mail_storage_set_error(storage, + "Mailbox doesn't allow inferior mailboxes"); + return FALSE; + } + if (errno != ENOENT) { - mail_storage_set_critical(storage, "stat() failed for mbox " - "file %s: %m", path); + mail_storage_set_critical(storage, + "stat() failed for mbox file %s: %m", path); return FALSE; } + /* create the hierarchy if needed */ + p = strrchr(path, '/'); + if (p != NULL) { + if (mkdir_parents(t_strdup_until(path, p)) < 0) { + mail_storage_set_critical(storage, + "mkdir_parents() failed for mbox path " + "%s: %m", path); + return FALSE; + } + } + /* create the mailbox file */ fd = open(path, O_RDWR | O_CREAT | O_EXCL, 0660); if (fd != -1) { @@ -407,7 +459,7 @@ static int mbox_rename_mailbox(MailStorage *storage, const char *oldname, const char *newname) { - const char *oldpath, *newpath, *old_indexdir, *new_indexdir; + const char *oldpath, *newpath, *old_indexdir, *new_indexdir, *p; mail_storage_clear_error(storage); @@ -423,6 +475,17 @@ oldpath = mbox_get_path(storage, oldname); newpath = mbox_get_path(storage, newname); + /* create the hierarchy */ + p = strrchr(newpath, '/'); + if (p != NULL) { + if (mkdir_parents(t_strdup_until(newpath, p)) < 0) { + mail_storage_set_critical(storage, + "mkdir_parents() failed for mbox path %s: %m", + newpath); + return FALSE; + } + } + /* NOTE: renaming INBOX works just fine with us, it's simply created the next time it's needed. */ if (link(oldpath, newpath) == 0) @@ -468,6 +531,9 @@ } else if (errno == ENOENT) { *status = MAILBOX_NAME_VALID; return TRUE; + } else if (errno == ENOTDIR) { + *status = MAILBOX_NAME_NOINFERIORS; + return TRUE; } else { mail_storage_set_critical(storage, "mailbox name status: " "stat(%s) failed: %m", path);