s390 specific implementations.
[kopensolaris-gnu/glibc.git] / resolv / res_debug.c
index bb314bc..f4e9169 100644 (file)
@@ -1,9 +1,7 @@
 /*
 /*
- * ++Copyright++ 1985, 1990, 1993
- * -
- * Copyright (c) 1985, 1990, 1993
+ * Copyright (c) 1985
  *    The Regents of the University of California.  All rights reserved.
  *    The Regents of the University of California.  All rights reserved.
- *
+ * 
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *     This product includes software developed by the University of
- *     California, Berkeley and its contributors.
  * 4. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  * 4. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
- *
+ * 
  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
- * -
+ */
+
+/*
  * Portions Copyright (c) 1993 by Digital Equipment Corporation.
  * Portions Copyright (c) 1993 by Digital Equipment Corporation.
- *
+ * 
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
  * copyright notice and this permission notice appear in all copies, and that
  * the name of Digital Equipment Corporation not be used in advertising or
  * publicity pertaining to distribution of the document or software without
  * specific, written prior permission.
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
  * copyright notice and this permission notice appear in all copies, and that
  * the name of Digital Equipment Corporation not be used in advertising or
  * publicity pertaining to distribution of the document or software without
  * specific, written prior permission.
- *
+ * 
  * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
  * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
  * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
  * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
  * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
  * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
@@ -49,7 +45,9 @@
  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  * SOFTWARE.
  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  * SOFTWARE.
- * -
+ */
+
+/*
  * Portions Copyright (c) 1995 by International Business Machines, Inc.
  *
  * International Business Machines, Inc. (hereinafter called IBM) grants
  * Portions Copyright (c) 1995 by International Business Machines, Inc.
  *
  * International Business Machines, Inc. (hereinafter called IBM) grants
  * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
  * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
  * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
  * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
- * --Copyright--
+ */
+
+/*
+ * Portions Copyright (c) 1996-1999 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
  */
 
 #if defined(LIBC_SCCS) && !defined(lint)
  */
 
 #if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)res_debug.c        8.1 (Berkeley) 6/4/93";
-static char rcsid[] = "$Id$";
+static const char sccsid[] = "@(#)res_debug.c  8.1 (Berkeley) 6/4/93";
+static const char rcsid[] = "$BINDId: res_debug.c,v 8.34 2000/02/29 05:30:55 vixie Exp $";
 #endif /* LIBC_SCCS and not lint */
 
 #endif /* LIBC_SCCS and not lint */
 
-#include <sys/param.h>
 #include <sys/types.h>
 #include <sys/types.h>
+#include <sys/param.h>
 #include <sys/socket.h>
 #include <sys/socket.h>
+
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <arpa/nameser.h>
 
 #include <ctype.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <arpa/nameser.h>
 
 #include <ctype.h>
+#include <errno.h>
+#include <math.h>
 #include <netdb.h>
 #include <resolv.h>
 #include <stdio.h>
 #include <netdb.h>
 #include <resolv.h>
 #include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 #include <time.h>
 
 #include <time.h>
 
-#if defined(BSD) && (BSD >= 199103) && defined(AF_INET6)
-# include <stdlib.h>
-# include <string.h>
+#ifdef SPRINTF_CHAR
+# define SPRINTF(x) strlen(sprintf/**/x)
 #else
 #else
-# include "../conf/portability.h"
-#endif
-
-#if defined(USE_OPTIONS_H)
-# include "../conf/options.h"
+# define SPRINTF(x) sprintf x
 #endif
 
 extern const char *_res_opcodes[];
 #endif
 
 extern const char *_res_opcodes[];
-extern const char *_res_resultcodes[];
+extern const char *_res_sectioncodes[];
 
 
-/* XXX: we should use getservbyport() instead. */
-static const char *
-dewks(wks)
-       int wks;
-{
-       static char nbuf[20];
-
-       switch (wks) {
-       case 5: return "rje";
-       case 7: return "echo";
-       case 9: return "discard";
-       case 11: return "systat";
-       case 13: return "daytime";
-       case 15: return "netstat";
-       case 17: return "qotd";
-       case 19: return "chargen";
-       case 20: return "ftp-data";
-       case 21: return "ftp";
-       case 23: return "telnet";
-       case 25: return "smtp";
-       case 37: return "time";
-       case 39: return "rlp";
-       case 42: return "name";
-       case 43: return "whois";
-       case 53: return "domain";
-       case 57: return "apts";
-       case 59: return "apfs";
-       case 67: return "bootps";
-       case 68: return "bootpc";
-       case 69: return "tftp";
-       case 77: return "rje";
-       case 79: return "finger";
-       case 87: return "link";
-       case 95: return "supdup";
-       case 100: return "newacct";
-       case 101: return "hostnames";
-       case 102: return "iso-tsap";
-       case 103: return "x400";
-       case 104: return "x400-snd";
-       case 105: return "csnet-ns";
-       case 109: return "pop-2";
-       case 111: return "sunrpc";
-       case 113: return "auth";
-       case 115: return "sftp";
-       case 117: return "uucp-path";
-       case 119: return "nntp";
-       case 121: return "erpc";
-       case 123: return "ntp";
-       case 133: return "statsrv";
-       case 136: return "profile";
-       case 144: return "NeWS";
-       case 161: return "snmp";
-       case 162: return "snmp-trap";
-       case 170: return "print-srv";
-       default: (void) sprintf(nbuf, "%d", wks); return (nbuf);
-       }
-}
+/*
+ * Print the current options.
+ */
+void
+fp_resstat(const res_state statp, FILE *file) {
+       u_long mask;
 
 
-/* XXX: we should use getprotobynumber() instead. */
-static const char *
-deproto(protonum)
-       int protonum;
-{
-       static char nbuf[20];
-
-       switch (protonum) {
-       case 1: return "icmp";
-       case 2: return "igmp";
-       case 3: return "ggp";
-       case 5: return "st";
-       case 6: return "tcp";
-       case 7: return "ucl";
-       case 8: return "egp";
-       case 9: return "igp";
-       case 11: return "nvp-II";
-       case 12: return "pup";
-       case 16: return "chaos";
-       case 17: return "udp";
-       default: (void) sprintf(nbuf, "%d", protonum); return (nbuf);
-       }
+       fprintf(file, ";; res options:");
+       for (mask = 1;  mask != 0;  mask <<= 1)
+               if (statp->options & mask)
+                       fprintf(file, " %s", p_option(mask));
+       putc('\n', file);
 }
 
 }
 
