summaryrefslogtreecommitdiffstats
path: root/gdbmobj
diff options
context:
space:
mode:
authorSam Varshavchik2013-08-19 16:39:41 -0400
committerSam Varshavchik2013-08-25 14:43:51 -0400
commit9c45d9ad13fdf439d44d7443ae75da15ea0223ed (patch)
tree7a81a04cb51efb078ee350859a64be2ebc6b8813 /gdbmobj
parenta9520698b770168d1f33d6301463bb70a19655ec (diff)
downloadcourier-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/.gitignore1
-rw-r--r--gdbmobj/Makefile.am33
-rw-r--r--gdbmobj/configure.in74
-rw-r--r--gdbmobj/gdbmobj.c177
-rw-r--r--gdbmobj/gdbmobj.h170
-rw-r--r--gdbmobj/gdbmobj2.c56
-rw-r--r--gdbmobj/gdbmobj3.c19
-rw-r--r--gdbmobj/testgdbm.C165
-rwxr-xr-xgdbmobj/testsuite14
-rw-r--r--gdbmobj/testsuite.txt11
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