1 // natClass.cc - Implementation of java.lang.Class native methods.
3 /* Copyright (C) 1998, 1999 Cygnus Solutions
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 #include <sys/param.h>
20 #include <sys/types.h>
21 #ifdef HAVE_SYS_SOCKET_H
22 #include <sys/socket.h>
24 #ifdef HAVE_NETINET_IN_H
25 #include <netinet/in.h>
27 #ifdef HAVE_ARPA_INET_H
28 #include <arpa/inet.h>
36 #include <java/net/InetAddress.h>
37 #include <java/net/UnknownHostException.h>
38 #include <java/lang/SecurityException.h>
40 #if defined(HAVE_UNAME) && ! defined(HAVE_GETHOSTNAME)
41 #include <sys/utsname.h>
44 #ifndef HAVE_GETHOSTNAME_DECL
45 extern "C" int gethostname (char *name, int namelen);
49 java::net::InetAddress::aton (jstring host)
53 int len = JvGetStringUTFLength(host);
57 hostname = (char*) _Jv_AllocBytesChecked (len+1);
58 JvGetStringUTFRegion (host, 0, host->length(), hostname);
64 if (inet_aton (hostname, &laddr))
66 bytes = (char*) &laddr;
69 #elif defined(HAVE_INET_ADDR)
70 in_addr_t laddr = inet_addr (hostname);
71 if (laddr != (in_addr_t)(-1))
73 bytes = (char*) &laddr;
79 if (len == 0 && inet_pton (AF_INET6, hostname, inet6_addr) > 0)
87 jbyteArray result = JvNewByteArray (len);
88 memcpy (elements (result), bytes, blen);
93 JArray<java::net::InetAddress*> *
94 java::net::InetAddress::lookup (jstring host, java::net::InetAddress* iaddr,
97 struct hostent *hptr = NULL;
98 #if defined (HAVE_GETHOSTBYNAME_R) || defined (HAVE_GETHOSTBYADDR_R)
99 struct hostent hent_r;
100 #if defined (__GLIBC__) && __GLIBC__ == 2 && __GLIBC_MINOR__ == 0
101 // glibc 2.0.7 has a bug where gethostbyname_r won't return an error
102 // if the buffer is too small. So in this case we size the buffer
103 // the same way that glibc does. This is fixed in glibc 2.1.
104 char fixed_buffer[1024];
106 char fixed_buffer[200];
108 char *buffer_r = fixed_buffer;
109 int size_r = sizeof (fixed_buffer);
116 int len = JvGetStringUTFLength(host);
120 hostname = (char*) _Jv_AllocBytesChecked (len+1);
121 JvGetStringUTFRegion (host, 0, host->length(), hostname);
123 #ifdef HAVE_GETHOSTBYNAME_R
125 while (hptr == NULL && herr == ERANGE)
128 #ifdef GETHOSTBYNAME_R_RETURNS_INT
129 ok = ! gethostbyname_r (hostname, &hent_r, buffer_r, size_r,
132 hptr = gethostbyname_r (hostname, &hent_r, buffer_r, size_r, &herr);
134 #endif /* GETHOSTNAME_R_RETURNS_INT */
135 if (! ok && herr == ERANGE)
138 buffer_r = (char *) _Jv_AllocBytesChecked (size_r);
142 // FIXME: this is insufficient if some other piece of code calls
143 // this gethostbyname.
144 JvSynchronize sync (java::net::InetAddress::localhostAddress);
145 hptr = gethostbyname (hostname);
146 #endif /* HAVE_GETHOSTBYNAME_R */
150 jbyteArray bytes = iaddr->address;
151 char *chars = (char*) elements (bytes);
152 int len = bytes->length;
163 val = (char *) &chars;
166 #endif /* HAVE_INET6 */
168 JvFail ("unrecognized size");
170 #ifdef HAVE_GETHOSTBYADDR_R
172 while (hptr == NULL && herr == ERANGE)
175 #ifdef GETHOSTBYADDR_R_RETURNS_INT
176 ok = ! gethostbyaddr_r (val, len, type, &hent_r,
177 buffer_r, size_r, &hptr, &herr);
179 hptr = gethostbyaddr_r (val, len, type, &hent_r,
180 buffer_r, size_r, &herr);
182 #endif /* GETHOSTBYADDR_R_RETURNS_INT */
183 if (! ok && herr == ERANGE)
186 buffer_r = (char *) _Jv_AllocBytesChecked (size_r);
189 #else /* HAVE_GETHOSTBYADDR_R */
190 // FIXME: this is insufficient if some other piece of code calls
191 // this gethostbyaddr.
192 JvSynchronize sync (java::net::InetAddress::localhostAddress);
193 hptr = gethostbyaddr (val, len, type);
194 #endif /* HAVE_GETHOSTBYADDR_R */
198 host = JvNewStringUTF (hptr->h_name);
199 java::lang::SecurityException *ex = checkConnect (host);
202 if (iaddr == NULL || iaddr->address == NULL)
209 if (iaddr != NULL && iaddr->address != NULL)
211 iaddr->hostname = iaddr->getHostAddress();
215 JvThrow (new java::net::UnknownHostException(host));
220 char** ptr = hptr->h_addr_list;
222 while (*ptr++) count++;
226 JArray<java::net::InetAddress*> *result;
227 java::net::InetAddress** iaddrs;
230 result = java::net::InetAddress::allocArray (count);
231 iaddrs = elements (result);
239 for (int i = 0; i < count; i++)
241 if (iaddrs[i] == NULL)
242 iaddrs[i] = new java::net::InetAddress (NULL, NULL);
244 iaddrs[0]->hostname = host;
245 if (iaddrs[i]->address == NULL)
247 char *bytes = hptr->h_addr_list[i];
248 iaddr->address = JvNewByteArray (hptr->h_length);
249 memcpy (elements (iaddr->address), bytes, hptr->h_length);
256 java::net::InetAddress::getLocalHostname ()
259 #ifdef HAVE_GETHOSTNAME
260 char buffer[MAXHOSTNAMELEN];
261 if (gethostname (buffer, MAXHOSTNAMELEN))
265 struct utsname stuff;
266 if (uname (&stuff) != 0)
268 chars = stuff.nodename;
272 // It is admittedly non-optimal to convert the hostname to Unicode
273 // only to convert it back in getByName, but simplicity wins. Note
274 // that unless there is a SecurityManager, we only get called once
275 // anyway, thanks to the InetAddress.localhost cache.
276 return JvNewStringUTF (chars);