From be9523f1e4b311310090145b84fa482aaed82ba2 Mon Sep 17 00:00:00 2001
From: zzz <zzz@mail.i2p>
Date: Mon, 17 Aug 2009 22:14:39 +0000
Subject: [PATCH]     * Config files: Add some encoding help     * DataHelper,
 Router:       - Save config files in UTF-8 rather than the default encoding, 
        since we read them in UTF-8     * jetty.xml: Change encoding to UTF-8 
    * logs.jsp: Add system encoding     * NTCP: Clean up clock skew shitlist
 message     * Shitlist: Clean up expire message     * WorkingDir: Ensure
 modified files are processed with UTF-8 encoding

---
 .../java/src/addressbook/ConfigParser.java           |  3 +++
 apps/i2psnark/i2psnark.config                        |  1 +
 apps/routerconsole/jsp/logs.jsp                      |  1 +
 core/java/src/net/i2p/data/DataHelper.java           | 12 ++++++++++--
 installer/resources/clients.config                   |  1 +
 installer/resources/i2ptunnel.config                 |  1 +
 installer/resources/jetty.xml                        |  9 ++++++++-
 router/java/src/net/i2p/router/Router.java           |  7 ++++++-
 router/java/src/net/i2p/router/Shitlist.java         |  8 ++++++--
 .../java/src/net/i2p/router/startup/WorkingDir.java  |  7 ++++---
 .../i2p/router/transport/ntcp/EstablishState.java    |  3 ++-
 11 files changed, 43 insertions(+), 10 deletions(-)

diff --git a/apps/addressbook/java/src/addressbook/ConfigParser.java b/apps/addressbook/java/src/addressbook/ConfigParser.java
index 5d5cd533f2..7fbb214f08 100644
--- a/apps/addressbook/java/src/addressbook/ConfigParser.java
+++ b/apps/addressbook/java/src/addressbook/ConfigParser.java
@@ -39,6 +39,9 @@ import java.util.Map;
  * Utility class providing methods to parse and write files in config file
  * format, and subscription file format.
  * 
