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