diff --git a/core/java/build.xml b/core/java/build.xml
index b86303d80..56423cd5b 100644
--- a/core/java/build.xml
+++ b/core/java/build.xml
@@ -58,6 +58,7 @@
+
diff --git a/core/java/src/net/i2p/util/CommandLine.java b/core/java/src/net/i2p/util/CommandLine.java
new file mode 100644
index 000000000..737187488
--- /dev/null
+++ b/core/java/src/net/i2p/util/CommandLine.java
@@ -0,0 +1,95 @@
+package net.i2p.util;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Locale;
+
+import net.i2p.CoreVersion;
+
+/**
+ * Simple command line access to various utilities.
+ * Not a public API. Subject to change.
+ * Apps and plugins should use specific classes.
+ *
+ * @since 0.9.25
+ */
+public class CommandLine {
+
+ protected static final List CLASSES = Arrays.asList(new String[] {
+ "freenet.support.CPUInformation.CPUID",
+ "net.i2p.CoreVersion",
+ "net.i2p.client.naming.BlockfileNamingService",
+ "net.i2p.crypto.CryptoCheck",
+ "net.i2p.crypto.SU3File",
+ "net.i2p.crypto.TrustedUpdate",
+ "net.i2p.data.Base32",
+ "net.i2p.data.Base64",
+ "net.i2p.data.PrivateKeyFile",
+ "net.i2p.util.Addresses",
+ "net.i2p.util.EepGet",
+ "net.i2p.util.EepHead",
+ "net.i2p.util.FileUtil",
+ "net.i2p.util.FortunaRandomSource",
+ "net.i2p.util.NativeBigInteger",
+ "net.i2p.util.PartialEepGet",
+ "net.i2p.util.ShellCommand",
+ "net.i2p.util.SSLEepGet",
+ //"net.i2p.util.SystemVersion",
+ "net.i2p.util.TranslateReader",
+ "net.i2p.util.ZipFileComment"
+ });
+
+ protected CommandLine() {}
+
+ public static void main(String args[]) {
+ if (args.length > 0) {
+ exec(args, CLASSES);
+ }
+ usage();
+ System.exit(1);
+ }
+
+ /** will only return if command not found */
+ protected static void exec(String args[], List classes) {
+ String cmd = args[0].toLowerCase(Locale.US);
+ for (String cls : classes) {
+ String ccmd = cls.substring(cls.lastIndexOf(".") + 1).toLowerCase(Locale.US);
+ if (cmd.equals(ccmd)) {
+ try {
+ String[] cargs = new String[args.length - 1];
+ System.arraycopy(args, 1, cargs, 0, args.length - 1);
+ Class> c = Class.forName(cls, true, ClassLoader.getSystemClassLoader());
+ Method main = c.getMethod("main", String[].class);
+ main.invoke(null, (Object) cargs);
+ System.exit(0);
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ }
+ }
+ }
+
+ private static void usage() {
+ System.err.println("I2P Core version " + CoreVersion.VERSION + '\n' +
+ "USAGE: java -jar /path/to/i2p.jar command [args]");
+ printCommands(CLASSES);
+ }
+
+ protected static void printCommands(List classes) {
+ System.err.println("Available commands:");
+ List cmds = new ArrayList(classes.size());
+ for (String cls : classes) {
+ String ccmd = cls.substring(cls.lastIndexOf(".") + 1).toLowerCase(Locale.US);
+ cmds.add(ccmd);
+ }
+ Collections.sort(cmds);
+ for (String cmd : cmds) {
+ System.err.println(" " + cmd);
+ }
+ System.err.println("Enter command for detailed help.");
+ }
+}
diff --git a/router/java/build.xml b/router/java/build.xml
index 85eba417d..b72169c44 100644
--- a/router/java/build.xml
+++ b/router/java/build.xml
@@ -63,11 +63,12 @@
-
+
+
diff --git a/router/java/src/net/i2p/router/CommandLine.java b/router/java/src/net/i2p/router/CommandLine.java
new file mode 100644
index 000000000..7f1b44e3b
--- /dev/null
+++ b/router/java/src/net/i2p/router/CommandLine.java
@@ -0,0 +1,44 @@
+package net.i2p.router;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Simple command line access to various utilities.
+ * Not a public API. Subject to change.
+ * Apps and plugins should use specific classes.
+ *
+ * @since 0.9.25
+ */
+public class CommandLine extends net.i2p.util.CommandLine {
+
+ protected static final List RCLASSES = Arrays.asList(new String[] {
+ "net.i2p.router.MultiRouter",
+ "net.i2p.router.Router",
+ "net.i2p.router.RouterLaunch",
+ "net.i2p.router.RouterVersion",
+ "net.i2p.router.peermanager.ProfileOrganizer",
+ "net.i2p.router.tasks.CryptoChecker",
+ //"net.i2p.router.transport.UPnP"
+ });
+
+ protected CommandLine() {}
+
+ public static void main(String args[]) {
+ List classes = new ArrayList(RCLASSES.size() + CLASSES.size());
+ classes.addAll(RCLASSES);
+ classes.addAll(CLASSES);
+ if (args.length > 0) {
+ exec(args, classes);
+ }
+ usage(classes);
+ System.exit(1);
+ }
+
+ private static void usage(List classes) {
+ System.err.println("I2P Router version " + RouterVersion.FULL_VERSION + '\n' +
+ "USAGE: java -jar /path/to/router.jar command [args]");
+ printCommands(classes);
+ }
+}