BSD stuff --> libndir and libdbm

Randy Suess randy at chinet.UUCP
Tue Jun 14 22:58:37 AEST 1988


I have been swamped with requests, so figure a posting is in order.
This posting and the following contain the mdbm source as posted 
a while ago and the mods made by Dave Ihnat (ignatz at chinet) to
make it look like a 99.9% clone of V7 dbm.  Made spacewar and news 2.11
work fine on a 3b2/310 running SysVr3.1.
Good luck.


#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 1 (of 2)."
# Contents:  . ./addons ./addons/READ.ME ./addons/bcmp.c
#   ./addons/bcmp.s ./addons/bcopy.c ./addons/bcopy.s ./addons/bzero.c
#   ./addons/bzero.s ./mdbm ./mdbm/.archinfo ./mdbm/Makefile
#   ./mdbm/access.c ./mdbm/bcmp.c ./mdbm/bcopy.c ./mdbm/bzero.c
#   ./mdbm/checkblock.c ./mdbm/close.c ./mdbm/compare.c ./mdbm/dbm.h
#   ./mdbm/dbmcompat.c ./mdbm/delete.c ./mdbm/delitem.c
#   ./mdbm/dumpdbm.c ./mdbm/fetch.c ./mdbm/firsthash.c
#   ./mdbm/firstkey.c ./mdbm/hash.c ./mdbm/hashinc.c ./mdbm/mdbm.h
#   ./mdbm/mdbm_local.h ./mdbm/nextkey.c ./mdbm/open.c ./mdbm/search.c
#   ./mdbm/sync.c ./mdbm/testdbm.c
# Wrapped by randy at chinet on Wed Jun  8 13:52:15 1988
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test ! -d ./addons ; then
    echo shar: Creating directory \"./addons\"
    mkdir ./addons
fi
if test -f ./addons/READ.ME -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"./addons/READ.ME\"
else
echo shar: Extracting \"./addons/READ.ME\" \(1514 characters\)
sed "s/^X//" >./addons/READ.ME <<'END_OF_./addons/READ.ME'
XFrom ihnp4!zehntel!hplabs!hao!seismo!umcp-cs!eneevax!chris Sat Aug 18 03:31:41 1984
XRelay-Version: version B 2.10.1 exptools 1/30/84; site ihnp3.UUCP
XPosting-Version: version B 2.10.1 6/24/83; site eneevax.UUCP
XPath: ihnp3!ihnp4!zehntel!hplabs!hao!seismo!umcp-cs!eneevax!chris
XFrom: chris at eneevax.UUCP (Chris Torek)
XNewsgroups: net.sources
XSubject: bcopy, bcmp, bzero for 4.1BSD
XMessage-ID: <153 at eneevax.UUCP>
XDate: Sat, 18-Aug-84 03:31:41 CDT
XArticle-I.D.: eneevax.153
XPosted: Sat Aug 18 03:31:41 1984
XDate-Received: Sun, 19-Aug-84 11:19:10 EDT
XOrganization: Univ. of Maryland, EE Dept.
XLines: 156
X
XI've received (justified) complaints for not explaining bcmp(),
Xbcopy(), and bzero() in my mdbm source posting.  This is one of those
X4.2 dependencies I warned about.  Anyway, here are implementations of
Xbcopy, bcmp, and bzero in Vax assembly and in C.  WARNING: I haven't
Xtested the Vax assembly version of bcmp (nor any of the C routines but
Xwho needs to test those?).  Also, the assembly routines won't work
Xunder VMS, which (I believe) needs r2-r11 saved; you'd have to change
Xthe entry masks.
X
XIf you're running 4.2 you should already have these in your C library,
Xso in that case, ignore this posting.  (Otherwise, why not rewrite
Xthese for your particular machine and *install* it in your C library?)
X
X--Chris Torek, U of MD CS/EE, seismo!umcp-cs!chris, chris at maryland.ARPA,
X  chris at umcp-cs.CSNet  (I don't have my regular .signature installed on
X  this machine)
X-------------------------------------------
END_OF_./addons/READ.ME
if test 1514 -ne `wc -c <./addons/READ.ME`; then
    echo shar: \"./addons/READ.ME\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f ./addons/bcmp.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"./addons/bcmp.c\"
else
echo shar: Extracting \"./addons/bcmp.c\" \(383 characters\)
sed "s/^X//" >./addons/bcmp.c <<'END_OF_./addons/bcmp.c'
X/*
X * bcmp
X *
X * compare count bytes at s1 and s2; return 0 iff equal
X *
X * N.B.: Beware large counts (>32767) on machines with 16 bit `int's.
X * (This routine should really be rewritten for those.)
X */
Xbcmp (s1, s2, count)
Xregister char *s1, *s2;
Xregister int count;
X{
X    while (--count >= 0)
X	if (*s1++ != *s2++)
X	    return 1;		/* or ``return *--s1 - *--s2;'' */
X    return 0;
X}
END_OF_./addons/bcmp.c
if test 383 -ne `wc -c <./addons/bcmp.c`; then
    echo shar: \"./addons/bcmp.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f ./addons/bcmp.s -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"./addons/bcmp.s\"
else
echo shar: Extracting \"./addons/bcmp.s\" \(518 characters\)
sed "s/^X//" >./addons/bcmp.s <<'END_OF_./addons/bcmp.s'
X# bcmp (s1, s2, count) char *s1, *s2; int count;
X#
X# Compare "count" bytes at "s1" with those at "s2"; return 0 iff equal
X
X	.align	2
X	.globl	_bcopy
X_bcopy:
X	.word	0
X	movl	4(ap),r1		# r1 = s1
X	movl	8(ap),r3		# r3 = s2
X	brb	2f
X1:
X	subl2	r0,12(ap)		# count-=65535 (bytes compared)
X	cmpc3	r0,(r1),(r3)		# r1, r3 magically point to next 65K
X	bneq	3f
X2:
X	movzwl	$65535,r0
X	cmpl	12(ap),r0		# <= 65535 bytes to compare?
X	jgtr	1b			# brif not, do 65535 and try again
X	cmpc3	12(ap),(r1),(r3)	# compare up to 65535 bytes
X3:
X	ret
END_OF_./addons/bcmp.s
if test 518 -ne `wc -c <./addons/bcmp.s`; then
    echo shar: \"./addons/bcmp.s\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f ./addons/bcopy.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"./addons/bcopy.c\"
else
echo shar: Extracting \"./addons/bcopy.c\" \(356 characters\)
sed "s/^X//" >./addons/bcopy.c <<'END_OF_./addons/bcopy.c'
X/*
X * bcopy - copy count bytes from "from" to "to" - not guaranteed to work
X * if "from" and "to" overlap
X *
X * N.B.: Beware large counts (>32767) on machines with 16 bit `int's.
X * (This routine should really be rewritten for those.)
X */
Xbcopy (from, to, count)
Xregister char *from, *to;
Xregister int count;
X{
X    while (--count >= 0)
X	*to++ = *from++;
X}
END_OF_./addons/bcopy.c
if test 356 -ne `wc -c <./addons/bcopy.c`; then
    echo shar: \"./addons/bcopy.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f ./addons/bcopy.s -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"./addons/bcopy.s\"
else
echo shar: Extracting \"./addons/bcopy.s\" \(540 characters\)
sed "s/^X//" >./addons/bcopy.s <<'END_OF_./addons/bcopy.s'
X# bcopy (from, to, count) char *from, *to; int count;
X#
X# Copy "count" bytes from "from" to "to"; not guaranteed to
X# work if "from" and "to" overlap.
X
X	.align	2
X	.globl	_bcopy
X_bcopy:
X	.word	0
X	movl	4(ap),r1		# r1 = from
X	movl	8(ap),r3		# r3 = to
X	brb	2f
X1:
X	subl2	r0,12(ap)		# count-=65535 (bytes moved this time)
X	movc3	r0,(r1),(r3)		# r1, r3 magically point to next 65K
X2:
X	movzwl	$65535,r0
X	cmpl	12(ap),r0		# <= 65535 bytes to move?
X	jgtr	1b			# brif not, move 65535 and try again
X	movc3	12(ap),(r1),(r3)	# move up to 65535 bytes
X	ret
END_OF_./addons/bcopy.s
if test 540 -ne `wc -c <./addons/bcopy.s`; then
    echo shar: \"./addons/bcopy.s\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f ./addons/bzero.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"./addons/bzero.c\"
else
echo shar: Extracting \"./addons/bzero.c\" \(284 characters\)
sed "s/^X//" >./addons/bzero.c <<'END_OF_./addons/bzero.c'
X/*
X * bzero - zero count bytes at address addr
X *
X * N.B.: Beware large counts (>32767) on machines with 16 bit `int's.
X * (This routine should really be rewritten for those.)
X */
Xbzero (addr, count)
Xregister char *addr;
Xregister int count;
X{
X    while (--count >= 0)
X	*addr++ = 0;
X}
END_OF_./addons/bzero.c
if test 284 -ne `wc -c <./addons/bzero.c`; then
    echo shar: \"./addons/bzero.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f ./addons/bzero.s -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"./addons/bzero.s\"
