created mirror
This commit is contained in:
71
Modules/ztp/ZTPclient.java
Normal file
71
Modules/ztp/ZTPclient.java
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
ZTPclient.java
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Antti-Juhani Kaijanaho
|
||||
*/
|
||||
package org.gzigzag.module;
|
||||
import org.gzigzag.*;
|
||||
import org.gzigzag.ztp.*;
|
||||
import org.gzigzag.ztp.client.*;
|
||||
import java.awt.*;
|
||||
import java.net.*;
|
||||
import java.io.*;
|
||||
|
||||
public class ZTPclient {
|
||||
public static boolean dbg = false;
|
||||
private static void p(String s) { if(dbg) ZZLogger.log(s); }
|
||||
private static void pa(String s) { ZZLogger.log(s); }
|
||||
|
||||
private static Action[] actions = { new Get(), new Put() };
|
||||
|
||||
public static ZZModule module = new ZZModule() {
|
||||
public void action(String id,
|
||||
ZZCell code,
|
||||
ZZCell target,
|
||||
ZZView view, ZZView cview, String key,
|
||||
Point pt, ZZScene xi) {
|
||||
for (int i = 0; i < actions.length; i++) {
|
||||
if (id.toUpperCase().equals(actions[i].name().toUpperCase())) {
|
||||
RemotePieceData rpd = new RemotePieceData();
|
||||
String err = rpd.readParams(target);
|
||||
if (err != null && !err.equals("")) throw new ZZError(err);
|
||||
Session ses = null;
|
||||
if (actions[i].needSession()) {
|
||||
try {
|
||||
ses = new Session(rpd.serverFQDN, rpd.serverPort);
|
||||
ses.login(rpd.userName, rpd.userPassword);
|
||||
} catch (UnknownHostException e) {
|
||||
throw new ZZError(""+e);
|
||||
} catch (IOException e) {
|
||||
throw new ZZError(""+e);
|
||||
}
|
||||
}
|
||||
actions[i].action(rpd, ses);
|
||||
try {
|
||||
if (ses != null) ses.close();
|
||||
} catch (IOException e) {
|
||||
throw new ZZError(""+e);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw new ZZError("unknown ZTPclient action");
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
82
Modules/ztp/ZTPserver.java
Normal file
82
Modules/ztp/ZTPserver.java
Normal file
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
STPserver.java
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Antti-Juhani Kaijanaho
|
||||
*/
|
||||
package org.gzigzag.module;
|
||||
import org.gzigzag.ztp.*;
|
||||
import org.gzigzag.ztp.server.*;
|
||||
import org.gzigzag.*;
|
||||
import java.net.*;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
/** This is a prototype STP server. Currently it supports a
|
||||
* mock-STP/TCP in order to test the ideas in the WIP spec. */
|
||||
public class ZTPserver {
|
||||
public static boolean dbg = false;
|
||||
private static void p(String s) { if(dbg) ZZLogger.log("[" + s + "]"); }
|
||||
private static void pa(String s) { ZZLogger.log(s); }
|
||||
|
||||
protected Listener listener;
|
||||
|
||||
public ZTPserver(ZZSpace space, Integer inetport) {
|
||||
this(space, inetport.intValue());
|
||||
}
|
||||
|
||||
public ZTPserver(ZZSpace space, int inetport) {
|
||||
p("ZTP creation start");
|
||||
ServerSocket sock;
|
||||
try {
|
||||
sock = new ServerSocket(inetport);
|
||||
} catch (IOException e) {
|
||||
throw new ZZError("Unable to bind to server port " + inetport + ": " + e);
|
||||
}
|
||||
listener = new Listener(space, sock);
|
||||
listener.start();
|
||||
p("ZTP creation finished");
|
||||
}
|
||||
|
||||
public void kill() throws InterruptedException {
|
||||
listener.interrupt();
|
||||
listener.join();
|
||||
for (Enumeration e = Session.getActiveSessions(); e.hasMoreElements();) {
|
||||
Session s = (Session) e.nextElement();
|
||||
s.interrupt();
|
||||
}
|
||||
for (Enumeration e = Session.getActiveSessions(); e.hasMoreElements();) {
|
||||
Session s = (Session) e.nextElement();
|
||||
s.join();
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
ZTPserver serv = new ZTPserver(new ZZDimSpace(), 5555);
|
||||
try {
|
||||
serv.listener.join();
|
||||
serv.kill();
|
||||
} catch (InterruptedException e) {
|
||||
ZZLogger.exc(e);
|
||||
}
|
||||
SafeExit.exit(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
29
Modules/ztp/client/Action.java
Normal file
29
Modules/ztp/client/Action.java
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
Action.java
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Antti-Juhani Kaijanaho
|
||||
*/
|
||||
|
||||
package org.gzigzag.ztp.client;
|
||||
|
||||
public interface Action {
|
||||
String name();
|
||||
boolean needSession();
|
||||
void action(RemotePieceData rpd, Session ses);
|
||||
}
|
||||
|
||||
43
Modules/ztp/client/Get.java
Normal file
43
Modules/ztp/client/Get.java
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
Get.java
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Antti-Juhani Kaijanaho
|
||||
*/
|
||||
|
||||
package org.gzigzag.ztp.client;
|
||||
import org.gzigzag.ztp.*;
|
||||
import org.gzigzag.*;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
public class Get implements Action {
|
||||
|
||||
public String name() { return "GET"; }
|
||||
public boolean needSession() { return true; }
|
||||
public void action(RemotePieceData rpd, Session ses) {
|
||||
|
||||
try {
|
||||
ses.get(rpd.subspaceName, rpd.subspace);
|
||||
} catch (IOException e) {
|
||||
throw new ZZError("" + e);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
43
Modules/ztp/client/Put.java
Normal file
43
Modules/ztp/client/Put.java
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
Put.java
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Antti-Juhani Kaijanaho
|
||||
*/
|
||||
|
||||
package org.gzigzag.ztp.client;
|
||||
import org.gzigzag.ztp.*;
|
||||
import org.gzigzag.*;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
public class Put implements Action {
|
||||
|
||||
public String name() { return "PUT"; }
|
||||
public boolean needSession() { return true; }
|
||||
public void action(RemotePieceData rpd, Session ses) {
|
||||
if (rpd.subspace == null) throw new ZZError("there's nothing to put!");
|
||||
Subspace ss = new Subspace(rpd.subspace.s("d.ztp-subspace"));
|
||||
try {
|
||||
ses.put(rpd.subspaceName, ss.getCells(), ss.getSoftDims());
|
||||
} catch (IOException e) {
|
||||
throw new ZZError("" + e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
64
Modules/ztp/client/RemotePieceData.zob
Normal file
64
Modules/ztp/client/RemotePieceData.zob
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
RemotePieceData.zob
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Antti-Juhani Kaijanaho
|
||||
*/
|
||||
package org.gzigzag.ztp.client;
|
||||
import org.gzigzag.*;
|
||||
|
||||
public class RemotePieceData implements ZOb {
|
||||
public static boolean dbg = false;
|
||||
private static void p(String s) { if(dbg) ZZLogger.log(s); }
|
||||
private static void pa(String s) { ZZLogger.log(s); }
|
||||
|
||||
STRUCTPARAMS {
|
||||
|
||||
/** Server FQDN. */
|
||||
String serverFQDN = null;
|
||||
|
||||
/** Server port. */
|
||||
int serverPort = -1;
|
||||
|
||||
/** User name. */
|
||||
String userName = null;
|
||||
|
||||
/** User password. */
|
||||
String userPassword = null;
|
||||
|
||||
/** Subspace name. */
|
||||
String subspaceName = "ALL";
|
||||
|
||||
/** Subspace handle. */
|
||||
ZZCell subspace = null;
|
||||
|
||||
}
|
||||
|
||||
INITIALIZE {
|
||||
if (serverFQDN == null) throw new ZZError("need server FQDN");
|
||||
if (serverPort == -1) throw new ZZError("need server port");
|
||||
if (userName == null) throw new ZZError("need a user name");
|
||||
if (subspaceName == null) throw new ZZError("need a subspace name");
|
||||
p("serverFQDN = " + serverFQDN);
|
||||
p("serverPort = " + serverPort);
|
||||
p("userName = " + userName);
|
||||
p("userPassword = " + userPassword);
|
||||
p("subspaceName = " + subspaceName);
|
||||
p("subspace = " + subspace);
|
||||
}
|
||||
|
||||
}
|
||||
76
Modules/ztp/client/Response.java
Normal file
76
Modules/ztp/client/Response.java
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
Session.java
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Antti-Juhani Kaijanaho
|
||||
*/
|
||||
package org.gzigzag.ztp.client;
|
||||
import org.gzigzag.*;
|
||||
import org.gzigzag.ztp.*;
|
||||
|
||||
class Response {
|
||||
public static boolean dbg = false;
|
||||
private static void p(String s) { if(dbg) ZZLogger.log("[" + s + "]"); }
|
||||
private static void pa(String s) { ZZLogger.log(s); }
|
||||
|
||||
public int major;
|
||||
public int minor;
|
||||
public int ident;
|
||||
|
||||
// Major codes
|
||||
public final static int positivePreliminary = 1;
|
||||
public final static int positiveCompletion = 2;
|
||||
public final static int positiveIntermediate = 3;
|
||||
public final static int transientNegativeCompletion = 4;
|
||||
public final static int permanentNegativeCompletion = 5;
|
||||
|
||||
// Minor codes
|
||||
public final static int syntaxCode = 0;
|
||||
public final static int informationCode = 1;
|
||||
public final static int connectionCode = 2;
|
||||
public final static int authenticationCode = 3;
|
||||
public final static int subspaceCode = 4;
|
||||
|
||||
public String explanation;
|
||||
|
||||
public Response(String line) {
|
||||
try {
|
||||
ZTPCommand.RV r;
|
||||
|
||||
r = ZTPCommand.ASCII_number(line);
|
||||
p("r = " + r);
|
||||
if (r == null || r.rest.charAt(0) != '.') throw new SyntaxError("bad response line: " + line);
|
||||
major = Integer.parseInt(r.token);
|
||||
|
||||
r = ZTPCommand.ASCII_number(r.rest.substring(1));
|
||||
p("r = " + r);
|
||||
if (r == null || r.rest.charAt(0) != '.') throw new SyntaxError("bad response line: " + line);
|
||||
minor = Integer.parseInt(r.token);
|
||||
|
||||
r = ZTPCommand.ASCII_number(r.rest.substring(1));
|
||||
p("r = " + r);
|
||||
if (r == null || r.rest.charAt(0) != ' ') throw new SyntaxError("bad response line: " + line);
|
||||
ident = Integer.parseInt(r.token);
|
||||
|
||||
r = ZTPCommand.lwsp(r.rest);
|
||||
explanation = r.rest;
|
||||
} catch (NumberFormatException e) {
|
||||
throw new ZZError("" + e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
165
Modules/ztp/client/Session.java
Normal file
165
Modules/ztp/client/Session.java
Normal file
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
Session.java
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Antti-Juhani Kaijanaho
|
||||
*/
|
||||
package org.gzigzag.ztp.client;
|
||||
import org.gzigzag.*;
|
||||
import org.gzigzag.ztp.*;
|
||||
import java.net.*;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
public class Session implements SafeExit.Cleanupable {
|
||||
|
||||
private String server;
|
||||
private Socket sock;
|
||||
private int port;
|
||||
private LineBufferedIO io;
|
||||
|
||||
public Session(String server, int port) throws UnknownHostException {
|
||||
this.server = server;
|
||||
this.port = port;
|
||||
|
||||
try {
|
||||
sock = new Socket(server, port);
|
||||
io = new LineBufferedIO(sock.getInputStream(), sock.getOutputStream());
|
||||
|
||||
String line = io.readline();
|
||||
Response resp = new Response(line);
|
||||
if (resp.major != Response.positiveCompletion) {
|
||||
sock.close();
|
||||
throw new ZZError("no response from server");
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new ZZError("" + e);
|
||||
}
|
||||
SafeExit.registerObject(this);
|
||||
}
|
||||
|
||||
/** Login to server. If passwd is null, attempt
|
||||
* preauthentication. */
|
||||
public void login(String username, String passwd) throws IOException {
|
||||
if (passwd == null) {
|
||||
io.writeln("AUTH/PRE " + ZTPCommand.encode(username));
|
||||
} else {
|
||||
io.writeln("AUTH/PASS " + ZTPCommand.encode(username)
|
||||
+ " " + ZTPCommand.encode(passwd));
|
||||
}
|
||||
Response resp = new Response(io.readline());
|
||||
if (resp.major != Response.positiveCompletion) {
|
||||
throw new ZZError("Unable to login: " + resp.explanation);
|
||||
}
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
io.writeln("QUIT");
|
||||
io.readline();
|
||||
sock.close();
|
||||
SafeExit.unregisterObject(this);
|
||||
}
|
||||
|
||||
public void cleanup() throws Throwable {
|
||||
io.writeln("A");
|
||||
io.readline();
|
||||
io.writeln("QUIT");
|
||||
io.readline();
|
||||
sock.close();
|
||||
}
|
||||
|
||||
public void put(String subspace, Enumeration cells, String[] sdims) throws IOException {
|
||||
io.writeln("PUT " + ZTPCommand.encode(subspace));
|
||||
Response res = new Response(io.readline());
|
||||
if (res.major != Response.positiveIntermediate) {
|
||||
throw new ZZError("unable to put: " + res.explanation);
|
||||
}
|
||||
SubspaceDump.dump(io, cells, sdims, "");
|
||||
res = new Response(io.readline());
|
||||
if (res.major != Response.positiveCompletion) {
|
||||
throw new ZZError("failed to put: " + res.explanation);
|
||||
}
|
||||
}
|
||||
|
||||
public void get(String subspace, ZZCell basecell) throws IOException {
|
||||
io.writeln("GET " + ZTPCommand.encode(subspace));
|
||||
Response res = new Response(io.readline());
|
||||
if (res.major != Response.positiveIntermediate) {
|
||||
throw new ZZError("unable to get: " + res.explanation);
|
||||
}
|
||||
|
||||
SubspaceDump sd;
|
||||
try {
|
||||
sd = new SubspaceDump(io);
|
||||
} finally {
|
||||
res = new Response(io.readline());
|
||||
if (res.major != Response.positiveCompletion) {
|
||||
throw new ZZError("failed to get: " + res.explanation);
|
||||
}
|
||||
}
|
||||
|
||||
// Delete the old subspace
|
||||
if (basecell != null && basecell.s("d.ztp-subspace") != null) {
|
||||
Subspace ss = new Subspace(basecell.s("d.ztp-subspace"));
|
||||
String[] sdims = ss.getSoftDims();
|
||||
for (Enumeration e = ss.getCells(); e.hasMoreElements();) {
|
||||
ZZCell c = (ZZCell)e.nextElement();
|
||||
|
||||
for (int i = 0; i < sdims.length; i++) {
|
||||
if (c.s(sdims[i], 1) != null) c.disconnect(sdims[i], 1);
|
||||
if (c.s(sdims[i], -1) != null) c.disconnect(sdims[i], -1);
|
||||
}
|
||||
if (c.s("d.ztp-subspace", 1) != null) c.disconnect("d.ztp-subspace", 1);
|
||||
if (c.s("d.ztp-subspace", -1) != null) c.disconnect("d.ztp-subspace", -1);
|
||||
}
|
||||
}
|
||||
|
||||
ZZDimSpace space = (ZZDimSpace)basecell.getSpace();
|
||||
|
||||
// Create the new subspace
|
||||
{
|
||||
ZZCell oc = basecell;
|
||||
for (Enumeration e = sd.cellids.keys(); e.hasMoreElements();) {
|
||||
String s = (String)e.nextElement();
|
||||
ZZCell c = space.getCellByID(s);
|
||||
oc.connect("d.ztp-subspace", 1, c);
|
||||
oc = c;
|
||||
}
|
||||
}
|
||||
|
||||
for (Enumeration e = sd.content.keys(); e.hasMoreElements();) {
|
||||
String s = (String)e.nextElement();
|
||||
ZZCell c = space.getCellByID(s);
|
||||
c.setText((String)sd.content.get(s));
|
||||
}
|
||||
for (Enumeration e = sd.dims.keys(); e.hasMoreElements();) {
|
||||
String dimname = (String)e.nextElement();
|
||||
Hashtable dim = (Hashtable)sd.dims.get(dimname);
|
||||
space.d(dimname);
|
||||
for (Enumeration f = dim.keys(); f.hasMoreElements();) {
|
||||
String s1 = (String)f.nextElement();
|
||||
String s2 = (String)dim.get(s1);
|
||||
ZZCell c1 = space.getCellByID(s1);
|
||||
ZZCell c2 = space.getCellByID(s2);
|
||||
c1.connect(dimname, c2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
76
Modules/ztp/client/Subspace.java
Normal file
76
Modules/ztp/client/Subspace.java
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
Put.java
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Antti-Juhani Kaijanaho
|
||||
*/
|
||||
|
||||
package org.gzigzag.ztp.client;
|
||||
import org.gzigzag.ztp.*;
|
||||
import org.gzigzag.*;
|
||||
import java.util.*;
|
||||
|
||||
class Subspace {
|
||||
|
||||
private String[] sdims;
|
||||
private Hashtable cells = new Hashtable();
|
||||
|
||||
public String[] getSoftDims() { return sdims; }
|
||||
public Enumeration getCells() { return cells.keys(); }
|
||||
|
||||
public Subspace(ZZCell base) {
|
||||
String[] origdims = base.getSpace().dims();
|
||||
Vector dimv = new Vector();
|
||||
|
||||
for (int i = 0; i < origdims.length; i++) {
|
||||
if (origdims[i].equals("d.ztp-subspace")
|
||||
|| origdims[i].equals("d.cellcreation")) {
|
||||
continue;
|
||||
}
|
||||
dimv.addElement(origdims[i]);
|
||||
}
|
||||
|
||||
sdims = new String[dimv.size()];
|
||||
for (int i = 0; i < sdims.length; i++) {
|
||||
sdims[i] = (String)dimv.elementAt(i);
|
||||
}
|
||||
|
||||
if (base == null) return;
|
||||
|
||||
Stack stack = new Stack();
|
||||
stack.push(base);
|
||||
Hashtable seen = new Hashtable();
|
||||
while (!stack.empty()) {
|
||||
ZZCell c = (ZZCell)stack.pop();
|
||||
|
||||
for (int i = 0; i < sdims.length; i++) {
|
||||
ZZCell d = c.s(sdims[i], 1);
|
||||
if (d != null && !seen.containsKey(d)) {
|
||||
stack.push(d);
|
||||
seen.put(d, d);
|
||||
}
|
||||
d = c.s(sdims[i], -1);
|
||||
if (d != null && !seen.containsKey(d)) {
|
||||
stack.push(d);
|
||||
seen.put(d, d);
|
||||
}
|
||||
}
|
||||
cells.put(c, c);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
111
Modules/ztp/common/LineBufferedIO.java
Normal file
111
Modules/ztp/common/LineBufferedIO.java
Normal file
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
LineBufferedIO.java
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Antti-Juhani Kaijanaho
|
||||
*/
|
||||
package org.gzigzag.ztp;
|
||||
import org.gzigzag.module.*;
|
||||
import org.gzigzag.*;
|
||||
import java.io.*;
|
||||
|
||||
/** Line-buffered UTF-8 I/O. */
|
||||
public class LineBufferedIO {
|
||||
public static boolean dbg = false;
|
||||
private static void p(String s) { if(dbg) ZZLogger.log(s); }
|
||||
private static void pa(String s) { ZZLogger.log(s); }
|
||||
|
||||
InputStream in;
|
||||
OutputStream out;
|
||||
String buffer = new String();
|
||||
public LineBufferedIO(InputStream in, OutputStream out) {
|
||||
this.in = in;
|
||||
this.out = out;
|
||||
}
|
||||
|
||||
public synchronized void flush() throws IOException {
|
||||
for (int i = 0; i < buffer.length(); i++) {
|
||||
UTF8Char ch = new UTF8Char(buffer.charAt(i));
|
||||
out.write(ch.b, 0, ch.b.length);
|
||||
}
|
||||
out.flush();
|
||||
if (buffer.charAt(buffer.length()-1) == '\n') {
|
||||
p("==> " + buffer.substring(0, buffer.length()-1));
|
||||
} else {
|
||||
p("==> " + buffer);
|
||||
}
|
||||
buffer = "";
|
||||
}
|
||||
public synchronized void write(String s) throws IOException {
|
||||
for (int i = 0; i < s.length(); i++) {
|
||||
buffer += s.charAt(i);
|
||||
if (s.charAt(i) == '\n') flush();
|
||||
}
|
||||
}
|
||||
public synchronized void writeln(String s) throws IOException {
|
||||
write(s + "\n");
|
||||
}
|
||||
|
||||
private boolean ineof = false;
|
||||
|
||||
public boolean isEOF() { return ineof; }
|
||||
|
||||
/** Reads one UTF-8 character. If EOF is reached, the EOF
|
||||
* flag is set and the returned value will be undefined. */
|
||||
public char getc() throws IOException {
|
||||
if (ineof) return '\n';
|
||||
int o = in.read();
|
||||
if (o == -1) {
|
||||
ineof = true;
|
||||
return '\n';
|
||||
}
|
||||
int len = UTF8Char.UTF8Len((byte) o);
|
||||
byte[] bs = new byte[len];
|
||||
bs[0] = (byte)o;
|
||||
for (int i = 1; i < len; i++) {
|
||||
o = in.read();
|
||||
if (o == -1) {
|
||||
ineof = true;
|
||||
throw new IOException("file ended before char was complete");
|
||||
}
|
||||
bs[i] = (byte)o;
|
||||
}
|
||||
return (new UTF8Char(bs)).c;
|
||||
}
|
||||
|
||||
/* Reads until the end of line (including the EOL character),
|
||||
* or to EOF. */
|
||||
public String readline() throws IOException {
|
||||
String rv = new String();
|
||||
|
||||
char c;
|
||||
do {
|
||||
c = getc();
|
||||
if (isEOF()) break;
|
||||
rv += c;
|
||||
} while (c != '\n');
|
||||
|
||||
if (rv.charAt(rv.length()-1) == '\n') {
|
||||
p("<== " + rv.substring(0, rv.length()-1));
|
||||
} else {
|
||||
p("<== " + rv);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
134
Modules/ztp/common/SubspaceDump.java
Normal file
134
Modules/ztp/common/SubspaceDump.java
Normal file
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
SubspaceDump.java
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Antti-Juhani Kaijanaho
|
||||
*/
|
||||
package org.gzigzag.ztp;
|
||||
import org.gzigzag.*;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
public class SubspaceDump {
|
||||
public static boolean dbg = false;
|
||||
private static void p(String s) { if(dbg) ZZLogger.log("[" + s + "]"); }
|
||||
private static void pa(String s) { ZZLogger.log(s); }
|
||||
|
||||
public static class AbortedException extends ZZError {
|
||||
public AbortedException(String s) {
|
||||
super(s);
|
||||
}
|
||||
}
|
||||
|
||||
/** Cell content. This hashtable maps cell IDs into cell
|
||||
* content. */
|
||||
public Hashtable content = new Hashtable();
|
||||
|
||||
/* Dimensions. This hashtable maps dimension names into
|
||||
* hashtables that map cells to cells (key connected to datum
|
||||
* posward along the dimension). */
|
||||
public Hashtable dims = new Hashtable();
|
||||
|
||||
|
||||
/* Cell IDs. This hashtable contains an entry for every cell that
|
||||
* has a content entry or a connection entry. */
|
||||
public Hashtable cellids = new Hashtable();
|
||||
|
||||
public SubspaceDump(LineBufferedIO io) throws IOException {
|
||||
boolean ok = true;
|
||||
while (!io.isEOF()) {
|
||||
try {
|
||||
String line = io.readline();
|
||||
ZTPCommand cmd = new ZTPCommand(line);
|
||||
|
||||
if (cmd.name.toUpperCase().equals("C")) {
|
||||
if (cmd.args.length != 2) {
|
||||
p("C args len = " + cmd.args.length);
|
||||
ok = false;
|
||||
continue;
|
||||
}
|
||||
Object o = content.get(cmd.args[0]);
|
||||
String s = "";
|
||||
if (o != null) s = (String)o;
|
||||
s += cmd.args[1];
|
||||
content.put(cmd.args[0], s);
|
||||
cellids.put(cmd.args[0], cmd.args[0]);
|
||||
} else if (cmd.name.toUpperCase().equals("R")) {
|
||||
if (cmd.args.length < 3) {
|
||||
p("R args len = " + cmd.args.length);
|
||||
ok = false;
|
||||
continue;
|
||||
}
|
||||
Hashtable dim = (Hashtable)dims.get(cmd.args[0]);
|
||||
if (dim == null) {
|
||||
dim = new Hashtable();
|
||||
dims.put(cmd.args[0], dim);
|
||||
}
|
||||
for (int i = 1; ok && i + 1 < cmd.args.length; i++) {
|
||||
Object o = dim.get(cmd.args[i]);
|
||||
if (o != null && !((String)o).equals(cmd.args[i+1])) {
|
||||
p("existing connection (" + cmd.args[i] + ", " + (String)o + ") will be broken"+
|
||||
" by new connection (" + cmd.args[i] + ", " + cmd.args[i+1]);
|
||||
ok = false;
|
||||
continue;
|
||||
}
|
||||
dim.put(cmd.args[i], cmd.args[i+1]);
|
||||
cellids.put(cmd.args[i], cmd.args[i]);
|
||||
cellids.put(cmd.args[i+1], cmd.args[i+1]);
|
||||
}
|
||||
} else if (cmd.name.toUpperCase().equals("F")) {
|
||||
break;
|
||||
} else if (cmd.name.toUpperCase().equals("A")) {
|
||||
throw new AbortedException("Subspace data transfer aborted");
|
||||
} else {
|
||||
p("unknown command");
|
||||
ok = false;
|
||||
continue;
|
||||
}
|
||||
} catch (SyntaxError e) {
|
||||
ZZLogger.exc(e);
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
if (!ok) throw new SyntaxError("Syntax error is subspace data");
|
||||
}
|
||||
|
||||
public static void dump(LineBufferedIO io, Enumeration cells,
|
||||
String[] sdims, String prefix) throws IOException {
|
||||
|
||||
for (; cells.hasMoreElements();) {
|
||||
ZZCell c = (ZZCell)cells.nextElement();
|
||||
String cid = c.getGlobalID().substring(prefix.length());
|
||||
p("cell " + c);
|
||||
io.writeln("C " + ZTPCommand.encode(cid) + " " + ZTPCommand.encode(c.getText()));
|
||||
// Find connections from this cell
|
||||
for (int i = 0; i < sdims.length; i++) {
|
||||
String dim = sdims[i];
|
||||
p("dim " + dim);
|
||||
ZZCell d = c.s(prefix + dim);
|
||||
if (d != null) {
|
||||
if (!d.getGlobalID().substring(0, prefix.length()).equals(prefix)) continue;
|
||||
String did = d.getGlobalID().substring(prefix.length());
|
||||
io.writeln("R " + ZTPCommand.encode(dim)
|
||||
+ " " + ZTPCommand.encode(cid)
|
||||
+ " " + ZTPCommand.encode(did));
|
||||
}
|
||||
}
|
||||
}
|
||||
io.writeln("F");
|
||||
}
|
||||
}
|
||||
112
Modules/ztp/server/GetMessage.java
Normal file
112
Modules/ztp/server/GetMessage.java
Normal file
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
PutMessage.java
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Antti-Juhani Kaijanaho
|
||||
*/
|
||||
package org.gzigzag.ztp.server;
|
||||
import org.gzigzag.*;
|
||||
import org.gzigzag.ztp.*;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
class GetMessage implements Session.Message {
|
||||
public static boolean dbg = false;
|
||||
private static void p(String s) { if(dbg) ZZLogger.log("[" + s + "]"); }
|
||||
private static void pa(String s) { ZZLogger.log(s); }
|
||||
|
||||
static String prefix = PutMessage.prefix;
|
||||
|
||||
public String name() { return "GET"; }
|
||||
public String help() { return "Gets a subspace from the server"; }
|
||||
public int prereqs() { return Session.FL_AUTH; }
|
||||
|
||||
public void invoke(Session sess, String[] args) throws IOException {
|
||||
LineBufferedIO io = sess.getIO();
|
||||
ZZSpace space = sess.space;
|
||||
if (args.length != 1) {
|
||||
io.writeln("5.0.1 Syntax: GET <subspace>");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!args[0].equals("ALL")) {
|
||||
io.writeln("5.4.1 No such subspace");
|
||||
return;
|
||||
}
|
||||
|
||||
io.writeln("3.4.1 Proceeding with subspace data ...");
|
||||
|
||||
synchronized (space) {
|
||||
// Find all relevant dimensions
|
||||
String[] dims;
|
||||
{
|
||||
Vector dimv = new Vector();
|
||||
for (ZZCell c = space.getHomeCell().s("d.masterdim", 1); c != null;
|
||||
c = c.s("d.masterdim", 1)) {
|
||||
String name = c.getText();
|
||||
if (name.length() >= prefix.length()
|
||||
&& name.substring(0, prefix.length()).equals(prefix)) {
|
||||
dimv.addElement(name.substring(prefix.length()));
|
||||
}
|
||||
}
|
||||
dims = new String[dimv.size()];
|
||||
for (int i = 0; i < dims.length; i++) {
|
||||
dims[i] = (String)dimv.elementAt(i);
|
||||
}
|
||||
}
|
||||
|
||||
class Enum implements Enumeration {
|
||||
Enumeration e;
|
||||
Object cur;
|
||||
private void Cur() {
|
||||
cur = null;
|
||||
while (e.hasMoreElements()) {
|
||||
cur = e.nextElement();
|
||||
ZZCell c = (ZZCell)cur;
|
||||
p("considering " + c);
|
||||
if (c.getID().substring(0, prefix.length()).equals(prefix))
|
||||
p("OK");
|
||||
break;
|
||||
}
|
||||
}
|
||||
public Enum(Enumeration e) {
|
||||
this.e = e;
|
||||
Cur();
|
||||
}
|
||||
public boolean hasMoreElements() {
|
||||
return cur != null;
|
||||
}
|
||||
public Object nextElement() {
|
||||
Object rv = cur;
|
||||
if (rv == null) throw new NoSuchElementException();
|
||||
Cur();
|
||||
p("nextElement = " + rv);
|
||||
return rv;
|
||||
}
|
||||
};
|
||||
|
||||
SubspaceDump.dump(io,
|
||||
new Enum(space.getHomeCell().s("d.ztpspace").enumRank("d.ztpspace")),
|
||||
dims, prefix);
|
||||
|
||||
}
|
||||
|
||||
io.writeln("2.4.1 Subspace successfully got");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
55
Modules/ztp/server/Listener.java
Normal file
55
Modules/ztp/server/Listener.java
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
Listener.java
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Antti-Juhani Kaijanaho
|
||||
*/
|
||||
package org.gzigzag.ztp.server;
|
||||
import org.gzigzag.*;
|
||||
import org.gzigzag.ztp.*;
|
||||
import java.net.*;
|
||||
import java.io.*;
|
||||
|
||||
public class Listener extends Thread {
|
||||
public static boolean dbg = false;
|
||||
private static void p(String s) { if(dbg) ZZLogger.log("[" + s + "]"); }
|
||||
private static void pa(String s) { ZZLogger.log(s); }
|
||||
|
||||
private ZZSpace space;
|
||||
private ServerSocket lsock;
|
||||
public Listener(ZZSpace space, ServerSocket lsock) {
|
||||
this.space = space;
|
||||
this.lsock = lsock;
|
||||
}
|
||||
public void run() {
|
||||
pa("Listener starts");
|
||||
while (!isInterrupted()) {
|
||||
try {
|
||||
p("waiting for connections");
|
||||
Socket csock = lsock.accept();
|
||||
p("connection request received");
|
||||
Session sess = new Session(space, csock);
|
||||
sess.start();
|
||||
} catch (IOException e) {
|
||||
ZZLogger.exc(e);
|
||||
}
|
||||
|
||||
}
|
||||
pa("Listener stops");
|
||||
}
|
||||
}
|
||||
|
||||
117
Modules/ztp/server/PutMessage.java
Normal file
117
Modules/ztp/server/PutMessage.java
Normal file
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
PutMessage.java
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Antti-Juhani Kaijanaho
|
||||
*/
|
||||
package org.gzigzag.ztp.server;
|
||||
import org.gzigzag.*;
|
||||
import org.gzigzag.ztp.*;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
class PutMessage implements Session.Message {
|
||||
public static boolean dbg = false;
|
||||
private static void p(String s) { if(dbg) ZZLogger.log("[" + s + "]"); }
|
||||
private static void pa(String s) { ZZLogger.log(s); }
|
||||
|
||||
static String prefix = "ztpspace!";
|
||||
|
||||
public String name() { return "PUT"; }
|
||||
public String help() { return "Puts a subspace to the server"; }
|
||||
public int prereqs() { return Session.FL_AUTH; }
|
||||
|
||||
public void invoke(Session sess, String[] args) throws IOException {
|
||||
LineBufferedIO io = sess.getIO();
|
||||
ZZSpace space = sess.space;
|
||||
if (args.length != 1) {
|
||||
io.writeln("5.0.1 Syntax: PUT <subspace>");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!args[0].equals("ALL")) {
|
||||
io.writeln("5.4.1 No such subspace");
|
||||
return;
|
||||
}
|
||||
|
||||
io.writeln("3.4.0 Please proceed with subspace data, end with 'F'");
|
||||
|
||||
|
||||
SubspaceDump sd;
|
||||
try {
|
||||
sd = new SubspaceDump(io);
|
||||
} catch (SubspaceDump.AbortedException e) {
|
||||
io.writeln("5.4.0 " + e.getMessage());
|
||||
return;
|
||||
} catch (SyntaxError e) {
|
||||
io.writeln("5.0.1 " + e.getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
// Verify that the cells all have a good ID.
|
||||
for (Enumeration e = sd.cellids.keys(); e.hasMoreElements();) {
|
||||
String s = (String)e.nextElement();
|
||||
if (s.indexOf("@") == -1) {
|
||||
io.writeln("5.4.2 Cannot put cells lacking a space ID");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
synchronized (space) {
|
||||
// Delete old subspace
|
||||
for (ZZCell c = space.getHomeCell().s("d.ztpspace", 1); c != null; ) {
|
||||
ZZCell s = c.s("d.ztpspace", 1);
|
||||
if (c.getID().substring(0, prefix.length()).equals(prefix)) {
|
||||
c.delete();
|
||||
}
|
||||
c = s;
|
||||
}
|
||||
|
||||
// Create the new subspace
|
||||
{
|
||||
ZZCell oc = space.getHomeCell();
|
||||
for (Enumeration e = sd.cellids.keys(); e.hasMoreElements();) {
|
||||
String s = (String)e.nextElement();
|
||||
ZZCell c = space.getCellByID(prefix + s);
|
||||
oc.connect("d.ztpspace", 1, c);
|
||||
oc = c;
|
||||
}
|
||||
}
|
||||
for (Enumeration e = sd.content.keys(); e.hasMoreElements();) {
|
||||
String s = (String)e.nextElement();
|
||||
ZZCell c = space.getCellByID(prefix + s);
|
||||
c.setText((String)sd.content.get(s));
|
||||
}
|
||||
for (Enumeration e = sd.dims.keys(); e.hasMoreElements();) {
|
||||
String dimname = (String)e.nextElement();
|
||||
Hashtable dim = (Hashtable)sd.dims.get(dimname);
|
||||
((ZZDimSpace)space).d(dimname);
|
||||
for (Enumeration f = dim.keys(); f.hasMoreElements();) {
|
||||
String s1 = (String)f.nextElement();
|
||||
String s2 = (String)dim.get(s1);
|
||||
ZZCell c1 = space.getCellByID(prefix + s1);
|
||||
ZZCell c2 = space.getCellByID(prefix + s2);
|
||||
c1.connect(prefix + dimname, c2);
|
||||
}
|
||||
}
|
||||
space.commit();
|
||||
}
|
||||
io.writeln("2.4.0 Subspace successfully put");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
227
Modules/ztp/server/Session.java
Normal file
227
Modules/ztp/server/Session.java
Normal file
@@ -0,0 +1,227 @@
|
||||
/*
|
||||
Session.java
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Antti-Juhani Kaijanaho
|
||||
*/
|
||||
package org.gzigzag.ztp.server;
|
||||
import org.gzigzag.*;
|
||||
import org.gzigzag.ztp.*;
|
||||
import java.net.*;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
public class Session extends Thread {
|
||||
public static boolean dbg = false;
|
||||
private static void p(String s) { if(dbg) ZZLogger.log("[" + s + "]"); }
|
||||
private static void pa(String s) { ZZLogger.log(s); }
|
||||
|
||||
public ZZSpace space;
|
||||
private Socket socket = null;
|
||||
|
||||
interface Message {
|
||||
String name();
|
||||
String help();
|
||||
int prereqs();
|
||||
void invoke(Session sess, String[] args) throws IOException;
|
||||
}
|
||||
|
||||
private LineBufferedIO io;
|
||||
|
||||
private boolean proper_close = false;
|
||||
|
||||
public LineBufferedIO getIO() { return io; }
|
||||
|
||||
private UserManager userManager;
|
||||
|
||||
public UserManager getUserManager() { return userManager; }
|
||||
|
||||
// prereq constants (orred)
|
||||
static final int FL_AUTH = 1;
|
||||
static final int FL_SAP = 2;
|
||||
|
||||
private int reqstatus;
|
||||
|
||||
public String user;
|
||||
|
||||
public void setFlag(int flag) { reqstatus |= flag; }
|
||||
public void clearFlag(int flag) { reqstatus &= ~flag; }
|
||||
|
||||
private void login(UserRecord ur) throws IOException {
|
||||
try {
|
||||
if (ur.sap) {
|
||||
setFlag(FL_SAP);
|
||||
} else {
|
||||
clearFlag(FL_SAP);
|
||||
}
|
||||
user = ur.username;
|
||||
setFlag(FL_AUTH);
|
||||
io.writeln("2.3.0 OK");
|
||||
if (socket != null) {
|
||||
pa("connection from " + socket.getInetAddress().getHostName()
|
||||
+ " authenticated as " + user);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
clearFlag(FL_AUTH);
|
||||
ZZLogger.exc(e);
|
||||
io.writeln("4.3.0 Problem authenticating user");
|
||||
}
|
||||
}
|
||||
|
||||
Message[] messages = {
|
||||
new Message() {
|
||||
public String name() { return "QUIT"; }
|
||||
public String help() { return "Quit the session"; }
|
||||
public int prereqs() { return 0; }
|
||||
public void invoke(Session ses, String[] args) throws IOException {
|
||||
clearFlag(FL_AUTH);
|
||||
ses.interrupt();
|
||||
ses.proper_close = true;
|
||||
ses.io.writeln("2.2.1 Be seeing you");
|
||||
}
|
||||
},
|
||||
new Message() {
|
||||
public String name() { return "AUTH/PRE"; }
|
||||
public String help() { return "Request preauthentication"; }
|
||||
public int prereqs() { return 0; }
|
||||
public void invoke(Session ses, String[] args) throws IOException {
|
||||
LineBufferedIO io = ses.getIO();
|
||||
if (args.length != 1) {
|
||||
io.writeln("5.0.1 Syntax: AUTH/PRE <username>");
|
||||
return;
|
||||
}
|
||||
UserRecord ur = ses.getUserManager().access(args[0]);
|
||||
if (ur == null || !ur.auth_pre) {
|
||||
io.writeln("5.3.0 Access denied");
|
||||
return;
|
||||
}
|
||||
if (ur.susp) {
|
||||
io.writeln("5.3.1 User disabled");
|
||||
return;
|
||||
}
|
||||
ses.login(ur);
|
||||
}
|
||||
},
|
||||
new Message() {
|
||||
public String name() { return "AUTH/PASS"; }
|
||||
public String help() { return "Request password authentication"; }
|
||||
public int prereqs() { return 0; }
|
||||
public void invoke(Session ses, String[] args) throws IOException {
|
||||
LineBufferedIO io = ses.getIO();
|
||||
if (args.length != 2) {
|
||||
io.writeln("5.0.1 Syntax: AUTH/PASS <username> <password>");
|
||||
return;
|
||||
}
|
||||
UserRecord ur = ses.getUserManager().access(args[0]);
|
||||
if (ur == null || !ur.auth_pass || !ur.password.equals(args[1])) {
|
||||
io.writeln("5.3.0 Access denied");
|
||||
return;
|
||||
}
|
||||
if (ur.susp) {
|
||||
io.writeln("5.3.1 User disabled");
|
||||
return;
|
||||
}
|
||||
ses.login(ur);
|
||||
}
|
||||
},
|
||||
new PutMessage(),
|
||||
new GetMessage()
|
||||
};
|
||||
|
||||
private static Hashtable sessions = new Hashtable();
|
||||
|
||||
|
||||
public static Enumeration getActiveSessions() {
|
||||
synchronized (sessions) {
|
||||
return sessions.keys();
|
||||
}
|
||||
}
|
||||
|
||||
public Session(ZZSpace space, Socket sock) throws IOException {
|
||||
this(space, sock.getInputStream(), sock.getOutputStream());
|
||||
socket = sock;
|
||||
}
|
||||
|
||||
public Session(ZZSpace space, InputStream in, OutputStream out) throws IOException {
|
||||
this.space = space;
|
||||
io = new LineBufferedIO(in, out);
|
||||
socket = null;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
try {
|
||||
p("session start");
|
||||
if (socket != null) {
|
||||
pa("accepting connection from " + socket.getInetAddress().getHostName());
|
||||
}
|
||||
userManager = UserManager.create(space);
|
||||
synchronized (sessions) {
|
||||
sessions.put(this, this);
|
||||
}
|
||||
try {
|
||||
io.writeln("2.2.0 Hello there!");
|
||||
} catch (IOException e) {
|
||||
ZZLogger.exc(e);
|
||||
}
|
||||
while (!io.isEOF() && !isInterrupted()) {
|
||||
try {
|
||||
try {
|
||||
String line = io.readline();
|
||||
p("read " + line);
|
||||
ZTPCommand c = new ZTPCommand(line);
|
||||
p("" + c);
|
||||
Message m = null;
|
||||
for (int i = 0; i < messages.length; i++) {
|
||||
if (messages[i].name().toUpperCase().equals(c.name.toUpperCase())) {
|
||||
m = messages[i];
|
||||
}
|
||||
}
|
||||
if (m == null) {
|
||||
io.writeln("5.0.1 What?");
|
||||
} else {
|
||||
if (((m.prereqs() & reqstatus) ^ m.prereqs()) == 0) {
|
||||
m.invoke(this, c.args);
|
||||
} else {
|
||||
io.writeln("5.0.2 Permission denied");
|
||||
}
|
||||
}
|
||||
} catch (SyntaxError e) {
|
||||
io.writeln("5.0.1 " + e.getMessage());
|
||||
}
|
||||
} catch (IOException e) {
|
||||
ZZLogger.exc(e);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
synchronized (sessions) {
|
||||
try {
|
||||
if (!proper_close) io.writeln("4.2.1 Aborting");
|
||||
socket.close();
|
||||
} catch (IOException e) {
|
||||
ZZLogger.exc(e);
|
||||
}
|
||||
sessions.remove(this);
|
||||
}
|
||||
userManager.close();
|
||||
}
|
||||
if (socket != null) {
|
||||
pa("closing connection from " + socket.getInetAddress().getHostName());
|
||||
}
|
||||
p("session end");
|
||||
}
|
||||
}
|
||||
|
||||
139
Modules/ztp/server/UserManager.java
Normal file
139
Modules/ztp/server/UserManager.java
Normal file
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
UserManager.java
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Antti-Juhani Kaijanaho
|
||||
*/
|
||||
package org.gzigzag.ztp.server;
|
||||
import org.gzigzag.*;
|
||||
import org.gzigzag.ztp.*;
|
||||
import java.util.*;
|
||||
|
||||
/** User manager for ZTP server. It enforces single-threaded access
|
||||
* to the user table in the space. */
|
||||
class UserManager {
|
||||
public static boolean dbg = true;
|
||||
private static void p(String s) { if(dbg) ZZLogger.log("[" + s + "]"); }
|
||||
private static void pa(String s) { ZZLogger.log(s); }
|
||||
|
||||
private static Hashtable managers = new Hashtable();
|
||||
|
||||
private int refcount;
|
||||
|
||||
private ZZSpace space;
|
||||
|
||||
private boolean live = false;
|
||||
|
||||
private void assertLiving() {
|
||||
if (!live) throw new ZZError("UserManager closed");
|
||||
}
|
||||
|
||||
/*
|
||||
private ZZCell userlist;
|
||||
*/
|
||||
|
||||
private UserManager(ZZSpace space) {
|
||||
synchronized (managers) {
|
||||
this.space = space;
|
||||
if (managers.containsKey(space)) {
|
||||
throw new ZZError("there already is a UserManager for that space");
|
||||
}
|
||||
managers.put(space, this);
|
||||
live = true;
|
||||
}
|
||||
|
||||
refcount = 0;
|
||||
|
||||
// NOT NOW
|
||||
//// we find the user list here for convenience
|
||||
//ZZCell home = space.getHomeCell();
|
||||
//userlist = home.findText("d.system", 1, "ZTPUserList");
|
||||
//if (userlist == null) {
|
||||
///* userlist = home.N("d.system", 1);
|
||||
//userlist.setText("ZTPUserList");*/
|
||||
//throw new ZZError("no user list in space!");
|
||||
//}
|
||||
}
|
||||
|
||||
|
||||
public static UserManager create(ZZSpace space) {
|
||||
UserManager rv;
|
||||
synchronized (managers) {
|
||||
Object o = managers.get(space);
|
||||
if (o == null) {
|
||||
rv = new UserManager(space);
|
||||
} else {
|
||||
rv = (UserManager)o;
|
||||
}
|
||||
}
|
||||
++rv.refcount;
|
||||
return rv;
|
||||
}
|
||||
|
||||
public void close() {
|
||||
if (--refcount < 1) {
|
||||
synchronized (managers) {
|
||||
live = false;
|
||||
managers.remove(space);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized UserRecord access(String username) {
|
||||
assertLiving();
|
||||
|
||||
UserRecord rv = new UserRecord();
|
||||
|
||||
rv.username = "adm";
|
||||
rv.password = "mda";
|
||||
rv.susp = false;
|
||||
rv.chpass = false;
|
||||
rv.sap = true;
|
||||
rv.auth_pre = true;
|
||||
rv.auth_pass = true;
|
||||
|
||||
return username.equals(rv.username) ? rv : null;
|
||||
}
|
||||
|
||||
public interface RecordHandler {
|
||||
void doit(UserRecord ur);
|
||||
}
|
||||
|
||||
public synchronized void access_atomic(String username, RecordHandler rh) {
|
||||
UserRecord ur = access(username);
|
||||
rh.doit(ur);
|
||||
}
|
||||
|
||||
public synchronized void replace(UserRecord ur) {
|
||||
throw new ZZError("user record replace not implemented at this time");
|
||||
}
|
||||
|
||||
public synchronized void replace_atomic(String username, RecordHandler rh) {
|
||||
UserRecord ur = access(username);
|
||||
rh.doit(ur);
|
||||
replace(ur);
|
||||
}
|
||||
|
||||
public synchronized void delete(String uname) {
|
||||
throw new ZZError("user record deletion not implemented at this time");
|
||||
}
|
||||
|
||||
public synchronized void insert(UserRecord ur) {
|
||||
throw new ZZError("user record insertion not implemented at this time");
|
||||
}
|
||||
|
||||
}
|
||||
56
Modules/ztp/server/UserRecord.zob
Normal file
56
Modules/ztp/server/UserRecord.zob
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
UserRecord.zob
|
||||
*
|
||||
* You may use and distribute under the terms of either the GNU Lesser
|
||||
* General Public License, either version 2 of the license or,
|
||||
* at your choice, any later version. Alternatively, you may use and
|
||||
* distribute under the terms of the XPL.
|
||||
*
|
||||
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
|
||||
* the licenses.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the README
|
||||
* file for more details.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Written by Antti-Juhani Kaijanaho
|
||||
*/
|
||||
package org.gzigzag.ztp.server;
|
||||
import org.gzigzag.*;
|
||||
import org.gzigzag.ztp.*;
|
||||
import java.util.*;
|
||||
|
||||
/** User manager for ZTP server. It enforces single-threaded access
|
||||
* to the user table in the space. */
|
||||
|
||||
public class UserRecord implements ZOb {
|
||||
|
||||
STRUCTPARAMS {
|
||||
/** The username. */
|
||||
String username;
|
||||
|
||||
/** The password for AUTH/PASS. */
|
||||
String password;
|
||||
|
||||
/** Is the user suspended? */
|
||||
boolean susp;
|
||||
|
||||
/** Is the user allowed to change her password? */
|
||||
boolean chpass;
|
||||
|
||||
/** Does the user have Space Administrator Privileges? */
|
||||
boolean sap;
|
||||
|
||||
/** May the user use preauthentication? */
|
||||
boolean auth_pre;
|
||||
|
||||
/** May the user use password authentication? */
|
||||
boolean auth_pass;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user