Google
 

Trailing-Edge - PDP-10 Archives - BB-J710A-BM - tools/nrt20/nrtsrv.mac
There are 20 other files named nrtsrv.mac in the archive. Click here to see a list.
	TITLE	NRTSRV - Program to provide remote network login service




;COPYRIGHT (C) 1979 BY
;DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.
;
;
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED
;ONLY  IN  ACCORDANCE  WITH  THE  TERMS  OF  SUCH LICENSE AND WITH THE
;INCLUSION OF THE ABOVE COPYRIGHT NOTICE.  THIS SOFTWARE OR ANY  OTHER
;COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
;OTHER PERSON.  NO TITLE TO AND OWNERSHIP OF THE  SOFTWARE  IS  HEREBY
;TRANSFERRED.
;
;
;THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT  NOTICE
;AND  SHOULD  NOT  BE  CONSTRUED  AS A COMMITMENT BY DIGITAL EQUIPMENT
;CORPORATION.
;
;DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY  OF  ITS
;SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL.
	SALL			; Keep listing uncluttered, no macro expansion
	SEARCH	MONSYM,MACSYM	; Universals to search
	.REQUIRE SYS:MACREL	; Make LINK load these automatically

;
; This program will allow a person to login to the system on which it is
; being run from a remote node on a DECnet network. It demonstrates use
; of of the TOPS-20 DECnet functionality in a program which performs a
; real and useful function. The person desiring to login to this system
; must run the NRT20 program, if on a TOPS-20 node, or a program of
; identical functionality on a node with another operating system.
;
	SUBTTL	DECLARED SYMBOLS

	T1==1			; AC definitions
	T2==2
	T3==3
	T4==4
	CX==16
	P==17

	MAXFRK==7		; Maximum number of server sub processes
	SRVOSZ==50		; Output buffer size in words
	MAXOUT==SRVOSZ*4	; Maximum number of output characters
	SRVSIZ==10		; Size of server buffer in words
	NPDL==40		; Size of pushdown list
	SUBTTL	IMPURE STORAGE

SAVAC:	BLOCK 4			; AC save area
DEVNAM:	BLOCK 2			; For building PTY names
PTYJFN:	BLOCK 1			; The JFN of the PTY
TTYJFN:	BLOCK 1			; TTY designator
SRVJFN:	BLOCK 1			; The JFN of the network connection
SRVINP:	BLOCK SRVSIZ		; Holds input characters
OUTPUT:	BLOCK 1			; Output buffer pointer
OUCNT:	BLOCK 1
PC:	BLOCK 1			; The software interrupt PC save area
SRVOUP:	BLOCK SRVOSZ		; Holds ouptut data
FORKS:	BLOCK MAXFRK		; Save process ID's here
HSTNAM:	BLOCK 2			; Host name string
PDL:	BLOCK NPDL		; Pushdown list (stack)

	RELOC 1000-140		; Start on page boundary

LEVTAB:	PC			; Where to stash the PC
CHNTAB:	1,,GOTCI		; Network connect received interrupt routine
	1,,GOTDAT		; Network data available interrupt routine
	SUBTTL	BEGIN - Start of NRTSRV program

BEGIN:	RESET			; Initialize ourselves
	MOVE T1,[SIXBIT /NRTSRV/] ; Our name in SIXBIT
	SETNM			; Set jobs private name
	HRROI T1,[ASCIZ /SRV/]	; See if network exists
	STDEV			; By checking for SRV device
	 JRST [	SETOM T1		; Doesn't exist, so go away
		LGOUT			; By logging out this job
		 JFCL			; Should always work, but...
		HALTF]			; Either way, go away
	MOVEI T1,.FHSLF		; This process
	RPCAP			; Get our capabilities
	MOVE T3,T2		; Copy them
	EPCAP			; Enable all capabilities we have
	MOVSI T4,-MAXFRK	; Maximum processes to create
FRKDO:	MOVX T1,CR%CAP		; Give them the same capabilities we have
	SETZM T2		; No AC's
	CFORK			; Create a process
	 ERJMP WTFRK			; If no more, done
	MOVEM T1,FORKS(T4)	; Save process handle
	HRLZ T2,T1		; Process handle of destination
	HRRI T2,1		; Start at page 1 in destination process
	MOVE T1,[.FHSLF,,1]	; Map this process to it
	MOVEI T3,ENDPRG-1	; Last address in use
	LSH T3,-11		; Make a repetition count
	TXO T3,PM%CNT!PM%RD!PM%WR ; Make PMAP argument
	PMAP			; Map the process' address space
	HLRZ T1,T2		; Get process handle
	MOVEI T2,START		; Start address
	SFORK			; Start the process up
