title HOSTAB  Host table printer

;Some kind person should rewrite this piece of shit

ifndef sailsw,sailsw==ife <.osmidas-sixbit/SAIL/>,[-1] .else 0
ifndef t20sw,t20sw==ife <.osmidas-sixbit/TWENEX/>,[-1] .else 0

;Cough bletch
ife sailsw\t20sw,.insrt MRC;MACROS
ifn sailsw,.insrt MACROS[1,MRC]
ifn t20sw,.insrt MACROS

;The format of the compiled HOSTS2 file is:
HSTSID==0	; wd 0	SIXBIT /HOSTS2/
HSTFN1==1	; wd 1	SIXBIT /HOSTS/ usually
HSTVRS==2	; wd 2	FN2 of HOSTS file which this was compiled from.
HSTDIR==3	; wd 3  SIXBIT /SYSENG/ usually, directory name of source file
HSTMCH==4	; wd 4  SIXBIT /AI/ (e.g.), device name of source file
HSTWHO==5	; wd 5	UNAME of person who compiled this
HSTDAT==6	; wd 6	Date of compilation as sixbit YYMMDD
HSTTIM==7	; wd 7	Time of compilation as sixbit HHMMSS
NAMPTR==10	; wd 10 Address in file of NAME table.
SITPTR==11	; wd 11	Address in file of SITE table.
NETPTR==12	; wd 12 Address in file of NETWORK table.
		;....expandable....

;NETWORK table
; wd 0	Number of entries in table.
; wd 1	Number of words per entry. (2)
;This table contains one entry for each network known about, sorted
;by network number.  A network number is bits 4.8-4.1 of a network
;address; these numbers are assigned by Jon Postel.  See symbols below.
;The reason for keeping track of different networks is that the user
;program must make different system calls to use each network.
;Each entry contains:
NETNUM==0	; wd 0	network number
NTLNAM==1	; wd 1 LH - address in file of name of network
NTRTAB==1	; wd 1 RH - address in file of network's address table

;ADDRESS table(s)
; wd 0	Number of entries in table.
; wd 1	Number of words per entry. (2)
;There is one of these tables for each network.  It contains entries
;for each site attached to that network, sorted by network address.
;These tables are used to convert a numeric address into a host name.
;Also, the list of network addresses for a site is stored
;within these tables.
;Each entry contains:
ADDADR==0	; wd 0	Network address of this entry (including network number).
ADLSIT==1	; wd 1 LH - address in file of SITE table entry
ADRCDR==1	; wd 1 RH - address in file of next ADDRESS entry for this site
		;	    0 = end of list

;SITE table
; wd 0	Number of entries in table.
; wd 1	Number of words per entry. (3)
;This table contains entries for each network site,
;not sorted by anything in particular.  A site can have more
;than one network address, usually on different networks.
;This is the main, central table.
;Each entry looks like:
STLNAM==0	; wd 0 LH - address in file of official host name
STRADR==0	; wd 0 RH - address in file of first ADDRESS table entry for this site
		;	    successive entries are threaded together through ADRCDR
STLSYS==1	; wd 1 LH - address in file of system name (ITS, TIP, TENEX, etc.)
		;			May be 0 => not known.
STRMCH==1	; wd 1 RH - address in file of machine name (PDP10, etc.)
		;			May be 0 => not known.
STLFLG==2	; wd 2 LH - flags:
STFSRV==400000	;	4.9 1 => server site (according to NIC)
		; wd 2 RH - not used

;NAMES table:
; wd 0	Number of entries
; wd 1	Number of words per entry. (1)
;This table is used to convert host names into network addresses.
; Followed by entries, sorted by the host name treated as a vector of
; signed integers, looking like:
NMLSIT==0	; lh	address in file of SITE table entry for this host.
NMRNAM==0	; rh	address in file of host name
		;This name is official if NMRNAM = STLNAM of NMLSIT.

