hcache_db_used=no
AC_ARG_ENABLE(hcache, AS_HELP_STRING([--enable-hcache],[Enable header caching]))
AC_ARG_WITH(tokyocabinet, AS_HELP_STRING([--without-tokyocabinet],[Don't use tokyocabinet even if it is available]))
+AC_ARG_WITH(kyotocabinet, AS_HELP_STRING([--without-kyotocabinet],[Don't use kyotocabinet even if it is available]))
AC_ARG_WITH(qdbm, AS_HELP_STRING([--without-qdbm],[Don't use qdbm even if it is available]))
AC_ARG_WITH(gdbm, AS_HELP_STRING([--without-gdbm],[Don't use gdbm even if it is available]))
AC_ARG_WITH(bdb, AS_HELP_STRING([--with-bdb@<:@=DIR@:>@],[Use BerkeleyDB4 if gdbm is not available]))
then
db_requested=TokyoCabinet
fi
+ if test -n "$with_kyotocabinet" && test "$with_kyotocabinet" != "no"
+ then
+ if test "$db_requested" != "auto"
+ then
+ AC_MSG_ERROR([more than one header cache engine requested.])
+ else
+ db_requested=KyotoCabinet
+ fi
+ fi
if test -n "$with_qdbm" && test "$with_qdbm" != "no"
then
if test "$db_requested" != "auto"
fi
fi
+ dnl -- Kyoto Cabinet --
+ if test "$with_kyotocabinet" != "no" \
+ && test "$db_requested" = auto -o "$db_requested" = KyotoCabinet
+ then
+ if test -n "$with_kyotocabinet" && test "$with_kyotocabinet" != "yes"
+ then
+ CPPFLAGS="$CPPFLAGS -I$with_kyotocabinet/include"
+ LDFLAGS="$LDFLAGS -L$with_kyotocabinet/lib"
+ fi
+
+ AC_CHECK_HEADER(kclangc.h,
+ AC_CHECK_LIB(kyotocabinet, kcdbopen,
+ [MUTTLIBS="$MUTTLIBS -lkyotocabinet"
+ AC_DEFINE(HAVE_KC, 1, [Kyoto Cabinet Support])
+ db_found=KyotoCabinet],
+ [CPPFLAGS="$OLDCPPFLAGS"
+ LDFLAGS="$OLDLDFLAGS"]))
+ if test "$db_requested" != auto && test "$db_found" != "$db_requested"
+ then
+ AC_MSG_ERROR([Kyoto Cabinet could not be used. Check config.log for details.])
+ fi
+ fi
+
dnl -- QDBM --
if test "$with_qdbm" != "no" && test $db_found = no \
&& test "$db_requested" = auto -o "$db_requested" = QDBM
if test $db_found = no
then
- AC_MSG_ERROR([You need Tokyo Cabinet, QDBM, GDBM, Berkeley DB4 or LMDB for hcache])
+ AC_MSG_ERROR([You need Tokyo Cabinet, Kyoto Cabinet, QDBM, GDBM, Berkeley DB4 or LMDB for hcache])
fi
fi
hcache_db_used=$db_found
#include <villa.h>
#elif HAVE_TC
#include <tcbdb.h>
+#elif HAVE_KC
+#include <kclangc.h>
#elif HAVE_GDBM
#include <gdbm.h>
#elif HAVE_DB4
char *folder;
unsigned int crc;
};
+#elif HAVE_KC
+struct header_cache
+{
+ KCDB *db;
+ char *folder;
+ unsigned int crc;
+};
#elif HAVE_GDBM
struct header_cache
{
#elif HAVE_TC
void *data;
int sp;
+#elif HAVE_KC
+ void *data;
+ size_t sp;
#elif HAVE_GDBM
datum key;
datum data;
#elif HAVE_TC
data = tcbdbget(h->db, path, ksize, &sp);
+ return data;
+#elif HAVE_KC
+ data = kcdbget(h->db, path, ksize, &sp);
+
return data;
#elif HAVE_GDBM
key.dptr = path;
return vlput(h->db, path, ksize, data, dlen, VL_DOVER);
#elif HAVE_TC
return tcbdbput(h->db, path, ksize, data, dlen);
+#elif HAVE_KC
+ return kcdbset(h->db, path, ksize, data, dlen);
#elif HAVE_GDBM
key.dptr = path;
key.dsize = ksize;
return tcbdbout(h->db, path, ksize);
}
+#elif HAVE_KC
+static int
+hcache_open_kc (struct header_cache *h, const char *path)
+{
+ char kcdbpath[_POSIX_PATH_MAX];
+ int printfresult;
+
+ printfresult = snprintf(kcdbpath, sizeof(kcdbpath),
+ "%s#type=kct#opts=%s#rcomp=lex",
+ path, option(OPTHCACHECOMPRESS) ? "lc" : "l");
+ if ((printfresult < 0) || (printfresult >= sizeof(kcdbpath)))
+ {
+ return -1;
+ }
+
+ h->db = kcdbnew();
+ if (!h->db)
+ return -1;
+
+ if (kcdbopen(h->db, kcdbpath, KCOWRITER | KCOCREATE))
+ return 0;
+ else
+ {
+#ifdef DEBUG
+ int ecode = kcdbecode (h->db);
+ dprint (2, (debugfile, "kcdbopen failed for %s: %s (ecode %d)\n", kcdbpath, kcdbemsg (h->db), ecode));
+#endif
+ kcdbdel(h->db);
+ return -1;
+ }
+}
+
+void
+mutt_hcache_close(header_cache_t *h)
+{
+ if (!h)
+ return;
+
+ if (!kcdbclose(h->db))
+ {
+#ifdef DEBUG
+ int ecode = kcdbecode (h->db);
+ dprint (2, (debugfile, "kcdbclose failed for %s: %s (ecode %d)\n", h->folder, kcdbemsg (h->db), ecode));
+#endif
+ }
+ kcdbdel(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 kcdbremove(h->db, path, ksize);
+}
+
#elif HAVE_GDBM
static int
hcache_open_gdbm (struct header_cache* h, const char* path)
#if HAVE_QDBM
hcache_open = hcache_open_qdbm;
#elif HAVE_TC
- hcache_open= hcache_open_tc;
+ hcache_open = hcache_open_tc;
+#elif HAVE_KC
+ hcache_open = hcache_open_kc;
#elif HAVE_GDBM
hcache_open = hcache_open_gdbm;
#elif HAVE_DB4
{
return "tokyocabinet " _TC_VERSION;
}
+#elif HAVE_KC
+const char *mutt_hcache_backend (void)
+{
+ /* SHORT_STRING(128) should be more than enough for KCVERSION */
+ static char version_cache[SHORT_STRING] = "";
+ if (!version_cache[0])
+ snprintf(version_cache, sizeof(version_cache), "kyotocabinet %s", KCVERSION);
+
+ return version_cache;
+}
#endif