xref: /inferno-os/appl/cmd/dial.b (revision 1ac9729e9325d84db36c04b5cda3b5b1bc0d041f)
1*1ac9729eSCharles Forsythimplement Dialc;
237da2899SCharles.Forsythinclude "sys.m";
337da2899SCharles.Forsyth	sys: Sys;
437da2899SCharles.Forsythinclude "draw.m";
537da2899SCharles.Forsythinclude "arg.m";
637da2899SCharles.Forsythinclude "keyring.m";
737da2899SCharles.Forsyth	keyring: Keyring;
837da2899SCharles.Forsythinclude "security.m";
937da2899SCharles.Forsyth	auth: Auth;
10*1ac9729eSCharles Forsythinclude "dial.m";
11*1ac9729eSCharles Forsyth	dial: Dial;
1237da2899SCharles.Forsythinclude "sh.m";
1337da2899SCharles.Forsyth	sh: Sh;
1437da2899SCharles.Forsyth	Context: import sh;
1537da2899SCharles.Forsyth
16*1ac9729eSCharles ForsythDialc: module {
1737da2899SCharles.Forsyth	init: fn(nil: ref Draw->Context, argv: list of string);
1837da2899SCharles.Forsyth};
1937da2899SCharles.Forsyth
2037da2899SCharles.Forsythbadmodule(p: string)
2137da2899SCharles.Forsyth{
2237da2899SCharles.Forsyth	sys->fprint(stderr(), "dial: cannot load %s: %r\n", p);
2337da2899SCharles.Forsyth	raise "fail:bad module";
2437da2899SCharles.Forsyth}
2537da2899SCharles.Forsyth
2637da2899SCharles.ForsythDEFAULTALG := "none";
2737da2899SCharles.Forsyth
2837da2899SCharles.Forsythverbose := 0;
2937da2899SCharles.Forsyth
3037da2899SCharles.Forsythinit(drawctxt: ref Draw->Context, argv: list of string)
3137da2899SCharles.Forsyth{
3237da2899SCharles.Forsyth	sys = load Sys Sys->PATH;
3337da2899SCharles.Forsyth	keyring = load Keyring Keyring->PATH;
3437da2899SCharles.Forsyth	auth = load Auth Auth->PATH;
3537da2899SCharles.Forsyth	if (auth == nil)
3637da2899SCharles.Forsyth		badmodule(Auth->PATH);
3737da2899SCharles.Forsyth	arg := load Arg Arg->PATH;
3837da2899SCharles.Forsyth	if (arg == nil)
3937da2899SCharles.Forsyth		badmodule(Arg->PATH);
4037da2899SCharles.Forsyth	sh = load Sh Sh->PATH;
4137da2899SCharles.Forsyth	if (sh == nil)
4237da2899SCharles.Forsyth		badmodule(Sh->PATH);
43*1ac9729eSCharles Forsyth	dial = load Dial Dial->PATH;
44*1ac9729eSCharles Forsyth	if (dial == nil)
45*1ac9729eSCharles Forsyth		badmodule(Dial->PATH);
4637da2899SCharles.Forsyth
4737da2899SCharles.Forsyth	auth->init();
4837da2899SCharles.Forsyth	alg: string;
4937da2899SCharles.Forsyth	keyfile: string;
5037da2899SCharles.Forsyth	doauth := 1;
5137da2899SCharles.Forsyth	arg->init(argv);
5237da2899SCharles.Forsyth	arg->setusage("dial [-A] [-k keyfile] [-a alg] addr command [arg...]");
5337da2899SCharles.Forsyth	while ((opt := arg->opt()) != 0) {
5437da2899SCharles.Forsyth		case opt {
5537da2899SCharles.Forsyth		'A' =>
5637da2899SCharles.Forsyth			doauth = 0;
5737da2899SCharles.Forsyth		'a' =>
5837da2899SCharles.Forsyth			alg = arg->earg();
5937da2899SCharles.Forsyth		'f' or
6037da2899SCharles.Forsyth		'k' =>
6137da2899SCharles.Forsyth			keyfile = arg->earg();
6237da2899SCharles.Forsyth			if (! (keyfile[0] == '/' || (len keyfile > 2 &&  keyfile[0:2] == "./")))
6337da2899SCharles.Forsyth				keyfile = "/usr/" + user() + "/keyring/" + keyfile;
6437da2899SCharles.Forsyth		'v' =>
6537da2899SCharles.Forsyth			verbose = 1;
6637da2899SCharles.Forsyth		* =>
6737da2899SCharles.Forsyth			arg->usage();
6837da2899SCharles.Forsyth		}
6937da2899SCharles.Forsyth	}
7037da2899SCharles.Forsyth	argv = arg->argv();
7137da2899SCharles.Forsyth	if (len argv < 2)
7237da2899SCharles.Forsyth		arg->usage();
7337da2899SCharles.Forsyth	arg = nil;
7437da2899SCharles.Forsyth	(addr, shcmd) := (hd argv, tl argv);
7537da2899SCharles.Forsyth
7637da2899SCharles.Forsyth	if (doauth && alg == nil)
7737da2899SCharles.Forsyth		alg = DEFAULTALG;
7837da2899SCharles.Forsyth
7937da2899SCharles.Forsyth	if (alg != nil && keyfile == nil) {
8037da2899SCharles.Forsyth		kd := "/usr/" + user() + "/keyring/";
8137da2899SCharles.Forsyth		if (exists(kd + addr))
8237da2899SCharles.Forsyth			keyfile = kd + addr;
8337da2899SCharles.Forsyth		else
8437da2899SCharles.Forsyth			keyfile = kd + "default";
8537da2899SCharles.Forsyth	}
8637da2899SCharles.Forsyth	cert: ref Keyring->Authinfo;
8737da2899SCharles.Forsyth	if (alg != nil) {
8837da2899SCharles.Forsyth		cert = keyring->readauthinfo(keyfile);
8937da2899SCharles.Forsyth		if (cert == nil) {
9037da2899SCharles.Forsyth			sys->fprint(stderr(), "dial: cannot read %s: %r\n", keyfile);
9137da2899SCharles.Forsyth			raise "fail:bad keyfile";
9237da2899SCharles.Forsyth		}
9337da2899SCharles.Forsyth	}
9437da2899SCharles.Forsyth
95*1ac9729eSCharles Forsyth	c := dial->dial(addr, nil);
96*1ac9729eSCharles Forsyth	if (c == nil) {
97*1ac9729eSCharles Forsyth		sys->fprint(stderr(), "dial: cannot dial %s: %r\n", addr);
9837da2899SCharles.Forsyth		raise "fail:errors";
9937da2899SCharles.Forsyth	}
10037da2899SCharles.Forsyth	user: string;
10137da2899SCharles.Forsyth	if (alg != nil) {
10237da2899SCharles.Forsyth		err: string;
10337da2899SCharles.Forsyth		(c.dfd, err) = auth->client(alg, cert, c.dfd);
10437da2899SCharles.Forsyth		if (c.dfd == nil) {
10537da2899SCharles.Forsyth			sys->fprint(stderr(), "dial: authentication failed: %s\n", err);
10637da2899SCharles.Forsyth			raise "fail:errors";
10737da2899SCharles.Forsyth		}
10837da2899SCharles.Forsyth		user = err;
10937da2899SCharles.Forsyth	}
11037da2899SCharles.Forsyth	sys->dup(c.dfd.fd, 0);
11137da2899SCharles.Forsyth	sys->dup(c.dfd.fd, 1);
11237da2899SCharles.Forsyth	c.dfd = c.cfd = nil;
11337da2899SCharles.Forsyth	ctxt := Context.new(drawctxt);
11437da2899SCharles.Forsyth	if (user != nil)
11537da2899SCharles.Forsyth		ctxt.set("user", sh->stringlist2list(user :: nil));
11637da2899SCharles.Forsyth	else
11737da2899SCharles.Forsyth		ctxt.set("user", nil);
11837da2899SCharles.Forsyth	ctxt.set("net", ref Sh->Listnode(nil, c.dir) :: nil);
11937da2899SCharles.Forsyth	ctxt.run(sh->stringlist2list(shcmd), 1);
12037da2899SCharles.Forsyth}
12137da2899SCharles.Forsyth
12237da2899SCharles.Forsythexists(f: string): int
12337da2899SCharles.Forsyth{
12437da2899SCharles.Forsyth	(ok, nil) := sys->stat(f);
12537da2899SCharles.Forsyth	return ok != -1;
12637da2899SCharles.Forsyth}
12737da2899SCharles.Forsyth
12837da2899SCharles.Forsythstderr(): ref Sys->FD
12937da2899SCharles.Forsyth{
13037da2899SCharles.Forsyth	return sys->fildes(2);
13137da2899SCharles.Forsyth}
13237da2899SCharles.Forsyth
13337da2899SCharles.Forsythuser(): string
13437da2899SCharles.Forsyth{
13537da2899SCharles.Forsyth	u := readfile("/dev/user");
13637da2899SCharles.Forsyth	if (u == nil)
13737da2899SCharles.Forsyth		return "nobody";
13837da2899SCharles.Forsyth	return u;
13937da2899SCharles.Forsyth}
14037da2899SCharles.Forsyth
14137da2899SCharles.Forsythreadfile(f: string): string
14237da2899SCharles.Forsyth{
14337da2899SCharles.Forsyth	fd := sys->open(f, sys->OREAD);
14437da2899SCharles.Forsyth	if(fd == nil)
14537da2899SCharles.Forsyth		return nil;
14637da2899SCharles.Forsyth
14737da2899SCharles.Forsyth	buf := array[128] of byte;
14837da2899SCharles.Forsyth	n := sys->read(fd, buf, len buf);
14937da2899SCharles.Forsyth	if(n < 0)
15037da2899SCharles.Forsyth		return nil;
15137da2899SCharles.Forsyth
15237da2899SCharles.Forsyth	return string buf[0:n];
15337da2899SCharles.Forsyth}
154