diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2012-10-07 21:17:16 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2012-10-07 21:20:00 +0300 |
commit | 3f1639c2112f8242a542ca0a1b959f657d012cc9 (patch) | |
tree | 6951514621c1ac6cde192dbed7cdf736fb6bc39a /lib/gdbmmap.c | |
parent | 1fbcbdb432e945aa3f63be5b9170e94a0c9ef6c3 (diff) | |
download | eclat-3f1639c2112f8242a542ca0a1b959f657d012cc9.tar.gz eclat-3f1639c2112f8242a542ca0a1b959f657d012cc9.tar.bz2 |
Implement GDBM map backend.
* README: Document --with-gdbm
* configure.ac: Detect libgdbm. New option --with-gdbm.
* lib/gdbmmap.c
* lib/Makefile.am (maps) [COND_GDBM]: Add new file.
* lib/libeclat.h (eclat_map_drv_gdbm): New extern.
* src/Makefile.am (LDADD): Add MAPLIBS.
* src/eclat.c (mail) [WITH_GDBM]: Register eclat_map_drv_gdbm.
Diffstat (limited to 'lib/gdbmmap.c')
-rw-r--r-- | lib/gdbmmap.c | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/lib/gdbmmap.c b/lib/gdbmmap.c new file mode 100644 index 0000000..4fdaa33 --- /dev/null +++ b/lib/gdbmmap.c @@ -0,0 +1,116 @@ +/* This file is part of Eclat. + Copyright (C) 2012 Sergey Poznyakoff. + + Eclat is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + Eclat 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Eclat. If not, see <http://www.gnu.org/licenses/>. */ + +#include "libeclat.h" +#include <gdbm.h> +#include <fcntl.h> +#include <errno.h> +#include <string.h> + +struct gdbm_map { + char *name; + GDBM_FILE file; + struct grecs_locus locus; + int nullflag; +}; + +static int +gdbm_map_config(int dbg, struct grecs_node *node, void *data) +{ + struct gdbm_map *gdbm_map, **return_gdbm_map = data; + const char *filename; + struct grecs_node *p; + + if (eclat_get_string_node(node, "file", 0, &p)) + return eclat_map_failure; + gdbm_map = grecs_malloc(sizeof(*gdbm_map)); + gdbm_map->name = grecs_strdup(p->v.value->v.string); + gdbm_map->locus = p->locus; + switch (eclat_get_string_node(node, "null", 1, &p)) { + case eclat_map_failure: + return eclat_map_failure; + case eclat_map_not_found: + break; + case eclat_map_ok: + if (grecs_string_convert(&gdbm_map->nullflag, grecs_type_bool, + p->v.value->v.string, + &p->locus)) + return eclat_map_failure; + } + + *return_gdbm_map = gdbm_map; + return eclat_map_ok; +} + +static void +gdbm_map_free(int dbg, void *data) +{ + struct gdbm_map *gdbm_map = data; + free(gdbm_map->name); + free(gdbm_map); +} + +static int +gdbm_map_open(int dbg, void *data) +{ + struct gdbm_map *gdbm_map = data; + + gdbm_map->file = gdbm_open(gdbm_map->name, 512, GDBM_READER, O_RDONLY, + NULL); + if (gdbm_map->file == NULL) + return eclat_map_failure; + return eclat_map_ok; +} + +static int +gdbm_map_close(int dbg, void *data) +{ + struct gdbm_map *gdbm_map = data; + gdbm_close(gdbm_map->file); + return eclat_map_ok; +} + +static int +gdbm_map_get(int dbg, void *data, const char *key, char **return_value) +{ + struct gdbm_map *gdbm_map = data; + datum keydat, content; + + keydat.dptr = (char*)key; + keydat.dsize = strlen(key) + (gdbm_map->nullflag ? 1 : 0); + gdbm_errno = 0; + content = gdbm_fetch(gdbm_map->file, keydat); + if (content.dptr == NULL) { + if (gdbm_errno == GDBM_ITEM_NOT_FOUND) + return eclat_map_not_found; + err("%s: %s", gdbm_map->name, gdbm_strerror(gdbm_errno)); + return eclat_map_failure; + } + *return_value = grecs_malloc(content.dsize + 1); + memcpy(*return_value, content.dptr, content.dsize); + (*return_value)[content.dsize] = 0; + free (content.dptr); + return eclat_map_ok; +} + +struct eclat_map_drv eclat_map_drv_gdbm = { + "gdbm", + gdbm_map_config, + gdbm_map_open, + gdbm_map_close, + gdbm_map_get, + gdbm_map_free +}; |