	.TITLE	FNDSRV 
	.IDENT	/1.0/
	.NLIST	BEX

;.begin.doc ************************** begin.doc
;  
; .c ;Module name: 
; .c ;^&FNDSRV\&
; .nf
; .x FNDSRV>Defined
; Source:FNDSRV.MAC
; Designer           :
; Author             :DAVE LUECK
; Date of last update:12-MAR-87
; Revision level     :1.0
; 	
; .C ;Formal Parameter List
; Receives:
;     
; Returns:
; 	
; Accesses common(s):
; 	
; .X RTRDBS>Common
;    RTRDBS                     RESIDENT COMMON ROUTING DATABASE
;
; Accesses file(s):
; 	
; Other modules referenced:
; 	
; .SK
; .fill
; .SK
; Description:
; .sk    
;	This program is requested to run from the RSX Router, RTRRSX.  This
; task maps to the Router's database, RTRDBS, and scans for any NRB's (nodes)
; that show that a primary node name is a logical node name and that a logical
; connection is not present.  When a logical node name is found, the 
; corresponding service name is sent to SYCLU2 (at Systems) to find what 
; node the service is currently on.  If this is successful, the secondary
; node name of the NRB will be filled with the node name returned from SYCLU2.
; Example:  If the logical name is 'PROD  ' and after calling the service on
; SYCLU2 the node name returned is 'SY880A', then the secondary node name
; will be filled with 'SY880A'.
; end.doc ****************************** end.doc  
;
	.PAGE
	.MCALL	QIOW$S			; QIO AND WAIT
	.MCALL	DIR$			; DIRECTIVE CALL
	.MCALL	ATRG$			; ATTACH REGION
	.MCALL	CRAW$			; CREATE ADDRESS WINDOW
	.MCALL	EXIT$S			; EXIT TASK
	.MCALL	NETDF$			; NETWORK OFFSETS
	.MCALL	RTRHED			; DATABASE HEADER OFFSETS
	.MCALL	NRBDEF			; NRB OFFSETS
	.MCALL	OPNW$S			; ACCESS NETWORK
	.MCALL	CONB$$			; BUILD CONNECT BLOCK
	.MCALL	CONW$S			; REQUEST CONNECTION
	.MCALL	SNDW$S			; SEND DATA
	.MCALL	RECW$S			; RECEIVE DATA
	.MCALL	CLSW$S			; CLOSE NETWORK
	
	NETDF$				; GET OFFSETS
	.LIST 	ME
	RTRHED
	NRBDEF
	.NLIST	ME
	
	CEFN = 1			; CONSOLE QIO EVENT FLAG
	ICO = 1				; CONSOLE MESSAGES
	INET = 2			; NETWORK LUN
	ILNK = 3			; LOGICAL LINK LUN
;;	BUG = 1				; IF DEFINED, DEBUG MSGS WILL BE LOGGED

	.PSECT	$DATA,RW,D,CON,REL,LCL

	.INCLUDE 	/FNDSRV1.MAC/
CONBL:
	CONB$$	SYCLU2,0,1,<WHATSWHERE>	; CONNECTION REQUEST BLOCK
					;   NODE = SYCLU2
					;   TASK = WHATSWHERE
IOST:
	.BLKW	2			; STATUS BLOCK FOR NETWORK QIO'S
NODE:	
	.ASCII	/      /		; ACTUAL NODE NAME RETURNED FROM
					;   SYSTEMS (SYCLU2)
;
; DPB'S TO ATTACH AND MAP ROUTING DATABASE
;
CRWND:
	CRAW$	WDB	; CREATE ADDRESS WINDOW
;
; WINDOW DESCRIPTOR BLOCK
;
WDB:
	.BYTE	0	; UNUSED
	.BYTE	2	; W.NAPR APR (2)
	.WORD	0	; W.NBAS RETURN V. A. OR WINDOW
	.WORD	0	; W.NSIZ DESIRED SIZE OF WINDOW IN 32W BLOCKS
	.WORD	0	; W.NRID TASK REGION ID (FROM CREATE REGION)
	.WORD	0	; W.NOFF OFFSET TO START MAP
	.WORD	0	; W.NLEN LENGTH TO BE MAPPED IN 32W BLOCKS
	.WORD	WS.RED!WS.WRT!WS.MAP!WS.UDS		; W.NSTS STATUS 
		; WS.MAP= IF WINDOW IS TO BE MAPPED
		; WS.RED= READ ACCESS
		; WS.WRT= WRITE ACCESS
		; WS.UDS= CREATE WINDOW IN USER "D" SPACE
