X-Git-Url: http://git.madism.org/?p=apps%2Fmadmutt.git;a=blobdiff_plain;f=lib-mx%2Fhcache.c;h=4b07b5a40b3508bdd4e8882e4c5718e6ca7479d8;hp=a6aa68d4f3e64402156da8a32bf40e4e8009b096;hb=9eb790d6eb4a56416d342816e1140aabd9c12de8;hpb=1d0ce70b85c36973b50e5783fe7b72941c81c0a9 diff --git a/lib-mx/hcache.c b/lib-mx/hcache.c index a6aa68d..4b07b5a 100644 --- a/lib-mx/hcache.c +++ b/lib-mx/hcache.c @@ -21,35 +21,22 @@ #include #elif defined(HAVE_GDBM) #include -#elif defined(HAVE_DB4) -#include #endif -#include -#include - #include #include "charset.h" #include "mutt.h" #include "hcache.h" -struct header_cache { +struct hcache_t { #if defined(HAVE_QDBM) VILLA *db; - char *folder; - unsigned int crc; #elif defined(HAVE_GDBM) GDBM_FILE db; +#endif char *folder; unsigned int crc; -#elif defined(HAVE_DB4) - DB_ENV *env; - DB *db; - unsigned int crc; - int fd; - char lockfile[_POSIX_PATH_MAX]; -#endif }; typedef union { @@ -361,7 +348,7 @@ static int generate_crc32 () (MUTTNG_HCACHE_ID "sithglan@stud.uni-erlangen.de[sithglan]|hcache.c|20041108231548|29613")); #ifdef HAVE_LANGINFO_CODESET - crc = crc32(crc, (unsigned char const *) Charset, m_strlen(Charset)); + 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 @@ -393,42 +380,30 @@ static int crc32_matches (const char *d, unsigned int crc) return (crc == mycrc); } -/* Append md5sumed folder to path if path is a directory. */ -static const char *mutt_hcache_per_folder (const char *path, - const char *folder) +static const char * +mutt_hcache_per_folder(const char *path, const char *folder) { - static char mutt_hcache_per_folder_path[_POSIX_PATH_MAX]; - struct stat path_stat; - MD5_CTX md5; - unsigned char md5sum[16]; - int ret; + static char buf[_POSIX_PATH_MAX]; + struct stat st; + int pos; - ret = stat (path, &path_stat); - if (ret < 0) { - return path; - } - - if (!S_ISDIR (path_stat.st_mode)) { - return path; - } - - MD5Init (&md5); - MD5Update (&md5, (unsigned char *) folder, m_strlen(folder)); - MD5Final (md5sum, &md5); + if (stat(path, &st) < 0 || !S_ISDIR(st.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]); + pos = m_strcpy(buf, sizeof(buf), path); + pos += m_strputc(buf + pos, sizeof(buf) - pos, '/'); - if (ret <= 0) { - return path; - } - - return mutt_hcache_per_folder_path; + 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; } /* This function transforms a header into a char so that it is useable by @@ -436,7 +411,7 @@ static const char *mutt_hcache_per_folder (const char *path, static void *mutt_hcache_dump (void *_db, HEADER * h, int *off, unsigned long uid_validity) { - struct header_cache *db = _db; + struct hcache_t *db = _db; unsigned char *d = NULL; *off = 0; @@ -499,58 +474,63 @@ HEADER *mutt_hcache_restore (const unsigned char *d, HEADER ** oh) return h; } -#if defined(HAVE_QDBM) -void * -mutt_hcache_open(const char *path, const char *folder) +hcache_t *mutt_hcache_open(const char *path, const char *folder) { - struct header_cache *h = p_new(struct header_cache, 1); - int flags = VL_OWRITER | VL_OCREAT; - h->db = NULL; - h->folder = m_strdup(folder); - h->crc = generate_crc32(); + hcache_t *h = p_new(hcache_t, 1); - if (!path || path[0] == '\0') - { - p_delete(&h->folder); - p_delete(&h); - return NULL; - } + h->folder = m_strdup(folder); + h->crc = generate_crc32(); - path = mutt_hcache_per_folder(path, folder); + if (m_strisempty(path)) { + p_delete(&h->folder); + p_delete(&h); + return NULL; + } - if (option(OPTHCACHECOMPRESS)) - flags |= VL_OZCOMP; + path = mutt_hcache_per_folder(path, folder); - h->db = vlopen(path, flags, VL_CMPLEX); - if (h->db) - return h; - else - { - p_delete(&h->folder); - p_delete(&h); + { +#if defined(HAVE_QDBM) + int flags = VL_OWRITER | VL_OCREAT; + if (option(OPTHCACHECOMPRESS)) + flags |= VL_OZCOMP; - return NULL; - } + h->db = vlopen(path, flags, VL_CMPLEX); +#elif defined(HAVE_GDBM) + int pagesize = atoi(HeaderCachePageSize) ?: 16384; + + h->db = gdbm_open((char *) path, pagesize, GDBM_WRCREAT, 00600, NULL); +#endif + } + + if (!h->db) { + p_delete(&h->folder); + p_delete(&h); + } + return h; } -void -mutt_hcache_close(void *db) +void mutt_hcache_close(hcache_t **db) { - struct header_cache *h = db; + if (!*db) + return; - if (!h) - return; +#if defined(HAVE_QDBM) + vlclose((*db)->db); +#elif defined(HAVE_GDBM) + gdbm_close((*db)->db); +#endif - vlclose(h->db); - p_delete(&h->folder); - p_delete(&h); + p_delete(&(*db)->folder); + p_delete(db); } +#if defined(HAVE_QDBM) void * -mutt_hcache_fetch(void *db, const char *filename, +mutt_hcache_fetch(hcache_t *db, const char *filename, ssize_t(*keylen) (const char *fn)) { - struct header_cache *h = db; + hcache_t *h = db; char path[_POSIX_PATH_MAX]; int ksize; char *data = NULL; @@ -575,11 +555,11 @@ mutt_hcache_fetch(void *db, const char *filename, } int -mutt_hcache_store(void *db, const char *filename, HEADER * header, +mutt_hcache_store(hcache_t *db, const char *filename, HEADER * header, unsigned long uid_validity, ssize_t(*keylen) (const char *fn)) { - struct header_cache *h = db; + hcache_t *h = db; char path[_POSIX_PATH_MAX]; int ret; int ksize, dsize; @@ -603,10 +583,10 @@ mutt_hcache_store(void *db, const char *filename, HEADER * header, } int -mutt_hcache_delete(void *db, const char *filename, +mutt_hcache_delete(hcache_t *db, const char *filename, ssize_t(*keylen) (const char *fn)) { - struct header_cache *h = db; + hcache_t *h = db; char path[_POSIX_PATH_MAX]; int ksize; @@ -623,58 +603,10 @@ mutt_hcache_delete(void *db, const char *filename, #elif defined(HAVE_GDBM) -void *mutt_hcache_open (const char *path, const char *folder) -{ - struct header_cache *h = p_new(struct header_cache, 1); - int pagesize = - atoi (HeaderCachePageSize) ? atoi (HeaderCachePageSize) : 16384; - h->db = NULL; - h->folder = m_strdup(folder); - h->crc = generate_crc32 (); - - if (!path || path[0] == '\0') { - p_delete(&h->folder); - p_delete(&h); - return NULL; - } - - path = mutt_hcache_per_folder (path, folder); - - h->db = gdbm_open ((char *) path, pagesize, GDBM_WRCREAT, 00600, NULL); - if (h->db) { - return h; - } - - /* if rw failed try ro */ - h->db = gdbm_open ((char *) path, pagesize, GDBM_READER, 00600, NULL); - if (h->db) { - return h; - } - else { - p_delete(&h->folder); - p_delete(&h); - - return NULL; - } -} - -void mutt_hcache_close (void *db) -{ - struct header_cache *h = db; - - if (!h) { - return; - } - - gdbm_close (h->db); - p_delete(&h->folder); - p_delete(&h); -} - -void *mutt_hcache_fetch (void *db, const char *filename, +void *mutt_hcache_fetch (hcache_t *db, const char *filename, ssize_t (*keylen) (const char *fn)) { - struct header_cache *h = db; + hcache_t *h = db; datum key; datum data; char path[_POSIX_PATH_MAX]; @@ -700,10 +632,10 @@ void *mutt_hcache_fetch (void *db, const char *filename, } int -mutt_hcache_store (void *db, const char *filename, HEADER * header, +mutt_hcache_store (hcache_t *db, const char *filename, HEADER * header, unsigned long uid_validity, ssize_t (*keylen) (const char *fn)) { - struct header_cache *h = db; + hcache_t *h = db; datum key; datum data; char path[_POSIX_PATH_MAX]; @@ -729,11 +661,11 @@ mutt_hcache_store (void *db, const char *filename, HEADER * header, } int -mutt_hcache_delete (void *db, const char *filename, +mutt_hcache_delete (hcache_t *db, const char *filename, ssize_t (*keylen) (const char *fn)) { datum key; - struct header_cache *h = db; + hcache_t *h = db; char path[_POSIX_PATH_MAX]; if (!h) { @@ -748,182 +680,6 @@ mutt_hcache_delete (void *db, const char *filename, return gdbm_delete (h->db, key); } -#elif defined(HAVE_DB4) - -static void mutt_hcache_dbt_init (DBT * dbt, void *data, ssize_t len) -{ - dbt->data = data; - dbt->size = dbt->ulen = len; - dbt->dlen = dbt->doff = 0; - dbt->flags = DB_DBT_USERMEM; -} - -static void mutt_hcache_dbt_empty_init (DBT * dbt) -{ - dbt->data = NULL; - dbt->size = dbt->ulen = dbt->dlen = dbt->doff = 0; - dbt->flags = 0; -} - -void *mutt_hcache_open (const char *path, const char *folder) -{ - struct stat sb; - u_int32_t createflags = DB_CREATE; - int ret; - struct header_cache *h = p_new(struct header_cache, 1); - int pagesize = atoi (HeaderCachePageSize); - - - h->crc = generate_crc32 (); - - if (!path || path[0] == '\0') { - p_delete(&h); - return NULL; - } - - path = mutt_hcache_per_folder (path, folder); - - snprintf (h->lockfile, _POSIX_PATH_MAX, "%s-lock-hack", path); - - h->fd = open (h->lockfile, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR); - if (h->fd < 0) { - p_delete(&h); - return NULL; - } - - if (mx_lock_file (h->lockfile, h->fd, 1, 0, 5)) { - close (h->fd); - p_delete(&h); - return NULL; - } - - ret = db_env_create (&h->env, 0); - if (ret) { - mx_unlock_file (h->lockfile, h->fd, 0); - close (h->fd); - p_delete(&h); - return NULL; - } - - ret = - (h->env->open)(h->env, NULL, DB_INIT_MPOOL | DB_CREATE | DB_PRIVATE, 0600); - if (!ret) { - ret = db_create (&h->db, h->env, 0); - if (ret) { - h->env->close (h->env, 0); - mx_unlock_file (h->lockfile, h->fd, 0); - close (h->fd); - p_delete(&h); - return NULL; - } - } - - if (stat (path, &sb) != 0 && errno == ENOENT) { - createflags |= DB_EXCL; - h->db->set_pagesize (h->db, pagesize); - } - - ret = (h->db->open)(h->db, NULL, path, folder, DB_BTREE, createflags, 0600); - if (ret) { - h->db->close (h->db, 0); - h->env->close (h->env, 0); - mx_unlock_file (h->lockfile, h->fd, 0); - close (h->fd); - p_delete(&h); - return NULL; - } - - return h; -} - -void mutt_hcache_close (void *db) -{ - struct header_cache *h = db; - - if (!h) { - return; - } - - h->db->close (h->db, 0); - h->env->close (h->env, 0); - mx_unlock_file (h->lockfile, h->fd, 0); - close (h->fd); - p_delete(&h); -} - -void *mutt_hcache_fetch (void *db, const char *filename, - ssize_t (*keylen) (const char *fn)) -{ - DBT key; - DBT data; - struct header_cache *h = db; - - if (!h) { - return NULL; - } - - filename++; /* skip '/' */ - - mutt_hcache_dbt_init (&key, (void *) filename, keylen (filename)); - mutt_hcache_dbt_empty_init (&data); - data.flags = DB_DBT_MALLOC; - - h->db->get (h->db, NULL, &key, &data, 0); - - if (!crc32_matches (data.data, h->crc)) { - p_delete(&data.data); - return NULL; - } - - return data.data; -} - -int -mutt_hcache_store (void *db, const char *filename, HEADER * header, - unsigned long uid_validity, ssize_t (*keylen) (const char *fn)) -{ - DBT key; - DBT data; - int ret; - struct header_cache *h = db; - - if (!h) { - return -1; - } - - filename++; /* skip '/' */ - - mutt_hcache_dbt_init (&key, (void *) filename, keylen (filename)); - - mutt_hcache_dbt_empty_init (&data); - data.flags = DB_DBT_USERMEM; - data.data = - mutt_hcache_dump (db, header, (signed int *) &data.size, uid_validity); - data.ulen = data.size; - - ret = h->db->put (h->db, NULL, &key, &data, 0); - - p_delete(&data.data); - - return ret; -} - -int -mutt_hcache_delete (void *db, const char *filename, - ssize_t (*keylen) (const char *fn)) -{ - DBT key; - struct header_cache *h = db; - - if (!h) { - return -1; - } - - filename++; /* skip '/' */ - - mutt_hcache_dbt_init (&key, (void *) filename, keylen (filename)); - return h->db->del (h->db, NULL, &key, 0); -} #endif #endif /* USE_HCACHE */