### NAME cdb - read a constant database ### SYNOPSIS #include "cdb.h" static struct cdb c; num fd; char *k; num klen; num result; char *d; num dlen; num dpos; cdb_init(&c,fd); result = cdb_find(&c,k,klen); /* optional decomposition of cdb_find: */ cdb_findstart(&c); result = cdb_findnext(&c,k,klen); dlen = cdb_datalen(&c); dpos = cdb_datapos(&c); result = cdb_read(&c,d,dlen,dpos); cdb_free(&c); ### DESCRIPTION You can read records in a constant database from file descriptor `fd` as follows: * Use `cdb_init` to place information about `fd` into a `struct cdb` variable `c`. * Carry out any number of searches, as described below. * Use `cdb_free` to remove any memory map that might have been reserved by `cdb_init`. Each search works as follows: * Use `cdb_find` to search for a record under key `k`. If `cdb_find` returns `0`, the database does not contain that key; stop. If `cdb_find` returns `-1`, there was a read error; abort. * Use `cdb_datalen` to find the number of bytes of data in this record. Allocate a pointer `d` to a region of memory large enough to hold the data. If not enough memory is available, abort. * Use `cdb_read` with `cdb_datapos` to read the data. If `cdb_read` returns `-1`, there was a read error; abort. * Do something with the data, and then free the allocated region of memory. There may be several records under a single key. You can use `cdb_findnext` to find the next record under this key. ### DETAILS A `struct cdb` variable such as `c` is either unallocated or allocated. If it is allocated, it holds information about a constant database: * a file descriptor `fd` reading from the database; * if convenient, a shared memory map reading from the database; and * information about a search in progress. `c` must be initialized to zero, meaning unallocated. `cdb_free` unallocates `c` if `c` is allocated. Otherwise it leaves `c` alone. `cdb_free` does not close `fd`. `cdb_init` allocates `c` to hold information about a constant database read by descriptor `fd`. You may call `cdb_init` repeatedly; if `c` is already allocated, `cdb_init` unallocates it first. `cdb_read` reads `dlen` bytes into `d` from byte position `dpos` in the database. You must allocate `c` before calling `cdb_read`. Normally `cdb_read` returns `0`. If the database file is shorter than `dpos+dlen` bytes, or if there is a disk read error, `cdb_read` returns `-1`, setting `errno` appropriately. `cdb_findstart` prepares `c` to search for the first record under a new key. You must allocate `c` before calling `cdb_findstart`, and you must call `cdb_findstart` before calling `cdb_findnext`. `cdb_findnext` looks for the nth record under key `k` in the database, where `n` is the number of calls to `cdb_findnext` after the most recent call to `cdb_findstart`. If it finds the record, `cdb_findnext` returns 1; if there are exactly `n-1` such records, `cdb_findnext` returns `0`; if there are fewer than `n-1` such records, the behavior of `cdb_findnext` is undefined; if there is a database format error or disk error, `cdb_findnext` returns `-1`, setting `errno` appropriately. Each call to `cdb_findnext` (before another call to `cdb_findstart`) must use the same `k` and `klen`. If `cdb_findnext` returns 1, it arranges for `cdb_datapos` to return the starting byte position of the data in the record, and for `cdb_datalen` to return the number of bytes of data in the record. Otherwise the results of `cdb_datapos` and `cdb_datalen` are undefined. `cdb_find` is the same as `cdb_findstart` followed by `cdb_findnext`: it finds the first record under key `k`. Beware that these functions may rely on non-atomic operations on the `fd` ofile, such as seeking to a particular position and then reading. Do not attempt two simultaneous database reads using a single ofile. ### SEE ALSO **cdbget**(1)