code: purgatorio

ref: d0ab3a0dd8f6355b3603d0fb04043a9ae867639b
dir: /appl/cmd/auxi/rstyxd.b/

View raw version
implement Rstyxd;

include "sys.m";
include "draw.m";
include "sh.m";
include "string.m";

sys: Sys;
str: String;
stderr: ref Sys->FD;

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, nil: list of string)
{
	sys = load Sys Sys->PATH;
	str = load String String->PATH;
	if (str == nil)
		badmod(String->PATH);

	fd := sys->fildes(0);
	stderr = sys->fildes(2);
	sys->pctl(sys->FORKFD, fd.fd :: nil);

	args := readargs(fd);
	if(args == nil)
		err(sys->sprint("error reading arguments: %r"));

	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;
	file: string;
	if(cmd == "sh")
		file = "/dis/sh.dis";
	else
		file = cmd + ".dis";
	mod := load Command file;
	if(mod == nil){
		mod = load Command "/dis/"+file;
		if(mod == nil)
			badmod("/dis/"+file);
	}

	sys->pctl(Sys->FORKNS|Sys->FORKENV, nil);

	if(sys->mount(fd, nil, "/n/client", Sys->MREPL, "") < 0)
		err(sys->sprint("cannot mount connection on /n/client: %r"));

	if(sys->bind("/n/client/dev", "/dev", Sys->MBEFORE) < 0)
		err(sys->sprint("cannot bind /n/client/dev to /dev: %r"));

	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);
}

readargs(fd: ref Sys->FD): list of string
{
	buf := array[1024] 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
{
	buf:= array[nb] of byte;
	if(sys->readn(fd, buf, nb) != nb)
		return nil;
	return buf;
}


err(s: string)
{
	sys->fprint(stderr, "rstyxd: %s\n", s);
	raise "fail:error";
}

badmod(s: string)
{
	sys->fprint(stderr, "rstyxd: can't load %s: %r\n", s);
	raise "fail:load";
}