Home | History | Annotate | Line # | Download | only in libhack
gethost.c revision 1.7
      1 /*	$NetBSD: gethost.c,v 1.7 2001/06/15 17:26:51 tsutsui 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/cdefs.h>
     62 
     63 #ifdef __weak_alias
     64 #define gethostbyaddr		_gethostbyaddr
     65 #define gethostbyname		_gethostbyname
     66 #endif
     67 
     68 #include <sys/param.h>
     69 #include <sys/socket.h>
     70 #include <netinet/in.h>
     71 #include <arpa/inet.h>
     72 #include <arpa/nameser.h>
     73 #include <netdb.h>
     74 #include <resolv.h>
     75 #include <stdio.h>
     76 #include <ctype.h>
     77 #include <errno.h>
     78 #include <string.h>
     79 
     80 #ifdef __weak_alias
     81 __weak_alias(gethostbyaddr,_gethostbyaddr);
     82 __weak_alias(gethostbyname,_gethostbyname);
     83 #endif
     84 
     85 #define	MAXALIASES	35
     86 #define	MAXADDRS	35
     87 
     88 static char *h_addr_ptrs[MAXADDRS + 1];
     89 
     90 static struct hostent host;
     91 static char *host_aliases[MAXALIASES];
     92 static char hostbuf[BUFSIZ+1];
     93 static struct in_addr host_addr;
     94 static FILE *hostf = NULL;
     95 static int stayopen = 0;
     96 
     97 void _sethtent __P((int));
     98 void _endhtent __P((void));
     99 struct hostent *_gethtent __P((void));
    100 struct hostent *_gethtbyname __P((const char *));
    101 struct hostent *_gethtbyaddr __P((const char *, int, int));
    102 
    103 
    104 #if PACKETSZ > 1024
    105 #define	MAXPACKET	PACKETSZ
    106 #else
    107 #define	MAXPACKET	1024
    108 #endif
    109 
    110 extern int h_errno;
    111 
    112 struct hostent *
    113 gethostbyname(name)
    114 	const char *name;
    115 {
    116 	register const char *cp;
    117 
    118 	/*
    119 	 * disallow names consisting only of digits/dots, unless
    120 	 * they end in a dot.
    121 	 */
    122 	if (isdigit(name[0]))
    123 		for (cp = name;; ++cp) {
    124 			if (!*cp) {
    125 				if (*--cp == '.')
    126 					break;
    127 				/*
    128 				 * All-numeric, no dot at the end.
    129 				 * Fake up a hostent as if we'd actually
    130 				 * done a lookup.
    131 				 */
    132 				if (!inet_aton(name, &host_addr)) {
    133 					h_errno = HOST_NOT_FOUND;
    134 					return((struct hostent *) NULL);
    135 				}
    136 				host.h_name = (char *)name;
    137 				host.h_aliases = host_aliases;
    138 				host_aliases[0] = NULL;
    139 				host.h_addrtype = AF_INET;
    140 				host.h_length = sizeof(u_int32_t);
    141 				h_addr_ptrs[0] = (char *)&host_addr;
    142 				h_addr_ptrs[1] = NULL;
    143 				host.h_addr_list = h_addr_ptrs;
    144 				return (&host);
    145 			}
    146 			if (!isdigit(*cp) && *cp != '.')
    147 				break;
    148 		}
    149 
    150 	/* XXX - Force host table lookup. */
    151 	return (_gethtbyname(name));
    152 }
    153 
    154 struct hostent *
    155 gethostbyaddr(addr, len, type)
    156 	const char *addr;
    157 	socklen_t len;
    158 	int type;
    159 {
    160 	char qbuf[MAXDNAME];
    161 
    162 	if (type != AF_INET)
    163 		return ((struct hostent *) NULL);
    164 	(void)sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa",
    165 		((unsigned)addr[3] & 0xff),
    166 		((unsigned)addr[2] & 0xff),
    167 		((unsigned)addr[1] & 0xff),
    168 		((unsigned)addr[0] & 0xff));
    169 
    170 	/* XXX - Force host table lookup. */
    171 	return (_gethtbyaddr(addr, len, type));
    172 }
    173 
    174 void
    175 _sethtent(f)
    176 	int f;
    177 {
    178 	if (hostf == NULL)
    179 		hostf = fopen(_PATH_HOSTS, "r" );
    180 	else
    181 		rewind(hostf);
    182 	stayopen = f;
    183 }
    184 
    185 void
    186 _endhtent()
    187 {
    188 	if (hostf && !stayopen) {
    189 		(void) fclose(hostf);
    190 		hostf = NULL;
    191 	}
    192 }
    193 
    194 struct hostent *
    195 _gethtent()
    196 {
    197 	char *p;
    198 	register char *cp, **q;
    199 
    200 	if (hostf == NULL && (hostf = fopen(_PATH_HOSTS, "r" )) == NULL)
    201 		return (NULL);
    202 again:
    203 	if ((p = fgets(hostbuf, BUFSIZ, hostf)) == NULL)
    204 		return (NULL);
    205 	if (*p == '#')
    206 		goto again;
    207 	cp = strpbrk(p, "#\n");
    208 	if (cp == NULL)
    209 		goto again;
    210 	*cp = '\0';
    211 	cp = strpbrk(p, " \t");
    212 	if (cp == NULL)
    213 		goto again;
    214 	*cp++ = '\0';
    215 	/* THIS STUFF IS INTERNET SPECIFIC */
    216 	h_addr_ptrs[0] = (char *)&host_addr;
    217 	h_addr_ptrs[1] = NULL;
    218 	(void) inet_aton(p, &host_addr);
    219 	host.h_addr_list = h_addr_ptrs;
    220 	host.h_length = sizeof(u_int32_t);
    221 	host.h_addrtype = AF_INET;
    222 	while (*cp == ' ' || *cp == '\t')
    223 		cp++;
    224 	host.h_name = cp;
    225 	q = host.h_aliases = host_aliases;
    226 	cp = strpbrk(cp, " \t");
    227 	if (cp != NULL)
    228 		*cp++ = '\0';
    229 	while (cp && *cp) {
    230 		if (*cp == ' ' || *cp == '\t') {
    231 			cp++;
    232 			continue;
    233 		}
    234 		if (q < &host_aliases[MAXALIASES - 1])
    235 			*q++ = cp;
    236 		cp = strpbrk(cp, " \t");
    237 		if (cp != NULL)
    238 			*cp++ = '\0';
    239 	}
    240 	*q = NULL;
    241 	return (&host);
    242 }
    243 
    244 struct hostent *
    245 _gethtbyname(name)
    246 	const char *name;
    247 {
    248 	register struct hostent *p;
    249 	register char **cp;
    250 
    251 	_sethtent(0);
    252 	while ((p = _gethtent()) != NULL) {
    253 		if (strcasecmp(p->h_name, name) == 0)
    254 			break;
    255 		for (cp = p->h_aliases; *cp != 0; cp++)
    256 			if (strcasecmp(*cp, name) == 0)
    257 				goto found;
    258 	}
    259 found:
    260 	_endhtent();
    261 	if (p==NULL)
    262 		h_errno = HOST_NOT_FOUND;
    263 	return (p);
    264 }
    265 
    266 struct hostent *
    267 _gethtbyaddr(addr, len, type)
    268 	const char *addr;
    269 	int len, type;
    270 {
    271 	register struct hostent *p;
    272 
    273 	_sethtent(0);
    274 	while ((p = _gethtent()) != NULL)
    275 		if (p->h_addrtype == type && !memcmp(p->h_addr, addr, len))
    276 			break;
    277 	_endhtent();
    278 	if (p==NULL)
    279 		h_errno = HOST_NOT_FOUND;
    280 	return (p);
    281 }
    282 
    283