Annotation of 43BSDTahoe/lib/libc/net/named/gethostnamadr.c, revision 1.1

1.1     ! root        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.34 (Berkeley) 6/27/88";
        !            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: static char *any();
        !            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: static 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:        host.h_aliases = host_aliases;
        !           119:        hap = h_addr_ptrs;
        !           120: #if BSD >= 43 || defined(h_addr)       /* new-style hostent structure */
        !           121:        host.h_addr_list = h_addr_ptrs;
        !           122: #endif
        !           123:        haveanswer = 0;
        !           124:        while (--ancount >= 0 && cp < eom) {
        !           125:                if ((n = dn_expand((char *)answer->buf, eom, cp, bp, buflen)) < 0)
        !           126:                        break;
        !           127:                cp += n;
        !           128:                type = _getshort(cp);
        !           129:                cp += sizeof(u_short);
        !           130:                class = _getshort(cp);
        !           131:                cp += sizeof(u_short) + sizeof(u_long);
        !           132:                n = _getshort(cp);
        !           133:                cp += sizeof(u_short);
        !           134:                if (type == T_CNAME) {
        !           135:                        cp += n;
        !           136:                        if (ap >= &host_aliases[MAXALIASES-1])
        !           137:                                continue;
        !           138:                        *ap++ = bp;
        !           139:                        n = strlen(bp) + 1;
        !           140:                        bp += n;
        !           141:                        buflen -= n;
        !           142:                        continue;
        !           143:                }
        !           144:                if (iquery && type == T_PTR) {
        !           145:                        if ((n = dn_expand((char *)answer->buf, eom,
        !           146:                            cp, bp, buflen)) < 0) {
        !           147:                                cp += n;
        !           148:                                continue;
        !           149:                        }
        !           150:                        cp += n;
        !           151:                        host.h_name = bp;
        !           152:                        return(&host);
        !           153:                }
        !           154:                if (iquery || type != T_A)  {
        !           155: #ifdef DEBUG
        !           156:                        if (_res.options & RES_DEBUG)
        !           157:                                printf("unexpected answer type %d, size %d\n",
        !           158:                                        type, n);
        !           159: #endif
        !           160:                        cp += n;
        !           161:                        continue;
        !           162:                }
        !           163:                if (haveanswer) {
        !           164:                        if (n != host.h_length) {
        !           165:                                cp += n;
        !           166:                                continue;
        !           167:                        }
        !           168:                        if (class != getclass) {
        !           169:                                cp += n;
        !           170:                                continue;
        !           171:                        }
        !           172:                } else {
        !           173:                        host.h_length = n;
        !           174:                        getclass = class;
        !           175:                        host.h_addrtype = (class == C_IN) ? AF_INET : AF_UNSPEC;
        !           176:                        if (!iquery) {
        !           177:                                host.h_name = bp;
        !           178:                                bp += strlen(bp) + 1;
        !           179:                        }
        !           180:                }
        !           181: 
        !           182:                bp += sizeof(align) - ((u_long)bp % sizeof(align));
        !           183: 
        !           184:                if (bp + n >= &hostbuf[sizeof(hostbuf)]) {
        !           185: #ifdef DEBUG
        !           186:                        if (_res.options & RES_DEBUG)
        !           187:                                printf("size (%d) too big\n", n);
        !           188: #endif
        !           189:                        break;
        !           190:                }
        !           191:                bcopy(cp, *hap++ = bp, n);
        !           192:                bp +=n;
        !           193:                cp += n;
        !           194:                haveanswer++;
        !           195:        }
        !           196:        if (haveanswer) {
        !           197:                *ap = NULL;
        !           198: #if BSD >= 43 || defined(h_addr)       /* new-style hostent structure */
        !           199:                *hap = NULL;
        !           200: #else
        !           201:                host.h_addr = h_addr_ptrs[0];
        !           202: #endif
        !           203:                return (&host);
        !           204:        } else {
        !           205:                h_errno = TRY_AGAIN;
        !           206:                return ((struct hostent *) NULL);
        !           207:        }
        !           208: }
        !           209: 
        !           210: struct hostent *
        !           211: gethostbyname(name)
        !           212:        char *name;
        !           213: {
        !           214:        querybuf buf;
        !           215:        register char *cp;
        !           216:        int n;
        !           217:        struct hostent *hp;
        !           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:                                h_errno = HOST_NOT_FOUND;
        !           230:                                return ((struct hostent *) NULL);
        !           231:                        }
        !           232:                        if (!isdigit(*cp) && *cp != '.') 
        !           233:                                break;
        !           234:                }
        !           235: 
        !           236:        if ((n = res_search(name, C_IN, T_A, buf.buf, sizeof(buf))) < 0) {
        !           237: #ifdef DEBUG
        !           238:                if (_res.options & RES_DEBUG)
        !           239:                        printf("res_search failed\n");
        !           240: #endif
        !           241:                if (errno == ECONNREFUSED)
        !           242:                        return (_gethtbyname(name));
        !           243:                else
        !           244:                        return ((struct hostent *) NULL);
        !           245:        }
        !           246:        return (getanswer(&buf, n, 0));
        !           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 ((struct hostent *) 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_query(qbuf, C_IN, T_PTR, (char *)&buf, sizeof(buf));
        !           268:        if (n < 0) {
        !           269: #ifdef DEBUG
        !           270:                if (_res.options & RES_DEBUG)
        !           271:                        printf("res_query failed\n");
        !           272: #endif
        !           273:                if (errno == ECONNREFUSED)
        !           274:                        return (_gethtbyaddr(addr, len, type));
        !           275:                return ((struct hostent *) NULL);
        !           276:        }
        !           277:        hp = getanswer(&buf, n, 1);
        !           278:        if (hp == NULL)
        !           279:                return ((struct hostent *) NULL);
        !           280:        hp->h_addrtype = type;
        !           281:        hp->h_length = len;
        !           282:        h_addr_ptrs[0] = (char *)&host_addr;
        !           283:        h_addr_ptrs[1] = (char *)0;
        !           284:        host_addr = *(struct in_addr *)addr;
        !           285:        return(hp);
        !           286: }
        !           287: 
        !           288: _sethtent(f)
        !           289:        int f;
        !           290: {
        !           291:        if (hostf == NULL)
        !           292:                hostf = fopen(HOSTDB, "r" );
        !           293:        else
        !           294:                rewind(hostf);
        !           295:        stayopen |= f;
        !           296: }
        !           297: 
        !           298: _endhtent()
        !           299: {
        !           300:        if (hostf && !stayopen) {
        !           301:                (void) fclose(hostf);
        !           302:                hostf = NULL;
        !           303:        }
        !           304: }
        !           305: 
        !           306: struct hostent *
        !           307: _gethtent()
        !           308: {
        !           309:        char *p;
        !           310:        register char *cp, **q;
        !           311: 
        !           312:        if (hostf == NULL && (hostf = fopen(HOSTDB, "r" )) == NULL)
        !           313:                return (NULL);
        !           314: again:
        !           315:        if ((p = fgets(hostbuf, BUFSIZ, hostf)) == NULL)
        !           316:                return (NULL);
        !           317:        if (*p == '#')
        !           318:                goto again;
        !           319:        cp = any(p, "#\n");
        !           320:        if (cp == NULL)
        !           321:                goto again;
        !           322:        *cp = '\0';
        !           323:        cp = any(p, " \t");
        !           324:        if (cp == NULL)
        !           325:                goto again;
        !           326:        *cp++ = '\0';
        !           327:        /* THIS STUFF IS INTERNET SPECIFIC */
        !           328: #if BSD >= 43 || defined(h_addr)       /* new-style hostent structure */
        !           329:        host.h_addr_list = host_addrs;
        !           330: #endif
        !           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:        
        !           380:        _sethtent(0);
        !           381:        while (p = _gethtent()) {
        !           382:                if (strcasecmp(p->h_name, name) == 0)
        !           383:                        break;
        !           384:                for (cp = p->h_aliases; *cp != 0; cp++)
        !           385:                        if (strcasecmp(*cp, name) == 0)
        !           386:                                goto found;
        !           387:        }
        !           388: found:
        !           389:        _endhtent();
        !           390:        return (p);
        !           391: }
        !           392: 
        !           393: struct hostent *
        !           394: _gethtbyaddr(addr, len, type)
        !           395:        char *addr;
        !           396:        int len, type;
        !           397: {
        !           398:        register struct hostent *p;
        !           399: 
        !           400:        _sethtent(0);
        !           401:        while (p = _gethtent())
        !           402:                if (p->h_addrtype == type && !bcmp(p->h_addr, addr, len))
        !           403:                        break;
        !           404:        _endhtent();
        !           405:        return (p);
        !           406: }

unix.superglobalmegacorp.com

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