aboutsummaryrefslogtreecommitdiff
path: root/libjava/java/net/natInetAddress.cc
diff options
context:
space:
mode:
authorTom Tromey <tromey@gcc.gnu.org>1999-04-07 14:42:40 +0000
committerTom Tromey <tromey@gcc.gnu.org>1999-04-07 14:42:40 +0000
commitee9dd3721be68b9fa63dea9aa5a1d86e66958cde (patch)
treed96801a16fdf03a5682ef98730fe333a46eef944 /libjava/java/net/natInetAddress.cc
parent140fa895c6b859f827fc4437b91775a82cd105fb (diff)
downloadgcc-ee9dd3721be68b9fa63dea9aa5a1d86e66958cde.zip
gcc-ee9dd3721be68b9fa63dea9aa5a1d86e66958cde.tar.gz
gcc-ee9dd3721be68b9fa63dea9aa5a1d86e66958cde.tar.bz2
Initial revision
From-SVN: r26263
Diffstat (limited to 'libjava/java/net/natInetAddress.cc')
-rw-r--r--libjava/java/net/natInetAddress.cc270
1 files changed, 270 insertions, 0 deletions
diff --git a/libjava/java/net/natInetAddress.cc b/libjava/java/net/natInetAddress.cc
new file mode 100644
index 0000000..7f7d953
--- /dev/null
+++ b/libjava/java/net/natInetAddress.cc
@@ -0,0 +1,270 @@
+// natClass.cc - Implementation of java.lang.Class native methods.
+
+/* Copyright (C) 1998, 1999 Cygnus Solutions
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#include <config.h>
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <string.h>
+#include <errno.h>
+
+#include <sys/param.h>
+#include <sys/types.h>
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+
+#include <cni.h>
+#include <jvm.h>
+#include <java/net/InetAddress.h>
+#include <java/net/UnknownHostException.h>
+#include <java/lang/SecurityException.h>
+
+#if defined(HAVE_UNAME) && ! defined(HAVE_GETHOSTNAME)
+#include <sys/utsname.h>
+#endif
+
+#ifndef HAVE_GETHOSTNAME_DECL
+extern "C" int gethostname (char *name, int namelen);
+#endif
+
+jbyteArray
+java::net::InetAddress::aton (jstring host)
+{
+ char *hostname;
+ char buf[100];
+ int len = JvGetStringUTFLength(host);
+ if (len < 100)
+ hostname = buf;
+ else
+ hostname = (char*) _Jv_AllocBytesChecked (len+1);
+ JvGetStringUTFRegion (host, 0, host->length(), hostname);
+ buf[len] = '\0';
+ char* bytes = NULL;
+ int blen = 0;
+#ifdef HAVE_INET_ATON
+ struct in_addr laddr;
+ if (inet_aton (hostname, &laddr))
+ {
+ bytes = (char*) &laddr;
+ len = 4;
+ }
+#elif defined(HAVE_INET_ADDR)
+ in_addr_t laddr = inet_addr (hostname);
+ if (laddr != (in_addr_t)(-1))
+ {
+ bytes = (char*) &laddr;
+ len = 4;
+ }
+#endif
+#ifdef HAVE_INET_PTON
+ char inet6_addr[16];
+ if (len == 0 && inet_pton (AF_INET6, hostname, inet6_addr) > 0)
+ {
+ bytes = inet6_addr;
+ len = 16;
+ }
+#endif
+ if (blen == 0)
+ return NULL;
+ jbyteArray result = JvNewByteArray (len);
+ memcpy (elements (result), bytes, blen);
+ return result;
+}
+
+
+JArray<java::net::InetAddress*> *
+java::net::InetAddress::lookup (jstring host, java::net::InetAddress* iaddr,
+ jboolean all)
+{
+ struct hostent *hptr = NULL;
+#if defined (HAVE_GETHOSTBYNAME_R) || defined (HAVE_GETHOSTBYADDR_R)
+ struct hostent hent_r;
+ char fixed_buffer[200];
+ char *buffer_r = fixed_buffer;
+ int size_r = sizeof (fixed_buffer);
+#endif
+
+ if (host != NULL)
+ {
+ char *hostname;
+ char buf[100];
+ int len = JvGetStringUTFLength(host);
+ if (len < 100)
+ hostname = buf;
+ else
+ hostname = (char*) _Jv_AllocBytesChecked (len+1);
+ JvGetStringUTFRegion (host, 0, host->length(), hostname);
+ buf[len] = '\0';
+#ifdef HAVE_GETHOSTBYNAME_R
+ int herr = ERANGE;
+ while (hptr == NULL && herr == ERANGE)
+ {
+ int ok;
+#ifdef GETHOSTBYNAME_R_RETURNS_INT
+ ok = ! gethostbyname_r (hostname, &hent_r, buffer_r, size_r,
+ &hptr, &herr);
+#else
+ hptr = gethostbyname_r (hostname, &hent_r, buffer_r, size_r, &herr);
+ ok = hptr != NULL;
+#endif /* GETHOSTNAME_R_RETURNS_INT */
+ if (! ok && herr == ERANGE)
+ {
+ size_r *= 2;
+ buffer_r = (char *) _Jv_AllocBytesChecked (size_r);
+ }
+ }
+#else
+ // FIXME: this is insufficient if some other piece of code calls
+ // this gethostbyname.
+ JvSynchronize sync (java::net::InetAddress::localhostAddress);
+ hptr = gethostbyname (hostname);
+#endif /* HAVE_GETHOSTBYNAME_R */
+ }
+ else
+ {
+ jbyteArray bytes = iaddr->address;
+ char *chars = (char*) elements (bytes);
+ int len = bytes->length;
+ int type;
+ char *val;
+ if (len == 4)
+ {
+ val = chars;
+ type = AF_INET;
+ }
+#ifdef HAVE_INET6
+ else if (len == 16)
+ {
+ val = (char *) &chars;
+ type = AF_INET16;
+ }
+#endif /* HAVE_INET6 */
+ else
+ JvFail ("unrecognized size");
+
+#ifdef HAVE_GETHOSTBYADDR_R
+ int herr = ERANGE;
+ while (hptr == NULL && herr == ERANGE)
+ {
+ int ok;
+#ifdef GETHOSTBYADDR_R_RETURNS_INT
+ ok = ! gethostbyaddr_r (val, len, type, &hent_r,
+ buffer_r, size_r, &hptr, &herr);
+#else
+ hptr = gethostbyaddr_r (val, len, type, &hent_r,
+ buffer_r, size_r, &herr);
+ ok = hptr != NULL;
+#endif /* GETHOSTBYADDR_R_RETURNS_INT */
+ if (! ok && herr == ERANGE)
+ {
+ size_r *= 2;
+ buffer_r = (char *) _Jv_AllocBytesChecked (size_r);
+ }
+ }
+#else /* HAVE_GETHOSTBYADDR_R */
+ // FIXME: this is insufficient if some other piece of code calls
+ // this gethostbyaddr.
+ JvSynchronize sync (java::net::InetAddress::localhostAddress);
+ hptr = gethostbyaddr (val, len, type);
+#endif /* HAVE_GETHOSTBYADDR_R */
+ }
+ if (hptr != NULL)
+ {
+ host = JvNewStringUTF (hptr->h_name);
+ java::lang::SecurityException *ex = checkConnect (host);
+ if (ex != NULL)
+ {
+ if (iaddr == NULL || iaddr->address == NULL)
+ JvThrow (ex);
+ hptr = NULL;
+ }
+ }
+ if (hptr == NULL)
+ {
+ if (iaddr != NULL && iaddr->address != NULL)
+ {
+ iaddr->hostname = iaddr->getHostAddress();
+ return NULL;
+ }
+ else
+ JvThrow (new java::net::UnknownHostException(host));
+ }
+ int count;
+ if (all)
+ {
+ char** ptr = hptr->h_addr_list;
+ count = 0;
+ while (*ptr++) count++;
+ }
+ else
+ count = 1;
+ JArray<java::net::InetAddress*> *result;
+ java::net::InetAddress** iaddrs;
+ if (all)
+ {
+ result = java::net::InetAddress::allocArray (count);
+ iaddrs = elements (result);
+ }
+ else
+ {
+ result = NULL;
+ iaddrs = &iaddr;
+ }
+
+ for (int i = 0; i < count; i++)
+ {
+ if (iaddrs[i] == NULL)
+ iaddrs[i] = new java::net::InetAddress (NULL, NULL);
+ if (i == 0)
+ iaddrs[0]->hostname = host;
+ if (iaddrs[i]->address == NULL)
+ {
+ char *bytes = hptr->h_addr_list[i];
+ iaddr->address = JvNewByteArray (hptr->h_length);
+ memcpy (elements (iaddr->address), bytes, hptr->h_length);
+ }
+ }
+ return result;
+}
+
+jstring
+java::net::InetAddress::getLocalHostname ()
+{
+ char *chars;
+#ifdef HAVE_GETHOSTNAME
+ char buffer[MAXHOSTNAMELEN];
+ if (gethostname (buffer, MAXHOSTNAMELEN))
+ return NULL;
+ chars = buffer;
+#elif HAVE_UNAME
+ struct utsname stuff;
+ if (uname (&stuff) != 0)
+ return NULL:
+ chars = stuff.nodename;
+#else
+ return NULL;
+#endif
+ // It is admittedly non-optimal to convert the hostname to Unicode
+ // only to convert it back in getByName, but simplicity wins. Note
+ // that unless there is a SecurityManager, we only get called once
+ // anyway, thanks to the InetAddress.localhost cache.
+ return JvNewStringUTF (chars);
+}