ref: d1540c7f666e3c5d636b48c956b444205b50502d
parent: 2459e34d77e2e21ef829c0dfaafd99433899494f
author: henesy <devnull@localhost>
date: Fri Aug 2 14:58:41 EDT 2019
add whoami(1) - no man - might remove ;; add newns(8) - no man yet
--- a/appl/cmd/auth/mkfile
+++ b/appl/cmd/auth/mkfile
@@ -16,6 +16,7 @@
getpk.dis\
logind.dis\
mkauthinfo.dis\
+ newns.dis\
passwd.dis\
rsagen.dis\
secstore.dis\
--- /dev/null
+++ b/appl/cmd/auth/newns.b
@@ -1,0 +1,187 @@
+implement NewNamespace;
+
+# This is a programized version of newns(2) in the style of 9front's newns(8)
+# You may need to call this doing something like
+# ; newns -d -n ./namespace `{whatis pwd}
+
+include "sys.m";
+ sys: Sys;
+ FD: import sys;
+include "draw.m";
+include "arg.m";
+include "newns.m";
+include "sh.m";
+include "string.m";
+
+NewNamespace: module {
+ init: fn(ctx: ref Draw->Context, argv: list of string);
+};
+
+debug: int;
+
+init(ctx: ref Draw->Context, argv: list of string) {
+ sys = load Sys Sys->PATH;
+ fprint, fildes: import sys;
+ arg := load Arg Arg->PATH;
+ if(arg == nil)
+ raise "Could not load " + Arg->PATH;
+ ns := load Newns Newns->PATH;
+ if(ns == nil)
+ raise "Could not load " + Newns->PATH;
+
+ forkns := 1;
+ debug = 0;
+ nsf := "";
+ user := readfile("/dev/user");
+
+ arg->init(argv);
+ arg->setusage("newns [-ad] [-n namespace] [-u user] command arg⋯");
+
+ while((o := arg->opt()) != 0)
+ case o {
+ 'a' => forkns = 0; # Affect the current process namespace
+ 'd' => debug = 1;
+ 'n' => nsf = arg->earg();
+ 'u' => user = arg->earg();
+ * => arg->usage();
+ }
+
+ argv = arg->argv();
+ argc := len argv;
+
+ if(argc <= 0)
+ arg->usage();
+
+ cmd := hd argv;
+
+ if(debug) {
+ fprint(fildes(2), "Argc = %d\nCmd = %s\n", argc, cmd);
+ fprint(fildes(2), "Args:\n");
+ for(a := argv; a != nil; a = tl a)
+ fprint(fildes(2), "\t%s\n", hd a);
+ }
+
+ if(forkns)
+ sys->pctl(sys->FORKNS, nil);
+
+ if(nsf != nil) {
+ err := ns->newns(user, nsf);
+ if(err != nil)
+ raise "err: newns(2) failed " + err;
+ }
+
+ cmd = lookup(cmd);
+
+ c := load Command cmd;
+ if(c == nil)
+ raise sys->sprint("err: could not load program %s %r", cmd);
+
+ spawn c->init(ctx, argv);
+}
+
+# Try to do a $path-style lookup for a shorthand command
+# You're supposed to use sh.m, but that's a lot of infra
+# $path = (/dis .)
+lookup(cmd: string): string {
+ # We can probably trust paths already possessing a leading /
+ if(cmd[0] == '/')
+ return cmd;
+
+ # Trust a ./
+ if(len cmd > 1) {
+ pref := cmd[:2];
+ if(pref == "./")
+ return cmd;
+ }
+
+ sprint, OREAD: import sys;
+
+ c := sprint("/dis/%s", cmd);
+ if(tryopen(c))
+ return c;
+
+ c = sprint("./%s", cmd);
+ if(tryopen(c))
+ return c;
+
+ # Try the same logic, but after appending .dis in case it was forgotten
+ if(! contains(cmd, ".dis"))
+ cmd = sprint("%s.dis", cmd);
+ else
+ return cmd; # Give up
+
+ c = sprint("/dis/%s", cmd);
+ if(tryopen(c))
+ return c;
+
+ c = sprint("./%s", cmd);
+ if(tryopen(c))
+ return c;
+
+ return cmd;
+}
+
+# Try to open helper for lookup()
+tryopen(c: string): int {
+ if(debug)
+ sys->fprint(sys->fildes(2), "Trying: %s\n", c);
+
+ fd := sys->open(c, sys->OREAD);
+ if(fd != nil) {
+ # Make sure it's not a directory - can't exec those ☺
+ (err, dir) := sys->fstat(fd);
+ if(err >= 0)
+ if(! (dir.mode & Sys->DMDIR))
+ return 1;
+ # Maybe handle error?
+ }
+
+ return 0;
+}
+
+# Reads a (small) file into a string
+readfile(f: string): string {
+ fd := sys->open(f, sys->OREAD);
+ if(fd == nil)
+ return nil;
+
+ buf := array[8192] of byte;
+ n := sys->read(fd, buf, len buf);
+ if(n < 0)
+ return nil;
+
+ return string buf[0:n];
+}
+
+# Check whether a string s₀ contains another string s₁
+contains(s₀, s₁: string ): int {
+ s₀len := len s₀;
+ s₁len := len s₁;
+
+ if(s₁ == s₀)
+ return 1;
+
+ if(s₁len - s₀len < 0)
+ return 0;
+
+ # fooduckbar contains duck
+ # dlen = 4
+ # flen = 10
+ # x₀ = 0
+ # x₁ = 4
+ # f[x₀:x₁]
+ x₀ := 0;
+ x₁ := s₁len;
+
+ while(x₁ <= s₀len) {
+ s := s₀[x₀:x₁];
+ if(s == s₁)
+ return 1;
+
+ x₀++;
+ x₁++;
+ }
+
+ return 0;
+}
+
--- a/appl/cmd/mkfile
+++ b/appl/cmd/mkfile
@@ -172,6 +172,7 @@
wav2iaf.dis\
wc.dis\
webgrab.dis\
+ whoami.dis\
whois.dis\
wish.dis\
wmexport.dis\
--- /dev/null
+++ b/appl/cmd/whoami.b
@@ -1,0 +1,35 @@
+implement Whoami;
+
+# Who are you?
+
+include "sys.m";
+ sys: Sys;
+
+include "draw.m";
+
+Whoami: module {
+ init: fn(nil: ref Draw->Context, nil: list of string);
+};
+
+init(nil: ref Draw->Context, nil: list of string) {
+ sys = load Sys Sys->PATH;
+
+ sys->print("%s\n", readfile("/dev/user"));
+
+ exit;
+}
+
+# Reads a (small) file into a string
+readfile(f: string): string {
+ fd := sys->open(f, sys->OREAD);
+ if(fd == nil)
+ return nil;
+
+ buf := array[8192] of byte;
+ n := sys->read(fd, buf, len buf);
+ if(n < 0)
+ return nil;
+
+ return string buf[0:n];
+}
+