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