Commit df905e61 df905e61a7c77f02203c3445757a6f59a02a85b0 by Wojciech Polak

Add Kyoto Cabinet DBM support.

* libmu_dbm/kyoto.c: New file.
* libmu_dbm/dbm.c: Update.
* libmu_dbm/mudbm.h: Update.
* libmu_dbm/Makefile.am: (libmu_dbm_la_SOURCES): Add kyoto.c
* configure.ac: Add --with-kyotocabinet.
* README: Update.
* doc/texinfo/programs.texi: Likewise.
* libmailutils/base/version.c: Likewise.
1 parent 65f1d1f2
......@@ -287,6 +287,11 @@ use DBM-based mail box quotas with maildag.
Use Tokyo Cabinet DBM
--with-kyotocabinet
Use Kyoto Cabinet DBM
Use following options to disable support for particular protocols or
features:
......
......@@ -413,6 +413,16 @@ case "${withval}" in
*) AC_MSG_ERROR(bad value ${withval} for --with-tokyocabinet) ;;
esac])
AC_ARG_WITH([kyotocabinet],
AC_HELP_STRING([--with-kyotocabinet],
[use Kyoto Cabinet]),
[
case "${withval}" in
yes) enable_dbm="$enable_dbm KC";;
no) disable_dbm="$disable_dbm KC";;
*) AC_MSG_ERROR(bad value ${withval} for --with-kyotocabinet) ;;
esac])
dnl Check for DBM
AH_TEMPLATE([WITH_BDB],
......@@ -551,6 +561,15 @@ check_dbm_impl() {
DBMLIB_DEPENDENCY="$DBMLIB_DEPENDENCY -lz -lbz2 -lrt"
DBMLIBS="$DBMLIBS -ltokyocabinet"
status_dbm="$status_dbm,Tokyo Cabinet"]);;
KC)
AC_CHECK_LIB(kyotocabinet, kcdbnew,
[AC_CHECK_HEADERS(kclangc.h,
AC_DEFINE(WITH_KYOTOCABINET,1,
[Enable use of Kyoto Cabinet]))
DBMLIB_DEPENDENCY="$DBMLIB_DEPENDENCY -lz -lbz2 -lrt"
DBMLIBS="$DBMLIBS -lkyotocabinet"
status_dbm="$status_dbm,Kyoto Cabinet"]);;
esac
}
......
......@@ -5649,8 +5649,8 @@ The mailbox quota can be retrieved from the following sources:
To use @acronym{DBM} quota database, GNU Mailutils must
be compiled with one of the following command line options:
@option{--with-gdbm}, @option{--with-berkeley-db}, @option{--with-ndbm},
or @option{--with-tokyocabinet}. Examine the output of @command{maidag
--show-config-options}, if not sure.
@option{--with-tokyocabinet}, or @option{--with-kyotocabinet}.
Examine the output of @command{maidag --show-config-options}, if not sure.
The quota database should have the following structure:
......
......@@ -61,6 +61,9 @@ static struct mu_conf_option mu_conf_option[] = {
#ifdef WITH_TOKYOCABINET
{ "WITH_TOKYOCABINET", N_("Tokyo Cabinet DBM") },
#endif
#ifdef WITH_KYOTOCABINET
{ "WITH_KYOTOCABINET", N_("Kyoto Cabinet DBM") },
#endif
#ifdef WITH_GNUTLS
{ "WITH_GNUTLS", N_("TLS support using GNU TLS") },
#endif
......
......@@ -36,6 +36,7 @@ libmu_dbm_la_SOURCES = \
store.c\
berkeley.c\
gdbm.c\
kyoto.c\
ndbm.c\
tokyo.c
......
......@@ -83,6 +83,9 @@ mu_dbm_init ()
#ifdef WITH_TOKYOCABINET
mu_dbm_register (&_mu_dbm_tokyocabinet);
#endif
#ifdef WITH_KYOTOCABINET
mu_dbm_register (&_mu_dbm_kyotocabinet);
#endif
if (!mu_dbm_hint)
{
struct mu_dbm_impl *impl;
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2011 Free Software Foundation, Inc.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General
Public License along with this library. If not, see
<http://www.gnu.org/licenses/>. */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <mailutils/types.h>
#include <mailutils/dbm.h>
#include <mailutils/util.h>
#include <mailutils/errno.h>
#include <mailutils/error.h>
#include <mailutils/stream.h>
#include <mailutils/io.h>
#include "mudbm.h"
#if defined(WITH_KYOTOCABINET)
#include <kclangc.h>
struct kc_descr
{
KCDB *db; /* db */
KCCUR *cur; /* cursor */
};
static int
_kc_file_safety (mu_dbm_file_t db, int mode, uid_t owner)
{
return mu_file_safety_check (db->db_name, mode, owner, NULL);
}
int
_kc_get_fd (mu_dbm_file_t db, int *pag, int *dir)
{
return ENOSYS;
}
static int
_kc_open (mu_dbm_file_t db, int flags, int mode)
{
struct kc_descr *kcd;
int f, result;
mode_t save_um;
KCDB *kdb;
switch (flags)
{
case MU_STREAM_CREAT:
f = KCOWRITER | KCOCREATE;
break;
case MU_STREAM_READ:
f = KCOREADER;
break;
case MU_STREAM_RDWR:
f = KCOREADER | KCOWRITER;
break;
default:
return EINVAL;
}
kdb = kcdbnew ();
save_um = umask (0666 & ~mode);
result = kcdbopen (kdb, db->db_name, f);
umask (save_um);
if (!result)
{
db->db_errno.n = kcdbecode (kdb);
return MU_ERR_FAILURE;
}
kcd = calloc (1, sizeof (*kcd));
kcd->db = kdb;
kcd->cur = NULL;
db->db_descr = kcd;
return 0;
}
static int
_kc_close (mu_dbm_file_t db)
{
if (db->db_descr)
{
struct kc_descr *kcd = db->db_descr;
kcdbclose (kcd->db);
kcdbdel (kcd->db);
free (kcd);
db->db_descr = NULL;
}
return 0;
}
static int
_kc_fetch (mu_dbm_file_t db, struct mu_dbm_datum const *key,
struct mu_dbm_datum *ret)
{
struct kc_descr *kcd = db->db_descr;
void *ptr;
size_t retsize;
ptr = kcdbget (kcd->db, key->mu_dptr, key->mu_dsize, &retsize);
if (ptr)
{
mu_dbm_datum_free (ret);
ret->mu_dptr = ptr;
ret->mu_dsize = retsize;
return 0;
}
else if ((db->db_errno.n = kcdbecode (kcd->db)) == KCENOREC)
return MU_ERR_NOENT;
return MU_ERR_FAILURE;
}
static int
_kc_store (mu_dbm_file_t db,
struct mu_dbm_datum const *key,
struct mu_dbm_datum const *contents,
int replace)
{
struct kc_descr *kcd = db->db_descr;
int result;
if (replace)
result = kcdbreplace (kcd->db, key->mu_dptr, key->mu_dsize,
contents->mu_dptr, contents->mu_dsize);
else
result = kcdbadd (kcd->db, key->mu_dptr, key->mu_dsize,
contents->mu_dptr, contents->mu_dsize);
if (result)
return 0;
db->db_errno.n = kcdbecode (kcd->db);
if (db->db_errno.n == KCEDUPREC)
return MU_ERR_EXISTS;
return MU_ERR_FAILURE;
}
static int
_kc_delete (mu_dbm_file_t db, struct mu_dbm_datum const *key)
{
struct kc_descr *kcd = db->db_descr;
if (kcdbremove (kcd->db, key->mu_dptr, key->mu_dsize))
return 0;
db->db_errno.n = kcdbecode (kcd->db);
if (db->db_errno.n == KCENOREC)
return MU_ERR_NOENT;
return MU_ERR_FAILURE;
}
static int
_kc_firstkey (mu_dbm_file_t db, struct mu_dbm_datum *ret)
{
struct kc_descr *kcd = db->db_descr;
void *ptr;
size_t retsize;
kcd->cur = kcdbcursor (kcd->db);
kccurjump (kcd->cur);
ptr = kccurgetkey (kcd->cur, &retsize, 1);
if (ptr)
{
mu_dbm_datum_free (ret);
ret->mu_dptr = ptr;
ret->mu_dsize = retsize;
return 0;
}
else if ((db->db_errno.n = kcdbecode (kcd->db)) == KCENOREC)
{
kccurdel (kcd->cur);
kcd->cur = NULL;
return MU_ERR_NOENT;
}
return MU_ERR_FAILURE;
}
static int
_kc_nextkey (mu_dbm_file_t db, struct mu_dbm_datum *ret)
{
struct kc_descr *kcd = db->db_descr;
void *ptr;
size_t retsize;
ptr = kccurgetkey (kcd->cur, &retsize, 1);
if (ptr)
{
mu_dbm_datum_free (ret);
ret->mu_dptr = ptr;
ret->mu_dsize = retsize;
return 0;
}
else if ((db->db_errno.n = kcdbecode (kcd->db)) == KCENOREC)
{
kccurdel (kcd->cur);
kcd->cur = NULL;
return MU_ERR_NOENT;
}
return MU_ERR_FAILURE;
}
static void
_kc_datum_free (struct mu_dbm_datum *datum)
{
free (datum->mu_dptr);
}
static char const *
_kc_strerror (mu_dbm_file_t db)
{
return kcecodename (db->db_errno.n);
}
struct mu_dbm_impl _mu_dbm_kyotocabinet = {
"kc",
_kc_file_safety,
_kc_get_fd,
_kc_open,
_kc_close,
_kc_fetch,
_kc_store,
_kc_delete,
_kc_firstkey,
_kc_nextkey,
_kc_datum_free,
_kc_strerror
};
#endif
......@@ -42,6 +42,9 @@ extern struct mu_dbm_impl _mu_dbm_ndbm;
#ifdef WITH_TOKYOCABINET
extern struct mu_dbm_impl _mu_dbm_tokyocabinet;
#endif
#ifdef WITH_KYOTOCABINET
extern struct mu_dbm_impl _mu_dbm_kyotocabinet;
#endif
void _mu_dbm_init (void);
......