Monitor source Part 3 of 9

jct jct at jct.UUCP
Tue Jul 11 14:02:17 AEST 1989


#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 3 (of 9)."
# Contents:  help/screen.hlp lib/scrin1.c lib/scrin2.c lib/scrinput.c
#   lib/scrout8.c lib/termcap.c montop.c
# Wrapped by jct@ on Mon Jul 10 22:48:09 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'help/screen.hlp' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'help/screen.hlp'\"
else
echo shar: Extracting \"'help/screen.hlp'\" \(6328 characters\)
sed "s/^X//" >'help/screen.hlp' <<'END_OF_FILE'
X.XXISTANDARD        231        676
X.XXIDATA_ENTRY        689       2096
X.XXISCR_DIR       2106       3650
X.XXISCR_EDIT       3661       6328
X........L.......T.......T.......T.......T.......T.......T.......T.......R......
X#STANDARD
General Help For Screens
X.XXW 12 50 7 15
X.XXC BLUE WHITE
X        Help may be called at any time by pressing Function Key 1, by
X        ESC-H or, if not entering data, by ?.  Help text may be of any
X        length and is automatically paged a screen at a time.  If you are
X        past the first page of help, you may backup up to 10 pages of
X        help, by pressing <SPACE>, or go directly to the first help page
X        by pressing (T)op.
X))
X
X#DATA_ENTRY
Help With Data Entry
X.XXW 12 50 7 15
X.XXC BLUE WHITE
X        During data entry the following funtions are available :
X
X        DEL -@@
X        AAA  
X           The delete key is used to delete a character to the left of
X           the cursor.
X
X        -> -@@
X        AA  
X           The right arrow key moves the cursor one character to the
X           right without affecting the character it passes over.
X
X        <- or BACKSPACE -@@
X        AA    AAAAAAAAA  
X           The left arrow key or BACKSPACE moves the cursor one
X           character to the left without affecting the character it
X           passes over.
X
X        INSERT or ESC-i -@@
X        AAAAAA    AAAAA  
X           Used to toggle the overwrite/insert mode. In overwrite mode,
X           if there are characters to the right of the cursor, when new
X           data is entered that data will replace the existing characters.
X           In insert mode, if there are characters to the right of the
X           cursor, when new data is entered that data will move the
X           existing data to the right and place the new data in front.
X
X        DEL LINE or ESC-x -@@
X        AAAAAAAA    AAAAA  
X           Used to delete a entire line of existing data so you may start
X           over from the beginning.
X
X        INTERRUPT, CANCEL or ESC-c -@@
X        AAAAAAAAA  AAAAAA    AAAAA  
X           Used to cancel current data input and return.
X))
X
X#SCR_DIR
Help With Screen Directories
X.XXW 12 50 7 15
X.XXC BLUE WHITE
X        Screen directories are used to select a file by "pointing" to its
X        name in a menu rather than typing it in from memory.  The arrow
X        keys are used to pick the file you want, then press RETURN to@@
X                                                            AAAAAA   
X        complete the selection.
X
X        Entries in the menu are in alphabetical order.  If the selection
X        menu contains more entries than can be shown at one time, the
X        word --more-- will appear in the menu.  If --more-- appears at@@
X             AAAAAAAA                              AAAAAAAA           
X        the end of the menu, then more entries are beyond your current
X        position.  If --more-- appears at the top of the menu, then more@@
X                      AAAAAAAA                                          
X        entries are behind your current position.  To move to the other
X        entries, simply use the arrows to go up or down past displayed
X        entries.
X
X        If you move right or left beyond the edge of the menu, you will
X        be wrapped around and moved up or down a line.  If you move up or
X        down beyond the top and bottom menu lines, you will be wrapped
X        around and moved right or left a column.
X
X        The following keys have special meaning in screen directory
X        operations :
X
X         INTERRUPT, CANCEL or ESC-c -@@
X         AAAAAAAAA  AAAAAA    AAAAA  
X           Used to cancel current data input and return.
X))
X
X#SCR_EDIT
Help With Screen Editing
X.XXW 12 70 4 5
X.XXC BLUE WHITE
X        The commands to move around are very similar to Wordstar. If you
X        don't have the special keys, which take precedence, then use the
X        control-key sequences :
X
X        UP_ARROW or ^e -@@
X        AAAAAAAA    AA  
X          move the cursor up 1 line.
X
X        DOWN_ARROW or ^x -@@
X        AAAAAAAAAA    AA  
X          move the cursor down 1 line.
X
X        RIGHT_ARROW or ^d -@@
X        AAAAAAAAAAA    AA  
X          move the cursor to the right 1 column.
X
X        LEFT_ARROW or ^s -@@
X        AAAAAAAAAA    AA  
X          move the cursor to the left 1 column.
X
X        PAGE_DOWN, NEXT_SCREEN or ^c -@@
X        AAAAAAAAA  AAAAAAAAAAA    AA  
X          move forward 1 screenful.
X
X        PAGE_UP, PREV_SCREEN or ^r -@@
X        AAAAAAA  AAAAAAAAAAA    AA  
X          move backward 1 screenful.
X
X        BEG_FILE or ^q^r -@@
X        AAAAAAAA    AAAA  
X          move to the beginning of the file.
X
X        END_FILE or ^q^c -@@
X        AAAAAAAA    AAAA  
X          move to the end of the file.
X
X        BEG_SCREEN or ^q^e -@@
X        AAAAAAAAAA    AAAA  
X          move to the beginning of the screen.
X
X        END_SCREEN or ^q^x -@@
X        AAAAAAAAAA    AAAA  
X          move to the end of the screen.
X
X        HOME, BEG_LINE or ^q^s -@@
X        AAAA  AAAAAAAA    AAAA  
X          move to the beginning of the line.
X
X        END, END_LINE or ^q^d -@@
X        AAA  AAAAAAAA    AAAA  
X          move to the end of the line.
X
X        DEL, DEL_CHAR or ^g -@@
X        AAA  AAAAAAAA    AA  
X          delete the character under the cursor.
X
X        DEL_WORD or ^t -@@
X        AAAAAAAA    AA  
X          delete the word the cursor is on.
X
X        DEL_LINE or ^y -@@
X        AAAAAAAA    AA  
X          delete the line the cursor is on.
X
X        QUIT or ESC-q -@@
X        AAAA    AAAAA  
X          quit editing without saving anything.
X
X        FUNCTION_KEY_1 -@@
X        AAAAAAAAAAAAAA  
X          give help (this).
X
X        FUNCTION_KEY_2 -@@
X        AAAAAAAAAAAAAA  
X          reformat current paragraph.
X
X        FUNCTION_KEY_3 -@@
X        AAAAAAAAAAAAAA  
X          mark current line as beginning of block.
X
X        FUNCTION_KEY_4 -@@
X        AAAAAAAAAAAAAA  
X          mark current line as end of block.
X
X        FUNCTION_KEY_5 -@@
X        AAAAAAAAAAAAAA  
X          move marked block to line cursor is on.
X
X        FUNCTION_KEY_6 -@@
X        AAAAAAAAAAAAAA  
X          copy marked block to line cursor is on.
X
X        FUNCTION_KEY_7 -@@
X        AAAAAAAAAAAAAA  
X          delete the marked block.
X
X        FUNCTION_KEY_8 -@@
X        AAAAAAAAAAAAAA  
X          unmark the marked block, ignore it.
X))
END_OF_FILE
if test 6328 -ne `wc -c <'help/screen.hlp'`; then
    echo shar: \"'help/screen.hlp'\" unpacked with wrong size!
