diff --git a/apps/BOB/src/net/i2p/BOB/BOB.java b/apps/BOB/src/net/i2p/BOB/BOB.java index 9f87e4f88f..1aa432e2eb 100644 --- a/apps/BOB/src/net/i2p/BOB/BOB.java +++ b/apps/BOB/src/net/i2p/BOB/BOB.java @@ -23,6 +23,7 @@ */ package net.i2p.BOB; +import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; @@ -34,6 +35,8 @@ import java.net.Socket; import java.net.SocketTimeoutException; import java.util.Properties; import java.util.concurrent.atomic.AtomicBoolean; + +import net.i2p.I2PAppContext; import net.i2p.client.I2PClient; import net.i2p.client.streaming.RetransmissionTimer; import net.i2p.util.Log; @@ -186,16 +189,19 @@ public class BOB { i = Y2.hashCode(); try { { + File cfg = new File(configLocation); + if (!cfg.isAbsolute()) + cfg = new File(I2PAppContext.getGlobalContext().getConfigDir(), configLocation); try { - FileInputStream fi = new FileInputStream(configLocation); + FileInputStream fi = new FileInputStream(cfg); props.load(fi); fi.close(); } catch (FileNotFoundException fnfe) { - warn("Unable to load up the BOB config file " + configLocation + ", Using defaults."); + warn("Unable to load up the BOB config file " + cfg.getAbsolutePath() + ", Using defaults."); warn(fnfe.toString()); save = true; } catch (IOException ioe) { - warn("IOException on BOB config file " + configLocation + ", using defaults."); + warn("IOException on BOB config file " + cfg.getAbsolutePath() + ", using defaults."); warn(ioe.toString()); } } @@ -228,13 +234,16 @@ public class BOB { props.setProperty(PROP_BOB_HOST, "localhost"); } if (save) { + File cfg = new File(configLocation); + if (!cfg.isAbsolute()) + cfg = new File(I2PAppContext.getGlobalContext().getConfigDir(), configLocation); try { - warn("Writing new defaults file " + configLocation); - FileOutputStream fo = new FileOutputStream(configLocation); - props.store(fo, configLocation); + warn("Writing new defaults file " + cfg.getAbsolutePath()); + FileOutputStream fo = new FileOutputStream(cfg); + props.store(fo, cfg.getAbsolutePath()); fo.close(); } catch (IOException ioe) { - error("IOException on BOB config file " + configLocation + ", " + ioe); + error("IOException on BOB config file " + cfg.getAbsolutePath() + ", " + ioe); } } diff --git a/apps/addressbook/java/src/addressbook/AddressBook.java b/apps/addressbook/java/src/addressbook/AddressBook.java index a46c256c80..2694cae781 100644 --- a/apps/addressbook/java/src/addressbook/AddressBook.java +++ b/apps/addressbook/java/src/addressbook/AddressBook.java @@ -94,20 +94,21 @@ public class AddressBook { * @param proxyPort port number of proxy */ public AddressBook(Subscription subscription, String proxyHost, int proxyPort) { + File tmp = new File(I2PAppContext.getGlobalContext().getTempDir(), "addressbook.tmp"); this.location = subscription.getLocation(); EepGet get = new EepGet(I2PAppContext.getGlobalContext(), true, - proxyHost, proxyPort, 0, -1l, MAX_SUB_SIZE, "addressbook.tmp", null, + proxyHost, proxyPort, 0, -1l, MAX_SUB_SIZE, tmp.getAbsolutePath(), null, subscription.getLocation(), true, subscription.getEtag(), subscription.getLastModified(), null); if (get.fetch()) { subscription.setEtag(get.getETag()); subscription.setLastModified(get.getLastModified()); } try { - this.addresses = ConfigParser.parse(new File("addressbook.tmp")); + this.addresses = ConfigParser.parse(tmp); } catch (IOException exp) { this.addresses = new HashMap(); } - new File("addressbook.tmp").delete(); + tmp.delete(); } /** diff --git a/apps/addressbook/java/src/addressbook/Daemon.java b/apps/addressbook/java/src/addressbook/Daemon.java index a1b1ae18a3..a8a9a2da6e 100644 --- a/apps/addressbook/java/src/addressbook/Daemon.java +++ b/apps/addressbook/java/src/addressbook/Daemon.java @@ -28,6 +28,8 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; +import net.i2p.I2PAppContext; + /** * Main class of addressbook. Performs updates, and runs the main loop. * @@ -125,11 +127,13 @@ public class Daemon { public void run(String[] args) { String settingsLocation = "config.txt"; - String home; + File homeFile; if (args.length > 0) { - home = args[0]; + homeFile = new File(args[0]); + if (!homeFile.isAbsolute()) + homeFile = new File(I2PAppContext.getGlobalContext().getRouterDir(), args[0]); } else { - home = "."; + homeFile = new File(System.getProperty("user.dir")); } Map defaultSettings = new HashMap(); @@ -145,7 +149,6 @@ public class Daemon { defaultSettings.put("last_modified", "last_modified"); defaultSettings.put("update_delay", "12"); - File homeFile = new File(home); if (!homeFile.exists()) { boolean created = homeFile.mkdirs(); if (created) @@ -169,7 +172,7 @@ public class Daemon { delay = 1; } - update(settings, home); + update(settings, homeFile.getAbsolutePath()); try { synchronized (this) { wait(delay * 60 * 60 * 1000); diff --git a/apps/i2psnark/java/src/org/klomp/snark/I2PSnarkUtil.java b/apps/i2psnark/java/src/org/klomp/snark/I2PSnarkUtil.java index b7e623060c..1a43514ded 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/I2PSnarkUtil.java +++ b/apps/i2psnark/java/src/org/klomp/snark/I2PSnarkUtil.java @@ -73,7 +73,7 @@ public class I2PSnarkUtil { // This is used for both announce replies and .torrent file downloads, // so it must be available even if not connected to I2CP. // so much for multiple instances - _tmpDir = new File("tmp", "i2psnark"); + _tmpDir = new File(ctx.getTempDir(), "i2psnark"); FileUtil.rmdir(_tmpDir, false); _tmpDir.mkdirs(); } diff --git a/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java b/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java index a45bf5161a..79ea62ebc4 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java +++ b/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java @@ -31,7 +31,7 @@ public class SnarkManager implements Snark.CompleteListener { /** map of (canonical) filename to Snark instance (unsynchronized) */ private Map _snarks; private Object _addSnarkLock; - private String _configFile = "i2psnark.config"; + private File _configFile; private Properties _config; private I2PAppContext _context; private Log _log; @@ -51,6 +51,7 @@ public class SnarkManager implements Snark.CompleteListener { public static final String PROP_META_PREFIX = "i2psnark.zmeta."; public static final String PROP_META_BITFIELD_SUFFIX = ".bitfield"; + private static final String CONFIG_FILE = "i2psnark.config"; public static final String PROP_AUTO_START = "i2snark.autoStart"; // oops public static final String DEFAULT_AUTO_START = "false"; public static final String PROP_LINK_PREFIX = "i2psnark.linkPrefix"; @@ -66,6 +67,9 @@ public class SnarkManager implements Snark.CompleteListener { _log = _context.logManager().getLog(SnarkManager.class); _messages = new ArrayList(16); _util = new I2PSnarkUtil(_context); + _configFile = new File(CONFIG_FILE); + if (!_configFile.isAbsolute()) + _configFile = new File(_context.getConfigDir(), CONFIG_FILE); loadConfig(null); } @@ -112,10 +116,11 @@ public class SnarkManager implements Snark.CompleteListener { } private int getStartupDelayMinutes() { return 3; } public File getDataDir() { - String dir = _config.getProperty(PROP_DIR); - if ( (dir == null) || (dir.trim().length() <= 0) ) - dir = "i2psnark"; - return new File(dir); + String dir = _config.getProperty(PROP_DIR, "i2psnark"); + File f = new File(dir); + if (!f.isAbsolute()) + f = new File(_context.getAppDir(), dir); + return f; } /** null to set initial defaults */ @@ -123,8 +128,10 @@ public class SnarkManager implements Snark.CompleteListener { if (_config == null) _config = new Properties(); if (filename != null) { - _configFile = filename; File cfg = new File(filename); + if (!cfg.isAbsolute()) + cfg = new File(_context.getConfigDir(), filename); + _configFile = cfg; if (cfg.exists()) { try { DataHelper.loadProps(_config, cfg); @@ -352,10 +359,10 @@ public class SnarkManager implements Snark.CompleteListener { public void saveConfig() { try { synchronized (_configFile) { - DataHelper.storeProps(_config, new File(_configFile)); + DataHelper.storeProps(_config, _configFile); } } catch (IOException ioe) { - addMessage("Unable to save the config to '" + _configFile + "'"); + addMessage("Unable to save the config to '" + _configFile.getAbsolutePath() + "'"); } } diff --git a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java index 3923484a80..410e804d98 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java +++ b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java @@ -173,6 +173,7 @@ public class I2PSnarkServlet extends HttpServlet { } else if ("Add torrent".equals(action)) { String newFile = req.getParameter("newFile"); String newURL = req.getParameter("newURL"); + // NOTE - newFile currently disabled in HTML form - see below File f = null; if ( (newFile != null) && (newFile.trim().length() > 0) ) f = new File(newFile.trim()); diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnel.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnel.java index 486bcdead5..e4f8453bc7 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnel.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnel.java @@ -372,6 +372,8 @@ public class I2PTunnel implements Logging, EventDispatcher { } privKeyFile = new File(args[2]); + if (!privKeyFile.isAbsolute()) + privKeyFile = new File(_context.getAppDir(), args[2]); if (!privKeyFile.canRead()) { l.log("private key file does not exist"); _log.error(getPrefix() + "Private key file does not exist or is not readable: " + args[2]); @@ -419,6 +421,8 @@ public class I2PTunnel implements Logging, EventDispatcher { } privKeyFile = new File(args[2]); + if (!privKeyFile.isAbsolute()) + privKeyFile = new File(_context.getAppDir(), args[2]); if (!privKeyFile.canRead()) { l.log("private key file does not exist"); _log.error(getPrefix() + "Private key file does not exist or is not readable: " + args[2]); @@ -476,6 +480,8 @@ public class I2PTunnel implements Logging, EventDispatcher { String spoofedHost = args[2]; privKeyFile = new File(args[3]); + if (!privKeyFile.isAbsolute()) + privKeyFile = new File(_context.getAppDir(), args[3]); if (!privKeyFile.canRead()) { l.log("private key file does not exist"); _log.error(getPrefix() + "Private key file does not exist or is not readable: " + args[3]); @@ -870,6 +876,8 @@ public class I2PTunnel implements Logging, EventDispatcher { } File privKeyFile = new File(args[1]); + if (!privKeyFile.isAbsolute()) + privKeyFile = new File(_context.getAppDir(), args[1]); if (!privKeyFile.canRead()) { l.log("private key file does not exist"); _log.error(getPrefix() + "Private key file does not exist or is not readable: " + args[3]); diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelConnectClient.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelConnectClient.java index 59971e8f3d..79270303b0 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelConnectClient.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelConnectClient.java @@ -3,6 +3,7 @@ */ package net.i2p.i2ptunnel; +import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -106,6 +107,8 @@ public class I2PTunnelConnectClient extends I2PTunnelClientBase implements Runna /** used to assign unique IDs to the threads / clients. no logic or functionality */ private static volatile long __clientId = 0; + private static final File _errorDir = new File(I2PAppContext.getGlobalContext().getBaseDir(), "docs"); + /** * @throws IllegalArgumentException if the I2PTunnel does not contain * valid config to contact the router @@ -261,9 +264,9 @@ public class I2PTunnelConnectClient extends I2PTunnelClientBase implements Runna String str; byte[] header; if (usingWWWProxy) - str = FileUtil.readTextFile("docs/dnfp-header.ht", 100, true); + str = FileUtil.readTextFile((new File(_errorDir, "dnfp-header.ht")).getAbsolutePath(), 100, true); else - str = FileUtil.readTextFile("docs/dnfh-header.ht", 100, true); + str = FileUtil.readTextFile((new File(_errorDir, "dnfh-header.ht")).getAbsolutePath(), 100, true); if (str != null) header = str.getBytes(); else @@ -357,9 +360,9 @@ public class I2PTunnelConnectClient extends I2PTunnelClientBase implements Runna String str; byte[] header; if (usingWWWProxy) - str = FileUtil.readTextFile("docs/dnfp-header.ht", 100, true); + str = FileUtil.readTextFile((new File(_errorDir, "dnfp-header.ht")).getAbsolutePath(), 100, true); else - str = FileUtil.readTextFile("docs/dnf-header.ht", 100, true); + str = FileUtil.readTextFile((new File(_errorDir, "dnf-header.ht")).getAbsolutePath(), 100, true); if (str != null) header = str.getBytes(); else diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java index 7e16114adc..cab438991d 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java @@ -4,6 +4,7 @@ package net.i2p.i2ptunnel; import java.io.BufferedReader; +import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; @@ -136,6 +137,9 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable /** used to assign unique IDs to the threads / clients. no logic or functionality */ private static volatile long __clientId = 0; + private static final File _errorDir = new File(I2PAppContext.getGlobalContext().getBaseDir(), "docs"); + + /** * @throws IllegalArgumentException if the I2PTunnel does not contain * valid config to contact the router @@ -372,7 +376,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable { String str; byte[] header; - str = FileUtil.readTextFile("docs/ahelper-conflict-header.ht", 100, true); + str = FileUtil.readTextFile((new File(_errorDir, "ahelper-conflict-header.ht")).getAbsolutePath(), 100, true); if (str != null) header = str.getBytes(); else header = ERR_AHELPER_CONFLICT; @@ -558,13 +562,13 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable byte[] header; boolean showAddrHelper = false; if (usingWWWProxy) - str = FileUtil.readTextFile("docs/dnfp-header.ht", 100, true); + str = FileUtil.readTextFile((new File(_errorDir, "dnfp-header.ht")).getAbsolutePath(), 100, true); else if(ahelper != 0) - str = FileUtil.readTextFile("docs/dnfb-header.ht", 100, true); + str = FileUtil.readTextFile((new File(_errorDir, "dnfb-header.ht")).getAbsolutePath(), 100, true); else if (destination.length() == 60 && destination.endsWith(".b32.i2p")) - str = FileUtil.readTextFile("docs/dnf-header.ht", 100, true); + str = FileUtil.readTextFile((new File(_errorDir, "dnf-header.ht")).getAbsolutePath(), 100, true); else { - str = FileUtil.readTextFile("docs/dnfh-header.ht", 100, true); + str = FileUtil.readTextFile((new File(_errorDir, "dnfh-header.ht")).getAbsolutePath(), 100, true); showAddrHelper = true; } if (str != null) @@ -733,9 +737,9 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable String str; byte[] header; if (usingWWWProxy) - str = FileUtil.readTextFile("docs/dnfp-header.ht", 100, true); + str = FileUtil.readTextFile((new File(_errorDir, "dnfp-header.ht")).getAbsolutePath(), 100, true); else - str = FileUtil.readTextFile("docs/dnf-header.ht", 100, true); + str = FileUtil.readTextFile((new File(_errorDir, "dnf-header.ht")).getAbsolutePath(), 100, true); if (str != null) header = str.getBytes(); else diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/TunnelController.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/TunnelController.java index 1f67783e9b..3dbcfea306 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/TunnelController.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/TunnelController.java @@ -72,6 +72,8 @@ public class TunnelController implements Logging { } File keyFile = new File(getPrivKeyFile()); + if (!keyFile.isAbsolute()) + keyFile = new File(I2PAppContext.getGlobalContext().getAppDir(), getPrivKeyFile()); if (keyFile.exists()) { //log("Not overwriting existing private keys in " + keyFile.getAbsolutePath()); return; diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/TunnelControllerGroup.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/TunnelControllerGroup.java index 16f418be9e..a0b8ea3f7f 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/TunnelControllerGroup.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/TunnelControllerGroup.java @@ -270,9 +270,11 @@ public class TunnelControllerGroup { */ private Properties loadConfig(String configFile) { File cfgFile = new File(configFile); + if (!cfgFile.isAbsolute()) + cfgFile = new File(I2PAppContext.getGlobalContext().getConfigDir(), configFile); if (!cfgFile.exists()) { if (_log.shouldLog(Log.ERROR)) - _log.error("Unable to load the controllers from " + configFile); + _log.error("Unable to load the controllers from " + cfgFile.getAbsolutePath()); return null; } @@ -282,7 +284,7 @@ public class TunnelControllerGroup { return props; } catch (IOException ioe) { if (_log.shouldLog(Log.ERROR)) - _log.error("Error reading the controllers from " + configFile, ioe); + _log.error("Error reading the controllers from " + cfgFile.getAbsolutePath(), ioe); return null; } } diff --git a/apps/routerconsole/java/src/net/i2p/router/web/ConfigServiceHandler.java b/apps/routerconsole/java/src/net/i2p/router/web/ConfigServiceHandler.java index 0dc4d1e62b..195889fad2 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/ConfigServiceHandler.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/ConfigServiceHandler.java @@ -41,7 +41,7 @@ public class ConfigServiceHandler extends FormHandler { } public void run() { try { - Router.killKeys(); + ContextHelper.getContext(null).router().killKeys(); WrapperManager.signalStopped(_exitCode); } catch (Throwable t) { t.printStackTrace(); diff --git a/apps/routerconsole/java/src/net/i2p/router/web/ContentHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/ContentHelper.java index ce29250b9f..721655a512 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/ContentHelper.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/ContentHelper.java @@ -3,7 +3,6 @@ package net.i2p.router.web; import java.io.File; import java.util.Locale; -import net.i2p.router.RouterContext; import net.i2p.util.FileUtil; public class ContentHelper extends HelperBase { @@ -14,6 +13,9 @@ public class ContentHelper extends HelperBase { public ContentHelper() {} + /** + * Caution, use absolute paths only, do not assume files are in CWD + */ public void setPage(String page) { _page = page; } public void setStartAtBeginning(String moo) { _startAtBeginning = Boolean.valueOf(""+moo).booleanValue(); diff --git a/apps/routerconsole/java/src/net/i2p/router/web/LogsHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/LogsHelper.java index e1fce8f3ec..a4896cdb80 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/LogsHelper.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/LogsHelper.java @@ -1,66 +1,70 @@ package net.i2p.router.web; +import java.io.File; import java.util.List; -import net.i2p.router.RouterContext; import net.i2p.util.FileUtil; public class LogsHelper extends HelperBase { public LogsHelper() {} public String getLogs() { - List msgs = _context.logManager().getBuffer().getMostRecentMessages(); - StringBuffer buf = new StringBuffer(16*1024); - buf.append("
\n");
- for (int i = msgs.size(); i > 0; i--) {
- String msg = (String)msgs.get(i - 1);
- msg = msg.replaceAll("<","<");
- buf.append("- ");
- buf.append(msg);
- buf.append("
\n");
- }
- buf.append("
\n");
- for (int i = msgs.size(); i > 0; i--) {
- String msg = (String)msgs.get(i - 1);
- msg = msg.replaceAll("<","<");
- buf.append("- ");
- buf.append(msg);
- buf.append("
\n");
- }
- buf.append("
" + str + ""; } } + /***** unused public String getConnectionLogs() { - List msgs = _context.commSystem().getMostRecentErrorMessages(); + return formatMessages(_context.commSystem().getMostRecentErrorMessages()); + } + ******/ + + private String formatMessages(List msgs) { + boolean colorize = Boolean.valueOf(_context.getProperty("routerconsole.logs.color")).booleanValue(); StringBuffer buf = new StringBuffer(16*1024); buf.append("
\n");
for (int i = msgs.size(); i > 0; i--) {
String msg = (String)msgs.get(i - 1);
buf.append("- ");
- buf.append(msg);
+ if (colorize) {
+ String color;
+ // Homeland Security Advisory System
+ // http://www.dhs.gov/xinfoshare/programs/Copy_of_press_release_0046.shtm
+ // but pink instead of yellow for WARN
+ if (msg.contains("CRIT"))
+ color = "#cc0000";
+ else if (msg.contains("ERROR"))
+ color = "#ff3300";
+ else if (msg.contains("WARN"))
+ color = "#ff00cc";
+ else if (msg.contains("INFO"))
+ color = "#000099";
+ else
+ color = "#006600";
+ buf.append("");
+ buf.append(msg.replaceAll("<", "<").replaceAll(">", ">"));
+ buf.append("");
+ } else {
+ buf.append(msg);
+ }
buf.append("
\n");
}
buf.append("
true
if the signed update file's version is newer
* than the current version, otherwise false
.
*/
- public boolean isUpdatedVersion(String currentVersion, String signedFile) {
+ public boolean isUpdatedVersion(String currentVersion, File signedFile) {
_newVersion = getVersionString(signedFile);
- return needsUpdate(currentVersion, getVersionString(signedFile));
+ return needsUpdate(currentVersion, _newVersion);
}
/**
@@ -413,7 +414,7 @@ D8usM7Dxp5yrDrCYZ5AIijc=
* @return null
if the signature and version were valid and the
* data was moved, and an error String
otherwise.
*/
- public String migrateVerified(String currentVersion, String signedFile, String outputFile) {
+ public String migrateVerified(String currentVersion, File signedFile, File outputFile) {
if (!isUpdatedVersion(currentVersion, signedFile))
return "Downloaded version is not greater than current version";
@@ -606,7 +607,7 @@ D8usM7Dxp5yrDrCYZ5AIijc=
* @return true
if the file has a valid signature, otherwise
* false
.
*/
- public boolean verify(String signedFile) {
+ public boolean verify(File signedFile) {
for (int i = 0; i < _trustedKeys.size(); i++) {
SigningPublicKey signingPublicKey = new SigningPublicKey();
@@ -662,7 +663,7 @@ D8usM7Dxp5yrDrCYZ5AIijc=
}
}
- return verify(signedFile, signingPublicKey);
+ return verify(new File(signedFile), signingPublicKey);
}
/**
@@ -676,7 +677,7 @@ D8usM7Dxp5yrDrCYZ5AIijc=
* @return true
if the file has a valid signature, otherwise
* false
.
*/
- public boolean verify(String signedFile, SigningPublicKey signingPublicKey) {
+ public boolean verify(File signedFile, SigningPublicKey signingPublicKey) {
FileInputStream fileInputStream = null;
try {
diff --git a/core/java/src/net/i2p/data/PrivateKeyFile.java b/core/java/src/net/i2p/data/PrivateKeyFile.java
index b5d68ee411..497733cc4e 100644
--- a/core/java/src/net/i2p/data/PrivateKeyFile.java
+++ b/core/java/src/net/i2p/data/PrivateKeyFile.java
@@ -109,6 +109,10 @@ public class PrivateKeyFile {
this(new File(file), I2PClientFactory.createClient());
}
+ public PrivateKeyFile(File file) {
+ this(file, I2PClientFactory.createClient());
+ }
+
public PrivateKeyFile(File file, I2PClient client) {
this.file = file;
this.client = client;
diff --git a/core/java/src/net/i2p/stat/BufferedStatLog.java b/core/java/src/net/i2p/stat/BufferedStatLog.java
index 7fed2d0904..ca016622fa 100644
--- a/core/java/src/net/i2p/stat/BufferedStatLog.java
+++ b/core/java/src/net/i2p/stat/BufferedStatLog.java
@@ -1,6 +1,7 @@
package net.i2p.stat;
import java.io.BufferedWriter;
+import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.text.SimpleDateFormat;
@@ -109,6 +110,9 @@ public class BufferedStatLog implements StatLog {
String filename = _context.getProperty(StatManager.PROP_STAT_FILE);
if (filename == null)
filename = StatManager.DEFAULT_STAT_FILE;
+ File foo = new File(filename);
+ if (!foo.isAbsolute())
+ filename = (new File(_context.getRouterDir(), filename)).getAbsolutePath();
if ( (_outFile != null) && (_outFile.equals(filename)) ) {
// noop
} else {
diff --git a/core/java/src/net/i2p/util/FileUtil.java b/core/java/src/net/i2p/util/FileUtil.java
index 677c500866..05346ccfe2 100644
--- a/core/java/src/net/i2p/util/FileUtil.java
+++ b/core/java/src/net/i2p/util/FileUtil.java
@@ -18,6 +18,12 @@ import java.util.zip.ZipFile;
/**
* General helper methods for messing with files
*
+ * These are static methods that do NOT convert arguments
+ * to absolute paths for a particular context and directtory.
+ *
+ * Callers should ALWAYS provide absolute paths as arguments,
+ * and should NEVER assume files are in the current working directory.
+ *
*/
public class FileUtil {
/**
diff --git a/core/java/src/net/i2p/util/LogManager.java b/core/java/src/net/i2p/util/LogManager.java
index 1f957515ca..c07445d9b5 100644
--- a/core/java/src/net/i2p/util/LogManager.java
+++ b/core/java/src/net/i2p/util/LogManager.java
@@ -67,8 +67,8 @@ public class LogManager {
/** when was the config file last read (or -1 if never) */
private long _configLastRead;
- /** filename of the config file */
- private String _location;
+ /** the config file */
+ private File _locationFile;
/** Ordered list of LogRecord elements that have not been written out yet */
private List _records;
/** List of explicit overrides of log levels (LogLimit objects) */
@@ -115,11 +115,11 @@ public class LogManager {
_logs = new HashMap(128);
_defaultLimit = Log.ERROR;
_configLastRead = 0;
- _location = context.getProperty(CONFIG_LOCATION_PROP, CONFIG_LOCATION_DEFAULT);
_context = context;
_log = getLog(LogManager.class);
+ String location = context.getProperty(CONFIG_LOCATION_PROP, CONFIG_LOCATION_DEFAULT);
+ setConfig(location);
_consoleBuffer = new LogConsoleBuffer(context);
- loadConfig();
_writer = new LogWriter(this);
Thread t = new I2PThread(_writer);
t.setName("LogWriter");
@@ -196,8 +196,9 @@ public class LogManager {
}
public void setConfig(String filename) {
- _log.debug("Config filename set to " + filename);
- _location = filename;
+ _locationFile = new File(filename);
+ if (!_locationFile.isAbsolute())
+ _locationFile = new File(_context.getConfigDir(), filename);
loadConfig();
}
@@ -232,20 +233,12 @@ public class LogManager {
loadConfig();
}
- ///
- ///
-
- //
- //
- //
-
private void loadConfig() {
- File cfgFile = new File(_location);
+ File cfgFile = _locationFile;
if (!cfgFile.exists()) {
if (!_alreadyNoticedMissingConfig) {
if (_log.shouldLog(Log.WARN))
- _log.warn("Log file " + _location + " does not exist");
- //System.err.println("Log file " + _location + " does not exist");
+ _log.warn("Log file " + _locationFile.getAbsolutePath() + " does not exist");
_alreadyNoticedMissingConfig = true;
}
parseConfig(new Properties());
@@ -262,9 +255,6 @@ public class LogManager {
return;
}
- if (_log.shouldLog(Log.DEBUG))
- _log.debug("Loading config from " + _location);
-
Properties p = new Properties();
FileInputStream fis = null;
try {
@@ -272,7 +262,7 @@ public class LogManager {
p.load(fis);
_configLastRead = _context.clock().now();
} catch (IOException ioe) {
- System.err.println("Error loading logger config from " + new File(_location).getAbsolutePath());
+ System.err.println("Error loading logger config from " + cfgFile.getAbsolutePath());
} finally {
if (fis != null) try {
fis.close();
@@ -540,7 +530,7 @@ public class LogManager {
String config = createConfig();
FileOutputStream fos = null;
try {
- fos = new FileOutputStream(_location);
+ fos = new FileOutputStream(_locationFile);
fos.write(config.getBytes());
return true;
} catch (IOException ioe) {
diff --git a/core/java/src/net/i2p/util/LogWriter.java b/core/java/src/net/i2p/util/LogWriter.java
index 29fcff7ccd..c9f2cb7562 100644
--- a/core/java/src/net/i2p/util/LogWriter.java
+++ b/core/java/src/net/i2p/util/LogWriter.java
@@ -15,6 +15,8 @@ import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
+import net.i2p.I2PAppContext;
+
/**
* Log writer thread that pulls log records from the LogManager, writes them to
* the current logfile, and rotates the logs as necessary. This also periodically
@@ -22,6 +24,7 @@ import java.util.List;
*
*/
class LogWriter implements Runnable {
+ /** every 10 seconds? why? Just have the gui force a reread after a change?? */
private final static long CONFIG_READ_ITERVAL = 10 * 1000;
private long _lastReadConfig = 0;
private long _numBytesInCurrentFile = 0;
@@ -38,6 +41,7 @@ class LogWriter implements Runnable {
public LogWriter(LogManager manager) {
_manager = manager;
+ _lastReadConfig = Clock.getInstance().now();
}
public void stopWriting() {
@@ -168,15 +172,21 @@ class LogWriter implements Runnable {
*
*/
private File getNextFile(String pattern) {
- File f = null;
+ File f = new File(pattern);
+ File base = null;
+ if (!f.isAbsolute())
+ base = I2PAppContext.getGlobalContext().getLogDir();
if ( (pattern.indexOf('#') < 0) && (pattern.indexOf('@') <= 0) ) {
- return new File(pattern);
+ if (base != null)
+ return new File(base, pattern);
+ else
+ return f;
}
int max = _manager.getRotationLimit();
if (_rotationNum == -1) {
- return getFirstFile(pattern, max);
+ return getFirstFile(base, pattern, max);
}
// we're in rotation, just go to the next
@@ -190,9 +200,13 @@ class LogWriter implements Runnable {
* Retrieve the first file, updating the rotation number accordingly
*
*/
- private File getFirstFile(String pattern, int max) {
+ private File getFirstFile(File base, String pattern, int max) {
for (int i = 0; i < max; i++) {
- File f = new File(replace(pattern, i));
+ File f;
+ if (base != null)
+ f = new File(base, replace(pattern, i));
+ else
+ f = new File(replace(pattern, i));
if (!f.exists()) {
_rotationNum = i;
return f;
@@ -202,7 +216,11 @@ class LogWriter implements Runnable {
// all exist, pick the oldest to replace
File oldest = null;
for (int i = 0; i < max; i++) {
- File f = new File(replace(pattern, i));
+ File f;
+ if (base != null)
+ f = new File(base, replace(pattern, i));
+ else
+ f = new File(replace(pattern, i));
if (oldest == null) {
oldest = f;
} else {
diff --git a/core/java/src/net/i2p/util/NativeBigInteger.java b/core/java/src/net/i2p/util/NativeBigInteger.java
index a6d7e97925..bafaa5e5c9 100644
--- a/core/java/src/net/i2p/util/NativeBigInteger.java
+++ b/core/java/src/net/i2p/util/NativeBigInteger.java
@@ -540,9 +540,10 @@ public class NativeBigInteger extends BigInteger {
FileOutputStream fos = null;
try {
InputStream libStream = resource.openStream();
- outFile = new File(_libPrefix + "jbigi" + _libSuffix);
+ outFile = new File(I2PAppContext.getGlobalContext().getBaseDir(), _libPrefix + "jbigi" + _libSuffix);
fos = new FileOutputStream(outFile);
- byte buf[] = new byte[4096*1024];
+ // wtf this was 4096*1024 which is really excessive for a roughly 50KB file
+ byte buf[] = new byte[4096];
while (true) {
int read = libStream.read(buf);
if (read < 0) break;
diff --git a/core/java/src/net/i2p/util/RandomSource.java b/core/java/src/net/i2p/util/RandomSource.java
index 550b37b8d2..c6ac80a65c 100644
--- a/core/java/src/net/i2p/util/RandomSource.java
+++ b/core/java/src/net/i2p/util/RandomSource.java
@@ -142,7 +142,7 @@ public class RandomSource extends SecureRandom implements EntropyHarvester {
private static final String SEEDFILE = "prngseed.rnd";
public static final void writeSeed(byte buf[]) {
- File f = new File(SEEDFILE);
+ File f = new File(I2PAppContext.getGlobalContext().getConfigDir(), SEEDFILE);
FileOutputStream fos = null;
try {
fos = new FileOutputStream(f);
@@ -164,7 +164,7 @@ public class RandomSource extends SecureRandom implements EntropyHarvester {
}
private static final boolean seedFromFile(String filename, byte buf[]) {
- File f = new File(filename);
+ File f = new File(I2PAppContext.getGlobalContext().getConfigDir(), filename);
if (f.exists()) {
FileInputStream fis = null;
try {
diff --git a/core/java/src/net/i2p/util/WorkingDir.java b/core/java/src/net/i2p/util/WorkingDir.java
new file mode 100644
index 0000000000..4e47f6458c
--- /dev/null
+++ b/core/java/src/net/i2p/util/WorkingDir.java
@@ -0,0 +1,481 @@
+package net.i2p.util;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.util.Properties;
+
+import net.i2p.data.DataHelper;
+
+/**
+ * Get a working directory for i2p.
+ *
+ * For the location, first try the system property i2p.dir.config
+ * Next try $HOME/.i2p on linux or %APPDATA%\I2P on Windows.
+ *
+ * If the dir exists, return it.
+ * Otherwise, attempt to create it, and copy files from the base directory.
+ * To successfully copy, the base install dir must be the system property i2p.dir.base
+ * or else must be in $CWD.
+ *
+ * If I2P was run from the install directory in the past,
+ * and migrateOldData = true, copy the
+ * necessary data files (except i2psnark/) over to the new working directory.
+ *
+ * Otherwise, just copy over a limited number of files over.
+ *
+ * Do not ever copy or move the old i2psnark/ directory, as if the
+ * old and new locations are on different file systems, this could
+ * be quite slow.
+ *
+ * Modify some files while copying, see methods below.
+ *
+ * After migration, the router will run using the new directory.
+ * The wrapper, however, must be stopped and restarted from the new script - until then,
+ * it will continue to write to wrapper.log* in the old directory.
+ *
+ * @param whether to copy all data over from an existing install
+ */
+public class WorkingDir {
+
+ private final static String PROP_BASE_DIR = "i2p.dir.base";
+ private final static String PROP_WORKING_DIR = "i2p.dir.config";
+ private final static String WORKING_DIR_DEFAULT_WINDOWS = "I2P";
+ private final static String WORKING_DIR_DEFAULT = ".i2p";
+
+ /**
+ * Only call this once on router invocation.
+ * Caller should store the return value for future reference.
+ */
+ public static String getWorkingDir(boolean migrateOldData) {
+ String dir = System.getProperty(PROP_WORKING_DIR);
+ boolean isWindows = System.getProperty("os.name").startsWith("Win");
+ File dirf = null;
+ if (dir != null) {
+ dirf = new File(dir);
+ } else {
+ String home = System.getProperty("user.home");
+ if (isWindows) {
+ String appdata = System.getenv("APPDATA");
+ if (appdata != null)
+ home = appdata;
+ dirf = new File(home, WORKING_DIR_DEFAULT_WINDOWS);
+ } else {
+ dirf = new File(home, WORKING_DIR_DEFAULT);
+ }
+ }
+ // where we are now
+ String cwd = System.getProperty(PROP_BASE_DIR);
+ if (cwd == null)
+ cwd = System.getProperty("user.dir");
+ // where we want to go
+ String rv = dirf.getAbsolutePath();
+ if (dirf.exists()) {
+ if (dirf.isDirectory())
+ return rv; // all is good, we found the user directory
+ System.err.println("Wanted to use " + rv + " for a working directory but it is not a directory");
+ return cwd;
+ }
+ if (!dirf.mkdir()) {
+ System.err.println("Wanted to use " + rv + " for a working directory but could not create it");
+ return cwd;
+ }
+
+ // Check for a hosts.txt file, if it exists then I2P is there
+ File oldDirf = new File(cwd);
+ File test = new File(oldDirf, "hosts.txt");
+ if (!test.exists()) {
+ System.err.println("ERROR - Cannot find I2P installation in " + cwd);
+ return cwd;
+ }
+
+ // Check for a router.keys file, if it exists it's an old install,
+ // and only migrate the data files if told to do so
+ test = new File(oldDirf, "router.keys");
+ boolean oldInstall = test.exists();
+ migrateOldData &= oldInstall;
+
+ // Do the copying
+ if (migrateOldData)
+ System.err.println("Migrating data files to new user directory " + rv);
+ else
+ System.err.println("Setting up new user directory " + rv);
+ boolean success = migrate(MIGRATE_BASE, oldDirf, dirf);
+ // this one must be after MIGRATE_BASE
+ success &= migrateJettyXml(oldDirf, dirf);
+ success &= migrateWrapperConfig(oldDirf, dirf);
+ if (migrateOldData) {
+ success &= migrate(MIGRATE_DATA, oldDirf, dirf);
+ success &= migrateI2PTunnelKeys(oldDirf, dirf);
+ success &= migrateSnark(oldDirf, dirf);
+ // new installs will have updated scripts left in the install dir
+ // don't bother migrating runplain.sh or i2prouter.bat
+ if (!isWindows)
+ success &= migrateI2prouter(oldDirf, dirf);
+ } else if (!oldInstall) {
+ // copy the default i2psnark.config over
+ success &= migrate("i2psnark.config", oldDirf, dirf);
+ }
+
+ // Report success or failure
+ if (success) {
+ System.err.println("Successfully copied data files to new user directory " + rv);
+ if (migrateOldData) {
+ System.err.println("Libraries and other files remain in the old directory " + cwd + ", do not remove them.");
+ System.err.println("You should manually move any non-standard files, such as additional eepsite directories and key files");
+ System.err.println("After verifying that all is working, you may delete the following data files and directories in " +
+ cwd + ": " + MIGRATE_DATA.replace(',', ' ') + " i2psnark.config tmp work");
+ if (System.getProperty("wrapper.version") != null)
+ System.err.println("Note that until you shutdown your router completely and restart, the wrapper will continue" +
+ " to log to the old wrapper logs in " + cwd);
+ if (!isWindows)
+ System.err.println("From now on, you should now use the i2prouter" +
+ " script in the " + rv + " directory to start i2p." +
+ " You may copy or move this script elsewhere, you need not run it from that directory.");
+ }
+ return rv;
+ } else {
+ System.err.println("FAILED copy of some or all data files to new directory " + rv);
+ System.err.println("Check logs for details");
+ System.err.println("Continung to use data files in old directory " + cwd);
+ return cwd;
+ }
+ }
+
+ /**
+ * files and directories from the base install to copy over
+ * None of these should be included in i2pupdate.zip
+ *
+ * The user should not delete these in the old location, leave them as templates for new users
+ */
+ private static final String MIGRATE_BASE =
+ // base install - dirs
+ // We don't currently have a default addressbook/ in the base distribution,
+ // but distros might put one in
+ "addressbook,eepsite," +
+ // base install - files
+ // We don't currently have a default router.config or logger.config in the base distribution,
+ // but distros might put one in
+ "blocklist.txt,clients.config,hosts.txt,i2ptunnel.config,jetty-i2psnark.xml," +
+ "logger.config,router.config,systray.config";
+
+ /**
+ * files and directories from an old single-directory installation to copy over - NOT including snark
+ * None of these should be included in i2pupdate.zip
+ *
+ * The user can be advised to delete these from the old location
+ */
+ private static final String MIGRATE_DATA =
+ // post install - dirs
+ // not required to copy - tmp/, work/
+ // addressbook included in MIGRATE_BASE above
+ "keyBackup,logs,netDb,peerProfiles," +
+ // post install - files
+ // not required to copy - prngseed.rnd
+ // logger.config and router.config included in MIGRATE_BASE above
+ "bob.config,privatehosts.txt,router.info,router.keys," +
+ "sam.keys,susimail.config,userhosts.txt,webapps.config," +
+ "wrapper.log,wrapper.log.1,wrapper.log.2";
+
+ private static boolean migrate(String list, File olddir, File todir) {
+ boolean rv = true;
+ String files[] = list.split(",");
+ for (int i = 0; i < files.length; i++) {
+ File from = new File(olddir, files[i]);
+ if (!copy(from, todir)) {
+ System.err.println("Error copying " + from.getAbsolutePath());
+ rv = false;
+ }
+ }
+ return rv;
+ }
+
+ /**
+ * Copy over the i2psnark.config file with modifications
+ */
+ private static boolean migrateSnark(File olddir, File todir) {
+ boolean rv = true;
+ File oldSnark = new File(olddir, "i2psnark");
+ File newSnark = new File(todir, "i2psnark");
+ File oldSnarkConfig = new File(olddir, "i2psnark.config");
+ File newSnarkConfig = new File(todir, "i2psnark.config");
+ boolean hasData = oldSnark.exists();
+ if (hasData) {
+ File children[] = oldSnark.listFiles();
+ hasData = children != null && children.length > 0;
+ }
+ if (oldSnarkConfig.exists()) {
+ if (hasData) {
+ // edit the snark config file to point to the old location, we aren't moving the data
+ try {
+ Properties props = new Properties();
+ DataHelper.loadProps(props, oldSnarkConfig);
+ String dir = props.getProperty("i2psnark.dir");
+ if (dir == null)
+ dir = "i2psnark";
+ // change relative to absolute path
+ File f = new File(dir);
+ props.setProperty("i2psnark.dir", f.getAbsolutePath());
+ DataHelper.storeProps(props, newSnarkConfig);
+ System.err.println("Copied i2psnark.config with modifications");
+ } catch (IOException ioe) {
+ System.err.println("FAILED copy i2psnark.config");
+ rv = false;
+ }
+ } else {
+ // copy the i2psnark config file over
+ copy(newSnarkConfig, todir);
+ System.err.println("Copied i2psnark.config");
+ }
+ } else {
+ if (hasData) {
+ // data but no previous config file (unlikely) - make new config file
+ try {
+ Properties props = new Properties();
+ File f = new File("i2psnark");
+ props.setProperty("i2psnark.dir", f.getAbsolutePath());
+ DataHelper.storeProps(props, newSnarkConfig);
+ } catch (IOException ioe) {
+ // ignore
+ }
+ } // else no config and no data
+ }
+ if (hasData) {
+ /*************
+ // crude attempt to detect same filesystem
+ if ((oldSnark.getAbsolutePath().startsWith("/home/") && newSnark.getAbsolutePath().startsWith("/home/")) ||
+ (System.getProperty("os.name").toLowerCase.indexOf("windows") >= 0 &&
+ oldSnark.getAbsolutePath().substring(0,1).equals(newSnark.getAbsolutePath().substring(0,1) &&
+ oldSnark.getAbsolutePath().substring(1,2).equals(":\\") &&
+ newSnark.getAbsolutePath().substring(1,2).equals(":\\"))) {
+ // OK, apparently in same file system
+ // move everything
+ }
+ **************/
+ System.err.println("NOT moving the i2psnark data directory " + oldSnark.getAbsolutePath() +
+ " to the new directory " + newSnark.getAbsolutePath() +
+ ". You may move the directory contents manually WHILE I2P IS NOT RUNNING," +
+ " and edit the file " + newSnarkConfig.getAbsolutePath() +
+ " to configure i2psnark to use a different location by editing the i2psnark.dir configuration to be" +
+ " i2psnark.dir=" + oldSnark.getAbsolutePath() +
+ " and restart, or you may leave the i2psnark directory in its old location.");
+ }
+ return true;
+ }
+
+ /**
+ * Copy over the i2prouter file with modifications
+ * The resulting script can be run from any location.
+ */
+ private static boolean migrateI2prouter(File olddir, File todir) {
+ File oldFile = new File(olddir, "i2prouter");
+ File newFile = new File(todir, "i2prouter");
+ FileInputStream in = null;
+ PrintWriter out = null;
+ try {
+ in = new FileInputStream(oldFile);
+ out = new PrintWriter(new BufferedWriter(new FileWriter(newFile)));
+ boolean firstTime = true;
+ String s = null;
+ while ((s = DataHelper.readLine(in)) != null) {
+ if (s.equals("WRAPPER_CMD=\"./i2psvc\"")) {
+ // i2psvc in the old location
+ File f = new File("i2psvc");
+ s = "WRAPPER_CMD=\"" + f.getAbsolutePath() + "\"";
+ } else if(s.equals("WRAPPER_CONF=\"wrapper.config\"")) {
+ // wrapper.config the new location
+ File f = new File(todir, "wrapper.config");
+ s = "WRAPPER_CONF=\"" + f.getAbsolutePath() + "\"";
+ } else if(s.equals("PIDDIR=\".\"")) {
+ // i2p.pid in the new location
+ s = "PIDDIR=\"" + todir.getAbsolutePath() + "\"";
+ }
+ out.println(s);
+ if (firstTime) {
+ // first line was #!/bin/sh, so had to wait until now
+ out.println("# Modified by I2P User dir migration script");
+ firstTime = false;
+ }
+ }
+ System.err.println("Copied i2prouter with modifications");
+ return true;
+ } catch (IOException ioe) {
+ if (in != null) {
+ System.err.println("FAILED copy i2prouter");
+ return false;
+ }
+ return true;
+ } finally {
+ if (in != null) try { in.close(); } catch (IOException ioe) {}
+ if (out != null) out.close();
+ }
+ }
+
+ /**
+ * Copy over the wrapper.config file with modifications
+ */
+ private static boolean migrateWrapperConfig(File olddir, File todir) {
+ File oldFile = new File(olddir, "wrapper.config");
+ File newFile = new File(todir, "wrapper.config");
+ FileInputStream in = null;
+ PrintWriter out = null;
+ try {
+ in = new FileInputStream(oldFile);
+ out = new PrintWriter(new BufferedWriter(new FileWriter(newFile)));
+ out.println("# Modified by I2P User dir migration script");
+ String s = null;
+ // Don't use replaceFirst because backslashes in the replacement string leads to havoc
+ // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4689750
+ // "Note that backslashes and dollar signs in the replacement string may cause the results
+ // to be different than if it were being treated as a literal replacement string.
+ // Dollar signs may be treated as references to captured subsequences as described above,
+ // and backslashes are used to escape literal characters in the replacement string."
+ while ((s = DataHelper.readLine(in)) != null) {
+ if (s.startsWith("wrapper.java.classpath.")) {
+ // libraries in the old location
+ s = s.replace("=lib/", '=' + olddir.getAbsolutePath() + File.separatorChar + "lib" + File.separatorChar);
+ } else if (s.startsWith("wrapper.java.library.path.")) {
+ // libraries in the old location
+ if (s.contains("=."))
+ s = s.replace("=.", '=' + olddir.getAbsolutePath());
+ else if (s.contains("=lib"))
+ s = s.replace("=lib", '=' + olddir.getAbsolutePath() + File.separatorChar + "lib");
+ } else if (s.startsWith("wrapper.logfile=wrapper.log")) {
+ // wrapper logs in the new location
+ s = s.replace("=", '=' + todir.getAbsolutePath() + File.separatorChar);
+ } else if (s.startsWith("wrapper.pidfile=i2p.pid")) {
+ // i2p.pid in the new location
+ s = s.replace("=", '=' + todir.getAbsolutePath() + File.separatorChar);
+ }
+ out.println(s);
+ }
+ System.err.println("Copied wrapper.config with modifications");
+ return true;
+ } catch (IOException ioe) {
+ if (in != null) {
+ System.err.println("FAILED copy wrapper.config");
+ return false;
+ }
+ return false;
+ } finally {
+ if (in != null) try { in.close(); } catch (IOException ioe) {}
+ if (out != null) out.close();
+ }
+ }
+
+ /**
+ * Copy over the jetty.xml file with modifications
+ * It was already copied over once in migrate(), throw that out and
+ * do it again with modifications.
+ */
+ private static boolean migrateJettyXml(File olddir, File todir) {
+ File eepsite1 = new File(olddir, "eepsite");
+ File oldFile = new File(eepsite1, "jetty.xml");
+ File eepsite2 = new File(todir, "eepsite");
+ File newFile = new File(eepsite2, "jetty.xml");
+ FileInputStream in = null;
+ PrintWriter out = null;
+ try {
+ in = new FileInputStream(oldFile);
+ out = new PrintWriter(new BufferedWriter(new FileWriter(newFile)));
+ String s = null;
+ while ((s = DataHelper.readLine(in)) != null) {
+ if (s.indexOf("./eepsite/") >= 0) {
+ s = s.replace("./eepsite/", todir.getAbsolutePath() + File.separatorChar + "eepsite" + File.separatorChar);
+ }
+ out.println(s);
+ }
+ out.println("");
+ System.err.println("Copied jetty.xml with modifications");
+ return true;
+ } catch (IOException ioe) {
+ if (in != null) {
+ System.err.println("FAILED copy jetty.xml");
+ return false;
+ }
+ return false;
+ } finally {
+ if (in != null) try { in.close(); } catch (IOException ioe) {}
+ if (out != null) out.close();
+ }
+ }
+
+ /**
+ * Relatively recent default i2ptunnel key file name
+ */
+ private static boolean migrateI2PTunnelKeys(File olddir, File todir) {
+ for (int i = 0; i < 100; i++) {
+ copy(new File(olddir, "i2ptunnel" + i + "-privKeys.dat"), todir);
+ }
+ return true;
+ }
+
+ /**
+ * Recursive copy a file or dir to a dir
+ *
+ * @param src file or directory, need not exist
+ * @param target the directory to copy to, will be created if it doesn't exist
+ * @return true for success OR if src does not exist
+ */
+ public static final boolean copy(File src, File targetDir) {
+ if (!src.exists())
+ return true;
+ if (!targetDir.exists()) {
+ if (!targetDir.mkdir()) {
+ System.err.println("FAILED copy " + src.getPath());
+ return false;
+ }
+ }
+ File targetFile = new File(targetDir, src.getName());
+ if (!src.isDirectory())
+ return copyFile(src, targetFile);
+ File children[] = src.listFiles();
+ if (children == null) {
+ System.err.println("FAILED copy " + src.getPath());
+ return false;
+ }
+ boolean rv = true;
+ for (int i = 0; i < children.length; i++) {
+ rv &= copy(children[i], targetFile);
+ }
+ return rv;
+ }
+
+ /**
+ * @param src not a directory, must exist
+ * @param dest not a directory, will be overwritten if existing
+ * @@reurn true if it was copied successfully
+ */
+ public static boolean copyFile(File src, File dst) {
+ if (!src.exists()) return false;
+ boolean rv = true;
+
+ byte buf[] = new byte[4096];
+ FileInputStream in = null;
+ FileOutputStream out = null;
+ try {
+ in = new FileInputStream(src);
+ out = new FileOutputStream(dst);
+
+ int read = 0;
+ while ( (read = in.read(buf)) != -1)
+ out.write(buf, 0, read);
+
+ System.err.println("Copied " + src.getPath());
+ } catch (IOException ioe) {
+ System.err.println("FAILED copy " + src.getPath());
+ rv = false;
+ } finally {
+ if (in != null) try { in.close(); } catch (IOException ioe) {}
+ if (out != null) try { out.close(); } catch (IOException ioe) {}
+ }
+ if (rv)
+ dst.setLastModified(src.lastModified());
+ return rv;
+ }
+}
diff --git a/router/java/src/net/i2p/router/Blocklist.java b/router/java/src/net/i2p/router/Blocklist.java
index 7546ac4a71..6195d6a769 100644
--- a/router/java/src/net/i2p/router/Blocklist.java
+++ b/router/java/src/net/i2p/router/Blocklist.java
@@ -166,6 +166,8 @@ public class Blocklist {
*/
private void readBlocklistFile(String file) {
File BLFile = new File(file);
+ if (!BLFile.isAbsolute())
+ BLFile = new File(_context.getConfigDir(), file);
if (BLFile == null || (!BLFile.exists()) || BLFile.length() <= 0) {
if (_log.shouldLog(Log.WARN))
_log.warn("Blocklist file not found: " + file);
@@ -701,6 +703,8 @@ public class Blocklist {
private synchronized void shitlistForever(Hash peer) {
String file = _context.getProperty(PROP_BLOCKLIST_FILE, BLOCKLIST_FILE_DEFAULT);
File BLFile = new File(file);
+ if (!BLFile.isAbsolute())
+ BLFile = new File(_context.getConfigDir(), file);
if (BLFile == null || (!BLFile.exists()) || BLFile.length() <= 0) {
if (_log.shouldLog(Log.ERROR))
_log.error("Blocklist file not found: " + file);
diff --git a/router/java/src/net/i2p/router/KeyManager.java b/router/java/src/net/i2p/router/KeyManager.java
index 9fc62a70f2..711759a408 100644
--- a/router/java/src/net/i2p/router/KeyManager.java
+++ b/router/java/src/net/i2p/router/KeyManager.java
@@ -147,10 +147,8 @@ public class KeyManager {
super(KeyManager.this._context);
}
public void runJob() {
- String keyDir = getContext().getProperty(PROP_KEYDIR);
- if (keyDir == null)
- keyDir = DEFAULT_KEYDIR;
- File dir = new File(keyDir);
+ String keyDir = getContext().getProperty(PROP_KEYDIR, DEFAULT_KEYDIR);
+ File dir = new File(getContext().getRouterDir(), keyDir);
if (!dir.exists())
dir.mkdirs();
if (dir.exists() && dir.isDirectory() && dir.canRead() && dir.canWrite()) {
diff --git a/router/java/src/net/i2p/router/Router.java b/router/java/src/net/i2p/router/Router.java
index 1e8e905528..35518feda3 100644
--- a/router/java/src/net/i2p/router/Router.java
+++ b/router/java/src/net/i2p/router/Router.java
@@ -44,6 +44,7 @@ import net.i2p.util.I2PThread;
import net.i2p.util.Log;
import net.i2p.util.SimpleScheduler;
import net.i2p.util.SimpleTimer;
+import net.i2p.util.WorkingDir;
/**
* Main driver for the router.
@@ -53,6 +54,7 @@ public class Router {
private Log _log;
private RouterContext _context;
private final Properties _config;
+ /** full path */
private String _configFilename;
private RouterInfo _routerInfo;
private long _started;
@@ -104,14 +106,6 @@ public class Router {
public Router(Properties envProps) { this(null, envProps); }
public Router(String configFilename) { this(configFilename, null); }
public Router(String configFilename, Properties envProps) {
- if (!beginMarkingLiveliness(envProps)) {
- System.err.println("ERROR: There appears to be another router already running!");
- System.err.println(" Please make sure to shut down old instances before starting up");
- System.err.println(" a new one. If you are positive that no other instance is running,");
- System.err.println(" please delete the file " + getPingFile(envProps));
- System.exit(-1);
- }
-
_gracefulExitCode = -1;
_config = new Properties();
@@ -125,7 +119,35 @@ public class Router {
_configFilename = configFilename;
}
+ // we need the user directory figured out by now, so figure it out here rather than
+ // in the RouterContext() constructor.
+ //
+ // Fixme read config file before migration? or before? or both?
+ //
+ // Then add it to envProps (but not _config, we don't want it in the router.config file)
+ // where it will then be available to all via _context.dir()
+ //
+ // This call also migrates all files to the new working directory,
+ // including router.config
+ //
+
+ // Do we copy all the data files to the new directory? default false
+ String migrate = System.getProperty("i2p.dir.migrate");
+ boolean migrateFiles = Boolean.valueOf(migrate).booleanValue();
+ String userDir = WorkingDir.getWorkingDir(migrateFiles);
+
+ // Use the router.config file specified in the router.configLocation property
+ // (default "router.config"),
+ // if it is an abolute path, otherwise look in the userDir returned by getWorkingDir
+ // replace relative path with absolute
+ File cf = new File(_configFilename);
+ if (!cf.isAbsolute()) {
+ cf = new File(userDir, _configFilename);
+ _configFilename = cf.getAbsolutePath();
+ }
+
readConfig();
+
if (envProps == null) {
envProps = _config;
} else {
@@ -135,11 +157,42 @@ public class Router {
envProps.setProperty(k, v);
}
}
+
// This doesn't work, guess it has to be in the static block above?
// if (Boolean.valueOf(envProps.getProperty("router.disableIPv6")).booleanValue())
// System.setProperty("java.net.preferIPv4Stack", "true");
+ if (envProps.getProperty("i2p.dir.config") == null)
+ envProps.setProperty("i2p.dir.config", userDir);
+
+ // The important thing that happens here is the directory paths are set and created
+ // i2p.dir.router defaults to i2p.dir.config
+ // i2p.dir.app defaults to i2p.dir.router
+ // i2p.dir.log defaults to i2p.dir.router
+ // i2p.dir.pid defaults to i2p.dir.router
+ // i2p.dir.base defaults to user.dir == $CWD
_context = new RouterContext(this, envProps);
+
+ // This is here so that we can get the directory location from the context
+ // for the ping file
+ if (!beginMarkingLiveliness()) {
+ System.err.println("ERROR: There appears to be another router already running!");
+ System.err.println(" Please make sure to shut down old instances before starting up");
+ System.err.println(" a new one. If you are positive that no other instance is running,");
+ System.err.println(" please delete the file " + getPingFile().getAbsolutePath());
+ System.exit(-1);
+ }
+
+ // This is here so that we can get the directory location from the context
+ // for the zip file and the base location to unzip to.
+ // If it does an update, it never returns.
+ // I guess it's better to have the other-router check above this, we don't want to
+ // overwrite an existing running router's jar files. Other than ours.
+ installUpdates();
+
+ // NOW we start all the activity
+ _context.initAll();
+
_routerInfo = null;
_higherVersionSeen = false;
_log = _context.logManager().getLog(Router.class);
@@ -245,6 +298,7 @@ public class Router {
_context.keyManager().startup();
+ // why are we reading this again, it's read in the constructor
readConfig();
setupHandlers();
@@ -285,6 +339,7 @@ public class Router {
}
}
+ /** this does not use ctx.getConfigDir(), must provide a full path in filename */
private static Properties getConfig(RouterContext ctx, String filename) {
Log log = null;
if (ctx != null) {
@@ -456,11 +511,11 @@ public class Router {
};
static final String IDENTLOG = "identlog.txt";
- public static void killKeys() {
+ public void killKeys() {
new Exception("Clearing identity files").printStackTrace();
int remCount = 0;
for (int i = 0; i < _rebuildFiles.length; i++) {
- File f = new File(_rebuildFiles[i]);
+ File f = new File(_context.getRouterDir(),_rebuildFiles[i]);
if (f.exists()) {
boolean removed = f.delete();
if (removed) {
@@ -474,7 +529,7 @@ public class Router {
if (remCount > 0) {
FileOutputStream log = null;
try {
- log = new FileOutputStream(IDENTLOG, true);
+ log = new FileOutputStream(new File(_context.getRouterDir(), IDENTLOG), true);
log.write((new Date() + ": Old router identity keys cleared\n").getBytes());
} catch (IOException ioe) {
// ignore
@@ -814,8 +869,9 @@ public class Router {
try { _context.messageValidator().shutdown(); } catch (Throwable t) { _log.log(Log.CRIT, "Error shutting down the message validator", t); }
try { _context.inNetMessagePool().shutdown(); } catch (Throwable t) { _log.log(Log.CRIT, "Error shutting down the inbound net pool", t); }
//try { _sessionKeyPersistenceHelper.shutdown(); } catch (Throwable t) { _log.log(Log.CRIT, "Error shutting down the session key manager", t); }
+ _context.deleteTempDir();
RouterContext.listContexts().remove(_context);
- dumpStats();
+ //dumpStats();
finalShutdown(exitCode);
}
@@ -833,7 +889,7 @@ public class Router {
killKeys();
}
- File f = new File(getPingFile());
+ File f = getPingFile();
f.delete();
if (_killVMOnEnd) {
try { Thread.sleep(1000); } catch (InterruptedException ie) {}
@@ -1003,8 +1059,9 @@ public class Router {
public static void main(String args[]) {
System.out.println("Starting I2P " + RouterVersion.FULL_VERSION);
- installUpdates();
- verifyWrapperConfig();
+ // installUpdates() moved to constructor so we can get file locations from the context
+ // installUpdates();
+ //verifyWrapperConfig();
Router r = new Router();
if ( (args != null) && (args.length == 1) && ("rebuild".equals(args[0])) ) {
r.rebuildNewIdentity();
@@ -1015,11 +1072,30 @@ public class Router {
public static final String UPDATE_FILE = "i2pupdate.zip";
- private static void installUpdates() {
- File updateFile = new File(UPDATE_FILE);
- if (updateFile.exists()) {
+ /**
+ * Unzip update file found in the router dir OR base dir, to the base dir
+ *
+ * If we can't write to the base dir, complain.
+ */
+ private void installUpdates() {
+ File updateFile = new File(_context.getRouterDir(), UPDATE_FILE);
+ boolean exists = updateFile.exists();
+ if (!exists) {
+ updateFile = new File(_context.getBaseDir(), UPDATE_FILE);
+ exists = updateFile.exists();
+ }
+ if (exists) {
+ File test = new File(_context.getBaseDir(), "history.txt");
+ if ((!test.canWrite()) || (!_context.getBaseDir().canWrite())) {
+ String msg = "ERROR: No write permissions on " + _context.getBaseDir() +
+ " to extract software update file";
+ System.out.println(msg);
+ _log.log(Log.CRIT, msg);
+ // carry on
+ return;
+ }
System.out.println("INFO: Update file exists [" + UPDATE_FILE + "] - installing");
- boolean ok = FileUtil.extractZip(updateFile, new File("."));
+ boolean ok = FileUtil.extractZip(updateFile, _context.getBaseDir());
if (ok)
System.out.println("INFO: Update installed");
else
@@ -1037,6 +1113,7 @@ public class Router {
}
}
+/*******
private static void verifyWrapperConfig() {
File cfgUpdated = new File("wrapper.config.updated");
if (cfgUpdated.exists()) {
@@ -1046,15 +1123,22 @@ public class Router {
System.exit(EXIT_HARD);
}
}
+*******/
+/*
private static String getPingFile(Properties envProps) {
if (envProps != null)
return envProps.getProperty("router.pingFile", "router.ping");
else
return "router.ping";
}
- private String getPingFile() {
- return _context.getProperty("router.pingFile", "router.ping");
+*/
+ private File getPingFile() {
+ String s = _context.getProperty("router.pingFile", "router.ping");
+ File f = new File(s);
+ if (!f.isAbsolute())
+ f = new File(_context.getPIDDir(), s);
+ return f;
}
static final long LIVELINESS_DELAY = 60*1000;
@@ -1066,9 +1150,8 @@ public class Router {
*
* @return true if the router is the only one running
*/
- private boolean beginMarkingLiveliness(Properties envProps) {
- String filename = getPingFile(envProps);
- File f = new File(filename);
+ private boolean beginMarkingLiveliness() {
+ File f = getPingFile();
if (f.exists()) {
long lastWritten = f.lastModified();
if (System.currentTimeMillis()-lastWritten > LIVELINESS_DELAY) {
@@ -1376,15 +1459,14 @@ private static class PersistRouterInfoJob extends JobImpl {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Persisting updated router info");
- String infoFilename = getContext().getProperty(Router.PROP_INFO_FILENAME);
- if (infoFilename == null)
- infoFilename = Router.PROP_INFO_FILENAME_DEFAULT;
+ String infoFilename = getContext().getProperty(PROP_INFO_FILENAME, PROP_INFO_FILENAME_DEFAULT);
+ File infoFile = new File(getContext().getRouterDir(), infoFilename);
RouterInfo info = getContext().router().getRouterInfo();
FileOutputStream fos = null;
try {
- fos = new FileOutputStream(infoFilename);
+ fos = new FileOutputStream(infoFile);
info.writeBytes(fos);
} catch (DataFormatException dfe) {
_log.error("Error rebuilding the router information", dfe);
diff --git a/router/java/src/net/i2p/router/RouterContext.java b/router/java/src/net/i2p/router/RouterContext.java
index 719224058b..656b1299bd 100644
--- a/router/java/src/net/i2p/router/RouterContext.java
+++ b/router/java/src/net/i2p/router/RouterContext.java
@@ -70,7 +70,11 @@ public class RouterContext extends I2PAppContext {
public RouterContext(Router router, Properties envProps) {
super(filterProps(envProps));
_router = router;
- initAll();
+ // Disabled here so that the router can get a context and get the
+ // directory locations from it, to do an update, without having
+ // to init everything. Caller MUST call initAll() afterwards.
+ // Sorry, this breaks some main() unit tests out there.
+ //initAll();
_contexts.add(this);
}
/**
@@ -86,7 +90,7 @@ public class RouterContext extends I2PAppContext {
envProps.setProperty("time.disabled", "false");
return envProps;
}
- private void initAll() {
+ public void initAll() {
//_adminManager = new AdminManager(this);
if ("false".equals(getProperty("i2p.dummyClientFacade", "false")))
_clientManagerFacade = new ClientManagerFacadeImpl(this);
diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/PersistentDataStore.java b/router/java/src/net/i2p/router/networkdb/kademlia/PersistentDataStore.java
index 282b67e0cd..92124d6901 100644
--- a/router/java/src/net/i2p/router/networkdb/kademlia/PersistentDataStore.java
+++ b/router/java/src/net/i2p/router/networkdb/kademlia/PersistentDataStore.java
@@ -410,7 +410,7 @@ class PersistentDataStore extends TransientDataStore {
private File getDbDir() throws IOException {
- File f = new File(_dbDir);
+ File f = new File(_context.getRouterDir(), _dbDir);
if (!f.exists()) {
boolean created = f.mkdirs();
if (!created)
diff --git a/router/java/src/net/i2p/router/peermanager/ProfilePersistenceHelper.java b/router/java/src/net/i2p/router/peermanager/ProfilePersistenceHelper.java
index 4f5d236116..e1f265d8f1 100644
--- a/router/java/src/net/i2p/router/peermanager/ProfilePersistenceHelper.java
+++ b/router/java/src/net/i2p/router/peermanager/ProfilePersistenceHelper.java
@@ -297,18 +297,8 @@ class ProfilePersistenceHelper {
private File getProfileDir() {
if (_profileDir == null) {
- String dir = null;
- if (_context.router() == null) {
- dir = _context.getProperty(PROP_PEER_PROFILE_DIR, DEFAULT_PEER_PROFILE_DIR);
- } else {
- dir = _context.router().getConfigSetting(PROP_PEER_PROFILE_DIR);
- if (dir == null) {
- _log.info("No peer profile dir specified [" + PROP_PEER_PROFILE_DIR
- + "], using [" + DEFAULT_PEER_PROFILE_DIR + "]");
- dir = DEFAULT_PEER_PROFILE_DIR;
- }
- }
- _profileDir = new File(dir);
+ String dir = _context.getProperty(PROP_PEER_PROFILE_DIR, DEFAULT_PEER_PROFILE_DIR);
+ _profileDir = new File(_context.getRouterDir(), dir);
}
return _profileDir;
}
diff --git a/router/java/src/net/i2p/router/startup/ClientAppConfig.java b/router/java/src/net/i2p/router/startup/ClientAppConfig.java
index 316c0b5006..f5d48cb1f2 100644
--- a/router/java/src/net/i2p/router/startup/ClientAppConfig.java
+++ b/router/java/src/net/i2p/router/startup/ClientAppConfig.java
@@ -43,6 +43,8 @@ public class ClientAppConfig {
Properties rv = new Properties();
String clientConfigFile = ctx.getProperty(PROP_CLIENT_CONFIG_FILENAME, DEFAULT_CLIENT_CONFIG_FILENAME);
File cfgFile = new File(clientConfigFile);
+ if (!cfgFile.isAbsolute())
+ cfgFile = new File(ctx.getConfigDir(), clientConfigFile);
// fall back to use router.config's clientApp.* lines
if (!cfgFile.exists())
@@ -91,9 +93,12 @@ public class ClientAppConfig {
public static void writeClientAppConfig(RouterContext ctx, List apps) {
String clientConfigFile = ctx.getProperty(PROP_CLIENT_CONFIG_FILENAME, DEFAULT_CLIENT_CONFIG_FILENAME);
+ File cfgFile = new File(clientConfigFile);
+ if (!cfgFile.isAbsolute())
+ cfgFile = new File(ctx.getConfigDir(), clientConfigFile);
FileOutputStream fos = null;
try {
- fos = new FileOutputStream(clientConfigFile);
+ fos = new FileOutputStream(cfgFile);
StringBuffer buf = new StringBuffer(2048);
for(int i = 0; i < apps.size(); i++) {
ClientAppConfig app = (ClientAppConfig) apps.get(i);
diff --git a/router/java/src/net/i2p/router/startup/CreateRouterInfoJob.java b/router/java/src/net/i2p/router/startup/CreateRouterInfoJob.java
index 92b176c30f..979cefa78f 100644
--- a/router/java/src/net/i2p/router/startup/CreateRouterInfoJob.java
+++ b/router/java/src/net/i2p/router/startup/CreateRouterInfoJob.java
@@ -8,6 +8,7 @@ package net.i2p.router.startup;
*
*/
+import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashSet;
@@ -76,16 +77,14 @@ public class CreateRouterInfoJob extends JobImpl {
info.sign(signingPrivKey);
- String infoFilename = getContext().router().getConfigSetting(Router.PROP_INFO_FILENAME);
- if (infoFilename == null)
- infoFilename = Router.PROP_INFO_FILENAME_DEFAULT;
- fos1 = new FileOutputStream(infoFilename);
+ String infoFilename = getContext().getProperty(Router.PROP_INFO_FILENAME, Router.PROP_INFO_FILENAME_DEFAULT);
+ File ifile = new File(getContext().getRouterDir(), infoFilename);
+ fos1 = new FileOutputStream(ifile);
info.writeBytes(fos1);
- String keyFilename = getContext().router().getConfigSetting(Router.PROP_KEYS_FILENAME);
- if (keyFilename == null)
- keyFilename = Router.PROP_KEYS_FILENAME_DEFAULT;
- fos2 = new FileOutputStream(keyFilename);
+ String keyFilename = getContext().getProperty(Router.PROP_KEYS_FILENAME, Router.PROP_KEYS_FILENAME_DEFAULT);
+ File kfile = new File(getContext().getRouterDir(), keyFilename);
+ fos2 = new FileOutputStream(kfile);
privkey.writeBytes(fos2);
signingPrivKey.writeBytes(fos2);
pubkey.writeBytes(fos2);
@@ -96,7 +95,7 @@ public class CreateRouterInfoJob extends JobImpl {
getContext().keyManager().setPrivateKey(privkey);
getContext().keyManager().setPublicKey(pubkey);
- _log.info("Router info created and stored at " + infoFilename + " with private keys stored at " + keyFilename + " [" + info + "]");
+ _log.info("Router info created and stored at " + ifile.getAbsolutePath() + " with private keys stored at " + kfile.getAbsolutePath() + " [" + info + "]");
} catch (DataFormatException dfe) {
_log.error("Error building the new router information", dfe);
} catch (IOException ioe) {
diff --git a/router/java/src/net/i2p/router/startup/LoadRouterInfoJob.java b/router/java/src/net/i2p/router/startup/LoadRouterInfoJob.java
index 0374922afd..f3428c4474 100644
--- a/router/java/src/net/i2p/router/startup/LoadRouterInfoJob.java
+++ b/router/java/src/net/i2p/router/startup/LoadRouterInfoJob.java
@@ -51,21 +51,17 @@ public class LoadRouterInfoJob extends JobImpl {
}
private void loadRouterInfo() {
- String routerInfoFile = getContext().router().getConfigSetting(Router.PROP_INFO_FILENAME);
- if (routerInfoFile == null)
- routerInfoFile = Router.PROP_INFO_FILENAME_DEFAULT;
+ String routerInfoFile = getContext().getProperty(Router.PROP_INFO_FILENAME, Router.PROP_INFO_FILENAME_DEFAULT);
RouterInfo info = null;
boolean failedRead = false;
- String keyFilename = getContext().router().getConfigSetting(Router.PROP_KEYS_FILENAME);
- if (keyFilename == null)
- keyFilename = Router.PROP_KEYS_FILENAME_DEFAULT;
+ String keyFilename = getContext().getProperty(Router.PROP_KEYS_FILENAME, Router.PROP_KEYS_FILENAME_DEFAULT);
- File rif = new File(routerInfoFile);
+ File rif = new File(getContext().getRouterDir(), routerInfoFile);
if (rif.exists())
_infoExists = true;
- File rkf = new File(keyFilename);
+ File rkf = new File(getContext().getRouterDir(), keyFilename);
if (rkf.exists())
_keysExist = true;
@@ -98,14 +94,14 @@ public class LoadRouterInfoJob extends JobImpl {
_us = info;
} catch (IOException ioe) {
- _log.error("Error reading the router info from " + routerInfoFile + " and the keys from " + keyFilename, ioe);
+ _log.error("Error reading the router info from " + rif.getAbsolutePath() + " and the keys from " + rkf.getAbsolutePath(), ioe);
_us = null;
rif.delete();
rkf.delete();
_infoExists = false;
_keysExist = false;
} catch (DataFormatException dfe) {
- _log.error("Corrupt router info or keys at " + routerInfoFile + " / " + keyFilename, dfe);
+ _log.error("Corrupt router info or keys at " + rif.getAbsolutePath() + " / " + rkf.getAbsolutePath(), dfe);
_us = null;
rif.delete();
rkf.delete();
diff --git a/router/java/src/net/i2p/router/startup/RebuildRouterInfoJob.java b/router/java/src/net/i2p/router/startup/RebuildRouterInfoJob.java
index 967bc7a797..fda82de8e5 100644
--- a/router/java/src/net/i2p/router/startup/RebuildRouterInfoJob.java
+++ b/router/java/src/net/i2p/router/startup/RebuildRouterInfoJob.java
@@ -57,18 +57,11 @@ public class RebuildRouterInfoJob extends JobImpl {
public void runJob() {
_log.debug("Testing to rebuild router info");
- String infoFile = getContext().router().getConfigSetting(Router.PROP_INFO_FILENAME);
- if (infoFile == null) {
- _log.debug("Info filename not configured, defaulting to " + Router.PROP_INFO_FILENAME_DEFAULT);
- infoFile = Router.PROP_INFO_FILENAME_DEFAULT;
- }
+ String infoFile = getContext().getProperty(Router.PROP_INFO_FILENAME, Router.PROP_INFO_FILENAME_DEFAULT);
+ File info = new File(getContext().getRouterDir(), infoFile);
+ String keyFilename = getContext().getProperty(Router.PROP_KEYS_FILENAME, Router.PROP_KEYS_FILENAME_DEFAULT);
+ File keyFile = new File(getContext().getRouterDir(), keyFilename);
- String keyFilename = getContext().router().getConfigSetting(Router.PROP_KEYS_FILENAME);
- if (keyFilename == null)
- keyFilename = Router.PROP_KEYS_FILENAME_DEFAULT;
- File keyFile = new File(keyFilename);
-
- File info = new File(infoFile);
if (!info.exists() || !keyFile.exists()) {
_log.info("Router info file [" + info.getAbsolutePath() + "] or private key file [" + keyFile.getAbsolutePath() + "] deleted, rebuilding");
rebuildRouterInfo();
@@ -86,14 +79,10 @@ public class RebuildRouterInfoJob extends JobImpl {
_log.debug("Rebuilding the new router info");
boolean fullRebuild = false;
RouterInfo info = null;
- String infoFilename = getContext().router().getConfigSetting(Router.PROP_INFO_FILENAME);
- if (infoFilename == null)
- infoFilename = Router.PROP_INFO_FILENAME_DEFAULT;
-
- String keyFilename = getContext().router().getConfigSetting(Router.PROP_KEYS_FILENAME);
- if (keyFilename == null)
- keyFilename = Router.PROP_KEYS_FILENAME_DEFAULT;
- File keyFile = new File(keyFilename);
+ String infoFilename = getContext().getProperty(Router.PROP_INFO_FILENAME, Router.PROP_INFO_FILENAME_DEFAULT);
+ File infoFile = new File(getContext().getRouterDir(), infoFilename);
+ String keyFilename = getContext().getProperty(Router.PROP_KEYS_FILENAME, Router.PROP_KEYS_FILENAME_DEFAULT);
+ File keyFile = new File(getContext().getRouterDir(), keyFilename);
if (keyFile.exists()) {
// ok, no need to rebuild a brand new identity, just update what we can
@@ -146,7 +135,7 @@ public class RebuildRouterInfoJob extends JobImpl {
FileOutputStream fos = null;
try {
- fos = new FileOutputStream(infoFilename);
+ fos = new FileOutputStream(infoFile);
info.writeBytes(fos);
} catch (DataFormatException dfe) {
_log.error("Error rebuilding the router information", dfe);
diff --git a/router/java/src/net/i2p/router/transport/GeoIP.java b/router/java/src/net/i2p/router/transport/GeoIP.java
index a7da9fad86..fb4984978d 100644
--- a/router/java/src/net/i2p/router/transport/GeoIP.java
+++ b/router/java/src/net/i2p/router/transport/GeoIP.java
@@ -130,7 +130,8 @@ public class GeoIP {
*
*/
private void readCountryFile() {
- File GeoFile = new File(GEOIP_DIR_DEFAULT, COUNTRY_FILE_DEFAULT);
+ File GeoFile = new File(_context.getBaseDir(), GEOIP_DIR_DEFAULT);
+ GeoFile = new File(GeoFile, COUNTRY_FILE_DEFAULT);
if (GeoFile == null || (!GeoFile.exists())) {
if (_log.shouldLog(Log.WARN))
_log.warn("Country file not found: " + GeoFile.getAbsolutePath());
@@ -188,7 +189,8 @@ public class GeoIP {
*
*/
private String[] readGeoIPFile(Long[] search) {
- File GeoFile = new File(GEOIP_DIR_DEFAULT, GEOIP_FILE_DEFAULT);
+ File GeoFile = new File(_context.getBaseDir(), GEOIP_DIR_DEFAULT);
+ GeoFile = new File(GeoFile, GEOIP_FILE_DEFAULT);
if (GeoFile == null || (!GeoFile.exists())) {
if (_log.shouldLog(Log.WARN))
_log.warn("GeoIP file not found: " + GeoFile.getAbsolutePath());