xref: /inferno-os/os/init/jsinit.b (revision 74a4d8c26dd3c1e9febcb717cfd6cb6512991a7a)
1implement Init;
2#
3# init program for standalone wm using TK
4#
5include "sys.m";
6sys: Sys;
7	FD, Connection, sprint, Dir: import sys;
8	print, fprint, open, bind, mount, dial, sleep, read: import sys;
9
10include "draw.m";
11	draw: Draw;
12	Context: import draw;
13
14include "keyring.m";
15	kr: Keyring;
16
17include "security.m";
18	auth: Auth;
19
20Init: module
21{
22	init:	fn();
23};
24
25Logon: module
26{
27	init:	fn(ctxt: ref Context, argv: list of string);
28};
29
30rootfs(server: string): int
31{
32	ok, n: int;
33	c: Connection;
34
35	(ok, c) = dial("tcp!" + server + "!6666", nil);
36	if(ok < 0)
37		return -1;
38
39	sys->print("Connected ...");
40	if(kr != nil && auth != nil){
41		err: string;
42		sys->print("Authenticate ...");
43		ai := kr->readauthinfo("/nvfs/default");
44		if(ai == nil){
45			sys->print("readauthinfo /nvfs/default failed: %r\n");
46			sys->print("trying mount as `nobody'\n");
47		}
48		(c.dfd, err) = auth->client("none", ai, c.dfd);
49		if(c.dfd == nil){
50			sys->print("authentication failed: %s\n", err);
51			return -1;
52		}
53	}
54
55	sys->print("mount ...");
56
57	c.cfd = nil;
58	n = mount(c.dfd, nil, "/", sys->MREPL, "");
59	if(n > 0)
60		return 0;
61	return -1;
62}
63
64Bootpreadlen: con 128;
65
66init()
67{
68	spec: string;
69
70	sys = load Sys Sys->PATH;
71	kr = load Keyring Keyring->PATH;
72	auth = load Auth Auth->PATH;
73	if(auth != nil)
74		auth->init();
75
76	sys->print("**\n** Inferno\n** Vita Nuova\n**\n");
77
78	sys->print("Setup boot net services ...\n");
79
80	#
81	# Setup what we need to call a server and
82	# Authenticate
83	#
84	bind("#l", "/net", sys->MREPL);
85	bind("#I", "/net", sys->MAFTER);
86	bind("#c", "/dev", sys->MAFTER);
87	bind("#r", "/dev", sys->MAFTER);
88	nvramfd := sys->open("#r/nvram", sys->ORDWR);
89	if(nvramfd != nil){
90		spec = "#Fnvram";
91		if(bind(spec, "/nvfs", sys->MAFTER) < 0)
92			print("init: bind %s: %r\n", spec);
93		nvramfd = nil;
94	}
95
96	setsysname();
97
98	sys->print("bootp...");
99
100	fd := open("/net/ipifc/clone", sys->OWRITE);
101	if(fd == nil) {
102		print("init: open /net/ipifc/clone: %r\n");
103		exit;
104	}
105	cfg := array of byte "bind ether ether";
106	if(sys->write(fd, cfg, len cfg) != len cfg) {
107		sys->print("could not bind interface: %r\n");
108		exit;
109	}
110	cfg = array of byte "bootp";
111	if(sys->write(fd, cfg, len cfg) != len cfg) {
112		sys->print("could not bootp: %r\n");
113		exit;
114	}
115
116	fd = open("/net/bootp", sys->OREAD);
117	if(fd == nil) {
118		print("init: open /net/bootp: %r");
119		exit;
120	}
121
122	buf := array[Bootpreadlen] of byte;
123	nr := read(fd, buf, len buf);
124	fd = nil;
125	if(nr <= 0) {
126		print("init: read /net/bootp: %r");
127		exit;
128	}
129
130	(ntok, ls) := sys->tokenize(string buf, " \t\n");
131	while(ls != nil) {
132		if(hd ls == "fsip"){
133			ls = tl ls;
134			break;
135		}
136		ls = tl ls;
137	}
138	if(ls == nil) {
139		print("init: server address not in bootp read");
140		exit;
141	}
142
143	srv := hd ls;
144	sys->print("server %s\nConnect ...\n", srv);
145
146	while(rootfs(srv) < 0)
147		sleep(1000);
148
149	sys->print("done\n");
150
151	#
152	# default namespace
153	#
154	bind("#c", "/dev", sys->MBEFORE);		# console
155	bind("#r", "/dev", sys->MAFTER);
156	if(spec != nil)
157		bind(spec, "/nvfs", sys->MBEFORE|sys->MCREATE);	# our keys
158	bind("#l", "/net", sys->MBEFORE);		# ethernet
159	bind("#I", "/net", sys->MBEFORE);		# TCP/IP
160	bind("#p", "/prog", sys->MREPL);		# prog device
161	sys->bind("#d", "/fd", Sys->MREPL);
162
163	sys->print("clock...\n");
164	setclock();
165
166	sys->print("logon...\n");
167
168	logon := load Logon "/dis/wm/logon.dis";
169	if(logon == nil) {
170		print("init: load /dis/wm/logon.dis: %r");
171		exit;
172	}
173	dc: ref Context;
174	spawn logon->init(dc, nil);
175}
176
177setclock()
178{
179	(ok, dir) := sys->stat("/");
180	if (ok < 0) {
181		print("init: stat /: %r");
182		return;
183	}
184
185	fd := sys->open("/dev/time", sys->OWRITE);
186	if (fd == nil) {
187		print("init: open /dev/time: %r");
188		return;
189	}
190
191	# Time is kept as microsecs, atime is in secs
192	b := array of byte sprint("%d000000", dir.atime);
193	if (sys->write(fd, b, len b) != len b)
194		print("init: write /dev/time: %r");
195}
196
197#
198# Set system name from nvram
199#
200setsysname()
201{
202	fd := open("/nvfs/ID", sys->OREAD);
203	if(fd == nil)
204		return;
205	fds := open("/dev/sysname", sys->OWRITE);
206	if(fds == nil)
207		return;
208	buf := array[128] of byte;
209	nr := sys->read(fd, buf, len buf);
210	if(nr <= 0)
211		return;
212	sys->write(fds, buf, nr);
213}
214