|
|
1.1 ! root 1: #ifndef lint ! 2: static char *sccsid = "@(#)script.c 4.5 (Berkeley) 83/07/02"; ! 3: #endif ! 4: ! 5: /* ! 6: * script ! 7: */ ! 8: #include <stdio.h> ! 9: #include <signal.h> ! 10: #include <sys/types.h> ! 11: #include <sys/stat.h> ! 12: #include <sys/ioctl.h> ! 13: #include <sgtty.h> ! 14: #include <sys/time.h> ! 15: ! 16: char *getenv(); ! 17: char *ctime(); ! 18: char *shell; ! 19: FILE *fscript; ! 20: int master; ! 21: int slave; ! 22: int child; ! 23: char *fname = "typescript"; ! 24: int finish(); ! 25: ! 26: struct sgttyb b; ! 27: struct tchars tc; ! 28: struct ltchars lc; ! 29: int lb; ! 30: int l; ! 31: char *line = "/dev/ptyXX"; ! 32: int aflg; ! 33: ! 34: main(argc, argv) ! 35: int argc; ! 36: char *argv[]; ! 37: { ! 38: int f; ! 39: ! 40: shell = getenv("SHELL"); ! 41: if (shell == 0) ! 42: shell = "/bin/sh"; ! 43: argc--, argv++; ! 44: while (argc > 0 && argv[0][0] == '-') { ! 45: switch (argv[0][1]) { ! 46: ! 47: case 'a': ! 48: aflg++; ! 49: break; ! 50: ! 51: default: ! 52: fprintf(stderr, ! 53: "usage: script [ -a ] [ typescript ]\n"); ! 54: exit(1); ! 55: } ! 56: argc--, argv++; ! 57: } ! 58: if (argc > 0) ! 59: fname = argv[0]; ! 60: if ((fscript = fopen(fname, aflg ? "a" : "w")) == NULL) { ! 61: perror(fname); ! 62: fail(); ! 63: } ! 64: getmaster(); ! 65: printf("Script started, file is %s\n", fname); ! 66: fixtty(); ! 67: ! 68: (void) signal(SIGCHLD, finish); ! 69: child = fork(); ! 70: if (child < 0) { ! 71: perror("fork"); ! 72: fail(); ! 73: } ! 74: if (child == 0) { ! 75: f = fork(); ! 76: if (f < 0) { ! 77: perror("fork"); ! 78: fail(); ! 79: } ! 80: if (f) ! 81: dooutput(); ! 82: else ! 83: doshell(); ! 84: } ! 85: doinput(); ! 86: } ! 87: ! 88: doinput() ! 89: { ! 90: char ibuf[BUFSIZ]; ! 91: int cc; ! 92: ! 93: (void) fclose(fscript); ! 94: while ((cc = read(0, ibuf, BUFSIZ)) > 0) ! 95: (void) write(master, ibuf, cc); ! 96: done(); ! 97: } ! 98: ! 99: #include <sys/wait.h> ! 100: ! 101: finish() ! 102: { ! 103: union wait status; ! 104: ! 105: if (wait3(&status, WNOHANG, 0) != child) ! 106: return; ! 107: done(); ! 108: } ! 109: ! 110: dooutput() ! 111: { ! 112: time_t tvec; ! 113: char obuf[BUFSIZ]; ! 114: int cc; ! 115: ! 116: (void) close(0); ! 117: tvec = time((time_t *)0); ! 118: fprintf(fscript, "Script started on %s", ctime(&tvec)); ! 119: for (;;) { ! 120: cc = read(master, obuf, sizeof (obuf)); ! 121: if (cc <= 0) ! 122: break; ! 123: (void) write(1, obuf, cc); ! 124: (void) fwrite(obuf, 1, cc, fscript); ! 125: } ! 126: tvec = time((time_t *)0); ! 127: fprintf(fscript,"\nscript done on %s", ctime(&tvec)); ! 128: (void) fclose(fscript); ! 129: (void) close(master); ! 130: exit(0); ! 131: } ! 132: ! 133: doshell() ! 134: { ! 135: int t; ! 136: ! 137: t = open("/dev/tty", 2); ! 138: if (t >= 0) { ! 139: ioctl(t, TIOCNOTTY, (char *)0); ! 140: (void) close(t); ! 141: } ! 142: getslave(); ! 143: (void) close(master); ! 144: (void) fclose(fscript); ! 145: dup2(slave, 0); ! 146: dup2(slave, 1); ! 147: dup2(slave, 2); ! 148: (void) close(slave); ! 149: execl(shell, "sh", "-i", 0); ! 150: perror(shell); ! 151: fail(); ! 152: } ! 153: ! 154: fixtty() ! 155: { ! 156: struct sgttyb sbuf; ! 157: ! 158: sbuf = b; ! 159: sbuf.sg_flags |= RAW; ! 160: sbuf.sg_flags &= ~ECHO; ! 161: ioctl(0, TIOCSETP, (char *)&sbuf); ! 162: } ! 163: ! 164: fail() ! 165: { ! 166: ! 167: (void) kill(0, SIGTERM); ! 168: done(); ! 169: } ! 170: ! 171: done() ! 172: { ! 173: ! 174: ioctl(0, TIOCSETP, (char *)&b); ! 175: printf("Script done, file is %s\n", fname); ! 176: exit(0); ! 177: } ! 178: ! 179: getmaster() ! 180: { ! 181: char c; ! 182: struct stat stb; ! 183: int i; ! 184: ! 185: for (c = 'p'; c <= 's'; c++) { ! 186: line[strlen("/dev/pty")] = c; ! 187: line[strlen("/dev/ptyp")] = '0'; ! 188: if (stat(line, &stb) < 0) ! 189: break; ! 190: for (i = 0; i < 16; i++) { ! 191: line[strlen("/dev/ptyp")] = "0123456789abcdef"[i]; ! 192: master = open(line, 2); ! 193: if (master >= 0) { ! 194: ioctl(0, TIOCGETP, (char *)&b); ! 195: ioctl(0, TIOCGETC, (char *)&tc); ! 196: ioctl(0, TIOCGETD, (char *)&l); ! 197: ioctl(0, TIOCGLTC, (char *)&lc); ! 198: ioctl(0, TIOCLGET, (char *)&lb); ! 199: return; ! 200: } ! 201: } ! 202: } ! 203: fprintf(stderr, "Out of pty's\n"); ! 204: fail(); ! 205: } ! 206: ! 207: getslave() ! 208: { ! 209: ! 210: line[strlen("/dev/")] = 't'; ! 211: slave = open(line, 2); ! 212: if (slave < 0) { ! 213: perror(line); ! 214: fail(); ! 215: } ! 216: ioctl(slave, TIOCSETP, (char *)&b); ! 217: ioctl(slave, TIOCSETC, (char *)&tc); ! 218: ioctl(slave, TIOCSLTC, (char *)&lc); ! 219: ioctl(slave, TIOCLSET, (char *)&lb); ! 220: ioctl(slave, TIOCSETD, (char *)&l); ! 221: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.