NDB(2)                                                     NDB(2)

          ndbopen, ndbcat, ndbchanged, ndbclose, ndbreopen, ndbsearch,
          ndbsnext, ndbgetvalue, ndbfree, ipattr, mkptrname,
          ndbgetipaddr, ndbipinfo, csipinfo, ndbhash, ndbparse,
          csgetvalue, ndbfindattr, dnsquery, ndbdiscard,
          ndbconcatenate, ndbreorder, ndbsubstitute, ndbdedup,
          ndbsetmalloctag, ndbvalfmt - network database

          #include <u.h>
          #include <libc.h>
          #include <bio.h>
          #include <ndb.h>

          Ndb*       ndbopen(char *file)

          Ndb*       ndbcat(Ndb *db1, Ndb *db2)

          int        ndbchanged(Ndb *db)

          int        ndbreopen(Ndb *db)

          void       ndbclose(Ndb *db)

          Ndbtuple*  ndbsearch(Ndb *db, Ndbs *s, char *attr, char

          Ndbtuple*  ndbsnext(Ndbs *s, char *attr, char *val)

          char*      ndbgetvalue(Ndb *db, Ndbs *s, char *attr, char
                     char *rattr, Ndbtuple **tp)

          char*      csgetvalue(char *netroot, char *attr, char *val,
                     char *rattr, Ndbtuple **tp)

          char*      ipattr(char *name)

          void       mkptrname(char *ip, char *rip, int rlen);

          Ndbtuple*  ndbgetipaddr(Ndb *db, char *sys);

          Ndbtuple*  ndbipinfo(Ndb *db, char *attr, char *val, char
                     int nattr)

          Ndbtuple*  csipinfo(char *netroot, char *attr, char *val,
                     char **attrs, int nattr)

          ulong      ndbhash(char *val, int hlen)

     NDB(2)                                                     NDB(2)

          Ndbtuple*  ndbparse(Ndb *db)

          Ndbtuple*  dnsquery(char *netroot, char *domainname, char

          Ndbtuple*  ndbfindattr(Ndbtuple *entry, Ndbtuple *line, char

          void       ndbfree(Ndbtuple *db)

          Ndbtuple*  ndbdiscard(Ndbtuple  *t, Ndbtuple *a)

          Ndbtuple*  ndbconcatenate(Ndbtuple *a, Ndbtuple *b)

          Ndbtuple*  ndbreorder(Ndbtuple *t, Ndbtuple *a)

          Ndbtuple*  ndbsubstitute(Ndbtuple *t, Ndbtuple *from, Ndbtu-
          ple *to)

          Ndbtuple*  ndbdedup(Ndbtuple *t)

          void       ndbsetmalloctag(Ndbtuple *t, uintptr tag)

          int        ndbvalfmt(Fmt*)

          These routines are used by network administrative programs
          to search the network database.  They operate on the data-
          base files described in ndb(6).

          Ndbopen opens the database file and calls malloc(2) to allo-
          cate a buffer for it.  If file is zero, all network database
          files are opened.

          Ndbcat concatenates two open databases.  Either argument may
          be nil.

          Ndbreopen throws out any cached information for the database
          files associated with db and reopens the files.

          Ndbclose closes any database files associated with db and
          frees all storage associated with them.

          Ndbsearch and ndbsnext search a database for an entry con-
          taining the attribute/value pair, attr=val.  Ndbsearch is
          used to find the first match and ndbsnext is used to find
          each successive match.  On a successful search both return a
          linked list of Ndbtuple structures acquired by malloc(2)
          that represent the attribute/value pairs in the entry.  On
          failure they return zero.

               typedef struct Ndbtuple Ndbtuple;

     NDB(2)                                                     NDB(2)

               struct Ndbtuple {
                       char      attr[Ndbalen];
                       char      *val;
                       Ndbtuple  *entry;
                       Ndbtuple  *line;
                       ulong     ptr;    /* for the application; starts 0 */
                       char      valbuf[Ndbvlen];  /* initial allocation for val */

          The entry pointers chain together all pairs in the entry in
          a null-terminated list.  The line pointers chain together
          all pairs on the same line in a circular list.  Thus, a pro-
          gram can implement 2 levels of binding for pairs in an
          entry.  In general, pairs on the same line are bound tighter
          than pairs on different lines.

          The argument s of ndbsearch has type Ndbs and should be
          pointed to valid storage before calling ndbsearch, which
          will fill it with information used by ndbsnext to link suc-
          cessive searches.  The structure Ndbs looks like:

               typedef struct Ndbs Ndbs;
               struct Ndbs {
                       Ndb      *db;   /* data base file being searched */
                       Ndbtuple *t;    /* last attribute value pair found */

          The t field points to the pair within the entry matched by
          the ndbsearch or ndbsnext.

          Ndbgetvalue searches the database for an entry containing
          not only an attribute/value pair, attr=val, but also a pair
          with the attribute rattr. If successful, it returns a mal-
          loced copy of the NUL-terminated value associated with
          rattr. If tp is non nil, *tp will point to the entry.  Oth-
          erwise the entry will be freed.

          Csgetvalue is like ndbgetvalue but queries the connection
          server instead of looking directly at the database.  Its
          first argument specifies the network root to use.  If the
          argument is 0, it defaults to "/net".

          Ndbfree frees a list of tuples returned by one of the other

          Ipattr takes the name of an IP system and returns the
          attribute it corresponds to:

               dom  domain name

               ip   Internet number

     NDB(2)                                                     NDB(2)

               sys  system name

          Mkptrname converts the address string ip to a reverse lookup
          domain-name, returned in rip. The rlen argument gives the
          maximum size of the rip buffer including the NUL-terminator.
          If ip already is a reverse lookup domain-name or has invalid
          ip address syntax, then ip is copied into rip verbatim.

          Ndbgetipaddr looks in db for entries matching sys as the
          value of a sys= or dom= attribute/value pair and returns all
          IP addresses.  If sys is already an IP address, a tuple con-
          taining just that address is returned.

          Ndbipinfo looks up Internet protocol information about a
          system.  This is an IP aware search.  It looks first for
          information in the system's database entry and then in the
          database entries for any IP subnets or networks containing
          the system.  The system is identified by the attribute/value
          pair, attr=val.  Ndbipinfo returns a list of tuples whose
          attributes match the attributes in the n element array
          attrs. If any attrs begin with `@', the `@' is excluded from
          the attribute name, but causes any corresponding value
          returned to be a resolved IP address(es), not a name.  For
          example, consider the following database entries describing
          a network, a subnetwork, and a system.

               ipnet=big ip=
               ipnet=dept ip= ipmask=


               ndbipinfo(db, "dom", "", ["bootf" "smtp" "dns"], 3)

          will return the tuples bootf=/386/9pc,,

          Csipinfo is to ndbipinfo as csgetvalue is to ndbgetvalue.

          The next three routines are used by programs that create the
          hash tables and database files.  Ndbhash computes a hash
          offset into a table of length hlen for the string val.
          Ndbparse reads and parses the next entry from the database
          file.  Multiple calls to ndbparse parse sequential entries
          in the database file.  A zero is returned at end of file.

          Dnsquery submits a query about domainname to the ndb/dns
          mounted at netroot/dns.  It returns a linked list of

     NDB(2)                                                     NDB(2)

          Ndbtuple's representing a single database entry.  The tuples
          are logically arranged into lines using the line field in
          the structure.  The possible type's of query are the
          attributes on each returned tuple line:

          ip   find the IP addresses.  Returns domain name (dom) and
               ip address (ip).

          ipv6 find the IPv6 addresses.  Returns domain name (dom) and
               ipv6 address (ip).

          mx   look up the mail exchangers.  Returns preference (pref)
               and exchanger (mx).

          ptr  do a reverse query.  Here domainname must be an ASCII
               IP address.  Returns reverse name (ptr) and domain name

               get the system that this name is a nickname for.
               Returns the nickname (dom) and the real name (cname).

          soa  return the start of area record for this field.
               Returns area name (dom), primary name server (ns),
               serial number (serial), refresh time in seconds
               (refresh), retry time in seconds (retry), expiration
               time in seconds (expire), and minimum time to lie

          srv  get the service records.  Returns the priority of tar-
               get host (pri), relative weight (weight) for entries
               with the same priority, port on this target host of
               this service (port), and the domain name of the target
               host (target).

          txt  get the descriptive text.  The semantics of the text
               depends on the domain.

          ns   name servers.  Returns domain name (dom) and name
               server (ns).

          caa  get the certificate authority records.  Returns the
               (tag) and (flags).

          Ndbfindattr searches entry for the tuple with attribute attr
          and returns a pointer to the tuple.  If line points to a
          particular line in the entry, the search starts there and
          then wraps around to the beginning of the entry.

          All of the routines provided to search the database provide
          an always consistent view of the relevant files.  However,
          it may be advantageous for an application to read in the

     NDB(2)                                                     NDB(2)

          whole database using ndbopen and ndbparse and provide its
          own search routines.  The ndbchanged routine can be used by
          the application to periodically check for changes.  It
          returns zero if none of the files comprising the database
          have changes and non-zero if they have.

          Finally, a number of routines are provided for manipulating

          Ndbdiscard removes attr/val pair a from tuple t and frees
          it.  If a isn't in t it is just freed.

          Ndbconcatenate concatenates two tuples and returns the
          result.  Either or both tuples may be nil.

          Ndbreorder reorders a tuple t to make the line containing
          attr/val pair a first in the entry and making a first in its

          Ndbsubstitute replaces a single attr/val pair from in t with
          the tuple to. All attr/val pairs in to end up on the same
          line.  from is freed.

          Ndbdedup removes duplicate attr/val pairs from tuple list t.

          Ndbsetmalloctag sets the malloc tag (see setmalloctag in
          malloc(2)) of each tuple in the list t to tag.

          Ndbvalfmt formats a char* string of a Ndbtuple val, adding "
          quoting if necessary.  It is typically enabled by calling:

               fmtinstall('$', ndbvalfmt);

          And then used like:

               Ndbtuple *t = ...
               print("%s=%$", t->attr, t->val);

          /lib/ndb    directory of network database files


          ndb(6), ndb(8)