- Add FileStreamFactory and I2PFile to deal with the problems from

the code CWD is / but the only writable directory is
  /data/data/net.i2p.router/files/ - still a ton of places to be
  fixed, will be fixed up as things get working
- Load some config files from resources at startup
- Fix up logging
- Add reseed capability, by copying some code over from routerconsole
- Deal with conflicting bouncycastle libs
This commit is contained in:
zzz
2009-03-13 18:56:16 +00:00
parent 5a8b3eb8f3
commit b8f22bf3bf
23 changed files with 437 additions and 54 deletions

View File

@@ -3,9 +3,11 @@
package="net.i2p.router"
android:versionCode="1"
android:versionName="1.0.0">
<uses-permission android:name="android.permission.INTERNET" />
<application android:label="@string/app_name">
<activity android:name=".I2PAndroid"
android:label="@string/app_name">
android:label="@string/app_name"
android:launchMode="singleTask" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />

View File

@@ -101,12 +101,15 @@
<echo>Creating output directories if needed...</echo>
<mkdir dir="${outdir}" />
<mkdir dir="${outdir-classes}" />
<mkdir dir="${external-libs}" />
</target>
<target name="clean">
<delete dir="${outdir}" />
<delete dir="${external-libs}" />
<delete dir="tmp/" />
<delete dir="res/drawable/" />
<delete file="res/raw/blocklist_txt" />
<delete file="${outdir-r}/net/i2p/router/R.java" />
</target>
@@ -140,7 +143,7 @@
</target>
<!-- Compile this project's .java files into .class files. -->
<target name="compile" depends="dirs, resource-src, aidl, buildrouter">
<target name="compile" depends="buildrouter, dirs, resource-src, aidl">
<javac encoding="ascii" target="1.5" debug="true" extdirs=""
srcdir="."
destdir="${outdir-classes}"
@@ -151,18 +154,68 @@
</javac>
</target>
<target name="buildrouter">
<target name="buildrouter" depends="dirs" >
<!-- for now, we just need the ReseedHandler from routerconsole -->
<ant dir="../apps/routerconsole/java" target="compile" />
<jar destfile="${external-libs}/routerconsole.jar" >
<fileset dir="../apps/routerconsole/java/build/obj/" >
<include name="net/i2p/router/web/ContextHelper.class" />
<include name="net/i2p/router/web/ReseedHandler.class" />
<include name="net/i2p/router/web/ReseedHandler$ReseedRunner.class" />
</fileset>
</jar>
<!-- build router and core (actually the routerconsole builds these anyway) -->
<ant dir=".." target="buildrouter" />
<!-- router -->
<copy file="../build/router.jar" todir="${external-libs}" />
<!-- core -->
<mkdir dir="tmp" />
<unjar src="../build/i2p.jar" dest="tmp/" />
<delete file="tmp/net/i2p/util/LogWriter.class" />
<!-- lots of unneeded stuff, like Log* -->
<delete file="tmp/net/i2p/util/FileStreamFactory.class" />
<delete file="tmp/net/i2p/util/I2PFile.class" />
<!-- org.bouncycastle.crypto already in android
but we need a little trickery because our HMac is incompatible...
and the libs aren't in the SDK to compile against??? -->
<jar destfile="${external-libs}/crypto.jar" >
<fileset dir="tmp/" >
<include name="org/bouncycastle/crypto/Digest.class" />
<include name="org/bouncycastle/crypto/Mac.class" />
<include name="org/bouncycastle/crypto/digests/GeneralDigest.class" />
<include name="org/bouncycastle/crypto/digests/MD5Digest.class" />
</fileset>
</jar>
<delete>
<fileset dir="tmp/" >
<include name="org/bouncycastle/crypto/Digest.class" />
<include name="org/bouncycastle/crypto/Mac.class" />
<include name="org/bouncycastle/crypto/digests/GeneralDigest.class" />
<include name="org/bouncycastle/crypto/digests/MD5Digest.class" />
</fileset>
</delete>
<!--
<delete dir="tmp/org/bouncycastle/" />
<delete file="tmp/net/i2p/crypto/HMACGenerator.class" />
-->
<delete file="tmp/org/bouncycastle/" />
<!-- lots of unneeded stuff could be deleted here -->
<jar destfile="${external-libs}/i2p.jar" basedir="tmp/" />
<!-- some resources -->
<mkdir dir="res/drawable/" />
<copy file="../apps/routerconsole/jsp/i2plogo.png" todir="res/drawable/" />
<copy file="../installer/resources/blocklist.txt" tofile="res/raw/blocklist_txt" />
</target>
<target name="hackcleanup">
<delete file="${external-libs}/crypto.jar" />
</target>
<!-- Convert this project's .class files into .dex files. -->
<target name="dex" depends="compile">
<target name="dex" depends="compile, hackcleanup">
<echo>Converting compiled files and external libraries into ${outdir}/${dex-file}...</echo>
<apply executable="${dx}" failonerror="true" parallel="true">
<!-- this is a bad sign that we need this -->

