]> granicus.if.org Git - neomutt/commitdiff
Make IMAP header cache layout match body cache.
authorBrendan Cully <brendan@kublai.com>
Wed, 11 Apr 2007 00:40:11 +0000 (17:40 -0700)
committerBrendan Cully <brendan@kublai.com>
Wed, 11 Apr 2007 00:40:11 +0000 (17:40 -0700)
You can now make them point to the same directory. Each folder will
have a folder.hcache file for the header cache.

hcache.c
imap/imap.c
imap/imap_private.h
imap/message.c
imap/util.c

index 1709509fc5be30446daf083877ebd649b899cd65..05ae8a2f1b3dd70f931fd2a2510b5b1410204e88 100644 (file)
--- a/hcache.c
+++ b/hcache.c
@@ -467,35 +467,61 @@ static const char *
 mutt_hcache_per_folder(const char *path, const char *folder,
                        hcache_namer_t namer)
 {
-  static char mutt_hcache_per_folder_path[_POSIX_PATH_MAX];
-  struct stat path_stat;
+  static char hcpath[_POSIX_PATH_MAX];
+  struct stat sb;
   MD5_CTX md5;
   unsigned char md5sum[16];
-  int ret;
+  char* s;
+  int ret, plen;
 
-  ret = stat(path, &path_stat);
-  if (ret < 0)
-    return path;
+  plen = mutt_strlen (path);
 
-  if (!S_ISDIR(path_stat.st_mode))
+  ret = stat(path, &sb);
+  if (ret < 0 && path[plen-1] != '/')
     return path;
 
-  MD5Init(&md5);
-  MD5Update(&md5, (unsigned char *) folder, strlen(folder));
-  MD5Final(md5sum, &md5);
+  if (ret >= 0 && !S_ISDIR(sb.st_mode))
+    return path;
 
-  ret = snprintf(mutt_hcache_per_folder_path, _POSIX_PATH_MAX,
-                "%s/%02x%02x%02x%02x%02x%02x%02x%02x"
-                "%02x%02x%02x%02x%02x%02x%02x%02x",
-                path, md5sum[0], md5sum[1], md5sum[2], md5sum[3],
-                md5sum[4], md5sum[5], md5sum[6], md5sum[7], md5sum[8],
-                md5sum[9], md5sum[10], md5sum[11], md5sum[12],
-                md5sum[13], md5sum[14], md5sum[15]);
+  if (namer)
+  {
+    snprintf (hcpath, sizeof (hcpath), "%s%s", path,
+              path[plen-1] == '/' ? "" : "/");
+    if (path[plen-1] != '/')
+      plen++;
 
+    ret = namer (folder, hcpath + plen, sizeof (hcpath) - plen);
+  }
+  else
+  {
+    MD5Init(&md5);
+    MD5Update(&md5, (unsigned char *) folder, strlen(folder));
+    MD5Final(md5sum, &md5);
+
+    ret = snprintf(hcpath, _POSIX_PATH_MAX,
+                   "%s/%02x%02x%02x%02x%02x%02x%02x%02x"
+                   "%02x%02x%02x%02x%02x%02x%02x%02x",
+                   path, md5sum[0], md5sum[1], md5sum[2], md5sum[3],
+                   md5sum[4], md5sum[5], md5sum[6], md5sum[7], md5sum[8],
+                   md5sum[9], md5sum[10], md5sum[11], md5sum[12],
+                   md5sum[13], md5sum[14], md5sum[15]);
+  }
+  
   if (ret <= 0)
     return path;
 
-  return mutt_hcache_per_folder_path;
+  s = strchr (hcpath + 1, '/');
+  while (s)
+  {
+    /* create missing path components */
+    *s = '\0';
+    if (stat (hcpath, &sb) < 0 && (errno != ENOENT || mkdir (hcpath, 0777) < 0))
+      return path;
+    *s = '/';
+    s = strchr (s + 1, '/');
+  }
+
+  return hcpath;
 }
 
 /* This function transforms a header into a char so that it is useable by
index 4a93872d00712dc998f72d3a631335baa6435942..e192f8410b3e73a481858d678b8e186019a72505 100644 (file)
@@ -249,7 +249,7 @@ void imap_expunge_mailbox (IMAP_DATA* idata)
   int i, cacheno;
 
 #ifdef USE_HCACHE
-  imap_hcache_open (idata);
+  idata->hcache = imap_hcache_open (idata, NULL);
 #endif
 
   for (i = 0; i < idata->ctx->msgcount; i++)
@@ -1146,7 +1146,7 @@ int imap_sync_mailbox (CONTEXT* ctx, int expunge, int* index_hint)
   }
 
 #if USE_HCACHE
-  imap_hcache_open (idata);
+  idata->hcache = imap_hcache_open (idata, NULL);
 #endif
 
   /* save messages with real (non-flag) changes */
