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