FRKLOP:	AOBJN T4,FRKDO		; Do all of them
WTFRK:	MOVEI T1,.FHSLF		; Our process
	SETZM T3		; No capabilities
	EPCAP			; Disable all capabilities
	MOVEI T1,.FHINF		; All the inferior processes
	RFORK			; Resume them
	WFORK			; Wait for any inferior to halt
	; ..
	SUBTTL	RSPROC - Restart inferior process after it halted

RSPROC:	MOVEI T1,.FHINF		; All the inferior processes
	FFORK			; Freeze them
	MOVSI T4,-MAXFRK	; Scan process table
DEDLOP:	SKIPN T1,FORKS(T4)	; This one exist?
	JRST DEDLO1		; No, go on
	RFSTS			; Yes, get its status
	LOAD T1,RF%STS,T1	; Get its status
	CAIE T1,.RFHLT		; Halted?
	CAIN T1,.RFFPT		; Or error?
	JRST [	MOVE T1,FORKS(T4) 	; Yes, get process handle again
		SETZM FORKS(T4)		; Clear entry
		KFORK			; Kill the process
		HRRZS T4		; Create one more process
		MOVEI T1,.FHSLF		; Our process
		RPCAP			; Get our capabilities
		MOVE T3,T2		; Copy them
		EPCAP			; Enable all capabilities we have
		JRST FRKDO]		; Go back and create another process
DEDLO1:	AOBJN T4,DEDLOP		; Look at them all
	JRST WTFRK		; Wait some more
	SUBTTL	START - Start of code for inferior process'

;
; Note: This code runs as an inferior process to be the DECnet server
;	for NRT20. Any node on the network can make a connection to this
;	server to login to the system on which this program is running. A
;	separate copy of this code is run for each process which will be
;	a server. The DECnet object number of this server is 200. A TOPS-20
;	program can access the server with the DECnet file specification -
;	'DCN:node-200' where node is the node name to be logged in on. When
;	the server gets a connection from the network it obtains a PTY, and
;	sends a ^C character on it. It then accepts the network connection
;	and waits for data to arrive on the network link. Data arriving on
;	the network link is then output to the PTY and any data from the 
;	PTY is sent on the network link.
;

START:	CIS			; Clear interrupt system
	SKIPN T1,SRVJFN		; Have a server JFN yet?
	JRST START1		; No...
	TXO T1,CZ%ABT		; Yes, abort it
	CLOSF			; Close and abort the network connection
	 JFCL				; Ignore errors
	SETZM SRVJFN		; Clear the server JFN
START1:	SKIPN T1,PTYJFN		; Have a PTY yet?
	JRST START2		; No...
	TXO T1,CZ%ABT		; Yes, abort it
	CLOSF			; Close the PTY
	 JFCL				; Ignore errors
START2:	MOVE P,[IOWD NPDL,PDL]	; Initialize the stack pointer
	MOVEI T1,.FHSLF		; Our process
	MOVE T2,[LEVTAB,,CHNTAB] ; Address of level and channel table
	SIR			; Set software interrupt table addresses
	MOVX T2,3B1		; Channel 0 and 1
	AIC			; Activate software interrupt channels
	EIR			; Enable software interrupt system
	MOVE T1,[POINT ^D8,SRVOUP] ; Initial output pointer
	MOVEM T1,OUTPUT		; Initialize the pointer
	MOVEI T1,MAXOUT		; Maximum output characters
	MOVEM T1,OUCNT		; Initialize the output count
	MOVEI T1,.FHSLF		; Our process
	RPCAP			; Get our capabilities
	MOVE T3,T2		; Copy them
	EPCAP			; Enable all capabilities we have
	MOVX T1,GJ%SHT		; Short form GTJFN
	HRROI T2,[ASCIZ /SRV:200/] ; The NRT server file spec
	GTJFN			; Get a JFN for it
	 JRST TRYAGN			; Failed, go try to recover
	MOVEM T1,SRVJFN		; Save the server JFN
	MOVX T2,<FLD(^D8,OF%BSZ)!OF%RD!OF%WR> ; 8 bit bytes, read/write access
	OPENF			; Open the server JFN
	 JRST [	MOVE T1,SRVJFN		; Failed, get server JFN
		RLJFN			; Release the JFN
		 JFCL			; Ignore errors
		SETZM SRVJFN		; Clear the server JFN
		JRST TRYAGN]		; And go try to recover
	MOVEI T1,.FHSLF		; Our process
	SETZB T2,T3		; No capabilities
	EPCAP			; Disable all capabilities
	MOVE T1,SRVJFN		; Get the server JFN
	MOVEI T2,.MOACN		; Assign interrupt system channel numbers
	MOVX T3,<FLD(0,MO%CDN)!FLD(1,MO%DAV)!FLD(.MOCIA,MO%INA)> ; Connect event on 0, data available on 1
	MTOPR			; Perform the device operation
	WAIT			; Wait for something to happen
	SUBTTL	TRYAGN - Wait before trying to become a server again

