1*1429Sbill static char *sccsid = "@(#)init.c 4.3 (Berkeley) 10/13/80"; 21029Sbill #include <signal.h> 31029Sbill #include <sys/types.h> 41029Sbill #include <utmp.h> 51029Sbill #include <setjmp.h> 61403Sbill #include <sys/reboot.h> 71029Sbill 81029Sbill #define LINSIZ sizeof(wtmp.ut_line) 91029Sbill #define TABSIZ 100 101029Sbill #define ALL p = &itab[0]; p < &itab[TABSIZ]; p++ 111029Sbill #define EVER ;; 121029Sbill #define SCPYN(a, b) strncpy(a, b, sizeof(a)) 131029Sbill #define SCMPN(a, b) strncmp(a, b, sizeof(a)) 141029Sbill 151029Sbill char shell[] = "/bin/sh"; 161403Sbill char getty[] = "/etc/getty"; 171029Sbill char minus[] = "-"; 181029Sbill char runc[] = "/etc/rc"; 191029Sbill char ifile[] = "/etc/ttys"; 201029Sbill char utmp[] = "/etc/utmp"; 211029Sbill char wtmpf[] = "/usr/adm/wtmp"; 221029Sbill char ctty[] = "/dev/console"; 231029Sbill char dev[] = "/dev/"; 241029Sbill 251029Sbill struct utmp wtmp; 261029Sbill struct 271029Sbill { 281029Sbill char line[LINSIZ]; 291029Sbill char comn; 301029Sbill char flag; 311029Sbill } line; 321029Sbill struct tab 331029Sbill { 341029Sbill char line[LINSIZ]; 351029Sbill char comn; 361029Sbill char xflag; 371029Sbill int pid; 381029Sbill } itab[TABSIZ]; 391029Sbill 401029Sbill int fi; 411029Sbill int mergflag; 421029Sbill char tty[20]; 43*1429Sbill jmp_buf sjbuf, shutpass; 441029Sbill 451029Sbill int reset(); 461029Sbill char *strcpy(), *strcat(); 471029Sbill long lseek(); 481029Sbill 491029Sbill main() 501029Sbill { 511403Sbill register int r11; /* passed thru from boot */ 521403Sbill int howto, oldhowto; 531403Sbill 541403Sbill howto = r11; 551029Sbill setjmp(sjbuf); 561029Sbill signal(SIGTERM, reset); 571029Sbill signal(SIGSTOP, SIG_IGN); 581029Sbill signal(SIGTSTP, SIG_IGN); 591029Sbill signal(SIGTTIN, SIG_IGN); 601029Sbill signal(SIGTTOU, SIG_IGN); 611029Sbill for(EVER) { 621403Sbill oldhowto = howto; 631403Sbill howto = RB_SINGLE; 64*1429Sbill if (setjmp(shutpass) == 0) 65*1429Sbill shutdown(); 661403Sbill if (oldhowto & RB_SINGLE) 671403Sbill single(); 681403Sbill if (runcom(oldhowto) == 0) 691403Sbill continue; 701029Sbill merge(); 711029Sbill multiple(); 721029Sbill } 731029Sbill } 741029Sbill 75*1429Sbill int shutreset(); 76*1429Sbill 771029Sbill shutdown() 781029Sbill { 791029Sbill register i; 801029Sbill register struct tab *p; 811029Sbill 821029Sbill close(creat(utmp, 0644)); 831029Sbill signal(SIGHUP, SIG_IGN); 841029Sbill for(ALL) { 851029Sbill term(p); 861029Sbill p->line[0] = 0; 871029Sbill } 88*1429Sbill signal(SIGALRM, shutreset); 89*1429Sbill alarm(30); 901029Sbill for(i=0; i<5; i++) 911029Sbill kill(-1, SIGKILL); 921029Sbill while(wait((int *)0) != -1) 931029Sbill ; 941029Sbill alarm(0); 95*1429Sbill shutend(); 96*1429Sbill } 97*1429Sbill 98*1429Sbill char shutfailm[] = "WARNING: Something is hung (wont die); ps axl advised\n"; 99*1429Sbill 100*1429Sbill shutreset() 101*1429Sbill { 102*1429Sbill int status; 103*1429Sbill 104*1429Sbill if (fork() == 0) { 105*1429Sbill int ct = open(ctty, 1); 106*1429Sbill write(ct, shutfailm, sizeof (shutfailm)); 107*1429Sbill sleep(5); 108*1429Sbill exit(1); 109*1429Sbill } 110*1429Sbill sleep(5); 111*1429Sbill shutend(); 112*1429Sbill longjmp(shutpass, 1); 113*1429Sbill } 114*1429Sbill 115*1429Sbill shutend() 116*1429Sbill { 117*1429Sbill register i; 118*1429Sbill 1191029Sbill signal(SIGALRM, SIG_DFL); 1201029Sbill for(i=0; i<10; i++) 1211029Sbill close(i); 1221029Sbill } 1231029Sbill 1241029Sbill single() 1251029Sbill { 1261029Sbill register pid; 1271029Sbill 1281029Sbill pid = fork(); 1291029Sbill if(pid == 0) { 1301029Sbill /* 1311029Sbill alarm(300); 1321029Sbill */ 1331029Sbill signal(SIGTERM, SIG_DFL); 1341029Sbill signal(SIGHUP, SIG_DFL); 1351029Sbill signal(SIGALRM, SIG_DFL); 1361029Sbill open(ctty, 2); 1371029Sbill dup(0); 1381029Sbill dup(0); 1391029Sbill execl(shell, minus, (char *)0); 1401029Sbill exit(0); 1411029Sbill } 1421029Sbill while(wait((int *)0) != pid) 1431029Sbill ; 1441029Sbill } 1451029Sbill 1461403Sbill runcom(oldhowto) 1471403Sbill int oldhowto; 1481029Sbill { 1491029Sbill register pid, f; 1501403Sbill int status; 1511029Sbill 1521029Sbill pid = fork(); 1531029Sbill if(pid == 0) { 1541029Sbill open("/", 0); 1551029Sbill dup(0); 1561029Sbill dup(0); 1571403Sbill if (oldhowto & RB_SINGLE) 1581403Sbill execl(shell, shell, runc, (char *)0); 1591403Sbill else 1601403Sbill execl(shell, shell, runc, "autoboot", (char *)0); 1611403Sbill exit(1); 1621029Sbill } 1631403Sbill while(wait(&status) != pid) 1641029Sbill ; 1651403Sbill if(status) 1661403Sbill return(0); 1671029Sbill f = open(wtmpf, 1); 1681029Sbill if (f >= 0) { 1691029Sbill lseek(f, 0L, 2); 1701029Sbill SCPYN(wtmp.ut_line, "~"); 1711029Sbill SCPYN(wtmp.ut_name, "reboot"); 1721029Sbill time(&wtmp.ut_time); 1731029Sbill write(f, (char *)&wtmp, sizeof(wtmp)); 1741029Sbill close(f); 1751029Sbill } 1761403Sbill return(1); 1771029Sbill } 1781029Sbill 1791029Sbill setmerge() 1801029Sbill { 1811029Sbill 1821029Sbill signal(SIGHUP, setmerge); 1831029Sbill mergflag = 1; 1841029Sbill } 1851029Sbill 1861029Sbill multiple() 1871029Sbill { 1881029Sbill register struct tab *p; 1891029Sbill register pid; 1901029Sbill 1911029Sbill loop: 1921029Sbill mergflag = 0; 1931029Sbill signal(SIGHUP, setmerge); 1941029Sbill for(EVER) { 1951029Sbill pid = wait((int *)0); 1961029Sbill if(mergflag) { 1971029Sbill merge(); 1981029Sbill goto loop; 1991029Sbill } 2001029Sbill if(pid == -1) 2011029Sbill return; 2021029Sbill for(ALL) 2031029Sbill if(p->pid == pid || p->pid == -1) { 2041029Sbill rmut(p); 2051029Sbill dfork(p); 2061029Sbill } 2071029Sbill } 2081029Sbill } 2091029Sbill 2101029Sbill term(p) 2111029Sbill register struct tab *p; 2121029Sbill { 2131029Sbill 2141029Sbill if(p->pid != 0) { 2151029Sbill rmut(p); 2161029Sbill kill(p->pid, SIGKILL); 2171029Sbill } 2181029Sbill p->pid = 0; 2191029Sbill } 2201029Sbill 2211029Sbill rline() 2221029Sbill { 2231029Sbill register c, i; 2241029Sbill 2251029Sbill loop: 2261029Sbill c = get(); 2271029Sbill if(c < 0) 2281029Sbill return(0); 2291029Sbill if(c == 0) 2301029Sbill goto loop; 2311029Sbill line.flag = c; 2321029Sbill c = get(); 2331029Sbill if(c <= 0) 2341029Sbill goto loop; 2351029Sbill line.comn = c; 2361029Sbill SCPYN(line.line, ""); 2371029Sbill for (i=0; i<LINSIZ; i++) { 2381029Sbill c = get(); 2391029Sbill if(c <= 0) 2401029Sbill break; 2411029Sbill line.line[i] = c; 2421029Sbill } 2431029Sbill while(c > 0) 2441029Sbill c = get(); 2451029Sbill if(line.line[0] == 0) 2461029Sbill goto loop; 2471029Sbill if(line.flag == '0') 2481029Sbill goto loop; 2491029Sbill strcpy(tty, dev); 2501029Sbill strncat(tty, line.line, LINSIZ); 2511029Sbill if(access(tty, 06) < 0) 2521029Sbill goto loop; 2531029Sbill return(1); 2541029Sbill } 2551029Sbill 2561029Sbill get() 2571029Sbill { 2581029Sbill char b; 2591029Sbill 2601029Sbill if(read(fi, &b, 1) != 1) 2611029Sbill return(-1); 2621029Sbill if(b == '\n') 2631029Sbill return(0); 2641029Sbill return(b); 2651029Sbill } 2661029Sbill 2671029Sbill #define FOUND 1 2681029Sbill #define CHANGE 2 2691029Sbill 2701029Sbill merge() 2711029Sbill { 2721029Sbill register struct tab *p; 2731029Sbill 2741029Sbill fi = open(ifile, 0); 2751029Sbill if(fi < 0) 2761029Sbill return; 2771029Sbill for(ALL) 2781029Sbill p->xflag = 0; 2791029Sbill while(rline()) { 2801029Sbill for(ALL) { 2811029Sbill if (SCMPN(p->line, line.line)) 2821029Sbill continue; 2831029Sbill p->xflag |= FOUND; 2841029Sbill if(line.comn != p->comn) { 2851029Sbill p->xflag |= CHANGE; 2861029Sbill p->comn = line.comn; 2871029Sbill } 2881029Sbill goto contin1; 2891029Sbill } 2901029Sbill for(ALL) { 2911029Sbill if(p->line[0] != 0) 2921029Sbill continue; 2931029Sbill SCPYN(p->line, line.line); 2941029Sbill p->xflag |= FOUND|CHANGE; 2951029Sbill p->comn = line.comn; 2961029Sbill goto contin1; 2971029Sbill } 2981029Sbill contin1: 2991029Sbill ; 3001029Sbill } 3011029Sbill close(fi); 3021029Sbill for(ALL) { 3031029Sbill if((p->xflag&FOUND) == 0) { 3041029Sbill term(p); 3051029Sbill p->line[0] = 0; 3061029Sbill } 3071029Sbill if((p->xflag&CHANGE) != 0) { 3081029Sbill term(p); 3091029Sbill dfork(p); 3101029Sbill } 3111029Sbill } 3121029Sbill } 3131029Sbill 3141029Sbill dfork(p) 3151029Sbill struct tab *p; 3161029Sbill { 3171029Sbill register pid; 3181029Sbill 3191029Sbill pid = fork(); 3201029Sbill if(pid == 0) { 3211029Sbill signal(SIGTERM, SIG_DFL); 3221029Sbill signal(SIGHUP, SIG_IGN); 3231029Sbill strcpy(tty, dev); 3241029Sbill strncat(tty, p->line, LINSIZ); 3251029Sbill chown(tty, 0, 0); 3261029Sbill chmod(tty, 0622); 3271029Sbill open(tty, 2); 3281029Sbill vhangup(); 3291029Sbill signal(SIGHUP, SIG_DFL); 3301029Sbill open(tty, 2); 3311029Sbill close(0); 3321029Sbill dup(1); 3331029Sbill dup(0); 3341029Sbill tty[0] = p->comn; 3351029Sbill tty[1] = 0; 3361029Sbill execl(getty, minus, tty, (char *)0); 3371029Sbill exit(0); 3381029Sbill } 3391029Sbill p->pid = pid; 3401029Sbill } 3411029Sbill 3421029Sbill rmut(p) 3431029Sbill register struct tab *p; 3441029Sbill { 3451029Sbill register f; 3461029Sbill 3471029Sbill f = open(utmp, 2); 3481029Sbill if(f >= 0) { 3491029Sbill while(read(f, (char *)&wtmp, sizeof(wtmp)) == sizeof(wtmp)) { 3501029Sbill if (SCMPN(wtmp.ut_line, p->line)) 3511029Sbill continue; 3521029Sbill lseek(f, -(long)sizeof(wtmp), 1); 3531029Sbill SCPYN(wtmp.ut_name, ""); 3541029Sbill time(&wtmp.ut_time); 3551029Sbill write(f, (char *)&wtmp, sizeof(wtmp)); 3561029Sbill } 3571029Sbill close(f); 3581029Sbill } 3591029Sbill f = open(wtmpf, 1); 3601029Sbill if (f >= 0) { 3611029Sbill SCPYN(wtmp.ut_line, p->line); 3621029Sbill SCPYN(wtmp.ut_name, ""); 3631029Sbill time(&wtmp.ut_time); 3641029Sbill lseek(f, (long)0, 2); 3651029Sbill write(f, (char *)&wtmp, sizeof(wtmp)); 3661029Sbill close(f); 3671029Sbill } 3681029Sbill } 3691029Sbill 3701029Sbill reset() 3711029Sbill { 3721029Sbill longjmp(sjbuf, 1); 3731029Sbill } 374