From: Brendan Cully Date: Wed, 11 Apr 2007 00:40:11 +0000 (-0700) Subject: Make IMAP header cache layout match body cache. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3452db42d69bc2fa513dbfb3499a58f2404c465e;p=neomutt Make IMAP header cache layout match body cache. You can now make them point to the same directory. Each folder will have a folder.hcache file for the header cache. --- diff --git a/hcache.c b/hcache.c index 1709509fc..05ae8a2f1 100644 --- a/hcache.c +++ b/hcache.c @@ -467,35 +467,61 @@ static const char * mutt_hcache_per_folder(const char *path, const char *folder, hcache_namer_t namer) { - static char mutt_hcache_per_folder_path[_POSIX_PATH_MAX]; - struct stat path_stat; + static char hcpath[_POSIX_PATH_MAX]; + struct stat sb; MD5_CTX md5; unsigned char md5sum[16]; - int ret; + char* s; + int ret, plen; - ret = stat(path, &path_stat); - if (ret < 0) - return path; + plen = mutt_strlen (path); - if (!S_ISDIR(path_stat.st_mode)) + ret = stat(path, &sb); + if (ret < 0 && path[plen-1] != '/') return path; - MD5Init(&md5); - MD5Update(&md5, (unsigned char *) folder, strlen(folder)); - MD5Final(md5sum, &md5); + if (ret >= 0 && !S_ISDIR(sb.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]); + if (namer) + { + snprintf (hcpath, sizeof (hcpath), "%s%s", path, + path[plen-1] == '/' ? "" : "/"); + if (path[plen-1] != '/') + plen++; + ret = namer (folder, hcpath + plen, sizeof (hcpath) - plen); + } + else + { + MD5Init(&md5); + MD5Update(&md5, (unsigned char *) folder, strlen(folder)); + MD5Final(md5sum, &md5); + + ret = snprintf(hcpath, _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]); + } + if (ret <= 0) return path; - return mutt_hcache_per_folder_path; + s = strchr (hcpath + 1, '/'); + while (s) + { + /* create missing path components */ + *s = '\0'; + if (stat (hcpath, &sb) < 0 && (errno != ENOENT || mkdir (hcpath, 0777) < 0)) + return path; + *s = '/'; + s = strchr (s + 1, '/'); + } + + return hcpath; } /* This function transforms a header into a char so that it is useable by diff --git a/imap/imap.c b/imap/imap.c index 4a93872d0..e192f8410 100644 --- a/imap/imap.c +++ b/imap/imap.c @@ -249,7 +249,7 @@ void imap_expunge_mailbox (IMAP_DATA* idata) int i, cacheno; #ifdef USE_HCACHE - imap_hcache_open (idata); + idata->hcache = imap_hcache_open (idata, NULL); #endif for (i = 0; i < idata->ctx->msgcount; i++) @@ -1146,7 +1146,7 @@ int imap_sync_mailbox (CONTEXT* ctx, int expunge, int* index_hint) } #if USE_HCACHE - imap_hcache_open (idata); + idata->hcache = imap_hcache_open (idata, NULL); #endif /* save messages with real (non-flag) changes */ @@ -1569,6 +1569,7 @@ IMAP_STATUS* imap_mboxcache_get (IMAP_DATA* idata, const char* mbox, int create) header_cache_t *hc = NULL; ciss_url_t url; char urlstr[LONG_STRING]; + char cpath[LONG_STRING]; unsigned int *uidvalidity = NULL; unsigned int *uidnext = NULL; #endif @@ -1594,10 +1595,7 @@ IMAP_STATUS* imap_mboxcache_get (IMAP_DATA* idata, const char* mbox, int create) } #ifdef USE_HCACHE - mutt_account_tourl (&idata->conn->account, &url); - url.path = (char*)mbox; - url_ciss_tostring (&url, urlstr, sizeof (urlstr), 0); - hc = mutt_hcache_open (HeaderCache, urlstr, NULL); + hc = imap_hcache_open (idata, mbox); if (hc) { uidvalidity = mutt_hcache_fetch_raw (hc, "/UIDVALIDITY", imap_hcache_keylen); diff --git a/imap/imap_private.h b/imap/imap_private.h index 410f6bff0..98adc8b2c 100644 --- a/imap/imap_private.h +++ b/imap/imap_private.h @@ -259,7 +259,7 @@ int imap_cache_del (IMAP_DATA* idata, HEADER* h); /* util.c */ #ifdef USE_HCACHE -int imap_hcache_open (IMAP_DATA* idata); +header_cache_t* imap_hcache_open (IMAP_DATA* idata, const char* path); void imap_hcache_close (IMAP_DATA* idata); HEADER* imap_hcache_get (IMAP_DATA* idata, unsigned int uid); int imap_hcache_put (IMAP_DATA* idata, HEADER* h); @@ -272,6 +272,8 @@ IMAP_DATA* imap_new_idata (void); void imap_free_idata (IMAP_DATA** idata); char* imap_fix_path (IMAP_DATA* idata, char* mailbox, char* path, size_t plen); +void imap_cachepath(IMAP_DATA* idata, const char* mailbox, char* dest, + size_t dlen); int imap_get_literal_count (const char* buf, long* bytes); char* imap_get_qualifier (char* buf); int imap_mxcmp (const char* mx1, const char* mx2); diff --git a/imap/message.c b/imap/message.c index d2fe9890d..0cd3e50e2 100644 --- a/imap/message.c +++ b/imap/message.c @@ -119,7 +119,7 @@ int imap_read_headers (IMAP_DATA* idata, int msgbegin, int msgend) idata->newMailCount = 0; #if USE_HCACHE - imap_hcache_open (idata); + idata->hcache = imap_hcache_open (idata, NULL); if (idata->hcache && !msgbegin) { @@ -847,35 +847,12 @@ int imap_copy_messages (CONTEXT* ctx, HEADER* h, char* dest, int delete) static body_cache_t *msg_cache_open (IMAP_DATA *idata) { - char *s; - char *p = idata->mailbox; char mailbox[_POSIX_PATH_MAX]; - size_t mlen = sizeof (mailbox); if (idata->bcache) return idata->bcache; - mailbox[0] = '\0'; - - for (s = mailbox; p && *p && mlen; mlen--) - { - if (*p == idata->delim) - { - *s = '/'; - /* simple way to avoid collisions with UIDs */ - if (*(p + 1) >= '0' && *(p + 1) <= '9') - { - mlen--; - if (mlen) - *++s = '_'; - } - } - else - *s = *p; - p++; - s++; - } - *s = '\0'; + imap_cachepath (idata, idata->mailbox, mailbox, sizeof (mailbox)); return mutt_bcache_open (&idata->conn->account, mailbox); } diff --git a/imap/util.c b/imap/util.c index 7fab623c2..076c75877 100644 --- a/imap/util.c +++ b/imap/util.c @@ -71,23 +71,34 @@ int imap_expand_path (char* path, size_t len) } #ifdef USE_HCACHE -int imap_hcache_open (IMAP_DATA* idata) +static int imap_hcache_namer (const char* path, char* dest, size_t dlen) +{ + return snprintf (dest, dlen, "%s.hcache", path); +} + +header_cache_t* imap_hcache_open (IMAP_DATA* idata, const char* path) { IMAP_MBOX mx; ciss_url_t url; char cachepath[LONG_STRING]; + char mbox[LONG_STRING]; if (imap_parse_path (idata->ctx->path, &mx) < 0) return -1; - mutt_account_tourl (&idata->conn->account, &url); - url.path = mx.mbox; - url_ciss_tostring (&url, cachepath, sizeof (cachepath), 0); - FREE (&mx.mbox); + if (path) + imap_cachepath (idata, path, mbox, sizeof (mbox)); + else + { + imap_cachepath (idata, mx.mbox, mbox, sizeof (mbox)); + FREE (&mx.mbox); + } - idata->hcache = mutt_hcache_open (HeaderCache, cachepath, NULL); + mutt_account_tourl (&idata->conn->account, &url); + url.path = mbox; + url_ciss_tostring (&url, cachepath, sizeof (cachepath), U_PATH); - return idata->hcache != NULL ? 0 : -1; + return mutt_hcache_open (HeaderCache, cachepath, imap_hcache_namer); } void imap_hcache_close (IMAP_DATA* idata) @@ -398,6 +409,32 @@ char *imap_fix_path (IMAP_DATA *idata, char *mailbox, char *path, return path; } +void imap_cachepath(IMAP_DATA* idata, const char* mailbox, char* dest, + size_t dlen) +{ + char* s; + const char* p = mailbox; + + for (s = dest; p && *p && dlen; dlen--) + { + if (*p == idata->delim) + { + *s = '/'; + /* simple way to avoid collisions with UIDs */ + if (*(p + 1) >= '0' && *(p + 1) <= '9') + { + if (--dlen) + *++s = '_'; + } + } + else + *s = *p; + p++; + s++; + } + *s = '\0'; +} + /* imap_get_literal_count: write number of bytes in an IMAP literal into * bytes, return 0 on success, -1 on failure. */ int imap_get_literal_count(const char *buf, long *bytes)