forsyth20121205-174063a80cc13 years agoHistory
170 lines · 3.2 KB · Brainfuck
RawDownload
implement Rcmd; include "sys.m";include "draw.m";include "arg.m";include "keyring.m";include "security.m"; Rcmd: module{	init:	fn(ctxt: ref Draw->Context, argv: list of string);}; DEFAULTALG := "none";sys: Sys;auth: Auth; init(nil: ref Draw->Context, argv: list of string){	sys = load Sys Sys->PATH;	arg := load Arg Arg->PATH;	if(arg == nil)		badmodule(Arg->PATH);	arg->init(argv);	alg: string;	doauth := 1;	exportpath := "/";	keyfile: string;	arg->setusage("rcmd [-A] [-f keyfile] [-a alg] [-e exportpath] tcp!mach cmd");	while((o := arg->opt()) != 0)		case o {		'a' =>			alg = arg->earg();		'A' =>			doauth = 0;		'e' =>			exportpath = arg->earg();			(n, nil) := sys->stat(exportpath);			if (n == -1 || exportpath == nil)				arg->usage();		'f' =>			keyfile = arg->earg();			if (! (keyfile[0] == '/' || (len keyfile > 2 &&  keyfile[0:2] == "./")))				keyfile = "/usr/" + user() + "/keyring/" + keyfile;		*   =>			arg->usage();		} 	argv = arg->argv();	if(argv == nil)		arg->usage();	arg = nil; 	if (doauth && alg == nil)		alg = DEFAULTALG; 	addr := hd argv;	argv = tl argv; 	args := "";	while(argv != nil){		args += " " + hd argv;		argv = tl argv;	}	if(args == "")		args = "sh"; 	kr: Keyring;	au: Auth;	if (doauth) {		kr = load Keyring Keyring->PATH;		if(kr == nil)			badmodule(Keyring->PATH);		au = load Auth Auth->PATH;		if(au == nil)			badmodule(Auth->PATH);		if (keyfile == nil)			keyfile = "/usr/" + user() + "/keyring/default";	} 	(ok, c) := sys->dial(netmkaddr(addr, "tcp", "rstyx"), nil);	if(ok < 0)		error(sys->sprint("dial server failed: %r")); 	fd := c.dfd;	if (doauth) {		ai := kr->readauthinfo(keyfile);		#		# let auth->client handle nil ai		# if(ai == nil){		#	sys->fprint(stderr(), "rcmd: certificate for %s not found\n", addr);		#	raise "fail:no certificate";		# }		# 		err := au->init();		if(err != nil)			error(err); 		(fd, err) = au->client(alg, ai, c.dfd);		if(fd == nil){			sys->fprint(stderr(), "rcmd: authentication failed: %s\n", err);			raise "fail:auth failed";		}	}	t := array of byte sys->sprint("%d\n%s\n", len (array of byte args)+1, args);	if(sys->write(fd, t, len t) != len t){		sys->fprint(stderr(), "rcmd: cannot write arguments: %r\n");		raise "fail:bad arg write";	} 	if(sys->export(fd, exportpath, sys->EXPWAIT) < 0) {		sys->fprint(stderr(), "rcmd: export: %r\n");		raise "fail:export failed";	}} exists(f: string): int{	(ok, nil) := sys->stat(f);	return ok >= 0;} user(): string{	sys = load Sys Sys->PATH; 	fd := sys->open("/dev/user", sys->OREAD);	if(fd == nil)		return ""; 	buf := array[128] of byte;	n := sys->read(fd, buf, len buf);	if(n < 0)		return ""; 	return string buf[0:n];	} netmkaddr(addr, net, svc: string): string{	if(net == nil)		net = "net";	(n, nil) := sys->tokenize(addr, "!");	if(n <= 1){		if(svc== nil)			return sys->sprint("%s!%s", net, addr);		return sys->sprint("%s!%s!%s", net, addr, svc);	}	if(svc == nil || n > 2)		return addr;	return sys->sprint("%s!%s", addr, svc);} stderr(): ref Sys->FD{	return sys->fildes(2);} badmodule(p: string){	sys->fprint(stderr(), "rcmd: cannot load %s: %r\n", p);	raise "fail:bad module";} error(e: string){	sys->fprint(stderr(), "rcmd: %s\n", e);	raise "fail:errors";}