xref: /inferno-os/os/init/pcdemo.b (revision 74a4d8c26dd3c1e9febcb717cfd6cb6512991a7a)
1#
2#	Init shell ``with the kitchen sink'', for development purposes.
3#
4implement InitShell;
5
6include "sys.m";
7include "draw.m";
8
9sys: Sys;
10FD, Connection, sprint, Dir: import sys;
11print, fprint, open, bind, mount, dial, sleep, read: import sys;
12
13stderr:	ref sys->FD;						# standard error FD
14
15InitShell: module
16{
17	init:	fn(nil: ref Draw->Context, nil: list of string);
18};
19
20Sh: module
21{
22	init:	fn(ctxt: ref Draw->Context, argv: list of string);
23};
24
25init(nil: ref Draw->Context, nil: list of string)
26{
27	sys = load Sys Sys->PATH;
28	stderr = sys->fildes(2);
29
30	sys->print("Welcome to Inferno...\n");
31
32	sys->pctl(Sys->NEWNS, nil);
33	if (imount("/n/remote")) {
34		bind("/n/remote", "/", sys->MAFTER);
35		bind("/n/remote/dis", "/dis", sys->MBEFORE);
36		mountkfs("#W/flash0fs", "fs", "/n/local", sys->MREPL);
37	}
38	else {
39		# bind("#U/pcdemo", "/", sys->MREPL);
40		# mountkfs("#U/pcdemo.kfs", "fs", "/", sys->MBEFORE);
41		# bind("#U/pcdemo/usr", "/usr", sys->MAFTER);
42		mountkfs("#R/ramdisk", "fs", "/", sys->MBEFORE);
43		bind("/services", "/data", sys->MREPL|sys->MCREATE);
44	}
45
46	namespace();
47	srv();
48
49	if (1) {
50		bind("/icons/oldlogon.bit", "/icons/logon.bit", sys->MREPL);
51		bind("/icons/tk/oldinferno.bit", "/icons/tk/inferno.bit", sys->MREPL);
52	}
53
54	sys->print("starting shell (type wm/logon or wm/wmcp)\n");
55	shell := sysenv("shell");
56	if (shell == nil)
57		shell = "/dis/sh.dis";
58	sh := load Sh shell;
59	spawn sh->init(nil, nil);
60}
61
62namespace()
63{
64	# Bind anything useful we can get our hands on.  Ignore errors.
65	sys->print("namespace...\n");
66	sys->bind("#I", "/net", sys->MAFTER);	# IP
67	sys->bind("#I1", "/net.alt", sys->MREPL);	# second IP for PPP tests
68	sys->bind("#p", "/prog", sys->MREPL);	# prog device
69	sys->bind("#d", "/fd", Sys->MREPL);
70	sys->bind("#i", "/dev", sys->MREPL); 	# draw device
71	sys->bind("#t", "/dev", sys->MAFTER);	# serial line
72	sys->bind("#c", "/dev", sys->MAFTER); 	# console device
73	sys->bind("#W", "/dev", sys->MAFTER);	# Flash
74	sys->bind("#O", "/dev", sys->MAFTER);	# Modem
75	sys->bind("#T", "/dev", sys->MAFTER);	# Touchscreen
76	sys->bind("#H", "/dev", sys->MAFTER);	# Ata disk device
77	sys->bind("#b", "/dev", sys->MAFTER);	# debug device
78	sys->bind("#c", "/chan", sys->MREPL);
79	sys->bind("/data", "/usr/inferno", sys->MREPL|sys->MCREATE);
80	sys->bind("/data", "/usr/charon", sys->MREPL|sys->MCREATE);
81	sys->bind("/data", "/usr/shaggy", sys->MREPL|sys->MCREATE);
82}
83
84mountkfs(devname: string, fsname: string, where: string, flags: int): int
85{
86	sys->print("mount kfs...\n");
87	fd := sys->open("#Kcons/kfsctl", sys->OWRITE);
88	if (fd == nil) {
89		sys->fprint(stderr, "could not open #Kcons/kfsctl: %r\n");
90		return 0;
91	}
92	kfsopt := "";
93	kfsrw := sysenv("kfsrw");
94#	if (kfsrw != "1")
95#		kfsopt = " ronly";
96	b := array of byte ("filsys " + fsname + " " + devname + kfsopt);
97	if (sys->write(fd, b, len b) < 0) {
98		sys->fprint(stderr, "could not write #Kcons/kfsctl: %r\n");
99		return 0;
100	}
101	if (sys->bind("#K" + fsname, where, flags) < 0) {
102		sys->fprint(stderr, "could not bind %s to %s: %r\n", "#K" + fsname, where);
103		return 0;
104	}
105	return 1;
106}
107
108dialfs(server: string, where: string): int
109{
110	ok, n: int;
111	c: Connection;
112
113	(ok, c) = dial("tcp!" + server + "!6666", nil);
114	if(ok < 0)
115		return 0;
116
117	sys->print("mount...");
118
119	c.cfd = nil;
120	n = mount(c.dfd, where, sys->MREPL, "");
121	if(n > 0)
122		return 1;
123	sys->print("mount failed: %r\n");
124	return 0;
125}
126
127Bootpreadlen: con 128;
128
129imount(where: string): int
130{
131	sys->print("bootp...");
132	if (sys->bind("#I", "/net", sys->MREPL) < 0) {
133		sys->fprint(stderr, "could not bind ip device: %r\n");
134		return 0;
135	}
136	if (sys->bind("#l", "/net", sys->MAFTER) < 0) {
137		sys->fprint(stderr, "could not bind ether device: %r\n");
138		return 0;
139	}
140
141	fd := sys->open("/net/ipifc/clone", sys->OWRITE);
142	if(fd == nil) {
143		sys->print("init: open /net/ipifc: %r");
144		return 0;
145	}
146
147	cfg := array of byte "bind ether ether0";
148	if(sys->write(fd, cfg, len cfg) != len cfg) {
149		sys->fprint(stderr, "could not bind interface: %r\n");
150		return 0;
151	}
152	cfg = array of byte "bootp";
153	if(sys->write(fd, cfg, len cfg) != len cfg) {
154		sys->fprint(stderr, "could not bootp: %r\n");
155		return 0;
156	}
157
158	bfd := sys->open("/net/bootp", sys->OREAD);
159	if(bfd == nil) {
160		sys->print("init: can't open /net/bootp: %r");
161		return 0;
162	}
163
164	buf := array[Bootpreadlen] of byte;
165	nr := sys->read(bfd, buf, len buf);
166	bfd = nil;
167	if(nr <= 0) {
168		sys->print("init: read /net/bootp: %r");
169		return 0;
170	}
171
172	(ntok, ls) := sys->tokenize(string buf, " \t\n");
173	while(ls != nil) {
174		if(hd ls == "fsip"){
175			ls = tl ls;
176			break;
177		}
178		ls = tl ls;
179	}
180	if(ls == nil) {
181		sys->print("init: server address not in bootp read");
182		return 0;
183	}
184
185	server := hd ls;
186	sys->print("imount: server %s\n", server);
187
188	return dialfs(server, where);
189}
190
191srv()
192{
193	remotedebug := sysenv("remotedebug");
194	if(remotedebug != "1")
195		return;
196	remotespeed := sysenv("remotespeed");
197	if (remotespeed == nil)
198		remotespeed = "38400";
199
200	sys->print("srv...");
201	if(echoto("#t/eia0ctl", "b" + remotespeed) < 0)
202		return;
203
204	fd := sys->open("/dev/eia0", Sys->ORDWR);
205	if (fd == nil) {
206		sys->print("eia data open: %r\n");
207		return;
208	}
209	if (sys->export(fd, Sys->EXPASYNC) < 0) {
210		sys->print("export: %r\n");
211		return;
212	}
213	sys->print("ok\n");
214}
215
216sysenv(param: string): string
217{
218	fd := sys->open("#c/sysenv", sys->OREAD);
219	if (fd == nil)
220		return(nil);
221	buf := array[4096] of byte;
222	nb := sys->read(fd, buf, len buf);
223	(nfl,fl) := sys->tokenize(string buf, "\n");
224	while (fl != nil) {
225		pair := hd fl;
226		(npl, pl) := sys->tokenize(pair, "=");
227		if (npl > 1) {
228			if ((hd pl) == param)
229				return hd tl pl;
230		}
231		fl = tl fl;
232	}
233	return nil;
234}
235
236echoto(fname, str: string): int
237{
238	fd := sys->open(fname, Sys->OWRITE);
239	if(fd == nil) {
240		sys->print("%s: %r\n", fname);
241		return -1;
242	}
243	x := array of byte str;
244	if(sys->write(fd, x, len x) == -1) {
245		sys->print("write: %r\n");
246		return -1;
247	}
248	return 0;
249}
250
251hang()
252{
253	c := chan of int;
254	<- c;
255}
256
257#
258# Set system name from nvram
259#
260setsysname()
261{
262	fd := open("/nvfs/ID", sys->OREAD);
263	if(fd == nil)
264		return;
265	fds := open("/dev/sysname", sys->OWRITE);
266	if(fds == nil)
267		return;
268	buf := array[128] of byte;
269	nr := sys->read(fd, buf, len buf);
270	if(nr <= 0)
271		return;
272	sys->write(fds, buf, nr);
273}
274