+ * TODO: Change file encoding from default to UTF-8?
+ *       Or switch to the DataHelper loadProps/storeProps methods?
+ * 
  * @author Ragnarok
  */
 public class ConfigParser {
diff --git a/apps/i2psnark/i2psnark.config b/apps/i2psnark/i2psnark.config
index 525046ac6a..06cba603ce 100644
--- a/apps/i2psnark/i2psnark.config
+++ b/apps/i2psnark/i2psnark.config
@@ -1,3 +1,4 @@
+# NOTE: This I2P config file must use UTF-8 encoding
 #
 # If you have a 'split' directory installation, with configuration
 # files in ~/.i2p (Linux) or %APPDATA%\I2P (Windows), be sure to
diff --git a/apps/routerconsole/jsp/logs.jsp b/apps/routerconsole/jsp/logs.jsp
index d9e9886bf7..0bfa685fa5 100644
--- a/apps/routerconsole/jsp/logs.jsp
+++ b/apps/routerconsole/jsp/logs.jsp
@@ -19,6 +19,7 @@ I2P <jsp:getProperty name="helper" property="version" /><br />
 <%=System.getProperty("os.name")%> <%=System.getProperty("os.arch")%> <%=System.getProperty("os.version")%><br />
 CPU <%=net.i2p.util.NativeBigInteger.cpuModel()%> (<%=net.i2p.util.NativeBigInteger.cpuType()%>)<br />
 jbigi <%=net.i2p.util.NativeBigInteger.loadStatus()%><br />
+Encoding <%=System.getProperty("file.encoding")%><br>
  </p>
  <hr />
  <jsp:useBean class="net.i2p.router.web.LogsHelper" id="logsHelper" scope="request" />
diff --git a/core/java/src/net/i2p/data/DataHelper.java b/core/java/src/net/i2p/data/DataHelper.java
index ef0b89fc24..0f48efef2d 100644
--- a/core/java/src/net/i2p/data/DataHelper.java
+++ b/core/java/src/net/i2p/data/DataHelper.java
@@ -17,11 +17,12 @@ import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.FileInputStream;
-import java.io.FileWriter;
+import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.OutputStream;
+import java.io.OutputStreamWriter;
 import java.io.PrintWriter;
 import java.io.UnsupportedEncodingException;
 import java.math.BigInteger;
@@ -217,6 +218,9 @@ public class DataHelper {
      * - '#' or ';' starts a comment line, but '!' does not
      * - Leading whitespace is not trimmed
      * - '=' is the only key-termination character (not ':' or whitespace)
+     *
+     * Note that the escaping of \r or \n was probably a mistake and should be taken out.
+     *
      */
     public static void loadProps(Properties props, File file) throws IOException {
         loadProps(props, file, false);
@@ -257,10 +261,14 @@ public class DataHelper {
         }
     }
     
+    /**
+     * Note that this does not escape the \r or \n that are unescaped in loadProps() above.
+     */
     public static void storeProps(Properties props, File file) throws IOException {
         PrintWriter out = null;
         try {
-            out = new PrintWriter(new BufferedWriter(new FileWriter(file)));
+            out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF-8")));
+            out.println("# NOTE: This I2P config file must use UTF-8 encoding");
             for (Iterator iter = props.keySet().iterator(); iter.hasNext(); ) {
                 String name = (String)iter.next();
                 String val = props.getProperty(name);
diff --git a/installer/resources/clients.config b/installer/resources/clients.config
index 88cc115f81..3f8add8e5f 100644
--- a/installer/resources/clients.config
+++ b/installer/resources/clients.config
@@ -1,3 +1,4 @@
+# NOTE: This I2P config file must use UTF-8 encoding
 #
 # If you have a 'split' directory installation, with configuration
 # files in ~/.i2p (Linux) or %APPDATA%\I2P (Windows), be sure to
diff --git a/installer/resources/i2ptunnel.config b/installer/resources/i2ptunnel.config
index db79ef5af8..6412a37e49 100644
--- a/installer/resources/i2ptunnel.config
+++ b/installer/resources/i2ptunnel.config
@@ -1,3 +1,4 @@
+# NOTE: This I2P config file must use UTF-8 encoding
 #
 # If you have a 'split' directory installation, with configuration
 # files in ~/.i2p (Linux) or %APPDATA%\I2P (Windows), be sure to
diff --git a/installer/resources/jetty.xml b/installer/resources/jetty.xml
index a9c04d9644..9ff09e0bb2 100644
--- a/installer/resources/jetty.xml
+++ b/installer/resources/jetty.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="ISO-8859-1" ?> 
+<?xml version="1.0" encoding="UTF-8" ?> 
 <!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure 1.2//EN" "http://jetty.mortbay.org/configure_1_2.dtd">
 
 <!-- ========================================================================= -->
@@ -26,6 +26,13 @@
 <!--                                                                           -->
 <!-- Jetty errors and warnings will appear in wrapper.log, check there         -->
 <!-- to diagnose problems.                                                     -->
+<!--                                                                           -->
+<!-- Note that the XML encoding for this file is UTF-8.                        -->
+<!--                                                                           -->
+<!-- If you have a 'split' directory installation, with configuration          -->
+<!-- files in ~/.i2p (Linux) or %APPDATA%\I2P (Windows), be sure to            -->
+<!-- edit the file in the configuration directory, NOT the install directory.  -->
+<!--                                                                           -->
 <!-- ========================================================================= -->
 
 <!-- =============================================================== -->
diff --git a/router/java/src/net/i2p/router/Router.java b/router/java/src/net/i2p/router/Router.java
index 7e472cd096..ca01ca666c 100644
--- a/router/java/src/net/i2p/router/Router.java
+++ b/router/java/src/net/i2p/router/Router.java
@@ -1013,12 +1013,17 @@ public class Router {
      * Save the current config options (returning true if save was 
      * successful, false otherwise)
      *
+     * Note that unlike DataHelper.storeProps(),
+     * this does escape the \r or \n that are unescaped in DataHelper.loadProps().
+     * Note that the escaping of \r or \n was probably a mistake and should be taken out.
+     *
      */
     public boolean saveConfig() {
         FileOutputStream fos = null;
         try {
             fos = new FileOutputStream(_configFilename);
             StringBuilder buf = new StringBuilder(8*1024);
+            buf.append("# NOTE: This I2P config file must use UTF-8 encoding\n");
             synchronized (_config) {
                 TreeSet ordered = new TreeSet(_config.keySet());
                 for (Iterator iter = ordered.iterator() ; iter.hasNext(); ) {
@@ -1031,7 +1036,7 @@ public class Router {
                     buf.append(key).append('=').append(val).append('\n');
                 }
             }
-            fos.write(buf.toString().getBytes());
+            fos.write(buf.toString().getBytes("UTF-8"));
         } catch (IOException ioe) {
             if (_log.shouldLog(Log.ERROR))
                 _log.error("Error saving the config to " + _configFilename, ioe);
diff --git a/router/java/src/net/i2p/router/Shitlist.java b/router/java/src/net/i2p/router/Shitlist.java
index d1307fdea7..d5a5567331 100644
--- a/router/java/src/net/i2p/router/Shitlist.java
+++ b/router/java/src/net/i2p/router/Shitlist.java
@@ -264,8 +264,12 @@ public class Shitlist {
             Hash key = e.getKey();
             Entry entry = e.getValue();
             buf.append("<li>").append(_context.commSystem().renderPeerHTML(key));
-            buf.append(" expiring in ");
-            buf.append(DataHelper.formatDuration(entry.expireOn-_context.clock().now()));
+            long expires = entry.expireOn-_context.clock().now();
+            if (expires < 5l*24*60*60*1000)
+                buf.append(" Temporary ban expiring in ");
+            else
+                buf.append(" Banned until restart or in ");
+            buf.append(DataHelper.formatDuration(expires));
             Set transports = entry.transports;
             if ( (transports != null) && (transports.size() > 0) )
                 buf.append(" on the following transport: ").append(transports);
diff --git a/router/java/src/net/i2p/router/startup/WorkingDir.java b/router/java/src/net/i2p/router/startup/WorkingDir.java
index 50833de737..5110c02e58 100644
--- a/router/java/src/net/i2p/router/startup/WorkingDir.java
+++ b/router/java/src/net/i2p/router/startup/WorkingDir.java
@@ -4,8 +4,9 @@ import java.io.BufferedWriter;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
-import java.io.FileWriter;
+import java.io.OutputStreamWriter;
 import java.io.IOException;
+import java.io.OutputStreamWriter;
 import java.io.PrintWriter;
 import java.util.Properties;
 
@@ -190,7 +191,7 @@ public class WorkingDir {
         PrintWriter out = null;
         try {
             in = new FileInputStream(oldFile);
-            out = new PrintWriter(new BufferedWriter(new FileWriter(newFile)));
+            out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(newFile), "UTF-8")));
             out.println("# Modified by I2P User dir migration script");
             String s = null;
             while ((s = DataHelper.readLine(in)) != null) {
@@ -229,7 +230,7 @@ public class WorkingDir {
         PrintWriter out = null;
         try {
             in = new FileInputStream(oldFile);
-            out = new PrintWriter(new BufferedWriter(new FileWriter(newFile)));
+            out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(newFile), "UTF-8")));
             String s = null;
             while ((s = DataHelper.readLine(in)) != null) {
                 if (s.indexOf("./eepsite/") >= 0) {
diff --git a/router/java/src/net/i2p/router/transport/ntcp/EstablishState.java b/router/java/src/net/i2p/router/transport/ntcp/EstablishState.java
index 89d1cf85b8..e204a5750a 100644
--- a/router/java/src/net/i2p/router/transport/ntcp/EstablishState.java
+++ b/router/java/src/net/i2p/router/transport/ntcp/EstablishState.java
@@ -368,7 +368,8 @@ public class EstablishState {
                 if (diff >= Router.CLOCK_FUDGE_FACTOR) {
                     _context.statManager().addRateData("ntcp.invalidOutboundSkew", diff, 0);
                     _transport.markReachable(_con.getRemotePeer().calculateHash(), false);
-                    _context.shitlist().shitlistRouter(_con.getRemotePeer().calculateHash(), "Outbound clock skew of " + diff + " ms");
+                    _context.shitlist().shitlistRouter(_con.getRemotePeer().calculateHash(),
+                                                       "Excessive clock skew: " + DataHelper.formatDuration(diff));
                     fail("Clocks too skewed (" + diff + " ms)", null, true);
                     return;
                 } else if (_log.shouldLog(Log.DEBUG)) {
-- 
GitLab