|
|
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: ! 8: #define LINSIZ sizeof(wtmp.ut_line) ! 9: #define TABSIZ 100 ! 10: #define ALL p = &itab[0]; p < &itab[TABSIZ]; p++ ! 11: #define EVER ;; ! 12: #define SCPYN(a, b) strncpy(a, b, sizeof(a)) ! 13: #define SCMPN(a, b) strncmp(a, b, sizeof(a)) ! 14: ! 15: char shell[] = "/bin/sh"; ! 16: char getty[] = "/etc/getty"; ! 17: char minus[] = "-"; ! 18: char runc[] = "/etc/rc"; ! 19: char ifile[] = "/etc/ttys"; ! 20: char utmp[] = "/etc/utmp"; ! 21: char wtmpf[] = "/usr/adm/wtmp"; ! 22: char ctty[] = "/dev/console"; ! 23: char dev[] = "/dev/"; ! 24: ! 25: struct utmp wtmp; ! 26: struct ! 27: { ! 28: char line[LINSIZ]; ! 29: char comn; ! 30: char flag; ! 31: } line; ! 32: struct tab ! 33: { ! 34: char line[LINSIZ]; ! 35: char comn; ! 36: char xflag; ! 37: int pid; ! 38: } itab[TABSIZ]; ! 39: ! 40: int fi; ! 41: int mergflag; ! 42: char tty[20]; ! 43: jmp_buf sjbuf, shutpass; ! 44: ! 45: int reset(); ! 46: char *strcpy(), *strcat(); ! 47: long lseek(); ! 48: ! 49: main() ! 50: { ! 51: register int r11; /* passed thru from boot */ ! 52: int howto, oldhowto; ! 53: ! 54: howto = r11; ! 55: setjmp(sjbuf); ! 56: signal(SIGTERM, reset); ! 57: signal(SIGSTOP, SIG_IGN); ! 58: signal(SIGTSTP, SIG_IGN); ! 59: signal(SIGTTIN, SIG_IGN); ! 60: signal(SIGTTOU, SIG_IGN); ! 61: for(EVER) { ! 62: oldhowto = howto; ! 63: howto = RB_SINGLE; ! 64: if (setjmp(shutpass) == 0) ! 65: shutdown(); ! 66: if (oldhowto & RB_SINGLE) ! 67: single(); ! 68: if (runcom(oldhowto) == 0) ! 69: continue; ! 70: merge(); ! 71: multiple(); ! 72: } ! 73: } ! 74: ! 75: int shutreset(); ! 76: ! 77: shutdown() ! 78: { ! 79: register i; ! 80: register struct tab *p; ! 81: ! 82: close(creat(utmp, 0644)); ! 83: signal(SIGHUP, SIG_IGN); ! 84: for(ALL) { ! 85: term(p); ! 86: p->line[0] = 0; ! 87: } ! 88: signal(SIGALRM, shutreset); ! 89: alarm(30); ! 90: for(i=0; i<5; i++) ! 91: kill(-1, SIGKILL); ! 92: while(wait((int *)0) != -1) ! 93: ; ! 94: alarm(0); ! 95: shutend(); ! 96: } ! 97: ! 98: char shutfailm[] = "WARNING: Something is hung (wont die); ps axl advised\n"; ! 99: ! 100: shutreset() ! 101: { ! 102: int status; ! 103: ! 104: if (fork() == 0) { ! 105: int ct = open(ctty, 1); ! 106: write(ct, shutfailm, sizeof (shutfailm)); ! 107: sleep(5); ! 108: exit(1); ! 109: } ! 110: sleep(5); ! 111: shutend(); ! 112: longjmp(shutpass, 1); ! 113: } ! 114: ! 115: shutend() ! 116: { ! 117: register i; ! 118: ! 119: signal(SIGALRM, SIG_DFL); ! 120: for(i=0; i<10; i++) ! 121: close(i); ! 122: } ! 123: ! 124: single() ! 125: { ! 126: register pid; ! 127: ! 128: pid = fork(); ! 129: if(pid == 0) { ! 130: /* ! 131: alarm(300); ! 132: */ ! 133: signal(SIGTERM, SIG_DFL); ! 134: signal(SIGHUP, SIG_DFL); ! 135: signal(SIGALRM, SIG_DFL); ! 136: open(ctty, 2); ! 137: dup(0); ! 138: dup(0); ! 139: execl(shell, minus, (char *)0); ! 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: open("/", 0); ! 155: dup(0); ! 156: dup(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_IGN); ! 323: strcpy(tty, dev); ! 324: strncat(tty, p->line, LINSIZ); ! 325: chown(tty, 0, 0); ! 326: chmod(tty, 0622); ! 327: open(tty, 2); ! 328: vhangup(); ! 329: signal(SIGHUP, SIG_DFL); ! 330: open(tty, 2); ! 331: close(0); ! 332: dup(1); ! 333: dup(0); ! 334: tty[0] = p->comn; ! 335: tty[1] = 0; ! 336: execl(getty, minus, tty, (char *)0); ! 337: exit(0); ! 338: } ! 339: p->pid = pid; ! 340: } ! 341: ! 342: rmut(p) ! 343: register struct tab *p; ! 344: { ! 345: register f; ! 346: ! 347: f = open(utmp, 2); ! 348: if(f >= 0) { ! 349: while(read(f, (char *)&wtmp, sizeof(wtmp)) == sizeof(wtmp)) { ! 350: if (SCMPN(wtmp.ut_line, p->line)) ! 351: continue; ! 352: lseek(f, -(long)sizeof(wtmp), 1); ! 353: SCPYN(wtmp.ut_name, ""); ! 354: time(&wtmp.ut_time); ! 355: write(f, (char *)&wtmp, sizeof(wtmp)); ! 356: } ! 357: close(f); ! 358: } ! 359: f = open(wtmpf, 1); ! 360: if (f >= 0) { ! 361: SCPYN(wtmp.ut_line, p->line); ! 362: SCPYN(wtmp.ut_name, ""); ! 363: time(&wtmp.ut_time); ! 364: lseek(f, (long)0, 2); ! 365: write(f, (char *)&wtmp, sizeof(wtmp)); ! 366: close(f); ! 367: } ! 368: } ! 369: ! 370: reset() ! 371: { ! 372: longjmp(sjbuf, 1); ! 373: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.