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

Defined functions

_endhtent defined in line 293; used 2 times
_gethtbyaddr defined in line 388; used 2 times
_gethtbyname defined in line 368; used 2 times
_gethtent defined in line 301; used 2 times
_sethtent defined in line 283; used 2 times
any defined in line 352; used 5 times
getanswer defined in line 64; used 2 times
gethostbyaddr defined in line 244; used 40 times
gethostbyname defined in line 205; used 76 times

Defined variables

HOSTDB defined in line 37; used 2 times
h_addr_ptrs defined in line 31; used 5 times
h_errno defined in line 61; used 5 times
host defined in line 33; used 19 times
host_addr defined in line 36; used 2 times
host_addrs defined in line 40; used 1 times
host_aliases defined in line 34; used 5 times
hostaddr defined in line 39; used 1 times
hostbuf defined in line 35; used 6 times
sccsid defined in line 14; never used
stayopen defined in line 41; used 2 times

Defined macros

MAXADDRS defined in line 29; used 2 times
MAXALIASES defined in line 28; used 3 times
MAXPACKET defined in line 47; used 1 times
  • in line 52
Last modified: 1994-07-11
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 5657
Valid CSS Valid XHTML 1.0 Strict