[alt.sources] Repeat

jv@mh.nl (Johan Vromans) (12/25/89)

In article <3136@taux01.UUCP> amos@taux01.UUCP (Amos Shapir) writes:

> The idea of DistantBiff is to run a command agin and again until
> something happens; here's a shell file that can do thi with any command.
> 
> Call it 'ww' to run the command until its output changes, and link to 'wu'
> to run until its output stops changing.  I have found it very useful.

Well, this reminds me I had this goodie running around for a while.
It periodically runs a command, and displays the output on the screen,
using 'curses'. Good for monitoring 'ps', 'df' or 'uustatus'; or
whatever purpose you can think of.
Compile with "-DSELECT" if you have the 'select(2)' system call [BSD,
HP-UX, ..].

------ begin of repeat.c -- ascii -- complete ------
static char SCCS_id[] = "@(#)@ rpt	1.4	repeat";
static char DP_id[] = "RepeatCommand 1.4";

/* Repeat.c - repeat a command and display its output using 'curses' .
 *
 * Copyright 1989 Johan Vromans
 * Usage of this program, in source and binary form, is free.
 *
 * Usage: repeat [-i interval] command...
 *
 * Defines: SYSNAME - your organisation name 
 *	    UPD_INT - default update interval
 *	    REFR_INT - refresh screen interval
 *	    SELECT - if you have 'select(2)'
 */

#include <curses.h>
#include <sys/types.h>

char *malloc();

#ifndef SYSNAME
#   define SYSNAME	"Multihouse Research"
#endif

#ifndef UPD_INT
#   define UPD_INT	(20)	/* update screen interval */
#endif

#ifndef REFR_INT
#   define REFR_INT	(5*60)	/* refresh screen interval */
#endif

#include <signal.h>

int ss_intr ()
{
    ss_timeout ();
#ifndef SELECT
    (void) signal (SIGINT, ss_intr);
#endif
}

int ss_quit ()
{
    move (1, 0);
    addstr ("Bye bye ...");
    refresh ();
    flushinp ();
    endwin ();
    exit (0);
}

/* the timeout timer will force a screen clear upon the next refresh, */
/* to cope with accidental messages and such */
/* also called upon INTR */

int ss_timeout ()
{
    static int first = 1;

    if (first) first = 0;
    else clearok (stdscr, 1);

    (void) signal (SIGALRM, ss_timeout);
    alarm (REFR_INT);
}

char *my_name;
char *cmd;

main (argc, argv)
int argc;
char *argv[];
{
    int slval = 0;
    extern char *optarg;
    extern int optind;
    int c;
    int need, i;

    my_name = argv[0];

    while ((c = getopt (argc, argv, "i:")) != EOF) {
      switch (c) {
      case 'i':			/* interval */
	slval = atoi (optarg);
	break;
      default:
	fprintf (stderr, "usage: %s [-iNN] command\n", my_name);
	exit(1);
      }
    }
    
    if (slval <= 0)
      slval = UPD_INT;

    need = 0;
    for (i = optind; i < argc; i++)
      need += strlen (argv[i]) + 1;
    cmd = malloc (need);
    if (cmd == NULL) {
      fprintf (stderr, "%s: no space for %d-byte command\n", my_name, need);
      exit(2);
    }
    *cmd = '\0';
    for (i = optind; i < argc; i++) {
      strcat (cmd, argv[i]);
      strcat (cmd, " ");
    }
    cmd[strlen(cmd)-1] = '\0';

    initscr ();
    idlok (stdscr, 1);
    intrflush (stdscr, 1);
    setup ();

    ss_intr ();			/* enable interrupts .. and alarm */

    for (;;) {
	(void) signal (SIGQUIT, SIG_IGN);
#ifdef SELECT
	(void) signal (SIGINT, SIG_IGN);
#endif
	move (1, 0);
	addstr (" Updating... ");
	addstr (cmd);
	addstr (" ");
	clrtoeol ();
	refresh ();
	if (fillscreen () == 0) ss_quit (0);
	addtime ();	
	move (1, 0);
	clrtoeol ();
	refresh ();
	(void) signal (SIGQUIT, ss_quit);
#ifdef SELECT
	(void) signal (SIGINT, ss_quit);
#endif
	suspend (slval);
    }
}

#include <sys/utsname.h>

int timepos;

addtime ()
{
  time_t t;
  time_t time ();
  char *ctime ();
  char *cp;

  time (&t);
  cp = ctime (&t);
  cp[strlen(cp)-1] = '\0';
  move (0, timepos);
  attrset (A_STANDOUT);
  addstr (cp);
  attrset (0);
}

setup ()
{
    struct utsname u;
    int y, x;

    uname (&u);
    move (0, 0);
    attrset (A_STANDOUT);
    printw ("%*s", COLS, " ");
    move (0, 1);
    addstr (u.nodename);
    addstr ("   ");	addstr (u.sysname);
    addstr (" ");	addstr (u.release);
    addstr (" ");	addstr (u.version);
    getyx (stdscr, y, x);
    timepos = x + (COLS - strlen (SYSNAME) - x - 25) / 2;
    move (0, COLS - strlen (SYSNAME) - 1);
    addstr (SYSNAME);
    attrset (0);
    move (2, 0);
    addstr (DP_id);
    addstr (" - (C) 1988 Multihouse Research - starting up...");
    move (5, 5);
    addstr ("Hit ");
    attrset (A_STANDOUT);
#ifdef SELECT
    addstr ("RET");
#else
    addstr ("INTR");
#endif
    attrset (0);
    addstr (" to refresh screen\n\n     ");
#ifdef SELECT
    attrset (A_STANDOUT);
    addstr ("INTR");
    attrset (0);
    addstr (" or ");
#endif
    attrset (A_STANDOUT);
    addstr ("QUIT");
    attrset (0);
    addstr (" to cancel\n\n     ");
    refresh ();
}

#ifdef SELECT
#include <time.h>
#endif

suspend (slval)
int slval;
{
#ifdef SELECT
    struct timeval tv;
    int readfds;

    tv.tv_sec = slval;
    tv.tv_usec = 0;

    readfds = 0 | (1 << 0);	/* only fd #0 */
    if (select (1, &readfds, 0, 0, &tv) > 0)
	flushinp ();
#else
    sleep (slval);
#endif
}

int fillscreen ()
{
  FILE *p;
  char buf [512];
  int line = 2;
  p = popen (cmd, "r");
  if (p == NULL) return 0;

  move(line,0);
  clrtobot();

  for (line = 2;;) {
    if (fgets (buf, sizeof buf, p) == NULL)
      break;
    buf[COLS-1] = '\0';
    mvaddstr(line,0,buf);
    if (++line >= LINES)
      break;
  }

  pclose (p);
  return 1;
}
------ end of repeat.c -- ascii -- complete ------
--
Johan Vromans				       jv@mh.nl via internet backbones
Multihouse Automatisering bv		       uucp: ..!{uunet,hp4nl}!mh.nl!jv
Doesburgweg 7, 2803 PL Gouda, The Netherlands  phone/fax: +31 1820 62944/62500
------------------------ "Arms are made for hugging" -------------------------