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 Comp.sys.att
mailing list