perm filename NETWRK.MID[S,NET]16 blob sn#756897 filedate 1984-05-25 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00034 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00005 00002	Network routines, intended to be .INSRT'ed
C00011 00003	 INTINR INTINS INTIMS INTINP RFCS RFCR CLSS CLSR SIU CCS SYS NLA ILB IDD GMM IOIMPM IODERR IODTER IOBKTL IODEND ERRBTS WINBTS ICP NET DAT NT$NUM NE%UNT NE%STR NN%IP NW%ARP NW%MIL NW%SI NW%SU
C00015 00004	 NWKDBG HSTADR HSTTOP HDBPTR DHSTST CONBLK CONSTS CONLSK CONWAT CONBYT ICPSKT CONFSK HOST CONHST LSNBLK LSNSTS LSNSKT LSNWAT LSNBYT LSNFSK LSNHST OPNBLK NETDEV
C00018 00005	 WATBLK WATSTS WATSKT INRBLK INRSTS INRSKT INSBLK INSSTS INSSKT ABTBLK ABTSTS WHYWHY NTIBF NTOBF DTIBF DTOBF RMKBLK RMKSTS RMKDAT FSOCKT LSOCKT
C00020 00006	 CONECT .CONEC
C00023 00007	 LISTEN .LISTE
C00026 00008	 DATI .DATI .DATI1
C00028 00009	 DATO .DATO .DATO1
C00030 00010	 NETICH NETICW NTICH2 NTICH4 NTICH3
C00033 00011	 NETOCH .NETOC
C00034 00012	 NETSND .NETSN NETOER
C00035 00013	 DATICH DATICW DTICH2 DTICH3 DTICH1 DTIC1A
C00039 00014	 DATOCH .DATOC
C00040 00015	 DATSND .DATSN DATOER
C00042 00016	 CLOSER CLSDAT
C00043 00017	 NETINR NETINS ABORT
C00044 00018	 MTPERR MTPER1 MTPE1A MERTAB MERLEN
C00048 00019	 NIOERR
C00049 00020	 HSTDED
C00052 00021	 HSTDE2
C00054 00022	 HSTSID HSTFN1 HSTVRS HSTDIR HSTDEV HSTWHO HSTDAT HSTTIM NAMPTR SITPTR NETPTR NTNPTR HDRLEN NETNUM NTLNAM NTRTAB NETLEN ADDADR ADLSIT ADRCDR ADLXXX ADRSVC SVLCNT SVRCDR SVLFLG SVRNAM SVCARG ADDLEN STLNAM STRADR STLSYS STRMCH STLFLG STFSRV STFGWY SITLEN NMLSIT NMRNAM NAMLEN NNLNET NNRNAM NTNLEN HSTFIL HSTPPF
C00065 00023	 MAPHST
C00067 00024	 UNMHST
C00068 00025	 HSTNUM HSTNUS HSTNU1 HSTNU2
C00072 00026	 HSTNAM CNTCHR HSTNAB HSTNB1 HSTNB2 HSDNB3 HSTNB4 HSTNB5 HSTUNK HSTUN1
C00076 00027	 SEARCH SRCNXW SRCWIN SRCLUZ SRCDUN GOTNAM AMBNAM GETHDB
C00080 00028	 HSTNXA
C00081 00029	 SVCCHK SVCCH1 SVCCH2 SVCCH3
C00083 00030	 SETANM SETA00 SETAN1 SETAN0 SETAN2 SETAN4 SETAN5 SETAN9 SETAN6 SETAN7 SETAN8
C00087 00031	 HNUMST HNUMS2 HNUMS4 HNUMS5 HNUMSD HNUMSO HNUMS6
C00090 00032	 OURNAM OURNA1
C00092 00033	 TTYSTR TTYST1 TTST1A TTYST2 TTST2A TTYST3 TTYST4 TTST4A TTYST5 TTST5A TTST5B TTYST6 TTYST9
C00097 00034	 CPOPJ2 CPOPJ1 CPOPJ WARNIN LUZBIG ..NLIT
C00098 ENDMK
C⊗;
SUBTTL Network routines, intended to be .INSRT'ed

; Mark Crispin, SU-AI, April 1978

;  This is a library of ARPAnet hacking routines.  Each routine describes its
; calling sequence and what AC's it smashes.  A pushdown stack is expected in 17.
;  I/O channel 0 is smashed, I/O channel 1 (NET) is used as the general TELNET
; connection channel, and I/O channel 2 (DAT) is used for data I/O.
;  Bugs → MRC.

;  This package can also be used with the Ethernet as well, but data connections
; are not implemented. Also, Ethernet does not have equivalent to INTINR, and
; simply sends an INTINS. Host down messages are bogus. (TVR/Dec81)

;  Modified for ARPAnet IP/TCP in April 1983.  Majgr change is the elimination
; of ICP for ARPAnet connections.  Bugs → ME and JJW.
¬
;  Changed host table to use HOSTS3 format (JJW - June 83).

;  This is the MIDAS version which lives in NETWRK.MID[S,NET].  The FAIL version
; lives in NETWRK.FAI[S,NET].

; Assembly switches

IF1,[
IFDEF FTHST3,[
PRIJTX/Please remove the FTHST3 switch and non-HOSTS3 code from this program.
All NETWRK-reading programs must now use HOSTS3 host numbers.
/];IFDAF FTHST3
];IF1
IFNDEF SVRRTS,SVRRTS==0			; ≠ 0 → server (not user) routines
IFNDEF DATRTS,DATRTS==0			; ≠ 0 → data channel routines
IFNDEF MRKCHR,MRKCHR==0			; ≠ 0 → pass BSP mark bytes as characters
IFNDEF ERRHAN,ERRHAN==0			; ≠ 0 → automagic error reporting in NIORTS
IFNDEF ERRINS,ERRINS==EXIT		; (iff ERRHAN≠0) what to do after an error
IFNDEF HSTSIX,HSTSIX==0			; ≠ 0 → sixbit alias name hacking
IFNDEF TTYSTS,TTYSTS==0			; ≠ 0 → code to get TTY location string

IFNDEF NIORTS,NIORTS==SVRRTS\DATRTS\ERRHAN ; ≠ 0 → network I/O routines

IFNDEF ERRTNS,ERRTNS==ERRHAN		; ≠ 0 → error reporting routines

IFNDEF HSTTAB,HSTTAB==HSTSIX		; ≠ 0 → host table routines

IFE NIORTS\ERRTNS\HSTTAB,.FATAL No NETWRK routines selected
IFE NIORTS,IFN SVRRTS\DATRTS\ERRHAN,.FATAL NIORTS Illegal switch setting
IFE ERRTNS,IFN ERRHAN,.FATAL ERRHAN Illegal switch setting
IFE HSTTAB,IFN HSTSIX,.FATAL HSTTAB Illegal switch setping
IFE NIORTS$IFN MRKCHR,.FATAL MRKCHR Illegal switch setting
¬
; Macro definitions

DEFIJE TMSG STRING
 OUTSTR YASCIZ\!STRING!\]
TERMIN
¬
;  FATAL errors type an eXclamation point andhalt.  WARLings type a question
; mark and continue.

DEFINE FATAL STRING
 PUSHJ 13,[OUTSDR [ASCIZ\!STRING!?\] ? JRST LUZBIG]
TERMIN

@EFINA GARN STRING
 PESHJ 17,[OUTSTR [ASCIZ\!STRIJG!!\] ? JRST WARNIN]
TERMIN

; Timeouts for various flavors of connection

IFNDEF CNTIMO,CNTIMO==010000170500	; connect ICP
IFNDEF LSTIMO,LSTIMO==011212360000	; listen ICP
IFNDEF TNTIMO,TNTIMO==011700050000	; TELNET socket
IFNDEF DATIMO,DATIMO==022400070000	; data socket

;Macro to zero all but network number in a word.  Placed outside .BEGIN so
;programs .INSRTing this file can use it.

DEFINE GETNET AC,(ADDR)
IFNB [ADDR] MOVE AC,ADDR
	TLNN AC,(17←32.)	; Check for non-Internet type addrs
	 TLNN AC,(1←31.)	9  Internet address, see if class A net
	  TDZA AC,[77,,-1]	;   Unternet or class A, zap low 3 octets
	TLNN AC,(1←30.)		; Class B or C, see which.
	 TRZA AC,177777		;  Class B network, zap low 2 octets
	  TRZ AC,377		;   Class C net, only zap 1 low octet
TERMIN
;⊗ INTINR INTINS INTIMS INTINP RFCS RFCR CLSS CLSR SIU CCS SYS NLA ILB IDD GMM IOIMPM IODERR IODTER IOBKTL IODEND ERRBTS WINBTS ICP NET DAT NT$NUM NE%UNT NE%STR NN%IP NW%ARP NW%MIL NW%SI NW%SU

; System bits and bytes

.BEGIN NETWRK

; Interrupt condition bits

.U"INTINR==000100,,			; IMP INR
.U"INTINS==000040,,			; IMP INS
.U"INTIMS==000020,,			; IMP status change
.U"INTINP==000010,,			; IMP input waiting

; Network socket status flags

