source: trunk/gcc/libjava/java/net/natInetAddress.cc

Last change on this file was 1392, checked in by bird, 21 years ago

This commit was generated by cvs2svn to compensate for changes in r1391,
which included commits to RCS files with non-trunk default branches.

  • Property cvs2svn:cvs-rev set to 1.1.1.2
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 8.0 KB
Line 
1// natInetAddress.cc
2
3/* Copyright (C) 1998, 1999, 2000 Free Software Foundation
4
5 This file is part of libgcj.
6
7This software is copyrighted work licensed under the terms of the
8Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
9details. */
10
11#include <config.h>
12
13#ifdef WIN32
14
15#include <windows.h>
16#include <winsock.h>
17#undef STRICT
18
19#ifndef MAXHOSTNAMELEN
20#define MAXHOSTNAMELEN 64
21#endif /* MAXHOSTNAMELEN */
22
23#else /* WIN32 */
24
25#ifdef HAVE_UNISTD_H
26#include <unistd.h>
27#endif
28#include <string.h>
29#include <errno.h>
30
31#include <sys/param.h>
32#include <sys/types.h>
33#ifdef HAVE_SYS_SOCKET_H
34#include <sys/socket.h>
35#endif
36#ifdef HAVE_NETINET_IN_H
37#include <netinet/in.h>
38#endif
39#ifdef HAVE_ARPA_INET_H
40#include <arpa/inet.h>
41#endif
42#ifdef HAVE_NETDB_H
43#include <netdb.h>
44#endif
45
46#endif /* WIN32 */
47
48#include <gcj/cni.h>
49#include <jvm.h>
50#include <java/net/InetAddress.h>
51#include <java/net/UnknownHostException.h>
52#include <java/lang/SecurityException.h>
53
54#if defined(HAVE_UNAME) && ! defined(HAVE_GETHOSTNAME)
55#include <sys/utsname.h>
56#endif
57
58#ifndef HAVE_GETHOSTNAME_DECL
59extern "C" int gethostname (char *name, int namelen);
60#endif
61
62#ifdef DISABLE_JAVA_NET
63
64jbyteArray
65java::net::InetAddress::aton (jstring)
66{
67 return NULL;
68}
69
70jint
71java::net::InetAddress::getFamily (jbyteArray bytes)
72{
73 return 0;
74}
75
76JArray<java::net::InetAddress*> *
77java::net::InetAddress::lookup (jstring, java::net::InetAddress *, jboolean)
78{
79 return NULL;
80}
81
82jstring
83java::net::InetAddress::getLocalHostname ()
84{
85 return NULL;
86}
87
88#else /* DISABLE_JAVA_NET */
89
90jbyteArray
91java::net::InetAddress::aton (jstring host)
92{
93 char *hostname;
94 char buf[100];
95 int len = JvGetStringUTFLength(host);
96 if (len < 100)
97 hostname = buf;
98 else
99 hostname = (char*) _Jv_AllocBytes (len+1);
100 JvGetStringUTFRegion (host, 0, host->length(), hostname);
101 buf[len] = '\0';
102 char* bytes = NULL;
103 int blen = 0;
104#ifdef HAVE_INET_ATON
105 struct in_addr laddr;
106 if (inet_aton (hostname, &laddr))
107 {
108 bytes = (char*) &laddr;
109 blen = 4;
110 }
111#elif defined(HAVE_INET_ADDR)
112#if ! HAVE_IN_ADDR_T
113 typedef jint in_addr_t;
114#endif
115 in_addr_t laddr = inet_addr (hostname);
116 if (laddr != (in_addr_t)(-1))
117 {
118 bytes = (char*) &laddr;
119 blen = 4;
120 }
121#endif
122#if defined (HAVE_INET_PTON) && defined (HAVE_INET6)
123 char inet6_addr[16];
124 if (len != 0 && inet_pton (AF_INET6, hostname, inet6_addr) > 0)
125 {
126 bytes = inet6_addr;
127 blen = 16;
128 }
129#endif
130 if (blen == 0)
131 return NULL;
132 jbyteArray result = JvNewByteArray (blen);
133 memcpy (elements (result), bytes, blen);
134 return result;
135}
136
137jint
138java::net::InetAddress::getFamily (jbyteArray bytes)
139{
140 int len = bytes->length;
141 if (len == 4)
142 return AF_INET;
143#ifdef HAVE_INET6
144 else if (len == 16)
145 return AF_INET6;
146#endif /* HAVE_INET6 */
147 else
148 JvFail ("unrecognized size");
149}
150
151
152JArray<java::net::InetAddress*> *
153java::net::InetAddress::lookup (jstring host, java::net::InetAddress* iaddr,
154 jboolean all)
155{
156 struct hostent *hptr = NULL;
157#if defined (HAVE_GETHOSTBYNAME_R) || defined (HAVE_GETHOSTBYADDR_R)
158 struct hostent hent_r;
159#if HAVE_STRUCT_HOSTENT_DATA
160 struct hostent_data fixed_buffer, *buffer_r = &fixed_buffer;
161#else
162#if defined (__GLIBC__)
163 // FIXME: in glibc, gethostbyname_r returns NETDB_INTERNAL to herr and
164 // ERANGE to errno if the buffer size is too small, rather than what is
165 // expected here. We work around this by setting a bigger buffer size and
166 // hoping that it is big enough.
167 char fixed_buffer[1024];
168#else
169 char fixed_buffer[200];
170#endif
171 char *buffer_r = fixed_buffer;
172 int size_r = sizeof (fixed_buffer);
173#endif
174#endif
175
176 if (host != NULL)
177 {
178 char *hostname;
179 char buf[100];
180 int len = JvGetStringUTFLength(host);
181 if (len < 100)
182 hostname = buf;
183 else
184 hostname = (char*) _Jv_AllocBytes (len+1);
185 JvGetStringUTFRegion (host, 0, host->length(), hostname);
186 buf[len] = '\0';
187#ifdef HAVE_GETHOSTBYNAME_R
188 while (true)
189 {
190 int ok;
191#if HAVE_STRUCT_HOSTENT_DATA
192 ok = ! gethostbyname_r (hostname, &hent_r, buffer_r);
193#else
194 int herr = 0;
195#ifdef GETHOSTBYNAME_R_RETURNS_INT
196 ok = ! gethostbyname_r (hostname, &hent_r, buffer_r, size_r,
197 &hptr, &herr);
198#else
199 hptr = gethostbyname_r (hostname, &hent_r, buffer_r, size_r, &herr);
200 ok = hptr != NULL;
201#endif /* GETHOSTNAME_R_RETURNS_INT */
202 if (! ok && herr == ERANGE)
203 {
204 size_r *= 2;
205 buffer_r = (char *) _Jv_AllocBytes (size_r);
206 }
207 else
208#endif /* HAVE_STRUCT_HOSTENT_DATA */
209 break;
210 }
211#else
212 // FIXME: this is insufficient if some other piece of code calls
213 // this gethostbyname.
214 JvSynchronize sync (java::net::InetAddress::localhostAddress);
215 hptr = gethostbyname (hostname);
216#endif /* HAVE_GETHOSTBYNAME_R */
217 }
218 else
219 {
220 jbyteArray bytes = iaddr->addr;
221 char *chars = (char*) elements (bytes);
222 int len = bytes->length;
223 int type;
224 char *val;
225 if (len == 4)
226 {
227 val = chars;
228 type = iaddr->family = AF_INET;
229 }
230#ifdef HAVE_INET6
231 else if (len == 16)
232 {
233 val = (char *) &chars;
234 type = iaddr->family = AF_INET6;
235 }
236#endif /* HAVE_INET6 */
237 else
238 JvFail ("unrecognized size");
239
240#ifdef HAVE_GETHOSTBYADDR_R
241 while (true)
242 {
243 int ok;
244#if HAVE_STRUCT_HOSTENT_DATA
245 ok = ! gethostbyaddr_r (val, len, type, &hent_r, buffer_r);
246#else
247 int herr = 0;
248#ifdef GETHOSTBYADDR_R_RETURNS_INT
249 ok = ! gethostbyaddr_r (val, len, type, &hent_r,
250 buffer_r, size_r, &hptr, &herr);
251#else
252 hptr = gethostbyaddr_r (val, len, type, &hent_r,
253 buffer_r, size_r, &herr);
254 ok = hptr != NULL;
255#endif /* GETHOSTBYADDR_R_RETURNS_INT */
256 if (! ok && herr == ERANGE)
257 {
258 size_r *= 2;
259 buffer_r = (char *) _Jv_AllocBytes (size_r);
260 }
261 else
262#endif /* HAVE_STRUCT_HOSTENT_DATA */
263 break;
264 }
265#else /* HAVE_GETHOSTBYADDR_R */
266 // FIXME: this is insufficient if some other piece of code calls
267 // this gethostbyaddr.
268 JvSynchronize sync (java::net::InetAddress::localhostAddress);
269 hptr = gethostbyaddr (val, len, type);
270#endif /* HAVE_GETHOSTBYADDR_R */
271 }
272 if (hptr != NULL)
273 {
274 if (!all)
275 host = JvNewStringUTF (hptr->h_name);
276 java::lang::SecurityException *ex = checkConnect (host);
277 if (ex != NULL)
278 {
279 if (iaddr == NULL || iaddr->addr == NULL)
280 throw ex;
281 hptr = NULL;
282 }
283 }
284 if (hptr == NULL)
285 {
286 if (iaddr != NULL && iaddr->addr != NULL)
287 {
288 iaddr->hostName = iaddr->getHostAddress();
289 return NULL;
290 }
291 else
292 throw new java::net::UnknownHostException(host);
293 }
294 int count;
295 if (all)
296 {
297 char** ptr = hptr->h_addr_list;
298 count = 0;
299 while (*ptr++) count++;
300 }
301 else
302 count = 1;
303 JArray<java::net::InetAddress*> *result;
304 java::net::InetAddress** iaddrs;
305 if (all)
306 {
307 result = java::net::InetAddress::allocArray (count);
308 iaddrs = elements (result);
309 }
310 else
311 {
312 result = NULL;
313 iaddrs = &iaddr;
314 }
315
316 for (int i = 0; i < count; i++)
317 {
318 if (iaddrs[i] == NULL)
319 iaddrs[i] = new java::net::InetAddress (NULL, NULL);
320 if (iaddrs[i]->hostName == NULL)
321 iaddrs[i]->hostName = host;
322 if (iaddrs[i]->addr == NULL)
323 {
324 char *bytes = hptr->h_addr_list[i];
325 iaddrs[i]->addr = JvNewByteArray (hptr->h_length);
326 iaddrs[i]->family = getFamily (iaddrs[i]->addr);
327 memcpy (elements (iaddrs[i]->addr), bytes, hptr->h_length);
328 }
329 }
330 return result;
331}
332
333jstring
334java::net::InetAddress::getLocalHostname ()
335{
336 char *chars;
337#ifdef HAVE_GETHOSTNAME
338 char buffer[MAXHOSTNAMELEN];
339 if (gethostname (buffer, MAXHOSTNAMELEN))
340 return NULL;
341 chars = buffer;
342#elif HAVE_UNAME
343 struct utsname stuff;
344 if (uname (&stuff) != 0)
345 return NULL;
346 chars = stuff.nodename;
347#else
348 return NULL;
349#endif
350 // It is admittedly non-optimal to convert the hostname to Unicode
351 // only to convert it back in getByName, but simplicity wins. Note
352 // that unless there is a SecurityManager, we only get called once
353 // anyway, thanks to the InetAddress.localhost cache.
354 return JvNewStringUTF (chars);
355}
356
357#endif /* DISABLE_JAVA_NET */
Note: See TracBrowser for help on using the repository browser.