]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/bind/lib/irs/gethostent_r.c
This commit was generated by cvs2svn to compensate for changes in r57422,
[FreeBSD/FreeBSD.git] / contrib / bind / lib / irs / gethostent_r.c
1 /*
2  * Copyright (c) 1998-1999 by Internet Software Consortium.
3  *
4  * Permission to use, copy, modify, and distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
9  * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
10  * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
11  * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
12  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
13  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
14  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
15  * SOFTWARE.
16  */
17
18 #if defined(LIBC_SCCS) && !defined(lint)
19 static const char rcsid[] = "$Id: gethostent_r.c,v 8.4 1999/01/18 07:46:52 vixie 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 <netinet/in.h>
30 #include <netdb.h>
31 #include <sys/param.h>
32 #include <port_after.h>
33
34 #ifdef HOST_R_RETURN
35
36 static HOST_R_RETURN 
37 copy_hostent(struct hostent *, struct hostent *, HOST_R_COPY_ARGS);
38
39 HOST_R_RETURN
40 gethostbyname_r(const char *name,  struct hostent *hptr, HOST_R_ARGS) {
41         struct hostent *he = gethostbyname(name);
42
43         HOST_R_ERRNO;
44
45         if (he == NULL)
46                 return (HOST_R_BAD);
47
48         return (copy_hostent(he, hptr, HOST_R_COPY));
49 }
50
51 HOST_R_RETURN
52 gethostbyaddr_r(const char *addr, int len, int type,
53                 struct hostent *hptr, HOST_R_ARGS) {
54         struct hostent *he = gethostbyaddr(addr, len, type);
55
56         HOST_R_ERRNO;
57
58         if (he == NULL)
59                 return (HOST_R_BAD);
60
61         return (copy_hostent(he, hptr, HOST_R_COPY));
62 }
63
64 /*
65  *      These assume a single context is in operation per thread.
66  *      If this is not the case we will need to call irs directly
67  *      rather than through the base functions.
68  */
69
70 HOST_R_RETURN
71 gethostent_r(struct hostent *hptr, HOST_R_ARGS) {
72         struct hostent *he = gethostent();
73
74         HOST_R_ERRNO;
75
76         if (he == NULL)
77                 return (HOST_R_BAD);
78
79         return (copy_hostent(he, hptr, HOST_R_COPY));
80 }
81
82 HOST_R_SET_RETURN
83 #ifdef HOST_R_ENT_ARGS
84 sethostent_r(int stay_open, HOST_R_ENT_ARGS)
85 #else
86 sethostent_r(int stay_open)
87 #endif
88 {
89         sethostent(stay_open);
90 #ifdef  HOST_R_SET_RESULT
91         return (HOST_R_SET_RESULT);
92 #endif
93 }
94
95 HOST_R_END_RETURN
96 #ifdef HOST_R_ENT_ARGS
97 endhostent_r(HOST_R_ENT_ARGS)
98 #else
99 endhostent_r()
100 #endif
101 {
102         endhostent();
103         HOST_R_END_RESULT(HOST_R_OK);
104 }
105
106 /* Private */
107
108 #ifndef HOSTENT_DATA
109 static HOST_R_RETURN
110 copy_hostent(struct hostent *he, struct hostent *hptr, HOST_R_COPY_ARGS) {
111         char *cp;
112         char **ptr;
113         int i, n;
114         int nptr, len;
115
116         /* Find out the amount of space required to store the answer. */
117         nptr = 2; /* NULL ptrs */
118         len = (char *)ALIGN(buf) - buf;
119         for (i = 0; he->h_addr_list[i]; i++, nptr++) {
120                 len += he->h_length;
121         }
122         for (i = 0; he->h_aliases[i]; i++, nptr++) {
123                 len += strlen(he->h_aliases[i]) + 1;
124         }
125         len += strlen(he->h_name) + 1;
126         len += nptr * sizeof(char*);
127         
128         if (len > buflen) {
129                 errno = ERANGE;
130                 return (HOST_R_BAD);
131         }
132
133         /* copy address size and type */
134         hptr->h_addrtype = he->h_addrtype;
135         n = hptr->h_length = he->h_length;
136
137         ptr = (char **)ALIGN(buf);
138         cp = (char *)ALIGN(buf) + nptr * sizeof(char *);
139
140         /* copy address list */
141         hptr->h_addr_list = ptr;
142         for (i = 0; he->h_addr_list[i]; i++ , ptr++) {
143                 memcpy(cp, he->h_addr_list[i], n);
144                 hptr->h_addr_list[i] = cp;
145                 cp += n;
146                 i++;
147         }
148         hptr->h_addr_list[i] = NULL;
149         ptr++;
150
151         /* copy official name */
152         n = strlen(he->h_name) + 1;
153         strcpy(cp, he->h_name);
154         hptr->h_name = cp;
155         cp += n;
156
157         /* copy aliases */
158         hptr->h_aliases = ptr;
159         for (i = 0 ; he->h_aliases[i]; i++) {
160                 n = strlen(he->h_aliases[i]) + 1;
161                 strcpy(cp, he->h_aliases[i]);
162                 hptr->h_aliases[i] = cp;
163                 cp += n;
164         }
165         hptr->h_aliases[i] = NULL;
166
167         return (HOST_R_OK);
168 }
169 #else /* !HOSTENT_DATA */
170 static int
171 copy_hostent(struct hostent *he, struct hostent *hptr, HOST_R_COPY_ARGS) {
172         char *cp, *eob;
173         int i, n;
174
175         /* copy address size and type */
176         hptr->h_addrtype = he->h_addrtype;
177         n = hptr->h_length = he->h_length;
178
179         /* copy up to first 35 addresses */
180         i = 0;
181         cp = hdptr->hostaddr;
182         eob = hdptr->hostaddr + sizeof(hdptr->hostaddr);
183         hptr->h_addr_list = hdptr->h_addr_ptrs;
184         while (he->h_addr_list[i] && i < (_MAXADDRS)) {
185                 if (n < (eob - cp)) {
186                         memcpy(cp, he->h_addr_list[i], n);
187                         hptr->h_addr_list[i] = cp;
188                         cp += n;
189                 } else {
190                         break;
191                 }
192                 i++;
193         }
194         hptr->h_addr_list[i] = NULL;
195
196         /* copy official name */
197         cp = hdptr->hostbuf;
198         eob = hdptr->hostbuf + sizeof(hdptr->hostbuf);
199         if ((n = strlen(he->h_name) + 1) < (eob - cp)) {
200                 strcpy(cp, he->h_name);
201                 hptr->h_name = cp;
202                 cp += n;
203         } else {
204                 return (-1);
205         }
206
207         /* copy aliases */
208         i = 0;
209         hptr->h_aliases = hdptr->host_aliases;
210         while (he->h_aliases[i] && i < (_MAXALIASES-1)) {
211                 if ((n = strlen(he->h_aliases[i]) + 1) < (eob - cp)) {
212                         strcpy(cp, he->h_aliases[i]);
213                         hptr->h_aliases[i] = cp;
214                         cp += n;
215                 } else {
216                         break;
217                 }
218                 i++;
219         }
220         hptr->h_aliases[i] = NULL;
221
222         return (HOST_R_OK);
223 }
224 #endif /* !HOSTENT_DATA */
225 #else /* HOST_R_RETURN */
226         static int gethostent_r_unknown_systemm = 0;
227 #endif /* HOST_R_RETURN */
228 #endif /* !defined(_REENTRANT) || !defined(DO_PTHREADS) */