1/*	$NetBSD$	*/
2
3/*
4 * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
5 * Copyright (c) 1998-1999 by Internet Software Consortium.
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
17 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20#if defined(LIBC_SCCS) && !defined(lint)
21static const char rcsid[] = "Id: getnetent_r.c,v 1.6 2005/09/03 12:41:38 marka Exp";
22#endif /* LIBC_SCCS and not lint */
23
24#include <port_before.h>
25#if !defined(_REENTRANT) || !defined(DO_PTHREADS)
26	static int getnetent_r_not_required = 0;
27#else
28#include <errno.h>
29#include <string.h>
30#include <stdio.h>
31#include <sys/types.h>
32#include <netinet/in.h>
33#include <netdb.h>
34#include <sys/param.h>
35#include <port_after.h>
36
37#ifdef NET_R_RETURN
38
39static NET_R_RETURN
40copy_netent(struct netent *, struct netent *, NET_R_COPY_ARGS);
41
42NET_R_RETURN
43getnetbyname_r(const char *name,  struct netent *nptr, NET_R_ARGS) {
44	struct netent *ne = getnetbyname(name);
45#ifdef NET_R_SETANSWER
46	int n = 0;
47
48	if (ne == NULL || (n = copy_netent(ne, nptr, NET_R_COPY)) != 0)
49		*answerp = NULL;
50	else
51		*answerp = ne;
52	if (ne == NULL)
53		*h_errnop = h_errno;
54	return (n);
55#else
56	if (ne == NULL)
57		return (NET_R_BAD);
58
59	return (copy_netent(ne, nptr, NET_R_COPY));
60#endif
61}
62
63#ifndef GETNETBYADDR_ADDR_T
64#define GETNETBYADDR_ADDR_T long
65#endif
66NET_R_RETURN
67getnetbyaddr_r(GETNETBYADDR_ADDR_T addr, int type, struct netent *nptr, NET_R_ARGS) {
68	struct netent *ne = getnetbyaddr(addr, type);
69#ifdef NET_R_SETANSWER
70	int n = 0;
71
72	if (ne == NULL || (n = copy_netent(ne, nptr, NET_R_COPY)) != 0)
73		*answerp = NULL;
74	else
75		*answerp = ne;
76	if (ne == NULL)
77		*h_errnop = h_errno;
78	return (n);
79#else
80
81	if (ne == NULL)
82		return (NET_R_BAD);
83
84	return (copy_netent(ne, nptr, NET_R_COPY));
85#endif
86}
87
88/*%
89 *	These assume a single context is in operation per thread.
90 *	If this is not the case we will need to call irs directly
91 *	rather than through the base functions.
92 */
93
94NET_R_RETURN
95getnetent_r(struct netent *nptr, NET_R_ARGS) {
96	struct netent *ne = getnetent();
97#ifdef NET_R_SETANSWER
98	int n = 0;
99
100	if (ne == NULL || (n = copy_netent(ne, nptr, NET_R_COPY)) != 0)
101		*answerp = NULL;
102	else
103		*answerp = ne;
104	if (ne == NULL)
105		*h_errnop = h_errno;
106	return (n);
107#else
108
109	if (ne == NULL)
110		return (NET_R_BAD);
111
112	return (copy_netent(ne, nptr, NET_R_COPY));
113#endif
114}
115
116NET_R_SET_RETURN
117#ifdef NET_R_ENT_ARGS
118setnetent_r(int stay_open, NET_R_ENT_ARGS)
119#else
120setnetent_r(int stay_open)
121#endif
122{
123#ifdef NET_R_ENT_ARGS
124	UNUSED(ndptr);
125#endif
126	setnetent(stay_open);
127#ifdef NET_R_SET_RESULT
128	return (NET_R_SET_RESULT);
129#endif
130}
131
132NET_R_END_RETURN
133#ifdef NET_R_ENT_ARGS
134endnetent_r(NET_R_ENT_ARGS)
135#else
136endnetent_r()
137#endif
138{
139#ifdef NET_R_ENT_ARGS
140	UNUSED(ndptr);
141#endif
142	endnetent();
143	NET_R_END_RESULT(NET_R_OK);
144}
145
146/* Private */
147
148#ifndef NETENT_DATA
149static NET_R_RETURN
150copy_netent(struct netent *ne, struct netent *nptr, NET_R_COPY_ARGS) {
151	char *cp;
152	int i, n;
153	int numptr, len;
154
155	/* Find out the amount of space required to store the answer. */
156	numptr = 1; /*%< NULL ptr */
157	len = (char *)ALIGN(buf) - buf;
158	for (i = 0; ne->n_aliases[i]; i++, numptr++) {
159		len += strlen(ne->n_aliases[i]) + 1;
160	}
161	len += strlen(ne->n_name) + 1;
162	len += numptr * sizeof(char*);
163
164	if (len > (int)buflen) {
165		errno = ERANGE;
166		return (NET_R_BAD);
167	}
168
169	/* copy net value and type */
170	nptr->n_addrtype = ne->n_addrtype;
171	nptr->n_net = ne->n_net;
172
173	cp = (char *)ALIGN(buf) + numptr * sizeof(char *);
174
175	/* copy official name */
176	n = strlen(ne->n_name) + 1;
177	strcpy(cp, ne->n_name);
178	nptr->n_name = cp;
179	cp += n;
180
181	/* copy aliases */
182	nptr->n_aliases = (char **)ALIGN(buf);
183	for (i = 0 ; ne->n_aliases[i]; i++) {
184		n = strlen(ne->n_aliases[i]) + 1;
185		strcpy(cp, ne->n_aliases[i]);
186		nptr->n_aliases[i] = cp;
187		cp += n;
188	}
189	nptr->n_aliases[i] = NULL;
190
191	return (NET_R_OK);
192}
193#else /* !NETENT_DATA */
194static int
195copy_netent(struct netent *ne, struct netent *nptr, NET_R_COPY_ARGS) {
196	char *cp, *eob;
197	int i, n;
198
199	/* copy net value and type */
200	nptr->n_addrtype = ne->n_addrtype;
201	nptr->n_net = ne->n_net;
202
203	/* copy official name */
204	cp = ndptr->line;
205	eob = ndptr->line + sizeof(ndptr->line);
206	if ((n = strlen(ne->n_name) + 1) < (eob - cp)) {
207		strcpy(cp, ne->n_name);
208		nptr->n_name = cp;
209		cp += n;
210	} else {
211		return (-1);
212	}
213
214	/* copy aliases */
215	i = 0;
216	nptr->n_aliases = ndptr->net_aliases;
217	while (ne->n_aliases[i] && i < (_MAXALIASES-1)) {
218		if ((n = strlen(ne->n_aliases[i]) + 1) < (eob - cp)) {
219			strcpy(cp, ne->n_aliases[i]);
220			nptr->n_aliases[i] = cp;
221			cp += n;
222		} else {
223			break;
224		}
225		i++;
226	}
227	nptr->n_aliases[i] = NULL;
228
229	return (NET_R_OK);
230}
231#endif /* !NETENT_DATA */
232#else /* NET_R_RETURN */
233	static int getnetent_r_unknown_system = 0;
234#endif /* NET_R_RETURN */
235#endif /* !defined(_REENTRANT) || !defined(DO_PTHREADS) */
236/*! \file */
237