1*058a8681Skre /* $NetBSD: sethostent.c,v 1.21 2023/12/07 22:33:49 kre Exp $ */
2efba316dSchristos
3efba316dSchristos /*
4efba316dSchristos * Copyright (c) 1985, 1993
5efba316dSchristos * The Regents of the University of California. All rights reserved.
6efba316dSchristos *
7efba316dSchristos * Redistribution and use in source and binary forms, with or without
8efba316dSchristos * modification, are permitted provided that the following conditions
9efba316dSchristos * are met:
10efba316dSchristos * 1. Redistributions of source code must retain the above copyright
11efba316dSchristos * notice, this list of conditions and the following disclaimer.
12efba316dSchristos * 2. Redistributions in binary form must reproduce the above copyright
13efba316dSchristos * notice, this list of conditions and the following disclaimer in the
14efba316dSchristos * documentation and/or other materials provided with the distribution.
15efba316dSchristos * 3. Neither the name of the University nor the names of its contributors
16efba316dSchristos * may be used to endorse or promote products derived from this software
17efba316dSchristos * without specific prior written permission.
18efba316dSchristos *
19efba316dSchristos * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20efba316dSchristos * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21efba316dSchristos * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22efba316dSchristos * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23efba316dSchristos * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24efba316dSchristos * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25efba316dSchristos * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26efba316dSchristos * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27efba316dSchristos * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28efba316dSchristos * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29efba316dSchristos * SUCH DAMAGE.
30efba316dSchristos */
31efba316dSchristos
32efba316dSchristos #include <sys/cdefs.h>
33efba316dSchristos #if defined(LIBC_SCCS) && !defined(lint)
34efba316dSchristos #if 0
35efba316dSchristos static char sccsid[] = "@(#)sethostent.c 8.1 (Berkeley) 6/4/93";
36efba316dSchristos static char rcsid[] = "Id: sethostent.c,v 8.5 1996/09/28 06:51:07 vixie Exp ";
37efba316dSchristos #else
38*058a8681Skre __RCSID("$NetBSD: sethostent.c,v 1.21 2023/12/07 22:33:49 kre Exp $");
39efba316dSchristos #endif
40efba316dSchristos #endif /* LIBC_SCCS and not lint */
41efba316dSchristos
42efba316dSchristos #include "namespace.h"
43efba316dSchristos #include <sys/param.h>
44efba316dSchristos #include <netinet/in.h>
45efba316dSchristos #include <arpa/nameser.h>
464d322dedSchristos #include <arpa/inet.h>
474d322dedSchristos #include <assert.h>
484d322dedSchristos #include <string.h>
494d322dedSchristos #include <nsswitch.h>
50efba316dSchristos #include <netdb.h>
51efba316dSchristos #include <resolv.h>
524d322dedSchristos #include <errno.h>
534d322dedSchristos #include <stdlib.h>
54efba316dSchristos
5502dd2447Schristos #include "hostent.h"
5602dd2447Schristos
57efba316dSchristos #ifdef __weak_alias
58efba316dSchristos __weak_alias(sethostent,_sethostent)
59efba316dSchristos __weak_alias(endhostent,_endhostent)
60efba316dSchristos #endif
61efba316dSchristos
62efba316dSchristos #ifndef _REENTRANT
63504f8671Smatt void res_close(void);
64efba316dSchristos #endif
65efba316dSchristos
664d322dedSchristos static struct hostent *_hf_gethtbyname2(const char *, int, struct getnamaddr *);
674d322dedSchristos
68efba316dSchristos void
69efba316dSchristos /*ARGSUSED*/
sethostent(int stayopen)70504f8671Smatt sethostent(int stayopen)
71efba316dSchristos {
72efba316dSchristos #ifndef _REENTRANT
73efba316dSchristos if ((_res.options & RES_INIT) == 0 && res_init() == -1)
74efba316dSchristos return;
75efba316dSchristos if (stayopen)
76efba316dSchristos _res.options |= RES_STAYOPEN | RES_USEVC;
77efba316dSchristos #endif
7802dd2447Schristos sethostent_r(&_h_file);
79efba316dSchristos }
80efba316dSchristos
81efba316dSchristos void
endhostent(void)82504f8671Smatt endhostent(void)
83efba316dSchristos {
84efba316dSchristos #ifndef _REENTRANT
85efba316dSchristos _res.options &= ~(RES_STAYOPEN | RES_USEVC);
86efba316dSchristos res_close();
87efba316dSchristos #endif
8802dd2447Schristos endhostent_r(&_h_file);
89efba316dSchristos }
904d322dedSchristos static const char *_h_hosts = _PATH_HOSTS;
914d322dedSchristos
924d322dedSchristos void
_hf_sethostsfile(const char * f)934d322dedSchristos _hf_sethostsfile(const char *f) {
944d322dedSchristos _h_hosts = f;
954d322dedSchristos }
964d322dedSchristos
974d322dedSchristos void
sethostent_r(FILE ** hf)984d322dedSchristos sethostent_r(FILE **hf)
994d322dedSchristos {
1004d322dedSchristos if (!*hf)
1014d322dedSchristos *hf = fopen(_h_hosts, "re");
1024d322dedSchristos else
1034d322dedSchristos rewind(*hf);
1044d322dedSchristos }
1054d322dedSchristos
1064d322dedSchristos void
endhostent_r(FILE ** hf)1074d322dedSchristos endhostent_r(FILE **hf)
1084d322dedSchristos {
1094d322dedSchristos if (*hf) {
1104d322dedSchristos (void)fclose(*hf);
1114d322dedSchristos *hf = NULL;
1124d322dedSchristos }
1134d322dedSchristos }
1144d322dedSchristos
1154d322dedSchristos /*ARGSUSED*/
1164d322dedSchristos int
_hf_gethtbyname(void * rv,void * cb_data,va_list ap)1174d322dedSchristos _hf_gethtbyname(void *rv, void *cb_data, va_list ap)
1184d322dedSchristos {
1194d322dedSchristos struct hostent *hp;
1204d322dedSchristos const char *name;
1214d322dedSchristos int af;
1224d322dedSchristos struct getnamaddr *info = rv;
1234d322dedSchristos
1244d322dedSchristos _DIAGASSERT(rv != NULL);
1254d322dedSchristos
1264d322dedSchristos name = va_arg(ap, char *);
1274d322dedSchristos /* NOSTRICT skip string len */(void)va_arg(ap, int);
1284d322dedSchristos af = va_arg(ap, int);
1294d322dedSchristos
1304d322dedSchristos #if 0
1314d322dedSchristos {
1324d322dedSchristos res_state res = __res_get_state();
1334d322dedSchristos if (res == NULL)
1344d322dedSchristos return NS_NOTFOUND;
1354d322dedSchristos if (res->options & RES_USE_INET6)
1364d322dedSchristos hp = _hf_gethtbyname2(name, AF_INET6, info);
1374d322dedSchristos else
1384d322dedSchristos hp = NULL;
1394d322dedSchristos if (hp == NULL)
1404d322dedSchristos hp = _hf_gethtbyname2(name, AF_INET, info);
1414d322dedSchristos __res_put_state(res);
1424d322dedSchristos }
1434d322dedSchristos #else
1444d322dedSchristos hp = _hf_gethtbyname2(name, af, info);
1454d322dedSchristos #endif
1464d322dedSchristos if (hp == NULL) {
1474d322dedSchristos *info->he = HOST_NOT_FOUND;
1484d322dedSchristos return NS_NOTFOUND;
1494d322dedSchristos }
1504d322dedSchristos return NS_SUCCESS;
1514d322dedSchristos }
1524d322dedSchristos
1534d322dedSchristos struct hostent *
_hf_gethtbyname2(const char * name,int af,struct getnamaddr * info)1544d322dedSchristos _hf_gethtbyname2(const char *name, int af, struct getnamaddr *info)
1554d322dedSchristos {
1564d322dedSchristos struct hostent *hp, hent;
1574d322dedSchristos char *buf, *ptr;
1584d322dedSchristos size_t len, anum, num, i;
1594d322dedSchristos FILE *hf;
1604d322dedSchristos char *aliases[MAXALIASES];
1614d322dedSchristos char *addr_ptrs[MAXADDRS];
1624d322dedSchristos
1634d322dedSchristos _DIAGASSERT(name != NULL);
1644d322dedSchristos
1654d322dedSchristos hf = NULL;
1664d322dedSchristos sethostent_r(&hf);
1674d322dedSchristos if (hf == NULL) {
1684d322dedSchristos errno = EINVAL;
1694d322dedSchristos *info->he = NETDB_INTERNAL;
1704d322dedSchristos return NULL;
1714d322dedSchristos }
1724d322dedSchristos
1734d322dedSchristos if ((ptr = buf = malloc(len = info->buflen)) == NULL) {
174*058a8681Skre endhostent_r(&hf);
1754d322dedSchristos *info->he = NETDB_INTERNAL;
1764d322dedSchristos return NULL;
1774d322dedSchristos }
1784d322dedSchristos
1794d322dedSchristos anum = 0; /* XXX: gcc */
1804d322dedSchristos hent.h_name = NULL; /* XXX: gcc */
1814d322dedSchristos hent.h_addrtype = 0; /* XXX: gcc */
1824d322dedSchristos hent.h_length = 0; /* XXX: gcc */
1834d322dedSchristos
1844d322dedSchristos for (num = 0; num < MAXADDRS;) {
1854d322dedSchristos info->hp->h_addrtype = af;
1864d322dedSchristos info->hp->h_length = 0;
1874d322dedSchristos
1884d322dedSchristos hp = gethostent_r(hf, info->hp, info->buf, info->buflen,
1894d322dedSchristos info->he);
1904d322dedSchristos if (hp == NULL)
1914d322dedSchristos break;
1924d322dedSchristos
1934d322dedSchristos if (strcasecmp(hp->h_name, name) != 0) {
1944d322dedSchristos char **cp;
1954d322dedSchristos for (cp = hp->h_aliases; *cp != NULL; cp++)
1964d322dedSchristos if (strcasecmp(*cp, name) == 0)
1974d322dedSchristos break;
1984d322dedSchristos if (*cp == NULL) continue;
1994d322dedSchristos }
2004d322dedSchristos
2014d322dedSchristos if (num == 0) {
2024d322dedSchristos hent.h_addrtype = af = hp->h_addrtype;
2034d322dedSchristos hent.h_length = hp->h_length;
2044d322dedSchristos
2054d322dedSchristos HENT_SCOPY(hent.h_name, hp->h_name, ptr, len);
2064d322dedSchristos for (anum = 0; hp->h_aliases[anum]; anum++) {
2074d322dedSchristos if (anum >= __arraycount(aliases))
2084d322dedSchristos goto nospc;
2094d322dedSchristos HENT_SCOPY(aliases[anum], hp->h_aliases[anum],
2104d322dedSchristos ptr, len);
2114d322dedSchristos }
2124d322dedSchristos ptr = (void *)ALIGN(ptr);
2134d322dedSchristos if ((size_t)(ptr - buf) >= info->buflen)
2144d322dedSchristos goto nospc;
2154d322dedSchristos }
2164d322dedSchristos
2174d322dedSchristos if (num >= __arraycount(addr_ptrs))
2184d322dedSchristos goto nospc;
2194d322dedSchristos HENT_COPY(addr_ptrs[num], hp->h_addr_list[0], hp->h_length, ptr,
2204d322dedSchristos len);
2214d322dedSchristos num++;
2224d322dedSchristos }
2234d322dedSchristos endhostent_r(&hf);
2244d322dedSchristos
2254d322dedSchristos if (num == 0) {
2264d322dedSchristos *info->he = HOST_NOT_FOUND;
227e2ecf243Schristos free(buf);
2284d322dedSchristos return NULL;
2294d322dedSchristos }
2304d322dedSchristos
2314d322dedSchristos hp = info->hp;
2324d322dedSchristos ptr = info->buf;
2334d322dedSchristos len = info->buflen;
2344d322dedSchristos
2354d322dedSchristos hp->h_addrtype = hent.h_addrtype;
2364d322dedSchristos hp->h_length = hent.h_length;
2374d322dedSchristos
2384d322dedSchristos HENT_ARRAY(hp->h_aliases, anum, ptr, len);
2394d322dedSchristos HENT_ARRAY(hp->h_addr_list, num, ptr, len);
2404d322dedSchristos
2414d322dedSchristos for (i = 0; i < num; i++)
2424d322dedSchristos HENT_COPY(hp->h_addr_list[i], addr_ptrs[i], hp->h_length, ptr,
2434d322dedSchristos len);
2444d322dedSchristos hp->h_addr_list[num] = NULL;
2454d322dedSchristos
2464d322dedSchristos HENT_SCOPY(hp->h_name, hent.h_name, ptr, len);
2474d322dedSchristos
2484d322dedSchristos for (i = 0; i < anum; i++)
2494d322dedSchristos HENT_SCOPY(hp->h_aliases[i], aliases[i], ptr, len);
2504d322dedSchristos hp->h_aliases[anum] = NULL;
2514d322dedSchristos
252e2ecf243Schristos free(buf);
2534d322dedSchristos return hp;
2544d322dedSchristos nospc:
255*058a8681Skre endhostent_r(&hf);
2564d322dedSchristos *info->he = NETDB_INTERNAL;
257e2ecf243Schristos free(buf);
2584d322dedSchristos errno = ENOSPC;
2594d322dedSchristos return NULL;
2604d322dedSchristos }
2614d322dedSchristos
2624d322dedSchristos /*ARGSUSED*/
2634d322dedSchristos int
_hf_gethtbyaddr(void * rv,void * cb_data,va_list ap)2644d322dedSchristos _hf_gethtbyaddr(void *rv, void *cb_data, va_list ap)
2654d322dedSchristos {
2664d322dedSchristos struct hostent *hp;
2674d322dedSchristos const unsigned char *addr;
2684d322dedSchristos struct getnamaddr *info = rv;
2694d322dedSchristos FILE *hf;
2704d322dedSchristos
2714d322dedSchristos _DIAGASSERT(rv != NULL);
2724d322dedSchristos
2734d322dedSchristos addr = va_arg(ap, unsigned char *);
2744d322dedSchristos info->hp->h_length = va_arg(ap, int);
2754d322dedSchristos info->hp->h_addrtype = va_arg(ap, int);
2764d322dedSchristos
2774d322dedSchristos hf = NULL;
2784d322dedSchristos sethostent_r(&hf);
2794d322dedSchristos if (hf == NULL) {
2804d322dedSchristos *info->he = NETDB_INTERNAL;
2814d322dedSchristos return NS_UNAVAIL;
2824d322dedSchristos }
2834d322dedSchristos while ((hp = gethostent_r(hf, info->hp, info->buf, info->buflen,
2844d322dedSchristos info->he)) != NULL)
2854d322dedSchristos if (!memcmp(hp->h_addr_list[0], addr, (size_t)hp->h_length))
2864d322dedSchristos break;
2874d322dedSchristos endhostent_r(&hf);
2884d322dedSchristos
2894d322dedSchristos if (hp == NULL) {
2904d322dedSchristos *info->he = HOST_NOT_FOUND;
2914d322dedSchristos return NS_NOTFOUND;
2924d322dedSchristos }
2934d322dedSchristos return NS_SUCCESS;
2944d322dedSchristos }
295