home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / ixemul-45.0-src.tgz / tar.out / contrib / ixemul / net / res_debug.c < prev    next >
C/C++ Source or Header  |  1996-09-28  |  17KB  |  751 lines

  1. /*    $NetBSD: res_debug.c,v 1.7 1995/02/25 06:20:56 cgd Exp $    */
  2.  
  3. /*-
  4.  * Copyright (c) 1985, 1990, 1993
  5.  *    The Regents of the University of California.  All rights reserved.
  6.  *
  7.  * Redistribution and use in source and binary forms, with or without
  8.  * modification, are permitted provided that the following conditions
  9.  * are met:
  10.  * 1. Redistributions of source code must retain the above copyright
  11.  *    notice, this list of conditions and the following disclaimer.
  12.  * 2. Redistributions in binary form must reproduce the above copyright
  13.  *    notice, this list of conditions and the following disclaimer in the
  14.  *    documentation and/or other materials provided with the distribution.
  15.  * 3. All advertising materials mentioning features or use of this software
  16.  *    must display the following acknowledgement:
  17.  *     This product includes software developed by the University of
  18.  *     California, Berkeley and its contributors.
  19.  * 4. Neither the name of the University nor the names of its contributors
  20.  *    may be used to endorse or promote products derived from this software
  21.  *    without specific prior written permission.
  22.  * 
  23.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  24.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  25.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  26.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  27.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  28.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  29.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  30.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  31.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  32.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  33.  * SUCH DAMAGE.
  34.  * -
  35.  * Portions Copyright (c) 1993 by Digital Equipment Corporation.
  36.  * 
  37.  * Permission to use, copy, modify, and distribute this software for any
  38.  * purpose with or without fee is hereby granted, provided that the above
  39.  * copyright notice and this permission notice appear in all copies, and that
  40.  * the name of Digital Equipment Corporation not be used in advertising or
  41.  * publicity pertaining to distribution of the document or software without
  42.  * specific, written prior permission.
  43.  * 
  44.  * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
  45.  * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
  46.  * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
  47.  * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
  48.  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
  49.  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
  50.  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  51.  * SOFTWARE.
  52.  * -
  53.  * --Copyright--
  54.  */
  55.  
  56. #if defined(LIBC_SCCS) && !defined(lint)
  57. #if 0
  58. static char sccsid[] = "@(#)res_debug.c    8.1 (Berkeley) 6/4/93";
  59. #else
  60. static char rcsid[] = "$NetBSD: res_debug.c,v 1.7 1995/02/25 06:20:56 cgd Exp $";
  61. #endif
  62. #endif /* LIBC_SCCS and not lint */
  63.  
  64. #include <sys/param.h>
  65. #include <netinet/in.h>
  66. #include <arpa/inet.h>
  67. #include <arpa/nameser.h>
  68. #include <resolv.h>
  69. #include <stdio.h>
  70. #include <string.h>
  71.  
  72. void __fp_query();
  73. char *__p_class(), *__p_time(), *__p_type();
  74. char *p_cdname(), *p_fqname(), *p_rr();
  75. static char *p_option __P((u_int32_t));
  76.  
  77. char *_res_opcodes[] = {
  78.     "QUERY",
  79.     "IQUERY",
  80.     "CQUERYM",
  81.     "CQUERYU",
  82.     "4",
  83.     "5",
  84.     "6",
  85.     "7",
  86.     "8",
  87.     "UPDATEA",
  88.     "UPDATED",
  89.     "UPDATEDA",
  90.     "UPDATEM",
  91.     "UPDATEMA",
  92.     "ZONEINIT",
  93.     "ZONEREF",
  94. };
  95.  
  96. char *_res_resultcodes[] = {
  97.     "NOERROR",
  98.     "FORMERR",
  99.     "SERVFAIL",
  100.     "NXDOMAIN",
  101.     "NOTIMP",
  102.     "REFUSED",
  103.     "6",
  104.     "7",
  105.     "8",
  106.     "9",
  107.     "10",
  108.     "11",
  109.     "12",
  110.     "13",
  111.     "14",
  112.     "NOCHANGE",
  113. };
  114.  
  115. static char retbuf[16];
  116.  
  117. static char *
  118. dewks(wks)
  119.     int wks;
  120. {
  121.     switch (wks) {
  122.     case 5: return("rje");
  123.     case 7: return("echo");
  124.     case 9: return("discard");
  125.     case 11: return("systat");
  126.     case 13: return("daytime");
  127.     case 15: return("netstat");
  128.     case 17: return("qotd");
  129.     case 19: return("chargen");
  130.     case 20: return("ftp-data");
  131.     case 21: return("ftp");
  132.     case 23: return("telnet");
  133.     case 25: return("smtp");
  134.     case 37: return("time");
  135.     case 39: return("rlp");
  136.     case 42: return("name");
  137.     case 43: return("whois");
  138.     case 53: return("domain");
  139.     case 57: return("apts");
  140.     case 59: return("apfs");
  141.     case 67: return("bootps");
  142.     case 68: return("bootpc");
  143.     case 69: return("tftp");
  144.     case 77: return("rje");
  145.     case 79: return("finger");
  146.     case 87: return("link");
  147.     case 95: return("supdup");
  148.     case 100: return("newacct");
  149.     case 101: return("hostnames");
  150.     case 102: return("iso-tsap");
  151.     case 103: return("x400");
  152.     case 104: return("x400-snd");
  153.     case 105: return("csnet-ns");
  154.     case 109: return("pop-2");
  155.     case 111: return("sunrpc");
  156.     case 113: return("auth");
  157.     case 115: return("sftp");
  158.     case 117: return("uucp-path");
  159.     case 119: return("nntp");
  160.     case 121: return("erpc");
  161.     case 123: return("ntp");
  162.     case 133: return("statsrv");
  163.     case 136: return("profile");
  164.     case 144: return("NeWS");
  165.     case 161: return("snmp");
  166.     case 162: return("snmp-trap");
  167.     case 170: return("print-srv");
  168.     default: (void) sprintf(retbuf, "%d", wks); return(retbuf);
  169.     }
  170. }
  171.  
  172. static char *
  173. deproto(protonum)
  174.     int protonum;
  175. {
  176.     switch (protonum) {
  177.     case 1: return("icmp");
  178.     case 2: return("igmp");
  179.     case 3: return("ggp");
  180.     case 5: return("st");
  181.     case 6: return("tcp");
  182.     case 7: return("ucl");
  183.     case 8: return("egp");
  184.     case 9: return("igp");
  185.     case 11: return("nvp-II");
  186.     case 12: return("pup");
  187.     case 16: return("chaos");
  188.     case 17: return("udp");
  189.     default: (void) sprintf(retbuf, "%d", protonum); return(retbuf);
  190.     }
  191. }
  192.  
  193. static char *
  194. do_rrset(msg, cp, cnt, pflag, file, hs)
  195.     int cnt, pflag;
  196.     char *cp,*msg, *hs;
  197.     FILE *file;
  198. {
  199.     int n;
  200.     int sflag;
  201.     /*
  202.      * Print  answer records
  203.      */
  204.     sflag = (_res.pfcode & pflag);
  205.     if ((n = ntohs(cnt))) {
  206.         if ((!_res.pfcode) || ((sflag) && (_res.pfcode & RES_PRF_HEAD1)))
  207.             fprintf(file, hs);
  208.         while (--n >= 0) {
  209.             cp = p_rr(cp, msg, file);
  210.             if ((cp-msg) > PACKETSZ)
  211.                 return (NULL);
  212.         }
  213.         if ((!_res.pfcode) || ((sflag) && (_res.pfcode & RES_PRF_HEAD1)))
  214.             putc('\n', file);
  215.     }
  216.     return(cp);
  217. }
  218.  
  219. void
  220. __p_query(msg)
  221.     char *msg;
  222. {
  223.     __fp_query(msg, stdout);
  224. }
  225.  
  226. /*
  227.  * Print the current options.
  228.  * This is intended to be primarily a debugging routine.
  229.  */
  230. void
  231. __fp_resstat(statp, file)
  232.     struct __res_state *statp;
  233.     FILE *file;
  234. {
  235.     int bit;
  236.  
  237.     fprintf(file, ";; res options:");
  238.     if (!statp)
  239.         statp = &_res;
  240.     for (bit = 0;  bit < 32;  bit++) {    /* XXX 32 - bad assumption! */
  241.         if (statp->options & (1<<bit))
  242.             fprintf(file, " %s", p_option(1<<bit));
  243.     }
  244.     putc('\n', file);
  245. }
  246.  
  247. /*
  248.  * Print the contents of a query.
  249.  * This is intended to be primarily a debugging routine.
  250.  */
  251. void
  252. __fp_query(msg,file)
  253.     char *msg;
  254.     FILE *file;
  255. {
  256.     register char *cp;
  257.     register HEADER *hp;
  258.     register int n;
  259.  
  260.     /*
  261.      * Print header fields.
  262.      */
  263.     hp = (HEADER *)msg;
  264.     cp = msg + sizeof(HEADER);
  265.     if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEADX) || hp->rcode) {
  266.         fprintf(file,";; ->>HEADER<<- opcode: %s, status: %s, id: %d",
  267.             _res_opcodes[hp->opcode],
  268.             _res_resultcodes[hp->rcode],
  269.             ntohs(hp->id));
  270.         putc('\n', file);
  271.     }
  272.     putc(';', file);
  273.     if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD2)) {
  274.         fprintf(file,"; flags:");
  275.         if (hp->qr)
  276.             fprintf(file," qr");
  277.         if (hp->aa)
  278.             fprintf(file," aa");
  279.         if (hp->tc)
  280.             fprintf(file," tc");
  281.         if (hp->rd)
  282.             fprintf(file," rd");
  283.         if (hp->ra)
  284.             fprintf(file," ra");
  285.         if (hp->pr)
  286.             fprintf(file," pr");
  287.     }
  288.     if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD1)) {
  289.         fprintf(file,"; Ques: %d", ntohs(hp->qdcount));
  290.         fprintf(file,", Ans: %d", ntohs(hp->ancount));
  291.         fprintf(file,", Auth: %d", ntohs(hp->nscount));
  292.         fprintf(file,", Addit: %d\n", ntohs(hp->arcount));
  293.     }
  294. #if 0
  295.     if (_res.pfcode & (RES_PRF_HEADX | RES_PRF_HEAD2 | RES_PRF_HEAD1)) {
  296.         putc('\n',file);
  297.     }
  298. #endif
  299.     /*
  300.      * Print question records.
  301.      */
  302.     if ((n = ntohs(hp->qdcount))) {
  303.         if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
  304.             fprintf(file,";; QUESTIONS:\n");
  305.         while (--n >= 0) {
  306.             fprintf(file,";;\t");
  307.             cp = p_cdname(cp, msg, file);
  308.             if (cp == NULL)
  309.                 return;
  310.             if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
  311.                 fprintf(file, ", type = %s",
  312.                     __p_type(_getshort(cp)));
  313.             cp += sizeof(u_int16_t);
  314.             if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
  315.                 fprintf(file, ", class = %s\n\n",
  316.                     __p_class(_getshort(cp)));
  317.             cp += sizeof(u_int16_t);
  318.         }
  319.     }
  320.     /*
  321.      * Print authoritative answer records
  322.      */
  323.     cp = do_rrset(msg, cp, hp->ancount, RES_PRF_ANS, file,
  324.               ";; ANSWERS:\n");
  325.     if (cp == NULL)
  326.         return;
  327.  
  328.     /*
  329.      * print name server records
  330.      */
  331.     cp = do_rrset(msg, cp, hp->nscount, RES_PRF_AUTH, file,
  332.               ";; AUTHORITY RECORDS:\n");
  333.     if (!cp)
  334.         return;
  335.  
  336.     /*
  337.      * print additional records
  338.      */
  339.     cp = do_rrset(msg, cp, hp->arcount, RES_PRF_ADD, file,
  340.               ";; ADDITIONAL RECORDS:\n");
  341.     if (!cp)
  342.         return;
  343. }
  344.  
  345. char *
  346. p_cdname(cp, msg, file)
  347.     char *cp, *msg;
  348.     FILE *file;
  349. {
  350.     char name[MAXDNAME];
  351.     int n;
  352.  
  353.     if ((n = dn_expand((u_char *)msg, (u_char *)cp + MAXCDNAME,
  354.         (u_char *)cp, (u_char *)name, sizeof(name))) < 0)
  355.         return (NULL);
  356.     if (name[0] == '\0')
  357.         putc('.', file);
  358.     else
  359.         fputs(name, file);
  360.     return (cp + n);
  361. }
  362.  
  363. char *
  364. p_fqname(cp, msg, file)
  365.     char *cp, *msg;
  366.     FILE *file;
  367. {
  368.     char name[MAXDNAME];
  369.     int n;
  370.  
  371.     if ((n = dn_expand((u_char *)msg, (u_char *)cp + MAXCDNAME,
  372.         (u_char *)cp, (u_char *)name, sizeof(name))) < 0)
  373.         return (NULL);
  374.     if (name[0] == '\0') {
  375.         putc('.', file);
  376.     } else {
  377.         fputs(name, file);
  378.         if (name[strlen(name) - 1] != '.')
  379.             putc('.', file);
  380.     }
  381.     return (cp + n);
  382. }
  383.  
  384. /*
  385.  * Print resource record fields in human readable form.
  386.  */
  387. char *
  388. p_rr(cp, msg, file)
  389.     char *cp, *msg;
  390.     FILE *file;
  391. {
  392.     int type, class, dlen, n, c;
  393.     struct in_addr inaddr;
  394.     char *cp1, *cp2;
  395.     u_int32_t tmpttl, t;
  396.     int lcnt;
  397.  
  398.     if ((cp = p_fqname(cp, msg, file)) == NULL)
  399.         return (NULL);            /* compression error */
  400.     type = _getshort(cp);
  401.     cp += sizeof(u_int16_t);
  402.     class = _getshort(cp);
  403.     cp += sizeof(u_int16_t);
  404.     tmpttl = _getlong(cp);
  405.     cp += sizeof(u_int32_t);
  406.     dlen = _getshort(cp);
  407.     cp += sizeof(u_int16_t);
  408.     cp1 = cp;
  409.     if ((!_res.pfcode) || (_res.pfcode & RES_PRF_TTLID))
  410.         fprintf(file, "\t%u", tmpttl);
  411.     if ((!_res.pfcode) || (_res.pfcode & RES_PRF_CLASS))
  412.         fprintf(file, "\t%s", __p_class(class));
  413.     fprintf(file, "\t%s", __p_type(type));
  414.     /*
  415.      * Print type specific data, if appropriate
  416.      */
  417.     switch (type) {
  418.     case T_A:
  419.         switch (class) {
  420.         case C_IN:
  421.         case C_HS:
  422.             bcopy(cp, (char *)&inaddr, sizeof(inaddr));
  423.             if (dlen == 4) {
  424.                 fprintf(file,"\t%s", inet_ntoa(inaddr));
  425.                 cp += dlen;
  426.             } else if (dlen == 7) {
  427.                 char *address;
  428.                 u_char protocol;
  429.                 u_short port;
  430.  
  431.                 address = inet_ntoa(inaddr);
  432.                 cp += sizeof(inaddr);
  433.                 protocol = *(u_char*)cp;
  434.                 cp += sizeof(u_char);
  435.                 port = _getshort(cp);
  436.                 cp += sizeof(u_int16_t);
  437.                 fprintf(file, "\t%s\t; proto %d, port %d",
  438.                     address, protocol, port);
  439.             }
  440.             break;
  441.         default:
  442.             cp += dlen;
  443.         }
  444.         break;
  445.     case T_CNAME:
  446.     case T_MB:
  447.     case T_MG:
  448.     case T_MR:
  449.     case T_NS:
  450.     case T_PTR:
  451.         putc('\t', file);
  452.         cp = p_fqname(cp, msg, file);
  453.         break;
  454.  
  455.     case T_HINFO:
  456.         if ((n = *cp++)) {
  457.             fprintf(file,"\t%.*s", n, cp);
  458.             cp += n;
  459.         }
  460.         if ((n = *cp++)) {
  461.             fprintf(file,"\t%.*s", n, cp);
  462.             cp += n;
  463.         }
  464.         break;
  465.  
  466.     case T_SOA:
  467.         putc('\t', file);
  468.         cp = p_fqname(cp, msg, file);    /* origin */
  469.         putc(' ', file);
  470.         cp = p_fqname(cp, msg, file);    /* mail addr */
  471.         fputs(" (\n", file);
  472.         t = _getlong(cp);  cp += sizeof(u_int32_t);
  473.         fprintf(file,"\t\t\t%u\t; serial\n", t);
  474.         t = _getlong(cp);  cp += sizeof(u_int32_t);
  475.         fprintf(file,"\t\t\t%u\t; refresh (%s)\n", t, __p_time(t));
  476.         t = _getlong(cp);  cp += sizeof(u_int32_t);
  477.         fprintf(file,"\t\t\t%u\t; retry (%s)\n", t, __p_time(t));
  478.         t = _getlong(cp);  cp += sizeof(u_int32_t);
  479.         fprintf(file,"\t\t\t%u\t; expire (%s)\n", t, __p_time(t));
  480.         t = _getlong(cp);  cp += sizeof(u_int32_t);
  481.         fprintf(file,"\t\t\t%u )\t; minimum (%s)", t, __p_time(t));
  482.         break;
  483.  
  484.     case T_MX:
  485.     case T_AFSDB:
  486.         fprintf(file,"\t%d ", _getshort(cp));
  487.         cp += sizeof(u_int16_t);
  488.         cp = p_fqname(cp, msg, file);
  489.         break;
  490.  
  491.       case T_TXT:
  492.         (void) fputs("\t\"", file);
  493.         cp2 = cp1 + dlen;
  494.         while (cp < cp2) {
  495.             if ((n = (unsigned char) *cp++)) {
  496.                 for (c = n; c > 0 && cp < cp2; c--)
  497.                     if (*cp == '\n') {
  498.                         (void) putc('\\', file);
  499.                         (void) putc(*cp++, file);
  500.                     } else
  501.                         (void) putc(*cp++, file);
  502.             }
  503.         }
  504.         putc('"', file);
  505.           break;
  506.  
  507.     case T_MINFO:
  508.     case T_RP:
  509.         putc('\t', file);
  510.         cp = p_fqname(cp, msg, file);
  511.         putc(' ', file);
  512.         cp = p_fqname(cp, msg, file);
  513.         break;
  514.  
  515.     case T_UINFO:
  516.         putc('\t', file);
  517.         fputs(cp, file);
  518.         cp += dlen;
  519.         break;
  520.  
  521.     case T_UID:
  522.     case T_GID:
  523.         if (dlen == 4) {
  524.             fprintf(file,"\t%u", _getlong(cp));
  525.             cp += sizeof(int32_t);
  526.         }
  527.         break;
  528.  
  529.     case T_WKS:
  530.         if (dlen < sizeof(u_int32_t) + 1)
  531.             break;
  532.         bcopy(cp, (char *)&inaddr, sizeof(inaddr));
  533.         cp += sizeof(u_int32_t);
  534.         fprintf(file, "\t%s %s ( ",
  535.             inet_ntoa(inaddr),
  536.             deproto((int) *cp));
  537.         cp += sizeof(u_char);
  538.         n = 0;
  539.         lcnt = 0;
  540.         while (cp < cp1 + dlen) {
  541.             c = *cp++;
  542.             do {
  543.                  if (c & 0200) {
  544.                     if (lcnt == 0) {
  545.                         fputs("\n\t\t\t", file);
  546.                         lcnt = 5;
  547.                     }
  548.                     fputs(dewks(n), file);
  549.                     putc(' ', file);
  550.                     lcnt--;
  551.                 }
  552.                  c <<= 1;
  553.             } while (++n & 07);
  554.         }
  555.         putc(')', file);
  556.         break;
  557.  
  558. #ifdef ALLOW_T_UNSPEC
  559.     case T_UNSPEC:
  560.         {
  561.             int NumBytes = 8;
  562.             char *DataPtr;
  563.             int i;
  564.  
  565.             if (dlen < NumBytes) NumBytes = dlen;
  566.             fprintf(file, "\tFirst %d bytes of hex data:",
  567.                 NumBytes);
  568.             for (i = 0, DataPtr = cp; i < NumBytes; i++, DataPtr++)
  569.                 fprintf(file, " %x", *DataPtr);
  570.             cp += dlen;
  571.         }
  572.         break;
  573. #endif /* ALLOW_T_UNSPEC */
  574.  
  575.     default:
  576.         fprintf(file,"\t?%d?", type);
  577.         cp += dlen;
  578.     }
  579. #if 0
  580.     fprintf(file, "\t; dlen=%d, ttl %s\n", dlen, __p_time(tmpttl));
  581. #else
  582.     putc('\n', file);
  583. #endif
  584.     if (cp - cp1 != dlen) {
  585.         fprintf(file,";; packet size error (found %ld, dlen was %d)\n",
  586.             cp - cp1, dlen);
  587.         cp = NULL;
  588.     }
  589.     return (cp);
  590. }
  591.  
  592. static    char nbuf[40];
  593.  
  594. /*
  595.  * Return a string for the type
  596.  */
  597. char *
  598. __p_type(type)
  599.     int type;
  600. {
  601.     switch (type) {
  602.     case T_A:
  603.         return("A");
  604.     case T_NS:        /* authoritative server */
  605.         return("NS");
  606.     case T_CNAME:        /* canonical name */
  607.         return("CNAME");
  608.     case T_SOA:        /* start of authority zone */
  609.         return("SOA");
  610.     case T_MB:        /* mailbox domain name */
  611.         return("MB");
  612.     case T_MG:        /* mail group member */
  613.         return("MG");
  614.     case T_MR:        /* mail rename name */
  615.         return("MR");
  616.     case T_NULL:        /* null resource record */
  617.         return("NULL");
  618.     case T_WKS:        /* well known service */
  619.         return("WKS");
  620.     case T_PTR:        /* domain name pointer */
  621.         return("PTR");
  622.     case T_HINFO:        /* host information */
  623.         return("HINFO");
  624.     case T_MINFO:        /* mailbox information */
  625.         return("MINFO");
  626.     case T_MX:        /* mail routing info */
  627.         return("MX");
  628.     case T_TXT:        /* text */
  629.         return("TXT");
  630.     case T_RP:        /* responsible person */
  631.         return("RP");
  632.     case T_AFSDB:        /* AFS cell database */
  633.         return("AFSDB");
  634.     case T_AXFR:        /* zone transfer */
  635.         return("AXFR");
  636.     case T_MAILB:        /* mail box */
  637.         return("MAILB");
  638.     case T_MAILA:        /* mail address */
  639.         return("MAILA");
  640.     case T_ANY:        /* matches any type */
  641.         return("ANY");
  642.     case T_UINFO:
  643.         return("UINFO");
  644.     case T_UID:
  645.         return("UID");
  646.     case T_GID:
  647.         return("GID");
  648. #ifdef ALLOW_T_UNSPEC
  649.     case T_UNSPEC:
  650.         return("UNSPEC");
  651. #endif /* ALLOW_T_UNSPEC */
  652.  
  653.     default:
  654.         (void)sprintf(nbuf, "%d", type);
  655.         return(nbuf);
  656.     }
  657. }
  658.  
  659. /*
  660.  * Return a mnemonic for class
  661.  */
  662. char *
  663. __p_class(class)
  664.     int class;
  665. {
  666.  
  667.     switch (class) {
  668.     case C_IN:        /* internet class */
  669.         return("IN");
  670.     case C_HS:        /* hesiod class */
  671.         return("HS");
  672.     case C_ANY:        /* matches any class */
  673.         return("ANY");
  674.     default:
  675.         (void)sprintf(nbuf, "%d", class);
  676.         return(nbuf);
  677.     }
  678. }
  679.  
  680. /*
  681.  * Return a mnemonic for an option
  682.  */
  683. static char *
  684. p_option(option)
  685.     u_int32_t option;
  686. {
  687.     switch (option) {
  688.     case RES_INIT:        return "init";
  689.     case RES_DEBUG:        return "debug";
  690.     case RES_AAONLY:    return "aaonly";
  691.     case RES_USEVC:        return "usevc";
  692.     case RES_PRIMARY:    return "primry";
  693.     case RES_IGNTC:        return "igntc";
  694.     case RES_RECURSE:    return "recurs";
  695.     case RES_DEFNAMES:    return "defnam";
  696.     case RES_STAYOPEN:    return "styopn";
  697.     case RES_DNSRCH:    return "dnsrch";
  698.     default:        sprintf(nbuf, "?0x%x?", option); return nbuf;
  699.     }
  700. }
  701.  
  702. /*
  703.  * Return a mnemonic for a time to live
  704.  */
  705. char *
  706. __p_time(value)
  707.     u_int32_t value;
  708. {
  709.     int secs, mins, hours, days;
  710.     register char *p;
  711.  
  712.     if (value == 0) {
  713.         strcpy(nbuf, "0 secs");
  714.         return(nbuf);
  715.     }
  716.  
  717.     secs = value % 60;
  718.     value /= 60;
  719.     mins = value % 60;
  720.     value /= 60;
  721.     hours = value % 24;
  722.     value /= 24;
  723.     days = value;
  724.     value = 0;
  725.  
  726. #define    PLURALIZE(x)    x, (x == 1) ? "" : "s"
  727.     p = nbuf;
  728.     if (days) {
  729.         (void)sprintf(p, "%d day%s", PLURALIZE(days));
  730.         while (*++p);
  731.     }
  732.     if (hours) {
  733.         if (days)
  734.             *p++ = ' ';
  735.         (void)sprintf(p, "%d hour%s", PLURALIZE(hours));
  736.         while (*++p);
  737.     }
  738.     if (mins) {
  739.         if (days || hours)
  740.             *p++ = ' ';
  741.         (void)sprintf(p, "%d min%s", PLURALIZE(mins));
  742.         while (*++p);
  743.     }
  744.     if (secs || ! (days || hours || mins)) {
  745.         if (days || hours || mins)
  746.             *p++ = ' ';
  747.         (void)sprintf(p, "%d sec%s", PLURALIZE(secs));
  748.     }
  749.     return(nbuf);
  750. }
  751.