Annotation of 42BSD/ucb/script.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.