From 112ddc71566f63ba00ebd3c9e97d9780d27b5e5b Mon Sep 17 00:00:00 2001 From: zzz Date: Sun, 14 Jun 2009 01:49:27 +0000 Subject: [PATCH] * jbigi, cpuid: - Extract files from jar to temp dir, load from that dir, then copy to the base dir if we have permissions (and failing silently if we don't), so we have optimized libs and no complaints when we have a read-only base dir. --- .../freenet/support/CPUInformation/CPUID.java | 16 ++++++++++++---- core/java/src/net/i2p/util/FileUtil.java | 16 +++++++++++++--- core/java/src/net/i2p/util/NativeBigInteger.java | 16 ++++++++++++---- 3 files changed, 37 insertions(+), 11 deletions(-) diff --git a/core/java/src/freenet/support/CPUInformation/CPUID.java b/core/java/src/freenet/support/CPUInformation/CPUID.java index 58469c6d7..e145c3795 100644 --- a/core/java/src/freenet/support/CPUInformation/CPUID.java +++ b/core/java/src/freenet/support/CPUInformation/CPUID.java @@ -10,6 +10,7 @@ import java.io.InputStream; import java.net.URL; import net.i2p.I2PAppContext; +import net.i2p.util.FileUtil; /** * @author Iakin @@ -484,8 +485,11 @@ public class CPUID { * *

This is a pretty ugly hack, using the general technique illustrated by the * onion FEC libraries. It works by pulling the resource, writing out the - * byte stream to a temporary file, loading the native library from that file, - * then deleting the file.

+ * byte stream to a temporary file, loading the native library from that file. + * We then attempt to copy the file from the temporary dir to the base install dir, + * so we don't have to do this next time - but we don't complain if it fails, + * so we transparently support read-only base dirs. + *

* * @return true if it was loaded successfully, else false * @@ -503,9 +507,10 @@ public class CPUID { File outFile = null; FileOutputStream fos = null; + String filename = libPrefix + "jcpuid" + libSuffix; try { InputStream libStream = resource.openStream(); - outFile = new File(I2PAppContext.getGlobalContext().getBaseDir(), libPrefix + "jcpuid" + libSuffix); + outFile = new File(I2PAppContext.getGlobalContext().getTempDir(), filename); fos = new FileOutputStream(outFile); // wtf this was 4096*1024 which is really excessive for a roughly 4KB file byte buf[] = new byte[4096]; @@ -517,7 +522,6 @@ public class CPUID { fos.close(); fos = null; System.load(outFile.getAbsolutePath());//System.load requires an absolute path to the lib - return true; } catch (UnsatisfiedLinkError ule) { if (_doLog) { System.err.println("ERROR: The resource " + resourceName @@ -536,6 +540,10 @@ public class CPUID { try { fos.close(); } catch (IOException ioe) {} } } + // copy to install dir, ignore failure + File newFile = new File(I2PAppContext.getGlobalContext().getBaseDir(), filename); + FileUtil.copy(outFile.getAbsolutePath(), newFile.getAbsolutePath(), false, true); + return true; } private static final String getResourceName() diff --git a/core/java/src/net/i2p/util/FileUtil.java b/core/java/src/net/i2p/util/FileUtil.java index 05346ccfe..b6140b6e4 100644 --- a/core/java/src/net/i2p/util/FileUtil.java +++ b/core/java/src/net/i2p/util/FileUtil.java @@ -201,9 +201,18 @@ public class FileUtil { } } - - /** return true if it was copied successfully */ + /** + * @return true if it was copied successfully + */ public static boolean copy(String source, String dest, boolean overwriteExisting) { + return copy(source, dest, overwriteExisting, false); + } + + /** + * @param quiet don't log fails to wrapper log if true + * @return true if it was copied successfully + */ + public static boolean copy(String source, String dest, boolean overwriteExisting, boolean quiet) { File src = new File(source); File dst = new File(dest); @@ -226,7 +235,8 @@ public class FileUtil { out.close(); return true; } catch (IOException ioe) { - ioe.printStackTrace(); + if (!quiet) + ioe.printStackTrace(); return false; } } diff --git a/core/java/src/net/i2p/util/NativeBigInteger.java b/core/java/src/net/i2p/util/NativeBigInteger.java index bafaa5e5c..44101afd9 100644 --- a/core/java/src/net/i2p/util/NativeBigInteger.java +++ b/core/java/src/net/i2p/util/NativeBigInteger.java @@ -24,6 +24,7 @@ import freenet.support.CPUInformation.IntelCPUInfo; import freenet.support.CPUInformation.UnknownCPUException; import net.i2p.I2PAppContext; +import net.i2p.util.FileUtil; import net.i2p.util.Log; /** @@ -516,8 +517,11 @@ public class NativeBigInteger extends BigInteger { * *

This is a pretty ugly hack, using the general technique illustrated by the * onion FEC libraries. It works by pulling the resource, writing out the - * byte stream to a temporary file, loading the native library from that file, - * then deleting the file.

+ * byte stream to a temporary file, loading the native library from that file. + * We then attempt to copy the file from the temporary dir to the base install dir, + * so we don't have to do this next time - but we don't complain if it fails, + * so we transparently support read-only base dirs. + *

* * @return true if it was loaded successfully, else false * @@ -538,9 +542,10 @@ public class NativeBigInteger extends BigInteger { File outFile = null; FileOutputStream fos = null; + String filename = _libPrefix + "jbigi" + _libSuffix; try { InputStream libStream = resource.openStream(); - outFile = new File(I2PAppContext.getGlobalContext().getBaseDir(), _libPrefix + "jbigi" + _libSuffix); + outFile = new File(I2PAppContext.getGlobalContext().getTempDir(), filename); fos = new FileOutputStream(outFile); // wtf this was 4096*1024 which is really excessive for a roughly 50KB file byte buf[] = new byte[4096]; @@ -552,7 +557,6 @@ public class NativeBigInteger extends BigInteger { fos.close(); fos = null; System.load(outFile.getAbsolutePath()); //System.load requires an absolute path to the lib - return true; } catch (UnsatisfiedLinkError ule) { if (_doLog) { System.err.println("ERROR: The resource " + resourceName @@ -571,6 +575,10 @@ public class NativeBigInteger extends BigInteger { try { fos.close(); } catch (IOException ioe) {} } } + // copy to install dir, ignore failure + File newFile = new File(I2PAppContext.getGlobalContext().getBaseDir(), filename); + FileUtil.copy(outFile.getAbsolutePath(), newFile.getAbsolutePath(), false, true); + return true; } private static final String getResourceName(boolean optimized) {