Merge from vendor branch GCC:
[dragonfly.git] / contrib / bind-9.3 / lib / lwres / gethost.c
1 /*
2  * Copyright (C) 2004  Internet Systems Consortium, Inc. ("ISC")
3  * Copyright (C) 2000, 2001  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 WITH
10  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15  * PERFORMANCE OF THIS SOFTWARE.
16  */
17
18 /* $Id: gethost.c,v 1.29.206.1 2004/03/06 08:15:30 marka Exp $ */
19
20 #include <config.h>
21
22 #include <errno.h>
23 #include <string.h>
24
25 #include <lwres/net.h>
26 #include <lwres/netdb.h>
27
28 #include "assert_p.h"
29
30 #define LWRES_ALIGNBYTES (sizeof(char *) - 1)
31 #define LWRES_ALIGN(p) \
32         (((unsigned long)(p) + LWRES_ALIGNBYTES) &~ LWRES_ALIGNBYTES)
33
34 static struct hostent *he = NULL;
35 static int copytobuf(struct hostent *, struct hostent *, char *, int);
36
37 struct hostent *
38 lwres_gethostbyname(const char *name) {
39
40         if (he != NULL)
41                 lwres_freehostent(he);
42
43         he = lwres_getipnodebyname(name, AF_INET, 0, &lwres_h_errno);
44         return (he);
45 }
46
47 struct hostent *
48 lwres_gethostbyname2(const char *name, int af) {
49         if (he != NULL)
50                 lwres_freehostent(he);
51
52         he = lwres_getipnodebyname(name, af, 0, &lwres_h_errno);
53         return (he);
54 }
55
56 struct hostent *
57 lwres_gethostbyaddr(const char *addr, int len, int type) {
58
59         if (he != NULL)
60                 lwres_freehostent(he);
61
62         he = lwres_getipnodebyaddr(addr, len, type, &lwres_h_errno);
63         return (he);
64 }
65
66 struct hostent *
67 lwres_gethostent(void) {
68         if (he != NULL)
69                 lwres_freehostent(he);
70
71         return (NULL);
72 }
73
74 void
75 lwres_sethostent(int stayopen) {
76         /*
77          * Empty.
78          */
79         UNUSED(stayopen);
80 }
81
82 void
83 lwres_endhostent(void) {
84         /*
85          * Empty.
86          */
87 }
88
89 struct hostent *
90 lwres_gethostbyname_r(const char *name, struct hostent *resbuf,
91                 char *buf, int buflen, int *error)
92 {
93         struct hostent *he;
94         int res;
95
96         he = lwres_getipnodebyname(name, AF_INET, 0, error);
97         if (he == NULL)
98                 return (NULL);
99         res = copytobuf(he, resbuf, buf, buflen);
100         lwres_freehostent(he);
101         if (res != 0) {
102                 errno = ERANGE;
103                 return (NULL);
104         }
105         return (resbuf);
106 }
107
108 struct hostent  *
109 lwres_gethostbyaddr_r(const char *addr, int len, int type,
110                       struct hostent *resbuf, char *buf, int buflen,
111                       int *error)
112 {
113         struct hostent *he;
114         int res;
115
116         he = lwres_getipnodebyaddr(addr, len, type, error);
117         if (he == NULL)
118                 return (NULL);
119         res = copytobuf(he, resbuf, buf, buflen);
120         lwres_freehostent(he);
121         if (res != 0) {
122                 errno = ERANGE;
123                 return (NULL);
124         }
125         return (resbuf);
126 }
127
128 struct hostent  *
129 lwres_gethostent_r(struct hostent *resbuf, char *buf, int buflen, int *error) {
130         UNUSED(resbuf);
131         UNUSED(buf);
132         UNUSED(buflen);
133         *error = 0;
134         return (NULL);
135 }
136
137 void
138 lwres_sethostent_r(int stayopen) {
139         /*
140          * Empty.
141          */
142         UNUSED(stayopen);
143 }
144
145 void
146 lwres_endhostent_r(void) {
147         /*
148          * Empty.
149          */
150 }
151
152 static int
153 copytobuf(struct hostent *he, struct hostent *hptr, char *buf, int buflen) {
154         char *cp;
155         char **ptr;
156         int i, n;
157         int nptr, len;
158
159         /*
160          * Find out the amount of space required to store the answer.
161          */
162         nptr = 2; /* NULL ptrs */
163         len = (char *)LWRES_ALIGN(buf) - buf;
164         for (i = 0; he->h_addr_list[i]; i++, nptr++) {
165                 len += he->h_length;
166         }
167         for (i = 0; he->h_aliases[i]; i++, nptr++) {
168                 len += strlen(he->h_aliases[i]) + 1;
169         }
170         len += strlen(he->h_name) + 1;
171         len += nptr * sizeof(char*);
172
173         if (len > buflen) {
174                 return (-1);
175         }
176
177         /*
178          * Copy address size and type.
179          */
180         hptr->h_addrtype = he->h_addrtype;
181         n = hptr->h_length = he->h_length;
182
183         ptr = (char **)LWRES_ALIGN(buf);
184         cp = (char *)LWRES_ALIGN(buf) + nptr * sizeof(char *);
185
186         /*
187          * Copy address list.
188          */
189         hptr->h_addr_list = ptr;
190         for (i = 0; he->h_addr_list[i]; i++, ptr++) {
191                 memcpy(cp, he->h_addr_list[i], n);
192                 hptr->h_addr_list[i] = cp;
193                 cp += n;
194         }
195         hptr->h_addr_list[i] = NULL;
196         ptr++;
197
198         /*
199          * Copy official name.
200          */
201         n = strlen(he->h_name) + 1;
202         strcpy(cp, he->h_name);
203         hptr->h_name = cp;
204         cp += n;
205
206         /*
207          * Copy aliases.
208          */
209         hptr->h_aliases = ptr;
210         for (i = 0; he->h_aliases[i]; i++) {
211                 n = strlen(he->h_aliases[i]) + 1;
212                 strcpy(cp, he->h_aliases[i]);
213                 hptr->h_aliases[i] = cp;
214                 cp += n;
215         }
216         hptr->h_aliases[i] = NULL;
217
218         return (0);
219 }