	.TITLE domsg - SCLI message handler
	.IDENT /1.27/

.REM |
*+	domsg - SCLI message handler

	File:domsg.mac
	Version: 1.27
	Author:
	Last Edit: 23-DEC-1985 12:54:31 
	Last Update: 23-Dec-1985 12:55:03 
		     PTH - fix misspelling


*-
|
	.sbttl dpbs

	.psect dpbs,d
; 
; this psect holds the static dpbs
;
	.LIBRARY /LB:[1,1]GLMAC.MLB/
	.MCALL call,exit$s
	.MCALL push,pop,scli$,DIR$,rpoi$

Scli:	scli$	SCLI,TT,0			; set cli  to ourselves (SCLI)
Rpoi:	rpoi$	MCR...,,,1,1,,reini,reinil,,TT,0	; reinit SCLI

	.SBTTL LOCAL DATA

	.psect ldat,d,lcl,con
;
; use this psect for scratch storage - it is not guaranteed to be saved
; across calls to the module
;
log1:	.word	0	; four words for logging variables
log2:	.word 	0	;
log3:	.word	0	;
log4:	.word	0	;
	
; get the global data
	.include /sclidat.mac/

	.psect data,d,gbl,con
;
; use this psect for module-specific data which must be retained across
; calls to the module
;
Reini:	.ASCII \CLI /ini=scli/mes/lgo/dpr="<12><15>/--->/"\
	; reinit message
Reinil = .-reini					; calculate length
	.even

	.even
	.PSECT
; code goes in the blank psect

	.SBTTL DOMSG - Process SCLI System Messages

.REM |
	DOMSG processes all messages (as opposed to commands) 
	received by SCLI. Messages come in two forms: those
	produced automatically by RSX, and those initiated
	by someone using the MCR "CLI /MESSAGE" command. 
	Both types are important to SCLI. 

	CALL
		jsr pc, domsg

	INPUT
		r0 -> GCCI command buffer
	OUTPUT
		various (including immediate exit)
		depending upon message received.
	REGS
		preserved

|

DOMSG::
	call	$saval		; save all regs
	movb	g.ccun(r0), r1	; get message ident

	mov	#tttbl, r2	; point to tt table
;
; when SCLI is initialized (noramlly at boot time only), we
; must set up the tt table to show the current state of affairs.
;
; If we are cold-starting (from boot or program crash), the init
; code in SCLI will clear out all user-id fields. In this case,
; we set the terminals to SCLI (us), and show them protected.
; 
; If we are re-starting (someone tried to eliminate us), then we
; grab those terminals with null user-id's and protect them, while
; setting those with non-null user-id's (those 'logged on') as
; unprotected. 
;


	cmpb	#cm.ind,r1	; initialized (either enabled/disabled)?
	blo	100$		; no
50$:
	tst	tt.uid(r2)	; user logged on?
	beq	60$		; no - take over tt ourselves
	bic	#fl.pro, tt.flg(r2)	; show un-protected
	br	70$

60$:	bis	#fl.pro, tt.flg(r2)	; show protected
	mov	tt.num(r2), <scli+s.ciun> ; set tt number
	dir$	#scli			; take over the terminal
	bcc	70$		; br if no error
	mov	$dsw, log3	; set up to log error
	mov	#6, log1
	mov	#1, log2
	dolog	9.,<log1,log2,log3>	; log internal error

70$:	add	#ttsiz, r2	; point to next record
	tst	(r2)		; off end?
	bne	50$		; no - loop
	dolog	4.		; make log entry
	jmp	dond		; and done
	
100$:
	; when a tt is linked (set to SCLI), we set the protected
	; bit.

	cmpb	#cm.lkt, r1	; is it a new terminal linked to us?
	bne	200$		; no - br
	mov	g.ccbf+2(r0), r3	; get tt number
	mov	r3, ttnum	; save for logging
110$:	cmp	r3,tt.num(r2)	; this tt?
	beq	120$		; yes - br
	add	#ttsiz, r2	; check next record
	tst	(r2)		; off end?
	bne	110$		; no - loop
	br	140$		;yes - ignore !	

120$:	
	tst	tt.uid(r2)	; someone logged on this tt?
	beq	130$		; no - br
	mov	tt.uid(r2), log1	; point to user for logging
	dolog	2,<log1,ttnum>		; log user logged-off
	clr	tt.uid(r2)		; show no user now

130$:	bis	#fl.pro, tt.flg(r2)	; show protected
	bic	#fl.mbl, tt.flg(r2)	; not mumbling
	clr	tt.foo(r2)		; no foo count yet
140$:
	dolog	5.,<ttnum>	; log connect
	jmp	dond
	
200$:
	; when a tt is removed (cli set to something other than SCLI),
	; special care is required. If we initiated the switch, all
	; is well. In this case, we have pre-cleared the protection
	; bit. However, if someone is playing games with SET /CLI, 
	; then we want to set the tt right back to ourselves, to 
	; continue protection. 

	cmpb	#cm.rmt,r1	 ;is it a terminal being removed
	bne	300$		; no - br
	mov	g.ccbf+2(r0), r3	; get tt number
	mov	r3, ttnum	; save for logging
210$:	cmp	r3,tt.num(r2)	; this tt?
	beq	220$		; yes - br
	add	#ttsiz, r2	; check next record
	tst	(r2)		; off end?
	bne	210$		; no - loop
	br	240$		;yes - ignore !	
220$:	bit	#fl.pro, tt.flg(r2)	; protected?
	beq	240$		; no - all is well
	bit	#gf.kil,flags	; maint mode?
	beq	222$		; no - br - cannot eliminate protected TT
	bic	#fl.pro,tt.flg(r2)	;force protect bit clear
	br	240$
