perm filename HOSTS3.DIF[HST,NET] blob sn#826025 filedate 1986-10-07 generic text, type T, neo UTF8
  1) HOSTS3.NIC[HST,NET] and 2) HOSTS3.MID[HST,NET]	10-07-86 09:19	pages 3,3

**** File 1) HOSTS3.NIC[HST,NET]/3P/20L
1)		SAIL:	HOSTS.TXT[HST,NET]	HOSTS3.BIN[HST,NET]	(or HOSTS2)
**** File 2) HOSTS3.MID[HST,NET]/3P/19L
2)		SAIL:	HOSTS.TXT[HST,NET]	HOSTS3.TMP[HST,NET]	(or HOSTS2)
***************


**** File 1) HOSTS3.NIC[HST,NET]/9P/32L
**** File 2) HOSTS3.MID[HST,NET]/9P/31L
2)	IFNDEF LCASE,LCASE==-1		; -1 to allow lower case in output
***************


**** File 1) HOSTS3.NIC[HST,NET]/10P/12L
1)		HSTTAB=:400000	; This must *NOT* change!!
**** File 2) HOSTS3.MID[HST,NET]/10P/11L
2)	;;	HSTTAB=:400000	; This must *NOT* change!!
2)	;Well, it has to.  Now that the internal tables have grown too large, we
2)	;run HOSTS3 as a single-segment program with the tables starting at 12000.
2)	;This gives enough room for I/O buffers, although there is no check to see
2)	;if JOBFF exceeds 12000 when they are allocated.
2)		HSTTAB=:12000	; This is about as low as we can go
***************


**** File 1) HOSTS3.NIC[HST,NET]/12P/4L
1)	HTSIZE==:31			; Number of K for internal host table
1)	NTSIZE==:2			; Number of K for internal network table
1)	STSIZE==:214			; Number of K for internal strings
1)	OFSIZE==:121			; Number of K for output file image
1)	UPSIZE==:HTSIZE+NTSIZE+STSIZE+OFSIZE	; Number of K for all allocated mem
1)					
1)	IFNDEF HSTTAB,HSTTAB=020000	; Location of internal host entry table
**** File 2) HOSTS3.MID[HST,NET]/12P/3L
2)	HTSIZE==:45			; Number of K for internal host table
2)	NTSIZE==:2			; Number of K for internal network table
2)	STSIZE==:166			; Number of K for internal strings
2)	OFSIZE==:135			; Number of K for output file image
2)	UPSIZE==:HTSIZE+NTSIZE+STSIZE+OFSIZE	; Number of K for all allocated mem
2)					
2)	IFNDEF HSTTAB,HSTTAB=100000	; Location of internal host entry table
***************


**** File 1) HOSTS3.NIC[HST,NET]/12P/15L
1)	OUTEND=<OUTTAB+2000*OFSIZE>-1	; Last word of internal buffers and junk
**** File 2) HOSTS3.MID[HST,NET]/12P/14L
2)	OUTEND=OUTTAB+2000*OFSIZE	; Last word of internal buffers and junk
***************


**** File 1) HOSTS3.NIC[HST,NET]/12P/21L
1)	LPDL==100
**** File 2) HOSTS3.MID[HST,NET]/12P/20L
2)	IFE SAILSW,[
2)	LPDL==100
2)	];IFE SAILSW
2)	IFN SAILSW,[
2)	LPDL==200			; Need more for SRTNAM
2)	];IFN SAILSW
***************


**** File 1) HOSTS3.NIC[HST,NET]/12P/170L
**** File 2) HOSTS3.MID[HST,NET]/12P/174L
2)	IFE SAILSW,[
***************


**** File 1) HOSTS3.NIC[HST,NET]/12P/187L
**** File 2) HOSTS3.MID[HST,NET]/12P/191L
2)	];IFE SAILSW
2)	IFN SAILSW,[		; Show progress as we go
2)	HSTPRC:	OUTSTR [ASCIZ/ MRGNET
2)	/]
2)		CALL MRGNET	; Flush duplicate network entries if any
2)		OUTSTR [ASCIZ/ ADDNET
2)	/]
2)		CALL ADDNET	; Add network entries if some are missing.
2)		OUTSTR [ASCIZ/ CANON
2)	/]
2)		CALL CANON	; Canonicalize strings to save space
2)		OUTSTR [ASCIZ/ MERGE
2)	/]
2)		CALL MERGE	; Combine entries with same official name (or complain)
2)		OUTSTR [ASCIZ/ MACH
2)	/]
2)		CALL MACH	; Figure out machine names for entries lacking them.
2)		OUTSTR [ASCIZ/ FLGSET
2)	/]
2)		CALL FLGSET	; Figure out flags for entries (mainly "server")
2)		OUTSTR [ASCIZ/ TABSET
2)	/]
2)		CALL TABSET	; Set up allocations for all output tables
2)		OUTSTR [ASCIZ/ BNT
2)	/]
2)		CALL BNT	; Build sorted NETWORK table
2)		OUTSTR [ASCIZ/ BNTNAM
2)	/]
2)		CALL BNTNAM	; Build sorted NETNAME table
2)		OUTSTR [ASCIZ/ BAT
2)	/]
2)		CALL BAT	; Build sorted ADDRESS tables
2)		OUTSTR [ASCIZ/ MT
2)	/]
2)		CALL MT		; Build the SITE table (not sorted), finish ADDRESSes.
2)		OUTSTR [ASCIZ/ MNAM
2)	/]
2)		CALL MNAM	; Build NAMES table
2)		OUTSTR [ASCIZ/ SRTNAM
2)	/]
2)		CALL SRTNAM	; Sort the NAMES table
2)		TLNE F,FL%2OU	; If we want to output a HOSTS2 format table,
2)		 CALL H2OFIX	; Go fix up host and net addresses, etc.
2)		RET
2)	];IFN SAILSW
***************


