	.IDENT	/01/
;
; This program mostly just hibernates, but wakes up at a predefined
; interval to see if it can hang up on any DZ lines.  The method employed
; is thus:
;
;	1) The program attempts get the terminal device characteristics.
;	2) If a terminal is not REMOTE, it goes on to the next terminal.
;	3) The program attempts to allocate the terminal.
;	4) If the allocation fails, someone is using it and we try next one.
;	5) If allocation succeeds, we assign a channel and issue a hangup QIO.
;
; In practice we run this program as a detached process fired up by the
; system startup file. It works out very well, since we have an environment
; in which users tend to log off without "hanging up", thus tying up terminal
; slots. The overhead is not all that great, and the reschedule interval could
; be adjusted considerably without degrading system preformance.
;
	$IODEF
	$SSDEF
	$TTDEF
;
; READ ONLY DATA
;
	.PSECT	RODATA,NOWRT,NOEXE

TTDESC:	.LONG	5
	.LONG	TTNAME
;
; This is the magic interval, it controls how long we hibernate between checks
;
INTERVAL:
	.ASCID	/0 00:10:00.00/

;
; READ/WRITE DATA
;
	.PSECT	RWDATA,RD,WRT,NOEXE

CHAR:	.LONG	12
	.LONG	TTCHAR
IOSB:	.BLKQ	1
TIMER:	.BLKQ	1
TTCHAR:	.BLKL	3
TTCHAN:	.BLKW	1
TTNAME:	.ASCII	/TT/			; We start out trying TTA0, TTA1...
CONTRL:	.ASCII	/A/			; Then TTB0,TTB1.......
UNIT:	.ASCII	/0/			; We quit when we get NOSUCHDEV status
	.ASCII	/:/
;
; EXECUTABLE CODE BEGINS
;

	.PSECT	CODE,EXE,RD,NOWRT

HANGUP::
	.WORD	0

	$BINTIM_S	TIMBUF=INTERVAL,-		;SET INTERVAL
			TIMADR=TIMER			;FOR WAKEUPS

	$SCHDWK_S	DAYTIM=TIMER,-			;SCHEDULE WAKEUPS
			REPTIM=TIMER

RESTART:

	$HIBER_S					;GO TO SLEEP

	MOVB		#^A/A/,CONTRL			;SET CONTROLLER
	MOVB		#^A/0/,UNIT			;SET UNIT

START:

	$GETDEV_S	DEVNAM=TTDESC,-			;GET DEVICE
			PRIBUF=CHAR			;CHARACTERISTICS

	CMPW		R0,#SS$_NOSUCHDEV		;CHECK IF EXISTS
	BEQL		RESTART				;ALL DONE IF NOT
	CMPW		R0,#SS$_BUFFEROVF		;EXPECT OVERFLOW
	BEQL		2$				;SKIP IF GET IT
	BRW		EXIT				;ABORT IF NOT

2$:	BBS		#TT$V_REMOTE,TTCHAR+8,3$	;SKIP IF REMOTE
	BRW		INC_TERM			;TRY NEXT TERM IF NOT

3$:	$ALLOC_S	DEVNAM=TTDESC			;ALLOCATE TERMINAL

	CMPW		R0,#SS$_NORMAL			;SUCCESSFUL?
	BNEQ		INC_TERM			;IF NOT SKIP TERMINAL

	$ASSIGN_S	DEVNAM=TTDESC,-			;ASSIGN CHANNEL
			CHAN=TTCHAN			;TO TERMINAL

	CMPW		R0,#SS$_NORMAL			;CHECK STATUS
	BNEQ		EXIT				;ABORT IF WRONG

	$QIO_S		CHAN=TTCHAN,-			;HANGUP THE TERMINAL
			FUNC=#IO$_SETMODE!IO$M_HANGUP	;TO MAKE IT LOCAL

	$DASSGN_S	CHAN=TTCHAN			;DEASSIGN THE CHANNEL

	$DALLOC_S	DEVNAM=TTDESC			;DEALLOCATE THE TERM

INC_TERM:

	INCB		UNIT				;INCREMENT UNIT #
	CMPB		UNIT,#^A/8/			;CHECK FOR NEW CONTROL.
	BLSS		1$				;TRY NEW TERM UNLESS
	INCB		CONTRL				;NEED NEXT CONTROLLER
	MOVB		#^A/0/,UNIT			;AND UNIT ZERO
1$:	BRW		START				;GO TRY NEXT TERMINAL

EXIT:
	$EXIT_S		R0

	.END		HANGUP
