perm filename HOSTS1.MID[HST,NET] blob
sn#696034 filedate 1983-01-14 generic text, type T, neo UTF8
;-*-MIDAS-*-
TITLE HOSTS1
IFNDEF SAILSW,SAILSW==IFE <.OSMIDAS-SIXBIT/SAIL/>,[-1] .ELSE 0
;This program .INSRTs the file SYSENG;HOSTS > describing all the network hosts
;and produces a compiled file SYSBIN;HOSTS1 > which network programs read in.
;At SAIL the files are HOSTS.TXT[S,NET] and HOSTS1.BIN[S,NET].
;The format of the compiled HOSTS1 file is:
HSTSID==0 ; wd 0 SIXBIT /HOSTS1/
HSTFN1==1 ; wd 1 SIXBIT /HOSTS/
HSTVRS==2 ; wd 2 FN2 of HOSTS file which this was compiled from.
; SIXBIT /SAIL/ if generated at SAIL
HSTWHO==3 ; wd 3 UNAME of person who compiled this
HSTDAT==4 ; wd 4 Date of compilation as sixbit YYMMDD
HSTTIM==5 ; wd 5 Time of compilation as sixbit HHMMSS
NAMPTR==6 ; wd 6 Address in file of NAME table.
NUMPTR==7 ; wd 7 Address in file of NUMBER table.
;....
;NUMBERS table:
; wd 0 Number of entries in this table.
; wd 1 Number of words per entry (currently 3).
; followed by entries, in order by host number.
; Each entry looks like this:
NUMNUM==0 ; entry wd 0 host number
NUMSYS==1 ; entry wd 1 lh ptr to system name (ITS, TIP, TENEX, etc.)
; May be 0 => not known.
NUMNAM==1 ; entry wd 1 rh ptr to official name of host.
NUMBTS==2 ; entry wd 2 lh flags:
NUMSRV==400000 ; 4.9 1 => server site.
NUMMCH==2 ; entry wd 2 rh ptr to machine name (PDP10, etc).
; May be 0 => not known.
NUMLEN==3
;....
;NAMES table:
; wd 0 Number of entries
; followed by one word entries, sorted by the host name treated as a vector of
; signed integers, looking like:
; lh address in file of NUMBERS table entry for this host.
NAMNAM==0 ; rh ptr to host name
NAMLEN==1 ;length of entry.
; Host, system and machine names are ASCIZ strings, all letters upper case.
; The strings are stored before, after and between the NAME and NUMBER tables.
;HSTNAM HSTNUM HSTSRV HSTSYS HSTMCH HSTNIC HSTLEN F A B C D E G H I J K M N R S P TYOC CALL RET SAVE REST
;The source file of the table is SYSENG;HOSTS > (at SAIL, HOSTS.TXT[S,NET]).
;Each host is described by a line which looks like
; HOST <official name>,<addresses>,<status>,<system>,<machine>,[<nickname list>]
;<addresses> can be a single <address> or a bracketed list of <address>s
;separated by commas. An <address> can be an octal number, or the name of
;a network (CHAOS, ARPA) followed by a space and a number. Arpanet addresses
;can also be written as host slash imp, which of course is backwards but
;seems to be what BBN is foolishly standardizing on. This program ignores
;addresses for other than the Arpanet.
;We assemble that into a string of entries, of this form:
HSTNAM==0 ; wd 0 -> asciz host name
HSTNUM==1 ; wd 1 host number
HSTSRV==2 ; wd 2 nonzero iff server host
HSTSYS==3 ; wd 3 -> asciz system name ("TIP" is a system name).
; (may be 0).
HSTMCH==4 ; wd 4 -> asciz machine name (may be 0).
HSTNIC==5 ; wd 5 -> nickname list, LISP-style. LH of each word, starting
; with this one itself, -> ASCIZ, RH is next. All zero
; word rather than zero RH terminates list
HSTLEN==6 ;6 words per host entry.
;AC Defs
F==0
A=1
B=2
C=3
D=4
E=5
G=6
H=7
I=10
J=11
K=12
M=13
N=14
R=15
S=16
P=17
TYOC==17 ;in case error messages
CALL=PUSHJ P,
RET=POPJ P,
SAVE=PUSH P,
REST=POP P,
;INCH OUTUUO LPDL PDL PATCH
IFE SAILSW,[
LOC 100 ;absolute assembly
;To make a new version of the HOSTS1 table, :XFILE AI:SYSENG;HOSTS1 XFILE
;which will run this program with latest host table and
;dump out a new version of the HOSTS1 file.
;1st arg name of system call,
;2nd like a literal has args to call.
DEFINE SYSCAL A,B
.CALL [SETZ ? SIXBIT/A/ ? B ((SETZ))]
TERMIN
INCH==1 ;Input channel
];IFE SAILSW
IFN SAILSW,[
;To make a new version of the HOSTS1 table, BATCH/NOW @HOSTS1
;which will run this program with latest host table and
;dump out a new version of the HOSTS1 file.
DEFINE .VALUE
JRST 4,.-1
TERMIN
IF1,[ ;name conflict with WAITS
OUTUUO=OUT
EXPUNGE OUT
];IF1
];IFN SAILSW
LPDL==40
PDL: BLOCK LPDL+10
PATCH: PAT: BLOCK 40
;DUMP
;Write out the compiled file.
DUMP: MOVE P,[-LPDL,,PDL-1]
IFE SAILSW,[
.OPEN TYOC,[.UAO,,'TTY]
.LOSE %LSFIL
.CORE <CORTOP+1777>/2000
.LOSE
.SUSET [.RUNAME,,UNAME]
.RDATE A, ;Init the auditing info at the front
MOVEM A,$DATE ;Name conflict with WAITS
.RTIME A,
MOVEM A,TIME
];IFE SAILSW
IFN SAILSW,[
MOVEI A,CORTOP
MOVEM A,JOBFF
CORE A,
.VALUE
SETZM OUTEND
MOVE A,[OUTEND,,OUTEND+1]
BLT A,CORTOP-1
GETPPN A,
CAI ;Fastest no-op in the West!
HRLZM A,UNAME
DATE B,
IDIVI B,12.*31.
ADDI B,64.
IDIVI C,31.
ADDI C,1
ADDI D,1
PUSH P,C
IDIVI B,10.
MOVEI A,'0(B)
LSH A,6
ADDI A,'0(C)
POP P,B
IDIVI B,10.
LSH A,6
ADDI A,'0(B)
LSH A,6
ADDI A,'0(C)
IDIVI D,10.
LSH A,6
ADDI A,'0(D)
LSH A,6
ADDI A,'0(E)
MOVEM A,$DATE
MSTIME B,
IDIVI B,1000.
IDIVI B,60.*60.
IDIVI C,60.
PUSH P,C
IDIVI B,10.
MOVEI A,'0(B)
LSH A,6
ADDI A,'0(C)
POP P,B
IDIVI B,10.
LSH A,6
ADDI A,'0(B)
LSH A,6
ADDI A,'0(C)
IDIVI D,10.
LSH A,6
ADDI A,'0(D)
LSH A,6
ADDI A,'0(E)
MOVEM A,TIME
];IFN SAILSW
CALL RHOSTF ;Read in the HOSTS file
; JRST UPPER ;Drops through to next page
;UPPER UPPER1 UPPER2 UPPER3 UPPERS UPPER4
;Now convert all system, machine and host names to upper case.
;This is so that user programs can search and compare more easily.
;Also, it makes sure that CANON really maps all instances of a system
;or machine name into the same name.
UPPER: MOVEI A,HSTTAB
UPPER1: MOVE B,HSTSYS(A)
CALL UPPERS
MOVE B,HSTMCH(A)
CALL UPPERS
MOVE B,HSTNAM(A)
CALL UPPERS
MOVE C,HSTNIC(A) ;Get nickname list
JUMPE C,UPPER3 ;empty
UPPER2: HLRZ B,C ;CAR
CALL UPPERS ;and convert each nickname in it.
SKIPE C,(C) ;CDR
JRST UPPER2
UPPER3: ADDI A,HSTLEN ;Advance to next host.
CAME A,HSTTBE
JRST UPPER1
JRST CANON
;Convert the the ASCIZ string that B points to to upper case,
;modifying it in place. Clobbers B and E.
UPPERS: HRLI B,440700
UPPER4: ILDB E,B
JUMPE E,CPOPJ
CAIL E,"a
CAILE E,"z
JRST UPPER4
SUBI E,"a-"A
DPB E,B
JRST UPPER4
;CANON CNTLP CNTLP1 CNTLP2
;Now store the System name strings into the file, storing each
;distinct name only once. We replace each System name pointer
;with a pointer (in our address space) to the string stored
;into the file (the "interned" string) so we don't have to search
;the file when we write the NAMES table.
;Also, G counts how many words of space will be needed for all
;the host names and nicknames.
CANON: MOVEI A,SYSNMS ;A is storing pointer for new system names.
MOVEI B,HSTTAB ;B points at data of next host to hack.
SETZB G,H
CNTLP: SKIPE C,HSTSYS(B) ;Store the system name if necessary.
CALL CONSNM
SKIPE HSTSYS(B)
MOVEM J,HSTSYS(B) ;replace system name string with interned one.
SKIPE C,HSTMCH(B)
CALL CONSNM ;Do the same thing with the machine name.
SKIPE HSTMCH(B)
MOVEM J,HSTMCH(B)
MOVE C,HSTNAM(B)
CALL COUNT ;Count space official name will take,
MOVE D,HSTNIC(B) ;and space the nicknames will take.
AOS H ;H counts number of names and nicknames.
JUMPE D,CNTLP2
CNTLP1: HLRZ C,D ;CAR
CALL COUNT
AOS H ;H counts number of names and nicknames.
SKIPE D,(D) ;CDR
JRST CNTLP1
CNTLP2: ADDI B,HSTLEN
CAMGE B,HSTTBE
JRST CNTLP
ADD G,OUTPT ;Leave space after system names for them
MOVEM G,NUMP ;to find where NUMBERS table should start.
MOVE M,NHOSTS
MOVEM M,(G) ;Store number of entries in NUMBERS table.
MOVEI A,NUMLEN
MOVEM A,1(G) ;Store number of words per entry.
IMUL M,A ;Compute total length
ADDI M,2(G) ;and thus the position of NAMES table.
MOVEM M,NAMEP
MOVEM M,NAMP
MOVEM H,@NAMEP ;Store size of NAMES table (= # of hosts + nicknames)
AOS NAMEP ;in its 1st word, and advance storing pointer.
SUBI G,OUT
MOVEM G,NUMPR
SUBI M,OUT
MOVEM M,NAMPR
JRST MACH ;Go figure out machine names if possible.
;COUNT CONSNM CONSLP CONSCM CONSNX CONSLS
;C -> an ASCIZ string. Add to G the number of words it occupies.
;Clobbers E.
COUNT: MOVE E,(C)
AOS G
TRNN E,376
RET
AOJA C,COUNT
;C -> an ASCIZ string; intern it in the system names table.
;If the table has no string EQUAL to the arg, make a new one at the end.
;In either case, return in J the address of the interned string.
;A -> the beginning of the system names table, and OUTPT -> the end.
;Clobbers D, E, and K.
CONSNM: MOVE E,A ;E looks at all strings in table, 1 by 1.
CONSLP: MOVE J,E
CAMN E,OUTPT ;Reached start of next string in table
JRST CONSLS ; but maybe it's the end of table.
MOVE K,C
CONSCM: MOVE D,(K)
CAME D,(E) ;Compare table string agains our arg word
JRST CONSNX ;by word. No match => skip to next string
TRNN D,376 ;in table. Match until end of ASCIZ =>
RET ;we found the arg in the table.
AOS E ;else compare next words of the two strings.
AOJA K,CONSCM
CONSNX: MOVE K,(E) ;Advance to start of next ASCIZ string in table
TRNN K,376
AOJA E,CONSLP ;then compare it against our arg.
AOJA E,CONSNX
CONSLS: MOVE D,(C) ;String not found in table, so copy it
MOVEM D,@OUTPT ;to the end of the table.
AOS OUTPT
TRNE D,376
AOJA C,CONSLS
RET
;MACH MACHL MACHNX
;Now figure out the type of machine from the system name, if possible,
;in case HOSTS currently has no info on machine type.
MACH: MOVEI A,HSTTAB
MACHL: MOVE B,HSTSYS(A)
SKIPE C,HSTMCH(A) ;If machine type not already known,
JRST MACHNX ;try to determine it from system name.
CAIE B,ITS
CAIN B,TENEX
MOVEI C,PDP10
CAIE B,TOPS10
CAIN B,TOPS20
MOVEI C,PDP10
CAIE B,SAIL
CAIN B,TEN50
MOVEI C,PDP10
CAIE B,BOTS10
CAIN B,TWENEX
MOVEI C,PDP10
CAIN B,TIP
MOVEI C,TIP
CAIN B,MULTIC
MOVEI C,MULTIC
CAIE B,HYDRA
CAIN B,RSX11
MOVEI C,PDP11
CAIE B,ELF
CAIN B,UNIX
MOVEI C,PDP11
MOVEM C,HSTMCH(A)
MACHNX: ADDI A,HSTLEN
CAME A,HSTTBE
JRST MACHL
; JRST MT ;After this, build the NAMES table.
;MT MTLP NAMCPY MTE1
;Now build the contents of the NUMBERS table, exact but not sorted.
MT: MOVEI B,HSTTAB ;B points at data of next host to hack.
MOVE A,NUMP
ADDI A,2 ;A is pointer for storing NUMBERS table entries.
MTLP: MOVE C,HSTNAM(B)
MOVE E,HSTNUM(B)
MOVEM E,NUMNUM(A) ;Store the host number.
SKIPE E,HSTSYS(B)
SUBI E,OUT ;Store ptr to system name (in file addr space).
HRLZM E,NUMSYS(A)
SKIPE E,HSTMCH(B)
SUBI E,OUT
MOVEM E,NUMMCH(A) ;and the machine name.
MOVSI E,NUMSRV
SKIPE HSTSRV(B) ;If a server host, set the flag for that.
IORM E,NUMBTS(A)
CALL NAMCPY ;Copy the host name to where OUTPT points,
HRRM E,NUMNAM(A) ;and store a pointer to the copy.
ADDI A,NUMLEN ;Advance A to store next entry next time.
ADDI B,HSTLEN
CAMGE B,HSTTBE
JRST MTLP
CAME A,NAMP ;Check that NUMBERS occupies expected
.VALUE ;amount of space.
SUB A,NUMP
SUBI A,2
MOVE B,@NUMP ;Check that right number of NUMBERS
IMULI B,NUMLEN ;entries were made.
CAME A,B
.VALUE
JRST SNT
;Copy ASCIZ string <- C to where OUTPT points, advancing OUTPT.
;Return in E the address of the copy, in file address space.
NAMCPY: MOVE E,OUTPT
SUBI E,OUT
SAVE E
MTE1: MOVE E,(C)
MOVEM E,@OUTPT
AOS OUTPT
TRNE E,376
AOJA C,MTE1
REST E
RET
;SNT SNTL SNTWN
;Now sort the NUMBERS table by numbers.
SNT: SETZ B, ;Another pass, no exchanges yet.
MOVE A,NUMP
ADDI A,2
SNTL: MOVE C,NUMNUM(A)
CAMN C,NUMNUM+NUMLEN(A) ;Check for duplicate host number
JRST [ MOVEI A,[ASCIZ/Duplicate host number: /]
PUSHJ P,ASZOUT
MOVE A,C
PUSHJ P,DECOUT
MOVEI A,[ASCIZ/ (decimal)/]
PUSHJ P,ASZOUT
.VALUE ]
CAMG C,NUMNUM+NUMLEN(A) ;Skip if this entry and next are mis-ordered.
JRST SNTWN ;No skip => this one's is less.
SETO B, ;Wrong order => interchange.
REPEAT 3,[
MOVE C,.RPCNT(A)
EXCH C,.RPCNT+NUMLEN(A)
MOVEM C,.RPCNT(A)
]
SNTWN: ADDI A,NUMLEN ;Keep exchanging if nec thru all of NUMBERS.
MOVEI C,NUMLEN(A)
CAME C,NAMP
JRST SNTL
JUMPN B,SNT ;If not finished exchanging, need another pass.
JRST MNAM ;Now NUMBERS is finished, so make NAMES.
;MNAM MNAML MNAML1 MNAMF MNAMN MNAMX
;Now that the NUMBERS table is finished, we can make the NAMES
;table, which has pointers into the NUMBERS table.
MNAM: MOVE A,NUMP ;A scans through the NUMBERS table.
ADDI A,2
MOVE B,@NUMP
MNAML: MOVEI C,HSTTAB ;Make the NAMES table entries for the next host.
MOVE D,NUMNUM(A)
MNAML1: CAMN D,HSTNUM(C) ;Find the HSTTAB entry for this host, since it
JRST MNAMF ;has the nicknames in it.
ADDI C,HSTLEN
CAME C,HSTTBE
JRST MNAML1
.VALUE ;It's in NUMBERS table but not in original input
MNAMF:
IFE SAILSW,HRLZI E,-OUT(A) ;Make the official name's entry. Get NUMBERS entry addr in lh.
IFN SAILSW,[
MOVEI D,(A) ;This allows reloation so can debug with RAID
SUBI D,OUT
HRLZI E,(D)
];IFN SAILSW
HRR E,NUMNAM(A) ;Put ptr to host name in rh (copy from NUMBERS entry).
MOVEM E,@NAMEP
AOS NAMEP
MOVE D,HSTNIC(C) ;D points to list of nickname pointers.
JUMPE D,MNAMX
MNAMN: HLRZ C,D ;C gets the next nickname. (CAR)
CALL NAMCPY ;Copy the nickname into file, E gets addr of copy.
IFE SAILSW,[
HRLI E,-OUT(A) ; Get NUMBERS entry addr in lh.
];IFE SAILSW
MOVEM E,@NAMEP
IFN SAILSW,[
MOVEI E,(A) ;This allows relocation so can debug with RAID
SUBI E,OUT
HRLM E,@NAMEP
];IFN SAILSW
AOS NAMEP
SKIPE D,(D) ;CDR
JRST MNAMN
MNAMX: ADDI A,NUMLEN ;Finished making NAMES entry for this host. Hack the next.
SOJG B,MNAML
MOVE B,NAMEP ;Check that expected number of NAMES
SUB B,NAMP ;entries were made.
SUBI B,1
CAME B,@NAMP
.VALUE
MOVE B,OUTPT ;Check that host names exactly filled
CAME B,NUMP ;the space allotted.
.VALUE
JRST SNAM ;Now go sort this table.
;SNAM SNAML SNAMWN COMPAR CMPRLP CMPRBF ASZOUT ASZOU1 POPJ1 CPOPJ
;Sort the NAMES table.
SNAM: SETZ B, ;No exchanges yet this pass.
MOVE A,NAMP ;A is pointer for scanning through.
ADDI A,1
MOVE G,NAMEP ;G -> next to the last NAMES entry.
SUBI G,2
SNAML: HRRZ C,NAMNAM(A) ;Get this entry's name and next entry's.
HRRZ D,NAMNAM+NAMLEN(A)
ADDI C,OUT ;Convert file's address space to ours.
ADDI D,OUT
CALL COMPAR ;Skip if these two entries mis-ordered.
JRST SNAMWN
SETO B,
MOVE E,(A)
EXCH E,NAMLEN(A)
MOVEM E,(A)
SNAMWN: CAME A,G ;Each pass scan whole table.
AOJA A,SNAML ;If we exchanged, we need another pass.
JUMPN B,SNAM
JRST WRITE
;Compare two ASCIZ strings alphabetically.
;C -> first string, D -> second. Skip if first is greater.
;If the strings are EQUAL, we barf.
COMPAR: MOVEM C,COMPR1'
MOVEM D,COMPR2'
CMPRLP: MOVE E,(D) ;Better make this comparison unsigned...
LSH E,-1
MOVEM E,COMPR3'
MOVE E,(C)
LSH E,-1
CAMGE E,COMPR3
RET
CAMLE E,COMPR3
JRST POPJ1
TRNN E,177 ;Two host names are EQUAL???
JRST CMPRBF
AOS C
AOJA D,CMPRLP
CMPRBF: MOVEI A,[ASCIZ/Two equal host names? /]
PUSHJ P,ASZOUT
MOVE A,COMPR1
PUSHJ P,ASZOUT
MOVEI A,[ASCIZ/ and /]
PUSHJ P,ASZOUT
MOVE A,COMPR2
PUSHJ P,ASZOUT
MOVEI A,[ASCIZ/
/]
PUSHJ P,ASZOUT
.VALUE
ASZOUT:
IFN SAILSW,[
OUTSTR (A)
POPJ P,
];SAILSW
IFE SAILSW,[
HRLI A,440700
ASZOU1: ILDB B,A
JUMPE B,CPOPJ
.IOT TYOC,B
JRST ASZOU1
];SAILSW
POPJ1: AOS (P)
CPOPJ: RET
;WRITE DMPDEV DMPFN1 DMPFN2 DMPSNM WRITE DMPFN1 DMPFN2 DMPSNM
;Now write out the compiled hosts file.
IFE SAILSW,[
WRITE: SYSCAL OPEN,[[.UIO,,] ? DMPDEV ? DMPFN1 ? DMPFN2 ? DMPSNM]
.LOSE %LSFIL
MOVE A,[444400,,OUT] ;get BP to data in core,
MOVE B,NAMEP
SUBI B,OUT ;and size of file.
SYSCAL SIOT,[1000,, ? A ? B]
.LOSE %LSSYS
.CLOSE ;write and close, and we're done.
.LOGOUT 1,
;These are the filenames to write.
DMPDEV: SIXBIT /DSK/
DMPFN1: SIXBIT /HOSTS1/
DMPFN2: SIXBIT />/
DMPSNM: SIXBIT /SYSBIN/
];IFE SAILSW
IFN SAILSW,[
WRITE: OPEN [17 ? 'DSK,, ? 0]
.VALUE
ENTER DMPFN1
.VALUE
MOVE B,NAMEP
SUBI B,OUT+1 ;and size of file.
HRLO A,B
EQVI A,OUT-1
SETZ B,
OUTUUO A
CAIA
.VALUE
CLOSE ;write and close
EXIT
;These are the filenames to write.
DMPFN1: SIXBIT /HOSTS1/
DMPFN2: SIXBIT /BIN/
0
DMPSNM: SIXBIT /HSTNET/
];IFN SAILSW
;RCH RCH2 RCH1 RTOKEN RTOK1 RTOK2 RTOKCM RCOMLF RCOMMA BARF DECOUT
;Midas doesn't really make it for parsing this hosts table.
;Here's the new frob.
;Get character in A
RCH:
IFE SAILSW,[
SKIPGE A,UNRCHF'
.IOT INCH,A
JUMPE A,.-1 ;SAIL might put nulls in the file?
HRRZS A ;Flush -1 in LH of EOF ↑C
];IFE SAILSW
IFN SAILSW,[
SKIPL A,UNRCHF'
JRST RCH1
RCH2: SOSG IBUFH+2
IN
CAIA
SKIPA A,[↑C]
ILDB A,IBUFH+1
RCH1: JUMPE A,RCH2
];IFN SAILSW
CAIN A,↑J ;Count lines
SKIPL UNRCHF
CAIA
AOS LINENO'
SETOM UNRCHF
RET
;Returns in A positive character (SCO), ↑C at eof, or negative BP to ASCIZ string
;Bash B
RTOKEN: CALL RCH ;First, skip white space and comments
CAIN A,↑C
RET ;EOF
CAIN A,";
JRST RTOKCM
CAIN A,↑J ;LF is an SCO
RET
CAIG A,40
JRST RTOKEN ;White space
CAIN A,", ;Comma is an SCO
RET
CAIE A,"[ ;Brackets are SCO
CAIN A,"]
RET
;; OK, this is going to be a long symbol
MOVE B,TOKBP ;Start of this symbol
RTOK1: IDPB A,TOKBP
CALL RCH
CAILE A,40 ;Check for termination
CAIN A,";
JRST RTOK2
CAIN A,",
JRST RTOK2
CAIE A,"[
CAIN A,"]
JRST RTOK2
JRST RTOK1
RTOK2: MOVEM A,UNRCHF
MOVEI A,0
IDPB A,TOKBP
MOVE A,B ;Return value is negative BP to ASCIZ
AOS B,TOKBP ;Advance BP to next word
HRLI B,440700
MOVEM B,TOKBP
RET
RTOKCM: CALL RCH ;Skip comment
CAIE A,↑J ;Which turns into CRLF
CAIN A,↑C ;EOF Shouldn't happen
RET
JRST RTOKCM
;Require a comma here, or a CRLF. Skip if comma
RCOMLF: CALL RTOKEN
CAIN A,↑J
RET
CAIN A,",
JRST POPJ1
MOVEI A,[ASCIZ/Missing comma or CRLF/]
JRST BARF
;Require a comma here
RCOMMA: CALL RTOKEN
CAIN A,",
RET
MOVEI A,[ASCIZ/Missing comma/]
JRST BARF
BARF: PUSHJ P,ASZOUT
MOVEI A,[ASCIZ/
Error near line #/]
PUSHJ P,ASZOUT
MOVE A,LINENO
PUSHJ P,DECOUT
.VALUE
DECOUT: IDIVI A,10.
HRLM B,(P)
SKIPE A
PUSHJ P,DECOUT
HLRZ B,(P)
ADDI B,"0
IFE SAILSW, .IOT TYOC,B
IFN SAILSW, OUTCHR B
POPJ P,
;GHOST GHOSTE GNET GHOST1 GHOST2 GHOST3 GHOST4 GHOST5 GHOST6
;; This guy is called to read HOST lines. Store indirect through D.
GHOST: CALL RTOKEN ;Should be HOST
JUMPL A,GHOST1 ;If SCO, hopefully EOF or blank line
CAIN A,↑J
JRST GHOST
CAIN A,↑C
RET
GHOSTE: MOVEI A,[ASCIZ/Randomness when expecting HOST/]
JRST BARF
GNET: CALL RCH ;Ignore network entries
CAIE A,↑J ;By flushing until end of line
JRST GNET
JRST GHOST
GHOST1: MOVE B,(A)
CAMN B,[ASCIZ/NET/]
JRST GNET
CAME B,[ASCIZ/HOST/]
JRST GHOSTE
CALL RTOKEN ;Next should be host name
JUMPGE A,[ MOVEI A,[ASCIZ/Random character when expecting host name/]
JRST BARF ]
MOVEM A,HSTNAM(D)
CALL RCOMMA ;Next should be comma
SETO C, ;Host number not got yet
CALL RTOKEN ;Should be either a host# or a bracketed list of such
CAIE A,"[ ;]
JRST [ CALL GHOSTN
JRST GHOST3 ]
GHOST2: CALL RTOKEN
CALL GHOSTN ;
CALL RTOKEN
CAIN A,",
JRST GHOST2 ;[
CAIE A,"]
JRST [ MOVEI A,[ASCIZ/Missing close bracket/]
JRST BARF ]
GHOST3: CALL RCOMMA ;Next a comma
JUMPL C,[ PUSHJ P,RTOKCM ;This host not to be included, treat as comment
JRST GHOST ]
MOVEM C,HSTNUM(D)
CALL RTOKEN ;Status
MOVE B,(A)
SETZM HSTSRV(D)
CAMN B,[ASCII/SERVE/]
SETOM HSTSRV(D)
CALL RCOMLF
JRST GHOST6 ;CRLF
CALL RTOKEN ;Optional system name
JUMPGE A,[ SETZM HSTSYS(D)
MOVEM A,UNRCHF
JRST .+2 ]
MOVEM A,HSTSYS(D)
CALL RCOMLF
JRST GHOST6 ;CRLF
CALL RTOKEN ;Optional machine name
JUMPGE A,[ SETZM HSTMCH(D)
JRST .+3 ]
MOVEM A,HSTMCH(D)
CALL RTOKEN
;Here A is comma before nicknames, or CRLF
SETZM HSTNIC(D)
CAIE A,",
JRST GHOST6
CALL RTOKEN ;Single nickname or bracket that begins list
CAIE A,"[ ;]
JRST [ CALL GNICKN
JRST GHOST5 ]
GHOST4: CALL RTOKEN
CALL GNICKN
CALL RTOKEN
CAIN A,",
JRST GHOST4 ;[
CAIE A,"]
JRST [ MOVEI A,[ASCIZ/Missing close bracket/]
JRST BARF ]
GHOST5: CALL RTOKEN
GHOST6: CAIE A,↑J ;Should be end of line
JRST [ MOVEI A,[ASCIZ/Garbage where end of line expected/]
JRST BARF ]
ADDI D,HSTLEN
AOS NHOSTS
JRST GHOST
;GHOSTN GHSTN1 GHSTN2 GHSTN3 GHSTN5 GHSTN9 GNICKN
;;; This parses up a host number and puts it in C if it likes it
;;; First token is in A
GHOSTN: JUMPGE A,GHSTN9 ;SCO?
ILDB B,A ;First char tells whether it's a number
CAIL B,"0
CAILE B,"9
JRST GHSTN5
MOVEM A,GHSNBP' ;Save ptr to this number
MOVEI C,0 ;It's a number, read in as octal in C
GHSTN1: LSH C,3
ADDI C,-"0(B)
ILDB B,A
JUMPE B,CPOPJ ;Clearly an Arpanet guy
CAIE B,"/ ;Slash allowed in numbers for host slash imp frob
JRST GHSTN1
MOVE A,GHSNBP ;Oh dear. Rescan the number in decimal
LDB B,A
MOVEI C,0
GHSTN2: IMULI C,10.
ADDI C,-"0(B)
ILDB B,A
CAIE B,"/
JRST GHSTN2
PUSH P,C ;Save host number
MOVEI C,0 ;It's a number, read in as decimal in C
ILDB B,A
CAIL B,"0
CAILE B,"9
JRST [MOVEI A,[ASCIZ/Random character in number/]
JRST BARF ]
GHSTN3: IMULI C,10.
ADDI C,-"0(B)
ILDB B,A
JUMPN B,GHSTN3
POP P,B ;B host, C imp. See if fits in old format
;New format result to C
LSH C,9
ADDI C,(B)
RET
GHSTN5: MOVE B,(A) ;Must be a network name
CAMN B,[ASCIZ/ARPA/]
JRST [ CALL RTOKEN ;Arpanet is OK
JRST GHOSTN ]
CALL RTOKEN ;Give up on this guy (skip his number)
RET
GHSTN9: .VALUE ;Shouldn't see SCO's here.
;Get a nickname. Make HSTNIC be pointer to vector of addresses of ASCIZ, end by zero.
;Nick name is already in A, just needs to be CONSed onto list.
GNICKN: MOVSS A ;CAR is in LH
HRR A,TOKBP ;CDR is next free loc
EXCH A,HSTNIC(D) ;Store first CONS, get set to store previous
MOVEM A,@TOKBP ;Store previous
AOS TOKBP ;Bump free ptr
RET
;UPSIZE RHOSTF HSTTAB RHOSTF HSTTAB
;; Here to read in and parse the hosts file, making HSTTAB and various ASCIZ strings
UPSIZE==12 ;Number of K for upper
IFE SAILSW,[
RHOSTF: MOVE A,[-UPSIZE,,HSTTAB/2000] ;5K should be enough core
SYSCAL CORBLK,[MOVEI %CBNDW ? MOVEI %JSELF ? A ? MOVEI %JSNEW ]
.LOSE %LSSYS
SETZM HSTTAB ;Always a good idea
MOVE A,[HSTTAB,,HSTTAB+1]
BLT A,<HSTTAB+UPSIZE*2000>-1
MOVE A,[440700,,HSTTAB+4000] ;2K of host table, rest is ASCIZ strings
MOVEM A,TOKBP'
SETZM NHOSTS'
SYSCAL OPEN,[[.UAI,,INCH] ? [SIXBIT/DSK/]
[SIXBIT/HOSTS/] ? [SIXBIT/>/] ? [SIXBIT/SYSENG/]]
.LOSE %LSFIL
MOVEI D,HSTTAB ;Store indirect through D
CALL GHOST
MOVEM D,HSTTBE'
SYSCAL RFNAME,[MOVEI INCH ? MOVEM A ? MOVEM FFN1 ? MOVEM FFN2 ]
.LOSE %LSSYS
.CLOSE INCH,
RET
HSTTAB=600000
];IFE SAILSW
IFN SAILSW,[
RHOSTF: MOVEI A,<HSTTAB+UPSIZE*2000>-1 ;Moon sez: 5K should be enough core
CORE2 A, ;Make us an upper (NOTE: If this program is
.VALUE ;brought up on a Tops-10 this will have to change)
SETZM HSTTAB ;And at SAIL you ain't got no choice!
MOVE A,[HSTTAB,,HSTTAB+1]
BLT A,<HSTTAB+UPSIZE*2000>-1
MOVE A,[440700,,HSTTAB+4000] ;2K of host table, rest is ASCIZ strings
MOVEM A,TOKBP'
SETZM NHOSTS'
OPEN [0 ? 'DSK,, ? IBUFH]
.VALUE
DMOVE A,[SIXBIT/HOSTS/ ? 'TXT,,]
MOVE D,[SIXBIT/HSTNET/]
LOOKUP A
.VALUE
MOVEI D,HSTTAB ;Store indirect through D
CALL GHOST
MOVEM D,HSTTBE'
CLOSE
RELEASE
RET
HSTTAB=400000 ;This must *NOT* change
];IFE SAILSW
;OUTPT NAMP NAMEP NUMP IBUFH OUT FFN1 FFN2 UNAME $DATE TIME NAMPR NUMPR SYSNMS TIP PDP10 ITS TENEX TOPS10 TOPS20 TEN50 TWENEX BOTS10 SAIL PDP11 ELF UNIX RSX11 HYDRA MULTIC OUTEND CORTOP FOO
;Here is the beginning of the hosts table file.
OUTPT: OUTEND ;Pointer to where to put next word we add.
NAMP: 0 ;Addr of place to put NAME table
;(in our address space).
NAMEP: 0 ;Ptr for storing into NUMBERS table.
NUMP: 0 ;Addr of place to put NUMBER table.
IFN SAILSW,[
IBUFH: BLOCK 3 ;Input buffer header
];IFN SAILSW
CONSTANTS
VARIABLES
;The data actually written into the file starts here.
OUT: SIXBIT /HOSTS1/
FFN1: ;Include filenames of HOSTS file.
IFE SAILSW,0
.ELSE SIXBIT/HOSTS/
FFN2:
IFE SAILSW,0
.ELSE SIXBIT/SAIL/
UNAME: 0 ;UNAME of person who compiles the file.
$DATE: 0 ;Date and time of compilation.
TIME: 0
NAMPR: 0 ;Pointer to NAME table, rel to OUT.
NUMPR: 0 ;Pointer to NUMBER tables, rel to OUT.
SYSNMS: ;The table of interned system and machine
;names starts here.
TIP: ASCIZ /TIP/ ;These are pre-interned so they go in known
PDP10: ASCIZ /PDP10/ ;places and are easy to test for in MACH.
ITS: ASCIZ /ITS/ ;Note: PDP10, not PDP-10, so fits in 1 word.
TENEX: ASCIZ /TENEX/
TOPS10: ASCIZ /TOPS-10/
TOPS20: ASCIZ /TOPS-20/
TEN50: ASCIZ /10-50/
TWENEX: ASCIZ /TWENEX/
BOTS10: ASCIZ /BOTTOMS-10/
SAIL: ASCIZ /WAITS/
PDP11: ASCIZ /PDP11/
ELF: ASCIZ /ELF/
UNIX: ASCIZ /UNIX/
RSX11: ASCIZ /RSX-11/
HYDRA: ASCIZ /HYDRA/
MULTIC: ASCIZ /MULTICS/
OUTEND=.
CORTOP=OUTEND+20*2000
FOO==.
CONSTANTS
VARIABLES
IFN .-FOO,Constants or variables in skeleton output file
END DUMP