Charles.Forsyth20060303644188019 years agoHistory
598 lines · 12.8 KB · Brainfuck
RawDownload
## Intrinsyc Cerf cube 405EP, also Manga switch## this encrusted version will be simplified shortly# implement Init; include "sys.m";	sys:	Sys; include "draw.m"; include "keyring.m";	kr: Keyring; include "security.m";	auth: Auth; include "dhcp.m";	dhcpclient: Dhcpclient;	Bootconf: import dhcpclient; include "sh.m"; Init: module{	init:	fn();}; Bootpreadlen: con 128;Microsec: con 1000000;Notime: con big 800000000 * big Microsec;	# fairly arbitrary time in 1995 to check validity # conventional Inferno NAND flash partitionsnandparts := array[] of {	# bootstrap from 0 to 0x210000	"add boot 0 0x210000",	"add fs 0x210000 end"}; userdefault := array[] of {	"inferno inferno",	"sys sys"}; ethername := "/net/ether0"; ## initialise flash translation# mount flash file system# add devices# start a shell or window manager# init(){	sys = load Sys Sys->PATH;	kr = load Keyring Keyring->PATH; 	sys->bind("/", "/", Sys->MREPL);	if(sys->bind("/boot", "/", Sys->MAFTER) < 0)		sys->print("can't bind /boot after /: %r\n");	sys->bind("/boot/nvfs", "/nvfs", Sys->MREPL); 	auth = load Auth Auth->PATH;	if(auth != nil)		auth->init(); 	localok := 0;	if(lfs() >= 0){		# let's just take a closer look		sys->bind("/n/local/nvfs", "/nvfs", Sys->MBEFORE|Sys->MCREATE);		(rc, nil) := sys->stat("/n/local/dis/sh.dis");		if(rc >= 0)			localok = 1;		else			err("local file system unusable");	} 	netok := sys->bind("#l", "/net", Sys->MREPL) >= 0;	if(!netok){		netok = sys->bind("#l1", "/net", Sys->MREPL) >= 0;		if(netok)			ethername = "/net/ether1";	}	if(netok)		configether(); 	dobind("#I", "/net", sys->MAFTER);	# IP	dobind("#p", "/prog", sys->MREPL);	# prog	sys->bind("#d", "/fd", Sys->MREPL);	dobind("#c", "/dev", sys->MREPL); 	# console	dobind("#t", "/dev", sys->MAFTER);	# serial line	drawok := sys->bind("#i", "/dev", sys->MAFTER) >= 0; 	# draw	sys->bind("#m", "/dev", sys->MAFTER);	# pointer	sys->bind("#e", "/env", sys->MREPL|sys->MCREATE);	# environment	sys->bind("#A", "/dev", Sys->MAFTER);	# optional audio	sys->bind("#ʟ", "/dev", Sys->MAFTER);	# logfs 	timefile: string;	rootsource: string;	cfd := sys->open("/dev/consctl", Sys->OWRITE);	if(cfd != nil)		sys->fprint(cfd, "rawon");	for(;;){		(rootsource, timefile) = askrootsource(localok, netok);		if(rootsource == nil)			break;	# internal		(rc, nil) := sys->stat(rootsource+"/dis/sh.dis");		if(rc < 0)			err("%s has no shell");		else if(sys->bind(rootsource, "/", Sys->MAFTER) < 0)			sys->print("can't bind %s on /: %r\n", rootsource);		else{			sys->bind("/n/local", rootsource+"/n/local", Sys->MREPL|Sys->MCREATE);			sys->unmount("#//./boot", "/");			sys->bind(rootsource+"/dis", "/dis", Sys->MBEFORE|Sys->MCREATE);			break;		}	}	cfd = nil; 	setsysname("cerf");			# set system name 	rtc := big rf("#r/rtc", "0") * big Microsec;	now := big 0;	if(timefile != nil){	# synchronise with remote time if it's valid		now = big rf(timefile, "0");		if(now < Notime && rootsource != nil)			now = big filetime(rootsource) * big Microsec;	# try the time of the root directory		if(now >= Notime){			setclock("#r/rtc", now/big Microsec);			rtc = now;		}	}	if(now < Notime)		now = rtc;	setclock("/dev/time", now); 	sys->chdir("/");	if(netok){		start("ndb/dns", nil);		start("ndb/cs", nil);	}	startup := "/nvfs/startup";	if(sys->open(startup, Sys->OREAD) != nil){		shell := load Command Sh->PATH;		if(shell != nil){			sys->print("Running %s\n", startup);			shell->init(nil, "sh" :: startup :: nil);		}	}	user := rdenv("user", "inferno");	(ok, nil) := sys->stat("/dis/wm/wm.dis");	if(drawok && ok >= 0)		(ok, nil) = sys->stat("/dis/wm/logon.dis");	if(drawok && ok >= 0 && userok(user)){		wm := load Command "/dis/wm/wm.dis";		if(wm != nil){			fd := sys->open("/nvfs/user", Sys->OWRITE);			if(fd != nil){				sys->fprint(fd, "%s", user);				fd = nil;			}			spawn wm->init(nil, list of {"wm/wm", "wm/logon", "-l", "-u", user});			exit;		}		sys->print("init: can't load wm/logon: %r");	}	sh := load Command Sh->PATH;	if(sh == nil){		err(sys->sprint("can't load %s: %r", Sh->PATH));		hang();	}	spawn sh->init(nil, "sh" :: nil);} start(cmd: string, args: list of string){	disfile := cmd;	if(disfile[0] != '/')		disfile = "/dis/"+disfile+".dis";	(ok, nil) := sys->stat(disfile);	if(ok >= 0){		dis := load Command disfile;		if(dis == nil)			sys->print("init: can't load %s: %r\n", disfile);		else			spawn dis->init(nil, cmd :: args);	}} dobind(f, t: string, flags: int){	if(sys->bind(f, t, flags) < 0)		err(sys->sprint("can't bind %s on %s: %r", f, t));} ## Set system name from nvram if possible#setsysname(def: string){	v := array of byte def;	fd := sys->open("/nvfs/ID", sys->OREAD);	if(fd == nil)		fd = sys->open("/env/sysname", sys->OREAD);	if(fd != nil){		buf := array[Sys->NAMEMAX] of byte;		nr := sys->read(fd, buf, len buf);		while(nr > 0 && buf[nr-1] == byte '\n')			nr--;		if(nr > 0)			v = buf[0:nr];	}	fd = sys->open("/dev/sysname", sys->OWRITE);	if(fd != nil)		sys->write(fd, v, len v);} filetime(name: string): int{	(ok, dir) := sys->stat(name);	if(ok < 0)		return 0;	return dir.atime;} setclock(timefile: string, now: big){	fd := sys->open(timefile, sys->OWRITE);	if(fd == nil)		sys->print("init: can't open %s: %r\n", timefile);	else if(sys->fprint(fd, "%bud", now) < 0)		sys->print("init: can't write to %s: %r\n", timefile);} err(s: string){	sys->fprint(sys->fildes(2), "init: %s\n", s);} hang(){	<-chan of int;} tried := 0; askrootsource(localok: int, netok: int): (string, string){	stdin := sys->fildes(0);	sources := "kernel" :: nil;	if(netok)		sources = "remote" :: sources;	if(localok){		sources = "local" :: sources;		if(netok)			sources = "local+remote" :: sources;	}	for(;;){		s := "";		if(tried == 0 && (s = rdenv("rootsource", nil)) != nil){			tried = 1;			sys->print("rootsource: root from %s\n", s);		} else {			sys->print("root from (");			cm := "";			for(l := sources; l != nil; l = tl l){				sys->print("%s%s", cm, hd l);				cm = ",";			}			sys->print(")[%s] ", hd sources); 			s = getline(stdin, hd sources);	# default		}		(nil, choice) := sys->tokenize(s, "\t ");		if(choice == nil)			choice = sources;		opt := hd choice;		case opt {		* =>			sys->print("\ninvalid boot option: '%s'\n", opt);		"kernel" =>			return (nil, nil);		"local" =>			return ("/n/local", nil);		"local+remote" =>			if(netfs("/n/remote") >= 0)				return ("/n/local", nil);		"remote" =>			if(netfs("/n/remote") >= 0)				return ("/n/remote", "/n/remote/dev/time");		}	}} getline(fd: ref Sys->FD, default: string): string{	result := "";	buf := array[10] of byte;	i := 0;	for(;;){		n := sys->read(fd, buf[i:], len buf - i);		if(n < 1)			break;		i += n;		while(i >0 && (nutf := sys->utfbytes(buf, i)) > 0){			s := string buf[0:nutf];			for(j := 0; j < len s; j++)				case s[j] {				'\b' =>					if(result != nil)						result = result[0:len result-1];				'u'&16r1F =>					sys->print("^U\n");					result = "";				'\r' =>					;				* =>					sys->print("%c", s[j]);					if(s[j] == '\n' || s[j] >= 16r80){						if(s[j] != '\n')							result[len result] = s[j];						if(result == nil)							return default;						return result;					}					result[len result] = s[j];				}			buf[0:] = buf[nutf:i];			i -= nutf;		}	}	return default;} ## serve local file system using logfs#lfs(): int{	if(!flashpart("#F1/flash1/flashctl", nandparts))		return -1;	if(!logfsinit("#F1/flash1/fs"))		return -1;	mfd := sys->open("/dev/logfsmain", Sys->ORDWR);	if(mfd == nil){		sys->print("can't open /dev/logfsmain: %r\n");		return -1;	}	if(sys->mount(mfd, nil, "/n/local", Sys->MREPL|Sys->MCREATE, nil) < 0){		sys->print("can't mount /dev/logfsmain on /n/local: %r\n");		return -1;	}	return 0;} ## partition flash#flashdone := 0; flashpart(ctl: string, parts: array of string): int{	if(flashdone)		return 1;	cfd := sys->open(ctl, Sys->ORDWR);	if(cfd == nil){		sys->print("can't open %s: %r\n", ctl);		return 0;	}	for(i := 0; i < len parts; i++)		if(sys->fprint(cfd, "%s", parts[i]) < 0){			sys->print("can't %q to %s: %r\n", parts[i], ctl);			return 0;		}	flashdone = 1;	return 1;} ## set up logfs#logfsdone := 0; logfsinit(flashmem: string): int{	if(logfsdone)		return 1;	fd := sys->open("/dev/logfsctl", Sys->OWRITE);	if(fd == nil){		if(sys->bind("#ʟ", "/dev", Sys->MBEFORE) < 0)			return -1;		fd = sys->open("/dev/logfsctl", Sys->OWRITE);		if(fd == nil){			sys->print("can't open /dev/logfsctl: %r\n");			return -1;		}	}	sys->print("Set logfs main on %s...\n", flashmem);	if(!ctlw(fd, "logfs", "fsys main config "+flashmem))		return -1;	if(!ctlw(fd, "logfs", "fsys main"))		return -1;	cm := rf("#e/logfsformat", nil);	if(cm == "yes"){		if(!ctlw(fd, "logfs", "format 0"))			return -1;	}	cf := rf("#e/logfsopen", nil);	if(cf == nil)		cf = "open";	if(!ctlw(fd, "logfs", cf))		return -1;	for(i := 0; i < len userdefault; i++)		ctlw(fd, "logfs", "uname "+userdefault[i]);	logfsdone = 1;	return 1;} ctlw(fd: ref Sys->FD, w: string, cmd: string): int{	if(sys->fprint(fd, "%s", cmd) < 0){		sys->print("%s ctl %q: %r\n", w, cmd);		return 0;	}	return 1;} configether(){	if(ethername == nil)		return;	fd := sys->open("/nvfs/etherparams", Sys->OREAD);	if(fd == nil)		return;	ctl := sys->open(ethername+"/clone", Sys->OWRITE);	if(ctl == nil){		sys->print("init: can't open %s/clone: %r\n", ethername);		return;	}	b := array[1024] of byte;	n := sys->read(fd, b, len b);	if(n <= 0)		return;	for(i := 0; i < n;){		for(e := i; e < n && b[e] != byte '\n'; e++)			;		s := string b[i:e];		if(sys->fprint(ctl, "%s", s) < 0)			sys->print("init: ctl write to %s/clone: %s: %r\n", ethername, s);		i = e+1;	}} donebind := 0;server: string; ## set up network mount#netfs(mountpt: string): int{	fd: ref Sys->FD;	if(!donebind){		fd = sys->open("/net/ipifc/clone", sys->OWRITE);		if(fd == nil){			sys->print("init: open /net/ipifc/clone: %r\n");			return -1;		}		if(sys->fprint(fd, "bind ether %s", ethername) < 0){			sys->print("could not bind %s interface: %r\n", ethername);			return -1;		}		donebind = 1;	}else{		fd = sys->open("/net/ipifc/0/ctl", Sys->OWRITE);		if(fd == nil){			sys->print("init: can't reopen /net/ipifc/0/ctl: %r\n");			return -1;		}	}	server = rdenv("fsip", nil);	if((ip := rdenv("ip", nil)) != nil){		sys->print("**using %s\n", ip);		sys->fprint(fd, "bind ether /net/ether0");		s := rdenv("ipmask", nil);		if(s == nil)			s = rdenv("netmask", nil);	# alternative name used by some bootstraps		sys->fprint(fd, "add %s %s", ip, s);		gate := rdenv("ipgw", nil);		if(gate == nil)			gate = rdenv("gateway", nil);		if(gate != nil){			rfd := sys->open("/net/iproute", Sys->OWRITE);			if(rfd != nil){				sys->fprint(rfd, "add 0 0 %s", gate);				sys->print("set gateway %s\n", gate);

Lines 1–500 of 598.