]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
JarURLConnection.java (getCertificates): New method from Classpath.
authorTom Tromey <tromey@redhat.com>
Fri, 30 Aug 2002 18:16:00 +0000 (18:16 +0000)
committerTom Tromey <tromey@gcc.gnu.org>
Fri, 30 Aug 2002 18:16:00 +0000 (18:16 +0000)
* java/net/JarURLConnection.java (getCertificates): New method
from Classpath.
* java/net/URLClassLoader.java (URLClassLoader): Extends
SecureClassLoader.
(definePackage): New method from Classpath.
(getPermissions): Likewise.
(newInstance): Likewise.
(findClass): Construct CodeSource for new class (from Classpath).
* java/net/SocketImpl.java (shutdownInput, shutdownOutput): New
methods.
* java/net/URL.java (getUserInfo): New method.
(set(String,String,int,String,String,String,String,String)): New
method.
* java/net/PlainSocketImpl.java (_Jv_SO_KEEPALIVE_): Define.
(shutdownInput, shutdownOutput): Declare.
* java/net/PlainDatagramSocketImpl.java (_Jv_SO_KEEPALIVE_):
Define.
* java/net/natPlainSocketImpl.cc (setOption): Handle keepalive.
(getOption): Likewise.
(shutdownInput): New method.
(shutdownOutput): Likewise.
* java/net/natPlainDatagramSocketImpl.cc (setOption): Handle
keepalive.
(getOption): Likewise.
* java/net/SocketOptions.java (SO_KEEPALIVE): New constant.
* java/net/Socket.java (setKeepAlive): New method.
(getKeepAlive): Likewise.
(shutdownInput, shutdownOutput): New methods.

From-SVN: r56685

libjava/ChangeLog
libjava/java/net/JarURLConnection.java
libjava/java/net/PlainDatagramSocketImpl.java
libjava/java/net/PlainSocketImpl.java
libjava/java/net/Socket.java
libjava/java/net/SocketImpl.java
libjava/java/net/SocketOptions.java
libjava/java/net/URL.java
libjava/java/net/URLClassLoader.java
libjava/java/net/natPlainDatagramSocketImpl.cc
libjava/java/net/natPlainSocketImpl.cc

index 06211f11563269ed67c5adad01d3d60b5342c150..33c9bb40fc09f4a521fb522e9d8be76dded04b37 100644 (file)
@@ -1,3 +1,34 @@
+2002-08-29  Tom Tromey  <tromey@redhat.com>
+
+       * java/net/JarURLConnection.java (getCertificates): New method
+       from Classpath.
+       * java/net/URLClassLoader.java (URLClassLoader): Extends
+       SecureClassLoader.
+       (definePackage): New method from Classpath.
+       (getPermissions): Likewise.
+       (newInstance): Likewise.
+       (findClass): Construct CodeSource for new class (from Classpath).
+       * java/net/SocketImpl.java (shutdownInput, shutdownOutput): New
+       methods.
+       * java/net/URL.java (getUserInfo): New method.
+       (set(String,String,int,String,String,String,String,String)): New
+       method.
+       * java/net/PlainSocketImpl.java (_Jv_SO_KEEPALIVE_): Define.
+       (shutdownInput, shutdownOutput): Declare.
+       * java/net/PlainDatagramSocketImpl.java (_Jv_SO_KEEPALIVE_):
+       Define.
+       * java/net/natPlainSocketImpl.cc (setOption): Handle keepalive.
+       (getOption): Likewise.
+       (shutdownInput): New method.
+       (shutdownOutput): Likewise.
+       * java/net/natPlainDatagramSocketImpl.cc (setOption): Handle
+       keepalive.
+       (getOption): Likewise.
+       * java/net/SocketOptions.java (SO_KEEPALIVE): New constant.
+       * java/net/Socket.java (setKeepAlive): New method.
+       (getKeepAlive): Likewise.
+       (shutdownInput, shutdownOutput): New methods.
+
 2002-08-29  Michael Koch  <konqueror@gmx.de>
 
        * java/net/DatagramPacket.java: updated to JDK 1.4 API