**** File 1) HOSTS3.NIC[HST,NET]/15P/15L
1)		CORE2 A,			; Make us an upper (NOTE: If pgm
1)		 ERROR "CORE2 failed",EVLAST	; moved to Tops-10 this needs fixing!)
**** File 2) HOSTS3.MID[HST,NET]/15P/14L
2)	;;	CORE2 A,			; Make us an upper (NOTE: If pgm
2)	;;	 ERROR "CORE2 failed",EVLAST	; moved to Tops-10 this needs fixing!)
2)		CORE A,				; Get more core in the lower segment
2)		 ERROR "CORE UUO failed",EVLAST	
***************


**** File 1) HOSTS3.NIC[HST,NET]/16P/53L
1)		CAME T3,(TT)
1)		 JRST APOPJ
**** File 2) HOSTS3.MID[HST,NET]/16P/52L
2)	IFE LCASE,[
2)		CAME T3,(TT)
2)		 JRST APOPJ
2)	];IFE LCASE
2)	IFN LCASE,[
2)		XOR T3,(TT)
2)		TDNE T3,[576773,,757677]
2)		 JRST APOPJ
2)		XOR T3,(TT)
2)	];IFN LCASE
***************


**** File 1) HOSTS3.NIC[HST,NET]/18P/84L
**** File 2) HOSTS3.MID[HST,NET]/18P/83L
2)	IFE SAILSW,[
***************


**** File 1) HOSTS3.NIC[HST,NET]/18P/114L
1)		; Whew, all done!  OUTPT points to 1st free fileaddr.
1)		RET
**** File 2) HOSTS3.MID[HST,NET]/18P/113L
2)	];IFE SAILSW
2)	IFN SAILSW,[
2)		; All strings now entered into the internal sort-string table.
2)		; Do an inorder tree traversal, storing each string into output
2)		; file space ("intern" it) and update all pointers which point
2)		; to that string.
2)	CAN50:	MOVEI T,STREND-2	; Start at root
2)		CALL CAN60		; Do it
2)	];IFN SAILSW
2)		; Whew, all done!  OUTPT points to 1st free fileaddr.
2)		RET
2)	IFN SAILSW,[
2)		; Visit tree node at T, by first visiting left child, then
2)		; interning T's string, then visiting right child.
2)	CAN60:	JUMPE T,APOPJ		; Easy case
2)		PUSH P,T
2)		HLRZ T,1(T)		; Get left child
2)		CALL CAN60		; Visit it
2)		POP P,T
2)		MOVE E,(T)		; Point to string
2)		MOVEI B,(E)
2)		; Copy string
2)		MOVE C,OUTPT		; Get current ptr
2)	CAN53:	MOVE A,(B)
2)		MOVEM A,(C)
2)		ADDI C,1		; Always bump output ptr
2)		TRNE A,376		; Copy until hit end
2)		 AOJA B,CAN53
2)		CAIL C,OUTEND
2)		 ERROR "Output file alloc too small, increase OFSIZE"
2)		EXCH C,OUTPT		; Update output ptr, and get back original val
2)	CAN55:	HLRZ A,E		; Find addr of first ptr to update
2)	CAN56:	HRRZ D,(A)		; Next ptr in chain is stored here
2)		HRRM C,(A)		; Store address of copied string!
2)		MOVEI A,(D)		; Advance to next ptr in chain
2)		JUMPN A,CAN56		; Continue until end of chain
2)		HRRZ T,1(T)		; Get right child
2)		JRST CAN60		; Visit it
2)	];IFN SAILSW
2)	IFE SAILSW,[			;Old version
***************


**** File 1) HOSTS3.NIC[HST,NET]/20P/2L
**** File 2) HOSTS3.MID[HST,NET]/19P/146L
2)	];IFE SAILSW
2)	IFN SAILSW,[			;This is the new version
2)	; ADDSTR - Adds ASCIZ string to internal sorted table of strings.
2)	;	  This table is kept as a binary tree for efficient sorting and
2)	;	searching.  It grows upwards from STREND (note strings themselves
2)	;	are stored downward from STRTAB during parsing).  For guaranteed
2)	;	efficiency, the tree should be kept balanced, but we assume that
2)	;	the input is fairly random.
2)	;	  Note this table is internal; it is not part of the output file.
2)	;	  Entries in this table are two words each, as follows:
2)	;	word n:	<addr of ARH>,,<addr of ASCIZ>	; RH is RH(c(addr))
2)	;	   n+1: <left child>,,<right child>
2)	;	  When a new string is found, a table entry is created for it.
2)	;	At the same time, the pointer to the string in the original word
2)	;	is set to 0, to begin a chain of pointers to the same string.
2)	;	  When a string is identical to one already in the table, no new
2)	;	entry is made, but the right half of the word pointing to it is
2)	;	chained to the previous word(s) pointing to the same string.
2)	; Takes
2)	;	A/ <address of ARH>	; ARH is a word with RH pointing to ASCIZ
2)	; Clobbers A, T, TT.
2)	ADDSTR:	HRLI A,(A)		; Copy RH into LH
2)		JUMPE A,APOPJ		; Ensure valid address
2)		SKIPE T,(A)		; Get the word
2)		 TRNN T,-1		; Ensure valid ASCIZ address
2)		  RET			; Null addr or no string, ignore.
2)		HLLZS (A)		; Zero right half of ARH word
2)		HRRI A,(T)		; Now have new table entry word.
2)		MOVEI T,STREND-2	; Point to end of table (root of tree)
2)		SKIPN ISTRP		; See if this is the first time through
2)		 JRST [	MOVEM T,ISTRP	; Initialize pointer and table.
2)			MOVEM A,(T)
2)			SETZM 1(T)	; No children yet.
2)			RET]
2)		PUSH P,B
2)		PUSH P,C
2)		PUSH P,D
2)		PUSH P,A
2)		; Start search with T pointing to root
2)	ASTR33:	MOVEI TT,(T)		; Save pointer to current entry
2)		; Compare strings at sample point
2)		MOVE A,(P)		; Set up A -> new string
2)		HRRZ T,(TT)		; Set up T -> table string
2)	ASTR35:	SKIPL B,(A)		; Get word of new string
2)		 JRST [	SKIPL C,(T)
2)			 JRST ASTR37	; Both positive, do compare.
2)			JRST ASTR32]	; Table string is greater, hunt lower.
2)		SKIPL C,(T)		; Get word of table string
2)		 JRST ASTR31		; New string greater, hunt higher.
2)		; Sign bit same in both words, must do a compare.
2)	ASTR37:
2)	IFN LCASE,[
2)		TDZ B,[201004,,020100]	; Map lower case letters to upper case (also
2)		TDZ C,[201004,,020100]	; maps other chars, though unlikely to matter)
2)	];IFN LCASE
2)		CAMLE B,C
2)		 JRST ASTR31		; New str greater than table, go higher.
2)		CAMGE B,C
2)		 JRST ASTR32		; New str less, must hunt lower now!
2)		TRNN B,377		; Words equal!  See if last word
2)		 JRST [	; Strings completely equal.  Add this ptr to the
2)			; chain for this string, to canonize.
2)			HLRZ B,(TT)	; Current head of ptr chain
2)			POP P,A		; <addr of ptr>,,<addr of string>
2)			HLRZ A,A	; Addr of new pointer
2)			HRRM B,(A)	; Link into head of chain
2)			HRLM A,(TT)	; Make this new head of chain
2)			JRST ASTR40]
2)		ADDI A,1
2)		AOJA T,ASTR35		; Go test next word.
2)	;Search higher from current entry.
2)	ASTR31:	HRRZ T,1(TT)		; Get right child
2)		JUMPN T,ASTR33		; Continue search if there is one
2)		CALL ASTR50		; Make a new entry
2)		HRRM B,1(TT)		; Make it the right child
2)		POP P,(B)		; Store entry word
2)		JRST ASTR40		; Return
2)	;Search lower from current entry.
2)	ASTR32:	HLRZ T,1(TT)		; Get left child
2)		JUMPN T,ASTR33		; Continue search if there is one
2)		CALL ASTR50		; Make a new entry
2)		HRLM B,1(TT)		; Make it the left child
2)		POP P,(B)		; Store entry word
2)	ASTR40:	POP P,D
2)		POP P,C
2)		POP P,B
2)		RET
2)	;Allocate space for a new entry, return addr in B.
2)	ASTR50:	SOS ISTRP		; Skip word for child ptrs
2)		SOS B,ISTRP		; Get new start of table
2)		HRRZ C,TOKBP		; Check to avoid collision with strings
2)		CAIG B,1(C)		; Check overlap!
2)		 ERROR "String table alloc too small, increase STSIZE"
2)		SETZM 1(B)		; Zero child ptrs, no children yet
2)		RET
2)	];IFN SAILSW
***************