@@ -1569,6 +1569,7 @@ IMAP_STATUS* imap_mboxcache_get (IMAP_DATA* idata, const char* mbox, int create)
   header_cache_t *hc = NULL;
   ciss_url_t url;
   char urlstr[LONG_STRING];
+  char cpath[LONG_STRING];
   unsigned int *uidvalidity = NULL;
   unsigned int *uidnext = NULL;
 #endif
@@ -1594,10 +1595,7 @@ IMAP_STATUS* imap_mboxcache_get (IMAP_DATA* idata, const char* mbox, int create)
   }
 
 #ifdef USE_HCACHE
-  mutt_account_tourl (&idata->conn->account, &url);
-  url.path = (char*)mbox;
-  url_ciss_tostring (&url, urlstr, sizeof (urlstr), 0);
-  hc = mutt_hcache_open (HeaderCache, urlstr, NULL);
+  hc = imap_hcache_open (idata, mbox);
   if (hc)
   {
     uidvalidity = mutt_hcache_fetch_raw (hc, "/UIDVALIDITY", imap_hcache_keylen);
index 410f6bff0024274b608260494b2501c51c84dcd7..98adc8b2ced029fbbcec6771d476b871aac6769e 100644 (file)
@@ -259,7 +259,7 @@ int imap_cache_del (IMAP_DATA* idata, HEADER* h);
 
 /* util.c */
 #ifdef USE_HCACHE
-int imap_hcache_open (IMAP_DATA* idata);
+header_cache_t* imap_hcache_open (IMAP_DATA* idata, const char* path);
 void imap_hcache_close (IMAP_DATA* idata);
 HEADER* imap_hcache_get (IMAP_DATA* idata, unsigned int uid);
 int imap_hcache_put (IMAP_DATA* idata, HEADER* h);
@@ -272,6 +272,8 @@ IMAP_DATA* imap_new_idata (void);
 void imap_free_idata (IMAP_DATA** idata);
 char* imap_fix_path (IMAP_DATA* idata, char* mailbox, char* path, 
   size_t plen);
+void imap_cachepath(IMAP_DATA* idata, const char* mailbox, char* dest,
+                    size_t dlen);
 int imap_get_literal_count (const char* buf, long* bytes);
 char* imap_get_qualifier (char* buf);
 int imap_mxcmp (const char* mx1, const char* mx2);
index d2fe9890db77280173dec4afa623f6b695f8b302..0cd3e50e220884be36e85fe26d6df9fb1655c7cc 100644 (file)
@@ -119,7 +119,7 @@ int imap_read_headers (IMAP_DATA* idata, int msgbegin, int msgend)
   idata->newMailCount = 0;
 
 #if USE_HCACHE
-  imap_hcache_open (idata);
+  idata->hcache = imap_hcache_open (idata, NULL);
 
   if (idata->hcache && !msgbegin)
   {
@@ -847,35 +847,12 @@ int imap_copy_messages (CONTEXT* ctx, HEADER* h, char* dest, int delete)
 
 static body_cache_t *msg_cache_open (IMAP_DATA *idata)
 {
-  char *s;
-  char *p = idata->mailbox;
   char mailbox[_POSIX_PATH_MAX];
-  size_t mlen = sizeof (mailbox);
 
   if (idata->bcache)
     return idata->bcache;
 
-  mailbox[0] = '\0';
-
-  for (s = mailbox; p && *p && mlen; mlen--)
-  {
-    if (*p == idata->delim)
-    {
-      *s = '/';
-      /* simple way to avoid collisions with UIDs */
-      if (*(p + 1) >= '0' && *(p + 1) <= '9')
-      {
-       mlen--;
-       if (mlen)
-         *++s = '_';
-      }
-    }
-    else
-      *s = *p;
-    p++;
-    s++;
-  }
-  *s = '\0';
+  imap_cachepath (idata, idata->mailbox, mailbox, sizeof (mailbox));
 
   return mutt_bcache_open (&idata->conn->account, mailbox);
 }
index 7fab623c2f3c8cf2f85173fe262617df674a7821..076c75877efd9c342656c8a8ba199554a15868c7 100644 (file)
@@ -71,23 +71,34 @@ int imap_expand_path (char* path, size_t len)
 }
 
 #ifdef USE_HCACHE
-int imap_hcache_open (IMAP_DATA* idata)
+static int imap_hcache_namer (const char* path, char* dest, size_t dlen)
+{
+  return snprintf (dest, dlen, "%s.hcache", path);
+}
+
+header_cache_t* imap_hcache_open (IMAP_DATA* idata, const char* path)
 {
   IMAP_MBOX mx;
   ciss_url_t url;
   char cachepath[LONG_STRING];
+  char mbox[LONG_STRING];
 
   if (imap_parse_path (idata->ctx->path, &mx) < 0)
     return -1;
 
-  mutt_account_tourl (&idata->conn->account, &url);
-  url.path = mx.mbox;
-  url_ciss_tostring (&url, cachepath, sizeof (cachepath), 0);
-  FREE (&mx.mbox);
+  if (path)
+    imap_cachepath (idata, path, mbox, sizeof (mbox));
+  else
+  {
+    imap_cachepath (idata, mx.mbox, mbox, sizeof (mbox));
+    FREE (&mx.mbox);
+  }
 
-  idata->hcache = mutt_hcache_open (HeaderCache, cachepath, NULL);
+  mutt_account_tourl (&idata->conn->account, &url);
+  url.path = mbox;
+  url_ciss_tostring (&url, cachepath, sizeof (cachepath), U_PATH);
 
-  return idata->hcache != NULL ? 0 : -1;
+  return mutt_hcache_open (HeaderCache, cachepath, imap_hcache_namer);
 }
 
 void imap_hcache_close (IMAP_DATA* idata)
@@ -398,6 +409,32 @@ char *imap_fix_path (IMAP_DATA *idata, char *mailbox, char *path,
   return path;
 }
 
+void imap_cachepath(IMAP_DATA* idata, const char* mailbox, char* dest,
+                    size_t dlen)
+{
+  char* s;
+  const char* p = mailbox;
+
+  for (s = dest; p && *p && dlen; dlen--)
+  {
+    if (*p == idata->delim)
+    {
+      *s = '/';
+      /* simple way to avoid collisions with UIDs */
+      if (*(p + 1) >= '0' && *(p + 1) <= '9')
+      {
+       if (--dlen)
+         *++s = '_';
+      }
+    }
+    else
+      *s = *p;
+    p++;
+    s++;
+  }
+  *s = '\0';
+}
+
 /* imap_get_literal_count: write number of bytes in an IMAP literal into
  *   bytes, return 0 on success, -1 on failure. */
 int imap_get_literal_count(const char *buf, long *bytes)