;
ATREG:
	ATRG$	RDB	; ATTACH REGION
;
; REGIONS DESCRIPTOR BLOCK
;
RDB:
	.WORD	0	; R.GID RETURNDED ID TO THE CREATED REGION
	.WORD	0	; R.GSIZ SIZE OF REGION TO CREATE IN 32W BLOCKS
	.RAD50	/RTRDBS/ ; R.GNAM NAME OF REGION
	.WORD	0,0	; R.GPAR PARTITION NAME (0= OUR PARTITION)
	.WORD	RS.RED!RS.WRT			   ; R.GSTS STATUS
	.WORD	010400	; R.GPRO PROTECTION, ALLOW ONLY OWNER AND SYSTEM FULL
			; ACCESS, REST READ ACCESS
	.PAGE

	.PSECT	$CODE,RO,I,CON,REL,LCL
START:
;
; ATTACH TO THE REGION
;
	DIR$	#ATREG		; ATTACH TO THE REGION
	BCC	2$		; ATTACH OK?
	MOV	#ATTERR,R1	; ADDRESS OF FORMAT STRING
	BR	3$		; LOG ERROR
;
; CREATE ADDRESS WINDOW AND MAP
;
2$:
	MOV	RDB+R.GSIZ,WDB+W.NSIZ  ; SET SIZE OF WINDOW
	MOV	RDB+R.GID,WDB+W.NRID   ; COPY REGION ID
	DIR$	#CRWND		; CREATE THE WINDOW
	BCC	5$		; EVERYTHING OK?
	MOV	#MAPERR,R1	; ADDRESS OF FORMAT STRING
3$:
	MOV	#MSGBUF,R0	; ADDRESS OF MESSAGE BUFFER
	BIS	#177400,$DSW	; MAKE SURE DSW IS NEGATIVE
	MOV	#$DSW,R2	; ADDRESS OF DSW
	CALL	$EDMSG		; FORMAT MESSAGE
	QIOW$S	#IO.WVB,#ICO,#CEFN,,#CONSTS,,<#MSGBUF,R1>
	EXIT$S			; FATAL ERROR
5$:
	MOV	WDB+W.NBAS,R5		; GET VIRT ADDRESS OF START OF DBS
	ADD	#HD.NRB,R5		; ADD OFFSET TO POINT TO FIRST NRB
					;   ADDRESS
	MOV	(R5),R5			; GET ADDRESS OF FIRST NRB
	MOV	WDB+W.NBAS,R4		; GET VIRT ADDRESS OF START OF DBS
	ADD	#HD.NCT,R4		; ADD OFFSET TO POINT TO NBR OF NRB'S
	MOV	(R4),R4			; GET NUMBER OF NRB'S DEFINED
10$:
	BIT	#NS.LND,N.STS(R5)	; IS THERE A LOGICAL NODE NAME TO
					;    TRANSLATE?
	BEQ	50$			; NO
	BIT	#NS.AVL,N.STS(R5)	; IS THE NODE ALREADY CONNECTED?
	BNE	50$			; YES

	MOV	#SRVCNT,R1		; GET NUMBER OF SERVICES
	CLR	R2			; POINTER INTO LOGICAL NAME ARRAY
	CLR	R3			; POINTER INTO SERVICE NAME ARRAY