222$:
;
;* call SCLI to force cli back to ourselves
;
	mov	#scli, r3		; point to dpb
	mov	tt.num(r2), s.ciun(r3)	; stuff tt number
	dir$	#scli			; do it
	bcc	240$
	mov	$dsw, r1
	mov	#3, r0
	iot			;crash and burn
240$:	dolog	6.,<ttnum>	; log the disconnect
	jmp	dond
	
300$:
	; cli elimination requires extra care
	; we don't allow ourselves to be eliminated, except
	; by the 'eliminate all' at system shutdown.
	; since there is nothing we can do about being eliminated,
	; we detect the condition, re-establish ourselves,
	; and do an SCLI to any protected terminals. 
	;
	; There is also maintenance shutdown, which we want
	; to allow. So if the flag is set, don't fight elimination,
	; just exit gracefully.
	;
	cmpb	#cm.elm,r1 	;is it a cli elimination message
	bne	400$
	dolog	8.		; log the elimination
	bit	#gf.kil, flags	; maint shutdown?
	bne	350$		; yes - br 
320$:	dir$	#rpoi		; reinit ourself
	bcc	370$
	mov	$dsw, r0
	mov	#4, r1
	iot			; crash and burn
350$:	exit$s			; exit gracefully

370$:	br	dond		; and exit

400$:
	; for eliminate all, just exit. Note that code below
	; may be commented in/out to treat eliminate all
	; just like eliminate individual. 
	; 
	cmpb	#cm.ext,r1	 ;is it a eliminate all packet
	bne	500$		; no - br
	dolog	8.		; log the elimination
	bit	#gf.kil,flags	; maint mode?
	beq	320$		; no - br - elimination not allowed
	dolog	12.		; log the exit
	exit$s			; kill this damn program!
500$:
.rem |
	 The general message appears when someone issues a CLI ttt/msg=xxxx
	 MCR command. The message text contains the ASCII device
	 and octal unit number in the first two words, followed
	 by the user's text. Three messages are known to SCLI.
	
       1.
	 We use the message mechanism to provide a maintenance back-door
	 method of shutting down the cli. When the secret message is
	 received, we set a flag indicating shutdown in progress.
	 The flag disables the auto-reinit features, and allows 
	 SCLI to be eliminated or a terminal to be removed from
	 the list of protected terminals.  If eliminated, 
	 SCLI will exit.  In all cases, once maintenance mode is 
	 entered, it remains in maintenance mode.  Thus to reset the
	 SCLI to normal, the current version must be eliminated and
	 the new one started all over from the start (@STARTSCLI).
	
      2. The message VERBOSE (case is important) causes SCLI to begin
	logging to CO: all illegal input commands. Normally, only
	the command which causes Mumble-mode to be initiated is logged.

      3. The message QUIET (case is important) causes SCLI to resume
  	normal behavior for logging illegal input commands. 

	***** NOTE WELL ****
	* 
	* Protect the password - meaning this source module - very
	* carefully!!! Anyone with the message can shut down 
	* protection for the system! We rely on the user of this
	* back-door to re-establish SCLI when he/she is finished.
	*
	************************
	
|

	cmpb	#cm.msg, r1	; general message?
	bne	1000$		; no - br
	mov	g.ccbf+2(r0), ttnum	; remember initiator for logging
	movb	g.ccct(r0), r1	; get length
	sub	#4, r1		; less sender id = text length
	add	#g.ccbf+4, r0	; point past sender id
	mov	(r0), log3	; save first four chars for poss. err log
	mov	2(r0), log4	; ...
	.globl	lookup
	call	lookup		; look up text
	bcs	700$		; not found - br
	mov	r2, r3		; compute offset into cmdtbl
	asr	r3		; mov to r3 for single-reg multiply
	mul	#cmdsiz, r3	; 
	cmp	r3, #maxcmd	; offset too big?
	bhi	700$		; yes - illegal - br
	add	#cmdtbl, r3	; point into command table
	cmp	#ac.mai, cm.act(r3)	; maint mode message?
	beq	550$			; yes - br
	cmp	#ac.vrb, cm.act(r3)	; verbose on message?
	beq	600$			; yes - br
	cmp	#ac.qui, cm.act(r3)	; verbose off message?
	beq	650$			; yes - br
	br	700$		; illegal message - br
;@MARK@
550$: 	; process maint mode shutdown message

	bis	#gf.kil, flags	; set maint. shutdown flag
	dolog	7,<ttnum>	; log maint mode
	; 
	; now, clear all protection bits - this is consistent,
	; but also required so the 'disconnect' code doesn't
	; get bent out of shape
	;
	mov	#tttbl, r2	; point to tt-table
540$:	bic	#fl.pro, tt.flg(r2)	; clear protected bit
	add	#ttsiz, r2	; point to next record
	tst	(r2)		; end of table?
	bne	540$		; no - keep clearing
	br	dond		

600$:	; process verbose on message
	bis	#gf.vrb, flags	; set verbose bit
	br	dond		; that's all folks

650$:	; process verbose off (quiet) message
	bic	#gf.vrb, flags	; clear verbose bit
	br	dond		; that's all folks


700$:
	; someone is sending funny messages! - 
	; emit 'internal error' with ttnumber, plus
	; first four bytes of message text (in octal)
	; as params. 
	;
	mov	#4, log1		; set error number
	mov	#3, log2		; number of params
	dolog	9.,<log1,log2,ttnum,log3,log4> ; log the 'error'
1000$:
10000$:
;
; these, we don't care about, and ignore
;
;	cm.cen -- cli enabled
;	cm.cds -- cli disabled
;	
dond:	return
	.end