index f0b3b5df34390336b7e608116f5ed9e6d4501bea..5ee438dd5152ffad0d2d799dc302126749caa97d 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1999, 2000  Free Software Foundation
+/* Copyright (C) 1999, 2000, 2002  Free Software Foundation
 
    This file is part of libgcj.
 
@@ -15,6 +15,7 @@ import java.util.zip.*;
 import java.util.Map;
 import java.util.Vector;
 import java.util.Hashtable;
+import java.security.cert.Certificate;
 
 /**
  * @author Kresten Krab Thorup <krab@gnu.org>
@@ -316,4 +317,16 @@ public abstract class JarURLConnection extends URLConnection
     hdrHash.put(key.toLowerCase(), Long.toString(len));
   }
 
+  /**
+   * Returns an array of Certificate objects for the jar file entry specified
+   * by this URL or null if there are none
+   *
+   * @return A Certificate array
+   *
+   * @exception IOException If an error occurs
+   */
+  public Certificate[] getCertificates() throws IOException
+  {
+    return getJarEntry().getCertificates();
+  }
 }
index 55ea468dadc19de80d951e7c0aaf63b6942cb5e2..5f8a559557c3f806a4c4e6d2f2fe2d54dae1a8ff 100644 (file)
@@ -1,6 +1,6 @@
 // PlainDatagramSocketImpl.java - Implementation of DatagramSocketImpl.
 
-/* Copyright (C) 1999  Free Software Foundation
+/* Copyright (C) 1999, 2002  Free Software Foundation
 
    This file is part of libgcj.
 
@@ -33,7 +33,8 @@ class PlainDatagramSocketImpl extends DatagramSocketImpl
                    _Jv_SO_LINGER_ = SocketOptions.SO_LINGER,
                    _Jv_SO_TIMEOUT_ = SocketOptions.SO_TIMEOUT,
                    _Jv_SO_SNDBUF_ = SocketOptions.SO_SNDBUF,
-                   _Jv_SO_RCVBUF_ = SocketOptions.SO_RCVBUF;
+                   _Jv_SO_RCVBUF_ = SocketOptions.SO_RCVBUF,
+                   _Jv_SO_KEEPALIVE_ = SocketOptions.SO_KEEPALIVE;
 
   int fnum = -1;
 
index 354d652a5bf6863e93722a96d4d5a89c16064060..2146f5e9a7db65aa1c5987f137678b44d36ff442 100644 (file)
@@ -32,7 +32,8 @@ class PlainSocketImpl extends SocketImpl
                    _Jv_SO_LINGER_ = SocketOptions.SO_LINGER,
                    _Jv_SO_TIMEOUT_ = SocketOptions.SO_TIMEOUT,
                    _Jv_SO_SNDBUF_ = SocketOptions.SO_SNDBUF,
-                   _Jv_SO_RCVBUF_ = SocketOptions.SO_RCVBUF;
+                   _Jv_SO_RCVBUF_ = SocketOptions.SO_RCVBUF,
+                   _Jv_SO_KEEPALIVE_ = SocketOptions.SO_KEEPALIVE;
 
   /**
    * The OS file handle representing the socket.
@@ -53,6 +54,10 @@ class PlainSocketImpl extends SocketImpl
 
   public native Object getOption(int optID) throws SocketException;
 
+  public native void shutdownInput () throws IOException;
+
+  public native void shutdownOutput () throws IOException;
+
   protected native void create (boolean stream)  throws IOException;
 
   protected void connect (String host, int port) throws IOException
index 6c0df5402b4ff3bb39999b14eaa5cf9e8c53470b..217e6956b5b781e99eb12263059872cd7ee88353 100644 (file)
@@ -617,6 +617,47 @@ public class Socket
       throw new SocketException("Internal Error: Unexpected type");
   }
 
+  /**
+   * This method sets the value for the socket level socket option
+   * SO_KEEPALIVE.
+   *
+   * @param on True if SO_KEEPALIVE should be enabled
+   *
+   * @exception SocketException If an error occurs or Socket is not connected
+   *
+   * @since Java 1.3
+   */
+  public void setKeepAlive (boolean on) throws SocketException
+  {
+    if (impl == null)
+      throw new SocketException("Not connected");
+
+    impl.setOption(SocketOptions.SO_RCVBUF, new Boolean(on));
+  }
+
+  /**
+   * This method returns the value of the socket level socket option
+   * SO_KEEPALIVE.
+   *
+   * @return The setting
+   *
+   * @exception SocketException If an error occurs or Socket is not connected
+   *
+   * @since Java 1.3
+   */
+  public boolean getKeepAlive () throws SocketException
+  {
+    if (impl == null)
+      throw new SocketException("Not connected");
+
+    Object buf = impl.getOption(SocketOptions.SO_RCVBUF);
+
+    if (buf instanceof Boolean)
+      return(((Boolean)buf).booleanValue());
+    else
+      throw new SocketException("Internal Error: Unexpected type");
+  }
+
   /**
    * Closes the socket.
    *
@@ -667,4 +708,26 @@ public class Socket
 
     factory = fac;
   }
+
+  /**
+   * Closes the input side of the socket stream.
+   *
+   * @exception IOException If an error occurs.
+   */
+  public void shutdownInput() throws IOException 
+  {
+    if (impl != null)
+      impl.shutdownInput();
+  }
+
+  /**
+   * Closes the output side of the socket stream.
+   *
+   * @exception IOException If an error occurs.
+   */
+  public void shutdownOutput() throws IOException
+  {
+    if (impl != null)
+      impl.shutdownOutput();
+  }
 }
