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
51 char buffer
[MAXHOSTNAMELEN
];
52 if (gethostname (buffer
, MAXHOSTNAMELEN
))
59 if (!gethostname (buffer
, size
-1))
62 return JvNewStringUTF (buffer
);
64 else if (errno
!= ENAMETOOLONG
)
71 if (uname (&stuff
) != 0)
73 chars
= stuff
.nodename
;
77 // It is admittedly non-optimal to convert the hostname to Unicode
78 // only to convert it back in getByName, but simplicity wins.
79 return JvNewStringUTF (chars
);
83 java::net::VMInetAddress::lookupInaddrAny ()
86 typedef jint in_addr_t
;
88 in_addr_t laddr
= INADDR_ANY
;
89 char *bytes
= (char *) &laddr
;
90 int blen
= sizeof (laddr
);
91 jbyteArray result
= JvNewByteArray (blen
);
92 memcpy (elements (result
), bytes
, blen
);
97 java::net::VMInetAddress::getHostByAddr (jbyteArray addr
)
99 struct hostent
*hptr
= NULL
;
100 #ifdef HAVE_GETHOSTBYADDR_R
101 struct hostent hent_r
;
102 #if HAVE_STRUCT_HOSTENT_DATA
103 struct hostent_data fixed_buffer
, *buffer_r
= &fixed_buffer
;
106 // FIXME: in glibc, gethostbyname_r returns NETDB_INTERNAL to herr and
107 // ERANGE to errno if the buffer size is too small, rather than what is
108 // expected here. We work around this by setting a bigger buffer size and
109 // hoping that it is big enough.
110 char fixed_buffer
[1024];
112 char fixed_buffer
[200];
113 #endif /* __GLIBC__ */
114 char *buffer_r
= fixed_buffer
;
115 int size_r
= sizeof (fixed_buffer
);
116 #endif /* HAVE_STRUCT_HOSTENT_DATA */
117 #endif /* HAVE_GETHOSTBYADDR_R */
119 char *bytes
= (char*) elements (addr
);
120 int len
= addr
->length
;
131 val
= (char *) &bytes
;
134 #endif /* HAVE_INET6 */
136 JvFail ("unrecognized size");
138 #ifdef HAVE_GETHOSTBYADDR_R
142 #if HAVE_STRUCT_HOSTENT_DATA
143 ok
= ! gethostbyaddr_r (val
, len
, type
, &hent_r
, buffer_r
);
146 #ifdef GETHOSTBYADDR_R_RETURNS_INT
147 ok
= ! gethostbyaddr_r (val
, len
, type
, &hent_r
,
148 buffer_r
, size_r
, &hptr
, &herr
);
150 hptr
= gethostbyaddr_r (val
, len
, type
, &hent_r
,
151 buffer_r
, size_r
, &herr
);
153 #endif /* GETHOSTBYADDR_R_RETURNS_INT */
154 if (! ok
&& herr
== ERANGE
)
157 buffer_r
= (char *) _Jv_AllocBytes (size_r
);
160 #endif /* HAVE_STRUCT_HOSTENT_DATA */
163 #else /* HAVE_GETHOSTBYADDR_R */
164 // FIXME: this is insufficient if some other piece of code calls
165 // this gethostbyaddr.
166 JvSynchronize
sync (&java::net::VMInetAddress::class$
);
167 hptr
= gethostbyaddr (val
, len
, type
);
168 #endif /* HAVE_GETHOSTBYADDR_R */
171 throw new java::net::UnknownHostException ();
173 return JvNewStringUTF (hptr
->h_name
);
177 java::net::VMInetAddress::getHostByName (jstring host
)
179 struct hostent
*hptr
= NULL
;
180 #ifdef HAVE_GETHOSTBYNAME_R
181 struct hostent hent_r
;
182 #if HAVE_STRUCT_HOSTENT_DATA
183 struct hostent_data fixed_buffer
, *buffer_r
= &fixed_buffer
;
186 // FIXME: in glibc, gethostbyname_r returns NETDB_INTERNAL to herr and
187 // ERANGE to errno if the buffer size is too small, rather than what is
188 // expected here. We work around this by setting a bigger buffer size and
189 // hoping that it is big enough.
190 char fixed_buffer
[1024];
192 char fixed_buffer
[200];
193 #endif /* __GLIBC__ */
194 char *buffer_r
= fixed_buffer
;
195 int size_r
= sizeof (fixed_buffer
);
196 #endif /* HAVE_STRUCT_HOSTENT_DATA */
197 #endif /* HAVE_GETHOSTBYNAME_R */
201 int len
= JvGetStringUTFLength(host
);
205 hostname
= (char *) _Jv_AllocBytes (len
+ 1);
206 JvGetStringUTFRegion (host
, 0, host
->length(), hostname
);
208 #ifdef HAVE_GETHOSTBYNAME_R
212 #if HAVE_STRUCT_HOSTENT_DATA
213 ok
= ! gethostbyname_r (hostname
, &hent_r
, buffer_r
);
216 #ifdef GETHOSTBYNAME_R_RETURNS_INT
217 ok
= ! gethostbyname_r (hostname
, &hent_r
, buffer_r
, size_r
,
220 hptr
= gethostbyname_r (hostname
, &hent_r
, buffer_r
, size_r
, &herr
);
222 #endif /* GETHOSTNAME_R_RETURNS_INT */
223 if (! ok
&& herr
== ERANGE
)
226 buffer_r
= (char *) _Jv_AllocBytes (size_r
);
229 #endif /* HAVE_STRUCT_HOSTENT_DATA */
232 #else /* HAVE_GETHOSTBYNAME_R */
233 // FIXME: this is insufficient if some other piece of code calls
234 // this gethostbyname.
235 JvSynchronize
sync (&java::net::VMInetAddress::class$
);
236 hptr
= gethostbyname (hostname
);
237 #endif /* HAVE_GETHOSTBYNAME_R */
240 throw new java::net::UnknownHostException (host
);
243 char ** ptr
= hptr
->h_addr_list
;
244 while (*ptr
++) count
++;
246 JArray
<jbyteArray
> *result
=
247 (JArray
<jbyteArray
> *) _Jv_NewObjectArray (
248 count
, _Jv_GetArrayClass(JvPrimClass(byte
), NULL
), NULL
);
249 jbyteArray
* addrs
= elements (result
);
251 for (int i
= 0; i
< count
; i
++)
253 addrs
[i
] = JvNewByteArray (hptr
->h_length
);
254 memcpy (elements (addrs
[i
]), hptr
->h_addr_list
[i
], hptr
->h_length
);
260 java::net::VMInetAddress::aton (jstring host
)
264 int len
= JvGetStringUTFLength(host
);
268 hostname
= (char *) _Jv_AllocBytes (len
+1);
269 JvGetStringUTFRegion (host
, 0, host
->length(), hostname
);
273 #ifdef HAVE_INET_ATON
274 struct in_addr laddr
;
275 if (inet_aton (hostname
, &laddr
))
277 bytes
= (char *) &laddr
;
280 #elif defined(HAVE_INET_ADDR)
282 typedef jint in_addr_t
;
284 in_addr_t laddr
= inet_addr (hostname
);
285 if (laddr
!= (in_addr_t
)(-1))
287 bytes
= (char *) &laddr
;
291 #if defined (HAVE_INET_PTON) && defined (HAVE_INET6)
293 if (len
!= 0 && inet_pton (AF_INET6
, hostname
, inet6_addr
) > 0)
301 jbyteArray result
= JvNewByteArray (blen
);
302 memcpy (elements (result
), bytes
, blen
);