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