#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
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
{
typedef union
{
struct timeval timeval;
- unsigned long uid_validity;
+ unsigned int uidvalidity;
} validate;
static void *
while (counter)
{
- *a = safe_malloc(sizeof (ADDRESS));
+ *a = rfc822_new_address();
#ifdef EXACT_ADDRESS
restore_char(&(*a)->val, d, off, convert);
#endif
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;
}
* 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;
*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;
nh.limited = 0;
nh.num_hidden = 0;
nh.recipient = 0;
+ nh.pair = 0;
nh.attach_valid = 0;
nh.path = NULL;
nh.tree = NULL;
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;
}
#endif
#ifdef HAVE_QDBM
char *data = NULL;
+#elif HAVE_TC
+ void *data;
+ int sp;
#elif HAVE_GDBM
datum key;
datum data;
#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;
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;
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);
#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;
#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;
}
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)
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);
#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
{
return "qdbm " _QDBM_VERSION;
}
+#elif HAVE_TC
+const char *mutt_hcache_backend (void)
+{
+ return "tokyocabinet " _TC_VERSION;
+}
#endif