; All names are ASCIZ strings, all letters upper case.
; The strings are stored before, after and between the tables.
; All strings are word-aligned, and fully zero-filled in the last word.

;Network addresses are defined as follows, for purposes of this table:
;    4.9     0
;    4.8-4.1 network number
;    Chaos net (number 7):
;	3.9-2.8	0
;	2.7-1.1 address (2.7-1.9 subnet, 1.8-1.1 host)
;    Arpa net (number 12):	(note, old-format Arpanet addresses
;	3.9-3.8	0	 	never appear in the host table.)
;	3.7-2.1	Imp
;	1.9	0
;	1.8-1.1	Host
;    Dialnet (number 26):
;	3.9-3.1	0
;	2.9-1.1	address in file of ASCIZ string of phone number

NW%CHS==7	;Chaosnet
NW%ARP==12	;Arpanet
NW%DLN==26	;Dialnet
NW%LCS==22	;LCSnet
NW%SU==44	;SUnet
NW$BYT==331000	;Byte pointer to network number

ife sailsw\t20sw,[
define TYPE string
 move x,[point. 7,[ascii\string\]]
 movx y,<.length\string\>
 syscal SIOT,[	clarg. tto
		%clarg x
		%clarg y]
  .lose %lssys
termin
]
ifn sailsw,[
define TYPE string
 outstr [asciz\string\]
termin
]
ifn t20sw,[
define TYPE string
 hrroi a1,[asciz\string\]
 psout
termin
];ifn t20sw

acdef. [a1 a2 a3 a4 x y z a b c d tbl]	; accumulators

acdef. [tto htb]			; I/O channels

nd. pdllen==50.				; push down list length

ifn t20sw,.decsav ? loc 140

pdl:	block pdllen			; push down list
;nout sout octout octou1 octou2

; I/O subroutines

; NOUT numeric output
; accepts in x:	base to use for outputting the number
;	     y:	number to be output
; returns:  +1:	always, with y and z clobbered

nout=call .
	idivi y,(x)			; get a digit
	save z				; save the lowest order digit left
	caxe y,%zeros			; got them all?
	 nout				; nope
	retr y				; get a digit to output
	addx y,"0			; convert to ASCII
ife sailsw\t20sw,.iot tto,y		; output it
ifn sailsw,outchr y			; output it
ifn t20sw,move a1,y ? pbout
	return				; and return

; SOUT string output
; accepts in x:	pointer to string (0 in LH means ASCIZ string)
; returns   +1:	always, with updated string pointer in x; 0 & y clobbered

sout=call .
	txnn x,%lhalf			; is there a left half?
	 hrli x,440700			; yes, make it a 7 bit pointer
	movx y,%zeros			; initialize string counter
ife sailsw\t20sw,[
	save x				; save pointer away
	ildb x				; get a character
	jumpn [aoja y,.-1]		; count character if non-null
	retr x				; else restore pointer
	movem y,strlen'			; save string length
	syscal SIOT,[	clarg. tto	; output to TTY
			%clarg x	; string pointer
			%clarg y]	; byte counter
	 .lose %lssys			; ? ? ?
];ife sailsw\t20sw
ifn sailsw,[
	ildb x
	jumpn [outchr ? aoja y,.-1]
	movem y,strlen'			; save string length
];ifn sailsw
ifn t20sw,[
	ildb x
	jumpn [move a1, ? pbout ? aoja y,.-1]
	movem y,strlen'			; save string length
];ifn t20sw
	return				; and return

;Right-justified octal from y, in x columns
;Bash x,z
octout:	jffo y,.+1			; haulong
	subi z,36.
	skipn z
	 movni z,1
	subi z,2
	push p,z+1
	idivi z,3			; z now has minus number of octal digits
	pop p,z+1
	add z,x				; z now has number of spaces
	jumple z,octou2
