home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume17 / cscript / cscript.c < prev    next >
C/C++ Source or Header  |  1989-02-08  |  3KB  |  162 lines

  1. /*
  2.  * cscript - record a terminal session
  3.  * Author:    Grant Dorman
  4.  * Modified by Ray Swartz
  5.  * Modified by Kent Forschmiedt 20jun88
  6.  */
  7. #ifndef lint
  8. static char *sccsid = "@(#)cscript.c    2.2  6/20/88";
  9. #endif
  10.  
  11. #include <stdio.h>
  12. #include <signal.h>
  13. #include <fcntl.h>
  14.  
  15. #define SHELL        "/bin/sh"
  16. #define SCRIPTOUT    "typescript"
  17. #define SHFLAGS        "-i"
  18.  
  19. void exit(), perror();
  20.  
  21. char *getenv(), *ctime();
  22.  
  23. int fd;                /* record file */
  24. char buf[BUFSIZ];
  25. char *fname;
  26. char *shell;
  27. int qflg;
  28. int ipd[2], opd[2];    /* pipes */
  29.  
  30. main(argc, argv)
  31. int argc; char **argv;
  32. {
  33.     int getopt();
  34.     extern char *optarg;
  35.     extern int optind;
  36.  
  37.     int c, oflags;
  38.  
  39.     oflags = O_WRONLY + O_CREAT + O_TRUNC;
  40.     shell = (char *)0;
  41.  
  42.     while ((c = getopt(argc, argv, "aqs:")) != EOF)
  43.         switch(c) {
  44.             case 'a':    /* append mode */
  45.                 oflags = O_WRONLY + O_CREAT + O_APPEND;
  46.                 break;
  47.             case 'q':    /* quiet mode */
  48.                 qflg++;
  49.                 break;
  50.             case 's':
  51.                 shell = optarg;
  52.                 break;
  53.             default:
  54.                 fprintf(stderr, "Usage: cscript [-aq] [ -s shell ] [file]\n");
  55.                 exit(3);
  56.         }
  57.  
  58.     if (!shell && (shell = getenv("SHELL")) == (char *)0)
  59.         shell = SHELL;
  60.  
  61.     fname = (optind < argc) ? argv[optind] : SCRIPTOUT;
  62.     if ( (fd = open(fname, oflags, 0666)) < 0) {
  63.         perror("cscript: open");
  64.         exit(4);
  65.     }
  66.  
  67.     if (pipe(ipd) == -1) {
  68.         perror("cscript: pipe");
  69.         exit(2);
  70.     }
  71.     if (pipe(opd) == -1) {
  72.         perror("cscript: pipe");
  73.         exit(2);
  74.     }
  75.  
  76.     switch(fork()) {
  77.         case -1: perror("cscript: fork 1"); exit(1);
  78.  
  79.         case 0: switch(fork()) {
  80.             case -1:    perror("cscript: fork 2"); exit(1);
  81.  
  82.             case 0:        do_stdin(); exit(6);
  83.             default:    do_shell(); exit(6);
  84.         }
  85.         default:    do_stdout(); exit(6);
  86.     }
  87.  
  88.     /* NOTREACHED */
  89. }
  90.  
  91.  
  92. do_stdout()
  93. {
  94.     unsigned nread;
  95.     long time(), tloc;
  96.  
  97.     /* this process will exit when the pipe closes */
  98.     signal(SIGHUP, SIG_IGN); /* */
  99.     signal(SIGINT, SIG_IGN); /* */
  100.     signal(SIGQUIT, SIG_IGN); /* */
  101.  
  102.     close(ipd[0]); close(ipd[1]);
  103.  
  104.     close(0); dup(opd[0]);
  105.     close(opd[0]); close(opd[1]);
  106.  
  107.     fprintf(stderr, "Recording...\nExit shell to stop\n");
  108.  
  109.     while((nread = read(0, buf, sizeof buf)) != 0) {
  110.         write(1, buf, nread);
  111.         write(fd, buf, nread);
  112.     }
  113.  
  114.     if (!qflg) {
  115.         time(&tloc);
  116.         fprintf(stderr, "Script done, file is %s\n", fname);
  117.         sprintf(buf, "\nScript done %s", ctime(&tloc));
  118.         write(fd, buf, (unsigned) strlen(buf));
  119.     }
  120.  
  121.     exit(0);
  122. }
  123.  
  124. do_stdin()
  125. {
  126.     unsigned nread;
  127.  
  128.     close(opd[0]); close(opd[1]);
  129.     close(1); dup(ipd[1]);
  130.     close(ipd[0]); close(ipd[1]);
  131.  
  132.     while((nread = read(0, buf, sizeof buf)) != 0) {
  133.         write(fd, buf, nread);
  134.         write(1, buf, nread);
  135.     }
  136.  
  137.     exit(0);
  138. }
  139.  
  140. do_shell()
  141. {
  142.     long time(), tloc;
  143.  
  144.     close(0); dup(ipd[0]);
  145.     close(1); dup(opd[1]);
  146.     /* mush stderr into stdout pipe */
  147.     close(2); dup(opd[1]);
  148.  
  149.     close(opd[0]); close(opd[1]);
  150.     close(ipd[0]); close(ipd[1]);
  151.     close(fd);
  152.  
  153.     if (!qflg) {
  154.         time(&tloc);
  155.         fprintf(stderr, "Script started %s", ctime(&tloc));
  156.     }
  157.  
  158.     execl(shell, shell, SHFLAGS, 0);
  159.     perror("cscript: execl");
  160.     exit(5);
  161. }
  162.