-static const u_char *
-do_rrset(msg, len, cp, cnt, pflag, file, hs)
-       int cnt, pflag, len;
-       const u_char *cp, *msg;
-       const char *hs;
-       FILE *file;
+static void
+do_section(const res_state statp,
+          ns_msg *handle, ns_sect section,
+          int pflag, FILE *file)
 {
 {
-       int n;
-       int sflag;
+       int n, sflag, rrnum;
+       static int buflen = 2048;
+       char *buf;
+       ns_opcode opcode;
+       ns_rr rr;
 
        /*
         * Print answer records.
         */
 
        /*
         * Print answer records.
         */
-       sflag = (_res.pfcode & pflag);
-       if (n = ntohs(cnt)) {
-               if ((!_res.pfcode) ||
-                   ((sflag) && (_res.pfcode & RES_PRF_HEAD1)))
-                       fprintf(file, hs);
-               while (--n >= 0) {
-                       if ((!_res.pfcode) || sflag) {
-                               cp = p_rr(cp, msg, file);
-                       } else {
-                               unsigned int dlen;
-                               cp += __dn_skipname(cp, cp + MAXCDNAME);
-                               cp += INT16SZ;
-                               cp += INT16SZ;
-                               cp += INT32SZ;
-                               dlen = _getshort((u_char*)cp);
-                               cp += INT16SZ;
-                               cp += dlen;
+       sflag = (statp->pfcode & pflag);
+       if (statp->pfcode && !sflag)
+               return;
+
+       buf = malloc(buflen);
+       if (buf == NULL) {
+               fprintf(file, ";; memory allocation failure\n");
+               return;
+       }
+
+       opcode = (ns_opcode) ns_msg_getflag(*handle, ns_f_opcode);
+       rrnum = 0;
+       for (;;) {
+               if (ns_parserr(handle, section, rrnum, &rr)) {
+                       if (errno != ENODEV)
+                               fprintf(file, ";; ns_parserr: %s\n",
+                                       strerror(errno));
+                       else if (rrnum > 0 && sflag != 0 &&
+                                (statp->pfcode & RES_PRF_HEAD1))
+                               putc('\n', file);
+                       goto cleanup;
+               }
+               if (rrnum == 0 && sflag != 0 && (statp->pfcode & RES_PRF_HEAD1))
+                       fprintf(file, ";; %s SECTION:\n",
+                               p_section(section, opcode));
+               if (section == ns_s_qd)
+                       fprintf(file, ";;\t%s, type = %s, class = %s\n",
+                               ns_rr_name(rr),
+                               p_type(ns_rr_type(rr)),
+                               p_class(ns_rr_class(rr)));
+               else {
+                       n = ns_sprintrr(handle, &rr, NULL, NULL,
+                                       buf, buflen);
+                       if (n < 0) {
+                               if (errno == ENOSPC) {
+                                       free(buf);
+                                       buf = NULL;
+                                       if (buflen < 131072)
+                                               buf = malloc(buflen += 1024);
+                                       if (buf == NULL) {
+                                               fprintf(file,
+                                             ";; memory allocation failure\n");
+                                             return;
+                                       }
+                                       continue;
+                               }
+                               fprintf(file, ";; ns_sprintrr: %s\n",
+                                       strerror(errno));
+                               goto cleanup;
                        }
                        }
-                       if ((cp - msg) > len)
-                               return (NULL);
+                       fputs(buf, file);
+                       fputc('\n', file);
                }
                }
-               if ((!_res.pfcode) ||
-                   ((sflag) && (_res.pfcode & RES_PRF_HEAD1)))
-                       putc('\n', file);
+               rrnum++;
        }
        }
-       return (cp);
-}
-
-void
-__p_query(msg)
-       const u_char *msg;
-{
-       __fp_query(msg, stdout);
-}
-
-#ifdef ultrix
-/* ultrix 4.0's packaging has some icky packaging.  alias for it here.
- * there is more junk of this kind over in res_comp.c.
- */
-void
-p_query(msg)
-       const u_char *msg;
-{
-       __p_query(msg);
-}
-#endif
-
-/*
- * Print the current options.
- * This is intended to be primarily a debugging routine.
- */
-void
-__fp_resstat(statp, file)
-       struct __res_state *statp;
-       FILE *file;
-{
-       register u_long mask;
-
-       fprintf(file, ";; res options:");
-       if (!statp)
-               statp = &_res;
-       for (mask = 1;  mask != 0;  mask <<= 1)
-               if (statp->options & mask)
-                       fprintf(file, " %s", p_option(mask));
-       putc('\n', file);
+ cleanup:
+       if (buf != NULL)
+               free(buf);
 }
 
 /*
 }
 
 /*
@@ -274,147 +214,79 @@ __fp_resstat(statp, file)
  * This is intended to be primarily a debugging routine.
  */
 void
  * This is intended to be primarily a debugging routine.
  */
 void
-__fp_nquery(msg, len, file)
-       const u_char *msg;
-       int len;
-       FILE *file;
-{
-       register const u_char *cp, *endMark;
-       register const HEADER *hp;
-       register int n;
+res_pquery(const res_state statp, const u_char *msg, int len, FILE *file) {
+       ns_msg handle;
+       int qdcount, ancount, nscount, arcount;
+       u_int opcode, rcode, id;
 
 
-       if ((_res.options & RES_INIT) == 0 && res_init() == -1)
+       if (ns_initparse(msg, len, &handle) < 0) {
+               fprintf(file, ";; ns_initparse: %s\n", strerror(errno));
                return;
                return;
-
-#define TruncTest(x) if (x >= endMark) goto trunc
-#define        ErrorTest(x) if (x == NULL) goto error
+       }
+       opcode = ns_msg_getflag(handle, ns_f_opcode);
+       rcode = ns_msg_getflag(handle, ns_f_rcode);
+       id = ns_msg_id(handle);
+       qdcount = ns_msg_count(handle, ns_s_qd);
+       ancount = ns_msg_count(handle, ns_s_an);
+       nscount = ns_msg_count(handle, ns_s_ns);
+       arcount = ns_msg_count(handle, ns_s_ar);
 
        /*
         * Print header fields.
         */
 
        /*
         * Print header fields.
         */
-       hp = (HEADER *)msg;
-       cp = msg + HFIXEDSZ;
-       endMark = cp + len;
-       if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEADX) || hp->rcode) {
-               fprintf(file, ";; ->>HEADER<<- opcode: %s, status: %s, id: %d",
-                       _res_opcodes[hp->opcode],
-                       _res_resultcodes[hp->rcode],
-                       ntohs(hp->id));
-               putc('\n', file);
-       }
-       if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEADX))
+       if ((!statp->pfcode) || (statp->pfcode & RES_PRF_HEADX) || rcode)
+               fprintf(file,
+                       ";; ->>HEADER<<- opcode: %s, status: %s, id: %d\n",
+                       _res_opcodes[opcode], p_rcode(rcode), id);
+       if ((!statp->pfcode) || (statp->pfcode & RES_PRF_HEADX))
                putc(';', file);
                putc(';', file);
-       if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD2)) {
+       if ((!statp->pfcode) || (statp->pfcode & RES_PRF_HEAD2)) {
                fprintf(file, "; flags:");
                fprintf(file, "; flags:");
-               if (hp->qr)
+               if (ns_msg_getflag(handle, ns_f_qr))
                        fprintf(file, " qr");
                        fprintf(file, " qr");
-               if (hp->aa)
+               if (ns_msg_getflag(handle, ns_f_aa))
                        fprintf(file, " aa");
                        fprintf(file, " aa");
-               if (hp->tc)
+               if (ns_msg_getflag(handle, ns_f_tc))
                        fprintf(file, " tc");
                        fprintf(file, " tc");
-               if (hp->rd)
+               if (ns_msg_getflag(handle, ns_f_rd))
                        fprintf(file, " rd");
                        fprintf(file, " rd");
-               if (hp->ra)
+               if (ns_msg_getflag(handle, ns_f_ra))
                        fprintf(file, " ra");
                        fprintf(file, " ra");
-               if (hp->unused)
-                       fprintf(file, " UNUSED-BIT-ON");
-               if (hp->ad)
+               if (ns_msg_getflag(handle, ns_f_z))
+                       fprintf(file, " ??");
+               if (ns_msg_getflag(handle, ns_f_ad))
                        fprintf(file, " ad");
                        fprintf(file, " ad");
-               if (hp->cd)
+               if (ns_msg_getflag(handle, ns_f_cd))
                        fprintf(file, " cd");
        }
                        fprintf(file, " cd");
        }
