dovecot-2.0: maildir: If we see unwanted non-empty directories i...
dovecot at dovecot.org
dovecot at dovecot.org
Tue Sep 28 19:15:55 EEST 2010
details: http://hg.dovecot.org/dovecot-2.0/rev/cf1e5238f747
changeset: 12195:cf1e5238f747
user: Timo Sirainen <tss at iki.fi>
date: Tue Sep 28 17:15:52 2010 +0100
description:
maildir: If we see unwanted non-empty directories in new/ or cur/, move them to ../extra-*
diffstat:
src/lib-storage/index/maildir/maildir-mail.c | 25 +-----------
src/lib-storage/index/maildir/maildir-storage.h | 1 +
src/lib-storage/index/maildir/maildir-sync-index.c | 2 +
src/lib-storage/index/maildir/maildir-util.c | 52 ++++++++++++++++++++++++++
4 files changed, 57 insertions(+), 23 deletions(-)
diffs (132 lines):
diff -r 2bfe672e7c8a -r cf1e5238f747 src/lib-storage/index/maildir/maildir-mail.c
--- a/src/lib-storage/index/maildir/maildir-mail.c Tue Sep 28 17:09:50 2010 +0100
+++ b/src/lib-storage/index/maildir/maildir-mail.c Tue Sep 28 17:15:52 2010 +0100
@@ -58,22 +58,6 @@
return -1;
}
-static int
-maildir_rmdir_unexpected_dir(struct mail_storage *storage, const char *path)
-{
- if (rmdir(path) == 0) {
- mail_storage_set_critical(storage,
- "Maildir: rmdir()ed unwanted empty directory: %s",
- path);
- return 0;
- } else {
- mail_storage_set_critical(storage,
- "Maildir: Found unwanted directory %s, "
- "but rmdir() failed: %m", path);
- return -1;
- }
-}
-
static struct istream *
maildir_open_mail(struct maildir_mailbox *mbox, struct mail *mail,
bool *deleted_r)
@@ -105,14 +89,9 @@
input = i_stream_create_fd(ctx.fd, 0, TRUE);
if (input->stream_errno == EISDIR) {
- /* there's a directory in maildir. many installations seem to
- have messed up something and causing "cur", "new" and "tmp"
- directories to be created under the "cur" directory.
- if the directory is empty, just get rid of it and log an
- error */
i_stream_destroy(&input);
- if (maildir_rmdir_unexpected_dir(&mbox->storage->storage,
- ctx.path) == 0)
+ if (maildir_lose_unexpected_dir(&mbox->storage->storage,
+ ctx.path) >= 0)
*deleted_r = TRUE;
} else {
i_stream_set_name(input, ctx.path);
diff -r 2bfe672e7c8a -r cf1e5238f747 src/lib-storage/index/maildir/maildir-storage.h
--- a/src/lib-storage/index/maildir/maildir-storage.h Tue Sep 28 17:09:50 2010 +0100
+++ b/src/lib-storage/index/maildir/maildir-storage.h Tue Sep 28 17:15:52 2010 +0100
@@ -109,6 +109,7 @@
bool maildir_set_deleted(struct mailbox *box);
uint32_t maildir_get_uidvalidity_next(struct mailbox_list *list);
+int maildir_lose_unexpected_dir(struct mail_storage *storage, const char *path);
struct mail_save_context *
maildir_save_alloc(struct mailbox_transaction_context *_t);
diff -r 2bfe672e7c8a -r cf1e5238f747 src/lib-storage/index/maildir/maildir-sync-index.c
--- a/src/lib-storage/index/maildir/maildir-sync-index.c Tue Sep 28 17:09:50 2010 +0100
+++ b/src/lib-storage/index/maildir/maildir-sync-index.c Tue Sep 28 17:15:52 2010 +0100
@@ -98,6 +98,8 @@
}
if (errno == ENOENT)
return 0;
+ if (errno == EISDIR)
+ return maildir_lose_unexpected_dir(box->storage, path);
mail_storage_set_critical(&mbox->storage->storage,
"unlink(%s) failed: %m", path);
diff -r 2bfe672e7c8a -r cf1e5238f747 src/lib-storage/index/maildir/maildir-util.c
--- a/src/lib-storage/index/maildir/maildir-util.c Tue Sep 28 17:09:50 2010 +0100
+++ b/src/lib-storage/index/maildir/maildir-util.c Tue Sep 28 17:15:52 2010 +0100
@@ -12,6 +12,7 @@
#include "maildir-filename.h"
#include "maildir-sync.h"
+#include <stdio.h>
#include <unistd.h>
#include <dirent.h>
#include <fcntl.h>
@@ -224,3 +225,54 @@
} T_END;
return ret < 0 ? FALSE : TRUE;
}
+
+int maildir_lose_unexpected_dir(struct mail_storage *storage, const char *path)
+{
+ const char *dest, *fname, *p;
+
+ /* There's a directory in maildir, get rid of it.
+
+ In some installations this was caused by a messed up configuration
+ where e.g. mails was initially delivered to new/new/ directory.
+ Also Dovecot v2.0.0 - v2.0.4 sometimes may have renamed tmp/
+ directory under new/ or cur/. */
+ if (rmdir(path) == 0) {
+ mail_storage_set_critical(storage,
+ "Maildir: rmdir()ed unwanted empty directory: %s",
+ path);
+ return 1;
+ } else if (errno == ENOENT) {
+ /* someone else rmdired or renamed it */
+ return 0;
+ } else if (errno != ENOTEMPTY) {
+ mail_storage_set_critical(storage,
+ "Maildir: Found unwanted directory %s, "
+ "but rmdir() failed: %m", path);
+ return -1;
+ }
+
+ /* It's not safe to delete this directory since it has some files in it,
+ but it's also not helpful to log this message over and over again.
+ Get rid of this error by renaming the directory elsewhere */
+ p = strrchr(path, '/');
+ i_assert(p != NULL);
+ fname = p + 1;
+ while (p != path && p[-1] != '/') p--;
+ i_assert(p != NULL);
+
+ dest = t_strconcat(t_strdup_until(path, p), "extra-", fname, NULL);
+ if (rename(path, dest) == 0) {
+ mail_storage_set_critical(storage,
+ "Maildir: renamed unwanted directory %s to %s",
+ path, dest);
+ return 1;
+ } else if (errno == ENOENT) {
+ /* someone else renamed it (could have been flag change) */
+ return 0;
+ } else {
+ mail_storage_set_critical(storage,
+ "Maildir: Found unwanted directory, "
+ "but rename(%s, %s) failed: %m", path, dest);
+ return -1;
+ }
+}
More information about the dovecot-cvs
mailing list