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