**** File 1) HOSTS3.NIC[HST,NET]/21P/7L
**** File 2) HOSTS3.MID[HST,NET]/22P/5L
2)	IFN SAILSW,[
2)		;The above comment doesn't apply to us.
2)	];IFN SAILSW
***************


**** File 1) HOSTS3.NIC[HST,NET]/21P/11L
**** File 2) HOSTS3.MID[HST,NET]/22P/12L
2)	IFN SAILSW,[
2)		;Skip entry if no Stanford address, since all merge entries have
2)		;them only.  This saves a lot of time in the merge.
2)		CALL STANCK		; Check for Stanford address
2)		 JRST MRG80		; Has none, don't check further
2)	];IFN SAILSW
***************


**** File 1) HOSTS3.NIC[HST,NET]/21P/17L
**** File 2) HOSTS3.MID[HST,NET]/22P/25L
2)	IFN SAILSW,[
2)		; Try to match entries for hosts in both the NIC and PUP tables.
2)		; This is basically a kludge until we get a Stanford IP host table,
2)		; or domain name servers make this whole business obsolete.
2)	IFN 0,[			; This no longer works with domain names
2)		; See if any nickname of G matches the primary name of H.  If so,
2)		; make that nickname the primary name of G and treat it as a match.
2)		MOVEI D,HSTNIC(G)	; Get first nickname list entry
2)		JRST MRG23
2)	MRG22:	HLRZ D,C		; Get next list entry
2)	MRG23:	SKIPN C,(D)		; Get nickname
2)		 JRST MRG25		; End of list, no nicknames match
2)		CAIE A,(C)		; Compare RH
2)		 JRST MRG22		; No match, continue
2)		HRRM A,HSTNAM(G)	; Switch this nickname with the hostname
2)		HRRM B,(D)
2)		JRST MRG30		; Go report a match
2)	];IFN 0
2)	IFN 1,[
2)		; Check for address overlap.
2)		TLNE B,HE%MRG		; Is G a merge entry?
2)		 CALL MRGHST		; Yes, check for address overlap
2)		  JRST MRG25		; Not a merge entry or no overlap
2)		; We already know the primary names of H and G don't match.
2)		; Since we want to keep the primary name of G in the table,
2)		; we make it a nickname of G and then merge as usual.  (In
2)		; most cases, it is already a nickname of H.)  To do this,
2)		; we need a word for the nickname entry.  Fortunately, we
2)		; can use the word containing the duplicate address.
2)		MOVE D,(T)		; Save word being freed
2)		HRRM E,(T)		; Flush duplicate address
2)		HRRZ A,HSTNAM(G)	; Get ptr to name of G
2)		HRLI A,(D)		; Make nickname entry
2)		EXCH A,HSTNIC(G)	; Save it as first nickname
2)		MOVEM A,(D)		; And store previous
2)		AOS NNAMS		; Since primary names DON'T match
2)		JRST MRG40		; Go finish the merge
2)	];IFN 1
2)	];IFN SAILSW
***************


