bind - Upgraded vendor branch to 9.5.2-P1
[dragonfly.git] / contrib / bind-9.2.4rc7 / lib / bind / irs / gethostent_r.c
1 /*
2  * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
3  * Copyright (c) 1998-1999 by Internet Software Consortium.
4  *
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.
8  *
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.
16  */
17
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 */
21
22 #include <port_before.h>
23 #if !defined(_REENTRANT) || !defined(DO_PTHREADS)
24         static int gethostent_r_not_required = 0;
25 #else
26 #include <errno.h>
27 #include <string.h>
28 #include <stdio.h>
29 #include <sys/types.h>
30 #include <netinet/in.h>
31 #include <netdb.h>
32 #include <sys/param.h>
33 #include <port_after.h>
34
35 #ifdef HOST_R_RETURN
36
37 static HOST_R_RETURN 
38 copy_hostent(struct hostent *, struct hostent *, HOST_R_COPY_ARGS);
39
40 HOST_R_RETURN
41 gethostbyname_r(const char *name,  struct hostent *hptr, HOST_R_ARGS) {
42         struct hostent *he = gethostbyname(name);
43 #ifdef HOST_R_SETANSWER
44         int n = 0;
45 #endif
46
47         HOST_R_ERRNO;
48
49 #ifdef HOST_R_SETANSWER
50         if (he == NULL || (n = copy_hostent(he, hptr, HOST_R_COPY)) == 0)
51                 *answerp = NULL;
52         else
53                 *answerp = hptr;
54         
55         return (n);
56 #else
57         if (he == NULL)
58                 return (HOST_R_BAD);
59
60         return (copy_hostent(he, hptr, HOST_R_COPY));
61 #endif
62 }
63
64 HOST_R_RETURN
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
69         int n = 0;
70 #endif
71
72         HOST_R_ERRNO;
73
74 #ifdef HOST_R_SETANSWER
75         if (he == NULL || (n = copy_hostent(he, hptr, HOST_R_COPY)) == 0)
76                 *answerp = NULL;
77         else
78                 *answerp = hptr;
79         
80         return (n);
81 #else
82         if (he == NULL)
83                 return (HOST_R_BAD);
84
85         return (copy_hostent(he, hptr, HOST_R_COPY));
86 #endif
87 }
88
89 /*
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.
93  */
94
95 HOST_R_RETURN
96 gethostent_r(struct hostent *hptr, HOST_R_ARGS) {
97         struct hostent *he = gethostent();
98 #ifdef HOST_R_SETANSWER
99         int n = 0;
100 #endif
101
102         HOST_R_ERRNO;
103
104 #ifdef HOST_R_SETANSWER
105         if (he == NULL || (n = copy_hostent(he, hptr, HOST_R_COPY)) == 0)
106                 *answerp = NULL;
107         else
108                 *answerp = hptr;
109         
110         return (n);
111 #else
112         if (he == NULL)
113                 return (HOST_R_BAD);
114
115         return (copy_hostent(he, hptr, HOST_R_COPY));
116 #endif
117 }
118
119 HOST_R_SET_RETURN
120 #ifdef HOST_R_ENT_ARGS
121 sethostent_r(int stay_open, HOST_R_ENT_ARGS)
122 #else
123 sethostent_r(int stay_open)
124 #endif
125 {
126         sethostent(stay_open);
127 #ifdef  HOST_R_SET_RESULT
128         return (HOST_R_SET_RESULT);
129 #endif
130 }
131
132 HOST_R_END_RETURN
133 #ifdef HOST_R_ENT_ARGS
134 endhostent_r(HOST_R_ENT_ARGS)
135 #else
136 endhostent_r(void)
137 #endif
138 {
139         endhostent();
140         HOST_R_END_RESULT(HOST_R_OK);
141 }
142
143 /* Private */
144
145 #ifndef HOSTENT_DATA
146 static HOST_R_RETURN
147 copy_hostent(struct hostent *he, struct hostent *hptr, HOST_R_COPY_ARGS) {
148         char *cp;
149         char **ptr;
150         int i, n;
151         int nptr, len;
152
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++) {
157                 len += he->h_length;
158         }
159         for (i = 0; he->h_aliases[i]; i++, nptr++) {
160                 len += strlen(he->h_aliases[i]) + 1;
161         }
162         len += strlen(he->h_name) + 1;
163         len += nptr * sizeof(char*);
164         
165         if (len > buflen) {
166                 errno = ERANGE;
167                 return (HOST_R_BAD);
168         }
169
170         /* copy address size and type */
171         hptr->h_addrtype = he->h_addrtype;
172         n = hptr->h_length = he->h_length;
173
174         ptr = (char **)ALIGN(buf);
175         cp = (char *)ALIGN(buf) + nptr * sizeof(char *);
176
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;
182                 cp += n;
183         }
184         hptr->h_addr_list[i] = NULL;
185         ptr++;
186
187         /* copy official name */
188         n = strlen(he->h_name) + 1;
189         strcpy(cp, he->h_name);
190         hptr->h_name = cp;
191         cp += n;
192
193         /* copy aliases */
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;
199                 cp += n;
200         }
201         hptr->h_aliases[i] = NULL;
202
203         return (HOST_R_OK);
204 }
205 #else /* !HOSTENT_DATA */
206 static int
207 copy_hostent(struct hostent *he, struct hostent *hptr, HOST_R_COPY_ARGS) {
208         char *cp, *eob;
209         int i, n;
210
211         /* copy address size and type */
212         hptr->h_addrtype = he->h_addrtype;
213         n = hptr->h_length = he->h_length;
214
215         /* copy up to first 35 addresses */
216         i = 0;
217         cp = hdptr->hostbuf;
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;
224                         cp += n;
225                 } else {
226                         break;
227                 }
228                 i++;
229         }
230         hptr->h_addr_list[i] = NULL;
231
232         /* copy official name */
233         if ((n = strlen(he->h_name) + 1) < (eob - cp)) {
234                 strcpy(cp, he->h_name);
235                 hptr->h_name = cp;
236                 cp += n;
237         } else {
238                 return (-1);
239         }
240
241         /* copy aliases */
242         i = 0;
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;
248                         cp += n;
249                 } else {
250                         break;
251                 }
252                 i++;
253         }
254         hptr->h_aliases[i] = NULL;
255
256         return (HOST_R_OK);
257 }
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) */