TRYAGN:	MOVX T1,^D<1000*60*2>	; Two minutes in milliseconds
	DISMS			; Dismiss the process until time expires
	JRST START		; And go back to try again
	SUBTTL	GOTCI - Got a connect from the network

;
; Note: This routine is run at software interrupt level when a
;	remote node attempts to make a connection to us.

GOTCI:	CALL GETPTY		; Get a PTY to use
	JRST [	CIS			; Failed, clear the software interrupt system
		HRROI T1,[ASCIZ /
?No more PTYs on remote host
/]					; Point to message to tell what happened
		MOVE T2,SRVJFN		; Get the server JFN
		SETZM T3		; All of the string
		SOUTR			; Send message on network link
		 ERJMP .+1		; Ignore errors
		MOVE T1,SRVJFN		; Get the server JFN
		CLOSF			; Close the network connection
		 JRST START			; Failed, go back to recover
		SETZM SRVJFN		; Clear the server JFN
		JRST START]		; Go back to recover
	MOVEM T1,PTYJFN		; Save the PTY JFN
	MOVEM T2,TTYJFN		; Save the TTY designator
	MOVEI T2,"C"-100	; Get a Control-C (^C)
	BOUT			; Output it to PTY to start up job
	MOVE T1,SRVJFN		; Get the server JFN
	MOVEI T2,.MOCC		; Confirm the network connection
	SETZB T3,T4		; No optional data
	MTOPR			; Do the device operation
	 ERJMP START			; If error, link broken, start again
	MOVEI T1,PTYIN		; Address of PTY input routine
	MOVEM T1,PC		; Change the interrupt PC value to start
	GJINF			; Get current job information
	JUMPL T4,DONCI		; If terminal attached to job, done
	HRROI T1,[ASCIZ /
NRTSRV- CONNECTION FROM /]	; Point to message to say who's connecting
	PSOUT			; Output to TTY
	SETZM HSTNAM		; Clear host name buffer
	MOVE T1,SRVJFN		; Get the server JFN
	MOVEI T2,.MORHN		; Read network host name
	HRROI T3,HSTNAM		; Pointer to buffer
	MTOPR			; Do the device operation
	 ERJMP .+1			; Ignore errors
	HRROI T1,HSTNAM		; Pointer to host name buffer
	PSOUT			; Output the host name to TTY
	HRROI T1,[ASCIZ / ON /]	; Pointer to continuation of message text
	PSOUT			; Output to TTY
	MOVEI T1,.PRIOU		; TTY designator
	MOVE T2,PTYJFN		; Get the PTY JFN
	SETZM T3		; Full file specification format
	JFNS			; Output file spec associated with PTY JFN
	HRROI T1,[ASCIZ /
/]
	PSOUT			; End the message nicely
DONCI:	DEBRK			; Dismiss interrupt and resume processing PTY input
	SUBTTL	GOTDAT - Got data available from network connection

;
; Note: This routine is run at software interrupt level when data is
;	available to be read from the network connection.
;

GOTDAT:	DMOVEM T1,SAVAC		; Save AC's
	DMOVEM T3,SAVAC+2
