Make message cache write to temporary location until file is complete.
authorBrendan Cully <brendan@kublai.com>
Thu, 29 Mar 2007 17:30:15 +0000 (10:30 -0700)
committerBrendan Cully <brendan@kublai.com>
Thu, 29 Mar 2007 17:30:15 +0000 (10:30 -0700)
Previously mutt trusted the cache file even when it was incomplete,
causing permanently incorrect message display if the fetch was
interrupted for some reason.

ChangeLog
bcache.c
bcache.h
imap/message.c

index b3d181b56194035475a6b5a0aeec70834d57add9..3dea57d3640e629df070ba6dbaf62171c7dbcc5f 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2007-03-28 09:43 +0200  Thomas Roessler  <roessler@does-not-exist.org>  (25cbd5588d35)
+
+       * alias.c: Fix debug message for mutt_adr_is_user
+
+2007-03-23 10:32 -0700  Brendan Cully  <brendan@kublai.com>  (888a57a2b5f2)
+
+       * imap/browse.c: Reset list.name before each list response in
+       folder browser
+
 2007-03-22 14:36 +0100  Thomas Roessler  <roessler@does-not-exist.org>  (68cfab02b411)
 
        * curs_main.c: Fix update_index().
index b6489bf9a7aba5086df44d3bf30d261823935f7e..fd52365c4a615d03dcfa212612188423389ca32e 100644 (file)
--- a/bcache.c
+++ b/bcache.c
@@ -161,6 +161,22 @@ FILE* mutt_bcache_put(body_cache_t *bcache, const char *id)
   return fp;
 }
 
+int mutt_bcache_move(body_cache_t* bcache, const char* id, const char* newid)
+{
+  char path[_POSIX_PATH_MAX];
+  char newpath[_POSIX_PATH_MAX];
+
+  if (!bcache || !id || !*id || !newid || !*newid)
+    return -1;
+
+  snprintf (path, sizeof (path), "%s%s", bcache->path, id);
+  snprintf (newpath, sizeof (newpath), "%s%s", bcache->path, newid);
+
+  dprint (3, (debugfile, "bcache: mv: '%s' '%s'\n", path, newpath));
+
+  return rename (path, newpath);
+}
+
 int mutt_bcache_del(body_cache_t *bcache, const char *id)
 {
   char path[_POSIX_PATH_MAX];
index f7728a5489f351035525e502a617d6878061e03f..d061a6ae70a5f7b9955940d202de7f5d62bf1e2a 100644 (file)
--- a/bcache.h
+++ b/bcache.h
@@ -49,6 +49,7 @@ void mutt_bcache_close (body_cache_t **bcache);
 
 FILE* mutt_bcache_get(body_cache_t *bcache, const char *id);
 FILE* mutt_bcache_put(body_cache_t *bcache, const char *id);
+int mutt_bcache_move(body_cache_t *bcache, const char *id, const char *newid);
 int mutt_bcache_del(body_cache_t *bcache, const char *id);
 int mutt_bcache_exists(body_cache_t *bcache, const char *id);
 
index a7a3fcac114af945d0d11987b57eaacd0287a58f..a25c17386d16ae7ce0ab0c10292e1479e405b5d5 100644 (file)
@@ -45,6 +45,7 @@
 
 static FILE* msg_cache_get (IMAP_DATA* idata, HEADER* h);
 static FILE* msg_cache_put (IMAP_DATA* idata, HEADER* h);
+static int msg_cache_commit (IMAP_DATA* idata, HEADER* h);
 
 static void flush_buffer(char* buf, size_t* len, CONNECTION* conn);
 static int msg_fetch_header (CONTEXT* ctx, IMAP_HEADER* h, char* buf,
@@ -500,7 +501,9 @@ int imap_fetch_message (MESSAGE *msg, CONTEXT *ctx, int msgno)
   if (!fetched || !imap_code (idata->buf))
     goto bail;
 
-parsemsg:
+  msg_cache_commit (idata, h);
+
+  parsemsg:
   /* Update the header information.  Previously, we only downloaded a
    * portion of the headers, those required for the main display.
    */
@@ -900,10 +903,25 @@ static FILE* msg_cache_put (IMAP_DATA* idata, HEADER* h)
     return NULL;
 
   idata->bcache = msg_cache_open (idata);
-  snprintf (id, sizeof (id), "%u-%u", idata->uid_validity, HEADER_DATA(h)->uid);
+  snprintf (id, sizeof (id), "%u-%u.tmp", idata->uid_validity, HEADER_DATA(h)->uid);
   return mutt_bcache_put (idata->bcache, id);
 }
 
+static int msg_cache_commit (IMAP_DATA* idata, HEADER* h)
+{
+  char id[_POSIX_PATH_MAX];
+  char newid[_POSIX_PATH_MAX];
+
+  if (!idata || !h)
+    return -1;
+
+  idata->bcache = msg_cache_open (idata);
+  snprintf (id, sizeof (id), "%u-%u.tmp", idata->uid_validity, HEADER_DATA(h)->uid);
+  snprintf (newid, sizeof (newid), "%u-%u", idata->uid_validity, HEADER_DATA(h)->uid);
+
+  return mutt_bcache_move (idata->bcache, id, newid);
+}
+
 int imap_cache_del (IMAP_DATA* idata, HEADER* h)
 {
   char id[_POSIX_PATH_MAX];