xref: /inferno-os/appl/cmd/cpu.b (revision cd8e99851af33e52bcdf8faf34f9d4e62fa0cbaf)
1implement CPU;
2
3include "sys.m";
4	sys: Sys;
5	stderr: ref Sys->FD;
6include "draw.m";
7include "string.m";
8	str: String;
9include "arg.m";
10include "keyring.m";
11include "security.m";
12include "dial.m";
13
14DEFCMD:	con "/dis/sh";
15
16CPU: module
17{
18	init:	fn(ctxt: ref Draw->Context, argv: list of string);
19};
20
21badmodule(p: string)
22{
23	sys->fprint(stderr, "cpu: cannot load %s: %r\n", p);
24	raise "fail:bad module";
25}
26
27usage()
28{
29	sys->fprint(stderr, "Usage: cpu [-C cryptoalg] mach command args...\n");
30	raise "fail:usage";
31}
32
33# The default level of security is NOSSL, unless
34# the keyring directory doesn't exist, in which case
35# it's disallowed.
36init(nil: ref Draw->Context, argv: list of string)
37{
38	sys = load Sys Sys->PATH;
39	stderr = sys->fildes(2);
40
41	arg := load Arg Arg->PATH;
42	if (arg == nil) badmodule(Arg->PATH);
43
44	str = load String String->PATH;
45	if (str == nil) badmodule(String->PATH);
46
47	au := load Auth Auth->PATH;
48	if (au == nil) badmodule(Auth->PATH);
49
50	kr := load Keyring Keyring->PATH;
51	if (kr == nil) badmodule(Keyring->PATH);
52
53	dial := load Dial Dial->PATH;
54
55	arg->init(argv);
56	alg := "";
57	while ((opt := arg->opt()) != 0) {
58		if (opt == 'C') {
59			alg = arg->arg();
60		} else
61			usage();
62	}
63	argv = arg->argv();
64	args := "auxi/cpuslave";
65#	if(ctxt != nil && ctxt.screen != nil)
66#		args += " -s" + string ctxt.screen.id;
67#	else
68		args += " --";
69
70	mach: string;
71	case len argv {
72	0 =>
73		usage();
74	1 =>
75		mach = hd argv;
76		args += " " + DEFCMD;
77	* =>
78		mach = hd argv;
79		args += " " + str->quoted(tl argv);
80	}
81
82	user := getuser();
83	kd := "/usr/" + user + "/keyring/";
84	cert := kd + dial->netmkaddr(mach, "tcp", "");
85	if (!exists(cert)) {
86		cert = kd + "default";
87		if (!exists(cert)) {
88			sys->fprint(stderr, "cpu: cannot find certificate in %s; use getauthinfo\n", kd);
89			raise "fail:no certificate";
90		}
91	}
92
93	c := dial->dial(dial->netmkaddr(mach, "net", "rstyx"), nil);
94	if(c == nil){
95		sys->fprint(stderr, "cpu: can't dial %s: %r\n", mach);
96		raise "fail:dial";
97	}
98
99	ai := kr->readauthinfo(cert);
100
101	if (alg == nil)
102		alg = "none";
103	err := au->init();
104	if(err != nil) {
105		sys->fprint(stderr, "cpu: cannot initialise auth module: %s\n", err);
106		raise "fail:auth init failed";
107	}
108
109	fd := ref Sys->FD;
110	#sys->fprint(stderr, "cpu: authenticating using alg '%s'\n", alg);
111	(fd, err) = au->client(alg, ai, c.dfd);
112	if(fd == nil) {
113		sys->fprint(stderr, "cpu: authentication failed: %s\n", err);
114		raise "fail:authentication failure";
115	}
116
117	t := array of byte sys->sprint("%d\n%s\n", len (array of byte args)+1, args);
118	if(sys->write(fd, t, len t) != len t){
119		sys->fprint(stderr, "cpu: export args write error: %r\n");
120		raise "fail:write error";
121	}
122
123	if(sys->export(fd, "/", sys->EXPWAIT) < 0){
124		sys->fprint(stderr, "cpu: export failed: %r\n");
125		raise "fail:export error";
126	}
127}
128
129exists(file: string): int
130{
131	(ok, nil) := sys->stat(file);
132	return ok != -1;
133}
134
135getuser(): string
136{
137	fd := sys->open("/dev/user", sys->OREAD);
138	if(fd == nil){
139		sys->fprint(stderr, "cpu: cannot open /dev/user: %r\n");
140		raise "fail:no user id";
141	}
142
143	buf := array[50] of byte;
144	n := sys->read(fd, buf, len buf);
145	if(n < 0){
146		sys->fprint(stderr, "cpu: cannot read /dev/user: %r\n");
147		raise "fail:no user id";
148	}
149
150	return string buf[0:n];
151}
152