--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pristine/cdb-0.75-traversal.diff2 Fri Oct 19 11:09:15 2007 +0200
@@ -0,0 +1,809 @@
+diff -uNr cdb-0.75/FILES cdb-0.75-fefe/FILES
+--- cdb-0.75/FILES Sat Feb 19 21:42:05 2000
++++ cdb-0.75-fefe/FILES Wed Sep 27 21:54:44 2000
+@@ -76,3 +76,21 @@
+ uint32.h2
+ uint32_pack.c
+ uint32_unpack.c
++traverse.c
++cdbdump.1
++cdbget.1
++cdbmake.1
++cdbstats.1
++cdbtest.1
++cdbnext.c
++cdb_datalen.3
++cdb_datapos.3
++cdb_find.3
++cdb_firstkey.3
++cdb_free.3
++cdb_init.3
++cdb_keylen.3
++cdb_keypos.3
++cdb_nextkey.3
++cdb_read.3
++cdb_successor.3
+diff -uNr cdb-0.75/Makefile cdb-0.75-fefe/Makefile
+--- cdb-0.75/Makefile Sat Feb 19 21:42:05 2000
++++ cdb-0.75-fefe/Makefile Wed Sep 27 21:46:39 2000
+@@ -87,13 +87,17 @@
+ ./compile byte_diff.c
+
+ cdb.a: \
+-makelib cdb.o cdb_hash.o cdb_make.o
+- ./makelib cdb.a cdb.o cdb_hash.o cdb_make.o
++makelib cdb.o cdb_hash.o cdb_make.o cdb_traverse.o
++ ./makelib cdb.a cdb.o cdb_hash.o cdb_make.o cdb_traverse.o
+
+ cdb.o: \
+ compile cdb.c readwrite.h error.h seek.h byte.h cdb.h uint32.h
+ ./compile cdb.c
+
++cdb_traverse.o: \
++compile cdb_traverse.c cdb.h uint32.h seek.h
++ ./compile cdb_traverse.c
++
+ cdb_hash.o: \
+ compile cdb_hash.c cdb.h uint32.h
+ ./compile cdb_hash.c
+@@ -244,7 +248,7 @@
+
+ prog: \
+ cdbget cdbmake cdbdump cdbstats cdbtest cdbmake-12 cdbmake-sv rts \
+-testzero
++testzero traverse cdbnext
+
+ rts: \
+ warn-auto.sh rts.sh conf-home
+@@ -318,3 +322,26 @@
+ seek_cur.o
+ ./makelib unix.a error.o open_read.o open_trunc.o \
+ error_str.o seek_set.o seek_cur.o
++
++traverse: \
++load traverse.o cdb.a uint32_unpack.o byte_copy.o seek_set.o \
++error.o byte_diff.o fmt_ulong.o
++ ./load traverse cdb.a uint32_unpack.o byte_copy.o seek_set.o \
++ error.o byte_diff.o fmt_ulong.o
++
++traverse.o: \
++compile traverse.c cdb.h uint32.h fmt.h
++ ./compile traverse.c
++
++cdbnext: \
++load cdbnext.o cdb.a buffer.a byte.a error.o error_str.o seek_set.o
++ ./load cdbnext cdb.a buffer.a byte.a error.o error_str.o \
++ seek_set.o
++
++cdbnext.o: \
++compile cdbnext.c exit.h scan.h str.h buffer.h strerr.h cdb.h \
++uint32.h
++ ./compile cdbnext.c
++
++clean:
++ rm -f `cat TARGETS`
+diff -uNr cdb-0.75/TARGETS cdb-0.75-fefe/TARGETS
+--- cdb-0.75/TARGETS Sat Feb 19 21:42:05 2000
++++ cdb-0.75-fefe/TARGETS Wed Sep 27 21:35:15 2000
+@@ -64,3 +64,8 @@
+ it
+ setup
+ check
++traverse
++traverse.o
++cdb_traverse.o
++cdbnext
++cdbnext.o
+diff -uNr cdb-0.75/cdb.h cdb-0.75-fefe/cdb.h
+--- cdb-0.75/cdb.h Sat Feb 19 21:42:05 2000
++++ cdb-0.75-fefe/cdb.h Wed Sep 27 21:02:59 2000
+@@ -31,7 +31,14 @@
+ extern int cdb_findnext(struct cdb *,char *,unsigned int);
+ extern int cdb_find(struct cdb *,char *,unsigned int);
+
++extern int cdb_firstkey(struct cdb *c,uint32 *kpos);
++extern int cdb_nextkey(struct cdb *c,uint32 *kpos);
++
++extern int cdb_successor(struct cdb *c,char *,unsigned int);
++
+ #define cdb_datapos(c) ((c)->dpos)
+ #define cdb_datalen(c) ((c)->dlen)
++#define cdb_keypos(c) ((c)->kpos)
++#define cdb_keylen(c) ((c)->dpos-(c)->kpos)
+
+ #endif
+diff -uNr cdb-0.75/cdb_datalen.3 cdb-0.75-fefe/cdb_datalen.3
+--- cdb-0.75/cdb_datalen.3 Thu Jan 1 01:00:00 1970
++++ cdb-0.75-fefe/cdb_datalen.3 Wed Sep 27 21:52:34 2000
+@@ -0,0 +1,17 @@
++.TH cdb_datalen 3
++.SH NAME
++cdb_datalen \- get length of data
++.SH SYNTAX
++.B #include <cdb.h>
++
++unsigned int cdb_datalen(struct cdb *\fIc\fR);
++
++.SH DESCRIPTION
++.B cdb_datalen
++returns the length of the data associated with the last key you looked
++up with cdb_find or cdb_findnext.
++
++Use cdb_datapos to get the position of the data.
++
++.SH "SEE ALSO"
++cdb_datapos(3), cdb_keylen(3), cdb_keypos(3)
+diff -uNr cdb-0.75/cdb_datapos.3 cdb-0.75-fefe/cdb_datapos.3
+--- cdb-0.75/cdb_datapos.3 Thu Jan 1 01:00:00 1970
++++ cdb-0.75-fefe/cdb_datapos.3 Wed Sep 27 21:52:37 2000
+@@ -0,0 +1,17 @@
++.TH cdb_datapos 3
++.SH NAME
++cdb_datapos \- get position of data
++.SH SYNTAX
++.B #include <cdb.h>
++
++uint32 cdb_datapos(struct cdb *\fIc\fR);
++
++.SH DESCRIPTION
++.B cdb_datapos
++returns the position of the data associated with the last key you looked
++up using cdb_find or cdb_findnext.
++
++Use cdb_datalen to get the length of the data.
++
++.SH "SEE ALSO"
++cdb_datalen(3), cdb_keypos(3), cdb_keylen(3)
+diff -uNr cdb-0.75/cdb_find.3 cdb-0.75-fefe/cdb_find.3
+--- cdb-0.75/cdb_find.3 Thu Jan 1 01:00:00 1970
++++ cdb-0.75-fefe/cdb_find.3 Wed Sep 27 21:53:03 2000
+@@ -0,0 +1,42 @@
++.TH cdb_find 3
++.SH NAME
++cdb_find \- look up a key in a constant database
++.SH SYNTAX
++.B #include <cdb.h>
++.br
++.B #include <uint32.h>
++
++int cdb_find(struct cdb *\fIc\fR,char *\fIkey\fR,unsigned int \fIkeylen\fR);
++.br
++int cdb_datalen(struct cdb *\fIc\fR);
++.br
++int cdb_datapos(struct cdb *\fIc\fR);
++.br
++int cdb_findnext(struct cdb *\fIc\fR,char *\fIkey\fR,unsigned int \fIkeylen\fR);
++
++.SH DESCRIPTION
++\fBcdb_find\fR looks for \fIkey\fR. If cdb_find returns 0, the database
++does not contain that key; stop. If cdb_find returns -1, there was a
++read error; abort.
++
++\fBcdb_datalen\fR returns the length of the data associated with the
++\fIkey\fR. Use it to allocate a pointer \fIp\fR with enough space to
++hold the data.
++
++\fBcdb_datapos\fR returns the position of the data inside the file. Use
++it as argument to cdb_read to retrieve the data.
++
++There may be several records under a single key. You can use
++\fBcdb_findnext\fR to find the next record under this key.
++
++.SH EXAMPLE
++static struct cdb;
++
++if (cdb_find(&c,key,strlen(key)>0) {
++ char *buf=alloca(cdb_datalen(&c));
++ cdb_read(&c,buf,cdb_datalen(&c),cdb_datapos(&c));
++ write(1,buf,cdb_datalen(&c));
++.br
++}
++.SH "SEE ALSO"
++cdb_read(3), cdb_init(3), cdb_free(3), cdbmake(1)
+diff -uNr cdb-0.75/cdb_firstkey.3 cdb-0.75-fefe/cdb_firstkey.3
+--- cdb-0.75/cdb_firstkey.3 Thu Jan 1 01:00:00 1970
++++ cdb-0.75-fefe/cdb_firstkey.3 Wed Sep 27 21:53:07 2000
+@@ -0,0 +1,19 @@
++.TH cdb_firstkey 3
++.SH NAME
++cdb_firstkey \- find first physical record in constant database
++.SH SYNTAX
++.B #include <cdb.h>
++.br
++.B #include <uint32.h>
++
++int cdb_firstkey(struct cdb *\fIc\fR,uint32 *\fIkpos\fR);
++
++.SH DESCRIPTION
++\fBcdb_firstkey\fR finds the physically first record in the constant
++database.
++
++You can use cdb_datapos or cdb_keypos to get \fIposition\fR and
++cdb_datalen and cdb_keylen to get \fIlen\fR.
++
++.SH "SEE ALSO"
++cdb_nextkey(3), cdb_successor(3)
+diff -uNr cdb-0.75/cdb_free.3 cdb-0.75-fefe/cdb_free.3
+--- cdb-0.75/cdb_free.3 Thu Jan 1 01:00:00 1970
++++ cdb-0.75-fefe/cdb_free.3 Wed Sep 27 21:53:10 2000
+@@ -0,0 +1,17 @@
++.TH cdb_free 3
++.SH NAME
++cdb_free \- close a constant databased
++.SH SYNTAX
++.B #include <cdb.h>
++
++int cdb_free(struct cdb *\fIc\fR);
++
++.SH DESCRIPTION
++.B cdb_free
++removes any memory mapping that cdb_init might have established.
++
++It will not close the file descriptor that you passed to cdb_init or
++attempt to call free() on the struct cdb pointer.
++
++.SH "SEE ALSO"
++cdb_free(3), cdb_read(3), cdb_find(3), cdbmake(1)
+diff -uNr cdb-0.75/cdb_init.3 cdb-0.75-fefe/cdb_init.3
+--- cdb-0.75/cdb_init.3 Thu Jan 1 01:00:00 1970
++++ cdb-0.75-fefe/cdb_init.3 Wed Sep 27 21:53:12 2000
+@@ -0,0 +1,20 @@
++.TH cdb_init 3
++.SH NAME
++cdb_init \- open a constant database
++.SH SYNTAX
++.B #include <cdb.h>
++
++int cdb_init(struct cdb *\fIc\fR,int \fIfd\fR);
++
++.SH DESCRIPTION
++.B cdb_init
++places information about \fIfd\fR into a struct cdb variable \fIc\fR.
++\fIfd\fR has to be a seekable file previously opened for reading.
++
++On systems that support mmap, cdb_init will try to map the whole
++constant database into memory.
++
++The inverse operation to cdb_init is cdb_free.
++
++.SH "SEE ALSO"
++cdb_free(3), cdb_read(3), cdb_find(3), cdbmake(1)
+diff -uNr cdb-0.75/cdb_keylen.3 cdb-0.75-fefe/cdb_keylen.3
+--- cdb-0.75/cdb_keylen.3 Thu Jan 1 01:00:00 1970
++++ cdb-0.75-fefe/cdb_keylen.3 Wed Sep 27 21:53:14 2000
+@@ -0,0 +1,16 @@
++.TH cdb_keylen 3
++.SH NAME
++cdb_keylen \- get length of key
++.SH SYNTAX
++.B #include <cdb.h>
++
++unsigned int cdb_keylen(struct cdb *\fIc\fR);
++
++.SH DESCRIPTION
++.B cdb_keylen
++returns the length of the key cdb_firstkey or cdb_nextkey found.
++
++Use cdb_keypos to get the position of the key.
++
++.SH "SEE ALSO"
++cdb_keypos(3), cdb_datalen(3), cdb_datapos(3)
+diff -uNr cdb-0.75/cdb_keypos.3 cdb-0.75-fefe/cdb_keypos.3
+--- cdb-0.75/cdb_keypos.3 Thu Jan 1 01:00:00 1970
++++ cdb-0.75-fefe/cdb_keypos.3 Wed Sep 27 21:53:16 2000
+@@ -0,0 +1,16 @@
++.TH cdb_keypos 3
++.SH NAME
++cdb_keypos \- get position of key
++.SH SYNTAX
++.B #include <cdb.h>
++
++uint32 cdb_keypos(struct cdb *\fIc\fR);
++
++.SH DESCRIPTION
++.B cdb_keypos
++returns the position of the key cdb_firstkey or cdb_nextkey found.
++
++Use cdb_keylen to get the length of the key.
++
++.SH "SEE ALSO"
++cdb_keylen(3), cdb_datapos(3), cdb_datalen(3)
+diff -uNr cdb-0.75/cdb_nextkey.3 cdb-0.75-fefe/cdb_nextkey.3
+--- cdb-0.75/cdb_nextkey.3 Thu Jan 1 01:00:00 1970
++++ cdb-0.75-fefe/cdb_nextkey.3 Wed Sep 27 21:52:17 2000
+@@ -0,0 +1,19 @@
++.TH cdb_nextkey 3
++.SH NAME
++cdb_nextkey \- find next physical record in constant database
++.SH SYNTAX
++.B #include <cdb.h>
++.br
++.B #include <uint32.h>
++
++int cdb_nextkey(struct cdb *\fIc\fR,uint32 *\fIkpos\fR);
++
++.SH DESCRIPTION
++\fBcdb_nextkey\fR finds the next physical record in the constant
++database.
++
++You can use cdb_datapos or cdb_keypos to get \fIposition\fR and
++cdb_datalen and cdb_keylen to get \fIlen\fR.
++
++.SH "SEE ALSO"
++cdb_firstkey(3), cdb_successor(3)
+diff -uNr cdb-0.75/cdb_read.3 cdb-0.75-fefe/cdb_read.3
+--- cdb-0.75/cdb_read.3 Thu Jan 1 01:00:00 1970
++++ cdb-0.75-fefe/cdb_read.3 Wed Sep 27 21:53:22 2000
+@@ -0,0 +1,20 @@
++.TH cdb_read 3
++.SH NAME
++cdb_read \- read bytes from a constant database
++.SH SYNTAX
++.B #include <cdb.h>
++.br
++.B #include <uint32.h>
++
++int cdb_read(struct cdb *\fIc\fR,char *\fIbuf\fR,unsigned int \fIlen\fR,uint32 \fIposition\fR);
++
++.SH DESCRIPTION
++\fBcdb_read\fR reads \fIlen\fR bytes starting at \fIposition\fR from
++\fIc\fR to buf. You can use cdb_datapos or cdb_keypos to get
++\fIposition\fR and cdb_datalen and cdb_keylen to get \fIlen\fR.
++
++\fIbuf\fR needs to point to a memory region large enough to hold
++\fIlen\fR bytes.
++
++.SH "SEE ALSO"
++cdb_find(3), cdb_init(3), cdb_free(3), cdbmake(1)
+diff -uNr cdb-0.75/cdb_successor.3 cdb-0.75-fefe/cdb_successor.3
+--- cdb-0.75/cdb_successor.3 Thu Jan 1 01:00:00 1970
++++ cdb-0.75-fefe/cdb_successor.3 Wed Sep 27 21:53:23 2000
+@@ -0,0 +1,21 @@
++.TH cdb_successor 3
++.SH NAME
++cdb_successor \- find next record
++.SH SYNTAX
++.B #include <cdb.h>
++
++int cdb_successor(struct cdb *\fIc\fR,char *\fIkey\fR,unsigned int \fIklen\fR);
++
++.SH DESCRIPTION
++\fBcdb_successor\fR finds the record that follows \fIkey\fR. If
++\fIkey\fR is NULL, cdb_successor finds the first record.
++
++\fBNOTE!\fR The database must not contain keys with more than one
++associated record or this API will lead to infinite loops! Use
++cdb_firstkey and cdb_nextkey instead.
++
++You can use cdb_datapos or cdb_keypos to get \fIposition\fR and
++cdb_datalen and cdb_keylen to get \fIlen\fR.
++
++.SH "SEE ALSO"
++cdb_firstkey(3), cdb_nextkey(3)
+diff -uNr cdb-0.75/cdb_traverse.c cdb-0.75-fefe/cdb_traverse.c
+--- cdb-0.75/cdb_traverse.c Thu Jan 1 01:00:00 1970
++++ cdb-0.75-fefe/cdb_traverse.c Wed Sep 27 21:39:18 2000
+@@ -0,0 +1,41 @@
++#include "cdb.h"
++#include "seek.h"
++
++static int doit(struct cdb *c,uint32 *kpos) {
++ char buf[8];
++ uint32 eod,klen;
++ if (cdb_read(c,buf,4,0)) return -1;
++ uint32_unpack(buf,&eod);
++ if (eod<8 || eod-8<*kpos) return 0;
++ c->kpos=*kpos+8;
++ if (c->kpos<*kpos) return -1; /* wraparound */
++ cdb_findstart(c);
++ c->hslots=1;
++ if (cdb_read(c,buf,8,*kpos) == -1) return -1;
++ uint32_unpack(buf,&klen);
++ uint32_unpack(buf+4,&c->dlen);
++ c->dpos=c->kpos+klen;
++ *kpos+=8+klen+c->dlen;
++ return 1;
++}
++
++int cdb_firstkey(struct cdb *c,uint32 *kpos) {
++ *kpos=2048;
++ return doit(c,kpos);
++}
++
++int cdb_nextkey(struct cdb *c,uint32 *kpos) {
++ return doit(c,kpos);
++}
++
++int cdb_successor(struct cdb *c,char *key,unsigned int klen) {
++ int r;
++ uint32 kpos;
++ if (key) {
++ r=cdb_find(c,key,klen);
++ if (r<1) return r;
++ kpos=c->dpos+c->dlen;
++ } else
++ kpos=2048;
++ return doit(c,&kpos);
++}
+diff -uNr cdb-0.75/cdbdump.1 cdb-0.75-fefe/cdbdump.1
+--- cdb-0.75/cdbdump.1 Thu Jan 1 01:00:00 1970
++++ cdb-0.75-fefe/cdbdump.1 Wed Sep 27 20:27:54 2000
+@@ -0,0 +1,17 @@
++.TH cdbdump 1
++.SH NAME
++cdbdump \- print the contents of a constant database
++.SH SYNOPSIS
++.B cdbdump
++.SH DESCRIPTION
++.B cbddump
++reads a constant database from its standard input
++and prints its contents, in
++.B cbdmake
++format,
++on standard output.
++.SH "SEE ALSO"
++cdbget(1),
++cdbmake(1),
++cdb_firstkey(3),
++cdb_nextkey(3)
+diff -uNr cdb-0.75/cdbget.1 cdb-0.75-fefe/cdbget.1
+--- cdb-0.75/cdbget.1 Thu Jan 1 01:00:00 1970
++++ cdb-0.75-fefe/cdbget.1 Sun Apr 30 14:31:33 2000
+@@ -0,0 +1,38 @@
++.TH cdbget 1
++.SH NAME
++cdbget \- look up one key in a constant database
++.SH SYNOPSIS
++.B cdbget
++.I key
++.SH DESCRIPTION
++.B cdbget
++searches for a record indexed by
++.I key
++in a constant database.
++The constant database must be readable (and seekable)
++on
++.BR cdbget 's
++standard input.
++
++.B cdbget
++normally (1) prints the data in the first matching record
++and (2) exits 0.
++Note that
++.B cdbget
++does not check for write errors,
++so it should be used only inside a pipe.
++
++If
++.I key
++is not in the database,
++.B cdbget
++exits 1 without printing anything.
++
++If
++.B cdbget
++encounters a read error,
++it complains and exits 111.
++.SH "SEE ALSO"
++cdbdump(1),
++cdbmake(1),
++cdb(3)
+diff -uNr cdb-0.75/cdbmake.1 cdb-0.75-fefe/cdbmake.1
+--- cdb-0.75/cdbmake.1 Thu Jan 1 01:00:00 1970
++++ cdb-0.75-fefe/cdbmake.1 Sun Apr 30 14:31:33 2000
+@@ -0,0 +1,113 @@
++.TH cdbmake 1
++.SH NAME
++cdbmake \- create a constant database
++.SH SYNOPSIS
++.B cdbmake
++.I file
++.I temp
++.SH DESCRIPTION
++.B cdbmake
++reads a series of encoded records from its standard input
++and writes a constant database to
++.IR file .
++
++Records are indexed by
++.BR keys .
++A key is a string.
++.I file
++is structured so that another program, starting from a key,
++can quickly find the relevant record.
++.B cdbmake
++allows several records with the same key,
++although (1) most readers only take the first record
++and (2)
++.B cdbmake
++slows down somewhat if there are many records with the same key.
++Note that
++.B cdbmake
++preserves the order of records in
++.IR file .
++
++A record is encoded for
++.B cdbmake
++as
++.B +\fIklen\fB,\fIdlen\fB:\fIkey\fB->\fIdata
++followed by a newline.
++Here
++.I klen
++is the number of bytes in
++.IR key
++and
++.I dlen
++is the number of bytes in
++.IR data .
++The end of data is indicated by an extra newline.
++For example:
++
++.EX
++ +3,5:one->Hello
++.br
++ +3,7:two->Goodbye
++.br
++
++.EE
++
++.I key
++and
++.I data
++may contain any characters, including colons, dashes, newlines, and nulls.
++
++.B cdbmake
++ensures that
++.I file
++is updated atomically,
++so programs reading
++.I file
++never have to wait for
++.B cdbmake
++to finish.
++It does this by first writing the database to
++.I temp
++and then moving
++.I temp
++on top of
++.IR file .
++If
++.I temp
++already exists,
++it is destroyed.
++The directories containing
++.I temp
++and
++.I file
++must be writable to
++.BR cdbmake ;
++they must also be on the same filesystem.
++
++.B cdbmake
++always makes sure that
++.I temp
++is safely written to disk before it replaces
++.IR file .
++If the input is in a bad format or if
++.B cdbmake
++has any trouble writing
++.I temp
++to disk,
++.B cdbmake
++complains and leaves
++.I file
++alone.
++
++Keys and data do not have to fit into memory,
++but
++.B cdbmake
++needs roughly 16 bytes of memory per record.
++A database cannot exceed 4 gigabytes.
++
++.I file
++is portable across machines.
++.SH "SEE ALSO"
++cdbdump(1),
++cdbget(1),
++cdbstats(1)
+diff -uNr cdb-0.75/cdbnext.c cdb-0.75-fefe/cdbnext.c
+--- cdb-0.75/cdbnext.c Thu Jan 1 01:00:00 1970
++++ cdb-0.75-fefe/cdbnext.c Wed Sep 27 21:43:32 2000
+@@ -0,0 +1,51 @@
++#include "exit.h"
++#include "scan.h"
++#include "str.h"
++#include "buffer.h"
++#include "strerr.h"
++#include "cdb.h"
++
++#define FATAL "cdbnext: fatal: "
++
++void die_read(void)
++{
++ strerr_die2sys(111,FATAL,"unable to read input: ");
++}
++void die_write(void)
++{
++ strerr_die2sys(111,FATAL,"unable to write output: ");
++}
++
++static struct cdb c;
++char buf[1024];
++
++main(int argc,char **argv)
++{
++ char *key;
++ int r;
++ uint32 pos;
++ uint32 len;
++ unsigned long u = 0;
++
++ key = argv[1];
++
++ cdb_init(&c,0);
++
++ r=cdb_successor(&c,key,key?str_len(key):0);
++ if (r == -1) die_read();
++ if (!r) _exit(100);
++
++ pos = cdb_keypos(&c);
++ len = cdb_keylen(&c);
++
++ while (len > 0) {
++ r = sizeof buf;
++ if (r > len) r = len;
++ if (cdb_read(&c,buf,r,pos) == -1) die_read();
++ if (buffer_put(buffer_1small,buf,r) == -1) die_write();
++ pos += r;
++ len -= r;
++ }
++ if (buffer_flush(buffer_1small) == -1) die_write();
++ _exit(0);
++}
+diff -uNr cdb-0.75/cdbstats.1 cdb-0.75-fefe/cdbstats.1
+--- cdb-0.75/cdbstats.1 Thu Jan 1 01:00:00 1970
++++ cdb-0.75-fefe/cdbstats.1 Sun Apr 30 14:31:33 2000
+@@ -0,0 +1,18 @@
++.TH cdbstats 1
++.SH NAME
++cdbstats \- summarize the contents of a constant database
++.SH SYNOPSIS
++.B cdbstats
++.SH DESCRIPTION
++.B cdbstats
++reads a (seekable) constant database from its standard input
++and prints a few statistics:
++.B slots
++is the number of hash positions;
++.B records
++is the number of records in the database;
++.B d0
++is the number of records at distance 0 from their hash.
++.SH "SEE ALSO"
++cdbdump(1),
++cdbmake(1)
+diff -uNr cdb-0.75/cdbtest.1 cdb-0.75-fefe/cdbtest.1
+--- cdb-0.75/cdbtest.1 Thu Jan 1 01:00:00 1970
++++ cdb-0.75-fefe/cdbtest.1 Sun Apr 30 14:31:33 2000
+@@ -0,0 +1,36 @@
++.TH cdbtest 1
++.SH NAME
++cdbtest \- check retrieval from a constant database
++.SH SYNOPSIS
++.B cdbtest
++.SH DESCRIPTION
++.B cdbtest
++reads a (seekable) constant database from its standard input.
++For each record in the database, it feeds the record's key to
++.B cdb_seek()
++and checks the result.
++It prints tallies in several categories:
++.TP 5
++.B found
++is the number of records found correctly by their keys.
++.TP
++.B different record
++is the number of records where a different record was found
++with the same key. This should not happen unless the database
++has multiple records with the same key.
++.TP
++.B bad length
++is the number of records found but with the wrong data length.
++This should never happen.
++.TP
++.B not found
++is the number of records not found.
++This should never happen.
++.TP
++.B too long to test
++is the number of records with keys longer than 1024 bytes.
++.B cdbtest
++doesn't bother testing these records.
++.SH "SEE ALSO"
++cdbget(1),
++cdb(3)
+Binary files cdb-0.75/foo.cdb and cdb-0.75-fefe/foo.cdb differ
+diff -uNr cdb-0.75/hier.c cdb-0.75-fefe/hier.c
+--- cdb-0.75/hier.c Sat Feb 19 21:42:05 2000
++++ cdb-0.75-fefe/hier.c Wed Sep 27 22:05:11 2000
+@@ -4,6 +4,10 @@
+ {
+ h(auto_home,-1,-1,02755);
+ d(auto_home,"bin",-1,-1,02755);
++ d(auto_home,"man",-1,-1,0755);
++ d(auto_home,"man/man1",-1,-1,0755);
++ d(auto_home,"man/man3",-1,-1,0755);
++
+
+ c(auto_home,"bin","cdbget",-1,-1,0755);
+ c(auto_home,"bin","cdbmake",-1,-1,0755);
+@@ -12,4 +16,22 @@
+ c(auto_home,"bin","cdbtest",-1,-1,0755);
+ c(auto_home,"bin","cdbmake-12",-1,-1,0755);
+ c(auto_home,"bin","cdbmake-sv",-1,-1,0755);
++
++ c(auto_home,"man/man1","cdbdump.1",-1,-1,0755);
++ c(auto_home,"man/man1","cdbget.1",-1,-1,0755);
++ c(auto_home,"man/man1","cdbmake.1",-1,-1,0755);
++ c(auto_home,"man/man1","cdbstats.1",-1,-1,0755);
++ c(auto_home,"man/man1","cdbtest.1",-1,-1,0755);
++
++ c(auto_home,"man/man3","cdb_datalen.3",-1,-1,0644);
++ c(auto_home,"man/man3","cdb_datapos.3",-1,-1,0644);
++ c(auto_home,"man/man3","cdb_find.3",-1,-1,0644);
++ c(auto_home,"man/man3","cdb_firstkey.3",-1,-1,0644);
++ c(auto_home,"man/man3","cdb_free.3",-1,-1,0644);
++ c(auto_home,"man/man3","cdb_init.3",-1,-1,0644);
++ c(auto_home,"man/man3","cdb_keylen.3",-1,-1,0644);
++ c(auto_home,"man/man3","cdb_keypos.3",-1,-1,0644);
++ c(auto_home,"man/man3","cdb_nextkey.3",-1,-1,0644);
++ c(auto_home,"man/man3","cdb_read.3",-1,-1,0644);
++ c(auto_home,"man/man3","cdb_successor.3",-1,-1,0644);
+ }
+diff -uNr cdb-0.75/traverse.c cdb-0.75-fefe/traverse.c
+--- cdb-0.75/traverse.c Thu Jan 1 01:00:00 1970
++++ cdb-0.75-fefe/traverse.c Wed Sep 27 18:41:38 2000
+@@ -0,0 +1,43 @@
++#include <unistd.h>
++#include <sys/fcntl.h>
++#include <stdlib.h>
++#include <assert.h>
++#include "cdb.h"
++#include "fmt.h"
++
++main(int argc,char *argv[]) {
++ int fd;
++ struct cdb c;
++ char strnum[FMT_ULONG];
++ uint32 kpos;
++ fd=open(argc>1?argv[1]:"foo.cdb",O_RDONLY);
++ assert(fd>=0);
++ cdb_init(&c,fd);
++ if (cdb_firstkey(&c,&kpos)==1) {
++ do {
++ uint32 kp,klen,dp,dlen;
++ char *key,*data;
++ kp=cdb_keypos(&c);
++ klen=cdb_keylen(&c);
++ dp=cdb_datapos(&c);
++ dlen=cdb_datalen(&c);
++ {
++ key=alloca(klen);
++ data=alloca(dlen);
++/* printf("%lu %lu; %lu %lu\n",kp,klen,dp,dlen); */
++ assert(cdb_read(&c,key,klen,kp)==0);
++ assert(cdb_read(&c,data,dlen,dp)==0);
++ write(1,"+",1);
++ write(1,strnum,fmt_ulong(strnum,klen));
++ write(1,",",1);
++ write(1,strnum,fmt_ulong(strnum,dlen));
++ write(1,":",1);
++ write(1,key,klen);
++ write(1,"->",2);
++ write(1,data,dlen);
++ write(1,"\n",1);
++ }
++ } while (cdb_nextkey(&c,&kpos)==1);
++ write(1,"\n",1);
++ }
++}