octou1:
ife sailsw\t20sw,.iot tto,[" ]
ifn sailsw,outchr [" ]
ifn t20sw,movei a1,<" > ? pbout
	sojg z,octou1
octou2:	movx x,8.			; load up octal base
	nout				; output it
	return

ifn sailsw\t20sw,.lose=<jrst 4,>
;hostab htbunm netprt nhashs skpntp

; Start of program

hostab:
ifn sailsw,[
	cai
	reset
	open [17 ? 'DSK,, ? 0]		; get a disk channel
	 .lose
	dmove [sixbit/HOSTS2BIN/]
	move 3,['NETMRC]
	lookup				; find file HOSTS2.BIN[NET,MRC]
	 .lose
	movei 2,hsttab
	movem 2,jobff
	movs 3 ? movn ? addb jobff	; get address of highest addr we need
	core				; get more core from system maybe
	 .lose
	move 3 ? hrri -1(2)		; compute IOWD to read host table in
	setz 1,
	input
	releas
];ifn sailsw
	move p,[pdl(-pdllen)]		; load PDP
ife sailsw\t20sw,[
	syscal OPEN,[	clctl. .uao	; open in single ASCII mode
			clarg. tto	; TTY output channel
			clarg. ('TTY)]	; the TTY
	 .lose %lsfil			; ? ? ?
	syscal OPEN,[	clctl. .bai	; open in block ASCII mode
			clarg. htb	; host table channel
			clarg. ('DSK)	; device
			clarg. 'HOSTS2	; fn1
			clarg. sixbit/>/; fn2
			clarg. 'SYSBIN]	; sname
	 .lose %lsfil			; ? ? ?
	move x,[-100.,,hsttab_-10.]	; 100. pages starting at HSTTAB
	syscal CORBLK,[	clarg. %cbndr	; map pages, fail if can't get all
			clarg. %jself	; this job
			x		; pointer to pages to load
			clarg. htb]	; channel
];ife sailsw\t20sw
ifn t20sw,[
	movsi a1,(gj%old\gj%sht)		; try to access host table
	hrroi a2,[asciz/SYSTEM:HOSTS2.BIN/]
	gtjfn
	 .lose
	movei a2,of%rd			; open up host table
	openf
	 .lose
	sizef				; get its size
	 .lose
	movsi a1,(a1)			; map in host table starting at page 0
	move a2,[.fhslf,,hsttab/1000]
	hrli a3,(pm%cnt\pm%rd)
	pmap
];ifn t20sw
	 skipn x,hsttab			; check first word of host table
	  .lose				; didn't read it all or bad?
	caxe x,'HOSTS2			; right first word?
	 .lose				; bad file?
	type [Host table generated by ]
	skipn x,hsttab+hstwho		; get UNAME of creator
	 .lose				; null UNAME?
htbunm:	movx y,%zeros			; zap where character will go
	rotc x,6			; gobble a character
	addx y,<" >			; ASCIIify
ife sailsw\t20sw,.iot tto,y		; output
ifn sailsw,outchr y
ifn t20sw,move a1,y ? pbout
	jumpn x,htbunm			; continue if more
	type [ on ]
	skipn x,hsttab+hstdat		; get compilation date
	 .lose				; null creation date?
	rot x,12.			; put year last
repeat 3,[
 repeat 2,[
	  movx y,%zeros			; zap character
	  rotc x,6			; gobble a character
	  addx y,<" >			; ASCIIify
ife sailsw\t20sw,.iot tto,y			; output the character
ifn sailsw,outchr y
ifn t20sw,move a1,y ? pbout
 ];repeat 2
 ifn .rpcnt-2,[
  ife sailsw\t20sw,.iot tto,["/]		; output a slash
  ifn sailsw,outchr ["/]
  ifn t20sw,movei a1,"/ ? pbout
 ];ifn .rpcnt-2
 ife .rpcnt-2,[
  ife sailsw\t20sw,.iot tto,[" ]		; output a space last time
  ifn sailsw,outchr [" ]
  ifn t20sw,movei a1,<" > ? pbout
 ];ife .rpcnt-2
];repeat 3
	skipn x,hsttab+hsttim		; get compilation time
	 .lose				; null compilation time?
repeat 3,[
 repeat 2,[
	  movx y,%zeros			; zap character
	  rotc x,6			; gobble a character
	  addx y,<" >			; ASCIIify
 ife sailsw\t20sw,.iot tto,y			; output the character
 ifn sailsw,outchr y
 ifn t20sw,move a1,y ? pbout
 ];repeat 2
 ifn .rpcnt-2,[
  ife sailsw\t20sw,.iot tto,[":]		; delimiter
  ifn sailsw,outchr [":]
  ifn t20sw,movei a1,": ? pbout
 ];ifn .rpcnt-2
];repeat 3
	type [
]
;Now, for each network print the name of the network
;and print a host map driven off its ADDRESS table.
	move a,hsttab+netptr
	addi a,hsttab
	move b,(a)			;Number of networks
	movem b,netcnt'
	move b,1(a)			;Words per entry
	movem b,netsiz'
	addi a,2			;Address of first network
	movem a,netloc'
netprt:	sosge netcnt
 ife sailsw\t20sw,.logout 1,			;No more networks
 ifn sailsw,exit
 ifn t20sw,haltf
	type [
]
	hlrz x,ntlnam(a)
	addi x,hsttab
	sout
	type [ Network:]
	hrrz tbl,ntrtab(a)
	jumpn tbl,nhashs
	type [  no hosts]
nhashs:	type [
]
	jumpe tbl,skpntp
	addi tbl,hsttab
	call onenet
skpntp:	move a,netsiz
	addb a,netloc
	jrst netprt
;onenet foo1 foo3 hstprt hstpr1 foo2 cpopj

;Print info for net whose ADDRESS table is pointed to by tbl
onenet:	ldb b,[nw$byt,,2+addadr(tbl)]	; Get network number
	cain b,nw%dln			; Dialnet is strange
	 jrst [	type [Phone #		]
		jrst foo3]
	type [Host #	]
foo3:	type [Official Name	Machine		System

]
	skipge d,(tbl)			; load number of entries
	 .lose				; invalid number of entries?
	jumpe d,cpopj			; no hosts this net
	skipg c,1(tbl)			; load number of words/entry
	 .lose				; invalid number of words?
ife sailsw,movei a,-hsttab+2(tbl)	;(Simulate old program)
ifn sailsw,[
	movei a,2(tbl)
	subi a,hsttab
];ifn sailsw
;a has file-relative address of next ADDRESS table entry to print
hstprt:	hlrz b,hsttab+adlsit(a)		; Get SITE entry
	movx x,"*			; assume a server
	skipl hsttab+stlflg(b)		; but is it really?
	 movx x,<" >			; nope, a user
ife sailsw\t20sw,.iot tto,x ? .iot tto,[" ]	; initial heading
ifn sailsw,outchr x ? outchr [" ]
ifn t20sw,move a1,x ? pbout ? move a1,<" > ? pbout
	skipg y,hsttab+addadr(a)	; get number of host
	 jrst ranhst			; funny host number?
	ldb x,[nw$byt,,y]		; Get network number
	cain x,nw%arp			; If Arpanet,
	 jrst [	ldb y,[001000,,y]	; decimal host
		movei x,10.
		nout
		ife sailsw\t20sw,.iot tto,["/]; slash
		ifn sailsw,outchr ["/]
		ifn t20sw,movei a1,"/ ? pbout
		ldb y,[112000,,hsttab+addadr(a)]
		movei x,10.		; decimal imp
		nout
		jrst hstpr1 ]
	cain x,nw%chs			; If Chaos net
	 jrst [	movei x,0		; Clear network
		dpb x,[nw$byt,,y]
		movei x,4
		call octout		; Print right-justified octal
		jrst hstpr1 ]
	cain x,nw%dln			; If Dialnet
	 jrst [	movei x,0		; Clear network
		dpb x,[nw$byt,,y]
		movei x,hsttab(y)	; get ptr to string
		sout			; output the string
		jrst hstpr1 ]
	cain x,nw%lcs			; If LCSnet,
	 jrst [	ldb y,[221000,,y]	; octal subnet
		movei x,8.
		nout
		ife sailsw\t20sw,.iot tto,["/]; slash
		ifn sailsw,outchr ["/]
		ifn t20sw,movei a1,"/ ? pbout
		ldb y,[001000,,hsttab+addadr(a)]
		movei x,8.		; octal host
		nout
		jrst hstpr1 ]
	cain x,nw%su			; If SUnet
	 jrst [	ldb y,[111000,,y]	; octal subnet
		movei x,8.
		nout
		ife sailsw\t20sw,.iot tto,["#]; slash
		ifn sailsw,outchr ["#]
		ifn t20sw,movei a1,"# ? pbout
		ldb y,[001000,,hsttab+addadr(a)]
		movei x,8.		; octal host
		nout
		jrst hstpr1 ]
	; Unknown net
ranhst:	move y,hsttab+addadr(a)		; Just print the whole number
	movei x,0			; except for the network number
	dpb x,[nw$byt,,y]
	movei x,8
	nout
hstpr1:
ife sailsw\t20sw,.iot tto,[^I]		; go to next field
ifn sailsw,outchr [^I]
ifn t20sw,movei a1,^I ? pbout
	hlrz x,hsttab+stlnam(b)		; get name of host
	jumpe x,[.lose]			; null host pointer?
	addi x,hsttab			; convert to absolute address
	sout				; output the string
	skipn x,strlen'			; get length of string
	 .lose				; null host name?
ifn t20sw,movei a1,^I
	caxge x,8.			; more than one field length?
ife sailsw\t20sw,[
	 .iot tto,[^I]			; yes, another tab required
	.iot tto,[^I]			; output another tab
];ife sailsw\t20sw
ifn sailsw,[
	outchr [^I]
	outchr [^I]
];ifn sailsw
ifn t20sw,pbout ? pbout
	hrrz x,hsttab+strmch(b)		; get machine host is
	jumpe x,[	movei x,[asciz/UNKNOWN/]; unknown name
			jrst .+2]	; and continue
	addi x,hsttab			; convert to absolute address
	move y,(x)			; get first word of machine name
	andx y,777777700000		; get first three characters
	caxe y,ascii/PDP/		; is this a PDP-nn?
	 jrst foo2
	ldb y,[100700,,(x)]		; yes, get fourth character
	caxn y,"-			; is it a dash?
	 jrst foo2			; yes (foo, somebody lost!)
	save x				; save current pointer
	type [PDP-]
	retr x				; get current pointer back
	hrli x,170700			; kludge up byte pointer after PDP
foo2:	sout				; and output it
	skipn x,strlen'			; get length of string
	 .lose				; null host name?
ifn t20sw,movei a1,^I
	caxge x,8.			; more than one field length?
ife sailsw\t20sw,[
	 .iot tto,[^I]			; yes, another tab needed
	.iot tto,[^I]			; output a delimiting tab
];ife sailsw\t20sw
ifn sailsw,[
	 outchr [^I]
	outchr [^I]
];ifn sailsw
ifn t20sw,pbout ? pbout
	hlrz x,hsttab+stlsys(b)		; get system host has
	jumpe x,[	movei x,[asciz/UNKNOWN/]; unknown system
			jrst .+2]	; and continue
	addi x,hsttab			; convert to absolute address
	sout				; and output it
	type [
]
	addi a,(c)			; go to next entry in the table
	sojg d,hstprt			; loop for next entry
	type [
* means this site is a server
]
cpopj:	return

; Generate literals

	variables ? constants

ife sailsw,hsttab=<.+1777>&-2000	; start of host table
ifn sailsw,hsttab=.

end HOSTAB
