aboutsummaryrefslogtreecommitdiff
path: root/libjava/java/net
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/java/net')
-rw-r--r--libjava/java/net/BindException.java35
-rw-r--r--libjava/java/net/ConnectException.java35
-rw-r--r--libjava/java/net/ContentHandler.java29
-rw-r--r--libjava/java/net/ContentHandlerFactory.java27
-rw-r--r--libjava/java/net/FileNameMap.java27
-rw-r--r--libjava/java/net/HttpURLConnection.java174
-rw-r--r--libjava/java/net/InetAddress.java255
-rw-r--r--libjava/java/net/MalformedURLException.java35
-rw-r--r--libjava/java/net/NoRouteToHostException.java35
-rw-r--r--libjava/java/net/PlainSocketImpl.java64
-rw-r--r--libjava/java/net/ProtocolException.java35
-rw-r--r--libjava/java/net/ServerSocket.java105
-rw-r--r--libjava/java/net/Socket.java209
-rw-r--r--libjava/java/net/SocketException.java33
-rw-r--r--libjava/java/net/SocketImpl.java70
-rw-r--r--libjava/java/net/SocketImplFactory.java25
-rw-r--r--libjava/java/net/URL.java341
-rw-r--r--libjava/java/net/URLConnection.java423
-rw-r--r--libjava/java/net/URLStreamHandler.java107
-rw-r--r--libjava/java/net/URLStreamHandlerFactory.java27
-rw-r--r--libjava/java/net/UnknownHostException.java34
-rw-r--r--libjava/java/net/UnknownServiceException.java35
-rw-r--r--libjava/java/net/natInetAddress.cc270
-rw-r--r--libjava/java/net/natPlainSocketImpl.cc177
24 files changed, 2607 insertions, 0 deletions
diff --git a/libjava/java/net/BindException.java b/libjava/java/net/BindException.java
new file mode 100644
index 0000000..5f7b491
--- /dev/null
+++ b/libjava/java/net/BindException.java
@@ -0,0 +1,35 @@
+// BindException.java
+
+/* Copyright (C) 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. */
+
+package java.net;
+
+/**
+ * @author Warren Levy <warrenl@cygnus.com>
+ * @date March 5, 1999.
+ */
+
+/**
+ * Written using on-line Java Platform 1.2 API Specification, as well
+ * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998).
+ * Status: Believed complete and correct.
+ */
+
+public class BindException extends SocketException
+{
+ public BindException()
+ {
+ super();
+ }
+
+ public BindException(String msg)
+ {
+ super(msg);
+ }
+}
diff --git a/libjava/java/net/ConnectException.java b/libjava/java/net/ConnectException.java
new file mode 100644
index 0000000..d4d3a48
--- /dev/null
+++ b/libjava/java/net/ConnectException.java
@@ -0,0 +1,35 @@
+// ConnectException.java
+
+/* Copyright (C) 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. */
+
+package java.net;
+
+/**
+ * @author Warren Levy <warrenl@cygnus.com>
+ * @date March 5, 1999.
+ */
+
+/**
+ * Written using on-line Java Platform 1.2 API Specification, as well
+ * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998).
+ * Status: Believed complete and correct.
+ */
+
+public class ConnectException extends SocketException
+{
+ public ConnectException()
+ {
+ super();
+ }
+
+ public ConnectException(String msg)
+ {
+ super(msg);
+ }
+}
diff --git a/libjava/java/net/ContentHandler.java b/libjava/java/net/ContentHandler.java
new file mode 100644
index 0000000..fd2e3b1
--- /dev/null
+++ b/libjava/java/net/ContentHandler.java
@@ -0,0 +1,29 @@
+// ContentHandler.java - Superclass of classes that read from a URLConnection.
+
+/* Copyright (C) 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. */
+
+package java.net;
+
+import java.io.IOException;
+
+/**
+ * @author Warren Levy <warrenl@cygnus.com>
+ * @date March 5, 1999.
+ */
+
+/**
+ * Written using on-line Java Platform 1.2 API Specification, as well
+ * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998).
+ * Status: Believed complete and correct.
+ */
+
+public abstract class ContentHandler
+{
+ public abstract Object getContent(URLConnection urlc) throws IOException;
+}
diff --git a/libjava/java/net/ContentHandlerFactory.java b/libjava/java/net/ContentHandlerFactory.java
new file mode 100644
index 0000000..ee6dcff
--- /dev/null
+++ b/libjava/java/net/ContentHandlerFactory.java
@@ -0,0 +1,27 @@
+// ContentHandlerFactory.java - Abstract Content Handler factory.
+
+/* Copyright (C) 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. */
+
+package java.net;
+
+/**
+ * @author Warren Levy <warrenl@cygnus.com>
+ * @date March 5, 1999.
+ */
+
+/**
+ * Written using on-line Java Platform 1.2 API Specification, as well
+ * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998).
+ * Status: Believed complete and correct.
+ */
+
+public abstract interface ContentHandlerFactory
+{
+ public ContentHandler createContentHandler(String mimetype);
+}
diff --git a/libjava/java/net/FileNameMap.java b/libjava/java/net/FileNameMap.java
new file mode 100644
index 0000000..24e8ef8
--- /dev/null
+++ b/libjava/java/net/FileNameMap.java
@@ -0,0 +1,27 @@
+// FileNameMap.java - Abstract interface to map from a File Name to MIME type.
+
+/* Copyright (C) 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. */
+
+package java.net;
+
+/**
+ * @author Warren Levy <warrenl@cygnus.com>
+ * @date March 5, 1999.
+ */
+
+/**
+ * Written using on-line Java Platform 1.2 API Specification, as well
+ * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998).
+ * Status: Believed complete and correct.
+ */
+
+public abstract interface FileNameMap
+{
+ public String getContentTypeFor(String fileName);
+}
diff --git a/libjava/java/net/HttpURLConnection.java b/libjava/java/net/HttpURLConnection.java
new file mode 100644
index 0000000..8b05b73
--- /dev/null
+++ b/libjava/java/net/HttpURLConnection.java
@@ -0,0 +1,174 @@
+// HttpURLConnection.java - Subclass of communications links using
+// Hypertext Transfer Protocol.
+
+/* Copyright (C) 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. */
+
+package java.net;
+
+import java.io.*;
+
+/**
+ * @author Warren Levy <warrenl@cygnus.com>
+ * @date March 29, 1999.
+ */
+
+/**
+ * Written using on-line Java Platform 1.2 API Specification, as well
+ * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998).
+ * Status: Believed complete and correct.
+ */
+
+public abstract class HttpURLConnection extends URLConnection
+{
+ /* HTTP Success Response Codes */
+ public static final int HTTP_OK = 200;
+ public static final int HTTP_CREATED = 201;
+ public static final int HTTP_ACCEPTED = 202;
+ public static final int HTTP_NOT_AUTHORITATIVE = 203;
+ public static final int HTTP_NO_CONTENT = 204;
+ public static final int HTTP_RESET = 205;
+ public static final int HTTP_PARTIAL = 206;
+
+ /* HTTP Redirection Response Codes */
+ public static final int HTTP_MULT_CHOICE = 300;
+ public static final int HTTP_MOVED_PERM = 301;
+ public static final int HTTP_MOVED_TEMP = 302;
+ public static final int HTTP_SEE_OTHER = 303;
+ public static final int HTTP_NOT_MODIFIED = 304;
+ public static final int HTTP_USE_PROXY = 305;
+
+ /* HTTP Client Error Response Codes */
+ public static final int HTTP_BAD_REQUEST = 400;
+ public static final int HTTP_UNAUTHORIZED = 401;
+ public static final int HTTP_PAYMENT_REQUIRED = 402;
+ public static final int HTTP_FORBIDDEN = 403;
+ public static final int HTTP_NOT_FOUND = 404;
+ public static final int HTTP_BAD_METHOD = 405;
+ public static final int HTTP_NOT_ACCEPTABLE = 406;
+ public static final int HTTP_PROXY_AUTH = 407;
+ public static final int HTTP_CLIENT_TIMEOUT = 408;
+ public static final int HTTP_CONFLICT = 409;
+ public static final int HTTP_GONE = 410;
+ public static final int HTTP_LENGTH_REQUIRED = 411;
+ public static final int HTTP_PRECON_FAILED = 412;
+ public static final int HTTP_ENTITY_TOO_LARGE = 413;
+ public static final int HTTP_REQ_TOO_LONG = 414;
+ public static final int HTTP_UNSUPPORTED_TYPE = 415;
+
+ /* HTTP Server Error Response Codes */
+ public static final int HTTP_SERVER_ERROR = 500;
+ public static final int HTTP_INTERNAL_ERROR = 501;
+ public static final int HTTP_BAD_GATEWAY = 502;
+ public static final int HTTP_UNAVAILABLE = 503;
+ public static final int HTTP_GATEWAY_TIMEOUT = 504;
+ public static final int HTTP_VERSION = 505;
+
+ protected String method = "GET";
+ protected int responseCode = -1;
+ protected String responseMessage;
+
+ static boolean followRedirects = true;
+
+ protected HttpURLConnection(URL url)
+ {
+ super(url);
+ }
+
+ public abstract void disconnect();
+
+ public abstract boolean usingProxy();
+
+ public static void setFollowRedirects(boolean set)
+ {
+ // Throw an exception if an extant security mgr precludes
+ // setting the factory.
+ SecurityManager s = System.getSecurityManager();
+ if (s != null)
+ s.checkSetFactory();
+
+ followRedirects = set;
+ }
+
+ public static boolean getFollowRedirects()
+ {
+ return followRedirects;
+ }
+
+ public void setRequestMethod(String method) throws ProtocolException
+ {
+ if (connected)
+ throw new ProtocolException("Already connected");
+
+ if (method.equals("GET") || method.equals("POST") ||
+ method.equals("HEAD") || method.equals("OPTIONS") ||
+ method.equals("PUT") || method.equals("DELETE") ||
+ method.equals("TRACE"))
+ this.method = method;
+ else
+ throw new ProtocolException("Invalid HTTP request method");
+ }
+
+ public String getRequestMethod()
+ {
+ return method;
+ }
+
+ public int getResponseCode() throws IOException
+ {
+ getResponseVals();
+ return responseCode;
+ }
+
+ public String getResponseMessage() throws IOException
+ {
+ getResponseVals();
+ return responseMessage;
+ }
+
+ private void getResponseVals() throws IOException
+ {
+ // Response is the first header received from the connection.
+ String respField = getHeaderField(0);
+ if (! respField.startsWith("HTTP/"))
+ {
+ // Set to default values on failure.
+ responseCode = -1;
+ responseMessage = null;
+ return;
+ }
+
+ int firstSpc, nextSpc;
+ firstSpc = respField.indexOf(' ');
+ nextSpc = respField.indexOf(' ', firstSpc + 1);
+ responseMessage = respField.substring(nextSpc + 1);
+ String codeStr = respField.substring(firstSpc + 1, nextSpc);
+ try
+ {
+ responseCode = Integer.parseInt(codeStr);
+ }
+ catch (NumberFormatException e)
+ {
+ // Set to default values on failure.
+ responseCode = -1;
+ responseMessage = null;
+ }
+ if (responseCode == HTTP_NOT_FOUND)
+ throw new FileNotFoundException(url.toString());
+ else if (responseCode >= 400)
+ throw new IOException(url.toString() + " " + respField);
+ }
+
+ // TODO12: public Permission getPermission() throws IOException
+ // {
+ // }
+
+ // TODO12: public InputStream getErrorStream()
+ // {
+ // }
+}
diff --git a/libjava/java/net/InetAddress.java b/libjava/java/net/InetAddress.java
new file mode 100644
index 0000000..baf5153e
--- /dev/null
+++ b/libjava/java/net/InetAddress.java
@@ -0,0 +1,255 @@
+// INetAddress.java -- An Internet Protocol (IP) address.
+
+/* 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. */
+
+package java.net;
+
+/**
+ * @author Per Bothner
+ * @date January 6, 1999.
+ */
+
+/*
+ * Written using on-line Java Platform 1.2 API Specification, as well
+ * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998).
+ * (The latter turns out to have some errors ...)
+ * Status: Believed complete and correct.
+ */
+
+public final class InetAddress
+{
+ String hostname;
+ byte[] address;
+
+ InetAddress (byte[] address, String hostname)
+ {
+ this.address = address;
+ this.hostname = hostname;
+ }
+
+ public boolean isMulticastAddress ()
+ {
+ int len = address.length;
+ if (len == 4)
+ return (address[0] & 0xF0) == 0xE0;
+ if (len == 16)
+ return address[0] == (byte) 0xFF;
+ return false;
+ }
+
+ public String getHostName ()
+ {
+ if (hostname == null)
+ lookup (null, this, false);
+ return hostname;
+ }
+
+ public byte[] getAddress ()
+ {
+ // An experiment shows that JDK1.2 returns a different byte array each
+ // time. This makes sense, in terms of security.
+ return (byte[]) address.clone();
+ }
+
+ /* Helper function due to a CNI limitation. */
+ private static InetAddress[] allocArray (int count)
+ {
+ return new InetAddress[count];
+ }
+
+ /* Helper function due to a CNI limitation. */
+ private static SecurityException checkConnect (String hostname)
+ {
+ SecurityManager s = System.getSecurityManager();
+ if (s == null)
+ return null;
+ try
+ {
+ s.checkConnect(hostname, -1);
+ return null;
+ }
+ catch (SecurityException ex)
+ {
+ return ex;
+ }
+ }
+
+ public String getHostAddress ()
+ {
+ StringBuffer sbuf = new StringBuffer(40);
+ int len = address.length;
+ int i = 0;
+ if (len == 16)
+ { // An IPv6 address.
+ for (; ; i += 2)
+ {
+ if (i >= 16)
+ return sbuf.toString();
+ int x = ((address[i] & 0xFF) << 8) | (address[i+1] & 0xFF);
+ boolean empty = sbuf.length() == 0;
+ if (empty)
+ {
+ if (i == 10 && x == 0xFFFF)
+ { // IPv4-mapped IPv6 address.
+ sbuf.append(":FFFF:");
+ break; // Continue as IPv4 address;
+ }
+ else if (i == 12)
+ { // IPv4-compatible IPv6 address.
+ sbuf.append(':');
+ break; // Continue as IPv4 address.
+ }
+ else if (i > 0)
+ sbuf.append("::");
+ }
+ else
+ sbuf.append(':');
+ if (x != 0 || i >= 14)
+ sbuf.append(Integer.toHexString(x).toUpperCase());
+ }
+ }
+ for ( ; ; )
+ {
+ sbuf.append(address[i] & 0xFF);
+ i++;
+ if (i == len)
+ break;
+ sbuf.append('.');
+ }
+ return sbuf.toString();
+ }
+
+ public int hashCode()
+ {
+ // There hashing algorithm is not specified, but a simple experiment
+ // shows that it is equal to the address, as a 32-bit big-endian integer.
+ int hash = 0;
+ int len = address.length;
+ int i = len > 4 ? len - 4 : 0;
+ for ( ; i < len; i++)
+ hash = (hash << 8) | (address[i] & 0xFF);
+ return hash;
+ }
+
+ public boolean equals (Object obj)
+ {
+ if (obj == null || ! (obj instanceof InetAddress))
+ return false;
+ // "The Java Class Libraries" 2nd edition says "If a machine has
+ // multiple names instances of InetAddress for different name of
+ // that same machine are not equal. This is because they have
+ // different host names." This violates the description in the
+ // JDK 1.2 API documentation. A little experiementation
+ // shows that the latter is correct.
+ byte[] addr1 = address;
+ byte[] addr2 = ((InetAddress) obj).address;
+ if (addr1.length != addr2.length)
+ return false;
+ for (int i = addr1.length; --i >= 0; )
+ if (addr1[i] != addr2[i])
+ return false;
+ return true;
+ }
+
+ public String toString()
+ {
+ return getHostName()+'/'+getHostAddress();
+ }
+
+ /** If host is a valid numeric IP address, return the numeric address.
+ * Otherwise, return null. */
+ private static native byte[] aton (String host);
+
+ private static native InetAddress[] lookup
+ (String hostname, InetAddress addr, boolean all);
+
+ public static InetAddress getByName (String host)
+ throws UnknownHostException
+ {
+ if (host == null)
+ return getLocalHost();
+ byte[] address = aton(host);
+ if (address != null)
+ return new InetAddress(address, null);
+ InetAddress iaddr = new InetAddress(null, null);
+ lookup(host, iaddr, false);
+ return iaddr;
+ }
+
+ public static InetAddress[] getAllByName (String host)
+ throws UnknownHostException
+ {
+ byte[] address = aton(host);
+ if (address != null)
+ {
+ InetAddress[] result = new InetAddress[1];
+ result[0] = new InetAddress(address, null);
+ return result;
+ }
+ return lookup(host, null, true);
+ }
+
+ private static final byte[] localhostAddress = { 127, 0, 0, 1 };
+
+ private static native String getLocalHostname ();
+
+ private static InetAddress localhost = null;
+
+ public static InetAddress getLocalHost() throws UnknownHostException
+ {
+ SecurityManager s = System.getSecurityManager();
+ // Experimentation shows that JDK1.2 does cache the result.
+ // However, if there is a security manager, and the cached result
+ // is other than "localhost", we need to check again.
+ if (localhost == null
+ || (s != null && localhost.address != localhostAddress))
+ getLocalHost(s);
+ return localhost;
+ }
+
+ private static synchronized void getLocalHost(SecurityManager s)
+ throws UnknownHostException
+ {
+ // Check the localhost cache again, now that we've synchronized.
+ if (s == null && localhost != null)
+ return;
+ String hostname = getLocalHostname();
+ if (s != null)
+ {
+ // "The Java Class Libraries" suggests that if the security
+ // manager disallows getting the local host name, then
+ // we use the loopback host.
+ // However, the JDK 1.2 API claims to throw SecurityException,
+ // which seems to suggest SecurityException is *not* caught.
+ // In this case, experimentation shows that former is correct.
+ try
+ {
+ // This is wrong, if the name returned from getLocalHostname()
+ // is not a fully qualified name. FIXME.
+ s.checkConnect(hostname, -1);
+ }
+ catch (SecurityException ex)
+ {
+ hostname = null;
+ }
+ }
+ if (hostname != null)
+ {
+ try
+ {
+ localhost = getByName(hostname);
+ }
+ catch (Exception ex)
+ {
+ }
+ }
+ if (localhost == null)
+ localhost = new InetAddress (localhostAddress, "localhost");
+ }
+}
diff --git a/libjava/java/net/MalformedURLException.java b/libjava/java/net/MalformedURLException.java
new file mode 100644
index 0000000..a5a8db5
--- /dev/null
+++ b/libjava/java/net/MalformedURLException.java
@@ -0,0 +1,35 @@
+// MalformedURLException.java
+
+/* Copyright (C) 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. */
+
+package java.net;
+
+/**
+ * @author Warren Levy <warrenl@cygnus.com>
+ * @date March 5, 1999.
+ */
+
+/**
+ * Written using on-line Java Platform 1.2 API Specification, as well
+ * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998).
+ * Status: Believed complete and correct.
+ */
+
+public class MalformedURLException extends java.io.IOException
+{
+ public MalformedURLException()
+ {
+ super();
+ }
+
+ public MalformedURLException(String msg)
+ {
+ super(msg);
+ }
+}
diff --git a/libjava/java/net/NoRouteToHostException.java b/libjava/java/net/NoRouteToHostException.java
new file mode 100644
index 0000000..dc01688
--- /dev/null
+++ b/libjava/java/net/NoRouteToHostException.java
@@ -0,0 +1,35 @@
+// NoRouteToHostException.java
+
+/* Copyright (C) 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. */
+
+package java.net;
+
+/**
+ * @author Warren Levy <warrenl@cygnus.com>
+ * @date March 5, 1999.
+ */
+
+/**
+ * Written using on-line Java Platform 1.2 API Specification, as well
+ * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998).
+ * Status: Believed complete and correct.
+ */
+
+public class NoRouteToHostException extends SocketException
+{
+ public NoRouteToHostException()
+ {
+ super();
+ }
+
+ public NoRouteToHostException(String msg)
+ {
+ super(msg);
+ }
+}
diff --git a/libjava/java/net/PlainSocketImpl.java b/libjava/java/net/PlainSocketImpl.java
new file mode 100644
index 0000000..5bc2cae
--- /dev/null
+++ b/libjava/java/net/PlainSocketImpl.java
@@ -0,0 +1,64 @@
+// 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. */
+
+package java.net;
+import java.io.*;
+
+class PlainSocketImpl extends SocketImpl
+{
+ int fnum = -1;
+
+ protected native void create (boolean stream) throws IOException;
+
+ protected void connect (String host, int port) throws IOException
+ {
+ connect(InetAddress.getByName(host), port);
+ }
+
+ protected native void connect (InetAddress host, int port)
+ throws IOException;
+
+ protected native void bind (InetAddress host, int port) throws IOException;
+
+ protected native void listen (int backlog) throws IOException;
+
+ private native void accept (PlainSocketImpl s) throws IOException;
+ protected void accept (SocketImpl s) throws IOException
+ {
+ accept((PlainSocketImpl) s);
+ }
+
+ private InputStream in;
+ private OutputStream out;
+
+ protected InputStream getInputStream() throws IOException
+ {
+ if (in == null)
+ in = new FileInputStream (fd);
+ return in;
+ }
+
+ protected OutputStream getOutputStream() throws IOException
+ {
+ if (out == null)
+ out = new FileOutputStream (fd);
+ return out;
+ }
+
+ protected int available () throws IOException
+ {
+ return in.available();
+ }
+
+ protected void close () throws IOException
+ {
+ fd.close();
+ }
+}
diff --git a/libjava/java/net/ProtocolException.java b/libjava/java/net/ProtocolException.java
new file mode 100644
index 0000000..f7db685
--- /dev/null
+++ b/libjava/java/net/ProtocolException.java
@@ -0,0 +1,35 @@
+// ProtocolException.java
+
+/* Copyright (C) 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. */
+
+package java.net;
+
+/**
+ * @author Warren Levy <warrenl@cygnus.com>
+ * @date March 5, 1999.
+ */
+
+/**
+ * Written using on-line Java Platform 1.2 API Specification, as well
+ * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998).
+ * Status: Believed complete and correct.
+ */
+
+public class ProtocolException extends java.io.IOException
+{
+ public ProtocolException()
+ {
+ super();
+ }
+
+ public ProtocolException(String msg)
+ {
+ super(msg);
+ }
+}
diff --git a/libjava/java/net/ServerSocket.java b/libjava/java/net/ServerSocket.java
new file mode 100644
index 0000000..e4b5069
--- /dev/null
+++ b/libjava/java/net/ServerSocket.java
@@ -0,0 +1,105 @@
+// Socket.java
+
+/* Copyright (C) 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. */
+
+/**
+ * @author Per Bothner <bothner@cygnus.com>
+ * @date January 6, 1999.
+ */
+
+/** Written using on-line Java Platform 1.2 API Specification.
+ * Status: I believe all methods are implemented, but many
+ * of them just throw an exception.
+ */
+
+package java.net;
+import java.io.*;
+
+public class ServerSocket
+{
+ static SocketImplFactory factory;
+ SocketImpl impl;
+
+ public ServerSocket (int port)
+ throws java.io.IOException
+ {
+ this(port, 5);
+ }
+
+ public ServerSocket (int port, int backlog)
+ throws java.io.IOException
+ {
+ this(port, backlog, InetAddress.getLocalHost());
+ }
+
+ public ServerSocket (int port, int backlog, InetAddress bindAddr)
+ throws java.io.IOException
+ {
+ if (factory == null)
+ this.impl = new PlainSocketImpl();
+ else
+ this.impl = factory.createSocketImpl();
+ SecurityManager s = System.getSecurityManager();
+ if (s != null)
+ s.checkListen(port);
+ impl.create(true);
+ impl.bind(bindAddr, port);
+ impl.listen(backlog);
+ }
+
+ public InetAddress getInetAddress()
+ {
+ return impl.getInetAddress();
+ }
+
+ public int getLocalPort()
+ {
+ return impl.getLocalPort();
+ }
+
+ public Socket accept () throws IOException
+ {
+ Socket s = new Socket(Socket.factory == null ? new PlainSocketImpl()
+ : Socket.factory.createSocketImpl());
+ implAccept (s);
+ return s;
+ }
+
+ protected final void implAccept (Socket s) throws IOException
+ {
+ impl.accept(s.impl);
+ }
+
+ public void close () throws IOException
+ {
+ impl.close();
+ }
+
+ public void setSoTimeout (int timeout) throws SocketException
+ {
+ throw new InternalError("ServerSocket.setSoTimeout not implemented");
+ }
+
+ public int getSoTimeout () throws SocketException
+ {
+ throw new InternalError("ServerSocket.getSoTimeout not implemented");
+ }
+
+ public String toString ()
+ {
+ return impl.toString();
+ }
+
+ public static void setSocketImplFactory (SocketImplFactory fac)
+ throws IOException
+ {
+ factory = fac;
+ }
+
+}
diff --git a/libjava/java/net/Socket.java b/libjava/java/net/Socket.java
new file mode 100644
index 0000000..8c027d9
--- /dev/null
+++ b/libjava/java/net/Socket.java
@@ -0,0 +1,209 @@
+// Socket.java
+
+/* Copyright (C) 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. */
+
+/**
+ * @author Per Bothner <bothner@cygnus.com>
+ * @date January 6, 1999.
+ */
+
+/** Written using on-line Java Platform 1.2 API Specification.
+ * Status: I believe all methods are implemented, but many
+ * of them just throw an exception.
+ */
+
+package java.net;
+import java.io.*;
+
+public class Socket
+{
+ static SocketImplFactory factory;
+ SocketImpl impl;
+
+ protected Socket ()
+ {
+ }
+
+ protected Socket (SocketImpl impl) throws SocketException
+ {
+ this.impl = impl;
+ }
+
+ public Socket (String host, int port)
+ throws UnknownHostException, IOException
+ {
+ this(factory == null ? new PlainSocketImpl() : factory.createSocketImpl());
+ SecurityManager s = System.getSecurityManager();
+ if (s != null)
+ s.checkConnect(host, port);
+ impl.create(true);
+ impl.connect(host, port);
+ }
+
+ public Socket (InetAddress address, int port)
+ throws IOException
+ {
+ this(factory == null ? new PlainSocketImpl() : factory.createSocketImpl());
+ SecurityManager s = System.getSecurityManager();
+ if (s != null)
+ s.checkConnect(address.getHostName(), port);
+ impl.create(true);
+ impl.connect(address, port);
+ }
+
+ public Socket (String host, int port,
+ InetAddress localAddr, int localPort) throws IOException
+ {
+ this(factory == null ? new PlainSocketImpl() : factory.createSocketImpl());
+ SecurityManager s = System.getSecurityManager();
+ if (s != null)
+ s.checkConnect(host, port);
+ impl.create(true);
+ impl.bind(localAddr, localPort);
+ impl.connect(host, port);
+ }
+
+ public Socket (InetAddress address, int port,
+ InetAddress localAddr, int localPort) throws IOException
+ {
+ this(factory == null ? new PlainSocketImpl() : factory.createSocketImpl());
+ SecurityManager s = System.getSecurityManager();
+ if (s != null)
+ s.checkConnect(address.getHostName(), port);
+ impl.create(true);
+ impl.bind(localAddr, localPort);
+ impl.connect(address, port);
+ }
+
+ /**
+ * @deprecated Use DatagramSocket instead for UDP transport.
+ */
+ public Socket (String host, int port, boolean stream) throws IOException
+ {
+ impl = factory == null ? new PlainSocketImpl()
+ : factory.createSocketImpl();
+ impl.create(stream);
+ SecurityManager s = System.getSecurityManager();
+ if (s != null)
+ s.checkConnect(host, port);
+ impl.connect(host, port);
+ }
+
+ /**
+ * @deprecated Use DatagramSocket instead for UDP transport.
+ */
+ public Socket (InetAddress host, int port, boolean stream) throws IOException
+ {
+ impl = factory == null ? new PlainSocketImpl()
+ : factory.createSocketImpl();
+ impl.create(stream);
+ SecurityManager s = System.getSecurityManager();
+ if (s != null)
+ s.checkConnect(host.getHostName(), port);
+ impl.connect(host, port);
+ }
+
+ public InetAddress getInetAddress ()
+ {
+ return impl.getInetAddress();
+ }
+
+ public InetAddress getLocalAddress ()
+ {
+ // There doesn't seem to be any way to implement this
+ // using a (generic) SocketImpl ... What am I missing?
+ throw new InternalError("Socket.getLocalAddres not implemented");
+ }
+
+ public int getPort ()
+ {
+ return impl.getPort();
+ }
+
+ public int getLocalPort ()
+ {
+ return impl.getLocalPort();
+ }
+
+ public InputStream getInputStream () throws IOException
+ {
+ return impl.getInputStream();
+ }
+
+ public OutputStream getOutputStream () throws IOException
+ {
+ return impl.getOutputStream();
+ }
+
+ public void setTcpNoDelay (boolean on) throws SocketException
+ {
+ throw new InternalError("Socket.setTcpNoDelay not implemented");
+ }
+
+ public boolean getTcpNoDelay() throws SocketException
+ {
+ throw new InternalError("Socket.getTcpNoDelay not implemented");
+ }
+
+ public void setSoLinger(boolean on, int linger) throws SocketException
+ {
+ throw new InternalError("Socket.setSoLinger not implemented");
+ }
+
+ public boolean getSoLinger() throws SocketException
+ {
+ throw new InternalError("Socket.getSoLinger not implemented");
+ }
+
+ public void setSoTimeout (int timeout) throws SocketException
+ {
+ throw new InternalError("Socket.setSoTimeout not implemented");
+ }
+
+ public int getSoTimeout () throws SocketException
+ {
+ throw new InternalError("Socket.getSoTimeout not implemented");
+ }
+
+ public void setSendBufferSize (int size) throws SocketException
+ {
+ throw new InternalError("Socket.setSendBufferSize not implemented");
+ }
+
+ public int getSendBufferSize () throws SocketException
+ {
+ throw new InternalError("Socket.getSendBufferSize not implemented");
+ }
+
+ public void setReceiveBufferSize (int size) throws SocketException
+ {
+ throw new InternalError("Socket.setReceiveBufferSize not implemented");
+ }
+
+ public int getReceiveBufferSize () throws SocketException
+ {
+ throw new InternalError("Socket.getReceiveBufferSize not implemented");
+ }
+
+ public void close () throws IOException
+ {
+ impl.close();
+ }
+
+ public String toString ()
+ {
+ return impl.toString();
+ }
+
+ public static void setSocketImplFactory (SocketImplFactory fac)
+ throws IOException
+ {
+ factory = fac;
+ }
+}
diff --git a/libjava/java/net/SocketException.java b/libjava/java/net/SocketException.java
new file mode 100644
index 0000000..24a50ef
--- /dev/null
+++ b/libjava/java/net/SocketException.java
@@ -0,0 +1,33 @@
+// SocketException.java - Base class for networking exceptions
+
+/* 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. */
+
+package java.net;
+
+/**
+ * @author Per Bothner
+ * @date January 6, 1999.
+ */
+
+/** Written using on-line Java Platform 1.2 API Specification.
+ * Believed complete and correct.
+ */
+
+public class SocketException extends java.io.IOException
+{
+ public SocketException ()
+ {
+ super();
+ }
+
+ public SocketException (String s)
+ {
+ super(s);
+ }
+}
diff --git a/libjava/java/net/SocketImpl.java b/libjava/java/net/SocketImpl.java
new file mode 100644
index 0000000..5ad3118
--- /dev/null
+++ b/libjava/java/net/SocketImpl.java
@@ -0,0 +1,70 @@
+// SocketImpl.java - Abstract socket implementation.
+
+/* Copyright (C) 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. */
+
+package java.net;
+import java.io.*;
+
+/**
+ * @author Per Bothner <bothner@cygnus.com>
+ * @date January 6, 1999.
+ */
+
+/** Written using on-line Java Platform 1.2 API Specification.
+ * Believed complete and correct, except for implementation of toString.
+ */
+
+public abstract class SocketImpl
+{
+ protected InetAddress address;
+
+ protected FileDescriptor fd;
+
+ protected int localport;
+
+ protected int port;
+
+ public SocketImpl ()
+ {
+ }
+
+ protected abstract void create (boolean stream) throws IOException;
+
+ protected abstract void connect (String host, int port) throws IOException;
+
+ protected abstract void connect (InetAddress host, int port)
+ throws IOException;
+
+ protected abstract void bind (InetAddress host, int port) throws IOException;
+
+ protected abstract void listen (int backlog) throws IOException;
+
+ protected abstract void accept (SocketImpl s) throws IOException;
+
+ protected abstract InputStream getInputStream() throws IOException;
+
+ protected abstract OutputStream getOutputStream() throws IOException;
+
+ protected abstract int available () throws IOException;
+
+ protected abstract void close () throws IOException;
+
+ protected FileDescriptor getFileDescriptor () { return fd; }
+
+ protected InetAddress getInetAddress () { return address; }
+
+ protected int getPort () { return port; }
+
+ protected int getLocalPort () { return localport; }
+
+ public String toString ()
+ {
+ return super.toString(); // FIXME
+ }
+}
diff --git a/libjava/java/net/SocketImplFactory.java b/libjava/java/net/SocketImplFactory.java
new file mode 100644
index 0000000..7631ab8
--- /dev/null
+++ b/libjava/java/net/SocketImplFactory.java
@@ -0,0 +1,25 @@
+// SocketImplFactory.java - Abstract socket implementation factory.
+
+/* Copyright (C) 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. */
+
+package java.net;
+
+/**
+ * @author Per Bothner <bothner@cygnus.com>
+ * @date January 6, 1999.
+ */
+
+/** Written using on-line Java Platform 1.2 API Specification.
+ * Status: Believed complete and correct.
+ */
+
+public abstract interface SocketImplFactory
+{
+ public SocketImpl createSocketImpl ();
+}
diff --git a/libjava/java/net/URL.java b/libjava/java/net/URL.java
new file mode 100644
index 0000000..da56f49
--- /dev/null
+++ b/libjava/java/net/URL.java
@@ -0,0 +1,341 @@
+// URL.java - A Uniform Resource Locator.
+
+/* Copyright (C) 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. */
+
+package java.net;
+
+import java.io.*;
+import java.util.Hashtable;
+import java.util.StringTokenizer;
+
+/**
+ * @author Warren Levy <warrenl@cygnus.com>
+ * @date March 4, 1999.
+ */
+
+/**
+ * Written using on-line Java Platform 1.2 API Specification, as well
+ * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998).
+ * Status: Believed complete and correct.
+ */
+
+public final class URL implements Serializable
+{
+ private String protocol;
+ private String host;
+ private int port;
+ private String file;
+ private String ref;
+ private URLStreamHandler handler;
+ private static Hashtable handlers = new Hashtable();
+ private static URLStreamHandlerFactory factory;
+
+ public URL(String protocol, String host, int port, String file)
+ throws MalformedURLException
+ {
+ this(protocol, host, port, file, null);
+ }
+
+ public URL(String protocol, String host, String file)
+ throws MalformedURLException
+ {
+ this(protocol, host, -1, file, null);
+ }
+
+ // JDK1.2
+ public URL(String protocol, String host, int port, String file,
+ URLStreamHandler handler) throws MalformedURLException
+ {
+ if (protocol == null)
+ throw new MalformedURLException("null protocol");
+ this.protocol = protocol;
+
+ if (handler != null)
+ {
+ // TODO12: Need SecurityManager.checkPermission and
+ // TODO12: java.net.NetPermission from JDK 1.2 to be implemented.
+ // Throw an exception if an extant security mgr precludes
+ // specifying a StreamHandler.
+ //
+ // SecurityManager s = System.getSecurityManager();
+ // if (s != null)
+ // s.checkPermission(NetPermission("specifyStreamHandler"));
+
+ this.handler = handler;
+ }
+ else
+ this.handler = setURLStreamHandler(protocol);
+
+ if (this.handler == null)
+ throw new MalformedURLException("Handler for protocol not found");
+
+ this.host = host;
+
+ this.port = port;
+
+ int hashAt = file.indexOf('#');
+ if (hashAt < 0)
+ {
+ this.file = file;
+ this.ref = null;
+ }
+ else
+ {
+ this.file = file.substring(0, hashAt);
+ this.ref = file.substring(hashAt + 1);
+ }
+ }
+
+ public URL(String spec) throws MalformedURLException
+ {
+ this((URL) null, spec, (URLStreamHandler) null);
+ }
+
+ public URL(URL context, String spec) throws MalformedURLException
+ {
+ this(context, spec, (URLStreamHandler) null);
+ }
+
+ // JDK1.2
+ public URL(URL context, String spec, URLStreamHandler handler)
+ throws MalformedURLException
+ {
+ /* A protocol is defined by the doc as the substring before a ':'
+ * as long as the ':' occurs before any '/'.
+ *
+ * If context is null, then spec must be an absolute URL.
+ *
+ * The relative URL need not specify all the components of a URL.
+ * If the protocol, host name, or port number is missing, the value
+ * is inherited from the context. A bare file component is appended
+ * to the context's file. The optional anchor is not inherited.
+ */
+
+ int colon;
+ int slash;
+ if ((colon = spec.indexOf(':')) > 0 &&
+ (colon < (slash = spec.indexOf('/')) || slash < 0))
+ {
+ // Protocol specified in spec string.
+ protocol = spec.substring(0, colon);
+ if (context != null && context.protocol == protocol)
+ {
+ // The 1.2 doc specifically says these are copied to the new URL.
+ host = context.host;
+ port = context.port;
+ file = context.file;
+ }
+ }
+ else if (context != null)
+ {
+ // Protocol NOT specified in spec string.
+ // Use context fields (except ref) as a foundation for relative URLs.
+ colon = -1;
+ protocol = context.protocol;
+ host = context.host;
+ port = context.port;
+ file = context.file;
+ }
+ else // Protocol NOT specified in spec. and no context available.
+ throw new
+ MalformedURLException("Absolute URL required with null context");
+
+ if (handler != null)
+ {
+ // TODO12: Need SecurityManager.checkPermission and
+ // TODO12: java.net.NetPermission from JDK 1.2 to be implemented.
+ // Throw an exception if an extant security mgr precludes
+ // specifying a StreamHandler.
+ //
+ // SecurityManager s = System.getSecurityManager();
+ // if (s != null)
+ // s.checkPermission(NetPermission("specifyStreamHandler"));
+
+ this.handler = handler;
+ }
+ else
+ this.handler = setURLStreamHandler(protocol);
+
+ if (this.handler == null)
+ throw new MalformedURLException("Handler for protocol not found");
+
+ // JDK 1.2 doc for parseURL specifically states that any '#' ref
+ // is to be excluded by passing the 'limit' as the indexOf the '#'
+ // if one exists, otherwise pass the end of the string.
+ int hashAt = spec.indexOf('#', colon + 1);
+ this.handler.parseURL(this, spec, colon + 1,
+ hashAt < 0 ? spec.length() : hashAt);
+ if (hashAt >= 0)
+ ref = spec.substring(hashAt + 1);
+ }
+
+ public boolean equals(Object obj)
+ {
+ if (obj == null || ! (obj instanceof URL))
+ return false;
+
+ URL uObj = (URL) obj;
+ if (protocol != uObj.protocol || host != uObj.host || port != uObj.port ||
+ file != uObj.file || ref != uObj.ref)
+ return false;
+
+ return true;
+ }
+
+ public final Object getContent() throws IOException
+ {
+ return openConnection().getContent();
+ }
+
+ public String getFile()
+ {
+ return file;
+ }
+
+ public String getHost()
+ {
+ return host;
+ }
+
+ public int getPort()
+ {
+ return port;
+ }
+
+ public String getProtocol()
+ {
+ return protocol;
+ }
+
+ public String getRef()
+ {
+ return ref;
+ }
+
+ public int hashCode()
+ {
+ // JCL book says this is computed using (only) the hashcodes of the
+ // protocol, host and file fields. Empirical evidence indicates this
+ // is probably XOR.
+ return (protocol.hashCode() ^ host.hashCode() ^ file.hashCode());
+ }
+
+ public URLConnection openConnection() throws IOException
+ {
+ return handler.openConnection(this);
+ }
+
+ public final InputStream openStream() throws IOException
+ {
+ return openConnection().getInputStream();
+ }
+
+ public boolean sameFile(URL other)
+ {
+ if (other == null || protocol != other.protocol || host != other.host ||
+ port != other.port || file != other.file)
+ return false;
+
+ return true;
+ }
+
+ protected void set(String protocol, String host, int port, String file,
+ String ref)
+ {
+ // TBD: Theoretically, a poorly written StreamHandler could pass an
+ // invalid protocol. It will cause the handler to be set to null
+ // thus overriding a valid handler. Callers of this method should
+ // be aware of this.
+ this.handler = setURLStreamHandler(protocol);
+ this.protocol = protocol;
+ this.port = port;
+ this.host = host;
+ this.file = file;
+ this.ref = ref;
+ }
+
+ public static synchronized void
+ setURLStreamHandlerFactory(URLStreamHandlerFactory fac)
+ {
+ if (factory != null)
+ throw new Error("URLStreamHandlerFactory already set");
+
+ // Throw an exception if an extant security mgr precludes
+ // setting the factory.
+ SecurityManager s = System.getSecurityManager();
+ if (s != null)
+ s.checkSetFactory();
+ factory = fac;
+ }
+
+ public String toExternalForm()
+ {
+ // Identical to toString().
+ return handler.toExternalForm(this);
+ }
+
+ public String toString()
+ {
+ // Identical to toExternalForm().
+ return handler.toExternalForm(this);
+ }
+
+ private URLStreamHandler setURLStreamHandler(String protocol)
+ {
+ URLStreamHandler handler;
+
+ // See if a handler has been cached for this protocol.
+ if ((handler = (URLStreamHandler) handlers.get(protocol)) != null)
+ return handler;
+
+ // If a non-default factory has been set, use it to find the protocol.
+ if (factory != null)
+ handler = factory.createURLStreamHandler(protocol);
+
+ // Non-default factory may have returned null or a factory wasn't set.
+ // Use the default search algorithm to find a handler for this protocol.
+ if (handler == null)
+ {
+ // Get the list of packages to check and append our default handler
+ // to it, along with the JDK specified default as a last resort.
+ // Except in very unusual environments the JDK specified one shouldn't
+ // ever be needed (or available).
+ String propVal = System.getProperty("java.protocol.handler.pkgs");
+ propVal = (propVal == null) ? "" : (propVal + "|");
+ propVal = propVal + "gnu.gcj.protocol|sun.net.www.protocol";
+
+ StringTokenizer pkgPrefix = new StringTokenizer(propVal, "|");
+ do
+ {
+ String facName = pkgPrefix.nextToken() + "." + protocol +
+ ".Handler";
+ try
+ {
+ handler =
+ (URLStreamHandler) Class.forName(facName).newInstance();
+ }
+ catch (Exception e)
+ {
+ // Can't instantiate; handler still null, go on to next element.
+ }
+ } while ((handler == null ||
+ ! (handler instanceof URLStreamHandler)) &&
+ pkgPrefix.hasMoreTokens());
+ }
+
+ // Update the hashtable with the new protocol handler.
+ if (handler != null)
+ if (handler instanceof URLStreamHandler)
+ handlers.put(protocol, handler);
+ else
+ handler = null;
+
+ return handler;
+ }
+}
diff --git a/libjava/java/net/URLConnection.java b/libjava/java/net/URLConnection.java
new file mode 100644
index 0000000..12e8a8b
--- /dev/null
+++ b/libjava/java/net/URLConnection.java
@@ -0,0 +1,423 @@
+// URLConnection.java - Superclass of all communications links between
+// an application and a URL.
+
+/* Copyright (C) 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. */
+
+package java.net;
+
+import java.io.*;
+import java.text.ParsePosition;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import java.util.Hashtable;
+import java.util.StringTokenizer;
+
+/**
+ * @author Warren Levy <warrenl@cygnus.com>
+ * @date March 5, 1999.
+ */
+
+/**
+ * Written using on-line Java Platform 1.2 API Specification, as well
+ * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998).
+ * Status: Two guessContentTypeFrom... methods not implemented.
+ * getContent method assumes content type from response; see comment there.
+ */
+
+public abstract class URLConnection
+{
+ protected URL url;
+ protected boolean doInput = true;
+ protected boolean doOutput = false;
+ protected boolean allowUserInteraction;
+ protected boolean useCaches;
+ protected long ifModifiedSince = 0L;
+ protected boolean connected = false;
+ private static boolean defaultAllowUserInteraction = false;
+ private static boolean defaultUseCaches = true;
+ private static FileNameMap fileNameMap; // Set by the URLConnection subclass.
+ private static ContentHandlerFactory factory;
+ private static ContentHandler contentHandler;
+ private static Hashtable handlers = new Hashtable();
+ private static Locale locale = new Locale("En", "Us", "Unix");
+ private static SimpleDateFormat dateFormat1 =
+ new SimpleDateFormat("EEE, dd MMM yyyy hh:mm:ss 'GMT'", locale);
+ private static SimpleDateFormat dateFormat2 =
+ new SimpleDateFormat("EEEE, dd-MMM-yy hh:mm:ss 'GMT'", locale);
+ private static SimpleDateFormat dateFormat3 =
+ new SimpleDateFormat("EEE MMM d hh:mm:ss yyyy", locale);
+
+ protected URLConnection(URL url)
+ {
+ this.url = url;
+ allowUserInteraction = defaultAllowUserInteraction;
+ useCaches = defaultUseCaches;
+ }
+
+ public abstract void connect() throws IOException;
+
+ public URL getURL()
+ {
+ return url;
+ }
+
+ public int getContentLength()
+ {
+ return getHeaderFieldInt("content-length", -1);
+ }
+
+ public String getContentType()
+ {
+ return getHeaderField("content-type");
+ }
+
+ public String getContentEncoding()
+ {
+ return getHeaderField("content-encoding");
+ }
+
+ public long getExpiration()
+ {
+ return getHeaderFieldDate("expiration", 0L);
+ }
+
+ public long getDate()
+ {
+ return getHeaderFieldDate("date", 0L);
+ }
+
+ public long getLastModified()
+ {
+ return getHeaderFieldDate("last-modified", 0L);
+ }
+
+ public String getHeaderField(int n)
+ {
+ // Subclasses for specific protocols override this.
+ return null;
+ }
+
+ public String getHeaderField(String name)
+ {
+ // Subclasses for specific protocols override this.
+ return null;
+ }
+
+ public int getHeaderFieldInt(String name, int val)
+ {
+ String str = getHeaderField(name);
+ try
+ {
+ if (str != null)
+ val = Integer.parseInt(str);
+ }
+ catch (NumberFormatException e)
+ {
+ ; // Do nothing; val is the default.
+ }
+ return val;
+ }
+
+ public long getHeaderFieldDate(String name, long val)
+ {
+ String str = getHeaderField(name);
+ if (str != null)
+ {
+ Date date;
+ if ((date = dateFormat1.parse(str, new ParsePosition(0))) != null)
+ val = date.getTime();
+ else if ((date = dateFormat2.parse(str, new ParsePosition(0))) != null)
+ val = date.getTime();
+ else if ((date = dateFormat3.parse(str, new ParsePosition(0))) != null)
+ val = date.getTime();
+ }
+ return val;
+ }
+
+ public String getHeaderFieldKey(int n)
+ {
+ // Subclasses for specific protocols override this.
+ return null;
+ }
+
+ public Object getContent() throws IOException
+ {
+ // FIXME: Doc indicates that other criteria should be applied as
+ // heuristics to determine the true content type, e.g. see
+ // guessContentTypeFromName() and guessContentTypeFromStream methods
+ // as well as FileNameMap class & fileNameMap field & get/set methods.
+ String cType = getContentType();
+ contentHandler = setContentHandler(cType);
+ if (contentHandler == null)
+ return getInputStream();
+
+ return contentHandler.getContent(this);
+ }
+
+// TODO12: public Permission getPermission() throws IOException
+// {
+// // Subclasses may override this.
+// return java.security.AllPermission;
+// }
+
+ public InputStream getInputStream() throws IOException
+ {
+ // Subclasses for specific protocols override this.
+ throw new UnknownServiceException("Protocol " + url.getProtocol() +
+ " does not support input.");
+ }
+
+ public OutputStream getOutputStream() throws IOException
+ {
+ // Subclasses for specific protocols override this.
+ throw new UnknownServiceException("Protocol " + url.getProtocol() +
+ " does not support output.");
+ }
+
+ public String toString()
+ {
+ return this.getClass().getName() + ":" + url.toString();
+ }
+
+ public void setDoInput(boolean doinput)
+ {
+ if (connected)
+ throw new IllegalAccessError("Already connected");
+
+ doInput = doinput;
+ }
+
+ public boolean getDoInput()
+ {
+ return doInput;
+ }
+
+ public void setDoOutput(boolean dooutput)
+ {
+ if (connected)
+ throw new IllegalAccessError("Already connected");
+
+ doOutput = dooutput;
+ if (doOutput)
+ doInput = false;
+ }
+
+ public boolean getDoOutput()
+ {
+ return doOutput;
+ }
+
+ public void setAllowUserInteraction(boolean allowuserinteraction)
+ {
+ if (connected)
+ throw new IllegalAccessError("Already connected");
+
+ allowUserInteraction = allowuserinteraction;
+ }
+
+ public boolean getAllowUserInteraction()
+ {
+ return allowUserInteraction;
+ }
+
+ public static void
+ setDefaultAllowUserInteraction(boolean defaultallowuserinteraction)
+ {
+ defaultAllowUserInteraction = defaultallowuserinteraction;
+ }
+
+ public static boolean getDefaultAllowUserInteraction()
+ {
+ return defaultAllowUserInteraction;
+ }
+
+ public void setUseCaches(boolean usecaches)
+ {
+ if (connected)
+ throw new IllegalAccessError("Already connected");
+
+ useCaches = usecaches;
+ }
+
+ public boolean getUseCaches()
+ {
+ return useCaches;
+ }
+
+ public void setIfModifiedSince(long ifmodifiedsince)
+ {
+ if (connected)
+ throw new IllegalAccessError("Already connected");
+
+ ifModifiedSince = ifmodifiedsince;
+ }
+
+ public long getIfModifiedSince()
+ {
+ return ifModifiedSince;
+ }
+
+ public boolean getDefaultUseCaches()
+ {
+ return defaultUseCaches;
+ }
+
+ public void setDefaultUseCaches(boolean defaultusecaches)
+ {
+ defaultUseCaches = defaultusecaches;
+ }
+
+ public void setRequestProperty(String key, String value)
+ {
+ // Do nothing unless overridden by subclasses that support setting
+ // header fields in the request.
+ }
+
+ public String getRequestProperty(String key)
+ {
+ // Overridden by subclasses that support reading header fields from the
+ // request.
+ return null;
+ }
+
+ public static void setDefaultRequestProperty(String key, String value)
+ {
+ // Do nothing unless overridden by subclasses that support setting
+ // default request properties.
+ }
+
+ public static String getDefaultRequestProperty(String key)
+ {
+ // Overridden by subclasses that support default request properties.
+ return null;
+ }
+
+ public static void setContentHandlerFactory(ContentHandlerFactory fac)
+ {
+ if (factory != null)
+ throw new Error("ContentHandlerFactory already set");
+
+ // Throw an exception if an extant security mgr precludes
+ // setting the factory.
+ SecurityManager s = System.getSecurityManager();
+ if (s != null)
+ s.checkSetFactory();
+ factory = fac;
+ }
+
+// TODO: protected static String guessContentTypeFromName(String fname)
+// {
+// }
+
+// TODO: public static String guessContentTypeFromStream(InputStream is)
+// throws IOException
+// {
+// }
+
+// TODO12: protected void parseURL(URL u, String spec, int start, int limit)
+
+ // JDK1.2
+ public static FileNameMap getFileNameMap()
+ {
+ return fileNameMap;
+ }
+
+ // JDK1.2
+ public static void setFileNameMap(FileNameMap map)
+ {
+ // Throw an exception if an extant security mgr precludes
+ // setting the factory.
+ SecurityManager s = System.getSecurityManager();
+ if (s != null)
+ s.checkSetFactory();
+
+ fileNameMap = map;
+ }
+
+ private ContentHandler setContentHandler(String contentType)
+ {
+ ContentHandler handler;
+
+ // No content type so just handle it as the default.
+ if (contentType == null || contentType == "")
+ return null;
+
+ // See if a handler has been cached for this content type.
+ // For efficiency, if a content type has been searched for but not
+ // found, it will be in the hash table but as the contentType String
+ // instead of a ContentHandler.
+ if ((handler = (ContentHandler) handlers.get(contentType)) != null)
+ if (handler instanceof ContentHandler)
+ return handler;
+ else
+ return null;
+
+ // If a non-default factory has been set, use it to find the content type.
+ if (factory != null)
+ handler = factory.createContentHandler(contentType);
+
+ // Non-default factory may have returned null or a factory wasn't set.
+ // Use the default search algorithm to find a handler for this content type.
+ if (handler == null)
+ {
+ // Get the list of packages to check and append our default handler
+ // to it, along with the JDK specified default as a last resort.
+ // Except in very unusual environments the JDK specified one shouldn't
+ // ever be needed (or available).
+ String propVal = System.getProperty("java.content.handler.pkgs");
+ propVal = (propVal == null) ? "" : (propVal + "|");
+ propVal = propVal + "gnu.gcj.content|sun.net.www.content";
+
+ // Replace the '/' character in the content type with '.' and
+ // all other non-alphabetic, non-numeric characters with '_'.
+ StringTokenizer pkgPrefix = new StringTokenizer(propVal, "|");
+ char[] cArray = contentType.toCharArray();
+ for (int i = 0; i < cArray.length; i++)
+ {
+ if (cArray[i] == '/')
+ cArray[i] = '.';
+ else if (! ((cArray[i] >= 'A' && cArray[i] <= 'Z') ||
+ (cArray[i] >= 'a' && cArray[i] <= 'z') ||
+ (cArray[i] >= '0' && cArray[i] <= '9')))
+ cArray[i] = '_';
+ }
+ String contentClass = new String(cArray);
+
+ // See if a class of this content type exists in any of the packages.
+ do
+ {
+ String facName = pkgPrefix.nextToken() + "." + contentClass;
+ try
+ {
+ handler =
+ (ContentHandler) Class.forName(facName).newInstance();
+ }
+ catch (Exception e)
+ {
+ // Can't instantiate; handler still null, go on to next element.
+ }
+ } while ((handler == null ||
+ ! (handler instanceof ContentHandler)) &&
+ pkgPrefix.hasMoreTokens());
+ }
+
+ // Update the hashtable with the new content handler.
+ if (handler != null && handler instanceof ContentHandler)
+ {
+ handlers.put(contentType, handler);
+ return handler;
+ }
+
+ // For efficiency on subsequent searches, put a dummy entry in the hash
+ // table for content types that don't have a non-default ContentHandler.
+ handlers.put(contentType, contentType);
+ return null;
+ }
+}
diff --git a/libjava/java/net/URLStreamHandler.java b/libjava/java/net/URLStreamHandler.java
new file mode 100644
index 0000000..29e0e6d
--- /dev/null
+++ b/libjava/java/net/URLStreamHandler.java
@@ -0,0 +1,107 @@
+// URLStreamHandler.java - Superclass of all stream protocol handlers.
+
+/* Copyright (C) 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. */
+
+package java.net;
+
+/**
+ * @author Warren Levy <warrenl@cygnus.com>
+ * @date March 4, 1999.
+ */
+
+/**
+ * Written using on-line Java Platform 1.2 API Specification, as well
+ * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998).
+ * Status: Believed complete and correct.
+ */
+
+public abstract class URLStreamHandler
+{
+ protected abstract URLConnection openConnection(URL u)
+ throws java.io.IOException;
+
+protected void parseURL(URL u, String spec, int start, int limit)
+ {
+ String tmpStr;
+ String host = ""; // Initialize to null string.
+ String file;
+ int port = -1;
+ int colon;
+
+ /* TBD: The JDK 1.2 doc specifically says that limit is the position
+ * to stop parsing at and that it will be either the end of the string
+ * or the position of '#'; thus the doc infers that this method does
+ * not set the ref.
+ */
+ tmpStr = spec.substring(start, limit);
+ int hostEnd = 0;
+ if (tmpStr.startsWith("//"))
+ {
+ int slash = tmpStr.indexOf('/', 2);
+ hostEnd = tmpStr.length();
+ if (slash >= 0)
+ hostEnd = slash;
+
+ host = tmpStr.substring(2, hostEnd);
+
+ // Look for optional port number.
+ if ((colon = host.indexOf(':')) >= 0)
+ {
+ try
+ {
+ port = Integer.parseInt(host.substring(colon + 1));
+ }
+ catch (NumberFormatException e)
+ {
+ ; // Ignore invalid port values; port is already set to -1.
+ }
+ host = host.substring(0, colon);
+ }
+ }
+
+ if (hostEnd < tmpStr.length())
+ file = ((tmpStr.startsWith("/")) ? "" : "/") + tmpStr.substring(hostEnd);
+ else
+ file = "/";
+
+ u.set(u.getProtocol(), host, port, file, u.getRef());
+ }
+
+ protected void setURL(URL u, String protocol, String host, int port,
+ String file, String ref)
+ {
+ u.set(protocol, host, port, file, ref);
+ }
+
+ protected String toExternalForm(URL u)
+ {
+ String resStr, host, file, ref;
+ int port;
+
+ resStr = u.getProtocol() + ":";
+ host = u.getHost();
+ port = u.getPort();
+ file = u.getFile();
+ ref = u.getRef();
+
+ if (! host.equals(""))
+ {
+ resStr = resStr + "//" + host;
+ if (port >= 0)
+ resStr = resStr + ":" + port;
+ }
+
+ resStr = resStr + file;
+
+ if (ref != null)
+ resStr = resStr + "#" + ref;
+
+ return resStr;
+ }
+}
diff --git a/libjava/java/net/URLStreamHandlerFactory.java b/libjava/java/net/URLStreamHandlerFactory.java
new file mode 100644
index 0000000..474d723
--- /dev/null
+++ b/libjava/java/net/URLStreamHandlerFactory.java
@@ -0,0 +1,27 @@
+// URLStreamHandlerFactory.java - Abstract URL Stream Handler factory.
+
+/* Copyright (C) 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. */
+
+package java.net;
+
+/**
+ * @author Warren Levy <warrenl@cygnus.com>
+ * @date March 5, 1999.
+ */
+
+/**
+ * Written using on-line Java Platform 1.2 API Specification, as well
+ * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998).
+ * Status: Believed complete and correct.
+ */
+
+public abstract interface URLStreamHandlerFactory
+{
+ public URLStreamHandler createURLStreamHandler(String protocol);
+}
diff --git a/libjava/java/net/UnknownHostException.java b/libjava/java/net/UnknownHostException.java
new file mode 100644
index 0000000..1c20509
--- /dev/null
+++ b/libjava/java/net/UnknownHostException.java
@@ -0,0 +1,34 @@
+// UnknownHostException.java
+
+/* 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. */
+
+package java.net;
+
+/**
+ * @author Per Bothner
+ * @date January 6, 1999.
+ */
+
+/*
+ * Written using on-line Java Platform 1.2 API Specification.
+ * Status: Believed complete and correct.
+ */
+
+public class UnknownHostException extends java.io.IOException
+{
+ public UnknownHostException ()
+ {
+ super();
+ }
+
+ public UnknownHostException (String host)
+ {
+ super(host);
+ }
+}
diff --git a/libjava/java/net/UnknownServiceException.java b/libjava/java/net/UnknownServiceException.java
new file mode 100644
index 0000000..dba798e
--- /dev/null
+++ b/libjava/java/net/UnknownServiceException.java
@@ -0,0 +1,35 @@
+// UnknownServiceException.java
+
+/* Copyright (C) 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. */
+
+package java.net;
+
+/**
+ * @author Warren Levy <warrenl@cygnus.com>
+ * @date March 5, 1999.
+ */
+
+/**
+ * Written using on-line Java Platform 1.2 API Specification, as well
+ * as "The Java Class Libraries", 2nd edition (Addison-Wesley, 1998).
+ * Status: Believed complete and correct.
+ */
+
+public class UnknownServiceException extends java.io.IOException
+{
+ public UnknownServiceException()
+ {
+ super();
+ }
+
+ public UnknownServiceException(String msg)
+ {
+ super(msg);
+ }
+}
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);
+}
diff --git a/libjava/java/net/natPlainSocketImpl.cc b/libjava/java/net/natPlainSocketImpl.cc
new file mode 100644
index 0000000..076ee71
--- /dev/null
+++ b/libjava/java/net/natPlainSocketImpl.cc
@@ -0,0 +1,177 @@
+/* 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>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <cni.h>
+#include <java/io/IOException.h>
+#include <java/io/FileDescriptor.h>
+#include <java/net/PlainSocketImpl.h>
+#include <java/net/InetAddress.h>
+
+#ifndef HAVE_SOCKLEN_T
+typedef int socklen_t;
+#endif
+
+union SockAddr
+{
+ struct sockaddr_in address;
+#ifdef HAVE_INET6
+ struct sockaddr_in6 address6;
+#endif
+};
+
+void
+java::net::PlainSocketImpl::create (jboolean stream)
+{
+ int sock = ::socket (AF_INET, stream ? SOCK_STREAM : SOCK_DGRAM, 0);
+ if (sock < 0)
+ {
+ char msg[100];
+ char* strerr = strerror (errno);
+ sprintf (msg, "SocketImpl.create: %.*s", 80, strerr);
+ JvThrow (new java::io::IOException (JvNewStringUTF (msg)));
+ }
+ fnum = sock;
+ fd = new java::io::FileDescriptor (sock);
+}
+
+void
+java::net::PlainSocketImpl::bind (java::net::InetAddress *host, jint lport)
+{
+ union SockAddr u;
+ jbyteArray haddress = host->address;
+ jbyte *bytes = elements (haddress);
+ int len = haddress->length;
+ struct sockaddr *ptr = (struct sockaddr *) &u.address;
+ if (len == 4)
+ {
+ u.address.sin_family = AF_INET;
+ memcpy (&u.address.sin_addr, bytes, len);
+ len = sizeof (struct sockaddr_in);
+ u.address.sin_port = htons (lport);
+ }
+#ifdef HAVE_INET6
+ else if (len == 16)
+ {
+ u.address6.sin6_family = AF_INET6;
+ memcpy (&u.address6.sin6_addr, bytes, len);
+ len = sizeof (struct sockaddr_in6);
+ u.address6.sin6_port = htons (lport);
+ }
+#endif
+ else
+ goto error;
+ if (::bind (fnum, ptr, len) == 0)
+ {
+ address = host;
+ localport = lport;
+ return;
+ }
+ error:
+ char msg[100];
+ char* strerr = strerror (errno);
+ sprintf (msg, "SocketImpl.bind: %.*s", 80, strerr);
+ JvThrow (new java::io::IOException (JvNewStringUTF (msg)));
+}
+
+void
+java::net::PlainSocketImpl::connect (java::net::InetAddress *host, jint rport)
+{
+ union SockAddr u;
+ jbyteArray haddress = host->address;
+ jbyte *bytes = elements (haddress);
+ int len = haddress->length;
+ struct sockaddr *ptr = (struct sockaddr *) &u.address;
+ if (len == 4)
+ {
+ u.address.sin_family = AF_INET;
+ memcpy (&u.address.sin_addr, bytes, len);
+ len = sizeof (struct sockaddr_in);
+ u.address.sin_port = htons (rport);
+ }
+#ifdef HAVE_INET6
+ else if (len == 16)
+ {
+ u.address6.sin6_family = AF_INET6;
+ memcpy (&u.address6.sin6_addr, bytes, len);
+ len = sizeof (struct sockaddr_in6);
+ u.address6.sin6_port = htons (rport);
+ }
+#endif
+ else
+ goto error;
+ if (::connect (fnum, ptr, len) == 0)
+ {
+ address = host;
+ port = rport;
+ return;
+ }
+ error:
+ char msg[100];
+ char* strerr = strerror (errno);
+ sprintf (msg, "SocketImpl.connect: %.*s", 80, strerr);
+ JvThrow (new java::io::IOException (JvNewStringUTF (msg)));
+}
+
+void
+java::net::PlainSocketImpl::listen (jint backlog)
+{
+ if (::listen (fnum, backlog) != 0)
+ {
+ char msg[100];
+ char* strerr = strerror (errno);
+ sprintf (msg, "SocketImpl.listen: %.*s", 80, strerr);
+ JvThrow (new java::io::IOException (JvNewStringUTF (msg)));
+ }
+}
+
+void
+java::net::PlainSocketImpl::accept (java::net::PlainSocketImpl *s)
+{
+ union SockAddr u;
+ socklen_t addrlen = sizeof(u);
+ int new_socket = ::accept (fnum, (sockaddr*) &u, &addrlen);
+ if (new_socket < 0)
+ goto error;
+ jbyteArray raddr;
+ jint rport;
+ if (u.address.sin_family == AF_INET)
+ {
+ raddr = JvNewByteArray (4);
+ memcpy (elements (raddr), &u.address.sin_addr, 4);
+ rport = ntohs (u.address.sin_port);
+ }
+#ifdef HAVE_INET6
+ {
+ raddr = JvNewByteArray (16);
+ memcpy (elements (raddr), &u.address6.sin6_addr, 16);
+ rport = ntohs (u.address6.sin6_port);
+ }
+#endif
+ else
+ goto error;
+ s->fnum = new_socket;
+ s->localport = localport;
+ s->address = new InetAddress (raddr, NULL);
+ s->port = rport;
+ s->fd = new java::io::FileDescriptor (new_socket);
+ return;
+ error:
+ char msg[100];
+ char* strerr = strerror (errno);
+ sprintf (msg, "SocketImpl.accept: %.*s", 80, strerr);
+ JvThrow (new java::io::IOException (JvNewStringUTF (msg)));
+}