-       if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD1)) {
-               fprintf(file, "; Ques: %d", ntohs(hp->qdcount));
-               fprintf(file, ", Ans: %d", ntohs(hp->ancount));
-               fprintf(file, ", Auth: %d", ntohs(hp->nscount));
-               fprintf(file, ", Addit: %d", ntohs(hp->arcount));
+       if ((!statp->pfcode) || (statp->pfcode & RES_PRF_HEAD1)) {
+               fprintf(file, "; %s: %d",
+                       p_section(ns_s_qd, opcode), qdcount);
+               fprintf(file, ", %s: %d",
+                       p_section(ns_s_an, opcode), ancount);
+               fprintf(file, ", %s: %d",
+                       p_section(ns_s_ns, opcode), nscount);
+               fprintf(file, ", %s: %d",
+                       p_section(ns_s_ar, opcode), arcount);
        }
        }
-       if ((!_res.pfcode) || (_res.pfcode &
+       if ((!statp->pfcode) || (statp->pfcode & 
                (RES_PRF_HEADX | RES_PRF_HEAD2 | RES_PRF_HEAD1))) {
                putc('\n',file);
        }
        /*
                (RES_PRF_HEADX | RES_PRF_HEAD2 | RES_PRF_HEAD1))) {
                putc('\n',file);
        }
        /*
-        * Print question records.
+        * Print the various sections.
         */
         */
-       if (n = ntohs(hp->qdcount)) {
-               if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
-                       fprintf(file, ";; QUESTIONS:\n");
-               while (--n >= 0) {
-                       if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
-                               fprintf(file, ";;\t");
-                       TruncTest(cp);
-                       if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
-                               cp = p_cdnname(cp, msg, len, file);
-                       else {
-                               int n;
-                               char name[MAXDNAME];
-
-                               if ((n = dn_expand(msg, msg+len, cp, name,
-                                               sizeof name)) < 0)
-                                       cp = NULL;
-                               else
-                                       cp += n;
-                       }
-                       ErrorTest(cp);
-                       TruncTest(cp);
-                       if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
-                               fprintf(file, ", type = %s",
-                                       __p_type(_getshort((u_char*)cp)));
-                       cp += INT16SZ;
-                       TruncTest(cp);
-                       if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
-                               fprintf(file, ", class = %s\n",
-                                       __p_class(_getshort((u_char*)cp)));
-                       cp += INT16SZ;
-                       if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
-                               putc('\n', file);
-               }
-       }
-       /*
-        * Print authoritative answer records
-        */
-       TruncTest(cp);
-       cp = do_rrset(msg, len, cp, hp->ancount, RES_PRF_ANS, file,
-                     ";; ANSWERS:\n");
-       ErrorTest(cp);
-
-       /*
-        * print name server records
-        */
-       TruncTest(cp);
-       cp = do_rrset(msg, len, cp, hp->nscount, RES_PRF_AUTH, file,
-                     ";; AUTHORITY RECORDS:\n");
-       ErrorTest(cp);
-
-       TruncTest(cp);
-       /*
-        * print additional records
-        */
-       cp = do_rrset(msg, len, cp, hp->arcount, RES_PRF_ADD, file,
-                     ";; ADDITIONAL RECORDS:\n");
-       ErrorTest(cp);
-       return;
- trunc:
-       fprintf(file, "\n;; ...truncated\n");
-       return;
- error:
-       fprintf(file, "\n;; ...malformed\n");
-}
-
-void
-__fp_query(msg, file)
-       const u_char *msg;
-       FILE *file;
-{
-       fp_nquery(msg, PACKETSZ, file);
+       do_section(statp, &handle, ns_s_qd, RES_PRF_QUES, file);
+       do_section(statp, &handle, ns_s_an, RES_PRF_ANS, file);
+       do_section(statp, &handle, ns_s_ns, RES_PRF_AUTH, file);
+       do_section(statp, &handle, ns_s_ar, RES_PRF_ADD, file);
+       if (qdcount == 0 && ancount == 0 &&
+           nscount == 0 && arcount == 0)
+               putc('\n', file);
 }
 
 const u_char *
 }
 
 const u_char *
-__p_cdnname(cp, msg, len, file)
-       const u_char *cp, *msg;
-       int len;
-       FILE *file;
-{
+p_cdnname(const u_char *cp, const u_char *msg, int len, FILE *file) {
        char name[MAXDNAME];
        int n;
 
        char name[MAXDNAME];
        int n;
 
@@ -428,19 +300,15 @@ __p_cdnname(cp, msg, len, file)
 }
 
 const u_char *
 }
 
 const u_char *
-__p_cdname(cp, msg, file)
-       const u_char *cp, *msg;
-       FILE *file;
-{
+p_cdname(const u_char *cp, const u_char *msg, FILE *file) {
        return (p_cdnname(cp, msg, PACKETSZ, file));
 }
 
        return (p_cdnname(cp, msg, PACKETSZ, file));
 }
 
-
 /* Return a fully-qualified domain name from a compressed name (with
    length supplied).  */
 
 const u_char *
 /* Return a fully-qualified domain name from a compressed name (with
    length supplied).  */
 
 const u_char *
-__p_fqnname(cp, msg, msglen, name, namelen)
+p_fqnname(cp, msg, msglen, name, namelen)
        const u_char *cp, *msg;
        int msglen;
        char *name;
        const u_char *cp, *msg;
        int msglen;
        char *name;
@@ -450,27 +318,24 @@ __p_fqnname(cp, msg, msglen, name, namelen)
 
        if ((n = dn_expand(msg, cp + msglen, cp, name, namelen)) < 0)
                return (NULL);
 
        if ((n = dn_expand(msg, cp + msglen, cp, name, namelen)) < 0)
                return (NULL);
-       newlen = strlen (name);
-       if (newlen == 0 || name[newlen - 1] != '.')
-               if (newlen+1 >= namelen)        /* Lack space for final dot */
+       newlen = strlen(name);
+       if (newlen == 0 || name[newlen - 1] != '.') {
+               if (newlen + 1 >= namelen)      /* Lack space for final dot */
                        return (NULL);
                else
                        strcpy(name + newlen, ".");
                        return (NULL);
                else
                        strcpy(name + newlen, ".");
+       }
        return (cp + n);
 }
 
        return (cp + n);
 }
 
-/* XXX:        the rest of these functions need to become length-limited, too. (vix)
- */
+/* XXX:        the rest of these functions need to become length-limited, too. */
 
 const u_char *
 
 const u_char *
