[comp.sources.misc] v09i045: siotools part 2/2

allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc) (12/05/89)

Posting-number: Volume 9, Issue 45
Submitted-by: wht%n4hgf@gatech.edu (Warren Tucker)
Archive-name: siotools/part02

#!/bin/sh
# This is a shell archive built by shar 3.03
# Created Mon Dec  4 18:28:32 EST 1989 by gatech!kd4nc!n4hgf!wht
# Source directory /u4/src/uusnap
#
# existing files WILL be overwriten
#
# This shar contains:
#    siomon.c
#    uusnap.c
#
touch 2>&1 | fgrep '[-amc]' > /tmp/s3_touch$$
if [ -s /tmp/s3_touch$$ ]
then
	TOUCH=can
else
	TOUCH=cannot
fi
rm -f /tmp/s3_touch$$
echo "x - extracting siomon.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > siomon.c &&
X/* CHK=0x4E4E */
Xchar *revision = "1.30";
X/*+-------------------------------------------------------------------------
X	siomon.c -- watch XENIX/UNIX serial I/O
X	...!gatech!kd4nc!n4hgf!wht
X
X    Sample output:
X    000000000011111111112222222222333333333344444444445555555555666666666677777
X    012345678901234567890123456789012345678901234567890123456789012345678901234
X 00  siomon 1.2 (UNIX V.3.2/i386) n4hgf               delay:  1        21:54:54
X 01	
X 02	 tty  raw  can   out   speed  state iflag  oflag  cflag  lflag  pgrp
X 03	 ---  ---  ---  -----  -----  ----- ------ ------ ------ ------ -----
X 04	 1a     0    0      0   9600  OC     10045      0   6655      0     0
X 05	 1b
X 06	 1c
X 07	 1d
X 08	 1e
X 09	 1f
X 10	 1g
X 11	 1h
X 12	 2a
X 13	 2b
X 14	 2c
X 15	 2d     0    0      0   9600  W          0      0   2275      0     0
X 16	 2e
X 17	 2f     0    0      0   4800  OC     10040      0   2374      0     0
X 18	 2g     0    0      0   4800  OC     10005      0   6374      0     0
X 19	 2h
X 20	
X 21	State: W waiting for open to complete  O open  C carrier on
X 22	       S stopped by XOFF  D delay timeout in progress
X 23 Commands: + inc delay  - dec delay  ^L refresh  q quit  d detail
X
XUnder XENIX, termio.h is included twice (once by curses.h/tcap.h andf
Xagain by sys/tty.h.  You need to bracket the termio.h under XENIX with
X  #if !defined(TERMIO_HACK) || (defined(TERMIO_HACK) && !defined(IOCTYPE))
X  ...
X  #endif
X
X  Defined functions:
X	detail()
X	disp_delay()
X	display_tod()
X	disp_tty(y,sionum,tty)
X	leave()
X	main(argc,argv,envp)
X	main_template()
X
X  Kudos to pyrnj.pyramid.com!romain (Romain Kang) for many suggestions
X  regarding screen and CPU efficiency in the original itpmon.c for Pyramid
X--------------------------------------------------------------------------*/
X/*+:EDITS:*/
X/*:12-04-1989-16:45-wht-add more to detail */
X/*:11-28-1989-19:49-wht-no more sprintf and allow nap/rdchk in lieu of select */
X/*:11-22-1989-12:33-wht-rehost my Pyramid itpmon.c */
X
X/* -------- select(S) availability --------- */
X/* define HAVE_SELECT */ /* uncomment for XENIX/386 2.3.2 and later */
X#if (defined(M_UNIX) && (!defined(HAVE_SELECT))) /* automatic for UNIX */
X#define HAVE_SELECT
X#endif
X
X#include <curses.h>
X#include <signal.h>
X#include <sys/types.h>
X#include <sys/utsname.h>
X#include <time.h>
X
X#if defined(HAVE_SELECT)
X#include <sys/select.h>
X#endif
X
X#define TERMIO_HACK /* for XENIX termio.h multiple inclusion problem */
X#include <sys/tty.h>
X
X#include "wintty.h"
X#include "kmemsio.h"
X#include "utoa.h"
X
X#define HY 2	/* header line */
X#define TX 1
X#define RX 6
X#define CX 11
X#define OX 16
X#define SX 23
X#define FX 30
X
Xextern char _sobuf[];
Xextern int errno;
Xextern char *sys_errlist[];
X
Xint no_tod = 0;
Xint delay_secs = 1;
Xstruct utsname me;
X
X/*+-------------------------------------------------------------------------
X	leave() - terminate curses, reset terminal and exit
X--------------------------------------------------------------------------*/
Xvoid
Xleave()
X{
X	if(!stdscr)
X	{
X		nocrmode();
X		echo();
X		exit(0);
X	}
X	move(LINES - 1,0);
X	refresh();
X	endwin();
X	exit(0);
X}	/* end of leave */
X
X/*+-------------------------------------------------------------------------
X	disp_tty(y,sionum,tty)
X--------------------------------------------------------------------------*/
Xvoid
Xdisp_tty(y,sionum,tty)
Xint y;
Xint sionum;
Xregister struct tty *tty;
X{
Xregister int xo = (sionum > 15) ? 40 : 0;	/* x offset */
Xregister unsigned int itmp;
Xregister opened = tty->t_state & (ISOPEN | WOPEN);
Xchar s8[8];
X
X	move(y,TX + xo);
X	addch((sionum < 8) ? '1' : '2');
X	addch((sionum % 8) + 'a');
X
X	if(!opened)
X	{
X		clrtoeol();
X		return;
X	}
X
X	if((itmp = (unsigned)tty->t_rawq.c_cc) > 999)
X		itmp = 999;
X	utoda(s8,3,itmp);
X	move(y,RX + xo);
X	if(itmp > 10)
X		standout();
X	addstr(s8);
X	if(itmp > 10)
X		standend();
X
X	if((itmp = (unsigned)tty->t_canq.c_cc) > 999)
X		itmp = 999;
X	utoda(s8,3,itmp);
X	move(y,CX + xo);
X	addstr(s8);
X
X	if((itmp = (unsigned)tty->t_outq.c_cc + tty->t_tbuf.c_count) > 99999)
X		itmp = 99999;
X	utoda(s8,5,itmp);
X	move(y,OX + xo);
X	addstr(s8);
X
X	move(y,SX + xo);
X	addstr(B_to_baud_rate(tty->t_cflag & CBAUD));
X
X	strcpy(s8,"     ");
X	if(tty->t_state & WOPEN)
X		s8[0] = 'W';
X	else if(tty->t_state & ISOPEN)
X		s8[0] = 'O';
X	if(tty->t_state & CARR_ON)
X		s8[1] = 'C';
X	if(tty->t_state & BUSY)
X		s8[2] = 'B';
X	if(tty->t_state & TTSTOP)
X		s8[3] = 'S';
X	if(tty->t_state & TIMEOUT)
X		s8[3] = 'D';
X	move(y,FX + xo);
X	addstr(s8);
X
X	utooa(s8,7,tty->t_iflag);
X	addstr(s8);
X
X	utooa(s8,7,tty->t_oflag);
X	addstr(s8);
X
X	utooa(s8,7,tty->t_cflag);
X	addstr(s8);
X
X	utooa(s8,7,tty->t_lflag);
X	addstr(s8);
X
X	utoda(s8,6,tty->t_pgrp);
X	addstr(s8);
X
X}	/* end of disp_tty */
X
X/*+-------------------------------------------------------------------------
X	disp_delay()
X--------------------------------------------------------------------------*/
Xvoid
Xdisp_delay()
X{
Xchar dmsg[12];
X
X	move(0,50);
X	addstr("delay: ");
X	utoda(dmsg,2,delay_secs);
X	addstr(dmsg);
X}	/* end of disp_delay */
X
X/*+-------------------------------------------------------------------------
X	display_tod()
X--------------------------------------------------------------------------*/
Xvoid
Xdisplay_tod()
X{
Xregister struct tm *lt;		/* local time */
Xstruct tm *localtime();
Xlong now;
Xchar buf[10];
X
X	if(no_tod)
X		return;
X
X	time(&now);
X	lt = localtime(&now);
X	utoda_lz(buf,2,lt->tm_hour);
X	buf[2] = ':';
X	utoda_lz(buf + 3,2,lt->tm_min);
X	buf[5] = ':';
X	utoda_lz(buf + 6,2,lt->tm_sec);
X	move(0,COLS - 13);
X	addstr(buf);
X}	/* end of display_tod */
X
X/*+-------------------------------------------------------------------------
X	main_template()
X--------------------------------------------------------------------------*/
Xvoid
Xmain_template()
X{
Xstatic char *header  = 
X	" tty  raw  can   out   speed  state iflag  oflag  cflag  lflag  pgrp";
Xstatic char *hyphens =
X	" ---  ---  ---  -----  -----  ----- ------ ------ ------ ------ -----";
XFILE *fp = fopen("/etc/systemid","r");
Xchar sysid[32];
X
X	wclear(stdscr);
X	move(0,0);
X	standout();
X	printw(" siomon %s (%s V.%s/%s)",
X		revision,
X#if defined(M_UNIX)
X		"UNIX",
X#else
X		"XENIX",
X#endif
X		me.release,me.machine);
X	if(fp)
X	{
X		sysid[0] = 0;
X		fgets(sysid,sizeof(sysid),fp);
X		if(sysid[0])
X		{
X			sysid[strlen(sysid) - 1] = 0;
X			printw(" %s ",sysid);
X		}
X		fclose(fp);
X	}
X	standend();
X	move(HY,0);
X	addstr(header);
X	move(HY + 1,0);
X	addstr(hyphens);
X	move(LINES - 4,0);
X	addstr(
X"State: W waiting for open to complete  O open  C carrier on");
X	move(LINES - 3,0);
X	addstr(
X"       S stopped by XOFF  D delay timeout in progress ");
X	move(LINES - 2,0);
X	addstr(
X"Commands: + inc delay  - dec delay  ^L refresh  q quit  d detail");
X	move(LINES - 1,0);
X	disp_delay();
X	refresh();
X}	/* end of main_template */
X
X/*+-------------------------------------------------------------------------
X	detail()
X--------------------------------------------------------------------------*/
Xvoid
Xdetail()
X{
Xint y,x;
Xint sionum;
Xchar tty_name[16];
Xchar *cptr;
Xchar cmd;
Xint cmd_available;
X#if defined(HAVE_SELECT)
Xstruct timeval timeout;
Xint readfds;
X#else
Xlong ltimeout;
Xlong nap();
X#endif
X
X	for(y = 0; y < 16; y++)
X	{
X		move(HY + 2 + y,0);
X		clrtoeol();
X	}
X	move(HY + 2,0);
X	addstr("display detail on /dev/tty__");
X	getyx(stdscr,y,x);
X	move(y,x - 2);
X	refresh();
X	resetty();
X	getstr(tty_name);
X	raw();
X	noecho();
X
X	if((strlen(tty_name) == 2) &&
X		((tty_name[0] == '1') || (tty_name[0] == '2')))
X		sionum = ((tty_name[0] - '1') * 8) + ((tty_name[1] & 7) - 1);
X	else
X	{
X		fputc(7,stderr);
X		goto DETAIL_EXIT;
X	}
X
X	move(HY + 2 + 11,0);
X	addstr("press ESC to return to main display (or -,+ delay cmds)");
X
X	move(HY + 2,0);
X	clrtoeol();
X	wintty_template(stdscr,HY + 2 + 2,0,1);
X	while(1)
X	{
X		display_tod();
X		kmem_read_tty(sionum,1);
X		disp_tty(HY + 2,sionum,&sio[0]);
X		wintty(stdscr,HY + 2 + 2,0,&sio[0]);
X		move(HY + 2 + 11,0);
X		refresh();
X#if defined(HAVE_SELECT)
X		readfds = 1;			/* for standard input */
X		timeout.tv_sec  = delay_secs;
X		timeout.tv_usec = (delay_secs) ? 0 : 100*1000L;
X		cmd_available = (select(32,&readfds,0,0,&timeout) > 0);
X#else
X		ltimeout = (delay_secs) ? (delay_secs * 1000L) : 100L;
X		while(ltimeout > 0)
X		{
X			ltimeout -= nap(100L);
X			if(cmd_available = rdchk(0))
X				break;
X		}
X#endif
X		if(rdchk(0))
X		{
X			cmd = getch();
X			if(cmd == 0x1B)
X				break;
X			switch(cmd)
X			{
X				case '+':
X					delay_secs++;
X					disp_delay();
X					break;
X
X				case '-':
X					if(!delay_secs)
X						break;
X					delay_secs--;
X					disp_delay();
X					break;
X			}
X		}
X	}
X
XDETAIL_EXIT:
X	main_template();
X	refresh();
X
X}	/* end of detail */
X
X/*+-------------------------------------------------------------------------
X	main(argc,argv,envp)
X--------------------------------------------------------------------------*/
Xmain(argc,argv,envp)
Xint argc;
Xchar **argv;
Xchar **envp;
X{
Xregister sionum;
Xchar *cptr;
Xint cmd_available;
X#if defined(HAVE_SELECT)
Xstruct timeval timeout;
Xint readfds;
X#else
Xlong ltimeout;
Xlong nap();
X#endif
X
X	if((argc > 1) && !strcmp(argv[1],"-n"))
X		no_tod = 1;
X
X	signal(SIGINT,leave);
X	signal(SIGTERM,leave);
X	uname(&me);
X
X	setbuf(stdout,_sobuf);
X	initscr();
X	crmode();
X	noecho();
X	if(!stdscr)
X	{
X		fprintf(stderr,"curses init failed\n");
X		nocrmode();
X		echo();
X		exit(1);
X	}
X	main_template();
X
X	move(4,0);
X	standout();
X	addstr("  initializing  ");
X	if(cptr = kmem_init_tty())
X	{
X		move(4,0);
X		addstr(cptr);
X		leave();
X	}
X	standend();
X	refresh();
X
X	move(4,0);
X	addstr("                ");
X
X	while(1)
X	{
X		kmem_read_tty(0,16);
X		for(sionum = 0; sionum < SIO_NTTY; sionum++)
X			disp_tty(HY + 2 + (sionum & 15),sionum,&sio[sionum]);
X		display_tod();
X		move(LINES - 1,0);
X		refresh();
X
X#if defined(HAVE_SELECT)
X		readfds = 1;			/* for standard input */
X		timeout.tv_sec  = delay_secs;
X		timeout.tv_usec = (delay_secs) ? 0 : 100*1000L;
X		cmd_available = (select(32,&readfds,0,0,&timeout) > 0);
X#else
X		ltimeout = (delay_secs) ? (delay_secs * 1000L) : 100L;
X		while(ltimeout > 0)
X		{
X			ltimeout -= nap(100L);
X			if(cmd_available = rdchk(0))
X				break;
X		}
X#endif
X
X		if(cmd_available)
X		{
X		char ch;
X			ch = getch();
X			switch(ch & 0x7F)
X			{
X			case 'L' & 0x1F:		/* redraw screen */
X			case 'R' & 0x1F:		/* redraw screen */
X				main_template();
X				continue;
X
X			case '+':
X				delay_secs++;
X				disp_delay();
X				break;
X
X			case '-':
X				if(!delay_secs)
X					break;
X				delay_secs--;
X				disp_delay();
X				break;
X
X			case 'q':		/* quit */
X			case 0x1B:
X				leave();
X				break;
X
X			case 'd':		/* detail */
X				detail();
X				break;
X
X			}
X		}
X	}
X}	/* end of main */
X
X/* vi: set tabstop=4 shiftwidth=4: */
X/* end of siomon.c */
SHAR_EOF
chmod 0644 siomon.c || echo "restore of siomon.c fails"
if [ $TOUCH = can ]
then
    touch -m 1204182889 siomon.c
