diff options
| author | Sam Varshavchik | 2013-08-19 16:39:41 -0400 |
|---|---|---|
| committer | Sam Varshavchik | 2013-08-25 14:43:51 -0400 |
| commit | 9c45d9ad13fdf439d44d7443ae75da15ea0223ed (patch) | |
| tree | 7a81a04cb51efb078ee350859a64be2ebc6b8813 /gdbmobj | |
| parent | a9520698b770168d1f33d6301463bb70a19655ec (diff) | |
| download | courier-libs-9c45d9ad13fdf439d44d7443ae75da15ea0223ed.tar.bz2 | |
Initial checkin
Imported from subversion report, converted to git. Updated all paths in
scripts and makefiles, reflecting the new directory hierarchy.
Diffstat (limited to 'gdbmobj')
| -rw-r--r-- | gdbmobj/.gitignore | 1 | ||||
| -rw-r--r-- | gdbmobj/Makefile.am | 33 | ||||
| -rw-r--r-- | gdbmobj/configure.in | 74 | ||||
| -rw-r--r-- | gdbmobj/gdbmobj.c | 177 | ||||
| -rw-r--r-- | gdbmobj/gdbmobj.h | 170 | ||||
| -rw-r--r-- | gdbmobj/gdbmobj2.c | 56 | ||||
| -rw-r--r-- | gdbmobj/gdbmobj3.c | 19 | ||||
| -rw-r--r-- | gdbmobj/testgdbm.C | 165 | ||||
| -rwxr-xr-x | gdbmobj/testsuite | 14 | ||||
| -rw-r--r-- | gdbmobj/testsuite.txt | 11 |
10 files changed, 720 insertions, 0 deletions
diff --git a/gdbmobj/.gitignore b/gdbmobj/.gitignore new file mode 100644 index 0000000..5bc272f --- /dev/null +++ b/gdbmobj/.gitignore @@ -0,0 +1 @@ +/testgdbm diff --git a/gdbmobj/Makefile.am b/gdbmobj/Makefile.am new file mode 100644 index 0000000..bc25384 --- /dev/null +++ b/gdbmobj/Makefile.am @@ -0,0 +1,33 @@ +# +# Copyright 1998 - 2008 Double Precision, Inc. See COPYING for +# distribution information. + + +LIBGDBMSOURCES=gdbmobj.h gdbmobj.c gdbmobj2.c gdbmobj3.c +TESTGDBMSOURCES=testgdbm.C + +if FOUND_GDBM +noinst_LTLIBRARIES=libgdbmobj.la +noinst_PROGRAMS=testgdbm + +libgdbmobj_la_SOURCES=$(LIBGDBMSOURCES) +libgdbmobj_la_LIBADD=@LIBGDBM@ + +testgdbm_SOURCES=$(TESTGDBMSOURCES) + +testgdbm_DEPENDENCIES=libgdbmobj.la +testgdbm_LDADD=libgdbmobj.la +testgdbm_LDFLAGS=-static + +check-am: + $(srcdir)/testsuite | cmp -s - $(srcdir)/testsuite.txt + +else +noinst_SCRIPTS=notfound + +notfound: + @exit 0 + +endif + +EXTRA_DIST=$(LIBGDBMSOURCES) $(TESTGDBMSOURCES) testsuite testsuite.txt diff --git a/gdbmobj/configure.in b/gdbmobj/configure.in new file mode 100644 index 0000000..fde1e9a --- /dev/null +++ b/gdbmobj/configure.in @@ -0,0 +1,74 @@ +dnl Process this file with autoconf to produce a configure script. +dnl +dnl Copyright 1998 - 1999 Double Precision, Inc. See COPYING for +dnl distribution information. + +AC_INIT(gdbmobj, 0.10, [courier-users@lists.sourceforge.net]) + +>confdefs.h # Kill PACKAGE_ macros + +AC_CONFIG_SRCDIR(gdbmobj.c) +AC_CONFIG_AUX_DIR(../..) +AM_INIT_AUTOMAKE([foreign no-define]) +AM_CONFIG_HEADER(config.h) + +dnl Checks for programs. +AC_USE_SYSTEM_EXTENSIONS +AC_PROG_CC +AC_ISC_POSIX +AC_PROG_AWK +AC_PROG_CXX +AC_PROG_LIBTOOL + +dnl Checks for libraries. + +saveLIBS="$LIBS" +AC_CHECK_LIB(gdbm, gdbm_open, [ LIBGDBM=-lgdbm ; LIBS="-lgdbm $LIBS" ]) + +AC_CHECK_FUNC(gdbm_open, FOUND_GDBM=1, FOUND_GDBM=0) + +if test "$FOUND_GDBM" = 1 +then + AC_CHECK_FUNCS(gdbm_fdesc) +fi +AC_CHECK_HEADERS(unistd.h fcntl.h) + +LIBS="$saveLIBS" + +AC_SUBST(LIBGDBM) + +AM_CONDITIONAL(FOUND_GDBM, test "$FOUND_GDBM" = 1) + +dnl Checks for header files. + +dnl Checks for typedefs, structures, and compiler characteristics. +AC_C_CONST +AC_TYPE_SIZE_T +AC_SYS_LARGEFILE + +dnl Checks for library functions. + +AC_LANG_CPLUSPLUS +AC_CACHE_CHECK([if the C++ compiler needs -fhandle-exceptions], + ac_cv_need_handlexceptions, + +AC_TRY_COMPILE([], +[ +throw; +], ac_cv_need_handlexceptions=no, +ac_cv_need_handlexceptions=yes) +) + +if test "$ac_cv_need_handlexceptions" = "yes" +then + case "$CXXFLAGS" in + *handle-exceptions*) + ;; + *) + CXXFLAGS="-fhandle-exceptions $CXXFLAGS" + CXXFLAGS=`echo "$CXXFLAGS" | sed 's/-O2//'` + ;; + esac +fi + +AC_OUTPUT(Makefile) diff --git a/gdbmobj/gdbmobj.c b/gdbmobj/gdbmobj.c new file mode 100644 index 0000000..61f6f93 --- /dev/null +++ b/gdbmobj/gdbmobj.c @@ -0,0 +1,177 @@ +/* +** Copyright 1998 - 2000 Double Precision, Inc. See COPYING for +** distribution information. +*/ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include "gdbmobj.h" +#include <stdlib.h> +#if HAVE_FCNTL_H +#include <fcntl.h> +#endif +#if HAVE_UNISTD_H +#include <unistd.h> +#endif + + +void gdbmobj_init(struct gdbmobj *obj) +{ + obj->has_dbf=0; + obj->prev_key=0; + obj->prev_key_len=0; +} + +void gdbmobj_close(struct gdbmobj *obj) +{ + if (obj->has_dbf) + { + obj->has_dbf=0; + gdbm_close(obj->dbf); + } + if (obj->prev_key) + { + free(obj->prev_key); + obj->prev_key=0; + } +} + +int gdbmobj_open(struct gdbmobj *obj, const char *filename, const char *modestr) +{ +int mode=GDBM_READER; + + for ( ; *modestr; modestr++) + switch (*modestr) { + case 'c': + case 'C': + mode=GDBM_WRCREAT; + break; + case 'w': + case 'W': + mode=GDBM_WRITER; + break; + case 'n': + case 'N': + mode=GDBM_NEWDB; + break; + } + + gdbmobj_close(obj); + if ((obj->dbf=gdbm_open((char *)filename, 0, mode, 0664, 0)) != 0) + { + /* Where possible, set the close-on-exec bit */ + +#if HAVE_GDBM_FDESC +#ifdef FD_CLOEXEC + + int fd=gdbm_fdesc(obj->dbf); + + if (fd >= 0) fcntl(fd, F_SETFD, FD_CLOEXEC); +#endif +#endif + + obj->has_dbf=1; + return (0); + } + return (-1); +} + +int gdbmobj_store(struct gdbmobj *obj, const char *key, size_t keylen, + const char *data, + size_t datalen, + const char *mode) +{ +datum dkey; +datum dval; + + dkey.dptr=(char *)key; + dkey.dsize=keylen; + + dval.dptr=(char *)data; + dval.dsize=datalen; + + return (obj->has_dbf ? gdbm_store(obj->dbf, dkey, dval, ( + *mode == 'i' || *mode == 'I' ? + GDBM_INSERT:GDBM_REPLACE)):-1); +} + +int gdbmobj_exists(struct gdbmobj *obj, const char *key, size_t keylen) +{ +datum dkey; + + if (!obj->has_dbf) return (0); + + dkey.dptr=(char *)key; + dkey.dsize=keylen; + + if (gdbm_exists(obj->dbf, dkey)) return (1); + return (0); +} + +char *gdbm_dofetch(struct gdbmobj *, const char *, size_t, size_t *); + +char *gdbmobj_fetch(struct gdbmobj *obj, const char *key, size_t keylen, + size_t *datalen, const char *options) +{ +char *p; + + for (;;) + { + if ((p=gdbm_dofetch(obj, key, keylen, datalen)) != 0) + return (p); + if (!options) break; + if (*options == 'I') + { + while (keylen && key[--keylen] != '.') + ; + if (!keylen) break; + continue; + } + if (*options == 'D') + { + size_t i; + + for (i=0; i<keylen; i++) + if (key[i] == '@') { ++i; break; } + if (i < keylen) + { + if ((p=gdbm_dofetch(obj, key, i, datalen)) != 0) + return (p); + key += i; + keylen -= i; + continue; + } + + for (i=0; i<keylen; i++) + if (key[i] == '.') { ++i; break; } + if (i < keylen) + { + key += i; + keylen -= i; + continue; + } + break; + } + break; + } + return (0); +} + +char *gdbm_dofetch(struct gdbmobj *obj, + const char *key, size_t keylen, size_t *datalen) +{ +datum dkey, val; + + if (!obj->has_dbf) return (0); + + dkey.dptr=(char *)key; + dkey.dsize=keylen; + + val=gdbm_fetch(obj->dbf, dkey); + + if (!val.dptr) return (0); + *datalen=val.dsize; + return (val.dptr); +} diff --git a/gdbmobj/gdbmobj.h b/gdbmobj/gdbmobj.h new file mode 100644 index 0000000..d9489fb --- /dev/null +++ b/gdbmobj/gdbmobj.h @@ -0,0 +1,170 @@ +#ifndef gdbmobj_h +#define gdbmobj_h + +/* +** Copyright 1998 - 2007 Double Precision, Inc. See COPYING for +** distribution information. +*/ + + +#include "config.h" +#include <gdbm.h> + +#include <stdlib.h> + +#ifdef __cplusplus +extern "C" { +#endif + +struct gdbmobj { + GDBM_FILE dbf; + int has_dbf; + char *prev_key; + size_t prev_key_len; + } ; + +void gdbmobj_init(struct gdbmobj *); + +int gdbmobj_open(struct gdbmobj *, const char *, const char *); +void gdbmobj_close(struct gdbmobj *); + +#define gdbmobj_isopen(p) (!!(p)->has_dbf) + +char *gdbmobj_fetch(struct gdbmobj *, const char *, size_t, size_t *, const char *); +int gdbmobj_exists(struct gdbmobj *, const char *, size_t); +int gdbmobj_delete(struct gdbmobj *, const char *, size_t); +int gdbmobj_store(struct gdbmobj *, const char *, size_t, const char *, + size_t, const char *); + +char *gdbmobj_firstkey(struct gdbmobj *, size_t *, char **, size_t *); +char *gdbmobj_nextkey(struct gdbmobj *, size_t *, char **, size_t *); + +#ifdef __cplusplus +} + +#include <string> + +class GdbmObj { + + struct gdbmobj obj; + + GdbmObj(const GdbmObj &); /* Undefined */ + GdbmObj &operator=(const GdbmObj &); /* Undefined */ + +public: + GdbmObj() { gdbmobj_init(&obj); } + ~GdbmObj() { gdbmobj_close(&obj); } + int Open(std::string filename, const char *mode) + { + return ( gdbmobj_open(&obj, filename.c_str(), mode)); + } + + int IsOpen() { return (gdbmobj_isopen(&obj)); } + void Close() { gdbmobj_close(&obj); } + + std::string Fetch(std::string key, std::string mode) + { + size_t l; + char *p=Fetch(key.c_str(), key.size(), l, mode.c_str()); + + if (!p) return ""; + + std::string v(p, p+l); + + free(p); + return v; + } + + bool Exists(std::string key) + { + return !!Exists(key.c_str(), key.size()); + } + + bool Delete(std::string key) + { + return !!Delete(key.c_str(), key.size()); + } + + int Store(std::string key, std::string val, std::string mode) + { + return Store(key.c_str(), key.size(), + val.c_str(), val.size(), mode.c_str()); + } + + std::string FetchFirstKeyVal(std::string &valRet) + { + char *key; + size_t keyLen; + char *val; + size_t valLen; + + key=FetchFirstKeyVal(keyLen, val, valLen); + + if (!key) + return ""; + + std::string r(key, key+keyLen); + + valRet=std::string(val, val+valLen); + free(val); + return r; + } + + std::string FetchNextKeyVal(std::string &valRet) + { + char *key; + size_t keyLen; + char *val; + size_t valLen; + + key=FetchNextKeyVal(keyLen, val, valLen); + + if (!key) + return ""; + + std::string r(key, key+keyLen); + + valRet=std::string(val, val+valLen); + free(val); + return r; + } + + + char *Fetch(const char *key, size_t keylen, + size_t &valuelen, const char *mode) + { + return (gdbmobj_fetch(&obj, key, keylen, + &valuelen, mode)); + } + + int Exists(const char *key, size_t keylen) + { + return (gdbmobj_exists(&obj, key, keylen)); + } + + int Delete(const char *key, size_t keylen) + { + return (gdbmobj_delete(&obj, key, keylen)); + } + + int Store(const char *key, size_t keylen, + const char *value, size_t valuelen, + const char *mode) + { + return (gdbmobj_store(&obj, key, keylen, value, + valuelen, mode)); + } + + char *FetchFirstKeyVal(size_t &keylen, char *&val, size_t &vallen) + { + return (gdbmobj_firstkey(&obj, &keylen, &val, &vallen)); + } + char *FetchNextKeyVal(size_t &keylen, char *&val, size_t &vallen) + { + return (gdbmobj_nextkey(&obj, &keylen, &val, &vallen)); + } +} ; + +#endif + +#endif diff --git a/gdbmobj/gdbmobj2.c b/gdbmobj/gdbmobj2.c new file mode 100644 index 0000000..e107800 --- /dev/null +++ b/gdbmobj/gdbmobj2.c @@ -0,0 +1,56 @@ +/* +** Copyright 1998 - 1999 Double Precision, Inc. See COPYING for +** distribution information. +*/ + +#include "gdbmobj.h" + +static char *fetchkeyval(struct gdbmobj *obj, size_t *, char **, size_t *); +extern char *gdbm_dofetch(struct gdbmobj *, const char *, size_t, size_t *); + +char *gdbmobj_firstkey(struct gdbmobj *obj, size_t *keylen, char **val, + size_t *vallen) +{ +datum key; + + if (!obj->has_dbf) return (0); + + if (obj->prev_key) free(obj->prev_key); + obj->prev_key=0; + + key=gdbm_firstkey(obj->dbf); + + if (!key.dptr) return (0); + + obj->prev_key=key.dptr; + obj->prev_key_len=key.dsize; + return (fetchkeyval(obj, keylen, val, vallen)); +} + + +static char *fetchkeyval(struct gdbmobj *obj, size_t *keylen, char **val, + size_t *vallen) +{ + if (!obj->prev_key) return (0); + *val=gdbm_dofetch(obj, obj->prev_key, obj->prev_key_len, vallen); + *keylen=obj->prev_key_len; + return (obj->prev_key); +} + +char *gdbmobj_nextkey(struct gdbmobj *obj, size_t *keylen, + char **val, size_t *vallen) +{ +datum dkey, key; + + if (!obj->has_dbf || !obj->prev_key) return (0); + + dkey.dptr=(char *)obj->prev_key; + dkey.dsize=obj->prev_key_len; + + key=gdbm_nextkey(obj->dbf, dkey); + + free(obj->prev_key); + obj->prev_key=key.dptr; + obj->prev_key_len=key.dsize; + return (fetchkeyval(obj, keylen, val, vallen)); +} diff --git a/gdbmobj/gdbmobj3.c b/gdbmobj/gdbmobj3.c new file mode 100644 index 0000000..1b3b432 --- /dev/null +++ b/gdbmobj/gdbmobj3.c @@ -0,0 +1,19 @@ +/* +** Copyright 1998 - 1999 Double Precision, Inc. See COPYING for +** distribution information. +*/ + +#include "gdbmobj.h" + +int gdbmobj_delete(struct gdbmobj *obj, const char *key, size_t keylen) +{ +datum dkey; + + if (!obj->has_dbf) return (0); + + dkey.dptr=(char *)key; + dkey.dsize=keylen; + + if (gdbm_delete(obj->dbf, dkey)) return (-1); + return (0); +} diff --git a/gdbmobj/testgdbm.C b/gdbmobj/testgdbm.C new file mode 100644 index 0000000..6723609 --- /dev/null +++ b/gdbmobj/testgdbm.C @@ -0,0 +1,165 @@ +#include "gdbmobj.h" +#include <stdio.h> +#include <string.h> + +/* either egcs or libc breaks fwrite on some platforms -- this is confirmed */ + +static void fw(char *p, size_t a, size_t b, FILE *f) +{ +size_t i, j=a*b; + + for (i=0; i<j; i++) + putc(p[i], f); +} + +struct kd { + struct kd *next; + char *key, *data; + } ; + +static int kdcmp (const void *a, const void *b) +{ + return (strcmp( (*(const struct kd **)a)->key, + (*(const struct kd **)b)->key)); +} + +int main(int argc, char **argv) +{ + if (argc < 2) exit(1); + + if (argc < 3) + { + GdbmObj dbw; + char *key, *data; + size_t keylen, datalen; + struct kd *kdlist, **kdarray; + size_t kdcnt; + + if (dbw.Open(argv[1], "R")) + { + perror("open"); + exit(1); + } + + printf("Dumping %s:\n", argv[1]); + kdlist=0; + kdcnt=0; + for (key=dbw.FetchFirstKeyVal(keylen, data, datalen); + key; key=dbw.FetchNextKeyVal(keylen, data, datalen)) + { + struct kd *k=(struct kd *)malloc(sizeof(struct kd)); + + if (!k) + { + perror("malloc"); + exit(1); + } + if ((k->key=(char *)malloc(keylen+1)) == 0 || + (k->data=(char *)malloc(datalen+1)) == 0) + { + perror("malloc"); + exit(1); + } + memcpy(k->key, key, keylen); + k->key[keylen]=0; + memcpy(k->data, data, datalen); + k->data[datalen]=0; + free(data); + ++kdcnt; + k->next=kdlist; + kdlist=k; + } + + if ((kdarray=(struct kd **) + malloc( (kdcnt+1)*sizeof(struct kd *))) == 0) + { + perror("malloc"); + exit(1); + } + kdcnt=0; + while ( kdlist ) + { + kdarray[kdcnt++]=kdlist; + kdlist=kdlist->next; + } + kdarray[kdcnt]=0; + + qsort( kdarray, kdcnt, sizeof(kdarray[0]), &kdcmp); + + for (kdcnt=0; kdarray[kdcnt]; kdcnt++) + { + printf("Key: "); + fw(kdarray[kdcnt]->key, strlen(kdarray[kdcnt]->key), + 1, stdout); + printf(", Data: "); + fw(kdarray[kdcnt]->data, strlen(kdarray[kdcnt]->data), + 1, stdout); + printf("\n"); + free(kdarray[kdcnt]->key); + free(kdarray[kdcnt]->data); + free(kdarray[kdcnt]); + } + free(kdarray); + dbw.Close(); + } else if (argc < 4 && argv[2][0] == '-') + { + GdbmObj dbw; + + if (dbw.Open(argv[1], "W")) + { + perror("open"); + exit(1); + } + + printf("Deleting %s from %s:\n", argv[2], argv[1]); + if (dbw.Delete(argv[2]+1, strlen(argv[2]+1))) + fprintf(stderr, "Not found.\n"); + + dbw.Close(); + } else if (argc < 4) + { + GdbmObj dbw; + + if (dbw.Open(argv[1], "R")) + { + perror("open"); + exit(1); + } + + size_t len; + char *val=dbw.Fetch(argv[2], strlen(argv[2]), len, 0); + + if (!val) + { + fprintf(stderr, "%s: not found.\n", argv[2]); + exit(1); + } + printf("Fetching %s from %s: ", argv[2], argv[1]); + fw(val, len, 1, stdout); + printf("\n"); + free(val); + dbw.Close(); + } + else + { + GdbmObj dbw; + + if (dbw.Open(argv[1], "C")) + { + perror("open"); + exit(1); + } + + printf("Storing %s/%s into %s:\n", argv[2], argv[3], argv[1]); + if (dbw.Store(argv[2], strlen(argv[2]), + argv[3], strlen(argv[3]), "R")) + { + perror("write"); + exit(1); + } + + dbw.Close(); + } + exit(0); + return (0); +} diff --git a/gdbmobj/testsuite b/gdbmobj/testsuite new file mode 100755 index 0000000..b8d8c5a --- /dev/null +++ b/gdbmobj/testsuite @@ -0,0 +1,14 @@ +#!/bin/sh + +rm -f testgdbm.dat + +./testgdbm testgdbm.dat foo bar +./testgdbm testgdbm.dat foo baz +./testgdbm testgdbm.dat bar foo +./testgdbm testgdbm.dat foo +./testgdbm testgdbm.dat bar +./testgdbm testgdbm.dat +./testgdbm testgdbm.dat -foo +./testgdbm testgdbm.dat + +rm -f testgdbm.dat diff --git a/gdbmobj/testsuite.txt b/gdbmobj/testsuite.txt new file mode 100644 index 0000000..920e80a --- /dev/null +++ b/gdbmobj/testsuite.txt @@ -0,0 +1,11 @@ +Storing foo/bar into testgdbm.dat: +Storing foo/baz into testgdbm.dat: +Storing bar/foo into testgdbm.dat: +Fetching foo from testgdbm.dat: baz +Fetching bar from testgdbm.dat: foo +Dumping testgdbm.dat: +Key: bar, Data: foo +Key: foo, Data: baz +Deleting -foo from testgdbm.dat: +Dumping testgdbm.dat: +Key: bar, Data: foo |