fi
# end of 'help/screen.hlp'
fi
if test -f 'lib/scrin1.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'lib/scrin1.c'\"
else
echo shar: Extracting \"'lib/scrin1.c'\" \(6902 characters\)
sed "s/^X//" >'lib/scrin1.c' <<'END_OF_FILE'
X/* Module screen input operations */
X
X/*
X   Preforms various data input functions for screen oriented programs
X*/
X
X/*
X   Created May 13, 1986 by JCT
X*/
X
X/*
X *	Copyright (c) John C. Tompkins 1989
X *	All rights reserved.
X *
X *	Permission is granted to use this for any personal, noncommercial use.
X *	You may not distribute source or executable code for profit, nor
X *	may you distribute it with a commercial product without the prior
X *      written consent of the author.  Please send modifications to the 
X *      author for inclusion in updates to the program.
X */
X
X#include <stdio.h>
X#include <ctype.h>
X#include <string.h>
X
X#include <km/defs.h>
X#include <km/ascii.h>
X#include <km/scrio.h>
X#include <km/string1.h>
X#include <km/string2.h>
X
X#ifdef DOS
X#include <dos.h>
X#else
X#include <setjmp.h>
X#include <signal.h>
X#include <fcntl.h>
X#endif
X
char *scr_hf = NULL, *scr_hs = NULL;
int  scr_key_curr, scr_esc_enable = FALSE, scr_print_enable = TRUE;
X
static int   kbuf_index = 0;
static short kbuf[KEY_BUF_SIZE];
X
X#ifdef DOS
static LOOKUP lookup[] =
X  {
X    0x0100 + 72, K_UP,
X    0x0100 + 80, K_DOWN,
X    0x0100 + 75, K_LEFT,
X    0x0100 + 77, K_RIGHT,
X    0x0100 + 119, K_BEG_BUF,
X    0x0100 + 117, K_END_BUF,
X    0x0100 + 132, K_BEG_SCREEN,
X    0x0100 + 118, K_END_SCREEN,
X    0x0100 + 71, K_BEG_LINE,
X    0x0100 + 79, K_END_LINE,
X    0x0100 + 81, K_FWD_SCREEN,
X    0x0100 + 73, K_BWD_SCREEN,
X    0x0100 + 116, K_FWD_WORD,
X    0x0100 + 115, K_BWD_WORD,
X    0x0100 + 38, K_DEL_LINE,
X    0x0100 + 17, K_DEL_WORD,
X    0x0100 + 83, K_DEL_CHAR,
X    0x0100 + 82, K_INSERT,
X    0x0100 + 35, K_HELP,
X    0x0100 + 46, K_CANCEL,
X    0x0100 + 45, K_QUIT,
X    0x0100 + 48, K_BACKUP,
X    0x0100 + 114, K_PRINT,
X    0x0100 + 59, K_F0,
X    0x0100 + 60, K_F1,
X    0x0100 + 61, K_F2,
X    0x0100 + 62, K_F3,
X    0x0100 + 63, K_F4,
X    0x0100 + 64, K_F5,
X    0x0100 + 65, K_F6,
X    0x0100 + 66, K_F7,
X    0x0100 + 67, K_F8,
X    0x0100 + 68, K_F9,
X    0x0100 + 69, K_F10,
X    0x0100 + 70, K_F11,
X    UNDETERMINED, UNDETERMINED
X  };
X#endif
X
X#ifdef UNIX
static jmp_buf env;
X#endif
X
X/*
X   The following are extensions beyond curses
X*/
X
X#ifdef UNIX
static void alarmfunc()
X{
X  longjmp(env, 1);
X}
X#endif
X
int get_key(wait)
X  int wait;
X{
X
X/*
X   OK, this ones pretty snazzy, try to keep up.
X
X   returns an integer from the terminal keyboard.
X
X   if wait is UNDETERMINED, waits forever until a key is pressed.
X   if wait is 0, checks the keyboard and if no key, returns UNDETERMINED.
X     if there is a key, returns the key.
X   if wait > 0, waits a maximum of 'wait' seconds before returning
X     UNDETERMINED if there is no key.
X
X   in any of the conditions, if the first key is the beginning
X     sequence of an entry in KEY_TBL, then continues to input keys until
X     an entry is fully matched or a wait of 1 returns UNDETERMINED. If
X     returning from an UNDETERMINED wait or the sequence is not in KEY_TBL,
X     then the first key of the partially completed sequence is returned
X     and the rest of the sequence is buffered for the next read. Otherwise
X     the value from the KEY_TBL entry is returned, this should be > 128
X     to distinguish it from normal single ASCII keys.
X*/
X
X#ifdef DOS
X  union REGS inregs, outregs;
X  int        stop_sec;
X#endif
X#ifdef UNIX
X  int flags;
X#endif
X  REGISTER short *buf_ptr;
X  REGISTER char  *tbl_ptr;
X  int            i, done = FALSE, in_seq, key;
X
X  do
X    {
X      in_seq = FALSE;
X      if (kbuf_index > 0)
X	{
X#ifdef UNIX
X	  for (i = 0; !done && (i < key_tbl_index); i++)
X	    {
X	      buf_ptr = kbuf;
X	      tbl_ptr = key_tbl[i].str;
X	      while (*buf_ptr && (*buf_ptr == *tbl_ptr))
X		{
X		  buf_ptr++;
X		  tbl_ptr++;
X		}
X	      if (!*buf_ptr && *tbl_ptr)
X		{
X		  in_seq = TRUE;
X		  if (scr_esc_enable)
X		    wait = 1;
X		  else
X		    wait = UNDETERMINED;
X		}
X	      else if (!*buf_ptr && !*tbl_ptr)
X		{
X		  done = TRUE;
X		  key = key_tbl[i].key;
X		  kbuf_index = 0;
X		}
X	    }
X#endif
X	  if (!done && !in_seq)
X	    {
X	      done = TRUE;
X	      key = kbuf[0];
X	      for (buf_ptr = kbuf; *buf_ptr; buf_ptr++)
X		*buf_ptr = *(buf_ptr + 1);
X	      kbuf_index--;
X	    }
X	}
X      if (!done)
X	{
X          if (wait > 0)
X            {
X#ifdef DOS
X  	      inregs.h.ah = 0x2c;
X  	      intdos(&inregs, &outregs);
X  	      stop_sec = outregs.h.dh + wait;
X  	      if (stop_sec >= 60)
X    		stop_sec -= 60;
X	      key = UNDETERMINED;
X  	      do
X    		{
X	          inregs.h.ah = 0x0b;
X	          intdos(&inregs, &outregs);
X	          if (outregs.h.al)
X		    {
X		      key = getch();
X		      break;
X		    }
X	          else
X		    {
X      		      inregs.h.ah = 0x2c;
X      		      intdos(&inregs, &outregs);
X      		      if (outregs.h.dh >= stop_sec)
X		        break;
X		    }
X    		}
X  	      while (TRUE);
X#else
X              (void)signal(SIGALRM, alarmfunc);
X              if (setjmp(env) == 0)
X		{
X                  (void)alarm((unsigned)wait);
X	          key = getch();
X		}
X              else
X	        key = UNDETERMINED;
X              (void)alarm((unsigned)0);
X#endif
X            }
X          else if (wait == 0)
X            {
X#ifdef DOS
X	      inregs.h.ah = 0x0b;
X	      intdos(&inregs, &outregs);
X	      if (outregs.h.al)
X		key = getch();
X	      else
X		key = UNDETERMINED;
X#else
X              if ((flags = fcntl(0, F_GETFL, 0)) != ERROR)
X	        {
X	          fcntl(0, F_SETFL, (flags | O_NDELAY));
X		  key = getch();
X	          fcntl(0, F_SETFL, flags);
X	        }
X	      else
X	        key = UNDETERMINED;
X#endif
X            }
X          else
X            key = getch();
X	  if (!in_seq && (key >= ' '))
X	    {
X	      done = TRUE;
X	      kbuf_index = 0;
X	    }
X          else if (key == UNDETERMINED)
X	    {
X	      done = TRUE;
X	      if (kbuf_index > 0)
X		{
X	          key = kbuf[0];
X	          for (buf_ptr = kbuf; *buf_ptr; buf_ptr++)
X		    *buf_ptr = *(buf_ptr + 1);
X	          kbuf_index--;
X		}
X	    }
X          else
X	    {
X	      kbuf[kbuf_index++] = key;
X	      kbuf[kbuf_index] = 0;
X              if (kbuf_index >= (KEY_BUF_SIZE - 1))
X	        {
X	          done = TRUE;
X	          key = kbuf[0];
X	          for (buf_ptr = kbuf; *buf_ptr; buf_ptr++)
X		    *buf_ptr = *(buf_ptr + 1);
X	          kbuf_index--;
X	        }
X	    }
X	} 
X    }
X  while (!done);
X#ifdef DOS
X  if (key & 0x0100)
X    {
X      for (i = 0; lookup[i].code != UNDETERMINED; i++)
X	{
X	  if (lookup[i].code == key)
X	    {
X	      key = lookup[i].key;
X	      break;
X	    }
X	}
X    }
X#endif
X#ifdef UNIX
X  if (key == K_PRINT)
X    {
X      if (scr_print_enable)
X        print_screen(NULL, NULL);
X    }
X#endif
X#ifndef MMAPPED
X  if (key == CTRL_L)
X    wrefresh(curscr);
X#endif
X  scr_key_curr = key;
X  return(key);
X}
X
int unget_key(key)
X  int key;
X{
X  REGISTER short *buf_ptr;
X  REGISTER int   i;
X
X  if (kbuf_index < (KEY_BUF_SIZE - 1)) 
X    {
X      for (buf_ptr = kbuf + kbuf_index, i = kbuf_index; i; buf_ptr--, i--)
X	*(buf_ptr + 1) = *buf_ptr;
X      kbuf_index++;
X      kbuf[0] = key;
X      return(TRUE);
X    }
X  return(FALSE);
X}
X
END_OF_FILE
if test 6902 -ne `wc -c <'lib/scrin1.c'`; then
    echo shar: \"'lib/scrin1.c'\" unpacked with wrong size!
