summaryrefslogtreecommitdiff
path: root/appl/cmd/auxi/rdbgsrv.b
diff options
context:
space:
mode:
Diffstat (limited to 'appl/cmd/auxi/rdbgsrv.b')
-rw-r--r--appl/cmd/auxi/rdbgsrv.b222
1 files changed, 222 insertions, 0 deletions
diff --git a/appl/cmd/auxi/rdbgsrv.b b/appl/cmd/auxi/rdbgsrv.b
new file mode 100644
index 00000000..2a958eee
--- /dev/null
+++ b/appl/cmd/auxi/rdbgsrv.b
@@ -0,0 +1,222 @@
+implement RDbgSrv;
+
+include "sys.m";
+ sys: Sys;
+include "draw.m";
+
+include "styx.m";
+ styx: Styx;
+ Rmsg, Tmsg: import styx;
+
+include "arg.m";
+ arg: Arg;
+
+RDbgSrv: module
+{
+ init: fn(nil: ref Draw->Context, argv: list of string);
+};
+
+debug:= 0;
+dev:= "/dev/eia0";
+speed:= 38400;
+progname: string;
+rpid := 0;
+wpid := 0;
+
+usage()
+{
+ sys->fprint(stderr(), "Usage: rdbgsrv [-d n] [-s speed] [-f dev] mountpoint\n");
+ raise "fail: usage";
+}
+
+init(nil: ref Draw->Context, av: list of string)
+{
+ sys = load Sys Sys->PATH;
+ if(sys == nil)
+ return;
+ styx = load Styx Styx->PATH;
+ if(styx == nil){
+ sys->fprint(stderr(), "rdbgsrv: can't load %s; %r\n", Styx->PATH);
+ raise "fail:load";
+ }
+ arg = load Arg Arg->PATH;
+ if(arg == nil){
+ sys->fprint(stderr(), "rdbgsrv: can't load %s: %r\n", Arg->PATH);
+ raise "fail:load";
+ }
+
+ arg->init(av);
+ progname = arg->progname();
+ while(o := arg->opt())
+ case o {
+ 'd' =>
+ d := arg->arg();
+ if(d == nil)
+ usage();
+ debug = int d;
+ 's' =>
+ s := arg->arg();
+ if(s == nil)
+ usage();
+ speed = int s;
+ 'f' =>
+ s := arg->arg();
+ if(s == nil)
+ usage();
+ dev = s;
+ 'h' =>
+ usage();
+ }
+
+ mtpt := arg->arg();
+ if(mtpt == nil)
+ usage();
+
+ ctl := dev + "ctl";
+ cfd := sys->open(ctl, Sys->OWRITE);
+ if(cfd == nil){
+ sys->fprint(stderr(), "%s: can't open %s: %r\n", progname, ctl);
+ raise "fail: open eia\n";
+ }
+
+ sys->fprint(cfd, "b%d", speed);
+ sys->fprint(cfd, "l8");
+ sys->fprint(cfd, "pn");
+ sys->fprint(cfd, "s1");
+
+ (rfd, wfd) := start(dev);
+ if(rfd == nil){
+ sys->fprint(stderr(), "%s: failed to start protocol\n", progname);
+ raise "fail:proto start";
+ }
+
+ fds := array[2] of ref Sys->FD;
+
+ if(sys->pipe(fds) == -1){
+ sys->fprint(stderr(), "%s: pipe: %r\n", progname);
+ raise "fail:no pipe";
+ }
+
+ if(debug)
+ sys->fprint(stderr(), "%s: starting server\n", progname);
+
+ rc := chan of int;
+ spawn copymsg(fds[1], wfd, "->", rc);
+ rpid = <-rc;
+ spawn copymsg(rfd, fds[1], "<-", rc);
+ wpid = <-rc;
+
+ if(sys->mount(fds[0], nil, mtpt, Sys->MREPL, nil) == -1) {
+ fds[1] = nil;
+ sys->fprint(stderr(), "%s: can't mount on %s: %r\n", progname, mtpt);
+ quit("mount");
+ }
+}
+
+stderr(): ref Sys->FD
+{
+ return sys->fildes(2);
+}
+
+killpid(pid: int)
+{
+ fd := sys->open("#p/"+string pid+"/ctl", sys->OWRITE);
+ if(fd != nil)
+ sys->fprint(fd, "kill");
+}
+
+quit(err: string)
+{
+ killpid(rpid);
+ killpid(wpid);
+ if(err != nil)
+ raise "fail:"+err;
+ exit;
+}
+
+start(name:string): (ref Sys->FD, ref Sys->FD)
+{
+ rfd := sys->open(name, Sys->OREAD);
+ wfd := sys->open(name, Sys->OWRITE);
+ if(rfd == nil || wfd == nil)
+ return (nil, nil);
+ if(sys->fprint(wfd, "go") < 0)
+ return (nil, nil);
+ c := array[1] of byte;
+ state := 0;
+ for(;;) {
+ if(sys->read(rfd, c, 1) != 1)
+ return (nil, nil);
+ if(state == 0 && c[0] == byte 'o')
+ state = 1;
+ else if(state == 1 && c[0] == byte 'k')
+ break;
+ else
+ state = 0;
+ }
+ return (rfd, wfd);
+}
+
+copymsg(f: ref Sys->FD, t: ref Sys->FD, dir: string, pidc: chan of int)
+{
+ pidc <-= sys->pctl(0, nil);
+
+ {
+ for(;;) {
+ (msg, err) := styx->readmsg(f, 0);
+ if(msg == nil){
+ sys->fprint(stderr(), "%s: %s: read error: %s\n", progname, dir, err);
+ quit("error");
+ }
+ if(debug &1)
+ trace(dir, msg);
+ if(debug & 2)
+ dump(dir, msg, len msg);
+ if(sys->write(t, msg, len msg) != len msg){
+ sys->fprint(stderr(), "%s: %s: write error: %r\n", progname, dir);
+ quit("error");
+ }
+ }
+ }exception e{
+ "*" =>
+ sys->print("%s: %s: %s: exiting\n", progname, dir, e);
+ quit("exception");
+ }
+}
+
+trace(sourcept: string, op: array of byte )
+{
+ if(styx->istmsg(op)){
+ (nil, m) := Tmsg.unpack(op);
+ if(m != nil)
+ sys->print("%s: %s\n", sourcept, m.text());
+ else
+ sys->print("%s: unknown\n", sourcept);
+ }else{
+ (nil, m) := Rmsg.unpack(op);
+ if(m != nil)
+ sys->print("%s: %s\n", sourcept, m.text());
+ else
+ sys->print("%s: unknown\n", sourcept);
+ }
+}
+
+dump(msg: string, buf: array of byte, n: int)
+{
+ sys->print("%s: [%d bytes]: ", msg, n);
+ s := "";
+ for(i:=0;i<n;i++) {
+ if((i % 20) == 0) {
+ sys->print(" %s\n", s);
+ s = "";
+ }
+ sys->print("%2.2x ", int buf[i]);
+ if(int buf[i] >= 32 && int buf[i] < 127)
+ s[len s] = int buf[i];
+ else
+ s += ".";
+ }
+ for(i %= 20; i < 20; i++)
+ sys->print(" ");
+ sys->print(" %s\n\n", s);
+}