fi
echo "x - extracting uusnap.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > uusnap.c &&
X/* CHK=0xB1F9 */
Xchar *revision = "1.60";
X/*+-------------------------------------------------------------------------
X	uusnap.c - display UUCP communications status for HDB systems
X    ...gatech!kd4nc!n4hgf!wht
X
X  Many ideas in this program came from uustatus.c by Ed Carp 
X
X  Defined functions:
X	basename(fullname)
X	bye(sig)
X	cmd_line(text)
X	datetime5(secs)
X	detail()
X	dir_close(dirp)
X	dir_open(dirname)
X	dir_read(dirp)
X	display_status(sysnum,system_name,y,status_info)
X	display_tod()
X	display_tty(sionum,tty)
X	get_status_info(system_name,buf,bufsize)
X	lockpid_to_tty(lockpid)
X	main(argc,argv)
X	spooldirname(fname)
X	statdirname(fname)
X
XUnder XENIX, termio.h is included twice (once by curses.h/tcap.h andf
Xagain by sys/tty.h.  You need to bracket the termio.h under XENIX with
X  #if !defined(TERMIO_HACK) || (defined(TERMIO_HACK) && !defined(IOCTYPE))
X  ...
X  #endif
X
X--------------------------------------------------------------------------*/
X/*+:EDITS:*/
X/*:12-04-1989-16:45-wht-add detail in full */
X/*:12-01-1989-16:53-wht-XENIX 286 work: no beep()! */
X/*:11-30-1989-17:48-wht-complete rewrite to add detail status */
X
X#include <curses.h>
X#include <signal.h>
X#include <time.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X#define TERMIO_HACK /* for XENIX termio.h multiple inclusion problem */
X#include <sys/tty.h>
X#include <sys/utsname.h>
X#if defined(M_UNIX)
X#include <sys/select.h>
X#endif
X
X#include "wintty.h"
X#include "kmemsio.h"
X#include "utoa.h"
X
X#define FIRSTSYS_Y	4
X#define NAME_X		4
X#define RCNT_X		14
X#define QCNT_X		19
X#define LAST_X		24
X#define NEXT_X		30
X#define PID_X		36
X#define STATUS_X	42
X
X/* display_tty x offsets */
X#define TX 0
X#define RX 5
X#define CX 10
X#define OX 15
X#define SX 22
X#define FX 29
X
Xextern char _sobuf[];
Xextern int errno;
Xextern char *sys_errlist[];
X
X#define DDIR FILE
XDDIR *stat_dp;
XDDIR *work_dp;
Xstruct dent 
X{
X	unsigned short d_inode;
X	char d_name[14];
X};
X
Xlong secs_now;
Xint systems;
Xint no_tod = 0;
Xchar sysnames[64 * 16];	/* sorta hack, but ka-plenty name space */
Xchar locked_tty[16];
X
Xchar *STATUSDIR = "/usr/spool/uucp/.Status";
Xchar *LOCKDIR = "/usr/spool/uucp/LCK..";
Xchar *WORKDIR = "/usr/spool/uucp/";
Xchar *SPOOLDIR = "/usr/spool/uucp";
Xchar *LOGFILE = "/tmp/uuexp.log";
X
X#define MAX_SYSTEMS (LINES - FIRSTSYS_Y - 6)
X#define WAITSECS_ACTIVE 1 /* sleep secs between samples when talking */
X#define WAITSECS_IDLE   7 /* sleep secs between samples when not talking */
X
X#define SS_OK                    0 	/* successful */
X#define SS_NO_DEVICE             1 	/* no device */
X#define SS_TIME_WRONG            2 	/* wrong time to call */
X#define SS_TALKING               3 	/* TALKING */
X#define SS_CONVERSATION          4 	/* conversation failed */
X#define SS_SEQBAD                5 	/* bad sequence check */
X#define SS_LOGIN_FAILED          6 	/* login failed */
X#define SS_DIAL_FAILED           7 	/* dial failed */
X#define SS_BAD_LOG_MCH           8 	/* bad login/machine */
X#define SS_LOCKED_DEVICE         9 	/* DEVICE LOCKED */
X#define SS_ASSERT_ERROR          10	/* assert error */
X#define SS_BADSYSTEM             11	/* system not in Systems */
X#define SS_CANT_ACCESS_DEVICE    12	/* can't access device */
X#define SS_DEVICE_FAILED         13	/* device failed */
X#define SS_WRONG_MCH             14	/* wrong machine name */
X#define SS_CALLBACK              15	/* callback required */
X#define SS_RLOCKED               16	/* remote has lock for me */
X#define SS_RUNKNOWN              17	/* remote does not know me */
X#define SS_RLOGIN                18	/* remote reject after login */
X#define SS_UNKNOWN_RESPONSE      19	/* remote reject, unknown msg */
X#define SS_STARTUP               20	/* startup failed */
X#define SS_CHAT_FAILED           21	/* caller script failed */
X#if defined(M_XENIX) || defined(M_UNIX)
X#define SS_CALL_IN_PROGRESS	     22	/* CALL IN PROGRESS */
X#define SS_CALL_FAILED           23	/* call failed (busy?) */
X#else
X#define SS_CALL_IN_PROGRESS	     22	/* CALL IN PROGRESS */
X#endif
X
Xstruct utsname me;
Xint uucico_active;
X
Xchar *errortext[] =
X{
X	/*       00000000001111111111222222 */
X	/*       01234567890123456789012346 */
X	/* 0 */ "successful",
X	/* 1 */ "no device",
X	/* 2 */ "wrong time to call",
X	/* 3 */ "TALKING",
X	/* 4 */ "conversation failed",
X	/* 5 */ "bad sequence check",
X	/* 6 */ "login failed",
X	/* 7 */ "dial failed",
X	/* 8 */ "bad login/machine",
X	/* 9 */ "DEVICE LOCKED",
X	/* 10*/ "assert error",
X	/* 11*/ "system not in Systems",
X	/* 12*/ "can't access device",
X	/* 13*/ "device failed",
X	/* 14*/ "wrong machine name",
X	/* 15*/ "callback required",
X	/* 16*/ "remote has lock for me",
X	/* 17*/ "remote does not know me",
X	/* 18*/ "remote reject after login",
X	/* 19*/ "remote reject, unknown msg",
X	/* 20*/ "startup failed",
X	/* 21*/ "caller script failed",
X#if defined(M_XENIX) || defined(M_UNIX)
X	/* 22*/ "CALL IN PROGRESS",
X	/* 23*/ "call failed (busy?)",
X#else
X	/* 22*/ "CALL IN PROGRESS",
X#endif
X};
X
X#if defined(M_XENIX) || defined(M_UNIX)
X#define SS_MSG_MAX 23
X#else
X#define SS_MSG_MAX 22
X#endif
X
X/*+-------------------------------------------------------------------------
X	dir_open(dirname)
X--------------------------------------------------------------------------*/
XDDIR *
Xdir_open(dirname)
Xchar *dirname;
X{
X	DDIR *fp = fopen(dirname,"r");
X	return(fp);
X}	/* end of dir_open */
X
X/*+-------------------------------------------------------------------------
X	dir_read(dirname)
X--------------------------------------------------------------------------*/
Xstruct dent *
Xdir_read(dirp)
XDDIR *dirp;
X{
Xstatic struct dent_w_null { 
X	struct dent dent; 
X	int null;
X} static_dent;
X
X
X	do {
X		if(fread((char *)&static_dent.dent,sizeof(struct dent),1,dirp) != 1)
X			return((struct dent *)0);
X	} while(!static_dent.dent.d_inode);
X
X	static_dent.null = 0;
X	return(&static_dent.dent);
X}	/* end of dir_open */
X
X/*+-------------------------------------------------------------------------
X	dir_close(dirp)
X--------------------------------------------------------------------------*/
Xvoid
Xdir_close(dirp)
XDDIR *dirp;
X{
X	if(dirp)
X		fclose(dirp);
X}	/* end of dir_close */
X
X/*+-------------------------------------------------------------------------
X	datetime5(secs) - return 5 char date or time string
X
Xneeds global 'secs_now' to reflect current time in "seconds since epoch"
X(done by display_tod()); returns 5 character 'mm/dd' if time now is more
Xthan 12 hours before now or 12 hours from now
X--------------------------------------------------------------------------*/
Xchar *
Xdatetime5(secs)
Xlong secs;
X{
Xregister long delta = secs_now - secs;
Xstruct tm *lt = localtime(&secs);
Xstatic char dt5[8];
X
X	if(delta < 0)
X		delta = -delta;
X
X	if(delta > (12L * 3600))
X	{
X		utoda_lz(dt5,2,lt->tm_mon);
X		dt5[2] = '/';
X		utoda_lz(dt5 + 3,2,lt->tm_mday);
X	}
X	else
X	{
X		utoda_lz(dt5,2,lt->tm_hour);
X		dt5[2] = ':';
X		utoda_lz(dt5 + 3,2,lt->tm_min);
X	}
X
X	return(dt5);
X
X}	/* end of datetime5 */
X
X/*+-------------------------------------------------------------------------
X	basename(fullname) - strip directory name from filename
X
Xreturns address of static string
X--------------------------------------------------------------------------*/
Xchar *
Xbasename(fullname)
Xchar *fullname;
X{
Xregister char *start;
Xstatic char outstr[256];
Xchar *strrchr();
X
X	start = strrchr(fullname,'/'); /* find last slash */
X	if(!start)
X		return(fullname);
X	start++;
X	strcpy(outstr,start);
X	return(outstr);
X}	/* end of basename */
X
X/*+-------------------------------------------------------------------------
X	statdirname(fname) - return base name prepended with status dir
X
Xreturns address of static string
X--------------------------------------------------------------------------*/
Xchar *
Xstatdirname(fname)
Xchar *fname;
X{
Xstatic char fullname[128];
Xstatic int fullname_cat_point = 0;
X
X	if(!fullname_cat_point)
X	{
X		strcpy(fullname,STATUSDIR);
X		strcat(fullname,"/");
X		fullname_cat_point = strlen(fullname);
X	}
X
X	strcpy(fullname + fullname_cat_point,fname);
X	return(fullname);
X
X}	/* end of statdirname */
X
X/*+-------------------------------------------------------------------------
X	spooldirname(fname) - return base name prepended with spool dir
X
Xreturns address of static string
X--------------------------------------------------------------------------*/
Xchar *
Xspooldirname(fname)
Xchar *fname;
X{
Xstatic char fullname[128];
Xstatic int fullname_cat_point = 0;
X
X	if(!fullname_cat_point)
X	{
X		strcpy(fullname,SPOOLDIR);
X		strcat(fullname,"/");
X		fullname_cat_point = strlen(fullname);
X	}
X
X	strcpy(fullname + fullname_cat_point,fname);
X	return(fullname);
X
X}	/* end of statdirname */
X
X/*+-------------------------------------------------------------------------
X	display_tod()
X--------------------------------------------------------------------------*/
Xvoid
Xdisplay_tod()
X{
Xregister struct tm *lt;		/* local time */
Xstruct tm *localtime();
Xchar buf[10];
X
X	(void)time(&secs_now);
X
X	if(no_tod)
X		return;
X
X	lt = localtime(&secs_now);
X	utoda_lz(buf,2,lt->tm_hour);
X	buf[2] = ':';
X	utoda_lz(buf + 3,2,lt->tm_min);
X	buf[5] = ':';
X	utoda_lz(buf + 6,2,lt->tm_sec);
X	move(0,COLS - 13);
X	addstr(buf);
X
X}	/* end of display_tod */
X
X/*+-------------------------------------------------------------------------
X	bye(sig) - exit cleanly
X--------------------------------------------------------------------------*/
Xvoid
Xbye(sig)
Xint sig;
X{
X	if(stdscr)
X	{
X		standend();
X		move(LINES - 4,0);
X		clrtobot();
X		refresh();
X		echo();
X		noraw();
X		move(LINES - 1,0);
X		refresh();
X		endwin();
X	}
X	exit(0);
X}	/* end of bye */
X
X/*+-------------------------------------------------------------------------
X	lockpid_to_tty(lockpid) - given pid, find first ttyname it has locked
X--------------------------------------------------------------------------*/
Xchar *
Xlockpid_to_tty(lockpid)
Xint lockpid;
X{
XDDIR *uspool_dp;
Xstruct dent *dp;
XFILE *fp;
Xint testpid;
Xstatic char rtnname[32];
X
X	if(uspool_dp = dir_open(SPOOLDIR))
X	{
X		while(dp = dir_read(uspool_dp))
X		{
X			if(strncmp(dp->d_name,"LCK..tty",8))
X				continue;
X			if(fp = fopen(spooldirname(dp->d_name),"r"))
X			{
X				fscanf(fp,"%d",&testpid);
X				fclose(fp);
X				if(testpid == lockpid)
X				{
X					strcpy(rtnname,dp->d_name + 5);
X					dir_close(uspool_dp);
X					return(rtnname);
X				}
X			}
X		}
X		dir_close(uspool_dp);
X	}
X	return((char *)0);
X}	/* end of lockpid_to_tty */
X
X/*+-------------------------------------------------------------------------
X	cmd_line(text)
X--------------------------------------------------------------------------*/
Xcmd_line(text)
Xchar *text;
X{
X	move(LINES - 4,0);
X	clrtoeol();
X
X	if(!text)
X		addstr(
X		"type 'q' to quit, 'd' for detail, SPACE to update immediately");
X	else
X		addstr(text);
X
X}	/* end of cmd_line */
X
X/*+-------------------------------------------------------------------------
X	get_status_info(system_name,buf,bufsize)
X--------------------------------------------------------------------------*/
Xint
Xget_status_info(system_name,buf,bufsize)
Xchar *system_name;
Xchar *buf;
Xint bufsize;
X{
XFILE *fp;
X
X	if(!(fp = fopen(statdirname(system_name),"r")))
X		return(-1);
X	buf[0] = 0;
X	fgets(buf,bufsize,fp);
X	fclose(fp);
X	if(!buf[0])
X		return(-1);
X	buf[strlen(buf) - 1] = 0;
X	return(0);
X
X}	/* end of get_status_info */
X
X/*+-------------------------------------------------------------------------
X	display_status(sysnum,system_name,y,status_info)
X
Xcalled with status_info either .Status/<system_name> line or null
Xif a tty is locked on the line, global locked_tty has "ttyxx"
Xreturns -1 if status_info null and can't get it, else 0
X--------------------------------------------------------------------------*/
Xdisplay_status(sysnum,system_name,y,status_info)
Xint sysnum;
Xchar *system_name;
Xint y;
Xchar *status_info;
X{
Xint itmp;
Xint retry_count;
Xint status;
Xint queue_count;
Xchar *stattxt;
Xint locking_pid;
Xchar *ttyname;
Xchar lock_name[64];
Xchar s32[32];
Xchar work_dir[64];
Xchar linebuf[512];
Xlong secs_last_try;
Xlong secs_next_try;
Xstruct dent *dp;
XFILE *fp;
X
X	if(!status_info)
X	{
X		status_info = linebuf;
X		if(get_status_info(system_name,status_info,sizeof(linebuf)))
X			return(-1);
X	}
X
X	sscanf(status_info,"%d %d %ld %ld",
X	    &status,&retry_count,&secs_last_try,&secs_next_try);
X	secs_next_try += secs_last_try;	/* files has secs til next retry */
X
X	strcpy(work_dir,WORKDIR);
X	strcat(work_dir,system_name);
X
X	queue_count = 0;
X	if(work_dp = dir_open(work_dir))
X	{
X		/* count the number of C. queue_count */
X		while(dp = dir_read(work_dp))
X		{
X			if(!strncmp(dp->d_name,"C.",2))
X				queue_count++;
X			if(queue_count > 99)
X				break;
X		}
X		dir_close(work_dp);
X	}
X
X	/* "kludges for screwy status stuff with HDB" thanks to Ed Carp */
X	strcpy(lock_name,LOCKDIR);
X	strcat(lock_name,system_name);
X	if(!access(lock_name,0) && (status != SS_TALKING))
X		status = SS_CALL_IN_PROGRESS;
X	if(status == SS_BADSYSTEM)
X		status = SS_DEVICE_FAILED;
X
X	move(y,0);
X	utoda(s32,2,sysnum);
X	addstr(s32);
X	addch(' ');
X
X	strcpy(s32,system_name);
X	if(strlen(s32) > 10)
X		s32[10] = 0;
X	addstr(s32);
X
X	move(y,RCNT_X);
X	if(retry_count)
X	{
X		if(retry_count > 999)
X			retry_count = 999;
X		utoda(s32,3,retry_count);
X		addstr(s32);
X	}
X	else
X		addstr("   ");
X
X	move(y,QCNT_X);
X	if(queue_count)
X	{
X		if(queue_count > 99)
X			addstr(">99");
X		else
X		{
X			utoda(s32,3,queue_count);
X			addstr(s32);
X		}
X	}
X	else
X		addstr("   ");
X
X	move(y,LAST_X);
X	addstr(datetime5(secs_last_try));
X
X	move(y,NEXT_X);
X	addstr(datetime5(secs_next_try));
X
X	locking_pid = 0;
X	locked_tty[0] = 0;
X	move(y,PID_X);
X	addstr("     ");
X	ttyname = (char *)0;
X	if( (status == SS_TALKING) ||
X		(status == SS_LOCKED_DEVICE ) ||
X		(status == SS_CALL_IN_PROGRESS))
X	{
X		uucico_active = 1;
X		if(fp = fopen(lock_name,"r"))
X		{
X			fscanf(fp,"%d",&locking_pid);
X			fclose(fp);
X		}
X		if(locking_pid)
X		{
X			strcpy(locked_tty,ttyname = lockpid_to_tty(locking_pid));
X			move(y,PID_X);
X			utoda(s32,5,locking_pid);
X			addstr(s32);
X		}
X		standout();
X	}
X
X	move(y,STATUS_X);
X	if(status > SS_MSG_MAX)
X	{
X		stattxt = s32;
X		strcpy(stattxt,"status ");
X		utoda_lz(stattxt + 7,3,status);
X	}
X	else
X		stattxt = errortext[status];
X	addstr(stattxt);
X	if(ttyname)
X	{
X		addstr(" (");
X		addstr(ttyname);
X		addch(')');
X	}
X	standend();
X	itmp = 27 - strlen(stattxt);
X	while(itmp--)
X		addch(' ');
X	return(0);
X}	/* end of display_status */
X
X/*+-------------------------------------------------------------------------
X	display_tty(sionum,tty)
X--------------------------------------------------------------------------*/
Xvoid
Xdisplay_tty(sionum,tty)
Xint sionum;
Xregister struct tty *tty;
X{
Xregister int x;
Xregister int y;
Xregister unsigned int itmp;
Xchar s8[8];
X
X	getyx(stdscr,y,x);
X	move(y,TX + x);
X	addch((sionum < 8) ? '1' : '2');
X	addch((sionum % 8) + 'a');
X
X	if((itmp = (unsigned)tty->t_rawq.c_cc) > 999)
X		itmp = 999;
X	utoda(s8,3,itmp);
X	move(y,RX + x);
X	if(itmp > 10)
X		standout();
X	addstr(s8);
X	if(itmp > 10)
X		standend();
X
X	if((itmp = (unsigned)tty->t_canq.c_cc) > 999)
X		itmp = 999;
X	utoda(s8,3,itmp);
X	move(y,CX + x);
X	addstr(s8);
X
X	if((itmp = (unsigned)tty->t_outq.c_cc + tty->t_tbuf.c_count) > 99999)
X		itmp = 99999;
X	utoda(s8,5,itmp);
X	move(y,OX + x);
X	addstr(s8);
X
X	move(y,SX + x);
X	addstr(B_to_baud_rate(tty->t_cflag & CBAUD));
X
X	strcpy(s8,"     ");
X	if(tty->t_state & WOPEN)
X		s8[0] = 'W';
X	else if(tty->t_state & ISOPEN)
X		s8[0] = 'O';
X	if(tty->t_state & CARR_ON)
X		s8[1] = 'C';
X	if(tty->t_state & BUSY)
X		s8[2] = 'B';
X	if(tty->t_state & TTSTOP)
X		s8[3] = 'S';
X	if(tty->t_state & TIMEOUT)
X		s8[3] = 'D';
X	move(y,FX + x);
X	addstr(s8);
X
X	utooa(s8,7,tty->t_iflag);
X	addstr(s8);
X
X	utooa(s8,7,tty->t_oflag);
X	addstr(s8);
X
X	utooa(s8,7,tty->t_cflag);
X	addstr(s8);
X
X	utooa(s8,7,tty->t_lflag);
X	addstr(s8);
X
X	utoda(s8,6,tty->t_pgrp);
X	addstr(s8);
X
X}	/* end of display_tty */
X
X/*+-------------------------------------------------------------------------
X	detail()
X--------------------------------------------------------------------------*/
Xvoid
Xdetail()
X{
Xint y,x;
Xint sysdetail;
Xint ttnum;
Xchar *sysname;
Xchar *cptr;
X
Xstatic char *header  = 
X	"tty  raw  can   out   speed  state iflag  oflag  cflag  lflag  pgrp";
Xstatic char *hyphens =
X	"---  ---  ---  -----  -----  ----- ------ ------ ------ ------ -----";
X
X
X	cmd_line("display detail on system #: __");
X	getyx(stdscr,y,x);
X	move(y,x - 2);
X	refresh();
X	resetty();
X	x = scanw("%d",&sysdetail);
X	raw();
X	noecho();
X	sysdetail--;
X	if(!x || (sysdetail > systems))
X	{
X		fputc(7,stderr);
X		cmd_line((char *)0);
X		refresh();
X		return;
X	}
X
X	cmd_line("press any key to return to main display  ");
X	sysname = sysnames + (sysdetail << 4);
X	y = FIRSTSYS_Y;
X	move(y,0);
X	clrtobot();
X
X	move(y+4,0);
X	addstr(header);
X	move(y+5,0);
X	addstr(hyphens);
X	move(y+8,0);
X	addstr(
X"State: W waiting for open to complete  O open  C carrier on");
X	move(y+9,0);
X	addstr(
X"       S stopped by XOFF  D delay timeout in progress ");
X
X
X	while(1)
X	{
X		display_tod();	/* display time and get 'secs_now' */
X		if(display_status(sysdetail + 1,sysname,FIRSTSYS_Y,(char *)0))
X		{
X			move(y,0);
X			standout();
X			printw("cannot get status for %s",sysname);
X			standend();
X			clrtobot();
X			goto DETAIL_SLEEP;
X		}
X
X							/* 00000 */
X							/* 01234 */
X							/* ttyxx */
X		move(y+6,0);
X		if(locked_tty[0] && ((locked_tty[3] == '1') || (locked_tty[3] == '2')))
X		{
X			ttnum = ((locked_tty[3] - '1') * 8) + ((locked_tty[4] & 7) - 1);
X			if(cptr = kmem_read_tty(ttnum,1))
X			{
X				standout();
X				addstr(cptr);
X				addstr(": ");
X				addstr(locked_tty);
X				cmd_line("press any key to return to main display  ");
X				standend();
X				refresh();
X				getch();
X				goto DETAIL_EXIT;
X			}
X			clrtoeol();
X			display_tty(ttnum,&sio[0]);
X			wintty_template(stdscr,y+11,0,1);
X			wintty(stdscr,y+11,0,&sio[0]);
X			move(y+11,0);
X		}
X		else
X		{
X			printw(" no tty or non-async connection");
X			clrtoeol();
X			wintty_template(stdscr,y+11,0,0);
X		}
X
XDETAIL_SLEEP:
X		refresh();
X		sleep(1);
X		if(rdchk(0))
X		{
X			getch();
X			break;
X		}
X	}
X
XDETAIL_EXIT:
X	move(y = FIRSTSYS_Y,0);
X	clrtobot();
X	cmd_line((char *)0);
X	refresh();
X
X}	/* end of detail */
X
X/*+-------------------------------------------------------------------------
X	main(argc,argv)
X--------------------------------------------------------------------------*/
Xmain(argc,argv)
Xint argc;
Xchar **argv;
X{
Xint display_delta_y;
Xchar s32[32];
Xchar linebuf[512];
Xchar *sysname;
Xchar *cptr;
Xchar cmd;
XFILE *fp;
Xstruct dent *dp;
X#if defined(M_UNIX)
Xstruct timeval timeout;
Xint fdmask;
X#else
Xlong nap();
Xlong timeout;
X#endif
X
X	if((argc > 1) && !strcmp(argv[1],"-n"))
X		no_tod = 1;
X
X	setbuf(stdout,_sobuf);
X
X	if(!initscr())
X	{
X		fprintf(stderr,"curses init failed... check terminal type\n");
X		exit(0);
X	}
X	savetty();
X	noecho();
X	raw();
X
X	signal(SIGTERM,bye);
X	signal(SIGINT,bye);
X	signal(SIGHUP,bye);
X
X	uname(&me);
X	cmd_line((char *)0);
X
X	move(0,0);
X	standout();
X	printw(" uusnap %s (%s V.%s/%s)",
X	    revision,
X#if defined(M_UNIX)
X	    "UNIX",
X#else
X	    "XENIX",
X#endif
X	    me.release,me.machine);
X	if(fp = fopen("/etc/systemid","r"))
X	{
X		s32[0] = 0;
X		fgets(s32,sizeof(s32),fp);
X		if(s32[0])
X		{
X			s32[strlen(s32) - 1] = 0;
X			printw(" %s ",s32);
X		}
X		fclose(fp);
X	}
X	standend();
X
X	move(2,0);
X	standout();
X	addstr(" initializing ");
X	refresh();
X	if(cptr = kmem_init_tty())
X	{
X		move(2,0);
X		addstr(cptr);
X		bye(255);
X	}
X	standend();
X
X	move(2,0);
X	addstr(" # SYSTEM     RCNT QCNT LAST  NEXT   PID  STATUS");
X	move(3,0);
X	addstr("-- ------     ---- ---- ----  ----   ---  ------");
X	while(1)
X	{
X		uucico_active = 0;		/* assume no uucico_active connections */
X		display_tod();	/* display time and get 'secs_now' */
X
X		if(!(stat_dp = dir_open(statdirname("."))))
X		{
X			move(6,0);
X			printw("%s: %s",STATUSDIR,sys_errlist[errno]);
X			move(7,0);
X			addstr("I don't think HoneyDanBer UUCP is installed.");
X			bye(255);
X		}
X		display_delta_y = systems = 0;
X		move(LINES - 4,0);
X		move(FIRSTSYS_Y,0);
X		while(dp = dir_read(stat_dp))
X		{
X			if(display_delta_y > MAX_SYSTEMS)
X				break;
X			if(*dp->d_name == '.')
X				continue;
X			if(get_status_info(dp->d_name,linebuf,sizeof(linebuf)))
X				continue;
X
X			sysname = sysnames + (systems++ << 4);
X			strcpy(sysname,dp->d_name);
X
X			display_status(systems,sysname,display_delta_y + FIRSTSYS_Y,linebuf);
X			display_delta_y++;
X		}
X		display_delta_y++;
X		move(display_delta_y + FIRSTSYS_Y,0);
X		addstr("UUCP connections active: ");
X		utoda(s32,2,systems);
X		addstr(s32);
X		display_delta_y++;
X		while(display_delta_y < MAX_SYSTEMS)
X		{
X			move(display_delta_y++ + FIRSTSYS_Y,0);
X			clrtoeol();
X		}
X
X		dir_close(stat_dp);
X		move(LINES - 4,0);
X		refresh();
X
X#if defined(M_UNIX)
X		timeout.tv_sec = (uucico_active) ? WAITSECS_ACTIVE : WAITSECS_IDLE;
X		timeout.tv_usec = 0;
X		fdmask = 1 << 0;
X		select(32,&fdmask,(int *)0,(int *)0,&timeout);
X#else
X		timeout = ((uucico_active) ? WAITSECS_ACTIVE : WAITSECS_IDLE) * 1000L;
X		while(timeout > 0)
X		{
X			timeout -= nap(200L);
X			if(rdchk(0))
X				break;
X		}
X#endif
X
X		if(rdchk(0))
X		{
X			read(0,&cmd,1);
X			cmd &= 0x7f;
X			switch(cmd &= 0x7f)
X			{
X				case 'q':
X					bye(0);
X				case 'd':
X					detail();
X					break;
X			}
X		}
X	}
X}	/* end of main */
X
X/* vi: set tabstop=4 shiftwidth=4: */
X/* end of uusnap.c */
SHAR_EOF
chmod 0644 uusnap.c || echo "restore of uusnap.c fails"
if [ $TOUCH = can ]
then
    touch -m 1204182889 uusnap.c
fi
exit 0