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

unix.superglobalmegacorp.com

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