**** File 1) HOSTS3.NIC[HST,NET]/21P/32L
1)	MRG30:	SETZ C,			; Clear flag
**** File 2) HOSTS3.MID[HST,NET]/22P/79L
2)	MRG30:
2)	IFE SAILSW,[
2)		SETZ C,			; Clear flag
***************


**** File 1) HOSTS3.NIC[HST,NET]/21P/40L
**** File 2) HOSTS3.MID[HST,NET]/22P/88L
2)	];IFE SAILSW
***************


**** File 1) HOSTS3.NIC[HST,NET]/22P/2L
**** File 2) HOSTS3.MID[HST,NET]/22P/259L
2)	IFN SAILSW,[
2)	;Skip if host in H has a Stanford address.
2)	STANCK:	SKIPN D,HSTNUM(H)	; Get addr list
2)		 RET
2)	STANC1:	TRNN D,-1		; If no RH ptr to next,
2)		 RET			; Done.
2)		MOVE D,(D)		; Get next
2)		HLRZ B,D
2)		MOVE B,(B)		; Get a host addr
2)		LDB A,[NT$NUM,,B]	; Get network number
2)		CAIE A,36.		; Stanford's net?
2)		JRST STANC1		; No, keep looking
2)		JRST POPJ1		; Yes, skip return
2)	];IFN SAILSW
***************


