From: Timo Sirainen Date: Sun, 4 Apr 2010 23:56:11 +0000 (+0300) Subject: mailbox_list_mailbox(): Fixed INBOX and root dir lookups. X-Git-Tag: 2.0.beta5~222 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=b6eced3d628ad0c50a3cbc9f966da0edc20108ab;p=thirdparty%2Fdovecot%2Fcore.git mailbox_list_mailbox(): Fixed INBOX and root dir lookups. --HG-- branch : HEAD --- diff --git a/src/lib-storage/index/maildir/maildir-storage.c b/src/lib-storage/index/maildir/maildir-storage.c index 9d02890a7d..34fe49fdf1 100644 --- a/src/lib-storage/index/maildir/maildir-storage.c +++ b/src/lib-storage/index/maildir/maildir-storage.c @@ -521,8 +521,11 @@ maildir_list_get_mailbox_flags(struct mailbox_list *list, selectable mailbox we have 3 more links (cur/, new/ and tmp/) than non-selectable. */ cur_path = t_strconcat(dir, "/", fname, "/cur", NULL); - if (stat(cur_path, &st2) < 0 || !S_ISDIR(st2.st_mode)) { - *flags |= MAILBOX_NOSELECT; + if ((ret = stat(cur_path, &st2)) < 0 || !S_ISDIR(st2.st_mode)) { + if (ret < 0 && errno == ENOENT) + *flags |= MAILBOX_NONEXISTENT; + else + *flags |= MAILBOX_NOSELECT; if (st_r->st_nlink > 2) *flags |= MAILBOX_CHILDREN; else diff --git a/src/lib-storage/list/mailbox-list-maildir-iter.c b/src/lib-storage/list/mailbox-list-maildir-iter.c index fb5ed9771d..f6fd393137 100644 --- a/src/lib-storage/list/mailbox-list-maildir-iter.c +++ b/src/lib-storage/list/mailbox-list-maildir-iter.c @@ -174,7 +174,8 @@ maildir_get_type(const char *dir, const char *fname, const char *path; struct stat st; - path = t_strdup_printf("%s/%s", dir, fname); + path = *fname == '\0' ? dir : + t_strdup_printf("%s/%s", dir, fname); if (stat(path, &st) < 0) { if (errno == ENOENT) { /* just deleted? */ @@ -215,7 +216,7 @@ int maildir_list_get_mailbox_flags(struct mailbox_list *list, case MAILBOX_LIST_FILE_TYPE_UNKNOWN: case MAILBOX_LIST_FILE_TYPE_SYMLINK: /* need to check with stat() to be sure */ - if (!list->mail_set->maildir_stat_dirs && + if (!list->mail_set->maildir_stat_dirs && *fname != '\0' && strcmp(list->name, MAILBOX_LIST_NAME_MAILDIRPLUSPLUS) == 0 && strncmp(fname, ".nfs", 4) != 0) { /* just assume it's a valid mailbox */ @@ -248,7 +249,12 @@ int maildir_list_get_mailbox_flags(struct mailbox_list *list, case MAILBOX_LIST_FILE_TYPE_SYMLINK: i_unreached(); } - *flags_r |= MAILBOX_SELECT; + if (*fname != '\0') { + /* this tells maildir storage code that it doesn't need to + see if cur/ exists, because just the existence of .dir/ + assumes that the mailbox exists. */ + *flags_r |= MAILBOX_SELECT; + } return 1; } diff --git a/src/lib-storage/mailbox-list.c b/src/lib-storage/mailbox-list.c index a113ee4366..2e304d6950 100644 --- a/src/lib-storage/mailbox-list.c +++ b/src/lib-storage/mailbox-list.c @@ -673,21 +673,32 @@ int mailbox_list_iter_deinit(struct mailbox_list_iterate_context **_ctx) int mailbox_list_mailbox(struct mailbox_list *list, const char *name, enum mailbox_info_flags *flags_r) { - const char *path, *fname; + const char *path, *fname, *rootdir; struct stat st; + unsigned int len; + rootdir = mailbox_list_get_path(list, NULL, + MAILBOX_LIST_PATH_TYPE_MAILBOX); path = mailbox_list_get_path(list, name, MAILBOX_LIST_PATH_TYPE_DIR); if (path == NULL) { /* shouldn't happen with anything except shared mailboxes */ return 0; } - fname = strrchr(path, '/'); - if (fname == NULL) { - fname = path; - path = "/"; + + len = strlen(rootdir); + if (strncmp(path, rootdir, len) == 0 && path[len] == '/') { + fname = strrchr(path, '/'); + if (fname == NULL) { + fname = path; + path = "/"; + } else { + path = t_strdup_until(path, fname); + fname++; + } } else { - path = t_strdup_until(path, fname); - fname++; + /* a) looking up INBOX that's elsewhere + b) looking up the root dir itself (as INBOX or "") */ + fname = ""; } return list->v.get_mailbox_flags(list, path, fname, MAILBOX_LIST_FILE_TYPE_UNKNOWN,