diff --git a/apps/routerconsole/java/src/net/i2p/router/web/PluginUpdateHandler.java b/apps/routerconsole/java/src/net/i2p/router/web/PluginUpdateHandler.java
index b892ca6a0..cd7bb8f1a 100644
--- a/apps/routerconsole/java/src/net/i2p/router/web/PluginUpdateHandler.java
+++ b/apps/routerconsole/java/src/net/i2p/router/web/PluginUpdateHandler.java
@@ -6,15 +6,12 @@ import java.util.Map;
import java.util.Properties;
import net.i2p.CoreVersion;
-import net.i2p.I2PAppContext;
import net.i2p.crypto.TrustedUpdate;
import net.i2p.data.DataHelper;
-import net.i2p.router.Router;
import net.i2p.router.RouterContext;
import net.i2p.util.EepGet;
import net.i2p.util.FileUtil;
import net.i2p.util.I2PAppThread;
-import net.i2p.util.Log;
import net.i2p.util.OrderedProperties;
import net.i2p.util.SecureDirectory;
import net.i2p.util.SimpleScheduler;
@@ -49,7 +46,7 @@ public class PluginUpdateHandler extends UpdateHandler {
public static final String PLUGIN_DIR = "plugins";
private static PluginUpdateHandler _instance;
- public static final synchronized PluginUpdateHandler getInstance(RouterContext ctx) {
+ public static final synchronized PluginUpdateHandler getInstance(RouterContext ctx) {
if (_instance != null)
return _instance;
_instance = new PluginUpdateHandler(ctx);
@@ -60,7 +57,7 @@ public class PluginUpdateHandler extends UpdateHandler {
super(ctx);
_appStatus = "";
}
-
+
public void update(String xpi2pURL) {
// don't block waiting for the other one to finish
if ("true".equals(System.getProperty(PROP_UPDATE_IN_PROGRESS))) {
@@ -79,7 +76,7 @@ public class PluginUpdateHandler extends UpdateHandler {
update.start();
}
}
-
+
public String getAppStatus() {
return _appStatus;
}
@@ -87,13 +84,13 @@ public class PluginUpdateHandler extends UpdateHandler {
public boolean isRunning() {
return _pluginUpdateRunner != null && _pluginUpdateRunner.isRunning();
}
-
+
@Override
public boolean isDone() {
// FIXME
return false;
}
-
+
/** @since 0.8.13 */
public boolean wasUpdateSuccessful() {
return _updated;
@@ -116,7 +113,7 @@ public class PluginUpdateHandler extends UpdateHandler {
public class PluginUpdateRunner extends UpdateRunner implements Runnable, EepGet.StatusListener {
- public PluginUpdateRunner(String url) {
+ public PluginUpdateRunner(String url) {
super();
}
@@ -124,23 +121,44 @@ public class PluginUpdateHandler extends UpdateHandler {
protected void update() {
_updated = false;
updateStatus("" + _("Downloading plugin from {0}", _xpi2pURL) + "");
- // use the same settings as for updater
- boolean shouldProxy = Boolean.valueOf(_context.getProperty(ConfigUpdateHandler.PROP_SHOULD_PROXY, ConfigUpdateHandler.DEFAULT_SHOULD_PROXY)).booleanValue();
- String proxyHost = _context.getProperty(ConfigUpdateHandler.PROP_PROXY_HOST, ConfigUpdateHandler.DEFAULT_PROXY_HOST);
- int proxyPort = ConfigUpdateHandler.proxyPort(_context);
- try {
- if (shouldProxy)
- // 10 retries!!
- _get = new EepGet(_context, proxyHost, proxyPort, 10, _updateFile, _xpi2pURL, false);
- else
- _get = new EepGet(_context, 1, _updateFile, _xpi2pURL, false);
- _get.addStatusListener(PluginUpdateRunner.this);
- _get.fetch();
- } catch (Throwable t) {
- _log.error("Error downloading plugin", t);
+ if(_xpi2pURL.startsWith("file://")) {
+ // strip off "file://"
+ String xpi2pfile = _xpi2pURL.substring(7);
+ if(xpi2pfile.isEmpty()) {
+ statusDone("" + _("No file specified {0}", _xpi2pURL) + "");
+ } else {
+ try {
+ // copy the contents of from to _updateFile
+ long alreadyTransferred = (new File(xpi2pfile)).getCanonicalFile().length();
+ if(FileUtil.copy((new File(xpi2pfile)).getCanonicalPath(), _updateFile, true, false)) {
+ transferComplete(alreadyTransferred, alreadyTransferred, 0L, _xpi2pURL, _updateFile, false);
+ } else {
+ statusDone("" + _("File copy failed {0}", _xpi2pURL) + "");
+ }
+ } catch (Throwable t) {
+ _log.error("Error copying plugin {0}", t);
+ }
+
+ }
+ } else {
+ // use the same settings as for updater
+ boolean shouldProxy = Boolean.valueOf(_context.getProperty(ConfigUpdateHandler.PROP_SHOULD_PROXY, ConfigUpdateHandler.DEFAULT_SHOULD_PROXY)).booleanValue();
+ String proxyHost = _context.getProperty(ConfigUpdateHandler.PROP_PROXY_HOST, ConfigUpdateHandler.DEFAULT_PROXY_HOST);
+ int proxyPort = ConfigUpdateHandler.proxyPort(_context);
+ try {
+ if (shouldProxy)
+ // 10 retries!!
+ _get = new EepGet(_context, proxyHost, proxyPort, 10, _updateFile, _xpi2pURL, false);
+ else
+ _get = new EepGet(_context, 1, _updateFile, _xpi2pURL, false);
+ _get.addStatusListener(PluginUpdateRunner.this);
+ _get.fetch();
+ } catch (Throwable t) {
+ _log.error("Error downloading plugin", t);
+ }
}
}
-
+
@Override
public void bytesTransferred(long alreadyTransferred, int currentWrite, long bytesTransferred, long bytesRemaining, String url) {
StringBuilder buf = new StringBuilder(64);
@@ -302,7 +320,6 @@ public class PluginUpdateHandler extends UpdateHandler {
statusDone("" + _("Downloaded plugin is for new installs only, but the plugin is already installed", url) + "");
return;
}
-
// compare previous version
File oldPropFile = new File(destDir, "plugin.config");
Properties oldProps = new OrderedProperties();
@@ -358,7 +375,24 @@ public class PluginUpdateHandler extends UpdateHandler {
statusDone("" + _("Plugin requires Jetty version {0} or lower", maxVersion) + "");
return;
}
-
+ /*
+ // not ready yet...
+ // do we defer extraction and installation?
+ if (Boolean.valueOf(props.getProperty("router-restart-required")).booleanValue() && !Boolean.valueOf(props.getProperty("dont-start-at-install")).booleanValue()) {
+ // Yup!
+ if (!destDir.mkdir()) {
+ to.delete();
+ statusDone("" + _("Cannot create plugin directory {0}", destDir.getAbsolutePath()) + "");
+ return;
+ }
+ if(!FileUtil.copy(to, destDir, true, true)) {
+ statusDone("" + _("Cannot copy plugin to directory {0}", destDir.getAbsolutePath()) + "");
+ }
+ // we don't need the original file anymore.
+ to.delete();
+ statusDone("" + _("Plugin will be installed on next restart.") + "");
+ }
+ */
if (PluginStarter.isPluginRunning(appName, _context)) {
wasRunning = true;
try {
@@ -390,7 +424,6 @@ public class PluginUpdateHandler extends UpdateHandler {
statusDone("" + _("Failed to install plugin in {0}", destDir.getAbsolutePath()) + "");
return;
}
-
_updated = true;
to.delete();
if (Boolean.valueOf(props.getProperty("dont-start-at-install")).booleanValue()) {
@@ -441,11 +474,11 @@ public class PluginUpdateHandler extends UpdateHandler {
}
}
-
+
@Override
protected void updateStatus(String s) {
super.updateStatus(s);
_appStatus = s;
}
}
-
+
diff --git a/history.txt b/history.txt
index ad504ebba..68e89dcdc 100644
--- a/history.txt
+++ b/history.txt
@@ -1,3 +1,11 @@
+2012-03-13 sponge
+ * Plugins:
+ - Handle 'file://' URLs for installation and updates.
+ You must specify the entire path, e.g.
+ file:///home/someone/magicplugin.xpi2p
+ - This works for updates too!
+ - Only tested on Linux, needs to be tested on Windows.
+
2012-03-12 zzz
* Console:
- Better IPv6 test, hopefully will work on Windows