11029Sbill #include <signal.h> 21029Sbill #include <sys/types.h> 31029Sbill #include <utmp.h> 41029Sbill #include <setjmp.h> 5*1403Sbill #include <sys/reboot.h> 61029Sbill 71029Sbill #define LINSIZ sizeof(wtmp.ut_line) 81029Sbill #define TABSIZ 100 91029Sbill #define ALL p = &itab[0]; p < &itab[TABSIZ]; p++ 101029Sbill #define EVER ;; 111029Sbill #define SCPYN(a, b) strncpy(a, b, sizeof(a)) 121029Sbill #define SCMPN(a, b) strncmp(a, b, sizeof(a)) 131029Sbill 141029Sbill char shell[] = "/bin/sh"; 15*1403Sbill char getty[] = "/etc/getty"; 161029Sbill char minus[] = "-"; 171029Sbill char runc[] = "/etc/rc"; 181029Sbill char ifile[] = "/etc/ttys"; 191029Sbill char utmp[] = "/etc/utmp"; 201029Sbill char wtmpf[] = "/usr/adm/wtmp"; 211029Sbill char ctty[] = "/dev/console"; 221029Sbill char dev[] = "/dev/"; 231029Sbill 241029Sbill struct utmp wtmp; 251029Sbill struct 261029Sbill { 271029Sbill char line[LINSIZ]; 281029Sbill char comn; 291029Sbill char flag; 301029Sbill } line; 311029Sbill struct tab 321029Sbill { 331029Sbill char line[LINSIZ]; 341029Sbill char comn; 351029Sbill char xflag; 361029Sbill int pid; 371029Sbill } itab[TABSIZ]; 381029Sbill 391029Sbill int fi; 401029Sbill int mergflag; 411029Sbill char tty[20]; 421029Sbill jmp_buf sjbuf; 431029Sbill 441029Sbill int reset(); 451029Sbill char *strcpy(), *strcat(); 461029Sbill long lseek(); 471029Sbill 481029Sbill main() 491029Sbill { 50*1403Sbill register int r11; /* passed thru from boot */ 51*1403Sbill int howto, oldhowto; 52*1403Sbill 53*1403Sbill howto = r11; 541029Sbill setjmp(sjbuf); 551029Sbill signal(SIGTERM, reset); 561029Sbill signal(SIGSTOP, SIG_IGN); 571029Sbill signal(SIGTSTP, SIG_IGN); 581029Sbill signal(SIGTTIN, SIG_IGN); 591029Sbill signal(SIGTTOU, SIG_IGN); 601029Sbill for(EVER) { 61*1403Sbill oldhowto = howto; 62*1403Sbill howto = RB_SINGLE; 631029Sbill shutdown(); 64*1403Sbill if (oldhowto & RB_SINGLE) 65*1403Sbill single(); 66*1403Sbill if (runcom(oldhowto) == 0) 67*1403Sbill continue; 681029Sbill merge(); 691029Sbill multiple(); 701029Sbill } 711029Sbill } 721029Sbill 731029Sbill shutdown() 741029Sbill { 751029Sbill register i; 761029Sbill register struct tab *p; 771029Sbill 781029Sbill close(creat(utmp, 0644)); 791029Sbill signal(SIGHUP, SIG_IGN); 801029Sbill for(ALL) { 811029Sbill term(p); 821029Sbill p->line[0] = 0; 831029Sbill } 841029Sbill signal(SIGALRM, reset); 851029Sbill alarm(60); 861029Sbill for(i=0; i<5; i++) 871029Sbill kill(-1, SIGKILL); 881029Sbill while(wait((int *)0) != -1) 891029Sbill ; 901029Sbill alarm(0); 911029Sbill signal(SIGALRM, SIG_DFL); 921029Sbill for(i=0; i<10; i++) 931029Sbill close(i); 941029Sbill } 951029Sbill 961029Sbill single() 971029Sbill { 981029Sbill register pid; 991029Sbill 1001029Sbill pid = fork(); 1011029Sbill if(pid == 0) { 1021029Sbill /* 1031029Sbill alarm(300); 1041029Sbill */ 1051029Sbill signal(SIGTERM, SIG_DFL); 1061029Sbill signal(SIGHUP, SIG_DFL); 1071029Sbill signal(SIGALRM, SIG_DFL); 1081029Sbill open(ctty, 2); 1091029Sbill dup(0); 1101029Sbill dup(0); 1111029Sbill execl(shell, minus, (char *)0); 1121029Sbill exit(0); 1131029Sbill } 1141029Sbill while(wait((int *)0) != pid) 1151029Sbill ; 1161029Sbill } 1171029Sbill 118*1403Sbill runcom(oldhowto) 119*1403Sbill int oldhowto; 1201029Sbill { 1211029Sbill register pid, f; 122*1403Sbill int status; 1231029Sbill 1241029Sbill pid = fork(); 1251029Sbill if(pid == 0) { 1261029Sbill open("/", 0); 1271029Sbill dup(0); 1281029Sbill dup(0); 129*1403Sbill if (oldhowto & RB_SINGLE) 130*1403Sbill execl(shell, shell, runc, (char *)0); 131*1403Sbill else 132*1403Sbill execl(shell, shell, runc, "autoboot", (char *)0); 133*1403Sbill exit(1); 1341029Sbill } 135*1403Sbill while(wait(&status) != pid) 1361029Sbill ; 137*1403Sbill if(status) 138*1403Sbill return(0); 1391029Sbill f = open(wtmpf, 1); 1401029Sbill if (f >= 0) { 1411029Sbill lseek(f, 0L, 2); 1421029Sbill SCPYN(wtmp.ut_line, "~"); 1431029Sbill SCPYN(wtmp.ut_name, "reboot"); 1441029Sbill time(&wtmp.ut_time); 1451029Sbill write(f, (char *)&wtmp, sizeof(wtmp)); 1461029Sbill close(f); 1471029Sbill } 148*1403Sbill return(1); 1491029Sbill } 1501029Sbill 1511029Sbill setmerge() 1521029Sbill { 1531029Sbill 1541029Sbill signal(SIGHUP, setmerge); 1551029Sbill mergflag = 1; 1561029Sbill } 1571029Sbill 1581029Sbill multiple() 1591029Sbill { 1601029Sbill register struct tab *p; 1611029Sbill register pid; 1621029Sbill 1631029Sbill loop: 1641029Sbill mergflag = 0; 1651029Sbill signal(SIGHUP, setmerge); 1661029Sbill for(EVER) { 1671029Sbill pid = wait((int *)0); 1681029Sbill if(mergflag) { 1691029Sbill merge(); 1701029Sbill goto loop; 1711029Sbill } 1721029Sbill if(pid == -1) 1731029Sbill return; 1741029Sbill for(ALL) 1751029Sbill if(p->pid == pid || p->pid == -1) { 1761029Sbill rmut(p); 1771029Sbill dfork(p); 1781029Sbill } 1791029Sbill } 1801029Sbill } 1811029Sbill 1821029Sbill term(p) 1831029Sbill register struct tab *p; 1841029Sbill { 1851029Sbill 1861029Sbill if(p->pid != 0) { 1871029Sbill rmut(p); 1881029Sbill kill(p->pid, SIGKILL); 1891029Sbill } 1901029Sbill p->pid = 0; 1911029Sbill } 1921029Sbill 1931029Sbill rline() 1941029Sbill { 1951029Sbill register c, i; 1961029Sbill 1971029Sbill loop: 1981029Sbill c = get(); 1991029Sbill if(c < 0) 2001029Sbill return(0); 2011029Sbill if(c == 0) 2021029Sbill goto loop; 2031029Sbill line.flag = c; 2041029Sbill c = get(); 2051029Sbill if(c <= 0) 2061029Sbill goto loop; 2071029Sbill line.comn = c; 2081029Sbill SCPYN(line.line, ""); 2091029Sbill for (i=0; i<LINSIZ; i++) { 2101029Sbill c = get(); 2111029Sbill if(c <= 0) 2121029Sbill break; 2131029Sbill line.line[i] = c; 2141029Sbill } 2151029Sbill while(c > 0) 2161029Sbill c = get(); 2171029Sbill if(line.line[0] == 0) 2181029Sbill goto loop; 2191029Sbill if(line.flag == '0') 2201029Sbill goto loop; 2211029Sbill strcpy(tty, dev); 2221029Sbill strncat(tty, line.line, LINSIZ); 2231029Sbill if(access(tty, 06) < 0) 2241029Sbill goto loop; 2251029Sbill return(1); 2261029Sbill } 2271029Sbill 2281029Sbill get() 2291029Sbill { 2301029Sbill char b; 2311029Sbill 2321029Sbill if(read(fi, &b, 1) != 1) 2331029Sbill return(-1); 2341029Sbill if(b == '\n') 2351029Sbill return(0); 2361029Sbill return(b); 2371029Sbill } 2381029Sbill 2391029Sbill #define FOUND 1 2401029Sbill #define CHANGE 2 2411029Sbill 2421029Sbill merge() 2431029Sbill { 2441029Sbill register struct tab *p; 2451029Sbill 2461029Sbill fi = open(ifile, 0); 2471029Sbill if(fi < 0) 2481029Sbill return; 2491029Sbill for(ALL) 2501029Sbill p->xflag = 0; 2511029Sbill while(rline()) { 2521029Sbill for(ALL) { 2531029Sbill if (SCMPN(p->line, line.line)) 2541029Sbill continue; 2551029Sbill p->xflag |= FOUND; 2561029Sbill if(line.comn != p->comn) { 2571029Sbill p->xflag |= CHANGE; 2581029Sbill p->comn = line.comn; 2591029Sbill } 2601029Sbill goto contin1; 2611029Sbill } 2621029Sbill for(ALL) { 2631029Sbill if(p->line[0] != 0) 2641029Sbill continue; 2651029Sbill SCPYN(p->line, line.line); 2661029Sbill p->xflag |= FOUND|CHANGE; 2671029Sbill p->comn = line.comn; 2681029Sbill goto contin1; 2691029Sbill } 2701029Sbill contin1: 2711029Sbill ; 2721029Sbill } 2731029Sbill close(fi); 2741029Sbill for(ALL) { 2751029Sbill if((p->xflag&FOUND) == 0) { 2761029Sbill term(p); 2771029Sbill p->line[0] = 0; 2781029Sbill } 2791029Sbill if((p->xflag&CHANGE) != 0) { 2801029Sbill term(p); 2811029Sbill dfork(p); 2821029Sbill } 2831029Sbill } 2841029Sbill } 2851029Sbill 2861029Sbill dfork(p) 2871029Sbill struct tab *p; 2881029Sbill { 2891029Sbill register pid; 2901029Sbill 2911029Sbill pid = fork(); 2921029Sbill if(pid == 0) { 2931029Sbill signal(SIGTERM, SIG_DFL); 2941029Sbill signal(SIGHUP, SIG_IGN); 2951029Sbill strcpy(tty, dev); 2961029Sbill strncat(tty, p->line, LINSIZ); 2971029Sbill chown(tty, 0, 0); 2981029Sbill chmod(tty, 0622); 2991029Sbill open(tty, 2); 3001029Sbill vhangup(); 3011029Sbill signal(SIGHUP, SIG_DFL); 3021029Sbill open(tty, 2); 3031029Sbill close(0); 3041029Sbill dup(1); 3051029Sbill dup(0); 3061029Sbill tty[0] = p->comn; 3071029Sbill tty[1] = 0; 3081029Sbill execl(getty, minus, tty, (char *)0); 3091029Sbill exit(0); 3101029Sbill } 3111029Sbill p->pid = pid; 3121029Sbill } 3131029Sbill 3141029Sbill rmut(p) 3151029Sbill register struct tab *p; 3161029Sbill { 3171029Sbill register f; 3181029Sbill 3191029Sbill f = open(utmp, 2); 3201029Sbill if(f >= 0) { 3211029Sbill while(read(f, (char *)&wtmp, sizeof(wtmp)) == sizeof(wtmp)) { 3221029Sbill if (SCMPN(wtmp.ut_line, p->line)) 3231029Sbill continue; 3241029Sbill lseek(f, -(long)sizeof(wtmp), 1); 3251029Sbill SCPYN(wtmp.ut_name, ""); 3261029Sbill time(&wtmp.ut_time); 3271029Sbill write(f, (char *)&wtmp, sizeof(wtmp)); 3281029Sbill } 3291029Sbill close(f); 3301029Sbill } 3311029Sbill f = open(wtmpf, 1); 3321029Sbill if (f >= 0) { 3331029Sbill SCPYN(wtmp.ut_line, p->line); 3341029Sbill SCPYN(wtmp.ut_name, ""); 3351029Sbill time(&wtmp.ut_time); 3361029Sbill lseek(f, (long)0, 2); 3371029Sbill write(f, (char *)&wtmp, sizeof(wtmp)); 3381029Sbill close(f); 3391029Sbill } 3401029Sbill } 3411029Sbill 3421029Sbill reset() 3431029Sbill { 3441029Sbill longjmp(sjbuf, 1); 3451029Sbill } 3461029Sbill 3471029Sbill 348