Annotation of 43BSD/lib/libc/net/named/gethostnamadr.c, revision 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.