index fb5a60ca52098b5474ad72b096b95dd7cf1b2f36..7dcf87de629b921958772387e1e1a4ee479a3127 100644 (file)
@@ -264,4 +264,20 @@ public abstract class SocketImpl implements SocketOptions
    * @XXX This redeclaration from SocketOptions is a workaround to a gcj bug.
    */
   public abstract Object getOption(int option_id) throws SocketException;
+
+  /**
+   * Shut down the input side of this socket.  Subsequent reads will
+   * return end-of-file.
+   *
+   * @exception IOException if an error occurs
+   */
+  public abstract void shutdownInput () throws IOException;
+
+  /**
+   * Shut down the output side of this socket.  Subsequent writes will
+   * fail with an IOException.
+   *
+   * @exception IOException if an error occurs
+   */
+  public abstract void shutdownOutput () throws IOException;
 }
index 7dcba2a67a6e7de8d545d90c2b4e56189e5d86a3..bf57450d0375dee24ec465bb79da26c50682c87f 100644 (file)
@@ -1,5 +1,5 @@
 /* SocketOptions.java -- Implements options for sockets (duh!)
-   Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+   Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -61,6 +61,11 @@ public interface SocketOptions
  * Static Variables
  */
 
+/**
+ * Option id for the SO_KEEPALIVE value
+ */
+static final int SO_KEEPALIVE = 0x8;
+
 /**
   * Option id for the SO_LINGER value
   */
index a3e9d784cef2553d59459e438ea88070ea4e168c..73edeca415d5140b1406d106019c768429e6142f 100644 (file)
@@ -175,7 +175,8 @@ public final class URL implements Serializable
       this.handler = setURLStreamHandler(protocol);
 
     if (this.handler == null)
-      throw new MalformedURLException("Protocol handler not found: " + protocol);
+      throw new MalformedURLException("Protocol handler not found: "
+                                     + protocol);
 
     // JDK 1.2 doc for parseURL specifically states that any '#' ref
     // is to be excluded by passing the 'limit' as the indexOf the '#'
@@ -245,6 +246,12 @@ public final class URL implements Serializable
     return ref;
   }
 
+  public String getUserInfo ()
+  {
+    int at = host.indexOf('@');
+    return at < 0 ? null : host.substring(0, at);
+  }
+
   public int hashCode()
   {
     // JCL book says this is computed using (only) the hashcodes of the 
@@ -299,6 +306,30 @@ public final class URL implements Serializable
     hashCode = hashCode();                     // Used for serialization.
   }
 
