[comp.sys.att] monitor data line - UNIX PC

pjc@pbhyf.UUCP (Paul Condie) (11/05/87)

/*
	AT&T UNIX PC - monitor data line,  if you please.
	If you are one of those who everytime the obm (on board modem) clicks
	you scramble to logon or get out of vi to see who is trying to log in 
	or if it is your uucp job finally coming across, then this might help.

	To compile just "make phdaemon".
	To run it must be started from the command line.
	If someone can get this to work with nohup(1) so that rc can start it
	at boot time, please send me the patch.
*/
--------------- as Rocky Balboa said  - CUT ME  -------------------------------
#ifndef LINT
static char Sccsid[] = "%W%   DeltaDate %G%   ExtrDate %H%";
#endif

/*
**  PROGRAM:	phdaemon 
**		Monitor data line (ph1).
**
**		Displays who is using ph1 next to "DATA 2:" in the status line. 
**		"DATA 2: > name"  - outbound call
**		"DATA 2: < name"  - inbound call
**		If "name" is in reverse_video then uucp/mail is in progress and
**		the machine you are talking to is displayed where "name" is.
**		If "name" is bold and it is a inbound call then the login name
**		of the person calling is displayed, otherwise "ph1" is displayed
**		for the outbound call.  I leave it up to you to guess who.
**
**		You have to start it up from a $ prompt.  Does not work
**		if you try to nohup it.  Therefore rc won't start it at
**		boot time.
**
**  AUTHOR:	Paul J. Condie   10/87
**		{ihnp4!lll-crg,qantel,pyramid}!ptsfa!pbody!pcbox!pjc
**
**  CONFIGURATION:
**		Voice line on line 1  (ph0).
**		Data line on line 2  (ph1).
**		You should be able to change PHLINE to monitor a different 
**		data line but this has not been tested.
*/

#include	<stdio.h>
#include	<fcntl.h>
#include	<sys/signal.h>
#include	<sys/types.h>
#include	<sys/stat.h>
#include	<sys/window.h>
#include	<utmp.h>

#define	TIMER	15				/* secs between checks */
#define	PHLINE	"ph1"				/* ph line to monitor */


#define	ROW	0				/* status window dimensions */
#define	COL	216				/* in pixels */
#define	HEIGHT	12
#define	WIDTH	80

#define	BELL	7
#define	ESC	27
#define	BOLD	"[1m"
#define	DIM	"[2m"
#define	REVERSE	"[7m"
#define	NORMAL	"[0m"
#define	CLEAR	"[2J"

#define	DIALIN		1
#define	DIALOUT		2
#define	UUCPIN		3
#define	UUCPOUT		4
#define	INBOUND		5
#define	OUTBOUND	6

#define	LOCKFILE	"/usr/spool/uucp/LCK.."

int		fd;				/* phdaemon status window */

