Home | History | Annotate | Line # | Download | only in net
sethostent.c revision 1.20.36.1
      1  1.20.36.1    martin /*	$NetBSD: sethostent.c,v 1.20.36.1 2023/12/10 13:08:31 martin Exp $	*/
      2        1.4       cgd 
      3        1.1       cgd /*
      4        1.4       cgd  * Copyright (c) 1985, 1993
      5        1.4       cgd  *	The Regents of the University of California.  All rights reserved.
      6        1.1       cgd  *
      7        1.1       cgd  * Redistribution and use in source and binary forms, with or without
      8        1.1       cgd  * modification, are permitted provided that the following conditions
      9        1.1       cgd  * are met:
     10        1.1       cgd  * 1. Redistributions of source code must retain the above copyright
     11        1.1       cgd  *    notice, this list of conditions and the following disclaimer.
     12        1.1       cgd  * 2. Redistributions in binary form must reproduce the above copyright
     13        1.1       cgd  *    notice, this list of conditions and the following disclaimer in the
     14        1.1       cgd  *    documentation and/or other materials provided with the distribution.
     15       1.12       agc  * 3. Neither the name of the University nor the names of its contributors
     16        1.1       cgd  *    may be used to endorse or promote products derived from this software
     17        1.1       cgd  *    without specific prior written permission.
     18        1.1       cgd  *
     19        1.1       cgd  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     20        1.1       cgd  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     21        1.1       cgd  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     22        1.1       cgd  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     23        1.1       cgd  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     24        1.1       cgd  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     25        1.1       cgd  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     26        1.1       cgd  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     27        1.1       cgd  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     28        1.1       cgd  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     29        1.1       cgd  * SUCH DAMAGE.
     30        1.1       cgd  */
     31        1.1       cgd 
     32        1.7  christos #include <sys/cdefs.h>
     33        1.1       cgd #if defined(LIBC_SCCS) && !defined(lint)
     34        1.4       cgd #if 0
     35        1.4       cgd static char sccsid[] = "@(#)sethostent.c	8.1 (Berkeley) 6/4/93";
     36        1.9     perry static char rcsid[] = "Id: sethostent.c,v 8.5 1996/09/28 06:51:07 vixie Exp ";
     37        1.4       cgd #else
     38  1.20.36.1    martin __RCSID("$NetBSD: sethostent.c,v 1.20.36.1 2023/12/10 13:08:31 martin Exp $");
     39        1.4       cgd #endif
     40        1.1       cgd #endif /* LIBC_SCCS and not lint */
     41        1.1       cgd 
     42       1.10    kleink #include "namespace.h"
     43        1.1       cgd #include <sys/param.h>
     44        1.1       cgd #include <netinet/in.h>
     45        1.1       cgd #include <arpa/nameser.h>
     46       1.19  christos #include <arpa/inet.h>
     47       1.19  christos #include <assert.h>
     48       1.19  christos #include <string.h>
     49       1.19  christos #include <nsswitch.h>
     50        1.1       cgd #include <netdb.h>
     51        1.1       cgd #include <resolv.h>
     52       1.19  christos #include <errno.h>
     53       1.19  christos #include <stdlib.h>
     54       1.10    kleink 
     55       1.18  christos #include "hostent.h"
     56       1.18  christos 
     57       1.10    kleink #ifdef __weak_alias
     58       1.11   mycroft __weak_alias(sethostent,_sethostent)
     59       1.11   mycroft __weak_alias(endhostent,_endhostent)
     60       1.10    kleink #endif
     61        1.1       cgd 
     62       1.13  christos #ifndef _REENTRANT
     63       1.17      matt void	res_close(void);
     64       1.13  christos #endif
     65        1.6       mrg 
     66       1.19  christos static struct hostent *_hf_gethtbyname2(const char *, int, struct getnamaddr *);
     67       1.19  christos 
     68        1.1       cgd void
     69       1.13  christos /*ARGSUSED*/
     70       1.17      matt sethostent(int stayopen)
     71        1.1       cgd {
     72       1.13  christos #ifndef _REENTRANT
     73        1.5       mrg 	if ((_res.options & RES_INIT) == 0 && res_init() == -1)
     74        1.5       mrg 		return;
     75        1.1       cgd 	if (stayopen)
     76        1.1       cgd 		_res.options |= RES_STAYOPEN | RES_USEVC;
     77       1.13  christos #endif
     78       1.18  christos 	sethostent_r(&_h_file);
     79        1.1       cgd }
     80        1.1       cgd 
     81        1.1       cgd void
     82       1.17      matt endhostent(void)
     83        1.1       cgd {
     84       1.13  christos #ifndef _REENTRANT
     85        1.1       cgd 	_res.options &= ~(RES_STAYOPEN | RES_USEVC);
     86        1.6       mrg 	res_close();
     87       1.13  christos #endif
     88       1.18  christos 	endhostent_r(&_h_file);
     89        1.1       cgd }
     90       1.19  christos static const char *_h_hosts = _PATH_HOSTS;
     91       1.19  christos 
     92       1.19  christos void
     93       1.19  christos _hf_sethostsfile(const char *f) {
     94       1.19  christos 	_h_hosts = f;
     95       1.19  christos }
     96       1.19  christos 
     97       1.19  christos void
     98       1.19  christos sethostent_r(FILE **hf)
     99       1.19  christos {
    100       1.19  christos 	if (!*hf)
    101       1.19  christos 		*hf = fopen(_h_hosts, "re");
    102       1.19  christos 	else
    103       1.19  christos 		rewind(*hf);
    104       1.19  christos }
    105       1.19  christos 
    106       1.19  christos void
    107       1.19  christos endhostent_r(FILE **hf)
    108       1.19  christos {
    109       1.19  christos 	if (*hf) {
    110       1.19  christos 		(void)fclose(*hf);
    111       1.19  christos 		*hf = NULL;
    112       1.19  christos 	}
    113       1.19  christos }
    114       1.19  christos 
    115       1.19  christos /*ARGSUSED*/
    116       1.19  christos int
    117       1.19  christos _hf_gethtbyname(void *rv, void *cb_data, va_list ap)
    118       1.19  christos {
    119       1.19  christos 	struct hostent *hp;
    120       1.19  christos 	const char *name;
    121       1.19  christos 	int af;
    122       1.19  christos 	struct getnamaddr *info = rv;
    123       1.19  christos 
    124       1.19  christos 	_DIAGASSERT(rv != NULL);
    125       1.19  christos 
    126       1.19  christos 	name = va_arg(ap, char *);
    127       1.19  christos 	/* NOSTRICT skip string len */(void)va_arg(ap, int);
    128       1.19  christos 	af = va_arg(ap, int);
    129       1.19  christos 
    130       1.19  christos #if 0
    131       1.19  christos 	{
    132       1.19  christos 		res_state res = __res_get_state();
    133       1.19  christos 		if (res == NULL)
    134       1.19  christos 			return NS_NOTFOUND;
    135       1.19  christos 		if (res->options & RES_USE_INET6)
    136       1.19  christos 			hp = _hf_gethtbyname2(name, AF_INET6, info);
    137       1.19  christos 		else
    138       1.19  christos 			hp = NULL;
    139       1.19  christos 		if (hp == NULL)
    140       1.19  christos 			hp = _hf_gethtbyname2(name, AF_INET, info);
    141       1.19  christos 		__res_put_state(res);
    142       1.19  christos 	}
    143       1.19  christos #else
    144       1.19  christos 	hp = _hf_gethtbyname2(name, af, info);
    145       1.19  christos #endif
    146       1.19  christos 	if (hp == NULL) {
    147       1.19  christos 		*info->he = HOST_NOT_FOUND;
    148       1.19  christos 		return NS_NOTFOUND;
    149       1.19  christos 	}
    150       1.19  christos 	return NS_SUCCESS;
    151       1.19  christos }
    152       1.19  christos 
    153       1.19  christos struct hostent *
    154       1.19  christos _hf_gethtbyname2(const char *name, int af, struct getnamaddr *info)
    155       1.19  christos {
    156       1.19  christos 	struct hostent *hp, hent;
    157       1.19  christos 	char *buf, *ptr;
    158       1.19  christos 	size_t len, anum, num, i;
    159       1.19  christos 	FILE *hf;
    160       1.19  christos 	char *aliases[MAXALIASES];
    161       1.19  christos 	char *addr_ptrs[MAXADDRS];
    162       1.19  christos 
    163       1.19  christos 	_DIAGASSERT(name != NULL);
    164       1.19  christos 
    165       1.19  christos 	hf = NULL;
    166       1.19  christos 	sethostent_r(&hf);
    167       1.19  christos 	if (hf == NULL) {
    168       1.19  christos 		errno = EINVAL;
    169       1.19  christos 		*info->he = NETDB_INTERNAL;
    170       1.19  christos 		return NULL;
    171       1.19  christos 	}
    172       1.19  christos 
    173       1.19  christos 	if ((ptr = buf = malloc(len = info->buflen)) == NULL) {
    174  1.20.36.1    martin 		endhostent_r(&hf);
    175       1.19  christos 		*info->he = NETDB_INTERNAL;
    176       1.19  christos 		return NULL;
    177       1.19  christos 	}
    178       1.19  christos 
    179       1.19  christos 	anum = 0;		/* XXX: gcc */
    180       1.19  christos 	hent.h_name = NULL;	/* XXX: gcc */
    181       1.19  christos 	hent.h_addrtype = 0;	/* XXX: gcc */
    182       1.19  christos 	hent.h_length = 0;	/* XXX: gcc */
    183       1.19  christos 
    184       1.19  christos 	for (num = 0; num < MAXADDRS;) {
    185       1.19  christos 		info->hp->h_addrtype = af;
    186       1.19  christos 		info->hp->h_length = 0;
    187       1.19  christos 
    188       1.19  christos 		hp = gethostent_r(hf, info->hp, info->buf, info->buflen,
    189       1.19  christos 		    info->he);
    190       1.19  christos 		if (hp == NULL)
    191       1.19  christos 			break;
    192       1.19  christos 
    193       1.19  christos 		if (strcasecmp(hp->h_name, name) != 0) {
    194       1.19  christos 			char **cp;
    195       1.19  christos 			for (cp = hp->h_aliases; *cp != NULL; cp++)
    196       1.19  christos 				if (strcasecmp(*cp, name) == 0)
    197       1.19  christos 					break;
    198       1.19  christos 			if (*cp == NULL) continue;
    199       1.19  christos 		}
    200       1.19  christos 
    201       1.19  christos 		if (num == 0) {
    202       1.19  christos 			hent.h_addrtype = af = hp->h_addrtype;
    203       1.19  christos 			hent.h_length = hp->h_length;
    204       1.19  christos 
    205       1.19  christos 			HENT_SCOPY(hent.h_name, hp->h_name, ptr, len);
    206       1.19  christos 			for (anum = 0; hp->h_aliases[anum]; anum++) {
    207       1.19  christos 				if (anum >= __arraycount(aliases))
    208       1.19  christos 					goto nospc;
    209       1.19  christos 				HENT_SCOPY(aliases[anum], hp->h_aliases[anum],
    210       1.19  christos 				    ptr, len);
    211       1.19  christos 			}
    212       1.19  christos 			ptr = (void *)ALIGN(ptr);
    213       1.19  christos 			if ((size_t)(ptr - buf) >= info->buflen)
    214       1.19  christos 				goto nospc;
    215       1.19  christos 		}
    216       1.19  christos 
    217       1.19  christos 		if (num >= __arraycount(addr_ptrs))
    218       1.19  christos 			goto nospc;
    219       1.19  christos 		HENT_COPY(addr_ptrs[num], hp->h_addr_list[0], hp->h_length, ptr,
    220       1.19  christos 		    len);
    221       1.19  christos 		num++;
    222       1.19  christos 	}
    223       1.19  christos 	endhostent_r(&hf);
    224       1.19  christos 
    225       1.19  christos 	if (num == 0) {
    226       1.19  christos 		*info->he = HOST_NOT_FOUND;
    227       1.20  christos 		free(buf);
    228       1.19  christos 		return NULL;
    229       1.19  christos 	}
    230       1.19  christos 
    231       1.19  christos 	hp = info->hp;
    232       1.19  christos 	ptr = info->buf;
    233       1.19  christos 	len = info->buflen;
    234       1.19  christos 
    235       1.19  christos 	hp->h_addrtype = hent.h_addrtype;
    236       1.19  christos 	hp->h_length = hent.h_length;
    237       1.19  christos 
    238       1.19  christos 	HENT_ARRAY(hp->h_aliases, anum, ptr, len);
    239       1.19  christos 	HENT_ARRAY(hp->h_addr_list, num, ptr, len);
    240       1.19  christos 
    241       1.19  christos 	for (i = 0; i < num; i++)
    242       1.19  christos 		HENT_COPY(hp->h_addr_list[i], addr_ptrs[i], hp->h_length, ptr,
    243       1.19  christos 		    len);
    244       1.19  christos 	hp->h_addr_list[num] = NULL;
    245       1.19  christos 
    246       1.19  christos 	HENT_SCOPY(hp->h_name, hent.h_name, ptr, len);
    247       1.19  christos 
    248       1.19  christos 	for (i = 0; i < anum; i++)
    249       1.19  christos 		HENT_SCOPY(hp->h_aliases[i], aliases[i], ptr, len);
    250       1.19  christos 	hp->h_aliases[anum] = NULL;
    251       1.19  christos 
    252       1.20  christos 	free(buf);
    253       1.19  christos 	return hp;
    254       1.19  christos nospc:
    255  1.20.36.1    martin 	endhostent_r(&hf);
    256       1.19  christos 	*info->he = NETDB_INTERNAL;
    257       1.20  christos 	free(buf);
    258       1.19  christos 	errno = ENOSPC;
    259       1.19  christos 	return NULL;
    260       1.19  christos }
    261       1.19  christos 
    262       1.19  christos /*ARGSUSED*/
    263       1.19  christos int
    264       1.19  christos _hf_gethtbyaddr(void *rv, void *cb_data, va_list ap)
    265       1.19  christos {
    266       1.19  christos 	struct hostent *hp;
    267       1.19  christos 	const unsigned char *addr;
    268       1.19  christos 	struct getnamaddr *info = rv;
    269       1.19  christos 	FILE *hf;
    270       1.19  christos 
    271       1.19  christos 	_DIAGASSERT(rv != NULL);
    272       1.19  christos 
    273       1.19  christos 	addr = va_arg(ap, unsigned char *);
    274       1.19  christos 	info->hp->h_length = va_arg(ap, int);
    275       1.19  christos 	info->hp->h_addrtype = va_arg(ap, int);
    276       1.19  christos 
    277       1.19  christos 	hf = NULL;
    278       1.19  christos 	sethostent_r(&hf);
    279       1.19  christos 	if (hf == NULL) {
    280       1.19  christos 		*info->he = NETDB_INTERNAL;
    281       1.19  christos 		return NS_UNAVAIL;
    282       1.19  christos 	}
    283       1.19  christos 	while ((hp = gethostent_r(hf, info->hp, info->buf, info->buflen,
    284       1.19  christos 	    info->he)) != NULL)
    285       1.19  christos 		if (!memcmp(hp->h_addr_list[0], addr, (size_t)hp->h_length))
    286       1.19  christos 			break;
    287       1.19  christos 	endhostent_r(&hf);
    288       1.19  christos 
    289       1.19  christos 	if (hp == NULL) {
    290       1.19  christos 		*info->he = HOST_NOT_FOUND;
    291       1.19  christos 		return NS_NOTFOUND;
    292       1.19  christos 	}
    293       1.19  christos 	return NS_SUCCESS;
    294       1.19  christos }
    295