+.TH DBM 3X "19 January 1983"
+.UC 4
+.SH NAME
+dbminit, fetch, store, delete, firstkey, nextkey \- data base subroutines
+.SH SYNOPSIS
+.nf
+.PP
+.B typedef struct {
+.B " char *dptr;"
+.B " int dsize;"
+.B } datum;
+.PP
+.B dbminit(file)
+.B char *file;
+.PP
+.B datum fetch(key)
+.B datum key;
+.PP
+.B store(key, content)
+.B datum key, content;
+.PP
+.B delete(key)
+.B datum key;
+.PP
+.B datum firstkey()
+.PP
+.B datum nextkey(key)
+.B datum key;
+.SH DESCRIPTION
+These functions maintain key/content pairs in a data base.
+The functions will handle very large (a billion blocks)
+databases and will access a keyed item in one or two file system accesses.
+The functions are obtained with the loader option
+.BR \-ldbm .
+.PP
+.IR Key s
+and
+.IR content s
+are described by the
+.I datum
+typedef. A
+.I datum
+specifies a string of
+.I dsize
+bytes pointed to by
+.I dptr.
+Arbitrary binary data, as well as normal ASCII strings, are allowed.
+The data base is stored in two files.
+One file is a directory containing a bit map and has `.dir' as its suffix.
+The second file contains all data and has `.pag' as its suffix.
+.PP
+Before a database can be accessed, it must be opened by
+.I dbminit.
+At the time of this call, the files
+.IB file .dir
+and
+.IB file .pag
+must exist.
+(An empty database is created by creating zero-length
+`.dir' and `.pag' files.)
+.PP
+Once open, the data stored under a key is accessed by
+.I fetch
+and data is placed under a key by
+.IR store .
+A key (and its associated contents) is deleted by
+.IR delete .
+A linear pass through all keys in a database may be made,
+in an (apparently) random order, by use of
+.I firstkey
+and
+.IR nextkey .
+.I Firstkey
+will return the first key in the database. With any key
+.I nextkey
+will return the next key in the database.
+This code will traverse the data base:
+.IP
+.B for
+(key = firstkey(); key.dptr != NULL; key = nextkey(key))
+.SH DIAGNOSTICS
+All functions that return an
+.I int
+indicate errors with negative values. A zero return indicates ok.
+Routines that return a
+.I datum
+indicate errors with a null (0)
+.I dptr.
+.SH BUGS
+The `.pag' file will contain holes so that its apparent size is about
+four times its actual content. Older UNIX systems may create real
+file blocks for these holes when touched. These files cannot be copied
+by normal means (cp, cat, tp, tar, ar) without filling in the holes.
+.PP
+.I Dptr
+pointers returned by these subroutines point into static storage
+that is changed by subsequent calls.
+.PP
+The sum of the sizes of a key/content pair must not exceed
+the internal block size (currently 1024 bytes).
+Moreover all key/content pairs that hash together must fit on a single block.
+.I Store
+will return an error in the event that a disk block fills with inseparable data.
+.PP
+.I Delete
+does not physically reclaim file space,
+although it does make it available for reuse.
+.PP
+The order of keys presented by
+.I firstkey
+and
+.I nextkey
+depends on a hashing function, not on anything interesting.