else
echo shar: Extracting \"./addons/bzero.s\" \(455 characters\)
sed "s/^X//" >./addons/bzero.s <<'END_OF_./addons/bzero.s'
X# bzero (addr, count) char *addr; int count;
X#
X# Zero "count" bytes at address "addr"
X
X	.align	2
X	.globl	_bzero
X_bzero:
X	.word	0
X	movl	4(ap),r3		# r3 = addr
X	brb	2f
X1:
X	subl2	r0,8(ap)		# count-=65535 (bytes zeroed this time)
X	movc5	$0,(sp),$0,r0,(r3)	# r3 magically points to next 65K
X2:
X	movzwl	$65535,r0
X	cmpl	8(ap),r0		# <= 65535 bytes to zero?
X	jgtr	1b			# brif not, zero 65535 and try again
X	movc5	$0,(sp),$0,8(ap),(r3)	# zero up to 65535 bytes
X	ret
END_OF_./addons/bzero.s
if test 455 -ne `wc -c <./addons/bzero.s`; then
    echo shar: \"./addons/bzero.s\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test ! -d ./mdbm ; then
    echo shar: Creating directory \"./mdbm\"
    mkdir ./mdbm
fi
if test ! -d ./mdbm/.archinfo ; then
    echo shar: Creating directory \"./mdbm/.archinfo\"
    mkdir ./mdbm/.archinfo
fi
if test -f ./mdbm/Makefile -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"./mdbm/Makefile\"
else
echo shar: Extracting \"./mdbm/Makefile\" \(1830 characters\)
sed "s/^X//" >./mdbm/Makefile <<'END_OF_./mdbm/Makefile'
X# $Header$
X#
X# The -R flag compiles initialized data into the text area.  Not really
X# necessary, but nice.
X# (DMI-AiC): Unfortunately, also not on BTL-derived compilers.
X# (DMI-AiC): Added dbm compatibility module
XCC = ccsh # 3b1 Only!
X#CC = cc
X
X#CFLAGS=	-O -R
XCFLAGS=	-O
X
XOBJS=	access.o checkblock.o close.o compare.o delete.o delitem.o\
X	fetch.o firsthash.o firstkey.o hash.o hashinc.o nextkey.o\
X	open.o search.o store.o sync.o dbmcompat.o
X
XSRCS=	access.c checkblock.c close.c compare.c delete.c delitem.c\
X	fetch.c firsthash.c firstkey.c hash.c hashinc.c nextkey.c\
X	open.c search.c store.c sync.c dbmcompat.c
X
XHDRS=	mdbm.h mdbm_local.h
X
X.c.o:
X	$(CC) -c $(CFLAGS) $<
X	@ld -r -x $@
X	@mv a.out $@
X
Xall: libmdbm.a testdbm dumpdbm
X
Xlibmdbm.a: $(OBJS)
X	ar cr libmdbm.a `lorder $(OBJS) | tsort`
X#	ranlib libmdbm.a
X
Xinstall:
X	install -m 444 -o bin -g bin -c libmdbm.a $(DESTDIR)/usr/lib
X	ln $(DESTDIR)/usr/lib/libmdbm.a $(DESTDIR)/usr/lib/libdbm.a
X#	ranlib $(DESTDIR)/usr/lib/libmdbm.a
X	install -m 444 -o bin -g bin -c mdbm.h $(DESTDIR)/include
X	install -c mdbm.3x $(DESTDIR)/usr/man/man3
X
Xtestdbm: testdbm.o libmdbm.a
X	cc $(CFLAGS) -o testdbm testdbm.o libmdbm.a
X
Xdumpdbm: dumpdbm.o libmdbm.a
X	cc $(CFLAGS) -o dumpdbm dumpdbm.o libmdbm.a
X
Xclean:
X	rm -f libmdbm.a *.o a.out testdbm dumpdbm core
X
Xlint:	$(SRCS) $(HDRS)
X	lint -h $(SRCS) | egrep -v 'possible pointer alignment problem'
X
Xaccess.o: mdbm.h mdbm_local.h
Xadditem.o: mdbm.h mdbm_local.h
Xcheckblock.o: mdbm.h mdbm_local.h
Xclose.o: mdbm.h mdbm_local.h
Xdelete.o: mdbm.h mdbm_local.h
Xdelitem.o: mdbm.h mdbm_local.h
Xfetch.o: mdbm.h mdbm_local.h
Xfirsthash.o: mdbm.h mdbm_local.h
Xfirstkey.o: mdbm.h mdbm_local.h
Xhash.o: mdbm.h mdbm_local.h
Xnextkey.o: mdbm.h mdbm_local.h
Xopen.o: mdbm.h mdbm_local.h
Xsearch.o: mdbm_local.h
Xstore.o: mdbm.h mdbm_local.h
Xsync.o: mdbm.h mdbm_local.h
X
X
END_OF_./mdbm/Makefile
if test 1830 -ne `wc -c <./mdbm/Makefile`; then
    echo shar: \"./mdbm/Makefile\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f ./mdbm/access.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"./mdbm/access.c\"
else
echo shar: Extracting \"./mdbm/access.c\" \(1210 characters\)
sed "s/^X//" >./mdbm/access.c <<'END_OF_./mdbm/access.c'
X#ifndef lint
Xstatic char rcsid[] = "$Header: /ful/chris/dist/mdbm/access.c,v 1.1 84/08/12 09:54:48 chris Rel $";
X#endif
X
X#include <stdio.h>
X#include "mdbm.h"
X#include "mdbm_local.h"
X
X/*
X * Read in the appropriate data block for an item whose hash index is
X * hash.  The hash index specifies the data block in an indirect way:
X * if the bit in the map is set then more bits of the hash value should
X * be considered.  If it is not set then we have the right hash bits
X * and the block number is just the low bits of the hash value.
X *
X * Return the hash mask that gets the right block number.
X */
Xint mdbm_access (d, hash)
Xregister struct mdbm *d;
Xregister long hash;
X{
X    register long   hmask,
X                    b;
X
X    for (hmask = 0;; hmask = (hmask << 1) + 1) {
X	b = (hash & hmask) + hmask;/* map bit number */
X	if (b < d -> mdbm_maxbit) {
X	    register int    i,
X	                    n;
X
X	    n = b % BYTESIZ;	/* bit index */
X	    b /= BYTESIZ;	/* byte index */
X	    i = b % d -> mdbm_msize;/* byte offset in map */
X	    b /= d -> mdbm_msize;/* map block number */
X	    MDBM_MREAD (d, b);
X	    if (d -> mdbm_m[i] & (1 << n))
X		continue;
X	}
X	b = hash & hmask;
X	MDBM_DREAD (d, b);
X	return hmask;
X    }
X}
END_OF_./mdbm/access.c
if test 1210 -ne `wc -c <./mdbm/access.c`; then
    echo shar: \"./mdbm/access.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f ./mdbm/bcmp.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"./mdbm/bcmp.c\"
else
echo shar: Extracting \"./mdbm/bcmp.c\" \(383 characters\)
sed "s/^X//" >./mdbm/bcmp.c <<'END_OF_./mdbm/bcmp.c'
X/*
X * bcmp
X *
X * compare count bytes at s1 and s2; return 0 iff equal
X *
X * N.B.: Beware large counts (>32767) on machines with 16 bit `int's.
X * (This routine should really be rewritten for those.)
X */
Xbcmp (s1, s2, count)
Xregister char *s1, *s2;
Xregister int count;
X{
X    while (--count >= 0)
X	if (*s1++ != *s2++)
X	    return 1;		/* or ``return *--s1 - *--s2;'' */
X    return 0;
X}
END_OF_./mdbm/bcmp.c
if test 383 -ne `wc -c <./mdbm/bcmp.c`; then
    echo shar: \"./mdbm/bcmp.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f ./mdbm/bcopy.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"./mdbm/bcopy.c\"
else
echo shar: Extracting \"./mdbm/bcopy.c\" \(356 characters\)
sed "s/^X//" >./mdbm/bcopy.c <<'END_OF_./mdbm/bcopy.c'
X/*
X * bcopy - copy count bytes from "from" to "to" - not guaranteed to work
X * if "from" and "to" overlap
X *
X * N.B.: Beware large counts (>32767) on machines with 16 bit `int's.
X * (This routine should really be rewritten for those.)
X */
Xbcopy (from, to, count)
Xregister char *from, *to;
Xregister int count;
X{
X    while (--count >= 0)
X	*to++ = *from++;
X}
END_OF_./mdbm/bcopy.c
if test 356 -ne `wc -c <./mdbm/bcopy.c`; then
    echo shar: \"./mdbm/bcopy.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f ./mdbm/bzero.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"./mdbm/bzero.c\"
else
echo shar: Extracting \"./mdbm/bzero.c\" \(284 characters\)
sed "s/^X//" >./mdbm/bzero.c <<'END_OF_./mdbm/bzero.c'
X/*
X * bzero - zero count bytes at address addr
X *
X * N.B.: Beware large counts (>32767) on machines with 16 bit `int's.
X * (This routine should really be rewritten for those.)
X */
Xbzero (addr, count)
Xregister char *addr;
Xregister int count;
X{
X    while (--count >= 0)
X	*addr++ = 0;
X}
END_OF_./mdbm/bzero.c
if test 284 -ne `wc -c <./mdbm/bzero.c`; then
    echo shar: \"./mdbm/bzero.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f ./mdbm/checkblock.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"./mdbm/checkblock.c\"