fi
# end of 'lib/scrin1.c'
fi
if test -f 'lib/scrin2.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'lib/scrin2.c'\"
else
echo shar: Extracting \"'lib/scrin2.c'\" \(7913 characters\)
sed "s/^X//" >'lib/scrin2.c' <<'END_OF_FILE'
X/* Module screen input operations */
X
X/*
X   Preforms various data input functions for screen oriented programs
X*/
X
X/*
X   Created May 13, 1986 by JCT
X*/
X
X/*
X *	Copyright (c) John C. Tompkins 1989
X *	All rights reserved.
X *
X *	Permission is granted to use this for any personal, noncommercial use.
X *	You may not distribute source or executable code for profit, nor
X *	may you distribute it with a commercial product without the prior
X *      written consent of the author.  Please send modifications to the 
X *      author for inclusion in updates to the program.
X */
X
X#undef VARGS
X
X#include <stdio.h>
X#include <ctype.h>
X#include <string.h>
X#ifdef VARGS
X#include <varargs.h>
X#endif
X
X#include <km/defs.h>
X#include <km/ascii.h>
X#include <km/scrio.h>
X#include <km/string1.h>
X#include <km/string2.h>
X
X#ifdef DOS
X#include <dos.h>
X#include <io.h>
X#else
X#include <setjmp.h>
X#include <signal.h>
X#include <fcntl.h>
X#endif
X
X#ifdef DOS
X#define SCREENHELP "\\help\\screen.hlp"
X#else
X#define SCREENHELP "/usr/lib/help/screen.hlp"
X#endif
X
X/*
X   The following are "curses" like routines
X*/
X
int wgetch(win)				/* get a single key */
X  WINDOW *win;
X{
X#ifdef DOS
X  union REGS inregs, outregs;
X  int  data;
X#endif
X  unsigned char read_char;
X
X#ifdef DOS
X  inregs.h.ah = 0x00;
X  int86(0x16, &inregs, &outregs);
X  data = outregs.h.al;
X  if (data == 0)
X    data = 0x0100 + outregs.h.ah;
X  if (_tty & TC_ECHO)
X    {
X      read_char = data;
X      write(1, &read_char, 1);
X    }
X  return(data);
X#else
X  if (read(0, &read_char, 1) != 1)
X    return(UNDETERMINED);
X  else
X    return(read_char & 0x7f);
X#endif
X}
X
X#ifdef VARGS
X
static int scan_chk(statp, format)
X  IN_STAT *statp;
X  char    format;
X{
X  return (isprint (statp->ch) ? statp->ch : UNDETERMINED);
X}
X
int wgetstr(win, str)			/* get a string */
X  WINDOW *win;
X  char   *str;
X{
X  str[0] = '\0';
X  wget_input(stdscr, str, 1000, scan_chk, NULL, NULL, NULL);
X  return(TRUE);
X}
X
int scanw(va_list)			/* scanf on stdscr */
X  va_dcl
X{
X  va_list args;
X  char    *fmt;
X  char    str[150];
X
X  va_start(args);
X  fmt = va_arg(args, char*);
X  str[0] = '\0';
X  wget_input(stdscr, str, sizeof(str), scan_chk, NULL, NULL, NULL);
X  vsscanf(str, fmt, args);
X  va_end(args);
X  return(TRUE);
X}
X
int wscanw(va_list)			/* scanf on a window */
X  va_dcl
X{
X  va_list args;
X  WINDOW  *win;
X  char    *fmt;
X  char    str[150];
X
X  va_start(args);
X  win = va_arg(args, WINDOW*);
X  fmt = va_arg(args, char*);
X  str[0] = '\0';
X  wget_input(win, str, sizeof(str), scan_chk, NULL, NULL, NULL);
X  vsscanf(str, fmt, args);
X  va_end(args);
X  return(TRUE);
X}
X#endif
X
X/*
X   The following are extensions beyond curses
X*/
X
char *wget_input(win, string, max, check, format, help_file, help_section)
X  WINDOW *win;
X  char   *string;
X  int    max;
X  int    (*check)();
X  char   *format;
X  char   *help_file;
X  char   *help_section;
X{
X  char    *temp;
X  int     y, x, at_max, distance, save, done = FALSE, help_stat;
X  IN_STAT stat;
X
X  save = scr_esc_enable;
X  scr_esc_enable = FALSE;
X  if (string)
X    {
X      stat.insert = FALSE;
X      stat.curr = string;
X      stat.str = string;
X      getyx(win, y, x);
X      for (temp = string; *temp && (max > 1); temp++, max--)
X        waddch(win, *temp);				/* default string */
X      if (*temp)					/* hit the max? */
X        *temp = '\0';
X      stat.end = temp;
X      wmove(win, y, x);
X      win->flags &= ~NO_CHANGE;
X      wrefresh(win);
X      while (!done)
X	{
X	  at_max = ((max == 1) && ((stat.end - stat.curr) == 1));
X          stat.ch = get_key(UNDETERMINED);
X          switch (stat.ch)
X            {
X	      case UNDETERMINED :
X		break;
X	      case CR :
X	      case LF :
X	        done = TRUE;
X	        break;
X	      case K_HELP :
X	      case K_F0 :
X		if (help_file)
X		  wdo_help(win, help_file, help_section, 0);
X		else
X		  wdo_help(win, SCREENHELP, "DATA_ENTRY", 0);
X		break;
X	      case K_CANCEL :
X	      case K_F9 :
X		done = TRUE;
X	        string = NULL;
X		break;
X	      case K_INSERT :
X	        stat.insert = !stat.insert;
X	        break;
X	      case K_BEG_SCREEN :
X	      case K_BEG_BUF :
X	      case K_BEG_LINE :
X		getyx(win, y, x);
X		distance = stat.curr - stat.str;
X		wmove(win, y, (x - distance));
X		win->flags &= ~NO_CHANGE;
X		wrefresh(win);
X		stat.curr = string;
X		break;
X	      case K_END_SCREEN :
X	      case K_END_BUF :
X	      case K_END_LINE :
X		getyx(win, y, x);
X                if ((distance = stat.end - stat.curr) != 0)
X		  distance--;
X		wmove(win, y, (x + distance));
X		win->flags &= ~NO_CHANGE;
X		wrefresh(win);
X		if (stat.end > stat.curr)
X		  stat.curr = stat.end - 1;
X		else
X		  stat.curr = stat.end;
X		break;
X	      case K_DEL_LINE :
X		getyx(win, y, x);
X		distance = stat.curr - stat.str;
X		wmove(win, y, (x - distance));
X		for (temp = stat.str; temp < stat.end; temp++)
X		  waddch(win, ' ');
X		wmove(win, y, (x - distance));
X		win->flags &= ~NO_CHANGE;
X		wrefresh(win);
X		max += (stat.end - stat.str);
X		stat.curr = string;
X		stat.end = string;
X		break;
X	      case BS :
X	        if (stat.curr > stat.str)
X	          {
X		    getyx(win, y, x);
X		    wmove(win, y, (x - 1));
X		    wdelch(win);
X		    wmove(win, y, (x + (stat.end - stat.curr) - 1));
X		    winsch(win, ' ');
X		    wmove(win, y, (x - 1));
X		    win->flags &= ~NO_CHANGE;
X		    wrefresh(win);
X		    if (stat.curr < stat.end)
X		      {
X		        for (temp = stat.curr; temp < stat.end; temp++)
X		          *(temp - 1) = *temp;
X		      }
X		    stat.curr--;
X		    stat.end--;
X		    max++;
X	          }
X	        break;
X	      case DEL :
X	      case K_DEL_CHAR :
X	        if (stat.curr < stat.end)
X	          {
X		    getyx(win, y, x);
X		    wdelch(win);
X		    wmove(win, y, (x + (stat.end - stat.curr) - 1));
X		    winsch(win, ' ');
X		    wmove(win, y, x);
X		    win->flags &= ~NO_CHANGE;
X		    wrefresh(win);
X		    for (temp = stat.curr; temp < (stat.end - 1); temp++)
X		      *temp = *(temp + 1);
X		    stat.end--;
X		    max++;
X	          }
X	        break;
X	      case K_LEFT :
X	        if (stat.curr > stat.str)
X	          {
X		    getyx(win, y, x);
X		    wmove(win, y, (x - 1));
X		    win->flags &= ~NO_CHANGE;
X		    wrefresh(win);
X		    stat.curr--;
X	          }
X	        break;
X	      case K_RIGHT :
X		if (!at_max && (stat.curr < stat.end))
X	          {
X		    getyx(win, y, x);
X		    wmove(win, y, (x + 1));
X		    win->flags &= ~NO_CHANGE;
X		    wrefresh(win);
X		    stat.curr++;
X	          }
X	        break;
X	      default :
X	        if ((stat.ch = (*check)(&stat, format)) != UNDETERMINED)
X		  {
X		    if ((stat.ch == '\n') || (stat.ch == '\r'))
X		      {
X			done = TRUE;
X			break;
X		      }
X		    else if (!isprint (stat.ch))
X		      break;
X		    else if (stat.insert && (stat.curr < stat.end))
X		      {
X		        if (max > 1)
X		          {
X		            getyx(win, y, x);
X		            if (!wmove(win, y, (x + max + (stat.end - stat.curr) - 2)))
X			      wmove(win, y, win->x_max - 1);
X		            wdelch(win);
X			    wmove(win, y, x);
X		            winsch(win, stat.ch);
X		            wmove(win, y, (x + 1));
X		            for (temp = (stat.end - 1); temp >= stat.curr; temp--)
X		              *(temp + 1) = *temp;
X		            *stat.curr++ = stat.ch;
X		            stat.end++;
X			    max--;
X		          }
X		      }
X		    else
X		      {
X		        if ((stat.curr < stat.end) || (max > 1))
X		          {
X		            waddch(win, stat.ch);
X		            *stat.curr = stat.ch;
X			    if (at_max)
X			      {
X		                getyx(win, y, x);
X			        wmove(win, y, (x - 1));
X			      }
X			    else if (stat.curr++ == stat.end)
X			      {
X			        if (max > 1)
X			          {
X				    stat.end++;
X				    max--;
X			          }
X			        if (max == 1)
X			          {
X			            stat.curr--;
X			            getyx(win, y, x);
X			            wmove(win, y, (x - 1));
X			          }
X			      }
X		          }
X		      }
X		    win->flags &= ~NO_CHANGE;
X		    wrefresh(win);
X		  }
X	        break;
X            }
X	}
X      *stat.end = '\0';
X    }
X  scr_esc_enable = save;
X  return(string);
X}
X
END_OF_FILE
if test 7913 -ne `wc -c <'lib/scrin2.c'`; then
    echo shar: \"'lib/scrin2.c'\" unpacked with wrong size!
fi
# end of 'lib/scrin2.c'
fi
if test -f 'lib/scrinput.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'lib/scrinput.c'\"
else
echo shar: Extracting \"'lib/scrinput.c'\" \(7419 characters\)
sed "s/^X//" >'lib/scrinput.c' <<'END_OF_FILE'
X/* Module screen input operations */
X
X/*
X   Preforms various data input functions for screen oriented programs
X*/
X
X/*
X   Created May 13, 1986 by JCT
X*/
X
X/*
X *	Copyright (c) John C. Tompkins 1989
X *	All rights reserved.
X *
X *	Permission is granted to use this for any personal, noncommercial use.
X *	You may not distribute source or executable code for profit, nor
X *	may you distribute it with a commercial product without the prior
X *      written consent of the author.  Please send modifications to the 
X *      author for inclusion in updates to the program.
X */
X
X#include <stdio.h>
X#include <ctype.h>
X
X#include <km/ascii.h>
X#include <km/defs.h>
X#include <km/scrio.h>
X#include <km/string1.h>
X
X#define DEF_SECTION	"STANDARD"
X#define BUF_SIZE	150
X
X#define END_SECTION	0x0001
X#define IN_INDEX	0x0002
X#define GOT_INDEX	0x0004
X#define FOUND_SECTION	0x0008
X
X/* declare external UNIX functions */
X
extern int	atoi();
extern int	atol();
X
static char buf1[BUF_SIZE], buf2[BUF_SIZE], *p1, *p2;
X
static int str_chk (statp, format)
X  IN_STAT *statp;
X  char    *format;
X{
X  if (isspace (statp->ch))
X    return ((statp->curr > statp->str) ?  statp->ch : UNDETERMINED);
X  return (statp->ch);
X}
X
char *wget_str(win, string, max, highlight)
X  WINDOW *win;
X  char   *string;
X  int    max;
X  int    highlight;
X{
X
X/*
X   returns a string from the keyboard
X   ignores all non-printible characters except CR, LF, BS, DEL and arrows
X*/
X
X  int  i, line, column;
X  char *stat, *p;
X
X  if (string)
X    {
X      getyx(win, line, column);
X      if (highlight)
X	wsetattrib(win, STANDOUT);
X      for (i = 0; i < (max - 1); i++)
X	waddch(win, ' ');
X      wmove(win, line, column);
X      wrefresh(win);
X      stat = wget_input(win, string, max, str_chk, NULL, NULL, NULL);
X      for (p = strend (string); p > string; p--)
X	{
X	  if (!isspace (*(p - 1)))
X	    break;
X	}
X      *p = '\0';
X      if (highlight)
X	wclrattrib(win, STANDOUT);
X      if (!stat)
X	return(NULL);
X    }
X  return(string);
X}
X
static int int_chk (statp, format)
X  IN_STAT *statp;
X  char    *format;
X{
X  char *temp;
X  int  sign = TRUE;
X
X  if (isspace (statp->ch))
X    return (statp->insert ? UNDETERMINED : ' ');
X  for (temp = statp->str; temp < statp->curr; temp++)
X    {
X      if (!isspace (*temp))
X	{
X	  sign = FALSE;
X	  break;
X	}
X    }
X  if ((statp->ch == '+') || (statp->ch == '-'))
X    return (sign ? statp->ch : UNDETERMINED);
X  if (isdigit (statp->ch))
X    return (statp->ch);
X  else
X    return (UNDETERMINED);
X}
X
int wget_int(win, data, min, max, places, highlight)
X  WINDOW *win;
X  int    *data;
X  int    min;
X  int    max;
X  int    places;
X  int    highlight;
X{
X
X/*
X   returns an integer from the keyboard
X   ignores all non-numeric chars except CR, LF, BS, DEL and arrows
X*/
X
X  char string[10];
X  int  i, line, column, any, size;
X  char *stat;
X
X  any = (min == max);
X  getyx(win, line, column);
X  if (places < 6)
X    size = places;
X  else
X    size = 6;
X  if (highlight)
X    wsetattrib(win, STANDOUT);
X  do
X    {
X      wmove(win, line, column);
X      for (i = 0; i < size; i++)
X	waddch(win, ' ');
X      string[0] = '\0';
X      wmove(win, line, column);
X      if ((stat = wget_input(win, string, size, int_chk, NULL, NULL, NULL)) != NULL)
X	*data = atoi(string);
X    }
X  while (stat && !any && ((*data < min) || (*data > max)));
X  if (highlight)
X    wclrattrib(win, STANDOUT);
X  if (stat)
X    return(TRUE);
X  else
X    return(FALSE);
X}
X
static char *eatspace(p)
X  REGISTER char *p;
X{
X
X/*
X   Skips over leading whitespace.
X   Like start_title() but " character nothing special.
X*/
X
X  if (p)
X    {
X      while (isspace(*p))
X	p++;
X    }
X  return(p);
X}
X
static char *findend(p)
X  REGISTER char *p;
X{
X
X/*
X   Finds whitespace or end of line.
X   Like end_title() but " not special.
X*/
X
X  if (p)
X    {
X      while (*p && (!isspace(*p) && (*p != '\n')))
X	p++;
X    }
X  return(p);
X}
X
static char *delimit(p)
X  REGISTER char *p;
X{
X
X/*
X   Substitutes null character, \0, for first whitespace found
X*/
X
X  if (p)
X    {
X      while (*p)
X        {
X          if (isspace(*p))
X	    {
X	      *p = '\0';
X	      p++;
X	      break;
X	    } 
X          else
X            p++;
X	}
X    }
X  return(p);
X}
X
static int line_empty(p)
X  REGISTER char *p;
X{
X
X/*
X   Looks through a "line", actually a string, if any non whitespace
X   character the line is not empty. If all whitespace, its empty.
X*/
X
X  if (p)
X    {
X      while (*p)
X	{
X	  if (*p == '\n')
X	    return(TRUE);
X	  if (!isspace(*p))
X	    return(FALSE);
X	  p++;
X	}
X    }
X  return(TRUE);
X}
X
static int find_section(scr_file, section)
X  FILE *scr_file;
X  char *section;
X{
X
X/*
X   Searches the start of the screen file for an index and if found, searches
X   the index for the desired section for direct fseek()-ing to. If the index
X   exists but the section is not found aborts. If the index does not exist,
X   searches the file sequentally until section found or end of file, much
X   slower.
X*/
X
X  int flags = 0;
X
X  while (!(flags & FOUND_SECTION) && (fgets(buf1, sizeof(buf1), scr_file)))
X    {
X      if (flags & IN_INDEX)
X	{
X	  if (substr(buf1, ".XXI", FALSE))
X	    {
X	      flags |= GOT_INDEX;
X	      p1 = eatspace(buf1 + 4);
X	      p2 = delimit(p1);
X	      if (substr(p1, section, TRUE))
X	        {
X		  p2 = eatspace(p2);
X		  p2 = findend(p2);
X		  fseek(scr_file, atol(p2), 0);
X		  flags |= FOUND_SECTION;
X		}
X	    }
X	  else if (!line_empty(buf1))
X	    {
X	      if (flags & GOT_INDEX)
X		return(FALSE);
X	      flags &= ~IN_INDEX;
X	    }
X	}
X      if (*buf1 == '#')
X	{
X	  delimit(buf1);
X	  if (substr((buf1 + 1), section, TRUE))
X	    flags |= FOUND_SECTION;
X	}
X    }
X  return(flags & FOUND_SECTION);
X}
X
static int get_page(win, scr_file)
X  WINDOW *win;
X  FILE   *scr_file;
X{
X  int temp, page_length, done = FALSE;
X
X  page_length = win->y_max;
X  werase(win);
X  wmove(win, 0, 0);
X  while (!done && (fgets(buf1, sizeof(buf1), scr_file)))
X    {
X      if (*buf1 == '.')
X	{
X	  if (substr((buf1 + 1), "PA", FALSE))
X	    done = TRUE;
X	  else if (substr((buf1 + 1), "PL", FALSE))
X	    {
X	      if ((temp = atoi(buf1 + 3)) <= (LINES - 4))
X		page_length = temp;
X	      else
X	        page_length = win->y_max;
X	    }
X	}
X      else if (substr(buf1, "))", FALSE))
X	done = TRUE;
X      else
X	{
X	  p1 = (strend(buf1) - 3);
X	  if (substr(p1, "@@", FALSE))			/* attribute mark? */
X	    {
X	      *p1++ = LF;				/* clear mark */
X	      *p1 = '\0';
X	      if (fgets(buf2, sizeof(buf2), scr_file)) /* get attributes */
X		{
X		  for (p1 = buf1, p2 = buf2; *p1; p1++)
X		    {
X		      if (!*p2 || (*p2 == ' ') || (*p2 == '\n'))
X			{
X			  if (win->attrib)
X			    wendattrib(win);
X			  waddch(win, *p1);
X			}
X		      else if (*p2 == '[')
X			{
X			  if (win->attrib)
X			    wendattrib(win);
X			  waddgraphic(win, *p1);
X			}
X		      else
X			{
X			  if (!(win->attrib & STANDOUT))
X			    wsetattrib(win, STANDOUT);
X			  waddch(win, *p1);
X			}
X		      if (*p2)
X			p2++;
X		    }
X		  wendattrib(win);
X	        } 
X	      else
X	        waddstr(win, buf1);
X	    }
X	  else
X	    waddstr(win, buf1);
X          if (win->y_cur >= page_length)
X	    done = TRUE;
X	}
X    }
X  return(TRUE);
X}
X
int wget_scr(win, file, section)
X  WINDOW *win;
X  char   *file;
X  char   *section;
X{
X  FILE   *scr_file;
X  int    stat = FALSE;
X
X  if (win && file)
X    {
X      if ((scr_file = fopen(file, "r")) != NULL)
X        {
X          if (!section)
X	    section = DEF_SECTION;
X          if (find_section(scr_file, section) && get_page(win, scr_file))
X	    stat = TRUE;
X          fclose(scr_file);
X	}
X    }
X  return(stat);
X}
X
END_OF_FILE
if test 7419 -ne `wc -c <'lib/scrinput.c'`; then
    echo shar: \"'lib/scrinput.c'\" unpacked with wrong size!
