1 #include <u.h> 2 #include <libc.h> 3 #include <auth.h> 4 5 void readenv(char*, char*, int); 6 void setenv(char*, char*); 7 void cpenv(char*, char*); 8 void closefds(void); 9 void fexec(void(*)(void)); 10 void rcexec(void); 11 void cpustart(void); 12 void pass(int); 13 14 char *service; 15 char *cmd; 16 char cpu[NAMELEN]; 17 char systemname[NAMELEN]; 18 int manual; 19 int iscpu; 20 21 void 22 main(int argc, char *argv[]) 23 { 24 char user[NAMELEN]; 25 int consctl, key; 26 27 closefds(); 28 29 service = "cpu"; 30 manual = 0; 31 ARGBEGIN{ 32 case 'c': 33 service = "cpu"; 34 break; 35 case 'm': 36 manual = 1; 37 break; 38 case 't': 39 service = "terminal"; 40 break; 41 }ARGEND 42 cmd = *argv; 43 44 readenv("#e/cputype", cpu, sizeof cpu); 45 setenv("#e/objtype", cpu); 46 setenv("#e/service", service); 47 cpenv("/adm/timezone/local", "#e/timezone"); 48 readenv("#c/user", user, sizeof user); 49 readenv("#c/sysname", systemname, sizeof systemname); 50 51 newns(user, 0); 52 53 iscpu = strcmp(service, "cpu")==0; 54 55 if(iscpu && manual == 0) 56 fexec(cpustart); 57 58 for(;;){ 59 if(iscpu){ 60 consctl = open("#c/consctl", OWRITE); 61 key = open("#c/key", OREAD); 62 if(consctl<0 || key<0 || write(consctl, "rawon", 5) != 5) 63 print("init: can't check password; insecure\n"); 64 else{ 65 /*pass(key);*/ 66 write(consctl, "rawoff", 6); 67 } 68 close(consctl); 69 close(key); 70 } 71 print("\ninit: starting /bin/rc\n"); 72 fexec(rcexec); 73 manual = 1; 74 cmd = 0; 75 sleep(1000); 76 } 77 } 78 79 void 80 pass(int fd) 81 { 82 char key[DESKEYLEN]; 83 char typed[32]; 84 char crypted[DESKEYLEN]; 85 int i; 86 87 for(;;){ 88 readenv("#c/systemname", systemname, sizeof systemname); 89 print("\n%s password:", systemname); 90 for(i=0; i<sizeof typed; i++){ 91 if(read(0, typed+i, 1) != 1){ 92 print("init: can't read password; insecure\n"); 93 return; 94 } 95 if(typed[i] == '\n'){ 96 typed[i] = 0; 97 break; 98 } 99 } 100 if(i == sizeof typed) 101 continue; 102 if(passtokey(crypted, typed) == 0) 103 continue; 104 seek(fd, 0, 0); 105 if(read(fd, key, DESKEYLEN) != DESKEYLEN){ 106 print("init: can't read key; insecure\n"); 107 return; 108 } 109 if(memcmp(crypted, key, sizeof key)) 110 continue; 111 /* clean up memory */ 112 memset(crypted, 0, sizeof crypted); 113 memset(key, 0, sizeof key); 114 return; 115 } 116 } 117 118 void 119 fexec(void (*execfn)(void)) 120 { 121 Waitmsg w; 122 int pid, i; 123 124 switch(pid=fork()){ 125 case 0: 126 rfork(RFNOTEG); 127 (*execfn)(); 128 print("init: exec error: %r\n"); 129 exits("exec"); 130 case -1: 131 print("init: fork error: %r\n"); 132 exits("fork"); 133 default: 134 casedefault: 135 i = wait(&w); 136 if(i == -1) 137 print("init: wait error: %r\n"); 138 else if(i != pid) 139 goto casedefault; 140 if(strcmp(w.msg, "exec") == 0){ 141 print("init: sleeping because exec failed\n"); 142 for(;;) 143 sleep(1000); 144 } 145 if(w.msg[0]) 146 print("init: rc exit status: %s\n", w.msg); 147 break; 148 } 149 } 150 151 void 152 rcexec(void) 153 { 154 if(cmd) 155 execl("/bin/rc", "rc", "-c", cmd, 0); 156 else if(manual || iscpu) 157 execl("/bin/rc", "rc", 0); 158 else if(strcmp(service, "terminal") == 0) 159 execl("/bin/rc", "rc", "-c", ". /rc/bin/termrc; home=/usr/$user; cd; . lib/profile", 0); 160 else 161 execl("/bin/rc", "rc", 0); 162 } 163 164 void 165 cpustart(void) 166 { 167 execl("/bin/rc", "rc", "-c", "/rc/bin/cpurc", 0); 168 } 169 170 void 171 readenv(char *name, char *val, int len) 172 { 173 int f; 174 175 f = open(name, OREAD); 176 if(f < 0){ 177 print("init: can't open %s\n", name); 178 return; 179 } 180 len = read(f, val, len-1); 181 close(f); 182 if(len < 0) 183 print("init: can't read %s\n", name); 184 else 185 val[len] = '\0'; 186 } 187 188 void 189 setenv(char *var, char *val) 190 { 191 int fd; 192 193 fd = create(var, OWRITE, 0644); 194 if(fd < 0) 195 print("init: can't open %s\n", var); 196 else{ 197 fprint(fd, val); 198 close(fd); 199 } 200 } 201 202 void 203 cpenv(char *file, char *var) 204 { 205 int i, fd; 206 char buf[8192]; 207 208 fd = open(file, OREAD); 209 if(fd < 0) 210 print("init: can't open %s\n", file); 211 else{ 212 i = read(fd, buf, sizeof(buf)-1); 213 if(i <= 0) 214 print("init: can't read %s: %r\n", file); 215 else{ 216 close(fd); 217 buf[i] = 0; 218 setenv(var, buf); 219 } 220 } 221 } 222 223 /* 224 * clean up after /boot 225 */ 226 void 227 closefds(void) 228 { 229 int i; 230 231 for(i = 3; i < 30; i++) 232 close(i); 233 } 234