|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1980 Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution and use in source and binary forms are permitted provided ! 6: * that: (1) source distributions retain this entire copyright notice and ! 7: * comment, and (2) distributions including binaries display the following ! 8: * acknowledgement: ``This product includes software developed by the ! 9: * University of California, Berkeley and its contributors'' in the ! 10: * documentation or other materials provided with the distribution and in ! 11: * all advertising materials mentioning features or use of this software. ! 12: * Neither the name of the University nor the names of its contributors may ! 13: * be used to endorse or promote products derived from this software without ! 14: * specific prior written permission. ! 15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED ! 16: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF ! 17: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 18: */ ! 19: ! 20: #ifndef lint ! 21: char copyright[] = ! 22: "@(#) Copyright (c) 1980 Regents of the University of California.\n\ ! 23: All rights reserved.\n"; ! 24: #endif /* not lint */ ! 25: ! 26: #ifndef lint ! 27: static char sccsid[] = "@(#)script.c 5.11 (Berkeley) 6/18/90"; ! 28: #endif /* not lint */ ! 29: ! 30: /* ! 31: * script ! 32: */ ! 33: #include <sys/types.h> ! 34: #include <sys/stat.h> ! 35: #include <termios.h> ! 36: #include <sys/ioctl.h> ! 37: #include <sys/time.h> ! 38: #include <sys/file.h> ! 39: #include <sys/signal.h> ! 40: #include <stdio.h> ! 41: #include <paths.h> ! 42: ! 43: char *shell; ! 44: FILE *fscript; ! 45: int master; ! 46: int slave; ! 47: int child; ! 48: int subchild; ! 49: char *fname; ! 50: ! 51: struct termios tt; ! 52: struct winsize win; ! 53: int lb; ! 54: int l; ! 55: char *line = "/dev/ptyXX"; ! 56: int aflg; ! 57: ! 58: main(argc, argv) ! 59: int argc; ! 60: char *argv[]; ! 61: { ! 62: extern char *optarg; ! 63: extern int optind; ! 64: int ch; ! 65: int finish(); ! 66: char *getenv(); ! 67: ! 68: while ((ch = getopt(argc, argv, "a")) != EOF) ! 69: switch((char)ch) { ! 70: case 'a': ! 71: aflg++; ! 72: break; ! 73: case '?': ! 74: default: ! 75: fprintf(stderr, "usage: script [-a] [file]\n"); ! 76: exit(1); ! 77: } ! 78: argc -= optind; ! 79: argv += optind; ! 80: ! 81: if (argc > 0) ! 82: fname = argv[0]; ! 83: else ! 84: fname = "typescript"; ! 85: if ((fscript = fopen(fname, aflg ? "a" : "w")) == NULL) { ! 86: perror(fname); ! 87: fail(); ! 88: } ! 89: ! 90: shell = getenv("SHELL"); ! 91: if (shell == NULL) ! 92: shell = _PATH_BSHELL; ! 93: ! 94: getmaster(); ! 95: printf("Script started, file is %s\n", fname); ! 96: fixtty(); ! 97: ! 98: (void) signal(SIGCHLD, finish); ! 99: child = fork(); ! 100: if (child < 0) { ! 101: perror("fork"); ! 102: fail(); ! 103: } ! 104: if (child == 0) { ! 105: subchild = child = fork(); ! 106: if (child < 0) { ! 107: perror("fork"); ! 108: fail(); ! 109: } ! 110: if (child) ! 111: dooutput(); ! 112: else ! 113: doshell(); ! 114: } ! 115: doinput(); ! 116: } ! 117: ! 118: doinput() ! 119: { ! 120: register int cc; ! 121: char ibuf[BUFSIZ]; ! 122: ! 123: (void) fclose(fscript); ! 124: while ((cc = read(0, ibuf, BUFSIZ)) > 0) ! 125: (void) write(master, ibuf, cc); ! 126: done(); ! 127: } ! 128: ! 129: #include <sys/wait.h> ! 130: ! 131: finish() ! 132: { ! 133: union wait status; ! 134: register int pid; ! 135: register int die = 0; ! 136: ! 137: while ((pid = wait3(&status, WNOHANG, 0)) > 0) ! 138: if (pid == child) ! 139: die = 1; ! 140: ! 141: if (die) ! 142: done(); ! 143: } ! 144: ! 145: dooutput() ! 146: { ! 147: register int cc; ! 148: time_t tvec, time(); ! 149: char obuf[BUFSIZ], *ctime(); ! 150: ! 151: (void) close(0); ! 152: tvec = time((time_t *)NULL); ! 153: fprintf(fscript, "Script started on %s", ctime(&tvec)); ! 154: for (;;) { ! 155: cc = read(master, obuf, sizeof (obuf)); ! 156: if (cc <= 0) ! 157: break; ! 158: (void) write(1, obuf, cc); ! 159: (void) fwrite(obuf, 1, cc, fscript); ! 160: } ! 161: done(); ! 162: } ! 163: ! 164: doshell() ! 165: { ! 166: int t; ! 167: ! 168: /*** ! 169: t = open(_PATH_TTY, O_RDWR); ! 170: if (t >= 0) { ! 171: (void) ioctl(t, TIOCNOTTY, (char *)0); ! 172: (void) close(t); ! 173: } ! 174: ***/ ! 175: getslave(); ! 176: (void) close(master); ! 177: (void) fclose(fscript); ! 178: (void) dup2(slave, 0); ! 179: (void) dup2(slave, 1); ! 180: (void) dup2(slave, 2); ! 181: (void) close(slave); ! 182: execl(shell, "sh", "-i", 0); ! 183: perror(shell); ! 184: fail(); ! 185: } ! 186: ! 187: fixtty() ! 188: { ! 189: struct termios rtt; ! 190: ! 191: rtt = tt; ! 192: cfmakeraw(&rtt); ! 193: rtt.c_lflag &= ~ECHO; ! 194: (void) tcsetattr(0, TCSAFLUSH, &rtt); ! 195: } ! 196: ! 197: fail() ! 198: { ! 199: ! 200: (void) kill(0, SIGTERM); ! 201: done(); ! 202: } ! 203: ! 204: done() ! 205: { ! 206: time_t tvec, time(); ! 207: char *ctime(); ! 208: ! 209: if (subchild) { ! 210: tvec = time((time_t *)NULL); ! 211: fprintf(fscript,"\nScript done on %s", ctime(&tvec)); ! 212: (void) fclose(fscript); ! 213: (void) close(master); ! 214: } else { ! 215: (void) tcsetattr(0, TCSAFLUSH, &tt); ! 216: printf("Script done, file is %s\n", fname); ! 217: } ! 218: exit(0); ! 219: } ! 220: ! 221: getmaster() ! 222: { ! 223: char *pty, *bank, *cp; ! 224: struct stat stb; ! 225: ! 226: pty = &line[strlen("/dev/ptyp")]; ! 227: for (bank = "pqrs"; *bank; bank++) { ! 228: line[strlen("/dev/pty")] = *bank; ! 229: *pty = '0'; ! 230: if (stat(line, &stb) < 0) ! 231: break; ! 232: for (cp = "0123456789abcdef"; *cp; cp++) { ! 233: *pty = *cp; ! 234: master = open(line, O_RDWR); ! 235: if (master >= 0) { ! 236: char *tp = &line[strlen("/dev/")]; ! 237: int ok; ! 238: ! 239: /* verify slave side is usable */ ! 240: *tp = 't'; ! 241: ok = access(line, R_OK|W_OK) == 0; ! 242: *tp = 'p'; ! 243: if (ok) { ! 244: (void) tcgetattr(0, &tt); ! 245: (void) ioctl(0, TIOCGWINSZ, ! 246: (char *)&win); ! 247: return; ! 248: } ! 249: (void) close(master); ! 250: } ! 251: } ! 252: } ! 253: fprintf(stderr, "Out of pty's\n"); ! 254: fail(); ! 255: } ! 256: ! 257: getslave() ! 258: { ! 259: ! 260: line[strlen("/dev/")] = 't'; ! 261: slave = open(line, O_RDWR); ! 262: if (slave < 0) { ! 263: perror(line); ! 264: fail(); ! 265: } ! 266: (void) tcsetattr(slave, TCSAFLUSH, &tt); ! 267: (void) ioctl(slave, TIOCSWINSZ, (char *)&win); ! 268: (void) setsid(); ! 269: (void) ioctl(slave, TIOCSCTTY, 0); ! 270: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.