View File

@@ -9,5 +9,10 @@
android:layout_height="wrap_content"
android:text="Hello World, I2PAndroid"
/>
<ImageView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:src="@drawable/i2plogo"
/>
</LinearLayout>

View File

@@ -0,0 +1,3 @@
logger.defaultLevel=INFO
logger.record.net.i2p.router.transport.FIFOBandwidthRefiller=ERROR
logger.record.net.i2p.stat.Rate=ERROR

View File

@@ -0,0 +1,7 @@
# initial router.config
# save memory
router.prng.buffers=2
router.decayingBloomFilterM=20
stat.full=false
# no I2CP
i2p.dummyClientFacade=true

View File

@@ -1,18 +1,118 @@
package net.i2p.router;
import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.Resources.NotFoundException;
import android.os.Bundle;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.IOException;
import net.i2p.router.Router;
import net.i2p.router.web.ReseedChecker;
import net.i2p.util.I2PFile;
public class I2PAndroid extends Activity
{
static Context _context;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
_context = this; // Activity extends Context
debugStuff();
initialize();
Router.main(null);
System.err.println("Router.main finished");
ReseedChecker.checkReseed();
}
public void onRestart()
{
System.err.println("onRestart called");
super.onRestart();
}
public void onResume()
{
System.err.println("onResume called");
super.onResume();
}
public void onPause()
{
System.err.println("onPause called");
super.onPause();
}
public void onStop()
{
System.err.println("onStop called");
super.onStop();
}
public void onDestroy()
{
System.err.println("onDestroy called");
super.onDestroy();
}
public static Context getContext() {
return _context;
}
private void debugStuff() {
System.err.println("java.vendor" + ": " + System.getProperty("java.vendor"));
System.err.println("java.version" + ": " + System.getProperty("java.version"));
System.err.println("os.arch" + ": " + System.getProperty("os.arch"));
System.err.println("os.name" + ": " + System.getProperty("os.name"));
System.err.println("os.version" + ": " + System.getProperty("os.version"));
System.err.println("user.dir" + ": " + System.getProperty("user.dir"));
System.err.println("user.home" + ": " + System.getProperty("user.home"));
System.err.println("user.name" + ": " + System.getProperty("user.name"));
}
private void initialize() {
// Until we can edit the router.config on the device,
// copy it from the resource every time.
// File f = new I2PFile("router.config");
// if (!f.exists()) {
copyResourceToFile(R.raw.router_config, "router.config");
copyResourceToFile(R.raw.logger_config, "logger.config");
copyResourceToFile(R.raw.blocklist_txt, "blocklist.txt");
// }
}
private void copyResourceToFile(int resID, String f) {
InputStream in = null;
FileOutputStream out = null;
System.err.println("Creating file " + f + " from resource");
byte buf[] = new byte[4096];
try {
// Context methods
in = getResources().openRawResource(resID);
out = openFileOutput(f, 0);
int read = 0;
while ( (read = in.read(buf)) != -1)
out.write(buf, 0, read);
} catch (IOException ioe) {
} catch (Resources.NotFoundException nfe) {
} finally {
if (in != null) try { in.close(); } catch (IOException ioe) {}
if (out != null) try { out.close(); } catch (IOException ioe) {}
}
}
}

View File

@@ -0,0 +1,37 @@
package net.i2p.router.web;
import java.io.File;
import net.i2p.router.web.ReseedHandler;
import net.i2p.util.I2PFile;
/**
* Copied from RouterConsoleRunner.java
*/
public class ReseedChecker {
public static void checkReseed() {
System.err.println("Checking to see if we should reseed");
// we check the i2p installation directory (.) for a flag telling us not to reseed,
// but also check the home directory for that flag too, since new users installing i2p
// don't have an installation directory that they can put the flag in yet.
File noReseedFile = new I2PFile(new I2PFile(System.getProperty("user.home")), ".i2pnoreseed");
File noReseedFileAlt1 = new I2PFile(new I2PFile(System.getProperty("user.home")), "noreseed.i2p");
File noReseedFileAlt2 = new I2PFile(".i2pnoreseed");
File noReseedFileAlt3 = new I2PFile("noreseed.i2p");
if (!noReseedFile.exists() && !noReseedFileAlt1.exists() && !noReseedFileAlt2.exists() && !noReseedFileAlt3.exists()) {
File netDb = new I2PFile("netDb");
// 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
// get i2p started - they can reseed later in the web console)
String names[] = (netDb.exists() ? netDb.list() : null);
if ( (names == null) || (names.length < 15) ) {
System.err.println("Yes, reseeding now");
ReseedHandler reseedHandler = new ReseedHandler();
reseedHandler.requestReseed();
}
}
}
}

View File

