propagate from branch 'i2p.i2p.zzz.dir' (head a871493662f67163f823576ba26e98322d3f896f)

to branch 'i2p.i2p.zzz.test' (head 1168ac4132d737382bf24ba8458a53a9db002ffa)
This commit is contained in:
zzz
2009-06-13 14:20:17 +00:00
51 changed files with 1068 additions and 257 deletions

View File

@ -23,6 +23,7 @@
*/ */
package net.i2p.BOB; package net.i2p.BOB;
import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.FileOutputStream; import java.io.FileOutputStream;
@ -34,6 +35,8 @@ import java.net.Socket;
import java.net.SocketTimeoutException; import java.net.SocketTimeoutException;
import java.util.Properties; import java.util.Properties;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import net.i2p.I2PAppContext;
import net.i2p.client.I2PClient; import net.i2p.client.I2PClient;
import net.i2p.client.streaming.RetransmissionTimer; import net.i2p.client.streaming.RetransmissionTimer;
import net.i2p.util.Log; import net.i2p.util.Log;
@ -186,16 +189,19 @@ public class BOB {
i = Y2.hashCode(); i = Y2.hashCode();
try { try {
{ {
File cfg = new File(configLocation);
if (!cfg.isAbsolute())
cfg = new File(I2PAppContext.getGlobalContext().getConfigDir(), configLocation);
try { try {
FileInputStream fi = new FileInputStream(configLocation); FileInputStream fi = new FileInputStream(cfg);
props.load(fi); props.load(fi);
fi.close(); fi.close();
} catch (FileNotFoundException fnfe) { } 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()); warn(fnfe.toString());
save = true; save = true;
} catch (IOException ioe) { } 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()); warn(ioe.toString());
} }
} }
@ -228,13 +234,16 @@ public class BOB {
props.setProperty(PROP_BOB_HOST, "localhost"); props.setProperty(PROP_BOB_HOST, "localhost");
} }
if (save) { if (save) {
File cfg = new File(configLocation);
if (!cfg.isAbsolute())
cfg = new File(I2PAppContext.getGlobalContext().getConfigDir(), configLocation);
try { try {
warn("Writing new defaults file " + configLocation); warn("Writing new defaults file " + cfg.getAbsolutePath());
FileOutputStream fo = new FileOutputStream(configLocation); FileOutputStream fo = new FileOutputStream(cfg);
props.store(fo, configLocation); props.store(fo, cfg.getAbsolutePath());
fo.close(); fo.close();
} catch (IOException ioe) { } catch (IOException ioe) {
error("IOException on BOB config file " + configLocation + ", " + ioe); error("IOException on BOB config file " + cfg.getAbsolutePath() + ", " + ioe);
} }
} }

View File

