Sync usage with man page.
[netbsd-mini2440.git] / external / bsd / libbind / dist / irs / gethostent_r.c
blobcb33b915272f646acb80cb5aac5f2a93b252807f
1 /* $NetBSD$ */
3 /*
4 * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
5 * Copyright (c) 1998-1999 by Internet Software Consortium.
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.
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.
20 #if defined(LIBC_SCCS) && !defined(lint)
21 static const char rcsid[] = "Id: gethostent_r.c,v 1.9 2005/09/03 12:41:37 marka Exp";
22 #endif /* LIBC_SCCS and not lint */
24 #include <port_before.h>
25 #if !defined(_REENTRANT) || !defined(DO_PTHREADS)
26 static int gethostent_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>
37 #ifdef HOST_R_RETURN
39 static HOST_R_RETURN
40 copy_hostent(struct hostent *, struct hostent *, HOST_R_COPY_ARGS);
42 HOST_R_RETURN
43 gethostbyname_r(const char *name, struct hostent *hptr, HOST_R_ARGS) {
44 struct hostent *he = gethostbyname(name);
45 #ifdef HOST_R_SETANSWER
46 int n = 0;
47 #endif
49 #ifdef HOST_R_ERRNO
50 HOST_R_ERRNO;
51 #endif
53 #ifdef HOST_R_SETANSWER
54 if (he == NULL || (n = copy_hostent(he, hptr, HOST_R_COPY)) != 0)
55 *answerp = NULL;
56 else
57 *answerp = hptr;
59 return (n);
60 #else
61 if (he == NULL)
62 return (HOST_R_BAD);
64 return (copy_hostent(he, hptr, HOST_R_COPY));
65 #endif
68 HOST_R_RETURN
69 gethostbyaddr_r(const char *addr, int len, int type,
70 struct hostent *hptr, HOST_R_ARGS) {
71 struct hostent *he = gethostbyaddr(addr, len, type);
72 #ifdef HOST_R_SETANSWER
73 int n = 0;
74 #endif
76 #ifdef HOST_R_ERRNO
77 HOST_R_ERRNO;
78 #endif
80 #ifdef HOST_R_SETANSWER
81 if (he == NULL || (n = copy_hostent(he, hptr, HOST_R_COPY)) != 0)
82 *answerp = NULL;
83 else
84 *answerp = hptr;
86 return (n);
87 #else
88 if (he == NULL)
89 return (HOST_R_BAD);
91 return (copy_hostent(he, hptr, HOST_R_COPY));
92 #endif
95 /*%
96 * These assume a single context is in operation per thread.
97 * If this is not the case we will need to call irs directly
98 * rather than through the base functions.
101 HOST_R_RETURN
102 gethostent_r(struct hostent *hptr, HOST_R_ARGS) {
103 struct hostent *he = gethostent();
104 #ifdef HOST_R_SETANSWER
105 int n = 0;
106 #endif
108 #ifdef HOST_R_ERRNO
109 HOST_R_ERRNO;
110 #endif
112 #ifdef HOST_R_SETANSWER
113 if (he == NULL || (n = copy_hostent(he, hptr, HOST_R_COPY)) != 0)
114 *answerp = NULL;
115 else
116 *answerp = hptr;
118 return (n);
119 #else
120 if (he == NULL)
121 return (HOST_R_BAD);
123 return (copy_hostent(he, hptr, HOST_R_COPY));
124 #endif
127 HOST_R_SET_RETURN
128 #ifdef HOST_R_ENT_ARGS
129 sethostent_r(int stay_open, HOST_R_ENT_ARGS)
130 #else
131 sethostent_r(int stay_open)
132 #endif
134 #ifdef HOST_R_ENT_ARGS
135 UNUSED(hdptr);
136 #endif
137 sethostent(stay_open);
138 #ifdef HOST_R_SET_RESULT
139 return (HOST_R_SET_RESULT);
140 #endif
143 HOST_R_END_RETURN
144 #ifdef HOST_R_ENT_ARGS
145 endhostent_r(HOST_R_ENT_ARGS)
146 #else
147 endhostent_r(void)
148 #endif
150 #ifdef HOST_R_ENT_ARGS
151 UNUSED(hdptr);
152 #endif
153 endhostent();
154 HOST_R_END_RESULT(HOST_R_OK);
157 /* Private */
159 #ifndef HOSTENT_DATA
160 static HOST_R_RETURN
161 copy_hostent(struct hostent *he, struct hostent *hptr, HOST_R_COPY_ARGS) {
162 char *cp;
163 char **ptr;
164 int i, n;
165 int nptr, len;
167 /* Find out the amount of space required to store the answer. */
168 nptr = 2; /*%< NULL ptrs */
169 len = (char *)ALIGN(buf) - buf;
170 for (i = 0; he->h_addr_list[i]; i++, nptr++) {
171 len += he->h_length;
173 for (i = 0; he->h_aliases[i]; i++, nptr++) {
174 len += strlen(he->h_aliases[i]) + 1;
176 len += strlen(he->h_name) + 1;
177 len += nptr * sizeof(char*);
179 if (len > buflen) {
180 errno = ERANGE;
181 return (HOST_R_BAD);
184 /* copy address size and type */
185 hptr->h_addrtype = he->h_addrtype;
186 n = hptr->h_length = he->h_length;
188 ptr = (char **)ALIGN(buf);
189 cp = (char *)ALIGN(buf) + nptr * sizeof(char *);
191 /* copy address list */
192 hptr->h_addr_list = ptr;
193 for (i = 0; he->h_addr_list[i]; i++ , ptr++) {
194 memcpy(cp, he->h_addr_list[i], n);
195 hptr->h_addr_list[i] = cp;
196 cp += n;
198 hptr->h_addr_list[i] = NULL;
199 ptr++;
201 /* copy official name */
202 n = strlen(he->h_name) + 1;
203 strcpy(cp, he->h_name);
204 hptr->h_name = cp;
205 cp += n;
207 /* copy aliases */
208 hptr->h_aliases = ptr;
209 for (i = 0 ; he->h_aliases[i]; i++) {
210 n = strlen(he->h_aliases[i]) + 1;
211 strcpy(cp, he->h_aliases[i]);
212 hptr->h_aliases[i] = cp;
213 cp += n;
215 hptr->h_aliases[i] = NULL;
217 return (HOST_R_OK);
219 #else /* !HOSTENT_DATA */
220 static int
221 copy_hostent(struct hostent *he, struct hostent *hptr, HOST_R_COPY_ARGS) {
222 char *cp, *eob;
223 int i, n;
225 /* copy address size and type */
226 hptr->h_addrtype = he->h_addrtype;
227 n = hptr->h_length = he->h_length;
229 /* copy up to first 35 addresses */
230 i = 0;
231 cp = hdptr->hostbuf;
232 eob = hdptr->hostbuf + sizeof(hdptr->hostbuf);
233 hptr->h_addr_list = hdptr->h_addr_ptrs;
234 while (he->h_addr_list[i] && i < (_MAXADDRS)) {
235 if (n < (eob - cp)) {
236 memcpy(cp, he->h_addr_list[i], n);
237 hptr->h_addr_list[i] = cp;
238 cp += n;
239 } else {
240 break;
242 i++;
244 hptr->h_addr_list[i] = NULL;
246 /* copy official name */
247 if ((n = strlen(he->h_name) + 1) < (eob - cp)) {
248 strcpy(cp, he->h_name);
249 hptr->h_name = cp;
250 cp += n;
251 } else {
252 return (-1);
255 /* copy aliases */
256 i = 0;
257 hptr->h_aliases = hdptr->host_aliases;
258 while (he->h_aliases[i] && i < (_MAXALIASES-1)) {
259 if ((n = strlen(he->h_aliases[i]) + 1) < (eob - cp)) {
260 strcpy(cp, he->h_aliases[i]);
261 hptr->h_aliases[i] = cp;
262 cp += n;
263 } else {
264 break;
266 i++;
268 hptr->h_aliases[i] = NULL;
270 return (HOST_R_OK);
272 #endif /* !HOSTENT_DATA */
273 #else /* HOST_R_RETURN */
274 static int gethostent_r_unknown_system = 0;
275 #endif /* HOST_R_RETURN */
276 #endif /* !defined(_REENTRANT) || !defined(DO_PTHREADS) */
277 /*! \file */