From a80fc4f8add5849bbc0e6db8ca3109b66ebdb350 Mon Sep 17 00:00:00 2001 From: Eric Swenson Date: Wed, 23 Nov 2016 15:19:32 -0800 Subject: [PATCH] Integrated basic ITS networking support and host table. This includes the host table compiler (SYSHST; HOSTS3 BIN) and the host table job submission tool (SYSHST; H3MAKE BIN). No daemons or user networking programs are included in this commit. The binary host table, however, is built from the host table source (SYSHST; H3TEXT >) and installed into SYSBIN; HOSTS3 >. --- Makefile | 2 +- README.md | 30 +- bin/sysbin/hosts3.2012 | Bin 0 -> 5338 bytes build/build.tcl | 12 + build/klh10/{config.202 => config.203} | 14 +- build/klh10/dskdmp.ini | 2 +- src/sra/usefmt.9 | 36 + src/syshst/h3make.56 | Bin 0 -> 7451 bytes src/syshst/h3text.2012 | 183 + src/syshst/hosts3.336 | 4372 ++++++++++++++++++++++++ 10 files changed, 4647 insertions(+), 4 deletions(-) create mode 100644 bin/sysbin/hosts3.2012 rename build/klh10/{config.202 => config.203} (98%) create mode 100755 src/sra/usefmt.9 create mode 100644 src/syshst/h3make.56 create mode 100644 src/syshst/h3text.2012 create mode 100644 src/syshst/hosts3.336 diff --git a/Makefile b/Makefile index 422b684f..14435b91 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ EMULATOR ?= simh -SRC = system syseng sysen1 sysen2 sysnet kshack dragon channa midas _teco_ emacs rms klh +SRC = system syseng sysen1 sysen2 sysnet kshack dragon channa midas _teco_ emacs rms klh syshst sra DOC = info _info_ sysdoc kshack _teco_ emacs emacs1 MINSYS = _ sys sys2 sys3 device emacs _teco_ RAM = bin/boot/ram.262 diff --git a/README.md b/README.md index 0b43d600..21c1e248 100644 --- a/README.md +++ b/README.md @@ -56,5 +56,33 @@ from scratch. - ATSIGN TARAKA, starts dragons. - Dragons: DMPCPY, MODEMS, NETIME, PFTHMG. - MTBOOT, make bootable tapes. + - HOSTS3, the host table compiler. + - H3MAKE, a job that requests DRAGON to build host table. + +6. A brand new host table is built from the host table source and + installed into SYSBIN; HOSTS3 > using H3MAKE. -6. Finally, the whole file system is dumped to tape. +7. Finally, the whole file system is dumped to tape. + +### Network Support + +Currently, networking is only supported under the KLH10 emulator. SIMH does +not have the necessary support. As of this release, only the ITS monitor, +host table tools, and binary host table are installed. There are no network +daemons or user networking tools. These will come in a subsequent release. + +The KLH10 dskdmp.ini file has an IP address (192.168.1.100) and gateway IP +address (192.168.0.45) configured for the ITS system. The IP address +matches the address configured in SYSTEM; CONFIG > (as IMPUS3). Finally, +the HOST table source (SYSHST; H3TEXT >) and binary (SYSBIN; HOSTS3 >) +defined a host called DB-ITS.EXAMPLE.COM at the IP address 192.168.1.100. + +In order to change the IP address of the host, you must update multiple +places and rebuild ITS and the host table. You will also have to modify +dskdmp.ini. Here are the places where the IP address is configured (and all +of these must agree): + +dskdmp.ini (in build/klh10 directory on the host) +SYSTEM; CONFIG > (ITS configuration file) +SYSHST; H3TEXT > (host table source file) +SYSBIN; HOSTS3 > (binary file compiled from SYSHST; H3TEXT >) diff --git a/bin/sysbin/hosts3.2012 b/bin/sysbin/hosts3.2012 new file mode 100644 index 0000000000000000000000000000000000000000..5377fef914bbc1384f6f1e33e13398c9a582b5c4 GIT binary patch literal 5338 zcmZu#Z)_t+6@RmK96NWheYro$T`xVi&E4gatg}h%T$0OOy-n^OIzZZYsc*|?eeDchUIbNWfH>Zz2_dou<_*^n`@80+c=bx|G zr9DZMc#qK8=(LNB@}`52=@gqzP_%0u5Fndg+qDBmuG!cN9Lp!u^BT6kvlH>jYeZ8z#lpF+iL+YM~DXtkPPR`sRjH5Mwg-bX7&jFw`w9HW&O zm10zm(Q1q?$0)Y365A-nHcGLLQf#9X+bG30O0kVnY@-z0D8)8Pv5j(Uqa52P$2Q8b zjdE!ByQNzaPXj#?bWQN zMYWo%w;yzw1PUw`Dnm6Jz8Y(AF+%G`pwP0xp=KTsmfS~?)InDFj!Vt)d%9|zh%_M2c~M#H~Q6@H>MlX?o z2C6GH;~hl7hAIa~mn*nJD(Mtbwj9QoLV)b=0$*cOHobqI69s)6mhTJ!Oqrk3wl1slQ*|*nLf4s zwyoQIdA0prJ<{Nt4w7m({e3g&Z4VZ@V(?if-*Rl%vWuO-toKieZ$Hq%rH6F&afl*I zzSBfBamvhgbFUXbnKzD6v~f`Z z;&4VNE=3)y)-crx?YPb^b=++i0Ug@ajt?z7l^$%Og6x>8kbvCrn{EB$!oF*_Tf0i> zp0}mGL=qE5xl70~q7}Ll0`rf_%e1i{QAD#ECFn|@qS+*qQ+;|i#Uw9I{XpJDSJY#O z>ACl>KSS$Lq#~0-nWRdM1YL{fM1mucFEeQ>)75lOB4>`%o3zr6*~e zuC5J`kI`nnM~eI$mbKX(klv(geaA(Sf*=6Pcs`I;VzLnTPvTYwXiRE{a(Dy z*7_@A=^0wj4@k?j9{UIBU9?{5N%>RaPS8>Qyw9GhsgoRtDdtUk=*}`aT1Qu4G|KvB z808poBe5o)pan)pcF`G(M2Joqn63b^b~?qQHyP!)tDs5k4e<}+dxk^-T^)^%r_rfW z{XWlNFG#R&s$h?^Z)}H-u=F8DFis>Hjl%3iBq>gou8 zqvxh#z&4W=#VY{S6vDiuiUCWKDh5dp2n~IRrecun0;w2`Fki)BBp;2yVJiSV3IUB6 zK>G?+fNm)ST|6Js5a=m|Kqn6vrO=WpeyKc0FpE+JAaU6*5BdPyEVpl{K99@T2rqX%T>4f=u1yiKptg$nJ- z%pd5-GIKyb&2`q~>Y&)7iSfX7KOSzIG4g46&j}nV8b-LlXCjHgibI(OGT#kfgjJ4hG1H zDecT5DMvi*@&HLMX!CM(hSXgGyJ>9_ZqQcGZcSSn7@R1Hzfk@_AQSj^q#~XikWxwf z?U1D7`{L^3V{OdQHm>NK@}<=Lg8-qgq0arp1>cyHjZ`KPXLW(@b`HcK5{xOzuR3 zv!Rwc988%|o0iEuC9}W9TMTcQ9Cvw{HRu(7Zrot>9e$CxGJA)9 zLRWC_%4|Tt;P*u+aUuSSA0D6P7tUv7_DA$PnSBk9K0FQ|m$?G{nV)}8^26;J*7pV0 z_b)uTgpk==Vg#>Ck&wBx$Z&UD=GMeXnfr#Al(~n*X*@+mPG+tSxDW2K zfW#S=;U`csq$zncYN= zXa6IfmAQTKWtlr6zRq*M$=ypb_mucHUaO+P56kb%Tur>nFU}4gg19@ck$8mGE8;Pp H_SXLaPCqnf literal 0 HcmV?d00001 diff --git a/build/build.tcl b/build/build.tcl index 3f68ccec..7e8f505c 100644 --- a/build/build.tcl +++ b/build/build.tcl @@ -289,6 +289,18 @@ respond "*" ":link sys; ts p,sys; ts peek\r" respond "*" ":midas kshack;ts mtboot_kshack;mtboot\r" expect ":KILL" +respond "*" ":midas syshst;_syshst;hosts3\r" +expect ":KILL" + +respond "*" ":link syseng;t20mac 999999,system;t20mac >\r" + +respond "*" ":midas syshst;_syshst;h3make\r" +expect ":KILL" + +respond "*" ":job h3make\r" +respond "*" ":load syshst;h3make bin\r" +respond "*" "\033g" + respond "*" ":link kshack;good ram,.;ram ram\r" respond "*" ":link kshack;ddt bin,.;@ ddt\r" respond "*" $emulator_escape diff --git a/build/klh10/config.202 b/build/klh10/config.203 similarity index 98% rename from build/klh10/config.202 rename to build/klh10/config.203 index 4bfdfcd8..b531a991 100644 --- a/build/klh10/config.202 +++ b/build/klh10/config.203 @@ -956,13 +956,20 @@ IFN DBRM80, DEFOPT RM80P==1 ; with one RM80 DEFOPT NMTCS==1 ;Number of magtape units (so why not NMTUS?) DEFOPT TM03S==1 ;TM03/RH11 Unibus tape controller +DEFOPT NETP==1 ;Has one kind of network anyway +DEFOPT INETP==1 ; Include Internet code +DEFOPT TCPP==1 ; Include TCP code +DEFOPT XBL==30. ; # TCP network channels +DEFOPT IMPP==1 ; Has an IMP interface +DEFOPT SSIMP==1 ; Hooked to "Simulated Simple IMP" + DEFOPT DZ11P==1 ;Has DZ11 TTY controllers DEFOPT DZ11NB==1 ; 1 of them DEFSYM DZ0BA=:760010 DEFOPT NKSTYS==1 ;# KS-10 8080 console 0 TTYs DEFOPT NDZTYS==8. ;# DZ-11 TTYs -DEFOPT NSTTYS==4. ;# of STY's (Pseudo-TTY's) +DEFOPT NSTTYS==20. ;# of STY's (Pseudo-TTY's) DEFOPT TSYSM==512. ;Total PDP10 1K memory blocks DEFOPT NMMP==4 ;# exec pages for MMP table (# vir pgs/512.) @@ -975,6 +982,11 @@ DEFSYM PMRCM==001777 ;2.1 - 1.1 Physical page number ; addresses.) DEFSYM PMUNSD==146000 ;Unused bits +DEFOPT IMPUS==100. ; IMP net host number (old-style) (100 octal) +DEFOPT IMPUS3== ; IP address +DEFOPT NM%IMP== ; Subnet mask +DEFOPT PKTTRC==-1 ;Packet tracing code enabled + DEFINE ITSIRP BODY IRPS ITS,,[DB] BODY diff --git a/build/klh10/dskdmp.ini b/build/klh10/dskdmp.ini index cef1a545..7afdfb2f 100644 --- a/build/klh10/dskdmp.ini +++ b/build/klh10/dskdmp.ini @@ -15,7 +15,7 @@ devdef mta0 rh1.0 tm02 fmtr=tm03 type=tu45 set clk_ithzfix=60 ; Define IMP for PI on ITS.JOSS.COM -devdef imp ub3 lhdh addr=767600 br=6 vec=250 ipaddr=199.34.53.51 gwaddr=199.34.53.50 +devdef imp ub3 lhdh addr=767600 br=6 vec=250 ipaddr=192.168.1.100 gwaddr=192.168.0.45 ; Dummy definitions. Only one DZ is still (apparently) needed. devdef dz0 ub3 dz11 addr=760010 br=5 vec=340 diff --git a/src/sra/usefmt.9 b/src/sra/usefmt.9 new file mode 100755 index 00000000..ac1a2f89 --- /dev/null +++ b/src/sra/usefmt.9 @@ -0,0 +1,36 @@ +;;; -*- Midas -*- code to use SYSENG;FORMAT reasonably + +irp x,,[a,b,c,d,e,j]y,,[1,2,3,4,5,16] + ifndef format"x, format"x==: +termin + +.insrt dsk:syseng;format > + +format"outstr: + ifxe. format"j,<-1,,0> + .call [setz ? sixbit 'siot' ? format"j ? format"a ? setz format"b] + .lose %lssys + ret + endif. + do. + sojl format"b,endlp. + ildb format"c,format"a + idpb format"c,format"j + loop. + enddo. + ret + +define format outdes,&string&,args + call [ saveac [format"a,format"b,format"c,format"d,format"e,format"j] + ifg ,{ + move format"j, + push p,[[movem format"j, ? popj p,]] + } .else ifg <+20>, movei format"j,- + irp x,y,[args] + push p,x + ifb [y] movni format"c,<.irpcnt+1> + termin + hrroi format"a,[ascii string] + movei format"b,.length string + jrst format"format] +termin diff --git a/src/syshst/h3make.56 b/src/syshst/h3make.56 new file mode 100644 index 0000000000000000000000000000000000000000..37423d91ea9d6052cd575167683fce2532a1863a GIT binary patch literal 7451 zcmb7J+j85;5zQ-*O;z6gGOH>TrCkt9N?JQhTGG;zY-!iJ6iLN#aaAc07?L9b7z7u| zbh-2a`PuwJPWJ#HDJkBK$|ixqU~YZ-^yy|-G{0+#^RwgLfUayiS9vJK>F#;&*Avlf zihdD`)62nduq%o+`TN8q|4h9$0}J zpB);VZ{ujcV+O;?E%cL_=s1QmnMpCxMQTna%e{qAvCt_@Pj9U+Wq0`T5+_T|*m29E zA&x>l9?Mh)Jjt{B#0xTAIq1{flYSrjFS1ktA1%7jxM7Guv{xVU)@IGq7erA%36^Kj5DFY;DoQ?d=;omuaM80FXxUQY%jj9Ec<6 zTc!Mst(MR`IlQ_T%9p^%Cx#7Zy^Cyv$dh#l~M>y!i9R4XnM8-pmn!%Jh9KG8s;6OU8kk zxVAmj9jn_FZ`HI&rO-t#)CBtmG#Z)k;suTX^GtB6MMiWIXxlPY6*`fzGa9*tr+(WE zbev8choEpnc4cQY7cfzEu~R-$Db7T=p`Ox=ZHFLvp+yEr`x5pl;=G*FBF2HdvvDN#y_sy~mZq$4ftqq+IM8O8VJ9}fi!}gLa1e7F(LFm%y^OEz)=(TK zGPG7*(A4zk(WDa<)}ubVxl|_7%f+rUs@LAWdAe?LBx2RLh>TC`_)exkEu2W^qTY

