Home | History | Annotate | Line # | Download | only in libhack
gethost.c revision 1.3
      1 /*	$NetBSD: gethost.c,v 1.3 1998/08/10 02:22:30 perry Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 1985, 1988, 1993
      5  *	The Regents of the University of California.  All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  * 3. All advertising materials mentioning features or use of this software
     16  *    must display the following acknowledgement:
     17  *	This product includes software developed by the University of
     18  *	California, Berkeley and its contributors.
     19  * 4. Neither the name of the University nor the names of its contributors
     20  *    may be used to endorse or promote products derived from this software
     21  *    without specific prior written permission.
     22  *
     23  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     33  * SUCH DAMAGE.
     34  * -
     35  * Portions Copyright (c) 1993 by Digital Equipment Corporation.
     36  *
     37  * Permission to use, copy, modify, and distribute this software for any
     38  * purpose with or without fee is hereby granted, provided that the above
     39  * copyright notice and this permission notice appear in all copies, and that
     40  * the name of Digital Equipment Corporation not be used in advertising or
     41  * publicity pertaining to distribution of the document or software without
     42  * specific, written prior permission.
     43  *
     44  * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
     45  * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
     46  * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
     47  * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
     48  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
     49  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
     50  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
     51  * SOFTWARE.
     52  * -
     53  * --Copyright--
     54  */
     55 
     56 /*
     57  * Copied from:  lib/libc/net/gethostnamadr.c
     58  * and then gutted, leaving only /etc/hosts support.
     59  */
     60 
     61 #include <sys/param.h>
     62 #include <sys/socket.h>
     63 #include <netinet/in.h>
     64 #include <arpa/inet.h>
     65 #include <arpa/nameser.h>
     66 #include <netdb.h>
     67 #include <resolv.h>
     68 #include <stdio.h>
     69 #include <ctype.h>
     70 #include <errno.h>
     71 #include <string.h>
     72 
     73 #define	MAXALIASES	35
     74 #define	MAXADDRS	35
     75 
     76 static char *h_addr_ptrs[MAXADDRS + 1];
     77 
     78 static struct hostent host;
     79 static char *host_aliases[MAXALIASES];
     80 static char hostbuf[BUFSIZ+1];
     81 static struct in_addr host_addr;
     82 static FILE *hostf = NULL;
     83 static int stayopen = 0;
     84 
     85 #if PACKETSZ > 1024
     86 #define	MAXPACKET	PACKETSZ
     87 #else
     88 #define	MAXPACKET	1024
     89 #endif
     90 
     91 extern int h_errno;
     92 
     93 struct hostent *
     94 gethostbyname(name)
     95 	const char *name;
     96 {
     97 	register const char *cp;
     98 	int n, i;
     99 	extern struct hostent *_gethtbyname();
    100 
    101 	/*
    102 	 * disallow names consisting only of digits/dots, unless
    103 	 * they end in a dot.
    104 	 */
    105 	if (isdigit(name[0]))
    106 		for (cp = name;; ++cp) {
    107 			if (!*cp) {
    108 				if (*--cp == '.')
    109 					break;
    110 				/*
    111 				 * All-numeric, no dot at the end.
    112 				 * Fake up a hostent as if we'd actually
    113 				 * done a lookup.
    114 				 */
    115 				if (!inet_aton(name, &host_addr)) {
    116 					h_errno = HOST_NOT_FOUND;
    117 					return((struct hostent *) NULL);
    118 				}
    119 				host.h_name = (char *)name;
    120 				host.h_aliases = host_aliases;
    121 				host_aliases[0] = NULL;
    122 				host.h_addrtype = AF_INET;
    123 				host.h_length = sizeof(u_int32_t);
    124 				h_addr_ptrs[0] = (char *)&host_addr;
    125 				h_addr_ptrs[1] = NULL;
    126 				host.h_addr_list = h_addr_ptrs;
    127 				return (&host);
    128 			}
    129 			if (!isdigit(*cp) && *cp != '.')
    130 				break;
    131 		}
    132 
    133 	/* XXX - Force host table lookup. */
    134 	return (_gethtbyname(name));
    135 }
    136 
    137 struct hostent *
    138 gethostbyaddr(addr, len, type)
    139 	const char *addr;
    140 	int len, type;
    141 {
    142 	int n, i;
    143 	char qbuf[MAXDNAME];
    144 	extern struct hostent *_gethtbyaddr();
    145 
    146 	if (type != AF_INET)
    147 		return ((struct hostent *) NULL);
    148 	(void)sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa",
    149 		((unsigned)addr[3] & 0xff),
    150 		((unsigned)addr[2] & 0xff),
    151 		((unsigned)addr[1] & 0xff),
    152 		((unsigned)addr[0] & 0xff));
    153 
    154 	/* XXX - Force host table lookup. */
    155 	return (_gethtbyaddr(addr, len, type));
    156 }
    157 
    158 void
    159 _sethtent(f)
    160 	int f;
    161 {
    162 	if (hostf == NULL)
    163 		hostf = fopen(_PATH_HOSTS, "r" );
    164 	else
    165 		rewind(hostf);
    166 	stayopen = f;
    167 }
    168 
    169 void
    170 _endhtent()
    171 {
    172 	if (hostf && !stayopen) {
    173 		(void) fclose(hostf);
    174 		hostf = NULL;
    175 	}
    176 }
    177 
    178 struct hostent *
    179 _gethtent()
    180 {
    181 	char *p;
    182 	register char *cp, **q;
    183 
    184 	if (hostf == NULL && (hostf = fopen(_PATH_HOSTS, "r" )) == NULL)
    185 		return (NULL);
    186 again:
    187 	if ((p = fgets(hostbuf, BUFSIZ, hostf)) == NULL)
    188 		return (NULL);
    189 	if (*p == '#')
    190 		goto again;
    191 	cp = strpbrk(p, "#\n");
    192 	if (cp == NULL)
    193 		goto again;
    194 	*cp = '\0';
    195 	cp = strpbrk(p, " \t");
    196 	if (cp == NULL)
    197 		goto again;
    198 	*cp++ = '\0';
    199 	/* THIS STUFF IS INTERNET SPECIFIC */
    200 	h_addr_ptrs[0] = (char *)&host_addr;
    201 	h_addr_ptrs[1] = NULL;
    202 	(void) inet_aton(p, &host_addr);
    203 	host.h_addr_list = h_addr_ptrs;
    204 	host.h_length = sizeof(u_int32_t);
    205 	host.h_addrtype = AF_INET;
    206 	while (*cp == ' ' || *cp == '\t')
    207 		cp++;
    208 	host.h_name = cp;
    209 	q = host.h_aliases = host_aliases;
    210 	cp = strpbrk(cp, " \t");
    211 	if (cp != NULL)
    212 		*cp++ = '\0';
    213 	while (cp && *cp) {
    214 		if (*cp == ' ' || *cp == '\t') {
    215 			cp++;
    216 			continue;
    217 		}
    218 		if (q < &host_aliases[MAXALIASES - 1])
    219 			*q++ = cp;
    220 		cp = strpbrk(cp, " \t");
    221 		if (cp != NULL)
    222 			*cp++ = '\0';
    223 	}
    224 	*q = NULL;
    225 	return (&host);
    226 }
    227 
    228 struct hostent *
    229 _gethtbyname(name)
    230 	char *name;
    231 {
    232 	register struct hostent *p;
    233 	register char **cp;
    234 
    235 	_sethtent(0);
    236 	while (p = _gethtent()) {
    237 		if (strcasecmp(p->h_name, name) == 0)
    238 			break;
    239 		for (cp = p->h_aliases; *cp != 0; cp++)
    240 			if (strcasecmp(*cp, name) == 0)
    241 				goto found;
    242 	}
    243 found:
    244 	_endhtent();
    245 	if (p==NULL)
    246 		h_errno = HOST_NOT_FOUND;
    247 	return (p);
    248 }
    249 
    250 struct hostent *
    251 _gethtbyaddr(addr, len, type)
    252 	const char *addr;
    253 	int len, type;
    254 {
    255 	register struct hostent *p;
    256 
    257 	_sethtent(0);
    258 	while (p = _gethtent())
    259 		if (p->h_addrtype == type && !memcmp(p->h_addr, addr, len))
    260 			break;
    261 	_endhtent();
    262 	if (p==NULL)
    263 		h_errno = HOST_NOT_FOUND;
    264 	return (p);
    265 }
    266 
    267