X-Git-Url: https://git.llucax.com/software/mutt-debian.git/blobdiff_plain/14c29200cb58d3c4a0830265f2433849781858d0..753c3b3409564dc4fe3824cba6272babc6db5fe6:/hcache.c?ds=sidebyside diff --git a/hcache.c b/hcache.c index af27b82..ddc0ec0 100644 --- a/hcache.c +++ b/hcache.c @@ -26,6 +26,8 @@ #include #include #include +#elif HAVE_TC +#include #elif HAVE_GDBM #include #elif HAVE_DB4 @@ -40,13 +42,10 @@ #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