diff options
Diffstat (limited to 'appl/alphabet/main')
| -rw-r--r-- | appl/alphabet/main/auth.b | 157 | ||||
| -rw-r--r-- | appl/alphabet/main/cat.b | 78 | ||||
| -rw-r--r-- | appl/alphabet/main/create.b | 55 | ||||
| -rw-r--r-- | appl/alphabet/main/dial.b | 85 | ||||
| -rw-r--r-- | appl/alphabet/main/echo.b | 51 | ||||
| -rw-r--r-- | appl/alphabet/main/export.b | 52 | ||||
| -rw-r--r-- | appl/alphabet/main/fd.b | 83 | ||||
| -rw-r--r-- | appl/alphabet/main/filter.b | 114 | ||||
| -rw-r--r-- | appl/alphabet/main/genfilter.b | 79 | ||||
| -rw-r--r-- | appl/alphabet/main/mkfile | 36 | ||||
| -rw-r--r-- | appl/alphabet/main/mount.b | 80 | ||||
| -rw-r--r-- | appl/alphabet/main/par.b | 50 | ||||
| -rw-r--r-- | appl/alphabet/main/parse.b | 43 | ||||
| -rw-r--r-- | appl/alphabet/main/pretty.b | 116 | ||||
| -rw-r--r-- | appl/alphabet/main/print.b | 55 | ||||
| -rw-r--r-- | appl/alphabet/main/read.b | 56 | ||||
| -rw-r--r-- | appl/alphabet/main/readall.b | 46 | ||||
| -rw-r--r-- | appl/alphabet/main/rewrite.b | 97 | ||||
| -rw-r--r-- | appl/alphabet/main/rw.b | 50 | ||||
| -rw-r--r-- | appl/alphabet/main/seq.b | 66 | ||||
| -rw-r--r-- | appl/alphabet/main/unparse.b | 38 | ||||
| -rw-r--r-- | appl/alphabet/main/w2fd.b | 61 | ||||
| -rw-r--r-- | appl/alphabet/main/wait.b | 35 |
23 files changed, 1583 insertions, 0 deletions
diff --git a/appl/alphabet/main/auth.b b/appl/alphabet/main/auth.b new file mode 100644 index 00000000..d05ecb46 --- /dev/null +++ b/appl/alphabet/main/auth.b @@ -0,0 +1,157 @@ +implement Authenticate, Mainmodule; +include "sys.m"; + sys: Sys; +include "draw.m"; +include "sh.m"; +include "keyring.m"; + keyring: Keyring; +include "security.m"; + auth: Auth; +include "alphabet/reports.m"; + reports: Reports; + Report, report: import reports; +include "alphabet.m"; + alphabet: Alphabet; + Value: import alphabet; + +Authenticate: module {}; + +typesig(): string +{ + return "ww-ks-Cs-v"; +} + +init() +{ + sys = load Sys Sys->PATH; + alphabet = load Alphabet Alphabet->PATH; + reports = load Reports Reports->PATH; + keyring = load Keyring Keyring->PATH; + auth = load Auth Auth->PATH; + auth->init(); +} + +quit() +{ +} + +After, Before, Create: con 1<<iota; + +run(nil: ref Draw->Context, r: ref Reports->Report, errorc: chan of string, + opts: list of (int, list of ref Alphabet->Value), + args: list of ref Alphabet->Value): ref Alphabet->Value +{ + keyfile: string; + alg: string; + verbose: int; + for(; opts != nil; opts = tl opts){ + case (hd opts).t0 { + 'k' => + keyfile = (hd (hd opts).t1).s().i; + if (keyfile != nil && ! (keyfile[0] == '/' || (len keyfile > 2 && keyfile[0:2] == "./"))) + keyfile = "/usr/" + user() + "/keyring/" + keyfile; + 'C' => + alg = (hd (hd opts).t1).s().i; + 'v' => + verbose = 1; + } + } + if(keyfile == nil) + keyfile = "/usr/" + user() + "/keyring/default"; + cert := keyring->readauthinfo(keyfile); + if (cert == nil) { + report(errorc, sys->sprint("auth: cannot read %q: %r", keyfile)); + return nil; + } + w := chan of ref Sys->FD; + spawn authproc((hd args).w().i, w, cert, verbose, alg, r.start("auth")); + return ref Value.Vw(w); +} + +authproc(f0, f1: chan of ref Sys->FD, cert: ref Keyring->Authinfo, + verbose: int, alg: string, errorc: chan of string) +{ + fd0 := <-f0; + if(fd0 == nil){ + sys->pipe(p := array[2] of ref Sys->FD); + f0 <-= p[1]; + fd0 = p[0]; + }else + f0 <-= nil; + + eu: string; + (fd0, eu) = auth->client(alg, cert, fd0); + if(fd0 == nil){ + report(errorc, "authentication failed: "+eu); + f1 <-= nil; + <-f1; + reports->quit(errorc); + } + if(verbose) + report(errorc, sys->sprint("remote user %q", eu)); + f1 <-= fd0; + fd1 := <-f1; + if(fd1 == nil) + reports->quit(errorc); + wstream(fd0, fd1, errorc); + reports->quit(errorc); +} + +wstream(fd0, fd1: ref Sys->FD, errorc: chan of string) +{ + sync := chan[2] of int; + qc := chan of int; + spawn stream(fd0, fd1, sync, qc, errorc); + spawn stream(fd1, fd0, sync, qc, errorc); + <-qc; + kill(<-sync); + kill(<-sync); +} + +stream(fd0, fd1: ref Sys->FD, sync, qc: chan of int, errorc: chan of string) +{ + sync <-= sys->pctl(0, nil); + buf := array[Sys->ATOMICIO] of byte; + while((n := sys->read(fd0, buf, len buf)) > 0){ + if(sys->write(fd1, buf, n) == -1){ + report(errorc, sys->sprint("write error: %r")); + break; + } + } + qc <-= 1; + exit; +} + +kill(pid: int) +{ + sys->fprint(sys->open("#p/"+string pid+"/ctl", Sys->OWRITE), "kill"); +} + + +exists(f: string): int +{ + (ok, nil) := sys->stat(f); + return ok != -1; +} + +user(): string +{ + u := readfile("/dev/user"); + if (u == nil) + return "nobody"; + return u; +} + +readfile(f: string): string +{ + fd := sys->open(f, sys->OREAD); + if(fd == nil) + return nil; + + buf := array[128] of byte; + n := sys->read(fd, buf, len buf); + if(n < 0) + return nil; + + return string buf[0:n]; +} diff --git a/appl/alphabet/main/cat.b b/appl/alphabet/main/cat.b new file mode 100644 index 00000000..b19b1fd9 --- /dev/null +++ b/appl/alphabet/main/cat.b @@ -0,0 +1,78 @@ +implement Mainmodule; +include "sys.m"; + sys: Sys; +include "draw.m"; +include "sh.m"; +include "alphabet/reports.m"; + reports: Reports; + Report, report: import reports; +include "alphabet.m"; + alphabet: Alphabet; + Value: import alphabet; + +typesig(): string +{ + return "ff*"; +} + +init() +{ + sys = load Sys Sys->PATH; + alphabet = load Alphabet Alphabet->PATH; + reports = load Reports Reports->PATH; +} + +quit() +{ +} + +run(nil: ref Draw->Context, r: ref Reports->Report, nil: chan of string, + nil: list of (int, list of ref Alphabet->Value), + args: list of ref Alphabet->Value): ref Alphabet->Value +{ + fds: list of chan of ref Sys->FD; + for(; args != nil; args = tl args) + fds = (hd args).f().i :: fds; + f := chan of ref Sys->FD; + spawn catproc(f, rev(fds), r.start("print")); + return ref Value.Vf(f); +} + +catproc(f: chan of ref Sys->FD, fds: list of chan of ref Sys->FD, reportc: chan of string) +{ + f <-= nil; + if((fd1 := <-f) == nil){ + for(; fds != nil; fds = tl fds){ + <-hd fds; + hd fds <-= nil; + } + reports->quit(reportc); + } + buf := array[8192] of byte; + for(; fds != nil; fds = tl fds){ + fd0 := <-hd fds; + if(fd0 == nil){ + p := array[2] of ref Sys->FD; + sys->pipe(p); + fd0 = p[0]; + hd fds <-= p[1]; + }else + hd fds <-= nil; + while((n := sys->read(fd0, buf, len buf)) > 0){ + sys->write(fd1, buf, n); + }exception{ + "write on closed pipe" => + ; + } + } + sys->write(fd1, array[0] of byte, 0); + reports->quit(reportc); +} + +rev[T](l: list of T): list of T +{ + r: list of T; + for(; l != nil; l = tl l) + r = hd l :: r; + return r; +}
\ No newline at end of file diff --git a/appl/alphabet/main/create.b b/appl/alphabet/main/create.b new file mode 100644 index 00000000..bb1601dc --- /dev/null +++ b/appl/alphabet/main/create.b @@ -0,0 +1,55 @@ +implement Create,Mainmodule; +include "sys.m"; + sys: Sys; +include "draw.m"; +include "sh.m"; +include "alphabet/reports.m"; + reports: Reports; + Report, report: import reports; +include "alphabet.m"; + alphabet: Alphabet; + Value: import alphabet; + +Create: module {}; + +typesig(): string +{ + return "rfs"; +} + +init() +{ + sys = load Sys Sys->PATH; + alphabet = load Alphabet Alphabet->PATH; + reports = load Reports Reports->PATH; +} + +quit() +{ +} + +run(nil: ref Draw->Context, nil: ref Reports->Report, errorc: chan of string, + nil: list of (int, list of ref Alphabet->Value), + args: list of ref Alphabet->Value): ref Alphabet->Value +{ + r := chan of string; + fd := sys->create((hd tl args).s().i, Sys->OWRITE, 8r666); + if(fd == nil){ + report(errorc, sys->sprint("error: cannot create %q: %r", (hd tl args).s().i)); + return nil; + } + spawn createproc(r, (hd args).f().i, fd); + return ref Value.Vr(r); +} + +createproc(r: chan of string, f: chan of ref Sys->FD, fd: ref Sys->FD) +{ + if(<-r != nil){ + <-f; + f <-= nil; + exit; + } + <-f; + f <-= fd; + r <-= nil; +} diff --git a/appl/alphabet/main/dial.b b/appl/alphabet/main/dial.b new file mode 100644 index 00000000..e8521b45 --- /dev/null +++ b/appl/alphabet/main/dial.b @@ -0,0 +1,85 @@ +implement Dial,Mainmodule; +include "sys.m"; + sys: Sys; +include "draw.m"; +include "sh.m"; +include "alphabet/reports.m"; + reports: Reports; + Report, report: import reports; +include "alphabet.m"; + alphabet: Alphabet; + Value: import alphabet; + +Dial: module {}; + +typesig(): string +{ + return "ws"; +} + +init() +{ + sys = load Sys Sys->PATH; + alphabet = load Alphabet Alphabet->PATH; + reports = load Reports Reports->PATH; +} + +quit() +{ +} + +run(nil: ref Draw->Context, r: ref Reports->Report, errorc: chan of string, + nil: list of (int, list of ref Alphabet->Value), + args: list of ref Alphabet->Value): ref Alphabet->Value +{ + w := chan of ref Sys->FD; + addr := (hd args).s().i; + (ok, c) := sys->dial(addr, nil); + if(ok == -1){ + report(errorc, sys->sprint("dial: cannot dial %q: %r", addr)); + return nil; + } + f := chan of ref Sys->FD; + spawn dialproc(f, c.dfd, r.start("dial")); + return ref Value.Vw(f); +} + +dialproc(f: chan of ref Sys->FD, fd0: ref Sys->FD, errorc: chan of string) +{ + f <-= fd0; + fd1 := <-f; + if(fd1 == nil) + reports->quit(errorc); + wstream(fd0, fd1, errorc); + reports->quit(errorc); +} + +wstream(fd0, fd1: ref Sys->FD, errorc: chan of string) +{ + sync := chan[2] of int; + qc := chan of int; + spawn stream(fd0, fd1, sync, qc, errorc); + spawn stream(fd1, fd0, sync, qc, errorc); + <-qc; + kill(<-sync); + kill(<-sync); +} + +stream(fd0, fd1: ref Sys->FD, sync, qc: chan of int, errorc: chan of string) +{ + sync <-= sys->pctl(0, nil); + buf := array[Sys->ATOMICIO] of byte; + while((n := sys->read(fd0, buf, len buf)) > 0){ + if(sys->write(fd1, buf, n) == -1){ + report(errorc, sys->sprint("write error: %r")); + break; + } + } + qc <-= 1; + exit; +} + +kill(pid: int) +{ + sys->fprint(sys->open("#p/"+string pid+"/ctl", Sys->OWRITE), "kill"); +} diff --git a/appl/alphabet/main/echo.b b/appl/alphabet/main/echo.b new file mode 100644 index 00000000..3b01c951 --- /dev/null +++ b/appl/alphabet/main/echo.b @@ -0,0 +1,51 @@ +implement Echo, Mainmodule; +include "sys.m"; + sys: Sys; +include "draw.m"; +include "sh.m"; +include "alphabet/reports.m"; + reports: Reports; + Report, report: import reports; +include "alphabet.m"; + alphabet: Alphabet; + Value: import alphabet; + +Echo: module {}; + +typesig(): string +{ + return "fs-n"; +} + +init() +{ + sys = load Sys Sys->PATH; + alphabet = load Alphabet Alphabet->PATH; + reports = load Reports Reports->PATH; +} + +quit() +{ +} + +run(nil: ref Draw->Context, nil: ref Reports->Report, nil: chan of string, + opts: list of (int, list of ref Alphabet->Value), + args: list of ref Alphabet->Value): ref Alphabet->Value +{ + f := chan of ref Sys->FD; + s := (hd args).s().i; + if(opts == nil) + s[len s] = '\n'; + spawn echoproc(f, s); + return ref Value.Vf(f); +} + +echoproc(f: chan of ref Sys->FD, s: string) +{ + f <-= nil; + fd := <-f; + if(fd == nil) + exit; + sys->fprint(fd, "%s", s); + sys->write(fd, array[0] of byte, 0); +} diff --git a/appl/alphabet/main/export.b b/appl/alphabet/main/export.b new file mode 100644 index 00000000..5e9b986e --- /dev/null +++ b/appl/alphabet/main/export.b @@ -0,0 +1,52 @@ +implement Export,Mainmodule; +include "sys.m"; + sys: Sys; +include "draw.m"; +include "sh.m"; +include "alphabet/reports.m"; + reports: Reports; + Report, report: import reports; +include "alphabet.m"; + alphabet: Alphabet; + Value: import alphabet; + +Export: module {}; + +typesig(): string +{ + return "ws"; +} + +init() +{ + sys = load Sys Sys->PATH; + alphabet = load Alphabet Alphabet->PATH; + reports = load Reports Reports->PATH; +} + +quit() +{ +} + +run(nil: ref Draw->Context, r: ref Reports->Report, nil: chan of string, + nil: list of (int, list of ref Alphabet->Value), + args: list of ref Alphabet->Value): ref Alphabet->Value +{ + w := chan of ref Sys->FD; + addr := (hd args).s().i; + f := chan of ref Sys->FD; + spawn exportproc(f, (hd args).s().i, r.start("export")); + return ref Value.Vw(f); +} + +exportproc(f: chan of ref Sys->FD, dir: string, errorc: chan of string) +{ + f <-= nil; + fd := <-f; + if(fd == nil) + reports->quit(errorc); + errorc <-= nil; + if(sys->export(fd, dir, Sys->EXPASYNC) == -1) + report(errorc, sys->sprint("cannot export: %r")); + reports->quit(errorc); +} diff --git a/appl/alphabet/main/fd.b b/appl/alphabet/main/fd.b new file mode 100644 index 00000000..11d10828 --- /dev/null +++ b/appl/alphabet/main/fd.b @@ -0,0 +1,83 @@ +implement Fd, Mainmodule; +include "sys.m"; + sys: Sys; +include "draw.m"; +include "sh.m"; +include "alphabet/reports.m"; + reports: Reports; + Report, report: import reports; +include "alphabet.m"; + alphabet: Alphabet; + Value: import alphabet; + +Fd: module {}; + +typesig(): string +{ + return "ws"; +} + +init() +{ + sys = load Sys Sys->PATH; + alphabet = load Alphabet Alphabet->PATH; + reports = load Reports Reports->PATH; +} + +quit() +{ +} + +run(nil: ref Draw->Context, r: ref Reports->Report, errorc: chan of string, + nil: list of (int, list of ref Alphabet->Value), + args: list of ref Alphabet->Value): ref Alphabet->Value +{ + fd := sys->fildes(int (hd args).s().i); + if(fd == nil){ + report(errorc, sys->sprint("error: no such file descriptor %q", (hd args).s().i)); + return nil; + } + f := chan of ref Sys->FD; + spawn readfdproc(f, fd, r.start("stdin")); + return ref Value.Vw(f); +} + +readfdproc(f: chan of ref Sys->FD, fd0: ref Sys->FD, errorc: chan of string) +{ + f <-= fd0; + fd1 := <-f; + if(fd1 == nil) + reports->quit(errorc); + wstream(fd0, fd1, errorc); + reports->quit(errorc); +} + +wstream(fd0, fd1: ref Sys->FD, errorc: chan of string) +{ + sync := chan[2] of int; + qc := chan of int; + spawn stream(fd0, fd1, sync, qc, errorc); + spawn stream(fd1, fd0, sync, qc, errorc); + <-qc; + kill(<-sync); + kill(<-sync); +} + +stream(fd0, fd1: ref Sys->FD, sync, qc: chan of int, errorc: chan of string) +{ + sync <-= sys->pctl(0, nil); + buf := array[Sys->ATOMICIO] of byte; + while((n := sys->read(fd0, buf, len buf)) > 0){ + if(sys->write(fd1, buf, n) == -1){ + report(errorc, sys->sprint("write error: %r")); + break; + } + } + qc <-= 1; + exit; +} + +kill(pid: int) +{ + sys->fprint(sys->open("#p/"+string pid+"/ctl", Sys->OWRITE), "kill"); +} diff --git a/appl/alphabet/main/filter.b b/appl/alphabet/main/filter.b new file mode 100644 index 00000000..f532f529 --- /dev/null +++ b/appl/alphabet/main/filter.b @@ -0,0 +1,114 @@ +implement Filter, Mainmodule; +include "sys.m"; + sys: Sys; +include "draw.m"; +include "sh.m"; + sh: Sh; + Context: import sh; +include "bufio.m"; + bufio: Bufio; + Iobuf: import bufio; +include "alphabet/reports.m"; + reports: Reports; + Report, report: import reports; +include "alphabet.m"; + alphabet: Alphabet; + Value: import alphabet; + +Filter: module {}; + +typesig(): string +{ + return "ffcs*"; # XXX option to suppress stderr? +} + +init() +{ + sys = load Sys Sys->PATH; + alphabet = load Alphabet Alphabet->PATH; + reports = load Reports Reports->PATH; + bufio = load Bufio Bufio->PATH; + sh = load Sh Sh->PATH; + sh->initialise(); +} + +quit() +{ +} + +run(drawctxt: ref Draw->Context, report: ref Reports->Report, nil: chan of string, + nil: list of (int, list of ref Value), + args: list of ref Value): ref Value +{ + f := chan of ref Sys->FD; + a: list of ref Sh->Listnode; + for(al := tl tl args; al != nil; al = tl al) + a = ref Sh->Listnode(nil, (hd al).s().i) :: a; + spawn filterproc(drawctxt, (hd args).f().i, f, (hd tl args).c().i, rev(a), report.start("filter")); + return ref Value.Vf(f); +} + +filterproc(drawctxt: ref Draw->Context, + f0, + f1: chan of ref Sys->FD, + c: ref Sh->Cmd, + args: list of ref Sh->Listnode, + errorc: chan of string) +{ + (fd0, fd1) := startfilter(f0, f1, errorc); + sys->pipe(p := array[2] of ref Sys->FD); + spawn stderrproc(p[0], errorc); + p[0] = nil; + + # i hate this stuff. + sys->pctl(Sys->FORKFD, nil); + sys->dup(fd0.fd, 0); + sys->dup(fd1.fd, 1); + sys->dup(p[1].fd, 2); + fd0 = fd1 = nil; + p = nil; + sys->pctl(Sys->NEWFD, 0::1::2::nil); + Context.new(drawctxt).run(ref Sh->Listnode(c, nil)::args, 0); + sys->fprint(sys->fildes(2), ""); +} + +# read side (when it's an argument): +# read proposed new fd +# write actual fd for them to write to (creating pipe in necessary) +# +# write side (when you're returning it): +# write a proposed new fd (or nil if no suggestion) +# read actual fd for writing +startfilter(f0, f1: chan of ref Sys->FD, errorc: chan of string): (ref Sys->FD, ref Sys->FD) +{ + f1 <-= nil; + if((fd1 := <-f1) == nil){ + <-f0; + f0 <-= nil; + reports->quit(errorc); + } + if((fd0 := <-f0) == nil){ + sys->pipe(p := array[2] of ref Sys->FD); + f0 <-= p[1]; + fd0 = p[0]; + }else + f0 <-= nil; + return (fd0, fd1); +} + +stderrproc(fd: ref Sys->FD, errorc: chan of string) +{ + iob := bufio->fopen(fd, Sys->OREAD); + while((s := iob.gets('\n')) != nil) + if(len s > 1) + errorc <-= s[0:len s - 1]; + errorc <-= nil; +} + +rev[T](l: list of T): list of T +{ + r: list of T; + for(; l != nil; l = tl l) + r = hd l :: r; + return r; +}
\ No newline at end of file diff --git a/appl/alphabet/main/genfilter.b b/appl/alphabet/main/genfilter.b new file mode 100644 index 00000000..9a920d7e --- /dev/null +++ b/appl/alphabet/main/genfilter.b @@ -0,0 +1,79 @@ +implement Myfilter, Mainmodule; +include "sys.m"; + sys: Sys; +include "draw.m"; +include "sh.m"; +include "bufio.m"; + bufio: Bufio; + Iobuf: import bufio; +include "alphabet/reports.m"; + reports: Reports; + Report, report: import reports; +include "alphabet.m"; + alphabet: Alphabet; + Value: import alphabet; + +Myfilter: module {}; + +typesig(): string +{ + return "ff"; +} + +init() +{ + sys = load Sys Sys->PATH; + alphabet = load Alphabet Alphabet->PATH; + reports = load Reports Reports->PATH; + bufio = load Bufio Bufio->PATH; +} + +quit() +{ +} + +run(drawctxt: ref Draw->Context, report: ref Reports->Report, nil: chan of string, + nil: list of (int, list of ref Alphabet->Value), + args: list of ref Alphabet->Value): ref Alphabet->Value +{ + f := chan of ref Sys->FD; + spawn filterproc(drawctxt, (hd args).f().i, f, report.start("myfilter")); + return ref Value.Vf(f); +} + +filterproc(nil: ref Draw->Context, f0, f1: chan of ref Sys->FD, errorc: chan of string) +{ + (fd0, fd1) := startfilter(f0, f1, errorc); + iob0 := bufio->fopen(fd0, Sys->OREAD); + iob1 := bufio->fopen(fd1, Sys->OWRITE); + + # XXX your filter here! + while((s := iob0.gets('\n')) != nil){ + d := array of byte s; + iob1.puts("data "+string len d+"\n"); + iob1.write(d, len d); + }exception{ + "write on closed pipe" => + ; + } + iob1.flush(); + sys->fprint(fd1, ""); + reports->quit(errorc); +} + +startfilter(f0, f1: chan of ref Sys->FD, errorc: chan of string): (ref Sys->FD, ref Sys->FD) +{ + f1 <-= nil; + if((fd1 := <-f1) == nil){ + <-f0; + f0 <-= nil; + reports->quit(errorc); + } + if((fd0 := <-f0) == nil){ + sys->pipe(p := array[2] of ref Sys->FD); + f0 <-= p[1]; + fd0 = p[0]; + }else + f0 <-= nil; + return (fd0, fd1); +} diff --git a/appl/alphabet/main/mkfile b/appl/alphabet/main/mkfile new file mode 100644 index 00000000..ff2d95fb --- /dev/null +++ b/appl/alphabet/main/mkfile @@ -0,0 +1,36 @@ +<../../../mkconfig + +TARG=\ + auth.dis\ + cat.dis\ + create.dis\ + dial.dis\ + echo.dis\ + env.dis\ + export.dis\ + fd.dis\ + filter.dis\ + mount.dis\ + par.dis\ + parse.dis\ + pretty.dis\ + print.dis\ + read.dis\ + readall.dis\ + rewrite.dis\ + seq.dis\ + unparse.dis\ + w2fd.dis\ + wait.dis\ + +SYSMODULES=\ + alphabet.m\ + alphabet/reports.m\ + draw.m\ + sh.m\ + sys.m\ + +DISBIN=$ROOT/dis/alphabet/main + +<$ROOT/mkfiles/mkdis +LIMBOFLAGS=-F $LIMBOFLAGS diff --git a/appl/alphabet/main/mount.b b/appl/alphabet/main/mount.b new file mode 100644 index 00000000..1b27617d --- /dev/null +++ b/appl/alphabet/main/mount.b @@ -0,0 +1,80 @@ +implement Mount,Mainmodule; +include "sys.m"; + sys: Sys; +include "draw.m"; +include "sh.m"; +include "alphabet/reports.m"; + reports: Reports; + Report, report: import reports; +include "alphabet.m"; + alphabet: Alphabet; + Value: import alphabet; + +Mount: module {}; + +typesig(): string +{ + return "rws-a-b-c-xs"; +} + +init() +{ + sys = load Sys Sys->PATH; + alphabet = load Alphabet Alphabet->PATH; + reports = load Reports Reports->PATH; +} + +quit() +{ +} + +After, Before, Create: con 1<<iota; + +run(nil: ref Draw->Context, report: ref Reports->Report, nil: chan of string, + opts: list of (int, list of ref Alphabet->Value), + args: list of ref Alphabet->Value): ref Alphabet->Value +{ + flag := Sys->MREPL; + aname := ""; + for(; opts != nil; opts = tl opts){ + case (hd opts).t0 { + 'a' => + flag = After & (flag&Sys->MCREATE); + 'b' => + flag = Before & (flag&Sys->MCREATE); + 'c' => + flag |= Create; + 'x' => + aname = (hd (hd opts).t1).s().i; + } + } + r := chan of string; + spawn mountproc(r, (hd args).w().i, (hd tl args).s().i, aname, flag, report.start("mount")); + return ref Value.Vr(r); +} + +mountproc(r: chan of string, w: chan of ref Sys->FD, dir, aname: string, flag: int, errorc: chan of string) +{ + if(<-r != nil){ + errorc <-= nil; + <-w; + w <-= nil; + exit; + } + fd := <-w; + if(fd == nil){ + sys->pipe(p := array[2] of ref Sys->FD); + w <-= p[0]; + fd = p[1]; + }else + w <-= nil; + if(sys->mount(fd, nil, dir, flag, aname) == -1){ + e := sys->sprint("mount error on %#q: %r", dir); + report(errorc, e); + r <-= e; + exit; + } + + errorc <-= nil; + r <-= nil; +} diff --git a/appl/alphabet/main/par.b b/appl/alphabet/main/par.b new file mode 100644 index 00000000..d2b47ef3 --- /dev/null +++ b/appl/alphabet/main/par.b @@ -0,0 +1,50 @@ +implement Seq, Mainmodule; +include "sys.m"; + sys: Sys; +include "draw.m"; +include "sh.m"; +include "alphabet/reports.m"; +include "alphabet.m"; + alphabet: Alphabet; + Value: import alphabet; + +Seq: module {}; + +typesig(): string +{ + return "rr*"; +} + +init() +{ + sys = load Sys Sys->PATH; + alphabet = load Alphabet Alphabet->PATH; +} + +quit() +{ +} + +run(nil: ref Draw->Context, nil: ref Reports->Report, nil: chan of string, + nil: list of (int, list of ref Alphabet->Value), + args: list of ref Alphabet->Value): ref Alphabet->Value +{ + spawn parproc(r := chan of string, args); + return ref Value.Vr(r); +} + +parproc(r: chan of string, args: list of ref Alphabet->Value) +{ + if(<-r != nil){ + for(; args != nil; args = tl args) + (hd args).r().i <-= "die!"; + }else{ + status := ""; + for(a := args; a != nil; a = tl a) + (hd a).r().i <-= nil; + for(; args != nil; args = tl args) + if((e := <-(hd args).r().i) != nil) + status = e; + r <-= status; + } +} diff --git a/appl/alphabet/main/parse.b b/appl/alphabet/main/parse.b new file mode 100644 index 00000000..c02ba124 --- /dev/null +++ b/appl/alphabet/main/parse.b @@ -0,0 +1,43 @@ +implement Parse, Mainmodule; +include "sys.m"; + sys: Sys; +include "draw.m"; +include "sh.m"; + sh: Sh; +include "alphabet/reports.m"; + reports: Reports; + Report, report: import reports; +include "alphabet.m"; + alphabet: Alphabet; + Value: import alphabet; + +Parse: module {}; + +typesig(): string +{ + return "cs"; +} + +init() +{ + sys = load Sys Sys->PATH; + alphabet = load Alphabet Alphabet->PATH; + sh = load Sh Sh->PATH; + sh->initialise(); +} + +quit() +{ +} + +run(nil: ref Draw->Context, nil: ref Reports->Report, errorc: chan of string, + nil: list of (int, list of ref Value), + args: list of ref Value): ref Value +{ + (c, err) := sh->parse((hd args).s().i); + if(c == nil){ + report(errorc, sys->sprint("parse: parse %q failed: %s", (hd args).s().i, err)); + return nil; + } + return ref Value.Vc(c); +} diff --git a/appl/alphabet/main/pretty.b b/appl/alphabet/main/pretty.b new file mode 100644 index 00000000..52d8b32f --- /dev/null +++ b/appl/alphabet/main/pretty.b @@ -0,0 +1,116 @@ +implement Pretty, Mainmodule; +include "sys.m"; + sys: Sys; +include "draw.m"; +include "sh.m"; + sh: Sh; + n_BLOCK, n_VAR, n_BQ, n_BQ2, n_REDIR, + n_DUP, n_LIST, n_SEQ, n_CONCAT, n_PIPE, n_ADJ, + n_WORD, n_NOWAIT, n_SQUASH, n_COUNT, + n_ASSIGN, n_LOCAL, + GLOB: import Sh; +include "alphabet/reports.m"; + reports: Reports; + Report, report: import reports; +include "alphabet.m"; + alphabet: Alphabet; + Value: import alphabet; + +Pretty: module {}; + +typesig(): string +{ + return "sc"; +} + +init() +{ + sys = load Sys Sys->PATH; + alphabet = load Alphabet Alphabet->PATH; + sh = load Sh Sh->PATH; + sh->initialise(); +} + +quit() +{ +} + +run(nil: ref Draw->Context, nil: ref Reports->Report, nil: chan of string, + nil: list of (int, list of ref Value), + args: list of ref Value): ref Value +{ + { + return ref Value.Vs(pretty((hd args).c().i, 0)); + }exception{ + "bad expr" => + return nil; + } +} + +pretty(n: ref Sh->Cmd, depth: int): string +{ + if (n == nil) + return nil; + s: string; + case n.ntype { + n_BLOCK => + s = "{\n"+tabs(depth+1)+pretty(n.left,depth+1) + "\n"+tabs(depth)+"}"; + n_VAR => + s = "$" + pretty(n.left, depth); + n_LIST => + s = "(" + pretty(n.left, depth) + ")"; + n_SEQ => + s = pretty(n.left, depth) + "\n"+tabs(depth)+pretty(n.right, depth); + n_PIPE => + s = pretty(n.left, depth) + " |\n"+tabs(depth)+pretty(n.right, depth); + n_ADJ => + s = pretty(n.left, depth) + " " + pretty(n.right, depth); + n_WORD => + s = quote(n.word, 1); + n_BQ2 => + # if we can't do it, revert to ugliness. + { + s = "\"" + pretty(n.left, depth); + } exception { + "bad expr" => + s = sh->cmd2string(n); + } + * => + raise "bad expr"; + } + return s; +} + +tabs(n: int): string +{ + s: string; + while(n-- > 0) + s[len s] = '\t'; + return s; +} + +# stolen from sh.y +quote(s: string, glob: int): string +{ + needquote := 0; + t := ""; + for (i := 0; i < len s; i++) { + case s[i] { + '{' or '}' or '(' or ')' or '`' or '&' or ';' or '=' or '>' or '<' or '#' or + '|' or '*' or '[' or '?' or '$' or '^' or ' ' or '\t' or '\n' or '\r' => + needquote = 1; + '\'' => + t[len t] = '\''; + needquote = 1; + GLOB => + if (glob) { + if (i < len s - 1) + i++; + } + } + t[len t] = s[i]; + } + if (needquote || t == nil) + t = "'" + t + "'"; + return t; +} diff --git a/appl/alphabet/main/print.b b/appl/alphabet/main/print.b new file mode 100644 index 00000000..12327934 --- /dev/null +++ b/appl/alphabet/main/print.b @@ -0,0 +1,55 @@ +implement Print,Mainmodule; +include "sys.m"; + sys: Sys; +include "draw.m"; +include "sh.m"; +include "alphabet/reports.m"; + reports: Reports; + Report, report: import reports; +include "alphabet.m"; + alphabet: Alphabet; + Value: import alphabet; + +Print: module {}; + +typesig(): string +{ + return "rfs"; +} + +init() +{ + sys = load Sys Sys->PATH; + alphabet = load Alphabet Alphabet->PATH; + reports = load Reports Reports->PATH; +} + +quit() +{ +} + +run(nil: ref Draw->Context, nil: ref Reports->Report, errorc: chan of string, + nil: list of (int, list of ref Alphabet->Value), + args: list of ref Alphabet->Value): ref Alphabet->Value +{ + r := chan of string; + fd := sys->fildes(int (hd tl args).s().i); + if(fd == nil){ + report(errorc, sys->sprint("error: no such fd %q", (hd tl args).s().i)); + return nil; + } + spawn printproc(r, (hd args).f().i, fd); + return ref Value.Vr(r); +} + +printproc(r: chan of string, f: chan of ref Sys->FD, fd: ref Sys->FD) +{ + if(<-r != nil){ + <-f; + f <-= nil; + exit; + } + <-f; + f <-= fd; + r <-= nil; +} diff --git a/appl/alphabet/main/read.b b/appl/alphabet/main/read.b new file mode 100644 index 00000000..ebc4d156 --- /dev/null +++ b/appl/alphabet/main/read.b @@ -0,0 +1,56 @@ +implement Read,Mainmodule; +include "sys.m"; + sys: Sys; +include "draw.m"; +include "sh.m"; +include "alphabet/reports.m"; + reports: Reports; + Report, report: import reports; +include "alphabet.m"; + alphabet: Alphabet; + Value: import alphabet; + +Read: module{}; + +typesig(): string +{ + return "fs"; +} + +init() +{ + sys = load Sys Sys->PATH; + alphabet = load Alphabet Alphabet->PATH; + reports = load Reports Reports->PATH; +} + +quit() +{ +} + +run(nil: ref Draw->Context, r: ref Reports->Report, errorc: chan of string, + nil: list of (int, list of ref Alphabet->Value), + args: list of ref Alphabet->Value): ref Alphabet->Value +{ + f := chan of ref Sys->FD; + file := (hd args).s().i; + if((fd0 := sys->open(file, Sys->OREAD)) == nil){ + report(errorc, sys->sprint("cannot open %q: %r", file)); + return nil; + } + spawn readproc(f, fd0, r.start("read")); + return ref Value.Vf(f); +} + +readproc(f: chan of ref Sys->FD, fd0: ref Sys->FD, errorc: chan of string) +{ + f <-= fd0; + fd1 := <-f; + if(fd1 == nil) + reports->quit(errorc); + buf := array[8192] of byte; + while((n := sys->read(fd0, buf, len buf)) > 0) + sys->write(fd1, buf, n); + sys->write(fd1, array[0] of byte, 0); + reports->quit(errorc); +} diff --git a/appl/alphabet/main/readall.b b/appl/alphabet/main/readall.b new file mode 100644 index 00000000..b8697332 --- /dev/null +++ b/appl/alphabet/main/readall.b @@ -0,0 +1,46 @@ +implement F2s, Mainmodule; +include "sys.m"; + sys: Sys; +include "draw.m"; +include "sh.m"; +include "alphabet/reports.m"; + reports: Reports; + Report, report: import reports; +include "alphabet.m"; + alphabet: Alphabet; + Value: import alphabet; + +F2s: module {}; + +typesig(): string +{ + return "sf"; +} + +init() +{ + sys = load Sys Sys->PATH; + alphabet = load Alphabet Alphabet->PATH; +} + +quit() +{ +} + +run(nil: ref Draw->Context, nil: ref Reports->Report, nil: chan of string, + nil: list of (int, list of ref Value), + args: list of ref Value): ref Value +{ + f := (hd args).f().i; + fd := <-f; + if(fd == nil){ + sys->pipe(p := array[2] of ref Sys->FD); + f <-= p[1]; + fd = p[0]; + } + s: string; + buf := array[Sys->ATOMICIO] of byte; + while((n := sys->read(fd, buf, len buf)) > 0) + s += string buf[0:n]; + return ref Value.Vs(s); +} diff --git a/appl/alphabet/main/rewrite.b b/appl/alphabet/main/rewrite.b new file mode 100644 index 00000000..96a6e205 --- /dev/null +++ b/appl/alphabet/main/rewrite.b @@ -0,0 +1,97 @@ +implement Rewrite, Mainmodule; +include "sys.m"; + sys: Sys; +include "draw.m"; +include "sh.m"; + sh: Sh; + Context: import sh; +include "alphabet/reports.m"; + reports: Reports; + report: import reports; +include "alphabet.m"; + Value: import Alphabet; + +Rewrite: module {}; + +typesig(): string +{ + return "ccc-ds"; +} + +init() +{ + sys = load Sys Sys->PATH; + sh = load Sh Sh->PATH; + sh->initialise(); + reports = load Reports Reports->PATH; +} + +quit() +{ +} + +run(drawctxt: ref Draw->Context, nil: ref Reports->Report, errorc: chan of string, + opts: list of (int, list of ref Value), + args: list of ref Value): ref Value +{ + c := chan of ref Value; + spawn rewriteproc(drawctxt, errorc, opts, args, c); + return <-c; +} + +# we need a separate process so that we can create a shell context +# without worrying about opening an already-opened wait file. +rewriteproc(drawctxt: ref Draw->Context, errorc: chan of string, + opts: list of (int, list of ref Value), + args: list of ref Value, + c: chan of ref Value) +{ + c <-= rewrite(drawctxt, errorc, opts, args); +} + +rewrite(drawctxt: ref Draw->Context, errorc: chan of string, + opts: list of (int, list of ref Value), + args: list of ref Value): ref Value +{ + alphabet := load Alphabet Alphabet->PATH; + if(alphabet == nil){ + report(errorc, sys->sprint("rewrite: cannot load %q: %r", Alphabet->PATH)); + return nil; + } + Value: import alphabet; + alphabet->init(); + expr := (hd args).c().i; + decls := (hd tl args).c().i; + ctxt := Context.new(drawctxt); + { + ctxt.run(w("load")::w("alphabet")::nil, 0); + ctxt.run(c(decls) :: nil, 0); + dstarg: list of ref Sh->Listnode; + if(opts != nil) + dstarg = w((hd (hd opts).t1).s().i) :: nil; + ctxt.run(w("{x=${rewrite $1 $2}}") :: c(expr) :: dstarg, 0); + } exception e { + "fail:*" => + ctxt.run(w("clear")::nil, 0); + report(errorc, "rewrite failed: "+e[5:]); + return nil; + } + r := ctxt.get("x"); + if(len r != 2 || (hd r).cmd == nil){ + ctxt.run(w("clear")::nil, 0); + report(errorc, "rewrite not available, strange... (len "+string len r+")"); + return nil; + } + ctxt.run(w("clear")::nil, 0); + return ref Value.Vc((hd r).cmd); +} + +c(c: ref Sh->Cmd): ref Sh->Listnode +{ + return ref Sh->Listnode(c, nil); +} + +w(w: string): ref Sh->Listnode +{ + return ref Sh->Listnode(nil, w); +} diff --git a/appl/alphabet/main/rw.b b/appl/alphabet/main/rw.b new file mode 100644 index 00000000..74ede534 --- /dev/null +++ b/appl/alphabet/main/rw.b @@ -0,0 +1,50 @@ +implement Mainmodule; +include "sys.m"; + sys: Sys; +include "draw.m"; +include "sh.m"; +include "alphabet/reports.m"; + reports: Reports; + Report, report, quit: import reports; +include "alphabet.m"; + alphabet: Alphabet; + Value: import alphabet; + +typesig(): string +{ + return "fs"; +} + +init() +{ + sys = load Sys Sys->PATH; + alphabet = load Alphabet Alphabet->PATH; + reports = load Reports Reports->PATH; +} + +run(nil: ref Draw->Context, r: ref Reports->Report, errorc: chan of string, + nil: list of (int, list of ref Alphabet->Value), + args: list of ref Alphabet->Value): ref Alphabet->Value +{ + f := chan of ref Sys->FD; + file := (hd args).s().i; + if((fd0 := sys->open(file, Sys->OREAD)) == nil){ + report(errorc, sys->sprint("cannot open %q: %r", file)); + return nil; + } + spawn readproc(f, fd0, r.start("read")); + return ref Value.F(f); +} + +readproc(f: chan of ref Sys->FD, fd0: ref Sys->FD, errorc: chan of string) +{ + f <-= fd0; + fd1 := <-f; + if(fd1 == nil) + quit(errorc); + buf := array[8192] of byte; + while((n := sys->read(fd0, buf, len buf)) > 0) + sys->write(fd1, buf, n); + sys->write(fd1, array[0] of byte, 0); + quit(errorc); +} diff --git a/appl/alphabet/main/seq.b b/appl/alphabet/main/seq.b new file mode 100644 index 00000000..8e062738 --- /dev/null +++ b/appl/alphabet/main/seq.b @@ -0,0 +1,66 @@ +implement Seq, Mainmodule; +include "sys.m"; + sys: Sys; +include "draw.m"; +include "sh.m"; +include "alphabet/reports.m"; +include "alphabet.m"; + alphabet: Alphabet; + Value: import alphabet; + +Seq: module {}; + +typesig(): string +{ + return "rr*-a-o"; +} + +init() +{ + sys = load Sys Sys->PATH; + alphabet = load Alphabet Alphabet->PATH; +} + +quit() +{ +} + +run(nil: ref Draw->Context, nil: ref Reports->Report, nil: chan of string, + opts: list of (int, list of ref Alphabet->Value), + args: list of ref Alphabet->Value): ref Alphabet->Value +{ + stop := -1; + for(; opts != nil; opts = tl opts){ + case (hd opts).t0 { + 'a' => + stop = 0; + 'o' => + stop = 1; + } + } + spawn seqproc(r := chan of string, args, stop); + return ref Value.Vr(r); +} + +seqproc(r: chan of string, args: list of ref Alphabet->Value, stop: int) +{ + status := ""; + if(<-r == nil){ +pid := sys->pctl(0, nil); +sys->print("%d. seq %d args\n", pid, len args); + for(; args != nil; args = tl args){ + sr := (hd args).r().i; +sys->print("%d. started\n", pid); + sr <-= nil; + status = <-sr; +sys->print("%d. got status\n", pid); + if((status == nil) == stop) + break; + } + }else + r = nil; + for(; args != nil; args = tl args) + (hd args).r().i <-= "die!"; + if(r != nil) + r <-= status; +} diff --git a/appl/alphabet/main/unparse.b b/appl/alphabet/main/unparse.b new file mode 100644 index 00000000..11aa0d48 --- /dev/null +++ b/appl/alphabet/main/unparse.b @@ -0,0 +1,38 @@ +implement Unparse, Mainmodule; +include "sys.m"; + sys: Sys; +include "draw.m"; +include "sh.m"; + sh: Sh; +include "alphabet/reports.m"; + reports: Reports; + Report, report: import reports; +include "alphabet.m"; + alphabet: Alphabet; + Value: import alphabet; + +Unparse: module {}; + +typesig(): string +{ + return "sc"; +} + +init() +{ + sys = load Sys Sys->PATH; + alphabet = load Alphabet Alphabet->PATH; + sh = load Sh Sh->PATH; + sh->initialise(); +} + +quit() +{ +} + +run(nil: ref Draw->Context, nil: ref Reports->Report, nil: chan of string, + nil: list of (int, list of ref Value), + args: list of ref Value): ref Value +{ + return ref Value.Vs(sh->cmd2string((hd args).c().i)); +} diff --git a/appl/alphabet/main/w2fd.b b/appl/alphabet/main/w2fd.b new file mode 100644 index 00000000..ab7e3a70 --- /dev/null +++ b/appl/alphabet/main/w2fd.b @@ -0,0 +1,61 @@ +implement ToFD,Mainmodule; +include "sys.m"; + sys: Sys; +include "draw.m"; +include "sh.m"; +include "alphabet/reports.m"; + reports: Reports; + Report: import reports; +include "alphabet.m"; + alphabet: Alphabet; + Value: import alphabet; + +ToFD: module {}; + +typesig(): string +{ + return "fw"; +} + +init() +{ + alphabet = load Alphabet Alphabet->PATH; + reports = load Reports Reports->PATH; +} + +quit() +{ +} + +run(nil: ref Draw->Context, r: ref Reports->Report, nil: chan of string, + nil: list of (int, list of ref Alphabet->Value), + args: list of ref Alphabet->Value): ref Alphabet->Value +{ + sys = load Sys Sys->PATH; + f := chan of ref Sys->FD; + spawn tofdproc(f, (hd args).w().i, r.start("2fd")); + return ref Value.Vf(f); +} + +tofdproc(f, w: chan of ref Sys->FD, errorc: chan of string) +{ + fd0 := <-w; + f <-= fd0; + fd1 := <-f; + if(fd1 == nil) # asked to quit? tell w to quit too. + w <-= nil; + else + if(fd0 == nil) # no proposed fd? give 'em the one we've just got. + w <-= fd1; + else{ # otherwise one-way stream from w to f. + w <-= nil; + buf := array[Sys->ATOMICIO] of byte; + while((n := sys->read(fd0, buf, len buf)) > 0){ + if(sys->write(fd1, buf, n) == -1){ + reports->report(errorc, sys->sprint("write error: %r")); + break; + } + } + } + reports->quit(errorc); +} diff --git a/appl/alphabet/main/wait.b b/appl/alphabet/main/wait.b new file mode 100644 index 00000000..04bf88c6 --- /dev/null +++ b/appl/alphabet/main/wait.b @@ -0,0 +1,35 @@ +implement Wait, Mainmodule; +include "sys.m"; + sys: Sys; +include "draw.m"; +include "sh.m"; +include "alphabet/reports.m"; +include "alphabet.m"; + alphabet: Alphabet; + Value: import alphabet; + +Wait: module {}; + +typesig(): string +{ + return "sr"; +} + +init() +{ + sys = load Sys Sys->PATH; + alphabet = load Alphabet Alphabet->PATH; +} + +quit() +{ +} + +run(nil: ref Draw->Context, nil: ref Reports->Report, nil: chan of string, + nil: list of (int, list of ref Alphabet->Value), + args: list of ref Alphabet->Value): ref Alphabet->Value +{ + r := (hd args).r().i; + r <-= nil; + return ref Value.Vs(<-r); +} |
