X-Git-Url: http://git.madism.org/?p=apps%2Fmadmutt.git;a=blobdiff_plain;f=lib-mx%2Fhcache.c;h=8748adf198c0f859064fb3c382f18b8ea905701f;hp=4b07b5a40b3508bdd4e8882e4c5718e6ca7479d8;hb=455a2390989dfcfc90899785b0d8e9ac94ebd28e;hpb=9eb790d6eb4a56416d342816e1140aabd9c12de8 diff --git a/lib-mx/hcache.c b/lib-mx/hcache.c index 4b07b5a..8748adf 100644 --- a/lib-mx/hcache.c +++ b/lib-mx/hcache.c @@ -13,466 +13,369 @@ #ifdef USE_HCACHE -#define MUTTNG_HCACHE_ID "0x004" - #if defined(HAVE_QDBM) #include #include #include #elif defined(HAVE_GDBM) #include +#else +#error neither HAVE_QDBM nor HAVE_GDBM are set ?! #endif -#include - #include "charset.h" #include "mutt.h" #include "hcache.h" struct hcache_t { #if defined(HAVE_QDBM) - VILLA *db; + VILLA *db; #elif defined(HAVE_GDBM) - GDBM_FILE db; + GDBM_FILE db; #endif - char *folder; - unsigned int crc; + char *folder; + unsigned int crc; }; -typedef union { - struct timeval timeval; - unsigned long uid_validity; -} validate; - -#define UPPER4K(i) ((i & ~(4096 - 1)) + 4096) - -static unsigned char *lazy_malloc(ssize_t siz) +static unsigned int crc32(unsigned int crc, const void *src, ssize_t len) { - return p_new(unsigned char, UPPER4K(siz)); -} + int i; + const unsigned char *p = src; -static void lazy_realloc(unsigned char **p, ssize_t siz) -{ - p_realloc(p, UPPER4K(siz)); + while (len--) { + crc ^= *p++; + for (i = 0; i < 8; i++) + crc = (crc >> 1) ^ ((crc & 1) ? 0xedb88320 : 0); + } + return crc; } -static unsigned char *dump_int (unsigned int i, unsigned char *d, int *off) +static int generate_crc32(void) { - lazy_realloc (&d, *off + sizeof (int)); - memcpy (d + *off, &i, sizeof (int)); - (*off) += sizeof (int); + int crc = 0; - return d; -} - -static void restore_int (unsigned int *i, const unsigned char *d, int *off) -{ - memcpy (i, d + *off, sizeof (int)); - (*off) += sizeof (int); + crc = crc32(crc, "madmutt.2007.05.13", m_strlen("madmutt.2007.05.13")); +#ifdef HAVE_LANGINFO_H + crc = crc32(crc, MCharset.charset, m_strlen(MCharset.charset)); +#endif + crc = crc32(crc, "USE_POP", m_strlen("USE_POP")); + crc = crc32(crc, "MIXMASTER", m_strlen("MIXMASTER")); + crc = crc32(crc, "USE_IMAP", m_strlen("USE_IMAP")); +#ifdef USE_NNTP + crc = crc32(crc, "USE_NNTP", m_strlen("USE_NNTP")); +#endif + return crc; } -static unsigned char *dump_char (char *c, unsigned char *d, int *off) +static const char * +mutt_hcache_per_folder(const char *path, const char *folder) { - unsigned int size; + static char buf[_POSIX_PATH_MAX]; + struct stat st; + int pos; - if (c == NULL) { - size = 0; - d = dump_int (size, d, off); - return d; - } + if (stat(path, &st) < 0 || !S_ISDIR(st.st_mode)) { + return path; + } - size = m_strlen(c) + 1; - d = dump_int (size, d, off); - lazy_realloc (&d, *off + size); - memcpy (d + *off, c, size); - *off += size; + pos = m_strcpy(buf, sizeof(buf), path); + pos += m_strputc(buf + pos, sizeof(buf) - pos, '/'); - return d; + while (*folder) { + if (isalnum((unsigned char)*folder) || *folder == '.') { + pos += m_strputc(buf + pos, sizeof(buf) - pos, *folder); + } else { + pos += m_strputc(buf + pos, sizeof(buf) - pos, '_'); + } + folder++; + } + pos += m_strcpy(buf + pos, sizeof(buf) - pos, ".hdb"); + return buf; } -static void restore_char (char **c, const unsigned char *d, int *off) -{ - unsigned int size; +/* store and restore things {{{ */ - restore_int (&size, d, off); - - if (size == 0) { - *c = NULL; - return; - } +static void dump_int(buffer_t *buf, int i) +{ + buffer_add(buf, &i, sizeof(i)); +} - *c = p_dup(d + *off, size); - *off += size; +static const void *restore_int(const char *d, int *i) +{ + memcpy(i, d, sizeof(*i)); + return d + sizeof(*i); } -static unsigned char *dump_address (address_t * a, unsigned char *d, int *off) +static void dump_cstr(buffer_t *buf, const char *s) { - unsigned int counter = 0; - unsigned int start_off = *off; + int size = 0; - d = dump_int (0xdeadbeef, d, off); + if (m_strisempty(s)) { + dump_int(buf, size); + return; + } - while (a) { - d = dump_char (a->personal, d, off); - d = dump_char (a->mailbox, d, off); - d = dump_int (a->group, d, off); - a = a->next; - counter++; - } + size = strlen(s) + 1; + dump_int(buf, size); + buffer_add(buf, s, size); +} - memcpy (d + start_off, &counter, sizeof (int)); +static const void *restore_cstr(const char *d, char **c) +{ + int size; - return d; + d = restore_int(d, &size); + *c = p_dup(d, size); + return d + size; } -static void restore_address (address_t ** a, const unsigned char *d, int *off) +static void dump_address(buffer_t *buf, address_t *a) { - unsigned int counter; + int counter = 0, pos = buf->len; - restore_int (&counter, d, off); + dump_int(buf, counter); - while (counter) { - *a = p_new(address_t, 1); - restore_char (&(*a)->personal, d, off); - restore_char (&(*a)->mailbox, d, off); - restore_int ((unsigned int *) &(*a)->group, d, off); - a = &(*a)->next; - counter--; - } + for (; a; a = a->next, counter++) { + dump_cstr(buf, a->personal); + dump_cstr(buf, a->mailbox); + dump_int(buf, a->group); + } - *a = NULL; + memcpy(buf->data + pos, &counter, sizeof(counter)); } -static unsigned char *dump_list (string_list_t * l, unsigned char *d, int *off) +static const void *restore_address(const char *d, address_t **a) { - unsigned int counter = 0; - unsigned int start_off = *off; + int counter; - d = dump_int (0xdeadbeef, d, off); + d = restore_int(d, &counter); - while (l) { - d = dump_char (l->data, d, off); - l = l->next; - counter++; - } - - memcpy (d + start_off, &counter, sizeof (int)); + for (; counter > 0; counter--) { + *a = address_new(); + d = restore_cstr(d, &(*a)->personal); + d = restore_cstr(d, &(*a)->mailbox); + d = restore_int(d, &(*a)->group); + a = &(*a)->next; + } - return d; + *a = NULL; + return d; } -static void restore_list (string_list_t ** l, const unsigned char *d, int *off) +static void dump_list(buffer_t *buf, string_list_t *l) { - unsigned int counter; + int pos = buf->len; + int counter = 0; - restore_int (&counter, d, off); + dump_int(buf, counter); - while (counter) { - *l = p_new(string_list_t, 1); - restore_char (&(*l)->data, d, off); - l = &(*l)->next; - counter--; - } + for (; l; l = l->next, counter++) { + dump_cstr(buf, l->data); + } - *l = NULL; + memcpy(buf->data + pos, &counter, sizeof(counter)); } -static unsigned char *dump_parameter (parameter_t * p, unsigned char *d, - int *off) +static const void *restore_list(const char *d, string_list_t **l) { - unsigned int counter = 0; - unsigned int start_off = *off; - - d = dump_int (0xdeadbeef, d, off); + int counter; - while (p) { - d = dump_char (p->attribute, d, off); - d = dump_char (p->value, d, off); - p = p->next; - counter++; - } + d = restore_int(d, &counter); - memcpy (d + start_off, &counter, sizeof (int)); + for (; counter > 0; counter--) { + *l = string_item_new(); + d = restore_cstr(d, &(*l)->data); + l = &(*l)->next; + } - return d; + *l = NULL; + return d; } -static void -restore_parameter (parameter_t ** p, const unsigned char *d, int *off) +static void dump_parameter(buffer_t *buf, parameter_t *p) { - unsigned int counter; + int pos = buf->len, counter = 0; - restore_int (&counter, d, off); + dump_int(buf, counter); - while (counter) { - *p = parameter_new(); - restore_char (&(*p)->attribute, d, off); - restore_char (&(*p)->value, d, off); - p = &(*p)->next; - counter--; - } + for (; p; p = p->next, counter++) { + dump_cstr(buf, p->attribute); + dump_cstr(buf, p->value); + } + + memcpy(buf->data + pos, &counter, sizeof(counter)); } -static unsigned char *dump_body (BODY * c, unsigned char *d, int *off) +static const void *restore_parameter(const char *d, parameter_t ** p) { - lazy_realloc (&d, *off + sizeof (BODY)); - memcpy (d + *off, c, sizeof (BODY)); - *off += sizeof (BODY); - - d = dump_char (c->xtype, d, off); - d = dump_char (c->subtype, d, off); + int counter; - d = dump_parameter (c->parameter, d, off); + d = restore_int(d, &counter); - d = dump_char (c->description, d, off); - d = dump_char (c->form_name, d, off); - d = dump_char (c->filename, d, off); - d = dump_char (c->d_filename, d, off); + for (; counter > 0; counter--) { + *p = parameter_new(); + d = restore_cstr(d, &(*p)->attribute); + d = restore_cstr(d, &(*p)->value); + p = &(*p)->next; + } - return d; + *p = NULL; + return d; } -static void restore_body (BODY * c, const unsigned char *d, int *off) +static void dump_body(buffer_t *buf, BODY *b) { - memcpy (c, d + *off, sizeof (BODY)); - *off += sizeof (BODY); - - restore_char (&c->xtype, d, off); - restore_char (&c->subtype, d, off); + buffer_add(buf, b, sizeof(*b)); + dump_cstr(buf, b->xtype); + dump_cstr(buf, b->subtype); - restore_parameter (&c->parameter, d, off); + dump_parameter(buf, b->parameter); - restore_char (&c->description, d, off); - restore_char (&c->form_name, d, off); - restore_char (&c->filename, d, off); - restore_char (&c->d_filename, d, off); + dump_cstr(buf, b->description); + dump_cstr(buf, b->form_name); + dump_cstr(buf, b->filename); + dump_cstr(buf, b->d_filename); } -static unsigned char *dump_envelope (ENVELOPE * e, unsigned char *d, int *off) +static const void *restore_body(const char *d, BODY *c) { - d = dump_address (e->return_path, d, off); - d = dump_address (e->from, d, off); - d = dump_address (e->to, d, off); - d = dump_address (e->cc, d, off); - d = dump_address (e->bcc, d, off); - d = dump_address (e->sender, d, off); - d = dump_address (e->reply_to, d, off); - d = dump_address (e->mail_followup_to, d, off); - - d = dump_char (e->subject, d, off); - if (e->real_subj) { - d = dump_int (e->real_subj - e->subject, d, off); - } - else { - d = dump_int (-1, d, off); - } - d = dump_char (e->message_id, d, off); - d = dump_char (e->supersedes, d, off); - d = dump_char (e->date, d, off); - d = dump_char (e->x_label, d, off); - d = dump_char (e->list_post, d, off); + memcpy(c, d, sizeof(*c)); + d += sizeof(*c); -#ifdef USE_NNTP - d = dump_char (e->newsgroups, d, off); - d = dump_char (e->xref, d, off); - d = dump_char (e->followup_to, d, off); - d = dump_char (e->x_comment_to, d, off); -#endif + d = restore_cstr(d, &c->xtype); + d = restore_cstr(d, &c->subtype); - d = dump_list (e->references, d, off); - d = dump_list (e->in_reply_to, d, off); - d = dump_list (e->userhdrs, d, off); + d = restore_parameter(d, &c->parameter); - return d; + d = restore_cstr(d, &c->description); + d = restore_cstr(d, &c->form_name); + d = restore_cstr(d, &c->filename); + d = restore_cstr(d, &c->d_filename); + return d; } -static void restore_envelope (ENVELOPE * e, const unsigned char *d, int *off) +static void dump_envelope(buffer_t *buf, ENVELOPE * e) { - int real_subj_off; - - restore_address (&e->return_path, d, off); - restore_address (&e->from, d, off); - restore_address (&e->to, d, off); - restore_address (&e->cc, d, off); - restore_address (&e->bcc, d, off); - restore_address (&e->sender, d, off); - restore_address (&e->reply_to, d, off); - restore_address (&e->mail_followup_to, d, off); - - restore_char (&e->subject, d, off); - restore_int ((unsigned int *) (&real_subj_off), d, off); - if (0 <= real_subj_off) { - e->real_subj = e->subject + real_subj_off; - } - else { - e->real_subj = NULL; - } - restore_char (&e->message_id, d, off); - restore_char (&e->supersedes, d, off); - restore_char (&e->date, d, off); - restore_char (&e->x_label, d, off); - restore_char (&e->list_post, d, off); + int n; + + dump_address(buf, e->return_path); + dump_address(buf, e->from); + dump_address(buf, e->to); + dump_address(buf, e->cc); + dump_address(buf, e->bcc); + dump_address(buf, e->sender); + dump_address(buf, e->reply_to); + dump_address(buf, e->mail_followup_to); + + dump_cstr(buf, e->subject); + n = e->real_subj ? e->real_subj - e->subject : -1; + dump_int(buf, n); + + dump_cstr(buf, e->message_id); + dump_cstr(buf, e->supersedes); + dump_cstr(buf, e->date); + dump_cstr(buf, e->x_label); + dump_cstr(buf, e->list_post); #ifdef USE_NNTP - restore_char (&e->newsgroups, d, off); - restore_char (&e->xref, d, off); - restore_char (&e->followup_to, d, off); - restore_char (&e->x_comment_to, d, off); + dump_cstr(buf, e->newsgroups); + dump_cstr(buf, e->xref); + dump_cstr(buf, e->followup_to); + dump_cstr(buf, e->x_comment_to); #endif - restore_list (&e->references, d, off); - restore_list (&e->in_reply_to, d, off); - restore_list (&e->userhdrs, d, off); + dump_list(buf, e->references); + dump_list(buf, e->in_reply_to); + dump_list(buf, e->userhdrs); } -static -unsigned int crc32 (unsigned int crc, unsigned char const *p, ssize_t len) +static const void *restore_envelope(const char *d, ENVELOPE *e) { - int i; - - while (len--) { - crc ^= *p++; - for (i = 0; i < 8; i++) - crc = (crc >> 1) ^ ((crc & 1) ? 0xedb88320 : 0); - } - return crc; -} - -static int generate_crc32 () -{ - int crc = 0; - - crc = crc32 (crc, (unsigned char const *) - MUTTNG_HCACHE_ID "sithglan@stud.uni-erlangen.de[sithglan]|hcache.c|20041108231548|29613", - m_strlen - (MUTTNG_HCACHE_ID "sithglan@stud.uni-erlangen.de[sithglan]|hcache.c|20041108231548|29613")); - -#ifdef HAVE_LANGINFO_CODESET - crc = crc32(crc, (unsigned char const *) MCharset.charset, m_strlen(MCharset.charset)); - crc = crc32(crc, (unsigned char const *) "HAVE_LANGINFO_CODESET", - m_strlen("HAVE_LANGINFO_CODESET")); -#endif - - crc = crc32(crc, (unsigned char const *) "USE_POP", m_strlen("USE_POP")); - - crc = crc32(crc, (unsigned char const *) "MIXMASTER", - m_strlen("MIXMASTER")); - - crc = crc32(crc, (unsigned char const *) "USE_IMAP", m_strlen("USE_IMAP")); + int real_subj_off; + + d = restore_address(d, &e->return_path); + d = restore_address(d, &e->from); + d = restore_address(d, &e->to); + d = restore_address(d, &e->cc); + d = restore_address(d, &e->bcc); + d = restore_address(d, &e->sender); + d = restore_address(d, &e->reply_to); + d = restore_address(d, &e->mail_followup_to); + + d = restore_cstr(d, &e->subject); + d = restore_int(d, &real_subj_off); + if (real_subj_off >= 0) { + e->real_subj = e->subject + real_subj_off; + } else { + e->real_subj = NULL; + } + d = restore_cstr(d, &e->message_id); + d = restore_cstr(d, &e->supersedes); + d = restore_cstr(d, &e->date); + d = restore_cstr(d, &e->x_label); + d = restore_cstr(d, &e->list_post); #ifdef USE_NNTP - crc = crc32(crc, (unsigned char const *) "USE_NNTP", m_strlen("USE_NNTP")); + d = restore_cstr(d, &e->newsgroups); + d = restore_cstr(d, &e->xref); + d = restore_cstr(d, &e->followup_to); + d = restore_cstr(d, &e->x_comment_to); #endif - return crc; -} - -static int crc32_matches (const char *d, unsigned int crc) -{ - int off = sizeof (validate); - unsigned int mycrc = 0; - - if (!d) { - return 0; - } - restore_int (&mycrc, (unsigned char *) d, &off); + d = restore_list(d, &e->references); + d = restore_list(d, &e->in_reply_to); + d = restore_list(d, &e->userhdrs); - return (crc == mycrc); + return d; } -static const char * -mutt_hcache_per_folder(const char *path, const char *folder) +static buffer_t *mutt_hcache_dump(hcache_t *db, HEADER *h, long uid_validity) { - static char buf[_POSIX_PATH_MAX]; - struct stat st; - int pos; - - if (stat(path, &st) < 0 || !S_ISDIR(st.st_mode)) { - return path; - } + buffer_t *res = buffer_new(); - pos = m_strcpy(buf, sizeof(buf), path); - pos += m_strputc(buf + pos, sizeof(buf) - pos, '/'); - - while (*folder) { - if (isalnum((unsigned char)*folder) || *folder == '.') { - pos += m_strputc(buf + pos, sizeof(buf) - pos, *folder); - } else { - pos += m_strputc(buf + pos, sizeof(buf) - pos, '_'); - } - folder++; + if (!uid_validity) { + uid_validity = time(NULL); } - pos += m_strcpy(buf + pos, sizeof(buf) - pos, ".hdb"); - return buf; + buffer_add(res, &uid_validity, sizeof(uid_validity)); + dump_int(res, db->crc); + buffer_add(res, h, sizeof(*h)); + + dump_envelope(res, h->env); + dump_body(res, h->content); + dump_cstr(res, h->maildir_flags); + return res; } -/* This function transforms a header into a char so that it is useable by - * db_store */ -static void *mutt_hcache_dump (void *_db, HEADER * h, int *off, - unsigned long uid_validity) +HEADER *mutt_hcache_restore(const void *_d, HEADER **oh) { - struct hcache_t *db = _db; - unsigned char *d = NULL; + const char *d = _d; + HEADER *h = header_new(); - *off = 0; + /* skip uid_validity + crc */ + d += sizeof(long) + sizeof(int); - d = lazy_malloc (sizeof (validate)); + memcpy(h, d, sizeof(*h)); + d += sizeof(*h); - if (uid_validity) { - memcpy (d, &uid_validity, sizeof (unsigned long)); - } - else { - struct timeval now; + h->env = envelope_new(); + d = restore_envelope(d, h->env); - gettimeofday (&now, NULL); - memcpy (d, &now, sizeof (struct timeval)); - } - *off += sizeof (validate); + h->content = body_new(); + d = restore_body(d, h->content); - d = dump_int (db->crc, d, off); + d = restore_cstr(d, &h->maildir_flags); - lazy_realloc (&d, *off + sizeof (HEADER)); - memcpy (d + *off, h, sizeof (HEADER)); - *off += sizeof (HEADER); - - d = dump_envelope (h->env, d, off); - d = dump_body (h->content, d, off); - d = dump_char (h->maildir_flags, d, off); + /* this is needed for maildir style mailboxes */ + if (oh) { + h->old = (*oh)->old; + h->path = m_strdup((*oh)->path); + header_delete(oh); + } - return d; + return h; } -HEADER *mutt_hcache_restore (const unsigned char *d, HEADER ** oh) -{ - int off = 0; - HEADER *h = header_new(); - - /* skip validate */ - off += sizeof (validate); - - /* skip crc */ - off += sizeof (unsigned int); - - memcpy (h, d + off, sizeof (HEADER)); - off += sizeof (HEADER); - - h->env = envelope_new(); - restore_envelope (h->env, d, &off); - - h->content = body_new(); - restore_body (h->content, d, &off); - - restore_char (&h->maildir_flags, d, &off); - - /* this is needed for maildir style mailboxes */ - if (oh) { - h->old = (*oh)->old; - h->path = m_strdup((*oh)->path); - header_delete(oh); - } - - return h; -} +/* }}} */ hcache_t *mutt_hcache_open(const char *path, const char *folder) { @@ -525,161 +428,88 @@ void mutt_hcache_close(hcache_t **db) p_delete(db); } -#if defined(HAVE_QDBM) -void * -mutt_hcache_fetch(hcache_t *db, const char *filename, - ssize_t(*keylen) (const char *fn)) +void *mutt_hcache_fetch(hcache_t *db, const char *filename, + ssize_t (*keylen)(const char *fn)) { - hcache_t *h = db; - char path[_POSIX_PATH_MAX]; - int ksize; - char *data = NULL; - - if (!h) - return NULL; - - m_strcpy(path, sizeof(path), h->folder); - m_strcat(path, sizeof(path), filename); - - ksize = strlen(h->folder) + keylen(path + strlen(h->folder)); - - data = vlget(h->db, path, ksize, NULL); - - if (!crc32_matches(data, h->crc)) - { - p_delete(&data); - return NULL; - } - - return data; -} + char path[_POSIX_PATH_MAX]; + char *data = NULL; -int -mutt_hcache_store(hcache_t *db, const char *filename, HEADER * header, - unsigned long uid_validity, - ssize_t(*keylen) (const char *fn)) -{ - hcache_t *h = db; - char path[_POSIX_PATH_MAX]; - int ret; - int ksize, dsize; - char *data = NULL; - - if (!h) - return -1; - - m_strcpy(path, sizeof(path), h->folder); - m_strcat(path, sizeof(path), filename); - - ksize = strlen(h->folder) + keylen(path + strlen(h->folder)); - - data = mutt_hcache_dump(db, header, &dsize, uid_validity); - - ret = vlput(h->db, path, ksize, data, dsize, VL_DOVER); - - p_delete(&data); - - return ret; -} - -int -mutt_hcache_delete(hcache_t *db, const char *filename, - ssize_t(*keylen) (const char *fn)) -{ - hcache_t *h = db; - char path[_POSIX_PATH_MAX]; - int ksize; - - if (!h) - return -1; - - m_strcpy(path, sizeof(path), h->folder); - m_strcat(path, sizeof(path), filename); + if (!db) + return NULL; - ksize = strlen(h->folder) + keylen(path + strlen(h->folder)); - - return vlout(h->db, path, ksize); -} + snprintf(path, sizeof(path), "%s%s", db->folder, filename); + { +#if defined(HAVE_QDBM) + int ksize = strlen(db->folder) + keylen(path + strlen(db->folder)); + data = vlget(db->db, path, ksize, NULL); #elif defined(HAVE_GDBM) + datum k = { .dptr = path, .dsize = keylen(path) }; -void *mutt_hcache_fetch (hcache_t *db, const char *filename, - ssize_t (*keylen) (const char *fn)) -{ - hcache_t *h = db; - datum key; - datum data; - char path[_POSIX_PATH_MAX]; - - if (!h) { - return NULL; - } - - m_strcpy(path, sizeof(path), h->folder); - strncat (path, filename, sizeof (path) - m_strlen(path)); - - key.dptr = path; - key.dsize = keylen (path); + data = gdbm_fetch(db->db, k).dtpr; +#endif + } - data = gdbm_fetch (h->db, key); + if (data) { + unsigned crc = 0; - if (!crc32_matches (data.dptr, h->crc)) { - p_delete(&data.dptr); - return NULL; - } + restore_int(data + sizeof(long), (int *)&crc); + if (crc != db->crc) + p_delete(&data); + } - return data.dptr; + return data; } -int -mutt_hcache_store (hcache_t *db, const char *filename, HEADER * header, - unsigned long uid_validity, ssize_t (*keylen) (const char *fn)) +int mutt_hcache_store(hcache_t *db, const char *filename, HEADER *header, + long uid_validity, ssize_t (*keylen)(const char *fn)) { - hcache_t *h = db; - datum key; - datum data; - char path[_POSIX_PATH_MAX]; - int ret; - - if (!h) { - return -1; - } + char path[_POSIX_PATH_MAX]; + buffer_t *data; + int ret; - m_strcpy(path, sizeof(path), h->folder); - strncat (path, filename, sizeof (path) - m_strlen(path)); + if (!db) + return -1; - key.dptr = path; - key.dsize = keylen (path); + snprintf(path, sizeof(path), "%s%s", db->folder, filename); + data = mutt_hcache_dump(db, header, uid_validity); - data.dptr = mutt_hcache_dump (db, header, &data.dsize, uid_validity); + { +#if defined(HAVE_QDBM) + int ksize = strlen(db->folder) + keylen(path + strlen(db->folder)); - ret = gdbm_store (h->db, key, data, GDBM_REPLACE); + ret = vlput(db->db, path, ksize, data->data, data->len, VL_DOVER); +#elif defined(HAVE_GDBM) + datum k = { .dptr = path, .dsize = keylen(path) }; + datum v = { .dptr = data->data, .dsize = data->len }; - p_delete(&data.dptr); + ret = gdbm_store(db->db, k, v, GDBM_REPLACE); +#endif + } - return ret; + buffer_delete(&data); + return ret; } -int -mutt_hcache_delete (hcache_t *db, const char *filename, - ssize_t (*keylen) (const char *fn)) +int mutt_hcache_delete(hcache_t *db, const char *filename, + ssize_t (*keylen)(const char *fn)) { - datum key; - hcache_t *h = db; - char path[_POSIX_PATH_MAX]; - - if (!h) { - return -1; - } + char path[_POSIX_PATH_MAX]; - m_strcpy(path, sizeof(path), h->folder); - strncat (path, filename, sizeof (path) - m_strlen(path)); + if (!db) + return -1; - key.dptr = path; - key.dsize = keylen (path); + snprintf(path, sizeof(path), "%s%s", db->folder, filename); - return gdbm_delete (h->db, key); -} + { +#if defined(HAVE_QDBM) + int ksize = strlen(db->folder) + keylen(path + strlen(db->folder)); + return vlout(db->db, path, ksize); +#elif defined(HAVE_GDBM) + datum k = { .dptr = path, .dsize = keylen(path) }; + return gdbm_delete(db->db, k); #endif + } +} #endif /* USE_HCACHE */