137da2899SCharles.Forsythimplement Newns; 237da2899SCharles.Forsyth# 337da2899SCharles.Forsyth# Build a new namespace from a file 437da2899SCharles.Forsyth# 537da2899SCharles.Forsyth# new create a new namespace from current directory (use cd) 637da2899SCharles.Forsyth# fork split the namespace before modification 737da2899SCharles.Forsyth# nodev disallow device attaches 837da2899SCharles.Forsyth# bind [-abrci] from to 937da2899SCharles.Forsyth# mount [-abrci9] [net!]machine[!svc] to [spec] 1037da2899SCharles.Forsyth# import [-abrci9] [net!]machine[!svc] [remotedir] dir 1137da2899SCharles.Forsyth# unmount [-i] [from] to 1237da2899SCharles.Forsyth# cd directory 1337da2899SCharles.Forsyth# 1437da2899SCharles.Forsyth# -i to bind/mount/unmount means continue in the face of errors 1537da2899SCharles.Forsyth# 1637da2899SCharles.Forsythinclude "sys.m"; 1737da2899SCharles.Forsyth sys: Sys; 1862d7827bScharles forsyth FD, FileIO: import Sys; 1937da2899SCharles.Forsyth stderr: ref FD; 2037da2899SCharles.Forsyth 2137da2899SCharles.Forsythinclude "draw.m"; 2237da2899SCharles.Forsyth 2337da2899SCharles.Forsythinclude "bufio.m"; 2437da2899SCharles.Forsyth bio: Bufio; 2537da2899SCharles.Forsyth Iobuf: import bio; 2637da2899SCharles.Forsyth 27fbc1184cSCharles Forsythinclude "dial.m"; 28fbc1184cSCharles Forsyth dial: Dial; 2962d7827bScharles forsyth Connection: import dial; 30fbc1184cSCharles Forsyth 3137da2899SCharles.Forsythinclude "newns.m"; 3237da2899SCharles.Forsyth 3337da2899SCharles.Forsyth#include "sh.m"; 3437da2899SCharles.Forsyth 3537da2899SCharles.Forsythinclude "keyring.m"; 3637da2899SCharles.Forsyth kr: Keyring; 3737da2899SCharles.Forsyth 3837da2899SCharles.Forsythinclude "security.m"; 3937da2899SCharles.Forsyth au: Auth; 4037da2899SCharles.Forsyth 4137da2899SCharles.Forsythinclude "factotum.m"; 4237da2899SCharles.Forsyth 4337da2899SCharles.Forsythinclude "arg.m"; 4437da2899SCharles.Forsyth arg: Arg; 4537da2899SCharles.Forsyth 466e425a9dSCharles.Forsythinclude "string.m"; 476e425a9dSCharles.Forsyth str: String; 486e425a9dSCharles.Forsyth 4937da2899SCharles.Forsythnewns(user: string, file: string): string 5037da2899SCharles.Forsyth{ 5137da2899SCharles.Forsyth sys = load Sys Sys->PATH; 5237da2899SCharles.Forsyth kr = load Keyring Keyring->PATH; 5337da2899SCharles.Forsyth stderr = sys->fildes(2); 5437da2899SCharles.Forsyth 5537da2899SCharles.Forsyth # Could do some authentication here, and bail if no good FIXME 5637da2899SCharles.Forsyth if(user == nil) 5737da2899SCharles.Forsyth ; 5837da2899SCharles.Forsyth bio = load Bufio Bufio->PATH; 5937da2899SCharles.Forsyth if(bio == nil) 6037da2899SCharles.Forsyth return sys->sprint("cannot load %s: %r", Bufio->PATH); 6137da2899SCharles.Forsyth 6237da2899SCharles.Forsyth arg = load Arg Arg->PATH; 6337da2899SCharles.Forsyth if (arg == nil) 6437da2899SCharles.Forsyth return sys->sprint("cannot load %s: %r", Arg->PATH); 6537da2899SCharles.Forsyth 6637da2899SCharles.Forsyth au = load Auth Auth->PATH; 6737da2899SCharles.Forsyth if(au == nil) 6837da2899SCharles.Forsyth return sys->sprint("cannot load %s: %r", Auth->PATH); 6937da2899SCharles.Forsyth err := au->init(); 7037da2899SCharles.Forsyth if(err != nil) 7137da2899SCharles.Forsyth return "Auth->init: "+err; 7237da2899SCharles.Forsyth 736e425a9dSCharles.Forsyth str = load String String->PATH; # no check, because we'll live without it 746e425a9dSCharles.Forsyth 7537da2899SCharles.Forsyth if(file == nil){ 7637da2899SCharles.Forsyth file = "namespace"; 7737da2899SCharles.Forsyth if(sys->stat(file).t0 < 0) 7837da2899SCharles.Forsyth file = "/lib/namespace"; 7937da2899SCharles.Forsyth } 8037da2899SCharles.Forsyth 8137da2899SCharles.Forsyth mfp := bio->open(file, bio->OREAD); 8237da2899SCharles.Forsyth if(mfp==nil) 8337da2899SCharles.Forsyth return sys->sprint("cannot open %q: %r", file); 8437da2899SCharles.Forsyth 8537da2899SCharles.Forsyth if(0 && user != nil){ 8637da2899SCharles.Forsyth sys->pctl(Sys->FORKENV, nil); 8737da2899SCharles.Forsyth setenv("user", user); 8837da2899SCharles.Forsyth setenv("home", "/usr/"+user); 8937da2899SCharles.Forsyth } 9037da2899SCharles.Forsyth 9137da2899SCharles.Forsyth facfd := sys->open("/mnt/factotum/rpc", Sys->ORDWR); 9237da2899SCharles.Forsyth return nsfile(mfp, facfd); 9337da2899SCharles.Forsyth} 9437da2899SCharles.Forsyth 9537da2899SCharles.Forsythnsfile(b: ref Iobuf, facfd: ref Sys->FD): string 9637da2899SCharles.Forsyth{ 9737da2899SCharles.Forsyth e := ""; 9837da2899SCharles.Forsyth while((l := b.gets('\n')) != nil){ 996e425a9dSCharles.Forsyth if(str != nil) 1006e425a9dSCharles.Forsyth slist := str->unquoted(l); 1016e425a9dSCharles.Forsyth else 1026e425a9dSCharles.Forsyth (nil, slist) = sys->tokenize(l, " \t\n\r"); # old way, in absence of String 1036e425a9dSCharles.Forsyth if(slist == nil) 10437da2899SCharles.Forsyth continue; 10537da2899SCharles.Forsyth e = nsop(expand(slist), facfd); 10637da2899SCharles.Forsyth if(e != "") 10737da2899SCharles.Forsyth break; 10837da2899SCharles.Forsyth } 10937da2899SCharles.Forsyth return e; 11037da2899SCharles.Forsyth} 11137da2899SCharles.Forsyth 11237da2899SCharles.Forsythexpand(l: list of string): list of string 11337da2899SCharles.Forsyth{ 11437da2899SCharles.Forsyth nl: list of string; 11537da2899SCharles.Forsyth for(; l != nil; l = tl l){ 11637da2899SCharles.Forsyth s := hd l; 11737da2899SCharles.Forsyth for(i := 0; i < len s; i++) 11837da2899SCharles.Forsyth if(s[i] == '$'){ 11937da2899SCharles.Forsyth for(j := i+1; j < len s; j++) 12037da2899SCharles.Forsyth if((c := s[j]) == '.' || c == '/' || c == '$') 12137da2899SCharles.Forsyth break; 12237da2899SCharles.Forsyth if(j > i+1){ 12337da2899SCharles.Forsyth (ok, v) := getenv(s[i+1:j]); 12437da2899SCharles.Forsyth if(!ok) 12537da2899SCharles.Forsyth return nil; 12637da2899SCharles.Forsyth s = s[0:i] + v + s[j:]; 12737da2899SCharles.Forsyth i = i + len v; 12837da2899SCharles.Forsyth } 12937da2899SCharles.Forsyth } 13037da2899SCharles.Forsyth nl = s :: nl; 13137da2899SCharles.Forsyth } 13237da2899SCharles.Forsyth l = nil; 13337da2899SCharles.Forsyth for(; nl != nil; nl = tl nl) 13437da2899SCharles.Forsyth l = hd nl :: l; 13537da2899SCharles.Forsyth return l; 13637da2899SCharles.Forsyth} 13737da2899SCharles.Forsyth 13837da2899SCharles.Forsythnsop(argv: list of string, facfd: ref Sys->FD): string 13937da2899SCharles.Forsyth{ 14037da2899SCharles.Forsyth # ignore comments 14137da2899SCharles.Forsyth if(argv == nil || (hd argv)[0] == '#') 14237da2899SCharles.Forsyth return nil; 14337da2899SCharles.Forsyth 14437da2899SCharles.Forsyth e := ""; 14537da2899SCharles.Forsyth c := 0; 14637da2899SCharles.Forsyth cmdstr := hd argv; 14737da2899SCharles.Forsyth case cmdstr { 14837da2899SCharles.Forsyth "." => 14937da2899SCharles.Forsyth if(tl argv == nil) 15037da2899SCharles.Forsyth return ".: needs a filename"; 15137da2899SCharles.Forsyth nsf := hd tl argv; 15237da2899SCharles.Forsyth mfp := bio->open(nsf, bio->OREAD); 15337da2899SCharles.Forsyth if(mfp==nil) 15437da2899SCharles.Forsyth return sys->sprint("can't open %q for read %r", nsf); 15537da2899SCharles.Forsyth e = nsfile(mfp, facfd); 15637da2899SCharles.Forsyth "new" => 15737da2899SCharles.Forsyth c = Sys->NEWNS | Sys->FORKENV; 15837da2899SCharles.Forsyth "clear" => 15937da2899SCharles.Forsyth if(sys->pctl(Sys->FORKNS, nil) < 0 || 16037da2899SCharles.Forsyth sys->bind("#/", "/", Sys->MREPL) < 0 || 16137da2899SCharles.Forsyth sys->chdir("/") < 0 || 16237da2899SCharles.Forsyth sys->pctl(Sys->NEWNS, nil) < 0) 16337da2899SCharles.Forsyth return sys->sprint("%r"); 16437da2899SCharles.Forsyth return nil; 16537da2899SCharles.Forsyth "fork" => 16637da2899SCharles.Forsyth c = Sys->FORKNS; 16737da2899SCharles.Forsyth "nodev" => 16837da2899SCharles.Forsyth c = Sys->NODEVS; 16937da2899SCharles.Forsyth "bind" => 17037da2899SCharles.Forsyth e = bind(argv); 17137da2899SCharles.Forsyth "mount" => 17237da2899SCharles.Forsyth e = mount(argv, facfd); 17337da2899SCharles.Forsyth "unmount" => 17437da2899SCharles.Forsyth e = unmount(argv); 17537da2899SCharles.Forsyth "import" => 17637da2899SCharles.Forsyth e = import9(argv, facfd); 17737da2899SCharles.Forsyth "cd" => 17837da2899SCharles.Forsyth if(len argv != 2) 17937da2899SCharles.Forsyth return "cd: must have one argument"; 18037da2899SCharles.Forsyth if(sys->chdir(hd tl argv) < 0) 18137da2899SCharles.Forsyth return sys->sprint("%r"); 18237da2899SCharles.Forsyth * => 18337da2899SCharles.Forsyth e = "invalid namespace command"; 18437da2899SCharles.Forsyth } 18537da2899SCharles.Forsyth if(c != 0) { 18637da2899SCharles.Forsyth if(sys->pctl(c, nil) < 0) 18737da2899SCharles.Forsyth return sys->sprint("%r"); 18837da2899SCharles.Forsyth } 18937da2899SCharles.Forsyth return e; 19037da2899SCharles.Forsyth} 19137da2899SCharles.Forsyth 19237da2899SCharles.ForsythMoptres: adt { 19337da2899SCharles.Forsyth argv: list of string; 19437da2899SCharles.Forsyth flags: int; 19537da2899SCharles.Forsyth alg: string; 19637da2899SCharles.Forsyth keyfile: string; 19737da2899SCharles.Forsyth ignore: int; 19837da2899SCharles.Forsyth use9: int; 199*e5242bb5SRyabin Sergey doauth: int; 20037da2899SCharles.Forsyth}; 20137da2899SCharles.Forsyth 20237da2899SCharles.Forsythmopt(argv: list of string): (ref Moptres, string) 20337da2899SCharles.Forsyth{ 204*e5242bb5SRyabin Sergey r := ref Moptres(nil, 0, "none", nil, 0, 0, 1); 20537da2899SCharles.Forsyth 20637da2899SCharles.Forsyth arg->init(argv); 20737da2899SCharles.Forsyth while ((opt := arg->opt()) != 0) { 20837da2899SCharles.Forsyth case opt { 20937da2899SCharles.Forsyth 'i' => r.ignore = 1; 21037da2899SCharles.Forsyth 'a' => r.flags |= sys->MAFTER; 21137da2899SCharles.Forsyth 'b' => r.flags |= sys->MBEFORE; 21237da2899SCharles.Forsyth 'c' => r.flags |= sys->MCREATE; 21337da2899SCharles.Forsyth 'r' => r.flags |= sys->MREPL; 21437da2899SCharles.Forsyth 'k' => 21537da2899SCharles.Forsyth if((r.keyfile = arg->arg()) == nil) 21637da2899SCharles.Forsyth return (nil, "mount: missing arg to -k option"); 21737da2899SCharles.Forsyth 'C' => 21837da2899SCharles.Forsyth if((r.alg = arg->arg()) == nil) 21937da2899SCharles.Forsyth return (nil, "mount: missing arg to -C option"); 22037da2899SCharles.Forsyth '9' => 22137da2899SCharles.Forsyth r.use9 = 1; 222*e5242bb5SRyabin Sergey 'A' => 223*e5242bb5SRyabin Sergey r.doauth = 0; 22437da2899SCharles.Forsyth * => 22537da2899SCharles.Forsyth return (nil, sys->sprint("mount: bad option -%c", opt)); 22637da2899SCharles.Forsyth } 22737da2899SCharles.Forsyth } 22837da2899SCharles.Forsyth if((r.flags & (Sys->MAFTER|Sys->MBEFORE)) == 0) 22937da2899SCharles.Forsyth r.flags |= Sys->MREPL; 23037da2899SCharles.Forsyth 23137da2899SCharles.Forsyth r.argv = arg->argv(); 23237da2899SCharles.Forsyth return (r, nil); 23337da2899SCharles.Forsyth} 23437da2899SCharles.Forsyth 23537da2899SCharles.Forsythbind(argv: list of string): string 23637da2899SCharles.Forsyth{ 23737da2899SCharles.Forsyth (r, err) := mopt(argv); 23837da2899SCharles.Forsyth if(err != nil) 23937da2899SCharles.Forsyth return err; 24037da2899SCharles.Forsyth 24137da2899SCharles.Forsyth if(len r.argv < 2) 24237da2899SCharles.Forsyth return "bind: too few args"; 24337da2899SCharles.Forsyth 24437da2899SCharles.Forsyth from := hd r.argv; 24537da2899SCharles.Forsyth r.argv = tl r.argv; 24637da2899SCharles.Forsyth todir := hd r.argv; 24737da2899SCharles.Forsyth if(sys->bind(from, todir, r.flags) < 0) 24837da2899SCharles.Forsyth return ig(r, sys->sprint("bind %s %s: %r", from, todir)); 24937da2899SCharles.Forsyth 25037da2899SCharles.Forsyth return nil; 25137da2899SCharles.Forsyth} 25237da2899SCharles.Forsyth 25337da2899SCharles.Forsythmount(argv: list of string, facfd: ref Sys->FD): string 25437da2899SCharles.Forsyth{ 25537da2899SCharles.Forsyth fd: ref Sys->FD; 25637da2899SCharles.Forsyth 25737da2899SCharles.Forsyth (r, err) := mopt(argv); 25837da2899SCharles.Forsyth if(err != nil) 25937da2899SCharles.Forsyth return err; 26037da2899SCharles.Forsyth 26137da2899SCharles.Forsyth if(len r.argv < 2) 26237da2899SCharles.Forsyth return ig(r, "mount: too few args"); 26337da2899SCharles.Forsyth 264fbc1184cSCharles Forsyth if(dial == nil){ 265fbc1184cSCharles Forsyth dial = load Dial Dial->PATH; 266fbc1184cSCharles Forsyth if(dial == nil) 267fbc1184cSCharles Forsyth return ig(r, "mount: can't load Dial"); 268fbc1184cSCharles Forsyth } 269fbc1184cSCharles Forsyth 27037da2899SCharles.Forsyth addr := hd r.argv; 27137da2899SCharles.Forsyth r.argv = tl r.argv; 272fbc1184cSCharles Forsyth dest := dial->netmkaddr(addr, "net", "styx"); 27337da2899SCharles.Forsyth dir := hd r.argv; 27437da2899SCharles.Forsyth r.argv = tl r.argv; 27537da2899SCharles.Forsyth if(r.argv != nil) 27637da2899SCharles.Forsyth spec := hd r.argv; 27737da2899SCharles.Forsyth 278fbc1184cSCharles Forsyth c := dial->dial(dest, nil); 279fbc1184cSCharles Forsyth if(c == nil) 28037da2899SCharles.Forsyth return ig(r, sys->sprint("dial: %s: %r", dest)); 28137da2899SCharles.Forsyth 282*e5242bb5SRyabin Sergey if(r.doauth != 1){ 283*e5242bb5SRyabin Sergey if(sys->mount(c.dfd, nil, dir, r.flags, spec) < 0) 284*e5242bb5SRyabin Sergey return ig(r, sys->sprint("mount %q %q: %r", addr, dir)); 285*e5242bb5SRyabin Sergey return nil; 286*e5242bb5SRyabin Sergey } 287*e5242bb5SRyabin Sergey 28837da2899SCharles.Forsyth if(r.use9){ 28937da2899SCharles.Forsyth factotum := load Factotum Factotum->PATH; 29037da2899SCharles.Forsyth if(factotum == nil) 29137da2899SCharles.Forsyth return ig(r, sys->sprint("cannot load %s: %r", Factotum->PATH)); 29237da2899SCharles.Forsyth factotum->init(); 29337da2899SCharles.Forsyth afd := sys->fauth(fd, spec); 294e84ac692SCharles.Forsyth if(afd != nil) 295e84ac692SCharles.Forsyth factotum->proxy(afd, facfd, "proto=p9any role=client"); # ignore result; if it fails, mount will fail 29637da2899SCharles.Forsyth if(sys->mount(fd, afd, dir, r.flags, spec) < 0) 29737da2899SCharles.Forsyth return ig(r, sys->sprint("mount %q %q: %r", addr, dir)); 29837da2899SCharles.Forsyth return nil; 29937da2899SCharles.Forsyth } 30037da2899SCharles.Forsyth 30137da2899SCharles.Forsyth user := user(); 30237da2899SCharles.Forsyth kd := "/usr/" + user + "/keyring/"; 30337da2899SCharles.Forsyth cert: string; 30437da2899SCharles.Forsyth if (r.keyfile != nil) { 30537da2899SCharles.Forsyth cert = r.keyfile; 30637da2899SCharles.Forsyth if (cert[0] != '/') 30737da2899SCharles.Forsyth cert = kd + cert; 308fbc1184cSCharles Forsyth if(sys->stat(cert).t0 < 0) 30937da2899SCharles.Forsyth return ig(r, sys->sprint("cannot find certificate %q: %r", cert)); 31037da2899SCharles.Forsyth } else { 31137da2899SCharles.Forsyth cert = kd + addr; 312fbc1184cSCharles Forsyth if(sys->stat(cert).t0 < 0) 31337da2899SCharles.Forsyth cert = kd + "default"; 31437da2899SCharles.Forsyth } 31537da2899SCharles.Forsyth ai := kr->readauthinfo(cert); 31637da2899SCharles.Forsyth if(ai == nil) 31737da2899SCharles.Forsyth return ig(r, sys->sprint("cannot read certificate from %q: %r", cert)); 31837da2899SCharles.Forsyth 31937da2899SCharles.Forsyth err = au->init(); 32037da2899SCharles.Forsyth if (err != nil) 32137da2899SCharles.Forsyth return ig(r, sys->sprint("auth->init: %r")); 32237da2899SCharles.Forsyth (fd, err) = au->client(r.alg, ai, c.dfd); 32337da2899SCharles.Forsyth if(fd == nil) 32437da2899SCharles.Forsyth return ig(r, sys->sprint("auth: %r")); 32537da2899SCharles.Forsyth 32637da2899SCharles.Forsyth if(sys->mount(fd, nil, dir, r.flags, spec) < 0) 32737da2899SCharles.Forsyth return ig(r, sys->sprint("mount %q %q: %r", addr, dir)); 32837da2899SCharles.Forsyth 32937da2899SCharles.Forsyth return nil; 33037da2899SCharles.Forsyth} 33137da2899SCharles.Forsyth 33237da2899SCharles.Forsythimport9(argv: list of string, facfd: ref Sys->FD): string 33337da2899SCharles.Forsyth{ 33437da2899SCharles.Forsyth (r, err) := mopt(argv); 33537da2899SCharles.Forsyth if(err != nil) 33637da2899SCharles.Forsyth return err; 33737da2899SCharles.Forsyth 33837da2899SCharles.Forsyth if(len r.argv < 2) 33937da2899SCharles.Forsyth return "import: too few args"; 34037da2899SCharles.Forsyth if(facfd == nil) 34137da2899SCharles.Forsyth return ig(r, "import: no factotum"); 34237da2899SCharles.Forsyth factotum := load Factotum Factotum->PATH; 34337da2899SCharles.Forsyth if(factotum == nil) 34437da2899SCharles.Forsyth return ig(r, sys->sprint("cannot load %s: %r", Factotum->PATH)); 34537da2899SCharles.Forsyth factotum->init(); 34637da2899SCharles.Forsyth addr := hd r.argv; 34737da2899SCharles.Forsyth r.argv = tl r.argv; 34837da2899SCharles.Forsyth rdir := hd r.argv; 34937da2899SCharles.Forsyth r.argv = tl r.argv; 35037da2899SCharles.Forsyth dir := rdir; 35137da2899SCharles.Forsyth if(r.argv != nil) 35237da2899SCharles.Forsyth dir = hd r.argv; 353fbc1184cSCharles Forsyth 354fbc1184cSCharles Forsyth if(dial == nil){ 355fbc1184cSCharles Forsyth dial = load Dial Dial->PATH; 356fbc1184cSCharles Forsyth if(dial == nil) 357fbc1184cSCharles Forsyth return ig(r, "import: can't load Dial"); 358fbc1184cSCharles Forsyth } 359fbc1184cSCharles Forsyth 360fbc1184cSCharles Forsyth dest := dial->netmkaddr(addr, "net", "17007"); # exportfs; might not be in inferno's ndb yet 361fbc1184cSCharles Forsyth c := dial->dial(dest, nil); 362fbc1184cSCharles Forsyth if(c == nil) 36337da2899SCharles.Forsyth return ig(r, sys->sprint("import: %s: %r", dest)); 36437da2899SCharles.Forsyth fd := c.dfd; 36537da2899SCharles.Forsyth if(factotum->proxy(fd, facfd, "proto=p9any role=client") == nil) 36637da2899SCharles.Forsyth return ig(r, sys->sprint("import: %s: %r", dest)); 36737da2899SCharles.Forsyth if(sys->fprint(fd, "%s", rdir) < 0) 36837da2899SCharles.Forsyth return ig(r, sys->sprint("import: %s: %r", dest)); 36937da2899SCharles.Forsyth buf := array[256] of byte; 37037da2899SCharles.Forsyth if((n := sys->read(fd, buf, len buf)) != 2 || buf[0] != byte 'O' || buf[1] != byte 'K'){ 37137da2899SCharles.Forsyth if(n >= 4) 37237da2899SCharles.Forsyth sys->werrstr(string buf[0:n]); 37337da2899SCharles.Forsyth return ig(r, sys->sprint("import: %s: %r", dest)); 37437da2899SCharles.Forsyth } 37537da2899SCharles.Forsyth # TO DO: new style: impo aan|nofilter clear|ssl|tls\n 37637da2899SCharles.Forsyth afd := sys->fauth(fd, ""); 377e84ac692SCharles.Forsyth if(afd != nil) 378e84ac692SCharles.Forsyth factotum->proxy(afd, facfd, "proto=p9any role=client"); 37937da2899SCharles.Forsyth if(sys->mount(fd, afd, dir, r.flags, "") < 0) 38037da2899SCharles.Forsyth return ig(r, sys->sprint("import %q %q: %r", addr, dir)); 38137da2899SCharles.Forsyth return nil; 38237da2899SCharles.Forsyth} 38337da2899SCharles.Forsyth 38437da2899SCharles.Forsythunmount(argv: list of string): string 38537da2899SCharles.Forsyth{ 38637da2899SCharles.Forsyth (r, err) := mopt(argv); 38737da2899SCharles.Forsyth if(err != nil) 38837da2899SCharles.Forsyth return err; 38937da2899SCharles.Forsyth 39037da2899SCharles.Forsyth from, tu: string; 39137da2899SCharles.Forsyth case len r.argv { 39237da2899SCharles.Forsyth * => 39337da2899SCharles.Forsyth return "unmount: takes 1 or 2 args"; 39437da2899SCharles.Forsyth 1 => 39537da2899SCharles.Forsyth from = nil; 39637da2899SCharles.Forsyth tu = hd r.argv; 39737da2899SCharles.Forsyth 2 => 39837da2899SCharles.Forsyth from = hd r.argv; 39937da2899SCharles.Forsyth tu = hd tl r.argv; 40037da2899SCharles.Forsyth } 40137da2899SCharles.Forsyth 40237da2899SCharles.Forsyth if(sys->unmount(from, tu) < 0) 40337da2899SCharles.Forsyth return ig(r, sys->sprint("unmount: %r")); 40437da2899SCharles.Forsyth 40537da2899SCharles.Forsyth return nil; 40637da2899SCharles.Forsyth} 40737da2899SCharles.Forsyth 40837da2899SCharles.Forsythig(r: ref Moptres, e: string): string 40937da2899SCharles.Forsyth{ 41037da2899SCharles.Forsyth if(r.ignore) 41137da2899SCharles.Forsyth return nil; 41237da2899SCharles.Forsyth return e; 41337da2899SCharles.Forsyth} 41437da2899SCharles.Forsyth 41537da2899SCharles.Forsythuser(): string 41637da2899SCharles.Forsyth{ 41737da2899SCharles.Forsyth sys = load Sys Sys->PATH; 41837da2899SCharles.Forsyth 41937da2899SCharles.Forsyth fd := sys->open("/dev/user", sys->OREAD); 42037da2899SCharles.Forsyth if(fd == nil) 42137da2899SCharles.Forsyth return ""; 42237da2899SCharles.Forsyth 42337da2899SCharles.Forsyth buf := array[Sys->NAMEMAX] of byte; 42437da2899SCharles.Forsyth n := sys->read(fd, buf, len buf); 42537da2899SCharles.Forsyth if(n < 0) 42637da2899SCharles.Forsyth return ""; 42737da2899SCharles.Forsyth 42837da2899SCharles.Forsyth return string buf[0:n]; 42937da2899SCharles.Forsyth} 43037da2899SCharles.Forsyth 43137da2899SCharles.Forsythgetenv(name: string): (int, string) 43237da2899SCharles.Forsyth{ 43337da2899SCharles.Forsyth fd := sys->open("#e/"+name, Sys->OREAD); 43437da2899SCharles.Forsyth if(fd == nil) 43537da2899SCharles.Forsyth return (0, nil); 43637da2899SCharles.Forsyth b := array[256] of byte; 43737da2899SCharles.Forsyth n := sys->read(fd, b, len b); 43837da2899SCharles.Forsyth if(n <= 0) 43937da2899SCharles.Forsyth return (1, ""); 44037da2899SCharles.Forsyth for(i := 0; i < n; i++) 44137da2899SCharles.Forsyth if(b[i] == byte 0 || b[i] == byte '\n') 44237da2899SCharles.Forsyth break; 44337da2899SCharles.Forsyth return (1, string b[0:i]); 44437da2899SCharles.Forsyth} 44537da2899SCharles.Forsyth 44637da2899SCharles.Forsythsetenv(name: string, val: string) 44737da2899SCharles.Forsyth{ 44837da2899SCharles.Forsyth fd := sys->create("#e/"+name, Sys->OWRITE, 8r664); 44937da2899SCharles.Forsyth if(fd != nil) 45037da2899SCharles.Forsyth sys->fprint(fd, "%s", val); 45137da2899SCharles.Forsyth} 45237da2899SCharles.Forsyth 453e84ac692SCharles.Forsythnewuser(user: string, cap: string, nsfile: string): string 454e84ac692SCharles.Forsyth{ 455e84ac692SCharles.Forsyth if(cap == nil) 456e84ac692SCharles.Forsyth return "no capability"; 457e84ac692SCharles.Forsyth 458e84ac692SCharles.Forsyth sys = load Sys Sys->PATH; 459e84ac692SCharles.Forsyth fd := sys->open("#¤/capuse", Sys->OWRITE); 460e84ac692SCharles.Forsyth if(fd == nil) 461e84ac692SCharles.Forsyth return sys->sprint("opening #¤/capuse: %r"); 462e84ac692SCharles.Forsyth 463e84ac692SCharles.Forsyth b := array of byte cap; 464e84ac692SCharles.Forsyth if(sys->write(fd, b, len b) < 0) 465e84ac692SCharles.Forsyth return sys->sprint("writing %s to #¤/capuse: %r", cap); 466e84ac692SCharles.Forsyth 467e84ac692SCharles.Forsyth # mount factotum as new user (probably unhelpful if not factotum owner) 468e84ac692SCharles.Forsyth sys->unmount(nil, "/mnt/factotum"); 469e84ac692SCharles.Forsyth sys->bind("#sfactotum", "/mnt/factotum", Sys->MREPL); 470e84ac692SCharles.Forsyth 471e84ac692SCharles.Forsyth return newns(user, nsfile); 472e84ac692SCharles.Forsyth} 473