@@ -0,0 +1,64 @@
/*
* This is free software, do as you please.
*/
package net.i2p.util;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import net.i2p.router.I2PAndroid;
/**
* Use android static file stream methods
* gaaah:
* 1) the CWD is /
* 2) we can only access /data/data/net.i2p.router/files/
* 3) you can't change your CWD in Java
* so we have this lovely and the one in I2PFile.
*
* @author zzz
*/
public class FileStreamFactory {
private static final String DIR = "/data/data/net.i2p.router/files/";
/** hopefully no path separators in string */
public static FileInputStream getFileInputStream(String f) throws FileNotFoundException {
System.err.println("Input file-s: " + I2PAndroid.getContext().getFileStreamPath(f).getAbsolutePath());
return I2PAndroid.getContext().openFileInput(f);
}
public static FileInputStream getFileInputStream(File f) throws FileNotFoundException {
System.err.println("Input file-f: " + getPath(f) +
' ' + f.getAbsolutePath());
//return I2PAndroid.getContext().openFileInput(f.getName());
return new FileInputStream(getPath(f));
}
/** hopefully no path separators in string */
public static FileOutputStream getFileOutputStream(String f) throws FileNotFoundException {
System.err.println("Output file-s: " + I2PAndroid.getContext().getFileStreamPath(f).getAbsolutePath());
return I2PAndroid.getContext().openFileOutput(f, 0);
}
public static FileOutputStream getFileOutputStream(File f) throws FileNotFoundException {
System.err.println("Output file-f: " + getPath(f) +
' ' + f.getAbsolutePath());
//return I2PAndroid.getContext().openFileOutput(f.getName(), 0);
return new FileOutputStream(getPath(f));
}
/**
* preserve path but convert /foo/blah to /data/data/net.i2p.router/files/foo/blah
* Although if the File arg was created with new I2PFile() then this isn't required
*
*/
private static String getPath(File f) {
String abs = f.getAbsolutePath();
if (abs.startsWith(DIR))
return abs;
return DIR + abs.substring(1); // strip extra '/'
}
}

View File

@@ -0,0 +1,29 @@
/*
* This is free software, do as you please.
*/
package net.i2p.util;
import java.io.File;
/**
* gaaah:
* 1) the CWD is /
* 2) we can only access /data/data/net.i2p.router/files/
* 3) you can't change your CWD in Java
* so we have this lovely and the one in FileStreamFactory.
*
* @author zzz
*/
public class I2PFile extends File {
public I2PFile (String f) {
super("/data/data/net.i2p.router/files/" + f);
}
/** one level deep only */
public I2PFile (File p, String f) {
super("/data/data/net.i2p.router/files/" + p.getName(), f);
}
}

View File

@@ -87,36 +87,44 @@ class LogWriter implements Runnable {
private void writeRecord(LogRecord rec) {
if (rec.getThrowable() == null)
log(rec.getPriority(), rec.getSourceName(), null, rec.getThreadName(), rec.getMessage());
log(rec.getPriority(), rec.getSource(), rec.getSourceName(), rec.getThreadName(), rec.getMessage());
else
log(rec.getPriority(), rec.getSourceName(), null, rec.getThreadName(), rec.getMessage(), rec.getThrowable());
log(rec.getPriority(), rec.getSource(), rec.getSourceName(), rec.getThreadName(), rec.getMessage(), rec.getThrowable());
}
public void log(int priority, String className, String name, String threadName, String msg) {
if (className != null)
public void log(int priority, Class src, String name, String threadName, String msg) {
if (src != null) {
String tag = src.getName();
int dot = tag.lastIndexOf(".");
if (dot >= 0)
tag = tag.substring(dot + 1);
android.util.Log.println(toAndroidLevel(priority),
className,
threadName + ' ' + msg);
else if (name != null)
tag,
'[' + threadName + "] " + msg);
} else if (name != null)
android.util.Log.println(toAndroidLevel(priority),
name,
threadName + ' ' + msg);
'[' + threadName + "] " + msg);
else
android.util.Log.println(toAndroidLevel(priority),
threadName, msg);
}
public void log(int priority, String className, String name, String threadName, String msg, Throwable t) {
if (className != null)
public void log(int priority, Class src, String name, String threadName, String msg, Throwable t) {
if (src != null) {
String tag = src.getName();
int dot = tag.lastIndexOf(".");
if (dot >= 0)
tag = tag.substring(dot + 1);
android.util.Log.println(toAndroidLevel(priority),
className,
threadName + ' ' + msg +
msg + ' ' + t.toString() + ' ' + android.util.Log.getStackTraceString(t));
else if (name != null)
tag,
'[' + threadName + "] " + msg +
' ' + t.toString() + ' ' + android.util.Log.getStackTraceString(t));
} else if (name != null)
android.util.Log.println(toAndroidLevel(priority),
name,
threadName + ' ' + msg +
msg + ' ' + t.toString() + ' ' + android.util.Log.getStackTraceString(t));
'[' + threadName + "] " + msg +
' ' + t.toString() + ' ' + android.util.Log.getStackTraceString(t));
else
android.util.Log.println(toAndroidLevel(priority),
threadName,