summaryrefslogtreecommitdiff
path: root/appl/demo/ns/ns.b
diff options
context:
space:
mode:
authorCharles.Forsyth <devnull@localhost>2006-12-22 17:07:39 +0000
committerCharles.Forsyth <devnull@localhost>2006-12-22 17:07:39 +0000
commit37da2899f40661e3e9631e497da8dc59b971cbd0 (patch)
treecbc6d4680e347d906f5fa7fca73214418741df72 /appl/demo/ns/ns.b
parent54bc8ff236ac10b3eaa928fd6bcfc0cdb2ba46ae (diff)
20060303a
Diffstat (limited to 'appl/demo/ns/ns.b')
-rw-r--r--appl/demo/ns/ns.b124
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;
+}