dovecot-2.2: dict: Added support for cdb backend.
dovecot at dovecot.org
dovecot at dovecot.org
Mon Jan 21 18:31:20 EET 2013
details: http://hg.dovecot.org/dovecot-2.2/rev/2c249941f9c2
changeset: 15665:2c249941f9c2
user: Timo Sirainen <tss at iki.fi>
date: Mon Jan 21 18:31:08 2013 +0200
description:
dict: Added support for cdb backend.
Based on patch by Hleb Valoshka.
diffstat:
configure.ac | 23 +++++++
src/dict/main.c | 3 +
src/lib-dict/Makefile.am | 1 +
src/lib-dict/dict-cdb.c | 138 ++++++++++++++++++++++++++++++++++++++++++++
src/lib-dict/dict-private.h | 1 +
5 files changed, 166 insertions(+), 0 deletions(-)
diffs (223 lines):
diff -r 9aba8584e5eb -r 2c249941f9c2 configure.ac
--- a/configure.ac Mon Jan 21 18:12:41 2013 +0200
+++ b/configure.ac Mon Jan 21 18:31:08 2013 +0200
@@ -126,6 +126,11 @@
# want_db=no)
want_db=no
+AC_ARG_WITH(cdb,
+AS_HELP_STRING([--with-cdb], [Build with CDB support]),
+ TEST_WITH(cdb, $withval),
+ want_cdb=no)
+
dnl The --with-sql is useful only if Dovecot is being built with all the SQL
dnl drivers as modules. If any SQL driver is built-in, this option is ignored.
AC_ARG_WITH(sql,
@@ -2113,6 +2118,23 @@
fi
fi
+if test $want_cdb != no; then
+ AC_CHECK_LIB(cdb, cdb_init, [
+ AC_CHECK_HEADER(cdb.h, [
+ DICT_LIBS="$DICT_LIBS -lcdb"
+ AC_DEFINE(BUILD_CDB,, Build with CDB support)
+ ], [
+ if test $want_cdb = yes; then
+ AC_ERROR([Can't build with CDB support: cdb.h not found])
+ fi
+ ])
+ ], [
+ if test $want_cdb = yes; then
+ AC_ERROR([Can't build with CDB support: libcdb not found])
+ fi
+ ])
+fi
+
if test $want_pgsql != no; then
AC_CHECK_PROG(PG_CONFIG, pg_config, pg_config, NO)
if test $PG_CONFIG = NO; then
@@ -2397,6 +2419,7 @@
AC_SUBST(SQLITE_LIBS)
AC_SUBST(DICT_LIBS)
+AC_SUBST(CDB_LIBS)
AC_SUBST(dict_drivers)
dnl **
diff -r 9aba8584e5eb -r 2c249941f9c2 src/dict/main.c
--- a/src/dict/main.c Mon Jan 21 18:12:41 2013 +0200
+++ b/src/dict/main.c Mon Jan 21 18:31:08 2013 +0200
@@ -35,6 +35,9 @@
/* Load built-in SQL drivers (if any) */
sql_drivers_init();
sql_drivers_register_all();
+#ifdef HAVE_CDB
+ dict_driver_register(&dict_driver_cdb);
+#endif
restrict_access_by_env(NULL, FALSE);
restrict_access_allow_coredumps(TRUE);
diff -r 9aba8584e5eb -r 2c249941f9c2 src/lib-dict/Makefile.am
--- a/src/lib-dict/Makefile.am Mon Jan 21 18:12:41 2013 +0200
+++ b/src/lib-dict/Makefile.am Mon Jan 21 18:31:08 2013 +0200
@@ -14,6 +14,7 @@
dict.c \
dict-client.c \
dict-file.c \
+ dict-cdb.c \
dict-memcached.c \
dict-memcached-ascii.c \
dict-redis.c \
diff -r 9aba8584e5eb -r 2c249941f9c2 src/lib-dict/dict-cdb.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib-dict/dict-cdb.c Mon Jan 21 18:31:08 2013 +0200
@@ -0,0 +1,138 @@
+/* Copyright (c) 2013 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+
+#ifdef BUILD_CDB
+#include "dict-private.h"
+
+#include <string.h>
+#include <cdb.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#define CDB_WITH_NULL 1
+#define CDB_WITHOUT_NULL 2
+
+struct cdb_dict {
+ struct dict dict;
+ struct cdb cdb;
+ char *path;
+ int fd, flag;
+};
+
+static void cdb_dict_deinit(struct dict *_dict);
+
+static int
+cdb_dict_init(struct dict *driver, const char *uri,
+ enum dict_data_type value_type ATTR_UNUSED,
+ const char *username ATTR_UNUSED,
+ const char *base_dir ATTR_UNUSED,
+ struct dict **dict_r, const char **error_r)
+{
+ struct cdb_dict *dict;
+
+ dict = i_new(struct cdb_dict, 1);
+ dict->dict = *driver;
+ dict->path = i_strdup(uri);
+ dict->flag = CDB_WITH_NULL | CDB_WITHOUT_NULL;
+
+ /* initialize cdb to 0 (unallocated) */
+ memset(&dict->cdb, 0, sizeof(struct cdb));
+
+ dict->fd = open(dict->path, O_RDONLY);
+ if (dict->fd == -1) {
+ *error_r = t_strdup_printf("open(%s) failed: %m", dict->path);
+ cdb_dict_deinit(&dict->dict);
+ return -1;
+ }
+
+#ifdef TINYCDB_VERSION
+ if (cdb_init(&dict->cdb, dict->fd) < 0) {
+ *error_r = t_strdup_printf("cdb_init(%s) failed: %m", dict->path);
+ cdb_dict_deinit(&dict->dict);
+ return -1;
+ }
+#else
+ cdb_init(&dict->cdb, dict->fd);
+#endif
+
+ *dict_r = &dict->dict;
+ return 0;
+}
+
+static void cdb_dict_deinit(struct dict *_dict)
+{
+ struct cdb_dict *dict = (struct cdb_dict *)_dict;
+
+ /* we can safely deinit unallocated cdb */
+ cdb_free(&dict->cdb);
+
+ if (dict->fd != -1) {
+ if (close(dict->fd) < 0)
+ i_error("close(%s) failed: %m", dict->path);
+ }
+
+ i_free(dict->path);
+ i_free(dict);
+}
+
+static int cdb_dict_lookup(struct dict *_dict, pool_t pool,
+ const char *key, const char **value_r)
+{
+ struct cdb_dict *dict = (struct cdb_dict *)_dict;
+ unsigned datalen;
+ int ret = 0;
+ char *data;
+
+ /* keys and values may be null terminated... */
+ if ((dict->flag & CDB_WITH_NULL) != 0) {
+ ret = cdb_find(&dict->cdb, key, (unsigned)strlen(key)+1);
+ if (ret > 0)
+ dict->flag &= ~CDB_WITHOUT_NULL;
+ }
+
+ /* ...or not */
+ if (ret == 0 && (dict->flag & CDB_WITHOUT_NULL) != 0) {
+ ret = cdb_find(&dict->cdb, key, (unsigned)strlen(key));
+ if (ret > 0)
+ dict->flag &= ~CDB_WITH_NULL;
+ }
+
+ if (ret <= 0) {
+ *value_r = NULL;
+ /* something bad with db */
+ if (ret < 0) {
+ i_error("cdb_lookup(%s) failed: %m", dict->path);
+ return -1;
+ }
+ /* found nothing */
+ return 0;
+ }
+
+ datalen = cdb_datalen(&dict->cdb);
+ data = p_new(pool, char, datalen + 1);
+ cdb_read(&dict->cdb, data, datalen, cdb_datapos(&dict->cdb));
+ *value_r = data;
+ return 1;
+}
+
+struct dict dict_driver_cdb = {
+ .name = "cdb",
+ {
+ cdb_dict_init,
+ cdb_dict_deinit,
+ NULL,
+ cdb_dict_lookup,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ }
+};
+#endif
diff -r 9aba8584e5eb -r 2c249941f9c2 src/lib-dict/dict-private.h
--- a/src/lib-dict/dict-private.h Mon Jan 21 18:12:41 2013 +0200
+++ b/src/lib-dict/dict-private.h Mon Jan 21 18:31:08 2013 +0200
@@ -59,5 +59,6 @@
extern struct dict dict_driver_memcached;
extern struct dict dict_driver_memcached_ascii;
extern struct dict dict_driver_redis;
+extern struct dict dict_driver_cdb;
#endif
More information about the dovecot-cvs
mailing list