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

Defined functions

doinput defined in line 103; used 1 times
done defined in line 187; used 4 times
dooutput defined in line 130; used 1 times
  • in line 96
doshell defined in line 149; used 1 times
  • in line 98
fail defined in line 180; used 6 times
finish defined in line 116; used 2 times
fixtty defined in line 170; used 1 times
  • in line 81
getmaster defined in line 203; used 1 times
  • in line 79
getslave defined in line 242; used 1 times
main defined in line 50; never used

Defined variables

aflg defined in line 48; used 2 times
b defined in line 41; used 4 times
child defined in line 36; used 7 times
copyright defined in line 8; never used
fname defined in line 38; used 5 times
l defined in line 46; used 2 times
lb defined in line 45; used 2 times
lc defined in line 43; used 2 times
line defined in line 47; used 9 times
master defined in line 34; used 7 times
sccsid defined in line 14; never used
shell defined in line 32; used 5 times
slave defined in line 35; used 12 times
subchild defined in line 37; used 2 times
tc defined in line 42; used 2 times
win defined in line 44; used 2 times
Last modified: 1987-09-05
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3572
Valid CSS Valid XHTML 1.0 Strict