+  /** @since 1.3 */
+  protected void set(String protocol, String host, int port,
+                    String authority, String userInfo,
+                    String path, String query, 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;
+    if (userInfo == null)
+      this.host = host;
+    else
+      this.host = userInfo + "@" + host;
+    this.port = port;
+    if (query == null)
+      this.file = path;
+    else
+      this.file = path + "?" + query;
+    this.ref = ref;
+    hashCode = hashCode();                     // Used for serialization.
+  }
+
   public static synchronized void
        setURLStreamHandlerFactory(URLStreamHandlerFactory fac)
   {
index 4fce6250e4afae8f2afdf2309ec002ee2bfe63e3..3afb8f1861ccc981c25edff66f557c6957fffad7 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1999, 2000  Free Software Foundation
+/* Copyright (C) 1999, 2000, 2002  Free Software Foundation
 
    This file is part of libgcj.
 
@@ -12,11 +12,15 @@ import java.io.*;
 import java.util.jar.*;
 import java.util.Enumeration;
 import java.util.Vector;
+import java.security.CodeSource;
+import java.security.SecureClassLoader;
+import java.security.PermissionCollection;
+import java.security.cert.Certificate;
 
 /**
  * @since 1.2
  */
-public class URLClassLoader extends ClassLoader 
+public class URLClassLoader extends SecureClassLoader
 {
   // The URLStreamHandlerFactory
   URLStreamHandlerFactory factory = null;
@@ -228,12 +232,12 @@ public class URLClassLoader extends ClassLoader
 
     try 
       {
-       URL u = getResource (name.replace ('.', '/') + ".class");
+       URL url = getResource (name.replace ('.', '/') + ".class");
 
-       if (u == null)
+       if (url == null)
          throw new ClassNotFoundException (name);
 
-       URLConnection connection = u.openConnection ();
+       URLConnection connection = url.openConnection ();
        InputStream is = connection.getInputStream ();
 
        int len = connection.getContentLength ();
@@ -250,12 +254,171 @@ public class URLClassLoader extends ClassLoader
            off += c;
          }
 
-       return defineClass (name, data, 0, len);
+       // Now construct the CodeSource (if loaded from a jar file)
+       CodeSource source = null;
+       if (url.getProtocol().equals("jar"))
+         {
+           Certificate[] certificates =
+             ((JarURLConnection) connection).getCertificates();
+           String u = url.toExternalForm ();
+           u = u.substring (4); //skip "jar:"
+           int i = u.indexOf ('!');
+           if (i >= 0)
+             u = u.substring (0, i);
+           url = new URL("jar", "", u);
+
+           source = new CodeSource(url, certificates);
+         }
+       else if (url.getProtocol().equals("file"))
+         {
+           try
+             {
+               String u = url.toExternalForm();
+               // Skip "file:" and then get canonical directory name.
+               File f = new File(u.substring(5));
+               f = f.getCanonicalFile();
+               url = new URL("file", "", f.getParent());
+               source = new CodeSource (url, null);
+             }
+           catch (IOException ignore)
+             {
+             }
+         }
+
+       return defineClass (name, data, 0, len, source);
       } 
     catch (java.io.IOException x)
       {
        throw new ClassNotFoundException(name);
       }
   }
-}
 
