123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612 |
- #
- # Intrinsyc Cerf cube
- #
- implement Init;
- include "sys.m";
- sys: Sys;
- include "draw.m";
- include "keyring.m";
- kr: Keyring;
- include "security.m";
- auth: Auth;
- include "sh.m";
- Init: module
- {
- init: fn();
- };
- Bootpreadlen: con 128;
- # standard flash partitions
- flashparts := array[] of {
- # bootstrap at 0x0 to 0x20000
- "add script 0x20000 0x40000",
- "add kernel 0x100000 0x200000",
- "add fs 0x200000 end",
- };
- ethername := "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;
- auth = load Auth Auth->PATH;
- if(auth != nil)
- auth->init();
- sys->bind("/", "/", Sys->MREPL);
- localok := 0;
- if(lfs() >= 0){
- # let's just take a closer look
- sys->bind("/n/local/nvfs", "/nvfs", Sys->MREPL|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 = "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
- timefile: string;
- rootsource: string;
- scale := 1;
- cfd := sys->open("/dev/consctl", Sys->OWRITE);
- if(cfd != nil)
- sys->fprint(cfd, "rawon");
- for(;;){
- (rootsource, timefile, scale) = 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(rootsource+"/dis", "/dis", Sys->MBEFORE|Sys->MCREATE);
- break;
- }
- }
- cfd = nil;
- setsysname("cerf"); # set system name
- now := getclock(timefile, rootsource);
- if(scale == 1)
- now *= big 1000000;
- setclock("/dev/time", now);
- if(timefile != "#r/rtc")
- setclock("#r/rtc", now/big 1000000);
- 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 := username("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);
- }
- getclock(timefile: string, timedir: string): big
- {
- now := big 0;
- if(timefile != nil){
- fd := sys->open(timefile, Sys->OREAD);
- if(fd != nil){
- b := array[64] of byte;
- n := sys->read(fd, b, len b-1);
- if(n > 0){
- now = big string b[0:n];
- if(now <= big 16r20000000)
- now = big 0; # remote itself is not initialised
- }
- }
- }
- if(now == big 0){
- if(timedir != nil){
- (ok, dir) := sys->stat(timedir);
- if(ok < 0) {
- sys->print("init: stat %s: %r", timedir);
- return big 0;
- }
- now = big dir.atime;
- }else{
- now = big 993826747000000;
- sys->print("time warped\n");
- }
- }
- return now;
- }
- setclock(timefile: string, now: big)
- {
- fd := sys->open(timefile, sys->OWRITE);
- if (fd == nil) {
- sys->print("init: can't open %s: %r", timefile);
- return;
- }
- b := sys->aprint("%ubd", now);
- if (sys->write(fd, b, len b) != len b)
- sys->print("init: can't write to %s: %r", timefile);
- }
- srv()
- {
- sys->print("remote debug srv...");
- fd := sys->open("/dev/eia0ctl", Sys->OWRITE);
- if(fd != nil)
- sys->fprint(fd, "b115200");
- fd = sys->open("/dev/eia0", Sys->ORDWR);
- if (fd == nil){
- err(sys->sprint("can't open /dev/eia0: %r"));
- return;
- }
- if (sys->export(fd, "/", Sys->EXPASYNC) < 0){
- err(sys->sprint("can't export on serial port: %r"));
- return;
- }
- }
- 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, int)
- {
- 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 = rf("/nvfs/rootsource", nil)) != nil) {
- tried = 1;
- if (s[len s - 1] == '\n')
- s = s[:len s - 1];
- sys->print("/nvfs/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, "#r/rtc", 1);
- "local" =>
- return ("/n/local", "#r/rtc", 1);
- "local+remote" =>
- if(netfs("/n/remote") >= 0)
- return ("/n/local", "/n/remote/dev/time", 1000000);
- "remote" =>
- if(netfs("/n/remote") >= 0)
- return ("/n/remote", "/n/remote/dev/time", 1000000);
- }
- }
- }
- 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 DOS file system using flash translation layer
- #
- lfs(): int
- {
- if(!flashpart("#F/flash/flashctl", flashparts))
- return -1;
- if(!ftlinit("#F/flash/fs"))
- return -1;
- c := chan of string;
- spawn startfs(c, "/dis/dossrv.dis", "dossrv" :: "-f" :: "#X/ftldata" :: "-m" :: "/n/local" :: nil);
- if(<-c != nil)
- return -1;
- return 0;
- }
- startfs(c: chan of string, file: string, args: list of string)
- {
- fs := load Command file;
- if(fs == nil){
- sys->print("can't load %s: %r\n", file);
- c <-= "load failed";
- }
- {
- fs->init(nil, args);
- }exception e {
- "*" =>
- c <-= "failed";
- exit;
- * =>
- c <-= "unknown exception";
- exit;
- }
- c <-= nil;
- }
- #
- # 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 flash translation layer
- #
- ftldone := 0;
- ftlinit(flashmem: string): int
- {
- if(ftldone)
- return 1;
- sys->print("Set flash translation of %s...\n", flashmem);
- fd := sys->open("#X/ftlctl", Sys->OWRITE);
- if(fd == nil){
- sys->print("can't open #X/ftlctl: %r\n");
- return 0;
- }
- if(sys->fprint(fd, "init %s", flashmem) <= 0){
- sys->print("can't init flash translation: %r\n");
- return 0;
- }
- ftldone = 1;
- return 1;
- }
- configether()
- {
- if(ethername == nil)
- return;
- fd := sys->open("/nvfs/etherparams", Sys->OREAD);
- if(fd == nil)
- return;
- ctl := sys->open("/net/"+ethername+"/clone", Sys->OWRITE);
- if(ctl == nil){
- sys->print("init: can't open %s'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: %s: %r\n", ethername, s);
- i = e+1;
- }
- }
- donebind := 0;
- #
- # set up network mount
- #
- netfs(mountpt: string): int
- {
- sys->print("bootp ...");
- 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;
- }
- }
- if ((ip := rf("/nvfs/ip", nil)) != nil) {
- sys->print("**using %s\n", ip);
- sys->fprint(fd, "bind ether /net/ether0");
- sys->fprint(fd, "add %s ", ip);
- } else {
- {
- if(sys->fprint(fd, "bootp") < 0)
- sys->print("could not bootp: %r\n");
- } exception e {
- "*" =>
- sys->print("could not bootp: %s\n", e);
- }
- }
- server := rf("/nvfs/fsip", nil);
- if (server != nil) {
- if (server[len server - 1] == '\n')
- server = server[:len server - 1];
- sys->print("/nvfs/fsip: server=%s\n", server);
- } else
- server = bootp();
- if(server == nil || server == "0.0.0.0")
- return -1;
- net := "tcp"; # how to specify il?
- svcname := net + "!" + server + "!6666";
- sys->print("dial %s...", svcname);
- (ok, c) := sys->dial(svcname, nil);
- if(ok < 0){
- sys->print("can't dial %s: %r\n", svcname);
- return -1;
- }
- sys->print("\nConnected ...\n");
- if(kr != nil){
- err: string;
- sys->print("Authenticate ...");
- ai := kr->readauthinfo("/nvfs/default");
- if(ai == nil){
- sys->print("readauthinfo /nvfs/default failed: %r\n");
- sys->print("trying mount as `nobody'\n");
- }
- (c.dfd, err) = auth->client("none", ai, c.dfd);
- if(c.dfd == nil){
- sys->print("authentication failed: %s\n", err);
- return -1;
- }
- }
- sys->print("mount %s...", mountpt);
- c.cfd = nil;
- n := sys->mount(c.dfd, nil, mountpt, sys->MREPL, "");
- if(n > 0)
- return 0;
- if(n < 0)
- sys->print("%r");
- return -1;
- }
- bootp(): string
- {
- fd := sys->open("/net/bootp", sys->OREAD);
- if(fd == nil) {
- sys->print("init: can't open /net/bootp: %r");
- return nil;
- }
- buf := array[Bootpreadlen] of byte;
- nr := sys->read(fd, buf, len buf);
- fd = nil;
- if(nr <= 0) {
- sys->print("init: read /net/bootp: %r");
- return nil;
- }
- (ntok, ls) := sys->tokenize(string buf, " \t\n");
- while(ls != nil) {
- if(hd ls == "fsip"){
- ls = tl ls;
- break;
- }
- ls = tl ls;
- }
- if(ls == nil) {
- sys->print("init: server address not in bootp read");
- return nil;
- }
- srv := hd ls;
- sys->print("%s\n", srv);
- return srv;
- }
-
- username(def: string): string
- {
- return rf("/nvfs/user", def);
- }
- userok(user: string): int
- {
- (ok, d) := sys->stat("/usr/"+user);
- return ok >= 0 && (d.mode & Sys->DMDIR) != 0;
- }
- rf(file: string, default: string): string
- {
- fd := sys->open(file, Sys->OREAD);
- if(fd != nil){
- buf := array[128] of byte;
- nr := sys->read(fd, buf, len buf);
- if(nr > 0)
- return string buf[0:nr];
- }
- return default;
- }
|