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