+  /** 
+   * Defines a Package based on the given name and the supplied manifest
+   * information. The manifest indicates the tile, version and
+   * vendor information of the specification and implementation and wheter the
+   * package is sealed. If the Manifest indicates that the package is sealed
+   * then the Package will be sealed with respect to the supplied URL.
+   *
+   * @exception IllegalArgumentException If this package name already exists
+   * in this class loader
+   * @param name The name of the package
+   * @param manifest The manifest describing the specification,
+   * implementation and sealing details of the package
+   * @param url the code source url to seal the package
+   * @return the defined Package
+   */
+  protected Package definePackage(String name, Manifest manifest, URL url) 
+    throws IllegalArgumentException
+  {
+    Attributes attr = manifest.getMainAttributes();
+    String specTitle =
+      attr.getValue(Attributes.Name.SPECIFICATION_TITLE); 
+    String specVersion =
+      attr.getValue(Attributes.Name.SPECIFICATION_VERSION); 
+    String specVendor =
+      attr.getValue(Attributes.Name.SPECIFICATION_VENDOR); 
+    String implTitle =
+      attr.getValue(Attributes.Name.IMPLEMENTATION_TITLE); 
+    String implVersion =
+      attr.getValue(Attributes.Name.IMPLEMENTATION_VERSION); 
+    String implVendor =
+      attr.getValue(Attributes.Name.IMPLEMENTATION_VENDOR);
+
+    // Look if the Manifest indicates that this package is sealed
+    // XXX - most likely not completely correct!
+    // Shouldn't we also check the sealed attribute of the complete jar?
+    // http://java.sun.com/products/jdk/1.3/docs/guide/extensions/spec.html#bundled
+    // But how do we get that jar manifest here?
+    String sealed = attr.getValue(Attributes.Name.SEALED);
+    if ("false".equals(sealed))
+      {
+       // Make sure that the URL is null so the package is not
+       // sealed.
+       url = null;
+      }
+
+    return definePackage(name, specTitle, specVersion, specVendor,
+                        implTitle, implVersion, implVendor, url);
+  }
+
+  /**
+   * Returns the permissions needed to access a particular code source.
+   * These permissions includes those returned by
+   * <CODE>SecureClassLoader.getPermissions</CODE> and the actual permissions
+   * to access the objects referenced by the URL of the code source.
+   * The extra permissions added depend on the protocol and file portion of
+   * the URL in the code source. If the URL has the "file" protocol ends with
+   * a / character then it must be a directory and a file Permission to read
+   * everthing in that directory and all subdirectories is added. If the URL
+   * had the "file" protocol and doesn't end with a / character then it must
+   * be a normal file and a file permission to read that file is added. If the
+   * URL has any other protocol then a socket permission to connect and accept
+   * connections from the host portion of the URL is added.
+   * @param source The codesource that needs the permissions to be accessed
+   * @return the collection of permissions needed to access the code resource
+   * @see SecureClassLoader.getPermissions()
+   */
+  protected PermissionCollection getPermissions(CodeSource source)
+  {
+    // XXX - This implementation does exactly as the Javadoc describes.
+    // But maybe we should/could use URLConnection.getPermissions()?
+
+    // First get the permissions that would normally be granted
+    PermissionCollection permissions = super.getPermissions(source);
+        
+    // Now add the any extra permissions depending on the URL location
+    URL url = source.getLocation();
+    String protocol = url.getProtocol();
+    if (protocol.equals("file"))
+      {
+       String file = url.getFile();
+       // If the file end in / it must be an directory
+       if (file.endsWith("/"))
+         {
+           // Grant permission to read everything in that directory and
+           // all subdirectories
+           permissions.add(new FilePermission(file + "-", "read"));
+         }
+       else
+         {
+           // It is a 'normal' file
+           // Grant permission to access that file
+           permissions.add(new FilePermission(file, "read"));
+         }
+      }
+    else
+      {
+       // Grant permission to connect to and accept connections from host
+         String host = url.getHost();
+         permissions.add(new SocketPermission(host, "connect,accept"));
+      }
+
+    return permissions;
+  }
+
+  /**
+   * Creates a new instance of a URLClassLoader that gets classes from the
+   * supplied URLs. This class loader will have as parent the standard
+   * system class loader.
+   * @param urls the initial URLs used to resolve classes and resources
+   */
+  public static URLClassLoader newInstance(URL urls[]) throws
+    SecurityException
+  {
+    return new URLClassLoader(urls);
+  }
+
+  /**
+   * Creates a new instance of a URLClassLoader that gets classes from the
+   * supplied URLs and with the supplied loader as parent class loader.
+   * @param urls the initial URLs used to resolve classes and resources
+   * @param parent the parent class loader
+   */
+  public static URLClassLoader newInstance(URL urls[],
+                                          ClassLoader parent)
+    throws SecurityException
+  {
+    return new URLClassLoader(urls, parent);
+  }
+}
index e581f08db5ce3186701c78b92fee82b3a8f64aa1..bb306e202bdfe572ba82ad94a07b205d45655ec7 100644 (file)
@@ -524,6 +524,10 @@ java::net::PlainDatagramSocketImpl::setOption (jint optID,
         throw new java::net::SocketException (
           JvNewStringUTF ("SO_LINGER not valid for UDP"));
         return;
+      case _Jv_SO_KEEPALIVE_ :
+        throw new java::net::SocketException (
+          JvNewStringUTF ("SO_KEEPALIVE not valid for UDP"));
+        return;
       case _Jv_SO_SNDBUF_ :
       case _Jv_SO_RCVBUF_ :
 #if defined(SO_SNDBUF) && defined(SO_RCVBUF)
@@ -613,11 +617,14 @@ java::net::PlainDatagramSocketImpl::getOption (jint optID)
         throw new java::net::SocketException (
           JvNewStringUTF ("TCP_NODELAY not valid for UDP"));
         break;
-
       case _Jv_SO_LINGER_ :
         throw new java::net::SocketException (
           JvNewStringUTF ("SO_LINGER not valid for UDP"));
         break;    
+      case _Jv_SO_KEEPALIVE_ :
+        throw new java::net::SocketException (
+          JvNewStringUTF ("SO_KEEPALIVE not valid for UDP"));
+        break;
       case _Jv_SO_RCVBUF_ :
       case _Jv_SO_SNDBUF_ :
 #if defined(SO_SNDBUF) && defined(SO_RCVBUF)
index 370c9946177183fb9bad2d38bc4bbc4fc6540cb8..f82aa6bb47cee3009dc939833b2feb98072bd057 100644 (file)
@@ -222,6 +222,20 @@ java::net::PlainSocketImpl::close(void)
     JvNewStringLatin1 ("SocketImpl.close: unimplemented"));
 }
 