GOTDA1:	MOVE T1,SRVJFN		; Get the server JFN
	MOVEI T2,.MORLS		; Read link's status
	MTOPR			; Do the device operation
	TXNN T3,MO%CON		; Connected?
	JRST START		; No, go start over
	SIBE			; Skip if input buffer empty
	 SKIPA			; Not empty, have some data
	JRST [	DMOVE T1,SAVAC		; Empty, no data, restore AC's
		DMOVE T3,SAVAC+2
		DEBRK]			; Dismiss interrupt and resume processing
	CAILE T2,SRVSIZ*5	; Buffer larger than number of bytes available?
	MOVEI T2,SRVSIZ*5	; No, get maximum buffer full
	MOVN T3,T2		; Get byte count
	MOVE T4,T3		; Save it
	HRROI T2,SRVINP		; Pointer to server input buffer
	SIN			; Read from network link
	 ERJMP START			; Failed, link broken, start again
	SUB T4,T3		; Calculate number of bytes read
	MOVE T3,T4		; Get byte count
	MOVE T1,PTYJFN		; Get PTY JFN
	HRROI T2,SRVINP		; Pointer to server input buffer
	SOUT			; Output data to PTY
	JRST GOTDA1		; And go back to do more
	SUBTTL	PTYIN - Pseudo TTY input routine

;
; Note: This routine gets run at background level by the GOTCI routine
;	changing the PC value at interrupt level when a network connection
;	is accepted.

PTYIN:	MOVE T1,PTYJFN		; Get PTY JFN
	BIN			; Input a byte from PTY
	IDPB T2,OUTPUT		; Store byte in output buffer and save pointer
	SOSG OUCNT		; Output buffer full?
	JRST PTYIN1		; Yes, write it then
	MOVE T1,TTYJFN		; Get TTY designator
	SOBE			; Skip if TTY output buffer empty
	 JRST PTYIN			; Not empty, go get more characters from PTY
PTYIN1:	MOVNI T3,MAXOUT		; Get negative maximum output count
	ADD T3,OUCNT		; Compute number of bytes in buffer
	MOVE T1,SRVJFN		; Get the server JFN
	MOVE T2,[POINT ^D8,SRVOUP] ; Get pointer to output buffer
	SOUTR			; Output data to network link
	 ERJMP START			; Failed, link died, start over
	MOVE T1,[POINT ^D8,SRVOUP] ; Get pointer to output buffer
	MOVEM T1,OUTPUT		; Reinitialize output buffer pointer
	MOVEI T2,MAXOUT		; Get maximum output count
	MOVEM T2,OUCNT		; Reinitialize output count
	JRST PTYIN		; Go back and get more characters from PTY
	SUBTTL	GETPTY - Get a pseudo TTY designator and return opened PTY JFN

GETPTY:	STKVAR <SAVCHR>		; Get stack variable storage
	MOVE T1,[SIXBIT /PTYPAR/] ; Pseudo TTY parameter table name
	SYSGT			; Get system table information for PTY
	HRRZM T1,SAVCHR		; Save TTY number of first pseudo TTY 
	HLRZ T4,T1		; Get number of PTY's
	MOVNS T4		; Get negative of count
	HRLZS T4		; Make an index loop pointer
GETPT1:	MOVSI T1,.DVDES+.DVPTY	; Get device designator for PTY
	HRR T1,T4		; Get PTY number
	DVCHR			; Get device characteristics of PTY
	TXNN T2,1B5		; Available?
	JRST GETPT2		; No, try next PTY then
	MOVE T2,T1		; Get device designator
	HRROI T1,DEVNAM		; Pointer to device name string buffer
	DEVST			; Translate device designator to string
	 JRST GETPT2			; Failed, try next PTY
	MOVEI T2,":"		; Get device string terminator character
	IDPB T2,T1		; Store it after device name string
	SETZM T2		; Get a null byte
	IDPB T2,T1		; Make device name string ASCIZ
	MOVX T1,GJ%SHT		; Short form GTJFN
	HRROI T2,DEVNAM		; Get pointer to PTY name string
	GTJFN			; Get a JFN for PTY
	 JRST GETPT2			; Failed, try next PTY
	MOVE T3,T1		; Save the PTY JFN
	MOVX T2,<FLD(^D8,OF%BSZ)!OF%RD!OF%WR> ; 8 bit bytes, read/write access
	OPENF			; Open the PTY
	 JRST [	MOVE T1,T3		; Failed, get PTY JFN
		RLJFN			; Release the PTY JFN
		 JFCL				; Ignore errors
		JRST GETPT2]		; And try next PTY
	MOVEI T2,.TTDES(T4)	; Get PTY index
	ADD T2,SAVCHR		; Get PTY designator
	RETSKP			; Done, return skip for success

; Step through all PTY's

GETPT2:	AOBJN T4,GETPT1		; Increment PTY number and go back if more to do
	RET			; No, give up, return no skip for failure

ENDPRG:				; End of code
	END BEGIN