.U"RFCS==  200000,,			9 RFC sent
.U"RFCR==  100000,,			; RFC received
.U"CLSS==  040000,,			; CLS sent
.U"CLSR==  020000,,			; CLS received
¬
; Network status word error co@⊃Kf~∀4∀]*EM∪*zz@b∩α∩$rAg←
WKhA%\Akg∀~∀]*	ππ&zt`d∩∩$∩vAG¬\OhA
QC]O∀Ag←G-KhA]U[EKeL~∀]*	'3&zt`f∩∩$∩vAQ=eeSE1JAgsMiKZA∃ee←d4∀]*E9→αzz@h∩∩∩$vA]↑↓YS]WLACmC%YCEY∀~∀]*	∪→∧zt`j∩∩$∩vAS1YKOC0AEsi∀AgSu∀~∀]*	∪	λzt`l∩∩$∩vA∪5 AIK¬H~∀]TE∂≠~tz`n∩$∩∩vA≥K]IKHA[Sg5CiGP4∀~∀v↓∩←≡AMiCikLAo←e⊂AKee=dAESQf~∀~(]*E∪=∪≠!~tzh``@``∩∩$vAS[Ae←aKHA[←I∀~∀]*	∪∨	I$zzd@````$∩∩vA!CeHA⊃KmSG∀AKee=d~∀]TE∪∨	Q$zzD````@∩∩∩v↓g←Mh↓IKmS
JAKeI←d
∀9*E∪∨	↔)_zt`h``@`∩∩∩lAEY←
VA]k5EKdA=khA←_AE←k9If~∀9*E∪∨⊃≥λzt`d``@`∩∩∩lAK]H↓←LAM%YJ~∀9*E⊃	∃βλzz``d`@`∩∩∩lAQ←gPA←dA⊃KgiS9CiS←8A∪≠ ↓IKCH4∀]*EI'(zt@@``@h``∩$∩vAQ=ghAg∃]hAB↓%'(~(]*E)5≡zz@@```H``∩∩$vAiS5JA←kP~∀~∃∃%%¬)Lz{∪∨%≠!≠9%∨	%I9∪∨	Q%9∪=¬↔)→q∪∨	9	9⊃	∃β	9%M)9)5≡~∃/%≥¬)&t{%
πM9%
πH∩∩∩v↓G←]]∃GiS←8AoS]9S]N~(~∀vA$←≡AG!C]]K0AIKM%]SiS=]f~∀4∃∪π tz`∩∩$∩∩vA
QC]]∃XAi↑↓OKhAM←GWKPAMe←4AY←O≥Kd~∀9*E≥Pzzb∩$∩∩vA
QC]]∃XAi↑↓I↑Ae∃CXA]∃io←e,AQCG-S]N~(]*E	¬(zzd$∩∩∩v↓GQC]9KXAi<AI↑A⊃CiBA!CGWS9N~∀~(vA≥KQo←eV↓]k[E∃ef@Q→←dAI%giS]≥kSgQ%]NA∪5 AMe=ZAY←
CXAQQKe]∃hR~∀9*E≥(⊃≥+~zttf`bP``∩w	siJAA←S]i∃dAi↑↓]Kio=eVA]U[EKdQQSO @bdA	SifR4∀]*E9
K+≥Pzzt`P````0X`∩w∃gGCa∀AESh↓S]IS
CiS]≤@E+]QKe]KPDAisAJACI⊃eKgf4∀]*E9
K')Hzztb@````0X`∩w∃gGCa∀AESh↓S]IS
CiS]≤@EgiIS]ND↓isaJ↓CIIe∃gf~∀9*E≥≤∃∪ zzhnh``@`XX`$wQ←gPA]k[	KdAE%ifAi!ChACIJA←M_AM←d↓CYXA% ACI⊃eKgg∃f~∀]TE≥.K¬% zzhxb`]|dh\|$w⊃∨'Q&fAkMKfAMUYXAo=eHA]∃io←e,@FAm¬YkKf4∀]*E9.K≠∪0zztxHl]>dP\|∩w1→_ASLA←\A5∪→]KP~∀]*	≥.K'$zztxPi>dh8|∩w∪9iKe]∃hACI⊃eKgf↓←LA'T[≥(5)≠ 4∀]*E9.K'*tzty≥∀K+≥(-≥.K'$|@vEU]iKe9KhDAUgKHA→←dA'QC]M←IHAi!Ke]KP~∀_v,A9/↔	¬≤A⊃')¬	$A⊃M))∨ ↓⊃	¬!Q$A	⊃M)'(A
∨≥¬→,Aπ∨≥M)&Aπ=≥→'⊗↓π∨≥/¬(Aπ∨9¬3(A%π!'↔PAπ∨≥→'⊗A⊃='(Aπ=≥⊃'(↓→'≥¬1⊗A→'9')&A1'≥'↔PA→'≥]β(A→M≥¬3(↓→'≥
M⊗A→'9⊃'(A=!≥¬→,A≥)⊃,~∀4∀vA	¬iBACIKB~∀4∃≥/↔⊃¬∞t∩@∩∩∩∩l@Zb@dAI↑A=+)π⊃HA←\A9Kio←IVA∩←<~∀~∃%
≤A⊃M))β∧16~∀~(vA⊃←MhAiC	YJAa=S]iKIf~∀~(]*E⊃M)β	$h∩∩∩∩l@6@`2ACI⊃eKgf↓←LAE∃OS]]%]NA←_AQ←gPAiCE1J~∀∪	→∨π⊗b∩α∩$v@z@@@2AQ=ghAi¬EYJA9←hAS8AG←e∀~∃⊃'Q)∨ t%↓→∨π,@b∩∩$∩vAi=`A←L↓Q←gh↓iCEY∀@Q∃∨	
ACPA[C`↓iS[J$~∃⊃		!)$t%↓→∨π,@b∩∩$∩vAa=S]iKHAi↑AIKYCi%mJA⊃⊃∧~∀~(vA¬Y=GVAM=dAβ'
∪4Ai∃qhA←_AI←iQKHAQ=ghA]U[EKd↓←LAQ=ghA]=hAS\↓iCEY∀~∃	⊃M)'(t%¬→∨π,@b`~(~∃:v↓]HA%
≤A⊃M))β∧4∀~∃∪→≤A))e')&Yl~∀~∃Q)3
∪0t∪'∪a¬∪(←Q)3→∨↑∩∩w→SYJA=LA'*5iQKI]KhAQ)2AY=GCiS=\AgiIS]Of4∀∪'∪a¬∪(←Q1(↑~)))3!A≤t∪'%1¬∪(=⊃')≥∃(↑~∃Q∪!
→≤t∪¬→=π⊗@b$∩∩w≥=\[uKI↑AM←HAiQ∃eiSaL~∃))e≥β~t%¬→∨π,@b`\$∩w¬Y=GVAi<AeKiUe\A)Q2AgiIS]N~(~∃:w∃]HA∪→≤A))e')&~(~∃∪
8A≥∪∨I)&Y64∀~∀v↓π∨≥≥∃π(A≠Qβ!
A	Y←GV4∀~∃π=≥¬→⊗h∩`∩∩$∩vAπ=≥≥πP~∃π∨9')&t%¬→∨π,@b∩∩$∩vAe∃ike]∃HAgi¬ikfA	Sif~)π∨≥→M⊗t∪¬1∨π⊗@D∩∩∩∩lAY←G¬XAg←
WKh~)π∨≥/¬(t∪¬1∨π⊗@D∩∩∩∩l@6@`2AoC%hAM←HAG←]9KGiS=\Ak]QSXAi%[K←kP~∃π∨9¬3(t%¬→∨π,@b∩∩$∩vAEeiJAg%uJ~∀9*E∪πA'↔(t4∃π∨≥→'⊗t∪	→∨π⊗b∩∩∩$vAM←IKSO\↓g←GW∃h~∀]TE⊃∨'Pt~∃π=≥⊃'(h∪¬→∨
⊗@b∩$∩∩vA→←eKS≥\AQ←Mh~∀~)∪
≤AM-%%)LY6~∀4∀vA→%')≤↓≠)β!∀AEY←
V~∀~)→'≥¬1⊗t∩b$∩∩∩v↓→∪')∃≤~∃→M≥')&h∪¬→∨
⊗@b∩$∩∩vAIKike9KHAgQCikf↓ESif4∀]*E1'≥'↔Pt~∀∪	→∨π⊗b∩∩∩$vAY←
CXAg=GWKh↓i↑AY%giK\↓i↑~∃1'≥/βPt∪¬→=π⊗@b$∩∩∩v6@`@dAoCSPAM←d↓G←]]∃GiS←8~∃→'9¬3(t%¬→∨π,@b∩∩$∩vAEeiJAg%uJ~∃1'≥
',t∪¬→=π⊗@b$∩∩∩v↓M←eK%O\Ag=GWKh4∃→'≥!'(t∪	→∨π⊗b∩∩∩$vAM←IKSO\host

]; End IFN SVRRTS

IFN NIORTS!SVRRTS,[
OPNBLK:	0
.U"NETDEV: 'IMP,,0			; device name
	 NTOBF,,NTIBF			; buffers
	
]; End IFN NIORTS!SVRRTS
;⊗ WATBLK WATSTS WATSKT INRBLK INRSTS INRSKT INSBLK INSSTS INSSKT ABTBLK ABTSTS WHYWHY NTIBF NTOBF DTIBF DTOBF RMKBLK RMKSTS RMKDAT FSOCKT LSOCKT

; More data area, shared by USER and SERVER

; WAIT MTAPE block

WATBLK:	4				; WAIT
WATSTS:	BLOCK 1				; returned status bits
WATSKT:	BLOCK 1				; socket number

; INTERRUPT MTAPE blocks

INRBLK:	11				; SEND INTERRUPT
INRSTS:	BLOCK 1				; returned status bits
INRSKT:	BLOCK 1				; socket number

INSBLK:	11
INSSTS:	BLOCK 1
INSSKT:	BLOCK 1

;ABORT MTAPE block

ABTBLK:	22			;ABORT
ABTSTS:	BLOCK 1			;Returned status bits

; Other stuff

WHYWHY:	BLOCK 1				; host down word

; I/O buffer headers

NTIBF:	BLMCK 3				; network input buffer header
NTOBF:	BLOCK 3				; network output buffer header

IFN DATRTS,[
DTIBF:	BLOCC 3				; network data Input buffer header
DTOBF:	BLOCK 3				; network data output buffer header
]; End IFN DATRTS

IFN MRKCHR,[
RMKBLK:	26				; READ MARK
RMKSTS:	BLOCK 1
RMKDAT:	BLOCK 1				; mark byte returned here
]; End IFN MRKCHR

; Base sockets, set up by CONECT and LISTEN

.U"FSOCKT:
	BLOCK 1				; foreign base socket
.U"LSOCKT:
	BLOCK 1				; local base socket

]; End IFN NIORTS
;⊗ CONECT .CONEC

; CONECT -- Connect to foreign host
; Call:	MOVEM <host number>,HOST
;	MOVEM <ICP socket number>,ICPSKT
;	PUSHJ 17,CONECT
;	<error return--MTAPE lossage, status in 0> iff ERRHAN = 0
;	<error return--I/O error, status in 0> iff ERRHAN = 0
;	<return>
; Smashes 0 and 1.

