xref: /inferno-os/appl/cmd/rcmd.b (revision fbc1184c08d18d5ac0f8763a058e015e95353341)
137da2899SCharles.Forsythimplement Rcmd;
237da2899SCharles.Forsyth
337da2899SCharles.Forsythinclude "sys.m";
437da2899SCharles.Forsythinclude "draw.m";
537da2899SCharles.Forsythinclude "arg.m";
637da2899SCharles.Forsythinclude "keyring.m";
7*fbc1184cSCharles Forsythinclude "dial.m";
837da2899SCharles.Forsythinclude "security.m";
937da2899SCharles.Forsyth
1037da2899SCharles.ForsythRcmd: module
1137da2899SCharles.Forsyth{
1237da2899SCharles.Forsyth	init:	fn(ctxt: ref Draw->Context, argv: list of string);
1337da2899SCharles.Forsyth};
1437da2899SCharles.Forsyth
1537da2899SCharles.ForsythDEFAULTALG := "none";
1637da2899SCharles.Forsythsys: Sys;
1737da2899SCharles.Forsythauth: Auth;
18*fbc1184cSCharles Forsythdial: Dial;
1937da2899SCharles.Forsyth
2037da2899SCharles.Forsythinit(nil: ref Draw->Context, argv: list of string)
2137da2899SCharles.Forsyth{
2237da2899SCharles.Forsyth	sys = load Sys Sys->PATH;
23*fbc1184cSCharles Forsyth	dial = load Dial Dial->PATH;
24*fbc1184cSCharles Forsyth	if(dial == nil)
25*fbc1184cSCharles Forsyth		badmodule(Dial->PATH);
2637da2899SCharles.Forsyth	arg := load Arg Arg->PATH;
2737da2899SCharles.Forsyth	if(arg == nil)
2837da2899SCharles.Forsyth		badmodule(Arg->PATH);
2937da2899SCharles.Forsyth	arg->init(argv);
3037da2899SCharles.Forsyth	alg: string;
3137da2899SCharles.Forsyth	doauth := 1;
3237da2899SCharles.Forsyth	exportpath := "/";
3337da2899SCharles.Forsyth	keyfile: string;
34e2311792SCharles Forsyth	arg->setusage("rcmd [-A] [-f keyfile] [-e alg] [-x exportpath] tcp!mach cmd");
3537da2899SCharles.Forsyth	while((o := arg->opt()) != 0)
3637da2899SCharles.Forsyth		case o {
37e2311792SCharles Forsyth		'e' or 'a' =>
3837da2899SCharles.Forsyth			alg = arg->earg();
3937da2899SCharles.Forsyth		'A' =>
4037da2899SCharles.Forsyth			doauth = 0;
41e2311792SCharles Forsyth		'x' =>
4237da2899SCharles.Forsyth			exportpath = arg->earg();
4337da2899SCharles.Forsyth			(n, nil) := sys->stat(exportpath);
4437da2899SCharles.Forsyth			if (n == -1 || exportpath == nil)
4537da2899SCharles.Forsyth				arg->usage();
4637da2899SCharles.Forsyth		'f' =>
4737da2899SCharles.Forsyth			keyfile = arg->earg();
4837da2899SCharles.Forsyth			if (! (keyfile[0] == '/' || (len keyfile > 2 &&  keyfile[0:2] == "./")))
4937da2899SCharles.Forsyth				keyfile = "/usr/" + user() + "/keyring/" + keyfile;
5037da2899SCharles.Forsyth		*   =>
5137da2899SCharles.Forsyth			arg->usage();
5237da2899SCharles.Forsyth		}
5337da2899SCharles.Forsyth
5437da2899SCharles.Forsyth	argv = arg->argv();
5537da2899SCharles.Forsyth	if(argv == nil)
5637da2899SCharles.Forsyth		arg->usage();
5737da2899SCharles.Forsyth	arg = nil;
5837da2899SCharles.Forsyth
5937da2899SCharles.Forsyth	if (doauth && alg == nil)
6037da2899SCharles.Forsyth		alg = DEFAULTALG;
6137da2899SCharles.Forsyth
6237da2899SCharles.Forsyth	addr := hd argv;
6337da2899SCharles.Forsyth	argv = tl argv;
6437da2899SCharles.Forsyth
6537da2899SCharles.Forsyth	args := "";
6637da2899SCharles.Forsyth	while(argv != nil){
6737da2899SCharles.Forsyth		args += " " + hd argv;
6837da2899SCharles.Forsyth		argv = tl argv;
6937da2899SCharles.Forsyth	}
7037da2899SCharles.Forsyth	if(args == "")
7137da2899SCharles.Forsyth		args = "sh";
7237da2899SCharles.Forsyth
7337da2899SCharles.Forsyth	kr: Keyring;
7437da2899SCharles.Forsyth	au: Auth;
7537da2899SCharles.Forsyth	if (doauth) {
7637da2899SCharles.Forsyth		kr = load Keyring Keyring->PATH;
7737da2899SCharles.Forsyth		if(kr == nil)
7837da2899SCharles.Forsyth			badmodule(Keyring->PATH);
7937da2899SCharles.Forsyth		au = load Auth Auth->PATH;
8037da2899SCharles.Forsyth		if(au == nil)
8137da2899SCharles.Forsyth			badmodule(Auth->PATH);
8237da2899SCharles.Forsyth		if (keyfile == nil)
8337da2899SCharles.Forsyth			keyfile = "/usr/" + user() + "/keyring/default";
8437da2899SCharles.Forsyth	}
8537da2899SCharles.Forsyth
86*fbc1184cSCharles Forsyth	c := dial->dial(dial->netmkaddr(addr, "tcp", "rstyx"), nil);
87*fbc1184cSCharles Forsyth	if(c == nil)
88*fbc1184cSCharles Forsyth		error(sys->sprint("dial %s failed: %r", addr));
8937da2899SCharles.Forsyth
9037da2899SCharles.Forsyth	fd := c.dfd;
9137da2899SCharles.Forsyth	if (doauth) {
9237da2899SCharles.Forsyth		ai := kr->readauthinfo(keyfile);
9337da2899SCharles.Forsyth		#
9437da2899SCharles.Forsyth		# let auth->client handle nil ai
9537da2899SCharles.Forsyth		# if(ai == nil){
9637da2899SCharles.Forsyth		#	sys->fprint(stderr(), "rcmd: certificate for %s not found\n", addr);
9737da2899SCharles.Forsyth		#	raise "fail:no certificate";
9837da2899SCharles.Forsyth		# }
9937da2899SCharles.Forsyth		#
10037da2899SCharles.Forsyth
10137da2899SCharles.Forsyth		err := au->init();
10237da2899SCharles.Forsyth		if(err != nil)
10337da2899SCharles.Forsyth			error(err);
10437da2899SCharles.Forsyth
10537da2899SCharles.Forsyth		(fd, err) = au->client(alg, ai, c.dfd);
10637da2899SCharles.Forsyth		if(fd == nil){
10737da2899SCharles.Forsyth			sys->fprint(stderr(), "rcmd: authentication failed: %s\n", err);
10837da2899SCharles.Forsyth			raise "fail:auth failed";
10937da2899SCharles.Forsyth		}
11037da2899SCharles.Forsyth	}
11137da2899SCharles.Forsyth	t := array of byte sys->sprint("%d\n%s\n", len (array of byte args)+1, args);
11237da2899SCharles.Forsyth	if(sys->write(fd, t, len t) != len t){
11337da2899SCharles.Forsyth		sys->fprint(stderr(), "rcmd: cannot write arguments: %r\n");
11437da2899SCharles.Forsyth		raise "fail:bad arg write";
11537da2899SCharles.Forsyth	}
11637da2899SCharles.Forsyth
11737da2899SCharles.Forsyth	if(sys->export(fd, exportpath, sys->EXPWAIT) < 0) {
11837da2899SCharles.Forsyth		sys->fprint(stderr(), "rcmd: export: %r\n");
11937da2899SCharles.Forsyth		raise "fail:export failed";
12037da2899SCharles.Forsyth	}
12137da2899SCharles.Forsyth}
12237da2899SCharles.Forsyth
12337da2899SCharles.Forsythexists(f: string): int
12437da2899SCharles.Forsyth{
12537da2899SCharles.Forsyth	(ok, nil) := sys->stat(f);
12637da2899SCharles.Forsyth	return ok >= 0;
12737da2899SCharles.Forsyth}
12837da2899SCharles.Forsyth
12937da2899SCharles.Forsythuser(): string
13037da2899SCharles.Forsyth{
13137da2899SCharles.Forsyth	sys = load Sys Sys->PATH;
13237da2899SCharles.Forsyth
13337da2899SCharles.Forsyth	fd := sys->open("/dev/user", sys->OREAD);
13437da2899SCharles.Forsyth	if(fd == nil)
13537da2899SCharles.Forsyth		return "";
13637da2899SCharles.Forsyth
13737da2899SCharles.Forsyth	buf := array[128] of byte;
13837da2899SCharles.Forsyth	n := sys->read(fd, buf, len buf);
13937da2899SCharles.Forsyth	if(n < 0)
14037da2899SCharles.Forsyth		return "";
14137da2899SCharles.Forsyth
14237da2899SCharles.Forsyth	return string buf[0:n];
14337da2899SCharles.Forsyth}
14437da2899SCharles.Forsyth
14537da2899SCharles.Forsythstderr(): ref Sys->FD
14637da2899SCharles.Forsyth{
14737da2899SCharles.Forsyth	return sys->fildes(2);
14837da2899SCharles.Forsyth}
14937da2899SCharles.Forsyth
15037da2899SCharles.Forsythbadmodule(p: string)
15137da2899SCharles.Forsyth{
15237da2899SCharles.Forsyth	sys->fprint(stderr(), "rcmd: cannot load %s: %r\n", p);
15337da2899SCharles.Forsyth	raise "fail:bad module";
15437da2899SCharles.Forsyth}
15537da2899SCharles.Forsyth
15637da2899SCharles.Forsytherror(e: string)
15737da2899SCharles.Forsyth{
15837da2899SCharles.Forsyth	sys->fprint(stderr(), "rcmd: %s\n", e);
15937da2899SCharles.Forsyth	raise "fail:errors";
16037da2899SCharles.Forsyth}
161