Skip to content

Instantly share code, notes, and snippets.

@aeroevan
Created March 12, 2014 14:48
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aeroevan/9508433 to your computer and use it in GitHub Desktop.
Save aeroevan/9508433 to your computer and use it in GitHub Desktop.
kyoto-cabinet support for mutt
From d05824c53dfeb99fd2f6846e4b8331dee10f96c9 Mon Sep 17 00:00:00 2001
From: Evan McClain <aeroevan@gmail.com>
Date: Wed, 12 Mar 2014 10:14:09 -0400
Subject: [PATCH] mutt: kyoto-cabinet support.
---
configure.ac | 30 +++++++++++++++++++++++++++++-
hcache.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 89 insertions(+), 1 deletion(-)
diff --git a/configure.ac b/configure.ac
index 1b6e010..45f371a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -834,6 +834,7 @@ db_found=no
db_requested=auto
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, AC_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]))
@@ -854,6 +855,10 @@ then
then
db_requested=tc
fi
+ if test -n "$with_kyotocabinet" && test "$with_kyotocabinet" != "no"
+ then
+ db_requested=kc
+ fi
if test -n "$with_qdbm" && test "$with_qdbm" != "no"
then
if test "$db_requested" != "auto"
@@ -883,7 +888,7 @@ then
fi
dnl -- Tokyo Cabinet --
- if test "$with_tokyocabinet" != "no" \
+ if test "$with_tokyocabinet" != "no" \
&& test "$db_requested" = auto -o "$db_requested" = tc
then
if test -n "$with_tokyocabinet" && test "$with_tokyocabinet" != "yes"
@@ -905,6 +910,29 @@ then
fi
fi
+ dnl -- Kyoto Cabinet --
+ if test "$with_kyotocabinet" != "no" \
+ && test "$db_requested" = auto -o "$db_requested" = kc
+ 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=kc],
+ [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
diff --git a/hcache.c b/hcache.c
index af17932..c4b2658 100644
--- a/hcache.c
+++ b/hcache.c
@@ -28,6 +28,8 @@
#include <villa.h>
#elif HAVE_TC
#include <tcbdb.h>
+#elif HAVE_KC
+#include <kclangc.h>
#elif HAVE_GDBM
#include <gdbm.h>
#elif HAVE_DB4
@@ -62,6 +64,13 @@ struct header_cache
TCBDB *db;
char *folder;
unsigned int crc;
+};
+#elif HAVE_KC
+struct header_cache
+{
+ KCDB *db;
+ char *folder;
+ unsigned int crc;
};
#elif HAVE_GDBM
struct header_cache
@@ -952,6 +961,50 @@ mutt_hcache_delete(header_cache_t *h, const char *filename,
return tcbdbout(h->db, path, ksize);
}
+#elif HAVE_KC
+static int
+hcache_open_kc (struct header_cache* h, const char* path)
+{
+ h->db = kcdbnew();
+ if (kcdbopen(h->db, path, KCOWRITER | KCOCREATE))
+ return 0;
+ else
+ {
+ kcdbdel(h->db);
+ return -1;
+ }
+}
+
+void
+mutt_hcache_close(header_cache_t *h)
+{
+ if (!h)
+ return;
+
+ kcdbclose(h->db);
+ 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)
@@ -1123,6 +1176,8 @@ mutt_hcache_open(const char *path, const char *folder, hcache_namer_t namer)
hcache_open = hcache_open_qdbm;
#elif HAVE_TC
hcache_open= hcache_open_tc;
+#elif HAVE_TC
+ hcache_open= hcache_open_kc;
#elif HAVE_GDBM
hcache_open = hcache_open_gdbm;
#elif HAVE_DB4
@@ -1211,4 +1266,9 @@ const char *mutt_hcache_backend (void)
{
return "tokyocabinet " _TC_VERSION;
}
+#elif HAVE_KC
+const char *mutt_hcache_backend (void)
+{
+ return KCVERSION;
+}
#endif
--
1.9.0
@ElDeveloper
Copy link

I just tried this patch out and it produced a segmentation fault, after having a quick look with gdb, it seems that mutt_hcache_close needed an extra check to validate the DB was not NULL,

+  if (!h->db)
+    return;
+
+  kcdbclose(h->db);

Then I also noticed that in line 155, there's a typo, should be HAVE_KC not HAVE_TC right?

After this I tried a few other things but the cache doesn't seem to be working, did you ever get it to work in your machine?

@francoisjacques
Copy link

The missing check seems reasonable, however, it seems to me that the real problem here is the fact that the database was not initialized. A little bit more debugging would be required at the initialization to get to the bottom of this. Would be nice to have it working...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment