1implement CPU; 2 3include "sys.m"; 4 sys: Sys; 5 stderr: ref Sys->FD; 6include "draw.m"; 7include "string.m"; 8 str: String; 9include "arg.m"; 10include "keyring.m"; 11include "security.m"; 12include "dial.m"; 13 14DEFCMD: con "/dis/sh"; 15 16CPU: module 17{ 18 init: fn(ctxt: ref Draw->Context, argv: list of string); 19}; 20 21badmodule(p: string) 22{ 23 sys->fprint(stderr, "cpu: cannot load %s: %r\n", p); 24 raise "fail:bad module"; 25} 26 27usage() 28{ 29 sys->fprint(stderr, "Usage: cpu [-C cryptoalg] mach command args...\n"); 30 raise "fail:usage"; 31} 32 33# The default level of security is NOSSL, unless 34# the keyring directory doesn't exist, in which case 35# it's disallowed. 36init(nil: ref Draw->Context, argv: list of string) 37{ 38 sys = load Sys Sys->PATH; 39 stderr = sys->fildes(2); 40 41 arg := load Arg Arg->PATH; 42 if (arg == nil) badmodule(Arg->PATH); 43 44 str = load String String->PATH; 45 if (str == nil) badmodule(String->PATH); 46 47 au := load Auth Auth->PATH; 48 if (au == nil) badmodule(Auth->PATH); 49 50 kr := load Keyring Keyring->PATH; 51 if (kr == nil) badmodule(Keyring->PATH); 52 53 dial := load Dial Dial->PATH; 54 55 arg->init(argv); 56 alg := ""; 57 while ((opt := arg->opt()) != 0) { 58 if (opt == 'C') { 59 alg = arg->arg(); 60 } else 61 usage(); 62 } 63 argv = arg->argv(); 64 args := "auxi/cpuslave"; 65# if(ctxt != nil && ctxt.screen != nil) 66# args += " -s" + string ctxt.screen.id; 67# else 68 args += " --"; 69 70 mach: string; 71 case len argv { 72 0 => 73 usage(); 74 1 => 75 mach = hd argv; 76 args += " " + DEFCMD; 77 * => 78 mach = hd argv; 79 args += " " + str->quoted(tl argv); 80 } 81 82 user := getuser(); 83 kd := "/usr/" + user + "/keyring/"; 84 cert := kd + dial->netmkaddr(mach, "tcp", ""); 85 if (!exists(cert)) { 86 cert = kd + "default"; 87 if (!exists(cert)) { 88 sys->fprint(stderr, "cpu: cannot find certificate in %s; use getauthinfo\n", kd); 89 raise "fail:no certificate"; 90 } 91 } 92 93 c := dial->dial(dial->netmkaddr(mach, "net", "rstyx"), nil); 94 if(c == nil){ 95 sys->fprint(stderr, "cpu: can't dial %s: %r\n", mach); 96 raise "fail:dial"; 97 } 98 99 ai := kr->readauthinfo(cert); 100 101 if (alg == nil) 102 alg = "none"; 103 err := au->init(); 104 if(err != nil) { 105 sys->fprint(stderr, "cpu: cannot initialise auth module: %s\n", err); 106 raise "fail:auth init failed"; 107 } 108 109 fd := ref Sys->FD; 110 #sys->fprint(stderr, "cpu: authenticating using alg '%s'\n", alg); 111 (fd, err) = au->client(alg, ai, c.dfd); 112 if(fd == nil) { 113 sys->fprint(stderr, "cpu: authentication failed: %s\n", err); 114 raise "fail:authentication failure"; 115 } 116 117 t := array of byte sys->sprint("%d\n%s\n", len (array of byte args)+1, args); 118 if(sys->write(fd, t, len t) != len t){ 119 sys->fprint(stderr, "cpu: export args write error: %r\n"); 120 raise "fail:write error"; 121 } 122 123 if(sys->export(fd, "/", sys->EXPWAIT) < 0){ 124 sys->fprint(stderr, "cpu: export failed: %r\n"); 125 raise "fail:export error"; 126 } 127} 128 129exists(file: string): int 130{ 131 (ok, nil) := sys->stat(file); 132 return ok != -1; 133} 134 135getuser(): string 136{ 137 fd := sys->open("/dev/user", sys->OREAD); 138 if(fd == nil){ 139 sys->fprint(stderr, "cpu: cannot open /dev/user: %r\n"); 140 raise "fail:no user id"; 141 } 142 143 buf := array[50] of byte; 144 n := sys->read(fd, buf, len buf); 145 if(n < 0){ 146 sys->fprint(stderr, "cpu: cannot read /dev/user: %r\n"); 147 raise "fail:no user id"; 148 } 149 150 return string buf[0:n]; 151} 152