From c8a73b63fdb837609a95a6e0df81c8701a3a12a4 Mon Sep 17 00:00:00 2001
From: str4d <str4d@mail.i2p>
Date: Sat, 21 Jul 2012 10:07:04 +0000
Subject: [PATCH] Added methods to read and write properties in arbitrary
 config files

---
 core/java/src/net/i2p/I2PAppContext.java | 80 ++++++++++++++++++++++++
 1 file changed, 80 insertions(+)

diff --git a/core/java/src/net/i2p/I2PAppContext.java b/core/java/src/net/i2p/I2PAppContext.java
index 313f6e445e..6909f23fc9 100644
--- a/core/java/src/net/i2p/I2PAppContext.java
+++ b/core/java/src/net/i2p/I2PAppContext.java
@@ -1,11 +1,15 @@
 package net.i2p;
 
 import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
 import java.util.Collections;
 import java.util.HashSet;
+import java.util.Iterator;
 import java.util.Properties;
 import java.util.Random;
 import java.util.Set;
+import java.util.TreeSet;
 
 import net.i2p.client.naming.NamingService;
 import net.i2p.crypto.AESEngine;
@@ -23,6 +27,7 @@ import net.i2p.crypto.SHA256Generator;
 import net.i2p.crypto.SessionKeyManager;
 import net.i2p.crypto.TransientSessionKeyManager;
 import net.i2p.data.Base64;
+import net.i2p.data.DataHelper;
 import net.i2p.data.RoutingKeyGenerator;
 import net.i2p.internal.InternalClientManager;
 import net.i2p.stat.StatManager;
@@ -32,11 +37,13 @@ import net.i2p.util.FileUtil;
 import net.i2p.util.FortunaRandomSource;
 import net.i2p.util.I2PProperties;
 import net.i2p.util.KeyRing;
+import net.i2p.util.Log;
 import net.i2p.util.LogManager;
 //import net.i2p.util.PooledRandomSource;
 import net.i2p.util.PortMapper;
 import net.i2p.util.RandomSource;
 import net.i2p.util.SecureDirectory;
+import net.i2p.util.SecureFileOutputStream;
 import net.i2p.util.SimpleScheduler;
 import net.i2p.util.SimpleTimer;
 import net.i2p.util.SimpleTimer2;
@@ -430,6 +437,79 @@ public class I2PAppContext {
         }
     }
 
+    /**
+     * Read config properties from a file
+     * @return the config properties
+     * @since 0.9.2
+     */
+    public Properties readConfigFile(String configFilename) {
+        Log log = logManager().getLog(I2PAppContext.class);
+        if (log.shouldLog(Log.DEBUG))
+            log.debug("Config file: " + configFilename, new Exception("location"));
+        Properties props = new Properties();
+        try {
+            File f = new File(configFilename);
+            if (!f.isAbsolute()) {
+                f = new File(this.getConfigDir(), configFilename);
+            }
+            if (f.canRead()) {
+                DataHelper.loadProps(props, f);
+            } else {
+                if (log != null)
+                    log.warn("Configuration file " + configFilename + " does not exist");
+            }
+        } catch (Exception ioe) {
+            if (log != null)
+                log.error("Error loading the router configuration from " + configFilename, ioe);
+            else
+                System.err.println("Error loading the router configuration from " + configFilename + ": " + ioe);
+        }
+        return props;
+    }
+
+    /**
+     * Write config properties to a file
+     * @return true if the write is successful, false otherwise
+     * @since 0.9.2
+     */
+    public boolean writeConfigFile(String configFilename, Properties props) {
+        synchronized (this) {
+            FileOutputStream fos = null;
+            String filename = configFilename;
+            try {
+                File f = new File(configFilename);
+                if (!f.isAbsolute()) {
+                    f = new File(this.getConfigDir(), configFilename);
+                    filename = f.getAbsolutePath();
+                }
+                fos = new SecureFileOutputStream(filename);
+                StringBuilder buf = new StringBuilder(8*1024);
+                buf.append("# NOTE: This I2P config file must use UTF-8 encoding\n");
+                TreeSet ordered = new TreeSet(props.keySet());
+                for (Iterator iter = ordered.iterator() ; iter.hasNext(); ) {
+                    String key = (String)iter.next();
+                    String val = props.getProperty(key);
+                        // Escape line breaks before saving.
+                        // Remember: "\" needs escaping both for regex and string.
+                        // NOOO - see comments in DataHelper
+                        //val = val.replaceAll("\\r","\\\\r");
+                        //val = val.replaceAll("\\n","\\\\n");
+                    buf.append(key).append('=').append(val).append('\n');
+                }
+                fos.write(buf.toString().getBytes("UTF-8"));
+            } catch (IOException ioe) {
+                Log log = logManager().getLog(I2PAppContext.class);
+                if (log.shouldLog(Log.ERROR))
+                    log.error("Error saving the config to " + filename, ioe);
+                return false;
+            } finally {
+                if (fos != null) try { fos.close(); } catch (IOException ioe) {}
+            }
+        }
+
+        return true;
+    }
+
     /**
      * Access the configuration attributes of this context, using properties 
      * provided during the context construction, or falling back on 
-- 
GitLab