IFN NIORTS,[

IFE SVRRTS,[

; Open channels and set timeouts

.U"CONECT:
IFN ERRHAN,[
	PUSHJ 17,.CONEC
	 JRST [PUSHJ 17,MTPERR ? ERRINS]
	 JRST [PUSHJ 17,NIOERR ? ERRINS]
	POPJ 17,
]; End IFN ERRHAN
.CONEC:	GETNET 0,HOST			; check network type
	MOVEI 1,'IMP			; Assume not PUP
	CAMN 0,[NW%SU]			; Ethernet?
	 MOVEI 1,'PUP			; Yes, use PUP
	MOVSM 1,NETDEV			; specify device for OPEN
	CAIN 1,'PUP
	 HRRZS HOST			; Don't confuse PUPSER with net number
	OPEN NET,OPNBLK			; open NET in ASCII mode
	 FATAL Network device INIT failure
	MTAPE NET,[17 ? CNTIMO]
	SETOM CONLSK			; gensym local socket
	SETOM CONWAT			; do wait until timeout
	MTAPE NET,CONBLK		; connect → foreign server
	MOVE CONLSK			; get gensymmed socket
	MOVEM LSOCKT			; save local base socket
	MOVE CONSTS			; get MTAPE status
	MOVEM WHYWHY			; save it
	GETSTS NET,			; check for I/O error on proper channel
	TRNE ERRBTS
	 JRST CPOPJ1
	MOVE WHYWHY
	TRNE 77				; check for MTAPE error
	 POPJ 17,
	TLC (WINBTS)			; for next instruction to win
	TLCE (WINBTS)			; legal socket state?
	 POPJ 17,
	MOVE CONFSK			; get socket we got
	MOVEM FSOCKT			; save foreign socket for later
	MOVE CONLSK			; for completeness and compatibilty
	MOVEM INSSKT
	MOVEI 8.			; change byte size in buffer header
	DPB [300600,,NTIBF+1]
	DPB [300600,,NTOBF+1]
	INBUF NET,
	OUTBUF NET,
	MTAPE NET,[17 ? TNTIMO]
	MTAPE NET,[10]
	 CAI
	JRST CPOPJ2

]; End IFE SVRRTS
;⊗ LISTEN .LISTE

; LISTEN -- Listen for an ICP from a foreign host
; Call:	MOVEM <ICP socket number>,LSNSKT
;	MOVEM <device name>,NETDEV	;If omitted, then use IMP
;	PUSHJ 17,LISTEN
;	<error return--MTAPE lossage, status in 0> iff ERRHAN = 0
;	<error return--I/O error, status in 0> iff ERRHAN = 0
3	<return--host we connected to in HOST>
; Smashes 0 and 1.

IFN SVRRTS,[

; Open channels and set timeouts (punts after a minute)

.U"LISTEN:
IFN ERRHAN,[
	PUSHJ 17,.LISTE
	 JRST [PUSHJ 17,MTPERR ? ERRINS]
	 JRST [PUSHJ 17,NIOERR ? ERRINS]
	POPJ 17,
]; End IFN ERRHAN
.LISTE:	OPEN NET,OPNBLK			; open NET in ASCII mode
	 FATAL Network device INIT failure
	MOVS 1,NETDEV
	MTAPE NET,[17 ? LSTIMO]
	SETOM LSNWAT			; do wait until timeout
	MTAPE NET,LSNBLK
	MOVE LSNSTS			; check for MTAPE error
	MOVEM WHYWHY
	TRNE 77
	 POPJ 17,
	GETSTS NET,			; check for I/O error
	TRNE ERRBTS
	 JRST CPOPJ1
	MOVE WHYWHY
	TLC (WINBTS)			; for next instruction to win
	TLCE (WINBTS)			; legal socket state?
	 POPJ 17,
	MOVE LSNHST
	MOVEM CONHST
	MOVE LSNFSK
	MOVEM FSOCKT			; save foreign base socket
	MOVE LSNSKT			; remember local socket
	MOVEM LSOCKT
	MOVEM INSSKT			; for completeness, set this as well
	MOVEI 8.			; change byte size in buffer header
	DPB [300600,,NTIBF+1]
	DPB [300600,,NTOBF+1]
	INBUF NET,
	OUTBUF NET,
	MTAPE NET,[17 ? TNTIMO]
	MTAPE NET,[10]
	 CAI
	JRST CPOPJ2

]; End IFN SVRRTS
;⊗ DATI .DATI .DATI1

; DATI -- Open data input network channel
; Call:	PUSHJ 17,DATI
;	<error return--MTAPE lossage, status in 0> iff ERRHAN = 0
;	<error return--I/O error, status in 0> iff ERRHAN = 0
;	<return--byte size in 0>
; Smashes 0 and 1.

IFN DATRTS,[

.U"DATI:
IFN ERRHAN,[
	PUSHJ 17,.DATI
	 JRST [PUSHJ 17,MTPERR ? ERRINS]
	 JRST [PUSHJ 17,NIOERR ? ERRINS]
	POPJ 17,
]; End IFN ERRHAN
.DATI:	CHNSTS DAT,			; check for channel open
	JUMPN .DATI1
	INIT DAT,0			; open channel
	 'IMP,,
	 DTOBF,,DTIBF			; buffers
	 FATAL IMP INIT failure
	MTAPE DAT,[17 ? DATIMO]
.DATI1:	MOVE LSOCKT
	ADDI 4				; ICP/U receive data offset
	MOVEM CONLSK			; local receive socket
	MOVE FSOCKT
	ADDI 3				; ICP/S transmit data offset
	MOVEM CONFSK			; foreign transmit socket
	SETOM CONWAT			; wait
	MTAPE DAT,CONBLK		; connect ← foreign data output
	MOVE CONSTS			; test for error
	MOVEM WHYWHY
	TRNE 77
	 POPJ 17,
	GETSTS DAT,
	TRNE ERRBTS
	 JRST CPOPJ1
	MOVE WHYWHY
	TLC (WINBTS)
	TLCE (WINBTS)
	 POPJ 17,
	MTAPE DAT,[15 ? 1]		; system maximum allocation
	MOVE CONBYT			; change byte size in buffer header
	DPB [300600,,DTIBF+1]
	INBUF DAT,
	MTAPE DAT,[10]
	 CAI
	JRST CPOPJ2
;⊗ DATO .DATO .DATO1

; DATO -- Open data output network channel
; Call:	MOVEI <byte size of connection>
;	PUSHJ 17,DATO
;	<error return--MTAPE lossage, status in 0> iff ERRHAN = 0
;	<error return--I/O error, status in 0> iff ERRHAN = 0
;	<return>
; Smashes 0 and 1.

.U"DATO:
IFN ERRHAN,[
	PUSHJ 17,.DATO
	 JRST [PUSHJ 17,MTPERR ? ERRINS]
	 JRST [PUSHJ 17,NIOERR ? ERRINS]
	POPJ 17,
]; End IFN ERRHAN
.DATO8	MOVEM CONBYT
	CHNSTS DAT,
	JUMPN .DATO1
	INIT DAT,0			; open channel
	 'IMP,,
	 DTO@F,,DTIBF			; buffers
	 FATAL IMP INIT failure
	MTAPE DAT,[17 ? DATIMO]
.DATO1:	MOVE LSOCKT
	ADDI 5				; ICP/U transmit data offset
	MOVEM CONLSK			; local receive socket
	MOVE FSOCKT
	ADDI 2				; ICP/S receive data offset
	MOVEM CONFSK			; foreign transmit socket
	SETOM CONWAT			; wait
	MTAPE DAT,CONBLK		; connect → foreign data input
	MOVE CONSTS			; test for error
↓MOVEM WHYWHY
	TRNE 77
	 POPJ 17,
	GETSTS DAT,
	TRNE ERRBTS
	 JRST CPOPJ1
	MOVE WHYWHY
	TLC (WINBTS)
	TLCE (WINBTS)
	 POPJ 17,
	MOVE CONBYT			; change byte size in buffer header
	DPB [300600,,DTOBF+1]
	OUTBUF DAT,
	JRST CPOPJ2

]; End IFN DATRTS
;⊗ NETACH NETIAW NTICH2 LTICH4 NTICH3

; NET@∪π ←≥	%β.@Z4A%KC⊂ABAG!CeCGQKdAMI←ZAi!JA]KQo←eV4∀vAπ¬YXt∪A+'⊃∀bnY≥∃)∪π⊂↓←dA↓U'⊃∀@DnY≥Q∪π.~(v∩yKIe←dAIKike8Z[∩←<AKee=dXAgQCikf↓S\@`xASML↓%%⊃¬≤@z@@~∀f∩qKee←HAeKiUe\Z[9↑AGQ¬eCGi∃efACYCSIC	YJ|A%MLA≥∃)∪π⊂4∀v∩yIKike8Z[GQ¬eCGi∃dAS\`|
∀lA'[CMQKf@@X@bX↓C]H@HX~∀~(]*E≥∃)∪π⊂h~∀∪)⊃5α@d0d∩∩∩lAI←\≥hAQC9N~∀]TE≥)%π.t~(∩A'Q≡@dX$∩∩vA!C]N~)∪
≤A∃%%⊃β8Y6~∀%!+'⊃(@bnY9)∪π⊂H~∀∩A)%'(Am!+'⊃(@bnY9∪∨%H@}AI%∪≥'t~∀αAA∨!∀@DnX∩∩$vA≥Q∪π.A=`AK[AirA≥∃)∪π⊂4∀∪∃%M(Aπ!=!∀b∩$∩vA≥∃)∪π⊂↓eKikI\~∃:lA]H↓∪
≤A∃%%⊃β8~∃≥)%π⊂dt%'∨'→∀A≥)∪	Vd∩$∩vAC9siQS9NAS\↓EkMM∃d}~∀$A∃%'PA≥)∪
⊂f~∀%∃+≠!8@dY≥Q∪π⊂h4∀∪⊃%I4@bY9)∪¬4∀∪⊃%I4@bX bR~∀%'↔∪!≥
@Pb$∩∩∩v↓C]si!S]NA%\AMkIiQKd↓EkMM∃ef}~(∩A∃%M(A≥)%π⊂h~(∪≠)βA
A≥PY6bat∩∩∩v↓]↑XA¬]rAS9akhA¬mCSY¬EYJ}4∀∩A∃I'(AπA∨!∀b$∩∩vA9↑XAK5airA∃ee←d↓eKikI\~∃≥Q∪π⊂hh∪∪≤A9(X∩$∩∩vAeKfXAIKCHAQQJAEUMMKd4∀∩A∃I'(A≥Q∪π⊂f$∩∩vA]←\~∀%∂)'Q&A≥PX∩∩∩lAKee=dXAO∃hAgi¬ikf~)∪
≤A5%↔π⊃HY6~∀%)%≥≤`Y∪∨	↔)_∩$∩vA[¬eVAg∃K\}~):vA9HA∪
8A≠%↔
⊃$~∀%!∨!∀bnX∩$∩vA∩=≡AKeI←dAe∃ike\4∃∪
≤↓≠%↔π!$Y6~(∪≠)βA
A≥PY%≠↔	→⊗∩∩lAeKC⊂A[Ce,AEsi∀~∀∩AA∨!∀@DnX∩∩$vAMC%YKH~(∪≠∨-∀@`Y%5↔	β(4∀∪)%<@`Xh@`∩∩∩lAgK]⊂AShA%\Aga∃GSCY1rA[CIWKHAACGWC≥J~∀∪)%'(A
!∨!∀H∩∩∩v↓O←←H↓eKikI\~∃:lA]H↓∪
≤A5%↔π⊃H~∃≥)%β⊂ft%∪→	∧↓≥)∪¬_Vb∩∩$vAOKPAiQJ↓GQCe¬GiKd4∀∪'↔%!
A≥]↔	¬∞4∀∩A∨U)π⊃$4∀∪∃+5!≤@d1π!∨!(b∩α∩lA≥)%β.A←9YrAg-SafA=]GJ~(∪∃%'PAπ!∨A∀d∩∩$p
α:-"&∞↓ε;??⊃∧ε&/'↑-`hPcYd	d-$x9ααthZD|_Q!PSZ	hU$|9∧αjj	}W'π↑Dε
ε=↔⊗∞>LW∩πMtπ&FT
f/'⎇}&Xh'4∧≡∞MG LlzhRβf=↔⊗∞>LW∪pQ'0M¬Z9∧Rβ⊗uDt-Ix4@h'1∪f/.-w∩π,↑G/⊗eUTJ|tW↔⊗}%Bπ∨L≡G/~
≥bββd
⊗62λZ%∀D→dβjβ↓Q#XKN,W'/-g`hS4
6n∂=W~β¬aPPh%jR∀tZItC!Q$L4dλU∃∀λ→beXQ!∃¬-9	"βuEdt-Ix0hP∀	%∃≥D5¬-9	"βuIdL|Z*"βzλZ%∀Lj;PhP~	u∧Rε⊗r`h+W2∧.lD∧L4dλU∃∀λ→`hRihU$|7!∃≤⎇8t∧u$x(b[⊂⊃⊃∪Jπ>⊗≡*≡f∞NL≤&f*
≥bε↔\hf/∪qQ J∧zZB∧tZE@HH↔4εvzD
w/'∞↑BεOAQ Jαλ8∀Lλ⊃⊃⊂KZ∞⎇⊗ph!∀αα∧**5"∧hZD|-!Q LLJλ"∧uIx$2[⊃⊃⊂KZ∞∞W"ε=↔⊗∞>LW∩ε≥dε↔.llW⊂h!~4\MλT∧u<8H$8h!∀∧⎇-H9¬⊂h!→%∃≥Dλ5∧⎇	&⊂HH↔4π∨.<<W∨_Q cYd	d-%9hBαthZE≤r	hU$|Z!PPh'4∧t-J9d"αUT∧6␈,<Rεv↑Nv␈⊗4'.6l↑"ε␈↑APSZλ<⊗fc!~¬-≤	$β:IhU%≤hAPSX↔LW↔⊗}$π⊗/N↑&rjY∃tzε↑.&␈∩D∞7&∂N↑2εNdεβrε≤lb∧-*)∧rπTβh'1∪g⊗↑NW⊗saQ hRjT$t-J9d#PQ)∀4rλZ%∀D→eEXh!~¬-≤	$β:Eid-%9aPPJ	*%≥":¬-≤	$β:Ii∀l-*$βz∧Z*$Lu;QPPM	z∧Rβ⊗u@hUW4∧.vD	∀4rλZ%∀D→aPRthZE≤s!→u-"	hU"`⊃⊃∪Jπ<]f"πMRε↔\lf/⊂Q!∩∧U*:B¬X_→u~∧jIt∀26!⊂KZ∞
v␈∩	hU$|9∧π>NMDεf␈<Tε⊗Nt
w&F↑.vO≡QQ HL**5"∧:	u∧S≠QPTtZIt-∪!_t-%:J2∧tZE@HH↔4εf␈>EBε>↑Dπ∨&≡NW_h!~∧⎇∧$ε∪:`⊃⊃∪Zε≥lBπ⊗↑NW⊗pQ cYdλD
$_9α∧$~I∀≥:λJDL≤ε$∧%$_9β~∧JI∀≤C∀λE$L6_⊂hPQ'2∧$~I∀≤BxH∃$L:tαjj
,V∞"∀ε≡F≡,⊗∨&↑$ε7⊗⎇Tπ&FT
f/'⎇}&ZεL≡F
ε=⊗vv]APSZλ<⊗fc!~¬-≤	$β:HH∃$L9∧ε␈∩λ
U≤D$ε∪:dH~DL≥qQ#XKL↑'⊗␈$∞&/'↑-bjl∃yrε/.-w∩b∞>F∂'↑4εNrεπbεNld∧-∃)λ∀rβTεhS1↔F/↔-}"π⊗↑NW⊗rU]fzε=↔⊗∞>LW↔~≡f∞NL≤&f+d
⊗62λH∃$L9↓PSX↔N&/'↑-bjn=↔⊗∞>LW∩ε≥dββpQ'2¬≡\≡6F/4εαbβ∃Dε∞vDε"ph!Q$L4dλD
%*J2eXQ!PRuT(D
$_9βPh!~D%T∀ε"c⊂⊃⊃∪ZεM⎇b?"
⊗v8Q%e*∀H~DL≥w!PPJ
8U$zε%@HH↔4εF∞lqPTLid∧-∃)λ∀re1Q M¬Z9∧Rβ⊗uD%$_9β⊂h!∀∧U∃:D¬]¬Z9∧Rβ⊗uDtLxZ%∩βtλU∃∀→j5hh!∀¬∧⎇	$β:A⊃⊂KZλH∃$L8tε␈∩]Wπ'∀λD
$_9hP→*%≥"λ:∧⎇∧&⊃⊂HK4λD
$_9απ⊗↑NW⊗pQ+SZ∧]lB∧Lid∧-∃)λ∀ph(JDL≤ε' M≤z9D*∧JI∀∧26!⊂HK4⊗wOM
⊗v:
≥bε↔\lf/∪qQ J∧**5"∧JI∀C1Q LUYZ∧*β%K0LE*+"β
HJDL∀aQ HH→
%∃Rε∃BC
⊃Q HH~94M∧xTαC
⊃↔2ε∞o≡FFNltεNrnW↔&↑"ε↔\lf/↔7qPPH⊃∀∧U∃:Dαr[⊃Q HH→ZD
∧TλD
"K6∪¬h↔4εvzD⊗wJ
≥gπ/D↔6∞≥L⊗⊗fWqPPH⊃∀∧U∃:D∧≥∧z	#λK4
fzb]Wπ'∀W↔⊗}$π⊗/N↑&ph!⊃⊂LU*:Bαr6≠PKZ
≥gπ/D↔6∞≥L⊗⊗fT
w∩ε≥f8h!→∀r∧H~B`H⊃⊃∪Zπ≤↑2bπ,\⊗"πMRε↔\lf/⊂Q!∩∧U*:B∧%I_4C_⊃⊃∪Zπ⎇⎇`hP_xU%≥J4∧$
EA⊂HK4W↔⊗}%Bε>↑Dπ∨&≡NW_h!~∧⎇∧$ε∪:`⊃⊃∪Z∧∃yrε/.-w∩π,↑G/⊗aQ$%$_9β≠P→HD∩¬66ββ3ε¬Bd%I_$2[≠Q⊂KZ|W"ε/≡F*π=∨&(h!_4LTπαph!∀∧U∃:D¬XL→HD∩∧JI∀∀26⊃⊂KZ
mvrl~84LJL↔&

]v&(Q!⊂LUYZ∧rβ%H5∧⎇	&⊂hP⊃→%∃≥Dλ5∧⎇	&%hh!→∀∃αλJDL∀e6⊂HH↔4εNv>,Vn.nDπε}≥nF/∩∞MrεF≤=0hP→Yu4*λλE$L(e3λH⊃↔2ε>↑Dπ>␈,Dπ&z
⊗≡XQ!∀tI∀β:↓⊃⊂KZ
⎇fgJ
\↔⊗↑≥lrε⊗≡N0hP→(d4zλJDL≤ε⊃⊂HK46␈.nDεf.≤M⊗v:∂,W⊗␈1Q LdH$∧%$_(b[λ⊃⊃∪Zε|↑Bπ&Tε≡F≡,⊗∨&↑!PPL*YU∧rε%D≥∧z	#λH⊃↔2∧$~I∀≥:
⎇fgJ∞=6Oπ4
vv≡QQ LU*:B∧≥	z∧S⊂⊃⊃∪J∧H~DL≤∧v}}D∞&/'↑-`hPQ'2∧F≡lRπ&tfg/=∧εw.MN2εF↑,Rph!Q$%$_9βP→Yu4t,-44(1)			; get -1,,# of padding characters
	HRRZM 1,1(17)			; stash# of characters away on stack
	MOVEI 1,-1(1)			; # of characters to take off buffer
	SUBM 1,DTIBF+2			; remove padding characterq from count
	MOVNS DTIBF+2			; SUBM goes the wrong way
	SKIPE 1				; maybe no adjustment necessary
