1*1029Sbill static char *sccsid = "@(#)init.c 4.1 (Berkeley) 10/01/80"; 2*1029Sbill #include <signal.h> 3*1029Sbill #include <sys/types.h> 4*1029Sbill #include <utmp.h> 5*1029Sbill #include <setjmp.h> 6*1029Sbill 7*1029Sbill #define LINSIZ sizeof(wtmp.ut_line) 8*1029Sbill #define TABSIZ 100 9*1029Sbill #define ALL p = &itab[0]; p < &itab[TABSIZ]; p++ 10*1029Sbill #define EVER ;; 11*1029Sbill #define SCPYN(a, b) strncpy(a, b, sizeof(a)) 12*1029Sbill #define SCMPN(a, b) strncmp(a, b, sizeof(a)) 13*1029Sbill 14*1029Sbill char shell[] = "/bin/sh"; 15*1029Sbill char getty[] = "/etc/getty.vm"; 16*1029Sbill char minus[] = "-"; 17*1029Sbill char runc[] = "/etc/rc"; 18*1029Sbill char ifile[] = "/etc/ttys"; 19*1029Sbill char utmp[] = "/etc/utmp"; 20*1029Sbill char wtmpf[] = "/usr/adm/wtmp"; 21*1029Sbill char ctty[] = "/dev/console"; 22*1029Sbill char dev[] = "/dev/"; 23*1029Sbill 24*1029Sbill struct utmp wtmp; 25*1029Sbill struct 26*1029Sbill { 27*1029Sbill char line[LINSIZ]; 28*1029Sbill char comn; 29*1029Sbill char flag; 30*1029Sbill } line; 31*1029Sbill struct tab 32*1029Sbill { 33*1029Sbill char line[LINSIZ]; 34*1029Sbill char comn; 35*1029Sbill char xflag; 36*1029Sbill int pid; 37*1029Sbill } itab[TABSIZ]; 38*1029Sbill 39*1029Sbill int fi; 40*1029Sbill int mergflag; 41*1029Sbill char tty[20]; 42*1029Sbill jmp_buf sjbuf; 43*1029Sbill 44*1029Sbill int reset(); 45*1029Sbill char *strcpy(), *strcat(); 46*1029Sbill long lseek(); 47*1029Sbill 48*1029Sbill main() 49*1029Sbill { 50*1029Sbill setjmp(sjbuf); 51*1029Sbill signal(SIGTERM, reset); 52*1029Sbill signal(SIGSTOP, SIG_IGN); 53*1029Sbill signal(SIGTSTP, SIG_IGN); 54*1029Sbill signal(SIGTTIN, SIG_IGN); 55*1029Sbill signal(SIGTTOU, SIG_IGN); 56*1029Sbill for(EVER) { 57*1029Sbill shutdown(); 58*1029Sbill single(); 59*1029Sbill runcom(); 60*1029Sbill merge(); 61*1029Sbill multiple(); 62*1029Sbill } 63*1029Sbill } 64*1029Sbill 65*1029Sbill shutdown() 66*1029Sbill { 67*1029Sbill register i; 68*1029Sbill register struct tab *p; 69*1029Sbill 70*1029Sbill close(creat(utmp, 0644)); 71*1029Sbill signal(SIGHUP, SIG_IGN); 72*1029Sbill for(ALL) { 73*1029Sbill term(p); 74*1029Sbill p->line[0] = 0; 75*1029Sbill } 76*1029Sbill signal(SIGALRM, reset); 77*1029Sbill alarm(60); 78*1029Sbill for(i=0; i<5; i++) 79*1029Sbill kill(-1, SIGKILL); 80*1029Sbill while(wait((int *)0) != -1) 81*1029Sbill ; 82*1029Sbill alarm(0); 83*1029Sbill signal(SIGALRM, SIG_DFL); 84*1029Sbill for(i=0; i<10; i++) 85*1029Sbill close(i); 86*1029Sbill } 87*1029Sbill 88*1029Sbill single() 89*1029Sbill { 90*1029Sbill register pid; 91*1029Sbill 92*1029Sbill pid = fork(); 93*1029Sbill if(pid == 0) { 94*1029Sbill /* 95*1029Sbill alarm(300); 96*1029Sbill */ 97*1029Sbill signal(SIGTERM, SIG_DFL); 98*1029Sbill signal(SIGHUP, SIG_DFL); 99*1029Sbill signal(SIGALRM, SIG_DFL); 100*1029Sbill open(ctty, 2); 101*1029Sbill dup(0); 102*1029Sbill dup(0); 103*1029Sbill execl(shell, minus, (char *)0); 104*1029Sbill exit(0); 105*1029Sbill } 106*1029Sbill while(wait((int *)0) != pid) 107*1029Sbill ; 108*1029Sbill } 109*1029Sbill 110*1029Sbill runcom() 111*1029Sbill { 112*1029Sbill register pid, f; 113*1029Sbill 114*1029Sbill pid = fork(); 115*1029Sbill if(pid == 0) { 116*1029Sbill open("/", 0); 117*1029Sbill dup(0); 118*1029Sbill dup(0); 119*1029Sbill execl(shell, shell, runc, (char *)0); 120*1029Sbill exit(0); 121*1029Sbill } 122*1029Sbill while(wait((int *)0) != pid) 123*1029Sbill ; 124*1029Sbill f = open(wtmpf, 1); 125*1029Sbill if (f >= 0) { 126*1029Sbill lseek(f, 0L, 2); 127*1029Sbill SCPYN(wtmp.ut_line, "~"); 128*1029Sbill SCPYN(wtmp.ut_name, "reboot"); 129*1029Sbill time(&wtmp.ut_time); 130*1029Sbill write(f, (char *)&wtmp, sizeof(wtmp)); 131*1029Sbill close(f); 132*1029Sbill } 133*1029Sbill } 134*1029Sbill 135*1029Sbill setmerge() 136*1029Sbill { 137*1029Sbill 138*1029Sbill signal(SIGHUP, setmerge); 139*1029Sbill mergflag = 1; 140*1029Sbill } 141*1029Sbill 142*1029Sbill multiple() 143*1029Sbill { 144*1029Sbill register struct tab *p; 145*1029Sbill register pid; 146*1029Sbill 147*1029Sbill loop: 148*1029Sbill mergflag = 0; 149*1029Sbill signal(SIGHUP, setmerge); 150*1029Sbill for(EVER) { 151*1029Sbill pid = wait((int *)0); 152*1029Sbill if(mergflag) { 153*1029Sbill merge(); 154*1029Sbill goto loop; 155*1029Sbill } 156*1029Sbill if(pid == -1) 157*1029Sbill return; 158*1029Sbill for(ALL) 159*1029Sbill if(p->pid == pid || p->pid == -1) { 160*1029Sbill rmut(p); 161*1029Sbill dfork(p); 162*1029Sbill } 163*1029Sbill } 164*1029Sbill } 165*1029Sbill 166*1029Sbill term(p) 167*1029Sbill register struct tab *p; 168*1029Sbill { 169*1029Sbill 170*1029Sbill if(p->pid != 0) { 171*1029Sbill rmut(p); 172*1029Sbill kill(p->pid, SIGKILL); 173*1029Sbill } 174*1029Sbill p->pid = 0; 175*1029Sbill } 176*1029Sbill 177*1029Sbill rline() 178*1029Sbill { 179*1029Sbill register c, i; 180*1029Sbill 181*1029Sbill loop: 182*1029Sbill c = get(); 183*1029Sbill if(c < 0) 184*1029Sbill return(0); 185*1029Sbill if(c == 0) 186*1029Sbill goto loop; 187*1029Sbill line.flag = c; 188*1029Sbill c = get(); 189*1029Sbill if(c <= 0) 190*1029Sbill goto loop; 191*1029Sbill line.comn = c; 192*1029Sbill SCPYN(line.line, ""); 193*1029Sbill for (i=0; i<LINSIZ; i++) { 194*1029Sbill c = get(); 195*1029Sbill if(c <= 0) 196*1029Sbill break; 197*1029Sbill line.line[i] = c; 198*1029Sbill } 199*1029Sbill while(c > 0) 200*1029Sbill c = get(); 201*1029Sbill if(line.line[0] == 0) 202*1029Sbill goto loop; 203*1029Sbill if(line.flag == '0') 204*1029Sbill goto loop; 205*1029Sbill strcpy(tty, dev); 206*1029Sbill strncat(tty, line.line, LINSIZ); 207*1029Sbill if(access(tty, 06) < 0) 208*1029Sbill goto loop; 209*1029Sbill return(1); 210*1029Sbill } 211*1029Sbill 212*1029Sbill get() 213*1029Sbill { 214*1029Sbill char b; 215*1029Sbill 216*1029Sbill if(read(fi, &b, 1) != 1) 217*1029Sbill return(-1); 218*1029Sbill if(b == '\n') 219*1029Sbill return(0); 220*1029Sbill return(b); 221*1029Sbill } 222*1029Sbill 223*1029Sbill #define FOUND 1 224*1029Sbill #define CHANGE 2 225*1029Sbill 226*1029Sbill merge() 227*1029Sbill { 228*1029Sbill register struct tab *p; 229*1029Sbill 230*1029Sbill fi = open(ifile, 0); 231*1029Sbill if(fi < 0) 232*1029Sbill return; 233*1029Sbill for(ALL) 234*1029Sbill p->xflag = 0; 235*1029Sbill while(rline()) { 236*1029Sbill for(ALL) { 237*1029Sbill if (SCMPN(p->line, line.line)) 238*1029Sbill continue; 239*1029Sbill p->xflag |= FOUND; 240*1029Sbill if(line.comn != p->comn) { 241*1029Sbill p->xflag |= CHANGE; 242*1029Sbill p->comn = line.comn; 243*1029Sbill } 244*1029Sbill goto contin1; 245*1029Sbill } 246*1029Sbill for(ALL) { 247*1029Sbill if(p->line[0] != 0) 248*1029Sbill continue; 249*1029Sbill SCPYN(p->line, line.line); 250*1029Sbill p->xflag |= FOUND|CHANGE; 251*1029Sbill p->comn = line.comn; 252*1029Sbill goto contin1; 253*1029Sbill } 254*1029Sbill contin1: 255*1029Sbill ; 256*1029Sbill } 257*1029Sbill close(fi); 258*1029Sbill for(ALL) { 259*1029Sbill if((p->xflag&FOUND) == 0) { 260*1029Sbill term(p); 261*1029Sbill p->line[0] = 0; 262*1029Sbill } 263*1029Sbill if((p->xflag&CHANGE) != 0) { 264*1029Sbill term(p); 265*1029Sbill dfork(p); 266*1029Sbill } 267*1029Sbill } 268*1029Sbill } 269*1029Sbill 270*1029Sbill dfork(p) 271*1029Sbill struct tab *p; 272*1029Sbill { 273*1029Sbill register pid; 274*1029Sbill 275*1029Sbill pid = fork(); 276*1029Sbill if(pid == 0) { 277*1029Sbill signal(SIGTERM, SIG_DFL); 278*1029Sbill signal(SIGHUP, SIG_IGN); 279*1029Sbill strcpy(tty, dev); 280*1029Sbill strncat(tty, p->line, LINSIZ); 281*1029Sbill chown(tty, 0, 0); 282*1029Sbill chmod(tty, 0622); 283*1029Sbill open(tty, 2); 284*1029Sbill vhangup(); 285*1029Sbill signal(SIGHUP, SIG_DFL); 286*1029Sbill open(tty, 2); 287*1029Sbill close(0); 288*1029Sbill dup(1); 289*1029Sbill dup(0); 290*1029Sbill tty[0] = p->comn; 291*1029Sbill tty[1] = 0; 292*1029Sbill execl(getty, minus, tty, (char *)0); 293*1029Sbill exit(0); 294*1029Sbill } 295*1029Sbill p->pid = pid; 296*1029Sbill } 297*1029Sbill 298*1029Sbill rmut(p) 299*1029Sbill register struct tab *p; 300*1029Sbill { 301*1029Sbill register f; 302*1029Sbill 303*1029Sbill f = open(utmp, 2); 304*1029Sbill if(f >= 0) { 305*1029Sbill while(read(f, (char *)&wtmp, sizeof(wtmp)) == sizeof(wtmp)) { 306*1029Sbill if (SCMPN(wtmp.ut_line, p->line)) 307*1029Sbill continue; 308*1029Sbill lseek(f, -(long)sizeof(wtmp), 1); 309*1029Sbill SCPYN(wtmp.ut_name, ""); 310*1029Sbill time(&wtmp.ut_time); 311*1029Sbill write(f, (char *)&wtmp, sizeof(wtmp)); 312*1029Sbill } 313*1029Sbill close(f); 314*1029Sbill } 315*1029Sbill f = open(wtmpf, 1); 316*1029Sbill if (f >= 0) { 317*1029Sbill SCPYN(wtmp.ut_line, p->line); 318*1029Sbill SCPYN(wtmp.ut_name, ""); 319*1029Sbill time(&wtmp.ut_time); 320*1029Sbill lseek(f, (long)0, 2); 321*1029Sbill write(f, (char *)&wtmp, sizeof(wtmp)); 322*1029Sbill close(f); 323*1029Sbill } 324*1029Sbill } 325*1029Sbill 326*1029Sbill reset() 327*1029Sbill { 328*1029Sbill longjmp(sjbuf, 1); 329*1029Sbill } 330*1029Sbill 331*1029Sbill 332