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