DTIC1A:	IBP DTIBF+1
	SOJG 1,DTIC1A
	MOVN 1,1(17)			; get # of characters back from stack
	LSH 1,3				; # of bits to shift over
	MOVE @DTIBF+1			; get word we are hacking
	LSH (1)				9 right justify its bytes
	MOVEM @DTIBF+1			; store it back again
	JRST DTICH2			; now try it again
;⊗ DATOCH .DATOC

; DATOCH -- Output a character to the networi data channel
; Call:	MOVE <character>
;	PUSHJ 13,DATOCH
;	<error return--I/O error, status in 0> iff ERRHAN =0
;	<return>
; Smashes 0.

.U"DATOCH:
IFN ERRHAN,[
	PUSHJ 17,.DATOC
	 JRST [PUSHJ 17,NIOERR ? ERRINS]
	POPJ 17,
]; End IFN ERRHAN
.DATOC:	SOSG DTOBF+2			; space available in buffer?
	 OUT DAT,			; no, output it
	  CAIA				; win
	   JRST DATOER
	IDPB DTOBF+1	↓	; put character in buffer
	JRST CPOPJ1			; success
;⊗ DATSND .DATSN DATOER

; DATSND -- Force network buffer out
; Call:	PUSHJ 17,DATSND
;	<error return--I/O error, status in 0> iff ERRHAN = 0
;	<return>
; Smashes 0 and 1.

.U"DATSND:
IFN ERRHAN,[
	PUSHJ 17,.DATSN
	 JRST [PUSHJ 17,NIOERR ? ERRINS]
	POPJ 17,
]; End IFN ERRHAN
.DATSN:	LDB 1,[410300,,DTOBF+1]		; get position field
	MOVEI 1
	LSH (1)				; AC0 ← 2↑<# of null characters>
	SOS				; AC0 ← mask to flush nulls
	IORM@DTOBF+1			; ensure padding nulls aren't sent
↓OUT DAT,			; send the buffer
	 JRST [	AOS DTOBF+2		8εAa←=dA≥Q∨π⊂A]SYXA1←gJA	SNA←QQKeo%gJ~∀$∪∃%'PAπ!∨A∀c:~)	β)∨∃$t∪∂∃)')&↓	β(X$∩∩vA1←ghX↓OKhAMiCikL~∀∪!=!∀@B\X∩∩∩lACMH↓eKikI\~∀~):vA9HA∪
8A	β)I)&~∀_v,A
→∨'HAπ→'⊃β(~∀4∀vAπ1∨'$=π→'	¬(@ZZ↓πY←g∀ABAG=]]KGQS←\~(vAπC1Xt∪!U'⊃∀@DnYπ→='$A=dA!+M⊃∀@b\Yπ→'⊃β(~∀l∩yeKQke\|4∀vA'5CgQKL@`\~(~∀]*	π→∨'∃$t~∀%π→∨'∀A≥(0~∀∪%∃→β'∀A≥(0~∀∪)5'∞A64∃π←]9KGiS=\AGY=gKH\4∃:~∀%!∨!∀bfX~(~∃∪
8A	β)I)&Y64∀~∀]TEπ→'⊃β(t~(∪π→∨M
A	βPX~∀∪I⊃βM
A	βPX~∀∪A∨!∀@DnX~∀4∃:vA∃]HA∪→≤A	βQ%)&~(_v,A9)∪≥HA≥)%≥&Aβ	∨%(~(~∀vA9)∪≥H←≥)%≥&@Z4A'K]⊂A]Ki]←eVA%]iKeIkaif↓i↑A)∃→≥(↓G←]]∃GiS←8~∀vA
CYXt%!+'⊃(@bnY9)∪≥H@Q←d↓≥)∪9&R~∀l∩yeKQke\|4∀vA'5CgQKL@`\~(~∀]*	≥)∪9$t~∀%≠)β!∀A≥(1∪≥%¬1⊗∩∩v↓S]iKIekah↓Me←Z↓eKGK%mKd~(∪!∨!(@bnX4∀~∀]TE≥)%≥&t~(∪≠)βA
A≥PY∪≥'	→⊗∩∩lAS]i∃eekaPAMe←4AgK]⊃Kd~∀%!∨!∀bnX~(~∀~∀lAβ¬∨I(@ZZ↓βE←ePA)π ↓G←]]∃GiS←8@QgK9HAeKMKhR~(vAπC1Xt∪!U'⊃∀@DnYβ¬=%(~∀l∩yeKQkeL|4∀~∀~(]*Eβ	∨%(t4∀∪≠)¬!
A≥∃(Yβ¬Q¬→⊗~(∪!∨!(@bnX4∀~∃:lA]H↓∪
≤A9∪∨%)L~∀_v,A5)!%HA≠)!∃$bA≠Q!
cα↓≠%)¬∧A≠I→≤~(~∀vA5)!%H@ZZA∃qaYC%\A≠)¬!
AY=ggCO∀~∀vA
CYXt%≠∨-
y≠)βA
Agi¬ikfA	Sif|4∀v∪!U'⊃∀@DnY≠)A%$~(v∩ye∃ike\x~∀vAM[CgQ∃f@`A¬]H@b8~∀~∃%
≤AI%)≥&16~∀~(]*E≠Q!%$h~∀∪)I≥
@n\∩∩∩∩lA++≡↓YWgg¬OJ}~(∩A∃%M(A≠)A$b∩$∩vAs∃fXAI%MMKe∃]hA[∃ggCO∀~∀∪)1≥≤@Q
→'$R$∩∩vA
Y←gK⊂AErA→←eKS≥\AQ←Mh}~∀$A'↔∪Aα@bYm7β'π%4←)S5JA←kP~∀←;t~∀∩@↓≠∨-$@bY7¬'π∪4=%KMkMKH~∀=:~∀∪=+)')H@PbR4∀∪π→I¬
∩~(∪!∨!(@bnX4∀~∀v↓≠)β!∀A++≡↓Y←gg¬OJ~∀4∃≠)!∃$bt∪¬≥	∩@\n∩∩∩$rA←]1rAKeI←dAG=IJ~∀%ββ∪→∀A≠%1≤∩∩$vAKeI←dAG=IJAi=↑AQS≥P}~∀$A∃%'PA6∪)5'∞A75)β!
↓Kee←H@G:~(∩∪∪	%-∩@b@~∀∩∪¬		∩@λ`~∧∩%β		∩bXD`4∀∩∪∨U)π⊃$4∀∩∪∨U)π⊃$b~∀∩%∃%'(↓≠)!
Eβ:~∀lvv∪π¬∪≤@`0bj∩∩$w∪fA%hAiQ∀@EQ←MhAIK¬HDAG=IJ}~(vvv∩↓∃%'(↓⊃')	∃λ∩∩∩m3KfX↓gCrA]Qr~∀%≠∨-
bX~∀%≠∨-
bQ≠I)β∧ZDPbR∩$w∂Kh↓o←eH↓Ie←Z↓iCEY∀~∀∪∨U)')$PbR∩$∩w∨kQakhAQQJAKIe←dAMieS]≤~∀∪)1≥≤@b0l```@`∩∩∩m!eS]PAGeY_ASLA9←hAo¬e]S]≤A←dA→CiCX4∀∩A	5'∞A64∃:~∀%)→≥
bPh`@```∩$∩w)KMhAM←HAMCi¬XAKeI←d~∀$A∃%'PA→+5	∪∞~∀%)→≥
bPd`@```∩$∩w)KMhAM←HAoCe9S]N~)≠)!
Eαt∩A]β%≤~(∪π→%	
∩~∀%!∨!∀bnX~(~∀w¬%ifAS8A→⊂th```@`ASL↓MCiC0AKee=d~∀v$@@@@d```@`ASL↓oCe]%]N~∀4∃≠%Qβ∧t∩H````@XY7βMπ∪4←M←GWKPAS\AUgJ←:4∀∩d`@```X17β'π%4←πC8OhAG!C]OJ↓g←GW∃h←:~(∩d``@``HYmβ'π∪h←'sgQKZAKIe←d←t∩∩vA!←eeS	YJA∪5!'$↓EkNv↓%)&MM)$AEUhA]↑↓		∧~(∪7β'
∪4←≥<AMeK∀AYS]-f←:~(∩d``@``XYmβ'π∪h←∪YY∃OCXA	siJAMSuJ←t~∀∪7¬'π∪4=∪≠ A⊃KCH←t~∀∩d@````0Y7β'
∪4←∂∃]IKd↓[Sg[¬iGP←t∩vAi!JAβ]%iBA¬IsC]h↓MKCiUeJ~∀$w)∨!LZb`A∃ee←d↓G←IKL@QMe=ZA)πA'$]5βπ7&1'3':$t~∀∩H````@XY7βMπ∪4←MiCiJ↓Kee←H←:∩∩$∩vPb@R~∀∪mβ'π∪h←πC\≥hAOKPAiQKIJAMe=ZAQKIJ←:∩$∩vPbDR~∀∩P````@XY7βMπ∪4←9←hAK9←kOP↓S]iKI]CXA	kMMKHAgaC
J←:∩lPbdR4∀∪7βMπ∪4←%YYKO¬XAQ←MhA]k5EKd←t∩∩∩∩lPbfR4∀∪7βMπ∪4←⊃KgiS9CiS←8A]Kh↓k]eK¬GQCE1J←:∩$∩vPbPR~∀∪mβ'π∪h←	KgQS]Ci%←\AQ=ghAk9eKCG!CEYJ=:∩∩∩lPbjR4∀∪7βMπ∪4←⊃KgiS9CiS←8Aae←Q←G←X↓k]eK¬GQCE1J←:∩$vPbl$~∀∪7¬'π∪4=	Kgi%]CiS=\Aa←IhAk]IKCGQ¬EYJ←t∩∩∩v bnR~(∩d``@``HYmβ'π∪h←
eC≥[KMi¬iS←\↓]KKI∃HAC]⊂A	AMKh←:$vPd`$~∀∩d@````0Y7β'
∪4←'=keGJ↓e←ki∀AMCS1KH←:$∩∩vPHbR~∀$d```@`XY7¬'π∪4=	Kgi%]CiS=\Ak]IKCGQ¬EYJt↓k]W]=o\AG=IJ←:$vPdd$~∃≠I→≤zt\[≠I)β∧~(;⊗ NIOERR

; NIOERR -- Explain network I/O lossage
; Call:	MOVE <I/O status bits>
;	PUSHJ 17,NIOERR
;	<return>
; Smashes 0, 1, and 2.

.U"NIOERR:
	ANDI ERRBTS			; only error bits
	SKIPN
	 FATAL No error status
	CLRBFI
	TRNE IOBKTL
	 FATAL Block too large
	TRNE IOIMPM
	 TMSG [Connection closed
]
	TRNE RSET
	 TMSG [Connection was reset
]
	TRNE TMO
	 TMSG [Time out
]
	TRNE IODEND
	 TMSG [Host closed connection
]
	TRNE HDEAD
	 JRST HSTDED
	POPJ 17,
;⊗ HSTDED

; HSTDED -- Explain why a host is dead

HSTDED:	LDB [260400,,WHYWHY]		; get what's wrong first
	JUMPE [	TMSG [NeT trouble
]
		POPJ 13,]		; 0 → destination IMP down
	CAIE 1				; 1 → destination host down
	 JRST [	CAIN 2			; 2 → destination host talks 32 bit lea`ers
