diff options
Diffstat (limited to 'appl/demo/ns/ns.b')
| -rw-r--r-- | appl/demo/ns/ns.b | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/appl/demo/ns/ns.b b/appl/demo/ns/ns.b new file mode 100644 index 00000000..266a07ff --- /dev/null +++ b/appl/demo/ns/ns.b @@ -0,0 +1,124 @@ +implement Ns; + +# +# Copyright © 2003 Vita Nuova Holdings Limited. All rights reserved. +# + +include "sys.m"; + sys: Sys; +include "draw.m"; +include "arg.m"; +include "sh.m"; + sh: Sh; + +ns : list of string; + +Ns: module { + init: fn(nil: ref Draw->Context, argv: list of string); +}; + +init(nil: ref Draw->Context, argv: list of string) +{ + sys = load Sys Sys->PATH; + if (sys == nil) + badmod(Sys->PATH); + sh = load Sh Sh->PATH; + if (sh == nil) + badmod(Sh->PATH); + # sys->pctl(sys->FORKNS, nil); + sys->unmount(nil, "/n/remote"); + arg := load Arg Arg->PATH; + if (arg == nil) + badmod(Arg->PATH); + + arg->init(argv); + arg->setusage("ns [-v] [-r relpath] paths..."); + verbose := 0; + relpath := ""; + while ((opt := arg->opt()) != 0) { + case opt { + 'v' => + verbose = 1; + 'r' => + relpath = arg->earg(); + if (relpath == nil) + arg->usage(); + if (relpath[len relpath - 1] != '/') + relpath[len relpath] = '/'; + * => + arg->usage(); + } + } + + ns = arg->argv(); + arg = nil; + if (ns == nil) { + sys->fprint(fdout(), "error no namespace selected\n"); + exit; + } + spawn buildns(relpath, verbose); +} + +fdout(): ref sys->FD +{ + return sys->fildes(1); +} + +buildns(relpath: string, verbose: int) +{ + # sys->pctl(sys->FORKNS, nil); + if (sh->run(nil, "memfs"::"/n/remote"::nil) != nil) { + sys->fprint(fdout(), "error MemFS mount failed\n"); + exit; + } + for (tmpl := ns; tmpl != nil; tmpl = tl tmpl) { + nspath := hd tmpl; + if (nspath[len nspath - 1] != '/') + nspath[len nspath] = '/'; + + bindpath := nspath; + if (bindpath[:len relpath] == relpath) { + bindpath = "/n/remote/"+bindpath[len relpath:]; + if (createdir(bindpath) != -1) { + if (sys->bind(nspath, bindpath, sys->MBEFORE | sys->MCREATE) == -1) { + if (sys->bind(nspath, bindpath, sys->MBEFORE) == -1) + sys->fprint(fdout(), "error bind failed %s: %r\n",bindpath); + else if (verbose) + sys->fprint(fdout(), "data nspath %s\n", nspath); + } + else if (verbose) + sys->fprint(fdout(), "data nspath %s\n", nspath); + } + else + sys->fprint(fdout(), "error create failed %s\n",bindpath); + } + } + spawn exportns(); +} + +exportns() +{ + sys->export(sys->fildes(0), "/n/remote", sys->EXPWAIT); +} + +createdir(path: string): int +{ + (nil, lst) := sys->tokenize(path, "/"); + npath := ""; + for (; lst != nil; lst = tl lst) { + (n, nil) := sys->stat(npath + "/" + hd lst); + if (n == -1) { + fd := sys->create(npath + "/" + hd lst, sys->OREAD, 8r777 | sys->DMDIR); + if (fd == nil) + return -1; + } + npath += "/" + hd lst; + } + return 0; +} + +badmod(path: string) +{ + sys->fprint(fdout(), "error Ns: failed to load: %s\n",path); + exit; +} |
