From 2918013afbb59fc006ac0e2e926277e82312a2c0 Mon Sep 17 00:00:00 2001 From: Thomas Roessler Date: Wed, 26 Sep 2001 09:38:04 +0000 Subject: [PATCH] Search for messages which may have been moving under our feet in maildir folders. Suggested by Bjoern Jacke. --- mh.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- mx.c | 7 ++++++- mx.h | 2 ++ 3 files changed, 73 insertions(+), 2 deletions(-) diff --git a/mh.c b/mh.c index 9b5c525f..38aa4f01 100644 --- a/mh.c +++ b/mh.c @@ -1196,7 +1196,7 @@ int mh_sync_mailbox (CONTEXT * ctx, int *index_hint) return 0; } -static char *maildir_canon_filename(char *dest, char *src, size_t l) +static char *maildir_canon_filename (char *dest, const char *src, size_t l) { char *t, *u; @@ -1443,3 +1443,67 @@ int mh_check_mailbox(CONTEXT *ctx, int *index_hint) return (modified || occult) ? M_REOPENED : have_new ? M_NEW_MAIL : 0; } + + + + +/* + * These functions try to find a message in a maildir folder when it + * has moved under our feet. Note that this code is rather expensive, but + * then again, it's called rarely. + */ + +FILE *_maildir_open_find_message (const char *folder, const char *unique, + const char *subfolder) +{ + char dir[_POSIX_PATH_MAX]; + char tunique[_POSIX_PATH_MAX]; + char fname[_POSIX_PATH_MAX]; + + DIR *dp; + struct dirent *de; + + FILE *fp = NULL; + int oe = ENOENT; + + snprintf (dir, sizeof (dir), "%s/%s", folder, subfolder); + + if ((dp = opendir (dir)) == NULL) + { + errno = ENOENT; + return NULL; + } + + while ((de = readdir (dp))) + { + maildir_canon_filename (tunique, de->d_name, sizeof (tunique)); + + if (!mutt_strcmp (tunique, unique)) + { + snprintf (fname, sizeof (fname), "%s/%s/%s", folder, subfolder, de->d_name); + fp = fopen (fname, "r"); /* __FOPEN_CHECKED__ */ + oe = errno; + break; + } + } + + closedir (dp); + + errno = oe; + return fp; +} + +FILE *maildir_open_find_message (const char *folder, const char *msg) +{ + char unique[_POSIX_PATH_MAX]; + FILE *fp; + + maildir_canon_filename (unique, msg, sizeof (unique)); + + if ((fp = _maildir_open_find_message (folder, unique, "new")) || errno != ENOENT) + return fp; + if ((fp = _maildir_open_find_message (folder, unique, "cur")) || errno != ENOENT) + return fp; + + return NULL; +} diff --git a/mx.c b/mx.c index 22115c5a..d5029b5c 100644 --- a/mx.c +++ b/mx.c @@ -1386,7 +1386,12 @@ MESSAGE *mx_open_message (CONTEXT *ctx, int msgno) char path[_POSIX_PATH_MAX]; snprintf (path, sizeof (path), "%s/%s", ctx->path, cur->path); - if ((msg->fp = fopen (path, "r")) == NULL) + + if ((msg->fp = fopen (path, "r")) == NULL && errno == ENOENT && + ctx->magic == M_MAILDIR) + msg->fp = maildir_open_find_message (ctx->path, cur->path); + + if (msg->fp == NULL) { mutt_perror (path); dprint (1, (debugfile, "mx_open_message: fopen: %s: %s (errno %d).\n", diff --git a/mx.h b/mx.h index 10ef9c50..f1548651 100644 --- a/mx.h +++ b/mx.h @@ -71,6 +71,8 @@ int mh_commit_message (CONTEXT *, MESSAGE *, HEADER *); int maildir_open_new_message (MESSAGE *, CONTEXT *, HEADER *); int mh_open_new_message (MESSAGE *, CONTEXT *, HEADER *); +FILE *maildir_open_find_message (const char *, const char *); + int mbox_strict_cmp_headers (const HEADER *, const HEADER *); int mutt_reopen_mailbox (CONTEXT *, int *); -- 2.40.0