13070Spst/*
23070Spst * Copyright (c) 1983, 1993
33070Spst *	The Regents of the University of California.  All rights reserved.
43070Spst *
53070Spst * Redistribution and use in source and binary forms, with or without
63070Spst * modification, are permitted provided that the following conditions
73070Spst * are met:
83070Spst * 1. Redistributions of source code must retain the above copyright
93070Spst *    notice, this list of conditions and the following disclaimer.
103070Spst * 2. Redistributions in binary form must reproduce the above copyright
113070Spst *    notice, this list of conditions and the following disclaimer in the
123070Spst *    documentation and/or other materials provided with the distribution.
133070Spst * 4. Neither the name of the University nor the names of its contributors
143070Spst *    may be used to endorse or promote products derived from this software
153070Spst *    without specific prior written permission.
163070Spst *
173070Spst * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
183070Spst * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
193070Spst * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
203070Spst * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
213070Spst * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
223070Spst * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
233070Spst * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
243070Spst * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
253070Spst * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
263070Spst * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
273070Spst * SUCH DAMAGE.
283070Spst */
293070Spst
3013408Speter/* Portions Copyright (c) 1993 Carlos Leandro and Rui Salgueiro
3113408Speter *	Dep. Matematica Universidade de Coimbra, Portugal, Europe
3213408Speter *
3313408Speter * Permission to use, copy, modify, and distribute this software for any
3413408Speter * purpose with or without fee is hereby granted, provided that the above
3513408Speter * copyright notice and this permission notice appear in all copies.
3613408Speter *
3713408Speter * from getnetent.c	1.1 (Coimbra) 93/06/02
3813408Speter */
3913408Speter
403070Spst#if defined(LIBC_SCCS) && !defined(lint)
413070Spststatic char sccsid[] = "@(#)getnetent.c	8.1 (Berkeley) 6/4/93";
4226974Speterstatic char orig_rcsid[] = "From: Id: getnetent.c,v 8.4 1997/06/01 20:34:37 vixie Exp";
433070Spst#endif /* LIBC_SCCS and not lint */
4492986Sobrien#include <sys/cdefs.h>
4592986Sobrien__FBSDID("$FreeBSD$");
463070Spst
473070Spst#include <sys/types.h>
483070Spst#include <sys/socket.h>
493070Spst#include <netinet/in.h>
503070Spst#include <arpa/inet.h>
5113408Speter#include <arpa/nameser.h>
52211276Sume#include <errno.h>
533070Spst#include <netdb.h>
54156960Sume#include <resolv.h>
553070Spst#include <stdio.h>
563070Spst#include <string.h>
5765532Snectar#include <stdarg.h>
5865532Snectar#include <nsswitch.h>
59145626Sume#include "netdb_private.h"
603070Spst
613070Spstvoid
62145626Sume_setnethtent(int f, struct netent_data *ned)
633070Spst{
6413408Speter
65145626Sume	if (ned->netf == NULL)
66254700Sjilles		ned->netf = fopen(_PATH_NETWORKS, "re");
673070Spst	else
68145626Sume		rewind(ned->netf);
69145626Sume	ned->stayopen |= f;
703070Spst}
713070Spst
723070Spstvoid
73145626Sume_endnethtent(struct netent_data *ned)
743070Spst{
7513408Speter
76145626Sume	if (ned->netf) {
77145626Sume		fclose(ned->netf);
78145626Sume		ned->netf = NULL;
793070Spst	}
80145626Sume	ned->stayopen = 0;
813070Spst}
823070Spst
83157779Sumestatic int
84157779Sumegetnetent_p(struct netent *ne, struct netent_data *ned)
853070Spst{
86145626Sume	char *p, *bp, *ep;
8792889Sobrien	char *cp, **q;
88145626Sume	int len;
89145626Sume	char line[BUFSIZ + 1];
903070Spst
91145626Sume	if (ned->netf == NULL &&
92254700Sjilles	    (ned->netf = fopen(_PATH_NETWORKS, "re")) == NULL)
93157779Sume		return (-1);
943070Spstagain:
95145626Sume	p = fgets(line, sizeof line, ned->netf);
963070Spst	if (p == NULL)
97157779Sume		return (-1);
983070Spst	if (*p == '#')
993070Spst		goto again;
1003070Spst	cp = strpbrk(p, "#\n");
101139612Ssobomax	if (cp != NULL)
102139612Ssobomax		*cp = '\0';
103145626Sume	bp = ned->netbuf;
104145626Sume	ep = ned->netbuf + sizeof ned->netbuf;
105145626Sume	ne->n_name = bp;
1063070Spst	cp = strpbrk(p, " \t");
1073070Spst	if (cp == NULL)
1083070Spst		goto again;
1093070Spst	*cp++ = '\0';
110145626Sume	len = strlen(p) + 1;
111145626Sume	if (ep - bp < len) {
112156960Sume		RES_SET_H_ERRNO(__res_state(), NO_RECOVERY);
113157779Sume		return (-1);
114145626Sume	}
115145626Sume	strlcpy(bp, p, ep - bp);
116145626Sume	bp += len;
1173070Spst	while (*cp == ' ' || *cp == '\t')
1183070Spst		cp++;
1193070Spst	p = strpbrk(cp, " \t");
1203070Spst	if (p != NULL)
1213070Spst		*p++ = '\0';
122145626Sume	ne->n_net = inet_network(cp);
123145626Sume	ne->n_addrtype = AF_INET;
124145626Sume	q = ne->n_aliases = ned->net_aliases;
125145477Sume	if (p != NULL) {
1263070Spst		cp = p;
127145477Sume		while (cp && *cp) {
128145477Sume			if (*cp == ' ' || *cp == '\t') {
129145477Sume				cp++;
130145477Sume				continue;
131145477Sume			}
132145626Sume			if (q >= &ned->net_aliases[_MAXALIASES - 1])
133145626Sume				break;
134145626Sume			p = strpbrk(cp, " \t");
135145626Sume			if (p != NULL)
136145626Sume				*p++ = '\0';
137145626Sume			len = strlen(cp) + 1;
138145626Sume			if (ep - bp < len)
139145626Sume				break;
140145626Sume			strlcpy(bp, cp, ep - bp);
141145626Sume			*q++ = bp;
142145626Sume			bp += len;
143145626Sume			cp = p;
1443070Spst		}
1453070Spst	}
1463070Spst	*q = NULL;
147157779Sume	return (0);
1483070Spst}
1493070Spst
150157779Sumeint
151157779Sumegetnetent_r(struct netent *nptr, char *buffer, size_t buflen,
152157779Sume    struct netent **result, int *h_errnop)
153157779Sume{
154157779Sume	struct netent_data *ned;
155157779Sume	struct netent ne;
156157779Sume	res_state statp;
157157779Sume
158157779Sume	statp = __res_state();
159157779Sume	if ((ned = __netent_data_init()) == NULL) {
160157779Sume		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
161157779Sume		*h_errnop = statp->res_h_errno;
162157779Sume		return (-1);
163157779Sume	}
164157779Sume	if (getnetent_p(&ne, ned) != 0)
165157779Sume		return (-1);
166211276Sume	if (__copy_netent(&ne, nptr, buffer, buflen) != 0) {
167211276Sume		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
168211276Sume		*h_errnop = statp->res_h_errno;
169211276Sume		return ((errno != 0) ? errno : -1);
170211276Sume	}
171157779Sume	*result = nptr;
172157779Sume	return (0);
173157779Sume}
174157779Sume
175145626Sumestruct netent *
176145626Sumegetnetent(void)
177145626Sume{
178145626Sume	struct netdata *nd;
179157779Sume	struct netent *rval;
180157779Sume	int ret_h_errno;
181145626Sume
182145626Sume	if ((nd = __netdata_init()) == NULL)
183157779Sume		return (NULL);
184157779Sume	if (getnetent_r(&nd->net, nd->data, sizeof(nd->data), &rval,
185157779Sume	    &ret_h_errno) != 0)
186157779Sume		return (NULL);
187157779Sume	return (rval);
188145626Sume}
189145626Sume
19065532Snectarint
19165532Snectar_ht_getnetbyname(void *rval, void *cb_data, va_list ap)
1923070Spst{
19365532Snectar	const char *name;
194157779Sume	char *buffer;
195157779Sume	size_t buflen;
196157779Sume	int *errnop, *h_errnop;
197157779Sume	struct netent *nptr, ne;
198145626Sume	struct netent_data *ned;
19992889Sobrien	char **cp;
200157779Sume	res_state statp;
201145626Sume	int error;
2023070Spst
20365532Snectar	name = va_arg(ap, const char *);
204157779Sume	nptr = va_arg(ap, struct netent *);
205157779Sume	buffer = va_arg(ap, char *);
206157779Sume	buflen = va_arg(ap, size_t);
207157779Sume	errnop = va_arg(ap, int *);
208157779Sume	h_errnop = va_arg(ap, int *);
20965532Snectar
210157779Sume	statp = __res_state();
211157779Sume	if ((ned = __netent_data_init()) == NULL) {
212157779Sume		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
213157779Sume		*h_errnop = statp->res_h_errno;
214157779Sume		return (NS_UNAVAIL);
215157779Sume	}
216157779Sume
217157779Sume	_setnethtent(ned->stayopen, ned);
218302444Sngie	while ((error = getnetent_p(&ne, ned)) == 0) {
219157779Sume		if (strcasecmp(ne.n_name, name) == 0)
2203070Spst			break;
221302444Sngie		for (cp = ne.n_aliases; *cp != 0; cp++)
2223070Spst			if (strcasecmp(*cp, name) == 0)
2233070Spst				goto found;
2243070Spst	}
2253070Spstfound:
226145626Sume	if (!ned->stayopen)
227157779Sume		_endnethtent(ned);
228157779Sume	if (error != 0) {
229157779Sume		*h_errnop = statp->res_h_errno;
230157779Sume		return (NS_NOTFOUND);
231157779Sume	}
232157779Sume	if (__copy_netent(&ne, nptr, buffer, buflen) != 0) {
233211276Sume		*errnop = errno;
234211276Sume		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
235157779Sume		*h_errnop = statp->res_h_errno;
236211276Sume		return (NS_RETURN);
237157779Sume	}
238157779Sume	*((struct netent **)rval) = nptr;
239157779Sume	return (NS_SUCCESS);
2403070Spst}
2413070Spst
24265532Snectarint
24365532Snectar_ht_getnetbyaddr(void *rval, void *cb_data, va_list ap)
2443070Spst{
245146244Sume	uint32_t net;
24665532Snectar	int type;
247157779Sume	char *buffer;
248157779Sume	size_t buflen;
249157779Sume	int *errnop, *h_errnop;
250157779Sume	struct netent *nptr, ne;
251145626Sume	struct netent_data *ned;
252157779Sume	res_state statp;
253145626Sume	int error;
2543070Spst
255146244Sume	net = va_arg(ap, uint32_t);
25665532Snectar	type = va_arg(ap, int);
257157779Sume	nptr = va_arg(ap, struct netent *);
258157779Sume	buffer = va_arg(ap, char *);
259157779Sume	buflen = va_arg(ap, size_t);
260157779Sume	errnop = va_arg(ap, int *);
261157779Sume	h_errnop = va_arg(ap, int *);
26265532Snectar
263157779Sume	statp = __res_state();
264157779Sume	if ((ned = __netent_data_init()) == NULL) {
265157779Sume		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
266157779Sume		*h_errnop = statp->res_h_errno;
267157779Sume		return (NS_UNAVAIL);
268157779Sume	}
269157779Sume
270157779Sume	_setnethtent(ned->stayopen, ned);
271157779Sume	while ((error = getnetent_p(&ne, ned)) == 0)
272157779Sume		if (ne.n_addrtype == type && ne.n_net == net)
2733070Spst			break;
274145626Sume	if (!ned->stayopen)
275157779Sume		_endnethtent(ned);
276157779Sume	if (error != 0) {
277157779Sume		*h_errnop = statp->res_h_errno;
278157779Sume		return (NS_NOTFOUND);
279157779Sume	}
280157779Sume	if (__copy_netent(&ne, nptr, buffer, buflen) != 0) {
281211276Sume		*errnop = errno;
282211276Sume		RES_SET_H_ERRNO(statp, NETDB_INTERNAL);
283157779Sume		*h_errnop = statp->res_h_errno;
284211276Sume		return (NS_RETURN);
285157779Sume	}
286157779Sume	*((struct netent **)rval) = nptr;
287157779Sume	return (NS_SUCCESS);
2883070Spst}
289