FSB#qjLn`ecK)xB`kLNC}}wJU;BQhn9(@5mdF8QekXH(#tV3-+4`Y}5QrJUb9_30N`w<_Qc!X>5HrDVICC#dG1mf&&da^k zW2W{%JPh#9efXK^ zf@D;MV01AA_jHF~TXI%foo%ntys_4WdJJ`35_#Ny{JC? zie^ACnh8e#0fHft%K*}Krux4)>T5$(K^R~(wl{*(P#nU7xmXQL2A~AQa({fJ^#Vif z1%Nm+C8<6PU~YIO6Uj4a2BE%>MsbzSE$Zs*vLnzuU~YseF9=eZfg|$pv$g9qO{nof zbzmm=vW|!v@!a+4#LOT(2E`6>uksnmnz``7HL*loU1R60NPNfHy&>;|CNq;#lxJbeMxeVm5=5~q3OnsvqwE?V;~eLCp1Dl7jRmve^u+LD4Xwa zcl4LB2T&5HQ(OaO8f|7^5rUvXnM-G6uxdQk=$lcgn;Wki1UG|X!tL#Z7Fgmc#}Sg@ zMwqY;ea*Jx)UW6HqH)83ZSFbj4DxQNG>k!Mlnj(3#c=qMA^;>?0@X%NN6M_07Nfnr z)~i;_ad1d{`)`l_)^6En7kFj3{){O3Ve?P)_XUT?>8E3K7=2O3P-#7j zR5SgRnMIjc@Z+i%jurCb;!Q`y1yUIxE%kg@H={5Ij`pPt2vZ?N29JUaY#$Rtdylb# z%z)IwsAX`)E&#mn34XGEa&}wpcRzmjvgHzBrwZYo!jp$k;$;|)u#zh}aW@O4Oz;N# z0&HU3sYvjM9fjM^5U5l<2flzvP%6@osUwCu*T`bJ9CK(7wHByBYvT%lL6W_ij+E(z zRizgQ+r3J7(yigK=&+oJjkhF=`Xf53&91I>LibX zFCvC{E5Hvkg;bg1EZ_{o(jwExi!7fZL!$DqGAH4l zMtgo)x>VV`5DN4V1pLalm_Vr+A5$2RN5gP+M-o~zcGWS^h)qy&4?gM7NkEU{UiG6T%AgaSELtnWc*zk|X)3p#kg@!8<= z!^IOQmUL+HUyfs$5J;THNOM_o zJMW#nZ%|h*C{=a618#zPDUDTtZ_CK314``@-wHgQh zzq+Pc8#Z($bpqbIpMm6z3TI9L>hHajiy#qP+ndUahGEuHX+r%0vO&M+^g=Ioei?pn ze6X@}-n#;!m&Hi&A9VZoU#zmuWSPXM`CU%G%5PL=9l`gBM9bCWp<>Y9HJ%Q^f0p^U1l469YQsjL5ut_ELZnMp)^A+M1 zlMt-Jdc`E?j}x@jH7#9rCa1B#ube6hpoZ7 zWM~sYDsYy#hPXnUS$+9`b$vFwFg#PI2VcuBLDaV3RT{*d`*R2y1nz#P6r>#8{3}F_VBAqvyFNTwrBCLF!p}|7>5`( literal 0 HcmV?d00001 diff --git a/src/syshst/h3text.2012 b/src/syshst/h3text.2012 new file mode 100644 index 00000000..b1266326 --- /dev/null +++ b/src/syshst/h3text.2012 @@ -0,0 +1,183 @@ +;;; -*- Mode: Fundamental; -*- +;;; File mintaka:/u/hosts/hosts3.nets +;;; generated by root@mintaka at 14-May-93 04:47:39 EDT + +;;; This file is generated by a program. Editing it is futile, as +;;; any edit will be lost the next time the program is run. +;;; To make changes to the LCS domain & host tables, you should +;;; use the namespace editor on a Symbolics lisp machine, +;;; and change, add, or delete hosts there. Changes to the LCS +;;; namespace are automatically reflected in this file. + +;;; There must be a comment at the begining of each file that +;;; TS HOSTS3 reads or it will barf. + +;;; Definition of Chaosnet for HOSTS3 UNTERNET scheme. +;;; This is not a value you can change, it's wired into the ITS monitor. +NET : UN 7.0.0.0 : CHAOS : + +NET : 3.0.0.0 : GE-INTERNET : +NET : 4.0.0.0 : SATNET : +NET : 6.0.0.0 : YPG-NET : +NET : 7.0.0.0 : EDN-TEMP : +NET : 8.0.0.0 : BBNCCNET : +NET : 9.0.0.0 : IBM : +NET : 10.0.0.0 : ARPANET : +NET : 11.0.0.0 : DODIIS : +NET : 12.0.0.0 : ATT : +NET : 13.0.0.0 : XEROX-NET : +NET : 14.0.0.0 : PDN : +NET : 15.0.0.0 : HP-INTERNET : +NET : 16.0.0.0 : DEC-INTERNET : +NET : 17.0.0.0 : APPLE-WWNET : +NET : 18.0.0.0 : MIT : +NET : 19.0.0.0 : FINET : +NET : 20.0.0.0 : ANALYTICS : +NET : 21.0.0.0 : DDN-RVN : +NET : 22.0.0.0 : DISNET : +NET : 23.0.0.0 : DDN-TC-NET : +NET : 24.0.0.0 : MINET : +NET : 25.0.0.0 : RSRE-EXP : +NET : 26.0.0.0 : MILNET : +NET : 27.0.0.0 : NOSC-LCCN-TEMP : +NET : 28.0.0.0 : DSI-NORTH : +NET : 29.0.0.0 : MILX25-TEMP : +NET : 30.0.0.0 : ARPAX25-TEMP : +NET : 31.0.0.0 : UCDLA-NET : +NET : 32.0.0.0 : NORGESNETT : +NET : 33.0.0.0 : DCMC : +NET : 34.0.0.0 : HALLIBURTON : +NET : 35.0.0.0 : MERIT : +NET : 36.0.0.0 : SU-NET-TEMP : +NET : 37.0.0.0 : SEQUENT-A : +NET : 38.0.0.0 : PSINETA : +NET : 39.0.0.0 : SRINET-TEMP : +NET : 40.0.0.0 : LILLY-NET : +NET : 41.0.0.0 : BBN-TEST-A : +NET : 42.0.0.0 : CAN-INET : +NET : 43.0.0.0 : JAPAN-A : +NET : 44.0.0.0 : AMPRNET : +NET : 45.0.0.0 : SHOWNETA : +NET : 46.0.0.0 : BBNNET : +NET : 47.0.0.0 : BNR : +NET : 48.0.0.0 : PRUBACHE : +NET : 49.0.0.0 : JITCNET1 : +NET : 50.0.0.0 : JITCNET2 : +NET : 51.0.0.0 : ITSANET : +NET : 52.0.0.0 : DUPONT1 : +NET : 53.0.0.0 : DB-NET2 : +NET : 54.0.0.0 : MERCK2 : +NET : 55.0.0.0 : RCAS : +NET : 56.0.0.0 : USPS1 : +NET : 127.0.0.0 : LOOPBACK : +NET : 128.0.0.0 : B-128 : +NET : 129.0.0.0 : B-129 : +NET : 130.0.0.0 : B-130 : +NET : 131.0.0.0 : B-131 : +NET : 132.0.0.0 : B-132 : +NET : 133.0.0.0 : B-133 : +NET : 134.0.0.0 : B-134 : +NET : 135.0.0.0 : B-135 : +NET : 136.0.0.0 : B-136 : +NET : 137.0.0.0 : B-137 : +NET : 138.0.0.0 : B-138 : +NET : 139.0.0.0 : B-139 : +NET : 140.0.0.0 : B-140 : +NET : 141.0.0.0 : B-141 : +NET : 142.0.0.0 : B-142 : +NET : 143.0.0.0 : B-143 : +NET : 144.0.0.0 : B-144 : +NET : 145.0.0.0 : B-145 : +NET : 146.0.0.0 : B-146 : +NET : 147.0.0.0 : B-147 : +NET : 148.0.0.0 : B-148 : +NET : 149.0.0.0 : B-149 : +NET : 150.0.0.0 : B-150 : +NET : 151.0.0.0 : B-151 : +NET : 152.0.0.0 : B-152 : +NET : 153.0.0.0 : B-153 : +NET : 154.0.0.0 : B-154 : +NET : 155.0.0.0 : B-155 : +NET : 156.0.0.0 : B-156 : +NET : 157.0.0.0 : B-157 : +NET : 158.0.0.0 : B-158 : +NET : 159.0.0.0 : B-159 : +NET : 160.0.0.0 : B-160 : +NET : 161.0.0.0 : B-161 : +NET : 162.0.0.0 : B-162 : +NET : 163.0.0.0 : B-163 : +NET : 164.0.0.0 : B-164 : +NET : 165.0.0.0 : B-165 : +NET : 188.0.0.0 : B-188 : +NET : 192.0.0.0 : C-192 : +NET : 193.0.0.0 : C-193 : +NET : 195.0.0.0 : C-195 : +NET : 196.0.0.0 : C-196 : +NET : 197.0.0.0 : C-197 : +NET : 198.0.0.0 : C-198 : +NET : 199.0.0.0 : C-199 : +NET : 200.0.0.0 : C-200 : +NET : 202.0.0.0 : C-202 : +NET : 224.0.0.0 : C-224 : + +;;; PI additions +HOST : 199.34.53.50 : CP.JOSS.COM, Cretaceous-Park.joss.com, CP, ITS.JOSS.COM, ITS : P3-450 : UNIX : : +HOST : 199.34.53.51 : PI.ITS.OS.ORG, PI : PDP-10 : ITS : : +HOST : 199.34.53.52 : DX.ITS.OS.ORG, DX : PDP-10 : ITS : : +HOST : 199.34.53.53 : DU.ITS.OS.ORG, DU : PDP-10 : ITS : : +HOST : 199.34.53.54 : UNKNOWN.ITS.OS.ORG : PDP-10 : ITS : : + +;;; Other virtual ITSes +HOST : 10.134.198.236 : KN.ITS.OS.ORG, KN : PDP-10 : ITS : : + +;;; KLH's NX additions, patched in for testing. +HOST : 192.168.0.203 : MD.ITS.OS.ORG, MD : PDP-10 : ITS : : +HOST : 192.168.0.236 : NX.MIT.EDU, MIT-NX, NX : PDP-10 : ITS : : +HOST : 192.168.0.10 : AXPKLH.KENTEN.COM, AXPKLH : AXP : UNIX : : +HOST : 192.168.0.33 : PCKLH.KENTEN.COM, PCKLH : C450 : UNIX : : + +;;; Eric Swenson's ITS +HOST : 192.168.0.100 : ES-ITS.SWENSON.ORG, ES : PDP-10 : ITS : : +HOST : 10.0.0.55 : ES-GW.SWENSON.ORG : PC : LINUX : : + +;;; Historical interest +HOST : 10.1.0.6 : DM.MIT.EDU, MIT-DM, DM : PDP-10 : ITS : : +HOST : 10.2.0.6 : AI.MIT.EDU, MIT-AI, AI : PDP-10 : ITS : : +HOST : 10.3.0.6 : ML.MIT.EDU, MIT-ML, ML : PDP-10 : ITS : : +HOST : 10.3.0.54 : MC.MIT.EDU, MIT-MC, MC : PDP-10 : ITS : : +HOST : 10.0.0.51 : SRI-NIC.ARPA,SRI-NIC,NIC,NIC.DDN.MIL : DEC-2060 : TOPS20 : : + + +;;; KLH: Most of the rest has been flushed, except for a few token entries. +;;; Oddly enough, neither of the last two ITS machines were originally here. +HOST : 36.86.0.194 : SAIL.STANFORD.EDU : DEC-1080 : WAITS : : +HOST : 36.21.0.101 : Lear.Stanford.EDU,LOTSA : DEC-2060 : TOPS20 : : +HOST : 192.88.110.20 : WSMR-SIMTEL20.ARMY.MIL,SIMTEL20.ARMY.MIL : DEC-2065T : TOPS20 : : +HOST : 36.67.0.210,36.19.0.210 : GSB-HOW.STANFORD.EDU,SU-GSB-HOW.STANFORD.EDU : DEC-2060 : TOPS20 : : +HOST : 36.67.0.209,36.19.0.209 : GSB-WHY.STANFORD.EDU,SU-GSB-WHY.STANFORD.EDU : DEC-2060 : TOPS20 : : +HOST : 36.21.0.102 : Othello.Stanford.EDU,LOTSB : DEC-2060 : TOPS20 : : +HOST : 36.36.0.196,36.8.0.53 : SUSHI.STANFORD.EDU,SU-SUSHI.STANFORD.EDU : DEC-2060 : TOPS20 : : +HOST : 192.5.56.1 : TL-20B.TARTAN.COM : DEC-2060 : TOPS20 : : +HOST : 36.21.0.13 : Macbeth.Stanford.EDU : SC-30M : TOPS20 : : +HOST : 128.110.192.2 : SCIENCE.UTAH.EDU : DEC-2060 : TOPS20 : : +HOST : 128.18.10.6 : KL.SRI.COM,STRIPE.SRI.COM : DEC-1090T : TOPS20 : : +HOST : 16.34.0.2 : GIDNEY.TOPS20.DEC.COM,TOPS20.DEC.COM : DEC-2065 : TOPS20 : : +HOST : 36.21.0.103 : Hamlet.Stanford.EDU,LOTSC : DEC-2060 : TOPS20 : : + + +;;; -*- Mode: Fundamental; -*- +;;; File mintaka:/u/hosts/hosts3.hosts +;;; generated by root@mintaka at Mon May 17 04:10:30 1993 + +;;; This file is generated by a program. Editing it is futile, as +;;; any edit will be lost the next time the program is run. +;;; To make changes to the LCS domain & host tables, you should +;;; use the namespace editor on a Symbolics lisp machine, +;;; and change, add, or delete hosts there. Changes to the LCS +;;; namespace are automatically reflected in this file. + +;;; KLH: All of the rest of this stuff was flushed... see older versions +;;; of H3TEXT for the cruft. +HOST : 192.168.1.100 : DB-ITS.EXAMPLE.COM : Linux : Linux : : + + \ No newline at end of file diff --git a/src/syshst/hosts3.336 b/src/syshst/hosts3.336 new file mode 100644 index 00000000..dde669e7 --- /dev/null +++ b/src/syshst/hosts3.336 @@ -0,0 +1,4372 @@ +;-*-MIDAS-*- Must be first thing so EMACS knows this is a MIDAS source file + +; The official version of this program is the file +; [SRI-NIC] HOSTS3.MID +; However, development rarely ends, and people who want to improve it +; should consult KLH@SRI-NIC for the latest changes. + +TITLE HOSTS3 Host-table Compiler + +; SYNOPSIS: HOSTS3 /INSERT /OUTFIL + +; This program is a "host-table compiler" which accepts human-readable +; text files describing nets, hosts, etc. and outputs a compact binary +; file which can be easily mapped in and used by any program. + +; Input text files must be in either "RFC810" (the default) or "HOSTS2" format. +; Descriptions of these text formats can be found in: +; HOSTS2 - [MIT-MC] SYSENG;HOSTS > +; RFC810 - [SRI-NIC] RFC810.TXT +; There are also a number of keywords that are "pseudo-ops", +; meaningful only to the HOSTS3 compiler. These are described later. +; The output binary file can be in either "HOSTS2" or "HOSTS3" format. +; Both of these formats are described later in this program. + +; Relevant mailing lists: +; INFO-HOSTS @ MIT-MC ; For updates to data or pgm +; INFO-HOSTS-REQUEST @ MIT-MC ; To be added to above list + +; Canned procedures to make new versions of the host-tables: +; ITS: Do :XFILE MC:SYSENG;HOSTS XFILE +; SAIL: Do BATCH/NOW @HOSTS. + +; Software packages that help use the binary host table: +; MIDAS assembler: +; ITS: [MIT-MC] DSK: SYSENG;NETWRK > +; TNX: [MIT-OZ] SS:NETWRK.MID + +SUBTTL Program Use - Keywords, Defaults, etc. +comment | + + Normally the formats and filenames used by the compiler are specified +by using certain keywords either in the JCL (job command line) or in +the input text files. However, if omitted, the compiler will try to +default things according to the following tables: + +Default formats Input text Output bin + Normal start: RFC810 HOSTS3 + Start addr+1: HOSTS2 HOSTS2 + Start addr+2: HOSTS2 HOSTS3 + Start addr+3: RFC810 HOSTS2 + +Default filenames + Input (after JCL) Output + ITS: HOSTS > HOSTS3 > (or HOSTS2) + TNX: HOSTS.TXT HOSTS3.BIN (or HOSTS2) + SAIL: HOSTS.TXT[HST,NET] HOSTS3.BIN[HST,NET] (or HOSTS2) + +----------------------------------------------------------------- + COMPILER KEYWORDS + + Keywords must always be the first thing on a line. The only +exception to this is when input is furnished as JCL, where "/" is +interpreted as newline (double it to quote, like "//"); thus several +keywords can be furnished on one line. For example, the old HOSTS2 +compiler can be emulated with JCL of "/HOSTS2 /OUTFMT HOSTS2". +The following list is functionally organized. + +NET - Data entry, defines a network name and number. +HOST - Data entry, defines a network site (names, addresses, attributes) +GATEWAY - Data entry, same as HOST but claims to be an Internet Gateway. + Eventually GATEWAY will be flushed and gatewayness will + simply be indicated by a service/protocol name such as "IP/GW". + +HOSTS2 - Parse following input as HOSTS2 format. +RFC810 - Parse following input as RFC810 format. +OUTFMT - Specify output format, one of HOSTS2 or HOSTS3. Once only. +OUTFIL - Specify output file name. Once only. +INSERT - Insert specified file at this point. The current input + format will be preserved across INSERTs. +MERGE - Indicate that all following data should be "merged" in certain + cases where definitions conflict. Meaning is still unclear. +MERGEOFF - Turns off indicator for following data. +ONLY - Include only hosts with addresses on the specified network + (can be used more than once). Makes a smaller table. + (This feature has been IFNd out, since it disappeared + from later versions of the source. Ask KLH?) +GWHOSTS - Do not report Gateway/Host duplicate addr errors +HST2DUPS - Only allowed when /OUTFMT HOSTS2. Specifies that if any + duplicate HOSTS2 addresses are found, report and count + them but do not consider them fatal. Useful when compiling + Internet addresses which are the same except for the third byte; + HOSTS2 cannot really represent such addresses correctly. + The MIT "new Chaosnet wrapping" scheme's uses such addresses. +ALLSERVER- Turn on the STFSRV flag for all entries in the table. This is + a kludge to allow the compiler to run in a single section for + a little while longer. Ask SRA@XX. + + +----------------------------------------------------------------- + COMPILER ERROR MESSAGES + + Most error messages are self-explanatory. However, a basic +notion of how the compiler works will make them easier to interpret. +In general, the program tries to proceed as far as it can before stopping, +in order to report as many errors as possible, and will only write out +the resulting binary file if it thinks that none of the errors are serious. +The definition of "serious" can depend on whether one is trying to use +HOSTS2 or HOSTS3 format, and a few other things. + + The first thing that the compiler does is read and parse ALL +of the input into an internal format. If there was anything wrong +with the syntax of anything in the input files, it will be reported +(along with the line number that the error happened on) and the +internal tables will NOT be processed after parsing is done. + + If all parsing was successful, the compiler will then print +"Processing tables..." and will start building the output file image. +During this processing, various checks are made both of the data (to +verify completeness, merge or eliminate duplicates, etc) and of internal +parameters. Some warning messages may be printed; most of these have +to do with duplicate definitions of host names or net addresses, and +may or may not be considered serious errors. In general, because processing +large amounts of data is so time-consuming, the compiler will usually +write out the binary anyway. + + The way that duplicate definitions are handled is explained +to some extent by the comments prefacing the MERGE routine. + +| ; End of comment + +subttl FORMATS + +; Herein is the description of the compiled binary output file. The +; HOSTS2 and HOSTS3 binary files have almost the same format and most +; of the following description applies to both; exceptions are noted. +; General terms: +; "fileaddr" = a file address, relative to start of file. +; "netaddr" = a network address, in either HOSTS2 or 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 /HOSTS2/ or /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 for HOSTS3, but alphabetically by name +; for HOSTS2 (for compatibility, sigh) +; Each entry contains: + +NETNUM==:0 ; wd 0 network number (HOSTS2: 8-bit #) (HOSTS3: full netaddr) +NTLNAM==:1 ; wd 1 LH - 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. (HOSTS2 2, HOSTS3 3) +; 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 and services for a site is stored +; within these tables. +; Each entry contains: + +ADDADR==:0 ; wd 0 Network address of this entry, in HOSTS2 or HOSTS3 fmt. +ADLSIT==:1 ; wd 1 LH - fileaddr of SITE table entry +ADRCDR==:1 ; wd 1 RH - fileaddr of next ADDRESS entry for this site + ; 0 = end of list + ADDLN2==:2 ; HOSTS2 length of entry; 3rd word only used if HOSTS3 +ADLXXX==:2 ; wd 2 LH - unused +ADRSVC==:2 ; wd 2 RH - fileaddr of services list for this address + ; 0 = none, else points to SERVICE node of format: + SVLCNT==:0 ; <# wds>,, + SVRCDR==:0 + SVLFLG==:1 ; ,, + SVRNAM==:1 + SVCARG==:2 ; ? ? ... + ADDLEN==:3 +.SCALAR ADDLNV,ADDLN1 ; Holds values of ADDLEN and ADDLEN-1 to use. + +; 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 - fileaddr of official host name +STRADR==:0 ; wd 0 RH - fileaddr of first ADDRESS table entry for this + ; site. Successive entries are threaded + ; together through ADRCDR. +STLSYS==:1 ; wd 1 LH - fileaddr of system name (ITS, TIP, TENEX, etc.) + ; May be 0 => not known. +STRMCH==:1 ; wd 1 RH - fileaddr of machine name (PDP10, etc.) + ; May be 0 => not known. +STLFLG==:2 ; wd 2 LH - flags: +STFSRV==:400000 ; 4.9 1 => server site (has FTP or TELNET) +STFGWY==:200000 ; 4.8 1 => Internet Gateway site (HOSTS3 only) + SITLEN==:3 + +; 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. It +; contains entries sorted alphabetically by host name. + +NMLSIT==:0 ; wd 0 LH - fileaddr of SITE table entry for this host. +NMRNAM==:0 ; wd 0 RH - fileaddr of host name + ; This name is official if NMRNAM = STLNAM of NMLSIT. + NAMLEN==:1 + +; NETNAME table: +; wd 0 Number of entries +; wd 1 Number of words per entry. (1) +; This table is used to convert network names into network numbers. It +; contains entries sorted alphabetically by network name, exactly as +; for the NAMES table. Although the symbols below are different (in order +; to make semantic distinctions), programs can depend on the fact +; that the NETNAME table format is identical to that of the NAMES table. +; NOTE: this table did not exist in the original HOSTS2 format, but its +; addition doesn't break anything in HOSTS2. + +NNLNET==:0 ; wd 0 LH - fileaddr of NETWORK table entry for this host. +NNRNAM==:0 ; wd 0 RH - fileaddr of network name + NTNLEN==:1 + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;; HOSTS3 Network Address Format ;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; +;;; All network numbers and network addresses are stored +;;; internally in HOSTS3 format. If the binary output is in +;;; HOSTS2 format, the addresses are converted as the last +;;; step before actual output begins. + +comment | +HOSTS3 network address format: + + 4.9-4.6 - 4 bits of format type, which specify interpretation of + the remaining 32 bits. +IN 0000 - Internet address (handles ARPA, RCC, LCS) + 4.5-1.1 - 32 bits of IN address. +UN 0001 - Unternet address. Same format, but not part of Internet. + 4.5-3.7 - HOSTS3-defined network number (1st 8-bit byte) + 3.6-1.1 - address value in next 24 bits. + This handles CHAOS and any local nets. The network + numbers are unique within the HOSTS3 table but + don't necessarily mean anything globally, as do + Internet network numbers. + 0011 - String address. + 4.5-3.7 - HOSTS3-defined network number (1st 8-bit byte) + 3.6-3.1 - 0 + 2.9-1.1 - address of ASCIZ string in file/process space + +Note that the "network number" for all of these formats is located in +the same place. However, for fast deciphering of the entire range of +possibilities, one could simply consider all of the high 12 bits as the +network number. Beware of the Internet class A, B, and C formats, though; +the only truly general way to compare network numbers is to use their +masked 36-bit values, although simpler checks are OK for specific nets. +For this reason (among others) network numbers are represented by +full 36-bit values with the "local address" portion zero. + +The 4-bit "String address" value is much more tentative than the IN or UN +values. Bit 4.9, the sign bit, is being reserved as usual for the possible +advent of a truly spectacular incompatible format. +| +NT$NUM==:301400 ; Byte pointer to network number (high 12 bits) +NE%UNT==:040000,,0 ; Escape bit indicating "Unternet" type address +NE%STR==:100000,,0 ; Escape bit indicating "string" type address + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;; HOSTS2 Network Address Format ;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; +;;; This is the old pre-HOSTS3 format. Only addresses for +;;; a few specific networks can be accepted, as the compiler +;;; must have built-in knowledge about each one. + +; The following networks are acceptable during HOSTS2 parsing: +; IN, ARPA, BBN-RCC, CHAOS, DSK, DIAL, LCS, SU, RU, ECL, ZOT. +; To add more networks, add entries to the UNTTAB table. +.see UNTTAB +comment | +HOSTS2 network address format: + + 4.9-4.1 network number. + 3.9-1.1 network dependent. In following descriptions, unused bits must be 0. + +Net - (0): in octal + For HOSTS2-format INPUT only, if a net address has a zero net number + then the compiler assumes it is an "old-format" ARPAnet address, + which looks like: + 1.8-1.7 Host number + 1.6-1.1 IMP number + However, it is instantly converted to a canonical format address + and thus "old-format" addresses will never appear in the tables. + +Net ARPA (12) and RCC (3): / in decimal + 3.7-2.1 IMP + 1.8-1.1 Host + +Net DIAL (26): ; Dialnet addresses are always ASCIZ strings. + 2.9-1.1 (RH) fileaddress of ASCIZ phone number string + +Net CHAOS (7)