-__p_fqname(cp, msg, file)
-       const u_char *cp, *msg;
-       FILE *file;
-{
+p_fqname(const u_char *cp, const u_char *msg, FILE *file) {
        char name[MAXDNAME];
        const u_char *n;
 
        char name[MAXDNAME];
        const u_char *n;
 
-       n = __p_fqnname(cp, msg, MAXCDNAME, name, sizeof name);
+       n = p_fqnname(cp, msg, MAXCDNAME, name, sizeof name);
        if (n == NULL)
                return (NULL);
        fputs(name, file);
        if (n == NULL)
                return (NULL);
        fputs(name, file);
@@ -478,363 +343,6 @@ __p_fqname(cp, msg, file)
 }
 
 /*
 }
 
 /*
- * Print resource record fields in human readable form.
- */
-const u_char *
-__p_rr(cp, msg, file)
-       const u_char *cp, *msg;
-       FILE *file;
-{
-       int type, class, dlen, n, c;
-       struct in_addr inaddr;
-       const u_char *cp1, *cp2;
-       u_int32_t tmpttl, t;
-       int lcnt;
-       u_int16_t keyflags;
-       char rrname[MAXDNAME];          /* The fqdn of this RR */
-       char base64_key[MAX_KEY_BASE64];
-
-       if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
-               h_errno = NETDB_INTERNAL;
-               return (NULL);
-       }
-       cp = __p_fqnname(cp, msg, MAXCDNAME, rrname, sizeof rrname);
-       if (!cp)
-               return (NULL);                  /* compression error */
-       fputs(rrname, file);
-
-       type = _getshort((u_char*)cp);
-       cp += INT16SZ;
-       class = _getshort((u_char*)cp);
-       cp += INT16SZ;
-       tmpttl = _getlong((u_char*)cp);
-       cp += INT32SZ;
-       dlen = _getshort((u_char*)cp);
-       cp += INT16SZ;
-       cp1 = cp;
-       if ((!_res.pfcode) || (_res.pfcode & RES_PRF_TTLID))
-               fprintf(file, "\t%lu", (u_long)tmpttl);
-       if ((!_res.pfcode) || (_res.pfcode & RES_PRF_CLASS))
-               fprintf(file, "\t%s", __p_class(class));
-       fprintf(file, "\t%s", __p_type(type));
-       /*
-        * Print type specific data, if appropriate
-        */
-       switch (type) {
-       case T_A:
-               switch (class) {
-               case C_IN:
-               case C_HS:
-                       bcopy(cp, (char *)&inaddr, INADDRSZ);
-                       if (dlen == 4) {
-                               fprintf(file, "\t%s", inet_ntoa(inaddr));
-                               cp += dlen;
-                       } else if (dlen == 7) {
-                               char *address;
-                               u_char protocol;
-                               u_short port;
-
-                               address = inet_ntoa(inaddr);
-                               cp += INADDRSZ;
-                               protocol = *(u_char*)cp;
-                               cp += sizeof (u_char);
-                               port = _getshort((u_char*)cp);
-                               cp += INT16SZ;
-                               fprintf(file, "\t%s\t; proto %d, port %d",
-                                       address, protocol, port);
-                       }
-                       break;
-               default:
-                       cp += dlen;
-               }
-               break;
-       case T_CNAME:
-       case T_MB:
-       case T_MG:
-       case T_MR:
-       case T_NS:
-       case T_PTR:
-               putc('\t', file);
-               if ((cp = p_fqname(cp, msg, file)) == NULL)
-                       return (NULL);
-               break;
-
-       case T_HINFO:
-       case T_ISDN:
-               cp2 = cp + dlen;
-               (void) fputs("\t\"", file);
-               if ((n = (unsigned char) *cp++) != 0) {
-                       for (c = n; c > 0 && cp < cp2; c--) {
-                               if (strchr("\n\"\\", *cp))
-                                       (void) putc('\\', file);
-                               (void) putc(*cp++, file);
-                       }
-               }
-               putc('"', file);
-               if (cp < cp2 && (n = (unsigned char) *cp++) != 0) {
-                       (void) fputs ("\t\"", file);
-                       for (c = n; c > 0 && cp < cp2; c--) {
-                               if (strchr("\n\"\\", *cp))
-                                       (void) putc('\\', file);
-                               (void) putc(*cp++, file);
-                       }
-                       putc('"', file);
-               } else if (type == T_HINFO) {
-                       (void) fputs("\"?\"", file);
-                       fprintf(file, "\n;; *** Warning *** OS-type missing");
-               }
-               break;
-
-       case T_SOA:
-               putc('\t', file);
-               if ((cp = p_fqname(cp, msg, file)) == NULL)
-                       return (NULL);
-               putc(' ', file);
-               if ((cp = p_fqname(cp, msg, file)) == NULL)
-                       return (NULL);
-               fputs(" (\n", file);
-               t = _getlong((u_char*)cp);  cp += INT32SZ;
-               fprintf(file, "\t\t\t%lu\t; serial\n", (u_long)t);
-               t = _getlong((u_char*)cp);  cp += INT32SZ;
-               fprintf(file, "\t\t\t%lu\t; refresh (%s)\n",
-                       (u_long)t, __p_time(t));
-               t = _getlong((u_char*)cp);  cp += INT32SZ;
-               fprintf(file, "\t\t\t%lu\t; retry (%s)\n",
-                       (u_long)t, __p_time(t));
-               t = _getlong((u_char*)cp);  cp += INT32SZ;
-               fprintf(file, "\t\t\t%lu\t; expire (%s)\n",
-                       (u_long)t, __p_time(t));
-               t = _getlong((u_char*)cp);  cp += INT32SZ;
-               fprintf(file, "\t\t\t%lu )\t; minimum (%s)",
-                       (u_long)t, __p_time(t));
-               break;
-
-       case T_MX:
-       case T_AFSDB:
-       case T_RT:
-               fprintf(file, "\t%d ", _getshort((u_char*)cp));
-               cp += INT16SZ;
-               if ((cp = p_fqname(cp, msg, file)) == NULL)
-                       return (NULL);
-               break;
-
-       case T_PX:
-               fprintf(file, "\t%d ", _getshort((u_char*)cp));
-               cp += INT16SZ;
-               if ((cp = p_fqname(cp, msg, file)) == NULL)
-                       return (NULL);
-               putc(' ', file);
-               if ((cp = p_fqname(cp, msg, file)) == NULL)
-                       return (NULL);
-               break;
-
-       case T_X25:
-               cp2 = cp + dlen;
-               (void) fputs("\t\"", file);
-               if ((n = (unsigned char) *cp++) != 0) {
-                       for (c = n; c > 0 && cp < cp2; c--) {
-                               if (strchr("\n\"\\", *cp))
-                                       (void) putc('\\', file);
-                               (void) putc(*cp++, file);
-                       }
-               }
-               putc('"', file);
-               break;
-
-       case T_TXT:
-               (void) putc('\t', file);
-               cp2 = cp1 + dlen;
-               while (cp < cp2) {
-                       putc('"', file);
-                       if (n = (unsigned char) *cp++) {
-                               for (c = n; c > 0 && cp < cp2; c--) {
-                                       if (strchr("\n\"\\", *cp))
-                                               (void) putc('\\', file);
-                                       (void) putc(*cp++, file);
-                               }
-                       }
-                       putc('"', file);
-                       if (cp < cp2)
-                               putc(' ', file);
-               }
-               break;
-
-       case T_NSAP:
-               (void) fprintf(file, "\t%s", inet_nsap_ntoa(dlen, cp, NULL));
-               cp += dlen;
-               break;
-
-       case T_AAAA: {
-               char t[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"];
-
-               fprintf(file, "\t%s\n", inet_ntop(AF_INET6, cp, t, sizeof t));
-               cp += dlen;
-               break;
-       }
-
-       case T_LOC: {
-               char t[255];
-
-               (void) fprintf(file, "\t%s\n", loc_ntoa(cp, t));
-               cp += dlen;
-               break;
-       }
-
-       case T_MINFO:
-       case T_RP:
-               putc('\t', file);
-               if ((cp = p_fqname(cp, msg, file)) == NULL)
-                       return (NULL);
-               putc(' ', file);
-               if ((cp = p_fqname(cp, msg, file)) == NULL)
-                       return (NULL);
-               break;
-
-       case T_UINFO:
-               putc('\t', file);
-               fputs((char *)cp, file);
-               cp += dlen;
-               break;
-
-       case T_UID:
-       case T_GID:
-               if (dlen == 4) {
-                       fprintf(file, "\t%u", _getlong((u_char*)cp));
-                       cp += INT32SZ;
-               }
-               break;
-
-       case T_WKS:
-               if (dlen < INT32SZ + 1)
-                       break;
-               bcopy(cp, (char *)&inaddr, INADDRSZ);
-               cp += INT32SZ;
-               fprintf(file, "\t%s %s ( ",
-                       inet_ntoa(inaddr),
-                       deproto((int) *cp));
-               cp += sizeof (u_char);
-               n = 0;
-               lcnt = 0;
-               while (cp < cp1 + dlen) {
-                       c = *cp++;
-                       do {
-                               if (c & 0200) {
-                                       if (lcnt == 0) {
-                                               fputs("\n\t\t\t", file);
-                                               lcnt = 5;
-                                       }
-                                       fputs(dewks(n), file);
-                                       putc(' ', file);
-                                       lcnt--;
-                               }
-                               c <<= 1;
-                       } while (++n & 07);
-               }
-               putc(')', file);
-               break;
-
-       case T_KEY:
-               putc('\t', file);
-               keyflags = _getshort(cp);
-               cp += 2;
-               fprintf(file,"0x%04x", keyflags );      /* flags */
-               fprintf(file," %u", *cp++);     /* protocol */
-               fprintf(file," %u (", *cp++);   /* algorithm */
-
-               n = b64_ntop(cp, (cp1 + dlen) - cp,
-                            base64_key, sizeof base64_key);
-               for (c = 0; c < n; ++c) {
-                       if (0 == (c & 0x3F))
-                               fprintf(file, "\n\t");
-                       putc(base64_key[c], file);  /* public key data */
-               }
-
-               fprintf(file, " )");
-               if (n < 0)
-                       fprintf(file, "\t; BAD BASE64");
-               fflush(file);
-               cp = cp1 + dlen;
-               break;
-
-       case T_SIG:
-               type = _getshort((u_char*)cp);
-               cp += INT16SZ;
-               fprintf(file, " %s", p_type(type));
-               fprintf(file, "\t%d", *cp++);   /* algorithm */
-               /* Check label value and print error if wrong. */
-               n = *cp++;
-               c = dn_count_labels (rrname);
-               if (n != c)
-                       fprintf(file, "\t; LABELS WRONG (%d should be %d)\n\t",
-                               n, c);
-               /* orig ttl */
-               n = _getlong((u_char*)cp);
-               if (n != tmpttl)
-                       fprintf(file, " %u", n);
-               cp += INT32SZ;
-               /* sig expire */
-               fprintf(file, " (\n\t%s",
-                       __p_secstodate(_getlong((u_char*)cp)));
-               cp += INT32SZ;
-               /* time signed */
-               fprintf(file, " %s", __p_secstodate(_getlong((u_char*)cp)));
-               cp += INT32SZ;
-               /* sig footprint */
-               fprintf(file," %u ", _getshort((u_char*)cp));
-               cp += INT16SZ;
-               /* signer's name */
-               cp = p_fqname(cp, msg, file);
-               n = b64_ntop(cp, (cp1 + dlen) - cp,
-                            base64_key, sizeof base64_key);
-               for (c = 0; c < n; c++) {
-                       if (0 == (c & 0x3F))
-                               fprintf (file, "\n\t");
-                       putc(base64_key[c], file);              /* signature */
-               }
-               /* Clean up... */
-               fprintf(file, " )");
-               if (n < 0)
-                       fprintf(file, "\t; BAD BASE64");
-               fflush(file);
-               cp = cp1+dlen;
-               break;
-
-#ifdef ALLOW_T_UNSPEC
-       case T_UNSPEC:
-               {
-                       int NumBytes = 8;
-                       u_char *DataPtr;
-                       int i;
-
-                       if (dlen < NumBytes) NumBytes = dlen;
-                       fprintf(file, "\tFirst %d bytes of hex data:",
-                               NumBytes);
-                       for (i = 0, DataPtr = cp; i < NumBytes; i++, DataPtr++)
-                               fprintf(file, " %x", *DataPtr);
-                       cp += dlen;
-               }
-               break;
-#endif /* ALLOW_T_UNSPEC */
-
-       default:
-               fprintf(file, "\t?%d?", type);
-               cp += dlen;
-       }
-#if 0
-       fprintf(file, "\t; dlen=%d, ttl %s\n", dlen, __p_time(tmpttl));
-#else
-       putc('\n', file);
-#endif
-       if (cp - cp1 != dlen) {
-               fprintf(file,
-                       ";; packet size error (found %lu, dlen was %d)\n",
-                       (unsigned long) (cp - cp1), dlen);
-               cp = NULL;
-       }
-       return (cp);
-}
-
-/*
  * Names of RR classes and qclasses.  Classes and qclasses are the same, except
  * that C_ANY is a qclass but not a class.  (You can ask for records of class
  * C_ANY, but you can't have any records of that class in the database.)
  * Names of RR classes and qclasses.  Classes and qclasses are the same, except
  * that C_ANY is a qclass but not a class.  (You can ask for records of class
  * C_ANY, but you can't have any records of that class in the database.)
@@ -845,7 +353,45 @@ const struct res_sym __p_class_syms[] = {
        {C_HS,          "HS"},
        {C_HS,          "HESIOD"},
        {C_ANY,         "ANY"},
        {C_HS,          "HS"},
        {C_HS,          "HESIOD"},
        {C_ANY,         "ANY"},
-       {C_IN,          (char *)0}
+       {C_NONE,        "NONE"},
+       {C_IN,          (char *)0}
+};
+
+/*
+ * Names of message sections.
+ */
+const struct res_sym __p_default_section_syms[] = {
+       {ns_s_qd,       "QUERY"},
+       {ns_s_an,       "ANSWER"},
+       {ns_s_ns,       "AUTHORITY"},
+       {ns_s_ar,       "ADDITIONAL"},
+       {0,             (char *)0}
+};
+
+const struct res_sym __p_update_section_syms[] = {
+       {S_ZONE,        "ZONE"},
+       {S_PREREQ,      "PREREQUISITE"},
+       {S_UPDATE,      "UPDATE"},
+       {S_ADDT,        "ADDITIONAL"},
+       {0,             (char *)0}
+};
+
+const struct res_sym __p_key_syms[] = {
+       {NS_ALG_MD5RSA,         "RSA",          "RSA KEY with MD5 hash"},
+       {NS_ALG_DH,             "DH",           "Diffie Hellman"},
+       {NS_ALG_DSA,            "DSA",          "Digital Signature Algorithm"},
+       {NS_ALG_EXPIRE_ONLY,    "EXPIREONLY",   "No algorithm"},
+       {NS_ALG_PRIVATE_OID,    "PRIVATE",      "Algorithm obtained from OID"},
+       {0,                     NULL,           NULL}
+};
+
+const struct res_sym __p_cert_syms[] = {
+       {cert_t_pkix,   "PKIX",         "PKIX (X.509v3) Certificate"},
+       {cert_t_spki,   "SPKI",         "SPKI certificate"},
+       {cert_t_pgp,    "PGP",          "PGP certificate"},
+       {cert_t_url,    "URL",          "URL Private"},
+       {cert_t_oid,    "OID",          "OID Private"},
+       {0,             NULL,           NULL}
 };
 
 /*
 };
 
 /*
@@ -854,59 +400,78 @@ const struct res_sym __p_class_syms[] = {
  * T_ANY, but you can't have any records of that type in the database.)
  */
 const struct res_sym __p_type_syms[] = {
  * T_ANY, but you can't have any records of that type in the database.)
  */
 const struct res_sym __p_type_syms[] = {
-       {T_A,           "A",            "address"},
-       {T_NS,          "NS",           "name server"},
-       {T_CNAME,       "CNAME",        "canonical name"},
-       {T_SOA,         "SOA",          "start of authority"},
-       {T_MB,          "MB",           "mailbox"},
-       {T_MG,          "MG",           "mail group member"},
-       {T_MR,          "MR",           "mail rename"},
-       {T_NULL,        "NULL",         "null"},
-       {T_WKS,         "WKS",          "well-known service"},
-       {T_PTR,         "PTR",          "domain name pointer"},
-       {T_HINFO,       "HINFO",        "host information"},
-       {T_MINFO,       "MINFO",        "mailbox information"},
-       {T_MX,          "MX",           "mail exchanger"},
-       {T_TXT,         "TXT",          "text"},
-       {T_RP,          "RP",           "responsible person"},
-       {T_AFSDB,       "AFSDB",        "DCE or AFS server"},
-       {T_X25,         "X25",          "X25 address"},
-       {T_ISDN,        "ISDN",         "ISDN address"},
-       {T_RT,          "RT",           "router"},
-       {T_NSAP,        "NSAP",         "nsap address"},
-       {T_NSAP_PTR,    "NSAP_PTR",     "domain name pointer"},
-       {T_SIG,         "SIG",          "signature"},
-       {T_KEY,         "KEY",          "key"},
-       {T_NXT,         "NXT",          "next valid name"},
-       {T_PX,          "PX",           "mapping information"},
-       {T_GPOS,        "GPOS",         "geographical position"},
-       {T_AAAA,        "AAAA",         "IPv6 address"},
-       {T_LOC,         "LOC",          "location"},
-       {T_AXFR,        "AXFR",         "zone transfer"},
-       {T_MAILB,       "MAILB",        "mailbox-related data"},
-       {T_MAILA,       "MAILA",        "mail agent"},
-       {T_UINFO,       "UINFO",        "user information"},
-       {T_UID,         "UID",          "user ID"},
-       {T_GID,         "GID",          "group ID"},
-#ifdef ALLOW_T_UNSPEC
-       {T_UNSPEC,      "UNSPEC",       "unspecified data"},
-#endif /* ALLOW_T_UNSPEC */
-       {T_ANY,         "ANY",          "\"any\""},
-       {0,             (char *)0,      (char *)0}
+       {ns_t_a,        "A",            "address"},
+       {ns_t_ns,       "NS",           "name server"},
+       {ns_t_md,       "MD",           "mail destination (deprecated)"},
+       {ns_t_mf,       "MF",           "mail forwarder (deprecated)"},
+       {ns_t_cname,    "CNAME",        "canonical name"},
+       {ns_t_soa,      "SOA",          "start of authority"},
+       {ns_t_mb,       "MB",           "mailbox"},
+       {ns_t_mg,       "MG",           "mail group member"},
+       {ns_t_mr,       "MR",           "mail rename"},
+       {ns_t_null,     "NULL",         "null"},
+       {ns_t_wks,      "WKS",          "well-known service (deprecated)"},
+       {ns_t_ptr,      "PTR",          "domain name pointer"},
+       {ns_t_hinfo,    "HINFO",        "host information"},
+       {ns_t_minfo,    "MINFO",        "mailbox information"},
+       {ns_t_mx,       "MX",           "mail exchanger"},
+       {ns_t_txt,      "TXT",          "text"},
+       {ns_t_rp,       "RP",           "responsible person"},
+       {ns_t_afsdb,    "AFSDB",        "DCE or AFS server"},
+       {ns_t_x25,      "X25",          "X25 address"},
+       {ns_t_isdn,     "ISDN",         "ISDN address"},
+       {ns_t_rt,       "RT",           "router"},
+       {ns_t_nsap,     "NSAP",         "nsap address"},
+       {ns_t_nsap_ptr, "NSAP_PTR",     "domain name pointer"},
+       {ns_t_sig,      "SIG",          "signature"},
+       {ns_t_key,      "KEY",          "key"},
+       {ns_t_px,       "PX",           "mapping information"},
+       {ns_t_gpos,     "GPOS",         "geographical position (withdrawn)"},
+       {ns_t_aaaa,     "AAAA",         "IPv6 address"},
+       {ns_t_loc,      "LOC",          "location"},
+       {ns_t_nxt,      "NXT",          "next valid name (unimplemented)"},
+       {ns_t_eid,      "EID",          "endpoint identifier (unimplemented)"},
+       {ns_t_nimloc,   "NIMLOC",       "NIMROD locator (unimplemented)"},
+       {ns_t_srv,      "SRV",          "server selection"},
+       {ns_t_atma,     "ATMA",         "ATM address (unimplemented)"},
+       {ns_t_tsig,     "TSIG",         "transaction signature"},
+       {ns_t_ixfr,     "IXFR",         "incremental zone transfer"},
+       {ns_t_axfr,     "AXFR",         "zone transfer"},
+       {ns_t_zxfr,     "ZXFR",         "compressed zone transfer"},
+       {ns_t_mailb,    "MAILB",        "mailbox-related data (deprecated)"},
+       {ns_t_maila,    "MAILA",        "mail agent (deprecated)"},
+       {ns_t_naptr,    "NAPTR",        "URN Naming Authority"},
+       {ns_t_kx,       "KX",           "Key Exchange"},
+       {ns_t_cert,     "CERT",         "Certificate"},
+       {ns_t_any,      "ANY",          "\"any\""},
+       {0,             NULL,           NULL}
+};
+
+/*
+ * Names of DNS rcodes.
+ */
+const struct res_sym __p_rcode_syms[] = {
+       {ns_r_noerror,  "NOERROR",              "no error"},
+       {ns_r_formerr,  "FORMERR",              "format error"},
+       {ns_r_servfail, "SERVFAIL",             "server failed"},
+       {ns_r_nxdomain, "NXDOMAIN",             "no such domain name"},
+       {ns_r_notimpl,  "NOTIMP",               "not implemented"},
+       {ns_r_refused,  "REFUSED",              "refused"},
+       {ns_r_yxdomain, "YXDOMAIN",             "domain name exists"},
+       {ns_r_yxrrset,  "YXRRSET",              "rrset exists"},
+       {ns_r_nxrrset,  "NXRRSET",              "rrset doesn't exist"},
+       {ns_r_notauth,  "NOTAUTH",              "not authoritative"},
+       {ns_r_notzone,  "NOTZONE",              "Not in zone"},
+       {ns_r_max,      "",                     ""},
+       {ns_r_badsig,   "BADSIG",               "bad signature"},
+       {ns_r_badkey,   "BADKEY",               "bad key"},
+       {ns_r_badtime,  "BADTIME",              "bad time"},
+       {0,             NULL,                   NULL}
 };
 
 int
 };
 
 int
-__sym_ston(syms, name, success)
-       const struct res_sym *syms;
-       char *name;
-       int *success;
-{
-#ifdef _LIBC
-       /* Changed to prevent warning. --drepper@gnu  */
-       for (; syms->name != 0; syms++) {
-#else
-       for (NULL; syms->name != 0; syms++) {
-#endif
+sym_ston(const struct res_sym *syms, const char *name, int *success) {
+       for ((void)NULL; syms->name != 0; syms++) {
                if (strcasecmp (name, syms->name) == 0) {
                        if (success)
                                *success = 1;
                if (strcasecmp (name, syms->name) == 0) {
                        if (success)
                                *success = 1;
@@ -915,23 +480,14 @@ __sym_ston(syms, name, success)
        }
        if (success)
                *success = 0;
        }
        if (success)
                *success = 0;
-       return (syms->number);          /* The default value. */
+       return (syms->number);          /* The default value. */
 }
 
 const char *
 }
 
 const char *
-__sym_ntos(syms, number, success)
-       const struct res_sym *syms;
-       int number;
-       int *success;
-{
+sym_ntos(const struct res_sym *syms, int number, int *success) {
        static char unname[20];
 
        static char unname[20];
 
-#ifdef _LIBC
-       /* Changed to prevent warning. --drepper@gnu  */
-       for (; syms->name != 0; syms++) {
-#else
-       for (NULL; syms->name != 0; syms++) {
-#endif
+       for ((void)NULL; syms->name != 0; syms++) {
                if (number == syms->number) {
                        if (success)
                                *success = 1;
                if (number == syms->number) {
                        if (success)
                                *success = 1;
@@ -939,66 +495,68 @@ __sym_ntos(syms, number, success)
                }
        }
 
                }
        }
 
-       sprintf (unname, "%d", number);
+       sprintf(unname, "%d", number);          /* XXX nonreentrant */
        if (success)
                *success = 0;
        return (unname);
 }
 
        if (success)
                *success = 0;
        return (unname);
 }
 
-
 const char *
 const char *
-__sym_ntop(syms, number, success)
-       const struct res_sym *syms;
-       int number;
-       int *success;
-{
+sym_ntop(const struct res_sym *syms, int number, int *success) {
        static char unname[20];
 
        static char unname[20];
 
-#ifdef _LIBC
-       /* Changed to prevent warning. --drepper@gnu  */
-       for (; syms->name != 0; syms++) {
-#else
-       for (NULL; syms->name != 0; syms++) {
-#endif
+       for ((void)NULL; syms->name != 0; syms++) {
                if (number == syms->number) {
                        if (success)
                                *success = 1;
                        return (syms->humanname);
                }
        }
                if (number == syms->number) {
                        if (success)
                                *success = 1;
                        return (syms->humanname);
                }
        }
-       sprintf(unname, "%d", number);
+       sprintf(unname, "%d", number);          /* XXX nonreentrant */
        if (success)
                *success = 0;
        return (unname);
 }
 
 /*
        if (success)
                *success = 0;
        return (unname);
 }
 
 /*
- * Return a string for the type
+ * Return a string for the type.
  */
 const char *
  */
 const char *
-__p_type(type)
-       int type;
-{
-       return (__sym_ntos (__p_type_syms, type, (int *)0));
+p_type(int type) {
+       return (sym_ntos(__p_type_syms, type, (int *)0));
 }
 
 /*
 }
 
 /*
- * Return a mnemonic for class
+ * Return a string for the type.
  */
 const char *
  */
 const char *
-__p_class(class)
-       int class;
-{
-       return (__sym_ntos (__p_class_syms, class, (int *)0));
+p_section(int section, int opcode) {
+       const struct res_sym *symbols;
+
+       switch (opcode) {
+       case ns_o_update:
+               symbols = __p_update_section_syms;
+               break;
+       default:
+               symbols = __p_default_section_syms;
+               break;
+       }
+       return (sym_ntos(symbols, section, (int *)0));
+}
+
+/*
+ * Return a mnemonic for class.
+ */
+const char *
+p_class(int class) {
+       return (sym_ntos(__p_class_syms, class, (int *)0));
 }
 
 /*
  * Return a mnemonic for an option
  */
 const char *
 }
 
 /*
  * Return a mnemonic for an option
  */
 const char *
-__p_option(option)
-       u_long option;
-{
+p_option(u_long option) {
        static char nbuf[40];
 
        switch (option) {
        static char nbuf[40];
 
        switch (option) {
@@ -1014,63 +572,33 @@ __p_option(option)
        case RES_DNSRCH:        return "dnsrch";
        case RES_INSECURE1:     return "insecure1";
        case RES_INSECURE2:     return "insecure2";
        case RES_DNSRCH:        return "dnsrch";
        case RES_INSECURE1:     return "insecure1";
        case RES_INSECURE2:     return "insecure2";
+                               /* XXX nonreentrant */
        default:                sprintf(nbuf, "?0x%lx?", (u_long)option);
                                return (nbuf);
        }
 }
 
 /*
        default:                sprintf(nbuf, "?0x%lx?", (u_long)option);
                                return (nbuf);
        }
 }
 
 /*
- * Return a mnemonic for a time to live
+ * Return a mnemonic for a time to live.
  */
  */
-char *
-__p_time(value)
-       u_int32_t value;
-{
-       static char nbuf[40];
-       int secs, mins, hours, days;
-       register char *p;
-
-       if (value == 0) {
-               strcpy(nbuf, "0 secs");
-               return (nbuf);
-       }
+const char *
+p_time(u_int32_t value) {
+       static char nbuf[40];           /* XXX nonreentrant */
 
 
-       secs = value % 60;
-       value /= 60;
-       mins = value % 60;
-       value /= 60;
-       hours = value % 24;
-       value /= 24;
-       days = value;
-       value = 0;
-
-#define        PLURALIZE(x)    x, (x == 1) ? "" : "s"
-       p = nbuf;
-       if (days) {
-               (void)sprintf(p, "%d day%s", PLURALIZE(days));
-               while (*++p);
-       }
-       if (hours) {
-               if (days)
-                       *p++ = ' ';
-               (void)sprintf(p, "%d hour%s", PLURALIZE(hours));
-               while (*++p);
-       }
-       if (mins) {
-               if (days || hours)
-                       *p++ = ' ';
-               (void)sprintf(p, "%d min%s", PLURALIZE(mins));
-               while (*++p);
-       }
-       if (secs || ! (days || hours || mins)) {
-               if (days || hours || mins)
-                       *p++ = ' ';
-               (void)sprintf(p, "%d sec%s", PLURALIZE(secs));
-       }
+       if (ns_format_ttl(value, nbuf, sizeof nbuf) < 0)
+               sprintf(nbuf, "%u", value);
        return (nbuf);
 }
 
 /*
        return (nbuf);
 }
 
 /*
+ * Return a string for the rcode.
+ */
+const char *
+p_rcode(int rcode) {
+       return (sym_ntos(__p_rcode_syms, rcode, (int *)0));
+}
+
+/*
  * routines to convert between on-the-wire RR format and zone file format.
  * Does not contain conversion to/from decimal degrees; divide or multiply
  * by 60*60*1000 for that.
  * routines to convert between on-the-wire RR format and zone file format.
  * Does not contain conversion to/from decimal degrees; divide or multiply
  * by 60*60*1000 for that.
@@ -1084,7 +612,7 @@ static const char *
 precsize_ntoa(prec)
        u_int8_t prec;
 {
 precsize_ntoa(prec)
        u_int8_t prec;
 {
-       static char retbuf[sizeof "90000000.00"];
+       static char retbuf[sizeof "90000000.00"];       /* XXX nonreentrant */
        unsigned long val;
        int mantissa, exponent;
 
        unsigned long val;
        int mantissa, exponent;
 
@@ -1104,9 +632,9 @@ precsize_aton(strptr)
 {
        unsigned int mval = 0, cmval = 0;
        u_int8_t retval = 0;
 {
        unsigned int mval = 0, cmval = 0;
        u_int8_t retval = 0;
-       register char *cp;
-       register int exponent;
-       register int mantissa;
+       char *cp;
+       int exponent;
+       int mantissa;
 
        cp = *strptr;
 
 
        cp = *strptr;
 
@@ -1145,7 +673,7 @@ latlon2ul(latlonstrptr,which)
        char **latlonstrptr;
        int *which;
 {
        char **latlonstrptr;
        int *which;
 {
-       register char *cp;
+       char *cp;
        u_int32_t retval;
        int deg = 0, min = 0, secs = 0, secsfrac = 0;
 
        u_int32_t retval;
        int deg = 0, min = 0, secs = 0, secsfrac = 0;
 
@@ -1283,7 +811,7 @@ loc_aton(ascii, binary)
                altsign = -1;
                cp++;
        }
                altsign = -1;
                cp++;
        }
-
+    
        if (*cp == '+')
                cp++;
 
        if (*cp == '+')
                cp++;
 
@@ -1312,7 +840,7 @@ loc_aton(ascii, binary)
                goto defaults;
 
        siz = precsize_aton(&cp);
                goto defaults;
 
        siz = precsize_aton(&cp);
-
+       
        while (!isspace(*cp) && (cp < maxcp))   /* if trailing garbage or m */
                cp++;
 
        while (!isspace(*cp) && (cp < maxcp))   /* if trailing garbage or m */
                cp++;
 
@@ -1345,36 +873,41 @@ loc_aton(ascii, binary)
        PUTLONG(latit,bcp);
        PUTLONG(longit,bcp);
        PUTLONG(alt,bcp);
        PUTLONG(latit,bcp);
        PUTLONG(longit,bcp);
        PUTLONG(alt,bcp);
-
+    
        return (16);            /* size of RR in octets */
 }
 
 /* takes an on-the-wire LOC RR and formats it in a human readable format. */
        return (16);            /* size of RR in octets */
 }
 
 /* takes an on-the-wire LOC RR and formats it in a human readable format. */
-char *
+const char *
 loc_ntoa(binary, ascii)
        const u_char *binary;
        char *ascii;
 {
        static char *error = "?";
 loc_ntoa(binary, ascii)
        const u_char *binary;
        char *ascii;
 {
        static char *error = "?";
-       register const u_char *cp = binary;
+       static char tmpbuf[sizeof
+"1000 60 60.000 N 1000 60 60.000 W -12345678.00m 90000000.00m 90000000.00m 90000000.00m"];
+       const u_char *cp = binary;
 
        int latdeg, latmin, latsec, latsecfrac;
        int longdeg, longmin, longsec, longsecfrac;
        char northsouth, eastwest;
        int altmeters, altfrac, altsign;
 
 
        int latdeg, latmin, latsec, latsecfrac;
        int longdeg, longmin, longsec, longsecfrac;
        char northsouth, eastwest;
        int altmeters, altfrac, altsign;
 
-       const int referencealt = 100000 * 100;
+       const u_int32_t referencealt = 100000 * 100;
 
        int32_t latval, longval, altval;
        u_int32_t templ;
        u_int8_t sizeval, hpval, vpval, versionval;
 
        int32_t latval, longval, altval;
        u_int32_t templ;
        u_int8_t sizeval, hpval, vpval, versionval;
-
+    
        char *sizestr, *hpstr, *vpstr;
 
        versionval = *cp++;
 
        char *sizestr, *hpstr, *vpstr;
 
        versionval = *cp++;
 
+       if (ascii == NULL)
+               ascii = tmpbuf;
+
        if (versionval) {
        if (versionval) {
-               sprintf(ascii, "; error: unknown LOC RR version");
+               (void) sprintf(ascii, "; error: unknown LOC RR version");
                return (ascii);
        }
 
                return (ascii);
        }
 
@@ -1455,14 +988,12 @@ loc_ntoa(binary, ascii)
 
 /* Return the number of DNS hierarchy levels in the name. */
 int
 
 /* Return the number of DNS hierarchy levels in the name. */
 int
-__dn_count_labels(name)
-       char *name;
-{
+dn_count_labels(const char *name) {
        int i, len, count;
 
        len = strlen(name);
        int i, len, count;
 
        len = strlen(name);
-
-       for(i = 0, count = 0; i < len; i++) {
+       for (i = 0, count = 0; i < len; i++) {
+               /* XXX need to check for \. or use named's nlabels(). */
                if (name[i] == '.')
                        count++;
        }
                if (name[i] == '.')
                        count++;
        }
@@ -1481,23 +1012,28 @@ __dn_count_labels(name)
 }
 
 
 }
 
 
-/*
- * Make dates expressed in seconds-since-Jan-1-1970 easy to read.
+/* 
+ * Make dates expressed in seconds-since-Jan-1-1970 easy to read.  
  * SIG records are required to be printed like this, by the Secure DNS RFC.
  */
 char *
  * SIG records are required to be printed like this, by the Secure DNS RFC.
  */
 char *
-__p_secstodate (secs)
-       unsigned long secs;
-{
-       static char output[15];         /* YYYYMMDDHHMMSS and null */
+p_secstodate (u_long secs) {
+       /* XXX nonreentrant */
+       static char output[15];         /* YYYYMMDDHHMMSS and null */
        time_t clock = secs;
        time_t clock = secs;
-       struct tm time;
-
-       __gmtime_r(&clock, &time);
-       time.tm_year += 1900;
-       time.tm_mon += 1;
+       struct tm *time;
+       
+#ifdef HAVE_TIME_R
+       struct tm timebuf;
+       
+       time = gmtime_r(&clock, &timebuf);
+#else
+       time = gmtime(&clock);
+#endif
+       time->tm_year += 1900;
+       time->tm_mon += 1;
        sprintf(output, "%04d%02d%02d%02d%02d%02d",
        sprintf(output, "%04d%02d%02d%02d%02d%02d",
-               time.tm_year, time.tm_mon, time.tm_mday,
-               time.tm_hour, time.tm_min, time.tm_sec);
+               time->tm_year, time->tm_mon, time->tm_mday,
+               time->tm_hour, time->tm_min, time->tm_sec);
        return (output);
 }
        return (output);
 }