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
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? */
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 */
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;
}
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,