@ -94,20 +94,21 @@ public class AddressBook {
* @param proxyPort port number of proxy * @param proxyPort port number of proxy
*/ */
public AddressBook(Subscription subscription, String proxyHost, int proxyPort) { public AddressBook(Subscription subscription, String proxyHost, int proxyPort) {
File tmp = new File(I2PAppContext.getGlobalContext().getTempDir(), "addressbook.tmp");
this.location = subscription.getLocation(); this.location = subscription.getLocation();
EepGet get = new EepGet(I2PAppContext.getGlobalContext(), true, 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); subscription.getLocation(), true, subscription.getEtag(), subscription.getLastModified(), null);
if (get.fetch()) { if (get.fetch()) {
subscription.setEtag(get.getETag()); subscription.setEtag(get.getETag());
subscription.setLastModified(get.getLastModified()); subscription.setLastModified(get.getLastModified());
} }
try { try {
this.addresses = ConfigParser.parse(new File("addressbook.tmp")); this.addresses = ConfigParser.parse(tmp);
} catch (IOException exp) { } catch (IOException exp) {
this.addresses = new HashMap(); this.addresses = new HashMap();
} }
new File("addressbook.tmp").delete(); tmp.delete();
} }
/** /**

View File

@ -28,6 +28,8 @@ import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import net.i2p.I2PAppContext;
/** /**
* Main class of addressbook. Performs updates, and runs the main loop. * Main class of addressbook. Performs updates, and runs the main loop.
* *
@ -125,11 +127,13 @@ public class Daemon {
public void run(String[] args) { public void run(String[] args) {
String settingsLocation = "config.txt"; String settingsLocation = "config.txt";
String home; File homeFile;
if (args.length > 0) { if (args.length > 0) {
home = args[0]; homeFile = new File(args[0]);
if (!homeFile.isAbsolute())
homeFile = new File(I2PAppContext.getGlobalContext().getRouterDir(), args[0]);
} else { } else {
home = "."; homeFile = new File(System.getProperty("user.dir"));
} }
Map defaultSettings = new HashMap(); Map defaultSettings = new HashMap();
@ -145,7 +149,6 @@ public class Daemon {
defaultSettings.put("last_modified", "last_modified"); defaultSettings.put("last_modified", "last_modified");
defaultSettings.put("update_delay", "12"); defaultSettings.put("update_delay", "12");
File homeFile = new File(home);
if (!homeFile.exists()) { if (!homeFile.exists()) {
boolean created = homeFile.mkdirs(); boolean created = homeFile.mkdirs();
if (created) if (created)
@ -169,7 +172,7 @@ public class Daemon {
delay = 1; delay = 1;
} }
update(settings, home); update(settings, homeFile.getAbsolutePath());
try { try {
synchronized (this) { synchronized (this) {
wait(delay * 60 * 60 * 1000); wait(delay * 60 * 60 * 1000);

View File

@ -73,7 +73,7 @@ public class I2PSnarkUtil {
// This is used for both announce replies and .torrent file downloads, // This is used for both announce replies and .torrent file downloads,
// so it must be available even if not connected to I2CP. // so it must be available even if not connected to I2CP.
// so much for multiple instances // so much for multiple instances
_tmpDir = new File("tmp", "i2psnark"); _tmpDir = new File(ctx.getTempDir(), "i2psnark");
FileUtil.rmdir(_tmpDir, false); FileUtil.rmdir(_tmpDir, false);
_tmpDir.mkdirs(); _tmpDir.mkdirs();
} }

View File

@ -31,7 +31,7 @@ public class SnarkManager implements Snark.CompleteListener {
/** map of (canonical) filename to Snark instance (unsynchronized) */ /** map of (canonical) filename to Snark instance (unsynchronized) */
private Map _snarks; private Map _snarks;
private Object _addSnarkLock; private Object _addSnarkLock;
private String _configFile = "i2psnark.config"; private File _configFile;
private Properties _config; private Properties _config;
private I2PAppContext _context; private I2PAppContext _context;
private Log _log; 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_PREFIX = "i2psnark.zmeta.";
public static final String PROP_META_BITFIELD_SUFFIX = ".bitfield"; 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 PROP_AUTO_START = "i2snark.autoStart"; // oops
public static final String DEFAULT_AUTO_START = "false"; public static final String DEFAULT_AUTO_START = "false";
public static final String PROP_LINK_PREFIX = "i2psnark.linkPrefix"; 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); _log = _context.logManager().getLog(SnarkManager.class);
_messages = new ArrayList(16); _messages = new ArrayList(16);
_util = new I2PSnarkUtil(_context); _util = new I2PSnarkUtil(_context);
_configFile = new File(CONFIG_FILE);
if (!_configFile.isAbsolute())
_configFile = new File(_context.getConfigDir(), CONFIG_FILE);
loadConfig(null); loadConfig(null);
} }
@ -112,10 +116,11 @@ public class SnarkManager implements Snark.CompleteListener {
} }
private int getStartupDelayMinutes() { return 3; } private int getStartupDelayMinutes() { return 3; }
public File getDataDir() { public File getDataDir() {
String dir = _config.getProperty(PROP_DIR); String dir = _config.getProperty(PROP_DIR, "i2psnark");
if ( (dir == null) || (dir.trim().length() <= 0) ) File f = new File(dir);
dir = "i2psnark"; if (!f.isAbsolute())
return new File(dir); f = new File(_context.getAppDir(), dir);
return f;
} }
/** null to set initial defaults */ /** null to set initial defaults */
@ -123,8 +128,10 @@ public class SnarkManager implements Snark.CompleteListener {
if (_config == null) if (_config == null)
_config = new Properties(); _config = new Properties();
if (filename != null) { if (filename != null) {
_configFile = filename;
File cfg = new File(filename); File cfg = new File(filename);
if (!cfg.isAbsolute())
cfg = new File(_context.getConfigDir(), filename);
_configFile = cfg;
if (cfg.exists()) { if (cfg.exists()) {
try { try {
DataHelper.loadProps(_config, cfg); DataHelper.loadProps(_config, cfg);
@ -352,10 +359,10 @@ public class SnarkManager implements Snark.CompleteListener {
public void saveConfig() { public void saveConfig() {
try { try {
synchronized (_configFile) { synchronized (_configFile) {
DataHelper.storeProps(_config, new File(_configFile)); DataHelper.storeProps(_config, _configFile);
} }
} catch (IOException ioe) { } catch (IOException ioe) {
addMessage("Unable to save the config to '" + _configFile + "'"); addMessage("Unable to save the config to '" + _configFile.getAbsolutePath() + "'");
} }
} }

View File

@ -173,6 +173,7 @@ public class I2PSnarkServlet extends HttpServlet {
} else if ("Add torrent".equals(action)) { } else if ("Add torrent".equals(action)) {
String newFile = req.getParameter("newFile"); String newFile = req.getParameter("newFile");
String newURL = req.getParameter("newURL"); String newURL = req.getParameter("newURL");
// NOTE - newFile currently disabled in HTML form - see below
File f = null; File f = null;
if ( (newFile != null) && (newFile.trim().length() > 0) ) if ( (newFile != null) && (newFile.trim().length() > 0) )
f = new File(newFile.trim()); f = new File(newFile.trim());

View File

@ -372,6 +372,8 @@ public class I2PTunnel implements Logging, EventDispatcher {
} }
privKeyFile = new File(args[2]); privKeyFile = new File(args[2]);
if (!privKeyFile.isAbsolute())
privKeyFile = new File(_context.getAppDir(), args[2]);
if (!privKeyFile.canRead()) { if (!privKeyFile.canRead()) {
l.log("private key file does not exist"); l.log("private key file does not exist");
_log.error(getPrefix() + "Private key file does not exist or is not readable: " + args[2]); _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]); privKeyFile = new File(args[2]);
if (!privKeyFile.isAbsolute())
privKeyFile = new File(_context.getAppDir(), args[2]);
if (!privKeyFile.canRead()) { if (!privKeyFile.canRead()) {
l.log("private key file does not exist"); l.log("private key file does not exist");
_log.error(getPrefix() + "Private key file does not exist or is not readable: " + args[2]); _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]; String spoofedHost = args[2];
privKeyFile = new File(args[3]); privKeyFile = new File(args[3]);
if (!privKeyFile.isAbsolute())
privKeyFile = new File(_context.getAppDir(), args[3]);
if (!privKeyFile.canRead()) { if (!privKeyFile.canRead()) {
l.log("private key file does not exist"); l.log("private key file does not exist");
_log.error(getPrefix() + "Private key file does not exist or is not readable: " + args[3]); _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]); File privKeyFile = new File(args[1]);
if (!privKeyFile.isAbsolute())
privKeyFile = new File(_context.getAppDir(), args[1]);
if (!privKeyFile.canRead()) { if (!privKeyFile.canRead()) {
l.log("private key file does not exist"); l.log("private key file does not exist");
_log.error(getPrefix() + "Private key file does not exist or is not readable: " + args[3]); _log.error(getPrefix() + "Private key file does not exist or is not readable: " + args[3]);

View File

@ -3,6 +3,7 @@
*/ */
package net.i2p.i2ptunnel; package net.i2p.i2ptunnel;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; 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 */ /** used to assign unique IDs to the threads / clients. no logic or functionality */
private static volatile long __clientId = 0; 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 * @throws IllegalArgumentException if the I2PTunnel does not contain
* valid config to contact the router * valid config to contact the router
@ -261,9 +264,9 @@ public class I2PTunnelConnectClient extends I2PTunnelClientBase implements Runna
String str; String str;
byte[] header; byte[] header;
if (usingWWWProxy) if (usingWWWProxy)
str = FileUtil.readTextFile("docs/dnfp-header.ht", 100, true); str = FileUtil.readTextFile((new File(_errorDir, "dnfp-header.ht")).getAbsolutePath(), 100, true);
else 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) if (str != null)
header = str.getBytes(); header = str.getBytes();
else else
@ -357,9 +360,9 @@ public class I2PTunnelConnectClient extends I2PTunnelClientBase implements Runna
String str; String str;
byte[] header; byte[] header;
if (usingWWWProxy) if (usingWWWProxy)
str = FileUtil.readTextFile("docs/dnfp-header.ht", 100, true); str = FileUtil.readTextFile((new File(_errorDir, "dnfp-header.ht")).getAbsolutePath(), 100, true);
else 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) if (str != null)
header = str.getBytes(); header = str.getBytes();
else else

View File

@ -4,6 +4,7 @@
package net.i2p.i2ptunnel; package net.i2p.i2ptunnel;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; 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 */ /** used to assign unique IDs to the threads / clients. no logic or functionality */
private static volatile long __clientId = 0; 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 * @throws IllegalArgumentException if the I2PTunnel does not contain
* valid config to contact the router * valid config to contact the router
@ -372,7 +376,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
{ {
String str; String str;
byte[] header; 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(); if (str != null) header = str.getBytes();
else header = ERR_AHELPER_CONFLICT; else header = ERR_AHELPER_CONFLICT;
@ -558,13 +562,13 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
byte[] header; byte[] header;
boolean showAddrHelper = false; boolean showAddrHelper = false;
if (usingWWWProxy) 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) 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")) 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 { else {
str = FileUtil.readTextFile("docs/dnfh-header.ht", 100, true); str = FileUtil.readTextFile((new File(_errorDir, "dnfh-header.ht")).getAbsolutePath(), 100, true);
showAddrHelper = true; showAddrHelper = true;
} }
if (str != null) if (str != null)
@ -733,9 +737,9 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
String str; String str;
byte[] header; byte[] header;
if (usingWWWProxy) if (usingWWWProxy)
str = FileUtil.readTextFile("docs/dnfp-header.ht", 100, true); str = FileUtil.readTextFile((new File(_errorDir, "dnfp-header.ht")).getAbsolutePath(), 100, true);
else 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) if (str != null)
header = str.getBytes(); header = str.getBytes();
else else

View File

@ -72,6 +72,8 @@ public class TunnelController implements Logging {
} }
File keyFile = new File(getPrivKeyFile()); File keyFile = new File(getPrivKeyFile());
if (!keyFile.isAbsolute())
keyFile = new File(I2PAppContext.getGlobalContext().getAppDir(), getPrivKeyFile());
if (keyFile.exists()) { if (keyFile.exists()) {
//log("Not overwriting existing private keys in " + keyFile.getAbsolutePath()); //log("Not overwriting existing private keys in " + keyFile.getAbsolutePath());
return; return;

View File

@ -270,9 +270,11 @@ public class TunnelControllerGroup {
*/ */
private Properties loadConfig(String configFile) { private Properties loadConfig(String configFile) {
File cfgFile = new File(configFile); File cfgFile = new File(configFile);
if (!cfgFile.isAbsolute())
cfgFile = new File(I2PAppContext.getGlobalContext().getConfigDir(), configFile);
if (!cfgFile.exists()) { if (!cfgFile.exists()) {
if (_log.shouldLog(Log.ERROR)) 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; return null;
} }
@ -282,7 +284,7 @@ public class TunnelControllerGroup {
return props; return props;
} catch (IOException ioe) { } catch (IOException ioe) {
if (_log.shouldLog(Log.ERROR)) 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; return null;
} }
} }

View File

@ -41,7 +41,7 @@ public class ConfigServiceHandler extends FormHandler {
} }
public void run() { public void run() {
try { try {
Router.killKeys(); ContextHelper.getContext(null).router().killKeys();
WrapperManager.signalStopped(_exitCode); WrapperManager.signalStopped(_exitCode);
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace(); t.printStackTrace();

View File

@ -3,7 +3,6 @@ package net.i2p.router.web;
import java.io.File; import java.io.File;
import java.util.Locale; import java.util.Locale;
import net.i2p.router.RouterContext;
import net.i2p.util.FileUtil; import net.i2p.util.FileUtil;
public class ContentHelper extends HelperBase { public class ContentHelper extends HelperBase {
@ -14,6 +13,9 @@ public class ContentHelper extends HelperBase {
public ContentHelper() {} public ContentHelper() {}
/**
* Caution, use absolute paths only, do not assume files are in CWD
*/
public void setPage(String page) { _page = page; } public void setPage(String page) { _page = page; }
public void setStartAtBeginning(String moo) { public void setStartAtBeginning(String moo) {
_startAtBeginning = Boolean.valueOf(""+moo).booleanValue(); _startAtBeginning = Boolean.valueOf(""+moo).booleanValue();

View File

@ -1,66 +1,70 @@
package net.i2p.router.web; package net.i2p.router.web;
import java.io.File;
import java.util.List; import java.util.List;
import net.i2p.router.RouterContext;
import net.i2p.util.FileUtil; import net.i2p.util.FileUtil;
public class LogsHelper extends HelperBase { public class LogsHelper extends HelperBase {
public LogsHelper() {} public LogsHelper() {}
public String getLogs() { public String getLogs() {
List msgs = _context.logManager().getBuffer().getMostRecentMessages(); return formatMessages(_context.logManager().getBuffer().getMostRecentMessages());
StringBuffer buf = new StringBuffer(16*1024);
buf.append("<ul>");
buf.append("<code>\n");
for (int i = msgs.size(); i > 0; i--) {
String msg = (String)msgs.get(i - 1);
msg = msg.replaceAll("<","&lt;");
buf.append("<li>");
buf.append(msg);
buf.append("</li>\n");
}
buf.append("</code></ul>\n");
return buf.toString();
} }
public String getCriticalLogs() { public String getCriticalLogs() {
List msgs = _context.logManager().getBuffer().getMostRecentCriticalMessages(); return formatMessages(_context.logManager().getBuffer().getMostRecentCriticalMessages());
StringBuffer buf = new StringBuffer(16*1024);
buf.append("<ul>");
buf.append("<code>\n");
for (int i = msgs.size(); i > 0; i--) {
String msg = (String)msgs.get(i - 1);
msg = msg.replaceAll("<","&lt;");
buf.append("<li>");
buf.append(msg);
buf.append("</li>\n");
}
buf.append("</code></ul>\n");
return buf.toString();
} }
public String getServiceLogs() { public String getServiceLogs() {
String str = FileUtil.readTextFile("wrapper.log", 250, false); // look in new and old place
File f = new File(_context.getLogDir(), "wrapper.log");
if (!f.exists())
f = new File(_context.getBaseDir(), "wrapper.log");
String str = FileUtil.readTextFile(f.getAbsolutePath(), 250, false);
if (str == null) if (str == null)
return ""; return "";
else { else {
str = str.replaceAll("<","&lt;"); str = str.replaceAll("<", "&lt;").replaceAll(">", "&gt;");
return "<pre>" + str + "</pre>"; return "<pre>" + str + "</pre>";
} }
} }
/***** unused
public String getConnectionLogs() { 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); StringBuffer buf = new StringBuffer(16*1024);
buf.append("<ul>"); buf.append("<ul>");
buf.append("<code>\n"); buf.append("<code>\n");
for (int i = msgs.size(); i > 0; i--) { for (int i = msgs.size(); i > 0; i--) {
String msg = (String)msgs.get(i - 1); String msg = (String)msgs.get(i - 1);
buf.append("<li>"); buf.append("<li>");
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("<font color=\"").append(color).append("\">");
buf.append(msg.replaceAll("<", "&lt;").replaceAll(">", "&gt;"));
buf.append("</font>");
} else {
buf.append(msg);
}
buf.append("</li>\n"); buf.append("</li>\n");
} }
buf.append("</code></ul>\n"); buf.append("</code></ul>\n");

View File

@ -27,6 +27,8 @@ public class NewsFetcher implements Runnable, EepGet.StatusListener {
private long _lastUpdated; private long _lastUpdated;
private String _updateVersion; private String _updateVersion;
private String _lastModified; private String _lastModified;
private File _newsFile;
private File _tempFile;
private static NewsFetcher _instance; private static NewsFetcher _instance;
//public static final synchronized NewsFetcher getInstance() { return _instance; } //public static final synchronized NewsFetcher getInstance() { return _instance; }
public static final synchronized NewsFetcher getInstance(I2PAppContext ctx) { public static final synchronized NewsFetcher getInstance(I2PAppContext ctx) {
@ -35,25 +37,26 @@ public class NewsFetcher implements Runnable, EepGet.StatusListener {
_instance = new NewsFetcher(ctx); _instance = new NewsFetcher(ctx);
return _instance; return _instance;
} }
private static final String NEWS_FILE = "docs/news.xml"; private static final String NEWS_FILE = "docs/news.xml";
private static final String TEMP_NEWS_FILE = "docs/news.xml.temp"; private static final String TEMP_NEWS_FILE = "news.xml.temp";
private NewsFetcher(I2PAppContext ctx) { private NewsFetcher(I2PAppContext ctx) {
_context = ctx; _context = ctx;
_log = ctx.logManager().getLog(NewsFetcher.class); _log = ctx.logManager().getLog(NewsFetcher.class);
_instance = this; _instance = this;
_lastFetch = 0; _lastFetch = 0;
_newsFile = new File(_context.getBaseDir(), NEWS_FILE);
_tempFile = new File(_context.getTempDir(), TEMP_NEWS_FILE);
updateLastFetched(); updateLastFetched();
_lastUpdated = _lastFetch; _lastUpdated = _lastFetch;
_updateVersion = ""; _updateVersion = "";
} }
private void updateLastFetched() { private void updateLastFetched() {
File news = new File(NEWS_FILE); if (_newsFile.exists()) {
if (news.exists()) {
if (_lastFetch == 0) if (_lastFetch == 0)
_lastFetch = news.lastModified(); _lastFetch = _newsFile.lastModified();
} else } else
_lastFetch = 0; _lastFetch = 0;
} }
@ -82,7 +85,7 @@ public class NewsFetcher implements Runnable, EepGet.StatusListener {
String policy = _context.getProperty(ConfigUpdateHandler.PROP_UPDATE_POLICY); String policy = _context.getProperty(ConfigUpdateHandler.PROP_UPDATE_POLICY);
if ("notify".equals(policy)) if ("notify".equals(policy))
return false; return false;
File zip = new File(Router.UPDATE_FILE); File zip = new File(_context.getRouterDir(), Router.UPDATE_FILE);
return !zip.exists(); return !zip.exists();
} }
@ -114,18 +117,17 @@ public class NewsFetcher implements Runnable, EepGet.StatusListener {
boolean shouldProxy = Boolean.valueOf(_context.getProperty(ConfigUpdateHandler.PROP_SHOULD_PROXY, ConfigUpdateHandler.DEFAULT_SHOULD_PROXY)).booleanValue(); 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); String proxyHost = _context.getProperty(ConfigUpdateHandler.PROP_PROXY_HOST, ConfigUpdateHandler.DEFAULT_PROXY_HOST);
String port = _context.getProperty(ConfigUpdateHandler.PROP_PROXY_PORT, ConfigUpdateHandler.DEFAULT_PROXY_PORT); String port = _context.getProperty(ConfigUpdateHandler.PROP_PROXY_PORT, ConfigUpdateHandler.DEFAULT_PROXY_PORT);
File tempFile = new File(TEMP_NEWS_FILE); if (_tempFile.exists())
if (tempFile.exists()) _tempFile.delete();
tempFile.delete();
int proxyPort = -1; int proxyPort = -1;
try { try {
proxyPort = Integer.parseInt(port); proxyPort = Integer.parseInt(port);
EepGet get = null; EepGet get = null;
if (shouldProxy) if (shouldProxy)
get = new EepGet(_context, true, proxyHost, proxyPort, 2, TEMP_NEWS_FILE, newsURL, true, null, _lastModified); get = new EepGet(_context, true, proxyHost, proxyPort, 2, _tempFile.getAbsolutePath(), newsURL, true, null, _lastModified);
else else
get = new EepGet(_context, false, null, 0, 0, TEMP_NEWS_FILE, newsURL, true, null, _lastModified); get = new EepGet(_context, false, null, 0, 0, _tempFile.getAbsolutePath(), newsURL, true, null, _lastModified);
get.addStatusListener(this); get.addStatusListener(this);
if (get.fetch()) if (get.fetch())
_lastModified = get.getLastModified(); _lastModified = get.getLastModified();
@ -138,11 +140,10 @@ public class NewsFetcher implements Runnable, EepGet.StatusListener {
private static final String VERSION_PREFIX = "version=\""; private static final String VERSION_PREFIX = "version=\"";
private void checkForUpdates() { private void checkForUpdates() {
_updateAvailable = false; _updateAvailable = false;
File news = new File(NEWS_FILE); if ( (!_newsFile.exists()) || (_newsFile.length() <= 0) ) return;
if ( (!news.exists()) || (news.length() <= 0) ) return;
FileInputStream in = null; FileInputStream in = null;
try { try {
in = new FileInputStream(news); in = new FileInputStream(_newsFile);
StringBuffer buf = new StringBuffer(128); StringBuffer buf = new StringBuffer(128);
while (DataHelper.readLine(in, buf)) { while (DataHelper.readLine(in, buf)) {
int index = buf.indexOf(VERSION_PREFIX); int index = buf.indexOf(VERSION_PREFIX);
@ -220,13 +221,12 @@ public class NewsFetcher implements Runnable, EepGet.StatusListener {
if (_log.shouldLog(Log.INFO)) if (_log.shouldLog(Log.INFO))
_log.info("News fetched from " + url + " with " + (alreadyTransferred+bytesTransferred)); _log.info("News fetched from " + url + " with " + (alreadyTransferred+bytesTransferred));
File temp = new File(TEMP_NEWS_FILE);
long now = _context.clock().now(); long now = _context.clock().now();
if (temp.exists()) { if (_tempFile.exists()) {
boolean copied = FileUtil.copy(TEMP_NEWS_FILE, NEWS_FILE, true); boolean copied = FileUtil.copy(_tempFile.getAbsolutePath(), _newsFile.getAbsolutePath(), true);
if (copied) { if (copied) {
_lastUpdated = now; _lastUpdated = now;
temp.delete(); _tempFile.delete();
checkForUpdates(); checkForUpdates();
} else { } else {
if (_log.shouldLog(Log.ERROR)) if (_log.shouldLog(Log.ERROR))
@ -242,8 +242,7 @@ public class NewsFetcher implements Runnable, EepGet.StatusListener {
public void transferFailed(String url, long bytesTransferred, long bytesRemaining, int currentAttempt) { public void transferFailed(String url, long bytesTransferred, long bytesRemaining, int currentAttempt) {
if (_log.shouldLog(Log.WARN)) if (_log.shouldLog(Log.WARN))
_log.warn("Failed to fetch the news from " + url); _log.warn("Failed to fetch the news from " + url);
File temp = new File(TEMP_NEWS_FILE); _tempFile.delete();
temp.delete();
} }
public void headerReceived(String url, int attemptNum, String key, String val) {} public void headerReceived(String url, int attemptNum, String key, String val) {}
public void attempting(String url) {} public void attempting(String url) {}

View File

@ -256,7 +256,7 @@ public class ReseedHandler {
private void writeSeed(String name, byte data[]) throws Exception { private void writeSeed(String name, byte data[]) throws Exception {
String dirName = "netDb"; // _context.getProperty("router.networkDatabase.dbDir", "netDb"); String dirName = "netDb"; // _context.getProperty("router.networkDatabase.dbDir", "netDb");
File netDbDir = new File(dirName); File netDbDir = new File(_context.getRouterDir(), dirName);
if (!netDbDir.exists()) { if (!netDbDir.exists()) {
boolean ok = netDbDir.mkdirs(); boolean ok = netDbDir.mkdirs();
} }

View File

@ -59,7 +59,7 @@ public class RouterConsoleRunner {
} }
public void startConsole() { public void startConsole() {
File workDir = new File("work"); File workDir = new File(I2PAppContext.getGlobalContext().getTempDir(), "jetty-work");
boolean workDirRemoved = FileUtil.rmdir(workDir, false); boolean workDirRemoved = FileUtil.rmdir(workDir, false);
if (!workDirRemoved) if (!workDirRemoved)
System.err.println("ERROR: Unable to remove Jetty temporary work directory"); System.err.println("ERROR: Unable to remove Jetty temporary work directory");
@ -95,8 +95,11 @@ public class RouterConsoleRunner {
} }
_server.setRootWebApp(ROUTERCONSOLE); _server.setRootWebApp(ROUTERCONSOLE);
WebApplicationContext wac = _server.addWebApplication("/", _webAppsDir + ROUTERCONSOLE + ".war"); WebApplicationContext wac = _server.addWebApplication("/", _webAppsDir + ROUTERCONSOLE + ".war");
File tmpdir = new File(workDir, ROUTERCONSOLE + "-" + _listenPort);
tmpdir.mkdir();
wac.setTempDirectory(tmpdir);
initialize(wac); initialize(wac);
File dir = new File(_webAppsDir); File dir = new File(I2PAppContext.getGlobalContext().getBaseDir(), _webAppsDir);
String fileNames[] = dir.list(WarFilenameFilter.instance()); String fileNames[] = dir.list(WarFilenameFilter.instance());
if (fileNames != null) { if (fileNames != null) {
for (int i = 0; i < fileNames.length; i++) { for (int i = 0; i < fileNames.length; i++) {
@ -106,6 +109,9 @@ public class RouterConsoleRunner {
if (! "false".equals(enabled)) { if (! "false".equals(enabled)) {
String path = new File(dir, fileNames[i]).getCanonicalPath(); String path = new File(dir, fileNames[i]).getCanonicalPath();
wac = _server.addWebApplication("/"+ appName, path); wac = _server.addWebApplication("/"+ appName, path);
tmpdir = new File(workDir, appName + "-" + _listenPort);
tmpdir.mkdir();
wac.setTempDirectory(tmpdir);
initialize(wac); initialize(wac);
if (enabled == null) { if (enabled == null) {
// do this so configclients.jsp knows about all apps from reading the config // do this so configclients.jsp knows about all apps from reading the config
@ -144,10 +150,10 @@ public class RouterConsoleRunner {
// don't have an installation directory that they can put the flag in yet. // don't have an installation directory that they can put the flag in yet.
File noReseedFile = new File(new File(System.getProperty("user.home")), ".i2pnoreseed"); File noReseedFile = new File(new File(System.getProperty("user.home")), ".i2pnoreseed");
File noReseedFileAlt1 = new File(new File(System.getProperty("user.home")), "noreseed.i2p"); File noReseedFileAlt1 = new File(new File(System.getProperty("user.home")), "noreseed.i2p");
File noReseedFileAlt2 = new File(".i2pnoreseed"); File noReseedFileAlt2 = new File(I2PAppContext.getGlobalContext().getConfigDir(), ".i2pnoreseed");
File noReseedFileAlt3 = new File("noreseed.i2p"); File noReseedFileAlt3 = new File(I2PAppContext.getGlobalContext().getConfigDir(), "noreseed.i2p");
if (!noReseedFile.exists() && !noReseedFileAlt1.exists() && !noReseedFileAlt2.exists() && !noReseedFileAlt3.exists()) { if (!noReseedFile.exists() && !noReseedFileAlt1.exists() && !noReseedFileAlt2.exists() && !noReseedFileAlt3.exists()) {
File netDb = new File("netDb"); File netDb = new File(I2PAppContext.getGlobalContext().getRouterDir(), "netDb");
// sure, some of them could be "my.info" or various leaseSet- files, but chances are, // sure, some of them could be "my.info" or various leaseSet- files, but chances are,
// if someone has those files, they've already been seeded (at least enough to let them // if someone has those files, they've already been seeded (at least enough to let them
// get i2p started - they can reseed later in the web console) // get i2p started - they can reseed later in the web console)
@ -216,7 +222,7 @@ public class RouterConsoleRunner {
Properties rv = new Properties(); Properties rv = new Properties();
// String webappConfigFile = ctx.getProperty(PROP_WEBAPP_CONFIG_FILENAME, DEFAULT_WEBAPP_CONFIG_FILENAME); // String webappConfigFile = ctx.getProperty(PROP_WEBAPP_CONFIG_FILENAME, DEFAULT_WEBAPP_CONFIG_FILENAME);
String webappConfigFile = DEFAULT_WEBAPP_CONFIG_FILENAME; String webappConfigFile = DEFAULT_WEBAPP_CONFIG_FILENAME;
File cfgFile = new File(webappConfigFile); File cfgFile = new File(I2PAppContext.getGlobalContext().getConfigDir(), webappConfigFile);
try { try {
DataHelper.loadProps(rv, cfgFile); DataHelper.loadProps(rv, cfgFile);
@ -230,7 +236,7 @@ public class RouterConsoleRunner {
public static void storeWebAppProperties(Properties props) { public static void storeWebAppProperties(Properties props) {
// String webappConfigFile = ctx.getProperty(PROP_WEBAPP_CONFIG_FILENAME, DEFAULT_WEBAPP_CONFIG_FILENAME); // String webappConfigFile = ctx.getProperty(PROP_WEBAPP_CONFIG_FILENAME, DEFAULT_WEBAPP_CONFIG_FILENAME);
String webappConfigFile = DEFAULT_WEBAPP_CONFIG_FILENAME; String webappConfigFile = DEFAULT_WEBAPP_CONFIG_FILENAME;
File cfgFile = new File(webappConfigFile); File cfgFile = new File(I2PAppContext.getGlobalContext().getConfigDir(), webappConfigFile);
try { try {
DataHelper.storeProps(props, cfgFile); DataHelper.storeProps(props, cfgFile);

View File

@ -31,6 +31,7 @@ public class UpdateHandler {
protected RouterContext _context; protected RouterContext _context;
protected Log _log; protected Log _log;
protected DecimalFormat _pct = new DecimalFormat("00.0%"); protected DecimalFormat _pct = new DecimalFormat("00.0%");
protected String _updateFile;
protected static final String SIGNED_UPDATE_FILE = "i2pupdate.sud"; protected static final String SIGNED_UPDATE_FILE = "i2pupdate.sud";
protected static final String PROP_UPDATE_IN_PROGRESS = "net.i2p.router.web.UpdateHandler.updateInProgress"; protected static final String PROP_UPDATE_IN_PROGRESS = "net.i2p.router.web.UpdateHandler.updateInProgress";
@ -41,6 +42,7 @@ public class UpdateHandler {
public UpdateHandler(RouterContext ctx) { public UpdateHandler(RouterContext ctx) {
_context = ctx; _context = ctx;
_log = ctx.logManager().getLog(UpdateHandler.class); _log = ctx.logManager().getLog(UpdateHandler.class);
_updateFile = (new File(ctx.getRouterDir(), SIGNED_UPDATE_FILE)).getAbsolutePath();
} }
/** /**
@ -137,9 +139,9 @@ public class UpdateHandler {
try { try {
EepGet get = null; EepGet get = null;
if (shouldProxy) if (shouldProxy)
get = new EepGet(_context, proxyHost, proxyPort, 20, SIGNED_UPDATE_FILE, updateURL, false); get = new EepGet(_context, proxyHost, proxyPort, 20, _updateFile, updateURL, false);
else else
get = new EepGet(_context, 1, SIGNED_UPDATE_FILE, updateURL, false); get = new EepGet(_context, 1, _updateFile, updateURL, false);
get.addStatusListener(UpdateRunner.this); get.addStatusListener(UpdateRunner.this);
get.fetch(); get.fetch();
} catch (Throwable t) { } catch (Throwable t) {
@ -167,8 +169,9 @@ public class UpdateHandler {
public void transferComplete(long alreadyTransferred, long bytesTransferred, long bytesRemaining, String url, String outputFile, boolean notModified) { public void transferComplete(long alreadyTransferred, long bytesTransferred, long bytesRemaining, String url, String outputFile, boolean notModified) {
_status = "<b>Update downloaded</b>"; _status = "<b>Update downloaded</b>";
TrustedUpdate up = new TrustedUpdate(_context); TrustedUpdate up = new TrustedUpdate(_context);
String err = up.migrateVerified(RouterVersion.VERSION, SIGNED_UPDATE_FILE, Router.UPDATE_FILE); File f = new File(_updateFile);
File f = new File(SIGNED_UPDATE_FILE); File to = new File(_context.getBaseDir(), Router.UPDATE_FILE);
String err = up.migrateVerified(RouterVersion.VERSION, f, to);
f.delete(); f.delete();
if (err == null) { if (err == null) {
String policy = _context.getProperty(ConfigUpdateHandler.PROP_UPDATE_POLICY); String policy = _context.getProperty(ConfigUpdateHandler.PROP_UPDATE_POLICY);

View File

@ -15,8 +15,11 @@ if (c != null && c.length() > 0) {
java.io.OutputStream cout = response.getOutputStream(); java.io.OutputStream cout = response.getOutputStream();
response.setContentType("image/png"); response.setContentType("image/png");
response.setHeader("Cache-Control", "max-age=86400"); // cache for a day response.setHeader("Cache-Control", "max-age=86400"); // cache for a day
String base = net.i2p.I2PAppContext.getGlobalContext().getBaseDir().getAbsolutePath();
String file = "docs" + java.io.File.separatorChar + "icons" + java.io.File.separatorChar +
"flags" + java.io.File.separatorChar + c + ".png";
try { try {
net.i2p.util.FileUtil.readFile(c + ".png", "docs/icons/flags", cout); net.i2p.util.FileUtil.readFile(file, base, cout);
rendered = true; rendered = true;
} catch (java.io.IOException ioe) {} } catch (java.io.IOException ioe) {}
if (rendered) if (rendered)

View File

@ -184,7 +184,8 @@ client applications can be found on our <a href="http://www.i2p2.i2p/download">d
<h2>Release history</h2> <h2>Release history</h2>
<jsp:useBean class="net.i2p.router.web.ContentHelper" id="contenthelper" scope="request" /> <jsp:useBean class="net.i2p.router.web.ContentHelper" id="contenthelper" scope="request" />
<jsp:setProperty name="contenthelper" property="page" value="history.txt" /> <% File fpath = new java.io.File(net.i2p.I2PAppContext.getGlobalContext().getBaseDir(), "history.txt"); %>
<jsp:setProperty name="contenthelper" property="page" value="<%=fpath.getAbsolutePath()%>" />
<jsp:setProperty name="contenthelper" property="maxLines" value="500" /> <jsp:setProperty name="contenthelper" property="maxLines" value="500" />
<jsp:setProperty name="contenthelper" property="startAtBeginning" value="true" /> <jsp:setProperty name="contenthelper" property="startAtBeginning" value="true" />
<jsp:getProperty name="contenthelper" property="textContent" /> <jsp:getProperty name="contenthelper" property="textContent" />

View File

@ -19,7 +19,8 @@ if (System.getProperty("router.consoleNonce") == null) {
<div class="news" id="news"> <div class="news" id="news">
<jsp:useBean class="net.i2p.router.web.ContentHelper" id="newshelper" scope="request" /> <jsp:useBean class="net.i2p.router.web.ContentHelper" id="newshelper" scope="request" />
<jsp:setProperty name="newshelper" property="page" value="docs/news.xml" /> <% File fpath = new java.io.File(net.i2p.I2PAppContext.getGlobalContext().getBaseDir(), "docs/news.xml"); %>
<jsp:setProperty name="newshelper" property="page" value="<%=fpath.getAbsolutePath()%>" />
<jsp:setProperty name="newshelper" property="maxLines" value="300" /> <jsp:setProperty name="newshelper" property="maxLines" value="300" />
<jsp:getProperty name="newshelper" property="content" /> <jsp:getProperty name="newshelper" property="content" />
@ -30,7 +31,8 @@ if (System.getProperty("router.consoleNonce") == null) {
<div class="main" id="main"> <div class="main" id="main">
<jsp:useBean class="net.i2p.router.web.ContentHelper" id="contenthelper" scope="request" /> <jsp:useBean class="net.i2p.router.web.ContentHelper" id="contenthelper" scope="request" />
<jsp:setProperty name="contenthelper" property="page" value="docs/readme.html" /> <% fpath = new java.io.File(net.i2p.I2PAppContext.getGlobalContext().getBaseDir(), "docs/readme.html"); %>
<jsp:setProperty name="contenthelper" property="page" value="<%=fpath.getAbsolutePath()%>" />
<jsp:setProperty name="contenthelper" property="maxLines" value="300" /> <jsp:setProperty name="contenthelper" property="maxLines" value="300" />
<jsp:setProperty name="contenthelper" property="lang" value="<%=request.getParameter("lang")%>" /> <jsp:setProperty name="contenthelper" property="lang" value="<%=request.getParameter("lang")%>" />
<jsp:getProperty name="contenthelper" property="content" /> <jsp:getProperty name="contenthelper" property="content" />

View File

@ -3,9 +3,10 @@
<a href="index.jsp"><img src="i2plogo.png" alt="Router Console" width="187" height="35" /></a><br /> <a href="index.jsp"><img src="i2plogo.png" alt="Router Console" width="187" height="35" /></a><br />
</div> </div>
<div class="toolbar"> <div class="toolbar">
<% if (new File("docs/toolbar.html").exists()) { %> <% File path = new File(net.i2p.I2PAppContext.getGlobalContext().getBaseDir(), "docs/toolbar.html");
if (path.exists()) { %>
<jsp:useBean class="net.i2p.router.web.ContentHelper" id="toolbarhelper" scope="request" /> <jsp:useBean class="net.i2p.router.web.ContentHelper" id="toolbarhelper" scope="request" />
<jsp:setProperty name="toolbarhelper" property="page" value="docs/toolbar.html" /> <jsp:setProperty name="toolbarhelper" property="page" value="<%=path.getAbsolutePath()%>" />
<jsp:setProperty name="toolbarhelper" property="maxLines" value="300" /> <jsp:setProperty name="toolbarhelper" property="maxLines" value="300" />
<jsp:getProperty name="toolbarhelper" property="content" /> <jsp:getProperty name="toolbarhelper" property="content" />
<% } else { %> <% } else { %>

View File

@ -1,4 +1,4 @@
<% <%
/* /*
* USE CAUTION WHEN EDITING * USE CAUTION WHEN EDITING
* Trailing whitespace OR NEWLINE on the last line will cause * Trailing whitespace OR NEWLINE on the last line will cause
@ -16,5 +16,7 @@ if (uri.endsWith(".css")) {
response.setContentType("image/jpeg"); response.setContentType("image/jpeg");
} }
net.i2p.util.FileUtil.readFile(uri, "./docs", response.getOutputStream()); String base = net.i2p.I2PAppContext.getGlobalContext().getBaseDir().getAbsolutePath() +
java.io.File.separatorChar + "docs";
net.i2p.util.FileUtil.readFile(uri, base, response.getOutputStream());
%> %>

View File

@ -33,12 +33,16 @@ import java.io.IOException;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.io.Serializable; import java.io.Serializable;
import net.i2p.I2PAppContext;
public class ConfigBean implements Serializable { public class ConfigBean implements Serializable {
/* /*
* as this is not provided as constant in addressbook, we define it here * as this is not provided as constant in addressbook, we define it here
*/ */
public static final String addressbookPrefix = "addressbook/"; public static final String addressbookPrefix =
(new File(I2PAppContext.getGlobalContext().getRouterDir(), "addressbook")).getAbsolutePath()
+ File.separatorChar;
public static final String configFileName = addressbookPrefix + "config.txt"; public static final String configFileName = addressbookPrefix + "config.txt";
private String action, config; private String action, config;

View File

@ -15,6 +15,7 @@
<classpath> <classpath>
<pathelement location="../jetty/jettylib/javax.servlet.jar" /> <pathelement location="../jetty/jettylib/javax.servlet.jar" />
<pathelement location="../jetty/jettylib/org.mortbay.jetty.jar" /> <pathelement location="../jetty/jettylib/org.mortbay.jetty.jar" />
<pathelement location="../../core/java/build/i2p.jar" />
</classpath> </classpath>
</javac> </javac>
</target> </target>

View File

@ -25,10 +25,13 @@ package i2p.susi.util;
import i2p.susi.debug.Debug; import i2p.susi.debug.Debug;
import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.util.Properties; import java.util.Properties;
import net.i2p.I2PAppContext;
/** /**
* @author susi * @author susi
*/ */
@ -81,7 +84,8 @@ public class Config {
} }
FileInputStream fis = null; FileInputStream fis = null;
try { try {
fis = new FileInputStream( "susimail.config" ); File cfg = new File(I2PAppContext.getGlobalContext().getConfigDir(), "susimail.config");
fis = new FileInputStream(cfg);
config.load( fis ); config.load( fis );
} catch (Exception e) { } catch (Exception e) {
Debug.debug( Debug.DEBUG, "Could not open susimail.config, reason: " + e.getMessage() ); Debug.debug( Debug.DEBUG, "Could not open susimail.config, reason: " + e.getMessage() );

View File

@ -17,6 +17,7 @@ import java.io.InputStreamReader;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import net.i2p.I2PAppContext;
import net.i2p.util.ShellCommand; import net.i2p.util.ShellCommand;
/** /**
@ -68,10 +69,11 @@ public class UrlLauncher {
String browserString = "\"C:\\Program Files\\Internet Explorer\\iexplore.exe\" -nohome"; String browserString = "\"C:\\Program Files\\Internet Explorer\\iexplore.exe\" -nohome";
BufferedReader bufferedReader = null; BufferedReader bufferedReader = null;
_shellCommand.executeSilentAndWait("regedit /E browser.reg \"HKEY_CLASSES_ROOT\\http\\shell\\open\\command\""); File foo = new File(I2PAppContext.getGlobalContext().getTempDir(), "browser.reg");
_shellCommand.executeSilentAndWait("regedit /E \"" + foo.getAbsolutePath() + "\" \"HKEY_CLASSES_ROOT\\http\\shell\\open\\command\"");
try { try {
bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream("browser.reg"), "UTF-16")); bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(foo), "UTF-16"));
for (String line; (line = bufferedReader.readLine()) != null; ) { for (String line; (line = bufferedReader.readLine()) != null; ) {
if (line.startsWith("@=")) { if (line.startsWith("@=")) {
// we should really use the whole line and replace %1 with the url // we should really use the whole line and replace %1 with the url
@ -86,7 +88,7 @@ public class UrlLauncher {
} catch (IOException e) { } catch (IOException e) {
// No worries. // No worries.
} }
new File("browser.reg").delete(); foo.delete();
} catch (Exception e) { } catch (Exception e) {
// Defaults to IE. // Defaults to IE.
} finally { } finally {

View File

@ -352,7 +352,7 @@
<copy file="build/BOB.jar" todir="pkg-temp/lib/" /> <copy file="build/BOB.jar" todir="pkg-temp/lib/" />
<copy file="build/sam.jar" todir="pkg-temp/lib/" /> <copy file="build/sam.jar" todir="pkg-temp/lib/" />
<copy file="build/i2psnark.jar" todir="pkg-temp/lib" /> <copy file="build/i2psnark.jar" todir="pkg-temp/lib" />
<!-- include systray fixes in 0.6.5 --> <!-- include systray changes in 0.7.5 -->
<copy file="build/systray.jar" todir="pkg-temp/lib/" /> <copy file="build/systray.jar" todir="pkg-temp/lib/" />
<copy file="build/susimail.war" todir="pkg-temp/webapps/" /> <copy file="build/susimail.war" todir="pkg-temp/webapps/" />
<copy file="build/susidns.war" todir="pkg-temp/webapps/" /> <copy file="build/susidns.war" todir="pkg-temp/webapps/" />

View File

@ -9,6 +9,8 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.net.URL; import java.net.URL;
import net.i2p.I2PAppContext;
/** /**
* @author Iakin * @author Iakin
* A class for retrieveing details about the CPU using the CPUID assembly instruction. * A class for retrieveing details about the CPU using the CPUID assembly instruction.
@ -503,9 +505,10 @@ public class CPUID {
FileOutputStream fos = null; FileOutputStream fos = null;
try { try {
InputStream libStream = resource.openStream(); InputStream libStream = resource.openStream();
outFile = new File(libPrefix + "jcpuid" + libSuffix); outFile = new File(I2PAppContext.getGlobalContext().getBaseDir(), libPrefix + "jcpuid" + libSuffix);
fos = new FileOutputStream(outFile); fos = new FileOutputStream(outFile);
byte buf[] = new byte[4096*1024]; // wtf this was 4096*1024 which is really excessive for a roughly 4KB file
byte buf[] = new byte[4096];
while (true) { while (true) {
int read = libStream.read(buf); int read = libStream.read(buf);
if (read < 0) break; if (read < 0) break;

View File

@ -1,5 +1,6 @@
package net.i2p; package net.i2p;
import java.io.File;
import java.util.HashSet; import java.util.HashSet;
import java.util.Properties; import java.util.Properties;
import java.util.Set; import java.util.Set;
@ -20,10 +21,12 @@ import net.i2p.crypto.KeyGenerator;
import net.i2p.crypto.SHA256Generator; import net.i2p.crypto.SHA256Generator;
import net.i2p.crypto.SessionKeyManager; import net.i2p.crypto.SessionKeyManager;
import net.i2p.crypto.TransientSessionKeyManager; import net.i2p.crypto.TransientSessionKeyManager;
import net.i2p.data.DataHelper;
import net.i2p.data.RoutingKeyGenerator; import net.i2p.data.RoutingKeyGenerator;
import net.i2p.stat.StatManager; import net.i2p.stat.StatManager;
import net.i2p.util.Clock; import net.i2p.util.Clock;
import net.i2p.util.ConcurrentHashSet; import net.i2p.util.ConcurrentHashSet;
import net.i2p.util.FileUtil;
import net.i2p.util.FortunaRandomSource; import net.i2p.util.FortunaRandomSource;
import net.i2p.util.KeyRing; import net.i2p.util.KeyRing;
import net.i2p.util.LogManager; import net.i2p.util.LogManager;
@ -96,6 +99,13 @@ public class I2PAppContext {
private volatile boolean _keyGeneratorInitialized; private volatile boolean _keyGeneratorInitialized;
protected volatile boolean _keyRingInitialized; // used in RouterContext protected volatile boolean _keyRingInitialized; // used in RouterContext
private Set<Runnable> _shutdownTasks; private Set<Runnable> _shutdownTasks;
private File _baseDir;
private File _configDir;
private File _routerDir;
private File _pidDir;
private File _logDir;
private File _appDir;
private File _tmpDir;
/** /**
@ -155,8 +165,145 @@ public class I2PAppContext {
_logManagerInitialized = false; _logManagerInitialized = false;
_keyRingInitialized = false; _keyRingInitialized = false;
_shutdownTasks = new ConcurrentHashSet(0); _shutdownTasks = new ConcurrentHashSet(0);
initializeDirs();
} }
/**
* Directories. These are all set at instantiation and will not be changed by
* subsequent property changes.
* All properties, if set, should be absolute paths.
*
* Name Property Method Files
* ----- -------- ----- -----
* Base i2p.dir.base getBaseDir() lib/, webapps/, docs/, geoip/, licenses/, ...
* Temp i2p.dir.temp getTempDir() Temporary files
* Config i2p.dir.config getConfigDir() *.config, hosts.txt, addressbook/, ...
* PID i2p.dir.pid getPIDDir() wrapper *.pid files, router.ping
*
* (the following all default to the same as Config)
*
* Router i2p.dir.router getRouterDir() netDb/, peerProfiles/, router.*, keyBackup/, ...
* Log i2p.dir.log getLogDir() wrapper.log*, logs/
* App i2p.dir.app getAppDir() eepsite/, ...
*
* Note that we can't control where the wrapper puts its files.
*
* The app dir is where all data files should be. Apps should always read and write files here,
* using a constructor such as:
*
* String path = mypath;
* File f = new File(path);
* if (!f.isAbsolute())
* f = new File(_context.geAppDir(), path);
*
* and never attempt to access files in the CWD using
*
* File f = new File("foo");
*
* An app should assume the CWD is not writable.
*
* Here in I2PAppContext, all the dirs default to CWD.
* However these will be different in RouterContext, as Router.java will set
* the properties in the RouterContext constructor.
*
* Apps should never need to access the base dir, which is the location of the base I2P install.
* However this is provided for the router's use, and for backward compatibility should an app
* need to look there as well.
*
* All dirs except the base are created if they don't exist, but the creation will fail silently.
*/
private void initializeDirs() {
String s = getProperty("i2p.dir.base", System.getProperty("user.dir"));
_baseDir = new File(s);
// config defaults to base
s = getProperty("i2p.dir.config");
if (s != null) {
_configDir = new File(s);
if (!_configDir.exists())
_configDir.mkdir();
} else {
_configDir = _baseDir;
}
_configDir = new File(s);
// router defaults to config
s = getProperty("i2p.dir.router");
if (s != null) {
_routerDir = new File(s);
if (!_routerDir.exists())
_routerDir.mkdir();
} else {
_routerDir = _configDir;
}
// pid defaults to system temp directory
s = getProperty("i2p.dir.pid", System.getProperty("java.io.tmpdir"));
_pidDir = new File(s);
if (!_pidDir.exists())
_pidDir.mkdir();
// these all default to router
s = getProperty("i2p.dir.log");
if (s != null) {
_logDir = new File(s);
if (!_logDir.exists())
_logDir.mkdir();
} else {
_logDir = _routerDir;
}
s = getProperty("i2p.dir.app");
if (s != null) {
_appDir = new File(s);
if (!_appDir.exists())
_appDir.mkdir();
} else {
_appDir = _routerDir;
}
// comment these out later, don't want user names in the wrapper logs
System.err.println("Base directory: " + _baseDir.getAbsolutePath());
System.err.println("Config directory: " + _configDir.getAbsolutePath());
System.err.println("Router directory: " + _routerDir.getAbsolutePath());
System.err.println("App directory: " + _appDir.getAbsolutePath());
System.err.println("Log directory: " + _logDir.getAbsolutePath());
System.err.println("PID directory: " + _pidDir.getAbsolutePath());
System.err.println("Temp directory: " + getTempDir().getAbsolutePath());
}
public File getBaseDir() { return _baseDir; }
public File getConfigDir() { return _configDir; }
public File getRouterDir() { return _routerDir; }
public File getPIDDir() { return _pidDir; }
public File getLogDir() { return _logDir; }
public File getAppDir() { return _appDir; }
public File getTempDir() {
// fixme don't synchronize every time
synchronized (this) {
if (_tmpDir == null) {
String d = getProperty("i2p.dir.temp", System.getProperty("java.io.tmpdir"));
// our random() probably isn't warmed up yet
String f = "i2p-" + (new java.util.Random()).nextInt() + ".tmp";
_tmpDir = new File(d, f);
if (_tmpDir.exists()) {
// good or bad ?
} else if (_tmpDir.mkdir()) {
_tmpDir.deleteOnExit();
} else {
System.err.println("Could not create temp dir " + _tmpDir.getAbsolutePath());
_tmpDir = new File(_routerDir, "tmp");
_tmpDir.mkdir();
}
}
}
return _tmpDir;
}
/** don't rely on deleteOnExit() */
public void deleteTempDir() {
synchronized (this) {
if (_tmpDir != null) {
FileUtil.rmdir(_tmpDir, false);
_tmpDir = null;
}
}
}
/** /**
* Access the configuration attributes of this context, using properties * Access the configuration attributes of this context, using properties
* provided during the context construction, or falling back on * provided during the context construction, or falling back on

View File

@ -89,7 +89,7 @@ public class HostsTxtNamingService extends NamingService {
String hostsfile = (String)filenames.get(i); String hostsfile = (String)filenames.get(i);
Properties hosts = new Properties(); Properties hosts = new Properties();
try { try {
File f = new File(hostsfile); File f = new File(_context.getRouterDir(), hostsfile);
if ( (f.exists()) && (f.canRead()) ) { if ( (f.exists()) && (f.canRead()) ) {
DataHelper.loadProps(hosts, f, true); DataHelper.loadProps(hosts, f, true);
@ -119,7 +119,7 @@ public class HostsTxtNamingService extends NamingService {
String hostsfile = (String)filenames.get(i); String hostsfile = (String)filenames.get(i);
Properties hosts = new Properties(); Properties hosts = new Properties();
try { try {
File f = new File(hostsfile); File f = new File(_context.getRouterDir(), hostsfile);
if ( (f.exists()) && (f.canRead()) ) { if ( (f.exists()) && (f.canRead()) ) {
DataHelper.loadProps(hosts, f, true); DataHelper.loadProps(hosts, f, true);
Set keyset = hosts.keySet(); Set keyset = hosts.keySet();
@ -145,7 +145,7 @@ public class HostsTxtNamingService extends NamingService {
String hostsfile = (String)filenames.get(i); String hostsfile = (String)filenames.get(i);
Properties hosts = new Properties(); Properties hosts = new Properties();
try { try {
File f = new File(hostsfile); File f = new File(_context.getRouterDir(), hostsfile);
if ( (f.exists()) && (f.canRead()) ) { if ( (f.exists()) && (f.canRead()) ) {
DataHelper.loadProps(hosts, f, true); DataHelper.loadProps(hosts, f, true);
Set keyset = hosts.keySet(); Set keyset = hosts.keySet();

View File

@ -1,6 +1,7 @@
package net.i2p.crypto; package net.i2p.crypto;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
@ -276,7 +277,7 @@ D8usM7Dxp5yrDrCYZ5AIijc=
} }
private static final void showVersionCLI(String signedFile) { private static final void showVersionCLI(String signedFile) {
String versionString = new TrustedUpdate().getVersionString(signedFile); String versionString = new TrustedUpdate().getVersionString(new File(signedFile));
if (versionString == "") if (versionString == "")
System.out.println("No version string found in file '" + signedFile + "'"); System.out.println("No version string found in file '" + signedFile + "'");
@ -294,7 +295,7 @@ D8usM7Dxp5yrDrCYZ5AIijc=
} }
private static final void verifySigCLI(String signedFile) { private static final void verifySigCLI(String signedFile) {
boolean isValidSignature = new TrustedUpdate().verify(signedFile); boolean isValidSignature = new TrustedUpdate().verify(new File(signedFile));
if (isValidSignature) if (isValidSignature)
System.out.println("Signature VALID"); System.out.println("Signature VALID");
@ -303,7 +304,7 @@ D8usM7Dxp5yrDrCYZ5AIijc=
} }
private static final void verifyUpdateCLI(String signedFile) { private static final void verifyUpdateCLI(String signedFile) {
boolean isUpdate = new TrustedUpdate().isUpdatedVersion(CoreVersion.VERSION, signedFile); boolean isUpdate = new TrustedUpdate().isUpdatedVersion(CoreVersion.VERSION, new File(signedFile));
if (isUpdate) if (isUpdate)
System.out.println("File version is newer than current version."); System.out.println("File version is newer than current version.");
@ -347,7 +348,7 @@ D8usM7Dxp5yrDrCYZ5AIijc=
* @return The version string read, or an empty string if no version string * @return The version string read, or an empty string if no version string
* is present. * is present.
*/ */
public String getVersionString(String signedFile) { public String getVersionString(File signedFile) {
FileInputStream fileInputStream = null; FileInputStream fileInputStream = null;
try { try {
@ -396,9 +397,9 @@ D8usM7Dxp5yrDrCYZ5AIijc=
* @return <code>true</code> if the signed update file's version is newer * @return <code>true</code> if the signed update file's version is newer
* than the current version, otherwise <code>false</code>. * than the current version, otherwise <code>false</code>.
*/ */
public boolean isUpdatedVersion(String currentVersion, String signedFile) { public boolean isUpdatedVersion(String currentVersion, File signedFile) {
_newVersion = getVersionString(signedFile); _newVersion = getVersionString(signedFile);
return needsUpdate(currentVersion, getVersionString(signedFile)); return needsUpdate(currentVersion, _newVersion);
} }
/** /**
@ -413,7 +414,7 @@ D8usM7Dxp5yrDrCYZ5AIijc=
* @return <code>null</code> if the signature and version were valid and the * @return <code>null</code> if the signature and version were valid and the
* data was moved, and an error <code>String</code> otherwise. * data was moved, and an error <code>String</code> otherwise.
*/ */
public String migrateVerified(String currentVersion, String signedFile, String outputFile) { public String migrateVerified(String currentVersion, File signedFile, File outputFile) {
if (!isUpdatedVersion(currentVersion, signedFile)) if (!isUpdatedVersion(currentVersion, signedFile))
return "Downloaded version is not greater than current version"; return "Downloaded version is not greater than current version";
@ -606,7 +607,7 @@ D8usM7Dxp5yrDrCYZ5AIijc=
* @return <code>true</code> if the file has a valid signature, otherwise * @return <code>true</code> if the file has a valid signature, otherwise
* <code>false</code>. * <code>false</code>.
*/ */
public boolean verify(String signedFile) { public boolean verify(File signedFile) {
for (int i = 0; i < _trustedKeys.size(); i++) { for (int i = 0; i < _trustedKeys.size(); i++) {
SigningPublicKey signingPublicKey = new SigningPublicKey(); 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 <code>true</code> if the file has a valid signature, otherwise * @return <code>true</code> if the file has a valid signature, otherwise
* <code>false</code>. * <code>false</code>.
*/ */
public boolean verify(String signedFile, SigningPublicKey signingPublicKey) { public boolean verify(File signedFile, SigningPublicKey signingPublicKey) {
FileInputStream fileInputStream = null; FileInputStream fileInputStream = null;
try { try {

View File

@ -109,6 +109,10 @@ public class PrivateKeyFile {
this(new File(file), I2PClientFactory.createClient()); this(new File(file), I2PClientFactory.createClient());
} }
public PrivateKeyFile(File file) {
this(file, I2PClientFactory.createClient());
}
public PrivateKeyFile(File file, I2PClient client) { public PrivateKeyFile(File file, I2PClient client) {
this.file = file; this.file = file;
this.client = client; this.client = client;

View File

@ -1,6 +1,7 @@
package net.i2p.stat; package net.i2p.stat;
import java.io.BufferedWriter; import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter; import java.io.FileWriter;
import java.io.IOException; import java.io.IOException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
@ -109,6 +110,9 @@ public class BufferedStatLog implements StatLog {
String filename = _context.getProperty(StatManager.PROP_STAT_FILE); String filename = _context.getProperty(StatManager.PROP_STAT_FILE);
if (filename == null) if (filename == null)
filename = StatManager.DEFAULT_STAT_FILE; 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)) ) { if ( (_outFile != null) && (_outFile.equals(filename)) ) {
// noop // noop
} else { } else {

View File

@ -18,6 +18,12 @@ import java.util.zip.ZipFile;
/** /**
* General helper methods for messing with files * 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 { public class FileUtil {
/** /**

View File

@ -67,8 +67,8 @@ public class LogManager {
/** when was the config file last read (or -1 if never) */ /** when was the config file last read (or -1 if never) */
private long _configLastRead; private long _configLastRead;
/** filename of the config file */ /** the config file */
private String _location; private File _locationFile;
/** Ordered list of LogRecord elements that have not been written out yet */ /** Ordered list of LogRecord elements that have not been written out yet */
private List _records; private List _records;
/** List of explicit overrides of log levels (LogLimit objects) */ /** List of explicit overrides of log levels (LogLimit objects) */
@ -115,11 +115,11 @@ public class LogManager {
_logs = new HashMap(128); _logs = new HashMap(128);
_defaultLimit = Log.ERROR; _defaultLimit = Log.ERROR;
_configLastRead = 0; _configLastRead = 0;
_location = context.getProperty(CONFIG_LOCATION_PROP, CONFIG_LOCATION_DEFAULT);
_context = context; _context = context;
_log = getLog(LogManager.class); _log = getLog(LogManager.class);
String location = context.getProperty(CONFIG_LOCATION_PROP, CONFIG_LOCATION_DEFAULT);
setConfig(location);
_consoleBuffer = new LogConsoleBuffer(context); _consoleBuffer = new LogConsoleBuffer(context);
loadConfig();
_writer = new LogWriter(this); _writer = new LogWriter(this);
Thread t = new I2PThread(_writer); Thread t = new I2PThread(_writer);
t.setName("LogWriter"); t.setName("LogWriter");
@ -196,8 +196,9 @@ public class LogManager {
} }
public void setConfig(String filename) { public void setConfig(String filename) {
_log.debug("Config filename set to " + filename); _locationFile = new File(filename);
_location = filename; if (!_locationFile.isAbsolute())
_locationFile = new File(_context.getConfigDir(), filename);
loadConfig(); loadConfig();
} }
@ -232,20 +233,12 @@ public class LogManager {
loadConfig(); loadConfig();
} }
///
///
//
//
//
private void loadConfig() { private void loadConfig() {
File cfgFile = new File(_location); File cfgFile = _locationFile;
if (!cfgFile.exists()) { if (!cfgFile.exists()) {
if (!_alreadyNoticedMissingConfig) { if (!_alreadyNoticedMissingConfig) {
if (_log.shouldLog(Log.WARN)) if (_log.shouldLog(Log.WARN))
_log.warn("Log file " + _location + " does not exist"); _log.warn("Log file " + _locationFile.getAbsolutePath() + " does not exist");
//System.err.println("Log file " + _location + " does not exist");
_alreadyNoticedMissingConfig = true; _alreadyNoticedMissingConfig = true;
} }
parseConfig(new Properties()); parseConfig(new Properties());
@ -262,9 +255,6 @@ public class LogManager {
return; return;
} }
if (_log.shouldLog(Log.DEBUG))
_log.debug("Loading config from " + _location);
Properties p = new Properties(); Properties p = new Properties();
FileInputStream fis = null; FileInputStream fis = null;
try { try {
@ -272,7 +262,7 @@ public class LogManager {
p.load(fis); p.load(fis);
_configLastRead = _context.clock().now(); _configLastRead = _context.clock().now();
} catch (IOException ioe) { } 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 { } finally {
if (fis != null) try { if (fis != null) try {
fis.close(); fis.close();
@ -540,7 +530,7 @@ public class LogManager {
String config = createConfig(); String config = createConfig();
FileOutputStream fos = null; FileOutputStream fos = null;
try { try {
fos = new FileOutputStream(_location); fos = new FileOutputStream(_locationFile);
fos.write(config.getBytes()); fos.write(config.getBytes());
return true; return true;
} catch (IOException ioe) { } catch (IOException ioe) {

View File

@ -15,6 +15,8 @@ import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.List; import java.util.List;
import net.i2p.I2PAppContext;
/** /**
* Log writer thread that pulls log records from the LogManager, writes them to * 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 * the current logfile, and rotates the logs as necessary. This also periodically
@ -22,6 +24,7 @@ import java.util.List;
* *
*/ */
class LogWriter implements Runnable { 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 final static long CONFIG_READ_ITERVAL = 10 * 1000;
private long _lastReadConfig = 0; private long _lastReadConfig = 0;
private long _numBytesInCurrentFile = 0; private long _numBytesInCurrentFile = 0;
@ -38,6 +41,7 @@ class LogWriter implements Runnable {
public LogWriter(LogManager manager) { public LogWriter(LogManager manager) {
_manager = manager; _manager = manager;
_lastReadConfig = Clock.getInstance().now();
} }
public void stopWriting() { public void stopWriting() {
@ -168,15 +172,21 @@ class LogWriter implements Runnable {
* *
*/ */
private File getNextFile(String pattern) { 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) ) { 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(); int max = _manager.getRotationLimit();
if (_rotationNum == -1) { if (_rotationNum == -1) {
return getFirstFile(pattern, max); return getFirstFile(base, pattern, max);
} }
// we're in rotation, just go to the next // 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 * 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++) { 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()) { if (!f.exists()) {
_rotationNum = i; _rotationNum = i;
return f; return f;
@ -202,7 +216,11 @@ class LogWriter implements Runnable {
// all exist, pick the oldest to replace // all exist, pick the oldest to replace
File oldest = null; File oldest = null;
for (int i = 0; i < max; i++) { 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) { if (oldest == null) {
oldest = f; oldest = f;
} else { } else {

View File

@ -540,9 +540,10 @@ public class NativeBigInteger extends BigInteger {
FileOutputStream fos = null; FileOutputStream fos = null;
try { try {
InputStream libStream = resource.openStream(); InputStream libStream = resource.openStream();
outFile = new File(_libPrefix + "jbigi" + _libSuffix); outFile = new File(I2PAppContext.getGlobalContext().getBaseDir(), _libPrefix + "jbigi" + _libSuffix);
fos = new FileOutputStream(outFile); 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) { while (true) {
int read = libStream.read(buf); int read = libStream.read(buf);
if (read < 0) break; if (read < 0) break;

View File

@ -142,7 +142,7 @@ public class RandomSource extends SecureRandom implements EntropyHarvester {
private static final String SEEDFILE = "prngseed.rnd"; private static final String SEEDFILE = "prngseed.rnd";
public static final void writeSeed(byte buf[]) { public static final void writeSeed(byte buf[]) {
File f = new File(SEEDFILE); File f = new File(I2PAppContext.getGlobalContext().getConfigDir(), SEEDFILE);
FileOutputStream fos = null; FileOutputStream fos = null;
try { try {
fos = new FileOutputStream(f); fos = new FileOutputStream(f);
@ -164,7 +164,7 @@ public class RandomSource extends SecureRandom implements EntropyHarvester {
} }
private static final boolean seedFromFile(String filename, byte buf[]) { 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()) { if (f.exists()) {
FileInputStream fis = null; FileInputStream fis = null;
try { try {

View File

@ -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("<!-- Modified by I2P User dir migration script -->");
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;
}
}

View File

@ -166,6 +166,8 @@ public class Blocklist {
*/ */
private void readBlocklistFile(String file) { private void readBlocklistFile(String file) {
File BLFile = new File(file); File BLFile = new File(file);
if (!BLFile.isAbsolute())
BLFile = new File(_context.getConfigDir(), file);
if (BLFile == null || (!BLFile.exists()) || BLFile.length() <= 0) { if (BLFile == null || (!BLFile.exists()) || BLFile.length() <= 0) {
if (_log.shouldLog(Log.WARN)) if (_log.shouldLog(Log.WARN))
_log.warn("Blocklist file not found: " + file); _log.warn("Blocklist file not found: " + file);
@ -701,6 +703,8 @@ public class Blocklist {
private synchronized void shitlistForever(Hash peer) { private synchronized void shitlistForever(Hash peer) {
String file = _context.getProperty(PROP_BLOCKLIST_FILE, BLOCKLIST_FILE_DEFAULT); String file = _context.getProperty(PROP_BLOCKLIST_FILE, BLOCKLIST_FILE_DEFAULT);
File BLFile = new File(file); File BLFile = new File(file);
if (!BLFile.isAbsolute())
BLFile = new File(_context.getConfigDir(), file);
if (BLFile == null || (!BLFile.exists()) || BLFile.length() <= 0) { if (BLFile == null || (!BLFile.exists()) || BLFile.length() <= 0) {
if (_log.shouldLog(Log.ERROR)) if (_log.shouldLog(Log.ERROR))
_log.error("Blocklist file not found: " + file); _log.error("Blocklist file not found: " + file);

View File

@ -147,10 +147,8 @@ public class KeyManager {
super(KeyManager.this._context); super(KeyManager.this._context);
} }
public void runJob() { public void runJob() {
String keyDir = getContext().getProperty(PROP_KEYDIR); String keyDir = getContext().getProperty(PROP_KEYDIR, DEFAULT_KEYDIR);
if (keyDir == null) File dir = new File(getContext().getRouterDir(), keyDir);
keyDir = DEFAULT_KEYDIR;
File dir = new File(keyDir);
if (!dir.exists()) if (!dir.exists())
dir.mkdirs(); dir.mkdirs();
if (dir.exists() && dir.isDirectory() && dir.canRead() && dir.canWrite()) { if (dir.exists() && dir.isDirectory() && dir.canRead() && dir.canWrite()) {

View File

@ -44,6 +44,7 @@ import net.i2p.util.I2PThread;
import net.i2p.util.Log; import net.i2p.util.Log;
import net.i2p.util.SimpleScheduler; import net.i2p.util.SimpleScheduler;
import net.i2p.util.SimpleTimer; import net.i2p.util.SimpleTimer;
import net.i2p.util.WorkingDir;
/** /**
* Main driver for the router. * Main driver for the router.
@ -53,6 +54,7 @@ public class Router {
private Log _log; private Log _log;
private RouterContext _context; private RouterContext _context;
private final Properties _config; private final Properties _config;
/** full path */
private String _configFilename; private String _configFilename;
private RouterInfo _routerInfo; private RouterInfo _routerInfo;
private long _started; private long _started;
@ -104,14 +106,6 @@ public class Router {
public Router(Properties envProps) { this(null, envProps); } public Router(Properties envProps) { this(null, envProps); }
public Router(String configFilename) { this(configFilename, null); } public Router(String configFilename) { this(configFilename, null); }
public Router(String configFilename, Properties envProps) { 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; _gracefulExitCode = -1;
_config = new Properties(); _config = new Properties();
@ -125,7 +119,35 @@ public class Router {
_configFilename = configFilename; _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(); readConfig();
if (envProps == null) { if (envProps == null) {
envProps = _config; envProps = _config;
} else { } else {
@ -135,11 +157,42 @@ public class Router {
envProps.setProperty(k, v); envProps.setProperty(k, v);
} }
} }
// This doesn't work, guess it has to be in the static block above? // This doesn't work, guess it has to be in the static block above?
// if (Boolean.valueOf(envProps.getProperty("router.disableIPv6")).booleanValue()) // if (Boolean.valueOf(envProps.getProperty("router.disableIPv6")).booleanValue())
// System.setProperty("java.net.preferIPv4Stack", "true"); // 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); _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; _routerInfo = null;
_higherVersionSeen = false; _higherVersionSeen = false;
_log = _context.logManager().getLog(Router.class); _log = _context.logManager().getLog(Router.class);
@ -245,6 +298,7 @@ public class Router {
_context.keyManager().startup(); _context.keyManager().startup();
// why are we reading this again, it's read in the constructor
readConfig(); readConfig();
setupHandlers(); 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) { private static Properties getConfig(RouterContext ctx, String filename) {
Log log = null; Log log = null;
if (ctx != null) { if (ctx != null) {
@ -456,11 +511,11 @@ public class Router {
}; };
static final String IDENTLOG = "identlog.txt"; static final String IDENTLOG = "identlog.txt";
public static void killKeys() { public void killKeys() {
new Exception("Clearing identity files").printStackTrace(); new Exception("Clearing identity files").printStackTrace();
int remCount = 0; int remCount = 0;
for (int i = 0; i < _rebuildFiles.length; i++) { 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()) { if (f.exists()) {
boolean removed = f.delete(); boolean removed = f.delete();
if (removed) { if (removed) {
@ -474,7 +529,7 @@ public class Router {
if (remCount > 0) { if (remCount > 0) {
FileOutputStream log = null; FileOutputStream log = null;
try { 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()); log.write((new Date() + ": Old router identity keys cleared\n").getBytes());
} catch (IOException ioe) { } catch (IOException ioe) {
// ignore // 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.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 { _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); } //try { _sessionKeyPersistenceHelper.shutdown(); } catch (Throwable t) { _log.log(Log.CRIT, "Error shutting down the session key manager", t); }
_context.deleteTempDir();
RouterContext.listContexts().remove(_context); RouterContext.listContexts().remove(_context);
dumpStats(); //dumpStats();
finalShutdown(exitCode); finalShutdown(exitCode);
} }
@ -833,7 +889,7 @@ public class Router {
killKeys(); killKeys();
} }
File f = new File(getPingFile()); File f = getPingFile();
f.delete(); f.delete();
if (_killVMOnEnd) { if (_killVMOnEnd) {
try { Thread.sleep(1000); } catch (InterruptedException ie) {} try { Thread.sleep(1000); } catch (InterruptedException ie) {}
@ -1003,8 +1059,9 @@ public class Router {
public static void main(String args[]) { public static void main(String args[]) {
System.out.println("Starting I2P " + RouterVersion.FULL_VERSION); System.out.println("Starting I2P " + RouterVersion.FULL_VERSION);
installUpdates(); // installUpdates() moved to constructor so we can get file locations from the context
verifyWrapperConfig(); // installUpdates();
//verifyWrapperConfig();
Router r = new Router(); Router r = new Router();
if ( (args != null) && (args.length == 1) && ("rebuild".equals(args[0])) ) { if ( (args != null) && (args.length == 1) && ("rebuild".equals(args[0])) ) {
r.rebuildNewIdentity(); r.rebuildNewIdentity();
@ -1015,19 +1072,51 @@ public class Router {
public static final String UPDATE_FILE = "i2pupdate.zip"; public static final String UPDATE_FILE = "i2pupdate.zip";
private static void installUpdates() { /**
File updateFile = new File(UPDATE_FILE); * Unzip update file found in the router dir OR base dir, to the base dir
if (updateFile.exists()) { *
* If we can't write to the base dir, complain.
* Note: _log not available here.
*/
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) {
// do a simple permissions test, if it fails leave the file in place and don't restart
File test = new File(_context.getBaseDir(), "history.txt");
if ((test.exists() && !test.canWrite()) || (!_context.getBaseDir().canWrite())) {
System.out.println("ERROR: No write permissions on " + _context.getBaseDir() +
" to extract software update file");
// carry on
return;
}
System.out.println("INFO: Update file exists [" + UPDATE_FILE + "] - installing"); 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) if (ok)
System.out.println("INFO: Update installed"); System.out.println("INFO: Update installed");
else else
System.out.println("ERROR: Update failed!"); System.out.println("ERROR: Update failed!");
boolean deleted = updateFile.delete(); if (!ok) {
if (!deleted) { // we can't leave the file in place or we'll continually restart, so rename it
System.out.println("ERROR: Unable to delete the update file!"); File bad = new File(_context.getRouterDir(), "BAD-" + UPDATE_FILE);
updateFile.deleteOnExit(); boolean renamed = updateFile.renameTo(bad);
if (renamed) {
System.out.println("Moved update file to " + bad.getAbsolutePath());
} else {
System.out.println("Deleting file " + updateFile.getAbsolutePath());
ok = true; // so it will be deleted
}
}
if (ok) {
boolean deleted = updateFile.delete();
if (!deleted) {
System.out.println("ERROR: Unable to delete the update file!");
updateFile.deleteOnExit();
}
} }
if (System.getProperty("wrapper.version") != null) if (System.getProperty("wrapper.version") != null)
System.out.println("INFO: Restarting after update"); System.out.println("INFO: Restarting after update");
@ -1037,6 +1126,7 @@ public class Router {
} }
} }
/*******
private static void verifyWrapperConfig() { private static void verifyWrapperConfig() {
File cfgUpdated = new File("wrapper.config.updated"); File cfgUpdated = new File("wrapper.config.updated");
if (cfgUpdated.exists()) { if (cfgUpdated.exists()) {
@ -1046,15 +1136,22 @@ public class Router {
System.exit(EXIT_HARD); System.exit(EXIT_HARD);
} }
} }
*******/
/*
private static String getPingFile(Properties envProps) { private static String getPingFile(Properties envProps) {
if (envProps != null) if (envProps != null)
return envProps.getProperty("router.pingFile", "router.ping"); return envProps.getProperty("router.pingFile", "router.ping");
else else
return "router.ping"; 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; static final long LIVELINESS_DELAY = 60*1000;
@ -1066,9 +1163,8 @@ public class Router {
* *
* @return true if the router is the only one running * @return true if the router is the only one running
*/ */
private boolean beginMarkingLiveliness(Properties envProps) { private boolean beginMarkingLiveliness() {
String filename = getPingFile(envProps); File f = getPingFile();
File f = new File(filename);
if (f.exists()) { if (f.exists()) {
long lastWritten = f.lastModified(); long lastWritten = f.lastModified();
if (System.currentTimeMillis()-lastWritten > LIVELINESS_DELAY) { if (System.currentTimeMillis()-lastWritten > LIVELINESS_DELAY) {
@ -1376,15 +1472,14 @@ private static class PersistRouterInfoJob extends JobImpl {
if (_log.shouldLog(Log.DEBUG)) if (_log.shouldLog(Log.DEBUG))
_log.debug("Persisting updated router info"); _log.debug("Persisting updated router info");
String infoFilename = getContext().getProperty(Router.PROP_INFO_FILENAME); String infoFilename = getContext().getProperty(PROP_INFO_FILENAME, PROP_INFO_FILENAME_DEFAULT);
if (infoFilename == null) File infoFile = new File(getContext().getRouterDir(), infoFilename);
infoFilename = Router.PROP_INFO_FILENAME_DEFAULT;
RouterInfo info = getContext().router().getRouterInfo(); RouterInfo info = getContext().router().getRouterInfo();
FileOutputStream fos = null; FileOutputStream fos = null;
try { try {
fos = new FileOutputStream(infoFilename); fos = new FileOutputStream(infoFile);
info.writeBytes(fos); info.writeBytes(fos);
} catch (DataFormatException dfe) { } catch (DataFormatException dfe) {
_log.error("Error rebuilding the router information", dfe); _log.error("Error rebuilding the router information", dfe);

View File

@ -70,7 +70,11 @@ public class RouterContext extends I2PAppContext {
public RouterContext(Router router, Properties envProps) { public RouterContext(Router router, Properties envProps) {
super(filterProps(envProps)); super(filterProps(envProps));
_router = router; _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); _contexts.add(this);
} }
/** /**
@ -86,7 +90,7 @@ public class RouterContext extends I2PAppContext {
envProps.setProperty("time.disabled", "false"); envProps.setProperty("time.disabled", "false");
return envProps; return envProps;
} }
private void initAll() { public void initAll() {
//_adminManager = new AdminManager(this); //_adminManager = new AdminManager(this);
if ("false".equals(getProperty("i2p.dummyClientFacade", "false"))) if ("false".equals(getProperty("i2p.dummyClientFacade", "false")))
_clientManagerFacade = new ClientManagerFacadeImpl(this); _clientManagerFacade = new ClientManagerFacadeImpl(this);

View File

@ -410,7 +410,7 @@ class PersistentDataStore extends TransientDataStore {
private File getDbDir() throws IOException { private File getDbDir() throws IOException {
File f = new File(_dbDir); File f = new File(_context.getRouterDir(), _dbDir);
if (!f.exists()) { if (!f.exists()) {
boolean created = f.mkdirs(); boolean created = f.mkdirs();
if (!created) if (!created)

View File

@ -297,18 +297,8 @@ class ProfilePersistenceHelper {
private File getProfileDir() { private File getProfileDir() {
if (_profileDir == null) { if (_profileDir == null) {
String dir = null; String dir = _context.getProperty(PROP_PEER_PROFILE_DIR, DEFAULT_PEER_PROFILE_DIR);
if (_context.router() == null) { _profileDir = new File(_context.getRouterDir(), dir);
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);
} }
return _profileDir; return _profileDir;
} }

View File

@ -43,6 +43,8 @@ public class ClientAppConfig {
Properties rv = new Properties(); Properties rv = new Properties();
String clientConfigFile = ctx.getProperty(PROP_CLIENT_CONFIG_FILENAME, DEFAULT_CLIENT_CONFIG_FILENAME); String clientConfigFile = ctx.getProperty(PROP_CLIENT_CONFIG_FILENAME, DEFAULT_CLIENT_CONFIG_FILENAME);
File cfgFile = new File(clientConfigFile); File cfgFile = new File(clientConfigFile);
if (!cfgFile.isAbsolute())
cfgFile = new File(ctx.getConfigDir(), clientConfigFile);
// fall back to use router.config's clientApp.* lines // fall back to use router.config's clientApp.* lines
if (!cfgFile.exists()) if (!cfgFile.exists())
@ -91,9 +93,12 @@ public class ClientAppConfig {
public static void writeClientAppConfig(RouterContext ctx, List apps) { public static void writeClientAppConfig(RouterContext ctx, List apps) {
String clientConfigFile = ctx.getProperty(PROP_CLIENT_CONFIG_FILENAME, DEFAULT_CLIENT_CONFIG_FILENAME); 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; FileOutputStream fos = null;
try { try {
fos = new FileOutputStream(clientConfigFile); fos = new FileOutputStream(cfgFile);
StringBuffer buf = new StringBuffer(2048); StringBuffer buf = new StringBuffer(2048);
for(int i = 0; i < apps.size(); i++) { for(int i = 0; i < apps.size(); i++) {
ClientAppConfig app = (ClientAppConfig) apps.get(i); ClientAppConfig app = (ClientAppConfig) apps.get(i);

View File

@ -8,6 +8,7 @@ package net.i2p.router.startup;
* *
*/ */
import java.io.File;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.util.HashSet; import java.util.HashSet;
@ -76,16 +77,14 @@ public class CreateRouterInfoJob extends JobImpl {
info.sign(signingPrivKey); info.sign(signingPrivKey);
String infoFilename = getContext().router().getConfigSetting(Router.PROP_INFO_FILENAME); String infoFilename = getContext().getProperty(Router.PROP_INFO_FILENAME, Router.PROP_INFO_FILENAME_DEFAULT);
if (infoFilename == null) File ifile = new File(getContext().getRouterDir(), infoFilename);
infoFilename = Router.PROP_INFO_FILENAME_DEFAULT; fos1 = new FileOutputStream(ifile);
fos1 = new FileOutputStream(infoFilename);
info.writeBytes(fos1); info.writeBytes(fos1);
String keyFilename = getContext().router().getConfigSetting(Router.PROP_KEYS_FILENAME); String keyFilename = getContext().getProperty(Router.PROP_KEYS_FILENAME, Router.PROP_KEYS_FILENAME_DEFAULT);
if (keyFilename == null) File kfile = new File(getContext().getRouterDir(), keyFilename);
keyFilename = Router.PROP_KEYS_FILENAME_DEFAULT; fos2 = new FileOutputStream(kfile);
fos2 = new FileOutputStream(keyFilename);
privkey.writeBytes(fos2); privkey.writeBytes(fos2);
signingPrivKey.writeBytes(fos2); signingPrivKey.writeBytes(fos2);
pubkey.writeBytes(fos2); pubkey.writeBytes(fos2);
@ -96,7 +95,7 @@ public class CreateRouterInfoJob extends JobImpl {
getContext().keyManager().setPrivateKey(privkey); getContext().keyManager().setPrivateKey(privkey);
getContext().keyManager().setPublicKey(pubkey); 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) { } catch (DataFormatException dfe) {
_log.error("Error building the new router information", dfe); _log.error("Error building the new router information", dfe);
} catch (IOException ioe) { } catch (IOException ioe) {

View File

@ -51,21 +51,17 @@ public class LoadRouterInfoJob extends JobImpl {
} }
private void loadRouterInfo() { private void loadRouterInfo() {
String routerInfoFile = getContext().router().getConfigSetting(Router.PROP_INFO_FILENAME); String routerInfoFile = getContext().getProperty(Router.PROP_INFO_FILENAME, Router.PROP_INFO_FILENAME_DEFAULT);
if (routerInfoFile == null)
routerInfoFile = Router.PROP_INFO_FILENAME_DEFAULT;
RouterInfo info = null; RouterInfo info = null;
boolean failedRead = false; boolean failedRead = false;
String keyFilename = getContext().router().getConfigSetting(Router.PROP_KEYS_FILENAME); String keyFilename = getContext().getProperty(Router.PROP_KEYS_FILENAME, Router.PROP_KEYS_FILENAME_DEFAULT);
if (keyFilename == null)
keyFilename = Router.PROP_KEYS_FILENAME_DEFAULT;
File rif = new File(routerInfoFile); File rif = new File(getContext().getRouterDir(), routerInfoFile);
if (rif.exists()) if (rif.exists())
_infoExists = true; _infoExists = true;
File rkf = new File(keyFilename); File rkf = new File(getContext().getRouterDir(), keyFilename);
if (rkf.exists()) if (rkf.exists())
_keysExist = true; _keysExist = true;
@ -98,14 +94,14 @@ public class LoadRouterInfoJob extends JobImpl {
_us = info; _us = info;
} catch (IOException ioe) { } 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; _us = null;
rif.delete(); rif.delete();
rkf.delete(); rkf.delete();
_infoExists = false; _infoExists = false;
_keysExist = false; _keysExist = false;
} catch (DataFormatException dfe) { } 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; _us = null;
rif.delete(); rif.delete();
rkf.delete(); rkf.delete();

View File

@ -57,18 +57,11 @@ public class RebuildRouterInfoJob extends JobImpl {
public void runJob() { public void runJob() {
_log.debug("Testing to rebuild router info"); _log.debug("Testing to rebuild router info");
String infoFile = getContext().router().getConfigSetting(Router.PROP_INFO_FILENAME); String infoFile = getContext().getProperty(Router.PROP_INFO_FILENAME, Router.PROP_INFO_FILENAME_DEFAULT);
if (infoFile == null) { File info = new File(getContext().getRouterDir(), infoFile);
_log.debug("Info filename not configured, defaulting to " + Router.PROP_INFO_FILENAME_DEFAULT); String keyFilename = getContext().getProperty(Router.PROP_KEYS_FILENAME, Router.PROP_KEYS_FILENAME_DEFAULT);
infoFile = Router.PROP_INFO_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()) { if (!info.exists() || !keyFile.exists()) {
_log.info("Router info file [" + info.getAbsolutePath() + "] or private key file [" + keyFile.getAbsolutePath() + "] deleted, rebuilding"); _log.info("Router info file [" + info.getAbsolutePath() + "] or private key file [" + keyFile.getAbsolutePath() + "] deleted, rebuilding");
rebuildRouterInfo(); rebuildRouterInfo();
@ -86,14 +79,10 @@ public class RebuildRouterInfoJob extends JobImpl {
_log.debug("Rebuilding the new router info"); _log.debug("Rebuilding the new router info");
boolean fullRebuild = false; boolean fullRebuild = false;
RouterInfo info = null; RouterInfo info = null;
String infoFilename = getContext().router().getConfigSetting(Router.PROP_INFO_FILENAME); String infoFilename = getContext().getProperty(Router.PROP_INFO_FILENAME, Router.PROP_INFO_FILENAME_DEFAULT);
if (infoFilename == null) File infoFile = new File(getContext().getRouterDir(), infoFilename);
infoFilename = Router.PROP_INFO_FILENAME_DEFAULT; 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);
if (keyFile.exists()) { if (keyFile.exists()) {
// ok, no need to rebuild a brand new identity, just update what we can // 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; FileOutputStream fos = null;
try { try {
fos = new FileOutputStream(infoFilename); fos = new FileOutputStream(infoFile);
info.writeBytes(fos); info.writeBytes(fos);
} catch (DataFormatException dfe) { } catch (DataFormatException dfe) {
_log.error("Error rebuilding the router information", dfe); _log.error("Error rebuilding the router information", dfe);

View File

@ -130,7 +130,8 @@ public class GeoIP {
* *
*/ */
private void readCountryFile() { 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 (GeoFile == null || (!GeoFile.exists())) {
if (_log.shouldLog(Log.WARN)) if (_log.shouldLog(Log.WARN))
_log.warn("Country file not found: " + GeoFile.getAbsolutePath()); _log.warn("Country file not found: " + GeoFile.getAbsolutePath());
@ -188,7 +189,8 @@ public class GeoIP {
* *
*/ */
private String[] readGeoIPFile(Long[] search) { 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 (GeoFile == null || (!GeoFile.exists())) {
if (_log.shouldLog(Log.WARN)) if (_log.shouldLog(Log.WARN))
_log.warn("GeoIP file not found: " + GeoFile.getAbsolutePath()); _log.warn("GeoIP file not found: " + GeoFile.getAbsolutePath());