home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume4 / vis / vis.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-02-03  |  5.7 KB  |  224 lines

  1. /*   Copyright (c) 1988 by George M. Sipe.  All rights reserved.
  2.  
  3. This software may only be redistributed without fee and without any
  4. other form of monetary gain (including sold, rented, leased, or
  5. traded), unless the express written permission of the copyright holder
  6. is obtained in advance.
  7.  
  8. This copyright notice must be reproduced in its entirety on all copies
  9. of this software.  Further, acknowledgment of the authorship of this
  10. software must not be removed from its current or derived
  11. documentation.
  12.  
  13. No expressed or implied warranty is made for this software.  No party
  14. connected with this software assumes any liability or responsibility
  15. for its use, the correctness of its operation, or its fitness for any
  16. purpose.
  17.  
  18. Any distributor of copies of this software shall grant the recipient
  19. permission for further redistribution as permitted by this notice.
  20.  
  21. Permission is hereby granted to copy, reproduce, redistribute and
  22. otherwise use this software as long as the conditions above are
  23. strictly adhered to.
  24.  
  25.     NOTE:  This software was originally written by Dan Heller
  26.     (argv@sri-spam.arpa) and enhanced / generalized by George M.
  27.     Sipe (rebel!george) to the point where Dan would no longer
  28.     recoginze it.  No copyright notices were embodied in the
  29.     original net distribution.
  30. */
  31.  
  32. #include <stdio.h>
  33. #include <curses.h>
  34. #include <signal.h>
  35. #include <sys/types.h>
  36.  
  37. #ifndef    DELAY
  38. #define    DELAY    15        /* default delay, if not otherwise set */
  39. #endif    DELAY
  40. #ifndef    BASELINE
  41. #define    BASELINE 2        /* default line number for output */
  42. #endif    BASELINE
  43.  
  44. #define max(a,b)         (a < b ? b : a)
  45. #define equal(str1,str2)    !strcmp(str1, str2)
  46.  
  47. #define pinput             fildes[0]
  48. #define poutput            fildes[1]
  49.  
  50. #ifdef    BSD
  51. #include <sys/wait.h>
  52. extern char *index();
  53. extern time_t time();
  54. extern int exit();
  55. extern int _exit();
  56. extern int perror();
  57. extern int sleep();
  58. #else
  59. union wait {
  60.     int w_status;
  61. };
  62. #define    vfork()        fork()                /* fork on non-BSD */
  63. #define    dup2(from,to)    close(to); (void) dup(from)    /* good enough here */
  64. #define    index(str,chr)    strchr(str,chr)            /* strchr on non-BSD */
  65. extern char *strchr();
  66. extern long time();
  67. extern void exit();
  68. extern void _exit();
  69. extern void perror();
  70. extern unsigned int sleep();
  71. #endif    BSD
  72.  
  73. extern int optind;
  74. extern char *optarg;
  75.  
  76. long wait_delay = DELAY;    /* delay interval */
  77. int force = 0;            /* true to force continued execution */
  78. int needshell = 0;        /* non-zero if subshell needed */
  79.  
  80. /* create command line string for display */
  81. static char *command(argc, argv)
  82. int argc;
  83. char **argv;
  84. {
  85.     static char string[255];
  86.     int count = 0;
  87.     char *cp = string;
  88.  
  89.     do {
  90.         (void) sprintf(cp, "%s ", argv[count]);
  91.         cp += strlen(cp);
  92.         needshell |= (int) index(argv[count], '|');
  93.         needshell |= (int) index(argv[count], ';');
  94.     } while (++count < argc);
  95.     *--cp = '\000';
  96.     return (string);
  97. }
  98.  
  99. /* all done, cleanup and exit */
  100. static int terminate(cause)
  101. {
  102. #ifdef    BSD
  103.     (void) sigsetmask(-1);
  104. #endif
  105.     move(LINES - 1, 0);
  106.     clrtoeol();
  107.     echo();
  108.     refresh();
  109.     endwin();
  110.     exit(cause);
  111. }
  112.  
  113. int main(argc, argv)
  114. int argc;
  115. char **argv;
  116. {
  117.     register int curline;
  118.     register int iteration = 0;
  119.     register int c;
  120.     int sw;
  121.     int badsw = 0;
  122.     int baseline = BASELINE;
  123.     long nextcycle;
  124.     long curtime;
  125.     long delta;
  126.     int fildes[2];
  127.     int pid;
  128.     union wait status;
  129.     char *cmd = argv[0];
  130.     char *shcmd[4];
  131.     FILE *fp;
  132.  
  133.     (void) signal(SIGQUIT, terminate);    /* exit when requested */
  134.     (void) signal(SIGINT, terminate);    /* exit when requested */
  135.     (void) signal(SIGPIPE, SIG_IGN);    /* when output > screen size */
  136.  
  137.     while ((sw = getopt (argc, argv, "d:f")) != EOF)
  138.         switch (sw) {
  139.             case 'f':
  140.                 force = !force;
  141.                 break;
  142.             case 'd':
  143.                 wait_delay = atoi(optarg);
  144.                 if (wait_delay < 1) wait_delay = 1;
  145.                 break;
  146.             case '?':
  147.             default:
  148.                 badsw = 1;
  149.                 break;
  150.         }
  151.     argv = &argv[optind];
  152.     argc -= optind;
  153.     if (badsw || argc < 1) {
  154.         (void) fprintf(stderr,
  155.             "Usage: %s [-d delay] [-f] command [args]\n", cmd);
  156.         exit (-1);
  157.     }
  158.     initscr();
  159.     cmd = command(argc, argv);
  160.     if (needshell != 0) {
  161.         shcmd[0] = "sh";
  162.         shcmd[1] = "-c";
  163.         shcmd[2] = cmd;
  164.         shcmd[3] = (char *) 0;
  165.     }
  166.     if (wait_delay != DELAY) {
  167.         if (strlen(cmd) > COLS-39)
  168.             (void) sprintf(cmd, "%.*s...", COLS-42, cmd);
  169.         mvprintw(0, max((COLS-11)/2, strlen(cmd)+15), "Delay:  %d",
  170.             wait_delay);
  171.     } else if (strlen(cmd) > COLS-21)
  172.         (void) sprintf(cmd, "%.*s...", COLS-24, cmd);
  173.     mvprintw(0, 0, "Command:  %s", cmd);
  174.     noecho();            /* don't let typing ruin our painting */
  175.     nextcycle = time(0) + wait_delay;
  176.     while (1) {
  177.         mvprintw(0, COLS - 10, "Exec:  %d", ++iteration);
  178.         if (iteration == 1) refresh();
  179.         (void) pipe(fildes);
  180.         /* fork and exec redirecting stdout thru pipe to curses */
  181.         if (!(pid = vfork())) {
  182.             (void) dup2(poutput, 1);
  183.             (void) dup2(poutput, 2);
  184.             (void) close(pinput);
  185.             if (needshell == 0) (void) execvp(*argv, argv);
  186.             else (void) execv("/bin/sh", shcmd);
  187.             perror(*argv);
  188.             _exit(-1);
  189.         }
  190.         if (pid == -1) terminate(-2);
  191.         if (!(fp = fdopen(pinput, "r"))) terminate(-3);
  192.         (void) close(poutput);
  193.         curline = baseline;
  194.         move(curline, 0);
  195.         /* read the command's output */
  196.         while ((c = getc(fp)) != EOF && !ferror(fp) && curline < LINES)
  197.                 if (c == '\n') {
  198.                     clrtoeol();
  199.                     move(++curline, 0);
  200.                 }
  201.                 else addch(c);
  202.         if (ferror(fp)) terminate(-4);
  203.         if (baseline > 1 && curline == LINES && c != EOF)
  204.             --baseline;
  205.         /* we've found the end of file, thus, the end of exec */
  206.         (void) fclose(fp);
  207.         clrtobot();
  208.         move(LINES - 1, 0);
  209.         refresh();
  210.         (void) wait(&status);    /* wait for child to terminate */
  211.         /* if child didn't terminate properly, w_status will != 0 */
  212.         if (status.w_status) {
  213.             mvprintw(0, COLS - 12, "!");
  214.             if (!force) terminate(status.w_status);
  215.         }
  216.         curtime = time(0);
  217.         delta = nextcycle - curtime;
  218.         if (delta > 0) {
  219.             nextcycle = curtime + delta + wait_delay;
  220.             (void) sleep((unsigned) delta);
  221.         } else nextcycle = curtime + wait_delay;
  222.     }
  223. }
  224.