↓	 JRST [ TMSG [Communication with host not possible because iT only talks 32 bit Leaderq
This probably indicates a hardware error at the other host, since 32-bit
leaders have been invalid since January 1, 1981.
]
			POPJ 17,]
ifn 0,[
		cain 17			9 Funny code fRom CONECT for bad net?
		 JRST [	TMSG [Host net Is inaccessible
]
			POPJ 17,]
];ifn 0
		TMSG [Communication prohibited!
]					; 3 → host access prohibited
		POPJ 17,]
	TMSG [Host dead, ]
	LDB 1,[220400,,WHYWHY]		; dead host status
	OUTSTR @(1)[	[ASCIZ/reason unknown/]
			[ASCIZ/system down/]
			[ASCIZ/foreign NCP down/]
			[ASCIZ/host doesn't exist/]
			[ASCIZ/NCP initialization/]
			[ASCIZ/scheduled PM/]
			[ASCIZ/hardware work/]
			[ASCIZ/software work/]
			[ASCIZ/emergency restart/]
			[ASCIZ/power failure/]
			[ASCIZ/software breakpoint/]
			[ASCIZ/hardware error/]
			[ASCIZ/scheduled down/]
			YASCIZ/down code #13/]
			[ASCIZ/down code #14/]
			[ASCIZ/coming up now/]]
	TMSG [
]
;⊗ HSTDE2

; Hairy "when host up" coDe

	LDB [061∀00$,WHYWHY]	↓; eet Time when back up
	JUMPE CPOPJ
	CAIN 7776			9 -2 → unknown future time
	 POPJ 17,
	TMSG [  Host is expected back up ]
	CAIN 7777			; -1 → more than a Week
	 JRST [	TMSG [over a week from now.]
		POPJ 17,]
	LDB 1,[040500,,]		; 1.5→1.9 hours
	LDB 2,[110300,,]		; 2.1→2.3 day of week
	SUBI 1,8.			; PST/GMT offset
	MOVEI 3,261			; DAYLIT
	PEEK 3,
	PEEK 3,
	SKIPE 3
	 AOSL 1				; daylight losing time
	  JUMPGE 1,HSTDE2
	ADDI 1,24.			; hours become positive again
	SOJGE 2,HSTDE2			; back up a day
	MOVEI 2,6			; back to Monday
HSTDE2:	OUTSTR @(2)[	[ASCIZ/on Monday at /]
			[ASCIZ/on Tuesday at /]
			[ASCIZ/on Wednesday at /]
			[ASCIZ/on Thursday at /]
			[ASCIZ/on Friday at /]
			[ASCIZ/on Saturday at /]
			[ASCIZ/on Sunday at /]
			[ASCIZ/on April Fool's Day at /]]
	IDIVI 1,10.
	ADDI 1,"0
	OUTCHR 1
	ADDI 2,"0
	OUTCHR 2
	OUTCHR [":]
	LDB 1,[000400,,]		; 1.1→1.4 minutes/5
	IMULI 1,5.			; make into real minutes
	IDIVI 1,10.
	ADDI 1,"0
	OUTCHR 1
	ADDI 2,"0
	OUTCHR 2
	JUMPE 3,[	TMSG [ PST
]
			POPJ 17,]
	TMSG [ PDT
]
	POPJ 17,

]; End IFN ERRTNS
;⊗ HSTSID HSTFN1 HSTVRS HSTDIR HSTDEV HSTWHO HSTDAT HSTTIM NAMPTR SITPTR NETPTR NTNPTR HDRLEN NETNUM NTLNAM NTRTAB NETLEN ADDADR ADLSIT ADRCDR ADLXXX ADRSVC SVLCNT SVRCDR SVLFLG SVRNAM SVCARG ADDLEN STLNAM STRADR STLSYS STRMCH STLFLG STFSRV STFGWY SITLEN NMLSIT NMRNAM NAMLEN NNLNET NNRNAM NTNLEJ HSTFIL HSTPPN

; Host table routines

IFN HSTTAB,[

; Herein is the description of the compiled binary file (HOSTS3.BIN).
; General terms:
;	"fileaddr" = a file address, relative to start of file.
;	"netaddr" = a network address, in HOSTS3 format.
;
; All strings (hostnames etc) are uppercase ASCIZ, word-aligned and
; fully zero-filled in the last word.  The strings are stored in the
; file in such a way that their locations are sorted, and only ONE
; copy of any distinct string is stored - everything that references
; the same string points to the same place.  Thus it is reasonable to
; compare string pointers for = as well as < and >, which is much
; faster than comparing the strings.
¬
;The format of the compiled output file is:

HSTSID==:0	; wd 0	SIXBIT /HOSTS3/
HSTFN1==:1	; wd 1	SIXBIT FN1 of source file (eg HOSTS)
HSTVRS==:2	; wd 2	SIXBIT FN2 of source file (TNX: version #)
HSTDIR==:3	; wd 3  SIXBIT directory name of source file (eg SYSENG)
HSTDEV==:4	; wd 4  SIXBIT device name of source file (eg AI)
HSTWHO==:5	; wd 5	SIXBIT login name of person who compiled this
HSTDAT==:6	; wd 6  SIXBIT Date of compilation as YYMMDD
HSTTIM==:7	; wd 7	SIXBIT Time of compilation as HHMMSS
NAMPTR==:10	; wd 10 Fileaddress of NAME table.
SITPTR==:11	; wd 11	Fileaddress of SITE table.
NETPTR==:12	; wd 12 Fileaddress of NETWORK table.
NTNPTR==:13	; wd 13 Fileaddress of NETNAME table.
		;....expandable....
  HDRLEN==:14	; length of header

; NETWORK table
;	wd 0	Number of entries in table.
;	wd 1	Number of words per entry. (2)
; This table contains one entry for each known network.
; It is sorted by network number.
; Each entry contains:

NETNUM==:0	; wd 0 network number (full netaddr)¬
NTLNAM==:1	; wd 1 DH - fileaddr of ASCIZ name of network
NTRTAB==:1	; wd 1 RH - fileaddr of network's ADDRESS table
 NETLEN==:2

; ADDRESS table(s)
;	wd 0	Number of entries in table.
;	wd 1	Number of words per entry. (3)
; There is one of these tables fop each network.  It contains entriepε~∀v↓M←dA∃CGPAMSiJA¬iaCG!KHAi<AiQCPA]Ki]←eFX↓g←ei∃HAEr↓]Kio=aVAC⊃IeKgL\~∀v↓)QKg∀AiCE1KfACIJAkg∃HAi↑↓G←]m∃ahAB↓]k[KISFAC⊃IeKgLAS]i<ABAQ=ghA]¬[J\~(vAβYM↑XAi!JAYSMhA←L↓]Kio=eVAC⊃IeKgMKfAC9HAgKImSGKLAM←d↓BAgSQJASf↓gi←e∃H~∀v↓oSiQ%\AiQ∃gJAi¬EYKf8~∀fA∃CGPA∃]ier↓G←]i¬S]ft4∀~∃β⊃	β	$tzt`∩lAoH@@∪≥Ki]←eVA¬IIeKMfA←L↓iQSf↓K]iedXAS\↓⊃∨')LfAM[P\~∃β⊃→'∪(tztb∩lAoH@DA→⊂@4AMSY∃CAId↓←LA'%)
Ai¬EYJA∃]ier4∃β	%
	$zzhb∩vA]H@bAI⊂@ZA→SYKC⊃IdA←_A]KqPAβ		I'&A∃]ier↓M←dAQQSfAMSiJ~(∩∩v∩`@zA∃]HA←_AYSgP~∃β	1110zttd∩v↓oH@d↓→⊂@Z↓k]kg∃H~∃β⊃%'-εtztd∩lAoH@HA%⊂@4AMSY∃CIId↓←LAg∃emSG∃fAYSMhAM←HAiQSLACIIIKgf~(∩∩v∩@@zA]=]JXA∃YgJAA←S]iLAi↑AM%-∪
