From: Timo Sirainen Date: Mon, 26 Jun 2017 16:06:26 +0000 (+0300) Subject: dbox: Check mailbox existence from index directory with ITERINDEX X-Git-Tag: 2.2.32.rc1~130 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ac9f468cfcc51a0878aa19021c0c51cdac7d5184;p=thirdparty%2Fdovecot%2Fcore.git dbox: Check mailbox existence from index directory with ITERINDEX --- diff --git a/src/lib-storage/index/dbox-common/dbox-storage.c b/src/lib-storage/index/dbox-common/dbox-storage.c index 463fdb18e8..8d890cb582 100644 --- a/src/lib-storage/index/dbox-common/dbox-storage.c +++ b/src/lib-storage/index/dbox-common/dbox-storage.c @@ -15,6 +15,7 @@ #include #include #include +#include void dbox_storage_get_list_settings(const struct mail_namespace *ns ATTR_UNUSED, struct mailbox_list_settings *set) @@ -178,10 +179,25 @@ dbox_cleanup_temp_files(struct mailbox_list *list, const char *path, /* not the time to scan it yet */ return FALSE; } else { + bool stated = FALSE; + if (last_change_time == (time_t)-1) { + /* Don't know the ctime yet - look it up. */ + struct stat st; + + if (stat(path, &st) < 0) { + if (errno == ENOENT) + i_error("stat(%s) failed: %m", path); + return FALSE; + } + last_change_time = st.st_ctime; + stated = TRUE; + } if (last_scan_time > last_change_time + DBOX_TMP_DELETE_SECS) { /* there haven't been any changes to this directory - since we last checked it. */ - return FALSE; + since we last checked it. If we did an extra stat(), + we need to update the last_scan_time to avoid + stat()ing the next time. */ + return stated; } const char *prefix = mailbox_list_get_global_temp_prefix(list); @@ -189,15 +205,41 @@ dbox_cleanup_temp_files(struct mailbox_list *list, const char *path, ioloop_time - DBOX_TMP_DELETE_SECS); return TRUE; } + return FALSE; } int dbox_mailbox_check_existence(struct mailbox *box, time_t *path_ctime_r) { - const char *box_path = mailbox_get_path(box); + const char *index_path, *box_path = mailbox_get_path(box); struct stat st; + int ret = -1; + + *path_ctime_r = (time_t)-1; + + if (box->list->set.iter_from_index_dir) { + /* Just because the index directory exists, it doesn't mean + that the mailbox is selectable. Check that by seeing if + dovecot.index.log exists. If it doesn't, fallback to + checking for the dbox-Mails in the mail root directory. + So this also means that if a mailbox is \NoSelect, listing + it will always do a stat() for dbox-Mails in the mail root + directory. That's not ideal, but this makes the behavior + safer and \NoSelect mailboxes are somewhat rare. */ + if (mailbox_get_path_to(box, MAILBOX_LIST_PATH_TYPE_INDEX, + &index_path) < 0) + return -1; + i_assert(index_path != NULL); + index_path = t_strconcat(index_path, "/", box->index_prefix, + ".log", NULL); + ret = stat(index_path, &st); + } + if (ret < 0) { + ret = stat(box_path, &st); + if (ret == 0) + *path_ctime_r = st.st_ctime; + } - if (stat(box_path, &st) == 0) { - *path_ctime_r = st.st_ctime; + if (ret == 0) { return 0; } else if (errno == ENOENT || errno == ENAMETOOLONG) { mail_storage_set_error(box->storage, MAIL_ERROR_NOTFOUND,