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
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++)
}
#if USE_HCACHE
- imap_hcache_open (idata);
+ idata->hcache = imap_hcache_open (idata, NULL);
#endif
/* save messages with real (non-flag) changes */
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
}
#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);
/* 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);
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);
idata->newMailCount = 0;
#if USE_HCACHE
- imap_hcache_open (idata);
+ idata->hcache = imap_hcache_open (idata, NULL);
if (idata->hcache && !msgbegin)
{
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);
}
}
#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)
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)