Author: toad
Date: 2006-03-15 19:53:25 +0000 (Wed, 15 Mar 2006)
New Revision: 8256
Added:
trunk/freenet/src/freenet/node/TextModeClientInterfaceServer.java
Modified:
trunk/freenet/src/freenet/node/Node.java
trunk/freenet/src/freenet/node/TextModeClientInterface.java
trunk/freenet/src/freenet/node/Version.java
trunk/freenet/src/freenet/node/fcp/ClientGet.java
trunk/freenet/src/freenet/node/fcp/FCPServer.java
Log:
536:
Make TextModeClientInterface capable of running on either stdin/stdout, or a
socket server.
The latter is on by default, the former is not.
Nextgens did a lot of the work for this.
Modified: trunk/freenet/src/freenet/node/Node.java
===================================================================
--- trunk/freenet/src/freenet/node/Node.java 2006-03-15 19:16:28 UTC (rev
8255)
+++ trunk/freenet/src/freenet/node/Node.java 2006-03-15 19:53:25 UTC (rev
8256)
@@ -70,9 +70,6 @@
import freenet.keys.SSKVerifyException;
import freenet.node.fcp.FCPServer;
import freenet.pluginmanager.PluginManager;
-import freenet.pluginmanager.PluginRespirator;
-import freenet.pluginmanager.PproxyToadlet;
-import freenet.snmplib.SNMPAgent;
import freenet.snmplib.SNMPStarter;
import freenet.store.BerkeleyDBFreenetStore;
import freenet.store.FreenetStore;
@@ -229,6 +226,7 @@
static final int EXIT_BAD_TEMP_DIR = 16;
static final int EXIT_COULD_NOT_START_FCP = 17;
static final int EXIT_COULD_NOT_START_FPROXY = 18;
+ static final int EXIT_COULD_NOT_START_TMCI = 19;
public final long bootID;
@@ -251,7 +249,8 @@
public final ClientRequestScheduler chkPutScheduler;
public final ClientRequestScheduler sskFetchScheduler;
public final ClientRequestScheduler sskPutScheduler;
- TextModeClientInterface tmci;
+ TextModeClientInterfaceServer tmci;
+ TextModeClientInterface directTMCI;
FCPServer fcpServer;
FproxyToadlet fproxyServlet;
private SymlinkerToadlet symlinkerToadlet;
@@ -900,7 +899,12 @@
// Start services
// TMCI
- TextModeClientInterface.maybeCreate(this, config);
+ try{
+ TextModeClientInterfaceServer.maybeCreate(this, config);
+ } catch (IOException e) {
+ e.printStackTrace();
+ throw new NodeInitException(EXIT_COULD_NOT_START_TMCI,
"Could not start TMCI: "+e);
+ }
// Fproxy
// FIXME this is a hack, the real way to do this is plugins
@@ -2073,6 +2077,10 @@
public SimpleToadletServer getToadletContainer() {
return toadletContainer;
}
+
+ public TextModeClientInterfaceServer getTextModeClientInterface(){
+ return tmci;
+ }
public void setFproxy(FproxyToadlet fproxy) {
this.fproxyServlet = fproxy;
@@ -2081,8 +2089,26 @@
public void setFCPServer(FCPServer fcp) {
this.fcpServer = fcp;
}
+
+ public void exit(){
+ config.store();
+ System.out.println("Goodbye.");
+ System.exit(0);
+ }
public SymlinkerToadlet getSymlinkerToadlet() {
return symlinkerToadlet;
}
+
+ public void setTMCI(TextModeClientInterfaceServer server) {
+ this.tmci = server;
+ }
+
+ public TextModeClientInterface getDirectTMCI() {
+ return directTMCI;
+ }
+
+ public void setDirectTMCI(TextModeClientInterface i) {
+ this.directTMCI = i;
+ }
}
Modified: trunk/freenet/src/freenet/node/TextModeClientInterface.java
===================================================================
--- trunk/freenet/src/freenet/node/TextModeClientInterface.java 2006-03-15
19:16:28 UTC (rev 8255)
+++ trunk/freenet/src/freenet/node/TextModeClientInterface.java 2006-03-15
19:53:25 UTC (rev 8256)
@@ -7,13 +7,16 @@
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
+import java.io.InputStream;
import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.Hashtable;
-import java.util.Iterator;
import freenet.client.ClientMetadata;
import freenet.client.DefaultMIMETypes;
@@ -22,12 +25,6 @@
import freenet.client.HighLevelSimpleClient;
import freenet.client.InsertBlock;
import freenet.client.InserterException;
-import freenet.client.Metadata;
-import freenet.client.events.EventDumper;
-import freenet.config.BooleanCallback;
-import freenet.config.Config;
-import freenet.config.InvalidConfigValueException;
-import freenet.config.SubConfig;
import freenet.crypt.RandomSource;
import freenet.io.comm.Peer;
import freenet.io.comm.PeerParseException;
@@ -55,71 +52,103 @@
final HighLevelSimpleClient client;
final Hashtable streams;
final File downloadsDir;
+ final InputStream in;
+ final OutputStream out;
- TextModeClientInterface(Node n) {
- this.n = n;
- client = n.makeClient(RequestStarter.INTERACTIVE_PRIORITY_CLASS);
- client.addGlobalHook(new EventDumper());
- this.r = n.random;
- streams = new Hashtable();
- new Thread(this, "Text mode client interface").start();
- this.downloadsDir = n.downloadDir;
+ public TextModeClientInterface(TextModeClientInterfaceServer server,
InputStream in, OutputStream out) {
+ this.n = server.n;
+ this.r = server.r;
+ this.client = server.client;
+ this.streams = new Hashtable();
+ this.downloadsDir = server.downloadsDir;
+ this.in = in;
+ this.out = out;
+ }
+
+ public TextModeClientInterface(Node n, HighLevelSimpleClient c, File
downloadDir, InputStream in, OutputStream out) {
+ this.n = n;
+ this.r = n.random;
+ this.client = c;
+ this.streams = new Hashtable();
+ this.downloadsDir = downloadDir;
+ this.in = in;
+ this.out = out;
}
- /**
- * Read commands, run them
- */
public void run() {
- printHeader();
- // Read command, and data
- BufferedReader reader = new BufferedReader(new
InputStreamReader(System.in));
+ try {
+ realRun();
+ } catch (IOException e) {
+ Logger.minor(this, "Caught "+e, e);
+ } catch (Throwable t) {
+ Logger.error(this, "Caught "+t, t);
+ }
+ }
+
+ public void realRun() throws IOException {
+ printHeader(out);
+
+ BufferedReader reader = new BufferedReader(new
InputStreamReader(in));
while(true) {
try {
- processLine(reader);
+ processLine(reader,out);
+ } catch (IOException e) {
+ Logger.error(this, "Socket error: "+e, e);
+ return;
} catch (Throwable t) {
Logger.error(this, "Caught "+t, t);
System.out.println("Caught: "+t);
- t.printStackTrace();
+ StringWriter sw = new StringWriter();
+ t.printStackTrace(new PrintWriter(sw));
+ try {
+ out.write(sw.toString().getBytes());
+ } catch (IOException e) {
+ Logger.error(this, "Socket error: "+e, e);
+ return;
+ }
}
}
}
-
- private void printHeader() {
- System.out.println("Freenet 0.7 Trivial Node Test Interface");
- System.out.println("---------------------------------------");
- System.out.println();
- System.out.println("Build "+Version.buildNumber());
- System.out.println("Enter one of the following commands:");
- System.out.println("GET:<Freenet key> - Fetch a key");
- System.out.println("PUT:\n<text, until a . on a line by itself> -
Insert the document and return the key.");
- System.out.println("PUT:<text> - Put a single line of text to a CHK
and return the key.");
- System.out.println("GETCHK:\n<text, until a . on a line by itself> -
Get the key that would be returned if the document was inserted.");
- System.out.println("GETCHK:<text> - Get the key that would be returned
if the line was inserted.");
- System.out.println("PUTFILE:<filename> - Put a file from disk.");
- System.out.println("GETFILE:<filename> - Fetch a key and put it in a
file. If the key includes a filename we will use it but we will not overwrite
local files.");
- System.out.println("GETCHKFILE:<filename> - Get the key that would be
returned if we inserted the file.");
- System.out.println("PUTDIR:<path>[#<defaultfile>] - Put the entire
directory from disk.");
- System.out.println("GETCHKDIR:<path>[#<defaultfile>] - Get the key
that would be returned if we'd put the entire directory from disk.");
- System.out.println("MAKESSK - Create an SSK keypair.");
- System.out.println("PUTSSK:<insert uri>;<url to redirect to> - Insert
an SSK redirect to a file already inserted.");
- System.out.println("PUTSSKDIR:<insert uri>#<path>[#<defaultfile>] -
Insert an entire directory to an SSK.");
- System.out.println("PLUGLOAD: - Load plugin. (use \"PLUGLOAD:?\" for
more info)");
- //System.out.println("PLUGLOAD: <pkg.classname>[(@<URI to
jarfile.jar>|<<URI to file containing real URI>|* (will load from freenets
pluginpool))] - Load plugin.");
- System.out.println("PLUGLIST - List all loaded plugins.");
- System.out.println("PLUGKILL: <pluginID> - Unload the plugin with the
given ID (see PLUGLIST).");
-// System.out.println("PUBLISH:<name> - create a publish/subscribe
stream called <name>");
-// System.out.println("PUSH:<name>:<text> - publish a single line of
text to the stream named");
-// System.out.println("SUBSCRIBE:<key> - subscribe to a
publish/subscribe stream by key");
- System.out.println("CONNECT:<filename|URL> - connect to a node from
its ref in a file/url.");
- System.out.println("CONNECT:\n<noderef including an End on a line by
itself> - enter a noderef directly.");
- System.out.println("DISCONNECT:<ip:port> - disconnect from a node by
providing it's ip+port or name");
- System.out.println("NAME:<new node name> - change the node's name.");
-// System.out.println("SUBFILE:<filename> - append all data received
from subscriptions to a file, rather than sending it to stdout.");
-// System.out.println("SAY:<text> - send text to the last
created/pushed stream");
- System.out.println("STATUS - display some status information on the
node including its reference and connections.");
- System.out.println("QUIT - exit the program");
+
+ private void printHeader(OutputStream s) throws IOException {
+ StringBuffer sb = new StringBuffer();
+
+ sb.append("Freenet 0.7 Trivial Node Test Interface\n");
+ sb.append("---------------------------------------\n");
+ sb.append("Build "+Version.buildNumber());
+ sb.append("Enter one of the following commands:\n");
+ sb.append("GET:<Freenet key> - Fetch a key\n");
+ sb.append("PUT:\n<text, until a . on a line by itself> - Insert the
document and return the key.\n");
+ sb.append("PUT:<text> - Put a single line of text to a CHK and return
the key.\n");
+ sb.append("GETCHK:\n<text, until a . on a line by itself> - Get the
key that would be returned if the document was inserted.\n");
+ sb.append("GETCHK:<text> - Get the key that would be returned if the
line was inserted.\n");
+ sb.append("PUTFILE:<filename> - Put a file from disk.\n");
+ sb.append("GETFILE:<filename> - Fetch a key and put it in a file. If
the key includes a filename we will use it but we will not overwrite local
files.\n");
+ sb.append("GETCHKFILE:<filename> - Get the key that would be returned
if we inserted the file.\n");
+ sb.append("PUTDIR:<path>[#<defaultfile>] - Put the entire directory
from disk.\n");
+ sb.append("GETCHKDIR:<path>[#<defaultfile>] - Get the key that would
be returned if we'd put the entire directory from disk.\n");
+ sb.append("MAKESSK - Create an SSK keypair.\n");
+ sb.append("PUTSSK:<insert uri>;<url to redirect to> - Insert an SSK
redirect to a file already inserted.\n");
+ sb.append("PUTSSKDIR:<insert uri>#<path>[#<defaultfile>] - Insert an
entire directory to an SSK.\n");
+ sb.append("PLUGLOAD: - Load plugin. (use \"PLUGLOAD:?\" for more
info)\n");
+ //sb.append("PLUGLOAD: <pkg.classname>[(@<URI to jarfile.jar>|<<URI to
file containing real URI>|* (will load from freenets pluginpool))] - Load
plugin.\n");
+ sb.append("PLUGLIST - List all loaded plugins.\n");
+ sb.append("PLUGKILL: <pluginID> - Unload the plugin with the given ID
(see PLUGLIST).\n");
+// sb.append("PUBLISH:<name> - create a publish/subscribe stream called
<name>\n");
+// sb.append("PUSH:<name>:<text> - publish a single line of text to the
stream named\n");
+// sb.append("SUBSCRIBE:<key> - subscribe to a publish/subscribe stream
by key\n");
+ sb.append("CONNECT:<filename|URL> - connect to a node from its ref in
a file/url.\n");
+ sb.append("CONNECT:\n<noderef including an End on a line by itself> -
enter a noderef directly.\n");
+ sb.append("DISCONNECT:<ip:port> - disconnect from a node by providing
it's ip+port or name\n");
+ sb.append("NAME:<new node name> - change the node's name.\n");
+// sb.append("SUBFILE:<filename> - append all data received from
subscriptions to a file, rather than sending it to stdout.\n");
+// sb.append("SAY:<text> - send text to the last created/pushed
stream\n");
+ sb.append("STATUS - display some status information on the node
including its reference and connections.\n");
+ sb.append("QUIT - exit the program\n");
if(n.testnetEnabled) {
- System.out.println("WARNING: TESTNET MODE ENABLED. YOU HAVE NO
ANONYMITY.");
+ sb.append("WARNING: TESTNET MODE ENABLED. YOU HAVE NO
ANONYMITY.\n");
+
+ s.write(sb.toString().getBytes());
}
}
@@ -127,11 +156,13 @@
* Process a single command.
* @throws IOException If we could not write the data to stdout.
*/
- private void processLine(BufferedReader reader) throws IOException {
+ private void processLine(BufferedReader reader, OutputStream out) throws
IOException {
String line;
+ StringBuffer outsb = new StringBuffer();
try {
line = reader.readLine();
} catch (IOException e) {
+ outsb.append("Bye... ("+e+")");
System.err.println("Bye... ("+e+")");
return;
}
@@ -152,17 +183,18 @@
uri = new FreenetURI(key);
Logger.normal(this, "Key: "+uri);
} catch (MalformedURLException e2) {
- System.out.println("Malformed URI: "+key+" : "+e2);
+ outsb.append("Malformed URI: "+key+" : "+e2);
return;
}
try {
FetchResult result = client.fetch(uri);
ClientMetadata cm = result.getMetadata();
- System.out.println("Content MIME type:
"+cm.getMIMEType());
+ outsb.append("Content MIME type:
"+cm.getMIMEType());
Bucket data = result.asBucket();
// FIXME limit it above
if(data.size() > 32*1024) {
System.err.println("Data is more than
32K: "+data.size());
+ outsb.append("Data is more than 32K:
"+data.size());
return;
}
byte[] dataBytes =
BucketTools.toByteArray(data);
@@ -175,15 +207,15 @@
}
if(evil) {
System.err.println("Data may contain
escape codes which could cause the terminal to run arbitrary commands! Save it
to a file if you must with GETFILE:");
- return;
+ outsb.append("Data may contain escape
codes which could cause the terminal to run arbitrary commands! Save it to a
file if you must with GETFILE:");
+ return;
}
- System.out.println("Data:\n");
- System.out.println(new String(dataBytes));
- System.out.println();
+ outsb.append("Data:\n");
+ outsb.append(new String(dataBytes));
} catch (FetchException e) {
- System.out.println("Error: "+e.getMessage());
+ outsb.append("Error: "+e.getMessage());
if(e.getMode() == e.SPLITFILE_ERROR && e.errorCodes != null) {
- System.out.println(e.errorCodes.toVerboseString());
+ outsb.append(e.errorCodes.toVerboseString());
}
}
} else if(uline.startsWith("GETFILE:")) {
@@ -198,14 +230,14 @@
try {
uri = new FreenetURI(key);
} catch (MalformedURLException e2) {
- System.out.println("Malformed URI: "+key+" : "+e2);
+ outsb.append("Malformed URI: "+key+" : "+e2);
return;
}
try {
long startTime = System.currentTimeMillis();
FetchResult result = client.fetch(uri);
ClientMetadata cm = result.getMetadata();
- System.out.println("Content MIME type:
"+cm.getMIMEType());
+ outsb.append("Content MIME type:
"+cm.getMIMEType());
Bucket data = result.asBucket();
// Now calculate filename
String fnam = uri.getDocName();
@@ -218,7 +250,7 @@
}
File f = new File(downloadsDir, fnam);
if(f.exists()) {
- System.out.println("File exists already: "+fnam);
+ outsb.append("File exists already: "+fnam);
fnam = "freenet-"+System.currentTimeMillis()+"-"+fnam;
}
FileOutputStream fos = null;
@@ -226,9 +258,9 @@
fos = new FileOutputStream(f);
BucketTools.copyTo(data, fos, Long.MAX_VALUE);
fos.close();
- System.out.println("Written to "+fnam);
+ outsb.append("Written to "+fnam);
} catch (IOException e) {
- System.out.println("Could not write file: caught "+e);
+ outsb.append("Could not write file: caught "+e);
e.printStackTrace();
} finally {
if(fos != null) try {
@@ -240,16 +272,15 @@
long endTime = System.currentTimeMillis();
long sz = data.size();
double rate = 1000.0 * sz / (endTime-startTime);
- System.out.println("Download rate: "+rate+" bytes / second");
+ outsb.append("Download rate: "+rate+" bytes / second");
} catch (FetchException e) {
- System.out.println("Error: "+e.getMessage());
+ outsb.append("Error: "+e.getMessage());
if(e.getMode() == e.SPLITFILE_ERROR && e.errorCodes != null) {
- System.out.println(e.errorCodes.toVerboseString());
+ outsb.append(e.errorCodes.toVerboseString());
}
}
} else if(uline.startsWith("QUIT")) {
- System.out.println("Goodbye.");
- System.exit(0);
+ n.exit();
} else if(uline.startsWith("PUT:") || (getCHKOnly =
uline.startsWith("GETCHK:"))) {
// Just insert to local store
if(getCHKOnly)
@@ -277,17 +308,17 @@
try {
uri = client.insert(block, getCHKOnly);
} catch (InserterException e) {
- System.out.println("Error: "+e.getMessage());
+ outsb.append("Error: "+e.getMessage());
if(e.uri != null)
- System.out.println("URI would have been: "+e.uri);
+ outsb.append("URI would have been: "+e.uri);
int mode = e.getMode();
if(mode == InserterException.FATAL_ERRORS_IN_BLOCKS || mode ==
InserterException.TOO_MANY_RETRIES_IN_BLOCKS) {
- System.out.println("Splitfile-specific
error:\n"+e.errorCodes.toVerboseString());
+ outsb.append("Splitfile-specific
error:\n"+e.errorCodes.toVerboseString());
}
return;
}
- System.out.println("URI: "+uri);
+ outsb.append("URI: "+uri);
////////////////////////////////////////////////////////////////////////////////
} else if(uline.startsWith("PUTDIR:") ||
(uline.startsWith("PUTSSKDIR")) || (getCHKOnly =
uline.startsWith("GETCHKDIR:"))) {
// TODO: Check for errors?
@@ -299,13 +330,15 @@
ssk = true;
} else if(uline.startsWith("GETCHKDIR:"))
line = line.substring(("GETCHKDIR:").length());
- else
+ else {
System.err.println("Impossible");
+ outsb.append("Impossible");
+ }
line = line.trim();
if(line.length() < 1) {
- printHeader();
+ printHeader(out);
return;
}
@@ -345,19 +378,19 @@
try {
uri = client.insertManifest(insertURI,
bucketsByName, defaultFile);
uri = uri.addMetaStrings(new String[] { "" });
-
System.out.println("=======================================================");
- System.out.println("URI: "+uri);
-
System.out.println("=======================================================");
+
outsb.append("=======================================================");
+ outsb.append("URI: "+uri);
+
outsb.append("=======================================================");
} catch (InserterException e) {
- System.out.println("Finished insert but: "+e.getMessage());
+ outsb.append("Finished insert but: "+e.getMessage());
if(e.uri != null) {
uri = e.uri;
uri = uri.addMetaStrings(new String[] { "" });
- System.out.println("URI would have been: "+uri);
+ outsb.append("URI would have been: "+uri);
}
if(e.errorCodes != null) {
- System.out.println("Splitfile errors breakdown:");
- System.out.println(e.errorCodes.toVerboseString());
+ outsb.append("Splitfile errors breakdown:");
+ outsb.append(e.errorCodes.toVerboseString());
}
Logger.error(this, "Caught "+e, e);
}
@@ -374,7 +407,7 @@
while(line.length() > 0 && line.charAt(line.length()-1) == ' ')
line = line.substring(0, line.length()-2);
File f = new File(line);
- System.out.println("Attempting to read file "+line);
+ outsb.append("Attempting to read file "+line);
long startTime = System.currentTimeMillis();
try {
if(!(f.exists() && f.canRead())) {
@@ -383,7 +416,7 @@
// Guess MIME type
String mimeType = DefaultMIMETypes.guessMIMEType(line);
- System.out.println("Using MIME type: "+mimeType);
+ outsb.append("Using MIME type: "+mimeType);
if(mimeType.equals(DefaultMIMETypes.DEFAULT_MIME_TYPE))
mimeType = ""; // don't need to override it
@@ -396,74 +429,73 @@
// FIXME depends on CHK's still being renamable
//uri = uri.setDocName(f.getName());
- System.out.println("URI: "+uri);
+ outsb.append("URI: "+uri);
long endTime = System.currentTimeMillis();
long sz = f.length();
double rate = 1000.0 * sz / (endTime-startTime);
- System.out.println("Upload rate: "+rate+" bytes / second");
+ outsb.append("Upload rate: "+rate+" bytes / second");
} catch (FileNotFoundException e1) {
- System.out.println("File not found");
+ outsb.append("File not found");
} catch (InserterException e) {
- System.out.println("Finished insert but: "+e.getMessage());
+ outsb.append("Finished insert but: "+e.getMessage());
if(e.uri != null) {
- System.out.println("URI would have been: "+e.uri);
+ outsb.append("URI would have been: "+e.uri);
long endTime = System.currentTimeMillis();
long sz = f.length();
double rate = 1000.0 * sz / (endTime-startTime);
- System.out.println("Upload rate: "+rate+" bytes / second");
+ outsb.append("Upload rate: "+rate+" bytes / second");
}
if(e.errorCodes != null) {
- System.out.println("Splitfile errors breakdown:");
- System.out.println(e.errorCodes.toVerboseString());
+ outsb.append("Splitfile errors breakdown:");
+ outsb.append(e.errorCodes.toVerboseString());
}
} catch (Throwable t) {
- System.out.println("Insert threw: "+t);
+ outsb.append("Insert threw: "+t);
t.printStackTrace();
}
} else if(uline.startsWith("MAKESSK")) {
InsertableClientSSK key = InsertableClientSSK.createRandom(r);
- System.out.println("Insert URI:
"+key.getInsertURI().toString(false));
- System.out.println("Request URI:
"+key.getURI().toString(false));
+ outsb.append("Insert URI: "+key.getInsertURI().toString(false));
+ outsb.append("Request URI: "+key.getURI().toString(false));
FreenetURI insertURI =
key.getInsertURI().setDocName("testsite");
String fixedInsertURI = insertURI.toString(false);
- System.out.println("Note that you MUST add a filename to the
end of the above URLs e.g.:\n"+fixedInsertURI);
- System.out.println("Normally you will then do PUTSSKDIR:<insert
URI>#<directory to upload>, for
example:\nPUTSSKDIR:"+fixedInsertURI+"#directoryToUpload/");
- System.out.println("This will then produce a manifest site
containing all the files, the default document can be accessed
at\n"+insertURI.addMetaStrings(new String[] { "" }).toString(false));
+ outsb.append("Note that you MUST add a filename to the end of
the above URLs e.g.:\n"+fixedInsertURI);
+ outsb.append("Normally you will then do PUTSSKDIR:<insert
URI>#<directory to upload>, for
example:\nPUTSSKDIR:"+fixedInsertURI+"#directoryToUpload/");
+ outsb.append("This will then produce a manifest site containing
all the files, the default document can be accessed
at\n"+insertURI.addMetaStrings(new String[] { "" }).toString(false));
} else if(uline.startsWith("PUTSSK:")) {
String cmd = line.substring("PUTSSK:".length());
cmd = cmd.trim();
if(cmd.indexOf(';') <= 0) {
- System.out.println("No target URI provided.");
- System.out.println("PUTSSK:<insert uri>;<url to
redirect to>");
+ outsb.append("No target URI provided.");
+ outsb.append("PUTSSK:<insert uri>;<url to redirect
to>");
return;
}
String[] split = cmd.split(";");
String insertURI = split[0];
String targetURI = split[1];
- System.out.println("Insert URI: "+insertURI);
- System.out.println("Target URI: "+targetURI);
+ outsb.append("Insert URI: "+insertURI);
+ outsb.append("Target URI: "+targetURI);
FreenetURI insert = new FreenetURI(insertURI);
FreenetURI target = new FreenetURI(targetURI);
InsertableClientSSK key = InsertableClientSSK.create(insert);
- System.out.println("Fetch URI: "+key.getURI());
+ outsb.append("Fetch URI: "+key.getURI());
try {
FreenetURI result =
client.insertRedirect(insert, target);
- System.out.println("Successfully inserted to
fetch URI: "+key.getURI());
+ outsb.append("Successfully inserted to fetch
URI: "+key.getURI());
} catch (InserterException e) {
- System.out.println("Finished insert but: "+e.getMessage());
+ outsb.append("Finished insert but: "+e.getMessage());
Logger.normal(this, "Error: "+e, e);
if(e.uri != null) {
- System.out.println("URI would have been: "+e.uri);
+ outsb.append("URI would have been: "+e.uri);
}
}
} else if(uline.startsWith("STATUS")) {
SimpleFieldSet fs = n.exportFieldSet();
- System.out.println(fs.toString());
- System.out.println();
- System.out.println(n.getStatus());
+ outsb.append(fs.toString());
+ outsb.append(n.getStatus());
if(Version.buildNumber()<Version.highestSeenBuild){
- System.out.println("The latest version is :
"+Version.highestSeenBuild);
+ outsb.append("The latest version is :
"+Version.highestSeenBuild);
}
} else if(uline.startsWith("CONNECT:")) {
String key = line.substring("CONNECT:".length());
@@ -476,13 +508,13 @@
if(key.length() > 0) {
// Filename
BufferedReader in;
- System.out.println("Trying to connect to noderef in "+key);
+ outsb.append("Trying to connect to noderef in "+key);
File f = new File(key);
if (f.isFile()) {
- System.out.println("Given string seems to be a file,
loading...");
+ outsb.append("Given string seems to be a file,
loading...");
in = new BufferedReader(new FileReader(f));
} else {
- System.out.println("Given string seems to be an URL,
loading...");
+ outsb.append("Given string seems to be an URL,
loading...");
URL url = new URL(key);
URLConnection uc = url.openConnection();
in = new BufferedReader(
@@ -498,13 +530,13 @@
connect(content);
} else if(uline.startsWith("NAME:")) {
- System.out.println("Node name currently: "+n.myName);
+ outsb.append("Node name currently: "+n.myName);
String key = line.substring("NAME:".length());
while(key.length() > 0 && key.charAt(0) == ' ')
key = key.substring(1);
while(key.length() > 0 && key.charAt(key.length()-1) == ' ')
key = key.substring(0, key.length()-2);
- System.out.println("New name: "+key);
+ outsb.append("New name: "+key);
n.setName(key);
} else if(uline.startsWith("DISCONNECT:")) {
String ipAndPort = line.substring("DISCONNECT:".length());
@@ -512,31 +544,34 @@
} else if(uline.startsWith("PLUGLOAD:")) {
if (line.substring("PLUGLOAD:".length()).trim().equals("?")) {
- System.out.println(" PLUGLOAD: pkg.Class
- Load plugin from current classpath");
- System.out.println(" PLUGLOAD: pkg.Class at
file:<filename> - Load plugin from file");
- System.out.println(" PLUGLOAD: pkg.Class at http://...
- Load plugin from online file");
- System.out.println(" PLUGLOAD: *@...
- Load plugin from manifest in given jarfile");
- System.out.println("");
- System.out.println("If the filename/url ends with
\".url\", it" +
+ outsb.append(" PLUGLOAD: pkg.Class -
Load plugin from current classpath");
+ outsb.append(" PLUGLOAD: pkg.Class at file:<filename>
- Load plugin from file");
+ outsb.append(" PLUGLOAD: pkg.Class at http://...
- Load plugin from online file");
+ outsb.append(" PLUGLOAD: *@... -
Load plugin from manifest in given jarfile");
+ outsb.append("");
+ outsb.append("If the filename/url ends with \".url\",
it" +
" is treated as a link, meaning that
the first line is" +
" the accual URL. Else it is loaded as
classpath and" +
" the class it loaded from it (meaning
the file could" +
" be either a jar-file or a
class-file).");
- System.out.println("");
- System.out.println(" PLUGLOAD: pkg.Class* - Load
newest version of plugin from
http://downloads.freenetproject.org/alpha/plugins/");
- System.out.println("");
+ outsb.append("");
+ outsb.append(" PLUGLOAD: pkg.Class* - Load newest
version of plugin from http://downloads.freenetproject.org/alpha/plugins/");
+ outsb.append("");
} else
n.pluginManager.startPlugin(line.substring("PLUGLOAD:".length()).trim());
- //System.out.println("PLUGLOAD: <pkg.classname>[(@<URI to
jarfile.jar>|<<URI to file containing real URI>|* (will load from freenets
pluginpool))] - Load plugin.");
+ //outsb.append("PLUGLOAD: <pkg.classname>[(@<URI to
jarfile.jar>|<<URI to file containing real URI>|* (will load from freenets
pluginpool))] - Load plugin.");
} else if(uline.startsWith("PLUGLIST")) {
- System.out.println(n.pluginManager.dumpPlugins());
+ outsb.append(n.pluginManager.dumpPlugins());
} else if(uline.startsWith("PLUGKILL:")) {
n.pluginManager.killPlugin(line.substring("PLUGKILL:".length()).trim());
} else {
if(uline.length() > 0)
- printHeader();
+ printHeader(out);
}
+ outsb.append("\n");
+ out.write(outsb.toString().getBytes());
+ out.flush();
}
/**
@@ -709,9 +744,4 @@
return sb.toString();
}
- public static void maybeCreate(Node node, Config config) {
- // FIXME make this configurable.
- // Depends on fixing QUIT issues. (bug #81)
- new TextModeClientInterface(node);
- }
}
Added: trunk/freenet/src/freenet/node/TextModeClientInterfaceServer.java
===================================================================
--- trunk/freenet/src/freenet/node/TextModeClientInterfaceServer.java
2006-03-15 19:16:28 UTC (rev 8255)
+++ trunk/freenet/src/freenet/node/TextModeClientInterfaceServer.java
2006-03-15 19:53:25 UTC (rev 8256)
@@ -0,0 +1,232 @@
+package freenet.node;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketException;
+import java.net.SocketTimeoutException;
+import java.util.Hashtable;
+
+import freenet.client.HighLevelSimpleClient;
+import freenet.client.events.EventDumper;
+import freenet.config.BooleanCallback;
+import freenet.config.Config;
+import freenet.config.IntCallback;
+import freenet.config.InvalidConfigValueException;
+import freenet.config.StringCallback;
+import freenet.config.SubConfig;
+import freenet.crypt.RandomSource;
+import freenet.support.Logger;
+
+public class TextModeClientInterfaceServer implements Runnable {
+
+ final RandomSource r;
+ final Node n;
+ final HighLevelSimpleClient client;
+ final Hashtable streams;
+ final File downloadsDir;
+ int port;
+ final String bindto;
+ boolean isEnabled;
+
+ TextModeClientInterfaceServer(Node n, HighLevelSimpleClient client, int
port, String bindto) {
+ this.n = n;
+ this.client = client;
+ client.addGlobalHook(new EventDumper());
+ this.r = n.random;
+ streams = new Hashtable();
+ this.downloadsDir = n.downloadDir;
+ this.port=port;
+ this.bindto=bindto;
+ this.isEnabled=true;
+ n.setTMCI(this);
+ new Thread(this, "Text mode client interface").start();
+ }
+
+ public static void maybeCreate(Node node, Config config) throws
IOException {
+ SubConfig TMCIConfig = new SubConfig("tmci", config);
+
+ TMCIConfig.register("enabled", true, 1, true, "Enable TMCI",
"Whether to enable the TMCI",
+ new TMCIEnabledCallback(node));
+ TMCIConfig.register("bindto", "127.0.0.1", 2, true, "IP address
to bind to", "IP address to bind to",
+ new TMCIBindtoCallback(node));
+ TMCIConfig.register("port", 2323, 1, true, "Testnet port",
"Testnet port number",
+ new TCMIPortNumberCallback(node));
+ TMCIConfig.register("directEnabled", false, 1, true, "Enable on
stdout/stdin?", "Enable text mode client interface on standard input/output?
(.enabled refers to providing a telnet-style server, this runs it over a
socket)",
+ new TMCIDirectEnabledCallback(node));
+
+ boolean TMCIEnabled = TMCIConfig.getBoolean("enabled");
+ int port = TMCIConfig.getInt("port");
+ String bind_ip = TMCIConfig.getString("bindto");
+ boolean direct = TMCIConfig.getBoolean("directEnabled");
+ HighLevelSimpleClient client =
node.makeClient(RequestStarter.INTERACTIVE_PRIORITY_CLASS);
+
+ if(TMCIEnabled){
+ new TextModeClientInterfaceServer(node, client, port,
bind_ip);
+ Logger.normal(node, "TMCI started on
"+bind_ip+":"+port);
+ System.out.println("TMCI started on "+bind_ip+":"+port);
+ }
+ else{
+ Logger.normal(node, "Not starting TMCI as it's
disabled");
+ }
+
+ if(direct) {
+ TextModeClientInterface directTMCI =
+ new TextModeClientInterface(node, client,
node.downloadDir, System.in, System.out);
+ Thread t = new Thread(directTMCI, "Direct text mode
interface");
+ t.setDaemon(true);
+ t.start();
+ node.setDirectTMCI(directTMCI);
+ }
+
+ TMCIConfig.finishedInitialization();
+ }
+
+
+ static class TMCIEnabledCallback implements BooleanCallback {
+
+ final Node node;
+
+ TMCIEnabledCallback(Node n) {
+ this.node = n;
+ }
+
+ public boolean get() {
+ return node.getTextModeClientInterface() != null;
+ }
+
+ public void set(boolean val) throws InvalidConfigValueException {
+ if(val == get()) return;
+ // FIXME implement - see bug #122
+ throw new InvalidConfigValueException("Cannot be updated on the
fly");
+ }
+ }
+
+ static class TMCIDirectEnabledCallback implements BooleanCallback {
+
+ final Node node;
+
+ TMCIDirectEnabledCallback(Node n) {
+ this.node = n;
+ }
+
+ public boolean get() {
+ return node.getDirectTMCI() != null;
+ }
+
+ public void set(boolean val) throws InvalidConfigValueException {
+ if(val == get()) return;
+ // FIXME implement - see bug #122
+ throw new InvalidConfigValueException("Cannot be updated on the
fly");
+ }
+ }
+
+ static class TMCIBindtoCallback implements StringCallback {
+
+ final Node node;
+
+ TMCIBindtoCallback(Node n) {
+ this.node = n;
+ }
+
+ public String get() {
+ if(node.getTextModeClientInterface()!=null)
+ return node.getTextModeClientInterface().bindto;
+ else
+ return "127.0.0.1";
+ }
+
+ public void set(String val) throws InvalidConfigValueException {
+ if(val == get()) return;
+ throw new InvalidConfigValueException("Cannot be updated on the
fly");
+ }
+ }
+
+ static class TCMIPortNumberCallback implements IntCallback{
+
+ final Node node;
+
+ TCMIPortNumberCallback(Node n) {
+ this.node = n;
+ }
+
+ public int get() {
+ if(node.getTextModeClientInterface()!=null)
+ return node.getTextModeClientInterface().port;
+ else
+ return 2323;
+ }
+
+ // TODO: implement it
+ public void set(int val) throws InvalidConfigValueException {
+ if(val == get()) return;
+ node.getTextModeClientInterface().setPort(val);
+ }
+ }
+
+ /**
+ * Read commands, run them
+ */
+ public void run() {
+ while(true) {
+ int curPort = port;
+ String bindTo = this.bindto;
+ ServerSocket server;
+ try {
+ server = new ServerSocket(curPort, 0,
InetAddress.getByName(bindTo));
+ } catch (IOException e) {
+ Logger.error(this, "Could not bind to TMCI port:
"+bindto+":"+port);
+ System.exit(-1);
+ return;
+ }
+ try {
+ server.setSoTimeout(1000);
+ } catch (SocketException e1) {
+ Logger.error(this, "Could not set timeout: "+e1, e1);
+ System.err.println("Could not start TMCI: "+e1);
+ e1.printStackTrace();
+ return;
+ }
+ while(isEnabled) {
+ // Maybe something has changed?
+ if(port != curPort) break;
+ if(!(this.bindto.equals(bindTo))) break;
+ try {
+ Socket s = server.accept();
+ InputStream in = s.getInputStream();
+ OutputStream out = s.getOutputStream();
+
+ TextModeClientInterface tmci =
+ new TextModeClientInterface(this, in,
out);
+
+ Thread t = new Thread(tmci, "Text mode client
interface handler for "+s.getPort());
+
+ t.setDaemon(true);
+
+ t.start();
+
+ } catch (SocketTimeoutException e) {
+ // Ignore and try again
+ } catch (SocketException e){
+ Logger.error(this, "Socket error : "+e, e);
+ } catch (IOException e) {
+ Logger.error(this, "TMCI failed to accept
socket: "+e, e);
+ }
+ }
+ try{
+ server.close();
+ }catch (IOException e){
+ Logger.error(this, "Error shuting down TMCI", e);
+ }
+ }
+ }
+
+ public void setPort(int val) {
+ port = val;
+ }
+
+}
Modified: trunk/freenet/src/freenet/node/Version.java
===================================================================
--- trunk/freenet/src/freenet/node/Version.java 2006-03-15 19:16:28 UTC (rev
8255)
+++ trunk/freenet/src/freenet/node/Version.java 2006-03-15 19:53:25 UTC (rev
8256)
@@ -20,7 +20,7 @@
public static final String protocolVersion = "1.0";
/** The build number of the current revision */
- private static final int buildNumber = 535;
+ private static final int buildNumber = 536;
/** Oldest build of Fred we will talk to */
private static final int lastGoodBuild = 507;
Modified: trunk/freenet/src/freenet/node/fcp/ClientGet.java
===================================================================
--- trunk/freenet/src/freenet/node/fcp/ClientGet.java 2006-03-15 19:16:28 UTC
(rev 8255)
+++ trunk/freenet/src/freenet/node/fcp/ClientGet.java 2006-03-15 19:53:25 UTC
(rev 8256)
@@ -1,6 +1,5 @@
package freenet.node.fcp;
-import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
Modified: trunk/freenet/src/freenet/node/fcp/FCPServer.java
===================================================================
--- trunk/freenet/src/freenet/node/fcp/FCPServer.java 2006-03-15 19:16:28 UTC
(rev 8255)
+++ trunk/freenet/src/freenet/node/fcp/FCPServer.java 2006-03-15 19:53:25 UTC
(rev 8256)
@@ -247,17 +247,17 @@
Logger.normal(node, "Starting FCP server on
"+fcpConfig.getString("bindto")+":"+fcpConfig.getInt("port")+".");
fcp = new FCPServer(fcpConfig.getString("bindto"),
fcpConfig.getInt("port"), node, persistentDownloadsEnabled,
persistentDownloadsDir, persistentDownloadsInterval);
node.setFCPServer(fcp);
+
+ if(fcp != null) {
+ cb1.server = fcp;
+ cb2.server = fcp;
+ cb3.server = fcp;
+ }
}else{
Logger.normal(node, "Not starting FCP server as it's
disabled");
fcp = null;
}
-
- if(fcp != null) {
- cb1.server = fcp;
- cb2.server = fcp;
- cb3.server = fcp;
- }
-
+
fcpConfig.finishedInitialization();
return fcp;
}