**** File 1) HOSTS3.NIC[HST,NET]/22P/29L
**** File 2) HOSTS3.MID[HST,NET]/23P/28L
2)	IFE SAILSW,[
***************


**** File 1) HOSTS3.NIC[HST,NET]/22P/32L
**** File 2) HOSTS3.MID[HST,NET]/23P/32L
2)	];IFE SAILSW
2)	IFN SAILSW,[			;Let's not be so presumptuous about Unix
2)		CAMN B,ELF
2)		 MOVE C,PDP11
2)	];IFN SAILSW
***************


**** File 1) HOSTS3.NIC[HST,NET]/26P/84L
**** File 2) HOSTS3.MID[HST,NET]/27P/83L
2)	IFE SAILSW,[
***************


**** File 1) HOSTS3.NIC[HST,NET]/26P/87L
**** File 2) HOSTS3.MID[HST,NET]/27P/87L
2)	];IFE SAILSW
2)	IFN SAILSW,[			;We get too many of these
2)		 JRST [	AOS ERRDGA	;Just count them
2)			POP P,B
2)			RET]
2)	];IFN SAILSW
***************


**** File 1) HOSTS3.NIC[HST,NET]/27P/54L
1)		HRRZ B,STRADR(A)	; CONS onto existing STRADR
1)		HRRM B,ADRCDR(E)	; Threaded through ADRCDR
**** File 2) HOSTS3.MID[HST,NET]/28P/53L
2)	IFE SAILSW,[
2)		HRRZ B,STRADR(A)	; CONS onto existing STRADR
2)		HRRM B,ADRCDR(E)	; Threaded through ADRCDR
2)	];IFE SAILSW
2)	IFN SAILSW,[
2)		CALL PRIADR		; Use priorities to insert address
2)	];IFN SAILSW
***************


**** File 1) HOSTS3.NIC[HST,NET]/27P/63L
**** File 2) HOSTS3.MID[HST,NET]/28P/67L
2)	IFE SAILSW,[
***************


**** File 1) HOSTS3.NIC[HST,NET]/27P/67L
**** File 2) HOSTS3.MID[HST,NET]/28P/72L
2)	];IFE SAILSW
***************


**** File 1) HOSTS3.NIC[HST,NET]/29P/2L
**** File 2) HOSTS3.MID[HST,NET]/29P/62L
2)	IFN SAILSW,[
2)	; PRIADR - Insert current ADDRESS entry in list according to priorities
2)	;	A/ ptr to SITE table entry
2)	;	D/ network address for current ADDRESS entry
2)	;	E/ ptr to ADDRESS table entry
2)	; Alters STRADR(A) and ADRCDR fields on list as necessary.
2)	; Clobbers B, D, T, TT
2)	PRIADR:	HRRZ B,STRADR(A)	;See if there's a list yet
2)		JUMPN B,PRIAD1		;Jump if there is
2)		HRRM B,ADRCDR(E)	;If no list, it's easy
2)		MOVEI B,(E)
2)		SUBI B,(FA)
2)		HRRM B,STRADR(A)
2)		RET
2)	PRIAD1:	MOVEI B,STRADR-ADRCDR(A) ;Set up for loop
2)		PUSH P,A		;Get some ACs
2)		PUSH P,C
2)		MOVE T,D
2)		CALL PRIORI		;Get priority for address in D
2)		MOVE D,T		;Save it in D
2)	PRIAD2:	HRRZ C,ADRCDR(B)	;Get next ADDRESS entry
2)		JUMPN C,PRIAD4		;Jump if there is one
2)		;Insert new ADDRESS entry after entry pointed to by B
2)	PRIAD3:	MOVEI T,(E)		;Get fileaddr
2)		SUBI T,(FA)
2)		HRRM T,ADRCDR(B)	;Insert in list
2)		POP P,C
2)		POP P,A
2)		RET
2)	PRIAD4:	ADDI C,(FA)		;Make absolute
2)		MOVE T,ADDADR(C)	;Get network address
2)		CALL PRIORI		;Get priority
2)		CAML D,T		;Compare priorities
2)		 JRST PRIAD5		;Jump if in right place
2)		MOVE B,C		;No good.  Keep looking
2)		JRST PRIAD2
2)	PRIAD5:	HRRZ T,ADRCDR(B)	;Link into list
2)		HRRM T,ADRCDR(E)
2)		JRST PRIAD3		;Go finish off
2)	;Compute priority of address in T
2)	PRIORI:	PUSH P,T
2)		MOVSI TT,-NPRIOR	;Table size for AOBJN
2)	PRIOR1:	MOVE T,(P)
2)		AND T,PRIMSK(TT)	;Mask interesting bits
2)		CAME T,PRIBTS(TT)	;Compare
2)		 AOBJN TT,PRIOR1	;Loop
2)		MOVE T,PRITAB(TT)	;Get priority from table
2)		ADJSP P,-1		;Fix stack
2)		RET
2)	;In the following tables, entries are in the order that we want matching to
2)	;occur.  For example, an ARPAnet address will match both the ARPAnet and
2)	;Internet entries, so ARPAnet is put first.
2)	;Tables of priorities for various networks
2)	PRITAB:	6		;ARPAnet	;Lower than Ethernet, as is flakey
2)		12		;SU-Net CSD subnet (IP)
2)		11		;SU-Net (IP)
2)		5		;Internet
2)		10		;SU-Net CSD subnet (PUP)
2)		7		;SU-Net (PUP)
2)		0		;Unknown network
2)	NPRIOR==.-PRITAB		;Number of entries in tables
2)	;Bits to mask for above networks
2)	PRIMSK:	777700,,0	;ARPAnet
2)		777777,,600000	;SU-Net CSD subnet (IP)
2)		777700,,0	;SU-Net (IP)
2)		740000,,0	;Internet
2)		777777,,777400	;SU-Net CSD subnet (PUP)
2)		777700,,0	;SU-Net (PUP)
2)		0		;match anything
2)	;Bits to match for above networks
2)	PRIBTS:	001200,,0	;ARPAnet
2)		004411,,0	;SU-Net MJH subnet (IP)
2)		004400,,0	;SU-Net (IP)
2)		0		;Internet
2)		044400,,022000	;SU-Net MJH subnet (PUP)
2)		044400,,0	;SU-Net (PUP)
2)		0		;match anything
2)	];IFN SAILSW
***************


