3 /* Copyright (C) 1998, 1999, 2000 Free Software Foundation
5 This file is part of libgcj.
7 This software is copyrighted work licensed under the terms of the
8 Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
19 #ifndef MAXHOSTNAMELEN
20 #define MAXHOSTNAMELEN 64
21 #endif /* MAXHOSTNAMELEN */
31 #include <sys/param.h>
32 #include <sys/types.h>
33 #ifdef HAVE_SYS_SOCKET_H
34 #include <sys/socket.h>
36 #ifdef HAVE_NETINET_IN_H
37 #include <netinet/in.h>
39 #ifdef HAVE_ARPA_INET_H
40 #include <arpa/inet.h>
50 #include <java/net/InetAddress.h>
51 #include <java/net/UnknownHostException.h>
52 #include <java/lang/SecurityException.h>
54 #if defined(HAVE_UNAME) && ! defined(HAVE_GETHOSTNAME)
55 #include <sys/utsname.h>
58 #ifndef HAVE_GETHOSTNAME_DECL
59 extern "C" int gethostname (char *name, int namelen);
62 #ifdef DISABLE_JAVA_NET
65 java::net::InetAddress::aton (jstring)
71 java::net::InetAddress::getFamily (jbyteArray bytes)
76 JArray<java::net::InetAddress*> *
77 java::net::InetAddress::lookup (jstring, java::net::InetAddress *, jboolean)
83 java::net::InetAddress::getLocalHostname ()
88 #else /* DISABLE_JAVA_NET */
91 java::net::InetAddress::aton (jstring host)
95 int len = JvGetStringUTFLength(host);
99 hostname = (char*) _Jv_AllocBytes (len+1);
100 JvGetStringUTFRegion (host, 0, host->length(), hostname);
104 #ifdef HAVE_INET_ATON
105 struct in_addr laddr;
106 if (inet_aton (hostname, &laddr))
108 bytes = (char*) &laddr;
111 #elif defined(HAVE_INET_ADDR)
113 typedef jint in_addr_t;
115 in_addr_t laddr = inet_addr (hostname);
116 if (laddr != (in_addr_t)(-1))
118 bytes = (char*) &laddr;
122 #if defined (HAVE_INET_PTON) && defined (HAVE_INET6)
124 if (len == 0 && inet_pton (AF_INET6, hostname, inet6_addr) > 0)
132 jbyteArray result = JvNewByteArray (blen);
133 memcpy (elements (result), bytes, blen);
138 java::net::InetAddress::getFamily (jbyteArray bytes)
140 int len = bytes->length;
146 #endif /* HAVE_INET6 */
148 JvFail ("unrecognized size");
152 JArray<java::net::InetAddress*> *
153 java::net::InetAddress::lookup (jstring host, java::net::InetAddress* iaddr,
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;
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];
169 char fixed_buffer[200];
171 char *buffer_r = fixed_buffer;
172 int size_r = sizeof (fixed_buffer);
180 int len = JvGetStringUTFLength(host);
184 hostname = (char*) _Jv_AllocBytes (len+1);
185 JvGetStringUTFRegion (host, 0, host->length(), hostname);
187 #ifdef HAVE_GETHOSTBYNAME_R
191 #if HAVE_STRUCT_HOSTENT_DATA
192 ok = ! gethostbyname_r (hostname, &hent_r, buffer_r);
195 #ifdef GETHOSTBYNAME_R_RETURNS_INT
196 ok = ! gethostbyname_r (hostname, &hent_r, buffer_r, size_r,
199 hptr = gethostbyname_r (hostname, &hent_r, buffer_r, size_r, &herr);
201 #endif /* GETHOSTNAME_R_RETURNS_INT */
202 if (! ok && herr == ERANGE)
205 buffer_r = (char *) _Jv_AllocBytes (size_r);
208 #endif /* HAVE_STRUCT_HOSTENT_DATA */
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 */
220 jbyteArray bytes = iaddr->addr;
221 char *chars = (char*) elements (bytes);
222 int len = bytes->length;
228 type = iaddr->family = AF_INET;
233 val = (char *) &chars;
234 type = iaddr->family = AF_INET6;
236 #endif /* HAVE_INET6 */
238 JvFail ("unrecognized size");
240 #ifdef HAVE_GETHOSTBYADDR_R
244 #if HAVE_STRUCT_HOSTENT_DATA
245 ok = ! gethostbyaddr_r (val, len, type, &hent_r, buffer_r);
248 #ifdef GETHOSTBYADDR_R_RETURNS_INT
249 ok = ! gethostbyaddr_r (val, len, type, &hent_r,
250 buffer_r, size_r, &hptr, &herr);
252 hptr = gethostbyaddr_r (val, len, type, &hent_r,
253 buffer_r, size_r, &herr);
255 #endif /* GETHOSTBYADDR_R_RETURNS_INT */
256 if (! ok && herr == ERANGE)
259 buffer_r = (char *) _Jv_AllocBytes (size_r);
262 #endif /* HAVE_STRUCT_HOSTENT_DATA */
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 */
275 host = JvNewStringUTF (hptr->h_name);
276 java::lang::SecurityException *ex = checkConnect (host);
279 if (iaddr == NULL || iaddr->addr == NULL)
286 if (iaddr != NULL && iaddr->addr != NULL)
288 iaddr->hostName = iaddr->getHostAddress();
292 throw new java::net::UnknownHostException(host);
297 char** ptr = hptr->h_addr_list;
299 while (*ptr++) count++;
303 JArray<java::net::InetAddress*> *result;
304 java::net::InetAddress** iaddrs;
307 result = java::net::InetAddress::allocArray (count);
308 iaddrs = elements (result);
316 for (int i = 0; i < count; i++)
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)
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);
334 java::net::InetAddress::getLocalHostname ()
337 #ifdef HAVE_GETHOSTNAME
338 char buffer[MAXHOSTNAMELEN];
339 if (gethostname (buffer, MAXHOSTNAMELEN))
343 struct utsname stuff;
344 if (uname (&stuff) != 0)
346 chars = stuff.nodename;
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);
357 #endif /* DISABLE_JAVA_NET */