source: trunk/src/gcc/libjava/java/net/natInetAddress.cc@ 2

Last change on this file since 2 was 2, checked in by bird, 23 years ago

Initial revision

  • Property cvs2svn:cvs-rev set to 1.1
  • 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, 2002 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
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.