res_debug.c
上传用户:nvosite88
上传日期:2007-01-17
资源大小:4983k
文件大小:17k
源码类别:

VxWorks

开发平台:

C/C++

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