13e12c5d1SDavid du Colombier #include <u.h> 23e12c5d1SDavid du Colombier #include <libc.h> 33e12c5d1SDavid du Colombier #include <auth.h> 43e12c5d1SDavid du Colombier 53e12c5d1SDavid du Colombier void readenv(char*, char*, int); 63e12c5d1SDavid du Colombier void setenv(char*, char*); 73e12c5d1SDavid du Colombier void cpenv(char*, char*); 83e12c5d1SDavid du Colombier void closefds(void); 93e12c5d1SDavid du Colombier void fexec(void(*)(void)); 103e12c5d1SDavid du Colombier void rcexec(void); 113e12c5d1SDavid du Colombier void cpustart(void); 123e12c5d1SDavid du Colombier void pass(int); 133e12c5d1SDavid du Colombier 143e12c5d1SDavid du Colombier char *service; 153e12c5d1SDavid du Colombier char *cmd; 163e12c5d1SDavid du Colombier char cpu[NAMELEN]; 173e12c5d1SDavid du Colombier char sysname[NAMELEN]; 183e12c5d1SDavid du Colombier int manual; 193e12c5d1SDavid du Colombier int iscpu; 203e12c5d1SDavid du Colombier 213e12c5d1SDavid du Colombier void 223e12c5d1SDavid du Colombier main(int argc, char *argv[]) 233e12c5d1SDavid du Colombier { 243e12c5d1SDavid du Colombier char user[NAMELEN]; 253e12c5d1SDavid du Colombier int consctl, key; 263e12c5d1SDavid du Colombier 273e12c5d1SDavid du Colombier closefds(); 283e12c5d1SDavid du Colombier 293e12c5d1SDavid du Colombier service = "cpu"; 303e12c5d1SDavid du Colombier manual = 0; 313e12c5d1SDavid du Colombier ARGBEGIN{ 323e12c5d1SDavid du Colombier case 'c': 333e12c5d1SDavid du Colombier service = "cpu"; 343e12c5d1SDavid du Colombier break; 353e12c5d1SDavid du Colombier case 'm': 363e12c5d1SDavid du Colombier manual = 1; 373e12c5d1SDavid du Colombier break; 383e12c5d1SDavid du Colombier case 't': 393e12c5d1SDavid du Colombier service = "terminal"; 403e12c5d1SDavid du Colombier break; 413e12c5d1SDavid du Colombier }ARGEND 423e12c5d1SDavid du Colombier cmd = *argv; 433e12c5d1SDavid du Colombier 443e12c5d1SDavid du Colombier readenv("#e/cputype", cpu, sizeof cpu); 453e12c5d1SDavid du Colombier setenv("#e/objtype", cpu); 463e12c5d1SDavid du Colombier setenv("#e/service", service); 473e12c5d1SDavid du Colombier cpenv("/adm/timezone/local", "#e/timezone"); 483e12c5d1SDavid du Colombier readenv("#c/user", user, sizeof user); 493e12c5d1SDavid du Colombier readenv("#c/sysname", sysname, sizeof sysname); 503e12c5d1SDavid du Colombier 513e12c5d1SDavid du Colombier newns(user, 0); 523e12c5d1SDavid du Colombier 533e12c5d1SDavid du Colombier iscpu = strcmp(service, "cpu")==0; 543e12c5d1SDavid du Colombier 55*219b2ee8SDavid du Colombier if(iscpu && manual == 0) 563e12c5d1SDavid du Colombier fexec(cpustart); 573e12c5d1SDavid du Colombier 583e12c5d1SDavid du Colombier for(;;){ 593e12c5d1SDavid du Colombier if(iscpu){ 603e12c5d1SDavid du Colombier consctl = open("#c/consctl", OWRITE); 613e12c5d1SDavid du Colombier key = open("#c/key", OREAD); 623e12c5d1SDavid du Colombier if(consctl<0 || key<0 || write(consctl, "rawon", 5) != 5) 633e12c5d1SDavid du Colombier print("init: can't check password; insecure\n"); 643e12c5d1SDavid du Colombier else{ 653e12c5d1SDavid du Colombier pass(key); 663e12c5d1SDavid du Colombier write(consctl, "rawoff", 6); 673e12c5d1SDavid du Colombier } 683e12c5d1SDavid du Colombier close(consctl); 693e12c5d1SDavid du Colombier close(key); 703e12c5d1SDavid du Colombier } 713e12c5d1SDavid du Colombier print("\ninit: starting /bin/rc\n"); 723e12c5d1SDavid du Colombier fexec(rcexec); 733e12c5d1SDavid du Colombier manual = 1; 743e12c5d1SDavid du Colombier cmd = 0; 753e12c5d1SDavid du Colombier sleep(1000); 763e12c5d1SDavid du Colombier } 773e12c5d1SDavid du Colombier } 783e12c5d1SDavid du Colombier 793e12c5d1SDavid du Colombier void 803e12c5d1SDavid du Colombier pass(int fd) 813e12c5d1SDavid du Colombier { 823e12c5d1SDavid du Colombier char key[DESKEYLEN]; 833e12c5d1SDavid du Colombier char typed[32]; 843e12c5d1SDavid du Colombier char crypted[DESKEYLEN]; 853e12c5d1SDavid du Colombier int i; 863e12c5d1SDavid du Colombier 873e12c5d1SDavid du Colombier for(;;){ 883e12c5d1SDavid du Colombier readenv("#c/sysname", sysname, sizeof sysname); 893e12c5d1SDavid du Colombier print("\n%s password:", sysname); 903e12c5d1SDavid du Colombier for(i=0; i<sizeof typed; i++){ 913e12c5d1SDavid du Colombier if(read(0, typed+i, 1) != 1){ 923e12c5d1SDavid du Colombier print("init: can't read password; insecure\n"); 933e12c5d1SDavid du Colombier return; 943e12c5d1SDavid du Colombier } 953e12c5d1SDavid du Colombier if(typed[i] == '\n'){ 963e12c5d1SDavid du Colombier typed[i] = 0; 973e12c5d1SDavid du Colombier break; 983e12c5d1SDavid du Colombier } 993e12c5d1SDavid du Colombier } 1003e12c5d1SDavid du Colombier if(i == sizeof typed) 1013e12c5d1SDavid du Colombier continue; 1023e12c5d1SDavid du Colombier if(passtokey(crypted, typed) == 0) 1033e12c5d1SDavid du Colombier continue; 1043e12c5d1SDavid du Colombier seek(fd, 0, 0); 1053e12c5d1SDavid du Colombier if(read(fd, key, DESKEYLEN) != DESKEYLEN){ 1063e12c5d1SDavid du Colombier print("init: can't read key; insecure\n"); 1073e12c5d1SDavid du Colombier return; 1083e12c5d1SDavid du Colombier } 1093e12c5d1SDavid du Colombier if(memcmp(crypted, key, sizeof key)) 1103e12c5d1SDavid du Colombier continue; 1113e12c5d1SDavid du Colombier /* clean up memory */ 1123e12c5d1SDavid du Colombier memset(crypted, 0, sizeof crypted); 1133e12c5d1SDavid du Colombier memset(key, 0, sizeof key); 1143e12c5d1SDavid du Colombier return; 1153e12c5d1SDavid du Colombier } 1163e12c5d1SDavid du Colombier } 1173e12c5d1SDavid du Colombier 1183e12c5d1SDavid du Colombier void 1193e12c5d1SDavid du Colombier fexec(void (*execfn)(void)) 1203e12c5d1SDavid du Colombier { 1213e12c5d1SDavid du Colombier Waitmsg w; 1223e12c5d1SDavid du Colombier int pid, i; 1233e12c5d1SDavid du Colombier 1243e12c5d1SDavid du Colombier switch(pid=fork()){ 1253e12c5d1SDavid du Colombier case 0: 1263e12c5d1SDavid du Colombier (*execfn)(); 1273e12c5d1SDavid du Colombier print("init: exec error: %r\n"); 1283e12c5d1SDavid du Colombier exits("exec"); 1293e12c5d1SDavid du Colombier case -1: 1303e12c5d1SDavid du Colombier print("init: fork error: %r\n"); 1313e12c5d1SDavid du Colombier exits("fork"); 1323e12c5d1SDavid du Colombier default: 1333e12c5d1SDavid du Colombier casedefault: 1343e12c5d1SDavid du Colombier i = wait(&w); 1353e12c5d1SDavid du Colombier if(i == -1) 1363e12c5d1SDavid du Colombier print("init: wait error: %r\n"); 1373e12c5d1SDavid du Colombier else if(i != pid) 1383e12c5d1SDavid du Colombier goto casedefault; 1393e12c5d1SDavid du Colombier if(strcmp(w.msg, "exec") == 0){ 1403e12c5d1SDavid du Colombier print("init: sleeping because exec failed\n"); 1413e12c5d1SDavid du Colombier for(;;) 1423e12c5d1SDavid du Colombier sleep(1000); 1433e12c5d1SDavid du Colombier } 1443e12c5d1SDavid du Colombier if(w.msg[0]) 1453e12c5d1SDavid du Colombier print("init: rc exit status: %s\n", w.msg); 1463e12c5d1SDavid du Colombier break; 1473e12c5d1SDavid du Colombier } 1483e12c5d1SDavid du Colombier } 1493e12c5d1SDavid du Colombier 1503e12c5d1SDavid du Colombier void 1513e12c5d1SDavid du Colombier rcexec(void) 1523e12c5d1SDavid du Colombier { 1533e12c5d1SDavid du Colombier if(cmd) 1543e12c5d1SDavid du Colombier execl("/bin/rc", "rc", "-c", cmd, 0); 1553e12c5d1SDavid du Colombier else if(manual || iscpu) 1563e12c5d1SDavid du Colombier execl("/bin/rc", "rc", 0); 1573e12c5d1SDavid du Colombier else if(strcmp(service, "terminal") == 0) 158*219b2ee8SDavid du Colombier execl("/bin/rc", "rc", "-c", ". /rc/bin/termrc; home=/usr/$user; cd; . lib/profile", 0); 1593e12c5d1SDavid du Colombier else 1603e12c5d1SDavid du Colombier execl("/bin/rc", "rc", 0); 1613e12c5d1SDavid du Colombier } 1623e12c5d1SDavid du Colombier 1633e12c5d1SDavid du Colombier void 1643e12c5d1SDavid du Colombier cpustart(void) 1653e12c5d1SDavid du Colombier { 1663e12c5d1SDavid du Colombier execl("/bin/rc", "rc", "-c", "/rc/bin/cpurc", 0); 1673e12c5d1SDavid du Colombier } 1683e12c5d1SDavid du Colombier 1693e12c5d1SDavid du Colombier void 1703e12c5d1SDavid du Colombier readenv(char *name, char *val, int len) 1713e12c5d1SDavid du Colombier { 1723e12c5d1SDavid du Colombier int f; 1733e12c5d1SDavid du Colombier 1743e12c5d1SDavid du Colombier f = open(name, OREAD); 1753e12c5d1SDavid du Colombier if(f < 0){ 1763e12c5d1SDavid du Colombier print("init: can't open %s\n", name); 1773e12c5d1SDavid du Colombier return; 1783e12c5d1SDavid du Colombier } 1793e12c5d1SDavid du Colombier len = read(f, val, len-1); 1803e12c5d1SDavid du Colombier close(f); 1813e12c5d1SDavid du Colombier if(len < 0) 1823e12c5d1SDavid du Colombier print("init: can't read %s\n", name); 1833e12c5d1SDavid du Colombier else 1843e12c5d1SDavid du Colombier val[len] = '\0'; 1853e12c5d1SDavid du Colombier } 1863e12c5d1SDavid du Colombier 1873e12c5d1SDavid du Colombier void 1883e12c5d1SDavid du Colombier setenv(char *var, char *val) 1893e12c5d1SDavid du Colombier { 1903e12c5d1SDavid du Colombier int fd; 1913e12c5d1SDavid du Colombier 1923e12c5d1SDavid du Colombier fd = create(var, OWRITE, 0644); 1933e12c5d1SDavid du Colombier if(fd < 0) 1943e12c5d1SDavid du Colombier print("init: can't open %s\n", var); 1953e12c5d1SDavid du Colombier else{ 1963e12c5d1SDavid du Colombier fprint(fd, val); 1973e12c5d1SDavid du Colombier close(fd); 1983e12c5d1SDavid du Colombier } 1993e12c5d1SDavid du Colombier } 2003e12c5d1SDavid du Colombier 2013e12c5d1SDavid du Colombier void 2023e12c5d1SDavid du Colombier cpenv(char *file, char *var) 2033e12c5d1SDavid du Colombier { 2043e12c5d1SDavid du Colombier int i, fd; 2053e12c5d1SDavid du Colombier char buf[8192]; 2063e12c5d1SDavid du Colombier 2073e12c5d1SDavid du Colombier fd = open(file, OREAD); 2083e12c5d1SDavid du Colombier if(fd < 0) 2093e12c5d1SDavid du Colombier print("init: can't open %s\n", file); 2103e12c5d1SDavid du Colombier else{ 2113e12c5d1SDavid du Colombier i = read(fd, buf, sizeof(buf)-1); 2123e12c5d1SDavid du Colombier if(i <= 0) 2133e12c5d1SDavid du Colombier print("init: can't read %s: %r\n", file); 2143e12c5d1SDavid du Colombier else{ 2153e12c5d1SDavid du Colombier close(fd); 2163e12c5d1SDavid du Colombier buf[i] = 0; 2173e12c5d1SDavid du Colombier setenv(var, buf); 2183e12c5d1SDavid du Colombier } 2193e12c5d1SDavid du Colombier } 2203e12c5d1SDavid du Colombier } 2213e12c5d1SDavid du Colombier 2223e12c5d1SDavid du Colombier /* 2233e12c5d1SDavid du Colombier * clean up after /boot 2243e12c5d1SDavid du Colombier */ 2253e12c5d1SDavid du Colombier void 2263e12c5d1SDavid du Colombier closefds(void) 2273e12c5d1SDavid du Colombier { 2283e12c5d1SDavid du Colombier int i; 2293e12c5d1SDavid du Colombier 2303e12c5d1SDavid du Colombier for(i = 3; i < 30; i++) 2313e12c5d1SDavid du Colombier close(i); 2323e12c5d1SDavid du Colombier } 233