1*5bbd2a12Schristos /* $NetBSD: gethostent_r.c,v 1.1.1.2 2012/09/09 16:07:57 christos Exp $ */
2b5677b36Schristos
3b5677b36Schristos /*
4b5677b36Schristos * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
5b5677b36Schristos * Copyright (c) 1998-1999 by Internet Software Consortium.
6b5677b36Schristos *
7b5677b36Schristos * Permission to use, copy, modify, and distribute this software for any
8b5677b36Schristos * purpose with or without fee is hereby granted, provided that the above
9b5677b36Schristos * copyright notice and this permission notice appear in all copies.
10b5677b36Schristos *
11b5677b36Schristos * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
12b5677b36Schristos * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13b5677b36Schristos * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
14b5677b36Schristos * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15b5677b36Schristos * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16b5677b36Schristos * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
17b5677b36Schristos * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18b5677b36Schristos */
19b5677b36Schristos
20b5677b36Schristos #if defined(LIBC_SCCS) && !defined(lint)
21b5677b36Schristos static const char rcsid[] = "Id: gethostent_r.c,v 1.9 2005/09/03 12:41:37 marka Exp ";
22b5677b36Schristos #endif /* LIBC_SCCS and not lint */
23b5677b36Schristos
24b5677b36Schristos #include <port_before.h>
25b5677b36Schristos #if !defined(_REENTRANT) || !defined(DO_PTHREADS)
26b5677b36Schristos static int gethostent_r_not_required = 0;
27b5677b36Schristos #else
28b5677b36Schristos #include <errno.h>
29b5677b36Schristos #include <string.h>
30b5677b36Schristos #include <stdio.h>
31b5677b36Schristos #include <sys/types.h>
32b5677b36Schristos #include <netinet/in.h>
33b5677b36Schristos #include <netdb.h>
34b5677b36Schristos #include <sys/param.h>
35b5677b36Schristos #include <port_after.h>
36b5677b36Schristos
37b5677b36Schristos #ifdef HOST_R_RETURN
38b5677b36Schristos
39b5677b36Schristos static HOST_R_RETURN
40b5677b36Schristos copy_hostent(struct hostent *, struct hostent *, HOST_R_COPY_ARGS);
41b5677b36Schristos
42b5677b36Schristos HOST_R_RETURN
gethostbyname_r(const char * name,struct hostent * hptr,HOST_R_ARGS)43b5677b36Schristos gethostbyname_r(const char *name, struct hostent *hptr, HOST_R_ARGS) {
44b5677b36Schristos struct hostent *he = gethostbyname(name);
45b5677b36Schristos #ifdef HOST_R_SETANSWER
46b5677b36Schristos int n = 0;
47b5677b36Schristos #endif
48b5677b36Schristos
49b5677b36Schristos #ifdef HOST_R_ERRNO
50b5677b36Schristos HOST_R_ERRNO;
51b5677b36Schristos #endif
52b5677b36Schristos
53b5677b36Schristos #ifdef HOST_R_SETANSWER
54b5677b36Schristos if (he == NULL || (n = copy_hostent(he, hptr, HOST_R_COPY)) != 0)
55b5677b36Schristos *answerp = NULL;
56b5677b36Schristos else
57b5677b36Schristos *answerp = hptr;
58b5677b36Schristos
59b5677b36Schristos return (n);
60b5677b36Schristos #else
61b5677b36Schristos if (he == NULL)
62b5677b36Schristos return (HOST_R_BAD);
63b5677b36Schristos
64b5677b36Schristos return (copy_hostent(he, hptr, HOST_R_COPY));
65b5677b36Schristos #endif
66b5677b36Schristos }
67b5677b36Schristos
68b5677b36Schristos HOST_R_RETURN
gethostbyaddr_r(const char * addr,int len,int type,struct hostent * hptr,HOST_R_ARGS)69b5677b36Schristos gethostbyaddr_r(const char *addr, int len, int type,
70b5677b36Schristos struct hostent *hptr, HOST_R_ARGS) {
71b5677b36Schristos struct hostent *he = gethostbyaddr(addr, len, type);
72b5677b36Schristos #ifdef HOST_R_SETANSWER
73b5677b36Schristos int n = 0;
74b5677b36Schristos #endif
75b5677b36Schristos
76b5677b36Schristos #ifdef HOST_R_ERRNO
77b5677b36Schristos HOST_R_ERRNO;
78b5677b36Schristos #endif
79b5677b36Schristos
80b5677b36Schristos #ifdef HOST_R_SETANSWER
81b5677b36Schristos if (he == NULL || (n = copy_hostent(he, hptr, HOST_R_COPY)) != 0)
82b5677b36Schristos *answerp = NULL;
83b5677b36Schristos else
84b5677b36Schristos *answerp = hptr;
85b5677b36Schristos
86b5677b36Schristos return (n);
87b5677b36Schristos #else
88b5677b36Schristos if (he == NULL)
89b5677b36Schristos return (HOST_R_BAD);
90b5677b36Schristos
91b5677b36Schristos return (copy_hostent(he, hptr, HOST_R_COPY));
92b5677b36Schristos #endif
93b5677b36Schristos }
94b5677b36Schristos
95b5677b36Schristos /*%
96b5677b36Schristos * These assume a single context is in operation per thread.
97b5677b36Schristos * If this is not the case we will need to call irs directly
98b5677b36Schristos * rather than through the base functions.
99b5677b36Schristos */
100b5677b36Schristos
101b5677b36Schristos HOST_R_RETURN
gethostent_r(struct hostent * hptr,HOST_R_ARGS)102b5677b36Schristos gethostent_r(struct hostent *hptr, HOST_R_ARGS) {
103b5677b36Schristos struct hostent *he = gethostent();
104b5677b36Schristos #ifdef HOST_R_SETANSWER
105b5677b36Schristos int n = 0;
106b5677b36Schristos #endif
107b5677b36Schristos
108b5677b36Schristos #ifdef HOST_R_ERRNO
109b5677b36Schristos HOST_R_ERRNO;
110b5677b36Schristos #endif
111b5677b36Schristos
112b5677b36Schristos #ifdef HOST_R_SETANSWER
113b5677b36Schristos if (he == NULL || (n = copy_hostent(he, hptr, HOST_R_COPY)) != 0)
114b5677b36Schristos *answerp = NULL;
115b5677b36Schristos else
116b5677b36Schristos *answerp = hptr;
117b5677b36Schristos
118b5677b36Schristos return (n);
119b5677b36Schristos #else
120b5677b36Schristos if (he == NULL)
121b5677b36Schristos return (HOST_R_BAD);
122b5677b36Schristos
123b5677b36Schristos return (copy_hostent(he, hptr, HOST_R_COPY));
124b5677b36Schristos #endif
125b5677b36Schristos }
126b5677b36Schristos
127b5677b36Schristos HOST_R_SET_RETURN
128b5677b36Schristos #ifdef HOST_R_ENT_ARGS
sethostent_r(int stay_open,HOST_R_ENT_ARGS)129b5677b36Schristos sethostent_r(int stay_open, HOST_R_ENT_ARGS)
130b5677b36Schristos #else
131b5677b36Schristos sethostent_r(int stay_open)
132b5677b36Schristos #endif
133b5677b36Schristos {
134b5677b36Schristos #ifdef HOST_R_ENT_ARGS
135b5677b36Schristos UNUSED(hdptr);
136b5677b36Schristos #endif
137b5677b36Schristos sethostent(stay_open);
138b5677b36Schristos #ifdef HOST_R_SET_RESULT
139b5677b36Schristos return (HOST_R_SET_RESULT);
140b5677b36Schristos #endif
141b5677b36Schristos }
142b5677b36Schristos
143b5677b36Schristos HOST_R_END_RETURN
144b5677b36Schristos #ifdef HOST_R_ENT_ARGS
endhostent_r(HOST_R_ENT_ARGS)145b5677b36Schristos endhostent_r(HOST_R_ENT_ARGS)
146b5677b36Schristos #else
147b5677b36Schristos endhostent_r(void)
148b5677b36Schristos #endif
149b5677b36Schristos {
150b5677b36Schristos #ifdef HOST_R_ENT_ARGS
151b5677b36Schristos UNUSED(hdptr);
152b5677b36Schristos #endif
153b5677b36Schristos endhostent();
154b5677b36Schristos HOST_R_END_RESULT(HOST_R_OK);
155b5677b36Schristos }
156b5677b36Schristos
157b5677b36Schristos /* Private */
158b5677b36Schristos
159b5677b36Schristos #ifndef HOSTENT_DATA
160b5677b36Schristos static HOST_R_RETURN
copy_hostent(struct hostent * he,struct hostent * hptr,HOST_R_COPY_ARGS)161b5677b36Schristos copy_hostent(struct hostent *he, struct hostent *hptr, HOST_R_COPY_ARGS) {
162b5677b36Schristos char *cp;
163b5677b36Schristos char **ptr;
164b5677b36Schristos int i, n;
165b5677b36Schristos int nptr, len;
166b5677b36Schristos
167b5677b36Schristos /* Find out the amount of space required to store the answer. */
168b5677b36Schristos nptr = 2; /*%< NULL ptrs */
169b5677b36Schristos len = (char *)ALIGN(buf) - buf;
170b5677b36Schristos for (i = 0; he->h_addr_list[i]; i++, nptr++) {
171b5677b36Schristos len += he->h_length;
172b5677b36Schristos }
173b5677b36Schristos for (i = 0; he->h_aliases[i]; i++, nptr++) {
174b5677b36Schristos len += strlen(he->h_aliases[i]) + 1;
175b5677b36Schristos }
176b5677b36Schristos len += strlen(he->h_name) + 1;
177b5677b36Schristos len += nptr * sizeof(char*);
178b5677b36Schristos
179b5677b36Schristos if (len > buflen) {
180b5677b36Schristos errno = ERANGE;
181b5677b36Schristos return (HOST_R_BAD);
182b5677b36Schristos }
183b5677b36Schristos
184b5677b36Schristos /* copy address size and type */
185b5677b36Schristos hptr->h_addrtype = he->h_addrtype;
186b5677b36Schristos n = hptr->h_length = he->h_length;
187b5677b36Schristos
188b5677b36Schristos ptr = (char **)ALIGN(buf);
189b5677b36Schristos cp = (char *)ALIGN(buf) + nptr * sizeof(char *);
190b5677b36Schristos
191b5677b36Schristos /* copy address list */
192b5677b36Schristos hptr->h_addr_list = ptr;
193b5677b36Schristos for (i = 0; he->h_addr_list[i]; i++ , ptr++) {
194b5677b36Schristos memcpy(cp, he->h_addr_list[i], n);
195b5677b36Schristos hptr->h_addr_list[i] = cp;
196b5677b36Schristos cp += n;
197b5677b36Schristos }
198b5677b36Schristos hptr->h_addr_list[i] = NULL;
199b5677b36Schristos ptr++;
200b5677b36Schristos
201b5677b36Schristos /* copy official name */
202b5677b36Schristos n = strlen(he->h_name) + 1;
203b5677b36Schristos strcpy(cp, he->h_name);
204b5677b36Schristos hptr->h_name = cp;
205b5677b36Schristos cp += n;
206b5677b36Schristos
207b5677b36Schristos /* copy aliases */
208b5677b36Schristos hptr->h_aliases = ptr;
209b5677b36Schristos for (i = 0 ; he->h_aliases[i]; i++) {
210b5677b36Schristos n = strlen(he->h_aliases[i]) + 1;
211b5677b36Schristos strcpy(cp, he->h_aliases[i]);
212b5677b36Schristos hptr->h_aliases[i] = cp;
213b5677b36Schristos cp += n;
214b5677b36Schristos }
215b5677b36Schristos hptr->h_aliases[i] = NULL;
216b5677b36Schristos
217b5677b36Schristos return (HOST_R_OK);
218b5677b36Schristos }
219b5677b36Schristos #else /* !HOSTENT_DATA */
220b5677b36Schristos static int
copy_hostent(struct hostent * he,struct hostent * hptr,HOST_R_COPY_ARGS)221b5677b36Schristos copy_hostent(struct hostent *he, struct hostent *hptr, HOST_R_COPY_ARGS) {
222b5677b36Schristos char *cp, *eob;
223b5677b36Schristos int i, n;
224b5677b36Schristos
225b5677b36Schristos /* copy address size and type */
226b5677b36Schristos hptr->h_addrtype = he->h_addrtype;
227b5677b36Schristos n = hptr->h_length = he->h_length;
228b5677b36Schristos
229b5677b36Schristos /* copy up to first 35 addresses */
230b5677b36Schristos i = 0;
231b5677b36Schristos cp = hdptr->hostbuf;
232b5677b36Schristos eob = hdptr->hostbuf + sizeof(hdptr->hostbuf);
233b5677b36Schristos hptr->h_addr_list = hdptr->h_addr_ptrs;
234b5677b36Schristos while (he->h_addr_list[i] && i < (_MAXADDRS)) {
235b5677b36Schristos if (n < (eob - cp)) {
236b5677b36Schristos memcpy(cp, he->h_addr_list[i], n);
237b5677b36Schristos hptr->h_addr_list[i] = cp;
238b5677b36Schristos cp += n;
239b5677b36Schristos } else {
240b5677b36Schristos break;
241b5677b36Schristos }
242b5677b36Schristos i++;
243b5677b36Schristos }
244b5677b36Schristos hptr->h_addr_list[i] = NULL;
245b5677b36Schristos
246b5677b36Schristos /* copy official name */
247b5677b36Schristos if ((n = strlen(he->h_name) + 1) < (eob - cp)) {
248b5677b36Schristos strcpy(cp, he->h_name);
249b5677b36Schristos hptr->h_name = cp;
250b5677b36Schristos cp += n;
251b5677b36Schristos } else {
252b5677b36Schristos return (-1);
253b5677b36Schristos }
254b5677b36Schristos
255b5677b36Schristos /* copy aliases */
256b5677b36Schristos i = 0;
257b5677b36Schristos hptr->h_aliases = hdptr->host_aliases;
258b5677b36Schristos while (he->h_aliases[i] && i < (_MAXALIASES-1)) {
259b5677b36Schristos if ((n = strlen(he->h_aliases[i]) + 1) < (eob - cp)) {
260b5677b36Schristos strcpy(cp, he->h_aliases[i]);
261b5677b36Schristos hptr->h_aliases[i] = cp;
262b5677b36Schristos cp += n;
263b5677b36Schristos } else {
264b5677b36Schristos break;
265b5677b36Schristos }
266b5677b36Schristos i++;
267b5677b36Schristos }
268b5677b36Schristos hptr->h_aliases[i] = NULL;
269b5677b36Schristos
270b5677b36Schristos return (HOST_R_OK);
271b5677b36Schristos }
272b5677b36Schristos #endif /* !HOSTENT_DATA */
273b5677b36Schristos #else /* HOST_R_RETURN */
274b5677b36Schristos static int gethostent_r_unknown_system = 0;
275b5677b36Schristos #endif /* HOST_R_RETURN */
276b5677b36Schristos #endif /* !defined(_REENTRANT) || !defined(DO_PTHREADS) */
277b5677b36Schristos /*! \file */
278