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

Defined functions

_endhtent defined in line 300; used 2 times
_gethtbyaddr defined in line 402; used 2 times
_gethtbyname defined in line 373; used 2 times
_gethtent defined in line 308; used 2 times
_sethtent defined in line 290; used 2 times
any defined in line 357; used 5 times
getanswer defined in line 53; used 2 times
gethostbyname defined in line 225; used 89 times

Defined variables

HOSTDB defined in line 31; used 2 times
h_addr_ptrs defined in line 25; used 4 times
host defined in line 27; used 18 times
host_addr defined in line 30; used 2 times
host_addrs defined in line 35; used 1 times
host_aliases defined in line 28; used 5 times
hostaddr defined in line 34; used 1 times
hostbuf defined in line 29; used 4 times
line defined in line 33; used 1 times
sccsid defined in line 8; never used
stayopen defined in line 36; used 2 times

Defined macros

MAXADDRS defined in line 23; used 2 times
MAXALIASES defined in line 22; used 3 times
Last modified: 1986-05-20
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2664
Valid CSS Valid XHTML 1.0 Strict