30$:
	CMP	N.PRI(R5),LOGNOD(R2)	; DOES LOGICAL NODE NAME IN DBS 
					;   MATCH NAME IN ARRAY?
	BNE	40$			; NO MATCH
	CMP	N.PRI+2(R5),LOGNOD+2(R2) 
	BNE	40$			; NO MATCH
	CMP	N.PRI+4(R5),LOGNOD+4(R2) 	
	BNE	40$			; NO MATCH

	.IF DF BUG
	MOV	LOGNOD(R2),ASCSTA	; DEBUG
	MOV	LOGNOD+2(R2),ASCSTA+2	
	MOV	LOGNOD+4(R2),ASCSTA+4
	CALL	DEBUG

	MOV	SRVNAM+20(R3),ASCSTA	; DEBUG
	MOV	SRVNAM+22(R3),ASCSTA+2
	MOV	SRVNAM+24(R3),ASCSTA+4
	CALL	DEBUG
	.ENDC

	CALL 	GETNAM			; GET NAME OF NODE SERVICE IS ON
	
	.IF DF BUG
	MOV	NODE,ASCSTA		; DEBUG
	MOV	NODE+2,ASCSTA+2
	MOV	NODE+4,ASCSTA+4
	CALL	DEBUG
	.ENDC

	CMP	#"ER,NODE		; WAS A VALID NODE NAME RETURNED?
	BNE	35$			; YES
	CMP	#"RO,NODE+2
	BNE	35$			; YES
	CMP 	#"R ,NODE+4
	BNE	35$			; YES
	BR	50$			; NODE NAME RETURNED NOT VALID
35$:
	MOV	NODE,N.SEC(R5)		; LOAD ACTUAL NODE NAME INTO DATABASE
	MOV	NODE+2,N.SEC+2(R5)	
	MOV	NODE+4,N.SEC+4(R5)	
	BIS	#NS.NOD,N.STS(R5)	; MARK THAT SERVICE NODE WAS RECEIVED
	BR	50$			
40$:	
	ADD	#LOGLEN,R2		; POINT TO NEXT LOGICAL NAME IN ARRAY
	ADD	#SRVLEN,R3		; POINT TO NEXT SERVICE NAME IN ARRAY
	DEC	R1
	BEQ	50$
	JMP	30$
50$:
	MOV	N.LNK(R5),R5		; POINT TO NEXT NRB
	DEC	R4
	BEQ	55$
	JMP	10$
55$:
	EXIT$S
	.PAGE
;
;	THIS ROUTINE WILL SEND THE SERVICE NAME TO 'SYCLU2' AND WILL WAIT
;	FOR THE NAME OF THE NODE THE SERVICE IS CURRENTLY ON (THE ACTUAL 
;	NODE NAME NEEDED TO CONNECT).  IF ANY DECNET ERRORS OCCUR, THE ERROR
;	AND STATUS IS LOGGED AND THE TASK IS TERMINATED.
;
GETNAM:
	OPNW$S	#INET,#INET,#IOST	; ACCESS THE NETWORK 
	BCC	10$			; DIRECTIVE OK?
	MOV	#ERR1,R1		; NO, LOG ERROR
	JMP	DSWERR
10$:
	TSTB	IOST			; I/O STATUS OK?
	BPL	20$			; YES
	MOV	#ERR1A,R1		; LOG ERROR
	JMP	IOERR
20$:
	CONW$S	#ILNK,#ILNK,#IOST,,<#CONBL>	; REQUEST CONNECTION
	BCC	30$				; DIRECTIVE OK?
	MOV	#ERR2,R1			; NO, LOG ERROR
	BR	DSWERR
30$:
	TSTB	IOST			; I/O STATUS OK?
	BPL	40$			; YES
	MOV	#ERR2A,R1		; LOG ERROR
	BR	IOERR
40$:
	MOV	#SRVNAM,R0		; GET ADDRESS OF LOGICAL NODE NAME ARRAY
	ADD	R3,R0			; POINT TO NAME IN ARRAY TO BE SENT
	SNDW$S	#ILNK,#ILNK,#IOST,,<R0,#SRVLEN>	; SEND SERVICE NAME
	BCC	50$				; DIRECTIVE OK?
	MOV	#ERR3,R1			; NO, LOG ERROR
	BR	DSWERR
50$:
	TSTB	IOST			; I/O STATUS OK?
	BPL	60$			; YES
	MOV	#ERR3A,R1		; LOG ERROR
	BR	IOERR
60$:
	RECW$S	#ILNK,#ILNK,#IOST,,<#NODE,#6>	; RECEIVE RESPONSE FROM SYSTEMS
	BCC	70$				; DIRECTIVE OK?
	MOV	#ERR4,R1			; NO, LOG ERROR
	BR	DSWERR
70$:
	TSTB	IOST			; I/O STATUS OK?
	BPL	80$			; YES
	MOV	#ERR4A,R1		; LOG ERROR
	BR	IOERR
