Add support for exec'ing file permissions for native libraries. (FELIX-1297)
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@790964 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/framework/src/main/java/org/apache/felix/framework/cache/BundleArchive.java b/framework/src/main/java/org/apache/felix/framework/cache/BundleArchive.java
index 8e64020..e8fbf5e 100644
--- a/framework/src/main/java/org/apache/felix/framework/cache/BundleArchive.java
+++ b/framework/src/main/java/org/apache/felix/framework/cache/BundleArchive.java
@@ -21,6 +21,7 @@
import java.io.*;
import java.net.URLDecoder;
+import java.util.Map;
import org.apache.felix.framework.Logger;
import org.osgi.framework.Bundle;
@@ -82,9 +83,10 @@
private static final transient String INSTALLED_STATE = "installed";
private static final transient String UNINSTALLED_STATE = "uninstalled";
- private Logger m_logger = null;
+ private final Logger m_logger;
+ private final Map m_configMap;
private long m_id = -1;
- private File m_archiveRootDir = null;
+ private final File m_archiveRootDir;
private String m_originalLocation = null;
private String m_currentLocation = null;
private int m_persistentState = -1;
@@ -102,6 +104,9 @@
**/
public BundleArchive()
{
+ m_logger = null;
+ m_configMap = null;
+ m_archiveRootDir = null;
}
/**
@@ -121,10 +126,11 @@
* @param is input stream from which to read the bundle content.
* @throws Exception if any error occurs.
**/
- public BundleArchive(Logger logger, File archiveRootDir, long id,
+ public BundleArchive(Logger logger, Map configMap, File archiveRootDir, long id,
String location, InputStream is) throws Exception
{
m_logger = logger;
+ m_configMap = configMap;
m_archiveRootDir = archiveRootDir;
m_id = id;
if (m_id <= 0)
@@ -153,10 +159,11 @@
* @param id the bundle identifier associated with the archive.
* @throws Exception if any error occurs.
**/
- public BundleArchive(Logger logger, File archiveRootDir)
+ public BundleArchive(Logger logger, Map configMap, File archiveRootDir)
throws Exception
{
m_logger = logger;
+ m_configMap = configMap;
m_archiveRootDir = archiveRootDir;
// Add a revision for each one that already exists in the file
@@ -976,22 +983,26 @@
// flag set to true.
if (BundleCache.getSecureAction().isFileDirectory(file))
{
- result = new DirectoryRevision(m_logger, revisionRootDir, location);
+ result = new DirectoryRevision(m_logger, m_configMap,
+ revisionRootDir, location);
}
else
{
- result = new JarRevision(m_logger, revisionRootDir, location, true);
+ result = new JarRevision(m_logger, m_configMap, revisionRootDir,
+ location, true);
}
}
else if (location.startsWith(INPUTSTREAM_PROTOCOL))
{
// Assume all input streams point to JAR files.
- result = new JarRevision(m_logger, revisionRootDir, location, false, is);
+ result = new JarRevision(m_logger, m_configMap, revisionRootDir,
+ location, false, is);
}
else
{
// Anything else is assumed to be a URL to a JAR file.
- result = new JarRevision(m_logger, revisionRootDir, location, false);
+ result = new JarRevision(m_logger, m_configMap, revisionRootDir,
+ location, false);
}
}
catch (Exception ex)
diff --git a/framework/src/main/java/org/apache/felix/framework/cache/BundleCache.java b/framework/src/main/java/org/apache/felix/framework/cache/BundleCache.java
index 1b6525e..c84a56f 100644
--- a/framework/src/main/java/org/apache/felix/framework/cache/BundleCache.java
+++ b/framework/src/main/java/org/apache/felix/framework/cache/BundleCache.java
@@ -80,8 +80,8 @@
protected static transient final String CACHE_ROOTDIR_DEFAULT = ".";
protected static transient final String BUNDLE_DIR_PREFIX = "bundle";
- private Map m_configMap = null;
- private Logger m_logger = null;
+ private final Logger m_logger;
+ private final Map m_configMap;
private File m_cacheDir = null;
private BundleArchive[] m_archives = null;
@@ -90,8 +90,8 @@
public BundleCache(Logger logger, Map configMap)
throws Exception
{
- m_configMap = configMap;
m_logger = logger;
+ m_configMap = configMap;
initialize();
}
@@ -156,7 +156,7 @@
{
// Create the archive and add it to the list of archives.
BundleArchive ba =
- new BundleArchive(m_logger, archiveRootDir, id, location, is);
+ new BundleArchive(m_logger, m_configMap, archiveRootDir, id, location, is);
BundleArchive[] tmp = new BundleArchive[m_archives.length + 1];
System.arraycopy(m_archives, 0, tmp, 0, m_archives.length);
tmp[m_archives.length] = ba;
@@ -378,7 +378,7 @@
// Recreate the bundle archive.
try
{
- archiveList.add(new BundleArchive(m_logger, children[i]));
+ archiveList.add(new BundleArchive(m_logger, m_configMap, children[i]));
}
catch (Exception ex)
{
diff --git a/framework/src/main/java/org/apache/felix/framework/cache/BundleRevision.java b/framework/src/main/java/org/apache/felix/framework/cache/BundleRevision.java
index 59bc7ce..6d8ae36 100644
--- a/framework/src/main/java/org/apache/felix/framework/cache/BundleRevision.java
+++ b/framework/src/main/java/org/apache/felix/framework/cache/BundleRevision.java
@@ -42,9 +42,10 @@
**/
public abstract class BundleRevision
{
- private Logger m_logger;
- private File m_revisionRootDir = null;
- private String m_location = null;
+ private final Logger m_logger;
+ private final Map m_configMap;
+ private final File m_revisionRootDir;
+ private final String m_location;
/**
* <p>
@@ -64,10 +65,11 @@
* @param trustedCaCerts the trusted CA certificates if any.
* @throws Exception if any errors occur.
**/
- public BundleRevision(Logger logger, File revisionRootDir, String location)
+ public BundleRevision(Logger logger, Map configMap, File revisionRootDir, String location)
throws Exception
{
m_logger = logger;
+ m_configMap = configMap;
m_revisionRootDir = revisionRootDir;
m_location = location;
}
@@ -85,6 +87,17 @@
/**
* <p>
+ * Returns the configuration map for this revision.
+ * </p>
+ * @return the configuration map for this revision.
+ **/
+ public Map getConfig()
+ {
+ return m_configMap;
+ }
+
+ /**
+ * <p>
* Returns the root directory for this revision.
* </p>
* @return the root directory for this revision.
diff --git a/framework/src/main/java/org/apache/felix/framework/cache/DirectoryContent.java b/framework/src/main/java/org/apache/felix/framework/cache/DirectoryContent.java
index 38901cd..25e1784 100644
--- a/framework/src/main/java/org/apache/felix/framework/cache/DirectoryContent.java
+++ b/framework/src/main/java/org/apache/felix/framework/cache/DirectoryContent.java
@@ -30,14 +30,17 @@
private static final transient String EMBEDDED_DIRECTORY = "-embedded";
private static final transient String LIBRARY_DIRECTORY = "lib";
- private Logger m_logger;
+ private final Logger m_logger;
+ private final Map m_configMap;
private final Object m_revisionLock;
- private File m_rootDir;
- private File m_dir;
+ private final File m_rootDir;
+ private final File m_dir;
- public DirectoryContent(Logger logger, Object revisionLock, File rootDir, File dir)
+ public DirectoryContent(Logger logger, Map configMap, Object revisionLock,
+ File rootDir, File dir)
{
m_logger = logger;
+ m_configMap = configMap;
m_revisionLock = revisionLock;
m_rootDir = rootDir;
m_dir = dir;
@@ -131,7 +134,7 @@
// just return it immediately.
if (entryName.equals(FelixConstants.CLASS_PATH_DOT))
{
- return new DirectoryContent(m_logger, m_revisionLock, m_rootDir, m_dir);
+ return new DirectoryContent(m_logger, m_configMap, m_revisionLock, m_rootDir, m_dir);
}
// Remove any leading slash, since all bundle class path
@@ -147,7 +150,7 @@
File file = new File(m_dir, entryName);
if (BundleCache.getSecureAction().isFileDirectory(file))
{
- return new DirectoryContent(m_logger, m_revisionLock, m_rootDir, file);
+ return new DirectoryContent(m_logger, m_configMap, m_revisionLock, m_rootDir, file);
}
else if (BundleCache.getSecureAction().fileExists(file)
&& entryName.endsWith(".jar"))
@@ -168,7 +171,7 @@
}
}
}
- return new JarContent(m_logger, m_revisionLock, extractedDir, file);
+ return new JarContent(m_logger, m_configMap, m_revisionLock, extractedDir, file);
}
// The entry could not be found, so return null.
diff --git a/framework/src/main/java/org/apache/felix/framework/cache/DirectoryRevision.java b/framework/src/main/java/org/apache/felix/framework/cache/DirectoryRevision.java
index 918f3e2..24d54d7 100644
--- a/framework/src/main/java/org/apache/felix/framework/cache/DirectoryRevision.java
+++ b/framework/src/main/java/org/apache/felix/framework/cache/DirectoryRevision.java
@@ -37,12 +37,12 @@
**/
class DirectoryRevision extends BundleRevision
{
- private File m_refDir = null;
+ private final File m_refDir;
public DirectoryRevision(
- Logger logger, File revisionRootDir, String location) throws Exception
+ Logger logger, Map configMap, File revisionRootDir, String location) throws Exception
{
- super(logger, revisionRootDir, location);
+ super(logger, configMap, revisionRootDir, location);
m_refDir = new File(location.substring(
location.indexOf(BundleArchive.FILE_PROTOCOL)
+ BundleArchive.FILE_PROTOCOL.length()));
@@ -96,7 +96,7 @@
public synchronized IContent getContent() throws Exception
{
- return new DirectoryContent(getLogger(), this, getRevisionRootDir(), m_refDir);
+ return new DirectoryContent(getLogger(), getConfig(), this, getRevisionRootDir(), m_refDir);
}
public void dispose() throws Exception
diff --git a/framework/src/main/java/org/apache/felix/framework/cache/JarContent.java b/framework/src/main/java/org/apache/felix/framework/cache/JarContent.java
index fc9ff53..1dca126 100644
--- a/framework/src/main/java/org/apache/felix/framework/cache/JarContent.java
+++ b/framework/src/main/java/org/apache/felix/framework/cache/JarContent.java
@@ -24,11 +24,15 @@
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
+import java.util.Map;
+import java.util.Properties;
import java.util.zip.ZipEntry;
import org.apache.felix.framework.Logger;
import org.apache.felix.framework.util.FelixConstants;
import org.apache.felix.framework.util.JarFileX;
+import org.apache.felix.framework.util.Util;
import org.apache.felix.moduleloader.IContent;
+import org.osgi.framework.Constants;
public class JarContent implements IContent
{
@@ -37,14 +41,16 @@
private static final transient String LIBRARY_DIRECTORY = "lib";
private final Logger m_logger;
+ private final Map m_configMap;
private final Object m_revisionLock;
private final File m_rootDir;
private final File m_file;
private JarFileX m_jarFile = null;
- public JarContent(Logger logger, Object revisionLock, File rootDir, File file)
+ public JarContent(Logger logger, Map configMap, Object revisionLock, File rootDir, File file)
{
m_logger = logger;
+ m_configMap = configMap;
m_revisionLock = revisionLock;
m_rootDir = rootDir;
m_file = file;
@@ -277,7 +283,7 @@
// just return it immediately.
if (entryName.equals(FelixConstants.CLASS_PATH_DOT))
{
- return new JarContent(m_logger, m_revisionLock, m_rootDir, m_file);
+ return new JarContent(m_logger, m_configMap, m_revisionLock, m_rootDir, m_file);
}
// Remove any leading slash.
@@ -344,7 +350,8 @@
}
}
return new JarContent(
- m_logger, m_revisionLock, extractedJar.getParentFile(), extractedJar);
+ m_logger, m_configMap, m_revisionLock,
+ extractedJar.getParentFile(), extractedJar);
}
// The entry could not be found, so return null.
@@ -409,6 +416,18 @@
// Create the file.
BundleCache.copyStreamToFile(is, libFile);
+
+ // Perform exec permission command on extracted library
+ // if one is configured.
+ String command = (String) m_configMap.get(Constants.FRAMEWORK_EXECPERMISSION);
+ if (command != null)
+ {
+ Properties props = new Properties();
+ props.setProperty("abspath", libFile.toString());
+ command = Util.substVars(command, "command", null, props);
+ Process p = BundleCache.getSecureAction().exec(command);
+ p.waitFor();
+ }
}
catch (Exception ex)
{
diff --git a/framework/src/main/java/org/apache/felix/framework/cache/JarRevision.java b/framework/src/main/java/org/apache/felix/framework/cache/JarRevision.java
index 9e47171..69b9051 100644
--- a/framework/src/main/java/org/apache/felix/framework/cache/JarRevision.java
+++ b/framework/src/main/java/org/apache/felix/framework/cache/JarRevision.java
@@ -50,18 +50,19 @@
private File m_bundleFile = null;
public JarRevision(
- Logger logger, File revisionRootDir, String location, boolean byReference)
+ Logger logger, Map configMap, File revisionRootDir,
+ String location, boolean byReference)
throws Exception
{
- this(logger, revisionRootDir, location, byReference, null);
+ this(logger, configMap, revisionRootDir, location, byReference, null);
}
public JarRevision(
- Logger logger, File revisionRootDir, String location,
+ Logger logger, Map configMap, File revisionRootDir, String location,
boolean byReference, InputStream is)
throws Exception
{
- super(logger, revisionRootDir, location);
+ super(logger, configMap, revisionRootDir, location);
if (byReference)
{
@@ -105,7 +106,7 @@
public synchronized IContent getContent() throws Exception
{
- return new JarContent(getLogger(), this, getRevisionRootDir(), m_bundleFile);
+ return new JarContent(getLogger(), getConfig(), this, getRevisionRootDir(), m_bundleFile);
}
public void dispose() throws Exception
diff --git a/framework/src/main/java/org/apache/felix/framework/util/SecureAction.java b/framework/src/main/java/org/apache/felix/framework/util/SecureAction.java
index 12a2dbf..b854334 100644
--- a/framework/src/main/java/org/apache/felix/framework/util/SecureAction.java
+++ b/framework/src/main/java/org/apache/felix/framework/util/SecureAction.java
@@ -176,6 +176,27 @@
}
}
+ public Process exec(String command) throws IOException
+ {
+ if (System.getSecurityManager() != null)
+ {
+ try
+ {
+ Actions actions = (Actions) m_actions.get();
+ actions.set(Actions.EXEC_ACTION, command);
+ return (Process) AccessController.doPrivileged(actions, m_acc);
+ }
+ catch (PrivilegedActionException ex)
+ {
+ throw (RuntimeException) ex.getException();
+ }
+ }
+ else
+ {
+ return Runtime.getRuntime().exec(command);
+ }
+ }
+
public String getAbsolutePath(File file)
{
if (System.getSecurityManager() != null)
@@ -971,36 +992,37 @@
public static final int CREATE_URL_ACTION = 4;
public static final int CREATE_URL_WITH_CONTEXT_ACTION = 5;
public static final int DELETE_FILE_ACTION = 6;
- public static final int FILE_EXISTS_ACTION = 7;
- public static final int FILE_IS_DIRECTORY_ACTION = 8;
- public static final int FOR_NAME_ACTION = 9;
- public static final int GET_ABSOLUTE_PATH_ACTION = 10;
- public static final int GET_CONSTRUCTOR_ACTION = 11;
- public static final int GET_DECLARED_CONSTRUCTOR_ACTION = 12;
- public static final int GET_DECLARED_METHOD_ACTION = 13;
- public static final int GET_FIELD_ACTION = 14;
- public static final int GET_FILE_INPUT_ACTION = 15;
- public static final int GET_FILE_OUTPUT_ACTION = 16;
- public static final int GET_JARURLCONNECTION_JAR_ACTION = 17;
- public static final int GET_METHOD_ACTION = 18;
- public static final int GET_POLICY_ACTION = 19;
- public static final int GET_PROPERTY_ACTION = 20;
- public static final int GET_URL_INPUT_ACTION = 21;
- public static final int INVOKE_CONSTRUCTOR_ACTION = 22;
- public static final int INVOKE_DIRECTMETHOD_ACTION = 23;
- public static final int INVOKE_METHOD_ACTION = 24;
- public static final int LIST_DIRECTORY_ACTION = 25;
- public static final int MAKE_DIRECTORIES_ACTION = 26;
- public static final int MAKE_DIRECTORY_ACTION = 27;
- public static final int OPEN_JARX_ACTION = 28;
- public static final int OPEN_JARX_VERIFY_ACTION = 29;
- public static final int OPEN_URLCONNECTION_ACTION = 30;
- public static final int RENAME_FILE_ACTION = 31;
- public static final int SET_ACCESSIBLE_ACTION = 32;
- public static final int START_ACTIVATOR_ACTION = 33;
- public static final int STOP_ACTIVATOR_ACTION = 34;
- public static final int SWAP_FIELD_ACTION = 35;
- public static final int SYSTEM_EXIT_ACTION = 36;
+ public static final int EXEC_ACTION = 7;
+ public static final int FILE_EXISTS_ACTION = 8;
+ public static final int FILE_IS_DIRECTORY_ACTION = 9;
+ public static final int FOR_NAME_ACTION = 10;
+ public static final int GET_ABSOLUTE_PATH_ACTION = 11;
+ public static final int GET_CONSTRUCTOR_ACTION = 12;
+ public static final int GET_DECLARED_CONSTRUCTOR_ACTION = 13;
+ public static final int GET_DECLARED_METHOD_ACTION = 14;
+ public static final int GET_FIELD_ACTION = 15;
+ public static final int GET_FILE_INPUT_ACTION = 16;
+ public static final int GET_FILE_OUTPUT_ACTION = 17;
+ public static final int GET_JARURLCONNECTION_JAR_ACTION = 18;
+ public static final int GET_METHOD_ACTION = 19;
+ public static final int GET_POLICY_ACTION = 20;
+ public static final int GET_PROPERTY_ACTION = 21;
+ public static final int GET_URL_INPUT_ACTION = 22;
+ public static final int INVOKE_CONSTRUCTOR_ACTION = 23;
+ public static final int INVOKE_DIRECTMETHOD_ACTION = 24;
+ public static final int INVOKE_METHOD_ACTION = 25;
+ public static final int LIST_DIRECTORY_ACTION = 26;
+ public static final int MAKE_DIRECTORIES_ACTION = 27;
+ public static final int MAKE_DIRECTORY_ACTION = 28;
+ public static final int OPEN_JARX_ACTION = 29;
+ public static final int OPEN_JARX_VERIFY_ACTION = 30;
+ public static final int OPEN_URLCONNECTION_ACTION = 31;
+ public static final int RENAME_FILE_ACTION = 32;
+ public static final int SET_ACCESSIBLE_ACTION = 33;
+ public static final int START_ACTIVATOR_ACTION = 34;
+ public static final int STOP_ACTIVATOR_ACTION = 35;
+ public static final int SWAP_FIELD_ACTION = 36;
+ public static final int SYSTEM_EXIT_ACTION = 37;
private int m_action = -1;
private Object m_arg1 = null;
@@ -1095,6 +1117,10 @@
return new URL((URL) arg1, (String) arg2,
(URLStreamHandler) arg3);
}
+ else if (action == EXEC_ACTION)
+ {
+ return Runtime.getRuntime().exec((String) arg1);
+ }
else if (action == GET_ABSOLUTE_PATH_ACTION)
{
return ((File) arg1).getAbsolutePath();