]> granicus.if.org Git - neomutt/commitdiff
Search for messages which may have been moving under our feet in
authorThomas Roessler <roessler@does-not-exist.org>
Wed, 26 Sep 2001 09:38:04 +0000 (09:38 +0000)
committerThomas Roessler <roessler@does-not-exist.org>
Wed, 26 Sep 2001 09:38:04 +0000 (09:38 +0000)
maildir folders.  Suggested by Bjoern Jacke.

mh.c
mx.c
mx.h

diff --git a/mh.c b/mh.c
index 9b5c525f648f678523de52b762161c20e43be445..38aa4f01642ca4800d74eec18e8bbde9f9ce3a0c 100644 (file)
--- 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 22115c5a063db6b5ff1ff67be81147145eb6f929..d5029b5c727de4c46f6e6921ab1c2827b562ab75 100644 (file)
--- 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 10ef9c503b41c68f93e3e1ebcc0e8e6b79e08de1..f1548651c55a807b4d9886840f50210531552ab3 100644 (file)
--- 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 *);