else
echo shar: Extracting \"./mdbm/checkblock.c\" \(724 characters\)
sed "s/^X//" >./mdbm/checkblock.c <<'END_OF_./mdbm/checkblock.c'
X#ifndef lint
Xstatic char rcsid[] = "$Header: /ful/chris/dist/mdbm/checkblock.c,v 1.1 84/08/12 09:56:16 chris Rel $";
X#endif
X
X#include <stdio.h>
X#include "mdbm.h"
X#include "mdbm_local.h"
X
X/*
X * Perform some sanity checks on a data block
X */
Xmdbm_checkblock (buf, size)
Xchar *buf;
Xint   size;
X{
X    register struct mdbm_dblock *db = (struct mdbm_dblock *) buf;
X    register struct mdbm_dentry *de;
X    register int    i,
X		    t = size;
X
X    de = &db -> db_e[1];
X    for (i = 1; i < db -> db_n; i++) {
X	if (de -> de_off > t)
X	    goto bad;
X	t = de -> de_off;
X	de++;
X    }
X    if (&buf[t] < (char *) de)
X	goto bad;
X    return;
X
Xbad: 
X    printf ("mdbm: bad block\n");
X    fflush(stdout);
X    abort ();
X    bzero (buf, size);
X}
END_OF_./mdbm/checkblock.c
if test 724 -ne `wc -c <./mdbm/checkblock.c`; then
    echo shar: \"./mdbm/checkblock.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f ./mdbm/close.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"./mdbm/close.c\"
else
echo shar: Extracting \"./mdbm/close.c\" \(454 characters\)
sed "s/^X//" >./mdbm/close.c <<'END_OF_./mdbm/close.c'
X#ifndef lint
Xstatic char rcsid[] = "$Header: /ful/chris/dist/mdbm/close.c,v 1.1 84/08/12 09:57:45 chris Rel $";
X#endif
X
X#include <stdio.h>
X#include "mdbm.h"
X#include "mdbm_local.h"
X
X/*
X * Close a database
X */
Xmdbm_close (d)
Xregister struct mdbm *d;
X{
X    MDBM_SYNC (d);
X    (void) close (d -> mdbm_datafd);
X    (void) close (d -> mdbm_mapfd);
X    free (d -> mdbm_d);
X    free (d -> mdbm_s);
X    free (d -> mdbm_m);
X    free ((char *) d);
X    return 0;
X}
END_OF_./mdbm/close.c
if test 454 -ne `wc -c <./mdbm/close.c`; then
    echo shar: \"./mdbm/close.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f ./mdbm/compare.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"./mdbm/compare.c\"
else
echo shar: Extracting \"./mdbm/compare.c\" \(492 characters\)
sed "s/^X//" >./mdbm/compare.c <<'END_OF_./mdbm/compare.c'
X#ifndef lint
Xstatic char rcsid[] = "$Header: /ful/chris/dist/mdbm/compare.c,v 1.1 84/08/12 09:57:59 chris Rel $";
X#endif
X
X/*
X * Compare strings s1 and s2 for len bytes; return the difference
X * between the first differing characters.  Could probably use strncmp
X * but I don't trust it to work the same way when encountering \0s.
X */
Xmdbm_compare (s1, s2, len)
Xregister char *s1, *s2;
Xregister int len;
X{
X    while (--len >= 0)
X	if (*s1++ != *s2++)
X	    return *--s1 - *--s2;
X    return 0;
X}
END_OF_./mdbm/compare.c
if test 492 -ne `wc -c <./mdbm/compare.c`; then
    echo shar: \"./mdbm/compare.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f ./mdbm/dbm.h -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"./mdbm/dbm.h\"
else
echo shar: Extracting \"./mdbm/dbm.h\" \(319 characters\)
sed "s/^X//" >./mdbm/dbm.h <<'END_OF_./mdbm/dbm.h'
X/*
X * Multiple key database library compatibility include file
X * David M. Ihnat, 1988
X */
X
X#include <mdbm.h>
X
Xextern datum   fetch ();
Xextern datum   firstkey ();
Xextern datum   nextkey ();
Xextern long    forder ();
Xextern int     delete ();
Xextern int     store ();
Xextern struct mdbm *open ();
Xextern int	close ();
X
END_OF_./mdbm/dbm.h
if test 319 -ne `wc -c <./mdbm/dbm.h`; then
    echo shar: \"./mdbm/dbm.h\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f ./mdbm/dbmcompat.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"./mdbm/dbmcompat.c\"
else
echo shar: Extracting \"./mdbm/dbmcompat.c\" \(4647 characters\)
sed "s/^X//" >./mdbm/dbmcompat.c <<'END_OF_./mdbm/dbmcompat.c'
X/*
X * Compat - provides mdbm <--> dbm compatibility
X *
X * Author: David M. Ihnat, 2/9/87
X * 
X * This is a work in the Public Domain.
X */
X#include <stdio.h>
X#include <errno.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X#include <fcntl.h>
X#include "mdbm.h"
X
Xstatic struct mdbm *compat_dat = (struct mdbm *)NULL;
X/**/
Xdbminit(file)
Xchar *file;
X{
X	/*
X	 * This is interesting; 'dbm' uses two files, '<file>.dir' and
X	 * '<file>.pag'; 'mdbm' uses '<file>.map' and '<file>.dat'.  There
X	 * also exists the possibility that calling programs may need to know
X	 * about the original files' existence and/or size, while all the mdbm
X	 * routines insist on the new file names.  Solution?  The following:
X	 *
X	 * 1) If called, and the old files don't exist, error--in
X	 *    the old 'dbm' scheme, they had to create the old files.
X	 *
X	 * 2) If called and the 'old' name files exist, AND they're of zero
X	 *    then LINK them to the new name files, since they're just creating
X	 *    the database.  This will satisfy both the old and new routines.
X	 *
X	 * 3) If called, and the 'old' name files exist and are NOT of zero
X	 *    length, then they MUST be already linked to the corresponding
X	 *    new-name file, else they could be trying to feed us an old-format
X	 *    'dbm' database.
X	 */
X
X	/* Only one database may be open at any one time under 'dbm' */
X	if(compat_dat != (struct mdbm *)NULL)
X		(void)mdbm_close(compat_dat);
X
X	/*
X	 * Ok, do the files exist (and, of course, if so, are they accessible?)
X	 */
X	if(dbm_fcheck(file,".dir",".map"))
X		return(-1);
X
X	if(dbm_fcheck(file,".pag",".dat"))
X		return(-1);
X
X	/* OK, all files either newly set up or already exist!  Continue... */
X	compat_dat =
X		mdbm_open(file,O_RDWR,0,(int *)NULL,(int *)NULL,(char *)NULL);
X
X	if(compat_dat == (struct mdbm *)NULL)
X		return(-1);
X
X	(void)mdbm_setflags(compat_dat,MDBM_ISAUTOW);
X
X	return(0);
X}
X/**/
Xdatum
Xfetch(key)
Xdatum key;
X{
X	return(mdbm_fetch(compat_dat,key));
X}
X/**/
Xstore(key,content)
Xdatum key,content;
X{
X	return(mdbm_store(compat_dat,key,content,MDBM_REPLACE));
X}
X/**/
Xdelete(key)
Xdatum key;
X{
X	return(mdbm_delete(compat_dat,key));
X}
X/**/
Xdatum
Xfirstkey()
X{
X	return(mdbm_firstkey(compat_dat));
X}
X/**/
Xdatum
Xnextkey(key)
Xdatum key;
X{
X	return(mdbm_nextkey(compat_dat,key));
X}
X/**/
Xstatic int
Xdbm_fcheck(file,old,new)
Xchar *file, *old, *new;
X{
X	register char *old_file, *new_file;
X	register int retval1, retval2;
X	struct stat old_statbuf, new_statbuf;
X
X	char *malloc();
X
X	/*
X	 * This routine performs all the validity checks.  Note that, on error
X	 * returns, the 'malloc'd space isn't released.  This isn't too evil an
X	 * action, since failure here should mean further processing can't normally
X	 * continue.
X	 */
X
X	/* Allocate enough space for '<file>.[map|dat]' and '<file>.[dir|pag]'*/
X	old_file = malloc((unsigned)(strlen(file) + 5));
X	new_file = malloc((unsigned)(strlen(file) + 5));
X
X	if(old_file == (char *)NULL || new_file == (char *)NULL)
X	{
X		fprintf(stderr,"dbmcompat: Couldn't allocate memory (1)\n");
X		return(-1);
X	}
X
X	/* Setup for test of the old/new file set */
X	strcpy(old_file,file);
X	strcat(old_file,old);
X
X	strcpy(new_file,file);
X	strcat(new_file,new);
X
X	retval1= stat(old_file,&old_statbuf);
X	if(retval1)
X		retval1 = errno;
X
X	retval2= stat(new_file,&new_statbuf);
X	if(retval2)
X		retval2 = errno;
X
X	if(retval1)
X	{
X		/* Something's fatally wrong */
X		if(retval1 == ENOENT)	/* Ok...not there... */
X		{
X			fprintf(stderr,"dbmcompat: No file %s\n",old_file);
X		}else
X		{ /* Couldn't get to it for some reason! */
X			fprintf(stderr,
X				"dbmcompat: Can't get to file %s: %d\n",
X				old_file,retval1);
X		}
X		return(-1);
X	}
X
X	/*
X	 * Got here; file exists & we can get to it.  Does the corresponding
X	 * 'new' file?
X	 */
X	if(retval2)
X	{
X		if(retval2 == ENOENT) /* Ok, not there... */
X		{
X			if(old_statbuf.st_size != (off_t)0)
X			{
X				fprintf(stderr,"dbmcompat: No %s and %s is non-zero size.",
X					new_file,old_file);
X				fprintf(stderr,"Possibly old 'dbm' database?\n");
X				return(-1);
X			}else
X			{
X				/* Interesting--could be initializing new database. */
X				if(link(old_file,new_file))
X				{
X					/* Ouch! */
X					perror("dbmcompat");
X					return(-1);
X				}
X			}
X		}else
X		{
X			fprintf(stderr,"dbmcompat: %s inacessible: %d\n",
X				new_file,retval2);
X			return(-1);
X		}
X	}else
X	{
X		/* It exists; had better be linked to the old file! */
X		if((old_statbuf.st_dev != new_statbuf.st_dev) ||
X		   (old_statbuf.st_ino != new_statbuf.st_ino))
X		{
X			fprintf(stderr,"dbmcompat: %s and %s are not linked!\n",
X				old_file,new_file);
X			return(-1);
X		}
X	}
X
X	/* Wow--it's all OK! */
X	(void)free(old_file);
X	(void)free(new_file);
X
X	return(0);
X}
END_OF_./mdbm/dbmcompat.c
if test 4647 -ne `wc -c <./mdbm/dbmcompat.c`; then
    echo shar: \"./mdbm/dbmcompat.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f ./mdbm/delete.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"./mdbm/delete.c\"