**** File 1) HOSTS3.NIC[HST,NET]/30P/16L
**** File 2) HOSTS3.MID[HST,NET]/31P/15L
2)	IFE SAILSW,[			;This is slow, slow, slow!
***************


**** File 1) HOSTS3.NIC[HST,NET]/30P/28L
**** File 2) HOSTS3.MID[HST,NET]/31P/27L
2)	];IFE SAILSW
2)	IFN SAILSW,[			; Let's use quicksort instead
2)		MOVE B,(A)		; Number of entries
2)		ADDI B,-1(E)		; Addr of last entry
2)		MOVEI A,(E)		; Addr of first entry
2)		CALL QSNAM		; Sort the table
2)	];IFN SAILSW
***************


**** File 1) HOSTS3.NIC[HST,NET]/31P/2L
**** File 2) HOSTS3.MID[HST,NET]/31P/94L
2)	IFN SAILSW,[
2)		; Quicksort entries from (A) to (B).
2)	QSNAM:	CAIL A,(B)		; Check trivial case
2)		RET
2)		PUSH P,B		; Save bounds on stack
2)		PUSH P,A
2)		HRRZ C,NMRNAM(A)	; Get element to partition on
2)		; Decrement B until it points to something less than C.
2)	QSN1:	HRRZ D,NMRNAM(B)
2)		CAIG C,(D)
2)		CAMGE B,(P)		; But not out of range
2)		JRST QSN2
2)		SOJA B,QSN1
2)		; Increment A until it points to something greater than or equal to C.
2)	QSN2:	HRRZ D,NMRNAM(A)
2)		CAILE C,(D)
2)		CAMLE A,-1(P)		; But not out of range
2)		JRST QSN3
2)		AOJA A,QSN2
2)		; If A still less than B, exchange items.
2)	QSN3:	CAIL A,(B)
2)		JRST QSN4
2)		MOVE D,(A)
2)		EXCH D,(B)
2)		MOVEM D,(A)
2)		ADDI A,1		; Now bump A and B
2)		SUBI B,1
2)		; If A less than or equal to B, continue scanning.
2)	QSN4:	CAIG A,(B)
2)		JRST QSN1
2)		; Done the partition.  See if anything was less than C.
2)		CAML B,(P)
2)		JRST QSN5
2)		; Degenerate case - nothing less than C.  Then the array hasn't changed
2)		; and its first element is smallest, so sort from (A)+1 to (B).
2)		POP P,A			; Get back original bounds
2)		POP P,B
2)		AOJA A,QSNAM
2)		; Normal case - sort both partitions.
2)	QSN5:	MOVEI B,-1(A)		; Upper bound of low half
2)		EXCH A,(P)		; Save splitting index, get lower bound
2)		CALL QSNAM
2)		POP P,A			; Lower bound of high half
2)		POP P,B			; Original upper bound
2)		JRST QSNAM
2)	];IFN SAILSW
***************


**** File 1) HOSTS3.NIC[HST,NET]/33P/110L
1)	RTOK1:	CAIL A,"a		; Make all chars uppercase before deposit.
**** File 2) HOSTS3.MID[HST,NET]/34P/109L
2)	RTOK1:
2)	IFE LCASE,[
2)		CAIL A,"a		; Make all chars uppercase before deposit.
***************


**** File 1) HOSTS3.NIC[HST,NET]/33P/114L
**** File 2) HOSTS3.MID[HST,NET]/34P/115L
2)	];IFE LCASE
***************