fi
# end of 'lib/scrinput.c'
fi
if test -f 'lib/scrout8.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'lib/scrout8.c'\"
else
echo shar: Extracting \"'lib/scrout8.c'\" \(6898 characters\)
sed "s/^X//" >'lib/scrout8.c' <<'END_OF_FILE'
X/* module screen output */
X
X/*
X   provides UNIX "curses" type routines
X*/
X
X/*
X   created May 5, 1987 by JCT
X*/
X
X/*
X *	Copyright (c) John C. Tompkins 1989
X *	All rights reserved.
X *
X *	Permission is granted to use this for any personal, noncommercial use.
X *	You may not distribute source or executable code for profit, nor
X *	may you distribute it with a commercial product without the prior
X *      written consent of the author.  Please send modifications to the 
X *      author for inclusion in updates to the program.
X */
X
X#include <stdio.h>
X
X#include <km/defs.h>
X#include <km/scrio.h>
X
extern void free();
X
int scroll(win)				/* scroll up 1 line */
X  WINDOW *win;
X{
X  int                 i, j, x;
X  YX_ELEMENT          buf;
X  REGISTER YX_ELEMENT *ptr1;
X  REGISTER YX_ELEMENT *ptr2;
X
X  buf.ch = ' ';
X  if (win->ch_flags & REVERSED_COLOR)
X    buf.color = (((win->color >> 4) & 0x0f) || ((win->color << 4) & 0xf0));
X  else
X    buf.color = win->color;
X  buf.attrib = 0;
X  buf.ch_flags = 0;
X  ptr1 = win->buf; 
X  ptr2 = ptr1 + win->x_max;
X  i = win->buf_len;
X  j = i - win->x_max;
X  if (win->flags & BOX_FLAG)
X    {
X      ptr1 += (win->x_max + 1);
X      ptr2 += (win->x_max + 1);
X      i -= ((win->x_max << 1) + 2);
X      j -= ((win->x_max << 1) + 2);
X      x = win->x_max - 2;
X      for ( ; j; )
X        {
X	  if (x)
X	    {
X	      x--;
X              *ptr1++ = *ptr2++;
X	      i--;
X	      j--;
X	    }
X	  else
X	    {
X	      x = win->x_max - 2;
X	      ptr1 += 2;
X	      ptr2 += 2;
X	      i -= 2;
X	      j -= 2;
X	    }
X	}
X      ptr1 += 2;
X      i -= 2;
X    }
X  else
X    {
X      for ( ; j; i--, j--)
X        *ptr1++ = *ptr2++;
X    }
X  for ( ; i; i--)
X    *ptr1++ = buf;
X  win->ch_first = win->buf;
X  win->ch_last = win->buf + win->buf_len - 1;
X  win->flags &= ~NO_CHANGE;
X  return(TRUE);
X}
X
int delwin(win, freshen)			/* get rid of a window */
X  REGISTER WINDOW *win;
X  int             freshen;
X{
X
X/*
X   Deletes a window.
X   If parent windows, 'touches' the covered areas and if freshen, refreshes
X   all parent windows.
X*/
X
X  int             ay_min, ax_min, ay_max, ax_max, y_min, x_min, y_max, x_max;
X  YX_ELEMENT      *first, *last;
X  REGISTER WINDOW *win2;
X
X  if ((win == curscr) || (win == stdscr))
X    return(FALSE);
X  if (win->next)
X    win->next->prev = win->prev;
X  if (win->prev)
X    {
X      win->prev->next = win->next;
X      ay_min = win->y_org;
X      ax_min = win->x_org;
X      ay_max = ay_min + win->y_max;
X      ax_max = ax_min + win->x_max;
X      for (win2 = win->prev; win2->prev; win2 = win2->prev)
X	;
X      for ( ; win2 != win->next; win2 = win2->next)
X	{
X	  y_min = ay_min - win2->y_org;
X	  x_min = ax_min - win2->x_org;
X	  y_max = ay_max - win2->y_org;
X	  x_max = ax_max - win2->x_org;
X	  if (y_min < 0)
X	    y_min = 0;
X	  if (x_min < 0)
X	    x_min = 0;
X	  if (y_max >= win2->y_max)
X	    y_max = win2->y_max - 1;
X	  if (x_max >= win2->x_max)
X	    x_max = win2->x_max - 1;
X	  first = win2->buf + (y_min * win2->x_max) + x_min;
X	  last = win2->buf + (y_max * win2->x_max) + x_max;
X	  if (first < win2->ch_first);
X	    win2->ch_first = first;
X	  if (last > win2->ch_last)
X	    win2->ch_last = last;
X	  win2->flags &= ~NO_CHANGE;
X          if (freshen)
X	    wrefresh(win2);
X	}
X    }
X  free(win->buf);
X  free(win);
X  return(TRUE);
X}
X
int mvwin(win, new_y_org, new_x_org, freshen)
X  REGISTER WINDOW *win;
X  int             new_y_org;
X  int             new_x_org;
X  int             freshen;
X{
X
X/*
X   Moves a window to a new origin. If a subwindow, 'touches' areas of the
X   parent window(s) that used to be covered.  If freshen, refreshes the 
X   parent window(s), if any, and then refreshes the window itself.
X*/
X
X  int             ay_min, ax_min, ay_max, ax_max, y_min, x_min, y_max, x_max;
X  int             old_y_org, old_x_org;
X  YX_ELEMENT      *first, *last;
X  REGISTER WINDOW *win2;
X
X  if ((win == curscr) || (win == stdscr))
X    return(FALSE);
X  if ((new_y_org < 0) || (new_x_org < 0) ||
X      ((new_y_org + win->y_max) > LINES) ||
X      ((new_x_org + win->x_max) > COLS))
X    return(FALSE);
X  old_y_org = win->y_org;
X  old_x_org = win->x_org;
X  win->y_org = new_y_org;
X  win->x_org = new_x_org;
X  if (win->prev)
X    {
X      ay_min = old_y_org;
X      ax_min = old_x_org;
X      ay_max = ay_min + win->y_max;
X      ax_max = ax_min + win->x_max;
X      for (win2 = win->prev; win2->prev; win2 = win2->prev)
X	;
X      for ( ; win2 != win; win2 = win2->next)
X	{
X	  y_min = ay_min - win2->y_org;
X	  x_min = ax_min - win2->x_org;
X	  y_max = ay_max - win2->y_org;
X	  x_max = ax_max - win2->x_org;
X	  if (y_min < 0)
X	    y_min = 0;
X	  if (x_min < 0)
X	    x_min = 0;
X	  if (y_max >= win2->y_max)
X	    y_max = win2->y_max - 1;
X	  if (x_max >= win2->x_max)
X	    x_max = win2->x_max - 1;
X	  first = win2->buf + (y_min * win2->x_max) + x_min;
X	  last = win2->buf + (y_max * win2->x_max) + x_max;
X	  if (first < win2->ch_first)
X	    win2->ch_first = first;
X	  if (last > win2->ch_last)
X	    win2->ch_last = last;
X  	  win2->flags &= ~NO_CHANGE;
X          if (freshen)
X	    wrefresh(win2);
X	}
X    }
X  touchwin(win);
X  if (freshen)
X    wrefresh(win);
X  return(TRUE);
X}
X
int cpwin(win1, win2, flags)
X  WINDOW *win1;
X  WINDOW *win2;
X  int    flags;
X{
X
X/*
X   Copy win1 to win2, buffer contents only. Does not copy window color
X   or attributes but does copy character colors and attributes. Windows
X   don't have to be the same dimensions or size. If win1 is larger in
X   the X direction and CW_WRAP is set, lines are wrapped when copied,
X   otherwise they are truncated. If win1 is smaller in X and CW_JOIN is
X   set, then lines are joined, otherwise the rest of the line in win2 is
X   unaffected. If CW_NOBLANK is set, spaces from win1 are not copied
X   into win2, otherwise they are.
X
X   Defaults are truncate, no join and write blanks, i.e. win1 is xeroxed
X   into win2 within vertical and horizontal size constraints.
X*/
X
X  int                 i, win1_xless, max, win1_x, win2_x;
X  REGISTER YX_ELEMENT *win1_yx;
X  REGISTER YX_ELEMENT *win2_yx;
X
X  win1_yx = win1->buf;
X  win2_yx = win2->buf;
X  win1_x = 0;
X  win2_x = 0;
X  max = win1->buf_len;
X  if (win2->buf_len < max)
X    max = win2->buf_len;
X  win1_xless = (win1->x_max < win2->x_max);
X  for (i = 0; i < max; i++)
X    {
X      if (win1_xless)
X	{
X          if (!(flags & CW_JOIN) && (win2_x >= win1->x_max))
X	    {
X	      win2_yx++;
X	      win2_x++;
X	    }
X	  else
X	    {
X	      if ((flags & CW_NOBLANK) && (win1_yx->ch == ' '))
X	        ;
X	      else
X                *win2_yx = *win1_yx;
X	      win1_yx++;
X	      win2_yx++;
X	      win1_x++;
X	      win2_x++;
X	    }
X	}
X      else
X	{
X          if ((flags & CW_WRAP) || (win1_x < win2->x_max))
X	    {
X	      if ((flags & CW_NOBLANK) && (win1_yx->ch == ' '))
X	        ;
X	      else
X                *win2_yx = *win1_yx;
X	    }
X	  win1_yx++;
X	  win2_yx++;
X	  win1_x++;
X	  win2_x++;
X	}
X      if (win1_x >= win1->x_max)
X	win1_x = 0;
X      if (win2_x >= win2->x_max)
X	win2_x = 0;
X    }
X  return(TRUE);
X}
X
END_OF_FILE
if test 6898 -ne `wc -c <'lib/scrout8.c'`; then
    echo shar: \"'lib/scrout8.c'\" unpacked with wrong size!
