mirror of
https://github.com/PDP-10/stacken.git
synced 2026-03-04 18:33:52 +00:00
1190 lines
39 KiB
Plaintext
1190 lines
39 KiB
Plaintext
;This software is furnished under a license and may only be used
|
||
; or copied in accordance with the terms of such license.
|
||
;
|
||
;Copyright (C) 1979,1980,1981,1982 by Digital Equipment Corporation
|
||
; 1983,1984,1985,1986 Maynard, Massachusetts, USA
|
||
|
||
|
||
TITLE MSHOST - Host table module for MS and friends
|
||
|
||
SEARCH GLXMAC,MSUNV,MACSYM
|
||
PROLOG (MSHOST)
|
||
|
||
CPYRYT
|
||
MSINIT
|
||
|
||
GLOBS
|
||
GLOBRS
|
||
|
||
;Routines defined herein
|
||
|
||
INTERNAL HSTINI, NAMINI, VALID8
|
||
|
||
;Routines defined elsewhere
|
||
|
||
;MSUTL.MAC
|
||
EXTERNAL ALCSB, COMPAC, COUNTS, MOVST0, MOVST2, RELSB, TBADDS
|
||
EXTERNAL ALCFOB
|
||
|
||
;Global data items defined herein
|
||
|
||
INTERNAL HOSTAB
|
||
|
||
;Global data items defined elsewhere
|
||
;MS.MAC
|
||
EXTERNAL MYHSPT, MYHDPT
|
||
|
||
;Local storage
|
||
|
||
IMPUR0
|
||
|
||
TOPS10<
|
||
MYHOST: BLOCK 1 ; Sixbit name of our host
|
||
NODNAM: BLOCK 2 ; ASCIZ name of node fetched from HOSTS.TXT
|
||
>;end TOPS10
|
||
LHOSTN: BLOCK 1 ; Local host number
|
||
CFSINI: BLOCK 1 ; CFS table initialization flag
|
||
PMRINI: BLOCK 1 ; PMR table initialization flag
|
||
HOSTAB: BLOCK 1 ; Address of the host table
|
||
SMLBUF==40 ; 199. characters ought to do it.
|
||
ATMBF2: BLOCK SMLBUF ; For parsing DNHOST.TXT
|
||
|
||
PURE
|
||
|
||
;Switches for UPS:DNHOST.TXT
|
||
|
||
SWTTAB: SWTTB0,,SWTTB0
|
||
CMD (NOMAIL20,NT%KWL)
|
||
SWTTB0==.-SWTTAB-1
|
||
SUBTTL Routines to parse host tables, determine what nets are present, etc.
|
||
|
||
;Figure out if we're on a network, and what our local host name is
|
||
; If we're both a DECNET and an ARPANET host, the ARPANET host name is used
|
||
; Also, note whether XMAILR exists
|
||
|
||
NAMINI: $SAVE <E> ; [3105]Save an AC
|
||
STKVAR <NODARG,<CFIGBL,10>> ; [3105]Add arg block for CNFIG%
|
||
TXZ F,F%ARPA!F%DECN!F%ANFX ; Assume no XMAILR or nets
|
||
TOPS20< MOVEI A,10 ; [3105]Length is 10
|
||
MOVEM A,CFIGBL ; [3105]Initialize the argument block
|
||
MOVX A,.CFINF ; [3105]Get Info
|
||
MOVEI B,CFIGBL ; [3105] from the CNFIG% jsys
|
||
CNFIG% ; [3105] into CFIGBL
|
||
ERJMP [JRETER <Can't find network info with CNFIG>
|
||
RET] ; [3105]Assume no network
|
||
MOVE A,.CFISO(B) ; [3105]Get the network bits
|
||
MOVE E,A ; [3105]Store them here
|
||
TXNN E,CF%ARP ; [3105]Do we have arpanet?
|
||
JRST NAMIN2 ; [3105]No...
|
||
MOVX A,.GTHSZ ; Try new style JSYS
|
||
GTHST ; for local host number
|
||
ERJMP NAMIN2 ; No ARPANET, try DECNET
|
||
MOVEM D,LHOSTN ; OK, save local host number
|
||
MOVE C,D ; Find our name
|
||
MOVE B,MYHSPT
|
||
MOVX A,.GTHNS
|
||
GTHST
|
||
ERJMP [JRETER <Can't find local host name with GTHST>
|
||
JRST NAMIN2] ; Eh? maybe try old stuff
|
||
TXO F,F%ARPA ; Remember net exists
|
||
NAMIN2: TXNN E,CF%DCN ; [3105]Do we have DECnet?
|
||
RET ; [3105]No, so we're done
|
||
MOVEI A,.NDGLN ; Get DECnet host name
|
||
MOVE B,MYHDPT
|
||
MOVEM B,NODARG ; Setup arg block for NODE jsys
|
||
MOVEI B,NODARG ; Point to it
|
||
NODE ; Get our name
|
||
ERJMP R ; Return - no network
|
||
TXO F,F%DECN!F%DNNM ; Set flag - we have DECnet, Default node names
|
||
|
||
; Edit 2370...
|
||
; Earlier code stuffed DECnet host name in ARPAnet node name string
|
||
; if there's no ARPAnet. This tends to break things, such as the
|
||
; default host name used for local user addresses, so MYHDEC is now
|
||
; the default host name always, and ARPAnet mail is the exception.
|
||
; This means there's no need to stuff the DECnet host name in MYHNAM
|
||
; so...
|
||
|
||
RET ; and return
|
||
>;End TOPS20
|
||
|
||
TOPS10<
|
||
MOVEI A,.GTLOC ; Get location of job 0 (crock)
|
||
GETTAB A, ; ..
|
||
JRST NOANF ; Failure, assume no net
|
||
SKIPN A ; ..
|
||
JRST NOANF ; ..
|
||
MOVEM A,LHOSTN ; Save local host number
|
||
MOVE C,A ; Copy to good place
|
||
MOVE A,[.NDRNN,,B] ; Function to return node name
|
||
MOVEI B,2 ; Length of arg block
|
||
NODE. A, ; Get our node name
|
||
JRST NOANF ; Ratz... assume no net
|
||
MOVEM A,MYHOST ; Save sixbit name for later checking
|
||
MOVE B,A ; Get SIXBIT into better AC
|
||
MOVE C,MYHSPT ; Where to put ASCII name
|
||
NAMIN2: SETZ A,
|
||
LSHC A,6 ; Get SIXBIT character in A
|
||
ADDI A,40 ; Make ASCII
|
||
IDPB A,C ; Stuff into name
|
||
JUMPN B,NAMIN2 ; Do all chars
|
||
IDPB B,C ; Insure ASCIZ
|
||
TXO F,F%ANFX ; Remember presence of ANF10 net
|
||
; Now see if there is a DECNET network
|
||
MOVEI A,B ; point to the DNET. table
|
||
MOVE B,[DN.FLE+<.DNLNN,,3>]
|
||
DNET. A,
|
||
RET ; there must be non DECNET network
|
||
MOVE B,D ; Get SIXBIT into better AC
|
||
MOVE C,MYHDPT ; Where to put ASCII name
|
||
NAMIN3: SETZ A,
|
||
LSHC A,6 ; Get SIXBIT character in C
|
||
ADDI A,40 ; Make ASCII
|
||
IDPB A,C ; Stuff into name
|
||
JUMPN B,NAMIN3 ; Do all chars
|
||
IDPB B,C ; Insure ASCIZ
|
||
TXOA F,F%DECN ; Remember presence of DECNET net
|
||
NOANF: SETZM MYHNAM ; No networks what-so-ever
|
||
RET ; Home, James
|
||
>;End TOPS10
|
||
|
||
SUBTTL HSTINI - init hostname tables
|
||
; HSTINI - Initialize host table control variables
|
||
;
|
||
HSTINI::SETZM HOSTAB ; no host table yet
|
||
SETZM PMRINI ; PMR hasn't been read
|
||
SETZM CFSINI ; We don't know about CFS either
|
||
RET ; All done
|
||
|
||
|
||
;
|
||
; VALID8 - Validate the existance of a host name
|
||
;
|
||
; - This routine uses HOSTAB as a cache of validated host names
|
||
; rather than the definitive source of legal hosts. It first
|
||
; checks this table to see if the requested host has already been
|
||
; validated.
|
||
; - Failing this, we ask the O/S for validation, first via DECnet, then
|
||
; ARPAnet (if TOPS20), then via ANF10 (if TOPS10)
|
||
; - If the host is still unknown, and the PMR table has not been parsed
|
||
; yet, then it is parsed, and the new hosts added to HOSTAB. HOSTAB
|
||
; is checked once more for the requested host name, and if not found
|
||
; VALID8 returns a failure (+1).
|
||
;
|
||
; A/ Pointer to ASCIZ host name string
|
||
;
|
||
; Returns:
|
||
; +1 - No such host
|
||
; +2 - Valid host
|
||
;
|
||
; This table contains the host name validation routines, in the order they
|
||
; are tried. If we haven't already validated this host, VALID8 uses these
|
||
; routines to figure out who this host is...
|
||
;
|
||
V8TABL:
|
||
TOPS20< CALL VALCFS> ; CFS, for TOPS-20 systems only
|
||
CALL VALDNA ; DECnet
|
||
TOPS20< CALL VALARP> ; ARPAnet
|
||
TOPS10<;CALL VALANF> ; ANF-10
|
||
V8NUM==.-V8TABL ; This is the table size
|
||
;
|
||
;
|
||
VALID8: STKVAR <SVPTR> ;Place to save the host name pointer
|
||
TLC A,-1 ; Did we get a -1,,addr?
|
||
TLCN A,-1 ; If so, it was a 0, so don't skip
|
||
HRLI A,(POINT 7,) ; Otherwise make it a pointer
|
||
MOVEM A,SVPTR ; Save pointer to host name
|
||
SKIPE B,HOSTAB ; Any host table?
|
||
IFNSK. ; No skip => table exists
|
||
EXCH A,B ; Put arguments where they're expected
|
||
$CALL S%TBLK ; Look up the host
|
||
EXCH A,B ; Put things back where they're expected
|
||
TXNE A,TL%EXM ; Has this host already been checked?
|
||
RETSKP ; Yes, this is a valid host
|
||
MOVE A,SVPTR ; Put the pointer back in A
|
||
ENDIF. ; Here when we have to take the longer route
|
||
MOVSI C,-V8NUM ; Make an AOBJN pointer
|
||
VALID9: XCT V8TABL(C) ; Check out the host
|
||
IFSKP. ; Skip return means this is a valid host
|
||
CALL NEWHST ; Add this host to HOSTAB
|
||
RET ; No room for host entry
|
||
RETSKP ; And return good
|
||
ENDIF. ; Otherwise...
|
||
AOBJN C,VALID9 ; Loop through the validation table
|
||
CALL VALPMR ; Check to see if we already loaded PMR table
|
||
RET ; Yes we did, so the host isn't valid
|
||
RETSKP ; It was a PMR host
|
||
|
||
SUBTTL Network Host name validation routines
|
||
;
|
||
; VALANF - TOPS-10 only routine to ask the system if the host name supplied
|
||
; is a valid ANF-10 host
|
||
;
|
||
; Called with A/ Pointer to ASCIZ host name
|
||
;
|
||
; Returns
|
||
; +1 - Not an ANF-10 host
|
||
; +2 - Valid host, B/ HOSTAB-style node block
|
||
;
|
||
TOPS10<
|
||
;VALANF:RET> ; For now
|
||
|
||
;
|
||
; VALARP - TOPS-20 only routine to ask the system if the host name supplied
|
||
; is valid
|
||
;
|
||
; Called with A/ Pointer to ASCIZ host name
|
||
;
|
||
; Returns
|
||
; +1 - Not an ARPAnet host
|
||
; +2 - Valid host, B/ HOSTAB-style node block
|
||
;
|
||
TOPS20<
|
||
VALARP: $SAVE <A,C,D> ; Save caller's ac's
|
||
STKVAR <HOSTN,HSTR,HBLK> ; Node number, host string block address
|
||
MOVEM A,HSTR ; save the pointer to the host name here
|
||
MOVE B,A ; Put the pointer in B
|
||
MOVX A,.GTHSN ; Convert name to host number function
|
||
GTHST% ; Ask the ARPAnet
|
||
ERJMP R ; Not a valid name
|
||
TXNN D,HS%SRV ; Is this a server host?
|
||
RET ; No, so it's not a legitimate host
|
||
MOVEM C,HOSTN ; Save host number for a bit
|
||
CALL ALCNB ; get a node block
|
||
IFNSK. ; No skip means memory exhausted,
|
||
MOVE A,HSTR ; So release the string block,
|
||
$TEXT(KBFTOR,<%Memory space exhausted.>)
|
||
$TEXT(KBFTOR,<%Cannot add ARPAnet host ^T/A/.>)
|
||
CALL RELSB ; because we can't build a HOSTAB entry
|
||
RET ; Bad return.
|
||
ENDIF.
|
||
MOVEM A,HBLK ; save the address of the block
|
||
MOVE A,HSTR ; get the string pointer back
|
||
CALL COUNTS ; find out how long it is
|
||
CALL ALCSB ; and get a string block that long
|
||
IFNSK. ; No skip means no memory left
|
||
$TEXT(KBFTOR,<%Memory space exhausted.>)
|
||
$TEXT(KBFTOR,<%Cannot add ARPAnet host ^T/A/.>)
|
||
RET ; No memory, no deal
|
||
ENDIF. ;
|
||
MOVE A,HBLK ; get the node block address
|
||
MOVEM B,N.NAME(A) ; save the address of the string block in it
|
||
MOVE A,B ; put the string block in A
|
||
HRLI A,(POINT 7,) ; make the string block address a pointer
|
||
MOVE B,HSTR ; get the pointer to the actual node name
|
||
CALL MOVST2 ; and move the host name into the string block
|
||
MOVX B,NT%ARP ; ARPANET host flag to RH
|
||
CAMN C,LHOSTN ; Is this us?
|
||
TXO B,NT%LCL ; Yes, light local host flag
|
||
MOVE A,HBLK ; get the node block address back
|
||
MOVEM B,N.FLGS(A) ; Set flags in node block
|
||
HRLZ B,N.NAME(A) ; get the address of the name string
|
||
HRR B,A ; Node block address to RH
|
||
RETSKP ; Here means it's a valid name
|
||
> ; End TOPS20 conditional
|
||
|
||
; VALCFS - TOPS-20 only routine to validate the host name supplied with the
|
||
; list of known CFS hosts that are sharing POBOX:. This routine
|
||
; is called AFTER VALID8 has looked in HOSTAB, so the only thing
|
||
; to do is to check if HOSTAB includes the CFS hosts. If it does,
|
||
; then obviously the host name isn't a CFS host. If it doesn't,
|
||
; then we load the CFS host names from SYSTEM:CFS-HOSTS.TXT and
|
||
; look again.
|
||
;
|
||
TOPS20<
|
||
VALCFS: $SAVE <A,C> ; Save the caller's ac's
|
||
STKVAR CFSSAV ; place to keep the pointer
|
||
SKIPN CFSINI ; Is CFS table initialized?
|
||
RET ; Yes, so we already checked it
|
||
MOVEM A,CFSSAV ; Save the host name pointer
|
||
CALL CFSOPN ; No, so open the file
|
||
RET ; No file, no CFS hosts
|
||
CALL CFSPRS ; Parse the CFS hosts into HOSTAB
|
||
CALL CFSCLS ; Close the CFS file
|
||
MOVE B,CFSSAV ; Put the string pointer in B
|
||
MOVEI A,HOSTAB ; Get the host table address
|
||
CALL S%TBLK ; Look it up
|
||
TXNN B,TL%EXM ; Did we find a match?
|
||
RET ; nope, not a CFS host
|
||
RETSKP ; yes, it's good
|
||
|
||
; CFSOPN - Open the CFS host name file (SYSTEM:CFS-HOSTS.TXT)
|
||
;
|
||
; Returns:
|
||
;
|
||
; +1 - file not found or open error
|
||
; +2 - succeeded, JFN in A
|
||
;
|
||
CFSOPN:
|
||
RET ; Do this later
|
||
; CFSPRS - Parse the CFS host name file
|
||
;
|
||
; Returns +1 always
|
||
;
|
||
CFSPRS:
|
||
RET
|
||
; CFSCLS - Close the CFS host name file
|
||
;
|
||
; Returns +1 always
|
||
;
|
||
CFSCLS:
|
||
RET
|
||
> ; End of TOPS20 conditional
|
||
;
|
||
; VALDNA - DECnet routine to validate the supplied host name
|
||
;
|
||
; Called with A/ Pointer to ASCIZ host name
|
||
;
|
||
; Returns
|
||
; +1 - Not a DECnet host name
|
||
; +2 - Valid DECnet host name
|
||
; with B/ TBLUK-style node block
|
||
;
|
||
VALDNA: $SAVE <A,C> ; Save the caller's ac's
|
||
STKVAR <VNBLK,VHPTR> ; local storage
|
||
MOVEM A,VHPTR ; Save the pointer to the node name
|
||
CALL NODVFY ; Call O/S-specific DECnet routine
|
||
RET ; Not a valid node
|
||
CALL ALCNB ; Allocate a node block
|
||
IFNSK. ; If there's no more memory,
|
||
$TEXT(KBFTOR,<%Memory space exhausted.>)
|
||
$TEXT(KBFTOR,<%Cannot add DECnet host ^T/A/.>)
|
||
RET ; And return bad
|
||
ENDIF. ;
|
||
MOVEM A,VNBLK ; Save N-block address
|
||
MOVE A,VHPTR ; Get the pointer to the node name
|
||
CALL COUNTS ; Count the bytes in it
|
||
CALL ALCSB ; Get a string block for it
|
||
IFNSK. ; If we're out of memory now...
|
||
MOVE A,VNBLK ; Get the N-block address
|
||
CALL RELNB ; And release it
|
||
$TEXT(KBFTOR,<%Memory space exhausted.>)
|
||
$TEXT(KBFTOR,<%Cannot add DECnet host ^T/A/.>)
|
||
RET ; and return bad
|
||
ENDIF. ;
|
||
MOVE A,VNBLK ; Get the node block address
|
||
MOVEM B,N.NAME(A) ; Stuff string address into N-block
|
||
MOVE A,B ; Set up for MOVST0
|
||
HRLI A,(POINT 7,) ; Byte pointer
|
||
MOVE B,VHPTR ; Get the pointer to the node name
|
||
CALL MOVST2 ; Copy to new block
|
||
MOVE B,VNBLK ; Point to N-block
|
||
MOVE A,N.NAME(B) ; Point to name string
|
||
HRLI A,(POINT 7,) ; ..
|
||
MOVE B,MYHDPT
|
||
TOPS20< STCMP > ; See if this name matches local node name
|
||
TOPS10< $CALL S%SCMP> ; Ditto
|
||
MOVX B,NT%DCN!NT%NM0 ; DECNET node, name in heap space
|
||
SKIPN A ; A = 0 if name matched
|
||
TXO B,NT%LCL ; Match, this is the local node
|
||
MOVE A,VNBLK ; Point to node block again
|
||
MOVEM B,N.FLGS(A) ; Stuff flags into N-block
|
||
HRR B,A ; Set up for TBADDS
|
||
HRL B,N.NAME(B) ; Ptr to name string in LH
|
||
RETSKP ; Return the HOSTAB-style node block address
|
||
; NODVFY - Operating System-specific DECnet Node name verification routine
|
||
;
|
||
; Called with A/ Pointer to ASCIZ node name string
|
||
;
|
||
; Returns:
|
||
; +1 - Not a valid name
|
||
; +2 - Valid
|
||
;
|
||
NODVFY: STKVAR <<NODBLK,2>> ; Temporary storage
|
||
TOPS20< MOVEI B,NODBLK ; Point to argument block
|
||
MOVEM A,.NDNOD(B) ; Save the pointer to the host name
|
||
MOVX A,.NDVFY ; NODE% JSYS Verify function
|
||
NODE% ; Call TOPS-20
|
||
ERJMP R ; Shouldn't happen, but just in case
|
||
MOVE B,.NDFLG(B) ; Get the flags returned by NODE%
|
||
TXNN B,ND%EXM ; Was it an exact match?
|
||
RET ; Nope, no good.
|
||
RETSKP ; Node name is ok.
|
||
>; End of TOPS20 conditional
|
||
TOPS10< CALL ASCSIX ; Turn the node name into SIXBIT
|
||
MOVEM B,.DNNAM+NODBLK ; And save it for DNET.
|
||
MOVE A,[DN.FLK+<.DNNDI,,2>] ; Args to ask DNET if this node valid
|
||
MOVEM A,NODBLK ; Save it away
|
||
MOVEI A,NODBLK ; Point to block
|
||
DNET. A, ; Is this a valid DECNET node name?
|
||
CAIE A,DNNSN% ; No such node.
|
||
RETSKP ; Node name is ok.
|
||
RET ; Node name is not legit.
|
||
|
||
;Convert ASCIZ string pointed to by A into SIXBIT in B
|
||
|
||
ASCSIX: SETZ B,
|
||
MOVE D,[POINT 6,B]
|
||
ASCSX1: ILDB C,A ; Next byte
|
||
JUMPE C,R ; Stop on null
|
||
CAIGE C,40 ; Insure no random ctrl chars
|
||
JRST ASCSX1 ; just ignore 'em if present
|
||
CAIL C,140 ; Uppercasify
|
||
TRZ C,40 ; ..
|
||
SUBI C,40 ; SIXBIT-ify
|
||
IDPB C,D ; Stuff
|
||
TRNN B,77 ; Stop at six chars
|
||
JRST ASCSX1 ; ..
|
||
R: RET
|
||
|
||
>; End of TOPS10 conditional
|
||
;
|
||
; NEWHST - Add the specified host name to HOSTAB
|
||
;
|
||
; Called with B/ TBLUK-style entry (string-addr,,block-addr)
|
||
;
|
||
; Returns +1 always
|
||
; with B/ Address of new HOSTAB slot
|
||
;
|
||
; Note: if HOSTAB is full, then the host just doesn't get into the table.
|
||
;
|
||
NEWHST: MOVEI A,HOSTAB ; Get the TBLUK header
|
||
CALL TBADDS ; Add it to the table.
|
||
RET ; No more room
|
||
MOVE B,A ; Put the entry where callers expect it.
|
||
RETSKP ; All set
|
||
; VALPMR - Check to see if the PMR tables have been loaded, if not
|
||
; do so and look for the specified host name again. Otherwise
|
||
; just return +1
|
||
;
|
||
; Called with A/ pointer to ASCIZ host name
|
||
;
|
||
; Returns:
|
||
; +1 - invalid host name
|
||
; +2 - Valid host, B/ Pointer into HOSTAB entry
|
||
;
|
||
VALPMR: SKIPE PMRINI ; Have we been here already?
|
||
RET ; Yes, so the host name is invalid
|
||
SETOM PMRINI ; Set the PMR flag
|
||
CALL HSTIND ; Initialize the table
|
||
MOVE B,A ; Put the host name here
|
||
MOVE A,HOSTAB ; and the address of the table
|
||
$CALL S%TBLK ; Look it up
|
||
EXCH A,B ; Put argument where it's expected
|
||
TXNN A,TL%EXM ; Match?
|
||
RET ; Nope
|
||
RETSKP ; Yes, return good.
|
||
|
||
|
||
;See if DECNET host name table exists, and add hosts to table if so.
|
||
|
||
TOPS20<
|
||
HSTIND: $SAVE <A,B,C> ; Just in case, save work registers
|
||
TRVAR <FBITS,HSTJFN,HFPGS,HFPGN,HFPTR,HFCNT,HSTR,HDST,SSTR,PATH,PTHFLG>
|
||
MOVX A,GJ%OLD!GJ%SHT ; Look for existing file
|
||
HRROI B,[ASCIZ /UPS:DNHOST.TXT/]
|
||
GTJFN
|
||
ERJMP R ; No table, just quit
|
||
MOVX B,OF%RD
|
||
OPENF ; open for read
|
||
JFATAL <Cannot open DECnet host name table>
|
||
MOVEM A,HSTJFN ; Save JFN
|
||
SIZEF ; Get file size
|
||
JFCL ; Unlikely
|
||
MOVEM C,HFPGS ; Save page count
|
||
MOVE A,C ; Acquire space to map file
|
||
$CALL M%AQNP ; ..
|
||
MOVEM A,HFPGN ; Save page no. of 1st page
|
||
LSH A,^D9 ; Form word address
|
||
HRLI A,(POINT 7,) ; Form byte pointer
|
||
MOVEM A,HFPTR ; save
|
||
HRLZ A,HSTJFN ; Map from file page zero
|
||
HRLI B,.FHSLF ; to fork page
|
||
HRR B,HFPGN ; here
|
||
MOVE C,HFPGS ; Page count
|
||
TXO C,PM%RD!PM%PLD!PM%CNT
|
||
PMAP
|
||
MOVE A,HSTJFN ; Get JFN back
|
||
MOVE B,[1,,.FBSIZ] ; Get byte count for file
|
||
MOVEI C,C ; Into C
|
||
GTFDB
|
||
MOVEM C,HFCNT ; Save
|
||
SETZM PATH ; No path block yet
|
||
; JRST HSTID1 ; Enter host parse loop
|
||
|
||
HSTID1: MOVE A,[POINT 7,ATMBF2] ; Where to build host name string
|
||
MOVEM A,HDST ; Init destination pointer
|
||
SETZM FBITS ; No flag bits known yet
|
||
SETZM SSTR ; No synonyms yet
|
||
SETZM PTHFLG ; Clear the path flag (set when parsing a path)
|
||
SETZM PATH ; Init path-seen flag
|
||
HSTID2: CALL BYTIN ; Get a byte
|
||
JRST HSTIDE ; Error or EOF - quit
|
||
CAIN B,"/" ; Check for switches
|
||
CALL HSTIDK ; Go handle
|
||
CAIN B,"," ; Comma? (routing info follows)
|
||
JRST [ SETZ B, ; Insure ASCIZ for name string
|
||
IDPB B,HDST ; ..
|
||
CALL CPYAT2 ; Allocate a string block
|
||
JRST HSTIDM ; Insufficient memory
|
||
MOVEM A,PATH ; Save addr of temp block
|
||
MOVE A,[POINT 7,ATMBF2] ; Reinit atom buffer pointer
|
||
MOVEM A,HDST ; for collection of path string
|
||
SETOM PTHFLG ; We are now parsing a path
|
||
JRST HSTID2] ; Go eat path string
|
||
CAIE B,";" ; Start of comment?
|
||
CAIN B,"!" ; ..
|
||
JRST HSTID3 ; Yes, go gobble it up
|
||
|
||
;Here with a valid character which is an element of a hostname
|
||
CAIN B,.CHLFD ; EOL? (Line Feed)
|
||
JRST HSTID5 ; Yes, quit this line
|
||
CAIN B,"=" ; Start of synonym?
|
||
JRST HSTIDS ; Yes, go handle synonym
|
||
IDPB B,HDST ; Save character
|
||
JRST HSTID2 ; Get next
|
||
|
||
;Here for comment, gobble it up to EOL
|
||
HSTID3: CALL BYTIN ; Eat chars until EOL
|
||
JRST HSTIDE
|
||
CAIN B,.CHLFD ; EOL?
|
||
JRST HSTID5 ; Yes, start interpreting chars again
|
||
JRST HSTID3 ; No, eat more comment
|
||
|
||
;Here on EOL to process this line
|
||
|
||
HSTID5: MOVE A,[POINT 7,ATMBF2] ; Get a virgin pointer
|
||
CAME A,HDST ; Was the pointer touched?
|
||
SKIPN PTHFLG ; Were we parsing a path?
|
||
IFNSK. ; No?
|
||
SKIPE A,PATH ; No, release path block if need be
|
||
CALL RELSB ; ..
|
||
JRST HSTID1 ; Don't put null name in table
|
||
ENDIF.
|
||
MOVEI B,0 ; Yes, add terminating null
|
||
IDPB B,HDST ; ..
|
||
SKIPE PATH ; Was a path string seen?
|
||
IFNSK. ; No?
|
||
CALL CPYAT2 ; Yes, copy to a string block
|
||
JRST HSTIDM ; Memory allocation error
|
||
MOVE D,PATH ; Get addr of hostname string
|
||
MOVEM A,PATH ; Save addr of path string
|
||
MOVE A,[POINT 7,ATMBF2] ; Copy host name string to atom buffer
|
||
MOVE B,D ; Set up for MOVST0
|
||
CALL MOVST0 ; Do the copy
|
||
MOVEM A,HDST ; Set up HDST so ASCIZing doesn't lose
|
||
MOVE A,D ; Get string block address back
|
||
CALL RELSB ; Release it
|
||
ENDIF. ; Rejoin mail line.
|
||
MOVE A,MYHDPT ; Local host name
|
||
HRROI B,ATMBF2 ; This host name
|
||
STCMP ; See if the same
|
||
SKIPN A ; A=0 if name matched
|
||
SKIPA B,[NT%LCL!NT%DCN] ; Local, set flag
|
||
MOVX B,NT%DCN ; Set DECnet flag
|
||
IORB B,FBITS ; Add in any switch-induced bits
|
||
TXNE B,NT%KWL ; Can this host receive 20-style mail?
|
||
JRST HSTID1 ; No, just reuse string block
|
||
HSTID7: MOVE A,[POINT 7,ATMBF2] ; Point to this name
|
||
CALL COUNTS ; Count the characters
|
||
ADDI A,5 ; Allow space for flag bits
|
||
CALL ALCSB ; Allocate a string block
|
||
JRST HSTIDM ; Insufficient memory
|
||
MOVEM B,HSTR ; Save address of string block
|
||
MOVX A,CM%FW ; Light bit that says "dere's flags here!"
|
||
IORM A,(B) ; ..
|
||
MOVEI A,1(B) ; Skip flags word, set up for MOVST0
|
||
HRLI A,(POINT 7,) ; ..
|
||
MOVEI B,ATMBF2 ; Address of name string
|
||
CALL MOVST0 ; Copy name string to string block
|
||
CALL ALCNB ; Allocate node block
|
||
JRST HSTIDM ; Insufficient memory
|
||
MOVE B,FBITS ; Flag bits
|
||
MOVEM B,N.FLGS(A) ; to node block
|
||
MOVE B,PATH ; Path string
|
||
MOVEM B,N.PATH(A) ; to node block
|
||
MOVE B,SSTR ; Addr of node block for real name
|
||
MOVEM B,N.REAL(A) ; to node block
|
||
MOVE B,HSTR ; String address
|
||
MOVEM B,N.NAME(A) ; to node block
|
||
HRLZS B,B ; and to LH for TBADD
|
||
HRR B,A ; Node block address to RH
|
||
MOVE D,B ; Preserve over this stuff
|
||
HLR B,B ; Get string address to RH
|
||
MOVE A,(B) ; Get possible flags word
|
||
TLNN A,(177B6) ; Is this a flags word?
|
||
TXNN A,CM%FW ; ..
|
||
SKIPA
|
||
ADDI B,1 ; Yes, skip the flags and point to string
|
||
HRLI B,(POINT 7,) ; Form kosher byte pointer
|
||
SKIPN A,HOSTAB ; See if already have an entry
|
||
JRST HSTID4 ; No table, so add the entry
|
||
$CALL S%TBLK ; ..
|
||
TXNE B,TL%EXM ; Do we have an entry?
|
||
JRST HSTID6 ; Yes, go link this to it
|
||
HSTID4: MOVE B,D ; No, restore HOSTAB entry
|
||
MOVEI A,HOSTAB ; Host name table
|
||
CALL TBADDS ; Add to table, maybe expanding table
|
||
JRST [ $TEXT(KBFTOR,<%Can't add DECnet node ^T/ATMBF2/ to host table>)
|
||
$TEXT(KBFTOR,<%Because: ^E/A/>)
|
||
CAIN A,ERTBF$ ; Is host table full?
|
||
JRST [WARN<Insufficient Memory>
|
||
RET]
|
||
JRST HSTID1] ; Get next node
|
||
JRST HSTID1 ; Get next
|
||
|
||
;Here if we've found an entry for a host already in the table. Link
|
||
; the node block for this entry to the end of the chain of node blocks
|
||
; for this name.
|
||
|
||
HSTID6: HRRZ C,(A) ; Get pointer to 1st node block
|
||
HSTD6A: SKIPE A,N.NEXT(C) ; Is this the last block in the chain?
|
||
JRST [ MOVE C,A ; No, keep looking
|
||
JRST HSTD6A] ; ..
|
||
HRRZM D,N.NEXT(C) ; Yes, append this block to the chain
|
||
JRST HSTID1 ; Keep parsing
|
||
|
||
;Parse switch
|
||
;Call: A/ JFN of input file
|
||
;Return +1: always, B/ terminating character, A preserved, C trashed
|
||
|
||
HSTIDK: STKVAR <TERM,IJFN,<TSTR,10>> ; Terminating character, JFN, string
|
||
MOVEM A,IJFN ; Save JFN
|
||
MOVEI C,TSTR ; Point to place to stuff switch
|
||
HRLI C,(POINT 7,)
|
||
HSTDK0: CALL BYTIN ; Get a byte
|
||
JRST HSTDK1 ; Let someone else bite it on this one
|
||
CAIG B,172
|
||
CAIGE B,101 ; If not alphabetic,
|
||
JRST [ CAIG B,71 ; And also not numeric
|
||
CAIGE B,60 ; ..
|
||
JRST HSTDK1 ; It terminates this field
|
||
JRST .+2] ; Don't TRZ numbers
|
||
TRZ B,40 ; Uppercase
|
||
IDPB B,C ; Stuff into switch
|
||
JRST HSTDK0 ; Loop thru all chars
|
||
HSTDK1: MOVEM B,TERM ; Save terminator
|
||
SETZ B, ; Insure ASCIZ
|
||
IDPB B,C
|
||
MOVEI B,TSTR ; Point to switch name
|
||
MOVEI A,SWTTAB ; Switch table
|
||
$CALL S%TBLK ; Get the sucker
|
||
JUMPF [ WARN <Internal error at HSTDK1>
|
||
RET]
|
||
TXNN B,TL%EXM!TL%ABR ; Found this switch?
|
||
RET ; Just ignore unknown switches
|
||
HRRZ A,(A) ; Get bits associated with switch
|
||
IORM A,FBITS ; Save for posterity
|
||
MOVE A,IJFN ; Restore A
|
||
MOVE B,TERM ; Return terminator
|
||
RET ; Return
|
||
|
||
;Still in TOPS20
|
||
|
||
;Still in TOPS20
|
||
|
||
;Here to handle synonym -- insure that what it is a synonym for is in the
|
||
; table, add it to table, and point its entry to real thing
|
||
|
||
HSTIDS: MOVEI B,0 ; Tie off this string
|
||
IDPB B,HDST ; ..
|
||
CALL CPYAT2 ; Copy synonym name to string block
|
||
JRST HSTIDM ; Insufficient memory
|
||
MOVEM A,SSTR ; Address of synonym string
|
||
MOVE C,[POINT 7,ATMBF2] ; Where to accumulate "real" name
|
||
|
||
HSTIS0: CALL BYTIN ; Next byte of real name
|
||
JRST HSTIDE
|
||
CAIN B,12 ; EOL?
|
||
JRST HSTIS1 ; Yes...
|
||
IDPB B,C ; No, stuff this char
|
||
JRST HSTIS0 ; Keep going
|
||
HSTIS1: MOVEI B,0 ; Terminate string
|
||
IDPB B,C ; ..
|
||
MOVE A,[POINT 7,ATMBF2] ; Point to the real name again
|
||
CALL VALID8 ; Call the host validation routine
|
||
IFNSK. ; No such host
|
||
HRROI A,ATMBF2 ; for error message
|
||
HRRO B,SSTR
|
||
WARN (UPS:DNHOST.TXT has bad format)
|
||
WARN < %2S=%1S, but %1S is not defined>
|
||
MOVE A,SSTR ; Release synonym string block
|
||
CALL RELSB
|
||
CALLRET HSTIDE ; Just quit now
|
||
ENDIF. ;
|
||
HRRZ A,(B) ; Get real N-block address
|
||
EXCH A,SSTR ; Get addr of synonym name, save real N-blk adr
|
||
MOVE D,A ; Safer AC
|
||
MOVE A,[POINT 7,ATMBF2] ; Copy synonym name to string space
|
||
MOVE B,D ; Set up for MOVST0
|
||
CALL MOVST0 ; Do the copy
|
||
MOVE A,D ; Release SSTR block
|
||
CALL RELSB ; ..
|
||
MOVE A,SSTR ; Get addr of real N-block
|
||
MOVE B,N.FLGS(A) ; Get flag bits for real name
|
||
TXZ B,NT%NXL ; Don't propagate no-translate bit
|
||
TXO B,NT%SYN ; Light synonym bit
|
||
IORM B,FBITS
|
||
HRROI A,[ASCIZ /Interoffice-mail/]
|
||
HRROI B,ATMBF2 ; Point to current synonym
|
||
STCMP ; Does synonym CONTAIN "Interoffice-mail"?
|
||
TXNE A,SC%SUB ; If so, it should never be translated
|
||
JRST [ MOVX A,NT%NXL ; Yes, light no-translate bit
|
||
IORM A,FBITS ; ..
|
||
MOVX A,NT%LCL ; Don't propagate "local" bit
|
||
ANDCAM A,FBITS ; ..
|
||
JRST .+1]
|
||
JRST HSTID7 ; Add to host table
|
||
|
||
;Memory allocation errors all come here
|
||
|
||
HSTIDM: WARN <Can't build host table because: insufficient memory>
|
||
; JRST HSTIDE
|
||
|
||
;Here on OK finish
|
||
|
||
HSTIDE: SETO A, ; Unmap file pages
|
||
HRLI B,.FHSLF ; from fork
|
||
HRR B,HFPGN ; Starting page
|
||
MOVE C,HFPGS ; page count
|
||
TXO C,PM%CNT
|
||
PMAP
|
||
MOVE A,HFPGS ; Release storage too
|
||
MOVE B,HFPGN
|
||
$CALL M%RLNP
|
||
MOVE A,HSTJFN
|
||
CLOSF ; EOF - close file
|
||
JFCL
|
||
RET ; Return
|
||
|
||
;Utility routine to read bytes, ignoring null, LWSP, and CR
|
||
;Return +1: EOF or error, msg already typed if error
|
||
; +2: OK, byte in B, A preserved
|
||
|
||
BYTIN: SOSGE HFCNT ; Any bytes left?
|
||
RET ; No, nonskip return
|
||
ILDB B,HFPTR ; Yes, fetch next
|
||
JUMPE B,BYTIN ; Ignore nulls
|
||
CAIE B," " ; spaces
|
||
CAIN B,.CHCRT ; and CR
|
||
JRST BYTIN
|
||
CAIE B,.CHFFD ; and Form feeds
|
||
CAIN B,.CHTAB ; and tabs
|
||
JRST BYTIN
|
||
RETSKP
|
||
> ; End TOPS20 conditional
|
||
;CPYAT2 - Count the bytes in the string in the atom buffer, allocate
|
||
; a chunk for it, and copy the string into the chunk.
|
||
;Call: no arguments
|
||
;Return +1: failure, no room
|
||
; +2: OK, A has address of first word of string in chunk
|
||
|
||
CPYAT2: STKVAR <STRAD>
|
||
MOVE A,[POINT 7,ATMBF2] ; Count the bytes
|
||
CALL COUNTS ; ..
|
||
CALL ALCSB ; Get a chunk
|
||
RET ; Propagate failure
|
||
MOVEM B,STRAD ; Save string address
|
||
MOVE A,B ; Copy address of string space
|
||
HRLI A,(POINT 7,) ; Form byte pointer
|
||
MOVEI B,ATMBF2 ; Copy from atom buffer to chunk
|
||
CALL MOVST0 ; With the null
|
||
MOVE A,STRAD ; Return string address to caller
|
||
RETSKP ; Success!
|
||
|
||
;HSTIND - Here from HSTINI for TOPS10
|
||
; to get list of all possible hosts
|
||
|
||
TOPS10<
|
||
HSTIND:
|
||
|
||
;See if host name table exists, and add hosts to table if so.
|
||
|
||
TRVAR <FBITS,HSTJFN,HFPTR,HFCNT,HSTR,HDST,SSTR,PATH,REDIFN>
|
||
MOVEI A,FDXSIZ ; Size of file descriptor
|
||
$CALL M%GMEM ; Try to allocate space
|
||
JUMPF HSTERR ; No space??
|
||
HRLZM A,.FDLEN(B) ;
|
||
MOVSI A,(SIXBIT /INI/) ; Structure name
|
||
MOVEM A,.FDSTR(B)
|
||
MOVE A,[SIXBIT /DNHOST/]
|
||
MOVEM A,.FDNAM(B)
|
||
MOVSI A,(SIXBIT /TXT/) ; Extension
|
||
MOVEM A,.FDEXT(B)
|
||
MOVE A,[XWD 5,34]
|
||
MOVEM A,.FDPPN(B)
|
||
MOVE A,B
|
||
CALL ALCFOB
|
||
JRST HSTERR
|
||
MOVX A,FB.LSN ; Don't try to remove sequence numbers
|
||
ANDCAM A,FOB.CW(B) ; ALCFOB set this
|
||
SETZM REDIFN ; No read IFN
|
||
MOVX A,FOB.MZ ; Fake smaller FOB to bypass protection checks
|
||
$CALL F%IOPN ; Open
|
||
JUMPF HSTERR
|
||
MOVEM A,REDIFN ; Remember IFN for reading and releasing
|
||
SETZM HFCNT ; Byte count in file buffer
|
||
SETZM HFPTR ; Byte pointer
|
||
SETZM PATH ; No path block yet
|
||
; JRST HSTID1 ; Enter host parse loop
|
||
|
||
HSTID1: MOVE A,[POINT 7,ATMBF2] ; Where to build host name string
|
||
MOVEM A,HDST ; Init destination pointer
|
||
SETZM FBITS ; No flag bits known yet
|
||
SETZM SSTR ; No synonyms yet
|
||
SETZM PATH ; Init path-seen flag
|
||
HSTID2: CALL BYTIN ; Get a byte
|
||
JRST HSTIDE ; Error or EOF - quit
|
||
CAIN B,"/" ; Check for switches
|
||
CALL HSTIDK ; Go handle
|
||
CAIN B,"," ; Comma? (routing info follows)
|
||
JRST [ SETZ B, ; Insure ASCIZ for name string
|
||
IDPB B,HDST ; ..
|
||
CALL CPYAT2 ; Allocate a string block
|
||
JRST HSTIDM ; Insufficient memory
|
||
MOVEM A,PATH ; Save addr of temp block
|
||
MOVE A,[POINT 7,ATMBF2] ; Reinit atom buffer pointer
|
||
MOVEM A,HDST ; for collection of path string
|
||
JRST HSTID2] ; Go eat path string
|
||
CAIE B,";" ; Start of comment?
|
||
CAIN B,"!" ; ..
|
||
JRST HSTID3 ; Yes, go gobble it up
|
||
|
||
;Here with a valid character which is an element of a hostname
|
||
CAIN B,12 ; EOL?
|
||
JRST HSTID5 ; Yes, quit this line
|
||
CAIN B,"=" ; Start of synonym?
|
||
JRST HSTIDS ; Yes, go handle synonym
|
||
IDPB B,HDST ; Save character
|
||
JRST HSTID2 ; Get next
|
||
|
||
;Here for comment, gobble it up to EOL
|
||
HSTID3: CALL BYTIN ; Eat chars until EOL
|
||
JRST HSTIDE
|
||
CAIN B,12 ; EOL?
|
||
JRST HSTID5 ; Yes, start interpreting chars again
|
||
JRST HSTID3 ; No, eat more comment
|
||
|
||
;Here on EOL to process this line
|
||
|
||
HSTID5: MOVE A,[POINT 7,ATMBF2] ; Get a virgin pointer
|
||
CAMN A,HDST ; Has this pointer been touched?
|
||
JRST [ SKIPE A,PATH ; No, release path block if need be
|
||
CALL RELSB ; ..
|
||
JRST HSTID2] ; Don't put null name in table
|
||
MOVEI B,0 ; Yes, add terminating null
|
||
IDPB B,HDST ; ..
|
||
SKIPE PATH ; Was a path string seen?
|
||
JRST [ CALL CPYAT2 ; Yes, copy to a string block
|
||
JRST HSTIDM ; Memory allocation error
|
||
MOVE D,PATH ; Get addr of hostname string
|
||
MOVEM A,PATH ; Save addr of path string
|
||
MOVE A,[POINT 7,ATMBF2] ; Copy host name string to atom buffer
|
||
MOVE B,D ; Set up for MOVST0
|
||
CALL MOVST0 ; Do the copy
|
||
MOVEM A,HDST ; Set up HDST so ASCIZing doesn't lose
|
||
MOVE A,D ; Get string block address back
|
||
CALL RELSB ; Release it
|
||
JRST .+1] ; Rejoin main flow
|
||
MOVE A,MYHDPT ; Local host name
|
||
HRROI B,ATMBF2 ; This host name
|
||
$CALL S%SCMP ; See if the same
|
||
SKIPN A ; A=0 if name matched
|
||
SKIPA B,[NT%LCL!NT%DCN] ; Local, set flag
|
||
MOVX B,NT%DCN ; Set DECnet flag
|
||
IORB B,FBITS ; Add in any switch-induced bits
|
||
TXNE B,NT%KWL ; Can this host receive 20-style mail?
|
||
JRST HSTID1 ; No, just reuse string block
|
||
HSTID7: MOVE A,[POINT 7,ATMBF2] ; Point to this name
|
||
CALL COUNTS ; Count the characters
|
||
ADDI A,5 ; Allow space for flag bits
|
||
CALL ALCSB ; Allocate a string block
|
||
JRST HSTIDM ; Insufficient memory
|
||
MOVEM B,HSTR ; Save address of string block
|
||
MOVX A,CM%FW ; Light bit that says "dere's flags here!"
|
||
IORM A,(B) ; ..
|
||
MOVEI A,1(B) ; Skip flags word, set up for MOVST0
|
||
HRLI A,(POINT 7,) ; ..
|
||
MOVEI B,ATMBF2 ; Address of name string
|
||
CALL MOVST0 ; Copy name string to string block
|
||
CALL ALCNB ; Allocate node block
|
||
JRST HSTIDM ; Insufficient memory
|
||
MOVE B,FBITS ; Flag bits
|
||
MOVEM B,N.FLGS(A) ; to node block
|
||
MOVE B,PATH ; Path string
|
||
MOVEM B,N.PATH(A) ; to node block
|
||
MOVE B,SSTR ; Addr of node block for real name
|
||
MOVEM B,N.REAL(A) ; to node block
|
||
MOVE B,HSTR ; String address
|
||
MOVEM B,N.NAME(A) ; to node block
|
||
HRLZS B,B ; and to LH for TBADD
|
||
HRR B,A ; Node block address to RH
|
||
MOVE D,B ; Preserve over this stuff
|
||
HLR B,B ; Get string address to RH
|
||
MOVE A,(B) ; Get possible flags word
|
||
TLNN A,(177B6) ; Is this a flags word?
|
||
TXNN A,CM%FW ; ..
|
||
SKIPA
|
||
ADDI B,1 ; Yes, skip the flags and point to string
|
||
HRLI B,(POINT 7,) ; Form kosher byte pointer
|
||
SKIPN A,HOSTAB ; See if already have an entry
|
||
JRST HSTID4 ; No table, so add the entry
|
||
$CALL S%TBLK ; ..
|
||
TXNE B,TL%EXM ; Do we have an entry?
|
||
JRST HSTID6 ; Yes, go link this to it
|
||
HSTID4: MOVE B,D ; No, restore HOSTAB entry
|
||
MOVEI A,HOSTAB ; Host name table
|
||
CALL TBADDS ; Add to table, maybe expanding table
|
||
JRST [ $TEXT(KBFTOR,<%Can't add DECnet node ^T/ATMBF2/ to host table>)
|
||
CAIN A,ERTBF$ ; Is host table full?
|
||
JRST [WARN<Insufficient Memory>
|
||
RET]
|
||
JRST HSTID1] ; Get next node
|
||
JRST HSTID1 ; Get next
|
||
|
||
;Here if we've found an entry for a host already in the table. Link
|
||
; the node block for this entry to the end of the chain of node blocks
|
||
; for this name.
|
||
|
||
HSTID6: HRRZ C,(A) ; Get pointer to 1st node block
|
||
HSTD6A: SKIPE A,N.NEXT(C) ; Is this the last block in the chain?
|
||
JRST [ MOVE C,A ; No, keep looking
|
||
JRST HSTD6A] ; ..
|
||
HRRZM D,N.NEXT(C) ; Yes, append this block to the chain
|
||
JRST HSTID1 ; Keep parsing
|
||
|
||
;Parse switch
|
||
;Call: A/ JFN of input file
|
||
;Return +1: always, B/ terminating character, A preserved, C trashed
|
||
|
||
HSTIDK: STKVAR <TERM,IJFN,<TSTR,10>> ; Terminating character, JFN, string
|
||
MOVEM A,IJFN ; Save JFN
|
||
MOVEI C,TSTR ; Point to place to stuff switch
|
||
HRLI C,(POINT 7,)
|
||
HSTDK0: CALL BYTIN ; Get a byte
|
||
JRST HSTDK1 ; Let someone else bite it on this one
|
||
CAIG B,172
|
||
CAIGE B,101 ; If not alphabetic,
|
||
JRST [ CAIG B,71 ; And also not numeric
|
||
CAIGE B,60 ; ..
|
||
JRST HSTDK1 ; It terminates this field
|
||
JRST .+2] ; Don't TRZ numbers
|
||
TRZ B,40 ; Uppercase
|
||
IDPB B,C ; Stuff into switch
|
||
JRST HSTDK0 ; Loop thru all chars
|
||
HSTDK1: MOVEM B,TERM ; Save terminator
|
||
SETZ B, ; Insure ASCIZ
|
||
IDPB B,C
|
||
MOVEI B,TSTR ; Point to switch name
|
||
MOVEI A,SWTTAB ; Switch table
|
||
$CALL S%TBLK ; Get the sucker
|
||
JUMPF [ WARN <Internal error at HSTDK1>
|
||
RET]
|
||
TXNN B,TL%EXM!TL%ABR ; Found this switch?
|
||
RET ; Just ignore unknown switches
|
||
HRRZ A,(A) ; Get bits associated with switch
|
||
IORM A,FBITS ; Save for posterity
|
||
MOVE A,IJFN ; Restore A
|
||
MOVE B,TERM ; Return terminator
|
||
RET ; Return
|
||
|
||
;Still in TOPS10
|
||
|
||
;Still in TOPS10
|
||
|
||
;Here to handle synonym -- insure that what it is a synonym for is in the
|
||
; table, add it to table, and point its entry to real thing
|
||
|
||
HSTIDS: MOVEI B,0 ; Tie off this string
|
||
IDPB B,HDST ; ..
|
||
CALL CPYAT2 ; Copy synonym name to string block
|
||
JRST HSTIDM ; Insufficient memory
|
||
MOVEM A,SSTR ; Address of synonym string
|
||
MOVE C,[POINT 7,ATMBF2] ; Where to accumulate "real" name
|
||
|
||
HSTIS0: CALL BYTIN ; Next byte of real name
|
||
JRST HSTIDE
|
||
CAIN B,12 ; EOL?
|
||
JRST HSTIS1 ; Yes...
|
||
IDPB B,C ; No, stuff this char
|
||
JRST HSTIS0 ; Keep going
|
||
HSTIS1: MOVEI B,0 ; Terminate string
|
||
IDPB B,C ; ..
|
||
MOVE A,HOSTAB ; Point to host name table
|
||
MOVE B,[POINT 7,ATMBF2] ; Look up this entry
|
||
$CALL S%TBLK ; Better exist
|
||
TXNN B,TL%EXM ; Does it?
|
||
JRST [ HRROI A,ATMBF2 ; for error message
|
||
HRRO B,SSTR
|
||
WARN (SYS:HOSTS.TXT has bad format)
|
||
WARN < %2S=%1S, but %1S is not defined>
|
||
MOVE A,SSTR ; Release synonym string block
|
||
CALL RELSB
|
||
CALLRET HSTIDE] ; Just quit now
|
||
HRRZ A,(A) ; Get real N-block address
|
||
EXCH A,SSTR ; Get addr of synonym name, save real N-blk adr
|
||
MOVE D,A ; Safer AC
|
||
MOVE A,[POINT 7,ATMBF2] ; Copy synonym name to string space
|
||
MOVE B,D ; Set up for MOVST0
|
||
CALL MOVST0 ; Do the copy
|
||
MOVE A,D ; Release SSTR block
|
||
CALL RELSB ; ..
|
||
MOVE A,SSTR ; Get addr of real N-block
|
||
MOVE B,N.FLGS(A) ; Get flag bits for real name
|
||
TXZ B,NT%NXL ; Don't propagate no-translate bit
|
||
TXO B,NT%SYN ; Light synonym bit
|
||
IORM B,FBITS
|
||
; HRROI A,[ASCIZ /Interoffice-mail/]
|
||
; HRROI B,ATMBF2 ; Point to current synonym
|
||
; STCMP ; Does synonym CONTAIN "Interoffice-mail"?
|
||
; TXNE A,SC%SUB ; If so, it should never be translated
|
||
; JRST [ MOVX A,NT%NXL ; Yes, light no-translate bit
|
||
; IORM A,FBITS ; ..
|
||
; MOVX A,NT%LCL ; Don't propagate "local" bit
|
||
; ANDCAM A,FBITS ; ..
|
||
; JRST .+1]
|
||
JRST HSTID7 ; Add to host table
|
||
|
||
;Memory allocation errors all come here
|
||
|
||
HSTIDM: WARN <Can't build host table because: insufficient memory>
|
||
; JRST HSTIDE
|
||
|
||
;Here on OK finish
|
||
|
||
HSTIDE: MOVE A,REDIFN ; Get file IFN
|
||
$CALL F%REL ; Done, close file
|
||
JFCL
|
||
SETZM REDIFN
|
||
HSTERR: RET ; Return
|
||
|
||
;Utility routine to read bytes, ignoring null, LWSP, and CR
|
||
;Return +1: EOF or error, msg already typed if error
|
||
; +2: OK, byte in B, A preserved
|
||
|
||
BYTIN: SOSGE HFCNT ; Any bytes left?
|
||
JRST RDBUF ; Try for more
|
||
ILDB B,HFPTR ; Yes, fetch next
|
||
JUMPE B,BYTIN ; Ignore nulls
|
||
CAIE B," " ; spaces
|
||
CAIN B,15 ; and CR
|
||
JRST BYTIN
|
||
CAIN B,11 ; Ignore tabs
|
||
JRST BYTIN
|
||
RETSKP
|
||
|
||
RDBUF: MOVE A,REDIFN ; Get the IFN for this file
|
||
$CALL F%IBUF ; Try to get a buffer
|
||
JUMPF RDONE
|
||
MOVEM A,HFCNT ; Save byte count
|
||
MOVEM B,HFPTR ; and pointer
|
||
JRST BYTIN
|
||
RDONE: RET
|
||
|
||
repeat 0,<
|
||
NODUUO: STKVAR <NBLK,SBLK,NPAG> ; Node block addr, Node name string block
|
||
; And NODE. UUO block address
|
||
$CALL M%GPAG ; Get a free page
|
||
MOVEM A,NPAG ; Save address for later
|
||
MOVE E,A ; Copy block address
|
||
HRLI E,.NDLND ; Insert NODE. function to list nodes
|
||
MOVEI B,1000 ; Length of block
|
||
MOVEM B,(A) ; Set for UUO
|
||
NODE. E, ; Return list of reachable nodes
|
||
JRST NODUUX ; There are no ANF-10 nodes
|
||
MOVNS E ; Get negative node count
|
||
MOVSS E ; Form into left half for AOBJN
|
||
HRRI E,1(A) ; Point to first node in list
|
||
NODUU0: MOVE C,(E) ; Get next node number to convert
|
||
MOVEI B,2 ; Number of words in block
|
||
MOVE A,[.NDRNN,,B] ; Set up for node uuo
|
||
NODE. A, ; Convert node number to name
|
||
JRST NODUU3 ; Node went off-line
|
||
MOVE B,A ; Get SIXBIT into better AC
|
||
MOVE C,[POINT 7,NODNAM]; Where to put ASCII name
|
||
NODUU1: SETZ A,
|
||
LSHC A,6 ; Get SIXBIT character in A
|
||
ADDI A,40 ; Make ASCII
|
||
IDPB A,C ; Stuff into name
|
||
JUMPN B,NODUU1 ; Do all chars
|
||
IDPB B,C ; Insure ASCIZ
|
||
MOVE A,[POINT 7,NODNAM]
|
||
CALL COUNTS ; Count the bytes in it
|
||
ADDI A,5 ; Account for flag word
|
||
CALL ALCSB ; Get a string block for it
|
||
JRST [ WARN <Can't get string block for local node names>
|
||
JRST NODUUM]
|
||
MOVEM B,SBLK ; Save address of string block
|
||
MOVX A,CM%FW ; There are flags in first word of block
|
||
IORM A,(B) ;
|
||
MOVEI A,1(B) ; Set up for MOVST2
|
||
HRLI A,(POINT 7,) ; Byte pointer
|
||
MOVE B,[POINT 7,NODNAM] ; Pointer to name
|
||
CALL MOVST2 ; Copy to new block
|
||
CALL ALCNB
|
||
JRST [ WARN <Can't get node block for local nodes>
|
||
JRST NODUUM]
|
||
MOVEM A,NBLK ; Save address of node block
|
||
MOVE A,[POINT 7,NODNAM] ; Name of node we are processing
|
||
MOVE B,MYHSPT ; Name of our host
|
||
$CALL S%SCMP ; See if this name matches local node name
|
||
MOVX B,NT%DCN!NT%NM0 ; DECNET node, name in heap space
|
||
SKIPN A ; A = 0 if name matched
|
||
TXO B,NT%LCL ; Match, this is the local node
|
||
MOVE A,NBLK ; Point to node block
|
||
MOVEM B,N.FLGS(A) ; Stuff flags into N-block
|
||
MOVE B,SBLK ; Get string block address
|
||
MOVEM B,N.NAME(A) ; and save pointer in node block
|
||
HRLZS B,B ; Set up for TBADDS with LH=string pointer
|
||
HRR B,A ; and right half in node block pointer
|
||
MOVEI A,HOSTAB ; Addr of ptr to host table
|
||
CALL TBADDS ; Load 'em on up!
|
||
JRST [$TEXT(KBFTOR,<%Can't add ANF node ^T/NODNAM/ to host table.>)
|
||
CAIN A,EREIT$ ; Is node already in table?
|
||
JRST NODUU3 ; Try the next node
|
||
JRST NODUUM] ; No more room
|
||
NODUU3: AOBJN E,NODUU0 ; Loop through all blocks we got
|
||
JRST NODUUX ; Finish up
|
||
|
||
NODUUM: WARN <Insufficient memory>
|
||
NODUUX: MOVE A,NPAG ; Get node block address back again
|
||
$CALL M%RPAG ; Return the page to the free pool
|
||
RET
|
||
|
||
>;End TOPS10
|
||
>; end repeat 0
|
||
|
||
;ALCNB - Allocate a node block
|
||
;Call: no arguments
|
||
;Return +1: failure, no memory
|
||
; +2: success, A/ address of Node Block (N.SIZE inited)
|
||
|
||
ALCNB: MOVEI A,N.LEN ; Length of a node block
|
||
$CALL M%GMEM ; Get a chunk
|
||
JUMPF R ; Error, nonskip return
|
||
MOVEM A,N.SIZE(B) ;
|
||
MOVE A,B ; Return addr of block in A for caller
|
||
RETSKP ; Good return
|
||
|
||
;RELNB - Release a node block
|
||
;Call: A/ address of node block
|
||
;Return +1: always
|
||
|
||
RELNB: MOVE B,A ; Set up for M%RMEM
|
||
MOVEI A,N.LEN ; Length of a node block
|
||
$CALL M%RMEM
|
||
RET
|
||
|
||
END
|
||
|
||
; Edit 2462 to MSHOST.MAC by PRATT on 1-Nov-85
|
||
; Merge many changes in -10, -20, and common code.
|
||
; *** Edit 2479 to MSHOST.MAC by PRATT on 20-Nov-85
|
||
; Fix off by one bug in VALID8 that kept Arpa mail from working
|
||
|
||
|
||
; *** Edit 2484 to MSHOST.MAC by SANTEE on 21-Nov-85
|
||
; Clean up the various edit histories.
|
||
; *** Edit 2485 to MSHOST.MAC by MAYO on 21-Nov-85
|
||
;
|
||
; *** Edit 2486 to MSHOST.MAC by PRATT on 22-Nov-85
|
||
; Copyright statements
|
||
|
||
; *** Edit 2651 to MSHOST.MAC by SANTEE on 2-Feb-86
|
||
; Eliminate the need for MSUTAB at all. Move the few useful lines elsewhere.
|
||
; *** Edit 2700 to MSHOST.MAC by RASPUZZI on 20-May-86
|
||
; Change MS to look for UPS:DNHOST.TXT instead of SYSTEM:DECNET-HOSTS.TXT
|
||
; Edit= 3105 to MSHOST.MAC on 17-May-88 by WADDINGTON, for SPR #21402
|
||
;Use the CNFIG% JSYS instead of relying on the NODE% jsys failure to determine
|
||
;if DECnet exists.
|