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