80$:
	CLSW$S	#INET,#INET,#IOST	; CLOSE NETWORK ACCESS
	BCC	90$			; DIRECTIVE OK?
	MOV	#ERR5,R1		; NO, LOG ERROR
	BR	DSWERR
90$:
	TSTB	IOST			; I/O STATUS OK?
	BPL	100$			; YES
	MOV	#ERR5A,R1		; LOG ERROR
	BR	IOERR
100$:
	RETURN

DSWERR:
	BIS	#177400,$DSW		; MAKE DSW NEGATIVE
	MOV	#$DSW,R2		; LOAD ADDRESS FOR $EDMSG
	BR	ERROR			
IOERR:
	BIS	#177400,IOST		; MAKE I/O STATUS NEGATIVE
	MOV	#IOST,R2		; LOAD ADDRESS FOR $EDMSG
ERROR:
	MOV	#MSGBUF,R0		; LOAD ADDRESS OF OUTPUT BUFFER FOR 
					;   $EDMSG
	CALL	$EDMSG			; FORMAT MESSAGE
	QIOW$S	#IO.WVB,#ICO,#CEFN,,#CONSTS,,<#MSGBUF,R1>
	EXIT$S				; CAN'T CONTINUE
	.PAGE
;
;	DEBUG MESSAGE
;
	.IF DF BUG
DEBUG:
	MOV	R1,-(SP)
	MOV	R2,-(SP)
	MOV	R3,-(SP)
	MOV	#MSGBUF,R0
	MOV	#DBG,R1
	MOV	#ASC,R2
	CALL	$EDMSG
	QIOW$S	#IO.WVB,#ICO,#CEFN,,#CONSTS,,<#MSGBUF,R1>
	MOV	(SP)+,R3
	MOV	(SP)+,R2
	MOV	(SP)+,R1
	RETURN	
	.ENDC
	.PAGE

	.PSECT	$DATA,RW,D,CON,REL,LCL
;
; QIO'S TO WRITE TO CONSOLE DEVICE
;
CONSTS:
	.WORD	1,0	; CONSOLE QIO STATUS
MSGBUF:	
	.BLKB	132.	; MESSAGE BUFFER
	
	.IF DF BUG
ASC:
	.WORD	ASCSTA
ASCSTA:
	.ASCII	/      /	; DEBUG
	.ENDC

ERR1:	.ASCIZ	/%NFNDSRV -- DIRECTIVE ERROR ACCESSING NETWORK; DSW: %D%N/
ERR2:	.ASCIZ	/%NFNDSRV -- DIRECTIVE ERROR REQUESTING CONNECTION; DSW: %D%N/
ERR3:	.ASCIZ	/%NFNDSRV -- DIRECTIVE ERROR SENDING DATA; DSW: %D%N/
ERR4:	.ASCIZ	/%NFNDSRV -- DIRECTIVE ERROR RECEIVING DATA; DSW: %D%N/
ERR5:	.ASCIZ	/%NFNDSRV -- DIRECTIVE ERROR CLOSING NETWORK; DSW: %D%N/
ERR1A:	.ASCIZ	?%NFNDSRV -- I/O ERROR ACCESSING NETWORK; I/O STATUS: %2D%N?
ERR2A:	.ASCIZ	?%NFNDSRV -- I/O ERROR REQUESTING CONNECTION; I/O STATUS: %2D%N?
ERR3A:	.ASCIZ	?%NFNDSRV -- I/O ERROR SENDING DATA; I/O STATUS: %2D%N?
ERR4A:	.ASCIZ	?%NFNDSRV -- I/O ERROR RECEIVING DATA; I/O STATUS: %2D%N?
ERR5A:	.ASCIZ	?%NFNDSRV -- I/O ERROR CLOSING NETWORK; I/O STATUS: %2D%N?
ATTERR:	.ASCIZ	/%NFNDSRV -- DIRECTIVE ERROR ATTACHING DATABASE; DSW: %D%N/
MAPERR:	.ASCIZ	/%NFNDSRV -- DIRECTIVE ERROR MAPPING DATABASE; DSW: %D%N/
	.IF DF BUG
DBG:	.ASCIZ	/%NFNDSRV -- DEBUG.... %6A%N/
	.ENDC
	.EVEN

	.END	START
