13e12c5d1SDavid du Colombier #include <u.h>
23e12c5d1SDavid du Colombier #include <libc.h>
33e12c5d1SDavid du Colombier #include <auth.h>
49a747e4fSDavid du Colombier #include <authsrv.h>
53e12c5d1SDavid du Colombier
69a747e4fSDavid du Colombier char* readenv(char*);
73e12c5d1SDavid du Colombier void setenv(char*, char*);
83e12c5d1SDavid du Colombier void cpenv(char*, char*);
93e12c5d1SDavid du Colombier void closefds(void);
103e12c5d1SDavid du Colombier void fexec(void(*)(void));
113e12c5d1SDavid du Colombier void rcexec(void);
123e12c5d1SDavid du Colombier void cpustart(void);
133e12c5d1SDavid du Colombier void pass(int);
143e12c5d1SDavid du Colombier
153e12c5d1SDavid du Colombier char *service;
163e12c5d1SDavid du Colombier char *cmd;
179a747e4fSDavid du Colombier char *cpu;
189a747e4fSDavid du Colombier char *systemname;
193e12c5d1SDavid du Colombier int manual;
203e12c5d1SDavid du Colombier int iscpu;
213e12c5d1SDavid du Colombier
223e12c5d1SDavid du Colombier void
main(int argc,char * argv[])233e12c5d1SDavid du Colombier main(int argc, char *argv[])
243e12c5d1SDavid du Colombier {
259a747e4fSDavid du Colombier char *user;
269a747e4fSDavid du Colombier int fd;
279a747e4fSDavid du Colombier char ctl[128];
283e12c5d1SDavid du Colombier
293e12c5d1SDavid du Colombier closefds();
30*8498559bSDavid du Colombier alarm(0);
313e12c5d1SDavid du Colombier
323e12c5d1SDavid du Colombier service = "cpu";
333e12c5d1SDavid du Colombier manual = 0;
343e12c5d1SDavid du Colombier ARGBEGIN{
353e12c5d1SDavid du Colombier case 'c':
363e12c5d1SDavid du Colombier service = "cpu";
373e12c5d1SDavid du Colombier break;
383e12c5d1SDavid du Colombier case 'm':
393e12c5d1SDavid du Colombier manual = 1;
403e12c5d1SDavid du Colombier break;
413e12c5d1SDavid du Colombier case 't':
423e12c5d1SDavid du Colombier service = "terminal";
433e12c5d1SDavid du Colombier break;
443e12c5d1SDavid du Colombier }ARGEND
453e12c5d1SDavid du Colombier cmd = *argv;
463e12c5d1SDavid du Colombier
479a747e4fSDavid du Colombier snprint(ctl, sizeof(ctl), "#p/%d/ctl", getpid());
489a747e4fSDavid du Colombier fd = open(ctl, OWRITE);
499a747e4fSDavid du Colombier if(fd < 0)
509a747e4fSDavid du Colombier print("init: warning: can't open %s: %r\n", ctl);
519a747e4fSDavid du Colombier else
529a747e4fSDavid du Colombier if(write(fd, "pri 10", 6) != 6)
539a747e4fSDavid du Colombier print("init: warning: can't set priority: %r\n");
549a747e4fSDavid du Colombier close(fd);
559a747e4fSDavid du Colombier
569a747e4fSDavid du Colombier cpu = readenv("#e/cputype");
573e12c5d1SDavid du Colombier setenv("#e/objtype", cpu);
583e12c5d1SDavid du Colombier setenv("#e/service", service);
593e12c5d1SDavid du Colombier cpenv("/adm/timezone/local", "#e/timezone");
609a747e4fSDavid du Colombier user = readenv("#c/user");
619a747e4fSDavid du Colombier systemname = readenv("#c/sysname");
623e12c5d1SDavid du Colombier
633e12c5d1SDavid du Colombier newns(user, 0);
643e12c5d1SDavid du Colombier iscpu = strcmp(service, "cpu")==0;
653e12c5d1SDavid du Colombier
66219b2ee8SDavid du Colombier if(iscpu && manual == 0)
673e12c5d1SDavid du Colombier fexec(cpustart);
683e12c5d1SDavid du Colombier
693e12c5d1SDavid du Colombier for(;;){
703e12c5d1SDavid du Colombier print("\ninit: starting /bin/rc\n");
713e12c5d1SDavid du Colombier fexec(rcexec);
723e12c5d1SDavid du Colombier manual = 1;
733e12c5d1SDavid du Colombier cmd = 0;
743e12c5d1SDavid du Colombier sleep(1000);
753e12c5d1SDavid du Colombier }
763e12c5d1SDavid du Colombier }
773e12c5d1SDavid du Colombier
783e12c5d1SDavid du Colombier void
pass(int fd)793e12c5d1SDavid du Colombier pass(int fd)
803e12c5d1SDavid du Colombier {
813e12c5d1SDavid du Colombier char key[DESKEYLEN];
823e12c5d1SDavid du Colombier char typed[32];
833e12c5d1SDavid du Colombier char crypted[DESKEYLEN];
843e12c5d1SDavid du Colombier int i;
853e12c5d1SDavid du Colombier
863e12c5d1SDavid du Colombier for(;;){
877dd7cddfSDavid du Colombier print("\n%s password:", systemname);
883e12c5d1SDavid du Colombier for(i=0; i<sizeof typed; i++){
893e12c5d1SDavid du Colombier if(read(0, typed+i, 1) != 1){
903e12c5d1SDavid du Colombier print("init: can't read password; insecure\n");
913e12c5d1SDavid du Colombier return;
923e12c5d1SDavid du Colombier }
933e12c5d1SDavid du Colombier if(typed[i] == '\n'){
943e12c5d1SDavid du Colombier typed[i] = 0;
953e12c5d1SDavid du Colombier break;
963e12c5d1SDavid du Colombier }
973e12c5d1SDavid du Colombier }
983e12c5d1SDavid du Colombier if(i == sizeof typed)
993e12c5d1SDavid du Colombier continue;
1003e12c5d1SDavid du Colombier if(passtokey(crypted, typed) == 0)
1013e12c5d1SDavid du Colombier continue;
1023e12c5d1SDavid du Colombier seek(fd, 0, 0);
1033e12c5d1SDavid du Colombier if(read(fd, key, DESKEYLEN) != DESKEYLEN){
1043e12c5d1SDavid du Colombier print("init: can't read key; insecure\n");
1053e12c5d1SDavid du Colombier return;
1063e12c5d1SDavid du Colombier }
1073e12c5d1SDavid du Colombier if(memcmp(crypted, key, sizeof key))
1083e12c5d1SDavid du Colombier continue;
1093e12c5d1SDavid du Colombier /* clean up memory */
1103e12c5d1SDavid du Colombier memset(crypted, 0, sizeof crypted);
1113e12c5d1SDavid du Colombier memset(key, 0, sizeof key);
1123e12c5d1SDavid du Colombier return;
1133e12c5d1SDavid du Colombier }
1143e12c5d1SDavid du Colombier }
1153e12c5d1SDavid du Colombier
1167c2ab1f1SDavid du Colombier static int gotnote;
1177c2ab1f1SDavid du Colombier
1187c2ab1f1SDavid du Colombier void
pinhead(void *,char * msg)1197c2ab1f1SDavid du Colombier pinhead(void*, char *msg)
1207c2ab1f1SDavid du Colombier {
1217c2ab1f1SDavid du Colombier gotnote = 1;
1227c2ab1f1SDavid du Colombier fprint(2, "init got note '%s'\n", msg);
1237c2ab1f1SDavid du Colombier noted(NCONT);
1247c2ab1f1SDavid du Colombier }
1257c2ab1f1SDavid du Colombier
1263e12c5d1SDavid du Colombier void
fexec(void (* execfn)(void))1273e12c5d1SDavid du Colombier fexec(void (*execfn)(void))
1283e12c5d1SDavid du Colombier {
1299a747e4fSDavid du Colombier Waitmsg *w;
1309a747e4fSDavid du Colombier int pid;
1313e12c5d1SDavid du Colombier
1323e12c5d1SDavid du Colombier switch(pid=fork()){
1333e12c5d1SDavid du Colombier case 0:
1347dd7cddfSDavid du Colombier rfork(RFNOTEG);
1353e12c5d1SDavid du Colombier (*execfn)();
1363e12c5d1SDavid du Colombier print("init: exec error: %r\n");
1373e12c5d1SDavid du Colombier exits("exec");
1383e12c5d1SDavid du Colombier case -1:
1393e12c5d1SDavid du Colombier print("init: fork error: %r\n");
1403e12c5d1SDavid du Colombier exits("fork");
1413e12c5d1SDavid du Colombier default:
1423e12c5d1SDavid du Colombier casedefault:
1437c2ab1f1SDavid du Colombier notify(pinhead);
1447c2ab1f1SDavid du Colombier gotnote = 0;
1459a747e4fSDavid du Colombier w = wait();
1469a747e4fSDavid du Colombier if(w == nil){
1477c2ab1f1SDavid du Colombier if(gotnote)
1487c2ab1f1SDavid du Colombier goto casedefault;
1493e12c5d1SDavid du Colombier print("init: wait error: %r\n");
1509a747e4fSDavid du Colombier break;
1519a747e4fSDavid du Colombier }
1529a747e4fSDavid du Colombier if(w->pid != pid){
1539a747e4fSDavid du Colombier free(w);
1543e12c5d1SDavid du Colombier goto casedefault;
1559a747e4fSDavid du Colombier }
1569a747e4fSDavid du Colombier if(strstr(w->msg, "exec error") != 0){
1579a747e4fSDavid du Colombier print("init: exit string %s\n", w->msg);
1583e12c5d1SDavid du Colombier print("init: sleeping because exec failed\n");
1599a747e4fSDavid du Colombier free(w);
1603e12c5d1SDavid du Colombier for(;;)
1613e12c5d1SDavid du Colombier sleep(1000);
1623e12c5d1SDavid du Colombier }
1639a747e4fSDavid du Colombier if(w->msg[0])
1649a747e4fSDavid du Colombier print("init: rc exit status: %s\n", w->msg);
1659a747e4fSDavid du Colombier free(w);
1663e12c5d1SDavid du Colombier break;
1673e12c5d1SDavid du Colombier }
1683e12c5d1SDavid du Colombier }
1693e12c5d1SDavid du Colombier
1703e12c5d1SDavid du Colombier void
rcexec(void)1713e12c5d1SDavid du Colombier rcexec(void)
1723e12c5d1SDavid du Colombier {
1733e12c5d1SDavid du Colombier if(cmd)
174f19e7b74SDavid du Colombier execl("/bin/rc", "rc", "-c", cmd, nil);
1753e12c5d1SDavid du Colombier else if(manual || iscpu)
176f19e7b74SDavid du Colombier execl("/bin/rc", "rc", nil);
1773e12c5d1SDavid du Colombier else if(strcmp(service, "terminal") == 0)
178f19e7b74SDavid du Colombier execl("/bin/rc", "rc", "-c", ". /rc/bin/termrc; home=/usr/$user; cd; . lib/profile", nil);
1793e12c5d1SDavid du Colombier else
180f19e7b74SDavid du Colombier execl("/bin/rc", "rc", nil);
1813e12c5d1SDavid du Colombier }
1823e12c5d1SDavid du Colombier
1833e12c5d1SDavid du Colombier void
cpustart(void)1843e12c5d1SDavid du Colombier cpustart(void)
1853e12c5d1SDavid du Colombier {
186f19e7b74SDavid du Colombier execl("/bin/rc", "rc", "-c", "/rc/bin/cpurc", nil);
1873e12c5d1SDavid du Colombier }
1883e12c5d1SDavid du Colombier
1899a747e4fSDavid du Colombier char*
readenv(char * name)1909a747e4fSDavid du Colombier readenv(char *name)
1913e12c5d1SDavid du Colombier {
1929a747e4fSDavid du Colombier int f, len;
1939a747e4fSDavid du Colombier Dir *d;
1949a747e4fSDavid du Colombier char *val;
1953e12c5d1SDavid du Colombier
1963e12c5d1SDavid du Colombier f = open(name, OREAD);
1973e12c5d1SDavid du Colombier if(f < 0){
1989a747e4fSDavid du Colombier print("init: can't open %s: %r\n", name);
1999a747e4fSDavid du Colombier return "*unknown*";
2003e12c5d1SDavid du Colombier }
2019a747e4fSDavid du Colombier d = dirfstat(f);
2029a747e4fSDavid du Colombier if(d == nil){
2039a747e4fSDavid du Colombier print("init: can't stat %s: %r\n", name);
2049a747e4fSDavid du Colombier return "*unknown*";
2059a747e4fSDavid du Colombier }
2069a747e4fSDavid du Colombier len = d->length;
2079a747e4fSDavid du Colombier free(d);
2089a747e4fSDavid du Colombier if(len == 0) /* device files can be zero length but have contents */
2099a747e4fSDavid du Colombier len = 64;
2109a747e4fSDavid du Colombier val = malloc(len+1);
2119a747e4fSDavid du Colombier if(val == nil){
2129a747e4fSDavid du Colombier print("init: can't malloc %s: %r\n", name);
2139a747e4fSDavid du Colombier return "*unknown*";
2149a747e4fSDavid du Colombier }
2159a747e4fSDavid du Colombier len = read(f, val, len);
2163e12c5d1SDavid du Colombier close(f);
2179a747e4fSDavid du Colombier if(len < 0){
2189a747e4fSDavid du Colombier print("init: can't read %s: %r\n", name);
2199a747e4fSDavid du Colombier return "*unknown*";
2209a747e4fSDavid du Colombier }else
2213e12c5d1SDavid du Colombier val[len] = '\0';
2229a747e4fSDavid du Colombier return val;
2233e12c5d1SDavid du Colombier }
2243e12c5d1SDavid du Colombier
2253e12c5d1SDavid du Colombier void
setenv(char * var,char * val)2263e12c5d1SDavid du Colombier setenv(char *var, char *val)
2273e12c5d1SDavid du Colombier {
2283e12c5d1SDavid du Colombier int fd;
2293e12c5d1SDavid du Colombier
2303e12c5d1SDavid du Colombier fd = create(var, OWRITE, 0644);
2313e12c5d1SDavid du Colombier if(fd < 0)
2323e12c5d1SDavid du Colombier print("init: can't open %s\n", var);
2333e12c5d1SDavid du Colombier else{
2343e12c5d1SDavid du Colombier fprint(fd, val);
2353e12c5d1SDavid du Colombier close(fd);
2363e12c5d1SDavid du Colombier }
2373e12c5d1SDavid du Colombier }
2383e12c5d1SDavid du Colombier
2393e12c5d1SDavid du Colombier void
cpenv(char * file,char * var)2403e12c5d1SDavid du Colombier cpenv(char *file, char *var)
2413e12c5d1SDavid du Colombier {
2423e12c5d1SDavid du Colombier int i, fd;
2433e12c5d1SDavid du Colombier char buf[8192];
2443e12c5d1SDavid du Colombier
2453e12c5d1SDavid du Colombier fd = open(file, OREAD);
2463e12c5d1SDavid du Colombier if(fd < 0)
2473e12c5d1SDavid du Colombier print("init: can't open %s\n", file);
2483e12c5d1SDavid du Colombier else{
2493e12c5d1SDavid du Colombier i = read(fd, buf, sizeof(buf)-1);
2503e12c5d1SDavid du Colombier if(i <= 0)
2513e12c5d1SDavid du Colombier print("init: can't read %s: %r\n", file);
2523e12c5d1SDavid du Colombier else{
2533e12c5d1SDavid du Colombier close(fd);
2543e12c5d1SDavid du Colombier buf[i] = 0;
2553e12c5d1SDavid du Colombier setenv(var, buf);
2563e12c5d1SDavid du Colombier }
2573e12c5d1SDavid du Colombier }
2583e12c5d1SDavid du Colombier }
2593e12c5d1SDavid du Colombier
2603e12c5d1SDavid du Colombier /*
2613e12c5d1SDavid du Colombier * clean up after /boot
2623e12c5d1SDavid du Colombier */
2633e12c5d1SDavid du Colombier void
closefds(void)2643e12c5d1SDavid du Colombier closefds(void)
2653e12c5d1SDavid du Colombier {
2663e12c5d1SDavid du Colombier int i;
2673e12c5d1SDavid du Colombier
2683e12c5d1SDavid du Colombier for(i = 3; i < 30; i++)
2693e12c5d1SDavid du Colombier close(i);
2703e12c5d1SDavid du Colombier }
271