home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / NETWORK / ISP / bind.4.8.3.lzh / BIND483 / RES / NAMED / gethostnamadr.c.compat < prev    next >
Text File  |  1993-08-24  |  9KB  |  413 lines

  1. /*
  2.  * Copyright (c) 1985, 1988 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms are permitted
  6.  * provided that the above copyright notice and this paragraph are
  7.  * duplicated in all such forms and that any documentation,
  8.  * advertising materials, and other materials related to such
  9.  * distribution and use acknowledge that the software was developed
  10.  * by the University of California, Berkeley.  The name of the
  11.  * University may not be used to endorse or promote products derived
  12.  * from this software without specific prior written permission.
  13.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  14.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  15.  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  16.  */
  17.  
  18. #if defined(LIBC_SCCS) && !defined(lint)
  19. static char sccsid[] = "@(#)gethostnamadr.c    6.37 (Berkeley) 3/9/89";
  20. #endif /* LIBC_SCCS and not lint */
  21.  
  22. #include <sys/param.h>
  23. #include <sys/socket.h>
  24. #include <netinet/in.h>
  25. #include <ctype.h>
  26. #include <netdb.h>
  27. #include <stdio.h>
  28. #include <errno.h>
  29. #include <arpa/inet.h>
  30. #include <arpa/nameser.h>
  31. #include <resolv.h>
  32.  
  33. #define    MAXALIASES    35
  34. #define    MAXADDRS    35
  35.  
  36. static char *h_addr_ptrs[MAXADDRS + 1];
  37.  
  38. static struct hostent host;
  39. static char *host_aliases[MAXALIASES];
  40. static char hostbuf[BUFSIZ+1];
  41. static struct in_addr host_addr;
  42. static char HOSTDB[] = "/etc/hosts";
  43. static FILE *hostf = NULL;
  44. static char hostaddr[MAXADDRS];
  45. static char *host_addrs[2];
  46. static int stayopen = 0;
  47. char *strpbrk();
  48.  
  49. #if PACKETSZ > 1024
  50. #define    MAXPACKET    PACKETSZ
  51. #else
  52. #define    MAXPACKET    1024
  53. #endif
  54.  
  55. typedef union {
  56.     HEADER hdr;
  57.     u_char buf[MAXPACKET];
  58. } querybuf;
  59.  
  60. typedef union {
  61.     long al;
  62.     char ac;
  63. } align;
  64.  
  65.  
  66. int h_errno;
  67. extern errno;
  68.  
  69. static struct hostent *
  70. getanswer(answer, anslen, iquery)
  71.     querybuf *answer;
  72.     int anslen;
  73.     int iquery;
  74. {
  75.     register HEADER *hp;
  76.     register u_char *cp;
  77.     register int n;
  78.     u_char *eom;
  79.     char *bp, **ap;
  80.     int type, class, buflen, ancount, qdcount;
  81.     int haveanswer, getclass = C_ANY;
  82.     char **hap;
  83.  
  84.     eom = answer->buf + anslen;
  85.     /*
  86.      * find first satisfactory answer
  87.      */
  88.     hp = &answer->hdr;
  89.     ancount = ntohs(hp->ancount);
  90.     qdcount = ntohs(hp->qdcount);
  91.     bp = hostbuf;
  92.     buflen = sizeof(hostbuf);
  93.     cp = answer->buf + sizeof(HEADER);
  94.     if (qdcount) {
  95.         if (iquery) {
  96.             if ((n = dn_expand((char *)answer->buf, eom,
  97.                  cp, bp, buflen)) < 0) {
  98.                 h_errno = NO_RECOVERY;
  99.                 return ((struct hostent *) NULL);
  100.             }
  101.             cp += n + QFIXEDSZ;
  102.             host.h_name = bp;
  103.             n = strlen(bp) + 1;
  104.             bp += n;
  105.             buflen -= n;
  106.         } else
  107.             cp += dn_skipname(cp, eom) + QFIXEDSZ;
  108.         while (--qdcount > 0)
  109.             cp += dn_skipname(cp, eom) + QFIXEDSZ;
  110.     } else if (iquery) {
  111.         if (hp->aa)
  112.             h_errno = HOST_NOT_FOUND;
  113.         else
  114.             h_errno = TRY_AGAIN;
  115.         return ((struct hostent *) NULL);
  116.     }
  117.     ap = host_aliases;
  118.     *ap = NULL;
  119.     host.h_aliases = host_aliases;
  120.     hap = h_addr_ptrs;
  121.     *hap = NULL;
  122. #if BSD >= 43 || defined(h_addr)    /* new-style hostent structure */
  123.     host.h_addr_list = h_addr_ptrs;
  124. #endif
  125.     haveanswer = 0;
  126.     while (--ancount >= 0 && cp < eom) {
  127.         if ((n = dn_expand((char *)answer->buf, eom, cp, bp, buflen)) < 0)
  128.             break;
  129.         cp += n;
  130.         type = _getshort(cp);
  131.          cp += sizeof(u_short);
  132.         class = _getshort(cp);
  133.          cp += sizeof(u_short) + sizeof(u_long);
  134.         n = _getshort(cp);
  135.         cp += sizeof(u_short);
  136.         if (type == T_CNAME) {
  137.             cp += n;
  138.             if (ap >= &host_aliases[MAXALIASES-1])
  139.                 continue;
  140.             *ap++ = bp;
  141.             n = strlen(bp) + 1;
  142.             bp += n;
  143.             buflen -= n;
  144.             continue;
  145.         }
  146.         if (iquery && type == T_PTR) {
  147.             if ((n = dn_expand((char *)answer->buf, eom,
  148.                 cp, bp, buflen)) < 0) {
  149.                 cp += n;
  150.                 continue;
  151.             }
  152.             cp += n;
  153.             host.h_name = bp;
  154.             return(&host);
  155.         }
  156.         if (iquery || type != T_A)  {
  157. #ifdef DEBUG
  158.             if (_res.options & RES_DEBUG)
  159.                 printf("unexpected answer type %d, size %d\n",
  160.                     type, n);
  161. #endif
  162.             cp += n;
  163.             continue;
  164.         }
  165.         if (haveanswer) {
  166.             if (n != host.h_length) {
  167.                 cp += n;
  168.                 continue;
  169.             }
  170.             if (class != getclass) {
  171.                 cp += n;
  172.                 continue;
  173.             }
  174.         } else {
  175.             host.h_length = n;
  176.             getclass = class;
  177.             host.h_addrtype = (class == C_IN) ? AF_INET : AF_UNSPEC;
  178.             if (!iquery) {
  179.                 host.h_name = bp;
  180.                 bp += strlen(bp) + 1;
  181.             }
  182.         }
  183.  
  184.         bp += sizeof(align) - ((u_long)bp % sizeof(align));
  185.  
  186.         if (bp + n >= &hostbuf[sizeof(hostbuf)]) {
  187. #ifdef DEBUG
  188.             if (_res.options & RES_DEBUG)
  189.                 printf("size (%d) too big\n", n);
  190. #endif
  191.             break;
  192.         }
  193.         bcopy(cp, *hap++ = bp, n);
  194.         bp +=n;
  195.         cp += n;
  196.         haveanswer++;
  197.     }
  198.     if (haveanswer) {
  199.         *ap = NULL;
  200. #if BSD >= 43 || defined(h_addr)    /* new-style hostent structure */
  201.         *hap = NULL;
  202. #endif
  203.         host.h_addr = h_addr_ptrs[0];
  204.         return (&host);
  205.     } else {
  206.         h_errno = TRY_AGAIN;
  207.         return ((struct hostent *) NULL);
  208.     }
  209. }
  210.  
  211. struct hostent *
  212. gethostbyname(name)
  213.     char *name;
  214. {
  215.     querybuf buf;
  216.     register char *cp;
  217.     int n;
  218.     extern struct hostent *_gethtbyname();
  219.  
  220.     /*
  221.      * disallow names consisting only of digits/dots, unless
  222.      * they end in a dot.
  223.      */
  224.     if (isdigit(name[0]))
  225.         for (cp = name;; ++cp) {
  226.             if (!*cp) {
  227.                 if (*--cp == '.')
  228.                     break;
  229.                 /*
  230.                  * All-numeric, no dot at the end.
  231.                  * Fake up a hostent as if we'd actually
  232.                  * done a lookup.  What if someone types
  233.                  * 255.255.255.255?  The test below will
  234.                  * succeed spuriously... ???
  235.                  */
  236.                 if ((host_addr.s_addr = inet_addr(name)) == -1) {
  237.                     h_errno = HOST_NOT_FOUND;
  238.                     return((struct hostent *) NULL);
  239.                 }
  240.                 host.h_name = name;
  241.                 host.h_aliases = host_aliases;
  242.                 host_aliases[0] = NULL;
  243.                 host.h_addrtype = AF_INET;
  244.                 host.h_length = sizeof(u_long);
  245.                 h_addr_ptrs[0] = (char *)&host_addr;
  246.                 h_addr_ptrs[1] = (char *)0;
  247. #if BSD >= 43 || defined(h_addr)    /* new-style hostent structure */
  248.                 host.h_addr_list = h_addr_ptrs;
  249. #endif
  250.                 host.h_addr = h_addr_ptrs[0];
  251.                 return (&host);
  252.             }
  253.             if (!isdigit(*cp) && *cp != '.') 
  254.                 break;
  255.         }
  256.  
  257.     if ((n = res_search(name, C_IN, T_A, buf.buf, sizeof(buf))) < 0) {
  258. #ifdef DEBUG
  259.         if (_res.options & RES_DEBUG)
  260.             printf("res_search failed\n");
  261. #endif
  262.         if (errno == ECONNREFUSED)
  263.             return (_gethtbyname(name));
  264.         else
  265.             return ((struct hostent *) NULL);
  266.     }
  267.     return (getanswer(&buf, n, 0));
  268. }
  269.  
  270. struct hostent *
  271. gethostbyaddr(addr, len, type)
  272.     char *addr;
  273.     int len, type;
  274. {
  275.     int n;
  276.     querybuf buf;
  277.     register struct hostent *hp;
  278.     char qbuf[MAXDNAME];
  279.     extern struct hostent *_gethtbyaddr();
  280.     
  281.     if (type != AF_INET)
  282.         return ((struct hostent *) NULL);
  283.     (void)sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa",
  284.         ((unsigned)addr[3] & 0xff),
  285.         ((unsigned)addr[2] & 0xff),
  286.         ((unsigned)addr[1] & 0xff),
  287.         ((unsigned)addr[0] & 0xff));
  288.     n = res_query(qbuf, C_IN, T_PTR, (char *)&buf, sizeof(buf));
  289.     if (n < 0) {
  290. #ifdef DEBUG
  291.         if (_res.options & RES_DEBUG)
  292.             printf("res_query failed\n");
  293. #endif
  294.         if (errno == ECONNREFUSED)
  295.             return (_gethtbyaddr(addr, len, type));
  296.         return ((struct hostent *) NULL);
  297.     }
  298.     hp = getanswer(&buf, n, 1);
  299.     if (hp == NULL)
  300.         return ((struct hostent *) NULL);
  301.     hp->h_addrtype = type;
  302.     hp->h_length = len;
  303.     h_addr_ptrs[0] = (char *)&host_addr;
  304.     h_addr_ptrs[1] = (char *)0;
  305.     host_addr = *(struct in_addr *)addr;
  306.     hp->h_addr = h_addr_ptrs[0];
  307.     return(hp);
  308. }
  309.  
  310. _sethtent(f)
  311.     int f;
  312. {
  313.     if (hostf == NULL)
  314.         hostf = fopen(HOSTDB, "r" );
  315.     else
  316.         rewind(hostf);
  317.     stayopen |= f;
  318. }
  319.  
  320. _endhtent()
  321. {
  322.     if (hostf && !stayopen) {
  323.         (void) fclose(hostf);
  324.         hostf = NULL;
  325.     }
  326. }
  327.  
  328. struct hostent *
  329. _gethtent()
  330. {
  331.     char *p;
  332.     register char *cp, **q;
  333.  
  334.     if (hostf == NULL && (hostf = fopen(HOSTDB, "r" )) == NULL)
  335.         return (NULL);
  336. again:
  337.     if ((p = fgets(hostbuf, BUFSIZ, hostf)) == NULL)
  338.         return (NULL);
  339.     if (*p == '#')
  340.         goto again;
  341.     cp = strpbrk(p, "#\n");
  342.     if (cp == NULL)
  343.         goto again;
  344.     *cp = '\0';
  345.     cp = strpbrk(p, " \t");
  346.     if (cp == NULL)
  347.         goto again;
  348.     *cp++ = '\0';
  349.     /* THIS STUFF IS INTERNET SPECIFIC */
  350. #if BSD >= 43 || defined(h_addr)    /* new-style hostent structure */
  351.     host.h_addr_list = host_addrs;
  352. #endif
  353.     host.h_addr = hostaddr;
  354.     *((u_long *)host.h_addr) = inet_addr(p);
  355.     host.h_length = sizeof (u_long);
  356.     host.h_addrtype = AF_INET;
  357.     while (*cp == ' ' || *cp == '\t')
  358.         cp++;
  359.     host.h_name = cp;
  360.     q = host.h_aliases = host_aliases;
  361.     cp = strpbrk(cp, " \t");
  362.     if (cp != NULL) 
  363.         *cp++ = '\0';
  364.     while (cp && *cp) {
  365.         if (*cp == ' ' || *cp == '\t') {
  366.             cp++;
  367.             continue;
  368.         }
  369.         if (q < &host_aliases[MAXALIASES - 1])
  370.             *q++ = cp;
  371.         cp = strpbrk(cp, " \t");
  372.         if (cp != NULL)
  373.             *cp++ = '\0';
  374.     }
  375.     *q = NULL;
  376.     return (&host);
  377. }
  378.  
  379. struct hostent *
  380. _gethtbyname(name)
  381.     char *name;
  382. {
  383.     register struct hostent *p;
  384.     register char **cp;
  385.     
  386.     _sethtent(0);
  387.     while (p = _gethtent()) {
  388.         if (strcasecmp(p->h_name, name) == 0)
  389.             break;
  390.         for (cp = p->h_aliases; *cp != 0; cp++)
  391.             if (strcasecmp(*cp, name) == 0)
  392.                 goto found;
  393.     }
  394. found:
  395.     _endhtent();
  396.     return (p);
  397. }
  398.  
  399. struct hostent *
  400. _gethtbyaddr(addr, len, type)
  401.     char *addr;
  402.     int len, type;
  403. {
  404.     register struct hostent *p;
  405.  
  406.     _sethtent(0);
  407.     while (p = _gethtent())
  408.         if (p->h_addrtype == type && !bcmp(p->h_addr, addr, len))
  409.             break;
  410.     _endhtent();
  411.     return (p);
  412. }
  413.