fi
# end of 'lib/scrout8.c'
fi
if test -f 'lib/termcap.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'lib/termcap.c'\"
else
echo shar: Extracting \"'lib/termcap.c'\" \(6602 characters\)
sed "s/^X//" >'lib/termcap.c' <<'END_OF_FILE'
X/* Module termcap */
X
X/*
X   Provides the Berckley UNIX tgetent(), tgetstr(), tgetflag(),
X   and tgetnum() functions of termcap
X*/
X
X/*
X   Created October 17, 1987 by JCT
X*/
X
X/*
X *	Copyright (c) John C. Tompkins 1989
X *	All rights reserved.
X *
X *	Permission is granted to use this for any personal, noncommercial use.
X *	You may not distribute source or executable code for profit, nor
X *	may you distribute it with a commercial product without the prior
X *      written consent of the author.  Please send modifications to the 
X *      author for inclusion in updates to the program.
X */
X
X#include <ctype.h>
X#include <string.h>
X#include <fcntl.h>
X
X#include <km/defs.h>
X#include <km/termcap.h>
X
X#define MAX_BUF	1024
X
X#ifdef DOS
char   *Def_term = "ansi", ttytype[30];
X#else
char   *Def_term = "dumb", ttytype[30];
X#endif
int    My_term = FALSE;
short  ospeed;
char   *BC, *UP, PC;
TERMIO _tty, _stty;
int    _tty_ch;
X
X
X#ifdef UNIX
static char *tc_buf;
static int  ctr;
static char msg0[] = "Bad termcap entry\n";
static char msg1[] = "Infinate tc= loop\n";
static char msg2[] = "Termcap entry too long\n";
X#endif
X
extern char *getenv();
X
X#ifdef UNIX
static char *tskip(ptr)
X  REGISTER char *ptr;
X{
X  while (*ptr && (*ptr != ':'))
X    ptr++;
X  if (*ptr)
X    ptr++;
X  return(ptr);
X}
X
static char *tdecode(ptr, area)
X  char *ptr;
X  char **area;
X{
X  int  temp, total, count, in_table;
X  char *dest, *start, *ptr2;
X
X  static char tbl[] =
X    {
X      'E',  '\033',
X      '^',  '^',
X      '\\', '\\',
X      ':',  ':',
X      'n',  '\n',
X      'r',  '\r',
X      't',  '\t',
X      'b',  '\b',
X      'f',  '\f',
X      0
X    };
X
X  start = *area;
X  dest = start;
X  while (temp = *ptr++)
X    {
X      if (temp == ':')
X	break;
X      else if (temp == '\\')
X	{
X	  if (*ptr == '0')
X	    {
X	      total = 0;
X	      count = 2;
X	      while (isdigit(*++ptr) && count)
X		{
X		  total = (total * 8) + *ptr - '0';
X		  count--;
X		}
X	      *dest++ = total;
X	    }
X	  else
X	    {
X	      for (ptr2 = tbl, in_table = FALSE; *ptr2; ptr2 += 2)
X	        {
X	          if (*ptr == *ptr2)
X		    {
X		      *dest++ = *(ptr2 + 1);
X		      ptr++;
X		      in_table = TRUE;
X		      break;
X		    }
X		}
X	      if (!in_table)
X		*dest++ = '\\';
X	    }
X	}
X      else if (temp == '^')
X	*dest++ = *ptr++ & 0x1f;
X      else
X	*dest++ = temp;
X    }
X  *dest++ = '\0';
X  *area = dest;
X  return(start);
X}
X
static int tnamatch(name)
X  char *name;
X{
X  REGISTER char *ptr, *ptr2;
X
X  ptr = tc_buf;
X  if (*ptr != '#')
X    {
X      while (*ptr && (*ptr != ':'))
X        {
X	  ptr2 = name;
X          while (*ptr2 && (*ptr2 == *ptr++))
X            ptr2++;
X          if (!(*ptr2) && ((*ptr == '|') || (*ptr == ':')))
X            return(TRUE);
X          while (*ptr && (*ptr != ':') && (*ptr != '|'))
X	    ptr++;
X	  if (*ptr)
X	    ptr++;
X	}
X    }
X  return(FALSE);
X}
X
int tget1ent(bp, name)
X  char *bp;
X  char *name;
X{
X  char *termcap, *term, *store, buf[MAX_BUF];
X  int  fd = 0, num_read = 0, curr_pos = 0, temp;
X
X  tc_buf = bp;
X  if ((termcap = getenv("TERMCAP")) && *termcap)
X    {
X      if (*termcap != '/')
X	{
X	  if (!(term = getenv("TERM")) || (strcmp(name, term) == 0))
X	    {
X	      strcpy(bp, termcap);
X	      return(1);
X	    }
X	  else
X	    fd = open("/etc/termcap", O_RDONLY);
X	}
X      else
X	fd = open(termcap, O_RDONLY);
X    }
X  if (fd == 0)
X    fd = open("/etc/termcap", O_RDONLY);
X  if (fd <= 0)
X    return(-1);
X  for (;;)
X    {
X      store = bp;
X      for (;;)
X        {
X          if (num_read == curr_pos)
X            {
X              if ((num_read = read(fd, buf, MAX_BUF)) <= 0)
X	        {
X	          close(fd);
X	          return(0);
X	        }
X              else
X	        curr_pos = 0;
X            }
X          if ((temp = buf[curr_pos++]) == '\n')
X            {
X              if ((store > bp) && (*(store - 1) == '\\'))
X	        store--;
X              else
X	        break;
X            }
X	  else
X	    {
X	      if (store >= (bp + 1024))
X		{
X		  write(2, msg2, sizeof(msg2));
X		  break;
X		}
X	      *store++ = temp;
X	    }
X        }
X      *store = '\0';
X      if (tnamatch(name))
X	{
X	  close(fd);
X	  return(1);
X	}
X    }
X}
X
static int tnchktc()
X{
X  char *ptr, *ptr2, *ptr3, name_buf[16], buf[MAX_BUF];
X  int  curr_len;
X
X  ptr = tc_buf;
X  for (;;)
X    {
X      ptr2 = tc_buf + strlen(tc_buf) - 2;
X      while (*--ptr2 != ':')
X        {
X          if (ptr2 < tc_buf)
X	    {
X	      write(2, msg0, sizeof(msg0));
X	      return(0);
X	    }
X        }
X      ptr2++;
X      if ((*ptr2 == 't') && (*(ptr2 + 1) == 'c'))
X        {
X          strcpy(name_buf, (ptr2 + 3));		/* copy name into buf */
X          ptr3 = name_buf;
X          while (*ptr3 && (*ptr3 != ':'))	/* replace end ':' with '\0' */
X	    ptr3++;
X          *ptr3 = '\0';
X          if (++ctr > 32)
X	    {
X	      write(2, msg1, sizeof(msg1));
X	      return(0);
X	    }
X          if (tget1ent(buf, name_buf) != 1)
X	    return(0);
X          ptr3 = buf;
X          while (*ptr3 != ':')			/* find true start of buf */
X	    ptr3++;
X          strlen(ptr3);				/* get current length */
X          if ((curr_len = strlen(ptr3) + ptr2 - ptr) > MAX_BUF)
X	    {
X	      write(2, msg2, sizeof(msg2));
X	      buf[1023] = '\0';
X	      return(1);
X	    }
X          strcpy(ptr2, ptr3);			/* overwrite "tc=" with real */
X          tc_buf = ptr;
X        }
X      else
X        return(1);
X    }
X}
X
int tgetent(bp, name)
X  char *bp;
X  char *name;
X{
X  REGISTER int stat;
X
X  if ((stat = tget1ent(bp, name)) != 1)
X    return(stat);
X  return(tnchktc());
X}
X
int tgetflag(id)
X  REGISTER char *id;
X{
X  REGISTER char *ptr;
X
X  ptr = tc_buf;
X  while (*(ptr = tskip(ptr)))
X    {
X      if ((*ptr++ == *id) && *ptr && (*ptr++ == *(id + 1)))
X	{
X	  if (!(*ptr) || (*ptr == ':'))
X	    return(TRUE);
X	  else if (*ptr == '@')
X	    return(FALSE);
X	}
X    }
X  return(FALSE);
X}
X
int tgetnum(id)
X  REGISTER char *id;
X{
X  REGISTER char *ptr;
X  int           multiplier, total;
X
X  ptr = tc_buf;
X  while (*(ptr = tskip(ptr)))
X    {
X      if ((*ptr++ == *id) && *ptr && (*ptr++ == *(id + 1)))
X	{
X	  if (*ptr == '#')
X	    {
X	      if (*++ptr == '0')
X		{
X		  multiplier = 8;
X		  ptr++;
X		}
X	      else
X	        multiplier = 10;
X	      total = 0;
X	      while (isdigit(*ptr))
X		total = (total * multiplier) + *ptr++ - '0';
X	      return(total);
X	    }
X	  else if (*ptr == '@')
X	    return(ERROR);
X	}
X    }
X  return(ERROR);
X}
X
char *tgetstr(id, area)
X  REGISTER char *id;
X  char          **area;
X{
X  REGISTER char *ptr;
X
X  ptr = tc_buf;
X  while (*(ptr = tskip(ptr)))
X    {
X      if ((*ptr++ == *id) && *ptr && (*ptr++ == *(id + 1)))
X	{
X	  if (*ptr == '=')
X	    return(tdecode(++ptr, area));
X	  else if (*ptr == '@')
X	    return(FALSE);
X	}
X    }
X  return(FALSE);
X}
X#endif
X
END_OF_FILE
if test 6602 -ne `wc -c <'lib/termcap.c'`; then
    echo shar: \"'lib/termcap.c'\" unpacked with wrong size!
