1
0
mirror of https://github.com/PDP-10/stacken.git synced 2026-03-04 18:33:52 +00:00
Files
Lars Brinkhoff 6e18f5ebef Extract files from tape images.
Some tapes could not be extracted.
2021-01-29 10:47:33 +01:00

1190 lines
39 KiB
Plaintext
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
;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.