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

1.1       root        1: /*
                      2:  * Copyright (c) 1980 Regents of the University of California.
                      3:  * All rights reserved.  The Berkeley software License Agreement
                      4:  * specifies the terms and conditions for redistribution.
                      5:  */
                      6: 
                      7: #ifndef lint
                      8: char copyright[] =
                      9: "@(#) Copyright (c) 1980 Regents of the University of California.\n\
                     10:  All rights reserved.\n";
                     11: #endif not lint
                     12: 
                     13: #ifndef lint
                     14: static char sccsid[] = "@(#)script.c   5.4 (Berkeley) 11/13/85";
                     15: #endif not lint
                     16: 
                     17: /*
                     18:  * script
                     19:  */
                     20: #include <stdio.h>
                     21: #include <signal.h>
                     22: #include <sys/types.h>
                     23: #include <sys/stat.h>
                     24: #include <sys/ioctl.h>
                     25: #include <sgtty.h>
                     26: #include <sys/time.h>
                     27: #include <sys/file.h>
                     28: 
                     29: char   *getenv();
                     30: char   *ctime();
                     31: char   *shell;
                     32: FILE   *fscript;
                     33: int    master;
                     34: int    slave;
                     35: int    child;
                     36: int    subchild;
                     37: char   *fname = "typescript";
                     38: int    finish();
                     39: 
                     40: struct sgttyb b;
                     41: struct tchars tc;
                     42: struct ltchars lc;
                     43: struct winsize win;
                     44: int    lb;
                     45: int    l;
                     46: char   *line = "/dev/ptyXX";
                     47: int    aflg;
                     48: 
                     49: main(argc, argv)
                     50:        int argc;
                     51:        char *argv[];
                     52: {
                     53: 
                     54:        shell = getenv("SHELL");
                     55:        if (shell == 0)
                     56:                shell = "/bin/sh";
                     57:        argc--, argv++;
                     58:        while (argc > 0 && argv[0][0] == '-') {
                     59:                switch (argv[0][1]) {
                     60: 
                     61:                case 'a':
                     62:                        aflg++;
                     63:                        break;
                     64: 
                     65:                default:
                     66:                        fprintf(stderr,
                     67:                            "usage: script [ -a ] [ typescript ]\n");
                     68:                        exit(1);
                     69:                }
                     70:                argc--, argv++;
                     71:        }
                     72:        if (argc > 0)
                     73:                fname = argv[0];
                     74:        if ((fscript = fopen(fname, aflg ? "a" : "w")) == NULL) {
                     75:                perror(fname);
                     76:                fail();
                     77:        }
                     78:        getmaster();
                     79:        printf("Script started, file is %s\n", fname);
                     80:        fixtty();
                     81: 
                     82:        (void) signal(SIGCHLD, finish);
                     83:        child = fork();
                     84:        if (child < 0) {
                     85:                perror("fork");
                     86:                fail();
                     87:        }
                     88:        if (child == 0) {
                     89:                subchild = child = fork();
                     90:                if (child < 0) {
                     91:                        perror("fork");
                     92:                        fail();
                     93:                }
                     94:                if (child)
                     95:                        dooutput();
                     96:                else
                     97:                        doshell();
                     98:        }
                     99:        doinput();
                    100: }
                    101: 
                    102: doinput()
                    103: {
                    104:        char ibuf[BUFSIZ];
                    105:        int cc;
                    106: 
                    107:        (void) fclose(fscript);
                    108:        while ((cc = read(0, ibuf, BUFSIZ)) > 0)
                    109:                (void) write(master, ibuf, cc);
                    110:        done();
                    111: }
                    112: 
                    113: #include <sys/wait.h>
                    114: 
                    115: finish()
                    116: {
                    117:        union wait status;
                    118:        register int pid;
                    119:        register int die = 0;
                    120: 
                    121:        while ((pid = wait3(&status, WNOHANG, 0)) > 0)
                    122:                if (pid == child)
                    123:                        die = 1;
                    124: 
                    125:        if (die)
                    126:                done();
                    127: }
                    128: 
                    129: dooutput()
                    130: {
                    131:        time_t tvec;
                    132:        char obuf[BUFSIZ];
                    133:        int cc;
                    134: 
                    135:        (void) close(0);
                    136:        tvec = time((time_t *)0);
                    137:        fprintf(fscript, "Script started on %s", ctime(&tvec));
                    138:        for (;;) {
                    139:                cc = read(master, obuf, sizeof (obuf));
                    140:                if (cc <= 0)
                    141:                        break;
                    142:                (void) write(1, obuf, cc);
                    143:                (void) fwrite(obuf, 1, cc, fscript);
                    144:        }
                    145:        done();
                    146: }
                    147: 
                    148: doshell()
                    149: {
                    150:        int t;
                    151: 
                    152:        t = open("/dev/tty", O_RDWR);
                    153:        if (t >= 0) {
                    154:                (void) ioctl(t, TIOCNOTTY, (char *)0);
                    155:                (void) close(t);
                    156:        }
                    157:        getslave();
                    158:        (void) close(master);
                    159:        (void) fclose(fscript);
                    160:        (void) dup2(slave, 0);
                    161:        (void) dup2(slave, 1);
                    162:        (void) dup2(slave, 2);
                    163:        (void) close(slave);
                    164:        execl(shell, "sh", "-i", 0);
                    165:        perror(shell);
                    166:        fail();
                    167: }
                    168: 
                    169: fixtty()
                    170: {
                    171:        struct sgttyb sbuf;
                    172: 
                    173:        sbuf = b;
                    174:        sbuf.sg_flags |= RAW;
                    175:        sbuf.sg_flags &= ~ECHO;
                    176:        (void) ioctl(0, TIOCSETP, (char *)&sbuf);
                    177: }
                    178: 
                    179: fail()
                    180: {
                    181: 
                    182:        (void) kill(0, SIGTERM);
                    183:        done();
                    184: }
                    185: 
                    186: done()
                    187: {
                    188:        time_t tvec;
                    189: 
                    190:        if (subchild) {
                    191:                tvec = time((time_t *)0);
                    192:                fprintf(fscript,"\nscript done on %s", ctime(&tvec));
                    193:                (void) fclose(fscript);
                    194:                (void) close(master);
                    195:        } else {
                    196:                (void) ioctl(0, TIOCSETP, (char *)&b);
                    197:                printf("Script done, file is %s\n", fname);
                    198:        }
                    199:        exit(0);
                    200: }
                    201: 
                    202: getmaster()
                    203: {
                    204:        char *pty, *bank, *cp;
                    205:        struct stat stb;
                    206: 
                    207:        pty = &line[strlen("/dev/ptyp")];
                    208:        for (bank = "pqrs"; *bank; bank++) {
                    209:                line[strlen("/dev/pty")] = *bank;
                    210:                *pty = '0';
                    211:                if (stat(line, &stb) < 0)
                    212:                        break;
                    213:                for (cp = "0123456789abcdef"; *cp; cp++) {
                    214:                        *pty = *cp;
                    215:                        master = open(line, O_RDWR);
                    216:                        if (master >= 0) {
                    217:                                char *tp = &line[strlen("/dev/")];
                    218:                                int ok;
                    219: 
                    220:                                /* verify slave side is usable */
                    221:                                *tp = 't';
                    222:                                ok = access(line, R_OK|W_OK) == 0;
                    223:                                *tp = 'p';
                    224:                                if (ok) {
                    225:                                    (void) ioctl(0, TIOCGETP, (char *)&b);
                    226:                                    (void) ioctl(0, TIOCGETC, (char *)&tc);
                    227:                                    (void) ioctl(0, TIOCGETD, (char *)&l);
                    228:                                    (void) ioctl(0, TIOCGLTC, (char *)&lc);
                    229:                                    (void) ioctl(0, TIOCLGET, (char *)&lb);
                    230:                                    (void) ioctl(0, TIOCGWINSZ, (char *)&win);
                    231:                                        return;
                    232:                                }
                    233:                                (void) close(master);
                    234:                        }
                    235:                }
                    236:        }
                    237:        fprintf(stderr, "Out of pty's\n");
                    238:        fail();
                    239: }
                    240: 
                    241: getslave()
                    242: {
                    243: 
                    244:        line[strlen("/dev/")] = 't';
                    245:        slave = open(line, O_RDWR);
                    246:        if (slave < 0) {
                    247:                perror(line);
                    248:                fail();
                    249:        }
                    250:        (void) ioctl(slave, TIOCSETP, (char *)&b);
                    251:        (void) ioctl(slave, TIOCSETC, (char *)&tc);
                    252:        (void) ioctl(slave, TIOCSLTC, (char *)&lc);
                    253:        (void) ioctl(slave, TIOCLSET, (char *)&lb);
                    254:        (void) ioctl(slave, TIOCSETD, (char *)&l);
                    255:        (void) ioctl(slave, TIOCSWINSZ, (char *)&win);
                    256: }

unix.superglobalmegacorp.com

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