2 * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (c) 1998-1999 by Internet Software Consortium.
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
15 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 #if defined(LIBC_SCCS) && !defined(lint)
19 static const char rcsid
[] = "$Id: gethostent_r.c,v 1.4.2.2 2004/04/22 03:21:02 marka Exp $";
20 #endif /* LIBC_SCCS and not lint */
22 #include <port_before.h>
23 #if !defined(_REENTRANT) || !defined(DO_PTHREADS)
24 static int gethostent_r_not_required
= 0;
29 #include <sys/types.h>
30 #include <netinet/in.h>
32 #include <sys/param.h>
33 #include <port_after.h>
38 copy_hostent(struct hostent
*, struct hostent
*, HOST_R_COPY_ARGS
);
41 gethostbyname_r(const char *name
, struct hostent
*hptr
, HOST_R_ARGS
) {
42 struct hostent
*he
= gethostbyname(name
);
43 #ifdef HOST_R_SETANSWER
49 #ifdef HOST_R_SETANSWER
50 if (he
== NULL
|| (n
= copy_hostent(he
, hptr
, HOST_R_COPY
)) == 0)
60 return (copy_hostent(he
, hptr
, HOST_R_COPY
));
65 gethostbyaddr_r(const char *addr
, int len
, int type
,
66 struct hostent
*hptr
, HOST_R_ARGS
) {
67 struct hostent
*he
= gethostbyaddr(addr
, len
, type
);
68 #ifdef HOST_R_SETANSWER
74 #ifdef HOST_R_SETANSWER
75 if (he
== NULL
|| (n
= copy_hostent(he
, hptr
, HOST_R_COPY
)) == 0)
85 return (copy_hostent(he
, hptr
, HOST_R_COPY
));
90 * These assume a single context is in operation per thread.
91 * If this is not the case we will need to call irs directly
92 * rather than through the base functions.
96 gethostent_r(struct hostent
*hptr
, HOST_R_ARGS
) {
97 struct hostent
*he
= gethostent();
98 #ifdef HOST_R_SETANSWER
104 #ifdef HOST_R_SETANSWER
105 if (he
== NULL
|| (n
= copy_hostent(he
, hptr
, HOST_R_COPY
)) == 0)
115 return (copy_hostent(he
, hptr
, HOST_R_COPY
));
120 #ifdef HOST_R_ENT_ARGS
121 sethostent_r(int stay_open
, HOST_R_ENT_ARGS
)
123 sethostent_r(int stay_open
)
126 sethostent(stay_open
);
127 #ifdef HOST_R_SET_RESULT
128 return (HOST_R_SET_RESULT
);
133 #ifdef HOST_R_ENT_ARGS
134 endhostent_r(HOST_R_ENT_ARGS
)
140 HOST_R_END_RESULT(HOST_R_OK
);
147 copy_hostent(struct hostent
*he
, struct hostent
*hptr
, HOST_R_COPY_ARGS
) {
153 /* Find out the amount of space required to store the answer. */
154 nptr
= 2; /* NULL ptrs */
155 len
= (char *)ALIGN(buf
) - buf
;
156 for (i
= 0; he
->h_addr_list
[i
]; i
++, nptr
++) {
159 for (i
= 0; he
->h_aliases
[i
]; i
++, nptr
++) {
160 len
+= strlen(he
->h_aliases
[i
]) + 1;
162 len
+= strlen(he
->h_name
) + 1;
163 len
+= nptr
* sizeof(char*);
170 /* copy address size and type */
171 hptr
->h_addrtype
= he
->h_addrtype
;
172 n
= hptr
->h_length
= he
->h_length
;
174 ptr
= (char **)ALIGN(buf
);
175 cp
= (char *)ALIGN(buf
) + nptr
* sizeof(char *);
177 /* copy address list */
178 hptr
->h_addr_list
= ptr
;
179 for (i
= 0; he
->h_addr_list
[i
]; i
++ , ptr
++) {
180 memcpy(cp
, he
->h_addr_list
[i
], n
);
181 hptr
->h_addr_list
[i
] = cp
;
184 hptr
->h_addr_list
[i
] = NULL
;
187 /* copy official name */
188 n
= strlen(he
->h_name
) + 1;
189 strcpy(cp
, he
->h_name
);
194 hptr
->h_aliases
= ptr
;
195 for (i
= 0 ; he
->h_aliases
[i
]; i
++) {
196 n
= strlen(he
->h_aliases
[i
]) + 1;
197 strcpy(cp
, he
->h_aliases
[i
]);
198 hptr
->h_aliases
[i
] = cp
;
201 hptr
->h_aliases
[i
] = NULL
;
205 #else /* !HOSTENT_DATA */
207 copy_hostent(struct hostent
*he
, struct hostent
*hptr
, HOST_R_COPY_ARGS
) {
211 /* copy address size and type */
212 hptr
->h_addrtype
= he
->h_addrtype
;
213 n
= hptr
->h_length
= he
->h_length
;
215 /* copy up to first 35 addresses */
218 eob
= hdptr
->hostbuf
+ sizeof(hdptr
->hostbuf
);
219 hptr
->h_addr_list
= hdptr
->h_addr_ptrs
;
220 while (he
->h_addr_list
[i
] && i
< (_MAXADDRS
)) {
221 if (n
< (eob
- cp
)) {
222 memcpy(cp
, he
->h_addr_list
[i
], n
);
223 hptr
->h_addr_list
[i
] = cp
;
230 hptr
->h_addr_list
[i
] = NULL
;
232 /* copy official name */
233 if ((n
= strlen(he
->h_name
) + 1) < (eob
- cp
)) {
234 strcpy(cp
, he
->h_name
);
243 hptr
->h_aliases
= hdptr
->host_aliases
;
244 while (he
->h_aliases
[i
] && i
< (_MAXALIASES
-1)) {
245 if ((n
= strlen(he
->h_aliases
[i
]) + 1) < (eob
- cp
)) {
246 strcpy(cp
, he
->h_aliases
[i
]);
247 hptr
->h_aliases
[i
] = cp
;
254 hptr
->h_aliases
[i
] = NULL
;
258 #endif /* !HOSTENT_DATA */
259 #else /* HOST_R_RETURN */
260 static int gethostent_r_unknown_system
= 0;
261 #endif /* HOST_R_RETURN */
262 #endif /* !defined(_REENTRANT) || !defined(DO_PTHREADS) */