#include <stdio.h>
#include <dirent.h>
#include <unistd.h>
+#include <utime.h>
void dbox_storage_get_list_settings(const struct mail_namespace *ns ATTR_UNUSED,
struct mailbox_list_settings *set)
/* 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);
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,