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