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 sysname[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", sysname, sizeof sysname); 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/sysname", sysname, sizeof sysname); 89 print("\n%s password:", sysname); 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 (*execfn)(); 127 print("init: exec error: %r\n"); 128 exits("exec"); 129 case -1: 130 print("init: fork error: %r\n"); 131 exits("fork"); 132 default: 133 casedefault: 134 i = wait(&w); 135 if(i == -1) 136 print("init: wait error: %r\n"); 137 else if(i != pid) 138 goto casedefault; 139 if(strcmp(w.msg, "exec") == 0){ 140 print("init: sleeping because exec failed\n"); 141 for(;;) 142 sleep(1000); 143 } 144 if(w.msg[0]) 145 print("init: rc exit status: %s\n", w.msg); 146 break; 147 } 148 } 149 150 void 151 rcexec(void) 152 { 153 if(cmd) 154 execl("/bin/rc", "rc", "-c", cmd, 0); 155 else if(manual || iscpu) 156 execl("/bin/rc", "rc", 0); 157 else if(strcmp(service, "terminal") == 0) 158 execl("/bin/rc", "rc", "-c", ". /rc/bin/termrc; home=/usr/$user; cd; . lib/profile", 0); 159 else 160 execl("/bin/rc", "rc", 0); 161 } 162 163 void 164 cpustart(void) 165 { 166 execl("/bin/rc", "rc", "-c", "/rc/bin/cpurc", 0); 167 } 168 169 void 170 readenv(char *name, char *val, int len) 171 { 172 int f; 173 174 f = open(name, OREAD); 175 if(f < 0){ 176 print("init: can't open %s\n", name); 177 return; 178 } 179 len = read(f, val, len-1); 180 close(f); 181 if(len < 0) 182 print("init: can't read %s\n", name); 183 else 184 val[len] = '\0'; 185 } 186 187 void 188 setenv(char *var, char *val) 189 { 190 int fd; 191 192 fd = create(var, OWRITE, 0644); 193 if(fd < 0) 194 print("init: can't open %s\n", var); 195 else{ 196 fprint(fd, val); 197 close(fd); 198 } 199 } 200 201 void 202 cpenv(char *file, char *var) 203 { 204 int i, fd; 205 char buf[8192]; 206 207 fd = open(file, OREAD); 208 if(fd < 0) 209 print("init: can't open %s\n", file); 210 else{ 211 i = read(fd, buf, sizeof(buf)-1); 212 if(i <= 0) 213 print("init: can't read %s: %r\n", file); 214 else{ 215 close(fd); 216 buf[i] = 0; 217 setenv(var, buf); 218 } 219 } 220 } 221 222 /* 223 * clean up after /boot 224 */ 225 void 226 closefds(void) 227 { 228 int i; 229 230 for(i = 3; i < 30; i++) 231 close(i); 232 } 233