fi
# end of 'lib/termcap.c'
fi
if test -f 'montop.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'montop.c'\"
else
echo shar: Extracting \"'montop.c'\" \(6255 characters\)
sed "s/^X//" >'montop.c' <<'END_OF_FILE'
X/* System process activity monitor */
X
X/*
X*/
X
X/*
X   Created Sept 5, 1987 by JCT
X*/
X
X/*
X *	Copyright (c) John C. Tompkins 1989
X *	All rights reserved.
X *
X *	Permission is granted to use this for any personal, noncommercial use.
X *	You may not distribute source or executable code for profit, nor
X *	may you distribute it with a commercial product without the prior
X *      written consent of the author.  Please send modifications to the 
X *      author for inclusion in updates to the program.
X */
X
X#include <stdio.h>
X#include <ctype.h>
X
X#include <km/defs.h>
X#include <km/ascii.h>
X#include <km/scrio.h>
X#include <km/scrops.h>
X#include <km/monitor.h>		/* must come after defs.h and scrops.h */
X
X#define TLINE_1		2
X#define TCOL_1		2
X#define TCOL_2		22
X#define TCOL_3		28
X#define TOP_SIZE	8
X#define BAR_SIZE	46
X
typedef struct
X  {
X    int         index;
X    struct proc *pptr;
X    long        usage;
X  } TOP_CPU;
X
typedef struct
X  {
X    int  index;
X    char name[DIRSIZ + 1];
X  } TOP_NAME;
X
int      top_max;
TOP_CPU  top_cpu[TOP_SIZE];
TOP_NAME top_name[TOP_SIZE];
X
extern long lseek();
X
int top_chk(scr, key)
X  SCR *scr;
X  int key;
X{
X  key = tolower(key);
X  if (key == 'w')
X    {
X      if (get_interval())
X	{
X	  mode_scr.timeout = sample_interval;
X	  return (TRUE);
X	}
X    }
X  else if ((key >= 'a') && (key <= (top_max - 1 + 'a')))
X    return(do_proc(top_cpu[key - 'a'].pptr));
X  return (FALSE);
X}
X
void insert_top(index, pptr, usage)
X  int         index;
X  struct proc *pptr;
X  long        usage;
X{
X  int i, j;
X
X  for (i = 0; i < TOP_SIZE; i++)
X    {
X      if (top_cpu[i].index == UNDETERMINED)
X	{
X	  top_cpu[i].index = index;
X	  top_cpu[i].pptr = pptr;
X	  top_cpu[i].usage = usage;
X	  break;
X	}
X      if (top_cpu[i].usage < usage)
X	{
X	  for (j = (TOP_SIZE - 1); j > i; j--)
X	    top_cpu[j] = top_cpu[j - 1];
X	  top_cpu[i].index = index;
X	  top_cpu[i].pptr = pptr;
X	  top_cpu[i].usage = usage;
X	  break;
X	}
X    }
X}
X
int set_top()
X{
X  int         i, j, k;
X  struct proc *proc_ptr;
X#ifdef SYSV
X  int	      idle_index;
X#endif
X
X  if ((lseek(kfd, offsets.proc, 0) != ERROR) &&
X      (read(kfd, proc_buf, proc_size) != ERROR))
X    {
X      for (i = 0; i < TOP_SIZE; i++)
X        top_cpu[i].index = UNDETERMINED;
X      for (i = 0, proc_ptr = proc_buf; i < v_buf.v_proc; i++, proc_ptr++)
X	{
X#ifdef SYSV
X	  if (proc_ptr->p_pid == 0)
X	    idle_index = i;
X	  else
X#endif
X	  if (proc_ptr->p_stat)
X	    {
X	      if (proc_ptr->p_cpu)
X		insert_top(i, proc_ptr, (long)proc_ptr->p_cpu);
X	    }
X	}
X#ifdef SYSV
X      insert_top(idle_index, 0, idle_usage);
X#endif
X      return(TRUE);
X    }
X  return(FALSE);
X}
X
void bar_fraction(y, x, data, total)
X  int  y;
X  int  x;
X  long data;
X  long total;
X{
X  int  i;
X  long temp;
X
X  if (total)
X    {
X      temp = (BAR_SIZE * data) / total;
X      if (temp > BAR_SIZE)
X	temp = BAR_SIZE;
X    }
X  else
X    temp = 0;
X  move(y, x);
X  if (have_standout)
X    {
X      standout();
X      for (i = 0; i < temp; i++)
X	addch(' ');
X      standend();
X    }
X  else
X    {
X      for (i = 0; i < temp; i++)
X	addch('X');
X    }
X  for ( ; i < BAR_SIZE; i++)
X    addch(' ');
X}
X
char *get_top_name(index)
X  int index;
X{
X  int         i, j, pid, temp;
X  char        *in_ptr, *out_ptr, *start_name;
X  struct proc *proc_ptr;
X
X  proc_ptr = &proc_buf[index];
X  pid = proc_ptr->p_pid;
X  out_ptr = top_name[0].name;
X  if (pid == 0)
X    in_ptr = "idle";
X  else if (pid == 1)
X    in_ptr = "init";
X  else if (pid == 2)
X    in_ptr = "pager";
X  else
X    {
X      if (proc_ptr->p_flag & SLOAD)
X        {
X#ifdef XENIX
X          offsets.user = proc_ptr->p_addr.p_caddr * 512L;
X#else
X          offsets.user = (proc_ptr->p_addr[0] * (long)NBPC) + 0x600L;
X#endif
X          ufd = mfd;
X        } 
X      else
X        {
X#ifdef XENIX
X          offsets.user = (proc_ptr->p_addr.p_daddr + swplo) * BSIZE;
X#else
X          offsets.user = (proc_ptr->p_swaddr + swplo) * BSIZE;
X#endif
X          ufd = sfd;
X        }
X      if ((lseek(ufd, offsets.user, 0) != ERROR) &&
X          (read(ufd, &user_new, sizeof(struct user)) != ERROR))
X        in_ptr = user_new.u_comm;
X      else
X	return(NULL);
X      if (user_new.u_procp !=
X          (struct proc near*)(offsets.proc + index * sizeof(struct proc)))
X	return(NULL);
X    }
X  start_name = out_ptr;
X  for (i = 0; *in_ptr && (*in_ptr != ' ') && (*in_ptr != '\t') && (i < DIRSIZ); in_ptr++, i++)
X    *out_ptr++ = *in_ptr;
X  *out_ptr = '\0';
X  return(start_name);
X}
X
void put_top_name(line, col, name, num)
X  int  line;
X  int  col;
X  char *name;
X  int  num;
X{
X  move(line, col);
X  if (num != UNDETERMINED)
X    printw("%c : %-14s", num + 'A', name);
X  else
X    printw("                  ");
X}
X
void show_top()
X{
X  int i, line;
X
X  for (i = 0, top_max = 0; i < TOP_SIZE; i++)
X    {
X      line = TLINE_1 + 1 + (i * 2);
X      if (top_cpu[i].index != UNDETERMINED)
X	{
X	  top_max++;
X          bar_fraction(line, TCOL_3 + 2, top_cpu[i].usage, cpu_total);
X	  put_top_name(line, TCOL_1, get_top_name(top_cpu[i].index), i);
X	  move(line, TCOL_2);
X	  if (top_cpu[i].pptr->p_pid != 0)
X  	    printw("%5d", top_cpu[i].pptr->p_pid);
X	  else
X	    addstr("     ");
X	}
X      else
X	{
X          bar_fraction(line, TCOL_3 + 2, 0L, 0L);
X	  put_top_name(line, TCOL_1, "", UNDETERMINED);
X	  move(line, TCOL_2);
X	  addstr("     ");
X	}
X    }
X}
X
void chart_top()
X{
X  int i;
X
X  for (i = 0; i < TOP_SIZE; i++)
X    top_name[i].index = UNDETERMINED;
X  draw_box(stdscr, TLINE_1, TCOL_3, TLINE_1 + (TOP_SIZE * 2) + 2, TCOL_3 + (BAR_SIZE + 3));
X  move(TLINE_1 + (TOP_SIZE * 2), TCOL_3 + 2);
X  for (i = 0; i <= (BAR_SIZE - 1); i++)
X    {
X      if (i == 0)
X	addgraphic(G_LL);
X      else if (i == (BAR_SIZE - 1))
X	addgraphic(G_LR);
X      else if ((i % 9) == 0)
X	addgraphic(G_UT);
X      else
X	addgraphic(G_H);
X    }
X  move(TLINE_1 + (TOP_SIZE * 2) + 1, TCOL_3 + 2);
X  addch('0');
X  move(TLINE_1 + (TOP_SIZE * 2) + 1, TCOL_3 + 11);
X  addstr("20");
X  move(TLINE_1 + (TOP_SIZE * 2) + 1, TCOL_3 + 20);
X  addstr("40");
X  move(TLINE_1 + (TOP_SIZE * 2) + 1, TCOL_3 + 29);
X  addstr("60");
X  move(TLINE_1 + (TOP_SIZE * 2) + 1, TCOL_3 + 38);
X  addstr("80");
X  move(TLINE_1 + (TOP_SIZE * 2) + 1, TCOL_3 + 46);
X  addstr("100");
X  move(TLINE_1 + (TOP_SIZE * 2) + 2, TCOL_3 + 16);
X  addstr(" % CPU Utilization ");
X  if (set_top())
X    show_top();
X}
X
void plot_top()
X{
X  if (set_top())
X    show_top();
X}
X
END_OF_FILE
if test 6255 -ne `wc -c <'montop.c'`; then
    echo shar: \"'montop.c'\" unpacked with wrong size!
fi
# end of 'montop.c'
fi
echo shar: End of archive 3 \(of 9\).
cp /dev/null ark3isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 9 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0



More information about the Comp.unix.xenix mailing list