implement Rstyxd; include "sys.m"; sys: Sys; stdin, stderr: ref Sys->FD; include "draw.m"; include "keyring.m"; include "security.m"; kr: Keyring; auth: Auth; include "sh.m"; sh: Command; include "string.m"; str: String; Rstyxd: module { init: fn(ctxt: ref Draw->Context, argv: list of string); }; # # argv is a list of Inferno supported algorithms from Security->Auth # init(nil: ref Draw->Context, argv: list of string) { sys = load Sys Sys->PATH; stdin = sys->fildes(0); stderr = sys->open("/dev/cons", sys->OWRITE); auth = load Auth Auth->PATH; if(auth == nil){ sys->fprint(stderr, "rstyxd: cannot load %s: %r\n", Auth->PATH); sys->raise("fail:bad module"); } str = load String String->PATH; if (str == nil) { sys->fprint(stderr, "rstyxd: cannot load %s: %r\n", String->PATH); sys->raise("fail:bad module"); } err := auth->init(); if(err != nil){ sys->fprint(stderr, "rstyxd: authinit failed: %s\n", err); sys->raise("fail:auth init failed"); } sh = load Command "/dis/sh.dis"; if(sh == nil){ sys->fprint(stderr, "rstyxd: can't load module sh: %r\n"); exit; } user := getuser(); kr = load Keyring Keyring->PATH; ai := kr->readauthinfo("/usr/"+user+"/keyring/default"); fd: ref Sys->FD; (fd, err) = auth->server(argv, ai, stdin, 1); if(fd == nil){ sys->fprint(stderr, "rstyxd: auth server failed: %s\n", err); sys->raise("fail:auth server failed"); } dorstyx(fd); } dorstyx(fd: ref Sys->FD) { sys->pctl(sys->FORKFD, fd.fd :: nil); args := readargs(fd); if(args == nil){ sys->fprint(stderr, "rstyxd: read args: %r\n"); exit; } cmd := hd args; s := ""; for (a := args; a != nil; a = tl a) s += hd a + " "; sys->fprint(stderr, "rstyxd: cmd: %s\n", s); s = nil; mod: Command; if(cmd == "sh") mod = sh; else{ file := cmd + ".dis"; mod = load Command file; if(mod == nil) mod = load Command "/dis/"+file; if(mod == nil) { sys->fprint(stderr, "rstyxd: can't load %s: %r\n", cmd); exit; } } sys->pctl(sys->FORKNS, nil); if(sys->mount(fd, "/n/client", sys->MREPL, "") < 0) { sys->fprint(stderr, "rstyxd: cannot mount: %r\n"); sys->raise("fail:mount failed"); } if(sys->bind("/n/client/dev", "/dev", sys->MBEFORE) < 0) { sys->fprint(stderr, "rstyxd: cannot bind client: %r\n"); sys->raise("fail:bind failed"); } fd = sys->open("/dev/cons", sys->OREAD); sys->dup(fd.fd, 0); fd = sys->open("/dev/cons", sys->OWRITE); sys->dup(fd.fd, 1); sys->dup(fd.fd, 2); fd = nil; mod->init(nil, args); exit; } readargs(fd: ref Sys->FD): list of string { buf := array[15] of byte; c := array[1] of byte; for(i:=0; ; i++){ if(i>=len buf || sys->read(fd, c, 1)!=1) return nil; buf[i] = c[0]; if(c[0] == byte '\n') break; } nb := int string buf[0:i]; if(nb <= 0) return nil; args := readn(fd, nb); if (args == nil) return nil; return str->unquoted(string args[0:nb]); } readn(fd: ref Sys->FD, nb: int): array of byte { m: int; buf:= array[nb] of byte; b1:= array[nb] of byte; for(n:=0; nread(fd, b1, nb-n); if(m <= 0) return nil; for(j:=0; jopen("/dev/user", sys->OREAD); if(fd == nil){ sys->fprint(stderr, "styxd: cannot open /dev/user: %r\n"); sys->raise("fail:no user id"); } buf := array[50] of byte; n := sys->read(fd, buf, len buf); if(n < 0){ sys->fprint(stderr, "styxd: cannot read /dev/user: %r\n"); sys->raise("fail:no user id"); } return string buf[0:n]; }