[comp.sys.att] phone manager replacement

campbell@vx2.GBA.NYU.EDU (bruce dietrich-campbell) (11/15/89)

This is a "poor man's" phone manager replacement.
It DOESN'T have a phone directory or use the async_main emulator.
It DOES allow both lines to be either VOICE or DATA (only one DATA at a time).
It DOES allow voice lines to be put on HOLD.
It DOES allow toggling and holding via the shifted function keys.

Please send bug fixes to:

Bruce Dietrich-Campbell    campbell@vx2.gba.nyu.edu

PS.  I would appreciate it if someone would send me a copy of the
STATUS MANAGER that was posted before.  (Sorry, I don't know who wrote it.
I'm not even sure that it really exists.)

        o /
---------x--------cut here--------------------------------------------------
        o \

#! /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 shell archive."
# Contents:  README Makefile key.h ph.c ph.h phhang.c phhold.c phinit
#   phkill.c phset.c phstat.c phtoggle.c set.c set.h sig.c sig.h
#   stat.c stat.h togl.c togl.h wind.c wind.h
# Wrapped by bruce@blitz on Tue Nov 14 13:32:15 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'README' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'README'\"
else
echo shar: Extracting \"'README'\" \(4547 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
XThis is a replacement for the phone manager supplied with the ATT UnixPC.
X
XIt is a "poor man's" phone manager, however, in that it just does the basics.
XThere is no dialing directory or automatic dialing.  I found that I
Xjust never used that feature of the phone manager.  I also never used the
Xasync_main terminal emulator, so that's also missing.  It's a start.
X
XThis new phone manager allows both line 0 and 1 to be either DATA or VOICE
X(only one may be DATA at any one time).  It also allows lines to be toggled
Xfrom VOICE to DATA and back by using the shifted function keys.  Since both
Xlines may be voice lines, a hold capability has been built in.  Holding
Xlines may also be done using the shifted function keys.
X
XThe key.h file contains the default definitions for the shifted function keys:
X
X#define F1	HOLD0		/* like running "phhold 0" (see below)	*/
X#define F2	HOLD1		/* like running "phhold 1"		*/
X#define F3	HANGUP		/* like running "phhang"		*/
X#define F4	TOGGLE0		/* like running "phtoggle 0"		*/
X#define F5	TOGGLE1		/* like running "phtoggle 1"		*/
X
XTyping the shifted F1 key puts line 0 on hold if it was ACTIVE, or makes
Xit the `selected line' if it was idle (see phhold below).
X
XAlong with the phone manager are the following programs:
X
Xphinit:		Simply starts up the phone manager.  The Makefile installs
X		this as /etc/.phinit, which is run by the /etc/rc file.
X
Xphkill:		Stops the phone manager.  Does so by sending a signal,
X		instead of just killing, so that the phone manager can
X		clean up a bit before quitting.  Installed as /etc/.phclr.
X
Xphtoggle:	A replacement for the original phtoggle.
X
X		Usage: phtoggle [0|1|ph0|ph1|/dev/ph0|/dev/ph1]
X
X		If run without any argument, line 0 is toggled.
X		Unlike the original phone manager, either line can be
X		toggled.  Since there is only one modem, however, only
X		one line can be in DATA mode at a given time.  The new
X		phone manager, therefore, when asked to toggle a line
X		into DATA mode will first check whether the other line is
X		in DATA mode.  If it is, it will then try to toggle it to
X		VOICE. 
X
Xphset:		A replacement for the phset posted to the net.  As with
X		phtoggle, one can set either line to DATA or VOICE.
X
X		Usage: phset [0|1|ph0|ph1|/dev/ph0|/dev/ph1] DATA|VOICE
X
X		If called with only one argument (DATA or VOICE) line 0
X		is assumed.
X
Xphstat:		A replacement for the phstat posted to the net.
X
X		Usage: phstat [0|1|ph0|ph1|/dev/ph0|/dev/ph1]
X
X		Prints one of the character strings "DATA", "VOICE-IDLE"
X		or "VOICE-ACTIVE" on stdout.
X
Xphhold:		Because the new phone manager allows two voice lines,
X		I decided to build in the capability of selecting the
X		line connected to the handset (handy thing to have :-) as
X		well as the capability of holding a line.
X
X		Usage: phhold [0|1|ph0|ph1|/dev/ph0|/dev/ph1]
X
X		Since there is only one handset, the phone manager has to
X		have the concept of `selected line.'  When the phone manager
X		starts up, one sees that both line 0 and 1 are idle.  Line 0, 
X		however, is "IDLE" while line 1 is "idle".  That is, line
X		0 is the selected line.  If "phhold 1" is run, then line 0
X		will become "idle" and line 1 "IDLE".  That is, line 1 is
X		now connected to the handset.
X
X		If line 0 is ACTIVE, ie. the line is in voice mode and the
X		handset lifted, then running "phhold 0" will change the
X		line status from ACTIVE to HOLD.  One can then run "phhold 1"
X		to select line 1.  If line 1 was previously set on hold,
X		then it will be unheld.
X
Xphhang:		After playing around with holding lines using phhold, you
X		will quickly notice that you once you have held a line it's
X		difficult to once again end up with both lines unheld.
X		When selecting a line which was previously held, the phone
X		manager will first hold the current line if it is ACTIVE.
X		Since ACTIVE just means handset lifted, this is usually the
X		case when switching between conversations.  How then does
X		one end up with both lines unheld once again?  Running
X		"phhang" hangs up the currently ACTIVE line and makes the
X		other line the `selected line.'  If the other line was
X		previously held, it is unheld.
X
X		Usage: phhang
X
XPlease excuse the paucity of error conditions handling.
XI'd appreciate it if fixes were sent to:
X
XBruce Dietrich-Campbell  campbell@vx2.gba.nyu.edu
X
XThese programs were influenced by jbm's setgetty posted a while ago to the net.
X(A slightly modified version can be found in file set.c.)  Also, the
Xphstat, newph and phset programs posted to the net by lenny, tanya and
X?? (sorry, lost the sourse to phset) were a great help.
END_OF_FILE
if test 4547 -ne `wc -c <'README'`; then
    echo shar: \"'README'\" unpacked with wrong size!
fi
# end of 'README'
fi
if test -f 'Makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Makefile'\"
else
echo shar: Extracting \"'Makefile'\" \(1620 characters\)
sed "s/^X//" >'Makefile' <<'END_OF_FILE'
XCC = cc
XCFLAGS = -g -DDEBUG
X# CFLAGS = -O
X
X# BIN is the directory where the support programs phtoggle phset phstat
X# should be installed
XBIN = /usr/local/bin
X
XPRGS = ph phstat phtoggle phset phhold phhang phkill
X
Xall:		$(PRGS)
X
Xph:		ph.o stat.o sig.o wind.o togl.o set.o
X		$(CC) -o ph ph.o stat.o sig.o wind.o togl.o set.o
X
Xphstat:		phstat.o stat.o
X		$(CC) -o phstat phstat.o stat.o
X
Xphtoggle:	phtoggle.o stat.o sig.o
X		$(CC) -o phtoggle phtoggle.o stat.o sig.o
X
Xphset:		phset.o stat.o sig.o
X		$(CC) -o phset phset.o stat.o sig.o
X
Xphhold:		phhold.o stat.o sig.o
X		$(CC) -o phhold phhold.o stat.o sig.o
X
Xphhang:		phhang.o stat.o sig.o
X		$(CC) -o phhang phhang.o stat.o sig.o
X
Xphkill:		phkill.o sig.o
X		$(CC) -o phkill phkill.o sig.o
X
Xinstall:	$(PRGS)
X		-mv /etc/ph /etc/ph-orig
X		-mv /etc/.phinit /etc/.phinit-orig
X		-mv /etc/.phclr /etc/.phclr-orig
X		-mv $(BIN)/phstat $(BIN)/phstat-orig
X		-mv $(BIN)/phtoggle $(BIN)/phtoggle-orig
X		-mv $(BIN)/phset $(BIN)/phset-orig
X		-mv $(BIN)/phhold $(BIN)/phhold-orig
X		-mv $(BIN)/phhang $(BIN)/phhang-orig
X		ln ph /etc
X		ln phinit /etc/.phinit
X		ln phkill /etc/.phclr
X		ln phstat $(BIN)
X		ln phtoggle $(BIN)
X		ln phset $(BIN)
X		ln phhold $(BIN)
X		ln phhang $(BIN)
X		chown root $(PRGS)
X		chgrp root $(PRGS)
X		chmod 4711 $(PRGS)
X
Xclean:		
X		rm -f *.o $(PRGS)
X
Xph.o:		ph.h stat.h sig.h wind.h togl.h
Xphstat.o:	ph.h stat.h
Xphtoggle.o:	ph.h stat.h sig.h
Xphset.o:	ph.h stat.h sig.h
Xphhold.o:	ph.h stat.h sig.h
Xphhang.o:	ph.h stat.h sig.h
Xphkill.o:	ph.h sig.h
Xstat.o:		ph.h stat.h wind.h
Xsig.o:		ph.h sig.h
Xwind.o:		ph.h wind.h key.h
Xtogl.o:		ph.h stat.h set.h togl.h
Xset.o:		ph.h set.h
END_OF_FILE
if test 1620 -ne `wc -c <'Makefile'`; then
    echo shar: \"'Makefile'\" unpacked with wrong size!
fi
# end of 'Makefile'
fi
if test -f 'key.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'key.h'\"
else
echo shar: Extracting \"'key.h'\" \(256 characters\)
sed "s/^X//" >'key.h' <<'END_OF_FILE'
X/*
X$Header: /usr/spool/in/new-ph/RCS/key.h,v 1.1 89/11/14 13:20:45 bruce Exp $
X$Log:	key.h,v $
X * Revision 1.1  89/11/14  13:20:45  bruce
X * Initial revision
X * 
X*/
X
X#define F1	HOLD0
X#define F2	HOLD1
X#define F3	HANGUP
X#define F4	TOGGLE0
X#define F5	TOGGLE1
END_OF_FILE
if test 256 -ne `wc -c <'key.h'`; then
    echo shar: \"'key.h'\" unpacked with wrong size!
fi
# end of 'key.h'
fi
if test -f 'ph.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'ph.c'\"
else
echo shar: Extracting \"'ph.c'\" \(1886 characters\)
sed "s/^X//" >'ph.c' <<'END_OF_FILE'
X/*
X$Header: /usr/spool/in/new-ph/RCS/ph.c,v 1.1 89/11/14 13:20:58 bruce Exp $
X$Log:	ph.c,v $
X * Revision 1.1  89/11/14  13:20:58  bruce
X * Initial revision
X * 
X*/
X
Xstatic char *rcsid = "$Header: /usr/spool/in/new-ph/RCS/ph.c,v 1.1 89/11/14 13:20:58 bruce Exp $";
X
X#include "ph.h"
X#include "stat.h"
X#include "sig.h"
X#include "wind.h"
X#include "togl.h"
X
Xstatic char *desc[2];
X#define display_status	(desc[0] = status_description(0), \
X			desc[1] = status_description(1), \
X			(((desc[0] == (char *) NULL) || \
X			(desc[1] == (char *) NULL)) ? FALSE : \
X			display_window(desc[0], desc[1])))
X
X#define START_LOOP	loop = TRUE
X#define LOOPY		loop
X#define END_LOOP	loop = FALSE
X
Xint main(argc, argv)
Xint	argc;
Xchar	**argv;
X{
X	char		*prog_name;
X	int		op;
X	int		loop;
X	jmp_buf		back;
X	int		i;
X
X	name(prog_name);
X
X	if (!open_window) {quit("couldn't make new window");}
X
X	switch(fork()) {
X	case -1:	quit("couldn't fork");
X	case 0:		break;
X	default:	exit(OK);
X	}
X
X	close_files;
X
X	ignore_signals;
X	if (!make_pid_file) {quit("couldn't create pid file");}
X	if (!get_away) {quit("couldn't create process group");}
X	if (!open_status) {quit("couldn't open status");}
X	if (!initialize_line(1) || !initialize_line(0))
X		{quit("couldn't initialize lines");}
X	if (!display_status) {quit("couldn't display status");}
X
X	after_sig_jump(back); /* catch signals and jump ... */
X
X	for (START_LOOP; LOOPY;) {
X
X		if ((op = setjmp(back)) == 0) { /* ... back to here */
X			allow_signals;
X			op = wait_until_read_window;
X		}
X
X		ignore_signals;
X
X		switch (op) {
X		case TOGGLE0:	toggle_line(0); break;
X		case TOGGLE1:	toggle_line(1); break;
X		case HOLD0:	hold_line(0); break;
X		case HOLD1:	hold_line(1); break;
X		case HANGUP:	hangup_line; break;
X		case QUIT:	END_LOOP; break;
X		case SIGPHONE:	break;
X		}
X
X		display_status;
X	}
X
X	quit_line(0);
X	quit_line(1);
X	unlink_pid_file;
X	close_status;
X	close_window;
X
X	return(OK);
X}
END_OF_FILE
if test 1886 -ne `wc -c <'ph.c'`; then
    echo shar: \"'ph.c'\" unpacked with wrong size!
fi
# end of 'ph.c'
fi
if test -f 'ph.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'ph.h'\"
else
echo shar: Extracting \"'ph.h'\" \(1419 characters\)
sed "s/^X//" >'ph.h' <<'END_OF_FILE'
X/*
X$Header: /usr/spool/in/new-ph/RCS/ph.h,v 1.1 89/11/14 13:21:00 bruce Exp $
X$Log:	ph.h,v $
X * Revision 1.1  89/11/14  13:21:00  bruce
X * Initial revision
X * 
X*/
X
X#include <stdio.h>
X#include <string.h>
X#include <fcntl.h>
X
X#define OK		0
X#define ERROR		1
X
X#define FALSE		0
X#define TRUE		1
Xtypedef int boolean;
X
X#define msgstart	fprintf(stderr, "%s: ", prog_name); fprintf(stderr,
X#define msgend		); fprintf(stderr,"\n"); fflush(stderr)
X
X#ifdef DEBUG
X#define msg(s)		msgstart s msgend
X#define msg1(s,a)	msgstart s,a msgend
X#define msg2(s,a,b)	msgstart s,a,b msgend
X#define msg3(s,a,b,c)	msgstart s,a,b,c msgend
X#else
X#define msg(s)
X#define msg1(s,a)
X#define msg2(s,a,b)
X#define msg3(s,a,b,c)
X#endif
X
X#define quit(s)		msgstart s msgend; exit(ERROR)
X#define quit1(s,a)	msgstart s,a msgend; exit(ERROR)
X#define quit2(s,a,b)	msgstart s,a,b msgend; exit(ERROR)
X#define quit3(s,a,b,c)	msgstart s,a,b,c msgend; exit(ERROR)
X
X#define name(s)		if ((s = strrchr(argv[0],'/')) == (char *) NULL) \
X				{s = argv[0];} else {s++;}
X
X#define is(s1,s2)	(strcmp(s1,s2) == 0)
X#define ph(s)		is(argv[1],s)
X#define phone0		(ph("0") || ph("ph0") || ph("/dev/ph0"))
X#define phone1		(ph("1") || ph("ph1") || ph("/dev/ph1"))
X
X#define WAIT		5  /* max seconds to wait for something */
Xstatic int wait_var;
X#define wait_until(x)	for(wait_var=0; !(x) && wait_var<WAIT; wait_var++) \
X			{sleep(1);}
X#define too_long	((wait_var == WAIT) ? TRUE : FALSE)
END_OF_FILE
if test 1419 -ne `wc -c <'ph.h'`; then
    echo shar: \"'ph.h'\" unpacked with wrong size!
fi
# end of 'ph.h'
fi
if test -f 'phhang.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'phhang.c'\"
else
echo shar: Extracting \"'phhang.c'\" \(609 characters\)
sed "s/^X//" >'phhang.c' <<'END_OF_FILE'
X/*
X$Header: /usr/spool/in/new-ph/RCS/phhang.c,v 1.1 89/11/14 13:21:02 bruce Exp $
X$Log:	phhang.c,v $
X * Revision 1.1  89/11/14  13:21:02  bruce
X * Initial revision
X * 
X*/
X
Xstatic char *rcsid = "$Header: /usr/spool/in/new-ph/RCS/phhang.c,v 1.1 89/11/14 13:21:02 bruce Exp $";
X
X#include "ph.h"
X#include "sig.h"
X
X#define usage	fprintf(stderr, "Usage: %s\n", prog_name); \
X		exit(ERROR)
X
Xmain(argc, argv)
Xint	argc;
Xchar	**argv;
X{
X	char	*prog_name;
X
X	name(prog_name);
X
X	switch (argc) {
X	case 1:		if (!sig_hangup)
X			  {quit("couldn't signal phone mgr (not running?)");}
X			break;
X	default:	usage;
X	}
X
X	exit(OK);
X}
END_OF_FILE
if test 609 -ne `wc -c <'phhang.c'`; then
    echo shar: \"'phhang.c'\" unpacked with wrong size!
fi
# end of 'phhang.c'
fi
if test -f 'phhold.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'phhold.c'\"
else
echo shar: Extracting \"'phhold.c'\" \(1111 characters\)
sed "s/^X//" >'phhold.c' <<'END_OF_FILE'
X/*
X$Header: /usr/spool/in/new-ph/RCS/phhold.c,v 1.1 89/11/14 13:21:04 bruce Exp $
X$Log:	phhold.c,v $
X * Revision 1.1  89/11/14  13:21:04  bruce
X * Initial revision
X * 
X*/
X
Xstatic char *rcsid = "$Header: /usr/spool/in/new-ph/RCS/phhold.c,v 1.1 89/11/14 13:21:04 bruce Exp $";
X
X#include "ph.h"
X#include "stat.h"
X#include "sig.h"
X
X#define hold_needed	(!(desired & get_status(phone)))
X
X#define usage		fprintf(stderr,"Usage: %s [device]\n",prog_name); \
X			exit(ERROR)
X
Xmain(argc, argv)
Xint	argc;
Xchar	**argv;
X{
X	char	*prog_name;
X	int	phone;
X	int	desired;
X	int	sig;
X
X	name(prog_name);
X
X	switch (argc) {
X	case 1:		phone = 0; sig = HOLD0; /* ph0 is the default */
X			break;
X	case 2:		if (phone0) {phone = 0; sig = HOLD0;}
X			else if (phone1) {phone = 1; sig = HOLD1;}
X			else {usage;}
X			break;
X	default:	usage;
X			break;
X	}
X
X	if (!open_status) {quit("couldn't open status");}
X	desired = ((is_hold(phone)) ? ~GT_VOICE_HOLD : GT_VOICE_HOLD);
X	if (!sig_hold(phone)) {quit("couldn't signal phone manager");}
X	wait_until(!hold_needed);
X	if (too_long) {quit("waited but no change in status");}
X
X	close_status;
X	exit(OK);
X}
END_OF_FILE
if test 1111 -ne `wc -c <'phhold.c'`; then
    echo shar: \"'phhold.c'\" unpacked with wrong size!
fi
# end of 'phhold.c'
fi
if test -f 'phinit' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'phinit'\"
else
echo shar: Extracting \"'phinit'\" \(8 characters\)
sed "s/^X//" >'phinit' <<'END_OF_FILE'
X/etc/ph
END_OF_FILE
if test 8 -ne `wc -c <'phinit'`; then
    echo shar: \"'phinit'\" unpacked with wrong size!
fi
chmod +x 'phinit'
# end of 'phinit'
fi
if test -f 'phkill.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'phkill.c'\"
else
echo shar: Extracting \"'phkill.c'\" \(729 characters\)
sed "s/^X//" >'phkill.c' <<'END_OF_FILE'
X/*
X$Header: /usr/spool/in/new-ph/RCS/phkill.c,v 1.1 89/11/14 13:21:06 bruce Exp $
X$Log:	phkill.c,v $
X * Revision 1.1  89/11/14  13:21:06  bruce
X * Initial revision
X * 
X*/
X
Xstatic char *rcsid = "$Header: /usr/spool/in/new-ph/RCS/phkill.c,v 1.1 89/11/14 13:21:06 bruce Exp $";
X
X#include "ph.h"
X#include "sig.h"
X
X#define usage	fprintf(stderr, "Usage: %s [sig]\n", prog_name); \
X		exit(ERROR)
X
Xmain(argc, argv)
Xint	argc;
Xchar	**argv;
X{
X	char	*prog_name;
X
X	name(prog_name);
X
X	switch (argc) {
X	case 1:		if (!kill_phone_mgr)
X			  {quit("couldn't kill phone mgr (not running?)");}
X			break;
X	case 2:		if (!sig_phone_mgr(atoi(argv[1])))
X			  {quit("couldn't signal phone mgr (not running?)");}
X			break;
X	default:	usage;
X	}
X
X	exit(OK);
X}
END_OF_FILE
if test 729 -ne `wc -c <'phkill.c'`; then
    echo shar: \"'phkill.c'\" unpacked with wrong size!
fi
# end of 'phkill.c'
fi
if test -f 'phset.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'phset.c'\"
else
echo shar: Extracting \"'phset.c'\" \(1337 characters\)
sed "s/^X//" >'phset.c' <<'END_OF_FILE'
X/*
X$Header: /usr/spool/in/new-ph/RCS/phset.c,v 1.1 89/11/14 13:21:07 bruce Exp $
X$Log:	phset.c,v $
X * Revision 1.1  89/11/14  13:21:07  bruce
X * Initial revision
X * 
X*/
X
Xstatic char *rcsid = "$Header: /usr/spool/in/new-ph/RCS/phset.c,v 1.1 89/11/14 13:21:07 bruce Exp $";
X
X#include "ph.h"
X#include "stat.h"
X#include "sig.h"
X
X#define isarg(n,s)		is(argv[n],s)
X#define toggle_needed(l)	(!(desired & get_status(l)))
X
X#define usage		fprintf(stderr,"Usage: %s [device] DATA | VOICE\n", \
X			prog_name); exit(ERROR)
X
Xmain(argc, argv)
Xint	argc;
Xchar	**argv;
X{
X	char	*prog_name;
X	int	phone;
X	int	desired;
X
X	name(prog_name);
X
X	switch (argc) {
X	case 1:		usage;
X			break;
X	case 2:		phone = 0; /* ph0 is the default */	
X			if (isarg(1,"DATA")) {desired = GT_DATA;}
X			else if (isarg(1,"VOICE")) {desired = GT_VOICE;}
X			else {usage;}
X			break;
X	case 3:		if (phone0) {phone = 0;}
X			else if (phone1) {phone = 1;}
X			else {usage;}
X			if (isarg(2,"DATA")) {desired = GT_DATA;}
X			else if (isarg(2,"VOICE")) {desired = GT_VOICE;}
X			else {usage;}
X			break;
X	default:	usage;
X			break;
X	}
X
X	if (!open_status) {quit("couldn't open status");}
X	if (toggle_needed(phone) && !sig_toggle(phone))
X		{quit("couldn't signal phone manager");}
X	wait_until(!toggle_needed(phone));
X	if (too_long) {quit("waited but no status change");}
X
X	close_status;
X	return (OK);
X}
END_OF_FILE
if test 1337 -ne `wc -c <'phset.c'`; then
    echo shar: \"'phset.c'\" unpacked with wrong size!
fi
# end of 'phset.c'
fi
if test -f 'phstat.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'phstat.c'\"
else
echo shar: Extracting \"'phstat.c'\" \(1110 characters\)
sed "s/^X//" >'phstat.c' <<'END_OF_FILE'
X/*
X$Header: /usr/spool/in/new-ph/RCS/phstat.c,v 1.1 89/11/14 13:21:09 bruce Exp $
X$Log:	phstat.c,v $
X * Revision 1.1  89/11/14  13:21:09  bruce
X * Initial revision
X * 
X*/
X
Xstatic char *rcsid = "$Header: /usr/spool/in/new-ph/RCS/phstat.c,v 1.1 89/11/14 13:21:09 bruce Exp $";
X
X#include "ph.h"
X#include "stat.h"
X
X#define usage		fprintf(stderr,"Usage: %s [device]\n",prog_name); \
X			exit(ERROR)
X
Xmain(argc, argv)
Xint	argc;
Xchar	**argv;
X{
X	char	*prog_name;
X	int	phone;
X
X	name(prog_name);
X
X	switch (argc) {
X	case 1:		phone = 0; /* ph0 is the default */
X			break;
X	case 2:		if (phone0) {phone = 0;}
X			else if (phone1) {phone = 1;}
X			else {usage;}
X			break;
X	default:	usage;
X			break;
X	}
X
X	if (!open_status) {quit("couldn't open status");}
X
X	switch (get_status(phone)) {
X	case GT_DATA:		printf("DATA\n");
X				break;
X	case GT_VOICE_SELECT:
X	case GT_VOICE_IDLE:	printf("VOICE-IDLE\n");
X				break;
X	case GT_VOICE_HOLD:
X	case GT_VOICE_ACTIVE:	printf("VOICE-ACTIVE\n");
X				break;
X	case GT_ERROR:		quit("couldn't get status");
X				break;
X	default:		quit("this can't happen");
X				break;
X	}
X
X	close_status;
X	exit(OK);
X}
END_OF_FILE
if test 1110 -ne `wc -c <'phstat.c'`; then
    echo shar: \"'phstat.c'\" unpacked with wrong size!
fi
# end of 'phstat.c'
fi
if test -f 'phtoggle.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'phtoggle.c'\"
else
echo shar: Extracting \"'phtoggle.c'\" \(1118 characters\)
sed "s/^X//" >'phtoggle.c' <<'END_OF_FILE'
X/*
X$Header: /usr/spool/in/new-ph/RCS/phtoggle.c,v 1.1 89/11/14 13:21:11 bruce Exp $
X$Log:	phtoggle.c,v $
X * Revision 1.1  89/11/14  13:21:11  bruce
X * Initial revision
X * 
X*/
X
Xstatic char *rcsid = "$Header: /usr/spool/in/new-ph/RCS/phtoggle.c,v 1.1 89/11/14 13:21:11 bruce Exp $";
X
X#include "ph.h"
X#include "stat.h"
X#include "sig.h"
X
X#define toggle_needed	(!(desired & get_status(phone)))
X
X#define usage		fprintf(stderr,"Usage: %s [device]\n",prog_name); \
X			exit(ERROR)
X
Xmain(argc, argv)
Xint	argc;
Xchar	**argv;
X{
X	char	*prog_name;
X	int	phone;
X	int	desired;
X	int	sig;
X
X	name(prog_name);
X
X	switch (argc) {
X	case 1:		phone = 0; sig = TOGGLE0; /* ph0 is the default */
X			break;
X	case 2:		if (phone0) {phone = 0; sig = TOGGLE0;}
X			else if (phone1) {phone = 1; sig = TOGGLE1;}
X			else {usage;}
X			break;
X	default:	usage;
X			break;
X	}
X
X	if (!open_status) {quit("couldn't open status");}
X	desired = ((is_voice(phone)) ? GT_DATA : GT_VOICE);
X	if (!sig_toggle(phone)) {quit("couldn't signal phone manager");}
X	wait_until(!toggle_needed);
X	if (too_long) {quit("waited but no change in status");}
X
X	close_status;
X	exit(OK);
X}
END_OF_FILE
if test 1118 -ne `wc -c <'phtoggle.c'`; then
    echo shar: \"'phtoggle.c'\" unpacked with wrong size!
fi
# end of 'phtoggle.c'
fi
if test -f 'set.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'set.c'\"
else
echo shar: Extracting \"'set.c'\" \(1670 characters\)
sed "s/^X//" >'set.c' <<'END_OF_FILE'
X/*
X$Header: /usr/spool/in/new-ph/RCS/set.c,v 1.1 89/11/14 13:21:13 bruce Exp $
X$Log:	set.c,v $
X * Revision 1.1  89/11/14  13:21:13  bruce
X * Initial revision
X * 
X*/
X
Xstatic char *rcsid = "$Header: /usr/spool/in/new-ph/RCS/set.c,v 1.1 89/11/14 13:21:13 bruce Exp $";
X
X#include "ph.h"
X#include "set.h"
X
Xstatic int fd;
X#define INITTAB		"/etc/inittab"
X#define open_inittab	((fd = open(INITTAB, O_RDWR)) != -1)
X
X#define BUFSIZE 4096
Xstatic char buf[BUFSIZE];
Xstatic int bytes_read;
X#define read_inittab	(((bytes_read = read(fd, buf, BUFSIZE)) != -1) && \
X			(bytes_read != BUFSIZE))
Xlong lseek();
X#define write_inittab	((lseek(fd, 0, 0) != -1) && \
X			(write(fd, buf, bytes_read) != -1))
X#define close_inittab	(close(fd) != -1)
X#define telinit		(kill(1,1) != -1)
X
X#define first_cmp	buf
X#define last_read	(buf + bytes_read - 1)
X#define last_cmp	(last_read - len_dev - 1)
X
X#define found_it	((*s == ' ' || *s == ':') && \
X			(strncmp(s+1, dev, len_dev) == 0) && \
X			(*(s+len_dev+1) == ':'))
X#define needs_change	((on_off == ON && *s == ':') || \
X			(on_off == OFF && *s == ' '))
X#define change_it	*s = ((on_off == ON) ? ' ' : ':')
X#define next_line	for (; s <= last_cmp && *s != '\n'; s++) {;}
X
Xboolean setgetty(dev, on_off)
Xchar	*dev;
Xboolean	on_off;
X{
X	int	len_dev;
X	char look,new,*s;
X
X	if (!open_inittab || !read_inittab) {return(SG_ERROR);}
X
X	len_dev = strlen(dev);
X	for (s = first_cmp; s <= last_cmp ; s++) {
X	    if (found_it) {
X		if (needs_change) {
X			change_it;
X			if (write_inittab && close_inittab) {
X				telinit;
X				return(SG_CHANGED);
X			} else {
X				return(SG_ERROR);
X			}
X		} else {
X			return(SG_NOT_CHANGED);
X		}
X	    }
X	    next_line;
X	}
X	return(SG_ERROR);
X}
END_OF_FILE
if test 1670 -ne `wc -c <'set.c'`; then
    echo shar: \"'set.c'\" unpacked with wrong size!
fi
# end of 'set.c'
fi
if test -f 'set.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'set.h'\"
else
echo shar: Extracting \"'set.h'\" \(315 characters\)
sed "s/^X//" >'set.h' <<'END_OF_FILE'
X/*
X$Header: /usr/spool/in/new-ph/RCS/set.h,v 1.1 89/11/14 13:21:14 bruce Exp $
X$Log:	set.h,v $
X * Revision 1.1  89/11/14  13:21:14  bruce
X * Initial revision
X * 
X*/
X
X#define OFF		0
X#define ON		1
X
X#define SG_CHANGED	0x1
X#define SG_NOT_CHANGED	0x2
X#define SG_ERROR	~(SG_CHANGED | SG_NOT_CHANGED)
X
Xboolean setgetty();
END_OF_FILE
if test 315 -ne `wc -c <'set.h'`; then
    echo shar: \"'set.h'\" unpacked with wrong size!
fi
# end of 'set.h'
fi
if test -f 'sig.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'sig.c'\"
else
echo shar: Extracting \"'sig.c'\" \(1565 characters\)
sed "s/^X//" >'sig.c' <<'END_OF_FILE'
X/*
X$Header: /usr/spool/in/new-ph/RCS/sig.c,v 1.1 89/11/14 13:21:16 bruce Exp $
X$Log:	sig.c,v $
X * Revision 1.1  89/11/14  13:21:16  bruce
X * Initial revision
X * 
X*/
X
Xstatic char *rcsid = "$Header: /usr/spool/in/new-ph/RCS/sig.c,v 1.1 89/11/14 13:21:16 bruce Exp $";
X
X#include "ph.h"
X#include "sig.h"
X
X#define PID_FILE	"/etc/phid"
X#define unlink_pid	unlink(PID_FILE)
X#define open_write_pid	((fd=open(PID_FILE,O_WRONLY|O_CREAT|O_EXCL,0644))!=-1)
X#define open_read_pid	((fd = open(PID_FILE, O_RDONLY)) != -1)
X#define write_pid	(write(fd, &pid, (unsigned) sizeof(pid)) != -1)
X#define read_pid	(read(fd, &pid, (unsigned) sizeof(pid)) != -1)
X
Xboolean makepid()
X{
X	int	fd;
X	int	pid;
X
X	unlink_pid;
X	pid = getpid();
X	return(open_write_pid && write_pid);
X}
X
Xboolean unlnkpid()
X{
X	return(unlink_pid == 0);
X}
X
Xint kill();
X#define send_sig	(kill(pid, sig) == 0)
X
Xboolean sigpid(sig)
Xint	sig;
X{
X	int	fd;
X	int	pid;
X
X	return(open_read_pid && read_pid && send_sig);
X}
X
X#define ignore(sig)	signal(sig, SIG_IGN)
X
Xvoid sigignor()
X{
X	int	i;
X
X	for (i = 0; i < NSIG; i++) {ignore(i);}
X#ifdef DEBUG
X	signal(SIGQUIT, SIG_DFL);
X#endif
X
X	return;
X}
X
Xstatic jmp_buf *jmpbuf_ptr;
X
Xvoid sigcatcher(sig)
Xint	sig;
X{
X	ignore_signals;
X
X	longjmp(*jmpbuf_ptr, sig);
X	exit(ERROR); /* this can't happen */
X}
X
X#define BADSIG		(int (*)()) -1
X#define set(sig)	(signal(sig, sigcatcher) != BADSIG)
X
Xboolean sigallow()
X{
X	return (set(TOGGLE0) && set(TOGGLE1) &&
X		set(HOLD0) && set(HOLD1) && set(HANGUP) &&
X		set(QUIT) && set(SIGPHONE));
X}
X
Xvoid sigjmp(where)
Xjmp_buf	*where;
X{
X	jmpbuf_ptr = where;
X	return;
X}
END_OF_FILE
if test 1565 -ne `wc -c <'sig.c'`; then
    echo shar: \"'sig.c'\" unpacked with wrong size!
fi
# end of 'sig.c'
fi
if test -f 'sig.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'sig.h'\"
else
echo shar: Extracting \"'sig.h'\" \(950 characters\)
sed "s/^X//" >'sig.h' <<'END_OF_FILE'
X/*
X$Header: /usr/spool/in/new-ph/RCS/sig.h,v 1.1 89/11/14 13:21:18 bruce Exp $
X$Log:	sig.h,v $
X * Revision 1.1  89/11/14  13:21:18  bruce
X * Initial revision
X * 
X*/
X
X#include <signal.h>
X#include <setjmp.h>
X
X#define TOGGLE0		SIGUSR1
X#define TOGGLE1		SIGUSR2
X#define HOLD0		SIGILL
X#define HOLD1		SIGTRAP
X#define HANGUP		SIGINT
X#define QUIT		SIGALRM
X#define DISPLAY		SIGPHONE
X
Xboolean	makepid();
Xboolean	unlnkpid();
Xboolean	sigpid();
Xvoid	sigignor();
Xint	sigallow();
Xvoid	sigjmp();
X
X#define make_pid_file		makepid()
X#define unlink_pid_file		unlnkpid()
X#define send_signal(sig)	sigpid(sig)
X#define ignore_signals		sigignor()
X#define allow_signals		sigallow()
X#define after_sig_jump(where)	sigjmp(where)
X
X#define sig_toggle(l)		send_signal(((l == 0) ? TOGGLE0 : TOGGLE1))
X#define sig_hold(l)		send_signal(((l == 0) ? HOLD0 : HOLD1))
X#define sig_hangup		send_signal(HANGUP)
X#define kill_phone_mgr		send_signal(QUIT)
X#define sig_phone_mgr(s)	send_signal(s)
END_OF_FILE
if test 950 -ne `wc -c <'sig.h'`; then
    echo shar: \"'sig.h'\" unpacked with wrong size!
fi
# end of 'sig.h'
fi
if test -f 'stat.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'stat.c'\"
else
echo shar: Extracting \"'stat.c'\" \(2737 characters\)
sed "s/^X//" >'stat.c' <<'END_OF_FILE'
X/*
X$Header: /usr/spool/in/new-ph/RCS/stat.c,v 1.1 89/11/14 13:21:20 bruce Exp $
X$Log:	stat.c,v $
X * Revision 1.1  89/11/14  13:21:20  bruce
X * Initial revision
X * 
X*/
X
Xstatic char *rcsid = "$Header: /usr/spool/in/new-ph/RCS/stat.c,v 1.1 89/11/14 13:21:20 bruce Exp $";
X
X#include <fcntl.h>
X#include <sys/types.h>
X#include <sys/ph.h>
X#include <sys/phone.h>
X#include <nlist.h>
X#include "ph.h"
X#include "stat.h"
X
X#define PHNDEF	0
X#define	UNIX	"/unix"
X#define	KMEM	"/dev/kmem"
X
Xstatic struct nlist unixsym[] = {		/* /unix name list of symbols */
X    { "phndef", },
X    { NULL, },
X};
X
Xstatic int		fdkmem;
Xstatic long		offset[2];
Xstatic struct phdef	phdata;
X
X#define get_namelist	(nlist(UNIX, &unixsym) != -1)
X
Xlong lseek();
X#define size_of_phdata	sizeof(phdata)
X
X#define open_kmem	((fdkmem = open(KMEM, O_RDONLY)) != -1)
X#define read_kmem(l)	(((long) lseek(fdkmem, (long) offset[l], 0) != \
X				(long) -1) && \
X			(read(fdkmem, &phdata, (unsigned) size_of_phdata) == \
X				size_of_phdata))
X#define close_kmem	(close(fdkmem) != -1)
X
X#define calc_offsets	offset[0] = (long) unixsym[PHNDEF].n_value; \
X			offset[1] = (long) offset[0] + (long) size_of_phdata
X
Xstatic int select_flag = 0;
X#define data		(phdata.p_lineparam & DATA)
X#define voice		(phdata.p_lineparam & VOICE)
X#define active		(voice && (phdata.p_linestatus & SETOFFHOOK))
X#define ring		(voice && (phdata.p_linestatus & INCOMERING))
X#define select		(voice && (select_flag == phone))
X#define hold		(voice && (phdata.p_statemch == PL_ONHOLD))
X
Xvoid selline(phone)
Xint	phone;
X{
X	select_flag = phone;
X	return;
X}
X
Xboolean openstat()
X{
X	if (get_namelist && open_kmem) {
X		calc_offsets;
X		return (TRUE);
X	} else {
X		close_kmem;
X		return (FALSE);
X	}
X}
X
Xboolean closstat()
X{
X	return(close_kmem);
X}
X
Xint getstat(phone)
Xint	phone;
X{
X	if (read_kmem(phone)) {
X		if (data) {return(GT_DATA);}
X		else if (hold) {return(GT_VOICE_HOLD);}
X		else if (active) {return(GT_VOICE_ACTIVE);}
X		else if (ring) {return(GT_VOICE_RING);}
X		else if (select) {return(GT_VOICE_SELECT);}
X		else {return(GT_VOICE_IDLE);}
X	} else {
X		return(GT_ERROR);
X	}
X}
X
Xtypedef struct {
X	int	stat_code;
X	char	*stat_desc;
X} stat_struct;
X
Xstatic stat_struct stat_list[] = {
X	{GT_DATA,		"DATA"},
X	{GT_VOICE_HOLD,		"HOLD"},
X	{GT_VOICE_ACTIVE,	"ACTIVE"},
X	{GT_VOICE_RING,		"RING"},
X	{GT_VOICE_SELECT,	"IDLE"},
X	{GT_VOICE_IDLE,		"idle"},
X	{0, (char *) NULL}
X};
X
Xstatic stat_struct	*p;
X
X#define status_desc	p->stat_desc
X
X#define found(s)	(p->stat_code == s)
X#define list_start	p = stat_list
X#define list_end	found(0)
X#define list_next	p++
X#define look_for(s)	for (list_start; !list_end && !found(s); list_next){;}
X
X
Xchar	*statdesc(phone)
Xint	phone;
X{
X	int	status;
X
X	status = get_status(phone);
X	look_for (status);
X	return (status_desc);
X}
END_OF_FILE
if test 2737 -ne `wc -c <'stat.c'`; then
    echo shar: \"'stat.c'\" unpacked with wrong size!
fi
chmod +x 'stat.c'
# end of 'stat.c'
fi
if test -f 'stat.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'stat.h'\"
else
echo shar: Extracting \"'stat.h'\" \(1166 characters\)
sed "s/^X//" >'stat.h' <<'END_OF_FILE'
X/*
X$Header: /usr/spool/in/new-ph/RCS/stat.h,v 1.1 89/11/14 13:21:22 bruce Exp $
X$Log:	stat.h,v $
X * Revision 1.1  89/11/14  13:21:22  bruce
X * Initial revision
X * 
X*/
X
X#define GT_DATA		0x1
X#define GT_VOICE_HOLD	0x2
X#define GT_VOICE_ACTIVE	0x4
X#define GT_VOICE_RING	0x8
X#define GT_VOICE_SELECT	0x10
X#define GT_VOICE_IDLE	0x20
X#define GT_VOICE	(GT_VOICE_HOLD | GT_VOICE_ACTIVE | GT_VOICE_RING | \
X			GT_VOICE_SELECT | GT_VOICE_IDLE)
X#define GT_ERROR	~(GT_DATA | GT_VOICE)
X
X#define is_data(l)	(get_status(l) == GT_DATA)
X#define is_voice(l)	(get_status(l) & GT_VOICE)
X#define is_hold(l)	(get_status(l) == GT_VOICE_HOLD)
X#define is_active(l)	(get_status(l) == GT_VOICE_ACTIVE)
X#define is_ring(l)	(get_status(l) == GT_VOICE_RING)
X#define is_select(l)	(get_status(l) == GT_VOICE_SELECT)
X#define is_idle(l)	(get_status(l) & (GT_VOICE_IDLE | GT_VOICE_SELECT))
X#define is_error(l)	(get_status(l) == GT_ERROR)
X
Xvoid	selline();
Xboolean openstat();
Xboolean closstat();
Xint	getstat();
Xchar	*statdesc();
X
X#define select_line(l)		selline(l)
X#define open_status		openstat()
X#define close_status		closstat()
X#define get_status(l)		getstat(l)
X#define status_description(l)	statdesc(l)
END_OF_FILE
if test 1166 -ne `wc -c <'stat.h'`; then
    echo shar: \"'stat.h'\" unpacked with wrong size!
fi
# end of 'stat.h'
fi
if test -f 'togl.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'togl.c'\"
else
echo shar: Extracting \"'togl.c'\" \(3469 characters\)
sed "s/^X//" >'togl.c' <<'END_OF_FILE'
X/*
X$Header: /usr/spool/in/new-ph/RCS/togl.c,v 1.1 89/11/14 13:21:23 bruce Exp $
X$Log:	togl.c,v $
X * Revision 1.1  89/11/14  13:21:23  bruce
X * Initial revision
X * 
X*/
X
Xstatic char *rcsid = "$Header: /usr/spool/in/new-ph/RCS/togl.c,v 1.1 89/11/14 13:21:23 bruce Exp $";
X
X#include <sys/phone.h>
X#include <dial.h>
X#include "ph.h"
X#include "stat.h"
X#include "set.h"
X#include "togl.h"
X
Xstatic char *prog_name = "togl";
X
X#define set_to_voice(phone)	setvoice(phone)
X#define set_to_data(phone)	setdata(phone)
X
X#define other_phone	((phone == 0) ? 1 : 0)
X
Xboolean toggle(phone)
Xint	phone;
X{
X	if (is_data(phone)) {
X		return (set_to_voice(phone));
X	} else {
X		if (is_idle(phone)) {
X			if (!is_data(other_phone) ||
X			   (is_data(other_phone) && set_to_voice(other_phone))){
X				return (set_to_data(phone));
X			}
X		}
X	}
X	return (FALSE);
X}
X
Xstatic int setg;
Xstatic char *dev[] =	{"ph0", "ph1"};
X#define set(on_off)	((setg = setgetty(dev[phone],on_off)) != SG_ERROR)
X#define set_changed	(setg == SG_CHANGED)
X
Xstatic int fdph[2];
Xstatic char *device[] =	{"/dev/ph0", "/dev/ph1"};
X#define open_read	((fdph[phone] = open(device[phone], O_RDONLY)) != -1)
X#define close_it	(close(fdph[phone]) != -1)
X#define tst_voice	(close_it && open_read && is_voice(phone)) 
X
X#define LOCKLEN		24
Xstatic char lock[LOCKLEN+1];
Xstatic int fdpid;
Xstatic int pid;
X#define make_lock_name	(sprintf(lock, "%s%s", LOCK, dev[phone]) == LOCKLEN)
X#define unlink_lock	(unlink(lock) != -1)
X#define create		(O_WRONLY | O_CREAT | O_EXCL)
X#define open_lock	((fdpid = open(lock, create, 0644)) != -1)
X#define write_lock	(pid = getpid(), (write(fdpid,&pid,sizeof(pid)) != -1))
X#define close_lock	(close(fdpid) != -1)
X#define make_lock_file	(make_lock_name && \
X			open_lock && write_lock && close_lock)
X#define unlock_phone	(make_lock_name && (unlink_lock, TRUE))
X#define lock_phone	(unlock_phone && make_lock_file)
X
Xstatic struct updata phdata;
X#define ioc(phone,x)	(ioctl(fdph[phone], x, &phdata) != -1)
X#define select(phone)	(ioc(phone,PIOCLINESEL) && (select_line(phone), TRUE))
X	    
Xboolean setvoice(phone)
Xint	phone;
X{
X	if (set(OFF)) {
X		wait_until(open_read);
X		if (!too_long) {
X			wait_until(tst_voice);
X			if (!too_long) {
X				if (lock_phone) {
X					return (TRUE);
X				}
X				unlock_phone;
X			}
X			close_it;
X		}
X		if (set_changed) {set(ON);}
X	}
X	return (FALSE);
X}
X
Xboolean setdata(phone)
Xint	phone;
X{
X	if (!is_idle(phone)) {return(FALSE);}
X	if (set(ON)) {
X		if (close_it) {unlock_phone;}
X		wait_until(is_data(phone));
X		if (!too_long) {return (TRUE);}
X	}
X	return (FALSE);
X}
X
Xboolean initline(phone)
Xint	phone;
X{
X	return (set_to_voice(phone) || set_to_data(phone));
X}
X
Xboolean quitline(phone)
Xint	phone;
X{
X	if (is_voice(phone)) {close_it; return(unlock_phone);}
X	return (TRUE);
X}
X
X#define get_data(phone)	ioc(phone,PIOCGETP)
X#define hold(phone)	(get_data(phone) && ioc(phone,PIOCHOLD))
X#define unhold(phone)	(get_data(phone) && ioc(phone, PIOCUNHOLD))
X
Xboolean holdline(phone)
Xint	phone;
X{
X	if (is_hold(phone)) {
X		if (!is_active(other_phone) ||
X		    is_active(other_phone) && hold(other_phone)) {
X			return (unhold(phone) && select(phone));
X		}
X	} else {
X		if (!is_data(phone)) {
X			if (is_active(phone)) {return (hold(phone));}
X			else if (is_idle(phone)) {return(select(phone));}
X		}
X	}
X	return (FALSE);
X}
X
X#define over_to(l)	((is_hold(l) ? unhold(l) : TRUE) && select(l))
X
Xboolean hangline()
X{
X	if (is_active(0)) {return (over_to(1));}
X	else if (is_active(1)) {return (over_to(0));}
X	else {return(FALSE);}
X}
END_OF_FILE
if test 3469 -ne `wc -c <'togl.c'`; then
    echo shar: \"'togl.c'\" unpacked with wrong size!
fi
# end of 'togl.c'
fi
if test -f 'togl.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'togl.h'\"
else
echo shar: Extracting \"'togl.h'\" \(440 characters\)
sed "s/^X//" >'togl.h' <<'END_OF_FILE'
X/*
X$Header: /usr/spool/in/new-ph/RCS/togl.h,v 1.1 89/11/14 13:21:25 bruce Exp $
X$Log:	togl.h,v $
X * Revision 1.1  89/11/14  13:21:25  bruce
X * Initial revision
X * 
X*/
X
Xboolean toggle();
Xboolean holdline();
Xboolean hangline();
Xboolean initline();
Xboolean quitline();
X
X#define toggle_line(l)		toggle(l)
X#define hold_line(l)		holdline(l)
X#define hangup_line		hangline()
X#define initialize_line(l)	initline(l)
X#define quit_line(l)		quitline(l)
END_OF_FILE
if test 440 -ne `wc -c <'togl.h'`; then
    echo shar: \"'togl.h'\" unpacked with wrong size!
fi
# end of 'togl.h'
fi
if test -f 'wind.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'wind.c'\"
else
echo shar: Extracting \"'wind.c'\" \(2997 characters\)
sed "s/^X//" >'wind.c' <<'END_OF_FILE'
X/*
X$Header: /usr/spool/in/new-ph/RCS/wind.c,v 1.1 89/11/14 13:21:27 bruce Exp $
X$Log:	wind.c,v $
X * Revision 1.1  89/11/14  13:21:27  bruce
X * Initial revision
X * 
X*/
X
Xstatic char *rcsid = "$Header: /usr/spool/in/new-ph/RCS/wind.c,v 1.1 89/11/14 13:21:27 bruce Exp $";
X
X#include "ph.h"
X#include "sig.h"
X#include "wind.h"
X#include "key.h"
X
Xstatic char* prog_name = "wind";
X
X#define WIDTH		20
X#define HEIGHT		1
X
Xstatic int		fdwind;
Xstatic struct uwdata	uwdata;
Xstatic struct utdata	utdata;
X
X#define	open_new_window	((fdwind = open("/dev/window", O_RDWR)) != -1)
X#define redefine_window	((ioctl(fdwind, WIOCGETD, &uwdata) != -1) && \
X			(uwdata.uw_x = 0, uwdata.uw_y = 0, \
X			uwdata.uw_width = 9 * (WIDTH + 1), \
X			uwdata.uw_height = 12 * HEIGHT, \
X			uwdata.uw_uflags = NBORDER, \
X    			utdata.ut_num = WTXTUSER, \
X			strcpy (utdata.ut_text, "Phone Manager"), \
X			(ioctl (fdwind, WIOCSETD, &uwdata) != -1) && \
X    			(ioctl (fdwind, WIOCSETTEXT, &utdata) != -1) && \
X			(ioctl (fdwind, WIOCSYS, 1) != -1)))
X#define close_new_wind	(close(fdwind) != -1)
X
Xstatic int fdold;
X
X#define to_old_window	(((fdold = ioctl(fdwind, WIOCGPREV, NULL)) != -1) && \
X			(ioctl(fdold, WIOCSELECT) != -1))
X
Xstatic struct termio	tty;
X
X#define redefine_tty	((ioctl (fdwind, TCGETA, &tty) != -1) && \
X			(tty.c_lflag = 0, \
X			tty.c_cc[VMIN] = 1, tty.c_cc[VTIME] = 0, \
X			(ioctl (fdwind, TCSETA, &tty) != -1)))
X
Xstatic struct umdata	mouseinfo;
Xstatic struct icon	myicon;
X
X#define zap_mouse	((ioctl (fdwind, WIOCGETMOUSE, &mouseinfo) != -1) && \
X			(mouseinfo.um_icon = &myicon, \
X			(ioctl (fdwind, WIOCSETMOUSE, &mouseinfo) != -1)))
X
Xstatic char		stat[WIDTH + 1];
X
X#define new_line	(write(fdwind, "\r\n", 2) != -1)
X#define display		((sprintf(stat,"0: %-6.6s 1: %-6.6s ",s0,s1)==WIDTH)&&\
X			(write(fdwind, stat, WIDTH) != -1))
X
X#define close_file(fd)	(close(fd) != -1)
X
Xboolean openwind()
X{
X	if (open_new_window && redefine_window && redefine_tty && zap_mouse) {
X		to_old_window;
X		return(TRUE);
X	} else {
X		return(FALSE);
X	}
X}
X
X#define set_program_grp	(setpgrp(), (ioctl(fdwind, WIOCPGRP) != -1))
X
Xboolean getaway()
X{
X	return(set_program_grp);
X}
X
Xboolean closwind()
X{
X	return(close_new_wind);
X}
X
X#define KEYLEN		3
X#define translate_key	((int)(key[2] - 'B'))
X
Xint readwind()
X{
X	char	key[KEYLEN];
X	int	ret;
X
X	if (read(fdwind, key, KEYLEN) != KEYLEN) {return(-1);}
X
X	switch (translate_key) {
X#ifdef F1
X	case 1:		ret = F1; break;
X#endif
X#ifdef F2
X	case 2:		ret = F2; break;
X#endif
X#ifdef F3
X	case 3:		ret = F3; break;
X#endif
X#ifdef F4
X	case 4:		ret = F4; break;
X#endif
X#ifdef F5
X	case 5:		ret = F5; break;
X#endif
X#ifdef F6
X	case 6:		ret = F6; break;
X#endif
X#ifdef F7
X	case 7:		ret = F7; break;
X#endif
X#ifdef F8
X	case 8:		ret = F8; break;
X#endif
X	default:	ret = DISPLAY; break;
X	}
X
X	return(ret);
X}
X
Xboolean dispwind(s0, s1)
Xchar	*s0, *s1;
X{
X	int n;
X
X	return(new_line && display);
X}
X	
X
Xvoid closfile()
X{
X	int	fd;
X
X	for (fd = 0; fd < _NFILE; fd++) {
X		if (fd != fdwind && fd != 2) {
X			close_file(fd);
X		}
X	}
X
X	return;
X}
END_OF_FILE
if test 2997 -ne `wc -c <'wind.c'`; then
    echo shar: \"'wind.c'\" unpacked with wrong size!
fi
# end of 'wind.c'
fi
if test -f 'wind.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'wind.h'\"
else
echo shar: Extracting \"'wind.h'\" \(561 characters\)
sed "s/^X//" >'wind.h' <<'END_OF_FILE'
X/*
X$Header: /usr/spool/in/new-ph/RCS/wind.h,v 1.1 89/11/14 13:21:28 bruce Exp $
X$Log:	wind.h,v $
X * Revision 1.1  89/11/14  13:21:28  bruce
X * Initial revision
X * 
X*/
X
X#include <sys/window.h>
X#include <sys/font.h>
X#include <termio.h>
X
Xboolean	openwind();
Xboolean	getaway();
Xboolean	closwind();
Xint	readwind();
Xboolean dispwind();
Xvoid	closfile();
X
X#define open_window		openwind()
X#define get_away		getaway()
X#define close_window		closwind()
X#define wait_until_read_window	readwind()
X#define display_window(s0,s1)	dispwind(s0,s1)
X#define close_files		closfile()
END_OF_FILE
if test 561 -ne `wc -c <'wind.h'`; then
    echo shar: \"'wind.h'\" unpacked with wrong size!
fi
# end of 'wind.h'
fi
echo shar: End of shell archive.
exit 0