Commit 87e973dd 87e973ddd0b24493db0b316890360a2fdb028626 by Wojciech Polak

Re-add Tokyo Cabinet DBM support.

* libmu_dbm/tokyo.c: New file.
* libmu_dbm/Makefile.am (libmu_dbm_la_SOURCES): Add tokyo.c.
* doc/texinfo/programs.texi: Update.
* README: Update.
1 parent 1145460e
......@@ -287,10 +287,6 @@ use DBM-based mail box quotas with maildag.
Use Tokyo Cabinet DBM
Only one dbm option may be specified. Which one depends on
the flavor of DBM you are using. GDBM is most common for GNU
system.
Use following options to disable support for particular protocols or
features:
......
......@@ -5648,8 +5648,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}, or
@option{--with-ndbm}. Examine the output of @command{maidag
@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.
The quota database should have the following structure:
......
......@@ -36,7 +36,8 @@ libmu_dbm_la_SOURCES = \
store.c\
berkeley.c\
gdbm.c\
ndbm.c
ndbm.c\
tokyo.c
noinst_HEADERS = mudbm.h
......
/* 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_TOKYOCABINET)
#include <tcutil.h>
#include <tchdb.h>
static int
_tc_file_safety (mu_dbm_file_t db, int mode, uid_t owner)
{
return mu_file_safety_check (db->db_name, mode, owner, NULL);
}
int
_tc_get_fd (mu_dbm_file_t db, int *pag, int *dir)
{
TCHDB *hdb = db->db_descr;
*pag = hdb->fd;
if (dir)
*dir = *pag;
return 0;
}
static int
_tc_open (mu_dbm_file_t db, int flags, int mode)
{
int f;
bool result;
mode_t save_um;
TCHDB *hdb;
switch (flags)
{
case MU_STREAM_CREAT:
f = HDBOWRITER | HDBOCREAT;
break;
case MU_STREAM_READ:
f = HDBOREADER;
break;
case MU_STREAM_RDWR:
f = HDBOREADER | HDBOWRITER;
break;
default:
return EINVAL;
}
hdb = tchdbnew ();
save_um = umask (0666 & ~mode);
result = tchdbopen (hdb, db->db_name, f);
umask (save_um);
if (!result)
{
db->db_errno.n = tchdbecode (hdb);
return MU_ERR_FAILURE;
}
db->db_descr = hdb;
return 0;
}
static int
_tc_close (mu_dbm_file_t db)
{
if (db->db_descr)
{
TCHDB *hdb = db->db_descr;
tchdbclose (hdb);
tchdbdel (hdb);
db->db_descr = NULL;
}
return 0;
}
static int
_tc_fetch (mu_dbm_file_t db, struct mu_dbm_datum const *key,
struct mu_dbm_datum *ret)
{
TCHDB *hdb = db->db_descr;
void *ptr;
int retsize;
ptr = tchdbget (hdb, 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 = tchdbecode (hdb)) == TCENOREC)
return MU_ERR_NOENT;
return MU_ERR_FAILURE;
}
static int
_tc_store (mu_dbm_file_t db,
struct mu_dbm_datum const *key,
struct mu_dbm_datum const *contents,
int replace)
{
TCHDB *hdb = db->db_descr;
bool result;
if (replace)
result = tchdbput (hdb, key->mu_dptr, key->mu_dsize,
contents->mu_dptr, contents->mu_dsize);
else
result = tchdbputkeep (hdb, key->mu_dptr, key->mu_dsize,
contents->mu_dptr, contents->mu_dsize);
if (result)
return 0;
db->db_errno.n = tchdbecode (hdb);
if (db->db_errno.n == TCEKEEP)
return MU_ERR_EXISTS;
return MU_ERR_FAILURE;
}
static int
_tc_delete (mu_dbm_file_t db, struct mu_dbm_datum const *key)
{
TCHDB *hdb = db->db_descr;
if (tchdbout (hdb, key->mu_dptr, key->mu_dsize))
return 0;
db->db_errno.n = tchdbecode (hdb);
if (db->db_errno.n == TCENOREC)
return MU_ERR_NOENT;
return MU_ERR_FAILURE;
}
static int
_tc_firstkey (mu_dbm_file_t db, struct mu_dbm_datum *ret)
{
TCHDB *hdb = db->db_descr;
void *ptr;
int retsize;
tchdbiterinit (hdb);
ptr = tchdbiternext (hdb, &retsize);
if (ptr)
{
mu_dbm_datum_free (ret);
ret->mu_dptr = ptr;
ret->mu_dsize = retsize;
return 0;
}
else if ((db->db_errno.n = tchdbecode (hdb)) == TCENOREC)
return MU_ERR_NOENT;
return MU_ERR_FAILURE;
}
static int
_tc_nextkey (mu_dbm_file_t db, struct mu_dbm_datum *ret)
{
TCHDB *hdb = db->db_descr;
void *ptr;
int retsize;
ptr = tchdbiternext (hdb, &retsize);
if (ptr)
{
mu_dbm_datum_free (ret);
ret->mu_dptr = ptr;
ret->mu_dsize = retsize;
return 0;
}
else if ((db->db_errno.n = tchdbecode (hdb)) == TCENOREC)
return MU_ERR_NOENT;
return MU_ERR_FAILURE;
}
static void
_tc_datum_free (struct mu_dbm_datum *datum)
{
free (datum->mu_dptr);
}
static char const *
_tc_strerror (mu_dbm_file_t db)
{
return tchdberrmsg (db->db_errno.n);
}
struct mu_dbm_impl _mu_dbm_tokyokabinet = {
"tc",
_tc_file_safety,
_tc_get_fd,
_tc_open,
_tc_close,
_tc_fetch,
_tc_store,
_tc_delete,
_tc_firstkey,
_tc_nextkey,
_tc_datum_free,
_tc_strerror
};
#endif