]> git.llucax.com Git - software/mutt-debian.git/blobdiff - hcache.c
a better way of closing 603186 (sidebar-{sorted,dotted} documentation)
[software/mutt-debian.git] / hcache.c
index af27b82742b01d9f84241808c6eecf73df670804..ddc0ec05f051417e3dfd43800cb9b02137c82422 100644 (file)
--- a/hcache.c
+++ b/hcache.c
@@ -26,6 +26,8 @@
 #include <depot.h>
 #include <cabin.h>
 #include <villa.h>
+#elif HAVE_TC
+#include <tcbdb.h>
 #elif HAVE_GDBM
 #include <gdbm.h>
 #elif HAVE_DB4
 #include "mutt.h"
 #include "hcache.h"
 #include "hcversion.h"
-#ifdef USE_IMAP
-#include "message.h"
-#endif
-#include "mime.h"
 #include "mx.h"
 #include "lib.h"
 #include "md5.h"
+#include "rfc822.h"
 
 #if HAVE_QDBM
 static struct header_cache
@@ -55,6 +54,13 @@ static struct header_cache
   char *folder;
   unsigned int crc;
 } HEADER_CACHE;
+#elif HAVE_TC
+static struct header_cache
+{
+  TCBDB *db;
+  char *folder;
+  unsigned int crc;
+} HEADER_CACHE;
 #elif HAVE_GDBM
 static struct header_cache
 {
@@ -80,7 +86,7 @@ static void mutt_hcache_dbt_empty_init(DBT * dbt);
 typedef union
 {
   struct timeval timeval;
-  unsigned long uid_validity;
+  unsigned int uidvalidity;
 } validate;
 
 static void *
@@ -226,7 +232,7 @@ restore_address(ADDRESS ** a, const unsigned char *d, int *off, int convert)
 
   while (counter)
   {
-    *a = safe_malloc(sizeof (ADDRESS));
+    *a = rfc822_new_address();
 #ifdef EXACT_ADDRESS
     restore_char(&(*a)->val, d, off, convert);
 #endif
@@ -362,19 +368,31 @@ restore_parameter(PARAMETER ** p, const unsigned char *d, int *off, int convert)
 static unsigned char *
 dump_body(BODY * c, unsigned char *d, int *off, int convert)
 {
+  BODY nb;
+
+  memcpy (&nb, c, sizeof (BODY));
+
+  /* some fields are not safe to cache */
+  nb.content = NULL;
+  nb.charset = NULL;
+  nb.next = NULL;
+  nb.parts = NULL;
+  nb.hdr = NULL;
+  nb.aptr = NULL;
+
   lazy_realloc(&d, *off + sizeof (BODY));
-  memcpy(d + *off, c, sizeof (BODY));
+  memcpy(d + *off, &nb, sizeof (BODY));
   *off += sizeof (BODY);
 
-  d = dump_char(c->xtype, d, off, 0);
-  d = dump_char(c->subtype, d, off, 0);
+  d = dump_char(nb.xtype, d, off, 0);
+  d = dump_char(nb.subtype, d, off, 0);
 
-  d = dump_parameter(c->parameter, d, off, convert);
+  d = dump_parameter(nb.parameter, d, off, convert);
 
-  d = dump_char(c->description, d, off, convert);
-  d = dump_char(c->form_name, d, off, convert);
-  d = dump_char(c->filename, d, off, convert);
-  d = dump_char(c->d_filename, d, off, convert);
+  d = dump_char(nb.description, d, off, convert);
+  d = dump_char(nb.form_name, d, off, convert);
+  d = dump_char(nb.filename, d, off, convert);
+  d = dump_char(nb.d_filename, d, off, convert);
 
   return d;
 }
@@ -571,7 +589,7 @@ mutt_hcache_per_folder(const char *path, const char *folder,
  * db_store */
 static void *
 mutt_hcache_dump(header_cache_t *h, HEADER * header, int *off,
-                unsigned long uid_validity)
+                unsigned int uidvalidity)
 {
   unsigned char *d = NULL;
   HEADER nh;
@@ -580,8 +598,8 @@ mutt_hcache_dump(header_cache_t *h, HEADER * header, int *off,
   *off = 0;
   d = lazy_malloc(sizeof (validate));
 
-  if (uid_validity)
-    memcpy(d, &uid_validity, sizeof (unsigned long));
+  if (uidvalidity)
+    memcpy(d, &uidvalidity, sizeof (uidvalidity));
   else
   {
     struct timeval now;
@@ -606,6 +624,7 @@ mutt_hcache_dump(header_cache_t *h, HEADER * header, int *off,
   nh.limited = 0;
   nh.num_hidden = 0;
   nh.recipient = 0;
+  nh.pair = 0;
   nh.attach_valid = 0;
   nh.path = NULL;
   nh.tree = NULL;
@@ -620,9 +639,9 @@ mutt_hcache_dump(header_cache_t *h, HEADER * header, int *off,
   memcpy(d + *off, &nh, sizeof (HEADER));
   *off += sizeof (HEADER);
 
-  d = dump_envelope(header->env, d, off, convert);
-  d = dump_body(header->content, d, off, convert);
-  d = dump_char(header->maildir_flags, d, off, convert);
+  d = dump_envelope(nh.env, d, off, convert);
+  d = dump_body(nh.content, d, off, convert);
+  d = dump_char(nh.maildir_flags, d, off, convert);
 
   return d;
 }
@@ -689,6 +708,9 @@ mutt_hcache_fetch_raw (header_cache_t *h, const char *filename,
 #endif
 #ifdef HAVE_QDBM
   char *data = NULL;
+#elif HAVE_TC
+  void *data;
+  int sp;
 #elif HAVE_GDBM
   datum key;
   datum data;
@@ -720,6 +742,10 @@ mutt_hcache_fetch_raw (header_cache_t *h, const char *filename,
 #ifdef HAVE_QDBM
   data = vlget(h->db, path, ksize, NULL);
   
+  return data;
+#elif HAVE_TC
+  data = tcbdbget(h->db, path, ksize, &sp);
+
   return data;
 #elif HAVE_GDBM
   key.dptr = path;
@@ -733,7 +759,7 @@ mutt_hcache_fetch_raw (header_cache_t *h, const char *filename,
 
 int
 mutt_hcache_store(header_cache_t *h, const char *filename, HEADER * header,
-                 unsigned long uid_validity,
+                 unsigned int uidvalidity,
                  size_t(*keylen) (const char *fn))
 {
   char* data;
@@ -743,7 +769,7 @@ mutt_hcache_store(header_cache_t *h, const char *filename, HEADER * header,
   if (!h)
     return -1;
   
-  data = mutt_hcache_dump(h, header, &dlen, uid_validity);
+  data = mutt_hcache_dump(h, header, &dlen, uidvalidity);
   ret = mutt_hcache_store_raw (h, filename, data, dlen, keylen);
   
   FREE(&data);
@@ -791,6 +817,8 @@ mutt_hcache_store_raw (header_cache_t* h, const char* filename, void* data,
 #endif
 #if HAVE_QDBM
   return vlput(h->db, path, ksize, data, dlen, VL_DOVER);
+#elif HAVE_TC
+  return tcbdbput(h->db, path, ksize, data, dlen);
 #elif HAVE_GDBM
   key.dptr = path;
   key.dsize = ksize;
@@ -802,19 +830,23 @@ mutt_hcache_store_raw (header_cache_t* h, const char* filename, void* data,
 #endif
 }
 
-static char* get_foldername(const char *folder) {
+static char* get_foldername(const char *folder)
+{
   char *p = NULL;
+  char path[_POSIX_PATH_MAX];
   struct stat st;
 
+  mutt_encode_path (path, sizeof (path), folder);
+
   /* if the folder is local, canonify the path to avoid
    * to ensure equivalent paths share the hcache */
-  if (stat (folder, &st) == 0)
+  if (stat (path, &st) == 0)
   {
-    p = safe_malloc (_POSIX_PATH_MAX+1);
-    if (!realpath (folder, p))
-      mutt_str_replace (&p, folder);
+    p = safe_malloc (PATH_MAX+1);
+    if (!realpath (path, p))
+      mutt_str_replace (&p, path);
   } else
-    p = safe_strdup (folder);
+    p = safe_strdup (path);
 
   return p;
 }
@@ -864,11 +896,60 @@ mutt_hcache_delete(header_cache_t *h, const char *filename,
   return vlout(h->db, path, ksize);
 }
 
+#elif HAVE_TC
+static int
+hcache_open_tc (struct header_cache* h, const char* path)
+{
+  h->db = tcbdbnew();
+  if (option(OPTHCACHECOMPRESS))
+    tcbdbtune(h->db, 0, 0, 0, -1, -1, BDBTDEFLATE);
+  if (tcbdbopen(h->db, path, BDBOWRITER | BDBOCREAT))
+    return 0;
+  else
+  {
+    tcbdbdel(h->db);
+    return -1;
+  }
+}
+
+void
+mutt_hcache_close(header_cache_t *h)
+{
+  if (!h)
+    return;
+
+  tcbdbclose(h->db);
+  tcbdbdel(h->db);
+  FREE(&h->folder);
+  FREE(&h);
+}
+
+int
+mutt_hcache_delete(header_cache_t *h, const char *filename,
+                  size_t(*keylen) (const char *fn))
+{
+  char path[_POSIX_PATH_MAX];
+  int ksize;
+
+  if (!h)
+    return -1;
+
+  strncpy(path, h->folder, sizeof (path));
+  safe_strcat(path, sizeof (path), filename);
+
+  ksize = strlen(h->folder) + keylen(path + strlen(h->folder));
+
+  return tcbdbout(h->db, path, ksize);
+}
+
 #elif HAVE_GDBM
 static int
 hcache_open_gdbm (struct header_cache* h, const char* path)
 {
-  int pagesize = atoi(HeaderCachePageSize) ? atoi(HeaderCachePageSize) : 16384;
+  int pagesize;
+
+  if (mutt_atoi (HeaderCachePageSize, &pagesize) < 0 || pagesize <= 0)
+    pagesize = 16384;
 
   h->db = gdbm_open((char *) path, pagesize, GDBM_WRCREAT, 00600, NULL);
   if (h->db)
@@ -936,7 +1017,10 @@ hcache_open_db4 (struct header_cache* h, const char* path)
   struct stat sb;
   int ret;
   u_int32_t createflags = DB_CREATE;
-  int pagesize = atoi (HeaderCachePageSize);
+  int pagesize;
+
+  if (mutt_atoi (HeaderCachePageSize, &pagesize) < 0 || pagesize <= 0)
+    pagesize = 16384;
 
   snprintf (h->lockfile, _POSIX_PATH_MAX, "%s-lock-hack", path);
 
@@ -1027,6 +1111,8 @@ mutt_hcache_open(const char *path, const char *folder, hcache_namer_t namer)
 
 #if HAVE_QDBM
   hcache_open = hcache_open_qdbm;
+#elif HAVE_TC
+  hcache_open= hcache_open_tc;
 #elif HAVE_GDBM
   hcache_open = hcache_open_gdbm;
 #elif HAVE_DB4
@@ -1078,4 +1164,9 @@ const char *mutt_hcache_backend (void)
 {
   return "qdbm " _QDBM_VERSION;
 }
+#elif HAVE_TC
+const char *mutt_hcache_backend (void)
+{
+  return "tokyocabinet " _TC_VERSION;
+}
 #endif