in octal + 2.7-1.1 address (2.7-1.9 subnet, 1.8-1.1 host) + +Net SU (44): # in octal + 2.7-1.1 address (2.7-1.9 subnet, 1.8-1.1 host) + +Net LCS (22): / in octal + 3.8-3.1 Subnet + 1.8-1.1 Host + +Net RU (61):
in octal + 3.8-3.1 Subnet + 1.8-1.1 Host + +Net DSK (777):
in octal (becomes Unternet 1 in HOSTS3) +Net ECL (776):
in octal (becomes Unternet 2 in HOSTS3) +Net ZOT (775):
in octal (becomes Unternet 3 in HOSTS3) + +Net IN (*): ... in decimal + 3.6-1.1 low 24 bits of Internet address + + If the network number is not otherwise known to HOSTS2, it is + interpreted as the first octet of an Internet address + with the remaining 24 bits right justified (ie a gap + of 3 bits between 1st octet and next 3 octets). +| +NW$BYT==:331100 ;Byte pointer to HOSTS2 network number + +comment | +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +The rest of this section talks about conversion from HOSTS2 to HOSTS3 netaddr +formats and details the possible areas of confusion. + +Formats required for feeding to operating systems: + For ITS: + Both HOSTS2 and HOSTS3 addresses are accepted directly + for NCP/TCP. Addresses are returned in HOSTS2 format + for NCP calls, HOSTS3 format for TCP calls. + CHAOS 16-bit addresses are extracted from the 36-bit word and + used in CHAOS-specific system calls. + No other unternets supported. + For 10X/20X: + ARPA addresses must be in HOSTS3 IN format (both NCP and TCP) + CHAOS probably not + LCS - could be, don't know. + DIAL needs conversion of course + SU is PUP net, pre-HOSTS2, so direct use unlikely. + RU, DSK - ? + Others:? + +HOSTS3 format network #'s that could be confused with valid HOSTS2 networks: + (If a HOSTS3 format # is given to a program that uses + a HOSTS2 BP to get the network number) + HOSTS3 # HOSTS2 # + RCC 3 0 (invalid) + Chaos 7 0 (invalid) + Arpa 12 (10.) 1 (invalid) + LCS 22 (18.) 2 (invalid) + Dial 26 (22.) 2 (invalid) + SU 44 (36.) 4 (invalid) + RU 61 (49.) 6 (invalid) + various 3x ( 24-31) 3 RCC + undef 7x ( 56-63) 7 Chaos + undef 12x ( 80-87) 12 Arpa + undef 22x (144-151) 22 LCSnet + undef 26x (176-184) 26 Dialnet + - UN 4x 44 SU + - UN 21x 61 RU + +HOSTS2 values that could be confused with HOSTS3 networks: + (if a HOSTS2 value is given to program using a HOSTS3 BP) + HOSTS2 # HOSTS3 # + RCC 3 30, 31 (24.,25. = BBN-LOCAL, RSRE-PPSN) + Chaos 7 70 (56. = undefined) + Arpa 12 120,121 (80.,81. = undefined) + LCS 22 220,221,222,223 (144.,145.,146.,147. = undefd) + Dial 26 260 (176. = undefined) + SU 44 UN 40 (undefined) + RU 61 UN 21x (undefined) + + +So the only real stinker is RCC; all other possible overlaps are +merely with undefined values. Since ITS won't be talking with RCC +except via Internet (in which case HOSTS3 will be used), it can be +ignored. TNX sites should likewise be using IN format host numbers for +RCC. I have ignored "DSKnet" since I don't know if anything uses it, +and it should be easy to stick local nets in with bit 4.6 set. +Note, by the way, that CHAOS might be expressed as a subset of +the LCS ("MIT") network, and consequently CHAOS addresses would be of +Internet type. Sort of a political decision. + +;;;;;;;;;;;;;;;;;;;;;;;;;; + +There are routines in MC:SYSENG;NETWRK > which will perform conversion +of addresses from any format to either HOSTS2 or HOSTS3 format: + + CVH2NA - Convert network host address in A to HOSTS2 format. + CVH3NA - Convert network host address in A to HOSTS3 format. + +| ; end of moby comment! + +;;;;;;;;;;;;;;; INTERNAL TABLE FORMATS ;;;;;;;;;;;;;;;;; + +; Both HOSTS2 and RFC810 format input files are parsed into the same +; internal format prior to generating the output file. During parsing, +; the following internal tables are used: + +; NWKTAB - internal network table with entries of this form: + +NWKNUM==:0 ; wd 0 -> network number +NWKNAM==:1 ; wd 1 LH # sites for this net + ; RH -> asciz network name +NWKPTR==:2 ; wd 2 LH fileaddr of ADDRESS table + ; RH abs addr of NETWORK table entry +NWKLEN==:3 ; 3 words per network entry + +; HSTTAB - internal host table at with entries of this form: + +HSTNAM==:0 ; wd 0 If = 0, entry is dead, should be ignored. Else, + ; RH -> asciz host name + ; LH Flags. + HE%SEC==400000 ; Sign bit = entry is secondary. + HE%2IN==200000 ; Entry was read in HOSTS2 format (else RFC810) + HE%MRG==100000 ; Entry was read with MERGE flag on. + HE%GWY==040000 ; Entry was read as a GATEWAY, not a HOST +HSTNUM==:1 ; wd 1 -> 1st item of host number list. Each item is 1 word, + ; NOT starting with HSTNUM: + ; LH -> host number + ; RH -> next item (or 0 if no more) +HSTFLG==:2 ; wd 2 LH Flags. Filled out as for STLFLG. + ; RH -> SITE entry in file space (set late in processing) +HSTSYS==:3 ; wd 3 RH -> asciz system name (may be 0). +HSTMCH==:4 ; wd 4 RH -> asciz machine name (may be 0). +HSTNIC==:5 ; wd 5 nickname list. Each item is 1 word, + ; starting with this word itself: + ; LH -> next item in list + ; RH -> asciz nickname + ; An all-zero item, rather than zero LH, terminates list. +HSTSVC==:6 ; wd 6 service list. Same as ADRSVC; points to list of + ; service nodes. + ; Not used by HOSTS2. +HSTSEC==:7 ; wd 7 LH -> primary entry (if this one is secondary) + ; RH -> next secondary entry (0 if none or no more) + ; as part of list starting from primary entry. + +HSTLEN==:10 ; # wds per internal host entry. + +; "Secondary" entries are created by MERGE. A normal "primary" entry +; will have a pointer in RH of HSTSEC if any secondaries exist for it; +; each such secondary entry will likewise have a pointer to any further +; secondaries. A zero pointer terminates the chained list. +; All secondary entries have a pointer (LH of HSTSEC) back to the primary +; entry, for cross-checking. + +SUBTTL General definitions + +; Determine OS we're assembling for. + +IFNDEF ITSSW,ITSSW==IFE <.OSMIDAS-SIXBIT/ITS/>,[-1] .ELSE 0 +IFNDEF SAILSW,SAILSW==IFE <.OSMIDAS-SIXBIT/SAIL/>,[-1] .ELSE 0 +IFNDEF TNXSW,TNXSW==IFE <<.OSMIDAS-SIXBIT/TENEX/>&<.OSMIDAS-SIXBIT/TWENEX/>>,[-1] .ELSE 0 +IFNDEF ONLY,ONLY==0 ;Switch controls the old ONLY feature +;AC Defs + +F=0 +A=1 +B=2 +C=3 +D=4 +E=5 +G=6 +H=7 +T=10 +TT=11 +T3=12 +M=13 +N=14 ; used as network table ptr in GHOST +FA=15 ; Pointer to file address 0 +;=16 +P=17 + +IFNDEF MAXINS,MAXINS==8 ; Max # of INSERT levels allowed. +IFNDEF MAXFIL,MAXFIL==10. ; Max # of distinct files allowed. + +CALL=PUSHJ P, +RET=POPJ P, +INS$AC==270400,, ; AC field BP + +EQUALS VAR,.SCALAR ; More reasonable name for defining vars + +DEFINE TYPE6 (ADDR) + MOVE A,ADDR + CALL SIXOUT +TERMIN +DEFINE TYPE &STR& + PUSH P,[[ASCIZ STR]] + CALL TYPOUT +TERMIN +DEFINE TYPECR &STR& + TYPE STR + CALL CROUT +TERMIN + +DEFINE MDBP7 AC ; Back up 7-bit BP in AC + ADD AC,[070000,,] ; Incr P + CAIG AC, ; If went to prev, + SUB AC,[430000,,1] ; point to prev. +TERMIN + +DEFINE BABBLE *A,*B + PRINTX Á!B +Š TERMIN + +; Flags in LH of AC F (Global, not saved/restored across INSERTs) + +FL%R2I==1 ; User requested HOSTS2 input parse (else RFC810) +FL%R2O==2 ; User requested HOSTS2 output +FL%R3O==4 ; User requested HOSTS3 output +FL%2OU==20 ; Currently outputting HOSTS2 binary format (otherwise HOSTS3) +FL%MRG==40 ; Currently merging new entries +FL%2DH==100 ; User says that HOSTS2 duplicate addrs are non-fatal + +; Flags in RH of AC F (local, saved and restored across INSERTs) + +FR%RCH==1 ; Backed-up char for RCH +FR%SIN==2 ; String input for RCH +FR%2IN==10 ; Currently parsing HOSTS2 input format (otherwise RFC810) + +SUBTTL System-dependent assembly initializations + +IFN ITSSW, LOC 100 ; ITS absolute assembly + +IFN TNXSW,[ ; TENEX/TOPS-20 + .DECSAV ; absolute assembly + LOC 140 +];IFN TNXSW + +IFN SAILSW,[ ; SAIL relocatable assembly + HSTTAB=:400000 ; This must *NOT* change!! +];IFN SAILSW + +SUBTTL Error Handling + +DEFINE ERROR &STR&,?ARG=EVNONE + CALL [ PUSH P,[[ASCIZ STR]] + PUSH P,ARG + JRST ERRGO] +TERMIN +DEFINE FILERR &STR&,FILPT,?ARG=EVNONE + CALL [ PUSH P,[[ASCIZ STR]] + PUSH P,ARG + PUSH P,FILPT + JRST ERRGOF] +TERMIN + + +ERRGOF: SOS -3(P) ; Decrement return addr so we re-try losing operation. + SOS -3(P) + EXCH A,-2(P) ; Get string + EXCH B,-1(P) ; Get error number arg + CALL ASZOUT ; Output the string + POP P,A ; Get pointer to filename + CALL SYSTFN ; Type it appropriately + JRST ERRGO5 + +ERRGO: EXCH A,-1(P) ; Get string + EXCH B,(P) ; Get error number arg + CALL ASZOUT ; Output the string +ERRGO5: CAME B,EVNONE + JRST [ TYPE " - " + MOVE A,B + CALL SYSERR ; Output system error if one + JRST .+1] + CALL CROUT + POP P,B + POP P,A + JRST SYSHLT ; Act as if called SYSHLT directly. + + +SUBTTL Start + +HTSIZE==:43. ; Number of K for internal host table +NTSIZE==:3. ; Number of K for internal network table +STSIZE==:120. ; Number of K for internal strings +OFSIZE==:83. ; Number of K for output file image +UPSIZE==:HTSIZE+NTSIZE+STSIZE+OFSIZE + +;; Actual space allocation moved to end of file so can do it on the fly. + +PATCH: PAT: BLOCK 40 + +LPDL==100 +VAR PDL(LPDL+10) + +VAR ERRPAR ; # of parsing errors +VAR ERRUNN ; # of hosts on unnamed network +VAR ERRDHA ; # duplicate host addresses +VAR ERRDGA ; # duplicate gateway-vs-host addrs +VAR ERRDHN ; # duplicate host names +VAR ERRDNA ; # duplicate network numbers +VAR ERRDNN ; # duplicate network names (maybe counted twice) +VAR ERRFTL ; # fatal internal consistency errors + +VAR ENTOFF ; Saved entry offset + +START: JRST START0 + JRST START1 + JRST START2 + JRST START3 + +START0: TDZA A,A ; Put start offset into A +START1: MOVEI A,1 + JRST START3+1 +START2: SKIPA A,[2] +START3: MOVEI A,3 + MOVEM A,ENTOFF ; Save for possible hackery + SETZ F, + TDO F,(A)[ FL%R3O,, ; 0 = Default - RFC810 in, HOSTS3 out + FL%R2I+FL%R2O,, ; 1 = HOSTS2 in, HOSTS2 out + FL%R2I+FL%R3O,, ; 2 = HOSTS2 in, HOSTS3 out + FL%R2O,,] ; 3 = RFC810 in, HOSTS2 out + MOVEI B,1 + TLNE F,FL%R2O ; If selected by entry vector, + MOVEM B,OFMTIX ; set output format index to HOSTS2 + MOVE P,[-LPDL,,PDL-1] + MOVEI FA,OUTTAB ; Define file address space to start here + CALL SYSINI ; Perform system-dependent initializations + + TLNE F,FL%R2I ; If requesting HOSTS2 input + TRO F,FR%2IN ; then claim now parsing that format. + TLNE F,FL%R2O ; If requesting HOSTS2 output + TLO F,FL%2OU ; then claim currently outputting that fmt. + MOVEI A,HDRLEN(FA) ; Set place to start writing into file + MOVEM A,OUTPT + SETZM (A) ; Ensure output file image is zeroed + HRLI A,(A) + ADDI A,1 + BLT A,-1(FA) + MOVE B,OFMTIX + MOVE A,OFMTBI(B) ; Get right ID for output file format + MOVEM A,HSTSID(FA) + MOVEI A,ADDLEN ; Set right value for ADDRESS-table length + TLNE F,FL%2OU + MOVEI A,ADDLN2 + MOVEM A,ADDLNV + SUBI A,1 + MOVEM A,ADDLN1 + +IFN TNXSW,{ ; Don't bother, just thrashes the pager + ; and makes the fork's page map illegable + SETZM HSTTAB ; Ensure internal table space all zeroed + MOVE A,[HSTTAB,,HSTTAB+1] + BLT A,STREND-1 +};IFN TNXSW + MOVE A,[440700,,STRTAB] ; Set up pointer for storing strings + MOVEM A,TOKBP +IFN ONLY,[SETZM ONLYLS] + MOVEI B,2000. ; Should be plenty! + CALL SYSJCL ; Get JCL if any + ERROR "JCL too large for buffer!" + JUMPGE B,[MOVEI C,10.(B) ; Got JCL, adjust storage pointer past it. + IDIVI C,5 + ADD C,A ; Get loc safely beyond end of JCL + HRLI C,440700 + MOVEM C,TOKBP ; Set new storage pointer + JRST .+1] + CALL RHOSTF ; Given possible arg string, read in host file + SKIPE ERRPAR + JRST [ TYPECR "Text file has parsing errors - not proceeding." + JRST SYSDON] + + TYPECR "Processing tables..." + CALL HSTPRC ; Process table entries + + CALL STATS ; Print out interesting stat stuff + + ; Last check... see if any errors during processing. + ; We don't currently consider ERRDHA (dup hostaddrs) errors for + ; HOSTS3 since that can legitimately happen for gateway entries. + ; This will eventually be fixed when gateways are merged too. + SETZ A, + ADD A,ERRFTL ; Always die for internal consistency errors. + ADD A,ERRUNN ; Die for Un-Named Networks (unknown) + TLNN F,FL%2DH ; Unless user said they're non-fatal + ADD A,ERRDHA ; count Duplicate Host Addrs too. + TLNE F,FL%2OU + JRST [ ; Check these errors only for HOSTS2 output + SKIPN FILCNT + ADD A,ERRDHN ; Duplicate Host Names are bad if only 1 file! + JRST .+1] + JUMPN A,[CALL DECOUT + TYPECR / "serious" errors, so not writing binary file./ + JRST SYSDON] + + MOVE D,OFMTIX ; Get format index + MOVE A,OFMTBI(D) ; Get right ID for output file format + MOVEM A,HSTSID(FA) ; Set it in output - now complete! + TYPE "Writing " + CALL SIXOUT + TYPE " format binary file " + SKIPN A,OUTFNM ; Get output filename if any specified + MOVE A,OFMTBF(D) ; None given, use default. + CALL SYSOUT ; Output host-table file (and filename to TTY) + TYPECR "" + + JRST SYSDON ; Done, exit gracefully. + + +; RHOSTF - Read in data, using JCL if a string is furnished, else default file. +; A/ BP to ASCIZ string. +; B/ # chars in string + +RHOSTF: MOVEI H,HSTTAB ; Place to start host table + MOVEI N,NWKTAB ; Place to start network table + + JUMPLE B,RHSTF2 ; Skip JCL stuff if no JCL. + MOVEM A,RCHBP ; Set up to read from JCL string + TRO F,FR%SIN ; and flag to make RCH do so. + CALL GENTRY ; Do initial parsing + SKIPLE FILCNT ; Did we read in at least one file? + JRST RHSTF5 ; Yep, parsing all done! + SKIPE ERRPAR ; Maybe no input file cuz JCL parse error... + ERROR "JCL parsing errors, aborting." + + ; No JCL or no input filename, so use default input file. +RHSTF2: SKIPL A,SYSIFN ; Specifying HOSTS file appropriate for sys, + HRLI A,440700 + CALL RDINS0 ; go insert the file. + +RHSTF5: MOVEM H,HSTTBE ; Save pointers to ends of tables + MOVEM N,NWKTBE + CAIG H,HSTTAB + ERROR "No HOST/GATEWAY entries seen, aborting." + CAIG N,NWKTAB + ERROR "No NET entries seen, aborting." + CAIL H,NWKTAB ; Host table overflowed into network table? + ERROR "Host table alloc too small, increase HTSIZE." + CAIL N,STRTAB ; Net table overflowed into string table? + ERROR "Net table alloc too small, increase NTSIZE." + HRRZ A,TOKBP + CAIL A,STREND + ERROR "String table alloc too small, increase STSIZE." + RET + +HSTPRC: CALL MRGNET ; Flush duplicate network entries if any +IFN ONLY,[CALL FLSHST] ; Flush hosts on networks we don't care about + CALL ADDNET ; Add network entries if some are missing. + CALL CANON ; Canonicalize strings to save space + CALL MERGE ; Combine entries with same official name (or complain) + CALL MACH ; Figure out machine names for entries lacking them. + CALL FLGSET ; Figure out flags for entries (mainly "server") + CALL TABSET ; Set up allocations for all output tables + CALL BNT ; Build sorted NETWORK table + CALL BNTNAM ; Build sorted NETNAME table + CALL BAT ; Build sorted ADDRESS tables + CALL MT ; Build the SITE table (not sorted), finish ADDRESSes. + CALL MNAM ; Build NAMES table + CALL SRTNAM ; Sort the NAMES table + TLNE F,FL%2OU ; If we want to output a HOSTS2 format table, + CALL H2OFIX ; Go fix up host and net addresses, etc. + RET + +; STATS - Print out various interesting stats after processing. + +STATS: MOVE A,NNETS + CALL DECOUT + TYPE " nets, " + MOVE A,NSITS + CALL DECOUT + TYPE " sites, " + MOVE A,NNAMS + CALL DECOUT + TYPE " names; length " + MOVE A,ENDFIL + SUBI A,(FA) ; get # words in output file + CALL DECOUT + CALL CROUT + RET + +subttl ITS init, file reading, file writing + +IFN ITSSW,[ + +SYSIFN: [ASCIZ /HOSTS >/] ; Input filename + +DEFINE SYSCAL A,B + .CALL [SETZ ? SIXBIT/A/ ? B ((SETZ))] +TERMIN + +INCH==1 ; Input channel +ERRCHN==2 ; Error input channel +OCH==16 ; File output channel +TYOC==17 ; TTY output channel, for error messages + + +; SYSINI - Called at startup to initialize OS-dependent stuff. + +SYSINI: .OPEN TYOC,[.UAO,,'TTY] + .LOSE %LSFIL + MOVE A,[-UPSIZE,,HSTTAB/2000] ; Get core for internal tables + SYSCAL CORBLK,[MOVEI %CBNDW ? MOVEI %JSELF ? A ? MOVEI %JSNEW ] + .LOSE %LSSYS + SKIPN ENTOFF ; If no special entry point, + JRST [ .SUSET [.RXJNAM,,A] ; See if job's name is special + CAMN A,[SIXBIT /HOSTS2/] + HRLI F,FL%R2I+FL%R2O ; Yes, use HOSTS2 in and out + CAMN A,[SIXBIT /HSTS23/] + HRLI F,FL%R2I ; HOSTS2 in, HOSTS3 out. + CAMN A,[SIXBIT /HSTS32/] + HRLI F,FL%R2O ; RFC810 in, HOSTS2 out + JRST .+1] ; Default is RFC810 in, HOSTS3 out. + .SUSET [.RXUNAME,,A] + MOVEM A,HSTWHO(FA) ; .SUSET arg can't do indexing + .RDATIM A, ; Init the auditing info at the front + MOVEM A,HSTTIM(FA) + MOVEM B,HSTDAT(FA) + RET + +; SYSJCL - Called to read in a JCL line if any. +; A/ address to read JCL into +; B/ # chars available +; Returns .+1 if JCL too long for buffer. +; Returns .+2: +; A/ BP to ASCIZ JCL string +; B/ # chars of JCL read (-1 = no JCL at all) +; Clobbers T, TT + +SYSJCL: MOVEI T,(B) ; Save # chars avail + SETZ B, + .SUSET [.ROPTIO,,TT] + TLNN TT,%OPCMD ; Has our superior said it has a cmd? + SOJA B,POPJ1 ; Nope. + CAIG T,5*3 ; Ensure reasonable JCL buffer size + RET + IDIVI T,5 ; Get # words we can use + ADDI T,(A) ; Get 1st non-usable addr + SETOM -1(T) ; Ensure last word non-zero + MOVEI TT,1(A) ; Zero the buffer + HRLI TT,(A) + SETZM (A) + BLT TT,-2(T) ; Zap! + HRLI A,5 + .BREAK 12,A ; Try to read command string. + SETZM -1(T) ; Get rid of terminating -1 + SKIPE -2(T) ; Next-to-last word should still be zero + RET ; Ugh, didn't have room for all of it. + SKIPN (A) + JRST POPJ1 ; Nothing there. + HRLI A,440700 ; Hurray, all's well! Make a BP + MOVE TT,A ; Count # of chars in JCL. + ILDB T,TT + JUMPE T,POPJ1 + AOJA B,.-2 + + +; SYSDON - Called to terminate program gracefully. + +SYSDON: .LOGOUT 1, + +; SYSHLT - Called to halt program violently. If user tries to continue, +; oblige resignedly. + +SYSHLT: .VALUE + RET + +; SYSOPN - Called to open input file for reading + +SYSOPN: TLNN A,-1 ; Ensure string arg is a BP + HRLI A,440700 + SYSCAL SOPEN,[[.UAI,,INCH] ? A] + .LOSE %LSFIL + SYSCAL RFNAME,[MOVEI INCH ? MOVEM B+F$DEV + MOVEM B+F$FN1 + MOVEM B+F$FN2 + MOVEM B+F$DIR] + .LOSE %LSSYS + MOVEM B+F$DIR,HSTDIR(FA) + MOVEM B+F$FN1,HSTFN1(FA) + MOVEM B+F$FN2,HSTVRS(FA) + MOVEI A,B + CALL SYSTFN + SYSCAL SSTATU,[REPEAT 5,[ A ? ] MOVEM HSTDEV(FA)] + .LOSE %LSSYS + RET + + +; SYSRCH - Called to read one char from file +; Returns +; A/ + +SYSRCH: .IOT INCH,A + HRRZS A ;Flush -1 in LH of EOF ^C + RET + +; SYSPSH - Called to effect a "push" of the input, prior to +; invoking SYSOPN again. + +SYSPSH: .IOPUSH INCH, + RET + +; SYSPOP - Called to "pop" the input back, after having read enough +; of current file (which is closed by this routine if necessary). + +SYSPOP: .IOPOP INCH, + RET + +; SYSCLS - Called when reading done, to close file or whatever is needed + +SYSCLS: .CLOSE INCH, + RET + +; SYSTYO - Called to output char to terminal. +; A/ ; Can clobber A but nothing else + +SYSTYO: .IOT TYOC,A + RET + +; SYSOUT - Called to output the completed binary format file. + +SYSOUT: TLNN A,-1 + HRLI A,440700 + SYSCAL SOPEN,[[.UIO,,OCH] ? A] + .LOSE %LSFIL + SYSCAL RFNAME,[MOVEI OCH ? MOVEM B+F$DEV + MOVEM B+F$FN1 + MOVEM B+F$FN2 + MOVEM B+F$DIR] + .LOSE %LSSYS + MOVEI A,B + CALL SYSTFN ; Print output file name + MOVSI A,444400 + HRRI A,(FA) ;get BP to data in core, + MOVE B,ENDFIL + SUBI B,(FA) ;and size of file. + SYSCAL SIOT,[MOVEI OCH ? A ? B] + .LOSE %LSSYS + .CLOSE OCH, ; write and close, and we're done. + RET + +; SYSTFN - Type Filename. Should take a system-dependent filename +; pointer in A and print out whatever filename it represents. +; If LH set, can assume it is a BP to ASCIZ string. +; A/ + +SYSTFN: TLNE A,-1 ; Is it a BP? + JRST BPZOUT ; Most likely, just go print it. + PUSH P,N ; Else assume its a ptr to filename block. + MOVEI N,(A) + MOVE A,F$DEV(N) ? CALL SIXOUT ? TYPE ":" + MOVE A,F$DIR(N) ? CALL SIXOUT ? TYPE ";" + MOVE A,F$FN1(N) ? CALL SIXOUT ? TYPE " " + MOVE A,F$FN2(N) ? CALL SIXOUT + POP P,N + RET + +; SYSERR - Takes error # in A, outputs corresponding error string. +; -1 means use last system call error. + +SYSERR: PUSH P,B + MOVEI B,4 ; Assume # specified, + CAIGE A, ; But if want "last error", + MOVEI B,1 ; ask system for that. + SYSCAL OPEN,[MOVEI ERRCHN + [SIXBIT/ERR/] ? B ? A ] + JRST [ TYPE "Can't find error msg" + JRST SYSER5] +SYSER2: .IOT ERRCHN,A + CAIGE A,40 + JRST SYSER5 + CALL SYSTYO + JRST SYSER2 +SYSER5: .CLOSE ERRCHN, + POP P,B + RET + +];IFN ITSSW + +SUBTTL TNX init, file reading, file writing + +IFN TNXSW,[ + +SYSIFN: [ASCIZ /HOSTS.TXT/] ; Input file name + +.SCALAR FL20X ; Zero if 10X, -1 if 20X. +.SCALAR INJPTR ; Pointer to JFN currently in use +.VECTOR INJPDL(MAXINS) ; Table holding JFNs for inserted files +.VECTOR TMPSTR(10.) ; Long enough for 39-char filename components + + +SYSINI: SETZM FL20X ; Default assumes TENEX. + MOVEI A,INJPDL + MOVEM A,INJPTR + MOVE A,['LOADTB] + SYSGT ; See if LOADTB table defined... + CAIN B, + SETOM FL20X ; If not, must be Twenex. + SETO B, + SETZ D, + ODCNV + HLRZ E,B + SUBI E,1900. + IDIVI E,10. + ADDI E,'0 + ADDI G,'0 + DPB E,[360600,,T] + DPB G,[300600,,T] + MOVEI E,1(B) + IDIVI E,10. + ADDI E,'0 + ADDI G,'0 + DPB E,[220600,,T] + DPB G,[140600,,T] + HLRZ E,C + ADDI E,1 + IDIVI E,10. + ADDI E,'0 + ADDI G,'0 + DPB E,[060600,,T] + DPB G,[000600,,T] + MOVEM T,HSTDAT(FA) + MOVEI B,(D) + 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,HSTTIM(FA) + RET + +SYSJCL: SKIPN FL20X + JRST SYSJCT ; Jump to handle Tenex differently. + MOVEI TT,(A) ; Save buffer addr + HRLI TT,440700 ; Make a BP out of it. + SETZ A, ; Check RSCAN. + RSCAN ; See if have anything in RSCAN buffer. + SETO A, ; Huh? Shouldn't happen, but ignore it. + CAIL A,(B) ; Ensure there's enough room for the input. + RET ; No, take failure return. + SKIPG B,A ; Find # chars waiting for us + JRST [ MOVE A,TT ; None, just return. + JRST POPJ1] + MOVEI T,(B) + PUSH P,C + MOVNI C,(A) ; Aha, set up cnt for SIN + MOVE B,TT + MOVEI A,.PRIIN ; Now ready for business... + SIN + POP P,C + SETZ A, + IDPB A,B ; Ensure string is ASCIZ. + MOVE A,TT ; Set up original BP + MOVEI B,(T) ; and original length + + ; Now must flush cruft that crufty EXEC sticks in crufty + ; front of crufty line!! + IRP PRE,,[RUN,ERUN] ; Cruft to flush + CAILE B,<.LENGTH /PRE/> + JRST [ IRPC X,,[PRE] + ILDB T,A + CAIE T,"X + CAIN T,"X-40 + CAIA + JRST .+1 + TERMIN + ILDB T,A + CAIE T,40 + JRST .+1 + SUBI B,1+<.LENGTH /PRE/> + JRST SYSJC2] + MOVE A,TT ; Restore original BP + TERMIN + ; Now flush the crufty name of the program or file being run. +SYSJC2: ILDB T,A ; Flush spaces + CAIN T,40 + SOJA B,.-2 + JUMPLE B,POPJ1 ; Return if zero cnt (with right BP) + ILDB T,A + CAILE T,40 + SOJA B,.-2 ; Flush until random ctl seen (space, ^M) + SUBI B,1 + CAIE T,40 ; If it wasn't a space, + SETZ B, ; then forget about the whole thing. + JRST POPJ1 + +; Get JCL if on TENEX + +SYSJCT: MOVEI TT,(A) + HRLI TT,440700 + MOVEI T,(B) + SETZ B, + MOVEI A,.PRIIN + BKJFN ; Get prev char + SOJA B,[MOVE A,TT + JRST POPJ1] ; Shouldn't happen, but claim no JCL if so + PBIN ; Get the char + CAIE A,40 ; Space? + SOJA B,[MOVE A,TT + JRST POPJ1] ; Nope, no JCL. + + ; TENEX "JCL" desired, must read directly from .PRIIN. + ; This code provides a very crude rubout facility. + PUSH P,TT ; Save original BP +SYSJC4: PBIN + CAIE A,^_ ; TENEX EOL? + CAIN A,^M ; or CR? + JRST SYSJC5 + CAIN A,177 ; Rubout? + SOJA B,[CAIGE B, + AOJA B,SYSJC4 + MOVEI A,"/ + PBOUT + LDB A,TT + PBOUT + MDBP7 TT + JRST SYSJC4] + IDPB A,TT + CAIL B,-3(T) ; Ensure enough room for terminator chars + JRST POPAJ ; Ugh! Restore BP and take failure return. + AOJA B,SYSJC4 + +SYSJC5: MOVEI A,^M + IDPB A,TT + SETZ A, + IDPB A,TT ; Ensure string is ASCIZ. + POP P,A ; Restore BP to start of string. + AOJA B,POPJ1 ; Include terminating CR in count. + +SYSDON: HALTF + JRST .-1 ; Never allow continuation +SYSHLT: HALTF + RET + +SYSOPN: MOVE B,A ; Get pointer to file in B + TLNN B,-1 ; If not already a BP, + HRLI B,440700 ; make it one. + MOVSI A,(GJ%SHT\GJ%OLD) + MOVE C,B ; Save filename ptr in case of err + GTJFN + FILERR "Failed to GTJFN input file ",C,A + MOVEI A,(A) ; Flush any bits in LH + MOVEM A,@INJPTR ; Store JFN on the JFN PDL. + MOVE B,[<70000,,0>\OF%RD] + OPENF + FILERR "Failed to OPENF input file ",@INJPTR,A + + CALL SYSTFN ; Output filename to TTY + MOVE E,[-4,, [100000,,HSTDEV] ; Dev name + [ 10000,,HSTDIR] ; Dir name + [ 1000,,HSTFN1] ; File name + [ 10,,HSTVRS]] ; Version # +SYSOP3: HRROI A,TMPSTR + MOVE B,@INJPTR + HLLZ C,(E) ; Get bits indicating field + JFNS + MOVE A,[440700,,TMPSTR] + CALL CVSSIX ; Get sixbit for string + MOVE B,(E) + ADDI B,(FA) + MOVEM A,(B) ; Store it in fileaddr space + AOBJN E,SYSOP3 + + GJINF ; Get user # in A (10X: dir #) + MOVE B,A + HRROI A,TMPSTR + DIRST ; Get username string + ERROR "DIRST failed",EVLAST + MOVE A,[440700,,TMPSTR] + CALL CVSSIX + MOVEM A,HSTWHO(FA) ; Store sixbit user name + +IFN 0,[ + MOVE A,['SYSVER] + SYSGT + CAIN B, + .VALUE + MOVEM A,TMPSTR + MOVE A,B + HRLI A,1 ; Get 2nd word of system name + GETAB + .VALUE + MOVEM A,TMPSTR+1 + MOVE A,[440700,,TMPSTR] + CALL CVSSIX + MOVEM A,OUT+HSTDEV ; Store sixbit machine name +] ; IFN 0 + RET + +SYSRCH: PUSH P,B + MOVE A,@INJPTR + BIN + ERJMP SYSRC2 ; When EOF happens, put in ITSish EOF + JUMPE B,[GTSTS + TLNE B,(GS%EOF) ; Really an EOF? + JRST SYSRC2 ; Yes, must be a Tenex 'cause ERJMP didn't fire + SETZ B, ; Nope, return the null. + JRST .+1] + SKIPA A,B +SYSRC2: MOVEI A,^C ; Put in an EOF + POP P,B + RET + +SYSPSH: AOS INJPTR ; Point to next slot on JFN PDL + RET + +SYSPOP: CALL SYSCLS ; Close current open JFN + SOS INJPTR ; and point back to previous slot. + RET + +SYSCLS: MOVE A,@INJPTR + CLOSF + JFCL ; Ignore error + SETZM @INJPTR + RET + +SYSTYO: PBOUT + RET + + +SYSOUT: TLNN A,-1 + HRLI A,440700 + MOVE B,A + MOVSI A,(GJ%SHT\GJ%NEW\GJ%FOU) + MOVE C,B ; In case of error + GTJFN + FILERR "Failed to GTJFN output file ",C,A + MOVE B,[<440000,,0>\OF%WR] + OPENF + FILERR "Failed to OPENF output file ",C,A + CALL SYSTFN ; Print output filename + MOVSI B,444400 + HRRI B,(FA) + MOVEI C,(FA) + SUB C,ENDFIL ; Get negative size of file + SOUT + ERJMP [ERROR "SOUT of output file failed",EVLAST] + CLOSF + ERROR "CLOSF of output file failed",A + RET + +; SYSTFN - Type out filename + +SYSTFN: TLNE A,-1 ; If it's a BP + JRST BPZOUT ; just type it out. + PUSH P,B + PUSH P,C ; Else it's a JFN, let system do it. + MOVEI B,(A) ; Print output filename + MOVEI A,.PRIOU + MOVE C,[111110,,1] + JFNS + MOVEI A,(B) + POP P,C + POP P,B + RET + +; SYSERR - Takes error # in A, outputs corresponding error string. +; -1 means use last system call error. + +SYSERR: PUSH P,B + PUSH P,C + MOVEI B,(A) + MOVEI A,.PRIOU + HRLI B,.FHSLF + SETZ C, + ERSTR + JRST [ TYPE "Undefined error" + JRST SYSER5] + JRST [ TYPE "(ERSTR failed)" + JRST SYSER5] +SYSER5: POP P,C + POP P,B + RET + +];IFN TNXSW + +SUBTTL SAIL init, file reading, file writing + +IFN SAILSW,[ +SYSIFN: [ASCIZ/HOSTS.TXT[HST,NET]/] ; Input file name + +ICH==0 ; Initial input channel # (must be zero) +OCH==17 +INCHAN: ICH ; Current input channel # + +IBFHLN==3 ; Length of each input buffer header +IBUFH: REPEAT MAXINS,BLOCK IBFHLN ; Input buffer headers + +SYSINI: MOVEI A,-1 ; Get core for internal tables + CORE2 A, ; Make us an upper (NOTE: If pgm + ERROR "CORE2 failed",EVLAST ; moved to Tops-10 this needs fixing!) + GETPPN A, + CAI ; Fastest no-op in the West! + HRLZM A,HSTWHO(FA) + 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,HSTDAT(FA) + 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,HSTTIM(FA) + RET + +; SYSJCL - Called to read in a JCL line if any. +; A/ address to read JCL into +; B/ # chars available +; Returns .+1 if JCL too long for buffer. +; Returns .+2: +; A/ BP to ASCIZ JCL string +; B/ # chars of JCL read (-1 = no JCL at all) +; Clobbers T, TT, T3. + +SYSJCL: MOVEI TT,(A) ; Save buffer addr + HRLI TT,440700 ; Make a BP out of it. + SETZ T3, ; Initialize count + RESCAN ; Rescan command line +SYSJC1: INCHWL T ; Get a char + CAIN T,12 ; Look for line feed + JRST SYSJC4 ; End of line, so fail + CAIE T,"; ; Beginning of JCL? + JRST SYSJC1 ; No, keep scanning +SYSJC2: INCHWL T ; Get a char + SOJL B,APOPJ ; Count down and return if overflowed + IDPB T,TT ; Store char + CAIE T,12 ; End of line? + AOJA T3,SYSJC2 ; No, count up and back for more +SYSJC3: HRLI A,440700 ; Byte ptr to string + AOSA B,T3 ; Character count including terminator +SYSJC4: SETO B, ; Return saying no JCL + JRST POPJ1 + +SYSDON: EXIT + JRST .-1 ; Who knows? +SYSHLT: JRST 4,.+1 + RET + +SYSOPN: PUSH P,H ; Preserve H + MOVE H,A ; Save pointer to filename + CALL SYSPFN ; Parse filename + MOVEM B,HSTDEV(FA) ; Store fields + MOVEM C,HSTFN1(FA) + MOVEM D,HSTVRS(FA) + MOVEM E,HSTDIR(FA) + MOVE G,INCHAN ; Get current input channel # + MOVEI B,0 ; .IOASC input mode + MOVE C,HSTDEV(FA) ; Device + MOVEI D,IBFHLN + IMULI D,(G) + ADDI D,IBUFH ; Point to right buffer header + SETZM (D) ; Ensure it's zapped. + MOVE A,[OPEN B] + DPB G,[INS$AC A] ; Deposit channel # in AC field of OPEN + XCT A + FILERR "Failed to OPEN input file ",H,EVLAST + + MOVE B,HSTFN1(FA) ; Name + MOVE C,HSTVRS(FA) ; Extension + SETZ D, + MOVE E,HSTDIR(FA) ; PPN + MOVE A,[LOOKUP B] + DPB G,[INS$AC A] + XCT A + FILERR "Failed to LOOKUP input file ",H,EVLAST + + MOVE A,H + CALL SYSTFN ; Type out filename + POP P,H ; Restore H + RET + + +SYSRCH: +SYSRC0: SOSG IBUFH+2 +SYSRC1: IN + CAIA ;Buffer not empty or IN succeeded + SKIPA A,[^C] ;IN failed, assume EOF +SYSRC2: ILDB A,IBUFH+1 + JUMPE A,SYSRCH ;Flush nulls (from E, etc.) + RET + +SYSPSH: AOS A,INCHAN + DPB A,[INS$AC SYSRC1] + MOVEI A,IBFHLN ; Point to next buff header + ADDM A,SYSRC0 + ADDM A,SYSRC2 + RET + +SYSPOP: CALL SYSCLS ; Close currently open channel + SOS A,INCHAN + DPB A,[INS$AC SYSRC1] + MOVNI A,IBFHLN ; Point to prev buff header + ADDM A,SYSRC0 + ADDM A,SYSRC2 + RET + +SYSCLS: MOVE B,INCHAN + MOVE A,[CLOSE] + DPB B,[INS$AC A] + XCT A + MOVE A,[RELEASE] + DPB B,[INS$AC A] + XCT A + RET + + +SYSTYO: OUTCHR A + RET + +SYSOUT: PUSH P,H ; Preserve H + MOVE H,A ; Save filename pointer + CALL SYSPFN ; Parse filename + PUSH P,C ; Save fields for ENTER + PUSH P,D + PUSH P,E + MOVE C,B ; Device to use (usually DSK) + MOVEI B,17 ; .IODUMP mode (one moby record!) + SETZ D, ; No buffer headers needed. + OPEN OCH,B + FILERR "Failed to OPEN output file ",H,EVLAST + POP P,E ; Put fields in place for ENTER + POP P,C ; (note D is still zero) + POP P,B + ENTER OCH,B + FILERR "Failed to ENTER output file ",H,EVLAST + MOVE A,H + CALL SYSTFN ; Type out filename + MOVEI B,(FA) + SUB B,ENDFIL ; Get neg of file size + HRLZ A,B + HRRI A,-1(FA) ; Make IOWD -n, loc-1 + SETZ B, ; End of command list + OUT OCH,A + CAIA + ERROR "Output to output file failed",EVLAST + CLOSE OCH, ; and close + POP P,H ; Restore H + RET + +; SYSPFN - Parses a WAITS filename pointed to by A. Returns: +; B: device +; C: name +; D: extension +; E: PPN +; Clobbers A, T, TT, T3. +SYSPFN: MOVSI B,'DSK ; Set default fields + SETZB D,E + CALL SYSPFF ; Get a field + CAIE T,": ; Is it end of device field? + JRST SYSPF1 ; No + HLLZ B,TT ; Yes, set device + CALL SYSPFF ; Get name +SYSPF1: MOVE C,TT ; Set name + CAIE T,". ; Do we have an extension? + JRST SYSPF2 ; No + CALL SYSPFF ; Yes, get it + HLLZ D,TT +SYSPF2: CAIE T,"[ ; Start of PPN? + JRST SYSPF3 ; No + CALL SYSPFF ; Get project + TLNN TT,77 ; Right-aligned in halfword? + LSH TT,-6 ; No, fix it + TLNN TT,77 ; Right-aligned now? + LSH TT,-6 ; No, fix it some more + TLNN TT,77 ; Right-aligned finally? + JRST SYSPF4 ; No, [,FOO] is illegal + HLLZ E,TT ; Set project + CAIE T,", ; This better be here + JRST SYSPF4 + CALL SYSPFF ; Get programmer + TLNN TT,77 ; Right-align as above + LSH TT,-6 + TLNN TT,77 + LSH TT,-6 + TLNN TT,77 + JRST SYSPF4 ; [FOO,] is illegal also + HLR E,TT ; Set programmer + CAIN T,"] ; We expect this to end filename + RET ; Normal return +SYSPF3: JUMPE T,APOPJ ; End of string is OK here +SYSPF4: ERROR "Bad format for filename" + RET + +;Subroutine to parse a sixbit string into TT. +SYSPFF: SETZ TT, ; Clear output word + MOVE T3,[440600,,TT] ; Byte ptr to start of TT +SYSFF1: ILDB T,A ; Get a char + JUMPE T,APOPJ ; Return if any of these delimiters + CAIE T,": + CAIN T,". + RET + CAIE T,"[ + CAIN T,", + RET + CAIN T,"] + RET + CAIL T,140 + SUBI T,40 ; Uppercase force + SUBI T,40 ; Convert to sixbit + TLNE T3,770000 ; Skip if at end of word - ignore char + IDPB T,T3 ; Deposit in TT + JRST SYSFF1 ; Back for more + +; Type out WAITS-style filename pointed to by A. +; Clobbers A +SYSTFN: JRST ASZOUT ; Print the string + +; SYSERR - Takes error # in A, outputs corresponding error string. +; -1 means use last system call error. + +SYSERR: ; Dunno if anything works here. + RET + +];IFN SAILSW + +; MRGNET - Flush duplicate network entries if any exist. + +MRGNET: MOVEI N,NWKTAB ; Get addr of network entry table + MOVE E,NWKTBE ; Use E to store current val of NWKTBE + CAIA +MRGN05: ADDI N,NWKLEN + CAIL N,(E) + JRST [ MOVEM E,NWKTBE ; All done! Restore new end-of-table val + RET] + MOVE C,NWKNUM(N) ; Set up net number to hunt for + MOVE B,NWKNAM(N) ; and pointer to net name. + MOVEI D,(N) +MRGN10: ADDI D,NWKLEN ; Point to next entry +MRGN11: CAIL D,(E) ; Ensure still in table + JRST MRGN05 ; Nope, back to top loop. + CAME C,NWKNUM(D) ; Same network #? + JRST MRGN10 + + ; Two entries with same number, check to see if they have same + ; name as well. Must do this via string compare since strings + ; havent been canonicalized yet. + MOVE A,NWKNAM(D) + CALL STREQ + JRST MRGN10 ; Not equal, will lose later on. + + ; Networks are identically defined. Flush the second one. + CAIL D,-NWKLEN(E) ; If 2nd entry is last one in table, + JRST MRGN30 ; then don't need to move anything. + MOVEI A,(D) + HRLI A,NWKLEN(D) + BLT A,-NWKLEN-1(E) +MRGN30: SUBI E,NWKLEN ; Reduce length of table! + SOS NNETS ; and # of nets + SOS NNTNS ; and # of net names + + TYPE /Flushing duplicate net def "/ + MOVE A,NWKNAM(N) + CALL ASZOUT + TYPE /" = / + MOVE A,NWKNUM(N) + CALL HADOUT + CALL CROUT + JRST MRGN11 + +; STREQ - Utility for MRGNET. +; A, B addrs of ASCIZ strings. +; Skips if strings equal. Clobbers T, TT, T3 + +STREQ: MOVEI T,(A) + MOVEI TT,(B) +STREQ1: MOVE T3,(T) + CAME T3,(TT) + JRST APOPJ + TRNN T3,377 + JRST POPJ1 + ADDI T,1 + AOJA TT,STREQ1 + +VAR NWKOTE ; Old value of NWKTBE, prior to ADDNET invocation + +; ADDNET - Add network entries if some appear to be missing. +; When this routine finishes, the NWKTAB table entries will be: +; wd 0 network address (internet) +; wd 1 <# sites on this net>,, + +ADDNET: MOVE A,NWKTBE + MOVEM A,NWKOTE ; Save old table end value + MOVEI B,HSTTAB ; Point to start of host entries +ADDN10: SKIPE HSTNAM(B) ; Ignore dead entries + SKIPN E,HSTNUM(B) ; Get ptr to host number list + JRST ADDN80 ; Hmm, no host number??? Continue, barf later. +ADDN20: HLRZ C,(E) ; Get addr of host number + MOVE C,(C) ; Get host number + MOVE D,C ; Save in D + CALL NETCHK ; See if network exists. + JRST ADDN60 ; Yup, skip hair. + + ; Host number exists with a network we don't know about. + ; Create fake network entry to handle it. + MOVE A,NWKTBE ; Get ptr to 1st free entry + MOVEM C,NWKNUM(A) ; Store new network number + MOVEI G,[ASCIZ /UNKNOWN-NET/] + HRRZM G,NWKNAM(A) ; Store fake network name + MOVEI G,NWKLEN(A) ; Update ptr + CAILE G,STRTAB ; Make sure haven't exceeded bounds + JRST [ TYPECR "Net table space exceeded, increase NTSIZE." + JRST SYSDON] + MOVEM G,NWKTBE ; Update size of network table. + AOS NNETS + +ADDN60: MOVSI G,1 ; Found network (real or faked), now + ADDM G,NWKNAM(A) ; increment count of sites for this net. + MOVEI A,(A) + CAMGE A,NWKOTE ; See if net is legit, for barf purposes. + JRST ADDN70 ; Yup, not a faked entry. + + AOS ERRUNN ; Sigh, loser needs to define this net. + PUSH P,A + TYPE "No network entry for " + MOVE A,C + CALL HADOUT ; Type network number + TYPE " = " + POP P,A + MOVE A,NWKNAM(A) ; Type faked network name + CALL ASZOUT + TYPE ", site " + MOVE A,D ; Retrieve and + CALL HADOUT ; Show losing host number + TYPE " = " + HRRZ A,HSTNAM(B) ; Show losing host name + CALL ASZOUT + CALL CROUT + +ADDN70: HRRZ E,(E) ; Get ptr to next host number for site + JUMPN E,ADDN20 ; If exists, back to check it. +ADDN80: ADDI B,HSTLEN + CAMGE B,HSTTBE ; More entries? + JRST ADDN10 ; Still some, hack em. + RET + + +; NETFND - Find address of NET entry in NWKTAB table, given +; an Internet address in C. Clobbers C, returns addr in A. + +NETFND: MOVEM C,NETFSV' ; Save original address for error report + CALL NETCHK + RET ; Won, return straightaway + + AOS ERRFTL ; Fatal error, should have caught earlier. + TYPE "No network name for address " + MOVE A,NETFSV + CALL HADOUT ; Output host address + CALL CROUT + MOVEI A,NWKTAB ; We're losing, but keep going; pretend to win. + RET + +; NETCHK - subroutine to find address of internal network entry, +; given host number in C. +; Returns .+1: won, +; A/ addr of network table entry +; C/ network number +; Returns .+2: failed, +; A/ addr of 1st unused network table entry +; C/ network number searched for + +NETCHK: CALL NETMSK ; Mask off network number in C + MOVN A,NNETS + HRLZ A,A + HRRI A,NWKTAB ; Now have -<# entries>,, +NETFN2: CAMN C,NWKNUM(A) + RET + ADDI A,NWKLEN-1 + AOBJN A,NETFN2 + AOS (P) ; Skip return is lossage. + RET + +; NETMSK - Mask off network number from address. +; C/ +; Returns +; C/ + +NETMSK: ;; This kludge is to save us some memory by reducing the size of + ;; the network table. (By making the network table almost + ;; useless.) It does mean that NETWRK will have to be fixed to + ;; understand that we no longer bother to know about class B and C + ;; networks, and that all its .INSRTers will have to be reassembled. + TDZ C,[<1_24.>-1] + RET + +IFN 0,[ +NETMSK: TLNN C,(17_32.) ; Check high 4 bits of address word, for escapes. + ; Resulting TDZ wins for all currently defined escape + ; bits, but this may change if new escapes are created. + TLNN C,(1_31.) ; Internet address - check high bit for class + JRST [ TDZ C,[77,,777777] ; 0, Class A network; zap low 3 bytes + RET] + TLNN C,(1_30.) ; 1, Check next + TRZA C,177777 ; 10, Class B network + TRZ C,377 ; 110, Class C network + RET +] ;IFN 0 + +HADOUT: TRNE F,FR%2IN + JRST OCTOUT ; If using HOSTS2 input, report number as octal. + PUSH P,A + TLNE A,(17_32.) ; Internet address? + JRST [ LDB A,[.BP <17_32.>, (P)] ; No, so exhibit high 4 bits. + CALL OCTOUT + TYPE ":" + JRST .+1] +REPEAT 4,[ + IFN .RPCNT, TYPE "." + LDB A,[.BP <377_<8.*<3-.RPCNT>>>, (P)] + CALL DECOUT +] + POP P,A + RET + +SUBTTL String area construction + +; CANON - store ALL strings into the file, storing each +; distinct string only once. We first build the internal sort-string +; table with ADDSTR, and then store unique strings into the file +; in their sorted order. We replace each string pointer +; with a pointer (in our address space) to the string stored +; into the file (the "interned" string). +; Secondary entries are not skipped, because other routines +; will want to do string compares on their data. +; Sets OUTPT (1st free addr following interned-string and misc stuff) + +CANON: SETZM NNAMS ; Clear # official names seen + + ; First handle predefined strings + MOVE D,[-NPDSTR,,PDSTRS] +CAN01: MOVEI A,(D) + CALL ADDSTR ; Put string into table + AOBJN D,CAN01 + + ; Loop over all site entries + MOVEI H,HSTTAB ; H points at data of next host to hack. +CANLP: SKIPN HSTNAM(H) ; Ignore dead entries + JRST CAN39 ; (get next entry) + MOVEI A,HSTSYS(H) ; Store the system name if necessary. + CALL ADDSTR + MOVEI A,HSTMCH(H) ; Do the same thing with the machine name. + CALL ADDSTR + + ; Check for "string" type host addrs + HRRZ E,HSTNUM(H) ; ptr to host number list +CNTL20: HLRZ A,(E) ; ptr to first host number + MOVE C,(A) ; Get host addr + TLNN C,(NE%STR) ; "String" bit set? + JRST CNTL25 ; Nope, needn't worry + CALL ADDSTR ; Intern the string (pointed to thru A) +CNTL25: HRRZ E,(E) ; Not string-type, try next + JUMPN E,CNTL20 ; Loop back for more addresses + + ; Now handle the official name + MOVEI A,HSTNAM(H) + CALL ADDSTR ; Stash it away + AOS NNAMS ; Count number of official names + + ; Now handle nicknames + MOVEI E,HSTNIC(H) + JRST CNTLP2 +CNTLP1: MOVEI A,(E) ; Point to word with ASCIZ addr in RH + CALL ADDSTR + AOS NNAMS ; Count number of nicknames. + HLRZ E,D ; Get CDR +CNTLP2: SKIPE D,(E) ; CDR + JRST CNTLP1 + + ; Hack service names similarly + TLNN F,FL%2OU ; If output is HOSTS2, ignore service names. + SKIPN E,HSTSVC(H) + JRST CNTLP4 +CNTLP3: HLRZ D,SVLCNT(E) ; Check node size + CAIGE D,1 ; Must have at least the name + ERROR "Internal error - bad service list" + MOVEI A,SVRNAM(E) ; Get ptr to service name + CALL ADDSTR + SKIPN E,(E) + JRST CNTLP4 + TRNE E,-1 + JRST CNTLP3 +CNTLP4: + +CAN39: ADDI H,HSTLEN + CAMGE H,HSTTBE + JRST CANLP + + ; Sites all done, now handle network names. + MOVEI N,NWKTAB ; Point to internal network table +CAN40: SKIPN C,1(N) + JRST CAN50 ; Jump out when none left. + MOVEI A,1(N) + CALL ADDSTR + ADDI N,NWKLEN + JRST CAN40 + + ; All strings now entered into the internal sort-string table + ; which ISTRP points to. Run through table, storing each + ; unique string into output file space ("intern" it) and + ; update all pointers which point to that string. +CAN50: MOVE TT,ISTRP + MOVEI T,(TT) + SUBI T,STREND + HRLI TT,(T) ; Get AOBJN to ISTR table + SETZ D, ; Clear "prev entry" value +CAN52: MOVE E,(TT) ; Get entry + CAIN D,(E) ; Same string as previous entry? + JRST CAN55 ; Yes, already set up for this! + + ; Copy string + MOVEI B,(E) ; Get new string addr + MOVE C,OUTPT ; Get current ptr +CAN53: MOVE A,(B) + MOVEM A,(C) + ADDI C,1 ; Always bump output ptr + TRNE A,376 ; Copy until hit end + AOJA B,CAN53 + CAIL C,OUTEND + ERROR "Output file alloc too small, increase OFSIZE" + EXCH C,OUTPT ; Update output ptr, and get back original val + +CAN55: HLRZ A,E ; Find addr of ptr to update + HRRM C,(A) ; Store address of copied string! + MOVEI D,(E) ; Save RH of entry as "prev entry". + AOBJN TT,CAN52 ; Loop over all ISTR entries + + ; Whew, all done! OUTPT points to 1st free fileaddr. + RET + +; ADDSTR - Adds ASCIZ string to internal sorted table of strings. +; The ISTR table grows upwards from STREND (note strings themselves +; are stored downward from STRTAB during parsing). +; Note this table is internal; it is not part of the output file. +; Entries in the table have this form: +; ,, ; RH is RH(c(addr)) +; Identical strings will have identical RHs but not LHs. +; Takes +; A/
; ARH is a word with RH pointing to ASCIZ +; Clobbers A, T, TT. + +ADDSTR: HRLI A,(A) ; Copy RH into LH + JUMPE A,APOPJ ; Ensure valid address + SKIPE T,(A) ; Get the word + TRNN T,-1 ; Ensure valid ASCIZ address + RET ; Null addr or no string, ignore. + HRRI A,(T) ; Now have new table entry word. + SKIPN TT,ISTRP ; Get current ptr to start of table + JRST [ MOVEI T,STREND-1 + MOVEM T,ISTRP ; Initialize pointer and table. + MOVEM A,(T) + RET] + PUSH P,B + PUSH P,C + PUSH P,D + PUSH P,A + + ; TT/ Base addr of start of table entries + ; T3/ # of table entries to check, starting with TT + ; A/ addr of new string + ; T/ addr of table string +IFN 0,[ + SKIPE FASTER' + JRST ASTR20 ; Try binary search + MOVEI T,(TT) + SUBI T,STREND ; Find negative # of entries + HRLI TT,(T) ; Now have AOBJN to internal sorted table +ASTR10: MOVE A,(P) ; Set up A -> new string + HRRZ T,(TT) ; Set up T -> table string +ASTR15: + SKIPL B,(A) ; Get word of new string + JRST [ SKIPL C,(T) + JRST ASTR17 ; Both positive, do compare. + JRST ASTR50] ; Table str is greater, found place to insert + SKIPL C,(T) ; Get word of table string + JRST ASTR19 ; New string greater, keep looking. + + ; Sign bit same in both words, must do a compare. +ASTR17: CAMLE B,C + JRST ASTR19 ; New str greater than table, keep looking + CAMGE B,C + JRST ASTR50 ; New str less, found place to insert. + TRNN B,377 ; Words equal! See if last word + JRST [ MOVE A,(TT) ; Strings completely equal. Copy RH of + HRRM A,(P) ; existing string (to canonize), + JRST ASTR50] ; and go store entry. + ADDI A,1 + AOJA T,ASTR15 ; Go test next word. +ASTR19: AOBJN TT,ASTR10 ; Try next entry + JRST ASTR50 + +] ;IFN 0 + ; Fast binary-search insertion + ; D has <# entries possible>,, + ; T3/ <# possibles>/2 + ; TT/ = D + T3 + +ASTR20: MOVEI T3,STREND + SUBI T3,(TT) ; Get # of entries upwards in core from here + MOVEI D,(TT) + HRLI D,(T3) ; LH = # entries including base addr + LSH T3,-1 + JRST ASTR33 + + ; Move probe point higher in core. Define new area + ; between TT+1 and D+<# entries>-1 inclusive. + ; D/ <# entries>,, + ; TT/ Current probe point + ; T3/ <# entries>/2 +ASTR31: HRRI D,1(TT) ; Make current+1 be new base + HLRZ T,D ; Get old # entries + SUBI T,1(T3) ; Find # entries left + CAIG T, ; If no more entries, + AOJA TT,ASTR50 ; then must insert after current probe. + HRLI D,(T) ; Save new # entries + MOVEI T3,(T) + LSH T3,-1 ; Find offset to new probe point + AOJA TT,ASTR33 +IFN 0,[ + ROT T3,-1 + JUMPG T3,ASTR33 ; Straight to test if no rem and nonzero. + TRNN T3,-1 ; If # entries was 0 or 1, + AOJA TT,ASTR50 ; we're done. + TLZ T3,(SETZ) ; If there was a remainder, + AOJA T3,ASTR33 ; preserve it in count. +] + ; Move probe point lower in core. Set up new area from + ; D to D+<# entries>/2 +ASTR32: JUMPE T3,ASTR50 ; If zero, we just tested last one. + HRLI D,(T3) ; Set new # entries possible + MOVEI TT,(D) ; Get back base addr of previous probe + LSH T3,-1 ; and make a smaller probe distance. + +ASTR33: ADDI TT,(T3) ; Point to new probe point + + ; Compare strings at sample point + MOVE A,(P) ; Set up A -> new string + HRRZ T,(TT) ; Set up T -> table string +ASTR35: SKIPL B,(A) ; Get word of new string + JRST [ SKIPL C,(T) + JRST ASTR37 ; Both positive, do compare. + JRST ASTR32] ; Table string is greater, hunt lower. + SKIPL C,(T) ; Get word of table string + JRST ASTR31 ; New string greater, hunt higher. + + ; Sign bit same in both words, must do a compare. +ASTR37: CAMLE B,C + JRST ASTR31 ; New str greater than table, go higher. + CAMGE B,C + JRST ASTR32 ; New str less, must hunt lower now! + TRNN B,377 ; Words equal! See if last word + JRST [ MOVE A,(TT) ; Strings completely equal. Copy RH of + HRRM A,(P) ; existing string (to canonize), + JRST ASTR50] ; and go store entry. + ADDI A,1 + AOJA T,ASTR35 ; Go test next word. + + ; TT has address of entry to insert IN FRONT of. + ; All previous entries must be bumped up, and new entry put in + ; (TT)-1. Table grows upwards in order to use BLT for bumping. +ASTR50: SOS B,ISTRP ; Get new start of table + HRRZ C,TOKBP ; Check to avoid collision with strings + CAIG B,1(C) ; Check overlap! + ERROR "String table alloc too small, increase STSIZE" + CAIL B,-1(TT) ; Make sure something to move + JRST ASTR52 ; We're at top, just store entry! + HRLI B,1(B) ; Copy from old start of table + BLT B,-2(TT) ; Bump up! +ASTR52: POP P,-1(TT) ; Store the new entry! + + POP P,D + POP P,C + POP P,B + RET + +; TABSET - Allocates room for all output tables, and initializes +; various pointers needed for building then. +; Converts NWKTAB entry format as side effect, while allocating +; the ADDRESS tables. + +TABSET: MOVE G,OUTPT ; Get pointer to 1st free wd in file area + + ; Count misc stuff (currently just service nodes) + TLNE F,FL%2OU ; If output is HOSTS2, ignore service names. + JRST TBST10 + MOVEI H,HSTTAB + CAIA +TBST02: ADDI H,HSTLEN + CAML H,HSTTBE + JRST TBST10 + SKIPE HSTNAM(H) ; Ignore dead entries + SKIPN E,HSTSVC(H) + JRST TBST02 +TBST03: HLRZ D,SVLCNT(E) ; Check node size + CAIGE D,1 ; Must have at least the name + ERROR "Internal error - bad service list" + ADDI G,1(D) ; Account for service node length + SKIPE E,(E) + TRNN E,-1 + JRST TBST02 ; Get next host + JRST TBST03 ; Get next service node + + ; Now convert NWKTAB table format. +TBST10: MOVEM G,ENDHSN ; Set new ptr to end of misc area! + CAIL G,OUTEND + ERROR "Output file alloc too small, increase OFSIZE" + MOVN B,NNETS + HRLZ B,B + HRRI B,NWKTAB +TABST2: HLRZ C,NWKNAM(B) ; Pluck out # of sites for this net + JUMPE C,TABST3 ; If no sites, just leave LH zero + MOVE A,G ; Has some sites, so find rel ptr to + SUBI A,(FA) ; its future ADDRESS block, and + HRLZM A,NWKPTR(B) ; save that value. + SETZM (G) ; Clear # entries (BAT will set up) + MOVE A,ADDLNV + MOVEM A,1(G) ; Set # wds/entry + ADDI G,2 + CAIL G,OUTEND + ERROR "Output file alloc too small, increase OFSIZE" + IMULI C,(A) ; Multiply # entries by # wds/entry + ADD G,C ; Bump up to next table +TABST3: ADDI B,NWKLEN-1 + AOBJN B,TABST2 + + ; NWKTAB table entries are now: + ; wd 0 network address (internet) + ; wd 1 ,, + + MOVE A,NNETS ; Must set # network names = to # networks. + MOVEM A,NNTNS +IRP TBL,,[NET,NTN,SIT,NAM] ; Set up 4 tables in that order. + MOVEM G,TBL!P ; Table starts here + MOVEI A,(G) + SUBI A,(FA) ; Find fileaddr for table + MOVEM A,TBL!PTR(FA) ; Store it in file header + MOVE M,N!TBL!S + MOVEM M,(G) ; Set number of entries in table + MOVEI A,TBL!LEN + MOVEM A,1(G) ; Set number of words per entry + IMUL M,A ; Compute total length + ADDI G,2(M) ; And thus get the position of next table + CAIL G,OUTEND + ERROR "Output file alloc too small, increase OFSIZE" +TERMIN + + MOVEM G,ENDFIL ; No more tables, say this is end. + MOVE A,NAMP + ADDI A,2 ; Allow for 2 table header words + MOVEM A,NAMEP ; Set pointer for storing into NAMES table. + RET + +;; Dump out literals accumulated so far, this program uses so many +;; that MIDAS barfs assembling it.... +..LIT1: CONSTANTS + +; MERGE - Combine entries that refer to same "site", resolving conflicts. +; Currently this is determined by checking official name - if same, +; entries are combined. This does make it harder to catch some +; kinds of errors. + +MERGE: MOVEI H,HSTTAB ; Start of table +MRG01: SKIPG A,HSTNAM(H) ; If dead or already marked secondary, + JRST MRG80 ; Needn't recheck! + + MOVEI G,(H) ; Search rest of entry table for a match. +MRG10: HRRZ A,HSTNAM(H) + JRST MRG25 +MRG20: MOVE B,HSTNAM(G) ; Get whole word + CAIN A,(B) ; But only compare RH + JRST MRG30 ; Equal, found a match! +MRG25: ADDI G,HSTLEN + CAMGE G,HSTTBE + JRST MRG20 + JRST MRG80 ; Search all done. + + ; Found a matching entry (official names are identical). + ; Must check for equality of system/mach + ; and then merge address lists. + ; If system/mach are equal and 2nd isn't merging, combine them. + ; If merging, depends on address. + ; (Yes this seems backwards, but...) + ; If system/mach are NOT equal, then check address overlap. + ; If share an address, link them up. + ; If merging, combine nicknames too. + +MRG30: SETZ C, ; Clear flag + MOVE B,HSTSYS(H) + CAME B,HSTSYS(G) + JRST MRG32 ; Error, system mismatch + MOVE B,HSTMCH(H) + CAME B,HSTMCH(G) + AOJA C,MRG32 ; Error, machine mismatch + + ; OS/mach both match. If not merging, verify no address overlap. + CALL MRGHST + JRST MRG48 ; No overlap, just link together. + MOVE A,HSTNAM(G) ; Address overlap! If not merging, complain. + TLNE A,HE%MRG + JRST MRG40 ; Merging, go do it. + ; Here print warning then merge them together. + AOS ERRDHN + TYPE "Warning: Duplicate host def for " + MOVE A,HSTNAM(H) + CALL ASZOUT + CALL CROUT + JRST MRG40 ; Go merge the entries. + + ; OS or MACH don't match, see if any addresses do. +MRG32: MOVE A,HSTNAM(G) ; But only allow if merging allowed. + TLNN A,HE%MRG + JRST MRG50 ; Not merging so must complain since OS/m diff + CALL MRGHST ; Can merge, check out dup addrs + JRST MRG50 ; None, so complain. + + ; Name and addr both same, merge. + ; OK, these two entries are probably referring to the same site, and + ; we assume site has multiple addresses. + ; Check to see whether there is any address overlap. + ; If no overlap, entries are linked together (1st becomes primary) + ; If partial overlap, also linked together (with hair). + ; If complete overlap, action depends on whether HE%MRG was + ; specified for either entry. + ; If neither, an info message is printed and second one flushed. + ; If one, that one is flushed quietly. + ; If both, the second one is flushed quietly. + + ; If secondary has HE%MRG set, + ; then try to merge address lists by flushing duplicates from + ; the secondary list. + MOVE A,HSTNAM(G) + TLNN A,HE%MRG + JRST MRG48 ; Naw, just link them together (barf later) +MRG40: CALL MRGHST + JRST MRG45 ; No overlap, done + HRRM E,(T) ; Match! Flush this entry, by pointing prev to + ; the next one after this. + JRST MRG40 ; Then scan again. +MRG45: SKIPE HSTNUM(G) ; If all addrs were removed for 2nd entry + JRST MRG48 + SETZM HSTNAM(G) ; Then flush this entry completely, mark dead. + JRST MRG49 + + ; Assume entries represent multi-address site. + ; Link together the entries. +MRG48: HRRZ B,HSTSEC(H) ; Get link for prime entry + HRRM B,HSTSEC(G) ; Set link in secondary entry + HRLM H,HSTSEC(G) ; Set back-link too (point back to prime) + HRRM G,HSTSEC(H) ; Now point prime entry to sec; cons done. + MOVSI B,HE%SEC + IORM B,HSTNAM(G) ; Mark added entry as secondary. +MRG49: SOS NSITS ; And decrement # of primary site entries. + SOS NNAMS ; and decrement # of name table entries. + + ; Now merge nicknames onto primary entry's list. + SKIPN HSTNIC(G) ; Check for trivial cases + JRST MRG10 ; No nicknames in secondary + SKIPN HSTNIC(H) + JRST [ MOVE A,HSTNIC(G) ; No nicknames in primary + MOVEM A,HSTNIC(H) + SETZM HSTNIC(G) + JRST MRG10] + MOVEI E,HSTNIC(G) ; Get 1st nickname entry + JRST MRG65 +MRG61: MOVEI A,(D) + + ; For each nickname in secondary entry, scan primary for match. + MOVEI C,HSTNIC(H) + JRST MRG63 +MRG62: CAIN A,(B) ; Compare strings + JRST [ SOS NNAMS ; Yes, subtract one for each nickname dup + JRST MRG64] ; Cuz we're flushing the extra reference. + HLRZ C,B +MRG63: SKIPE B,(C) + JRST MRG62 + ; Nickname not in primary entry, must add it! + ; C points to last wd in primary list (zero) + ; D has secondary entry, E has addr it came from + HRRM D,(C) ; Store ptr to nickname string in zero wd + HRLM E,(C) ; and make "next" ptr point to the place + ; that secondary entry was in. + SETZM (E) ; Ensure it's a zero list terminator. +MRG64: HLRZ E,D +MRG65: SKIPE D,(E) + JRST MRG61 + +; Might be part of new list, so dont clobber this wd. +; SETZM HSTNIC(G) + JRST MRG10 + + + + MOVEI B,HSTNIC(G) ; Find # of nicknames + JRST MRG36 +MRG35: SOS NNAMS ; Subtract one for each nickname + HLRZ B,B +MRG36: SKIPE B,(B) + JRST MRG35 + JRST MRG10 ; Go check for more. + +MRG50: AOS ERRDHN + PUSH P,A + TYPE "Duplicate hostname " + MOVE A,HSTNAM(H) + CALL ASZOUT + TYPE " = " + MOVE A,HSTSYS(H) + MOVE B,HSTSYS(G) + JUMPN C,[MOVE A,HSTMCH(H) + MOVE B,HSTMCH(G) + JRST .+1] + CALL ASZOUT + TYPE ", " + MOVE A,B + CALL ASZOUT + CALL CROUT + POP P,A + JRST MRG25 ; Go check for more. + +MRG80: ADDI H,HSTLEN + CAMGE H,HSTTBE + JRST MRG01 + RET + + +; MRGHST - Skips if two entries share an address. +; G, H point to entries +; Clobbers B,C,D,E,T +; On win return, +; T/ addr of node previous to duplicate (on list G) +; E/ duplicate node contents (list G) + +MRGHST: SKIPN D,HSTNUM(H) ; Get addr list for primary + RET +MRGH40: TRNN D,-1 ; If no RH ptr to next, + RET ; Done. + MOVE D,(D) ; Get next + HLRZ B,D + MOVE B,(B) ; Get a host addr from primary + + MOVEI T,HSTNUM(G) ; Get addr list for secondary + SKIPN E,(T) + RET + CAIA +MRGH41: MOVE T,(T) ; Save addr of prev node + TRNN E,-1 ; If no more, + JRST MRGH40 ; done with secondary list. + MOVE E,(E) + HLRZ C,E + CAME B,(C) ; Compare primary addr with secondary + JRST MRGH41 ; No match, try another. + AOS (P) + RET + ; Host addresses match!! If secondary has HE%MRG set, + ; then try to merge address lists by flushing duplicates from + ; the secondary list. +; MOVE A,HSTNAM(G) +; TLNN A,HE%MRG +; JRST MRGH49 ; Naw, just link them together (barf later) +; HRRM E,(T) ; Flush this entry, by pointing prev to +; ; the next one after this. +; JRST MRGH42 + +; MACH - Figure out the type of machine from the system name, if possible, +; in case we currently have no info on machine type. + +MACH: MOVEI A,HSTTAB +MACHL: SKIPG HSTNAM(A) ; Ignore secondary entries for now + JRST MACHNX + MOVE B,HSTSYS(A) + SKIPE C,HSTMCH(A) ;If machine type not already known, + JRST MACHNX + CAME B,ITS ;try to determine it from system name. + CAMN B,TENEX + MOVE C,PDP10 + CAME B,TOPS10 + CAIN B,TOPS20 + MOVE C,PDP10 + CAME B,TOPS1X + CAMN B,TOPS2X + MOVE C,PDP10 + CAMN B,WAITS + MOVE C,PDP10 + CAMN B,TIP + MOVE C,TIP + CAMN B,MULTIC + MOVE C,MULTIC + CAME B,HYDRA + CAMN B,RSX11 + MOVE C,PDP11 + CAME B,ELF + CAMN B,UNIX + MOVE C,PDP11 + MOVEM C,HSTMCH(A) +MACHNX: ADDI A,HSTLEN + CAMGE A,HSTTBE + JRST MACHL + RET + +; FLGSET - Run through internal site entries fixing up whatever flags +; can be fixed up at this point. Currently this mostly means +; setting the "server" flag if the services list looks reasonable. + +FLGSET: MOVEI H,HSTTAB ; Run through entries +FLST05: SKIPG C,HSTNAM(H) ; Ignore secondary entries for now + JRST FLST35 + SKIPE ASERVE ; If user wants STFSRV for all entries + JRST FLST30 ; just go turn it on. + TLNE C,HE%2IN ; If entry was in HOSTS2 format, + JRST FLST35 ; also ignore since SERVER explicitly spec'd. + SKIPN C,HSTSVC(H) ; Get our service list if any + JRST FLST35 ; None +FLST10: HRRZ B,SVRNAM(C) ; Get addr of service name + CAME B,SNTEL + CAMN B,STTEL + JRST FLST30 + CAME B,SNFTP + CAMN B,STFTP + JRST FLST30 + CAME B,SNSMTP + CAMN B,STSMTP + JRST FLST30 + SKIPE C,SVRCDR(C) + TRNN C,-1 + CAIA + JRST FLST10 + + ; Sigh, couldn't find a plausible service, so let's cheat and + ; check the system type... + MOVE A,HSTSYS(H) ; Get addr of system name + CAME A,TENEX + CAMN A,TOPS20 + JRST FLST30 + CAME A,WAITS + CAMN A,TOPS10 + JRST FLST30 + CAME A,TOPS1X + CAMN A,TOPS2X + JRST FLST30 + CAME A,ITS + CAMN A,UNIX + JRST FLST30 + CAME A,MULTIC + CAMN A,VMS + JRST FLST30 + + ; Sigh, give up on "server" flag. + JRST FLST35 + +FLST30: MOVSI A,STFSRV ; OK, we think it's a "server", so set up flag + IORM A,HSTFLG(H) ; and set it! +FLST35: ADDI H,HSTLEN + CAMGE H,HSTTBE + JRST FLST05 + RET + +; BNT - Build sorted NETWORK table + +BNT: MOVEI N,NWKTAB ;Source + MOVE C,NNETS ;Number of times to do + MOVE A,NETP ;Destination + ADDI A,2 ;Skip header +BNT1: MOVE D,NWKNUM(N) ; Network number + MOVEM D,NETNUM(A) + HRRZ E,NWKNAM(N) ; Now the name + SUBI E,(FA) ; Make fileaddr + HRLZM E,NTLNAM(A) + + ; Set up NT pointers for the ADDRESS tables to fill in + HRRM N,NTRTAB(A) ; Save back-pointer to NWKTAB entry for sort + HRRM A,NWKPTR(N) ; and set ptr in NWKTAB to NETWORK entry. + + ADDI A,NETLEN ;Next slot in line + ADDI N,NWKLEN ;Done with this network, try next + SOJG C,BNT1 + + ; NETWORK table entries are now: + ; wd 0 network address + ; wd 1 ,, + ; NWKTAB table entries are now: + ; wd 0 network address + ; wd 1 <# sites in net>,, + ; wd 2 ,, + + CALL SRTNET ; Sort the NETWORK table (invalidates NWKTAB wd2 RH) + + MOVN N,NNETS + MOVSI N,(N) + HRR N,NETP + ADDI N,2 ; Get AOBJN to NETWORK table +BNT50: HRRZ A,NTRTAB(N) ; Get backlink to NWKTAB + MOVE B,NWKNUM(A) ; Get net number for entry + CAME B,NETNUM(N) ; Should match + ERROR "Internal error - NWKTAB backlink inconsistency" + HRRM N,NWKPTR(A) ; OK, update NWKTAB's ptr to NETWORK entry! + HLRZ C,NWKPTR(A) ; And get back its ADDRESS table fileaddr + HRRM C,NTRTAB(N) ; Store to finalize NETWORK table entry + ADDI N,NETLEN-1 + AOBJN N,BNT50 + RET + + ; NETWORK table entries are now in their final file format! + ; wd 0 network address + ; wd 1 ,, + ; NWKTAB entries have had RH(NWKPTR) updated properly. + +; BNTNAM - Build the sorted NETNAME table + +BNTNAM: SKIPG G,NTNP ; Get pointer to NETNAME table + RET ; No table defined, don't do it. + ADDI G,2 ; Point to 1st loc to store into + MOVE N,NETP ; Get pointer to already built NETWORK table + MOVN A,(N) ; Get # of entries + ADDI N,2 + HRLI N,(A) ; Now have AOBJN ptr to NETWORK table +BNTN10: MOVEI A,(N) ; Get addr of this entry + SUBI A,(FA) ; Make it a fileaddr + HLL A,NTLNAM(N) ; Get ptr to ASCIZ (already a fileaddr) + MOVSM A,(G) ; Store in NETNAME table + ADDI G,1 + ADDI N,NETLEN-1 + AOBJN N,BNTN10 + + MOVEI A,-2(G) + SUB A,NTNP ; Find # entries filled in + CAMN A,NNTNS ; Should match # entries predicted + CAME G,SITP ; And should have filled table exactly + ERROR "Internal error - NETNAME size inconsistency" + + ; Now sort the resulting table... + CALL SRTNTN ; Sort NETNAME table + RET + +; BAT - Build the sorted ADDRESS tables +; First stage (BAT) fills in all the numbers, using insertion sort. +; Second stage (MT) fills in the address lists and SITE pointers. +; Note "secondary" entries are treated just like primary entries here. + +BAT: MOVEI H,HSTTAB ; Step through all site entries +BAT0: SKIPN HSTNAM(H) ; Ignore dead entries + JRST BAT80 + HRRZ B,HSTNUM(H) ; For each address of that host + JUMPN B,BAT1 ; insert an entry in some address table. + TYPE "Internal error - " + HRRZ A,HSTNAM(H) ; If no addresses, barf + PUSHJ P,ASZOUT + ERROR " has no addresses" + +BAT1: HLRZ E,(B) ; CAR + MOVE A,(E) ; Is a network address for this site + MOVE G,E ; Save addr of original HOSTS3-format # here. + TLNE F,FL%2OU ; If output format is HOSTS2 + CALL H2ADR ; Then convert address to HOSTS2 for sorting + MOVE E,A ; Put it in E for compares + MOVE C,(G) ; Then use HOSTS3 fmt # to + CALL NETFND ; Find addr of internal network entry. + HRRZ D,NWKPTR(A) ; Get abs addr to NETWORK entry + + MOVE D,NTRTAB(D) ; Get offset for start of ADDRESS block + ADDI D,(FA) ; Get absolute addr for it + AOS C,(D) ; Get 1+ number of entries in table + SUBI C,1 + IMUL C,ADDLNV ;Index into table of last+1 entry + ADDI C,2(D) ;Address + MOVE M,C ;Save upper bound +BAT2: SUB C,ADDLNV ;Next guy to compare against + CAIGE C,2(D) ;Anybody there? + JRST BAT3 ;No, put this one in at bottom of table + CAMN E,ADDADR(C) ; Compare host addresses + CALL BATDHA ; Duplicate address, report it! + CAMG E,ADDADR(C) ; Does new guy go after this one? + JRST BAT2 ; No, keep looking + + ;Address in C is last guy before new guy + ;BLT (C)+ADDLEN ... (M)-ADDLEN up by ADDLEN +BAT3: ADD C,ADDLNV ; 1st guy to move up, also where new frob goes + HRROI A,-1(M) ; Get "PDL ptr" to last active wd + MOVEI T,(M) + SUBI T,(C) ; Find # words to move + ADD M,ADDLN1 ; and addr of 1st place to move to + JUMPLE T,BAT5 ; If no words to move, don't try! +BAT4: POP A,(M) ; Move word... + SUBI M,1 ; Fix index (Geez why isn't there a SOBJN???) + SOJG T,BAT4 + +BAT5: MOVEM E,ADDADR(C) ; Store new guy + HRLM H,ADLSIT(C) ; Store abs ptr to host entry + TLNE F,FL%2OU ; If addrs are in HOSTS2 fmt, + HRRM G,ADRCDR(C) ; Temporarily remember loc of HOSTS3 fmt # + HRRZ B,(B) ; CDR + JUMPN B,BAT1 +BAT80: ADDI H,HSTLEN ; Next host + CAMGE H,HSTTBE + JRST BAT0 + + TLNE F,FL%2OU ; If we were storing HOSTS2 fmt numbers, + CALL H3AFIX ; must re-convert back to HOSTS3 format + ; for rest of processing. + + ; Maybe later should expand NWKTAB for another word to hold + ; count, etc for cross-checking final length of each table. + + RET + +; BATDHA - Report duplicate host address while building ADDRESS tables. +; Can clobber A only. +; H/ ptr to internal site entry +; G/ addr of HOSTS3 format netaddr +; C/ addr of existing ADDRESS table entry + +BATDHA: PUSH P,B + HLRZ B,ADLSIT(C) ; Get back ptr to existing internal site entry + MOVE A,HSTFLG(B) ; Get its flags + XOR A,HSTFLG(H) ; Compare with new (duplicate) entry + TLNE A,STFGWY ; Is one a Gateway and the other a Host? + JRST [ SKIPE GWHSTS + JRST BATDH9 + TYPE "Gateway/Host duplicate addr " + AOS ERRDGA ; Bump cnt of gateway vs host duplicates + JRST BATDH2] + TYPE "Duplicate address " + AOS ERRDHA ; Bump cnt of errs +BATDH2: MOVE A,(G) ; Use HOSTS3 format # + PUSHJ P,HADOUT + TYPE " = " + HRRZ A,HSTNAM(B) ; Get official hostname for existing addr + CALL ASZOUT + TYPE ", " + HRRZ A,HSTNAM(H) ; Get current hostname + PUSHJ P,ASZOUT + CALL CROUT +BATDH9: POP P,B + RET + + + +; H3AFIX - This routine scans through the ADDRESS tables for each +; network, to convert the HOSTS2 addresses to HOSTS3 format +; after the ADDRESS tables have been properly sorted. + +H3AFIX: MOVE N,NETPTR(FA) ; Get pointer to NETWORK table + MOVEI A,(N) + ADDI A,(FA) + MOVN A,(A) ; Get # entries + HRLI N,(A) ; Set up -<# entries> in LH + ADDI N,2(FA) ; Now have AOBJN ptr to NETWORK table + + ; Now restore each address for this net. +H3AFX2: HRRZ H,NTRTAB(N) ; Get file addr of ADDRESS table + JUMPE H,H3AFX4 + ADDI H,2(FA) ; Make absolute, point to 1st entry + MOVN A,-2(H) ; Find # of entries + JUMPGE A,H3AFX4 ; Jump if none + HRLI H,(A) ; Now have AOBJN ptr + +H3AFX3: MOVE B,ADRCDR(H) ; Get word of entry with H3-fmt ptr in RH + MOVE A,(B) ; Get original HOSTS3 format addr + MOVE C,A ; Save it + CALL H2ADR ; Convert it + CAME A,ADDADR(H) ; Results should match exactly + ERROR "Internal error - BAT routine blew H2 conversion" + MOVEM C,ADDADR(H) ; Store original HOSTS3 format value! + HLLZM B,ADRCDR(H) ; Clear out the temporary pointer from entry. + + ADD H,ADDLN1 ; ADDLEN-1 + AOBJN H,H3AFX3 + +H3AFX4: ADDI N,NETLEN-1 + AOBJN N,H3AFX2 + RET + + +;Now build the contents of the SITE table, which does not need to be sorted, +; and fill in rest of the ADDRESS table. + +MT: MOVEI H,HSTTAB ; H points at data of next host to hack. + MOVE A,SITP + ADDI A,2 ;A is pointer for storing SITES table entries. +MTLP: SKIPG HSTNAM(H) ; Ignore secondary entries at this level + JRST MT80 + HRRM A,HSTFLG(H) ; Got a primary, save SITE entry ptr for it. + + ; Fill in SITE entry values from primary entry. + ; Sets STLSYS, STRMCH, STLFLG, STLNAM (everything but STRADR) + SKIPE E,HSTSYS(H) + SUBI E,(FA) ; Get ptr to system name (in file addr space). + HRLZM E,STLSYS(A) ; Stash away + SKIPE E,HSTMCH(H) + SUBI E,(FA) + HRRM E,STRMCH(A) ; Store machine name. + HLLZ E,HSTFLG(H) ; Just copy flag word + MOVEM E,STLFLG(A) + HRRZ E,HSTNAM(H) + SUBI E,(FA) ; Now get fileaddr for official name + HRLZM E,STLNAM(A) ; and store a pointer to the copy. + + ; Now must fill in the ADDRESS table entries for this site. + ; Must scan secondary SITE entries as well in order to do this. + ; The algorithm arranges for the primary entry to be the last one + ; processed, so that its ADDRESS entries are the first on list. + ; This is not terribly important, but seems appropriate. + ; A points to file SITE entry. + ; G always points to primary entry + ; H points to current internal entry (= G means last scan) + MOVEI G,(H) ; Save pointer to primary entry +MT30: HRRZ H,HSTSEC(H) ; Get ptr to next secondary entry + JUMPE H,[MOVEI H,(G) ; If none, just use primary entry, + JRST MT31] ; and skip over some error checks. + SKIPL HSTNAM(H) ; Secondary entry must have flag set! + ERROR "Internal error - entry HDRSEC/flag conflict" + HLRZ B,HSTSEC(H) ; And must point back to + CAIE B,(G) ; its primary! + ERROR "Internal error - bad HDRSEC backlink" +MT31: + SETZ M, ; Initialize service list for entry + TLNN F,FL%2OU ; Ignore if outputting HOSTS2 + CALL CPYSVC ; Copy service list, leave ptr in M + + ;; For each address of this entry, fill in ADDRESS table entry + ;; Also, make STRADR point to list of them + HRRZ C,HSTNUM(H) ; List of addresses +MT35: HLRZ D,(C) ; CAR + MOVE D,(D) ; Network address + CALL ADRFND ; Find address entry in tables, return ptr in E + HRRZ B,STRADR(A) ; CONS onto existing STRADR + HRRM B,ADRCDR(E) ; Threaded through ADRCDR + TLNE F,FL%2OU ; If building HOSTS2 format, + JRST MT37 ; Skip the service list stuff below. + HRRZ B,ADRSVC(E) ; Get existing services list + CAIE B, ; Should be nothing there! + ERROR "Internal error - addr/site service conflict" + HRRM M,ADRSVC(E) ; Store services list we consed up earlier. +MT37: + ; Link together the SITE and ADDRESS entries + MOVEI B,(E) ; Get fileaddr of + SUBI B,(FA) ; ptr to ADDRESS entry + HRRM B,STRADR(A) ; Stash away, setting STRADR finally + MOVEI B,(A) ; Now do same for + SUBI B,(FA) ; ptr to SITE entry + HRLM B,ADLSIT(E) ; Stash it away in ADDRESS entry + + HRRZ C,(C) ; Get CDR for next net address to link in. + JUMPN C,MT35 + CAIE G,(H) ; Entry done, any more secondary entries? + JRST MT30 ; Maybe, go check. + + ; All's done for this SITE entry. + ADDI A,SITLEN ; Advance A to store next entry next time. +MT80: ADDI H,HSTLEN + CAMGE H,HSTTBE + JRST MTLP + + CAME A,NAMP ; Check that SITES table has predicted size + ERROR "Internal error - SITES table size inconsistency" + SUB A,SITP ; Get space allocated to SITES table. + SUBI A,2 + MOVE B,@SITP ; Check that right number of SITES + IMULI B,SITLEN ; entries were made. + CAME A,B + ERROR "Internal error - SITES table count inconsistency" + + MOVE B,OUTPT ; Check that host names & misc exactly filled + CAME B,ENDHSN ; the space allotted. + ERROR "Internal error - string/misc area size inconsistency" + RET + +; Subroutines for MT + +; CPYSVC - Copy service list from internal tables to filespace. +; H/ ptr to internal entry +; Conses onto list in M, leaves ptr in M. +; Clobbers B,C,T,TT and bumps OUTPT + +CPYSVC: SKIPN B,HSTSVC(H) ; Get 1st service name, ptr to rest + RET ; Nothing there, oh well. + MOVE T,OUTPT +CPSV10: HLRZ TT,SVLCNT(B) ; Find # words in service node (-1) + JUMPE TT,CPSV19 + MOVEI C,(T) + HRLI C,(B) + ADDI TT,(C) ; Get last addr to copy into + BLT C,(TT) ; Copy the service node! + HRRZ C,SVRNAM(T) ; Get ptr to svc name + SUBI C,(FA) ; Make it a fileaddr + HRRM C,SVRNAM(T) + HRRM M,SVRCDR(T) ; Cons existing list onto end + MOVEI M,(T) ; Save ptr to new head of list + SUBI M,(FA) ; Make it a fileaddr + HLRZ TT,SVLCNT(B) ; Get back size of node again + ADDI T,1(TT) + MOVEM T,OUTPT ; Update free ptr +CPSV19: SKIPN B,SVRCDR(B) ; Get next service name + RET + TRNE B,-1 ; Did we just hack last one? + JRST CPSV10 + RET + +; ADRFND - Look up ADDRESS table entry +; D/ network address +; H/ ptr to internal SITE entry +; Returns +; E/ ptr to ADDRESS table entry +; Clobbers T,TT + +ADRFND: PUSH P,A + PUSH P,C + MOVE C,D + CALL NETFND ; Find net entry for address + HRRZ E,NWKPTR(A) ; Get abs addr of NETWORK entry, which holds + POP P,C ; fileaddr of ADDRESS blk (sigh) + POP P,A + + MOVE E,NTRTAB(E) ; Get fileaddr of ADDRESS table for this net + ADDI E,(FA) ; Make it absolute + SKIPG T,(E) ; Get number of entries for this net + ERROR "Internal error - empty address table" + ADDI E,2 ; Point to start of ADDRESS table entries +ADRFN2: CAMN D,ADDADR(E) ; Linear search for specified number + JRST [ HLRZ TT,ADLSIT(E) ; Found right number, see if + CAIE TT,(H) ; site ptr matches too? + JRST .+1 ; Nope, keep searching + RET] ; Matched, found entry! + ADD E,ADDLNV ; Point to next entry + SOJG T,ADRFN2 + ERROR "Internal error - addr not found in address table" + RET + +; MNAM - Make NAMES table. Must come after SITES table is done, +; since it contains pointers into SITES table. + +MNAM: MOVEI H,HSTTAB ; Driven by HSTTAB + MOVE G,NAMEP ; Get pointer for writing into NAMES table +MNAM10: SKIPG HSTNAM(H) ; Only use names of primary entries! + JRST MNAM50 + + ; Make the official name's entry. Get SITES entry addr in LH. + HRRZ A,HSTFLG(H) ; Get abs ptr to SITES entry + MOVEI D,(A) + SUBI D,(FA) ; Make it a fileaddr + MOVSI D,(D) ; in LH + HLR D,STLNAM(A) ; Set RH to fileaddr of hostname + MOVEM D,(G) ; Now store + MOVEI E,HSTNIC(H) ; E points to list of nickname pointers. + AOJA G,MNAM39 ; Bump deposit ptr and jump into loop + +MNAM30: HRRI D,(E) ; Get ptr to nickname + SUBI D,(FA) ; Get fileaddr of copy + MOVEM D,(G) ; Store another table entry (note LH unchanged) + ADDI G,1 + HLRZ E,E ; Get CDR for next nickname entry +MNAM39: SKIPE E,(E) ; Get nickname + JRST MNAM30 + +MNAM50: ADDI H,HSTLEN ; Finished making NAMES entry for this host. + CAMGE H,HSTTBE ; Hack the next... + JRST MNAM10 + MOVEM G,NAMEP ; Store back write-ptr into NAMES table + + SUB G,NAMP ; Check that expected number of NAMES + SUBI G,2 ; entries were made. + CAME G,@NAMP + ERROR "Internal error - NAMES table size inconsistency" + RET + +; SRTNAM - Sort the NAMES table. Uses fact that all strings are +; already sorted and can just examine file-address for compares! +; SRTNTN - Sort the NETNAME table. + +SRTNAM: MOVE A,NAMP ; Get addr of NAMES table + MOVEI H,SRTN60 ; Set addr of duplicate err routine + JRST SNAM01 +SRTNTN: MOVE A,NTNP ; Get addr of NETNAME table + MOVEI H,SRTN70 ; Set addr of duplicate err rtn + +SNAM01: MOVEI E,2(A) ; Addr of start of entries + MOVN C,(A) ; Get -<# entries> + CAMN C,[-1] + RET + HRLI E,1(C) ; Make AOBJN with count of 1 less than # ents. + +SNAM: SETZ B, ; No exchanges yet this pass. + MOVE A,E ; Set up AOBJN +SNAML: HRRZ C,NMRNAM(A) ; Get string addr for this entry + HRRZ D,NMRNAM+NAMLEN(A) ; and that of next one + CAILE C,(D) ; Skip if ordered OK + AOJA B,[MOVE C,(A) ; Out of order, must exchange! + EXCH C,NAMLEN(A) + MOVEM C,(A) + JRST .+1] + AOBJN A,SNAML ; Each pass scan whole table. + JUMPN B,SNAM ; do another pass if anything exchanged. + + ; Table sorted, now scan through for any duplicates. + MOVE A,E ; Get AOBJN once more +SRTN50: HRRZ C,NMRNAM(A) + HRRZ D,NMRNAM+NAMLEN(A) + CAIN C,(D) + CALL (H) ; Error, go handle it + AOBJN A,SRTN50 + RET + + ; Handle duplicate host name situation - possible error. + ; A has ptr to 1st of 2 duplicate entries. + ; Can clobber B,C,D +SRTN60: AOS ERRDHN ; Bump cnt of duplicates + MOVE B,A ; Save current aobjn + TYPE "Duplicate host name " + HRRZ A,NMRNAM(B) ; Get addr of ASCIZ name string + ADDI A,(FA) ; Make abs + CALL ASZOUT + TYPE " = " + HLRZ A,NMLSIT(B) ; Get file addr of SITE entry for 1st name + ADDI A,(FA) ; Make abs + HRRZ A,STRADR(A) ; Get file addr of its 1st ADDRESS entry + ADDI A,(FA) ; Make abs + MOVE A,ADDADR(A) ; Get its 1st host addr + CALL HADOUT + TYPE ", " ; Now do same thing for 2nd + HLRZ A,NAMLEN+NMLSIT(B) ; Get file addr of SITE entry for 2nd name + ADDI A,(FA) ; Make abs + HRRZ A,STRADR(A) ; Get file addr of its 1st ADDRESS entry + ADDI A,(FA) ; Make abs + MOVE A,ADDADR(A) ; Get its 1st host addr + CALL HADOUT + CALL CROUT + MOVE A,B ; Restore aobjn ptr + RET ; Continue check loop + + ; Handle duplicate net name situation - possible error. + ; A has ptr to 1st of 2 duplicate entries. + ; Can clobber B,C,D +SRTN70: AOS ERRDNN ; Bump cnt of duplicates + MOVE B,A ; Save current aobjn + TYPE "Duplicate net name " + HRRZ A,NNRNAM(B) ; Get addr of ASCIZ name string + ADDI A,(FA) ; Make abs + CALL ASZOUT + TYPE " = " + HLRZ A,NNLNET(B) ; Get file addr of NETWORK entry for 1st name + ADDI A,(FA) ; Make abs + MOVE A,NETNUM(A) ; Get its number + CALL HADOUT + TYPE ", " ; Now do same thing for 2nd + HLRZ A,NTNLEN+NNLNET(B) ; Get file addr of SITE entry for 2nd name + ADDI A,(FA) ; Make abs + MOVE A,NETNUM(A) ; Get its number + CALL HADOUT + CALL CROUT + MOVE A,B ; Restore aobjn ptr + RET ; Continue check loop + +; SRTNET - Sort the NETWORK table numerically or alphabetically. +; Uses fact that all strings are already sorted and can +; just examine file-address for compares! + +SRTNET: MOVE A,NETP ; Get addr of NETWORK table + MOVEI E,2(A) ; Addr of start of entries + MOVN C,(A) ; Get -<# entries> + CAMN C,[-1] ; If there is only one network + RET ; don't bother to incorectly sort the table! + HRLI E,1(C) ; Make AOBJN with count of 1 less than # ents. +SNET: SETZ B, ; No exchanges yet this pass. + MOVE A,E ; Set up AOBJN (of sorts) +SNET1: TLNN F,FL%2OU + JRST [ MOVE C,NETNUM(A) ; HOSTS3 format sorts numerically + MOVE D,NETNUM+NETLEN(A) + JRST SNET11] + HLRZ C,NTLNAM(A) ; Get string addr for this entry + HLRZ D,NTLNAM+NETLEN(A) ; and that of next one +SNET11: CAMG C,D ; Skip if ordered wrong + JRST SNET1Z + MOVSI D,-NETLEN ; Set up to switch entries + HRRI D,(A) +SNET1A: MOVE C,(D) ; Out of order, must exchange! + EXCH C,NETLEN(D) + MOVEM C,(D) + AOBJN D,SNET1A + ADDI B,1 ; Count one more exchange +SNET1Z: ADD A,[1,,NETLEN] ; Each pass scan whole table. + JUMPL A,SNET1 + JUMPN B,SNET ; do another pass if anything exchanged. + + ; Table sorted, now scan through for any duplicates. + MOVE A,E ; Get AOBJN once more +SNET2: TLNN F,FL%2OU + JRST [ MOVE C,NETNUM(A) ; HOSTS3 sorts numerically + MOVE D,NETNUM+NETLEN(A) + CAMN C,D + CALL SNET3E ; Duplicate net number, report. + JRST SNET22] + HLRZ C,NTLNAM(A) + HLRZ D,NTLNAM+NETLEN(A) + CAIN C,(D) + CALL SNET2E ; Error, go handle it +SNET22: ADD A,[1,,NETLEN] + JUMPL A,SNET2 + RET + + ; Handle duplicate name situation - possible error. + ; A has ptr to 1st of 2 duplicate entries. + ; Can clobber B,C,D +SNET2E: AOS ERRDNN ; Bump cnt of duplicates + MOVE B,A ; Save current aobjn + TYPE "Duplicate network name " + HLRZ A,NTLNAM(B) ; Get addr of ASCIZ name string + ADDI A,(FA) ; Make abs + PUSHJ P,ASZOUT + TYPE " = " + MOVE A,NETNUM(B) ; Get 1st network addr + CALL HADOUT + TYPE ", " ; Now do same thing for 2nd + MOVE A,NETLEN+NETNUM(B) ; Get 2nd network addr + CALL HADOUT + CALL CROUT + MOVE A,B ; Restore aobjn ptr + RET ; Continue check loop + + ; Handle duplicate network number situation - possible error. + ; A has ptr to 1st of 2 duplicate entries. + ; Can clobber B,C,D +SNET3E: AOS ERRDNA ; Bump cnt of duplicates + MOVE B,A ; Save current aobjn + TYPE "Duplicate network number " + MOVE A,NETNUM(B) ; Get network number + CALL HADOUT + TYPE " = " + HLRZ A,NTLNAM(B) ; Get addr of ASCIZ name string for 1st + ADDI A,(FA) ; Make abs + PUSHJ P,ASZOUT + TYPE ", " + HLRZ A,NTLNAM+NETLEN(B) ; Now do same thing for 2nd entry + ADDI A,(FA) + CALL ASZOUT + CALL CROUT + MOVE A,B ; Restore aobjn ptr + RET ; Continue check loop + +SUBTTL Internal format -> HOSTS2 output fixup + +; This routine scans through the NETWORK table, and +; the ADDRESS tables for each network, to convert the host/net addresses +; to HOSTS2 format. Currently this is the only thing that needs to +; be munged. + +H2OFIX: MOVE N,NETPTR(FA) ; Get pointer to NETWORK table + MOVEI A,(N) + ADDI A,(FA) + MOVN A,(A) ; Get # entries + HRLI N,(A) ; Set up -<# entries> in LH + ADDI N,2(FA) ; Now have AOBJN ptr to NETWORK table + + ; First, smash network number +H2FX10: MOVE A,NETNUM(N) ; Get network number + CALL H2ADR ; Convert to HOSTS2 format + LDB B,[NW$BYT,,A] ; Extract net number + MOVEM B,NETNUM(N) + + ; Now convert each address for this net. + HRRZ H,NTRTAB(N) ; Get file addr of ADDRESS table + JUMPE H,H2FX35 + ADDI H,2(FA) ; Make absolute, point to 1st entry + MOVN A,-2(H) ; Find # of entries + JUMPGE A,H2FX35 ; Jump if none + HRLI H,(A) ; Now have AOBJN ptr + +H2FX30: MOVE A,ADDADR(H) ; Get host address + CALL H2ADR ; Convert it + MOVEM A,ADDADR(H) + ADD H,ADDLN1 ; ADDLEN-1 + AOBJN H,H2FX30 + +H2FX35: ADDI N,NETLEN-1 + AOBJN N,H2FX10 + RET + + +; H2ADR - Given a HOSTS3 host address in A, converts to HOSTS2 form +; as nearly as possible. + +H2ADR: PUSH P,B + PUSH P,C + MOVE C,A + CALL NETMSK ; Mask off network number + SKIPA B,[UNTTAB] +H2ADR2: ADDI B,UNTLEN + SKIPN UNTNAM(B) + JRST H2ADR3 ; Table end, unknown net number + CAME C,UNTNUM(B) + JRST H2ADR2 + + PUSH P,A + SETZ A, + MOVE C,UNTH2N(B) + DPB C,[NW$BYT,,A] + POP P,C + CALL @UNTH32(B) +H2ADR9: POP P,C + POP P,B + RET + + ; Not a known network, but try to do something plausible. +H2ADR3: LDB B,[NT$NUM,,A] + ANDCM A,[7777_24.] ; Preserve low 24 bits + DPB B,[NW$BYT,,A] ; Put net # into HOSTS2 field. + JRST H2ADR9 + +; Conversion routines, pointed to by UNTTAB. +; A/ HOSTS2 net field already set up +; B scratch +; C/ HOSTS3 address + +H32CV1: LDB B,[201000,,C] ; Get "host" field (2nd byte) + DPB B,[001000,,A] ; Deposit host + DPB C,[112000,,A] ; Deposit "imp" field (2 bytes) + RET + +H32CV2: HRRI A,(C) + RET + +H32CV3: LDB B,[201000,,C] ; Get 2nd byte + DPB B,[221100,,A] ; Deposit subnet + DPB C,[001100,,A] ; and host + RET + +SUBTTL File parsing routines + +; Note the term "SCO" stands for "Single Char Object". + +; RCH - Get input character in A + +RCH: TRNE F,FR%RCH+FR%SIN ; Skip if nothing unusual to do. + JRST RCH20 ; Hmm, do special stuff. + CALL SYSRCH ; Nothing special, get char from input file + CAIN A,^J ; Count lines read from file. + AOS LINENO + RET +RCH20: SKIPL A,UNRCHF + JRST [ SETOM UNRCHF + RET] + SKIPL A,UNRCH2 ; Handle secondary backup + JRST [ SETOM UNRCH2 + RET] + TRZE F,FR%RCH ; No backup left, ensure flag zeroed. + JRST RCH ; We were backing up, assume nothing else. + ILDB A,RCHBP ; Something else, must be FR%SIN. + CAIN A,"/ ; Special escape char? + JRST [ ILDB A,RCHBP ; Yes, get next one + CAIN A,"/ ; If another escape char, + RET ; then just return it (quoted) + JUMPE A,.+1 + CALL UNRCH ; Else back up one char + MOVEI A,^J ; and pretend we saw a LF! + RET] + JUMPN A,APOPJ ; Got a char, return it. + SETZM RCHBP ; No more input! Clear BP + TRZ F,FR%SIN ; and flag + MOVEI A,^C ; and return EOF char. + RET + +; UNRCH - Back up the character in A, so next RCH will see it. + +UNRCH: TRO F,FR%RCH ; Say char is backed up, do special stuff. + EXCH A,UNRCHF ; Store it, get prev backed-up char if any + CAIL A, ; Was there a prev backed-up char? + MOVEM A,UNRCH2 ; Yes, must save it in next place. + RET + +RCHCON: CALL RCH + TRNE F,FR%2IN ; HOSTS2 format doesn't allow continuation lines + RET + CAIN A,^M ; But if RFC810, check for continuation. + JRST [ CALL RCH + CAIN A,^J ; Next char should be LF + JRST .+1 + JRST RCHC9] ; Ugh, back up and pretend hit LF. + CAIE A,^J ; When we see a LF, check for continuation line + RET + CALL RCH + CAIE A,40 + CAIN A,^I + RET ; Hurray, continuation line! Keep going as if saw wsp. +RCHC9: CALL UNRCH ; Nope, must re-read this one + MOVEI A,^J + RET ; and return LF as terminator. + + +; RTOKEN - Read token (string or delimiter) +; Note this routine uppercases the returned token. If preserving +; lowercase ever becomes important, another entry point can be made. +; Returns .+1: +; A/ positive char (delim), ^C at EOF, or negative BP to ASCIZ string +; Clobbers B + +RTOKEN: TRNE F,FR%2IN + JRST RTOK01 ; HOSTS2 skips RTKCOM stuff + SETOM RTKCOM' + CAIA +RFIELD: SETZM RTKCOM + +RTOK01: CALL RCHCON ;First, skip white space and comments + CAIN A,^C + RET ;EOF + CAIN A,"; + JRST [ CALL RTOKCM ; Handle comment + JRST RTOK01] + CAIN A,^J ;LF is an SCO + RET + CAIG A,40 + JRST RTOK01 ;White space + TRNE F,FR%2IN + JRST RTOK02 + + CAIN A,": ; Colon is field delimiter for RFC810 + RET + SKIPN RTKCOM ; If reading whole field, ignore comma etc. + JRST [ SETZM RTKSBP' + JRST RTOK0] + +RTOK02: CAIN A,", ;Comma is an SCO + RET + TRNN F,FR%2IN + JRST RTOK0 ; Don't allow brackets if RFC810 + CAIE A,"[ ; HOSTS2 - Brackets are SCO + CAIN A,"] + RET + + ;; OK, this is going to be a long symbol +RTOK0: MOVE B,TOKBP ; Start of this symbol +RTOK1: CAIL A,"a ; Make all chars uppercase before deposit. + CAILE A,"z + CAIA + SUBI A,40 + IDPB A,TOKBP + CALL RCHCON ; Read stuff, allowing continuation lines + TRNE F,FR%2IN + JRST RTOK15 ; Skip a bunch of stuff if HOSTS2 + + SKIPN RTKCOM ; If gobbling whole field, + JRST [ CAIGE A,40 ; need special path + JRST RTOK21 + CAIN A,40 + JRST [ MOVE A,TOKBP + SKIPN RTKSBP + MOVEM A,RTKSBP + MOVEI A,40 + JRST RTOK1] + CAIE A,": + CAIN A,"; + JRST RTOK21 + SETZM RTKSBP ; Valid char, so any spaces were included. + JRST RTOK1] + +RTOK15: CAILE A,40 ;Check for termination + CAIN A,"; + JRST RTOK2 + TRNN F,FR%2IN ; Don't allow ":" as HOSTS2 delimiter + CAIE A,": + CAIN A,", + JRST RTOK2 + TRNN F,FR%2IN + JRST RTOK1 ; If RFC810, check done + CAIE A,"[ ; HOSTS2 also checks for brackets. + CAIN A,"] + JRST RTOK2 + JRST RTOK1 + + ; Crock to flush trailing blanks from a complete field-gobble. + ; If RTKSBP is set, an IDPB on it will smash the first trailing + ; blank. + ; Not used by HOSTS2. +RTOK21: CALL UNRCH ; Back up this char + SKIPN A,RTKSBP + JRST RTOK22 ; No trailing blanks + TLNN A,760000 ; Make sure pointing at a char pos + JRST [ SETZM 1(A) ; Last char position, so smash next wd. + JRST RTOK22] + PUSH P,A + LDB A,[360600,,(P)] ; Get P field of the BP + DPB A,[301400,,(P)] ; Deposit 0,P into P,S + SETZ A, ; get a zero ac + DPB A,(P) ; Deposit, clearing rest of word. + POP P,A + CAIA + +RTOK2: CALL UNRCH ; Back up this char +RTOK22: 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 + +EOLFLS: +RTOKCM: CALL RCH ; Skip comment + CAIE A,^J + CAIN A,^C ; EOF shouldn't happen, but... + CAIA + JRST RTOKCM + CALL UNRCH ; Comment ended, back up to check terminator + RET + +; RTOKLN - Get a line as token. Stops either when hit a control char, +; or when a comment is seen (defined as a semicolon preceded by +; whitespace). +; RTOKLI - Ditto but doesn't flush whitespace at front + +RTOKLN: CALL RWSPFL +RTOKLI: MOVE B,TOKBP +RTOKL2: CALL RCH +RTOKL3: CAIGE A,40 + JRST [ CAIN A,^I + JRST .+1 + JRST RTOKL9] + IDPB A,TOKBP + CAIE A,^I + CAIN A,40 + CAIA + JRST RTOKL2 + CALL RCH + CAIE A,"; + JRST RTOKL3 + CALL RTOKCM + CAIA +RTOKL9: CALL UNRCH + 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 + +; RWSPFL - Flushes whitespace. Next char read will be first non-WSP char. + +RWSPFL: CALL RCH + CAIE A,40 + CAIN A,^I + JRST RWSPFL + JRST UNRCH ; Not a WSP char, push back and return. + +; Miscellaneous routines that invoke RCH and RTOKEN. + +;Require a field terminator here (comma), or a CRLF. Skip if comma + +RCOMLF: CALL RTOKEN + CAIN A,^J + RET + TRNN F,FR%2IN ; HOSTS2 doesn't term on ":" + CAIE A,": + 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 + +;Require a field terminator here + +RFTERM: CALL RTOKEN + TRNE F,FR%2IN ; Field term for HOSTS2 is comma + JRST [ CAIN A,", + RET + MOVEI A,[ASCIZ /Missing comma/] + JRST BARF] + CAIN A,": + RET + MOVEI A,[ASCIZ /Missing colon/] + JRST BARF + + +; Require comma or colon - skip if colon. Fail if anything else. +; Not used by HOSTS2 +RFNEXT: CALL RTOKEN + CAIN A,": + AOSA (P) + CAIN A,", + RET + MOVEI A,[ASCIZ /Missing colon or comma/] + JRST BARF + +; Terminal output routines + +CROUT: PUSH P,A + MOVEI A,[ASCIZ / +/] + CALL ASZOUT + POP P,A + RET + +TYPOUT: EXCH A,(P) + EXCH A,-1(P) + CALL ASZOUT + POP P,A + RET + +BPZOUT: PUSH P,B + MOVE B,A + JRST ASZOU2 + +ASZOUT: PUSH P,B + HRLI A,440700 + SKIPA B,A +ASZOU1: CALL SYSTYO +ASZOU2: ILDB A,B + JUMPN A,ASZOU1 + POP P,B + RET + +SIXOUT: JUMPE A,APOPJ + PUSH P,B + MOVE B,A +SIXOU1: SETZ A, + ROTC A,6 + ADDI A,40 + PUSHJ P,SYSTYO + JUMPN B,SIXOU1 + JRST POPBJ + +DECOUT: PUSH P,B + CALL DECOU1 + POP P,B + RET +DECOU1: IDIVI A,10. + HRLM B,(P) + SKIPE A + PUSHJ P,DECOU1 + HLRZ A,(P) + ADDI A,"0 + CALL SYSTYO + RET + +OCTOUT: PUSH P,B + CALL OCTOU1 + POP P,B + RET + +OCTOU1: IDIVI A,8 + HRLM B,(P) + SKIPE A + PUSHJ P,OCTOU1 + HLRZ A,(P) + ADDI A,"0 + CALL SYSTYO + RET + +POPJ1: AOS (P) +APOPJ: RET +POPBJ: POP P,B + RET +POPAJ: POP P,A + RET + +; GENTRY - Host-table file reader. +; H points to next free HOST entry slot, +; N points to next free NET entry slot. + +GENTRY: MOVEM P,PARSVP' ; Save PDL ptr for throws + CALL RTOKEN ; Get initial token - should be HOST, etc. + JUMPGE A,[CAIN A,^J ; SCO - see if EOF or blank line + JRST GENTRY ; Blank line + CAIN A,^C + RET ; EOF + MOVEI A,[ASCIZ/Randomness when expecting keyword/] + JRST BARF] ; Nope, error. + MOVE B,(A) + MOVSI D,-NKYWDS +GENTR2: MOVS C,KYWDTB(D) + CAME B,(C) + JRST GENTR4 + TRNN B,377 + JRST GENTR5 ; Won! + MOVE T,1(A) + CAME T,1(C) + JRST GENTR4 + TRNN T,377 + JRST GENTR5 ; Won! + MOVE T,2(A) + CAMN T,2(C) + JRST GENTR5 +GENTR4: AOBJN D,GENTR2 +GENTR9: MOVEI B,(A) + MOVEI A,[ASCIZ /Unknown or illegal keyword: /] + JRST BARF2 ; Error, no match. + +GENTR5: HLRZ C,C + CALL (C) ; Execute function + JRST GENTRY + +; Keyword function table. Names up to 15 chars long are allowed. + +KYWDTB: [ASCIZ /HOST/] ,,GHOST + [ASCIZ /NET/] ,,GNET + [ASCIZ /GATEWAY/],,[TRNE F,FR%2IN + JRST GENTR9 ; If HOSTS2, don't allow this keyword. + JRST GGWAY] + [ASCIZ /HOSTS2/],,[TRO F,FR%2IN ; Say now processing HOSTS2 format! + JRST EOLFLS] + [ASCIZ /RFC810/],,[TRZ F,FR%2IN ; Now processing RFC810 format! + JRST EOLFLS] + [ASCIZ /INSERT/],,RDINSF ; Read insert file! + [ASCIZ /MERGE/] ,,[TLO F,FL%MRG ; Merge entries from here on + JRST EOLFLS] + [ASCIZ /MERGEOFF/],,[TLZ F,FL%MRG ; Stop merging + JRST EOLFLS] + [ASCIZ /OUTFMT/],,OFMT ; Specify output format! + [ASCIZ /OUTFIL/],,OUTFIL ; Specify output filename + [ASCIZ /HST2DUPS/],,H2DAOK + [ASCIZ /GWHOSTS/],,[SETOM GWHSTS ? JRST EOLFLS] + [ASCIZ /ALLSERVER/],,[SETOM ASERVE ? JRST EOLFLS] +IFN ONLY,[ + [ASCIZ /ONLY/],,ONLYCM ; Specify only network to include +];ONLY + [ASCIZ /BEGIN/],,EOLFLS ; Ignore this keyword. + [ASCIZ /END/],,EOLFLS ; Ignore this keyword. +NKYWDS==<.-KYWDTB> + + +; BARF - Parsing error seen. Print message, flush to EOL, +; continue reading. Bump error count so won't process tables. +; BARF2 - Like BARF but adds 2nd error message in B. + +BARF: SETZ B, +BARF2: PUSH P,A ; Save err message + SKIPGE A,LINENO + JRST [ TYPE "Error in JCL" + JRST BARFR5] + TYPE "Error on line " + PUSHJ P,DECOUT +BARFR5: TYPE ": " + POP P,A + CALL ASZOUT + SKIPE A,B ; Add 2nd string if any + CALL ASZOUT + CALL CROUT + AOS ERRPAR ; Bump error count + MOVE P,PARSVP ; Restore PDL ptr for main parsing loop + CALL RTOKCM ; Now flush to LF + JRST GENTRY ; Continue... + +; Here to handle INSERT keyword. +; Read rest of line into a filename buffer for parsing. Some +; cleverness exerted in order to handle comments properly. + +RDINSF: CALL RTOKLN ; Get single line (no continuations) +RDINS0: JUMPGE A,[MOVEI A,[ASCIZ/No filename for INSERT/] + JRST BARF] + MOVE B,A ; Save ptr to filename + MOVE A,FILCNT + CAIL A,MAXFIL-1 ; Ensure there will be enough room. + JRST [ TYPE "Too many files, cannot insert " + MOVE A,B + CALL ASZOUT + CALL CROUT + ERROR "File table too small, increase MAXFIL" + MOVEI A,[ASCIZ /Too many files, cannot insert /] + JRST BARF2] + MOVEM B,FILTBN+1(A) ; Will be enough, save filename. + AOS C,RDINCT + CAIL C,MAXINS + JRST [ SOS RDINCT + ERROR "INSERT depth too deep, possibly looping." + MOVEI A,[ASCIZ /INSERT depth too deep, cannot insert /] + JRST BARF2] + PUSH P,FA + SKIPG C,RDINCT + JRST [ TYPE "Reading text file " ; If 1st file, skip some stuff + JRST RDINS3] + MOVEI A,[ASCIZ / /] ; Type 3 spaces per level + CALL ASZOUT + SOJG C,.-2 + TYPE "Inserting file " + CALL SYSPSH ; Push current stuff + MOVEI FA,JUNKHD ; and point to fake output file header. + +RDINS3: MOVE A,B + CALL SYSOPN ; Open this file and type filename. + POP P,FA ; OK, restore pointer to real header. + TYPECR "" + PUSH P,FILIDX ; Save old index + PUSH P,LINENO + PUSH P,UNRCHF + PUSH P,UNRCH2 + PUSH P,RCHBP + PUSH P,PARSVP + PUSH P,F + AOS C,FILCNT ; Get new index + MOVEM C,FILIDX ; Set new index + SETZM LINENO ; and new # lines + TRZ F,FR%RCH+FR%SIN + CALL GENTRY ; Grovel over the inserted file. + POP P,A + HRRI F,(A) ; Restore flags in RH. + POP P,PARSVP + POP P,RCHBP + POP P,UNRCH2 + POP P,UNRCHF + POP P,LINENO + POP P,FILIDX + SOSGE RDINCT ; Pop up a level + JRST [ CALL SYSCLS ; If popped completely out, close file. + RET] + CALL SYSPOP ; When done, pop back. + RET ; Back to scan for tokens. + + + +OUTFIL: CALL RTOKLN ; Get line + JUMPGE A,[MOVEI A,[ASCIZ /No filename given for OUTFIL/] + JRST BARF] + SKIPE OUTFNM + JRST [ MOVE B,A + MOVEI A,[ASCIZ /Output file already specified, ignoring OUTFIL /] + JRST BARF2] + MOVEM A,OUTFNM + RET + + +; OFTM - Handle "OUTFMT " keyword to specify binary output format. + +OFMT: CALL RTOKEN ; Get argument + JUMPGE A,[MOVEI A,[ASCIZ /Bad syntax for OUTFMT/] + JRST BARF] + MOVE B,A ; Save ptr to arg + CALL CVSSIX ; Get word in sixbit in A + MOVEI D,NOFMTS-1 + CAME A,OFMTBI(D) + SOJGE D,.-1 + JUMPL D,[MOVEI A,[ASCIZ /Bad arg to OUTFMT - /] + JRST BARF2] + + SKIPE OFMTSL ; Output format already selected? + JRST [ CAMN D,OFMTIX ; Yes, is it identical? + JRST EOLFLS ; Yes, can ignore it then. + MOVEI A,[ASCIZ /Only one OUTFMT allowed/] + JRST BARF] + MOVEM D,OFMTIX ; Hurray, store format # to use! + SETOM OFMTSL ; Say format selected + TLZ F,FL%R2O+FL%R3O+FL%2OU + XCT OFMTBX(D) ; Set up output format flags + JRST EOLFLS + +OFMTBI: SIXBIT /HOSTS3/ ; Format ID table + SIXBIT /HOSTS2/ +NOFMTS==.-OFMTBI + + ; Output Format Execution Table +OFMTBX: TLO F,FL%R3O + TLO F,FL%R2O+FL%2OU + + ; Output Format Filename table (defaults) +OFMTBF: + IFN ITSSW,[ + 440700,,[ASCIZ /HOSTS3 >/] + 440700,,[ASCIZ /HOSTS2 >/] + ] + IFN TNXSW,[ + 440700,,[ASCIZ /HOSTS3.BIN/] + 440700,,[ASCIZ /HOSTS2.BIN/] + ] + IFN SAILSW,[ + 440700,,[ASCIZ /HOSTS3.BIN[HST,NET]/] + 440700,,[ASCIZ /HOSTS2.BIN[HST,NET]/] + ] +F$DEV==0 ; Indices into SIXBIT filename spec block +F$DIR==1 +F$FN1==2 +F$FN2==3 + +; H2DAOK - Allow duplicate HOSTS2 addresses + +H2DAOK: SKIPN OFMTSL + JRST [ MOVEI A,[ASCIZ /HST2DUPS before OUTFMT/] + JRST BARF ] + TLNN F,FL%2OU + JRST [ MOVEI A,[ASCIZ /HST2DUPS only allowed for HOSTS2/] + JRST BARF ] + TLO F,FL%2DH + JRST EOLFLS + + +; ONLY command +IFN ONLY,[ +ONLYLS: 0 ; List of network name (asciz),,cdr +ONLYCM: CALL RTOKEN ; Get argument + JUMPGE A,[MOVEI A,[ASCIZ /Bad syntax for ONLY/] + JRST BARF] + AOS B,TOKBP ; Allocate a cons + HRL A,ONLYLS ; Pick up cdr + MOVSM A,-1(B) + MOVEI B,-1(B) + MOVEM B,ONLYLS + RET +; Flush hosts that are on networks we don't care about +FLSHST: SKIPN ONLYLS + RET ; Nothing to do + MOVEI H,HSTTAB +FLSHS1: SKIPG HSTNAM(H) ; Ignore secondary entries + JRST FLSHS9 + CALL HOSTOK + CAIA + JRST FLSHS9 + SETZM HSTNAM(H) ; No good, flush it + SOS NSITS ; And decrement # of primary site entries. + SOS NNAMS ; and decrement # of name table entries. + MOVEI B,HSTNIC(H) ; Find # of nicknames + JRST FLSHS3 +FLSHS2: SOS NNAMS ; Subtract one for each nickname + HLRZ B,B +FLSHS3: SKIPE B,(B) + JRST FLSHS2 +FLSHS9: ADDI H,HSTLEN + CAMGE H,HSTTBE + JRST FLSHS1 + RET +; Skip if this host (H) is okay to include in the output file +HOSTOK: HRRZ D,HSTNUM(H) ; List of addresses +HSTOK1: HLRZ C,(D) ; CAR + MOVE C,(C) ; Network address + CALL NETFND ; Find the network in A + HRRZ A,NWKNAM(A) ; Get addr of network's name + MOVE C,ONLYLS ; Compare against list of good guys +HSTOK2: HLRZ B,(C) + CALL CMPSTR + JRST POPJ1 ; Succeed + HRRZ C,(C) ; Cdr list of good networks + JUMPN C,HSTOK2 + HRRZ D,(D) ; Cdr host's list of addresses + JUMPN D,HSTOK1 + RET ; Fail + +];ONLY + +; Here to gobble a NET entry + +GNET: SETZ C, + TLNE F,FL%MRG + MOVSI C,HE%MRG ; Set MERGE flag in entry + MOVEM C,HSTNAM(H) + TRNE F,FR%2IN + JRST GNET2 ; Go hack HOSTS2 style + + ; RFC810 format NET entry + CALL RFTERM + CALL RTOKEN ; Get net number + JUMPGE A,GNET99 ; Foo + CALL GNETAD ; Munch into net address in C + MOVEM C,NWKNUM(N) ; Store net number + CALL RFTERM + CALL RTOKEN ; Next should be network name + JUMPGE A,GNET95 + HRRZM A,NWKNAM(N) ; LH zero for net-sites count + CALL RFTERM + JRST GNET80 + +GNET2: CALL RTOKEN ; Next should be network name + JUMPGE A,GNET95 + HRRZM A,NWKNAM(N) ; LH zero for net-sites count + CALL RCOMMA + CALL RTOKEN + CALL GDECN ; Parse number into C (terminator in B) + JUMPN B,GNET99 ; Jump if error + SKIPA A,[UNTTAB] ; Scan for funny nets (note B is zero!) +GNET25: ADDI A,UNTLEN + SKIPN UNTNAM(A) ; If at end of table, + JRST GNET26 ; we just deposit net number in field. + CAME C,UNTH2N(A) ; Number matches? + JRST GNET25 ; No, keep looking + SKIPA B,UNTNUM(A) ; Yes, get internal net number for it! +GNET26: DPB C,[NT$NUM,,B] ; Come here for unspecial net number. + MOVEM B,NWKNUM(N) ; Store network number + +GNET80: SETZM NWKPTR(N) + CALL RTOKEN + CAIE A,^J ;Should be end of line + JRST [ MOVEI A,[ASCIZ /Garbage where end of line expected/] + JRST BARF] + ADDI N,NWKLEN + AOS NNETS + RET +GNET95: MOVEI A,[ASCIZ/Random character when expecting net name/] + JRST BARF +GNET99: MOVEI A,[ASCIZ/Random character when expecting net number/] + JRST BARF + +; Here to gobble a HOST/GATEWAY entry + +GGWAY: MOVSI C,HE%GWY ; Set GATEWAY flag in entry + MOVSI B,STFGWY ; For now, also set it in site flags. + CAIA ; Later will hack this at FLGSET. +GHOST: SETZB B,C + TLNE F,FL%MRG + TLO C,HE%MRG ; Set MERGE flag in entry + MOVEM C,HSTNAM(H) + MOVEM B,HSTFLG(H) ; Set/clear site flags (later just clear) + SETZM HSTNUM(H) + SETZM HSTSYS(H) + SETZM HSTMCH(H) + SETZM HSTNIC(H) + SETZM HSTSVC(H) + TRNE F,FR%2IN + JRST GHST2 ; Handle HOSTS2 format + + CALL RFTERM +GHST31: CALL RTOKEN ; Get Internet addr + CALL GHOSTN ; Process it + CALL RFNEXT ; See if more in field + JRST GHST31 ; Comma, more stuff. + + CALL RTOKEN ; Next is host name + JUMPGE A,GHST91 ; Jump if bad hostname field + HRRM A,HSTNAM(H) ; Store official hostname +GHST33: CALL RFNEXT ; More? + JRST [ CALL RTOKEN + CALL GNICKN ; Handle as nicknames. + JRST GHST33] + + CALL RFIELD ; Next is machine type + JUMPL A,[HRRZM A,HSTMCH(H) + CALL RTOKEN + JRST .+1] + CAIE A,": + JRST GHST92 ; Bad machine field + + CALL RFIELD ; Next is system name + JUMPL A,[HRRZM A,HSTSYS(H) + CALL RTOKEN + JRST .+1] + CAIE A,": + JRST GHST92 ; Bad system field + +GHST35: CALL RTOKEN ; Next is list of services + JUMPL A,[CALL GSVCN ; Get service name like nickname + CALL RFNEXT + JRST GHST35 + JRST .+1] + CAIE A,": + JRST GHST93 ; Bad service field + +GHST37: CALL RTOKEN ; Should now be at EOL. + CAIE A,^J ; For now, flush remaining fields. + CAIN A,^C + CAIA + JRST GHST37 + +GHSTOK: TLNE F,FL%2OU ; If outputting HOSTS2 format, + JRST [ MOVE B,HSTFLG(H) + TLNE B,STFGWY ; We ignore gateway entries after parse check! + RET ; Ignore this one + JRST .+1] ; Else OK to add it. + ADDI H,HSTLEN + AOS NSITS + RET ; That's all! + +GHST90: MOVEI A,[ASCIZ /Bad net address field/] + JRST BARF +GHST91: MOVEI A,[ASCIZ /Bad site name field/] + JRST BARF +GHST92: MOVEI A,[ASCIZ /Bad system type field/] + JRST BARF +GHST93: MOVEI A,[ASCIZ /Bad services field/] + JRST BARF +GHST94: MOVEI A,[ASCIZ /Garbage at end of entry/] + JRST BARF + + + + ; HOSTS2 format parsing for HOST entry +GHST2: MOVSI B,HE%2IN ; Set flag for entry to mark HOSTS2 format. + IORM B,HSTNAM(H) + CALL RTOKEN ; Next should be host name + JUMPGE A,[MOVEI A,[ASCIZ/Random character when expecting host name/] + JRST BARF ] + HRRM A,HSTNAM(H) + CALL RCOMMA ;Next should be comma + 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 + CALL RTOKEN ;Status + MOVE B,(A) + MOVSI C,STFSRV + CAMN B,[ASCII/SERVE/] + IORM C,HSTFLG(H) + CALL RCOMLF + JRST GHOST6 ;CRLF + CALL RTOKEN ;Optional system name + JUMPGE A,[CALL UNRCH + JRST GHST22] + HRRZM A,HSTSYS(H) +GHST22: CALL RCOMLF + JRST GHOST6 ;CRLF + CALL RTOKEN ;Optional machine name + JUMPGE A,GHST23 + HRRZM A,HSTMCH(H) + CALL RTOKEN + + ;Here A is comma before nicknames, or CRLF +GHST23: 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 ] + + JRST GHSTOK ; Successful parse of entry + +;;; This parses up a host address and conses it onto list in HSTNUM(H) +;;; First token is in A + +GHOSTN: CALL GNETAD ; Parse net addr into result in C + MOVE B,TOKBP ; 2 words to CONS into + MOVEM C,1(B) ; Full word of host number + MOVSI C,1(B) ; car,,cdr + HRR C,HSTNUM(H) + MOVEM C,0(B) + HRRZM B,HSTNUM(H) + ADDI B,2 + MOVEM B,TOKBP + RET + +; GNETAD - Parse a net address and return value in C. +; First token already in A. + +GNETAD: MOVE B,A + ILDB C,B ; Check 1st char of address + CAIL C,"0 + CAILE C,"9 ; If not a number (implying Internet) + JRST GADR20 ; then it's a non-Internet addr, go hack it. + TRNN F,FR%2IN ; For RFC810, + CALL GINUM ; parse an Internet address into C + TRNE F,FR%2IN ; For HOSTS2, + JRST [ MOVEI D,UNTTAB ; parse host/imp Arpanet address into C + MOVE C,UNTPAR(D) + JRST GADR26] +GADR80: RET + + + ; Parse non-Internet address. Token is network name; identify + ; it and continue parsing as specified by network definition. +GADR20: MOVEI D,UNTTAB ; Point to unternet def table + MOVE B,(A) ; Get first word of token + CAMN B,[ASCIZ /IN/] ; Special hack: Internet? + JRST [ CALL RTOKEN ; Get next token, should be + CALL GINUM ; an Internet address. + JRST GADR80] + CAMN B,[ASCIZ /UN/] ; Special hack: Unternet? + JRST [ CALL RTOKEN ; Get next token, should be + CALL GINUM ; an Internet-style address. + TLO C,(NE%UNT) ; Add the Unternet bit! + JRST GADR80] + +GADR21: SKIPN B,UNTNAM(D) ; Get pointer to name string + JRST [ MOVEI A,[ASCIZ /Undefined network name in address field/] + JRST BARF] ; Ran out of definitions + CALL CMPSTR ; Compare strings pointed to by A and B + JRST GADR25 ; Won! + ADDI D,UNTLEN ; No match, try next entry + JRST GADR21 + + ; Found network definition. For now, use quick hack of jumping + ; to specific parse types. Later generalize. +GADR25: SKIPL C,UNTPAR(D) ; Get parsing type + JRST [ CALL RTOKEN ; Unless sign bit set, get next token + JUMPGE A,GADR92 ; Barf if no next token. + JRST .+1] +GADR26: CALL @GADRPT(C) ; Get number into C + CAIA ; (Skip to avoid net-number insertion) + JRST GADR80 + ANDCM C,UNTMSK(D) ; Mask out the network-number field + IOR C,UNTNUM(D) ; and stash in the net number for this net! + JRST GADR80 + +UNTNAM==:0 ; Net name +UNTNUM==:1 ; Net number +UNTMSK==:2 ; Mask for net number +UNTPAR==:3 ; Parsing routine for this net's addresses +UNTH2N==:4 ; HOSTS2 net number +UNTH32==:5 ; Rtn for internal to HOSTS2 format conversion (see H2ADR) + UNTLEN==:6 +DEFINE DEFUNT NAME,TYP,VAL,PARSE,CVT,H2VAL +%%UVAL==<_24.> + IRPC CHAR,,[TYP] + IFSE CHAR,U, %%UVAL==%%UVAL+NE%UNT + IFSE CHAR,S, %%UVAL==%%UVAL+NE%STR + TERMIN +[ASCIZ /NAME/] ? %%UVAL ? 7777_24. ? $UP!PARSE + IFSE [H2VAL][] VAL + .ELSE H2VAL +CVT +TERMIN + +UNTTAB: DEFUNT ARPA,,12,ARP,H32CV1 + DEFUNT RCC,,3,ARP,H32CV1 + DEFUNT LCS,,22,LCS,H32CV3 + DEFUNT SU,U,44,PUP,H32CV2 + DEFUNT RU,U,61,OCT,H32CV3 + DEFUNT DSK,U,1,OCT,H32CV2,777 ; Note HOSTS2 netnum very different + DEFUNT CHAOS,U,7,OCT,H32CV2 + DEFUNT DIAL,US,26,STR,H32CV2 + DEFUNT ECL,U,2,OCT,H32CV2,776 ; For JSOL (USC-ECL) + DEFUNT ZOT,U,3,OCT,H32CV2,775 ; For JSOL (USC-ECL) + 0 + +$UPIN==:0 +$UPOCT==:1 +$UPARP==:2 +$UPLCS==:3 +$UPPUP==:4 +$UPSTR==:5 +GADRPT: GADR30 ; IN - Hack Internet-style number + GADR31 ; OCT - Hack single octal number + GADR32 ; ARP - Hack Arpa-style host/imp + GADR34 ; LCS - Hack subnet/host + GADR36 ; PUP - Hack subnet#host + GADR38 ; STR - Hack string + + ; Internet-style number (4 decimal octets) +GADR30: CALL GINUM + RET + + ; Single octal number +GADR31: CALL GOCTN + JUMPN B,GADR93 + RET + + ; Arpanet host/imp (decimal) +GADR32: CALL GDECN + CAIE B,"/ ; Should get slash + JRST GADR93 + PUSH P,C + CALL GDECN ; Continue reading next number + JUMPN B,GADR93 + POP P,B ; Host # in B, Imp # in C + CAILE C,177777 ; 16 bits allowed for Imp # + JRST GADR94 + CAILE B,377 + JRST GADR94 + DPB B,[201000,,C] ; Stick host # into address + RET + + ; Hack subnet/host +GADR34: CALL GOCTN + CAIE B,"/ ; Should get slash + JRST GADR93 + PUSH P,C + CALL GOCTN + JUMPN B,GADR93 + POP P,B ; Subnet # in B, Host # in C + CAILE C,377 + JRST GADR94 + CAILE B,377 + JRST GADR94 + DPB B,[201000,,C] ; Stick subnet # into address + RET + + ; Hack subnet#host +GADR36: CALL GOCTN + CAIE B,"# ; Should get pound-sign + JRST GADR93 + PUSH P,C + CALL GOCTN + JUMPN B,GADR93 + POP P,B ; Subnet # in B, Host # in C + CAILE C,377 + JRST GADR94 + CAILE B,377 + JRST GADR94 + DPB B,[101000,,C] ; Stick subnet # into address + RET + + ; Hack string +GADR38: MOVEI C,(A) ; Use address of string + RET + +GADR91: MOVEI A,[ASCIZ /Non-digit when digit expected in address/] + JRST BARF +GADR92: MOVEI A,[ASCIZ /No number given in address field/] + JRST BARF +GADR93: MOVEI A,[ASCIZ /Bad syntax for address number/] + JRST BARF +GADR94: MOVEI A,[ASCIZ /Address number out of range/] + JRST BARF + +GINUM: JUMPGE A,GADR91 ; SCO? + PUSH P,[0] ; Put zero word on stack + MOVE E,[401000,,(P)] ; and set up ptr into it +REPEAT 3,[ + CALL GDECN ; Get first octet + CAIE B,". ; Verify terminated OK + JRST GADR93 + IDPB C,E +] ; For 3 octets + CALL GDECN + JUMPN B,GADR93 + IDPB C,E + POP P,C ; Number finished, stash in AC + RET + +; Get a nickname. Make HSTNIC be pointer to vector of addresses of ASCIZ, +; end by zero. +; Nickname is already in A, just needs to be CONSed onto list. +GNICKN: HRL A,TOKBP ; CDR is next free loc, in LH + EXCH A,HSTNIC(H) ; Store first CONS, get set to store previous + MOVEM A,@TOKBP ; Store previous + AOS TOKBP ; Bump free ptr + RET + +; Store service name, similar to nickname list (but parameters possible) +; For now, no params are parsed. +; Not used by HOSTS2 + +GSVCN: MOVE T,TOKBP ; Get ptr to free loc + HRRZM A,SVRNAM(T) ; Store service name ptr in new node + MOVE TT,HSTSVC(H) ; Get previous ptr + HRLI TT,1 ; Say just 1 extra wd + MOVEM TT,SVRCDR(T) ; Store 1st word of service node + HRRZM T,HSTSVC(H) ; Store new ptr to list + HLRZ A,SVLCNT(T) ; Retrieve # words in node + ADDI T,1(A) ; Bump free-ptr past stored node + MOVEM T,TOKBP + RET + + +; Routine to fetch an octal number from an input string +; Entry: a = str ptr to number string +; Call: GOCTN -- begin loading digits +; GOCTN0 -- 1st digit already in b +; Return: +1, a = updated str ptr, b = terminating char, c = number +GOCTN: ILDB B,A ; b _ first digit +GOCTN0: SETZ C, ; Clear starting value +GOCTN1: CAIL B,"0 ; b = octal digit? + CAILE B,"7 + RET ; No + LSH C,3 ; c _ 8 * (old value) + ADDI C,-"0(B) ; c _ c + (new digit) + ILDB B,A ; b _ next input char + JRST GOCTN1 ; Check it out + +; Routine to fetch a decimal number from an input string +; Entry: a = str ptr to number string +; Call: GDECN -- begin loading digits +; GDECN0 -- 1st digit already in b +; Return: +1, a = updated str ptr, b = terminating char, c = number +GDECN: ILDB B,A ; b _ first digit +GDECN0: SETZ C, ; Clear starting value +GDECN1: CAIL B,"0 ; b = decimal digit? + CAILE B,"9 + RET ; No + IMULI C,10. ; c _ 10 * (old value) + ADDI C,-"0(B) ; c _ c + (new digit) + ILDB B,A ; b _ next input char + JRST GDECN1 ; Check it out + + + +; CVSSIX - Converts ASCIZ string to SIXBIT word. +; A/ BP to ASCIZ string, +; Returns SIXBIT word in A. Clobbers nothing else. + +CVSSIX: PUSH P,B + PUSH P,C + PUSH P,D + MOVE D,A + SETZ A, + MOVE B,[440600,,A] + JRST CVSSX3 +CVSSX2: CAIL C,140 + SUBI C,40 ; Uppercase force + SUBI C,40 ; cvt to 6bit + IDPB C,B ; deposit + TLNN B,770000 ; If BP at end of word, + JRST CVSSX5 ; leave loop. +CVSSX3: ILDB C,D + JUMPN C,CVSSX2 +CVSSX5: POP P,D + POP P,C + POP P,B + POPJ P, + + +; CMPSTR - Compare two strings pointed to by A and B. +; Currently assumes word-aligned ASCIZ, case dependent. +; Returns .+1 if strings match, +; .+2 if they don't. + +CMPSTR: PUSH P,A + PUSH P,B + PUSH P,C +CMPST1: ADDI A,1 + MOVE C,-1(A) + CAME C,(B) + JRST CMPST8 + TRNE C,376 ; Last char zero? + AOJA B,CMPST1 + CAIA ; Won, take non-skip return. +CMPST8: AOS -3(P) + POP P,C + POP P,B + POP P,A + RET + +; UPPERA - Uppercase the ASCIZ string pointed to by A, +; modifying it in place. Clobbers T, TT. + +UPPERA: MOVEI T,(A) + HRLI T,440700 +UPPER4: ILDB TT,T + JUMPE TT,APOPJ + CAIL TT,"a + CAILE TT,"z + JRST UPPER4 + SUBI TT,"a-"A + DPB TT,T + JRST UPPER4 + +; CPSTR - Copy ASCIZ string B to BP in A + +CPSTR: TLNN B,-1 ; If LH is zero + HRLI B,440700 ; Furnish BP to ASCIZ string + CAIA +CPSTR2: IDPB T,A + ILDB T,B + JUMPN T,CPSTR2 + MOVE B,A + IDPB T,A + MOVE A,B + RET + +SUBTTL Storage + +;; Dump out literals to make purification possible +..LIT2: CONSTANTS +ENDPUR:: +IF2,BABBLE "Pure code ends at ",\ENDPUR + +;; Round up to (twenex) page boundry for pure code +.=<<.+777>&<#777>> +BEGDAT:: ; Beginning of small data section + + +;; Initialized variables. Some of these used to live up top mixed +;; in with the code. + +NWKTBE: 0 ; First unused addr in internal network table +HSTTBE: 0 ; First unused addr in internal host table +TOKBP: 0 ; Byte ptr to end of internal string table, for adding stuff +ISTRP: 0 ; Ptr to start of internal sort-string table (ends at STREND) + ; Error if RH of TOKBP is > ISTRP (overlap) + +OUTPT: 0 ; Pointer for storing into file string & misc area +ENDHSN: 0 ; Set to predicted end of above area. +NETP: 0 ; Addr of place to put NETWORK table. +NTNP: 0 ; Addr of place to put NETNAME table. +SITP: 0 ; Addr of place to put SITES table. +NAMP: 0 ; Addr of place to put NAMES table. +NAMEP: 0 ; Ptr for storing into NAMES table. +ENDFIL: 0 ; Predicted end of fileaddr space + +NNETS: 0 ; Number of networks +NNTNS: 0 ; Number of network names (should be same as NNETS) +NSITS: 0 ; Number of active site entries +NNAMS: 0 ; Number of names (for NAMES table) + +UNRCHF: -1 ; 1st char backup +UNRCH2: -1 ; 2nd char backup +RCHBP: 0 ; BP for string input, if FR%SIN is set. + +EVLAST: -1 ; For using last system error # +EVNONE: 0 ; For using no system error + +LINENO: -1 ; # lines read in current file (-1 for JCL) +RDINCT: -1 ; Depth of insert so far + +FILIDX: 0 ; Index of file currently being read +FILCNT: 0 ; Highest index thus far +FILTBN: BLOCK MAXFIL ; Pointer to ASCIZ file name + +JUNKHD: BLOCK HDRLEN + +OUTFNM: 0 ; If non-zero points to ASCIZ output filename string + +OFMTSL: 0 ; -1 if user has explicitly specified a format +OFMTIX: 0 ; Always indicates current output format + +GWHSTS: 0 ; GWHOSTS keyword switch +ASERVE: 0 ; ALLSERVE keyword switch + +;; End of initialized variables + +SUBTTL Pre-defined file strings + +; Here are strings which are "pre-defined" by CANON so that their +; values are easy to test for (in MACH for example) simply by comparing +; addresses. Note that CANON changes the addresses in this table to +; point at the actual stored strings in the file. +; +; Now, it might seem a little odd to you that these are all down here +; in the variables section. Yup. The compiler does fixups on these +; silly things, for absolutely no reason at all except that they are +; in the string pointer table when it starts doing fixups. Good thing +; nobody ever tries to use the core image of this program twice in a +; row... + +PDSTRS: +PDP10: [ASCIZ "PDP10"] ;Note: PDP10, not PDP-10, so fits in 1 word. +PDP11: [ASCIZ "PDP11"] +TIP: [ASCIZ "TIP"] +ITS: [ASCIZ "ITS"] +TENEX: [ASCIZ "TENEX"] +TOPS10: [ASCIZ "TOPS10"] ; RFC810 source uses this variant. +TOPS20: [ASCIZ "TOPS20"] +TOPS1X: [ASCIZ "TOPS-10"] ; Sigh... HOSTS2 source has this variant +TOPS2X: [ASCIZ "TOPS-20"] +WAITS: [ASCIZ "WAITS"] +ELF: [ASCIZ "ELF"] +UNIX: [ASCIZ "UNIX"] +RSX11: [ASCIZ "RSX-11"] +HYDRA: [ASCIZ "HYDRA"] +MULTIC: [ASCIZ "MULTICS"] +VMS: [ASCIZ "VMS"] +SNTEL: [ASCIZ "NCP/TELNET"] ; For fast comparison in FLGSET +STTEL: [ASCIZ "TCP/TELNET"] +SNFTP: [ASCIZ "NCP/FTP"] +STFTP: [ASCIZ "TCP/FTP"] +SNSMTP: [ASCIZ "NCP/SMTP"] +STSMTP: [ASCIZ "TCP/SMTP"] +NPDSTR==.-PDSTRS + +...VAR::VARIABLES ; Dump out .SCALARs +...NAM: CONSTANTS ; Dump out more literals (see prev page) +ENDDAT:: ; First free location + +IF2,BABBLE "Small data ends at ",\ENDDAT + +;; Now allocate the big buffers. The hell with the 20X symbol table, +;; we don't have the address space to spare for it anymore. Just +;; round up to next page boundry. Use IDDT's ;O and ;W commands to +;; debug on 20X. + +PAGDAT==<<.+777>&<#777>> ; [Default] beginning of paged data + +IFNDEF HSTTAB,HSTTAB=:PAGDAT ; Location of internal host entry table +NWKTAB=:HSTTAB+2000*HTSIZE ; Location of internal network table +STRTAB=:NWKTAB+2000*NTSIZE ; Location of internal strings table +STREND=:STRTAB+2000*STSIZE-1 ; End of string area +OUTTAB=:STREND+1 ; Location of output file image +OUTEND=:OUTTAB+2000*OFSIZE-1 ; End of string area + +ENDINT=:OUTEND ; Last word of internal buffers and junk +IFG ENDINT-775777,{ ; Barf city + BABBLE "ENDINT=",\ENDINT + .FATAL Internal buffers overflow available address space!!! +} + +IF2,{ +BABBLE "Large data ends at ",\ENDINT +PRINTX " +Large data configuration: +" +BABBLE "HSTTAB = ",\HSTTAB +BABBLE "NWKTAB = ",\NWKTAB +BABBLE "STRTAB = ",\STRTAB +BABBLE "OUTTAB = ",\OUTTAB +PRINTX " +" +} + +;; Zee End + +IFN TNXSW, END <4,,START> +.ELSE END START