maildir-util.c revision 7ccdf78cd45aea9d14e048a5b9f077515c71978f
89a126810703c666309310d0f3189e9834d70b5bTimo Sirainen/* Copyright (c) 2004-2007 Dovecot authors, see the included COPYING file */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "lib.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "ioloop.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "str.h"
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen#include "mkdir-parents.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "maildir-storage.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "maildir-uidlist.h"
5fb3bff645380804c9db2510940c41db6b8fdb01Timo Sirainen#include "maildir-sync.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include <unistd.h>
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen#include <dirent.h>
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include <fcntl.h>
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen#include <utime.h>
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include <sys/stat.h>
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
7ccdf78cd45aea9d14e048a5b9f077515c71978fTimo Sirainen#define MAILDIR_RESYNC_RETRY_COUNT 10
7ccdf78cd45aea9d14e048a5b9f077515c71978fTimo Sirainen
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainenstatic int maildir_file_do_try(struct maildir_mailbox *mbox, uint32_t uid,
00efa7d99981e18e286c02b18c1163dde18ee521Timo Sirainen maildir_file_do_func *callback, void *context)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const char *fname, *path;
641f0c0900ee6e7cf9667f4b40ed95cec7d0cdcaTimo Sirainen enum maildir_uidlist_rec_flag flags;
641f0c0900ee6e7cf9667f4b40ed95cec7d0cdcaTimo Sirainen int ret;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen fname = maildir_uidlist_lookup(mbox->uidlist, uid, &flags);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (fname == NULL)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -2; /* expunged */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
2f2823ad8928654ed405467c6c1f4fd4c6f5cf7cTimo Sirainen t_push();
641f0c0900ee6e7cf9667f4b40ed95cec7d0cdcaTimo Sirainen if ((flags & MAILDIR_UIDLIST_REC_FLAG_NEW_DIR) != 0) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* probably in new/ dir */
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen path = t_strconcat(mbox->path, "/new/", fname, NULL);
00efa7d99981e18e286c02b18c1163dde18ee521Timo Sirainen ret = callback(mbox, path, context);
2f2823ad8928654ed405467c6c1f4fd4c6f5cf7cTimo Sirainen if (ret != 0) {
2f2823ad8928654ed405467c6c1f4fd4c6f5cf7cTimo Sirainen t_pop();
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return ret;
2f2823ad8928654ed405467c6c1f4fd4c6f5cf7cTimo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen path = t_strconcat(mbox->path, "/cur/", fname, NULL);
00efa7d99981e18e286c02b18c1163dde18ee521Timo Sirainen ret = callback(mbox, path, context);
2f2823ad8928654ed405467c6c1f4fd4c6f5cf7cTimo Sirainen t_pop();
2f2823ad8928654ed405467c6c1f4fd4c6f5cf7cTimo Sirainen return ret;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
825f6569a5276488133796c2f529c65128a09ba0Timo Sirainenstatic int do_racecheck(struct maildir_mailbox *mbox, const char *path,
43d32cbe60fdaef2699d99f1ca259053e9350411Timo Sirainen void *context ATTR_UNUSED)
825f6569a5276488133796c2f529c65128a09ba0Timo Sirainen{
825f6569a5276488133796c2f529c65128a09ba0Timo Sirainen struct stat st;
825f6569a5276488133796c2f529c65128a09ba0Timo Sirainen
825f6569a5276488133796c2f529c65128a09ba0Timo Sirainen if (lstat(path, &st) == 0 && (st.st_mode & S_IFLNK) != 0) {
825f6569a5276488133796c2f529c65128a09ba0Timo Sirainen /* most likely a symlink pointing to a non-existing file */
825f6569a5276488133796c2f529c65128a09ba0Timo Sirainen mail_storage_set_critical(&mbox->storage->storage,
825f6569a5276488133796c2f529c65128a09ba0Timo Sirainen "Maildir: Symlink destination doesn't exist: %s", path);
825f6569a5276488133796c2f529c65128a09ba0Timo Sirainen return -2;
825f6569a5276488133796c2f529c65128a09ba0Timo Sirainen } else {
825f6569a5276488133796c2f529c65128a09ba0Timo Sirainen mail_storage_set_critical(&mbox->storage->storage,
825f6569a5276488133796c2f529c65128a09ba0Timo Sirainen "maildir_file_do(%s): Filename keeps changing", path);
825f6569a5276488133796c2f529c65128a09ba0Timo Sirainen return -1;
825f6569a5276488133796c2f529c65128a09ba0Timo Sirainen }
825f6569a5276488133796c2f529c65128a09ba0Timo Sirainen}
825f6569a5276488133796c2f529c65128a09ba0Timo Sirainen
59151b71059df1190acd75d8717ed04a7920c862Timo Sirainen#undef maildir_file_do
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainenint maildir_file_do(struct maildir_mailbox *mbox, uint32_t uid,
00efa7d99981e18e286c02b18c1163dde18ee521Timo Sirainen maildir_file_do_func *callback, void *context)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen int i, ret;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
00efa7d99981e18e286c02b18c1163dde18ee521Timo Sirainen ret = maildir_file_do_try(mbox, uid, callback, context);
7ccdf78cd45aea9d14e048a5b9f077515c71978fTimo Sirainen for (i = 0; i < MAILDIR_RESYNC_RETRY_COUNT && ret == 0; i++) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* file is either renamed or deleted. sync the maildir and
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen see which one. if file appears to be renamed constantly,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen don't try to open it more than 10 times. */
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen if (maildir_storage_sync_force(mbox) < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
00efa7d99981e18e286c02b18c1163dde18ee521Timo Sirainen ret = maildir_file_do_try(mbox, uid, callback, context);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
7ccdf78cd45aea9d14e048a5b9f077515c71978fTimo Sirainen if (i == MAILDIR_RESYNC_RETRY_COUNT)
825f6569a5276488133796c2f529c65128a09ba0Timo Sirainen ret = maildir_file_do_try(mbox, uid, do_racecheck, context);
039e42997fe5e0d1c5ad9306dc0ae69bf0e1ca10Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return ret == -2 ? 0 : ret;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainenvoid maildir_tmp_cleanup(struct mail_storage *storage, const char *dir)
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen{
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen DIR *dirp;
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen struct dirent *d;
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen struct stat st;
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen string_t *path;
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen unsigned int dir_len;
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen dirp = opendir(dir);
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen if (dirp == NULL) {
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen if (errno != ENOENT) {
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen mail_storage_set_critical(storage,
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen "opendir(%s) failed: %m", dir);
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen }
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen return;
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen }
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen t_push();
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen path = t_str_new(256);
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen str_printfa(path, "%s/", dir);
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen dir_len = str_len(path);
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen while ((d = readdir(dirp)) != NULL) {
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen if (d->d_name[0] == '.' &&
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen (d->d_name[1] == '\0' ||
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen (d->d_name[1] == '.' && d->d_name[2] == '\0'))) {
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen /* skip . and .. */
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen continue;
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen }
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen str_truncate(path, dir_len);
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen str_append(path, d->d_name);
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen if (stat(str_c(path), &st) < 0) {
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen if (errno != ENOENT) {
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen mail_storage_set_critical(storage,
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen "stat(%s) failed: %m", str_c(path));
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen }
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen } else if (st.st_ctime <=
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen ioloop_time - MAILDIR_TMP_DELETE_SECS) {
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen if (unlink(str_c(path)) < 0 && errno != ENOENT) {
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen mail_storage_set_critical(storage,
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen "unlink(%s) failed: %m", str_c(path));
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen }
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen }
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen }
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen t_pop();
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen#ifdef HAVE_DIRFD
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen if (fstat(dirfd(dirp), &st) < 0) {
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen mail_storage_set_critical(storage,
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen "fstat(%s) failed: %m", dir);
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen }
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen#else
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen if (stat(dir, &st) < 0) {
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen mail_storage_set_critical(storage,
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen "stat(%s) failed: %m", dir);
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen }
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen#endif
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen else if (st.st_atime < ioloop_time) {
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen /* mounted with noatime. update it ourself. */
1ec927ba3bb5a904754219c2dd5e2514ea77a6f8Timo Sirainen if (utime(dir, NULL) < 0 && errno != ENOENT) {
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen mail_storage_set_critical(storage,
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen "utime(%s) failed: %m", dir);
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen }
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen }
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen if (closedir(dirp) < 0) {
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen mail_storage_set_critical(storage,
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen "closedir(%s) failed: %m", dir);
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen }
73a552a9ed06cd6017ad4ee4b252a8b38c8ac42dTimo Sirainen}
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainenstatic int maildir_create_subdirs(struct maildir_mailbox *mbox)
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen{
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen static const char *subdirs[] = { "cur", "new", "tmp" };
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen const char *dirs[N_ELEMENTS(subdirs) + 2];
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen struct mailbox *box = &mbox->ibox.box;
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen struct stat st;
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen const char *path;
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen unsigned int i;
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen t_push();
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen /* @UNSAFE: get a list of directories we want to create */
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen for (i = 0; i < N_ELEMENTS(subdirs); i++)
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen dirs[i] = t_strconcat(mbox->path, "/", subdirs[i], NULL);
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen dirs[i++] = mail_storage_get_mailbox_control_dir(box->storage,
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen box->name);
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen dirs[i++] = mail_storage_get_mailbox_index_dir(box->storage,
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen box->name);
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen i_assert(i == N_ELEMENTS(dirs));
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen for (i = 0; i < N_ELEMENTS(dirs); i++) {
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen path = dirs[i];
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen if (path == NULL || stat(path, &st) == 0)
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen continue;
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen if (errno != ENOENT) {
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen mail_storage_set_critical(box->storage,
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen "stat(%s) failed: %m", path);
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen break;
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen }
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen if (mkdir_parents(path, box->dir_create_mode) < 0 &&
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen errno != EEXIST) {
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen if (errno == ENOENT) {
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen /* mailbox was being deleted just now */
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen mailbox_set_deleted(box);
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen break;
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen }
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen mail_storage_set_critical(box->storage,
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen "mkdir(%s) failed: %m", path);
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen break;
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen }
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen }
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen t_pop();
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen return i == N_ELEMENTS(dirs) ? 0 : -1;
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen}
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainenbool maildir_set_deleted(struct maildir_mailbox *mbox)
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen{
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen struct mailbox *box = &mbox->ibox.box;
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen struct stat st;
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen if (stat(mbox->path, &st) < 0) {
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen if (errno == ENOENT)
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen mailbox_set_deleted(box);
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen else {
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen mail_storage_set_critical(box->storage,
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen "stat(%s) failed: %m", mbox->path);
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen }
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen return TRUE;
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen }
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen /* maildir itself exists. create all of its subdirectories in case
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen they got lost. */
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen return maildir_create_subdirs(mbox) < 0 ? TRUE : FALSE;
32ee977e189266744ef69ac4e832fd3111d6f949Timo Sirainen}