Annotation of 43BSD/lib/libc/net/named/gethostnamadr.c, revision 1.1.1.1

1.1       root        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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.