else
echo shar: Extracting \"./mdbm/delete.c\" \(1007 characters\)
sed "s/^X//" >./mdbm/delete.c <<'END_OF_./mdbm/delete.c'
X#ifndef lint
Xstatic char rcsid[] = "$Header: /ful/chris/dist/mdbm/delete.c,v 1.1 84/08/12 09:58:22 chris Rel $";
X#endif
X
X#include <stdio.h>
X#include <errno.h>
X#include "mdbm.h"
X#include "mdbm_local.h"
X
X/*
X * Delete datum under key in dbm d
X */
Xmdbm_delete (d, key)
Xregister struct mdbm *d;
Xdatum key;
X{
X#define db ((struct mdbm_dblock *) d -> mdbm_d)
X    register struct mdbm_dentry *de;
X    long    keyblock;
X    int     keyindex;
X    extern int errno;
X
X    de = mdbm_search (d, key.dptr, key.dsize, &keyblock, &keyindex, 0);
X    if (de == 0) {
X	errno = ENOENT;
X	return (-1);
X    }
X    if (d -> mdbm_flags & MDBM_ISRONLY) {
X	errno = EPERM;
X	return (-1);
X    }
X
X /* delete the datum */
X    mdbm_delitem (d, de - db -> db_e);
X
X /* delete the key */
X    de = mdbm_search (d, key.dptr, key.dsize, &keyblock, &keyindex, 1);
X    MDBM_DREAD (d, keyblock);
X    de = &db -> db_e[keyindex];
X    de -> de_outx = 0;		/* not in use as a key anymore */
X    mdbm_delitem (d, keyindex);
X    MDBM_AUTO (d);
X    return 0;
X}
END_OF_./mdbm/delete.c
if test 1007 -ne `wc -c <./mdbm/delete.c`; then
    echo shar: \"./mdbm/delete.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f ./mdbm/delitem.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"./mdbm/delitem.c\"
else
echo shar: Extracting \"./mdbm/delitem.c\" \(1356 characters\)
sed "s/^X//" >./mdbm/delitem.c <<'END_OF_./mdbm/delitem.c'
X#ifndef lint
Xstatic char rcsid[] = "$Header: /ful/chris/dist/mdbm/delitem.c,v 1.1 84/08/12 09:58:37 chris Rel $";
X#endif lint
X
X#include <stdio.h>
X#include "mdbm.h"
X#include "mdbm_local.h"
X
X/*
X * Delete item 'n' from current data buffer of dbm d
X */
Xmdbm_delitem (d, n)
Xregister struct mdbm *d;
Xregister int n;
X{
X    register int    i;
X#define db ((struct mdbm_dblock *) d -> mdbm_d)
X    register struct mdbm_dentry *de;
X
X    if (n < 0 || n >= db -> db_n)
X	goto bad;
X    de = &db -> db_e[n];
X    if (de -> de_links > 1) {
X	de -> de_links--;
X	goto done;
X    }
X    db -> db_n--;
X    i = (n ? de[-1].de_off : d -> mdbm_dsize) - de -> de_off;
X    if (i) {			/* delete i bytes of text */
X	if (n < db -> db_n) {
X	    register char  *to,
X	                   *from;
X	    register int    bytes;
X
X	    to = d -> mdbm_d + (n ? de[-1].de_off : d -> mdbm_dsize);
X	    from = to - i;
X	    bytes = de -> de_off - db -> db_e[db -> db_n].de_off;
X	    while (--bytes >= 0)
X		*--to = *--from;
X	}
X	bzero (d -> mdbm_d + db -> db_e[db -> db_n].de_off, i);
X    }
X    {
X	register struct mdbm_dentry *e;
X
X	e = &db -> db_e[db -> db_n];
X	while (de < e) {
X	    *de = de[1];
X	    de -> de_off += i;
X	    de++;
X	}
X	bzero ((char *) e, sizeof e);
X    }
Xdone:
X    d -> mdbm_flags |= MDBM_DDIRTY;
X    return;
X
Xbad:
X    printf ("mdbm bug: bad delitem\n");
X    fflush(stdout);
X    abort ();
X}
END_OF_./mdbm/delitem.c
if test 1356 -ne `wc -c <./mdbm/delitem.c`; then
    echo shar: \"./mdbm/delitem.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f ./mdbm/dumpdbm.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"./mdbm/dumpdbm.c\"
else
echo shar: Extracting \"./mdbm/dumpdbm.c\" \(1830 characters\)
sed "s/^X//" >./mdbm/dumpdbm.c <<'END_OF_./mdbm/dumpdbm.c'
X#include "mdbm.h"
X#include "mdbm_local.h"
X#include <stdio.h>
X#include <sys/types.h>
X#ifdef SYSV
X#include <fcntl.h>
X#else
X#include <sys/file.h>
X#endif
X#include <sys/stat.h>
X#include <signal.h>
X
Xabort () { kill (getpid (), SIGILL); }
X
Xmain (argc, argv)
Xint argc;
Xchar **argv;
X{
X    register struct mdbm *mp;
X    register struct mdbm_dblock *db;
X    register struct mdbm_dentry *de;
X    int dsize, msize, blocks;
X    register int i, j, len;
X    struct stat sb;
X
X    if (argc < 2) {
X	fprintf (stderr, "Usage: dumpdbm dbname\n");
X	exit (1);
X    }
X    if (argc > 2)
X	signal (SIGILL, SIG_IGN);
X    dsize = msize = 0;
X    mp = mdbm_open (argv[1], O_RDONLY, 0, &dsize, &msize, (char *) 0);
X    if (!mp) {
X	perror (argv[1]);
X	exit (1);
X    }
X    printf ("dbm %s: dsize = %d, msize = %d\n", argv[1], dsize, msize);
X    (void) fstat (mp -> mdbm_datafd, &sb);
X    blocks = sb.st_size / dsize;
X    printf ("(%d data blocks)\n", blocks);
X    db = (struct mdbm_dblock *) mp -> mdbm_d;
X    for (i = 0; i < blocks; i++) {
X	MDBM_DREAD (mp, i);
X	printf ("block %d: %d entries\n", i, db -> db_n);
X	for (j = 0, de = db -> db_e; j < db -> db_n; j++, de++) {
X	    printf ("\t%2d: @%4d links=%2d inx=%4d outx=%4d outh=%08x ",
X		    j, de -> de_off, de -> de_links, de -> de_inx,
X		    de -> de_outx, de -> de_outh);
X	    len = (j ? de[-1].de_off : dsize) - de -> de_off;
X	    pr_entry (mp -> mdbm_d + de -> de_off, len);
X	}
X    }
X    (void) mdbm_close (mp);
X    exit (0);
X}
X
Xpr_entry (s, len)
Xregister char *s;
Xregister int len;
X{
X    register int c;
X
X    putchar ('"');
X    while (--len >= 0) {
X	c = *s++ & 0377;
X	if (c & 0200)
X	    putchar ('M'), putchar ('-'), c &= 0177;
X	if (c == 0177)
X	    putchar ('^'), putchar ('?');
X	else if (c < ' ')
X	    putchar ('^'), putchar (c + '@');
X	else
X	    putchar (c);
X    }
X    putchar ('"');
X    putchar ('\n');
X}
END_OF_./mdbm/dumpdbm.c
if test 1830 -ne `wc -c <./mdbm/dumpdbm.c`; then
    echo shar: \"./mdbm/dumpdbm.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f ./mdbm/fetch.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"./mdbm/fetch.c\"
else
echo shar: Extracting \"./mdbm/fetch.c\" \(670 characters\)
sed "s/^X//" >./mdbm/fetch.c <<'END_OF_./mdbm/fetch.c'
X#ifndef lint
Xstatic char rcsid[] = "$Header: /ful/chris/dist/mdbm/fetch.c,v 1.1 84/08/12 09:59:20 chris Rel $";
X#endif
X
X#include <stdio.h>
X#include "mdbm.h"
X#include "mdbm_local.h"
X
X/*
X * Find datum in dbm d, given key
X */
Xdatum mdbm_fetch (d, key)
Xregister struct mdbm *d;
Xdatum key;
X{
X#define db ((struct mdbm_dblock *) d -> mdbm_d)
X    register struct mdbm_dentry *de;
X    datum item;
X
X    de = mdbm_search (d, key.dptr, key.dsize, (long *) 0, (int *) 0, 0);
X    if (de) {
X	item.dptr = d -> mdbm_d + de -> de_off;
X	item.dsize = (de > db -> db_e ? de[-1].de_off : d -> mdbm_dsize) -
X	    de -> de_off;
X    }
X    else
X	item.dptr = 0, item.dsize = 0;
X    return item;
X}
END_OF_./mdbm/fetch.c
if test 670 -ne `wc -c <./mdbm/fetch.c`; then
    echo shar: \"./mdbm/fetch.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f ./mdbm/firsthash.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"./mdbm/firsthash.c\"