**** File 1) HOSTS3.NIC[HST,NET]/33P/169L
**** File 2) HOSTS3.MID[HST,NET]/34P/171L
2)	IFN SAILSW,[			;Clear to end of word
2)		MOVE A,TOKBP
2)		PUSH P,A
2)		LDB A,[360600,,(P)]	; Get P field of the BP
2)		DPB A,[301400,,(P)]	; Deposit 0,P into P,S
2)		SETZ A,			; get a zero ac
2)		DPB A,(P)		; Deposit, clearing rest of word.
2)		POP P,A
2)	];IFN SAILSW
***************


**** File 1) HOSTS3.NIC[HST,NET]/36P/7L
1)		CALL RTOKEN		; Get initial token - should be HOST, etc.
**** File 2) HOSTS3.MID[HST,NET]/37P/6L
2)	IFN SAILSW,[PUSH P,TOKBP]
2)		CALL RTOKEN		; Get initial token - should be HOST, etc.
2)	IFN SAILSW,[POP P,TOKBP]
***************


**** File 1) HOSTS3.NIC[HST,NET]/36P/14L
**** File 2) HOSTS3.MID[HST,NET]/37P/15L
2)	IFN LCASE,[CALL UPPERA]
***************


**** File 1) HOSTS3.NIC[HST,NET]/39P/47L
1)		440700,,[ASCIZ /HOSTS3.BIN[HST,NET]/]
1)		440700,,[ASCIZ /HOSTS2.BIN[HST,NET]/]
**** File 2) HOSTS3.MID[HST,NET]/40P/46L
2)		440700,,[ASCIZ /HOSTS3.TMP[HST,NET]/]
2)		440700,,[ASCIZ /HOSTS2.TMP[HST,NET]/]
***************


**** File 1) HOSTS3.NIC[HST,NET]/41P/30L
**** File 2) HOSTS3.MID[HST,NET]/42P/29L
2)	IFE SAILSW,[
***************


**** File 1) HOSTS3.NIC[HST,NET]/41P/34L
**** File 2) HOSTS3.MID[HST,NET]/42P/33L
2)	];IFE SAILSW
2)	IFN SAILSW,[
2)		 JRST [	PUSH P,TOKBP
2)			CALL RTOKEN
2)			CALL CKNICK	; Check this nickname
2)			 JRST [	POP P,TOKBP	; Don't want it.  Return string space.
2)				JRST GHST33]
2)			ADJSP P,-1
2)			CALL GNICKN	; Handle as nicknames.
2)			JRST GHST33]
2)	];IFN SAILSW
***************


**** File 1) HOSTS3.NIC[HST,NET]/41P/41L
1)		CALL RFIELD		; Next is system name
**** File 2) HOSTS3.MID[HST,NET]/42P/52L
2)	IFN SAILSW,[
2)		PUSH P,TOKBP
2)	];IFN SAILSW
2)		CALL RFIELD		; Next is system name
2)	IFN SAILSW,[
2)		CALL CKPDEF		; Check if it is a predefined string
2)		 JRST [	ADJSP P,-1	; No
2)			JRST GHST34]
2)		POP P,TOKBP		; Yes, recover string space
2)					; (A now points to predefined string)
2)	GHST34:
2)	];IFN SAILSW
***************


**** File 1) HOSTS3.NIC[HST,NET]/41P/48L
**** File 2) HOSTS3.MID[HST,NET]/42P/70L
2)	IFE SAILSW,[
***************


**** File 1) HOSTS3.NIC[HST,NET]/41P/53L
**** File 2) HOSTS3.MID[HST,NET]/42P/76L
2)	];IFE SAILSW
2)	IFN SAILSW,[
2)	GHST35:	PUSH P,TOKBP
2)		CALL RTOKEN		; Read a service name
2)		CALL CKPDEF		; Check if it is a predefined string
2)		 JRST [	ADJSP P,-1	; No
2)			JRST GHST36]
2)		POP P,TOKBP		; Yes, recover string space
2)					; (A now points to predefined string)
2)	GHST36:	JUMPL A,[CALL GSVCN	; Get service name like nickname
2)			CALL RFNEXT
2)			 JRST GHST35
2)			JRST .+1]
2)	];IFN SAILSW
***************


