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