main ()
{
	extern unsigned alarm();
	extern 		wakeup();
	int		bye();
	struct stat	Statbuf;
	struct uwdata 	uwdata;
	struct utdata	utdata;
	struct utmp	*getutid();
	struct utmp	*utmp;
	struct utmp	uph1;
	FILE		*popen(), *pp;
	char		machine[10];		/* machine name */
	char		ws[80];
	int		WhichWay;
	int		mode;


	strcpy (uph1.ut_id, PHLINE);			/* init for getuid */
	uph1.ut_type = LOGIN_PROCESS;

	fd = open ("/dev/window", O_RDWR);		/* status window */
	ioctl (fd, WIOCGETD, &uwdata);

	if (fork() != 0)
	{
						/* PARENT */
		sleep (2);
		if (!isatty(0))
		{
			/* nohup fix goes here */
		}
		else
			/* executed from command line */
			ioctl (0, WIOCSELECT);
		exit (0);
	}
						/* CHILD */

	signal (SIGHUP, SIG_IGN);	
 	signal (SIGINT, SIG_IGN);
	signal (SIGQUIT, bye);

	setpgrp ();				/* kick child out of house */
	chdir ("/");
	umask (0);
	close (0);
	dup (fd);
	close (1);
	dup (fd);
	close (2);
	dup (fd);
	close (fd);
	ioctl (0, WIOCPGRP);			/* set controlling group */

	uwdata.uw_x = COL;			/* set window dimensions */
	uwdata.uw_y = ROW;
	uwdata.uw_width = WIDTH;		
	uwdata.uw_height = HEIGHT;
	uwdata.uw_uflags = NBORDER;
	ioctl (0, WIOCSETD, &uwdata);

	/* To get this process out of the Suspd/Rsume window */
	utdata.ut_num = 3;
	strcpy (utdata.ut_text, "Status Manager");
	ioctl (0, WIOCSETTEXT, &utdata);

	strcpy (machine, "");

	while (1)
	{
		/* Set wakeup call */
		signal (SIGALRM, wakeup);
		alarm (TIMER);
		pause ();
		alarm (0);

		/* Find out whats happening with data line */
		utmpname ("/etc/utmp");			/* rewind file */
		utmp = getutid (&uph1);
		if (utmp == NULL  ||  strcmp (utmp->ut_id, PHLINE) != 0)
		{
			/* Internal Error */
			continue;
		}

		if (strcmp (machine, "") != 0)
		{
			/*
			**  Check if data call is still in progress.
			**  If one data call ends and another starts up
			**  between wakeup calls, this code won't update
			**  the machine/login name.
			*/
			if (utmp->ut_type != LOGIN_PROCESS)
				continue;	/* still in progress */

			/* blank window */
			sprintf (ws, "%c%s", ESC, CLEAR);
			write (0, ws, strlen(ws));
			strcpy (machine, "");
		}


		/*
		**  Check if a new data call has been started.
		*/

		if (utmp->ut_type == LOGIN_PROCESS)
			continue;			/* getty on ph1 */

		if (utmp->ut_type == USER_PROCESS)
		{
			/*
			**  If /usr/spool/uucp/LCK.. file exists
			**     then  inbound uucp/mail in progress
			**           machine name = LCK..machine_name
			**     else  someone has logged in
			**           user is in ut_user
			*/
			WhichWay = INBOUND;
			sleep (3);	/* give uucp time to create LOCKFILE */
		    	sprintf (ws, "ls %s%s", LOCKFILE, "*");
			pp = popen (ws, "r");
			while (fscanf (pp, "%s", ws) != EOF)
			{
				/*
				**  I ignore ph0 - voice and 
				**        tty000 - external modem
				*/
				if (strcmp (PHLINE, "ph1") == 0)
				{
					if (strcmp (ws+21, "ph0") == 0)   
						continue;
				}
				else
					if (strcmp (ws+21, "ph1") == 0)   
						continue;
				if (strcmp (ws+21, "tty000") == 0)   continue;
				strcpy (machine, ws+21);
			}
			pclose (pp);
			if (strcmp (machine, "") == 0)
			{
				mode = DIALIN;
				strcpy (machine, utmp->ut_user);
			}
			else
				mode = UUCPIN;
		}

		if (utmp->ut_type == DEAD_PROCESS)
		{
			/*
			**  if only /usr/spool/uucp/LCK..ph1 exists
			**     then  a dial-out call is in progress
			**     else  there sb 2 LCK.. files
			**           (LCK..ph1 and LCK..machine_name)
			**	     outbound uucp/mail in progress
			*/
			WhichWay = OUTBOUND;
			sleep (2);	/* give uucp time to create LOCKFILE */
			sprintf (ws, "ls %s%s", LOCKFILE, "*");
			pp = popen (ws, "r");
			while (fscanf (pp, "%s", ws) != EOF)
			{
				if (strcmp (ws+21, "ph0") == 0)   continue;
				if (strcmp (ws+21, "tty000") == 0)   continue;
				if (strcmp (ws+21, "ph1") == 0) continue;
				strcpy (machine, ws+21);
			}
			pclose (pp);
			if (strcmp (machine, "") == 0)
			{
				mode = DIALOUT;
				strcpy (machine, PHLINE);
			}
			else
				mode = UUCPOUT;
		}

		/* show it man...show it */
		sprintf (ws, "%c[1;1H", ESC);	      /* home cursor */
		write (0, ws, strlen(ws));
		sprintf (ws, "%c%c%c", BELL, BELL, BELL);
		write (0, ws, strlen (ws));
		sleep (1);
		write (0, ws, strlen (ws));
		write (0, ws, strlen (ws));

		if (WhichWay == INBOUND)
			sprintf (ws, "%c%s%c%s<%c%s", 
				ESC, REVERSE, ESC, BOLD, ESC, NORMAL);
		else
			sprintf (ws, "%c%s%c%s>%c%s", 
				ESC, REVERSE, ESC, BOLD, ESC, NORMAL);
		write (0, ws, strlen(ws));

		if (mode == DIALOUT  ||  mode == DIALIN)
			sprintf (ws, "%c%s %-6s%c%s", 
				    ESC, BOLD, machine, ESC, NORMAL);
		else
			sprintf (ws, "%c%s %-6s%c%s", 
				    ESC, REVERSE, machine, ESC, NORMAL);
		write (0, ws, strlen(ws));
	} /* end while (1) */
	close (fd);
	exit (0);
}

wakeup ()
{
}

bye ()
{
	close (fd);
	exit (0);
}
/* pjc 10/87 */