else
echo shar: Extracting \"./mdbm/firsthash.c\" \(1440 characters\)
sed "s/^X//" >./mdbm/firsthash.c <<'END_OF_./mdbm/firsthash.c'
X#ifndef lint
Xstatic char rcsid[] = "$Header: /ful/chris/dist/mdbm/firsthash.c,v 1.1 84/08/12 09:59:59 chris Rel $";
X#endif
X
X#include <stdio.h>
X#include "mdbm.h"
X#include "mdbm_local.h"
X
X/*
X * Return the first datum in dbm d with hash value hash
X */
Xdatum mdbm_firsthash (d, hash)
Xregister struct mdbm *d;
Xlong hash;
X{
X#define db ((struct mdbm_dblock *) d -> mdbm_d)
X    register struct mdbm_dentry *de;
X    register int    i;
X    char   *bp;
X    int     bl;
X    char   *ip;
X    int     il,
X            found;
X    long    hmask;
X    datum rval;
X
Xloop: 
X /* Suck in the block for the given hash, then find the "first" key. */
X    hmask = mdbm_access (d, hash);
X    found = 0;
X#ifdef lint			/* lint doesn't realize that 'found'
X				   overrides the tests on bl and bp */
X    bl = 0;
X    bp = 0;
X#endif lint
X    for (i = 0, de = db -> db_e; i < db -> db_n; i++, de++) {
X	if (de -> de_outx == 0)	/* not a key */
X	    continue;
X	il = (i ? de[-1].de_off : d -> mdbm_dsize) - de -> de_off;
X	ip = d -> mdbm_d + de -> de_off;
X	if (!found || il < bl || (il == bl && mdbm_compare (ip, bp, il) < 0)) {
X	    bl = il;
X	    bp = ip;
X	    found++;
X	}
X    }
X    if (found) {
X	bcopy (bp, rval.dptr = d -> mdbm_s, rval.dsize = bl);
X	return rval;
X    }
X
X /* No item with this hash, so get next hash and try again */
X    hash = mdbm_hashinc (hash, hmask);
X    if (hash == 0) {		/* no more */
X	rval.dsize = 0;
X	rval.dptr = 0;
X	return rval;
X    }
X    goto loop;
X}
END_OF_./mdbm/firsthash.c
if test 1440 -ne `wc -c <./mdbm/firsthash.c`; then
    echo shar: \"./mdbm/firsthash.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f ./mdbm/firstkey.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"./mdbm/firstkey.c\"
else
echo shar: Extracting \"./mdbm/firstkey.c\" \(306 characters\)
sed "s/^X//" >./mdbm/firstkey.c <<'END_OF_./mdbm/firstkey.c'
X#ifndef lint
Xstatic char rcsid[] = "$Header: /ful/chris/dist/mdbm/firstkey.c,v 1.1 84/08/12 10:00:27 chris Rel $";
X#endif
X
X#include <stdio.h>
X#include "mdbm.h"
X#include "mdbm_local.h"
X
X/*
X * Return the "first" key in dbm d
X */
Xdatum mdbm_firstkey (d)
Xstruct mdbm *d;
X{
X    return mdbm_firsthash (d, 0L);
X}
END_OF_./mdbm/firstkey.c
if test 306 -ne `wc -c <./mdbm/firstkey.c`; then
    echo shar: \"./mdbm/firstkey.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f ./mdbm/hash.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"./mdbm/hash.c\"
else
echo shar: Extracting \"./mdbm/hash.c\" \(1708 characters\)
sed "s/^X//" >./mdbm/hash.c <<'END_OF_./mdbm/hash.c'
X#include <stdio.h>
X#include "mdbm.h"
X#include "mdbm_local.h"
X
Xint hitab[16] = {
X/* ken's
X	055,043,036,054,063,014,004,005,
X	010,064,077,000,035,027,025,071, */
X
X	61, 57, 53, 49, 45, 41, 37, 33,
X	29, 25, 21, 17, 13,  9,  5,  1,
X};
X
Xlong hltab[64] = {
X	06100151277L,06106161736L,06452611562L,05001724107L,
X	02614772546L,04120731531L,04665262210L,07347467531L,
X	06735253126L,06042345173L,03072226605L,01464164730L,
X	03247435524L,07652510057L,01546775256L,05714532133L,
X	06173260402L,07517101630L,02431460343L,01743245566L,
X	00261675137L,02433103631L,03421772437L,04447707466L,
X	04435620103L,03757017115L,03641531772L,06767633246L,
X	02673230344L,00260612216L,04133454451L,00615531516L,
X	06137717526L,02574116560L,02304023373L,07061702261L,
X	05153031405L,05322056705L,07401116734L,06552375715L,
X	06165233473L,05311063631L,01212221723L,01052267235L,
X	06000615237L,01075222665L,06330216006L,04402355630L,
X	01451177262L,02000133436L,06025467062L,07121076461L,
X	03123433522L,01010635225L,01716177066L,05161746527L,
X	01736635071L,06243505026L,03637211610L,01756474365L,
X	04723077174L,03642763134L,05750130273L,03655541561L,
X};
X
X/*
X * Calculate the hash val for the given item.
X */
Xlong mdbm_calchash (s, len)
Xregister char *s;
Xregister int   len;
X{
X    register int    hashi = 0;
X    register long   hashl = 0L;
X
X    while (--len >= 0) {
X	register int    f = *s++;
X
X#if BYTESIZ > 4 && BYTESIZ <= 8	/* an easy optimization */
X	hashi += hitab[f & 15];
X	hashl += hltab[hashi & 63];
X	f >>= 4;
X	hashi += hitab[f & 15];
X	hashl += hltab[hashi & 63];
X#else
X	register int    j;
X
X	for (j = 0; j < BYTESIZ; j += 4) {
X	    hashi += hitab[f & 15];
X	    hashl += hltab[hashi & 63];
X	    f >>= 4;
X	}
X#endif
X    }
X    return hashl;
X}
END_OF_./mdbm/hash.c
if test 1708 -ne `wc -c <./mdbm/hash.c`; then
    echo shar: \"./mdbm/hash.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f ./mdbm/hashinc.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"./mdbm/hashinc.c\"
else
echo shar: Extracting \"./mdbm/hashinc.c\" \(447 characters\)
sed "s/^X//" >./mdbm/hashinc.c <<'END_OF_./mdbm/hashinc.c'
X#ifndef lint
Xstatic char rcsid[] = "$Header: /ful/chris/dist/mdbm/hashinc.c,v 1.1 84/08/12 10:01:19 chris Rel $";
X#endif
X
X/*
X * Return the next hash number for this dbm, or 0 for no more
X */
Xlong mdbm_hashinc (hash, hmask)
Xregister long hash, hmask;
X{
X    register long   bit;
X
X    hash &= hmask;
X    bit = hmask + 1;
X    for (;;) {
X	bit >>= 1;
X	if (bit == 0)
X	    return 0L;
X	if ((hash & bit) == 0)
X	    return hash | bit;
X	hash &= ~bit;
X    }
X}
END_OF_./mdbm/hashinc.c
if test 447 -ne `wc -c <./mdbm/hashinc.c`; then
    echo shar: \"./mdbm/hashinc.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f ./mdbm/mdbm.h -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"./mdbm/mdbm.h\"
else
echo shar: Extracting \"./mdbm/mdbm.h\" \(2312 characters\)
sed "s/^X//" >./mdbm/mdbm.h <<'END_OF_./mdbm/mdbm.h'
X/* $Header: /ful/chris/dist/mdbm/mdbm.h,v 1.1 84/08/12 10:05:08 chris Rel $ */
X
X/*
X * Multiple key database library (-lmdbm)
X */
X
X/* structure describing an open mdbm file */
Xstruct mdbm {
X	int	mdbm_flags;	/* flags (see below) */
X	int	mdbm_datafd;	/* data area file descriptor */
X	int	mdbm_mapfd;	/* bitmap file descriptor */
X	int	mdbm_dsize;	/* data buffer size */
X	int	mdbm_msize;	/* bitmap buffer size */
X	long	mdbm_maxbit;	/* max possible set bit in map + 1 */
X	long	mdbm_dblock;	/* index of current data block */
X	long	mdbm_mblock;	/* index of current map block */
X	char   *mdbm_d;		/* current data block */
X	char   *mdbm_s;		/* secondary data block */
X	char   *mdbm_m;		/* current map block */
X};
X
X/* structure giving (external) description of data and keys */
Xtypedef struct {
X	char   *dptr;
X	int	dsize;
X} datum;
X
X/*
X * mdbm_flags
X */
X#define	MDBM_ISRONLY	0x01	/* true => db is readonly */
X#define	MDBM_ISAUTOW	0x02	/* true => do all writes immediately */
X#define	MDBM_DDIRTY	0x04	/* true => data buffer out of sync */
X#define	MDBM_MDIRTY	0x08	/* true => map buffer out of sync */
X
X#define MDBM_UF		0x02	/* user allowed to modify only these flags */
X
X/*
X * flags to mdbm_store()
X */
X#define MDBM_INSERT	0	/* insert only; abort if key found */
X#define MDBM_REPLACE	1	/* replace (or insert if not found) */
X
Xdatum   mdbm_fetch ();
Xdatum   mdbm_firstkey ();
Xdatum   mdbm_nextkey ();
Xlong    mdbm_forder ();
Xint     mdbm_delete ();
Xint     mdbm_store ();
Xstruct mdbm *mdbm_open ();
Xint	mdbm_close ();
X
X/*
X * open flags the same as those for the open() system call
X * with the exception that we force O_RDWR for O_WRONLY opens.
X */
X
X/*
X * mdbm files contain a descriptive comment whose length is not
X * longer than this, and is (supposed to be) null terminated.
X */
X#define MDBM_CSIZ 248
X
X/*
X * ``routines'' to examine and alter flags
X */
X#define mdbm_getflags(m) \
X	((m) -> mdbm_flags)
X#define mdbm_setflags(m,f) \
X	((m) -> mdbm_flags &= ~MDBM_UF, (m) -> mdbm_flags |= (f) & MDBM_UF)
X#define mdbm_bisflags(m,f) \
X	((m) -> mdbm_flags |= (f) & MDBM_UF)
X#define mdbm_bicflags(m,f) \
X	((m) -> mdbm_flags &= ~((f) & MDBM_UF))
X
X/*
X * BSD-isms
X */
X#define	SYSV
X
X#ifdef SYSV
X#define bcmp(s1, s2, cnt) memcmp(s1,s2,cnt)
X#define bcopy(fr, to, cnt) memcpy(to,fr,cnt)
X#define bzero(addr,cnt) memset(addr,'\0',cnt)
X#endif
END_OF_./mdbm/mdbm.h
if test 2312 -ne `wc -c <./mdbm/mdbm.h`; then
    echo shar: \"./mdbm/mdbm.h\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f ./mdbm/mdbm_local.h -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"./mdbm/mdbm_local.h\"