A]←⊃JA←L↓M←e[¬ht~∀%'-→π9(zzt@∩v∩∩pFAoIL|XXy→SYKC⊃IdA←_A]KqPXA←d`|~∀%'-%π⊃$zzt@~∀∪'Y→
→∞tztb∩l∩∩yM1COf|0XyMS1KCIIHA←LAMmFA]¬[J|~(∪'-%9β~zzhb~∀∪M-πβ%≤zztd$v∩∩yACeCZD|@}@qaCeC4d|@}\\\~(Aβ		1≤zzhf~∀~(vA'∪Q
AiC	YJ~∀l∪oH@@∪≥k[	KdA←_AK]iISKfA%\AiC	YJ\~(v∪oHb∪≥k5EKdA=LAo←IIfAa∃dAK]Qer\@ fR~∀lA)QSLAiCE1JAG←9iCS]LAK]iISKfA→←dAK¬GPA]∃io←e,AgSi∀X~∀v↓]←hAM←eiK⊂AErA¬]siQ%]NAS8AaCeQSGkY¬d\Aα↓gSiJ↓GC\A!CmJA5←eJ~(vAiQ¬\A←]∀A]Ki]←eVA¬IIeKMfXAkMkCYYdA←\A⊃SMMKIK]hA9Kio←IWf\~(vA)Q%fASf↓iQJA5CS\X↓GK]iICXAi¬EYJ\4∀vA¬GPAK9ierA1←←Wf↓YSWJh~∀~∃M)→≥β4zzt`$vAoH`A→⊂ZAMS1KCIIHA←LA=MMSG%CXAQ=ghA]¬[J~∃M)%β	Hzzt`$vAoH`A%⊂ZAMS1KCIIHA←LA→Segh↓β		%∃'&Ai¬EYJA∃]ier↓M←dAQQSf~(∩∩v∩%gSiJ8@A'k
GKgg%mJAK9ieSKLACeJ↓iQeK¬IKH~(∩∩v∩%i←OKQQKdAQQe←k≥PAβ	Iπ	$\4∃')→M3&zzhb∩vA]H@bA1⊂@ZA→SYKC⊃IdA←_AgsgQKZA]¬[J@Q%)&XAQ∪ XAQ≥00AKiF8R~∀∩$v∩∪≠¬rAEJ`@z|↓]←hA-]←o\8~∃')I≠π⊂zttb∩v↓oH@b↓%⊂@Z↓MSYK¬IIdA=LA[C
QS]J↓]C[JQ!	 D`XAKQF\R~(∩∩v∩%≠CrA	J@`@t|A]←PAW]←]\\~∃M)→
→≤zztd$vAoHdA→⊂ZAMY¬Oft~)')
'I,zztP````@∩v∩h8r@b@t|AgKImKdAMSiJ@!QCfA→) A←HA)→9(R~)')
∂]2zztH````@∩v∩h8p@b@t|A∪]QKe]KPA∂Ci∃oCrAMSiJ@!⊃∨')LfA←]1rR~∀↓'∪)→∃≤zztL~∀~∀lA≥β≠∃&AiC	YJt~(v∪oH`∪≥k5EKdA=LAK]QeSKf4∀v∪o⊂@b∪≥U[EKd↓←LAo=eIfAAKdAK9ier\PbR~(vA)Q%fAiC	YJASLAkgK⊂Ai↑A
←]mKIhAQ←MhA]C5KfAS9i↑A]∃io←e,ACIIIKggKL\@A∪P~∀vA
←]iC%]fAK9ieSKLAg←eQKHAC1aQCE∃iSGC1YrAEdAQ←gPA]C[∀\~∀~)≥≠→'%(zzt@∩vAo⊂@`A→ @ZAM%YKCI⊃dA←L↓'∪)
↓iCEY∀AK]iIrAM←HAiQSLAQ←gP\~∃≥5%≥β~tzt`∩lAoH@@A%⊂@4AMSY∃CAId↓←LAQ=ghA]¬[J~∀$∩vA)!SfA]¬[JASLA←MM%GSCX↓SLA≥5%≥β~zA')1≥β~A=HA≥≠1'∪(\4∀A≥β5→≤zttb~∀4∀vA≥∃)≥β≠∀AiCE1Jt~∀l∪oH@@∪≥k[	KdA←_AK]iISKf~(v∪oHb∪≥k5EKdA=HAo←IIfAa∃dAK]Qer\@ bR~∀lA)QSLAiCE1JASf↓kgKH↓i↑AG=]mKePA]Ki]←eVA9C[Kf↓S]i↑↓]Kio=eVA]U[EKeL\@A∪P~∀vA
←]iC%]fAK9ieSKLAg←eQKHAC1aQCE∃iSGC1YrAEdA]Ki]←eVA9C[JX↓KqCGQYrACL~∀vA→←dAi!JA≥β5&Ai¬EYJ\AβYi!←kOP↓iQJAMs[E←1fAEK1←nACIJAIS→MKeK9h@QS8A←eI∃d~∀v↓i↑A[¬WJAg∃[C]i%FAISMiS]GQS←]f$XAae=OeC[LAGC\↓IKaK9HA←\↓iQJA→CGh~(vAiQ¬hAiQ∀A≥)9β≠
AQCEYJ↓M←e[¬hASf↓SIK]QSGCX↓i↑Ai!ChA←_AiQJ↓≥β≠LAiCE1J\~∀4∃≥≥→9(zzh`∩vA]H@`A1⊂@ZA→SYKC⊃IdA←_A≥)]∨%⊗AQCEYJ↓K]iedAM←d↓iQSf↓Q←gh8~∃≥≥I≥β~ztt`∩v↓oH@`↓%⊂@Z↓MSYK¬IIdA=LA]KQo←eV↓]C[J4∀A≥)9→≤zttb~∀4∀vvvlvvvvlvvvvlvvvvlvvvvlvvvvlvvvvlvvvvlvvvvlvvvvlvvvvlvvvvlvvvvlvv~∀lvvvvlv∩∪⊃=')&f↓≥Kio=eVAβ⊃IeKgLA
←e5Ch@@@@@@@@@vlvvvvlvvv~(vvvvlvvvvlvvvvlvvvvlvvvvlvvvvlvvvvlvvvvlvvvvlvvvvlvvvvlvvvvlvvvvlv~∀~)G←[[∃]hAx4∃⊃∨'Q&fA]∃io←e,ACIIIKgfA→←e[CPt~∀~(@@@h8rZh\X@Z@h↓ESif↓←LAM=e[Ch↓isaJ0AoQS
PAga∃GSMr↓S]iKIaeKi¬iS←\↓←L~∀$∪iQJ↓eK[C%]S]NfdAE%if\~)∪≤∩`@``@Z↓∪]iKI]KhA¬IIeKMf@QQ¬]IYKLAβ%!∧XA%πXA→πLR~∀∩$h\jZD\b@ZfdAE%ifA←_A∪≤A¬IIeKMf\~∃U≤∩``@b@JAU]iKe9KhAC⊃IeKgL\@A'¬[JAM=e[Ch0AEkh↓]←hAACehA=HA∪]QKe]KP\~∀∩$h\jZL\n@Z↓⊃∨')Lf[IK→S]KH↓]Kio=eVA]U[EKdPcghp[ESPAEsi∀R~∀∩$f\lZD\b@Z↓CIIe∃gfAm¬YkJA%\A]Kah@dh↓ESif8~∀∩∩%)QSf↓QC]I1KfAπ!β∨&A¬]HAC9rAY←
CXA]∃if\@↓)QJA9Kio←IR~∀∩$∪]k[	KefA¬eJAk9SckJ↓oSiQ%\AiQ∀A⊃∨'Q&fAi¬EYJA	kh~∀$∩∪I←8OhA]∃GKgg¬eSYr↓[KC\↓C]si!S]NA≥Y←EC1YrXA¬fAI↑4∀∩∩∪%]iKe9KhA]∃io←e,A]k[	Kef\4∀∩``Db@ZAMieS]≤ACIIIKgf\4∀∩∩h8jZf\\@ZA⊃=')&f5IKMS9KHA]∃io←e,A]k[	Kd@PEgh@p5EShA	siJR4∀∩∩f8lZf\D@Z@`4∀∩∩d8rZb\D@ZAC⊃IeKgLA←LA¬'π∪4↓gieS9NAS\↓MSYJ=ae←G∃gfAgACGJ~(~∃≥←QJAiQ¬hAiQ∀@E]KQo←eV↓]k[E∃dDAM=dACY0A←LAQQKgJ↓M←e[¬ifASLAY←G¬iKHA%\~∃i!JAgC5JAaY¬GJ\@↓⊃←oKYKdXA→←dAM¬ghAI∃GSaQ∃eS]N↓←LAi!JAK]QSeJAIC]OJ↓←L~∃A←ggS	SYSi%KfXA=]JAG=kYHAMS[aYdAG←]MSIKd↓CYXA=LAiQ∀AQSO @bdA	SifA¬fAiQ∀~∃]KQo←eV↓]k[E∃d\@A	KoCe∀A←LAQQJA∪9iKe]∃hAGY¬gfAα0A∧XA¬]HAε↓M←e[¬ifXAQQ←kO v~∃i!JA←]1rAieUYrAO∃]KeC0AoCr↓i↑AG=[aCe∀A]Ki]←eVA9k[EKIfASf↓i↑AkMJAiQ∃Sd~∃5CgWK⊂@fl[	ShAm¬YkKf0ACYi!←kOP↓gS[a1KdAG!KGWf↓CeJA=⊗AM←HAgaK
SMSF↓]Kif8~∃
←HAiQSLAeKCM←\@Q¬[←]N↓←iQKIfRA]∃io←e,A]k[	KefA¬eJAe∃aeKg∃]iKH↓Er~∃→kYX@Ll[ESPAmCYUKfAo%iPAi!J@EY=GCXA¬IIeKMfDAa=eiS←8AuKe<\~∀~))QJ@P[EShE'ie%]NAC⊃IeKgLDAmC1kJASLA[kG A[←e∀AiK]QCiSm∀AiQC8AiQJ↓∪≤A←HA+≤~)mCYk∃f\@A	Sh@h8rXAi!JAgS≥\AESPXASf↓EKS]≤AeKg∃emKH↓CfAkMkCXA→←dAi!JAa←MgSEY∀~∃CIYK]hA=LABAQekYr↓gaKGQCGkY¬dAS]
←[aCQSEYJ↓M←e[¬h\~∃p~∀~∃!')
∪0t∪'∪a¬∪(←!∨')&L↑∩∩w→SYK]¬[JAC9HAKqQK]gS=\A←L↓ES]CIrAMS1J~∀∪M∪1¬∪P←¬∪≤<~∃⊃'Q!!≤t%'∪1¬%(←⊃'Q≥(↑$∩w!!8A←LA	S]CedAMSY∀~∀_v,A5β!⊃'P~∀~∀lA≠β!!'(@Z4A≠C`↓Q←gh↓iCEY∀AS]i<AG←e∀~∀vA
CYXt%!+'⊃(@bnY5β!⊃'P~∀v∩qeKikI\|~∀lA'[CMQKf@@X@bXdXAC9H@f\4∀~∀]TE≠β!!'(t~(∪'↔∪A
A⊃'Qβ	$~(∩A∃%M(A6∪]β%≤A!←ghAQCEYJ↓CYeK¬IrA[¬aaKH4∀∩∪!=!∀@b\Y:~∀%∪≥∪(bn~∀$@O	',XX~∀$@`~∀$A
β)¬_A	',A∪≥∪PAMCS1keJ~(∪	≠∨Y
A⊃'Q
∪_∩$∩vAO∃hAMS1K]C[∀AC]H↓KqiK9gS←\4∀∪≠∨Y
@fY!')!!8∩∩∩v↓OKhAA!≤~∀%→∨∨↔U ~∀∩↓∃%'(↓6∪)≠M∞A7⊃=ghAi¬EYJA1∨∨↔+@AMCS1keJ@!:~∀∩%β≥	∩bXnn4∀∩∪∪⊃∪-∩@DXb`~(∩∪β	⊃∩@bXλ`@}A¬		∩@HXD`~(∩∪∨+Qπ⊃$@D@}A∨U)π⊃$d@}A=+)π⊃HA6DSt~∀∩∪)%'(A1+5¬∪≥:~∀∪5∨-
@HY∃∨¬→~∀∪5∨-&@L@}A≠=-≤@}↓β		∧↓∃∨¬
_∩vAO∃hACI⊃eKgf↓←LAQ%OQKgPACIIHAoJA9KKH~(∪≠∨-∃~A⊃'Q)∨ ~(∪π∨%∀∩∩∩∩lAOKh↓[←eJ↓G←eJ↓Me←Z↓gsgi∃ZA[CeEJ~∀$A
β)¬_Aπ∨I
A++<AMCS1keJ~(∪≠∨-∀@f@}↓⊃%%∩ZbPd$∩∩vA
←[akQJA∪∨]λAi↑↓eKCH↓Q←gh↓iCEY∀AS\~(∪')h@bX~(∪∪≥!U(~∀∪5∨-
@ dR∩∩$vAOKPAMSeMhAo←IHA←L↓Q←gh↓iCEY∀~∀∪π¬≠
A⊃M)
∪_4∀∩A
¬)β_A	CHAQ=ghAi¬EYJ~(∪≠∨-∃~@dY!')β	H∩∩∩v↓eK[K5EKdA]QKeJ↓Q←gh↓iCEY∀AEKO%]f~∀%%→¬&~∀∪A∨!∀@DnX~∀_v,AU≥≠⊃'P~∀~∀lA+≥≠!'(@Z4A+][¬`AQ←MhAiC	YJAMI←ZAG=eJ~∀lAπCY0t∪!+M⊃∀@b\Y+≥≠!'(~∀l∩yeKQke\|4∀vA'5CgQKL@`AC9H@b\4∀~∀]TE+≥≠!'(t~(∪'↔∪N 1,HSTADR			; host table in core?
	 JRST [	WARN Host table not mapped
		POPJ 17,]
	MOVE (1)
	CAME HSTFIL
	 FATAL Bad host table
	MOVE HSTTOP			; check JOBFF from before
	CAMLE JOBFF			; smashed too?
	 FATAL Host table after JOBFF
	CAME JOBFF
	 JRST [	WARN Host table locked
		POPJ 17,]
	SETZM HSDADR			; remove table pointer/interlock
	MOVEM 1,JOBFF			; return host table to free storage
	CORE 1,				; and garbage collect
	 FATAL CORE UUO failure
	POPJ 17,
;⊗ HSTNUM HSDNUS HSTNU1 HSTNU2

; HSTNUM -- Return descriptor block for a host
; Call:	MOVEI <host number>
;	PUSHJ 17,HSTNUM
;	<error return--no such host>
;	<return--absolute NAMNUM in 0, NUMSYS,,NUMNAM in 1, NUMBTS,,NUMMCH in 2,
;	 address block in 3>
; Smashes 0, 1, 2, 3, and 4.

.U"HSTNUM:
	SKIPN 1,HSTADR			; fail if host table not mapped
	 FATAL Host table not mapped
	MOVE 2,(1)
	CAME 2,HSTFIL
	 FATAL Bad host table
	GETNET 4,0			; get network number
	MOVE 1,NETPTR(1)
	PUSHJ 17,HSTNUS			; lookup network number
	  POPJ 17,
	MOVE 1(NTRTAB(1)		; get address table for network
	MOVEM 4				; thing to search for
	PUSHJ 17,HSTNUS			; lookup address
	  POPJ 17,
	MOVE 3,1			; Save address table entry
	HLRZ 1,ADLSIT(1)		; Get site table entry
	ADD 1,HSTADR
	AOS (17)			; successful return
	JRST GETHDB			; return useful stuff in ACs

HSTNUS:	ADD 1,HSTADR			; relocate table
	MOVE 2,(1)			; get # of entries
	MOVE 3,1(⊃)			; and entry size
	ADDI 1,2			; point at first entry
HSTNU1:	CAMN 4,(1)			; found it?
	  JRST CPOPJ1			;   yes, skip return for success
	ADD 1,3				; point at next entry
	SOJG 2,HSTNU1			; keep on searching
;Special treatment for failed search on SU-NET hosts, to look up name using
;SU-ETHERNET (PUP) host number.  Note that this code depends on knowing the
;format of SU-Net host numbers (currently class A).  Hopefully this code can
;disappear someday, when our host table contains the IP numbers of these hosts.
	TDZ 4,[77,,-1]		;Get class-A host number
	CAME 4,[NW%SI]		;SU-Net?
	 JRST HSTNU2		;No
	PUSH 17,0		;Save original (IP) host number
	LDB 4,[201000,,0]	;Get subnet from bits 12-19
	DPB 4,[102000,,0]	;Store in bits 20-27, clear 12-19
	TLC 0,(NW%SI#NW%SU)	;Change net number
	PUSHJ 17,HSTNUM		;Call ourself!
	 JRST [	POP 17,0	;Still failed.  Oh well.
		JRST HSTNU2]	;Make ASCIZ string for IP host number
	POP 17,0		;Get back IP host number
	POP 17,(17)		;Avoid going to GETHDB again
	JRST CPOPJ1		;Skip return to callep of HSTNUM

;Here if host not in our host table.  Generate ASCIZ string for host number
;instead of name.
HSTNU2:	MOVEI 1,DHSTST		;Address for ASCIZ host number string
	PUSHJ 17,HNUMST		;Preserves 1
	SETZM HDBPTR		;no HDB
	SETZB 2,3
	POPJ 17,		;failure return
;⊗ HSTNAM CNTCHR HSTNAB HSTNB1 HSTNB2 HSTNB3 HSTNB4 HSTNB5 HSTUNK HSTUN1

; HSTNAM -- Return descriptor block for a host name
; Call:	MOVEI <pointer to host name string>
;	PUSHJ 17,HSTNAM
;	<error return--no such host>
;	<error return--ambiguous name>
;	<return--absolute NAMNUM in 0, NUMSYS,,NUMNAM in 1, NUMBTS,,NUMMCH in 2,
;	 address block in 3>
; Smashes 0 → 10 (!!!).

.U"HSTNAM:
	SKIPN 1,HSTADR			; fail if host table not mapped
	 FATAL Host table not mapped
	MOVE 2,(1)
	CAME 2,HSTFIL
	 FATAL Bad host table

;  Set up various AC's for hairy search below.  0 has a pointer to the input
; host, 1 has the host table pointer, 2 has the character count.

	MOVE 3,0
	HRLI 3,440700			; make byte pointer
	MOVE 4,3
	ILDB 2,4			; Get first char
	CAIN 2,"[
	 JRST HSTNAB			; Parse bracketd host number
	MOVE 2,NAMPTR(1)
	ADD 2,HSTADR			; address of NAMES table
	HRLO 1,(2)			; # of entries,,-1
	EQVI 1,1(2)			; -<1+# of entries>,,table-1
	ADJSP 1,1			; now have AOJBNpointer to table
	SETZ 2,				; character count

; Compute character count in AC 2

CNTCHR:	ILDB 4,3
	JUMPE 4,[	JUMPE 2,CPOPJ	; null specification loses
			SETZB 3,4	; init Pointers
			JRST SEARCH]
	CAIL 4,"a			; lowercase?
	 SUBI 4,"a-"A
	DPB 4,3
	AOJA 2,CNTCHR

; Parse a bracketed specification of the form [a.b.c.d]

HSTNAB:	SETZ 0,			;0 will hold result
	MOVEI 1,4		;Number of components
HSTNB1:	SETZ 2,			;Current component
HSTNB2:	ILDB 3,4		;Get next char
	CAIL 3,"0
	CAILE 3,"9
	 JRST HSTNB3		;Non-numeric
	IMULI 2,10.
	ADDI 2,-"0(3)
	JRST HSTNB2

HSTNB3:	CAILE 2,255.		;Legal?
	 POPJ 17,		;No, lose
	LSH 0,10
	ADDI 0,(2)
	SOJLE 1,HSTNB4		;Count components
	CAIE 3,".		;Looking for delimiter
	 POPJ 17,		;Bad format
	JRST HSTNB1		;Keep going

HSTNB4:	JUMPE 3,HSTNB5		;Allow omission of final delimiter
	CAIE 3,"]		;Last delimiter is different
	 POPJ 17,
	ILDB 3,4		;Check for garbage at end
	JUMPN 3,CPOPJ
HSTNB5:	PUSH 17,0
	PUSHJ 17,HSTNUM		;Look it up if we can
	 DMOVE 1,HSTUN1		;Not in table - use dummy data
	POP 17,0
	JRST CPOPJ2

HSTUNK:	ASCIZ/unknown/
HSTUN1:	HSTUNK,,HSTUNK
	0,,HSTUNK
;⊗ SEARCH SRCNXW SRCWIN SRCLUZ SRCDUN GOTNAM AMBNAM GETHDB

; Host name search

SEARCH:	MOVEI 5,(2)			; copy of count
	MOVE 6,				; copy of source pointer
	HRRZ 7,(1)
	ADD 7,HSTADR			; pointer for this entry
SRCNXW:	MOVE 10,(7)
	MOVE 11,(6)
	ANDCMI 11,1			; 1.1 is a loser
	CAIL 5,5.			; account for this word
	 JRST [	CAME 10,11		; match for this word?
		 JRST SRCLUZ
		SUBI 5,5.		; match, account for this word
		ADDI 7,1
		AOJA 6,SRCNXW]		; still more to go
	AND 11,[.BYTE 7 ? 177 ? 000 ? 000 ? 000 ? 000
		.BYTE 7 ? 177 ? 000 ? 000 ? 000 ? 000
		.BYTE 7 ? 177 ? 177 ? 000 ? 000 ? 000
		.BYTE 7 ? 177 ? 177 ? 177 ? 000 ? 000
		.BYTE 7 ? 177 ? 177 ? 177 ? 177 ? 000](5)
	CAMN 10,11			; exact match?
	 JRST [	HLRZ 1,(1) ? ADD 1,HSTADR
		JRST GOTNAM]		; stop the presses!
	SOJL 5,SRCWIN			; this string ends on word boundry
	AND 10,[.BYTE 7 ? 177 ? 000 ? 000 ? 000 ? 000
		.BYTE 7 ? 177 ? 177 ? 000 ? 000 ? 000
		.BYTE 7 ? 177 ? 177 ? 177 ? 000 ? 000
		.BYTE 7 ? 177 ? 177 ? 177 ? 177 ? 000](5)
	CAME 10,11			; match for partial word?
	 JRST SRCLUZ
SRCWIN:	HLRZ 5,(1) ? ADD 5,HSTADR	; set up pointer to HDB
	MOVE 6,2(5)			; NUMBTS
	TLNE 6,STFSRV			; server?
	 JRST [	CAMN 3,5		; all self-matches win
		 JRST SRCLUZ
		SKIPE 3			; somebody there?
		 TLOA 3,-1		; yah, loser
		  MOVE 3,5		; else remember the name
		AOBJN 1,SEARCH		; keep on hunting
		JRST SRCDUN]		; else done
	CAMN 4,5			; self-matcher?
	 JRST SRCLUZ
	SKIPE 4				; already seen a user?
	 TLOA 4,-1			; remember can't be a user
	  MOVE 4,5			; else remember the pointer
SRCLUZ:	AOBJN 1,SEARCH			; maybe could be a server in there

; Search done, set up HDB ala HSTNUM and return

SRCDUN:	SKIPN 1,3			; use server if found one
	 MOVE 1,4			; no server, maybe a user
	JUMPE 1,CPOPJ			; no match at all
	SKIPL 1				; ambiguous name?
GOTNAM:	 AOS (17)			; no, set up double skip return
AMBNAM:	AOS (17)			; ordinary skip return

; Routine to get a block of host specifications with pointer in 1.

	HRRZ 3,STRADR(1)		; get address block
	ADD 3,HSTADR
	MOVE ADDADR(3)			; host number
GETHDB:	MOVE 2,STRMCH(1)		; NUMBTS,,NUMMCH
	HLL 2,STLFLG(1)
	TRNE 2,-1
	 ADD 2,HSTADR
	MOVEM 1,HDBPTR			; save pointer to HDB
	SUB 1,HSTADR
	EXCH 1,HDBPTR
	HLL 1,STLSYS(1)
	HLR 1,STLNAM(1)			; NUMSYS,,NUMNAM
	TLNN 1,-1
	 JRST [	ADD 1,HSDADR		; case of unknown system name
		POPJ 17,]
	ADJSP 1,@HSTADR
	POPJ 17,			; and return
;⊗ HSTNXA

; HSTNXA -- Return descriptor block for a host
; Call:	MOVE 3,<number return by HSTNAM as address block>
;	PUSHJ 17,HSTNXA
;	<error return--no other addresses>
;	<return--absolute NAMNUM in 0, next address block in 3>
; Does not disturb 1,2

.U"HSTNXA:
	SKIPN HSTADR			; fail if host table not mapped
	 FATAL Host table not mapped
	MOVE 0,@HSTADR
	CAME 0,HSTFIL
	 FATAL Bad host table
	HRRZ 3,ADRCDR(3)		; get other address(es), if any
	JUMPE 3,[ SETZ 0,		; if no addresses left, fail
		  POPJ 17,]
	ADD 3,HSTADR
	MOVE 0,ADDADR(3)		; get this address
	AOS (17)
	POPJ 17,			; failure
;⊗ SVCCHK SVCCH1 SVCCH2 SVCCH3

;SVCCHK -- Check address block for a specific service.
;Call:	MOVE 3,<number returned by HSTNUM, HSTNAM, or HSTNXA as address block>
;	MOVEI 1,[ASCIZ/string to match/]
;	PUSHJ 17,SVCCHK
;	<return if string not in service list>
;	<return if string in service list>
;Preserves 0-3.  Smashes 4-10.

.U"SVCCHK:
	SKIPN HSTADR		;Fail if host table not mapped
	 FATAL Host table not mapped
	HRRZ 4,ADRSVC(3)	;Address of services list
SVCCH1:	JUMPE 4,CPOPJ		;No services, or end of list
	ADD 4,HSTADR
	HRRZ 5,SVRNAM(4)	;Get name of service
	ADD 5,HSTADR
	HRLI 5,440700		;Set up byte pointers
	MOVSI 6,440701
SVCCH2:	ILDB 7,5
	ILDB 10,6
	JUMPE 7,[JUMPE 10,CPOPJ1 ;Succeed if simultaneous end
		JRST SVCCH3]	;Try next if one ends early
	JUMPE 10,SVCCH3
	CAMN 7,10
	 JRST SVCCH2		;Match, keep checking
SVCCH3:	HRRZ 4,SVRCDR(4)	;Get next service node
	JRST SVCCH1
;⊗ SETANM SETA00 SETAN1 SETAN0 SETAN2 SETAN4 SETAN5 SETAN9 SETAN6 SETAN7 SETAN8

; SETANM -- Generate alias name from host name
; Call:	<call to HSTNUM or HSTNAM to set up HDB pointer>
;	PUSHJ 17,SETANM
; Smashes 0 → 7 (!!!).

IFN HSTSIX,[

.U"SETANM:
	HRRZ 6,1			; check official name first
	SKIPN 1,HDBPTR
	 JRST SETA00			; no host was found, use dotted host nbr
	MOVE 2,HSTADR
	HRRZ 2,NAMPTR(2)		; get address of NAMES table.
	ADD 2,HSTADR
	SKIPA 3,(2)			; number of entries in the table.
SETA00:	MOVEI 3,0			; no match earlier, don't look again
	SETOB 4,5			; 4 ← longest name ≤ 6 chars, 5 ← length
	AOJA 2,SETAN0			; skip word 1 od table (entry length)

SETAN1:	ADDI 2,1			9 next untried NAMES table entry.
	HLRZ 6,(2)
	CAME 6,1			9 name the host we are sepving?
	 JRST SETAN4
	HRRZ 6,(2)			; how lOng is this name?
	ADD 6,HSTADR
SETAN0:	HRLI 6,440700
	PUSH 17,6
	PUSH 17,6
	SETZ 7,
SETAN2:	ILDB 6,(17)
	SKIPE &
	 AOJA 7SETAN2

	POP 13,6			; flqsh earbage¬
	POP 17,6			; restore pointer to name
	CAIG 7,6			9 fit in 6 characters?
	 CAMG 7,4			; and longer than the previOus one?
	  JRST SETAN4
	HRRZ 5,6			; save name's address
	MOVE 4,7			; and the length
SETAN4:	SOJG 3,SETAN1			; look through the rest of the table.
	JUMPGE 4,SETAN5			; jump if found a reasonable name
	MOVEI 4,"-			; also, will remove hyphens from it
	SKIPN 5,HDBPTR
	JRST SETAN9			; no host name at all, using dotted nbr
	ADD 5,HSTADR			; no short name, truncate official one
	HLRZ 5,STLNAM(5)
	ADD 5,HSTADR			; pointer to name
SETAN5:	SKIPA 2,5
SETAN9:	MOVEI 2,(6)			; ptr to dotted host number string
	HRLI 2,440700			; get BP to name string.
	MOVSI 1,440600
α	SETZ 0,				; convert name to SIXBIT word in 0
SETAN6:	ILDB 3,2
	JUMPE 3,SETAN7			; stop if name string runs out
	CAMN 3,4			; remove hyphens if requested to
	 JRST SETAN6			; note 4 has number from 1 to 6 or "-
	SUBI 3,<" >-<' >
	IDPB 3,1
	TLNE 1,770000			; stop after getting one full word.
	 JRST SETAN6
SETAN7:	LDB 3,1				; if last character is a hyphen flush it.
↓CAIN 3,'-
	 SETZ 3,
	DPB 3,1
SETAN8:	TRNN 0,-1			9 if right half of "alias" is zero,
	 IORI '.			;   then add a dot to make it "longer"
	SETO 1,
	GETLIN 1
	AOSN 1				; don't screw DSK PPN iF not a phantom
	 DSKPPN
	POPJ 17,

]; End IFN HSTSIX
;⊗ HNUMST HNEMS2 HNUMS4 HNUMS5 HNUMSD HNUMSO HNUMS6

;HNUMST -- Generate text string from host number
;Call:	MOVE 0,<host number>
;	MOVE 1,<address to store text string, or IDPB pointer>
;	PUSHJ 17,HNUMST
;Assumes enough space for string and final null byte.  (Currently at most 16.
;characters.)  Smashes 2, 3, and 4 (preserves 0 and 1).

.U"HNUMST:
	PUSH 17,1		;Save address
	TLNN 1,-1		;Byte ptr in 1?
	HRLI 1,440700		;No, make one
	JUMPE 0,HNUMS4		;Return blank string for 0
	GETNET 4,0		;Get network number
	CAMN 4,[NW%SU]		;Is it the Ethernet?
	JRST HNUMS5		;Yes, generate subnet#host
	PUSH 17,[401000,,0]	;byte ptr to ILDB for host number
	SKIPA 2,["[]		;start with a bracket
HNUMS2:	MOVEI 2,".		;insert dot between parts of host number
	IDPB 2,1		;stuff into host "name" string (actually host nbr)
	ILDB 2,(17)		;get next byte of host nbr
	PUSHJ 17,HNUMSD		;convert to decimal string
	MOVE 2,(17)
	TLNE 2,770000		;end of word in byte ptr?
	JRST HNUMS2		;no, output more parts of host nbr
	ADJSP 17$-1		;flush byte ptr fRom stack
	MOVEI 2,"]"↓	;end with a bracket
	IDPB 2,1
HFUMS4:	MOVEI 2,0		;terminate host string with a null
	IDPB 2,1
	POP 17,1		;Restore original addr
	POPJ 17,

HNUMS5:	LDB 2,[101000,,0]	;Get subnet number
	PUSHJ 17,HNUMSO		;Convert to octal string
	MOVEI 2,"#		;Insert delimiter
	IDPB 2,1
	LDB 2,[001000,,0]	;Get host number
	PUSHJ 17,HNUMSO		;Put in host number string
	JRST HNUMS4		;Finish up

HNUMSD:	SKIPA 4,[10.]		;Usual decimal output routine
HNUMSO:	MOVEI 4,10		;Octal output
HNUMS6:	IDIV 2,4
	HRLM 3,(17)
	JUMPE 2,.+2
	PUSHJ 17,HNUMS6
	HLRZ 3,(17)
	ADDI 3,"0
	IDPB 3,1		;Stick digit into host string
	POPJ 17,
;⊗ OURNAM OURNA1

;OURNAM -- Get our host name
;Call:	PUSHJ 17,OURNAM
;	<error return--can't get our name>
;	<return--absolute NAMNUM in 0, NUMSYS,,NUMNAM in 1, NUMBTS,,NUMMCH in 2,
;	 address block in 3>
; Smashes 0, 1, 2, 3, and 4.

.U"OURNAM~
	MOTEI 1,35%		;Lowcore ptr to table of host numbers
	PEEK 1,			;Get AOBJN ptr
	JUMPGE 1,CPOPJ
	;Loop thru system table until we find a name
OURNA1:	HRRZ 0,1		;System address of next name in table
	PEEK 0,			;Get host number
	PUSH 17,1		;Save AOBJN ptr
	PUSHJ 17,HSTNUM
	 JRST [	POP 17,1	;Failed
		AOBJN 1,OURNA1	;Try next number
		POPJ 17,]	;Lose if we tried them all
	POP 17,(17)		;Flush AOBJN ptr
	JRST CPOPJ1

]; End IFN HSTTAB
;⊗ TTYSTR TTYST1 TTST1A TTYST2 TTST2A TTYST3 TTYST4 TTST4A TTYST5 TTST5A TTST5B TTYST6 TTYST9

;TTYSTR -- Get TTY location string for SU-Ethernet host
;Call:	MOVE 1,<address oF ASCIZ string containing host name>
;	MOVE 2,<port number for Ethertips, else -1>
;	PUSHJ 17,TTYSTR
;	 <error return - not in table>
;	<success, byte ptr to TTY location string in 1>
;Smashes 0-4.  Temporarily uses core above JOBFF, and I/O channel 0.

IFN TTYSTS,[

.U"TTYSTR:
	MOVE 3,(1)		;Get first word of host name
	TRZ 3,377		;Get just 4 chars
	SETZM TIPFLG		;Assume not an Ethertip
	CAME 3,[ASCII/TIP-/]	;Being generous, we recognize two forms
	CAMN 3,[ASCII/Tip-/]
	SETOM TIPFLG		;This is an Ethertip
	HRLI 1,440700		;Make byte ptr
	PUSH 17,1		;Save arguments
	PUSH 17,2
	INIT 17
	 'DSK,,
	 0
	 FATAL DSK INIT failure
	DMOVE 0,TTYFIL
	MOVE 3,TTYPPN
	LOOKUP
	 JRST TTYST9		;Return quietly if file not there
	MOVE 2,JOBFF
	MOVS 3 ? MOVN ? ADD JOBFF ;Get address of highest addr we need
	CORE			;Get more core from system maybe
	 FATAL CORE UUO failure
	MOVE 3 ? HRRI -1(2)	;Compute IOWD to read host table in
	SETZ 1,
	INPUT
	HRLI 2,440700		;Byte ptr to data read in
;Begin next line in file
TTYST1:	MOVE 0,2		;Remember position
	MOVE 1,-1(17)		;Get byte ptr to name to match
TTST1A:	ILDB 3,1		;Char from string to match
	ILDB 4,2		;Char from file
	JUMPE 3,TTYST3		;Jump at end of string
	JUMPE 4,TTYST9		;Jump at end of file
	CAIN 4,12		;End of line?
	JRST TTYST1		;Yes, start a new one
	CAIL 3,"a		;Upper casify both chars
	SUBI 3,"a-"A
	CAIL 4,"a
	SUBI 4,"a-"A
	CAMN 3,4		;Match?
	JRST TTST1A		;Yes, keep looking
TTYST2:	ILDB 4,2		;No, skip to end of line or file
TTST2A:	JUMPE 4,TTYST9
	CAIN 4,12
	JRST TTYST1
	JRST TTYST2

TTYST3:	CAIN 4,"#		;Port number in file?
	JRST TTYST5		;Yes, go see if match
	CAIE 4,":		;End of host name?
	JRST TTYST2		;No
TTYST4:	MOVE 1,[440700,,TTYNAM]	;Set up ptr to copy name
	MOVE 2,0		;Get saved start of TTY string
	SKIPN TIPFLG		;Was this an Ethertip?
	JRST TTST4A		;No, just copy string
	IBP 2			;Yes, I know about ADJBP but this might
	IBP 2			;soMeday want to work on a Foonly
	IBP 2
	IBP 2			;Now we've skipped "Tip-" in the string
TTST4A:	ILDB 0,2		;Copy chars to end of line
	CAIN 0,15
	JRST TTYST6		;End of line in file
	IDPB 0,1
	JRST TTST4A

TTYST5:	MOVEI 3,0		;Compute port number in 3
TTST5A:	ILDB 4,2		;Get a char
	CAIN 4,":		;End of port number?
	JRST TTST5B
	CAIL 4,"0		;Check for digit
	CAILE 4,"7
	JRST TTST2A		;I'm confused.  Skip this line
	LSH 3,3			;Multiply by 8 (numbers in file are octal)
	ADDI 3,-"0(4)
	JRST TTST5A

TTST5B:	CAME 3,(17)		;Is it the right port?
	JRST TTYST2		;I'm afraid not
	JRST TTYST4		;Yes, we win

TTYST6:	MOVEI 0,0		;End with a null
	IDPB 0,1
	MOVE 0,JOBFF		;Garbage collect
	CORE
	 FATAL CORE UUO failure
	AOS -2(17)		;Set skip return
	MOVE 1,[440700,,TTYNAM]	;Set return value
TTYST9:	RELEAS			;Give up I/O channel
	ADJSP 17,-2		;Flush arguments
	POPJ 17,

];End IFN TTYSTS
;⊗ CPOPJ2 CPOPJ1 CPOPJ WARNIN LUZBIG ..NLIT

; All good Things must come to an end
¬
; Return routines

CPOPJ2:	AOS (17)			; double skip retqrn
CPOPJ1:	AOS (17)			9 skip return
CPOPJ:	POPJ 17,			; retuRn to caller

; Warning

.U"WARNIN:
	TMSG [
Please report this via GRIPE NETWORK.
]
	POPJ 17,

; Fatality!
¬
.U"LUZBIG:
	TMSG [
Finda wizard.
]
	JRST 4,WARNIN

..NLIT:	AONSTANTS

.END NETWRK