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