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