else
echo shar: Extracting \"./mdbm/mdbm_local.h\" \(4198 characters\)
sed "s/^X//" >./mdbm/mdbm_local.h <<'END_OF_./mdbm/mdbm_local.h'
X/* $Header: /ful/chris/dist/mdbm/mdbm_local.h,v 1.1 84/08/12 10:05:28 chris Rel $ */
X
X/*
X * Definitions local to the various mdbm source files
X */
X
X#define BYTESIZ		8	/* size of a byte */
X#define MAXUSHORT	65535	/* largest legal value for unsigned short */
X
X/* Default database sizes for new databases */
X#define MDBM_DefaultDataSize	1024	/* data buffer block size */
X#define MDBM_DefaultMapSize	4096	/* bitmap buffer block size */
X
X/* Minimum sizes.  Requests for anything smaller will be brought up
X   to these values. */
X#define MDBM_MinDataSize	128	/* minimum data buffer size */
X#define MDBM_MinMapSize		128	/* minimum map buffer size */
X
X/*
X * This structure goes in at the front of the map file.  It describes
X * the per-database info.  Typically the "comment" field contains the
X * name of the database.
X */
Xstruct mdbm_h {
X	int	mh_dsize;	/* size of data file blocks */
X	int	mh_msize;	/* size of map file blocks */
X	char	mh_comment[MDBM_CSIZ];/* whatever you like */
X};
X
X/*
X * Within the map file, we simply have bits set whenever a data block
X * was split.  The data file is more complex.  It contains the following
X * info in each block:
X *	# entries in block
X *	entries
X *	free space
X *	text
X *
X * where the format of an entry is (as given by struct mdbm_dentry)
X *	<off, links, inx, outx, outh>
X *
X * off is the offset within the block of the text (and thus also specifies
X * the size of the text string); links is the number of links to this item;
X * inx is the ``in index'' number of this item; outx is the ``out index''
X * number of this item; and outh is the out hash.
X *
X * If an item is in use as a key, its outx will contain a nonzero
X * number which is repeated in the inx field of its datum.  The hash value
X * in outh will (by the usual extensible hashing rules) determine a block
X * number, and the item with the matching inx field in that block is the
X * datum under the key in question.
X *
X * An item's inx field will always contain a nonzero number that is unique
X * to the block in which the item resides.
X */
Xstruct mdbm_dblock {
X	int db_n;	/* number of entries */
X	struct mdbm_dentry {
X		unsigned short de_off;	/* offset to beginning of text */
X		unsigned short de_links;/* number of links */
X		unsigned short de_inx;	/* in index */
X		unsigned short de_outx;	/* out index */
X		unsigned long  de_outh;	/* out hash */
X	} db_e[1];	/* actually db_e[db_n], but can't say that */
X};
X
X/* Some macros to simplify(?) things a bit */
X
X/* Read block blk (size sz offset off) from file f into buffer buf */
X#define MDBM_RBLK(f,blk,buf,sz,off) \
X	((void) lseek (f, (blk)*(sz)+(off), 0), (void) read (f, buf, sz))
X
X/* Write block blk (size sz offset off) to file f from buffer buf */
X#define	MDBM_WBLK(f,blk,buf,sz,off) \
X	((void) lseek (f, (blk)*(sz)+(off), 0), (void) write (f, buf, sz))
X
X/* Write (if needed) */
X#define MDBM_DSYNC(d) \
X    if ((d) -> mdbm_flags & MDBM_DDIRTY) { \
X	MDBM_WBLK ((d) -> mdbm_datafd, (d) -> mdbm_dblock, (d) -> mdbm_d, \
X		   (d) -> mdbm_dsize, 0); \
X	(d) -> mdbm_flags &= ~MDBM_DDIRTY; \
X    }
X
X#define MDBM_MSYNC(d) \
X    if ((d) -> mdbm_flags & MDBM_MDIRTY) { \
X	MDBM_WBLK ((d) -> mdbm_mapfd, (d) -> mdbm_mblock, (d) -> mdbm_m, \
X		   (d) -> mdbm_msize, sizeof (struct mdbm_h)); \
X	(d) -> mdbm_flags &= ~MDBM_MDIRTY; \
X    }
X
X#define MDBM_SYNC(d) { MDBM_DSYNC(d); MDBM_MSYNC(d); }
X
X/* Do autowrites */
X#define	MDBM_AUTO(d) if ((d) -> mdbm_flags & MDBM_ISAUTOW) MDBM_SYNC (d)
X
X/* Read data block b */
X#define	MDBM_DREAD(d,b) \
X    if ((d) -> mdbm_dblock != (b)) { \
X	MDBM_DSYNC (d); \
X	bzero ((d) -> mdbm_d, (d) -> mdbm_dsize); \
X	MDBM_RBLK ((d) -> mdbm_datafd, (d) -> mdbm_dblock = (b), \
X		   (d) -> mdbm_d, (d) -> mdbm_dsize, 0); \
X	mdbm_checkblock ((d) -> mdbm_d, (d) -> mdbm_dsize); \
X    }
X
X/* Read map block b */
X#define MDBM_MREAD(d,b) \
X    if ((d) -> mdbm_mblock != (b)) { \
X	MDBM_MSYNC (d); \
X	bzero ((d) -> mdbm_m, (d) -> mdbm_msize); \
X	MDBM_RBLK ((d) -> mdbm_mapfd, (d) -> mdbm_mblock = (b), \
X		   (d) -> mdbm_m, (d) -> mdbm_msize, sizeof (struct mdbm_h)); \
X    }
X
X/*
X * function types
X */
Xlong	mdbm_calchash ();
Xlong	mdbm_hashinc ();
Xstruct  mdbm_dentry *mdbm_search ();
Xdatum   mdbm_firsthash ();
Xlong	lseek ();
Xchar   *malloc ();
END_OF_./mdbm/mdbm_local.h
if test 4198 -ne `wc -c <./mdbm/mdbm_local.h`; then
    echo shar: \"./mdbm/mdbm_local.h\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f ./mdbm/nextkey.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"./mdbm/nextkey.c\"
else
echo shar: Extracting \"./mdbm/nextkey.c\" \(1627 characters\)
sed "s/^X//" >./mdbm/nextkey.c <<'END_OF_./mdbm/nextkey.c'
X#ifndef lint
Xstatic char rcsid[] = "$Header: /ful/chris/dist/mdbm/nextkey.c,v 1.1 84/08/12 10:01:55 chris Rel $";
X#endif
X
X#include <stdio.h>
X#include "mdbm.h"
X#include "mdbm_local.h"
X
X/*
X * Return the "next" key in dbm d
X */
Xdatum mdbm_nextkey (d, key)
Xregister struct mdbm *d;
Xdatum key;
X{
X#define db ((struct mdbm_dblock *) d -> mdbm_d)
X    register struct mdbm_dentry *de;
X    register int    i;
X    char   *bp;
X    int     bl;
X    char   *ip;
X    int     il,
X            found;
X    long    hash,
X            hmask;
X    datum rval;
X
X /* Suck in the block for the given hash, then find the key that follows
X    the one given */
X    hash = mdbm_calchash (key.dptr, key.dsize);
X    hmask = mdbm_access (d, hash);
X    found = 0;
X#ifdef lint			/* lint doesn't realize that 'found'
X				   overrides the tests on bl and bp */
X    bl = 0;
X    bp = 0;
X#endif lint
X    for (i = 0, de = db -> db_e; i < db -> db_n; i++, de++) {
X	if (de -> de_outx == 0)	/* not a key */
X	    continue;
X	il = (i ? de[-1].de_off : d -> mdbm_dsize) - de -> de_off;
X	ip = d -> mdbm_d + de -> de_off;
X	if (il < key.dsize ||
X		(il == key.dsize && mdbm_compare (ip, key.dptr, il) <= 0))
X	    continue;
X	if (!found || il < bl || (il == bl && mdbm_compare (ip, bp, il) < 0)) {
X	    bl = il;
X	    bp = ip;
X	    found++;
X	}
X    }
X    if (found) {
X	bcopy (bp, rval.dptr = d -> mdbm_s, rval.dsize = bl);
X	return rval;
X    }
X
X /* No item with this hash, so get next hash and return its first item */
X    hash = mdbm_hashinc (hash, hmask);
X    if (hash == 0) {		/* no more */
X	rval.dsize = 0;
X	rval.dptr = 0;
X	return rval;
X    }
X    return mdbm_firsthash (d, hash);
X}
END_OF_./mdbm/nextkey.c
if test 1627 -ne `wc -c <./mdbm/nextkey.c`; then
    echo shar: \"./mdbm/nextkey.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f ./mdbm/open.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"./mdbm/open.c\"
