1 /* Copyright (C) 2003, 2006 Free Software Foundation
3 This file is part of libgcj.
5 This software is copyrighted work licensed under the terms of the
6 Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
17 #include <sys/param.h>
18 #include <sys/types.h>
19 #ifdef HAVE_SYS_SOCKET_H
20 #include <sys/socket.h>
22 #ifdef HAVE_NETINET_IN_H
23 #include <netinet/in.h>
25 #ifdef HAVE_ARPA_INET_H
26 #include <arpa/inet.h>
34 #include <java/net/VMInetAddress.h>
35 #include <java/net/UnknownHostException.h>
37 #if defined(HAVE_UNAME) && ! defined(HAVE_GETHOSTNAME)
38 #include <sys/utsname.h>
41 #ifndef HAVE_GETHOSTNAME_DECL
42 extern "C" int gethostname (char *name, int namelen);
46 java::net::VMInetAddress::getLocalHostname ()
49 #ifdef HAVE_GETHOSTNAME
50 char buffer[MAXHOSTNAMELEN];
51 if (gethostname (buffer, MAXHOSTNAMELEN))
56 if (uname (&stuff) != 0)
58 chars = stuff.nodename;
62 // It is admittedly non-optimal to convert the hostname to Unicode
63 // only to convert it back in getByName, but simplicity wins.
64 return JvNewStringUTF (chars);
68 java::net::VMInetAddress::lookupInaddrAny ()
71 typedef jint in_addr_t;
73 in_addr_t laddr = INADDR_ANY;
74 char *bytes = (char *) &laddr;
75 int blen = sizeof (laddr);
76 jbyteArray result = JvNewByteArray (blen);
77 memcpy (elements (result), bytes, blen);
82 java::net::VMInetAddress::getHostByAddr (jbyteArray addr)
84 struct hostent *hptr = NULL;
85 #ifdef HAVE_GETHOSTBYADDR_R
86 struct hostent hent_r;
87 #if HAVE_STRUCT_HOSTENT_DATA
88 struct hostent_data fixed_buffer, *buffer_r = &fixed_buffer;
91 // FIXME: in glibc, gethostbyname_r returns NETDB_INTERNAL to herr and
92 // ERANGE to errno if the buffer size is too small, rather than what is
93 // expected here. We work around this by setting a bigger buffer size and
94 // hoping that it is big enough.
95 char fixed_buffer[1024];
97 char fixed_buffer[200];
98 #endif /* __GLIBC__ */
99 char *buffer_r = fixed_buffer;
100 int size_r = sizeof (fixed_buffer);
101 #endif /* HAVE_STRUCT_HOSTENT_DATA */
102 #endif /* HAVE_GETHOSTBYADDR_R */
104 char *bytes = (char*) elements (addr);
105 int len = addr->length;
116 val = (char *) &bytes;
119 #endif /* HAVE_INET6 */
121 JvFail ("unrecognized size");
123 #ifdef HAVE_GETHOSTBYADDR_R
127 #if HAVE_STRUCT_HOSTENT_DATA
128 ok = ! gethostbyaddr_r (val, len, type, &hent_r, buffer_r);
131 #ifdef GETHOSTBYADDR_R_RETURNS_INT
132 ok = ! gethostbyaddr_r (val, len, type, &hent_r,
133 buffer_r, size_r, &hptr, &herr);
135 hptr = gethostbyaddr_r (val, len, type, &hent_r,
136 buffer_r, size_r, &herr);
138 #endif /* GETHOSTBYADDR_R_RETURNS_INT */
139 if (! ok && herr == ERANGE)
142 buffer_r = (char *) _Jv_AllocBytes (size_r);
145 #endif /* HAVE_STRUCT_HOSTENT_DATA */
148 #else /* HAVE_GETHOSTBYADDR_R */
149 // FIXME: this is insufficient if some other piece of code calls
150 // this gethostbyaddr.
151 JvSynchronize sync (&java::net::VMInetAddress::class$);
152 hptr = gethostbyaddr (val, len, type);
153 #endif /* HAVE_GETHOSTBYADDR_R */
156 throw new java::net::UnknownHostException ();
158 return JvNewStringUTF (hptr->h_name);
162 java::net::VMInetAddress::getHostByName (jstring host)
164 struct hostent *hptr = NULL;
165 #ifdef HAVE_GETHOSTBYNAME_R
166 struct hostent hent_r;
167 #if HAVE_STRUCT_HOSTENT_DATA
168 struct hostent_data fixed_buffer, *buffer_r = &fixed_buffer;
171 // FIXME: in glibc, gethostbyname_r returns NETDB_INTERNAL to herr and
172 // ERANGE to errno if the buffer size is too small, rather than what is
173 // expected here. We work around this by setting a bigger buffer size and
174 // hoping that it is big enough.
175 char fixed_buffer[1024];
177 char fixed_buffer[200];
178 #endif /* __GLIBC__ */
179 char *buffer_r = fixed_buffer;
180 int size_r = sizeof (fixed_buffer);
181 #endif /* HAVE_STRUCT_HOSTENT_DATA */
182 #endif /* HAVE_GETHOSTBYNAME_R */
186 int len = JvGetStringUTFLength(host);
190 hostname = (char *) _Jv_AllocBytes (len + 1);
191 JvGetStringUTFRegion (host, 0, host->length(), hostname);
193 #ifdef HAVE_GETHOSTBYNAME_R
197 #if HAVE_STRUCT_HOSTENT_DATA
198 ok = ! gethostbyname_r (hostname, &hent_r, buffer_r);
201 #ifdef GETHOSTBYNAME_R_RETURNS_INT
202 ok = ! gethostbyname_r (hostname, &hent_r, buffer_r, size_r,
205 hptr = gethostbyname_r (hostname, &hent_r, buffer_r, size_r, &herr);
207 #endif /* GETHOSTNAME_R_RETURNS_INT */
208 if (! ok && herr == ERANGE)
211 buffer_r = (char *) _Jv_AllocBytes (size_r);
214 #endif /* HAVE_STRUCT_HOSTENT_DATA */
217 #else /* HAVE_GETHOSTBYNAME_R */
218 // FIXME: this is insufficient if some other piece of code calls
219 // this gethostbyname.
220 JvSynchronize sync (&java::net::VMInetAddress::class$);
221 hptr = gethostbyname (hostname);
222 #endif /* HAVE_GETHOSTBYNAME_R */
225 throw new java::net::UnknownHostException (host);
228 char ** ptr = hptr->h_addr_list;
229 while (*ptr++) count++;
231 JArray<jbyteArray> *result =
232 (JArray<jbyteArray> *) _Jv_NewObjectArray (
233 count, _Jv_GetArrayClass(JvPrimClass(byte), NULL), NULL);
234 jbyteArray* addrs = elements (result);
236 for (int i = 0; i < count; i++)
238 addrs[i] = JvNewByteArray (hptr->h_length);
239 memcpy (elements (addrs[i]), hptr->h_addr_list[i], hptr->h_length);
245 java::net::VMInetAddress::aton (jstring host)
249 int len = JvGetStringUTFLength(host);
253 hostname = (char *) _Jv_AllocBytes (len+1);
254 JvGetStringUTFRegion (host, 0, host->length(), hostname);
258 #ifdef HAVE_INET_ATON
259 struct in_addr laddr;
260 if (inet_aton (hostname, &laddr))
262 bytes = (char *) &laddr;
265 #elif defined(HAVE_INET_ADDR)
267 typedef jint in_addr_t;
269 in_addr_t laddr = inet_addr (hostname);
270 if (laddr != (in_addr_t)(-1))
272 bytes = (char *) &laddr;
276 #if defined (HAVE_INET_PTON) && defined (HAVE_INET6)
278 if (len != 0 && inet_pton (AF_INET6, hostname, inet6_addr) > 0)
286 jbyteArray result = JvNewByteArray (blen);
287 memcpy (elements (result), bytes, blen);