**** File 1) HOSTS3.NIC[HST,NET]/43P/2L
**** File 2) HOSTS3.MID[HST,NET]/44P/1L
2)	IFN SAILSW,[
2)	IFN 0,[	;Too many important nicknames get flushed this way.
2)	; Check a nickname.  Return non-skip if a non-domain name, skip if
2)	; name contains a ".".
2)	CKNICK:	MOVEI T,(A)
2)		HRLI T,440700
2)	CKNIC1:	ILDB TT,T
2)		JUMPE TT,APOPJ
2)		CAIN TT,".
2)		JRST POPJ1
2)		JRST CKNIC1
2)	];IFN 0
2)	IFN 1,[
2)	;Check a nickname.  Return non-skip if a prefix of the official name
2)	;up to a ".", else give skip return to allow the name.
2)	CKNICK:	PUSH P,A
2)		PUSH P,B
2)		HRRZ B,HSTNAM(H)
2)		HRLI A,440700		;Nickname being tested
2)		HRLI B,440700		;Official name
2)	CKNIC1:	ILDB T,A		;Get next char from each
2)		ILDB TT,B
2)		JUMPE T,[CAIN TT,".	;Nickname ended.  Matched up to a "."?
2)			JRST CKNIC3	;Yes, return non-skip to flush nickname
2)			JRST CKNIC2]	;No, keep nickname
2)		JUMPE TT,CKNIC2		;Official name ended, keep nickname
2)		CAIN T,(TT)		;Same so far?
2)		JRST CKNIC1		;Yes, keep checking
2)	CKNIC2:	AOS -2(P)
2)	CKNIC3:	POP P,B
2)		POP P,A
2)		RET
2)	];IFN 1
2)	;Check a string in A to see if it matches any of the predefined strings.
2)	;Skip return if so, with A set to the predefined string.
2)	CKPDEF:	MOVSI C,-NPDSTR		;Set up AOBJN ptr
2)	CKPDE1:	MOVE B,PDSTRS(C)	;Addr of next string
2)		HRLI B,440700
2)		PUSHJ P,CMPSTR
2)		 JRST [	MOVE A,B	;Match
2)			JRST POPJ1]
2)		AOBJN C,CKPDE1		;No match, try next
2)		RET
2)	];IFN SAILSW
***************


**** File 1) HOSTS3.NIC[HST,NET]/43P/94L
1)		CAME C,(B)
1)		 JRST CMPST8
**** File 2) HOSTS3.MID[HST,NET]/44P/139L
2)	IFE LCASE,[
2)		CAME C,(B)
2)		 JRST CMPST8
2)	];IFE LCASE
2)	IFN LCASE,[
2)		XOR C,(B)
2)		TDNE C,[576773,,757677]
2)		 JRST CMPST8
2)		XOR C,(B)
2)	];IFN LCASE
***************


**** File 1) HOSTS3.NIC[HST,NET]/44P/32L
**** File 2) HOSTS3.MID[HST,NET]/45P/31L
2)	IFN SAILSW,[
2)		;Predefine some more strings for our modified code at GHST35.
2)		;The more we put here, the less space will be wasted in reading
2)		;the input files.
2)		[ASCIZ "IP"]
2)		[ASCIZ "IP/GW"]
2)		[ASCIZ "GW/PRIME"]
2)		[ASCIZ "GW/DUMB"]
2)		[ASCIZ "GW/ALWAYS-UP"]
2)		[ASCIZ "EGP"]
2)		[ASCIZ "ICMP"]
2)		[ASCIZ "UDP"]
2)		[ASCIZ "UDP/CHARGEN"]
2)		[ASCIZ "UDP/DISCARD"]
2)		[ASCIZ "UDP/DOMAIN"]
2)		[ASCIZ "UDP/ECHO"]
2)		[ASCIZ "UDP/TIME"]
2)		[ASCIZ "UDP/TFTP"]
2)		[ASCIZ "TCP"]
2)		[ASCIZ "TCP/ASCII-NAME"]
2)		[ASCIZ "TCP/CHARGEN"]
2)		[ASCIZ "TCP/DAYTIME"]
2)		[ASCIZ "TCP/DISCARD"]
2)		[ASCIZ "TCP/ECHO"]
2)		[ASCIZ "TCP/FINGER"]
2)		[ASCIZ "TCP/LOGIN"]
2)		[ASCIZ "TCP/MLDEV"]
2)		[ASCIZ "TCP/MPM"]
2)		[ASCIZ "TCP/MTP"]
2)		[ASCIZ "TCP/NAME"]
2)		[ASCIZ "TCP/NNTP"]
2)		[ASCIZ "TCP/PRINTER"]
2)		[ASCIZ "TCP/PWDGEN"]
2)		[ASCIZ "TCP/QUOTE"]
2)		[ASCIZ "TCP/SUPDUP"]
2)		[ASCIZ "TCP/SYSTAT"]
2)		[ASCIZ "TCP/TIME"]
2)		[ASCIZ "TCP/UUCP"]
2)		[ASCIZ "X.25"]
2)	];IFN SAILSW
***************


**** File 1) HOSTS3.NIC[HST,NET]/45P/27L
1)	FSTFRE==.	; 1st free location (may clobber symbols tho)
1)	IFL HSTTAB-FSTFRE, .ERR HSTTAB too low, overlaps code.  Must increase it!
**** File 2) HOSTS3.MID[HST,NET]/46P/26L
***************