else
echo shar: Extracting \"./mdbm/open.c\" \(3310 characters\)
sed "s/^X//" >./mdbm/open.c <<'END_OF_./mdbm/open.c'
X#ifndef lint
Xstatic char rcsid[] = "$Header: /ful/chris/dist/mdbm/open.c,v 1.1 84/08/12 10:02:40 chris Rel $";
X#endif
X
X#include "mdbm.h"
X#include "mdbm_local.h"
X#include <stdio.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X#ifdef SYSV
X#include <fcntl.h>
X#else
X#include <sys/file.h>
X#endif
X#include <errno.h>
X
X/*
X * Open or create a database
X */
Xstruct mdbm *mdbm_open (file, flags, mode, adsize, amsize, comment)
Xchar *file;
Xint flags, mode;
Xint *adsize, *amsize;
Xchar *comment;
X{
X    register struct mdbm   *d;
X    struct stat stat;
X    struct mdbm_h   mdbm_h;
X    int     dsize,
X            msize,
X            l;
X    char   *namebuf,
X           *p;
X    char   *strcpy ();
X    char   *strncpy ();
X    extern int  errno;
X
X /* get a descriptor */
X    if ((d = (struct mdbm *) malloc (sizeof *d)) == 0) {
X	errno = ENOMEM;
X	return 0;
X    }
X /* get enough room for the file names */
X    l = strlen (file);
X    if ((namebuf = malloc ((unsigned) (l + 5))) == 0) {
X	l = ENOMEM;
X	goto out;
X    }
X
X /* find out how big the buffers should be, if this is a new db */
X    dsize = adsize == 0 || *adsize == 0 ? MDBM_DefaultDataSize : *adsize;
X    msize = amsize == 0 || *amsize == 0 ? MDBM_DefaultMapSize : *amsize;
X    if (dsize < MDBM_MinDataSize)
X	dsize = MDBM_MinDataSize;
X    if (msize < MDBM_MinMapSize)
X	msize = MDBM_MinMapSize;
X
X /* fix up the mode, then open them files */
X    if ((flags & 3) == O_WRONLY)
X	flags = (flags & ~3) | O_RDWR;
X    (void) strcpy (namebuf, file);
X    p = &namebuf[l];
X    (void) strcpy (p, ".dat");
X    if ((d -> mdbm_datafd = open (namebuf, flags, mode)) < 0) {
X	l = errno;
X	goto out;
X    }
X    (void) strcpy (p, ".map");
X    if ((d -> mdbm_mapfd = open (namebuf, flags, mode)) < 0) {
X	l = errno;
X	goto out1;
X    }
X    free (namebuf);
X
X /* initialize the dbm descriptor */
X    d -> mdbm_flags = (flags & 3) == O_RDONLY ? MDBM_ISRONLY : 0;
X
X    (void) fstat (d -> mdbm_mapfd, &stat);
X    if (stat.st_size == 0) {
X	mdbm_h.mh_dsize = dsize;
X	mdbm_h.mh_msize = msize;
X	bzero (mdbm_h.mh_comment, MDBM_CSIZ);
X	(void) strncpy (mdbm_h.mh_comment,
X		comment && *comment ? comment : file, MDBM_CSIZ);
X	mdbm_h.mh_comment[MDBM_CSIZ - 1] = 0;
X	if ((d -> mdbm_flags & MDBM_ISRONLY) == 0)
X	    if (write (d -> mdbm_mapfd, (char *) & mdbm_h, sizeof mdbm_h) !=
X		    sizeof mdbm_h)
X		goto out2;
X    }
X    else {
X	if (read (d -> mdbm_mapfd, (char *) & mdbm_h, sizeof mdbm_h) !=
X		sizeof mdbm_h) {
X	    l = EINVAL;
X	    goto out2;
X	}
X	dsize = mdbm_h.mh_dsize;
X	msize = mdbm_h.mh_msize;
X    }
X    if (adsize)
X	*adsize = dsize;
X    if (amsize)
X	*amsize = msize;
X    if (comment)
X	(void) strncpy (comment, mdbm_h.mh_comment, MDBM_CSIZ);
X    if ((d -> mdbm_d = malloc ((unsigned) dsize)) == 0) {
X	l = ENOMEM;
X	goto out2;
X    }
X    if ((d -> mdbm_s = malloc ((unsigned) dsize)) == 0) {
X	free (d -> mdbm_d);
X	l = ENOMEM;
X	goto out2;
X    }
X    if ((d -> mdbm_m = malloc ((unsigned) msize)) == 0) {
X	free (d -> mdbm_s);
X	free (d -> mdbm_d);
X	l = ENOMEM;
X	goto out2;
X    }
X    d -> mdbm_dsize = dsize;
X    d -> mdbm_msize = msize;
X    d -> mdbm_maxbit = (stat.st_size - sizeof mdbm_h) * BYTESIZ;
X    d -> mdbm_dblock = -1;
X    d -> mdbm_mblock = -1;
X
X    return d;
X
Xout2: 
X    (void) close (d -> mdbm_datafd);
Xout1: 
X    (void) close (d -> mdbm_mapfd);
Xout: 
X    free ((char *) d);
X    errno = l;
X    return 0;
X}
END_OF_./mdbm/open.c
if test 3310 -ne `wc -c <./mdbm/open.c`; then
    echo shar: \"./mdbm/open.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f ./mdbm/search.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"./mdbm/search.c\"
else
echo shar: Extracting \"./mdbm/search.c\" \(1528 characters\)
sed "s/^X//" >./mdbm/search.c <<'END_OF_./mdbm/search.c'
X#ifndef lint
Xstatic char rcsid[] = "$Header: /ful/chris/dist/mdbm/search.c,v 1.1 84/08/12 10:03:12 chris Rel $";
X#endif
X
X#include <stdio.h>
X#include "mdbm.h"
X#include "mdbm_local.h"
X
X/*
X * Search for the given key, and if found, return a pointer to the
X * datum under the key.  If ablock and aindex are nonzero, fill in
X * the block and index numbers of the key.  If justkey is true,
X * forget about the datum and stop when the key is found.
X *
X * (Workhorse for fetch, also used by delete & store.)
X */
Xstruct mdbm_dentry *mdbm_search (d, s, len, ablock, aindex, justkey)
Xregister struct mdbm *d;
Xchar *s;
Xregister int len;
Xlong *ablock;
Xint *aindex;
Xint justkey;
X{
X#define db ((struct mdbm_dblock *) d -> mdbm_d)
X    register struct mdbm_dentry *de;
X    register int    i;
X    register unsigned short outx;
X    long    outh;
X
X    (void) mdbm_access (d, mdbm_calchash (s, len));
X    for (i = 0, de = db -> db_e; i < db -> db_n; i++, de++) {
X	if (de -> de_outx == 0)	/* not a key */
X	    continue;
X	if (len == (i ? de[-1].de_off : d -> mdbm_dsize) - de -> de_off)
X	    if (bcmp (s, d -> mdbm_d + de -> de_off, len) == 0)
X		goto found;
X    }
X    return 0;
Xfound: 
X    if (ablock)
X	*ablock = d -> mdbm_dblock;
X    if (aindex)
X	*aindex = i;
X    if (justkey)
X	return de;
X    outx = de -> de_outx;
X    (void) mdbm_access (d, outh = de -> de_outh);
X    for (i = 0, de = db -> db_e; i < db -> db_n; i++, de++)
X	if (de -> de_inx == outx)
X	    return de;
X    printf ("mdbm bug: no datum for key (%d, %d)\n", outh, outx);
X    return 0;
X}
END_OF_./mdbm/search.c
if test 1528 -ne `wc -c <./mdbm/search.c`; then
    echo shar: \"./mdbm/search.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f ./mdbm/sync.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"./mdbm/sync.c\"
else
echo shar: Extracting \"./mdbm/sync.c\" \(423 characters\)
sed "s/^X//" >./mdbm/sync.c <<'END_OF_./mdbm/sync.c'
X#ifndef lint
Xstatic char rcsid[] = "$Header: /ful/chris/dist/mdbm/sync.c,v 1.1 84/08/12 10:04:03 chris Rel $";
X#endif
X
X#include <stdio.h>
X#include "mdbm.h"
X#include "mdbm_local.h"
X
X/*
X * Sync the file attached to dbm d
X */
Xmdbm_sync (d)
Xregister struct mdbm *d;
X{
X    MDBM_SYNC (d);
X#ifdef SYSV
X    (void) sync ();
X    (void) sync ();
X#else
X    (void) fsync (d -> mdbm_datafd);
X    (void) fsync (d -> mdbm_mapfd);
X#endif
X}
END_OF_./mdbm/sync.c
if test 423 -ne `wc -c <./mdbm/sync.c`; then
    echo shar: \"./mdbm/sync.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f ./mdbm/testdbm.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"./mdbm/testdbm.c\"
