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
18 #ifndef MAXHOSTNAMELEN
19 #define MAXHOSTNAMELEN 64
20 #endif /* MAXHOSTNAMELEN */
30 #include <sys/param.h>
31 #include <sys/types.h>
32 #ifdef HAVE_SYS_SOCKET_H
33 #include <sys/socket.h>
35 #ifdef HAVE_NETINET_IN_H
36 #include <netinet/in.h>
38 #ifdef HAVE_ARPA_INET_H
39 #include <arpa/inet.h>
45 #endif /* USE_WINSOCK */
49 #include <java/net/InetAddress.h>
50 #include <java/net/UnknownHostException.h>
51 #include <java/lang/SecurityException.h>
53 #if defined(HAVE_UNAME) && ! defined(HAVE_GETHOSTNAME)
54 #include <sys/utsname.h>
57 #ifndef HAVE_GETHOSTNAME_DECL
58 extern "C" int gethostname (char *name
, int namelen
);
61 #ifdef DISABLE_JAVA_NET
64 java::net::InetAddress::aton (jstring
)
70 java::net::InetAddress::getFamily (jbyteArray bytes
)
75 JArray
<java::net::InetAddress
*> *
76 java::net::InetAddress::lookup (jstring
, java::net::InetAddress
*, jboolean
)
82 java::net::InetAddress::getLocalHostname ()
87 #else /* DISABLE_JAVA_NET */
90 java::net::InetAddress::aton (jstring host
)
94 int len
= JvGetStringUTFLength(host
);
98 hostname
= (char*) _Jv_AllocBytesChecked (len
+1);
99 JvGetStringUTFRegion (host
, 0, host
->length(), hostname
);
103 #ifdef HAVE_INET_ATON
104 struct in_addr laddr
;
105 if (inet_aton (hostname
, &laddr
))
107 bytes
= (char*) &laddr
;
110 #elif defined(HAVE_INET_ADDR)
112 typedef jint in_addr_t
;
114 in_addr_t laddr
= inet_addr (hostname
);
115 if (laddr
!= (in_addr_t
)(-1))
117 bytes
= (char*) &laddr
;
121 #if defined (HAVE_INET_PTON) && defined (HAVE_INET6)
123 if (len
== 0 && inet_pton (AF_INET6
, hostname
, inet6_addr
) > 0)
131 jbyteArray result
= JvNewByteArray (blen
);
132 memcpy (elements (result
), bytes
, blen
);
137 java::net::InetAddress::getFamily (jbyteArray bytes
)
139 int len
= bytes
->length
;
145 #endif /* HAVE_INET6 */
147 JvFail ("unrecognized size");
151 JArray
<java::net::InetAddress
*> *
152 java::net::InetAddress::lookup (jstring host
, java::net::InetAddress
* iaddr
,
155 struct hostent
*hptr
= NULL
;
156 #if defined (HAVE_GETHOSTBYNAME_R) || defined (HAVE_GETHOSTBYADDR_R)
157 struct hostent hent_r
;
158 #if HAVE_STRUCT_HOSTENT_DATA
159 struct hostent_data fixed_buffer
, *buffer_r
= &fixed_buffer
;
161 #if defined (__GLIBC__)
162 // FIXME: in glibc, gethostbyname_r returns NETDB_INTERNAL to herr and
163 // ERANGE to errno if the buffer size is too small, rather than what is
164 // expected here. We work around this by setting a bigger buffer size and
165 // hoping that it is big enough.
166 char fixed_buffer
[1024];
168 char fixed_buffer
[200];
170 char *buffer_r
= fixed_buffer
;
171 int size_r
= sizeof (fixed_buffer
);
179 int len
= JvGetStringUTFLength(host
);
183 hostname
= (char*) _Jv_AllocBytesChecked (len
+1);
184 JvGetStringUTFRegion (host
, 0, host
->length(), hostname
);
186 #ifdef HAVE_GETHOSTBYNAME_R
190 #if HAVE_STRUCT_HOSTENT_DATA
191 ok
= ! gethostbyname_r (hostname
, &hent_r
, buffer_r
);
194 #ifdef GETHOSTBYNAME_R_RETURNS_INT
195 ok
= ! gethostbyname_r (hostname
, &hent_r
, buffer_r
, size_r
,
198 hptr
= gethostbyname_r (hostname
, &hent_r
, buffer_r
, size_r
, &herr
);
200 #endif /* GETHOSTNAME_R_RETURNS_INT */
201 if (! ok
&& herr
== ERANGE
)
204 buffer_r
= (char *) _Jv_AllocBytesChecked (size_r
);
207 #endif /* HAVE_STRUCT_HOSTENT_DATA */
211 // FIXME: this is insufficient if some other piece of code calls
212 // this gethostbyname.
213 JvSynchronize
sync (java::net::InetAddress::localhostAddress
);
214 hptr
= gethostbyname (hostname
);
215 #endif /* HAVE_GETHOSTBYNAME_R */
219 jbyteArray bytes
= iaddr
->addr
;
220 char *chars
= (char*) elements (bytes
);
221 int len
= bytes
->length
;
227 type
= iaddr
->family
= AF_INET
;
232 val
= (char *) &chars
;
233 type
= iaddr
->family
= AF_INET6
;
235 #endif /* HAVE_INET6 */
237 JvFail ("unrecognized size");
239 #ifdef HAVE_GETHOSTBYADDR_R
243 #if HAVE_STRUCT_HOSTENT_DATA
244 ok
= ! gethostbyaddr_r (val
, len
, type
, &hent_r
, buffer_r
);
247 #ifdef GETHOSTBYADDR_R_RETURNS_INT
248 ok
= ! gethostbyaddr_r (val
, len
, type
, &hent_r
,
249 buffer_r
, size_r
, &hptr
, &herr
);
251 hptr
= gethostbyaddr_r (val
, len
, type
, &hent_r
,
252 buffer_r
, size_r
, &herr
);
254 #endif /* GETHOSTBYADDR_R_RETURNS_INT */
255 if (! ok
&& herr
== ERANGE
)
258 buffer_r
= (char *) _Jv_AllocBytesChecked (size_r
);
261 #endif /* HAVE_STRUCT_HOSTENT_DATA */
264 #else /* HAVE_GETHOSTBYADDR_R */
265 // FIXME: this is insufficient if some other piece of code calls
266 // this gethostbyaddr.
267 JvSynchronize
sync (java::net::InetAddress::localhostAddress
);
268 hptr
= gethostbyaddr (val
, len
, type
);
269 #endif /* HAVE_GETHOSTBYADDR_R */
274 host
= JvNewStringUTF (hptr
->h_name
);
275 java::lang::SecurityException
*ex
= checkConnect (host
);
278 if (iaddr
== NULL
|| iaddr
->addr
== NULL
)
285 if (iaddr
!= NULL
&& iaddr
->addr
!= NULL
)
287 iaddr
->hostName
= iaddr
->getHostAddress();
291 throw new java::net::UnknownHostException(host
);
296 char** ptr
= hptr
->h_addr_list
;
298 while (*ptr
++) count
++;
302 JArray
<java::net::InetAddress
*> *result
;
303 java::net::InetAddress
** iaddrs
;
306 result
= java::net::InetAddress::allocArray (count
);
307 iaddrs
= elements (result
);
315 for (int i
= 0; i
< count
; i
++)
317 if (iaddrs
[i
] == NULL
)
318 iaddrs
[i
] = new java::net::InetAddress (NULL
, NULL
);
319 if (iaddrs
[i
]->hostName
== NULL
)
320 iaddrs
[i
]->hostName
= host
;
321 if (iaddrs
[i
]->addr
== NULL
)
323 char *bytes
= hptr
->h_addr_list
[i
];
324 iaddrs
[i
]->addr
= JvNewByteArray (hptr
->h_length
);
325 iaddrs
[i
]->family
= getFamily (iaddrs
[i
]->addr
);
326 memcpy (elements (iaddrs
[i
]->addr
), bytes
, hptr
->h_length
);
333 java::net::InetAddress::getLocalHostname ()
336 #ifdef HAVE_GETHOSTNAME
337 char buffer
[MAXHOSTNAMELEN
];
338 if (gethostname (buffer
, MAXHOSTNAMELEN
))
342 struct utsname stuff
;
343 if (uname (&stuff
) != 0)
345 chars
= stuff
.nodename
;
349 // It is admittedly non-optimal to convert the hostname to Unicode
350 // only to convert it back in getByName, but simplicity wins. Note
351 // that unless there is a SecurityManager, we only get called once
352 // anyway, thanks to the InetAddress.localhost cache.
353 return JvNewStringUTF (chars
);
356 #endif /* DISABLE_JAVA_NET */