+void
+java::net::PlainSocketImpl::shutdownInput (void)
+{
+  throw new SocketException (
+    JvNewStringLatin1 ("SocketImpl.shutdownInput: unimplemented"));
+}
+
+void
+java::net::PlainSocketImpl::shutdownOutput (void)
+{
+  throw new SocketException (
+    JvNewStringLatin1 ("SocketImpl.shutdownOutput: unimplemented"));
+}
+
 #else /* DISABLE_JAVA_NET */
 
 union SockAddr
@@ -722,12 +736,18 @@ java::net::PlainSocketImpl::setOption (jint optID, java::lang::Object *value)
 #ifdef TCP_NODELAY
         if (::setsockopt (fnum, IPPROTO_TCP, TCP_NODELAY, (char *) &val,
            val_len) != 0)
-         goto error;    
+         goto error;
 #else
         throw new java::lang::InternalError (
           JvNewStringUTF ("TCP_NODELAY not supported"));
 #endif /* TCP_NODELAY */
         return;
+
+      case _Jv_SO_KEEPALIVE_ :
+        if (::setsockopt (fnum, SOL_SOCKET, SO_KEEPALIVE, (char *) &val,
+           val_len) != 0)
+         goto error;
+
       case _Jv_SO_LINGER_ :
 #ifdef SO_LINGER
         struct linger l_val;
@@ -816,6 +836,14 @@ java::net::PlainSocketImpl::getOption (jint optID)
           JvNewStringUTF ("SO_LINGER not supported"));
 #endif
         break;    
+
+      case _Jv_SO_KEEPALIVE_ :
+        if (::getsockopt (fnum, SOL_SOCKET, SO_KEEPALIVE, (char *) &val,
+           &val_len) != 0)
+          goto error;
+        else
+         return new java::lang::Boolean (val != 0);
+
       case _Jv_SO_RCVBUF_ :
       case _Jv_SO_SNDBUF_ :
 #if defined(SO_SNDBUF) && defined(SO_RCVBUF)
@@ -876,4 +904,18 @@ java::net::PlainSocketImpl::getOption (jint optID)
   throw new java::net::SocketException (JvNewStringUTF (strerr));
 }
 
+void
+java::net::PlainSocketImpl::shutdownInput (void)
+{
+  if (::shutdown (fnum, 0))
+    throw new SocketException (JvNewStringUTF (strerror (errno)));
+}
+
+void
+java::net::PlainSocketImpl::shutdownOutput (void)
+{
+  if (::shutdown (fnum, 1))
+    throw new SocketException (JvNewStringUTF (strerror (errno)));
+}
+
 #endif /* DISABLE_JAVA_NET */