else
echo shar: Extracting \"./mdbm/testdbm.c\" \(5554 characters\)
sed "s/^X//" >./mdbm/testdbm.c <<'END_OF_./mdbm/testdbm.c'
X#ifndef lint
Xstatic char rcsid[] = "$Header: /ful/chris/dist/mdbm/testdbm.c,v 1.1 84/08/12 10:04:23 chris Rel $";
X#endif lint
X
X/*
X * testdbm - test the new multiple key database library
X */
X
X#include "mdbm.h"
X#include <stdio.h>
X#include <sys/types.h>
X#ifdef SYSV
X#include <fcntl.h>
X#else
X#include <sys/file.h>
X#endif
X#include <ctype.h>
X
Xstruct mdbm *mp;
X#define NAV 10
Xstruct stringarg {
X	int s_len;
X	char *s_str;
X} av[NAV];
X
Xint c_open (), c_close (), c_fetch (), c_insert (), c_replace ();
Xint c_delete (), c_list (), c_quit (), c_sync ();
X
Xstruct cmd {
X	char *c_name;
X	int (*c_func)();
X	int   c_args;
X} cmds[] = {
X	"open",		c_open,		2,
X	"open",		c_open,		4,
X	"open",		c_open,		5,
X	"close",	c_close,	1,
X	"fetch",	c_fetch,	2,
X	"get",		c_fetch,	2,
X	"insert",	c_insert,	3,
X	"store",	c_insert,	3,
X	"replace",	c_replace,	3,
X	"delete",	c_delete,	2,
X	"list",		c_list,		1,
X	"quit",		c_quit,		1,
X	"sync",		c_sync,		1,
X	0, 0, 0
X};
Xchar serrbuf[BUFSIZ];
X
X#define checkdb() \
X	if (!mp) { \
X		fprintf (stderr, "no database active\n"); \
X		return; \
X	} \
X	else
X
Xmain () {
X	char cmdbuf[BUFSIZ];
X
X	setbuf (stderr, serrbuf);
X	for (;;) {
X		fflush (stderr);
X		printf ("testdbm> ");
X		fflush (stdout);
X		if (fgets (cmdbuf, sizeof cmdbuf, stdin) == NULL) {
X			putchar ('\n');
X			c_quit (0);
X		}
X		if (doit (cmdbuf))
X			printf ("Eh?\n");
X	}
X}
X
Xdoit (s)
Xchar *s;
X{
X	register int argc = parse (s);
X	register struct cmd *cp;
X
X	if (argc < 1)
X		return 0;
X	if (av[0].s_len < 1)
X		return 1;
X	for (cp = cmds; cp -> c_name; cp++) {
X		if (cp -> c_args != argc)
X			continue;
X		if (strncmp (cp -> c_name, av[0].s_str, av[0].s_len) == 0) {
X			(*cp -> c_func) (argc);
X			return 0;
X		}
X	}
X	return 1;
X}
X
Xc_open (argc) {
X	int dsize, msize;
X	static char comment[MDBM_CSIZ];
X
X	if (mp)
X		(void) mdbm_close (mp);
X	if (argc == 5)
X		strncpy (comment, av[4].s_str, sizeof comment);
X	else
X		*comment = 0;
X	if (argc >= 4) {
X		dsize = atoi (av[2].s_str);
X		msize = atoi (av[3].s_str);
X	}
X	else
X		dsize = msize = 0;
X	mp = mdbm_open (av[1].s_str, O_RDWR|O_CREAT, 0666, &dsize, &msize, comment);
X	if (mp == 0) {
X		fprintf (stderr, "can't open ");
X		perror (av[1].s_str);
X		return;
X	}
X	comment[sizeof comment - 1] = 0;
X	printf ("opened %s - dsize %d, msize %d, comment %s\n",
X		av[1].s_str, dsize, msize, comment);
X}
X
Xc_close (argc) {
X	if (mp)
X		(void) mdbm_close (mp);
X	mp = 0;
X}
X
Xc_fetch (argc) {
X	datum key, dat;
X
X	checkdb ();
X	key.dptr = av[1].s_str;
X	key.dsize = av[1].s_len;
X	dat = mdbm_fetch (mp, key);
X	prdatum (key);
X	printf (": ");
X	if (dat.dptr == 0)
X		printf ("not found");
X	else
X		prdatum (dat);
X	putchar ('\n');
X}
X
Xprdatum (d)
Xdatum d;
X{
X	register char *p;
X	register int c;
X	register int i;
X
X	i = d.dsize;
X	p = d.dptr;
X	while (--i >= 0) {
X		c = *p++ & 0377;
X		if (c & 0200) {
X			putchar ('M'), putchar ('-');
X			c &= 0177;
X		}
X		if (c == 0177 || c < ' ') {
X			putchar ('^');
X			if (c == 0177)
X				putchar ('?');
X			else
X				putchar (c + '@');
X		}
X		else
X			putchar (c);
X	}
X}
X
Xc_insert (argc) {
X	datum key, dat;
X	int e;
X
X	checkdb ();
X	key.dptr = av[1].s_str;
X	key.dsize = av[1].s_len;
X	dat.dptr = av[2].s_str;
X	dat.dsize = av[2].s_len;
X	e = mdbm_store (mp, key, dat, MDBM_INSERT);
X	if (e == 0)
X		return;
X	if (e < 0)
X		perror ("store failed");
X	else
X		fprintf (stderr, "insert failed, key in use\n");
X}
X
Xc_replace (argc) {
X	datum key, dat;
X	int e;
X
X	checkdb ();
X	key.dptr = av[1].s_str;
X	key.dsize = av[1].s_len;
X	dat.dptr = av[2].s_str;
X	dat.dsize = av[2].s_len;
X	if (mdbm_store (mp, key, dat, MDBM_REPLACE))
X		perror ("store failed");
X}
X
Xc_delete (argc) {
X	datum key;
X
X	checkdb ();
X	key.dptr = av[1].s_str;
X	key.dsize = av[1].s_len;
X	if (mdbm_delete (mp, key))
X		perror ("delete failed");
X}
X
Xc_list () {
X	datum key, dat;
X
X	checkdb ();
X	for (key = mdbm_firstkey (mp); key.dptr; key = mdbm_nextkey (mp, key)) {
X		dat = mdbm_fetch (mp, key);
X		prdatum (key);
X		printf (": ");
X		if (dat.dptr == 0)
X			printf ("datum not found!");
X		else
X			prdatum (dat);
X		putchar ('\n');
X	}
X}
X
Xc_quit () {
X	if (mp)
X		(void) mdbm_close (mp);
X	exit (0);
X}
X
Xc_sync () {
X	checkdb ();
X	mdbm_sync (mp);
X}
X
Xparse (s)
Xregister char *s;
X{
X    register struct stringarg  *ap;
X    register int    aleft;
X    register int    qu = 0;
X    register char  *cp;
X    register int    c;
X    static char xbuf[BUFSIZ];
X    char *malloc ();
X
X    for (ap = av, aleft = NAV; --aleft >= 0; ap++)
X	if (ap -> s_str) {
X	    free (ap -> s_str);
X	    ap -> s_str = 0;
X	}
X
X    ap = av;
X    aleft = NAV;
X    while (*s) {
X	while (isspace (*s))
X	    s++;
X	if (!*s)
X	    break;
X	qu = 0;
X	cp = xbuf;
X	while (((c = *s) != 0) && (qu || !isspace (c))) {
X	    s++;
X	    if (qu == '\\') {
X		switch (c) {
X		    case 'n': 
X			c = '\n';
X			break;
X		    case 'r': 
X			c = '\r';
X			break;
X		    case 't': 
X			c = '\t';
X			break;
X		    case 'b': 
X			c = '\b';
X			break;
X		    case 'f': 
X			c = '\f';
X			break;
X		    case '0': 
X		    case '1': 
X		    case '2': 
X		    case '3': 
X		    case '4': 
X		    case '5': 
X		    case '6': 
X		    case '7': 
X			c -= '0';
X			if (*s >= '0' && *s <= '7') {
X			    c = (c << 3) + *s++ - '0';
X			    if (*s >= '0' && *s <= '7')
X				c = (c << 3) + *s++ - '0';
X			}
X			break;
X		}
X		*cp++ = c;
X		qu = 0;
X	    }
X	    else if (c == qu)
X		qu = 0;
X	    else if (qu == 0 && (c == '\'' || c == '"' || c == '\\'))
X		qu = c;
X	    else
X		*cp++ = c;
X	}
X	*cp++ = 0;
X	if (--aleft < 0) {
X	    fprintf (stderr, "too many argv's\n");
X	    return 0;
X	}
X	ap -> s_str = malloc (cp - xbuf);
X	ap -> s_len = cp - xbuf;
X	bcopy (xbuf, ap -> s_str, ap -> s_len);
X	ap -> s_len--;		/* stop counting trailing \0 */
X	ap++;
X    }
X    return NAV - aleft;
X}
END_OF_./mdbm/testdbm.c
if test 5554 -ne `wc -c <./mdbm/testdbm.c`; then
    echo shar: \"./mdbm/testdbm.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of archive 1 \(of 2\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 2 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked both archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0

---

But don't underestimate raw, frothing, manic hardware.
				(barry shein)
Randy Suess
..!att!chinet!randy
-- 
But don't underestimate raw, frothing, manic hardware.
				(barry shein)
Randy Suess
..!att!chinet!randy



More information about the Unix-pc.general mailing list