121575Sdist /* 221575Sdist * Copyright (c) 1980 Regents of the University of California. 334628Sbostic * All rights reserved. 434628Sbostic * 542765Sbostic * %sccs.include.redist.c% 621575Sdist */ 721575Sdist 86318Swnj #ifndef lint 921575Sdist char copyright[] = 1021575Sdist "@(#) Copyright (c) 1980 Regents of the University of California.\n\ 1121575Sdist All rights reserved.\n"; 1234628Sbostic #endif /* not lint */ 1312990Ssam 1421575Sdist #ifndef lint 15*50403Smarc static char sccsid[] = "@(#)script.c 5.14 (Berkeley) 07/03/91"; 1634628Sbostic #endif /* not lint */ 1721575Sdist 181089Sbill /* 196318Swnj * script 201089Sbill */ 216318Swnj #include <sys/types.h> 226318Swnj #include <sys/stat.h> 2337141Smarc #include <termios.h> 246318Swnj #include <sys/ioctl.h> 2513621Ssam #include <sys/time.h> 2617589Ssam #include <sys/file.h> 2737874Sbostic #include <sys/signal.h> 2834628Sbostic #include <stdio.h> 2937874Sbostic #include <paths.h> 301089Sbill 316318Swnj char *shell; 326318Swnj FILE *fscript; 336318Swnj int master; 346318Swnj int slave; 356318Swnj int child; 3624450Sbloom int subchild; 3734628Sbostic char *fname; 381089Sbill 3937141Smarc struct termios tt; 4018029Sbloom struct winsize win; 416318Swnj int lb; 426318Swnj int l; 4347012Sdonn char line[] = "/dev/ptyXX"; 446318Swnj int aflg; 451089Sbill 466318Swnj main(argc, argv) 476318Swnj int argc; 486318Swnj char *argv[]; 496318Swnj { 5034628Sbostic extern char *optarg; 5134628Sbostic extern int optind; 5234628Sbostic int ch; 5346853Sbostic void finish(); 5434628Sbostic char *getenv(); 551089Sbill 5634628Sbostic while ((ch = getopt(argc, argv, "a")) != EOF) 5734628Sbostic switch((char)ch) { 586318Swnj case 'a': 596318Swnj aflg++; 606318Swnj break; 6134628Sbostic case '?': 626318Swnj default: 6334628Sbostic fprintf(stderr, "usage: script [-a] [file]\n"); 646318Swnj exit(1); 651089Sbill } 6634628Sbostic argc -= optind; 6734628Sbostic argv += optind; 6834628Sbostic 696318Swnj if (argc > 0) 706318Swnj fname = argv[0]; 7134628Sbostic else 7234628Sbostic fname = "typescript"; 736318Swnj if ((fscript = fopen(fname, aflg ? "a" : "w")) == NULL) { 746318Swnj perror(fname); 751089Sbill fail(); 761089Sbill } 7734628Sbostic 7834628Sbostic shell = getenv("SHELL"); 7934628Sbostic if (shell == NULL) 8037874Sbostic shell = _PATH_BSHELL; 8134628Sbostic 82*50403Smarc (void) tcgetattr(0, &tt); 83*50403Smarc (void) ioctl(0, TIOCGWINSZ, (char *)&win); 84*50403Smarc if (openpty(&master, &slave, NULL, &tt, &win) == -1) { 85*50403Smarc perror("openpty"); 86*50403Smarc exit(1); 87*50403Smarc } 88*50403Smarc 896318Swnj printf("Script started, file is %s\n", fname); 90*50403Smarc fixtty(); /* go raw */ 911089Sbill 926318Swnj (void) signal(SIGCHLD, finish); 936318Swnj child = fork(); 946318Swnj if (child < 0) { 956318Swnj perror("fork"); 966318Swnj fail(); 971089Sbill } 986318Swnj if (child == 0) { 9924450Sbloom subchild = child = fork(); 10024450Sbloom if (child < 0) { 1016318Swnj perror("fork"); 1026318Swnj fail(); 1036318Swnj } 10424450Sbloom if (child) 1051089Sbill dooutput(); 1066318Swnj else 1076318Swnj doshell(); 1081089Sbill } 1096318Swnj doinput(); 1101089Sbill } 1111089Sbill 1121089Sbill doinput() 1131089Sbill { 11434628Sbostic register int cc; 1156318Swnj char ibuf[BUFSIZ]; 1161089Sbill 1176318Swnj (void) fclose(fscript); 1186318Swnj while ((cc = read(0, ibuf, BUFSIZ)) > 0) 1196318Swnj (void) write(master, ibuf, cc); 1206318Swnj done(); 1216318Swnj } 1221089Sbill 12313621Ssam #include <sys/wait.h> 1241089Sbill 12546853Sbostic void 1266318Swnj finish() 1276318Swnj { 1286318Swnj union wait status; 12924450Sbloom register int pid; 13024450Sbloom register int die = 0; 1311089Sbill 13246853Sbostic while ((pid = wait3((int *)&status, WNOHANG, 0)) > 0) 13324450Sbloom if (pid == child) 13424450Sbloom die = 1; 13524450Sbloom 13624450Sbloom if (die) 13724450Sbloom done(); 1381089Sbill } 1391089Sbill 1401089Sbill dooutput() 1411089Sbill { 14234628Sbostic register int cc; 14334628Sbostic time_t tvec, time(); 14434628Sbostic char obuf[BUFSIZ], *ctime(); 1451089Sbill 1466318Swnj (void) close(0); 14734628Sbostic tvec = time((time_t *)NULL); 1486318Swnj fprintf(fscript, "Script started on %s", ctime(&tvec)); 1496318Swnj for (;;) { 1506318Swnj cc = read(master, obuf, sizeof (obuf)); 1516318Swnj if (cc <= 0) 1526318Swnj break; 1536318Swnj (void) write(1, obuf, cc); 1546318Swnj (void) fwrite(obuf, 1, cc, fscript); 1551089Sbill } 15625473Sserge done(); 1571089Sbill } 1581089Sbill 1591089Sbill doshell() 1601089Sbill { 1611089Sbill 162*50403Smarc close(master); 1636318Swnj (void) fclose(fscript); 164*50403Smarc login_tty(slave); 1651089Sbill execl(shell, "sh", "-i", 0); 1666318Swnj perror(shell); 1671089Sbill fail(); 1681089Sbill } 1691089Sbill 1701089Sbill fixtty() 1711089Sbill { 17237141Smarc struct termios rtt; 1731089Sbill 17437141Smarc rtt = tt; 17537141Smarc cfmakeraw(&rtt); 17637141Smarc rtt.c_lflag &= ~ECHO; 17743236Sbostic (void) tcsetattr(0, TCSAFLUSH, &rtt); 1781089Sbill } 1791089Sbill 1801089Sbill fail() 1811089Sbill { 1821089Sbill 1836318Swnj (void) kill(0, SIGTERM); 1841089Sbill done(); 1851089Sbill } 1861089Sbill 1871089Sbill done() 1881089Sbill { 18934628Sbostic time_t tvec, time(); 19034628Sbostic char *ctime(); 1911089Sbill 19225473Sserge if (subchild) { 19334628Sbostic tvec = time((time_t *)NULL); 19438683Sbostic fprintf(fscript,"\nScript done on %s", ctime(&tvec)); 19525473Sserge (void) fclose(fscript); 19625473Sserge (void) close(master); 19725473Sserge } else { 19843236Sbostic (void) tcsetattr(0, TCSAFLUSH, &tt); 19924450Sbloom printf("Script done, file is %s\n", fname); 20024450Sbloom } 2016318Swnj exit(0); 2021089Sbill } 203