home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 1 / crawlyvol1.bin / bbs / md115 / md.gfa (.txt) < prev   
GFA-BASIC Atari  |  1994-09-11  |  86KB  |  3,758 lines

  1. ' MakeDiff Nodelist Editing/Creating Package
  2. ' Copyright David John Thomas, B.Sc.(Hons.); 1991, 1992, 1993, 1994.
  3. '
  4. ' This program is free software; you can redistribute it and/or modify
  5. ' it under the terms of the GNU General Public License as published by
  6. ' the Free Software Foundation; either version 2 of the License, or
  7. ' (at your option) any later version.
  8. '
  9. ' This program is distributed in the hope that it will be useful,
  10. ' but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. ' GNU General Public License for more details.
  13. '
  14. ' You should have received a copy of the GNU General Public License
  15. ' along with this program; if not, write to the Free Software
  16. ' Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. '
  18. ' I can be contacted via email to David J. Thomas at 2:442/600@fidonet.org,
  19. ' 90:103/103@nest.ftn, 100:104/0@turbonet.ftn, or as davtom@dream.embassy.co.uk.
  20. ' My address for paper mail is currently 56 Forrest Road, CARDIFF, CF5 1HQ, UK
  21. ' until October/November 1994.
  22. '
  23. DEFWRD "a-z"
  24. ver$="1.15"
  25. dist!=-1
  26. ' ## INLINE:
  27. ' $0000: 00 00 00 1f 00 3b 00 5a 00 78 00 97 00 b5 00 d4 
  28. ' $0010: 00 f3 01 11 01 30 01 4e 
  29. ' 24  Bytes.
  30. INLINE dpm%,24
  31. IF NOT dist!
  32.   ON BREAK GOSUB brk
  33.   nobar!=-1
  34. ENDIF
  35. CLS
  36. BOUNDARY 0
  37. env%={BASEPAGE+&H2C}
  38. env$=""
  39. DO WHILE BYTE{env%+LEN(env$)}>0
  40.   env$=env$+CHAR{env%}+CHR$(0)
  41. LOOP
  42. env$=env$+CHR$(0)
  43. check!=-1
  44. lf$=CHR$(10)
  45. maxsize&=5000
  46. netmail!=0
  47. HIDEM
  48. IF dist!
  49.   ON ERROR GOSUB errout
  50. ENDIF
  51. arc_min%=2048
  52. diff_min%=4096
  53. eof$=CHR$(26) !End of file
  54. MODE 0
  55. ' ## INLINE:
  56. ' $0000: 30 30 30 31 2e 48 44 52 00 ff ff ff 00 00 00 03 
  57. ' $0010: 01 20 00 2a e7 20 62 f0 1b 45 00 01 18 20 30 30 
  58. ' $0020: 30 31 2e 48 44 52 00 4b 45 59 00 00 
  59. ' 44  Bytes.
  60. INLINE dta%,44
  61. ~FSETDTA(dta%)
  62. DIM k&(11),d$(6),m$(11),fjd&(11,1),njd&(11,1),seg$(499),node$(499),typ$(499),pw$(499),pw!(499),field$(7),bps%(6),arg$(50),arc$(25,1),pb&(999),node!(32767),net!(32767),zone!(32767),fieldname$(7),reg%(15)
  63. nbps&=6
  64. bps%(1)=300
  65. bps%(2)=1200
  66. bps%(3)=2400
  67. bps%(4)=9600
  68. bps%(5)=19200
  69. bps%(6)=38400
  70. fieldname$(0)="Keyword"
  71. fieldname$(1)="Node number"
  72. fieldname$(2)="Node name"
  73. fieldname$(3)="Location"
  74. fieldname$(4)="Sysop name"
  75. fieldname$(5)="Phone number"
  76. fieldname$(6)="BPS rate"
  77. fieldname$(7)="Flags"
  78. rev$=CHR$(27)+"p"
  79. nor$=CHR$(27)+"q"
  80. CLS
  81. PRINT "MakeDiff Nodelist Editor/Creator version ";ver$;" - Created using GFA Basic v3.5E E"
  82. PRINT "Copyright David J. Thomas, B.Sc.(Hons.); 1991, 1992, 1993, 1994."
  83. PRINT
  84. PRINT "Use and distribution of this program is governed by the GNU General Public"
  85. PRINT "License (see file COPYING for details). This means that the program is freely"
  86. PRINT "usable and distributable under the conditions contained therein."
  87. PRINT
  88. PRINT "Initialising"
  89. PRINT
  90. FOR i&=0 TO 11
  91.   READ k&(i&)
  92. NEXT i&
  93. FOR i&=0 TO 6
  94.   READ d$(i&)
  95. NEXT i&
  96. FOR i&=0 TO 11
  97.   READ m$(i&)
  98. NEXT i&
  99. FOR l&=0 TO 1
  100.   d&=0
  101.   FOR i&=0 TO 11
  102.     fjd&(i&,l&)=d&
  103.     READ x&
  104.     njd&(i&,l&)=x&
  105.     d&=d&+x&
  106.   NEXT i&
  107. NEXT l&
  108. argc&=0
  109. IF BYTE{BASEPAGE+128}
  110.   cl$=TRIM$(CHAR{BASEPAGE+129})+" "
  111. ELSE
  112.   cl$=""
  113. ENDIF
  114. ctl$="MAKEDIFF.CTL"
  115. DO UNTIL cl$="" OR cl$=" "
  116.   INC argc&
  117.   arg$(argc&)=TRIM$(LEFT$(cl$,INSTR(cl$," ")-1))
  118.   cl$=TRIM$(MID$(cl$,INSTR(cl$," ")))+" "
  119. LOOP
  120. FOR i&=1 TO argc&
  121.   IF LEFT$(arg$(i&))="-"
  122.     FOR j&=2 TO LEN(arg$(i&))
  123.       x$=UPPER$(MID$(arg$(i&),j&,1))
  124.       IF x$="P"
  125.         pro!=-1
  126.       ENDIF
  127.       IF x$="T"
  128.         test!=-1
  129.         cltest!=-1
  130.       ENDIF
  131.       IF x$="M"
  132.         merge!=-1
  133.       ENDIF
  134.       IF x$="R"
  135.         rept!=-1
  136.       ENDIF
  137.     NEXT j&
  138.   ELSE
  139.     IF LEFT$(arg$(i&))<>"-" AND arg$(i&)<>""
  140.       ctl$=UPPER$(arg$(i&))
  141.       IF NOT EXIST(ctl$) AND RINSTR(ctl$,"\")>RINSTR(ctl$,".")
  142.         ctl$=ctl$+".CTL"
  143.       ENDIF
  144.     ENDIF
  145.   ENDIF
  146. NEXT i&
  147. IF NOT EXIST(ctl$)
  148.   nobar!=-1
  149.   PRINT "Control file does not exist - aborting"
  150.   fin(255)
  151. ENDIF
  152. PRINT "Reading control file ";ctl$
  153. PRINT
  154. inpctl(ctl$)
  155. IF NOT nobar!
  156.   ytop&=INT{L~A-4}-INT{L~A-46}+1
  157.   ybot&=INT{L~A-4}-1
  158.   origlines&=INT{L~A-42}
  159.   xwid&=INT{L~A-12}-2
  160.   INT{L~A-42}=origlines&-1
  161.   timebar(0)
  162. ENDIF
  163. DIM nold$(maxsize&-1),nnew$(maxsize&-1),ndif$(maxsize&-1),index&(maxsize&-1)
  164. log("#Address "+STR$(ozone&)+":"+STR$(onet&)+"/"+STR$(onode&))
  165. day$=@day$
  166. ' here we must set passed=-1 if today is between send day and publishing day
  167. x$=LEFT$(day$,3)
  168. y$=LEFT$(sendday$,3)
  169. z$=LEFT$(pubday$,3)
  170. SELECT z$
  171. CASE "Sun"
  172.   d$="MonTueWedThuFriSat"
  173. CASE "Mon"
  174.   d$="TueWedThuFriSatSun"
  175. CASE "Tue"
  176.   d$="WedThuFriSatSunMon"
  177. CASE "Wed"
  178.   d$="ThuFriSatSunMonTue"
  179. CASE "Thu"
  180.   d$="FriSatSunMonTueWed"
  181. CASE "Fri"
  182.   d$="SatSunMonTueWedThu"
  183. CASE "Sat"
  184.   d$="SunMonTueWedThuFri"
  185. ENDSELECT
  186. IF INSTR(d$,z$)
  187.   d$=MID$(d$,INSTR(d$,z$)+3)
  188. ELSE
  189.   d$=""
  190. ENDIF
  191. passed!=INSTR(z$,x$)
  192. IF passed!
  193.   daylst2$=@daylst$
  194.   daylst$=@daynxt$
  195.   daynxt$=@daynxt2$
  196.   datlst$=@datnxt$
  197.   datnxt$=@datnxt2$
  198. ELSE
  199.   daylst2$=@daylst2$
  200.   daylst$=@daylst$
  201.   daynxt$=@daynxt$
  202.   datlst$=@datlst$
  203.   datnxt$=@datnxt$
  204. ENDIF
  205. log("#Next list: "+datnxt$+" -- Day number "+daynxt$)
  206. dat$=@dat$
  207. IF nsegs&
  208.   log("+Checking for nodelist segment updates")
  209.   inpnew
  210. ENDIF
  211. IF test!=TRUE
  212.   pro!=FALSE
  213. ENDIF
  214. IF rept!
  215.   report
  216. ELSE IF (sendday$=LEFT$(dat$,LEN(sendday$)) OR pro!) AND test!=0
  217.   process
  218. ELSE IF NOT subset!
  219.   IF cltest!
  220.     test
  221.   ELSE
  222.     IF @fullreq
  223.       log("!Test mode overridden by netmail request")
  224.       process
  225.     ELSE
  226.       test
  227.     ENDIF
  228.   ENDIF
  229. ELSE
  230.   log("!Test not executed in subset mode")
  231. ENDIF
  232. fin(-netmail!)
  233. ' input control file info
  234. > PROCEDURE inpctl(ctl$)
  235.   LOCAL l$
  236.   nsegs&=0
  237.   sendarc&=-1
  238.   pvtvalid!=-1
  239.   OPEN "I",#0,ctl$
  240.   DO UNTIL EOF(#0)
  241.     l$=@in$(0)
  242.     ' convert tabs into spaces
  243.     DO WHILE INSTR(l$,CHR$(9))
  244.       BYTE{V:l$+INSTR(l$,CHR$(9))-1}=32
  245.     LOOP
  246.     DO WHILE LEFT$(l$)=" "
  247.       l$=MID$(l$,2)
  248.     LOOP
  249.     IF INSTR(l$,";")
  250.       l$=LEFT$(l$,INSTR(l$,";")-1)
  251.     ENDIF
  252.     DO WHILE RIGHT$(l$)=" "
  253.       l$=LEFT$(l$,LEN(l$)-1)
  254.     LOOP
  255.     DO WHILE INSTR(l$,"  ")
  256.       l$=LEFT$(l$,INSTR(l$,"  "))+MID$(l$,INSTR(l$,"  ")+2)
  257.     LOOP
  258.     IF INSTR(l$," ")
  259.       com$=UPPER$(LEFT$(l$,INSTR(l$," ")-1))
  260.       par$=MID$(l$,INSTR(l$," ")+1)
  261.     ELSE
  262.       com$=UPPER$(l$)
  263.       par$=""
  264.     ENDIF
  265.     upr$=UPPER$(par$)
  266.     IF com$="THRESHOLD" !Syntax: Threshold <arc_min> [<diff_min>]
  267.       IF thr!
  268.         er$=er$+"Threshold levels defined twice"+lf$
  269.       ENDIF
  270.       thr!=TRUE
  271.       IF INSTR(par$," ")
  272.         arc_min%=VAL(LEFT$(par$,INSTR(par$," ")-1))
  273.         diff_min%=VAL(MID$(par$,INSTR(par$," ")+1))
  274.         IF diff_min%<arc_min%
  275.           er$=er$+"DIFF length min must be > ARC length min"+lf$
  276.         ENDIF
  277.       ELSE
  278.         arc_min%=VAL(par$)
  279.         diff_min%=arc_min%
  280.       ENDIF
  281.     ELSE IF com$="ISSUE"
  282.       IF iss!
  283.         er$=er$+"Issue statement defined twice in control file"+lf$
  284.       ENDIF
  285.       iss!=TRUE
  286.       nlissue%=VAL(par$)
  287.       x%=INSTR(par$," (updated ")
  288.       IF x%
  289.         nlupday%=VAL(MID$(par$,x%+10))
  290.         nlupmonth%=(INSTR("JanFebMarAprMayJunJulAugSepOctNovDec",MID$(par$,x%+13,3))+2)/3
  291.         nlupyear%=VAL(MID$(par$,x%+17))
  292.       ENDIF
  293.     ELSE IF com$="DEBUG"
  294.       IF debug!
  295.         er$=er$+"Debug statement defined twice"+lf$
  296.       ENDIF
  297.       debug!=TRUE
  298.     ELSE IF com$="NETWORK"
  299.       IF nam$>""
  300.         er$=er$+"Network name defined twice"+lf$
  301.       ENDIF
  302.       nam$=par$
  303.     ELSE IF com$="INBOUND"
  304.       IF inb$>""
  305.         er$=er$+"Inbound directory defined twice"+lf$
  306.       ENDIF
  307.       inb$=@fullpath$(upr$)
  308.     ELSE IF com$="HOLD"
  309.       IF hold$>""
  310.         er$=er$+"Hold directory defined twice"+lf$
  311.       ENDIF
  312.       hold$=@fullpath$(upr$)
  313.     ELSE IF com$="SEGMENT"
  314.       IF dat!
  315.         er$=er$+"Segment and Data both specified"+lf$
  316.       ENDIF
  317.       IF seg$>""
  318.         er$=er$+"Local segment name defined twice"+lf$
  319.       ENDIF
  320.       IF subset!
  321.         er$=er$+"Segment and Subset both specified"+lf$
  322.       ENDIF
  323.       seg$=upr$
  324.     ELSE IF com$="DATA"
  325.       IF seg$>""
  326.         er$=er$+"Segment and Data both specified"+lf$
  327.       ENDIF
  328.       IF subset!
  329.         er$=er$+"Data and Subset both specified"+lf$
  330.       ENDIF
  331.       dat!=-1
  332.     ELSE IF com$="FILE"
  333.       IF INSTR(upr$," ")=0
  334.         er$=er$+"Node number for producer of File "+upr$+" is not present"+lf$
  335.       ENDIF
  336.       node$=MID$(upr$,INSTR(upr$," ")+1)
  337.       IF INSTR(node$," ")
  338.         styp$=MID$(node$,INSTR(node$," ")+1)
  339.         node$=LEFT$(node$,INSTR(node$," ")-1)
  340.       ENDIF
  341.       par$=LEFT$(par$,INSTR(upr$," ")-1)
  342.       IF INSTR(styp$,"!")
  343.         pw!(nsegs&)=-1
  344.         IF INSTR(upr$,"*")
  345.           er$=er$+"Pure data file "+par$+" cannot have a password"+lf$
  346.         ENDIF
  347.         pw$=MID$(styp$,INSTR(styp$,"!")+1)
  348.         styp$=TRIM$(LEFT$(styp$,INSTR(styp$,"!")-1))
  349.       ELSE
  350.         pw!(nsegs&)=0
  351.         pw$="Zone"
  352.         IF LEFT$(styp$)="R"
  353.           pw$="Region"
  354.         ELSE IF LEFT$(styp$)="N"
  355.           pw$="Host"
  356.         ELSE IF LEFT$(styp$)="H"
  357.           pw$="Hub"
  358.         ELSE
  359.           pw$=""
  360.         ENDIF
  361.       ENDIF
  362.       IF (INSTR("ZRNH",LEFT$(styp$))=0 OR VAL(MID$(styp$,2))=0) AND styp$>""
  363.         er$=er$+"Type of File "+par$+" is not specified correctly"+lf$
  364.       ENDIF
  365.       FOR i%=0 TO nsegs&
  366.         IF seg$(i%)=UPPER$(par$)
  367.           er$=er$+"Remote segment "+par$+" defined twice"+lf$
  368.         ENDIF
  369.       NEXT i%
  370.       seg$(nsegs&)=UPPER$(par$)
  371.       node$(nsegs&)=node$
  372.       typ$(nsegs&)=styp$
  373.       pw$(nsegs&)=pw$
  374.       INC nsegs&
  375.     ELSE IF com$="SUBSET"
  376.       IF subset!
  377.         er$=er$+"Subset statement defined twice"+lf$
  378.       ENDIF
  379.       IF INSTR(upr$," ")=0
  380.         er$=er$+"Subset instruction malformed"+lf$
  381.       ENDIF
  382.       IF seg$>""
  383.         er$=er$+"Segment and Subset both specified"+lf$
  384.       ENDIF
  385.       IF dat!=-1
  386.         er$=er$+"Data and Subset both specified"+lf$
  387.       ENDIF
  388.       subset!=-1
  389.       seg$=LEFT$(upr$,INSTR(upr$," ")-1)
  390.       subset$=MID$(upr$,INSTR(upr$," ")+1)
  391.     ELSE IF com$="MASTER"
  392.       IF mas$>""
  393.         er$=er$+"Master directory defined twice"+lf$
  394.       ENDIF
  395.       mas$=@fullpath$(upr$)
  396.     ELSE IF com$="UPDATE"
  397.       IF upd$>""
  398.         er$=er$+"Update directory defined twice"+lf$
  399.       ENDIF
  400.       upd$=@fullpath$(upr$)
  401.     ELSE IF com$="NODELIST"
  402.       IF nldir$>""
  403.         er$=er$+"Nodelist directory defined twice"+lf$
  404.       ENDIF
  405.       nldir$=@fullpath$(LEFT$(upr$,RINSTR(upr$,"\")))
  406.       nlnam$=MID$(upr$,RINSTR(upr$,"\")+1)
  407.     ELSE IF com$="MERGE"
  408.       IF merge!
  409.         er$=er$+"Merge statement listed twice"
  410.       ENDIF
  411.       merge!=TRUE
  412.     ELSE IF com$="OUTLIST"
  413.       IF olist$>""
  414.         er$=er$+"Output filename for full list specified twice"+lf$
  415.       ENDIF
  416.       olist$=upr$
  417.     ELSE IF com$="OUTDIFF"
  418.       IF odiff$>""
  419.         er$=er$+"Output filename for difference file specified twice"+lf$
  420.       ENDIF
  421.       odiff$=upr$
  422.     ELSE IF com$="PUBLISHDAY"
  423.       IF pubday$>""
  424.         er$=er$+"Publication day specified twice"+lf$
  425.       ENDIF
  426.       SELECT LEFT$(upr$,2)
  427.       CASE "SU"
  428.         pubday$="Sunday"
  429.       CASE "MO"
  430.         pubday$="Monday"
  431.       CASE "TU"
  432.         pubday$="Tuesday"
  433.       CASE "WE"
  434.         pubday$="Wednesday"
  435.       CASE "TH"
  436.         pubday$="Thursday"
  437.       CASE "FR"
  438.         pubday$="Friday"
  439.       CASE "SA"
  440.         pubday$="Saturday"
  441.       DEFAULT
  442.         er$=er$+"Publication day wrongly specified as "+par$+lf$
  443.       ENDSELECT
  444.     ELSE IF com$="PROCESSDAY"
  445.       IF sendday$>""
  446.         er$=er$+"SendDay specified twice"+lf$
  447.       ENDIF
  448.       SELECT LEFT$(upr$,2)
  449.       CASE "SU"
  450.         sendday$="Sunday"
  451.       CASE "MO"
  452.         sendday$="Monday"
  453.       CASE "TU"
  454.         sendday$="Tuesday"
  455.       CASE "WE"
  456.         sendday$="Wednesday"
  457.       CASE "TH"
  458.         sendday$="Thursday"
  459.       CASE "FR"
  460.         sendday$="Friday"
  461.       CASE "SA"
  462.         sendday$="Saturday"
  463.       DEFAULT
  464.         er$=er$+"SendDay wrongly specified as "+par$+lf$
  465.       ENDSELECT
  466.     ELSE IF com$="COPYRIGHT"
  467.       IF copyright$>""
  468.         er$=er$+"Copyright text filename specified twice"+lf$
  469.       ENDIF
  470.       copyright$=upr$
  471.     ELSE IF com$="HEAD"
  472.       IF head$>""
  473.         er$=er$+"Head-end text filename specified twice"+lf$
  474.       ENDIF
  475.       head$=upr$
  476.     ELSE IF com$="TAIL"
  477.       IF tail$>""
  478.         er$=er$+"Tail-end text filename specified twice"+lf$
  479.       ENDIF
  480.       tail$=upr$
  481.     ELSE IF com$="TYPE"
  482.       IF type$>""
  483.         er$=er$+"Two types specified"+lf$
  484.       ENDIF
  485.       SELECT LEFT$(upr$,3)
  486.       CASE "HUB"
  487.         type$="Hub"
  488.       CASE "NET"
  489.         type$="Host"
  490.       CASE "HOS"
  491.         type$="Host"
  492.       CASE "REG"
  493.         type$="Region"
  494.       CASE "ZON"
  495.         type$="Zone"
  496.       CASE "DIS"
  497.         type$="Compound"
  498.       DEFAULT
  499.         type$="Node"
  500.         er$=er$+"Unknown type specifier: "+com$+lf$
  501.       ENDSELECT
  502.       typeval%=VAL(MID$(upr$,INSTR(upr$," ")))
  503.     ELSE IF com$="ADDRESS"
  504.       IF ozone& OR onet& OR onode&
  505.         er$=er$+"Local address defined twice"+lf$
  506.       ENDIF
  507.       IF INSTR(par$,":")=0 OR INSTR(par$,"/")=0
  508.         er$=er$+"Local address malformed: "+par$+lf$
  509.       ENDIF
  510.       ozone&=VAL(par$)
  511.       onet&=VAL(MID$(par$,INSTR(par$,":")+1))
  512.       onode&=VAL(MID$(par$,INSTR(par$,"/")+1))
  513.     ELSE IF com$="SUBMIT"
  514.       IF dzone& OR dnet& OR dnode&
  515.         er$=er$+"Submit address defined twice"+lf$
  516.       ENDIF
  517.       IF INSTR(par$,":")=0 OR INSTR(par$,"/")=0
  518.         er$=er$+"Submit address malformed: "+par$+lf$
  519.       ENDIF
  520.       dzone&=VAL(par$)
  521.       dnet&=VAL(MID$(par$,INSTR(par$,":")+1))
  522.       dnode&=VAL(MID$(par$,INSTR(par$,"/")+1))
  523.       IF INSTR(upr$,"HOLD")
  524.         attr%=913 !Pvt, W/File, K/Snt, Local, Hold
  525.       ELSE IF INSTR(upr$,"CRASH")
  526.         attr%=403 !Pvt, Crash, W/File, K/Snt, Local
  527.       ELSE
  528.         attr%=401 !Pvt, W/File, K/Snt, Local
  529.       ENDIF
  530.     ELSE IF com$="NETMAIL"
  531.       IF netmail$>""
  532.         er$=er$+"Netmail area path defined twice"+lf$
  533.       ENDIF
  534.       netmail$=upr$
  535.     ELSE IF com$="LOGLEVEL"
  536.       IF lgl!
  537.         er$=er$+"LogLevel defined twice"+lf$
  538.       ENDIF
  539.       lgl!=TRUE
  540.       loglevel%=VAL(upr$)
  541.     ELSE IF com$="STATUSLOG"
  542.       IF log$>""
  543.         er$=er$+"StatusLog filename defined twice"+lf$
  544.       ELSE
  545.         log$=@fullpath$(LEFT$(upr$,RINSTR(upr$,"\")))+MID$(upr$,RINSTR(upr$,"\")+1)
  546.         IF EXIST(log$)
  547.           OPEN "A",#9,log$
  548.           PRINT #9
  549.         ELSE
  550.           OPEN "O",#9,log$
  551.         ENDIF
  552.       ENDIF
  553.     ELSE IF com$="CLEANUP"
  554.       IF clean!
  555.         er$=er$+"CleanUp statement defined twice"+lf$
  556.       ENDIF
  557.       clean!=TRUE
  558.     ELSE IF com$="BPS"
  559.       IF bps!
  560.         er$=er$+"BPS list defined twice"+lf$
  561.       ENDIF
  562.       bps!=TRUE
  563.       nbps&=0
  564.       DO WHILE par$>""
  565.         INC nbps&
  566.         bps%=VAL(par$)
  567.         IF INSTR(par$,",")
  568.           par$=MID$(par$,INSTR(par$,",")+1)
  569.         ELSE
  570.           par$=""
  571.         ENDIF
  572.       LOOP
  573.     ELSE IF com$="ARC" OR com$="UNPACK"
  574.       lnum%=ASC(par$)-65
  575.       IF lnum%=3
  576.         er$=er$+"Cannot use D as identifier for archive file"+lf$
  577.       ENDIF
  578.       IF arc$(lnum%,0)>"" OR arc$(lnum%,1)>""
  579.         er$=er$+"Archiver with letter "+CHR$(lnum%+65)+" defined twice"+lf$
  580.       ELSE IF MID$(par$,2,1)<>" "
  581.         er$=er$+"Archive line "+par$+" malformed"+lf$
  582.       ELSE
  583.         par$=MID$(par$,3)
  584.         arc$(lnum%,0)=LEFT$(par$,INSTR(par$," ")-1)
  585.         par$=MID$(par$,INSTR(par$," ")+1)
  586.         arc$(lnum%,1)=par$ !archiver parameters
  587.       ENDIF
  588.     ELSE IF com$="SENDARC" OR com$="PACK"
  589.       IF sendarc&>=0
  590.         er$=er$+"SendArc type defined twice"+lf$
  591.       ELSE
  592.         sendarc&=ASC(upr$)-65
  593.         IF sendarc&=3
  594.           er$=er$+"Cannot use D as identifier for archive file"+lf$
  595.         ENDIF
  596.         par$=TRIM$(MID$(par$,2))
  597.         sendarc$=par$
  598.       ENDIF
  599.     ELSE IF com$="BAD"
  600.       IF bad$>""
  601.         er$=er$+"Bad files path defined twice"+lf$
  602.       ELSE
  603.         bad$=@fullpath$(upr$)
  604.       ENDIF
  605.     ELSE IF com$="CONFREC"
  606.       IF confrec!
  607.         er$=er$+"Confirm receipt level defined twice"+lf$
  608.       ENDIF
  609.       confrec!=TRUE
  610.       upr$=LEFT$(upr$)
  611.       IF upr$="N"
  612.         crcpt%=-2
  613.       ELSE IF upr$="H"
  614.         crcpt%=-1
  615.       ELSE IF upr$="R"
  616.         crcpt%=0
  617.       ELSE IF upr$="C"
  618.         crcpt%=1
  619.       ELSE
  620.         er$=er$+"Confirm receipt level unknown"+lf$
  621.       ENDIF
  622.     ELSE IF com$="CONFERROR"
  623.       IF conferr!
  624.         er$=er$+"Confirm error level defined twice"+lf$
  625.       ENDIF
  626.       conferr!=TRUE
  627.       upr$=LEFT$(upr$)
  628.       IF upr$="N"
  629.         cerr%=-2
  630.       ELSE IF upr$="H"
  631.         cerr%=-1
  632.       ELSE IF upr$="R"
  633.         cerr%=0
  634.       ELSE IF upr$="C"
  635.         cerr%=1
  636.       ELSE
  637.         er$=er$+"Confirm error level unknown"+lf$
  638.       ENDIF
  639.     ELSE IF com$="CONFNOSEG"
  640.       IF confnoseg!
  641.         er$=er$+"Confirm no segment error level defined twice"+lf$
  642.       ENDIF
  643.       confnoseg!=TRUE
  644.       upr$=LEFT$(upr$)
  645.       IF upr$="N"
  646.         cnoseg%=-2
  647.       ELSE IF upr$="H"
  648.         cnoseg%=-1
  649.       ELSE IF upr$="R"
  650.         cnoseg%=0
  651.       ELSE IF upr$="C"
  652.         cnoseg%=1
  653.       ELSE
  654.         er$=er$+"Confirm no segment error level unknown"+lf$
  655.       ENDIF
  656.     ELSE IF com$="BINK"
  657.       IF mailer!
  658.         er$=er$+"Mailer type defined twice"+lf$
  659.       ENDIF
  660.       mailer!=TRUE
  661.       bink!=TRUE
  662.     ELSE IF com$="THE-BOX"
  663.       IF mailer!
  664.         er$=er$+"Mailer type defined twice"+lf$
  665.       ENDIF
  666.       mailer!=TRUE
  667.       bink!=FALSE
  668.     ELSE IF com$="NOCHECK"
  669.       check!=0
  670.     ELSE IF com$="PRIVATE"
  671.       pvtvalid!=0
  672.       pvtlist$=pvtlist$+par$
  673.     ELSE IF com$="NOPRIVATE"
  674.       pvtvalid!=0
  675.     ELSE IF com$="MAXLINE" OR com$="MAXLIST"
  676.       IF maxl!=-1
  677.         er$=er$+"MaxLine parameter defined twice"+lf$
  678.       ENDIF
  679.       maxl!=-1
  680.       maxsize&=VAL(par$)
  681.     ELSE IF com$="EQUALHIER"
  682.       IF equhier!=-1
  683.         er$=er$+"EquHier parameter specified twice"+lf$
  684.       ENDIF
  685.       equhier!=-1
  686.     ELSE IF com$="PASSWORD"
  687.       IF pwd$>""
  688.         er$=er$+"Password specified twice"+lf$
  689.       ENDIF
  690.       pwd$=upr$
  691.     ELSE IF com$="NOBAR"
  692.       IF nobar!=-1
  693.         er$=er$+"NoBar specified twice"+lf$
  694.       ENDIF
  695.       nobar!=-1
  696.     ELSE IF com$="AUTOFILE"
  697.       IF autoarea$>""
  698.         er$=er$+"AutoFile parameter specified twice"+lf$
  699.       ENDIF
  700.       autoarea$=LEFT$(upr$,INSTR(upr$," ")-1)
  701.       autodesc$=MID$(par$,INSTR(par$," ")+1)
  702.       DO WHILE INSTR(autodesc$,"_")
  703.         MID$(autodesc$,INSTR(autodesc$,"_"),1)=" "
  704.       LOOP
  705.     ELSE IF com$="AUTODIFF"
  706.       IF diffarea$>""
  707.         er$=er$+"AutoDiff parameter specified twice"+lf$
  708.       ENDIF
  709.       diffarea$=LEFT$(upr$,INSTR(upr$," ")-1)
  710.       diffdesc$=MID$(par$,INSTR(par$," ")+1)
  711.       DO WHILE INSTR(diffdesc$,"_")
  712.         MID$(diffdesc$,INSTR(diffdesc$,"_"),1)=" "
  713.       LOOP
  714.     ELSE IF com$="AUTOFILEPATH"
  715.       IF afilpath$>""
  716.         er$=er$+"AutoFile Path specified twice"
  717.       ENDIF
  718.       afilpath$=@fullpath$(upr$)
  719.     ENDIF
  720.   LOOP
  721.   CLOSE #0
  722.   aozone&=ozone&
  723.   aonet&=onet&
  724.   aonode&=onode&
  725.   IF typeval%>0
  726.     IF type$="Hub"
  727.       aonode&=typeval%
  728.     ELSE IF type$="Host" OR type$="Region"
  729.       aonet&=typeval%
  730.       aonode&=0
  731.     ELSE IF type$="Zone"
  732.       aozone&=typeval%
  733.       aonet&=typeval%
  734.       aonode&=0
  735.     ENDIF
  736.   ENDIF
  737.   IF sendarc&>-1
  738.     IF arc$(sendarc&,0)=""
  739.       er$=er$+"SendArc type not defined in an Arc statement"+lf$
  740.     ENDIF
  741.   ENDIF
  742.   IF pubday$=""
  743.     pubday$="Friday"
  744.   ENDIF
  745.   IF pwd$="" AND type$<>"Compound"
  746.     pwd$=type$
  747.   ELSE IF pwd$>"" AND type$="Compound"
  748.     er$=er$+"Password cannot be defined in a Distribution"+lf$
  749.   ELSE IF type$="Compound"
  750.     pwd$=nam$
  751.   ENDIF
  752.   IF loglevel%>0 AND log$=""
  753.     er$=er$+"StatusLog must be specified before LogLevel can be used"+lf$
  754.     loglevel%=0
  755.   ENDIF
  756.   IF iss! AND type$<>"Compound"
  757.     er$=er$+"Issue statement defined for a non-Distribution control"+lf$
  758.   ENDIF
  759.   IF mas$=upd$ AND nsegs&
  760.     er$=er$+"Master directory and Update directory defined as same"+lf$
  761.   ENDIF
  762.   IF type$=""
  763.     er$=er$+"Local nodelist level (Type) undefined"+lf$
  764.   ENDIF
  765.   IF type$="Compound" AND (dzone& OR dnet& OR dnode&)
  766.     er$=er$+"Distribution files are not submitted"+lf$
  767.   ENDIF
  768.   IF mas$=""
  769.     mas$=@fullpath$("")
  770.   ENDIF
  771.   IF upd$="" AND nsegs&
  772.     er$=er$+"Update directory undefined"+lf$
  773.   ENDIF
  774.   IF crcpt%>cerr%
  775.     er$=er$+"ConfReceipt level is greater than ConfError level"+lf$
  776.   ENDIF
  777.   IF sendarc&=-1 AND diff_min%=-1 AND arc_min%>-1 !threshold x for no sendarc
  778.     diff_min%=arc_min%
  779.   ENDIF
  780.   IF debug! AND log$>""
  781.     CLOSE #9
  782.   ENDIF
  783.   IF mailer! AND hold$=""
  784.     er$=er$+"Mailer specified without a Hold directory"+lf$
  785.   ELSE IF bink!
  786.     d$="."+HEX$(dzone&,3)
  787.     IF FSFIRST(LEFT$(hold$,LEN(hold$)-1)+d$,16)
  788.       d$=""
  789.     ENDIF
  790.     hold$=LEFT$(hold$,LEN(hold$)-1)+d$+"\"
  791.   ENDIF
  792.   IF mailer! AND ozone&=0
  793.     er$=er$+"Mailer specified without a Submit address"+lf$
  794.   ENDIF
  795.   IF diffarea$>"" AND odiff$=""
  796.     er$=er$+"AutoDiff specified without OutDiff"+lf$
  797.   ENDIF
  798.   log("+begin, MakeDiff-ST "+ver$+", "+STR$(FRE(0))+" bytes free")
  799.   IF er$>""
  800.     error(er$)
  801.   ENDIF
  802.   IF hold$=""
  803.     hold$=mas$
  804.   ENDIF
  805.   IF NOT confnoseg!
  806.     cnoseg%=crcpt%
  807.   ENDIF
  808. RETURN
  809. ' search for new nodelist segments and nodediff segments received
  810. > PROCEDURE inpnew
  811.   log(">Searching inbound for updated files")
  812.   FOR i%=0 TO nsegs&-1
  813.     oldfile_len%=0
  814.     cntinue!=-1
  815.     da!=FALSE
  816.     IF INSTR(node$(i%),"*") OR NOT @generic(seg$(i%))
  817.       IF FSFIRST(inb$+seg$(i%),0)>=0
  818.         ' this file should be copied into the update folder
  819.         from$=seg$(i%)
  820.         diff!=0
  821.         log(":List file "+inb$+from$+" found, processing")
  822.         report$="Nodelist segment "+from$+" received"
  823.       ELSE
  824.         cntinue!=0
  825.       ENDIF
  826.       IF INSTR(node$(i%),"*")
  827.         da!=TRUE
  828.       ENDIF
  829.     ELSE
  830.       cntinue!=0
  831.       x%=FSFIRST(inb$+seg$(i%)+".*",0)
  832.       DO UNTIL x%
  833.         from$=CHAR{dta%+30}
  834.         ext$=MID$(from$,INSTR(from$,".")+1)
  835.         IF ext$=daynxt$
  836.           ' this file should be copied into the update folder
  837.           diff!=0
  838.           report$="Nodelist segment "+from$+" received"
  839.           x%=1
  840.           cntinue!=-1
  841.           log(":List file "+inb$+from$+" found, processing")
  842.         ELSE IF ext$=daylst$
  843.           ' this file should have been here last week! copy it to this week's
  844.           ' number into the update folder
  845.           diff!=0
  846.           report$="Nodelist segment "+from$+" received (deadline for day "+daylst$+" passed)"
  847.           x%=1
  848.           cntinue!=-1
  849.           log(":List file "+inb$+from$+" found, processing")
  850.           log(":  (deadline for day "+daylst$+" passed)")
  851.         ELSE IF ext$="D"+RIGHT$(daynxt$,2)
  852.           ' this file is a diff from last week's segment
  853.           diff!=-1
  854.           report$="Nodelist segment difference file "+from$+" received"
  855.           x%=1
  856.           cntinue!=-1
  857.           log(":Diff file "+inb$+from$+" found, processing")
  858.         ELSE IF ext$="D"+RIGHT$(daylst$,2)
  859.           ' this file should have been here last week! apply it to the latest
  860.           ' file, it is a diff
  861.           diff!=-1
  862.           report$="Nodelist segment difference file "+from$+" received (deadline for day "+daylst$+" passed)"
  863.           x%=1
  864.           cntinue!=-1
  865.           log(":Diff file "+inb$+from$+" found, processing")
  866.           log(":  (deadline for day "+daylst$+" passed)")
  867.         ELSE IF RIGHT$(ext$,2)="D"+RIGHT$(daynxt$) OR RIGHT$(ext$,2)="D"+RIGHT$(daylst$) OR RIGHT$(ext$,2)=RIGHT$(daynxt$,2) OR RIGHT$(ext$,2)=RIGHT$(daylst$,2)
  868.           ' this file is an archived diff file from current segment
  869.           ' or it is an archived file for the current segment
  870.           ' file is unarc'ed, and then Fsfirst() is recalled to process the file
  871.           ' that was unpacked
  872.           log(":Archive "+inb$+from$+" found, unpacking")
  873.           archiver%=ASC(ext$)-65
  874.           IF arc$(archiver%,0)=""
  875.             log("!No archiver defined for type "+CHR$(archiver%+65)+" files")
  876.             log("!File "+inb$+from$+" not processed")
  877.             x%=FSNEXT()
  878.           ELSE IF EXIST(arc$(archiver%,0))
  879.             arc$=arc$(archiver%,1)
  880.             cl$=LEFT$(arc$,INSTR(arc$,"%")-1)
  881.             cl$=cl$+from$
  882.             cl$=cl$+MID$(arc$,INSTR(arc$,"%")+1)
  883.             log("#Calling "+arc$(archiver%,0))
  884.             log(" (Parameters: """+cl$+""")")
  885.             log(">"+STR$(FRE(0)-16384)+" bytes available")
  886.             RESERVE 16384-FRE(0)
  887.             cwd$=@fullpath$("")
  888.             cd(inb$)
  889.             el%=EXEC(0,arc$(archiver%,0),CHR$(LEN(cl$))+cl$,env$)
  890.             cd(cwd$)
  891.             RESERVE
  892.             log(">Errorlevel exit "+STR$(el%))
  893.             KILL inb$+from$
  894.             log(" "+inb$+from$+" deleted")
  895.             x%=FSFIRST(inb$+seg$(i%)+".*",0)
  896.           ELSE
  897.             log("!Archiver "+arc$(archiver%,0)+" does not exist")
  898.           ENDIF
  899.         ELSE
  900.           x%=FSNEXT()
  901.         ENDIF
  902.       LOOP
  903.     ENDIF
  904.     IF cntinue!
  905.       report$=report$+CHR$(10)+CHR$(10)+"Error analysis:"+CHR$(10)+CHR$(10)
  906.       nerrs%=0
  907.       IF diff!
  908.         IF EXIST(mas$+seg$(i%)+"."+daylst$)
  909.           OPEN "I",#0,mas$+seg$(i%)+"."+daylst$
  910.           log("#  Original file "+mas$+seg$(i%)+"."+daylst$+" used")
  911.           OPEN "O",#2,upd$+seg$(i%)+"."+daynxt$
  912.           OPEN "I",#1,inb$+from$
  913.           ' now #0 is the original, #1 is the diff and #2 will be the new file
  914.           lin1f$=@in$(0)
  915.           oldfile_crc%=VAL(MID$(lin1f$,LEN(lin1f$)-5))
  916.           oldfile_len%=LOF(#0)
  917.           lin1t$=@in$(1)
  918.           lin1fa$=LEFT$(lin1f$,INSTR(lin1f$,"Nodelist for ")+13)+datlst$+" -- Day number "+daylst$+" : "+MID$(lin1f$,RINSTR(lin1f$," : ")+3)
  919.           SEEK #0,0
  920.           IF lin1f$<>lin1t$ AND lin1fa$<>lin1t$
  921.             log("!  Diff does not match to our segment")
  922.             report$=report$+"- This difference file does not match to our master copy"+CHR$(10)
  923.             INC nerrs%
  924.           ELSE
  925.             log("#  Writing "+upd$+seg$(i%)+"."+daynxt$)
  926.             status("Constructing new segment")
  927.             timebar(0)
  928.             DO UNTIL EOF(#1)
  929.               timebar(LOC(#1)/LOF(#1))
  930.               x$=@in$(1)
  931.               IF LEFT$(x$)="D"
  932.                 FOR j%=1 TO VAL(MID$(x$,2))
  933.                   x$=@in$(0)
  934.                 NEXT j%
  935.               ELSE IF LEFT$(x$)="C"
  936.                 FOR j%=1 TO VAL(MID$(x$,2))
  937.                   x$=@in$(0)
  938.                   PRINT #2,x$
  939.                 NEXT j%
  940.               ELSE IF LEFT$(x$)="A"
  941.                 FOR j%=1 TO VAL(MID$(x$,2))
  942.                   x$=@in$(1)
  943.                   PRINT #2,x$
  944.                 NEXT j%
  945.               ENDIF
  946.             LOOP
  947.             timebar(1)
  948.           ENDIF
  949.           OUT #2,&H1A
  950.           CLOSE #0
  951.           CLOSE #1
  952.           CLOSE #2
  953.         ELSE
  954.           log("!  File "+mas$+seg$(i%)+"."+daylst$+" doesn't exist!")
  955.           report$=report$+"- This system does not have "+seg$(i%)+"."+daylst$+", please send a copy of your full segment (it can be found in your Master directory)"+CHR$(10)
  956.           INC nerrs%
  957.         ENDIF
  958.       ELSE IF da!
  959.         ' This is a file written by a human
  960.         log("#Pure data file "+inb$+from$)
  961.         OPEN "I",#0,inb$+from$
  962.         IF @generic(seg$(i%))
  963.           OPEN "O",#1,upd$+seg$(i%)+"."+daynxt$
  964.         ELSE
  965.           OPEN "O",#1,upd$+seg$(i%)
  966.         ENDIF
  967.         lnew%=0
  968.         status("Constructing new segment")
  969.         timebar(0)
  970.         DO UNTIL EOF(#0)
  971.           INC lnew%
  972.           x$=@in$(0)
  973.           IF x$<>eof$
  974.             timebar(LOC(#0)/LOF(#0))
  975.             nnew$(lnew%)=x$
  976.             IF lnew%=1 AND MID$(node$(i%),INSTR(node$(i%)," ")+1,1)<>"H" AND nnew$(1)<>";"
  977.               nnew$(2)=nnew$(1)
  978.               nnew$(1)=";"
  979.             ENDIF
  980.           ENDIF
  981.         LOOP
  982.         timebar(1)
  983.         SELECT MID$(node$(i%),INSTR(node$(i%)," ")+1,1)
  984.         CASE "Z"
  985.           x$="Zone"
  986.         CASE "R"
  987.           x$="Region"
  988.         CASE "N"
  989.           x$="Host"
  990.         CASE "H"
  991.           x$="Hub"
  992.         ENDSELECT
  993.         nnew$(0)=";A "+x$+" Nodelist for "+daynxt$+" : "
  994.         status("Calculating CRC")
  995.         timebar(0)
  996.         crc%=0
  997.         FOR i%=1 TO lnew%
  998.           timebar(i%/lnew%)
  999.           x$=nnew$(i%)
  1000.           FOR j%=0 TO LEN(x$)-1
  1001.             crc%=@xcrc(crc%,BYTE{V:x$+j%})
  1002.           NEXT j%
  1003.           crc%=@xcrc(crc%,13)
  1004.           crc%=@xcrc(crc%,10)
  1005.         NEXT i%
  1006.         nnew$(0)=nnew$(0)+RIGHT$("0000"+STR$(crc%),5)
  1007.         log(">CRC = "+STR$(crc%))
  1008.         log(">File written")
  1009.         FOR i%=0 TO lnew%
  1010.           PRINT #1,nnew$(i%)
  1011.         NEXT i%
  1012.         OUT #1,&H1A
  1013.         CLOSE #1
  1014.       ELSE
  1015.         IF @generic(seg$(i%))
  1016.           ~@copy(inb$+from$,upd$+seg$(i%)+"."+daynxt$)
  1017.         ELSE
  1018.           ~@copy(inb$+from$,upd$+seg$(i%))
  1019.         ENDIF
  1020.       ENDIF
  1021.       ' delete file from inbound
  1022.       KILL inb$+from$
  1023.       log("   File "+inb$+from$+" deleted")
  1024.       ' perform CRC check on new file here
  1025.       IF NOT da! !no point if we've made the CRC here!
  1026.         OPEN "I",#0,upd$+seg$(i%)+"."+daynxt$
  1027.         x$=@in$(0)
  1028.         expect_crc%=VAL(MID$(x$,RINSTR(x$," : ")+3))
  1029.         crc%=0
  1030.         status("Checking CRC")
  1031.         timebar(0)
  1032.         DO UNTIL EOF(#0)
  1033.           x$=@in$(0)
  1034.           timebar(LOC(#0)/LOF(#0))
  1035.           IF x$<>eof$
  1036.             FOR j%=0 TO LEN(x$)-1
  1037.               crc%=@xcrc(crc%,BYTE{V:x$+j%})
  1038.             NEXT j%
  1039.             crc%=@xcrc(crc%,13)
  1040.             crc%=@xcrc(crc%,10)
  1041.           ENDIF
  1042.         LOOP
  1043.         CLOSE #0
  1044.         timebar(1)
  1045.         crc%=AND(crc%,&HFFFF)
  1046.         IF crc%<>expect_crc%
  1047.           report$=report$+"- Your submitted nodelist segment does not have a valid CRC"+CHR$(10)
  1048.           INC nerrs%
  1049.           log("!CRC error - "+STR$(crc%)+" calculated, "+STR$(expect_crc%)+" shown in file")
  1050.         ENDIF
  1051.       ENDIF
  1052.       x$=upd$+seg$(i%)
  1053.       IF @generic(seg$(i%))
  1054.         x$=x$+"."+daynxt$
  1055.       ENDIF
  1056.       checkfile(x$,typ$(i%),pw$(i%),pw!(i%))
  1057.       IF nerrs%=0 AND badpvt%=0
  1058.         report$=LEFT$(report$,INSTR(report$,CHR$(10))-1)
  1059.         report$=report$+" and processed OK, the changes should be processed for the "+datnxt$+" nodelist edition (number "+daynxt$+")"
  1060.       ELSE IF nerrs%=1
  1061.         report$=report$+lf$+"1 error found"
  1062.       ELSE
  1063.         report$=report$+lf$+STR$(nerrs%)+" errors found"
  1064.       ENDIF
  1065.       IF badpvt%>0
  1066.         IF badpvt%=1
  1067.           report$=report$+lf$+"1 unauthorised private node found"
  1068.         ELSE
  1069.           report$=report$+lf$+STR$(badpvt%)+" unauthorised private nodes found"
  1070.         ENDIF
  1071.       ENDIF
  1072.       IF nerrs%
  1073.         report$=report$+" - please send a copy of the full nodelist segment, until an error-free update is received the old copy will be used"
  1074.         x$=seg$(i%)
  1075.         IF @generic(seg$(i%))
  1076.           x$=x$+"."+daynxt$
  1077.         ENDIF
  1078.         IF bad$>""
  1079.           ~@move(upd$+x$,bad$+x$)
  1080.         ENDIF
  1081.       ENDIF
  1082.       IF nerrs%=0
  1083.         x$=from$+" received - OK"
  1084.         x%=crcpt%
  1085.       ELSE
  1086.         x$="Request for "+seg$(i%)
  1087.         x%=cerr%
  1088.       ENDIF
  1089.       IF x%=1
  1090.         send_crashmail(node$(i%),x$,report$)
  1091.       ELSE IF x%=0
  1092.         send_netmail(node$(i%),x$,report$)
  1093.       ELSE IF x%=-1
  1094.         send_holdmail(node$(i%),x$,report$)
  1095.       ENDIF
  1096.     ENDIF
  1097.   NEXT i%
  1098. RETURN
  1099. > PROCEDURE skipspc(VAR cl$)
  1100.   DO WHILE LEFT$(cl$)=" "
  1101.     cl$=MID$(cl$,2)
  1102.   LOOP
  1103. RETURN
  1104. > PROCEDURE error(er$)
  1105.   log("!Errors in control file as follows:")
  1106.   DO WHILE INSTR(er$,CHR$(10))
  1107.     log("!  "+LEFT$(er$,INSTR(er$,CHR$(10))-1))
  1108.     er$=MID$(er$,INSTR(er$,CHR$(10))+1)
  1109.   LOOP
  1110.   fin(255)
  1111. RETURN
  1112. ' finish program execution
  1113. > PROCEDURE fin(retcode%)
  1114.   ~MFREE(addr%)
  1115.   IF NOT nobar!
  1116.     DPOKE L~A-42,origlines&
  1117.   ENDIF
  1118.   log("+end, MakeDiff-ST "+ver$+", Exit with errorlevel "+STR$(retcode%))
  1119.   ~XBIOS(21,1,0)
  1120.   ~XBIOS(21,2,0)
  1121.   CLOSE #9
  1122.   IF dist!
  1123.     SYSTEM retcode%
  1124.   ELSE
  1125.     END
  1126.   ENDIF
  1127. RETURN
  1128. > PROCEDURE nrerror(x$)
  1129.   PRINT x$
  1130.   fin(-1)
  1131. RETURN
  1132. > PROCEDURE brk
  1133.   ON BREAK CONT
  1134.   fin(250)
  1135. RETURN
  1136. > PROCEDURE addlist(f$)
  1137.   LOCAL x%
  1138.   IF EXIST(f$)
  1139.     OPEN "I",#0,f$
  1140.     DO
  1141.       nnew$(lnew%)=@in$(0)
  1142.       IF nnew$(lnew%)<>eof$
  1143.         INC lnew%
  1144.       ENDIF
  1145.     LOOP UNTIL EOF(#0)
  1146.     CLOSE #0
  1147.   ENDIF
  1148. RETURN
  1149. > PROCEDURE addlistnocom(f$)
  1150.   LOCAL x%
  1151.   IF EXIST(f$)
  1152.     OPEN "I",#0,f$
  1153.     DO
  1154.       nnew$(lnew%)=@in$(0)
  1155.       IF LEFT$(nnew$(lnew%),5)="Host," OR LEFT$(nnew$(lnew%),7)="Region," OR LEFT$(nnew$(lnew%),5)="Zone,"
  1156.         nnew$(lnew%+1)=nnew$(lnew%)
  1157.         nnew$(lnew%)=";"
  1158.         INC lnew%
  1159.       ENDIF
  1160.       IF nnew$(lnew%)<>eof$ AND LEFT$(nnew$(lnew%))<>";"
  1161.         INC lnew%
  1162.       ENDIF
  1163.     LOOP UNTIL EOF(#0)
  1164.     CLOSE #0
  1165.   ENDIF
  1166. RETURN
  1167. > PROCEDURE nmsend(oz%,one%,ono%,dz%,dne%,dno%,fr$,to$,sb$,flags%,txt$)
  1168.   netmail!=-1
  1169.   ' attr : bit  0 -> Private
  1170.   '             1 -> Crash
  1171.   '             2 -> Recv
  1172.   '             3 -> Sent
  1173.   '             4 -> With File
  1174.   '             5 -> Forwarded
  1175.   '             6 -> Orphan
  1176.   '             7 -> Kill/Sent
  1177.   '             8 -> Local
  1178.   '             9 -> Hold
  1179.   '            15 -> Deleted
  1180.   LOCAL op%,dp%
  1181.   op%=0
  1182.   dp%=0
  1183.   DO WHILE RIGHT$(txt$)=lf$
  1184.     txt$=LEFT$(txt$,LEN(txt$)-1)
  1185.   LOOP
  1186.   txt$=txt$+lf$+lf$+"--- MakeDiff "+ver$
  1187.   IF reg!
  1188.     txt$=txt$+" (Registered)"
  1189.   ELSE
  1190.     txt$=txt$+" (Unregistered)"
  1191.   ENDIF
  1192.   txt$=txt$+CHR$(0)
  1193.   IF EXIST(netmail$+".HDR")
  1194.     OPEN "A",#0,netmail$+".HDR"
  1195.   ELSE
  1196.     OPEN "O",#0,netmail$+".HDR"
  1197.   ENDIF
  1198.   IF EXIST(netmail$+".MSG")
  1199.     OPEN "A",#1,netmail$+".MSG"
  1200.   ELSE
  1201.     OPEN "O",#1,netmail$+".MSG"
  1202.   ENDIF
  1203.   tofile(fr$,36)
  1204.   tofile(to$,36)
  1205.   tofile(sb$,72)
  1206.   tofile(LEFT$(@dat$,3)+" "+LEFT$(DATE$,2)+" "+LEFT$(m$(VAL(MID$(DATE$,4))-1),3)+" "+RIGHT$(DATE$,2)+" "+LEFT$(TIME$,5),20)
  1207.   x%=@stamp
  1208.   OUT #0,x%\256\256\256,x%\256\256,x%\256,x%
  1209.   x%=LOF(#1)
  1210.   OUT #0,x%\256\256\256,x%\256\256,x%\256,x%
  1211.   OUT #0,0,0,0,0
  1212.   OUT #0,flags%\256,flags%
  1213.   OUT #0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  1214.   OUT #0,LEN(txt$)\256,LEN(txt$)
  1215.   OUT #0,0,0,0,0
  1216.   OUT #0,oz%\256,oz%,one%\256,one%,ono%\256,ono%,op%\256,op%
  1217.   OUT #0,dz%\256,dz%,dne%\256,dne%,dno%\256,dno%,dp%\256,dp%
  1218.   FOR i%=0 TO LEN(txt$)-1
  1219.     OUT #1,BYTE{V:txt$+i%}
  1220.   NEXT i%
  1221.   CLOSE #0
  1222.   CLOSE #1
  1223. RETURN
  1224. > PROCEDURE send_holdmail(node$,subj$,text$) !sent Pvt K/Snt Local Hold
  1225.   LOCAL x$,x%,i%,dzone&,dnet&,dnode&
  1226.   dzone&=VAL(node$)
  1227.   dnet&=VAL(MID$(node$,INSTR(node$,":")+1))
  1228.   dnode&=VAL(MID$(node$,INSTR(node$,"/")+1))
  1229.   nmsend(ozone&,onet&,onode&,dzone&,dnet&,dnode&,"MakeDiff","Coordinator",subj$,897,text$)
  1230.   log("#Report netmail held for "+node$)
  1231. RETURN
  1232. > PROCEDURE send_netmail(node$,subj$,text$) !sent Pvt K/Snt Local
  1233.   LOCAL x$,x%,i%,dzone&,dnet&,dnode&
  1234.   dzone&=VAL(node$)
  1235.   dnet&=VAL(MID$(node$,INSTR(node$,":")+1))
  1236.   dnode&=VAL(MID$(node$,INSTR(node$,"/")+1))
  1237.   nmsend(ozone&,onet&,onode&,dzone&,dnet&,dnode&,"MakeDiff","Coordinator",subj$,385,text$)
  1238.   log("#Report netmail routed to "+node$)
  1239. RETURN
  1240. > PROCEDURE send_crashmail(node$,subj$,text$) !sent Pvt K/Snt Local Crash
  1241.   LOCAL x$,x%,i%,dzone&,dnet&,dnode&
  1242.   dzone&=VAL(node$)
  1243.   dnet&=VAL(MID$(node$,INSTR(node$,":")+1))
  1244.   dnode&=VAL(MID$(node$,INSTR(node$,"/")+1))
  1245.   nmsend(ozone&,onet&,onode&,dzone&,dnet&,dnode&,"MakeDiff","Coordinator",subj$,387,text$)
  1246.   log("#Report netmail crashed to "+node$)
  1247. RETURN
  1248. > PROCEDURE send(subject$,oz%,one%,ono%,dz%,dne%,dno%)
  1249.   LOCAL x$,x%,i%,d$,in!
  1250.   IF autoarea$>""
  1251.   ELSE IF mailer!
  1252.     IF bink!
  1253.       d$=hold$+HEX$(dne%,4)+HEX$(dno%,4)+"."
  1254.       IF attr% AND 2
  1255.         d$=d$+"C"
  1256.       ELSE IF attr% AND 512
  1257.         d$=d$+"H"
  1258.       ELSE
  1259.         d$=d$+"F"
  1260.       ENDIF
  1261.       d$=d$+"LO"
  1262.       IF EXIST(d$)
  1263.         in!=0
  1264.         OPEN "U",#0,d$
  1265.         DO UNTIL EOF(#0)
  1266.           x$=@in$(0)
  1267.           IF LEFT$(x$)="^"
  1268.             x$=MID$(x$,2)
  1269.           ENDIF
  1270.           IF UPPER$(LEFT$(x$,LEN(subject$)))=UPPER$(subject$)
  1271.             in!=-1
  1272.           ENDIF
  1273.         LOOP UNTIL in!
  1274.         IF NOT in!
  1275.           IF LEFT$(subject$,LEN(mas$))<>mas$
  1276.             PRINT #0,"^";
  1277.           ENDIF
  1278.           PRINT #0,subject$;" ; Nodelist segment update for ";STR$(dz%);":";STR$(dne%);"/";STR$(dno%)
  1279.         ENDIF
  1280.         CLOSE #0
  1281.       ELSE
  1282.         OPEN "O",#0,d$
  1283.         IF LEFT$(subject$,LEN(mas$))<>mas$
  1284.           PRINT #0,"^";
  1285.         ENDIF
  1286.         PRINT #0,subject$;" ; Nodelist segment update for ";STR$(dz%);":";STR$(dne%);"/";STR$(dno%)
  1287.         CLOSE #0
  1288.       ENDIF
  1289.     ELSE
  1290.       d$=hold$+@base36$(dz%,2)+@base36$(dne%,3)+@base36$(dno%,3)+"."
  1291.       IF attr% AND 2
  1292.         d$=d$+"I"
  1293.       ELSE IF attr% AND 512
  1294.         d$=d$+"H"
  1295.       ELSE
  1296.         d$=d$+"I"
  1297.       ENDIF
  1298.       d$=d$+"F"
  1299.       IF EXIST(d$)
  1300.         in!=0
  1301.         OPEN "U",#0,d$
  1302.         DO UNTIL EOF(#0)
  1303.           x$=@in$(0)
  1304.           IF LEFT$(x$)="."
  1305.             x$=MID$(x$,2)
  1306.           ENDIF
  1307.           IF UPPER$(LEFT$(x$,LEN(subject$)))=UPPER$(subject$)
  1308.             in!=-1
  1309.           ENDIF
  1310.         LOOP UNTIL in!
  1311.         IF NOT in!
  1312.           IF LEFT$(subject$,LEN(mas$))<>mas$
  1313.             PRINT #0,".";
  1314.           ENDIF
  1315.           PRINT #0,subject$
  1316.         ENDIF
  1317.         CLOSE #0
  1318.       ELSE
  1319.         OPEN "O",#0,d$
  1320.         IF LEFT$(subject$,LEN(mas$))<>mas$
  1321.           PRINT #0,".";
  1322.         ENDIF
  1323.         PRINT #0,subject$
  1324.         CLOSE #0
  1325.       ENDIF
  1326.       CLOSE #0
  1327.     ENDIF
  1328.     log(":File sent to "+STR$(dz%)+":"+STR$(dne%)+"/"+STR$(dno%))
  1329.   ELSE
  1330.     IF type$="Hub"
  1331.       x$="Net Coordinator"
  1332.     ELSE IF type$="Host"
  1333.       x$="Region Coordinator"
  1334.     ELSE IF type$="Region"
  1335.       x$="Zone Coordinator"
  1336.     ELSE
  1337.       x$="International Coordinator"
  1338.     ENDIF
  1339.     txt$="Nodelist Segment Update File"+CHR$(10)+CHR$(10)
  1340.     txt$=txt$+"Segment "
  1341.     IF difsize%>0
  1342.       txt$=txt$+"difference file "
  1343.     ENDIF
  1344.     txt$=txt$+"for list issue date "+datnxt$+CHR$(10)
  1345.     txt$=txt$+"Filename = "+MID$(subject$,RINSTR(subject$,"\")+1)+CHR$(10)
  1346.     IF difsize%>0
  1347.       txt$=txt$+"Size     = (Diff = "+STR$(difsize%)+", Full Segment = "+STR$(size%)+")"
  1348.     ELSE
  1349.       txt$=txt$+"Size     = "+STR$(size%)+CHR$(10)
  1350.     ENDIF
  1351.     txt$=txt$+"CRC      = "+STR$(crc%)
  1352.     nmsend(oz%,one%,ono%,dz%,dne%,dno%,"MakeDiff",x$,subject$,attr%,txt$)
  1353.     log(":File attach sent to "+STR$(dz%)+":"+STR$(dne%)+"/"+STR$(dno%))
  1354.   ENDIF
  1355. RETURN
  1356. > PROCEDURE tofile(s$,l%)
  1357.   FOR i%=1 TO LEN(s$)
  1358.     OUT #0,ASC(MID$(s$,i%))
  1359.   NEXT i%
  1360.   FOR i%=1 TO l%-LEN(s$)
  1361.     OUT #0,0
  1362.   NEXT i%
  1363. RETURN
  1364. > PROCEDURE makediff
  1365.   LOCAL cold%,cnew%,c%,d%,ad!,i%,j%,t%,index&,cpb%,s1%,s2%
  1366.   ' variables:
  1367.   ' cold     = current line in old list
  1368.   ' cnew     = current line in new list
  1369.   ' cdif     = current line in diff
  1370.   ' lold     = length of old list in lines
  1371.   ' lnew     = length of new list in lines
  1372.   ' nold$()  = old nodelist line
  1373.   ' nnew$()  = new nodelist line
  1374.   ' ndif$()  = diff line
  1375.   ' index&() = index to line in old nodelist that is in new nodelist
  1376.   ' pb&()    = index to first entry in sequenced table
  1377.   ' npb      = number of blocks
  1378.   cold%=0
  1379.   cnew%=0
  1380.   cdif%=1
  1381.   ndif$(0)=nold$(0)
  1382.   npb%=1
  1383.   c%=0
  1384.   pb&(0)=0
  1385.   status("Computing difference information, First pass")
  1386.   timebar(0)
  1387.   log(">Block 1 starts at NL 1")
  1388.   ' The first pass detects lines that are in both nold$() and nnew$(). It
  1389.   ' attempts to get lines in as sequential an order as possible. It also creates
  1390.   ' a number of parameter blocks, as follows:
  1391.   FOR i%=0 TO lnew%-1
  1392.     timebar(i%/lnew%)
  1393.     j%=0
  1394.     index&=-1
  1395.     IF RIGHT$(nnew$(i%))<>CHR$(1)
  1396.       DO WHILE index&=-1
  1397.         INC j%
  1398.         IF nold$((j%+c%) MOD lold%)=nnew$(i%)
  1399.           index&=(j%+c%) MOD lold%
  1400.         ENDIF
  1401.       LOOP UNTIL j%=lold%
  1402.       IF index&>-1 AND index&<=c%
  1403.         pb&(npb%)=i%
  1404.         INC npb%
  1405.         log(">Block "+STR$(npb%)+" starts at NL "+STR$(pb&(npb%-1)+1))
  1406.       ENDIF
  1407.     ENDIF
  1408.     IF index&>-1
  1409.       c%=index&
  1410.       log(">NL "+STR$(i%+1)+"=OL "+STR$(c%+1))
  1411.     ENDIF
  1412.     index&(i%)=index&
  1413.     IF index&(i%)=-1
  1414.       IF RIGHT$(nnew$(i%))=CHR$(1)
  1415.         log(">NL "+STR$(i%+1)+"=copyright text")
  1416.       ELSE
  1417.         log(">NL "+STR$(i%+1)+"=new")
  1418.       ENDIF
  1419.     ENDIF
  1420.   NEXT i%
  1421.   timebar(1)
  1422.   pb&(npb%)=lnew%
  1423.   ' We now have to determine which entries are best [A]dded or [C]opied, by the
  1424.   ' number of parameter blocks; e.g. take the following situation:
  1425.   ' Line 1 replicated in old line 1 (65 bytes)
  1426.   ' Line 2 replicated in old line 4 (57 bytes)
  1427.   ' Line 3 replicated in old line 5 (78 bytes)
  1428.   ' Line 4 replicated in old line 2 (86 bytes)
  1429.   ' Line 5 replicated in old line 3 (67 bytes)
  1430.   ' Line 6 replicated in old line 6 (77 bytes)
  1431.   ' Would it be best to copy the first line from the old list, skip the next
  1432.   ' two, and copy the next two, add the next two as complete lines, and copy
  1433.   ' line 6, or to copy the first line, add the next two, copy the next two
  1434.   ' lines from the old list, skip the next two and add the last line? A size
  1435.   ' analysis shows that:
  1436.   ' Case 1 will take 4+4+4+88+69+4 = 173 bytes
  1437.   ' Case 2 will take 4+59+80+4+4+4 = 155 bytes
  1438.   ' In this case, case 2 would be preferable, and it is up to the routine to
  1439.   ' sort this out. There are two possible cases per npb.
  1440.   status("Computing difference information, Second pass")
  1441.   timebar(0)
  1442.   cpb%=1
  1443.   DO UNTIL cpb%+1>npb%
  1444.     timebar((cpb%+1)/npb%)
  1445.     log(">Smoothing blocks "+STR$(cpb%)+" and "+STR$(cpb%+1))
  1446.     indexmin%=index&(pb&(cpb%)) !this would be 2 in above case
  1447.     indexmax%=-1
  1448.     i%=1
  1449.     DO UNTIL indexmax%>-1
  1450.       indexmax%=index&(pb&(cpb%)-i%) !this would be 5 in above case
  1451.       INC i%
  1452.     LOOP
  1453.     log(">Block "+STR$(cpb%)+" ends with OL "+STR$(indexmax%+1))
  1454.     log(">Block "+STR$(cpb%+1)+" starts with OL "+STR$(indexmin%+1))
  1455.     ' Find the number of lines that could be copied between block cpb-1 and
  1456.     ' block cpb+1 (or end of list) in both possible cases, and we use the type
  1457.     ' which produces the higher number
  1458.     c1%=0
  1459.     c2%=0
  1460.     cm%=1
  1461.     p2%=pb&(cpb%)
  1462.     i%=p2%-1
  1463.     DO WHILE index&(i%)>=indexmin% OR index&(i%)=-1
  1464.       IF index&(i%)<>-1
  1465.         ADD c1%,LEN(nnew$(i%))
  1466.       ENDIF
  1467.       DEC i%
  1468.     LOOP
  1469.     p1%=i%+1
  1470.     i%=p2%
  1471.     DO WHILE index&(i%)<=indexmax%
  1472.       IF index&(i%)<>-1
  1473.         ADD c2%,LEN(nnew$(i%))
  1474.       ENDIF
  1475.       INC i%
  1476.     LOOP
  1477.     p3%=i%-1
  1478.     log(">Upper lines in Diff:S="+STR$(c1%))
  1479.     log(">Lower lines in Diff:S="+STR$(c2%))
  1480.     IF c1%>c2%
  1481.       log(">Upper lines copied, lower lines added")
  1482.       log(">NL "+STR$(p1%+1)+" to "+STR$(p2%)+":copy")
  1483.       log(">NL "+STR$(p2%+1)+" to "+STR$(p3%+1)+":add")
  1484.       FOR i%=p2% TO p3%
  1485.         index&(i%)=-1
  1486.       NEXT i%
  1487.       DO WHILE pb&(cpb%+1)<p3%+1
  1488.         INC cpb%
  1489.       LOOP
  1490.     ELSE
  1491.       log(">Upper lines added, lower lines copied")
  1492.       log(">NL "+STR$(p1%+1)+" to "+STR$(p2%)+":add")
  1493.       log(">NL "+STR$(p2%+1)+" to "+STR$(p3%+1)+":copy")
  1494.       FOR i%=p1% TO p2%-1
  1495.         index&(i%)=-1
  1496.       NEXT i%
  1497.     ENDIF
  1498.     INC cpb%
  1499.   LOOP
  1500.   timebar(1)
  1501.   log(">Final pass, creating diff")
  1502.   cdif%=1
  1503.   cold%=0
  1504.   cnew%=0
  1505.   ndif$(0)=nold$(0)
  1506.   status("Computing difference information, Third pass")
  1507.   timebar(0)
  1508.   DO UNTIL cnew%=lnew%
  1509.     timebar(cnew%/lnew%)
  1510.     IF index&(cnew%)=-1 !Add lines
  1511.       n%=0
  1512.       DO WHILE index&(cnew%+n%)=-1
  1513.         INC n%
  1514.       LOOP
  1515.       ndif$(cdif%)="A"+STR$(n%)
  1516.       log(">A"+STR$(n%)+" (OL="+STR$(cold%)+", NL="+STR$(cnew%)+", DL="+STR$(cdif%)+")")
  1517.       FOR i%=0 TO n%-1
  1518.         ndif$(cdif%+i%+1)=nnew$(cnew%+i%)
  1519.         IF RIGHT$(ndif$(cdif%+i%+1))=CHR$(1)
  1520.           ndif$(cdif%+i%+1)=LEFT$(ndif$(cdif%+i%+1),LEN(ndif$(cdif%+i%+1))-1)
  1521.         ENDIF
  1522.       NEXT i%
  1523.       ADD cdif%,n%+1
  1524.       ADD cnew%,n%
  1525.     ENDIF
  1526.     IF cnew%<lnew%
  1527.       IF index&(cnew%)>cold% !Delete lines
  1528.         ndif$(cdif%)="D"+STR$(index&(cnew%)-cold%)
  1529.         log(">D"+STR$(index&(cnew%)-cold%)+" (OL="+STR$(cold%)+", NL="+STR$(cnew%)+", DL="+STR$(cdif%)+")")
  1530.         INC cdif%
  1531.         cold%=index&(cnew%)
  1532.       ENDIF
  1533.       n%=0 !Copy lines
  1534.       DO WHILE index&(cnew%+n%)=cold%+n%
  1535.         INC n%
  1536.       LOOP
  1537.       ndif$(cdif%)="C"+STR$(n%)
  1538.       log(">C"+STR$(n%)+" (OL="+STR$(cold%)+", NL="+STR$(cnew%)+", DL="+STR$(cdif%)+")")
  1539.       INC cdif%
  1540.       ADD cold%,n%
  1541.       ADD cnew%,n%
  1542.     ENDIF
  1543.   LOOP
  1544.   timebar(1)
  1545. RETURN
  1546. > PROCEDURE log(l$)
  1547.   LOCAL log!
  1548.   IF log$>""
  1549.     log!=0
  1550.     SELECT LEFT$(l$)
  1551.     CASE "!"
  1552.       log!=loglevel%>0
  1553.     CASE "*"
  1554.       log!=loglevel%>0
  1555.     CASE "+"
  1556.       log!=loglevel%>1
  1557.     CASE ":"
  1558.       log!=loglevel%>2
  1559.     CASE "#"
  1560.       log!=loglevel%>3
  1561.     CASE " "
  1562.       log!=loglevel%>4
  1563.     CASE ">"
  1564.       log!=debug!
  1565.     DEFAULT
  1566.       log!=0
  1567.     ENDSELECT
  1568.     IF LEFT$(l$)<>">"
  1569.       PRINT LEFT$(l$);" ";TIME$;" ";MID$(l$,2);CHR$(27);"K"
  1570.     ELSE
  1571.       status(MID$(l$,2))
  1572.     ENDIF
  1573.     IF log!
  1574.       IF debug!
  1575.         OPEN "A",#9,log$
  1576.       ENDIF
  1577.       PRINT #9,LEFT$(l$);" ";LEFT$(DATE$,2);" ";LEFT$(m$(VAL(MID$(DATE$,4,2))-1),3);" ";TIME$;" MKDF ";MID$(l$,2)
  1578.       IF debug!
  1579.         CLOSE #9
  1580.       ENDIF
  1581.     ENDIF
  1582.   ENDIF
  1583. RETURN
  1584. ' send processing
  1585. > PROCEDURE issueinc
  1586.   log(":Updating Control file issue number")
  1587.   NAME ctl$ AS "$TEMP"
  1588.   OPEN "I",#0,"$TEMP"
  1589.   OPEN "O",#1,ctl$
  1590.   DO UNTIL EOF(#0)
  1591.     lin$=@in$(0)
  1592.     l$=lin$
  1593.     IF INSTR(l$,";")
  1594.       l$=LEFT$(l$,INSTR(l$,";")-1)
  1595.     ENDIF
  1596.     IF UPPER$(LEFT$(l$,5))="ISSUE"
  1597.       i%=7
  1598.       DO UNTIL INSTR("0123456789",MID$(l$,i%,1))
  1599.         INC i%
  1600.       LOOP
  1601.       l$=LEFT$(l$,i%-1)
  1602.       l$=l$+STR$(nlissue%+1)
  1603.       l$=l$+" (updated "+LEFT$(DATE$,2)+" "+LEFT$(m$(VAL(MID$(DATE$,4,2))-1),3)+" "+MID$(DATE$,7)+")"
  1604.       PRINT #1,l$
  1605.     ELSE
  1606.       PRINT #1,lin$
  1607.     ENDIF
  1608.   LOOP
  1609.   CLOSE #0
  1610.   CLOSE #1
  1611.   log("#Modified control file written")
  1612.   KILL "$TEMP"
  1613. RETURN
  1614. > PROCEDURE segment(fil$,c!)
  1615.   ' if c! is set then these are copyright lines
  1616.   OPEN "I",#0,fil$
  1617.   status("Reading "+fil$)
  1618.   timebar(0)
  1619.   DO
  1620.     nnew$(lnew%)=@in$(0)
  1621.     timebar(LOC(#0)/LOF(#0))
  1622.     IF nnew$(lnew%)<>eof$
  1623.       c$=nnew$(lnew%)
  1624.       nnew$(lnew%)=""
  1625.       DO WHILE INSTR(c$,"%")
  1626.         l$=LEFT$(c$,INSTR(c$,"%")-1)
  1627.         r$=MID$(c$,INSTR(c$,"%")+2)
  1628.         SELECT UPPER$(MID$(c$,INSTR(c$,"%")+1,1))
  1629.         CASE "Y"
  1630.           nnew$(lnew%)=nnew$(lnew%)+l$+MID$(DATE$,7)
  1631.         CASE "I"
  1632.           nnew$(lnew%)=nnew$(lnew%)+l$+STR$(nlissue%)
  1633.         CASE "%"
  1634.           nnew$(lnew%)=nnew$(lnew%)+l$+"%"
  1635.         DEFAULT
  1636.           nnew$(lnew%)=nnew$(lnew%)+l$
  1637.         ENDSELECT
  1638.         c$=r$
  1639.       LOOP
  1640.       nnew$(lnew%)=nnew$(lnew%)+c$
  1641.       INC lnew%
  1642.     ENDIF
  1643.     IF c!
  1644.       nnew$(lnew%-1)=nnew$(lnew%-1)+CHR$(1)
  1645.     ENDIF
  1646.   LOOP UNTIL EOF(#0)
  1647.   CLOSE #0
  1648. RETURN
  1649. > PROCEDURE procseg(i%)
  1650.   LOCAL x$,y$,z$
  1651.   IF @generic(seg$(i%))
  1652.     IF clean! AND EXIST(mas$+seg$(i%)+"."+daylst2$)
  1653.       KILL mas$+seg$(i%)+"."+daylst2$
  1654.       log(" Old segment "+mas$+seg$(i%)+"."+daylst2$+" deleted")
  1655.     ENDIF
  1656.   ENDIF
  1657.   IF @nameseg$(i%)=""
  1658.     log("!No file matching segment "+seg$(i%))
  1659.     nm$="The file "+seg$(i%)+" does not currently exist at your coordinator's system. Please send a full update."
  1660.     IF cnoseg%=1
  1661.       send_crashmail(node$(i%),"Request for "+seg$(i%),nm$)
  1662.     ELSE IF cnoseg%=0
  1663.       send_netmail(node$(i%),"Request for "+seg$(i%),nm$)
  1664.     ELSE IF cnoseg%=-1
  1665.       send_holdmail(node$(i%),"Request for "+seg$(i%),nm$)
  1666.     ENDIF
  1667.     IF cerr%>-2
  1668.       log("#Request for "+seg$(i%)+" written to "+node$(i%))
  1669.     ENDIF
  1670.   ELSE
  1671.     addlistnocom(@nameseg$(i%))
  1672.     log("#Segment "+@nameseg$(i%)+" added")
  1673.     IF @generic(seg$(i%))
  1674.       IF @nameseg$(i%)<>mas$+seg$(i%)+"."+daynxt$
  1675.         y$=@nameseg$(i%)
  1676.         IF @copy(y$,mas$+seg$(i%)+"."+daynxt$)=0
  1677.           log("#"+mas$+seg$(i%)+"."+daynxt$+" created")
  1678.           IF LEFT$(y$,LEN(upd$))=upd$
  1679.             KILL y$
  1680.             log(" "+y$+" deleted")
  1681.           ENDIF
  1682.         ELSE
  1683.           log("!Copy failed")
  1684.         ENDIF
  1685.       ENDIF
  1686.     ELSE IF @nameseg$(i%)<>mas$+seg$(i%)
  1687.       IF @copy(@nameseg$(i%),mas$+seg$(i%))=0
  1688.         log("#"+mas$+seg$(i%)+" created")
  1689.         KILL upd$+seg$(i%)
  1690.         log(" "+upd$+seg$(i%)+" deleted")
  1691.       ELSE
  1692.         log("!Copy failed")
  1693.       ENDIF
  1694.     ENDIF
  1695.   ENDIF
  1696. RETURN
  1697. > PROCEDURE check(loc!)
  1698.   ' lnew is updated. nerrs is returned, with number of errors. rpt$ is report.
  1699.   ' lines are replaced if loc!=FALSE (loc! is for local testing)
  1700.   ' badpvt is the number of unauthorised private nodes found
  1701.   LOCAL i%,j%,zone%,net%,node%,xx$
  1702.   zone%=0
  1703.   net%=0
  1704.   node%=0
  1705.   badpvt%=0
  1706.   ARRAYFILL node!(),0
  1707.   ARRAYFILL net!(),0
  1708.   ARRAYFILL zone!(),0
  1709.   rpt$=""
  1710.   i%=1
  1711.   nerrs%=0
  1712.   uppcor%=0
  1713.   timebar(0)
  1714.   status("Checking complete segment for errors")
  1715.   DO WHILE i%<lnew%
  1716.     timebar(i%/lnew%)
  1717.     x$=nnew$(i%)
  1718.     er$=@valid$(x$)
  1719.     nnew$(i%)=x$
  1720.     IF LEFT$(er$,12)="Unauthorised"
  1721.       INC badpvt%
  1722.       log("*Unauthorised Private node commented out")
  1723.       IF loc!
  1724.         log("!Error in line "+STR$(i%)+" of local segment")
  1725.         rpt$=rpt$+"Unauthorised Private node at line "+STR$(i%)+lf$
  1726.       ELSE
  1727.         log("!Unauthorised Private node at line "+STR$(i%-nerrs%-badpvt%))
  1728.         nnew$(i%)=";E "+nnew$(i%)
  1729.         INC i%
  1730.         INC lnew%
  1731.         INSERT nnew$(i%)=";E "+er$
  1732.         FOR j%=1 TO LEN(nnew$(i%))
  1733.           IF ASC(MID$(nnew$(i%),j%))<32 OR ASC(MID$(nnew$(i%),j%))>126
  1734.             MID$(nnew$(i%),j%,1)="?"
  1735.           ENDIF
  1736.         NEXT j%
  1737.       ENDIF
  1738.     ELSE IF er$>""
  1739.       INC nerrs%
  1740.       IF loc!
  1741.         log("!Local Error: "+er$)
  1742.         log("!Error in line "+STR$(i%)+" of local segment")
  1743.         rpt$=rpt$+"Error in line "+STR$(i%)+": "+er$+lf$
  1744.       ELSE
  1745.         log("!Error: "+er$)
  1746.         log("!Error in line "+STR$(i%+1))
  1747.         nnew$(i%)=";E "+nnew$(i%)
  1748.         INC i%
  1749.         INC lnew%
  1750.         INSERT nnew$(i%)=";E "+er$
  1751.         FOR j%=1 TO LEN(nnew$(i%))
  1752.           IF ASC(MID$(nnew$(i%),j%))<32 OR ASC(MID$(nnew$(i%),j%))>126
  1753.             MID$(nnew$(i%),j%,1)="?"
  1754.           ENDIF
  1755.         NEXT j%
  1756.       ENDIF
  1757.       timebar(-1)
  1758.     ENDIF
  1759.     INC i%
  1760.   LOOP
  1761. RETURN
  1762. > PROCEDURE checkfile(fil$,typ$,pw$,pw!)
  1763.   ' check a remote file for errors (in update directory) and report
  1764.   ' append report of errors found to report$
  1765.   ' increment nerrs for each error
  1766.   ' fil$ = file to test (which must exist)
  1767.   ' typ$ = [Z]one/[R]egion/[N]et/[H]ub number or ""
  1768.   ' badpvt is number of unauthorised private nodes
  1769.   LOCAL i%,j%,zone%,net%,node%,x$,xx$
  1770.   zone%=0
  1771.   net%=0
  1772.   node%=0
  1773.   badpvt%=0
  1774.   ARRAYFILL node!(),0
  1775.   ARRAYFILL net!(),0
  1776.   ARRAYFILL zone!(),0
  1777.   rpt$=""
  1778.   i%=1
  1779.   uppcor%=0
  1780.   IF LEFT$(typ$)="H" !Hub files do not need Host entry
  1781.     uppcor%=2
  1782.   ENDIF
  1783.   OPEN "I",#0,fil$
  1784.   x$=@in$(0)
  1785.   IF UPPER$(MID$(x$,4,LEN(pw$)))<>UPPER$(pw$)
  1786.     INC nerrs%
  1787.     IF pw!
  1788.       report$=report$+"- The file submitted had an incorrect password"+lf$
  1789.       log("!Password wrong - remote='"+UPPER$(MID$(x$,4,LEN(pw$)))+"', ours='"+pw$+"'")
  1790.     ELSE
  1791.       report$=report$+"- The file submitted should have been produced by a Type "+pw$+" control file, and should have been passwordless"+lf$
  1792.       log("!Incorrect segment type submitted")
  1793.     ENDIF
  1794.   ENDIF
  1795.   status("Checking segment "+fil$+" for errors")
  1796.   timebar(0)
  1797.   DO UNTIL EOF(#0)
  1798.     INC i%
  1799.     x$=@in$(0)
  1800.     timebar(LOC(#0)/LOF(#0))
  1801.     er$=@valid$(x$)
  1802.     IF LEFT$(er$,12)="Unauthorised"
  1803.       INC badpvt%
  1804.       report$=report$+"- Unauthorised private node in line "+STR$(i%)+lf$
  1805.       log("!Unauthorised private node in line "+STR$(i%))
  1806.     ELSE IF er$>""
  1807.       INC nerrs%
  1808.       report$=report$+"- Error in line "+STR$(i%)+": "+er$+lf$
  1809.       log("!Error in line "+STR$(i%)+": "+er$)
  1810.     ENDIF
  1811.   LOOP
  1812.   SELECT LEFT$(typ$)
  1813.   CASE "Z"
  1814.     line1$="Zone,"
  1815.     invalid$=""
  1816.     IF NOT equhier!
  1817.       invalid$="Zone"
  1818.     ENDIF
  1819.     t$="Zone"
  1820.   CASE "R"
  1821.     line1$="Region,"
  1822.     invalid$="Zone"
  1823.     IF NOT equhier!
  1824.       invalid$=invalid$+"Region"
  1825.     ENDIF
  1826.     t$="Region"
  1827.   CASE "N"
  1828.     line1$="Host,"
  1829.     invalid$="ZoneRegion"
  1830.     IF NOT equhier!
  1831.       invalid$=invalid$+"Host"
  1832.     ENDIF
  1833.     t$="Net"
  1834.   CASE "H"
  1835.     line1$="Hub,"
  1836.     invalid$="ZoneRegionHost"
  1837.     IF NOT equhier!
  1838.       invalid$=invalid$+"Hub"
  1839.     ENDIF
  1840.     t$="Hub"
  1841.   ENDSELECT
  1842.   IF VAL(MID$(typ$,2))>0
  1843.     line1$=line1$+STR$(VAL(MID$(typ$,2)))+","
  1844.   ENDIF
  1845.   IF line1$>""
  1846.     SEEK #0,0
  1847.     valid!=0
  1848.     done!=0
  1849.     DO UNTIL EOF(#0)
  1850.       x$=@in$(0)
  1851.       IF LEFT$(x$)<>";"
  1852.         IF LEFT$(x$,LEN(line1$))=line1$
  1853.           valid!=-1
  1854.         ELSE
  1855.           done!=-1
  1856.         ENDIF
  1857.       ENDIF
  1858.     LOOP UNTIL done! OR valid!
  1859.     IF NOT valid!
  1860.       report$=report$+"- The first entry of a "+t$+" should be a "+LEFT$(line1$,INSTR(line1$,","))+" entry ("""+line1$+"..."")"+lf$
  1861.       log("!First entry of incorrect type")
  1862.       INC nerrs%
  1863.     ELSE
  1864.       DO UNTIL EOF(#0)
  1865.         x$=@in$(0)
  1866.         IF LEFT$(x$)<>";"
  1867.           IF INSTR(invalid$,LEFT$(x$,INSTR(x$,",")-1))
  1868.             report$=report$+"- """+LEFT$(x$,INSTR(x$,",")-1)+""" entries are not allowed in a "+t$
  1869.             report$=report$+lf$
  1870.             log("!Entry type not allowed in segment type")
  1871.             INC nerrs%
  1872.           ENDIF
  1873.         ENDIF
  1874.       LOOP
  1875.     ENDIF
  1876.   ENDIF
  1877.   CLOSE #0
  1878. RETURN
  1879. > PROCEDURE arcdiff
  1880.   LOCAL s$
  1881.   IF type$="Compound" AND @generic(olist$)
  1882.     ' Write nodelist file in Hold directory
  1883.     s$=hold$+olist$+"."+daynxt$
  1884.     log(":Creating nodelist "+s$)
  1885.     OPEN "O",#0,s$
  1886.     FOR i%=0 TO lnew%-1
  1887.       IF RIGHT$(nnew$(i%))=CHR$(1)
  1888.         PRINT #0,LEFT$(nnew$(i%),LEN(nnew$(i%))-1)
  1889.       ELSE
  1890.         PRINT #0,nnew$(i%)
  1891.       ENDIF
  1892.     NEXT i%
  1893.     OUT #0,&H1A
  1894.     CLOSE #0
  1895.     olarc$=olist$+"."+CHR$(sendarc&+65)+MID$(daynxt$,2)
  1896.     IF sendarc&>-1
  1897.       IF EXIST(arc$(sendarc&,0))
  1898.         ' Convert to an archived file
  1899.         cl$=LEFT$(sendarc$,INSTR(sendarc$,"&")-1)
  1900.         cl$=cl$+olarc$
  1901.         cl$=cl$+MID$(sendarc$,INSTR(sendarc$,"&")+1,INSTR(sendarc$,"%")-INSTR(sendarc$,"&")-1)
  1902.         cl$=cl$+olist$+"."+daynxt$
  1903.         cl$=cl$+MID$(sendarc$,INSTR(sendarc$,"%")+1)
  1904.         log("#Calling "+arc$(sendarc&,0))
  1905.         log(" (Parameters: "+cl$+")")
  1906.         x%=FRE(0)-16384
  1907.         log(">"+STR$(x%)+" bytes available")
  1908.         RESERVE -x%
  1909.         cwd$=@fullpath$("")
  1910.         cd(hold$)
  1911.         el%=EXEC(0,arc$(sendarc&,0),CHR$(LEN(cl$))+cl$,env$)
  1912.         RESERVE x%
  1913.         cd(cwd$)
  1914.         log(">Errorlevel exit "+STR$(el%))
  1915.         IF EXIST(hold$+olarc$)
  1916.           s$=hold$+olarc$
  1917.           log("#Archive file "+hold$+olarc$+" created")
  1918.           IF EXIST(hold$+olist$+"."+daynxt$)
  1919.             KILL hold$+olist$+"."+daynxt$
  1920.           ENDIF
  1921.         ELSE
  1922.           log("!Archiver has not produced "+hold$+olarc$)
  1923.         ENDIF
  1924.       ENDIF
  1925.     ENDIF
  1926.     IF autoarea$>""
  1927.       autosend(s$,autoarea$,autodesc$)
  1928.     ENDIF
  1929.   ENDIF
  1930.   IF odiff$=""
  1931.     odiff$=olist$+".D"+MID$(daynxt$,2)
  1932.     oarc$=olist$+"."+CHR$(sendarc&+65)+"D"+RIGHT$(daynxt$)
  1933.   ELSE IF @generic(odiff$)
  1934.     oarc$=odiff$+"."+CHR$(sendarc&+65)+MID$(daynxt$,2)
  1935.     odiff$=odiff$+"."+daynxt$
  1936.   ENDIF
  1937.   sendfile$=hold$+odiff$
  1938.   lold%=0
  1939.   log("#Reading "+mas$+olist$+"."+daylst$)
  1940.   OPEN "I",#0,mas$+olist$+"."+daylst$
  1941.   DO
  1942.     nold$(lold%)=@in$(0)
  1943.     IF nold$(lold%)<>eof$
  1944.       INC lold%
  1945.     ENDIF
  1946.   LOOP UNTIL EOF(#0)
  1947.   CLOSE #0
  1948.   diff!=-1
  1949.   log(":Creating difference file "+hold$+odiff$)
  1950.   makediff
  1951.   OPEN "O",#0,hold$+odiff$
  1952.   FOR i%=0 TO cdif%-1
  1953.     PRINT #0,ndif$(i%)
  1954.   NEXT i%
  1955.   difsize%=LOF(#0)
  1956.   CLOSE #0
  1957.   log(">LOF = "+STR$(difsize%))
  1958.   ERASE nnew$(),nold$(),ndif$()
  1959.   log(">Memory space taken by nodelist section released")
  1960.   IF difsize%>arc_min% AND sendarc&>-1
  1961.     log(" Archive file creation threshold exceeded")
  1962.     IF EXIST(arc$(sendarc&,0))
  1963.       cl$=LEFT$(sendarc$,INSTR(sendarc$,"&")-1)
  1964.       cl$=cl$+oarc$
  1965.       cl$=cl$+MID$(sendarc$,INSTR(sendarc$,"&")+1,INSTR(sendarc$,"%")-INSTR(sendarc$,"&")-1)
  1966.       cl$=cl$+odiff$
  1967.       cl$=cl$+MID$(sendarc$,INSTR(sendarc$,"%")+1)
  1968.       log("#Calling "+arc$(sendarc&,0))
  1969.       log(" (Parameters: "+cl$+")")
  1970.       log(">"+STR$(FRE(0)-16384)+" bytes available")
  1971.       RESERVE 16384-FRE(0)
  1972.       cwd$=@fullpath$("")
  1973.       cd(hold$)
  1974.       el%=EXEC(0,arc$(sendarc&,0),CHR$(LEN(cl$))+cl$,env$)
  1975.       cd(cwd$)
  1976.       log(">Errorlevel exit "+STR$(el%))
  1977.       IF EXIST(hold$+oarc$)
  1978.         log("#Archived diff "+hold$+oarc$+" created")
  1979.         sendfile$=hold$+oarc$
  1980.         IF EXIST(hold$+odiff$)
  1981.           KILL hold$+odiff$
  1982.         ENDIF
  1983.       ELSE
  1984.         log("!Archiver has not produced "+hold$+oarc$)
  1985.       ENDIF
  1986.     ELSE
  1987.       log("!Archiver "+arc$(sendarc&,0)+" does not exist")
  1988.     ENDIF
  1989.   ENDIF
  1990. RETURN
  1991. > PROCEDURE arc
  1992.   IF sendarc&>-1
  1993.     IF EXIST(arc$(sendarc&,0))
  1994.       cl$=LEFT$(sendarc$,INSTR(sendarc$,"&")-1)
  1995.       cl$=cl$+hold$+olist$+"."+CHR$(sendarc&+65)+MID$(daynxt$,2)
  1996.       cl$=cl$+MID$(sendarc$,INSTR(sendarc$,"&")+1,INSTR(sendarc$,"%")-INSTR(sendarc$,"&")-1)
  1997.       cl$=cl$+olist$+"."+daynxt$
  1998.       cl$=cl$+MID$(sendarc$,INSTR(sendarc$,"%")+1)
  1999.       log("#Calling "+arc$(sendarc&,0))
  2000.       log(" (Parameters: "+cl$+")")
  2001.       log(">"+STR$(FRE(0)-16384)+" bytes available")
  2002.       RESERVE 16384-FRE(0)
  2003.       cwd$=@fullpath$("")
  2004.       cd(mas$)
  2005.       el%=EXEC(0,arc$(sendarc&,0),CHR$(LEN(cl$))+cl$,env$)
  2006.       cd(cwd$)
  2007.       log(">Errorlevel exit "+STR$(el%))
  2008.       IF EXIST(hold$+olist$+"."+CHR$(sendarc&+65)+RIGHT$(daynxt$,2))
  2009.         sendfile$=hold$+olist$+"."+CHR$(sendarc&+65)+RIGHT$(daynxt$,2)
  2010.       ELSE
  2011.         log("!Archiver has not produced "+hold$+olist$+"."+CHR$(sendarc&+65)+RIGHT$(daynxt$,2))
  2012.       ENDIF
  2013.     ELSE
  2014.       log("!Archiver "+arc$(sendarc&,0)+" does not exist")
  2015.     ENDIF
  2016.   ELSE
  2017.     log("!No archiver specified")
  2018.   ENDIF
  2019. RETURN
  2020. > PROCEDURE testmyseg
  2021.   LOCAL lnew%
  2022.   lnew%=1
  2023.   IF dat!
  2024.     OPEN "I",#0,ctl$
  2025.     x$=""
  2026.     DO UNTIL UPPER$(x$)="DATA"
  2027.       x$=@in$(0)
  2028.       DO WHILE RIGHT$(x$)=" "
  2029.         x$=LEFT$(x$,LEN(x$)-1)
  2030.       LOOP
  2031.     LOOP
  2032.     x$=@in$(0)
  2033.     DO WHILE RIGHT$(x$)=" "
  2034.       x$=LEFT$(x$,LEN(x$)-1)
  2035.     LOOP
  2036.     DO WHILE UPPER$(x$)<>"END"
  2037.       nnew$(lnew%)=x$
  2038.       INC lnew%
  2039.       x$=@in$(0)
  2040.       DO WHILE RIGHT$(x$)=" "
  2041.         x$=LEFT$(x$,LEN(x$)-1)
  2042.       LOOP
  2043.     LOOP
  2044.     CLOSE #0
  2045.     log(">Our segment data found from "+ctl$)
  2046.   ELSE
  2047.     addlistnocom(mas$+seg$)
  2048.     log(">Our segment data found from "+mas$+seg$)
  2049.   ENDIF
  2050.   FOR i%=0 TO nsegs&-1
  2051.     IF @nameseg$(i%)>""
  2052.       addlistnocom(@nameseg$(i%))
  2053.     ENDIF
  2054.   NEXT i%
  2055.   check(-1)
  2056.   IF type$="Compound"
  2057.     start$="Zone"
  2058.   ELSE
  2059.     start$=type$
  2060.   ENDIF
  2061.   IF LEFT$(start$,4)="Host"
  2062.     segtype$="Net"
  2063.   ELSE
  2064.     segtype$=start$
  2065.   ENDIF
  2066.   IF type$="Zone"
  2067.     desc$="Zone "+STR$(aozone&)
  2068.     start$="Zone,"+STR$(aozone&)+","
  2069.   ELSE IF type$="Region" OR type$="Host"
  2070.     desc$=start$+" "+STR$(aonet&)
  2071.     start$=start$+","+STR$(aonet&)+","
  2072.   ELSE IF type$="Hub"
  2073.     desc$="Hub "+STR$(aonode&)
  2074.     start$="Hub,"+STR$(aonode&)+","
  2075.   ENDIF
  2076.   i%=1
  2077.   DO WHILE LEFT$(nnew$(i%))=";"
  2078.     INC i%
  2079.   LOOP
  2080.   IF LEFT$(nnew$(i%),LEN(start$))<>start$
  2081.     log("!Local segment must start with "+desc$+" entry")
  2082.     log("!Fatal Error")
  2083.     INC nerrs%
  2084.     rpt$="Error in line 1: Segment must start with "+desc$+" line"+lf$+rpt$
  2085.     fat!=-1 !fatal error!
  2086.   ENDIF
  2087.   FOR i%=i%+1 TO lnew%
  2088.     IF ((type$="Zone" AND equhier!=0) OR type$="Region" OR type$="Host" OR type$="Hub") AND LEFT$(nnew$(i%),5)="Zone,"
  2089.       IF type$="Zone"
  2090.         log("!Local error: Zone entry not allowed after first line in a Zone")
  2091.       ELSE
  2092.         log("!Local error: Zone entry not allowed in a "+segtype$)
  2093.       ENDIF
  2094.       log("!Error in line "+STR$(i%))
  2095.       log("!Fatal Error")
  2096.       IF type$="Zone"
  2097.         rpt$=rpt$+"Error in line "+STR$(i%)+": Zone entry not allowed after first line in a Zone"+lf$
  2098.       ELSE
  2099.         rpt$=rpt$+"Error in line "+STR$(i%)+": Zone entry not allowed in a "+segtype$+lf$
  2100.       ENDIF
  2101.       INC nerrs%
  2102.       fat!=-1
  2103.     ENDIF
  2104.     IF ((type$="Region" AND equhier!=0) OR type$="Host" OR type$="Hub") AND LEFT$(nnew$(i%),7)="Region,"
  2105.       IF type$="Region"
  2106.         log("!Local error: Region entry not allowed after first line in a Region")
  2107.       ELSE
  2108.         log("!Local error: Region entry not allowed in a "+segtype$)
  2109.       ENDIF
  2110.       log("!Error in line "+STR$(i%))
  2111.       log("!Fatal Error")
  2112.       IF type$="Region"
  2113.         rpt$=rpt$+"Error in line "+STR$(i%)+": Region entry not allowed after first line in a Region"+lf$
  2114.       ELSE
  2115.         rpt$=rpt$+"Error in line "+STR$(i%)+": Region entry not allowed in a "+segtype$+lf$
  2116.       ENDIF
  2117.       INC nerrs%
  2118.       fat!=-1
  2119.     ENDIF
  2120.     IF ((type$="Host" AND equhier!=0) OR type$="Hub") AND LEFT$(nnew$(i%),5)="Host,"
  2121.       IF type$="Host"
  2122.         log("!Local error: Host entry not allowed after first line in a Net")
  2123.       ELSE
  2124.         log("!Local error: Host entry not allowed in a Hub")
  2125.       ENDIF
  2126.       log("!Error in line "+STR$(i%))
  2127.       log("!Fatal Error")
  2128.       IF type$="Host"
  2129.         rpt$=rpt$+"Error in line "+STR$(i%)+": Host entry not allowed after first line in a Net"+lf$
  2130.       ELSE
  2131.         rpt$=rpt$+"Error in line "+STR$(i%)+": Host entry not allowed in a Hub"+lf$
  2132.       ENDIF
  2133.       INC nerrs%
  2134.       fat!=-1
  2135.     ENDIF
  2136.     IF (type$="Hub" AND equhier!=0) AND LEFT$(nnew$(i%),4)="Hub,"
  2137.       log("!Local error: Hub entry not allowed after first line in a Hub")
  2138.       log("!Error in line "+STR$(i%))
  2139.       log("!Fatal Error")
  2140.       rpt$=rpt$+"Error in line "+STR$(i%)+": Hub entry not allowed after first line in a Hub"+lf$
  2141.       fat!=-1
  2142.     ENDIF
  2143.   NEXT i%
  2144.   timebar(1)
  2145.   IF nerrs%>0
  2146.     IF nerrs%<>1
  2147.       log("!"+STR$(nerrs%)+" errors found in current segment")
  2148.     ELSE
  2149.       log("!1 error found in current segment")
  2150.     ENDIF
  2151.     log(">Sending netmail to sysop")
  2152.     nmsend(ozone&,onet&,onode&,ozone&,onet&,onode&,"MakeDiff","Coordinator","Local error notification",257,"Error report of current nodelist segment:"+lf$+lf$+rpt$)
  2153.   ELSE
  2154.     log("#Current segment is OK")
  2155.   ENDIF
  2156.   IF fat!
  2157.     fin(deflevel%+2)
  2158.   ENDIF
  2159. RETURN
  2160. > PROCEDURE test
  2161.   LOCAL i%
  2162.   log("*Test mode")
  2163.   testmyseg
  2164.   IF (type$="Compound" OR EXIST(nldir$+nlnam$+"."+daylst$)) AND merge!
  2165.     log(":Merging new data into old nodelist")
  2166.     ' merge current data into nodelist
  2167.     current_nl
  2168.     check(0)
  2169.     IF type$="Distribution"
  2170.       FOR i%=1 TO lnew%
  2171.         nold$(i%)=nnew$(i%)
  2172.       NEXT i%
  2173.     ELSE IF EXIST(nldir$+nlnam$+"."+daylst$)
  2174.       log(">Opening "+nldir$+nlnam$+"."+daylst$)
  2175.       OPEN "I",#0,nldir$+nlnam$+"."+daylst$
  2176.       log(">Reading header information")
  2177.       flin$=@in$(0) !save the first line
  2178.       x$=flin$
  2179.       cmerg%=1
  2180.       DO UNTIL LEFT$(x$)<>";"
  2181.         x$=@in$(0)
  2182.         nold$(cmerg%)=x$
  2183.         INC cmerg%
  2184.       LOOP
  2185.       log(">Header information passed")
  2186.       DEC cmerg%
  2187.       zone%=VAL(MID$(x$,6))
  2188.       net%=zone%
  2189.       hub%=0
  2190.       term!=FALSE
  2191.       IF type$="Zone"
  2192.         log(">Replacing Zone "+STR$(ozone&))
  2193.       ELSE IF type$="Region"
  2194.         log(">Replacing Region "+STR$(ozone&)+":"+STR$(onet&))
  2195.       ELSE IF type$="Host"
  2196.         log(">Replacing Net "+STR$(ozone&)+":"+STR$(onet&))
  2197.       ELSE IF type$="HuB"
  2198.         log(">Replacing Hub "+STR$(ozone&)+":"+STR$(onet&)+"/"+STR$(ohub%))
  2199.       ENDIF
  2200.       DO
  2201.         IF type$="Zone" AND ozone&=zone%
  2202.           log(">Zone "+STR$(ozone&)+" found")
  2203.           term!=TRUE
  2204.         ELSE IF type$="Region" AND ozone&=zone% AND onet&=net%
  2205.           log(">Region "+STR$(ozone&)+":"+STR$(onet&)+" found")
  2206.           term!=TRUE
  2207.         ELSE IF type$="Host" AND ozone&=zone% AND onet&=net%
  2208.           log(">Net "+STR$(ozone&)+":"+STR$(onet&)+" found")
  2209.           term!=TRUE
  2210.         ELSE IF type$="Hub" AND ozone&=zone% AND onet&=net% AND onode&=hub%
  2211.           log(">Hub "+STR$(ozone&)+":"+STR$(onet&)+"/"+STR$(onode&)+" found")
  2212.           term!=TRUE
  2213.         ELSE IF (LEFT$(x$)=";" AND x$<>";") OR x$=eof$
  2214.           log(">Tail information reached")
  2215.           term!=TRUE !we've come to the end part of the nodelist!
  2216.           copy!=TRUE
  2217.         ELSE IF (type$="Region" OR type$="Host") AND lzone%=zone% AND ozone&<>zone%
  2218.           log(">"+type$+" "+STR$(ozone&)+":"+STR$(onet&)+" not found, inserting")
  2219.           term!=TRUE
  2220.         ELSE IF type$="Hub" AND lzone%=zone% AND lnet%=net% AND (ozone&<>zone% OR onet&<>net%)
  2221.           log(">Hub "+STR$(ozone&)+":"+STR$(onet&)+"/"+STR$(onode&)+" not found, inserting")
  2222.           term!=TRUE
  2223.         ENDIF
  2224.         ' do the copy, check for special statements
  2225.         IF NOT term!
  2226.           lzone%=zone%
  2227.           lnet%=net%
  2228.           lhub%=hub%
  2229.           nold$(cmerg%)=x$
  2230.           INC cmerg%
  2231.           x$=@in$(0)
  2232.           IF LEFT$(x$,5)="Zone,"
  2233.             zone%=VAL(MID$(x$,6))
  2234.             net%=zone%
  2235.             hub%=0
  2236.           ELSE IF LEFT$(x$,7)="Region,"
  2237.             net%=VAL(MID$(x$,8))
  2238.             hub%=0
  2239.           ELSE IF LEFT$(x$,5)="Host,"
  2240.             net%=VAL(MID$(x$,6))
  2241.             hub%=0
  2242.           ELSE IF LEFT$(x$,4)="Hub,"
  2243.             hub%=VAL(MID$(x$,5))
  2244.           ENDIF
  2245.         ENDIF
  2246.       LOOP UNTIL term!
  2247.       FOR i%=2 TO lnew%-1
  2248.         nold$(cmerg%)=nnew$(i%)
  2249.         INC cmerg%
  2250.       NEXT i%
  2251.       IF type$<>"Hub"
  2252.         nold$(cmerg%)=";"
  2253.         INC cmerg%
  2254.       ENDIF
  2255.       log(">New segment in place, looking for end of old segment")
  2256.       DO UNTIL copy!
  2257.         x$=@in$(0)
  2258.         IF LEFT$(x$,5)="Zone,"
  2259.           zone%=VAL(MID$(x$,6))
  2260.           net%=zone%
  2261.           hub%=0
  2262.         ELSE IF LEFT$(x$,7)="Region,"
  2263.           net%=VAL(MID$(x$,8))
  2264.           hub%=0
  2265.         ELSE IF LEFT$(x$,5)="Host,"
  2266.           net%=VAL(MID$(x$,6))
  2267.           hub%=0
  2268.         ELSE IF LEFT$(x$,4)="Hub,"
  2269.           hub%=VAL(MID$(x$,5))
  2270.         ENDIF
  2271.         IF type$="Zone" AND ozone&<>zone%
  2272.           log(">End of Zone "+STR$(ozone&)+" found")
  2273.           copy!=-1
  2274.         ELSE IF type$="Region" AND (ozone&<>zone% OR onet&<>net%)
  2275.           log(">End of Region "+STR$(ozone&)+":"+STR$(onet&)+" found")
  2276.           copy!=-1
  2277.         ELSE IF type$="Host" AND (ozone&<>zone% OR onet&<>net%)
  2278.           log(">End of Net "+STR$(ozone&)+":"+STR$(onet&)+" found")
  2279.           copy!=-1
  2280.         ELSE IF type$="Hub" AND (ozone&<>zone% OR onet&<>net% OR onode&<>hub%)
  2281.           log(">End of Hub "+STR$(ozone&)+":"+STR$(onet&)+"/"+STR$(onode&)+" found")
  2282.           copy!=-1
  2283.         ELSE IF (LEFT$(x$)=";" AND x$<>";") OR x$=eof$
  2284.           log(">Tail information reached")
  2285.           copy!=TRUE
  2286.         ENDIF
  2287.       LOOP
  2288.       DO UNTIL x$=eof$
  2289.         nold$(cmerg%)=x$
  2290.         INC cmerg%
  2291.         x$=@in$(0)
  2292.       LOOP
  2293.       DEC cmerg%
  2294.       log(">End of old nodelist file reached")
  2295.       log(">New nodelist contains "+STR$(cmerg%+1)+" lines")
  2296.       CLOSE #0
  2297.       log(">Preparing new nodelist")
  2298.       crc%=0
  2299.       FOR i%=1 TO cmerg%-1
  2300.         status("Calculating CRC - line "+STR$(i%+1))
  2301.         l%=LEN(nold$(i%))-1
  2302.         FOR j%=0 TO l%
  2303.           crc%=@xcrc(crc%,BYTE{V:nold$(i%)+j%})
  2304.         NEXT j%
  2305.         crc%=@xcrc(crc%,13)
  2306.         crc%=@xcrc(crc%,10)
  2307.       NEXT i%
  2308.       crc%=AND(crc%,&HFFFF)
  2309.       status("")
  2310.       log(">CRC of new nodelist = "+STR$(crc%))
  2311.       ' make first line
  2312.       nold$(0)=LEFT$(flin$,INSTR(flin$," Nodelist for ")+13)+datnxt$+" -- Day number "+daynxt$+" : "+RIGHT$("0000"+STR$(crc%),5)
  2313.       IF EXIST(nldir$+nlnam$+".000")
  2314.         log(" Deleting "+nldir$+nlnam$+".000")
  2315.         KILL nldir$+nlnam$+".000"
  2316.       ENDIF
  2317.       log(" Creating "+nldir$+nlnam$+".000")
  2318.       OPEN "O",#0,nldir$+nlnam$+".000"
  2319.       FOR i%=0 TO cmerg%
  2320.         PRINT #0,nold$(i%)
  2321.       NEXT i%
  2322.       OUT #0,&H1A
  2323.       CLOSE #0
  2324.       ERASE nnew$()
  2325.     ELSE
  2326.       log("!Nodelist not found to merge data")
  2327.     ENDIF
  2328.   ENDIF
  2329.   IF NOT cltest!
  2330.     FOR i%=0 TO nsegs&-1
  2331.       IF @nameseg$(i%)=""
  2332.         log("!No file matching segment "+seg$(i%))
  2333.         nm$="The file "+seg$(i%)+" does not currently exist at your coordinator's system. Please send a full update."
  2334.         IF cnoseg%=1
  2335.           send_crashmail(node$(i%),"Request for "+seg$(i%),nm$)
  2336.         ELSE IF cnoseg%=0
  2337.           send_netmail(node$(i%),"Request for "+seg$(i%),nm$)
  2338.         ELSE IF cnoseg%=-1
  2339.           send_holdmail(node$(i%),"Request for "+seg$(i%),nm$)
  2340.         ENDIF
  2341.         IF cerr%>-2
  2342.           log("#Request for "+seg$(i%)+" written to "+node$(i%))
  2343.         ENDIF
  2344.       ENDIF
  2345.     NEXT i%
  2346.   ENDIF
  2347. RETURN
  2348. > PROCEDURE current_nl
  2349.   LOCAL x$,y$
  2350.   ' get current edition of nodelist
  2351.   IF subset!
  2352.     ' look for newest edition of nodelist here
  2353.     IF EXIST(seg$+"."+daynxt$)
  2354.       x$=daynxt$
  2355.     ELSE IF EXIST(seg$+"."+daylst$)
  2356.       x$=daylst$
  2357.       daynxt$=daylst$
  2358.       daylst$=daylst2$
  2359.       datnxt$=datlst$
  2360.       datlst$=datlst2$
  2361.     ELSE IF EXIST(seg$+"."+daylst2$)
  2362.       x$=daylst2$
  2363.       daynxt$=daylst2$
  2364.       daylst$=@daylst3$
  2365.       datnxt$=datlst2$
  2366.     ELSE
  2367.       log("!Nodelist not found")
  2368.       fin(5)
  2369.     ENDIF
  2370.     OPEN "I",#0,seg$+"."+x$
  2371.     log("#Reading "+seg$+"."+x$)
  2372.     x$=@in$(0)
  2373.     lold%=1
  2374.     nnew$(1)=";A This is a subset of the "+MID$(x$,4,INSTR(x$,"Nodelist")+4)+" which contains:"
  2375.     lnew%=2
  2376.     x$=subset$
  2377.     y$=""
  2378.     DO WHILE x$>""
  2379.       SELECT LEFT$(x$)
  2380.       CASE "Z"
  2381.         nnew$(lnew%)=";A - Zone "+STR$(VAL(MID$(x$,2)))
  2382.         y$=y$+"Zone,"+STR$(VAL(MID$(x$,2)))+",|"
  2383.       CASE "R"
  2384.         nnew$(lnew%)=";A - Region "+STR$(VAL(MID$(x$,INSTR(x$,":")+1)))+" of Zone "+STR$(VAL(MID$(x$,2)))
  2385.         y$=y$+"Zone,"+STR$(VAL(MID$(x$,2)))+",Region,"+STR$(VAL(MID$(x$,INSTR(x$,":")+1)))+",|"
  2386.       CASE "N"
  2387.         nnew$(lnew%)=";A - Net "+STR$(VAL(MID$(x$,INSTR(x$,":")+1)))+" of Zone "+STR$(VAL(MID$(x$,2)))
  2388.         y$=y$+"Zone,"+STR$(VAL(MID$(x$,2)))+",Host,"+STR$(VAL(MID$(x$,INSTR(x$,":")+1)))
  2389.       DEFAULT
  2390.         DEC lnew%
  2391.       ENDSELECT
  2392.       INC lnew%
  2393.       DO
  2394.         x$=MID$(x$,2)
  2395.       LOOP UNTIL LEFT$(x$)="Z" OR LEFT$(x$)="R" OR LEFT$(x$)="N" OR x$=""
  2396.     LOOP
  2397.     zone$=""
  2398.     region$=""
  2399.     log(":Creating subset of nodelist")
  2400.     timebar(0)
  2401.     x$=@nlin$(0)
  2402.     DO
  2403.       IF LEFT$(x$)<>","
  2404.         IF LEFT$(x$)=";" AND MID$(x$,2,1)<>"E" AND x$<>";"
  2405.           nnew$(lnew%)=x$
  2406.           INC lnew%
  2407.           x$=@nlin$(0)
  2408.         ELSE IF LEFT$(x$,5)="Zone,"
  2409.           zone$=x$
  2410.           region$=""
  2411.           z$=LEFT$(x$,INSTR(MID$(x$,6),",")+5)
  2412.           IF INSTR(y$,z$) AND MID$(y$,INSTR(y$,z$)+LEN(z$),1)="|"
  2413.             log("#Inserting Zone "+STR$(VAL(MID$(z$,6)))+" from line "+STR$(lold%))
  2414.             timebar(-1)
  2415.             IF nnew$(lnew%-1)<>";"
  2416.               nnew$(lnew%)=";"
  2417.               INC lnew%
  2418.             ENDIF
  2419.             nnew$(lnew%)=x$
  2420.             INC lnew%
  2421.             DO
  2422.               x$=@nlin$(0)
  2423.               nnew$(lnew%)=x$
  2424.               INC lnew%
  2425.             LOOP UNTIL LEFT$(x$,5)="Zone," OR x$=eof$
  2426.             DEC lnew%
  2427.             y$=LEFT$(y$,INSTR(y$,z$+"|")-1)+MID$(y$,INSTR(y$,z$+"|")+LEN(z$)+1)
  2428.             log("#End of Zone reached at line "+STR$(lold%-1))
  2429.             timebar(-1)
  2430.           ELSE
  2431.             x$=@nlin$(0)
  2432.           ENDIF
  2433.         ELSE IF LEFT$(x$,7)="Region,"
  2434.           region$=x$
  2435.           z$=LEFT$(x$,INSTR(MID$(x$,8),",")+7)
  2436.           w$=LEFT$(zone$,INSTR(MID$(zone$,6),",")+5)
  2437.           IF INSTR(y$,z$) AND zone$="" OR INSTR(y$,z$)=INSTR(y$,w$)+LEN(w$)
  2438.             log("#Inserting Region "+STR$(VAL(MID$(z$,8)))+" of Zone "+STR$(VAL(MID$(w$,6)))+" from line "+STR$(lold%))
  2439.             timebar(-1)
  2440.             IF nnew$(lnew%-1)<>";"
  2441.               nnew$(lnew%)=";"
  2442.               INC lnew%
  2443.             ENDIF
  2444.             IF LEN(zone$)>11
  2445.               nnew$(lnew%)=zone$
  2446.               zone$=LEFT$(zone$,6+LEN(STR$(VAL(MID$(zone$,6)))))
  2447.               nnew$(lnew%+1)=";"
  2448.               lnew%=lnew%+2
  2449.             ENDIF
  2450.             nnew$(lnew%)=x$
  2451.             INC lnew%
  2452.             DO
  2453.               x$=@nlin$(0)
  2454.               nnew$(lnew%)=x$
  2455.               INC lnew%
  2456.             LOOP UNTIL LEFT$(x$,7)="Region," OR LEFT$(x$,5)="Zone," OR x$=eof$
  2457.             DEC lnew%
  2458.             y$=LEFT$(y$,INSTR(y$,w$+z$+"|")-1)+MID$(y$,INSTR(y$,w$+z$+"|")+LEN(w$+z$)+1)
  2459.             log("#End of Region reached at line "+STR$(lold%-1))
  2460.             timebar(-1)
  2461.           ELSE
  2462.             x$=@nlin$(0)
  2463.           ENDIF
  2464.         ELSE IF LEFT$(x$,5)="Host,"
  2465.           z$=LEFT$(x$,INSTR(MID$(x$,6),",")+5)
  2466.           w$=LEFT$(zone$,INSTR(MID$(zone$,6),",")+5)
  2467.           IF INSTR(y$,z$) AND (zone$="" OR INSTR(y$,z$)=INSTR(y$,w$)+LEN(w$))
  2468.             log("#Inserting Net "+STR$(VAL(MID$(z$,6)))+" of Zone "+STR$(VAL(MID$(w$,6)))+" from line "+STR$(lold%))
  2469.             timebar(-1)
  2470.             IF nnew$(lnew%-1)<>";"
  2471.               nnew$(lnew%)=";"
  2472.               INC lnew%
  2473.             ENDIF
  2474.             IF LEN(zone$)>11
  2475.               nnew$(lnew%)=zone$
  2476.               zone$=LEFT$(zone$,6+LEN(STR$(VAL(MID$(zone$,6)))))
  2477.               nnew$(lnew%+1)=";"
  2478.               lnew%=lnew%+2
  2479.             ENDIF
  2480.             IF region$>""
  2481.               nnew$(lnew%)=region$
  2482.               region$=""
  2483.               nnew$(lnew%+1)=";"
  2484.               lnew%=lnew%+2
  2485.             ENDIF
  2486.             nnew$(lnew%)=x$
  2487.             INC lnew%
  2488.             DO
  2489.               x$=@nlin$(0)
  2490.               nnew$(lnew%)=x$
  2491.               INC lnew%
  2492.             LOOP UNTIL LEFT$(x$,5)="Host," OR LEFT$(x$,7)="Region," OR LEFT$(x$,5)="Zone," OR x$=eof$
  2493.             DEC lnew%
  2494.             y$=LEFT$(y$,INSTR(y$,w$+z$+"|")-1)+MID$(y$,INSTR(y$,w$+z$+"|")+LEN(w$+z$)+1)
  2495.             log("#End of Net reached at line "+STR$(lold%-1))
  2496.             timebar(-1)
  2497.           ELSE
  2498.             x$=@nlin$(0)
  2499.           ENDIF
  2500.         ELSE
  2501.           x$=@nlin$(0)
  2502.         ENDIF
  2503.       ELSE
  2504.         x$=@nlin$(0)
  2505.       ENDIF
  2506.     LOOP UNTIL x$=eof$ OR y$=""
  2507.     IF y$=""
  2508.       log("#End of required data found, adding comments")
  2509.       timebar(-1)
  2510.       DO
  2511.         x$=@nlin$(0)
  2512.         IF LEFT$(x$)=";" AND MID$(x$,2,1)<>"E" AND x$<>";"
  2513.           nnew$(lnew%)=x$
  2514.           INC lnew%
  2515.         ENDIF
  2516.       LOOP UNTIL EOF(#0)
  2517.     ENDIF
  2518.     CLOSE #0
  2519.     timebar(1)
  2520.     log(" "+STR$(lnew%)+" lines read out of "+STR$(lold%))
  2521.   ELSE
  2522.     lnew%=1
  2523.     ' comments files
  2524.     IF copyright$=""
  2525.       copyright$="CPYRIGHT.TXT"
  2526.     ENDIF
  2527.     IF type$="Compound" AND EXIST(copyright$)
  2528.       segment(copyright$,-1)
  2529.       log("#Copyright file "+copyright$+" added")
  2530.     ENDIF
  2531.     IF head$=""
  2532.       head$="HEAD.TXT"
  2533.     ENDIF
  2534.     IF type$="Compound" AND EXIST(head$)
  2535.       segment(head$,0)
  2536.       log("#Header file "+head$+" added")
  2537.     ENDIF
  2538.     IF type$<>"Hub"
  2539.       nnew$(lnew%)=";"
  2540.       INC lnew%
  2541.     ENDIF
  2542.     ' incorporate our segment data into list
  2543.     IF dat!
  2544.       OPEN "I",#0,ctl$
  2545.       x$=""
  2546.       DO UNTIL UPPER$(x$)="DATA"
  2547.         x$=@in$(0)
  2548.         DO WHILE RIGHT$(x$)=" "
  2549.           x$=LEFT$(x$,LEN(x$)-1)
  2550.         LOOP
  2551.       LOOP
  2552.       x$=@in$(0)
  2553.       DO WHILE RIGHT$(x$)=" "
  2554.         x$=LEFT$(x$,LEN(x$)-1)
  2555.       LOOP
  2556.       DO WHILE UPPER$(x$)<>"END"
  2557.         IF LEFT$(x$)<>";" OR x$=";"
  2558.           nnew$(lnew%)=x$
  2559.           INC lnew%
  2560.         ENDIF
  2561.         x$=@in$(0)
  2562.         DO WHILE RIGHT$(x$)=" "
  2563.           x$=LEFT$(x$,LEN(x$)-1)
  2564.         LOOP
  2565.       LOOP
  2566.       CLOSE #0
  2567.       log("#Our segment data added from "+ctl$)
  2568.     ELSE
  2569.       addlistnocom(mas$+seg$)
  2570.       log("#Our segment data added from "+mas$+seg$)
  2571.     ENDIF
  2572.     ' add other people's segment data
  2573.     ' not used for-next in case error lines have to be added, therefore the number
  2574.     ' of lines is dynamic at this stage
  2575.     n%=0
  2576.     DO WHILE n%<nsegs&
  2577.       procseg(n%)
  2578.       INC n%
  2579.     LOOP
  2580.     IF tail$=""
  2581.       tail$="TAIL.TXT"
  2582.     ENDIF
  2583.     IF type$="Compound" AND EXIST(tail$)
  2584.       nnew$(lnew%)=";"
  2585.       INC lnew%
  2586.       addlist(tail$)
  2587.     ENDIF
  2588.   ENDIF
  2589. RETURN
  2590. > PROCEDURE process
  2591.   log("*Process mode")
  2592.   IF NOT subset!
  2593.     testmyseg
  2594.   ENDIF
  2595.   IF nlissue%>0 AND DATE$<>RIGHT$("0"+STR$(nlupday%),2)+"."+RIGHT$("0"+STR$(nlupmonth%),2)+"."+RIGHT$("0"+STR$(nlupyear%),4)
  2596.     issueinc
  2597.   ENDIF
  2598.   log("+Creating new copy of our nodelist section")
  2599.   current_nl !get current nodelist
  2600.   ' check nodelist for errors
  2601.   IF check!
  2602.     check(0)
  2603.     log(" Nodelist produced contains "+STR$(lnew%)+" lines")
  2604.     IF nerrs%>0
  2605.       IF nerrs%<>1
  2606.         log("!"+STR$(nerrs%)+" errors found")
  2607.       ELSE
  2608.         log("!1 error found")
  2609.       ENDIF
  2610.     ENDIF
  2611.   ENDIF
  2612.   ' calculate crc of nodelist lines 1 to lnew
  2613.   crc%=0
  2614.   status("Calculating CRC")
  2615.   timebar(0)
  2616.   FOR i%=1 TO lnew%-1
  2617.     timebar(i%/(lnew%-1))
  2618.     IF RIGHT$(nnew$(i%))=CHR$(1)
  2619.       l%=-2
  2620.     ELSE
  2621.       l%=-1
  2622.     ENDIF
  2623.     l%=l%+LEN(nnew$(i%))
  2624.     FOR j%=0 TO l%
  2625.       crc%=@xcrc(crc%,BYTE{V:nnew$(i%)+j%})
  2626.     NEXT j%
  2627.     crc%=@xcrc(crc%,13)
  2628.     crc%=@xcrc(crc%,10)
  2629.   NEXT i%
  2630.   crc%=AND(crc%,&HFFFF)
  2631.   status("")
  2632.   log(" CRC of nodelist = "+STR$(crc%))
  2633.   ' make first line
  2634.   nnew$(0)=";A "+pwd$+" Nodelist for "+datnxt$+" -- Day number "+daynxt$+" : "+RIGHT$("0000"+STR$(crc%),5)
  2635.   IF @generic(olist$)
  2636.     IF EXIST(mas$+olist$+"."+daynxt$)
  2637.       x$=mas$+olist$+"."+daynxt$
  2638.     ELSE
  2639.       x$=mas$+olist$+"."+daylst$
  2640.     ENDIF
  2641.   ELSE
  2642.     x$=mas$+olist$
  2643.   ENDIF
  2644.   IF type$="Compound"
  2645.     change!=TRUE
  2646.   ELSE IF @fullreq
  2647.     change!=TRUE
  2648.     diff_min%=-1
  2649.   ELSE
  2650.     IF EXIST(x$)
  2651.       log("#Comparing with "+x$)
  2652.       OPEN "I",#0,x$
  2653.       change!=FALSE
  2654.       lold%=1
  2655.       n$=@in$(0)
  2656.       ocrc%=VAL(MID$(n$,RINSTR(n$,":")+1))
  2657.       log(">CRC of old file = "+STR$(ocrc%))
  2658.       IF ocrc%<>crc%
  2659.         log(">CRC mismatch")
  2660.         change!=TRUE
  2661.         log("#Segment has changed since previous sending of update")
  2662.       ELSE
  2663.         DO
  2664.           n$=@in$(0)
  2665.           IF n$<>nnew$(lold%) AND n$<>eof$
  2666.             log(">Line "+STR$(lold%)+" mismatch")
  2667.             change!=TRUE
  2668.             log("+Segment has changed since previous sending of update")
  2669.           ELSE IF n$<>eof$
  2670.             log(">Line "+STR$(lold%)+" match")
  2671.           ENDIF
  2672.           IF n$<>eof$
  2673.             INC lold%
  2674.           ENDIF
  2675.         LOOP UNTIL EOF(#0) OR change!
  2676.         IF NOT change!
  2677.           log(">Old copy has "+STR$(lold%)+" lines")
  2678.           IF lnew%>lold%
  2679.             log(">Size mismatch")
  2680.             change!=TRUE
  2681.             log("#Segment has changed since previous sending of update")
  2682.           ENDIF
  2683.         ENDIF
  2684.       ENDIF
  2685.       IF NOT change!
  2686.         log("#No changes since previous copy, update will not be sent")
  2687.       ENDIF
  2688.       CLOSE #0
  2689.     ELSE
  2690.       change!=TRUE
  2691.       log("#Old file "+x$+" does not exist")
  2692.       log("#Full segment will be sent")
  2693.     ENDIF
  2694.   ENDIF
  2695.   IF @generic(olist$)
  2696.     y$=mas$+olist$+"."+daynxt$
  2697.   ELSE
  2698.     y$=mas$+olist$
  2699.   ENDIF
  2700.   IF change! OR x$<>y$
  2701.     IF type$<>"Compound" OR nldir$="" OR nlnam$=""
  2702.       log("+Creating "+y$)
  2703.       OPEN "O",#0,y$
  2704.       FOR i%=0 TO lnew%-1
  2705.         IF RIGHT$(nnew$(i%))=CHR$(1)
  2706.           PRINT #0,LEFT$(nnew$(i%),LEN(nnew$(i%))-1)
  2707.         ELSE
  2708.           PRINT #0,nnew$(i%)
  2709.         ENDIF
  2710.       NEXT i%
  2711.       OUT #0,&H1A
  2712.       size%=LOF(#0)
  2713.       CLOSE #0
  2714.       log(">LOF = "+STR$(size%))
  2715.     ELSE
  2716.       IF EXIST(nldir$+nlnam$+"."+daylst$)
  2717.         log("#Replacing old nodelist with new nodelist")
  2718.         ~@copy(nldir$+nlnam$+"."+daylst$,mas$+olist$+"."+daylst$)
  2719.         KILL nldir$+nlnam$+"."+daylst$
  2720.         log(" "+nldir$+nlnam$+"."+daylst$+" moved to "+mas$)
  2721.       ENDIF
  2722.       log("+Creating "+nldir$+nlnam$+"."+daynxt$)
  2723.       OPEN "O",#0,nldir$+nlnam$+"."+daynxt$
  2724.       FOR i%=0 TO lnew%-1
  2725.         IF RIGHT$(nnew$(i%))=CHR$(1)
  2726.           PRINT #0,LEFT$(nnew$(i%),LEN(nnew$(i%))-1)
  2727.         ELSE
  2728.           PRINT #0,nnew$(i%)
  2729.         ENDIF
  2730.       NEXT i%
  2731.       OUT #0,&H1A
  2732.       size%=LOF(#0)
  2733.       CLOSE #0
  2734.       log(">LOF = "+STR$(size%))
  2735.     ENDIF
  2736.     IF @generic(olist$)
  2737.       sendfile$=hold$+olist$+"."+daynxt$
  2738.     ELSE
  2739.       sendfile$=hold$+olist$
  2740.     ENDIF
  2741.     IF change!
  2742.       diff!=0
  2743.       IF size%>diff_min% AND EXIST(mas$+olist$+"."+daylst$) AND @generic(olist$) AND diff_min%>-1
  2744.         log(" Difference file creation threshold exceeded")
  2745.         arcdiff
  2746.       ELSE IF size%>arc_min% AND @generic(olist$) AND arc_min%>-1
  2747.         log(" Archive file creation threshold exceeded")
  2748.         arc
  2749.       ELSE
  2750.         ' save new list to outbound
  2751.         IF hold$<>mas$
  2752.           log("+Creating "+sendfile$)
  2753.           OPEN "O",#0,sendfile$
  2754.           FOR i%=0 TO lnew%-1
  2755.             IF RIGHT$(nnew$(i%))=CHR$(1)
  2756.               PRINT #0,LEFT$(nnew$(i%),LEN(nnew$(i%))-1)
  2757.             ELSE
  2758.               PRINT #0,nnew$(i%)
  2759.             ENDIF
  2760.           NEXT i%
  2761.           OUT #0,&H1A
  2762.           CLOSE #0
  2763.         ENDIF
  2764.       ENDIF
  2765.       IF dzone& OR dnet& OR dnode&
  2766.         log("#Sending "+sendfile$+" to "+STR$(dzone&)+":"+STR$(dnet&)+"/"+STR$(dnode&))
  2767.         send(sendfile$,ozone&,onet&,onode&,dzone&,dnet&,dnode&)
  2768.       ENDIF
  2769.       IF diff! AND diffarea$>""
  2770.         autosend(sendfile$,diffarea$,diffdesc$)
  2771.       ELSE IF autoarea$>"" AND type$<>"Compound"
  2772.         autosend(sendfile$,autoarea$,autodesc$)
  2773.       ENDIF
  2774.     ENDIF
  2775.   ENDIF
  2776.   fin(3-netmail!)
  2777. RETURN
  2778. > PROCEDURE status(l$)
  2779.   IF l$>""
  2780.     PRINT "> ";TIME$;" ";l$;SPACE$(68-LEN(l$));
  2781.   ELSE
  2782.     PRINT SPACE$(79);
  2783.   ENDIF
  2784.   OUT 2,13
  2785. RETURN
  2786. > PROCEDURE errout
  2787.   log("!Error "+STR$(ERR))
  2788.   log("!  ("+MID$(ERR$(ERR),INSTR(2,ERR$(ERR),"[")+1,INSTR(6,ERR$(ERR),"]")-5)+")")
  2789.   fin(254)
  2790. RETURN
  2791. > PROCEDURE cd(d$)
  2792.   IF MID$(d$,2,1)=":"
  2793.     CHDRIVE d$
  2794.   ENDIF
  2795.   CHDIR d$
  2796. RETURN
  2797. > PROCEDURE timebar(x#)
  2798.   IF NOT nobar!
  2799.     x#=x#*xwid&
  2800.     IF x#=-xwid&
  2801.     ELSE IF x#<p_x% OR x#=0
  2802.       PBOX 0,ytop&,xwid&+1,ybot&
  2803.       IF x#>=1
  2804.         DEFFILL 0
  2805.         PBOX 1,ytop&+1,x#,ybot&-1
  2806.       ENDIF
  2807.       IF x#>-1
  2808.         p_x%=x#
  2809.       ENDIF
  2810.       DEFFILL 1
  2811.     ELSE IF x#>=p_x%+1
  2812.       DEFFILL 0
  2813.       PBOX 1+p_x%,ytop&+1,x#,ybot&-1
  2814.       DEFFILL 1
  2815.       p_x%=x#
  2816.     ENDIF
  2817.   ENDIF
  2818. RETURN
  2819. > PROCEDURE autosend(file$,area$,desc$)
  2820.   LOCAL d$,x$
  2821.   log("#Auto Hatching "+file$+" in "+area$)
  2822.   d$=""
  2823.   DO WHILE INSTR(desc$,"%")
  2824.     x%=INSTR(desc$,"%")
  2825.     SELECT MID$(desc$,x%+1,1)
  2826.     CASE "%"
  2827.       d$=d$+LEFT$(desc$,x%)
  2828.     CASE "Y","y"
  2829.       d$=d$+LEFT$(desc$,x%-1)+MID$(DATE$,7)
  2830.     CASE "I","i"
  2831.       d$=d$+LEFT$(desc$,x%-1)+STR$(nlissue%)
  2832.     CASE "D","d"
  2833.       d$=d$+LEFT$(desc$,x%-1)+STR$(VAL(LEFT$(DATE$,2)))
  2834.     CASE "M","m"
  2835.       d$=d$+LEFT$(desc$,x%-1)+m$(VAL(MID$(DATE$,4))-1)
  2836.     CASE "J","j"
  2837.       d$=d$+LEFT$(desc$,x%-1)+daynxt$
  2838.     ENDSELECT
  2839.     desc$=MID$(desc$,x%+2)
  2840.   LOOP
  2841.   d$=d$+desc$
  2842.   log(" Desc "+d$)
  2843.   x$=afilpath$+"HATCH"
  2844.   IF EXIST(x$)
  2845.     log(" Appending to existing HATCH file for AutoFile")
  2846.     OPEN "A",#0,x$
  2847.   ELSE
  2848.     log(" Creating a new HATCH file for AutoFile")
  2849.     OPEN "O",#0,x$
  2850.   ENDIF
  2851.   PRINT #0,file$
  2852.   PRINT #0,area$
  2853.   PRINT #0,d$
  2854.   PRINT #0,"---"
  2855.   CLOSE #0
  2856. RETURN
  2857. > PROCEDURE report
  2858.   LOCAL czone&,cnet&,cnode&,i&,first$,nname$,nloc$,nsysop$,nphone$,nbps$,nflags$,txt$,attrib&,n$
  2859.   log("*Report mode")
  2860.   current_nl
  2861.   czone&=ozone&
  2862.   cnet&=onet&
  2863.   cnode&=onode&
  2864.   i&=0
  2865.   uppcor%=0
  2866.   first$="-"
  2867.   DO UNTIL INSTR(first$,LEFT$(nnew$(i&),INSTR(first$,",")))
  2868.     x$=nnew$(i&)
  2869.     IF LEFT$(x$)<>";"
  2870.       IF @valid$(x$)=""
  2871.         IF LEFT$(x$,5)="Zone,"
  2872.           czone&=VAL(MID$(x$,6))
  2873.           cnet&=VAL(MID$(x$,6))
  2874.           cnode&=0
  2875.         ELSE IF LEFT$(x$,7)="Region,"
  2876.           cnet&=VAL(MID$(x$,8))
  2877.           cnode&=0
  2878.         ELSE IF LEFT$(x$,5)="Host,"
  2879.           cnet&=VAL(MID$(x$,6))
  2880.           cnode&=0
  2881.         ENDIF
  2882.         IF first$="-"
  2883.           first$="Zone,Region,Host,"
  2884.           IF LEFT$(x$,5)="Zone,"
  2885.             czone&=VAL(MID$(x$,6))
  2886.             cnet&=VAL(MID$(x$,6))
  2887.             cnode&=0
  2888.           ELSE IF LEFT$(x$,7)="Region,"
  2889.             cnet&=VAL(MID$(x$,8))
  2890.             cnode&=0
  2891.           ELSE IF LEFT$(x$,5)="Host,"
  2892.             cnet&=VAL(MID$(x$,6))
  2893.             cnode&=0
  2894.           ENDIF
  2895.         ELSE IF LEFT$(x$)="," OR LEFT$(x$,4)="Pvt,"
  2896.           x$=MID$(x$,INSTR(x$,",")+1)
  2897.           cnode&=VAL(x$)
  2898.           x$=MID$(x$,INSTR(x$,",")+1)
  2899.           nname$=LEFT$(x$,INSTR(x$,",")-1)
  2900.           x$=MID$(x$,INSTR(x$,",")+1)
  2901.           nloc$=LEFT$(x$,INSTR(x$,",")-1)
  2902.           x$=MID$(x$,INSTR(x$,",")+1)
  2903.           nsysop$=LEFT$(x$,INSTR(x$,",")-1)
  2904.           x$=MID$(x$,INSTR(x$,",")+1)
  2905.           nphone$=LEFT$(x$,INSTR(x$,",")-1)
  2906.           x$=MID$(x$,INSTR(x$,",")+1)
  2907.           nbps$=LEFT$(x$,INSTR(x$,",")-1)
  2908.           nflags$=MID$(x$,INSTR(x$,",")+1)
  2909.           txt$=LEFT$(nsysop$,INSTR(nsysop$,"_")-1)+","+CHR$(10)+CHR$(10)
  2910.           txt$=txt$+"Your coordinator is running MakeDiff (copyright AutoMagic Software) to cause the nodelist updating with your details. If you would, please check the following, and report any errors to your coordinator:"+CHR$(10)+CHR$(10)
  2911.           n$=STR$(cnet&)+"/"+STR$(cnode&)
  2912.           IF czone&>0
  2913.             n$=STR$(czone&)+":"+n$
  2914.           ENDIF
  2915.           x$="NODELIST ENTRY FOR NODE "+n$+CHR$(10)
  2916.           x$=x$+STRING$(LEN(x$)-1,"~")+CHR$(10)
  2917.           txt$=txt$+x$+"Node Name . . . . . . . . . . . . . . "+nname$+CHR$(10)
  2918.           txt$=txt$+"Location. . . . . . . . . . . . . . . "+nloc$+CHR$(10)
  2919.           txt$=txt$+"Sysop name (your name). . . . . . . . "+nsysop$+CHR$(10)
  2920.           txt$=txt$+"Phone number (international format) . "+nphone$+CHR$(10)
  2921.           txt$=txt$+"Highest BPS rate of modem . . . . . . "+nbps$+CHR$(10)
  2922.           txt$=txt$+"Flags associated with your entry. . . "+nflags$+CHR$(10)+CHR$(10)
  2923.           txt$=txt$+"Thanks for checking your entry. If you have any queries, please address them to your coordinator."
  2924.           SELECT crcpt%
  2925.           CASE -2 TO -1 !hold
  2926.             attrib&=897
  2927.             log("#Report netmail held for "+n$)
  2928.           CASE 0 !route
  2929.             attrib&=385
  2930.             log("#Report netmail routed to "+n$)
  2931.           CASE 1 !crash
  2932.             attrib&=387
  2933.             log("#Report netmail crashed to "+n$)
  2934.           ENDSELECT
  2935.           nmsend(ozone&,onet&,onode&,czone&,cnet&,cnode&,"Coordinator",nsysop$,"Your Nodelist entry",attrib&,txt$)
  2936.         ENDIF
  2937.       ENDIF
  2938.     ENDIF
  2939.     INC i&
  2940.   LOOP UNTIL i&>=lnew%
  2941. RETURN
  2942. > FUNCTION xcrc(crc%,cp%)
  2943.   '
  2944.   ' This position independent code (DevpacST 2) exists in the inline.
  2945.   '
  2946.   ' * crc16 routine: D0 is running CRC-16, D1.b is data to shift in
  2947.   ' * bits 8-15 of D1 are assumed to be reset (zero)
  2948.   '
  2949.   ' crc16   lea     crc16tb(pc),a0
  2950.   '         move.w  d0,d2
  2951.   '         lsr.w   #8,d0
  2952.   '         eor.w   d1,d0
  2953.   '         lsl.w   d0
  2954.   '         move.w  0(a0,d0.w),d0
  2955.   '         lsl.w   #8,d2
  2956.   '         eor.w   d2,d0
  2957.   '         rts
  2958.   '
  2959.   '         data
  2960.   ' crc16tb dc.w    $0000,$1021,$2042,$3063,$4084,$50a5,$60c6,$70e7
  2961.   '         dc.w    $8108,$9129,$a14a,$b16b,$c18c,$d1ad,$e1ce,$f1ef
  2962.   '         dc.w    $1231,$0210,$3273,$2252,$52b5,$4294,$72f7,$62d6
  2963.   '         dc.w    $9339,$8318,$b37b,$a35a,$d3bd,$c39c,$f3ff,$e3de
  2964.   '         dc.w    $2462,$3443,$0420,$1401,$64e6,$74c7,$44a4,$5485
  2965.   '         dc.w    $a56a,$b54b,$8528,$9509,$e5ee,$f5cf,$c5ac,$d58d
  2966.   '         dc.w    $3653,$2672,$1611,$0630,$76d7,$66f6,$5695,$46b4
  2967.   '         dc.w    $b75b,$a77a,$9719,$8738,$f7df,$e7fe,$d79d,$c7bc
  2968.   '         dc.w    $48c4,$58e5,$6886,$78a7,$0840,$1861,$2802,$3823
  2969.   '         dc.w    $c9cc,$d9ed,$e98e,$f9af,$8948,$9969,$a90a,$b92b
  2970.   '         dc.w    $5af5,$4ad4,$7ab7,$6a96,$1a71,$0a50,$3a33,$2a12
  2971.   '         dc.w    $dbfd,$cbdc,$fbbf,$eb9e,$9b79,$8b58,$bb3b,$ab1a
  2972.   '         dc.w    $6ca6,$7c87,$4ce4,$5cc5,$2c22,$3c03,$0c60,$1c41
  2973.   '         dc.w    $edae,$fd8f,$cdec,$ddcd,$ad2a,$bd0b,$8d68,$9d49
  2974.   '         dc.w    $7e97,$6eb6,$5ed5,$4ef4,$3e13,$2e32,$1e51,$0e70
  2975.   '         dc.w    $ff9f,$efbe,$dfdd,$cffc,$bf1b,$af3a,$9f59,$8f78
  2976.   '         dc.w    $9188,$81a9,$b1ca,$a1eb,$d10c,$c12d,$f14e,$e16f
  2977.   '         dc.w    $1080,$00a1,$30c2,$20c3,$5004,$4025,$7046,$6067
  2978.   '         dc.w    $83b9,$9398,$a3fb,$b3da,$c33d,$d31c,$e37f,$f35e
  2979.   '         dc.w    $02b1,$1290,$22f3,$32d2,$4235,$5214,$6277,$7256
  2980.   '         dc.w    $b5ea,$a5cb,$95a8,$8589,$f56e,$e54f,$d52c,$c50d
  2981.   '         dc.w    $34e2,$24c3,$14a0,$0481,$7466,$6447,$5424,$4405
  2982.   '         dc.w    $a7db,$b7fa,$8799,$97b8,$e75f,$f77e,$c71d,$d73c
  2983.   '         dc.w    $26d3,$36f2,$0691,$16b0,$6657,$7676,$4615,$5634
  2984.   '         dc.w    $d94c,$c96d,$f90e,$e92f,$99c8,$89e9,$b98a,$a9ab
  2985.   '         dc.w    $5844,$4865,$7806,$6827,$18c0,$08e1,$3882,$28a3
  2986.   '         dc.w    $cb7d,$db5c,$eb3f,$fb1e,$8bf9,$9bd8,$abbb,$bb9a
  2987.   '         dc.w    $4a75,$5a54,$6a37,$7a16,$0af1,$1ad0,$2ab3,$3a92
  2988.   '         dc.w    $fd2e,$ed0f,$dd6c,$cd4d,$bdaa,$ad8b,$9de8,$8dc9
  2989.   '         dc.w    $7c26,$6c07,$5c64,$4c45,$3ca2,$2c83,$1ce0,$0cc1
  2990.   '         dc.w    $ef1f,$ff3e,$cf5d,$df7c,$af9b,$bfba,$8fd9,$9ff8
  2991.   '         dc.w    $6e17,$7e36,$4e55,$5e74,$2e93,$3eb2,$0ed1,$1ef0
  2992.   '
  2993.   ' Parts of the above were derived from code in BinkleyTerm-ST, copyright
  2994.   ' Stephen Satchell of Satchell Evaluations and Chuck Forsberg of Omen
  2995.   ' Technologies. The conversion to 68k machine code was by me. Please see the
  2996.   ' BinkleyTerm source code for more details.
  2997.   '
  2998.   LOCAL crc16%
  2999. ' ## INLINE:
  3000. ' $0000: 41 fa 00 14 34 00 e0 48 b3 40 e3 48 30 30 00 00 
  3001. ' $0010: e1 4a b5 40 4e 75 00 00 10 21 20 42 30 63 40 84 
  3002. ' $0020: 50 a5 60 c6 70 e7 81 08 91 29 a1 4a b1 6b c1 8c 
  3003. ' $0030: d1 ad e1 ce f1 ef 12 31 02 10 32 73 22 52 52 b5 
  3004. ' $0040: 42 94 72 f7 62 d6 93 39 83 18 b3 7b a3 5a d3 bd 
  3005. ' $0050: c3 9c f3 ff e3 de 24 62 34 43 04 20 14 01 64 e6 
  3006. ' $0060: 74 c7 44 a4 54 85 a5 6a b5 4b 85 28 95 09 e5 ee 
  3007. ' $0070: f5 cf c5 ac d5 8d 36 53 26 72 16 11 06 30 76 d7 
  3008. ' $0080: 66 f6 56 95 46 b4 b7 5b a7 7a 97 19 87 38 f7 df 
  3009. ' $0090: e7 fe d7 9d c7 bc 48 c4 58 e5 68 86 78 a7 08 40 
  3010. ' $00a0: 18 61 28 02 38 23 c9 cc d9 ed e9 8e f9 af 89 48 
  3011. ' $00b0: 99 69 a9 0a b9 2b 5a f5 4a d4 7a b7 6a 96 1a 71 
  3012. ' $00c0: 0a 50 3a 33 2a 12 db fd cb dc fb bf eb 9e 9b 79 
  3013. ' $00d0: 8b 58 bb 3b ab 1a 6c a6 7c 87 4c e4 5c c5 2c 22 
  3014. ' $00e0: 3c 03 0c 60 1c 41 ed ae fd 8f cd ec dd cd ad 2a 
  3015. ' $00f0: bd 0b 8d 68 9d 49 7e 97 6e b6 5e d5 4e f4 3e 13 
  3016. ' $0100: 2e 32 1e 51 0e 70 ff 9f ef be df dd cf fc bf 1b 
  3017. ' $0110: af 3a 9f 59 8f 78 91 88 81 a9 b1 ca a1 eb d1 0c 
  3018. ' $0120: c1 2d f1 4e e1 6f 10 80 00 a1 30 c2 20 e3 50 04 
  3019. ' $0130: 40 25 70 46 60 67 83 b9 93 98 a3 fb b3 da c3 3d 
  3020. ' $0140: d3 1c e3 7f f3 5e 02 b1 12 90 22 f3 32 d2 42 35 
  3021. ' $0150: 52 14 62 77 72 56 b5 ea a5 cb 95 a8 85 89 f5 6e 
  3022. ' $0160: e5 4f d5 2c c5 0d 34 e2 24 c3 14 a0 04 81 74 66 
  3023. ' $0170: 64 47 54 24 44 05 a7 db b7 fa 87 99 97 b8 e7 5f 
  3024. ' $0180: f7 7e c7 1d d7 3c 26 d3 36 f2 06 91 16 b0 66 57 
  3025. ' $0190: 76 76 46 15 56 34 d9 4c c9 6d f9 0e e9 2f 99 c8 
  3026. ' $01a0: 89 e9 b9 8a a9 ab 58 44 48 65 78 06 68 27 18 c0 
  3027. ' $01b0: 08 e1 38 82 28 a3 cb 7d db 5c eb 3f fb 1e 8b f9 
  3028. ' $01c0: 9b d8 ab bb bb 9a 4a 75 5a 54 6a 37 7a 16 0a f1 
  3029. ' $01d0: 1a d0 2a b3 3a 92 fd 2e ed 0f dd 6c cd 4d bd aa 
  3030. ' $01e0: ad 8b 9d e8 8d c9 7c 26 6c 07 5c 64 4c 45 3c a2 
  3031. ' $01f0: 2c 83 1c e0 0c c1 ef 1f ff 3e cf 5d df 7c af 9b 
  3032. ' $0200: bf ba 8f d9 9f f8 6e 17 7e 36 4e 55 5e 74 2e 93 
  3033. ' $0210: 3e b2 0e d1 1e f0 
  3034. ' 534  Bytes.
  3035.   INLINE crc16%,534
  3036.   reg%(0)=crc%
  3037.   reg%(1)=cp%
  3038.   RCALL crc16%,reg%()
  3039.   RETURN reg%(0)
  3040. ENDFUNC
  3041. ' Data for Date function:
  3042. DATA 0,3,3,6,1,4,6,2,5,0,3,5
  3043. DATA Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday
  3044. DATA January,February,March,April,May,June
  3045. DATA July,August,September,October,November,December
  3046. DATA 31,28,31,30,31,30,31,31,30,31,30,31
  3047. DATA 31,29,31,30,31,30,31,31,30,31,30,31
  3048. > FUNCTION move(fr$,to$)
  3049.   LOCAL x%
  3050.   IF LEFT$(@fullpath$(LEFT$(fr$,RINSTR(fr$,"\"))))=LEFT$(@fullpath$(LEFT$(to$,RINSTR(to$,"\"))))
  3051.     NAME fr$ AS to$
  3052.     log(" Rename from "+fr$)
  3053.     log(" to "+to$)
  3054.   ELSE
  3055.     x%=@copy(fr$,to$)
  3056.     KILL fr$
  3057.     log(" File "+fr$+" deleted")
  3058.   ENDIF
  3059.   RETURN x%
  3060. ENDFUNC
  3061. > FUNCTION copy(fr$,to$)
  3062.   LOCAL l%,x%
  3063.   OPEN "I",#6,fr$
  3064.   l%=LOF(#6)
  3065.   IF MID$(to$,2,1)=":"
  3066.     x%=DFREE(ASC(UPPER$(to$))-64)
  3067.   ELSE
  3068.     x%=DFREE(0)
  3069.   ENDIF
  3070.   log(" Copy from "+fr$)
  3071.   log(" to "+to$)
  3072.   status("File copying")
  3073.   timebar(0)
  3074.   IF x%>=l%
  3075.     OPEN "O",#7,to$
  3076.     DO UNTIL l%=0
  3077.       RECALL #6,nold$(),-1,l%
  3078.       timebar((LOC(#6)+LOC(#7))/LOF(#6)/2)
  3079.       IF l%>0
  3080.         IF nold$(l%-1)=eof$
  3081.           l%=l%-1
  3082.         ENDIF
  3083.         STORE #7,nold$(),l%
  3084.         timebar((LOC(#6)+LOC(#7))/LOF(#6)/2)
  3085.       ENDIF
  3086.     LOOP
  3087.     OUT 7,&H1A
  3088.     CLOSE #6
  3089.     CLOSE #7
  3090.     ret%=0
  3091.   ELSE
  3092.     CLOSE #6
  3093.     log("!Not enough disk space for copy")
  3094.     ret%=-39
  3095.   ENDIF
  3096.   ERASE nold$()
  3097.   DIM nold$(maxsize&)
  3098.   RETURN ret%
  3099. ENDFUNC
  3100. > FUNCTION get$(st%,no%)
  3101.   LOCAL i%,x$
  3102.   x$=""
  3103.   FOR i%=st% TO st%+no%-1
  3104.     x$=x$+CHR$(b_|(i%))
  3105.   NEXT i%
  3106.   RETURN x$
  3107. ENDFUNC
  3108. > FUNCTION dat$
  3109.   LOCAL y&,m&,d&,d$
  3110.   d$=DATE$
  3111.   y&=VAL(MID$(d$,7))
  3112.   m&=VAL(MID$(d$,4,2))
  3113.   d&=VAL(LEFT$(d$,2))
  3114.   RETURN @datf$(y&,m&,d&)
  3115. ENDFUNC
  3116. ' return FTS-0005 format date string
  3117. ' e.g. Friday, June 5, 1992
  3118. > FUNCTION datf$(y&,m&,d&)
  3119.   LOCAL b&,x&,a&,i&,w&,l&
  3120.   b&=y& MOD 100
  3121.   x&=y&\100-15
  3122.   a&=3+x&*21
  3123.   i&=(a& MOD 28)\4
  3124.   a&=b&*5+4*(d&+k&(m&-1)+i&)
  3125.   w&=1+(a& MOD 28)\4
  3126.   IF m&<3
  3127.     l&=x&-1+4*((x&-1)\4)
  3128.     IF b&>0
  3129.       l&=y& MOD 4
  3130.     ENDIF
  3131.     IF l&<=0
  3132.       IF w&=0
  3133.         w&=6
  3134.       ENDIF
  3135.       w&=w&-1
  3136.     ENDIF
  3137.   ENDIF
  3138.   IF w&=0
  3139.     w&=7
  3140.   ENDIF
  3141.   RETURN d$(w&-1)+", "+m$(m&-1)+" "+STR$(d&)+", "+STR$(y&)
  3142. ENDFUNC
  3143. > FUNCTION datnxt2$
  3144.   LOCAL y&,m&,d&,d$,x$,l&
  3145.   d$=DATE$
  3146.   y&=VAL(MID$(d$,7))
  3147.   m&=VAL(MID$(d$,4,2))
  3148.   d&=VAL(LEFT$(d$,2))
  3149.   l&=@leapyear(y&)
  3150.   x$=@datf$(y&,m&,d&)
  3151.   DO WHILE LEFT$(x$,LEN(pubday$))<>pubday$
  3152.     IF d&=njd&(m&-1,l&)
  3153.       d&=1
  3154.       IF m&=12
  3155.         m&=1
  3156.         INC y&
  3157.       ELSE
  3158.         INC m&
  3159.       ENDIF
  3160.     ELSE
  3161.       INC d&
  3162.     ENDIF
  3163.     x$=@datf$(y&,m&,d&)
  3164.   LOOP
  3165.   IF d&=njd&(m&-1,l&)
  3166.     d&=1
  3167.     IF m&=12
  3168.       m&=1
  3169.       INC y&
  3170.     ELSE
  3171.       INC m&
  3172.     ENDIF
  3173.   ELSE
  3174.     INC d&
  3175.   ENDIF
  3176.   x$=@datf$(y&,m&,d&)
  3177.   DO WHILE LEFT$(x$,LEN(pubday$))<>pubday$
  3178.     IF d&=njd&(m&-1,l&)
  3179.       d&=1
  3180.       IF m&=12
  3181.         m&=1
  3182.         INC y&
  3183.       ELSE
  3184.         INC m&
  3185.       ENDIF
  3186.     ELSE
  3187.       INC d&
  3188.     ENDIF
  3189.     x$=@datf$(y&,m&,d&)
  3190.   LOOP
  3191.   RETURN x$
  3192. ENDFUNC
  3193. > FUNCTION datnxt$
  3194.   LOCAL y&,m&,d&,d$,x$,l&
  3195.   d$=DATE$
  3196.   y&=VAL(MID$(d$,7))
  3197.   m&=VAL(MID$(d$,4,2))
  3198.   d&=VAL(LEFT$(d$,2))
  3199.   l&=@leapyear(y&)
  3200.   x$=@datf$(y&,m&,d&)
  3201.   DO WHILE LEFT$(x$,LEN(pubday$))<>pubday$
  3202.     IF d&=njd&(m&-1,l&)
  3203.       d&=1
  3204.       IF m&=12
  3205.         m&=1
  3206.         INC y&
  3207.       ELSE
  3208.         INC m&
  3209.       ENDIF
  3210.     ELSE
  3211.       INC d&
  3212.     ENDIF
  3213.     x$=@datf$(y&,m&,d&)
  3214.   LOOP
  3215.   RETURN x$
  3216. ENDFUNC
  3217. > FUNCTION datlst$
  3218.   LOCAL y&,m&,d&,d$,x$,l&
  3219.   d$=DATE$
  3220.   y&=VAL(MID$(d$,7))
  3221.   m&=VAL(MID$(d$,4,2))
  3222.   d&=VAL(LEFT$(d$,2))
  3223.   l&=@leapyear(y&)
  3224.   DO
  3225.     IF d&=1
  3226.       IF m&=1
  3227.         m&=12
  3228.         DEC y&
  3229.       ELSE
  3230.         DEC m&
  3231.       ENDIF
  3232.       d&=njd&(m&-1,l&)
  3233.     ELSE
  3234.       DEC d&
  3235.     ENDIF
  3236.     x$=@datf$(y&,m&,d&)
  3237.   LOOP WHILE LEFT$(x$,LEN(pubday$))<>pubday$
  3238.   RETURN x$
  3239. ENDFUNC
  3240. > FUNCTION datlst2$
  3241.   LOCAL y&,m&,d&,d$,x$,l&,i&
  3242.   d$=DATE$
  3243.   y&=VAL(MID$(d$,7))
  3244.   m&=VAL(MID$(d$,4,2))
  3245.   d&=VAL(LEFT$(d$,2))
  3246.   l&=@leapyear(y&)
  3247.   FOR i&=1 TO 2
  3248.     DO
  3249.       IF d&=1
  3250.         IF m&=1
  3251.           m&=12
  3252.           DEC y&
  3253.         ELSE
  3254.           DEC m&
  3255.         ENDIF
  3256.         d&=njd&(m&-1,l&)
  3257.       ELSE
  3258.         DEC d&
  3259.       ENDIF
  3260.       x$=@datf$(y&,m&,d&)
  3261.     LOOP WHILE LEFT$(x$,LEN(pubday$))<>pubday$
  3262.   NEXT i&
  3263.   RETURN x$
  3264. ENDFUNC
  3265. > FUNCTION day$
  3266.   LOCAL l&,y&,m&,d&,d$
  3267.   d$=DATE$
  3268.   y&=VAL(MID$(d$,7))
  3269.   m&=VAL(MID$(d$,4,2))
  3270.   d&=VAL(LEFT$(d$,2))
  3271.   l&=@leapyear(y&)
  3272.   RETURN RIGHT$("00"+STR$(fjd&(m&-1,l&)+d&),3)
  3273. ENDFUNC
  3274. > FUNCTION daynxt2$
  3275.   LOCAL y&,m&,d&,d$,x$,l&
  3276.   d$=DATE$
  3277.   y&=VAL(MID$(d$,7))
  3278.   m&=VAL(MID$(d$,4,2))
  3279.   d&=VAL(LEFT$(d$,2))
  3280.   l&=@leapyear(y&)
  3281.   x$=@datf$(y&,m&,d&)
  3282.   DO WHILE LEFT$(x$,LEN(pubday$))<>pubday$
  3283.     IF d&=njd&(m&-1,l&)
  3284.       d&=1
  3285.       IF m&=12
  3286.         m&=1
  3287.         INC y&
  3288.       ELSE
  3289.         INC m&
  3290.       ENDIF
  3291.     ELSE
  3292.       INC d&
  3293.     ENDIF
  3294.     x$=@datf$(y&,m&,d&)
  3295.   LOOP
  3296.   IF d&=njd&(m&-1,l&)
  3297.     d&=1
  3298.     IF m&=12
  3299.       m&=1
  3300.       INC y&
  3301.     ELSE
  3302.       INC m&
  3303.     ENDIF
  3304.   ELSE
  3305.     INC d&
  3306.   ENDIF
  3307.   x$=@datf$(y&,m&,d&)
  3308.   DO WHILE LEFT$(x$,LEN(pubday$))<>pubday$
  3309.     IF d&=njd&(m&-1,l&)
  3310.       d&=1
  3311.       IF m&=12
  3312.         m&=1
  3313.         INC y&
  3314.       ELSE
  3315.         INC m&
  3316.       ENDIF
  3317.     ELSE
  3318.       INC d&
  3319.     ENDIF
  3320.     x$=@datf$(y&,m&,d&)
  3321.   LOOP
  3322.   RETURN RIGHT$("00"+STR$(fjd&(m&-1,l&)+d&),3)
  3323. ENDFUNC
  3324. > FUNCTION daynxt$
  3325.   LOCAL y&,m&,d&,d$,x$,l&
  3326.   d$=DATE$
  3327.   y&=VAL(MID$(d$,7))
  3328.   m&=VAL(MID$(d$,4,2))
  3329.   d&=VAL(LEFT$(d$,2))
  3330.   x$=@datf$(y&,m&,d&)
  3331.   l&=@leapyear(y&)
  3332.   DO WHILE LEFT$(x$,LEN(pubday$))<>pubday$
  3333.     IF d&=njd&(m&-1,l&)
  3334.       d&=1
  3335.       IF m&=12
  3336.         m&=1
  3337.         INC y&
  3338.       ELSE
  3339.         INC m&
  3340.       ENDIF
  3341.     ELSE
  3342.       INC d&
  3343.     ENDIF
  3344.     x$=@datf$(y&,m&,d&)
  3345.   LOOP
  3346.   RETURN RIGHT$("00"+STR$(fjd&(m&-1,l&)+d&),3)
  3347. ENDFUNC
  3348. > FUNCTION daylst$
  3349.   LOCAL y&,m&,d&,d$,x$,l&
  3350.   d$=DATE$
  3351.   y&=VAL(MID$(d$,7))
  3352.   m&=VAL(MID$(d$,4,2))
  3353.   d&=VAL(LEFT$(d$,2))
  3354.   l&=@leapyear(y&)
  3355.   DO
  3356.     IF d&=1
  3357.       IF m&=1
  3358.         m&=12
  3359.         DEC y&
  3360.       ELSE
  3361.         DEC m&
  3362.       ENDIF
  3363.       d&=njd&(m&-1,l&)
  3364.     ELSE
  3365.       DEC d&
  3366.     ENDIF
  3367.     x$=@datf$(y&,m&,d&)
  3368.   LOOP WHILE LEFT$(x$,LEN(pubday$))<>pubday$
  3369.   RETURN RIGHT$("00"+STR$(fjd&(m&-1,l&)+d&),3)
  3370. ENDFUNC
  3371. > FUNCTION daylst2$
  3372.   LOCAL x&,y&,m&,d&,d$,x$,l&
  3373.   d$=DATE$
  3374.   y&=VAL(MID$(d$,7))
  3375.   m&=VAL(MID$(d$,4,2))
  3376.   d&=VAL(LEFT$(d$,2))
  3377.   l&=@leapyear(y&)
  3378.   FOR x&=1 TO 2
  3379.     DO
  3380.       IF d&=1
  3381.         IF m&=1
  3382.           m&=12
  3383.           DEC y&
  3384.         ELSE
  3385.           DEC m&
  3386.         ENDIF
  3387.         d&=njd&(m&-1,l&)
  3388.       ELSE
  3389.         DEC d&
  3390.       ENDIF
  3391.       x$=@datf$(y&,m&,d&)
  3392.     LOOP WHILE LEFT$(x$,LEN(pubday$))<>pubday$
  3393.   NEXT x&
  3394.   RETURN RIGHT$("00"+STR$(fjd&(m&-1,l&)+d&),3)
  3395. ENDFUNC
  3396. > FUNCTION daylst3$
  3397.   LOCAL x&,y&,m&,d&,d$,x$,l&
  3398.   d$=DATE$
  3399.   y&=VAL(MID$(d$,7))
  3400.   m&=VAL(MID$(d$,4,2))
  3401.   d&=VAL(LEFT$(d$,2))
  3402.   l&=@leapyear(y&)
  3403.   FOR x&=1 TO 3
  3404.     DO
  3405.       IF d&=1
  3406.         IF m&=1
  3407.           m&=12
  3408.           DEC y&
  3409.         ELSE
  3410.           DEC m&
  3411.         ENDIF
  3412.         d&=njd&(m&-1,l&)
  3413.       ELSE
  3414.         DEC d&
  3415.       ENDIF
  3416.       x$=@datf$(y&,m&,d&)
  3417.     LOOP WHILE LEFT$(x$,LEN(pubday$))<>pubday$
  3418.   NEXT x&
  3419.   RETURN RIGHT$("00"+STR$(fjd&(m&-1,l&)+d&),3)
  3420. ENDFUNC
  3421. > FUNCTION stamp
  3422.   LOCAL y&,m&,d&,d$,l%
  3423.   d$=DATE$
  3424.   y&=VAL(MID$(d$,7))
  3425.   m&=VAL(MID$(d$,4,2))
  3426.   d&=VAL(LEFT$(d$,2))
  3427.   l%=INT(y&-1970)*365+((y&-1969)\4-(y&-1901)\100+(y&-1601)\400)
  3428.   IF dpm%=0
  3429.     nrerror("stamp: Days per month buffer dpm% not defined")
  3430.   ENDIF
  3431.   ADD l%,WORD{dpm%+2*m&-2}
  3432.   MUL l%,86400
  3433.   d$=TIME$
  3434.   ADD l%,MUL(VAL(TIME$),3600)
  3435.   ADD l%,MUL(VAL(MID$(TIME$,4)),60)
  3436.   ADD l%,VAL(MID$(TIME$,7))
  3437.   RETURN l%
  3438. ENDFUNC
  3439. > FUNCTION in$(handle%)
  3440.   LOCAL x$,x%
  3441.   IF EOF(#handle%)
  3442.     RETURN eof$
  3443.   ELSE
  3444.     x%=INP(#handle%)
  3445.     IF x%=&H1A
  3446.       RETURN eof$
  3447.     ELSE
  3448.       LINE INPUT #handle%,x$
  3449.       x$=CHR$(x%)+x$
  3450.       RETURN x$
  3451.     ENDIF
  3452.   ENDIF
  3453. ENDFUNC
  3454. > FUNCTION nlin$(handle%)
  3455.   x$=@in$(handle%)
  3456.   INC lold%
  3457.   IF LEFT$(x$)=","
  3458.     RETURN x$
  3459.   ELSE IF LEFT$(x$,5)="Zone,"
  3460.     log(">Zone "+STR$(VAL(MID$(x$,6)))+" at line "+STR$(lold%))
  3461.     timebar(LOC(#0)/LOF(#0))
  3462.   ELSE IF LEFT$(x$,7)="Region,"
  3463.     log(">Region "+STR$(VAL(MID$(x$,8)))+" at line "+STR$(lold%))
  3464.     timebar(LOC(#0)/LOF(#0))
  3465.   ELSE IF LEFT$(x$,5)="Host,"
  3466.     log(">Net "+STR$(VAL(MID$(x$,6)))+" at line "+STR$(lold%))
  3467.     timebar(LOC(#0)/LOF(#0))
  3468.   ENDIF
  3469.   RETURN x$
  3470. ENDFUNC
  3471. > FUNCTION generic(n$)
  3472.   RETURN RINSTR(n$,".")<RINSTR(n$,"\") OR INSTR(n$,".")=0
  3473. ENDFUNC
  3474. > FUNCTION fullpath$(d$)
  3475.   LOCAL cwd$,ret$
  3476.   cwd$=CHR$(ASC("A")+GEMDOS(25))+":"+DIR$(0)
  3477.   IF MID$(d$,2,1)=":"
  3478.     IF (BIOS(10) AND 2^(ASC(d$)-65))=0
  3479.       log("!Drive "+LEFT$(d$)+" doesn't exist!")
  3480.       fin(255)
  3481.     ENDIF
  3482.     CHDRIVE d$
  3483.     d$=MID$(d$,3)
  3484.   ENDIF
  3485.   IF LEFT$(d$)="\"
  3486.     CHDIR "\"
  3487.     d$=MID$(d$,2)
  3488.   ENDIF
  3489.   DO WHILE d$>""
  3490.     IF INSTR(d$,"\")
  3491.       c$=LEFT$(d$,INSTR(d$,"\")-1)
  3492.       d$=MID$(d$,INSTR(d$,"\")+1)
  3493.     ELSE
  3494.       c$=d$
  3495.       d$=""
  3496.     ENDIF
  3497.     IF FSFIRST(c$,16) AND c$<>"."
  3498.       MKDIR c$
  3499.     ENDIF
  3500.     CHDIR c$
  3501.   LOOP
  3502.   ret$=CHR$(ASC("A")+GEMDOS(25))+":"+DIR$(0)
  3503.   CHDRIVE cwd$
  3504.   CHDIR cwd$
  3505.   RETURN ret$+"\"
  3506. ENDFUNC
  3507. > FUNCTION base36$(number%,digits%)
  3508.   RETURN RIGHT$(STRING$(digits%-1,"0")+@b36$(number%),digits%)
  3509. ENDFUNC
  3510. > FUNCTION b36$(number%)
  3511.   LOCAL x$,n%
  3512.   n%=number% MOD 36
  3513.   IF n%<10
  3514.     x$=CHR$(n%+48)
  3515.   ELSE
  3516.     x$=CHR$(n%+55)
  3517.   ENDIF
  3518.   IF number%<36
  3519.     RETURN x$
  3520.   ELSE
  3521.     RETURN @b36$(number%\36)+x$
  3522.   ENDIF
  3523. ENDFUNC
  3524. > FUNCTION valid$(VAR x$)
  3525.   LOCAL l$,j%,xx$,tnode%
  3526.   ' check for extended characters and replace with ?
  3527.   prob!=0
  3528.   FOR j%=1 TO LEN(x$)
  3529.     IF ASC(MID$(x$,j%))>126 OR ASC(MID$(x$,j%))<32
  3530.       IF j%<LEN(x$) OR ASC(MID$(x$,j%))<>1
  3531.         MID$(x$,j%,1)="?"
  3532.         prob!=-1
  3533.       ENDIF
  3534.     ENDIF
  3535.   NEXT j%
  3536.   IF prob!
  3537.     RETURN "Line contains illegal characters"
  3538.   ELSE IF LEFT$(x$)<>";"
  3539.     l$=x$
  3540.     ' line is a true entry
  3541.     FOR j%=0 TO 7
  3542.       IF INSTR(l$,",") AND j%<7
  3543.         field$(j%)=LEFT$(l$,INSTR(l$,",")-1)
  3544.         l$=MID$(l$,INSTR(l$,",")+1)
  3545.       ELSE
  3546.         IF j%=7
  3547.           field$(j%)=l$
  3548.           l$=""
  3549.         ELSE
  3550.           RETURN "Missing fields"
  3551.         ENDIF
  3552.       ENDIF
  3553.     NEXT j%
  3554.     FOR j%=1 TO 7
  3555.       SELECT j%
  3556.       CASE 1 !Node number
  3557.         ok$="0123456789"
  3558.       CASE 2 !Node name
  3559.         ok$="!""#$%&'()*+-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
  3560.       CASE 3 !Location
  3561.         ok$="!""#$%&'()*+-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
  3562.       CASE 4 !Sysop name
  3563.         ok$="!""#$%&'()*+-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
  3564.       CASE 5 !Phone number
  3565.         ok$="-0123456789"
  3566.       CASE 6 !Baud rate field
  3567.         ok$="0123456789"
  3568.       CASE 7 !Flags field
  3569.         ok$="!""#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[/]^_`abcdefghijklmnopqrstuvwxyz{|}~"
  3570.       ENDSELECT
  3571.       IF field$(j%)>""
  3572.         IF (j%=5 AND (UPPER$(field$(j%))<>"-UNPUBLISHED-") OR j%<>5)
  3573.           FOR k&=1 TO LEN(field$(j%))
  3574.             IF INSTR(ok$,MID$(field$(j%),k&,1))=0 AND j%<>6 AND UPPER$(field$(j%))<>"-UNPUBLISHED-"
  3575.               RETURN "Invalid character(s) in "+fieldname$(j%)
  3576.             ENDIF
  3577.           NEXT k&
  3578.         ENDIF
  3579.       ENDIF
  3580.     NEXT j%
  3581.     IF uppcor%=0 AND field$(0)<>"Host" AND field$(0)<>"Region" AND field$(0)<>"Zone" AND type$<>"Hub"
  3582.       RETURN "Node is not of a Zone, Region or Net"
  3583.     ELSE IF field$(0)<>"" AND field$(0)<>"Zone" AND field$(0)<>"Region" AND field$(0)<>"Host" AND field$(0)<>"Hub" AND field$(0)<>"Hold" AND field$(0)<>"Down" AND field$(0)<>"Pvt"
  3584.       RETURN "Invalid keyword"
  3585.     ELSE IF field$(0)="Pvt" AND uppcor%>2
  3586.       IF uppcor%=3
  3587.         RETURN "Private nodes not valid in a region"
  3588.       ELSE
  3589.         RETURN "Private nodes not valid in a zone"
  3590.       ENDIF
  3591.     ELSE IF field$(0)="Pvt"
  3592.       tnode%=VAL(field$(1))
  3593.       IF zone%=0 AND region%=0
  3594.         xx$="/"+STR$(tnode%)
  3595.       ELSE IF zone%=0
  3596.         xx$=":"+STR$(net%)+"/"+STR$(tnode%)
  3597.       ELSE
  3598.         xx$=STR$(zone%)+":"+STR$(net%)+"/"+STR$(tnode%)
  3599.       ENDIF
  3600.       IF (pvtvalid!=0 AND INSTR(pvtlist$,xx$)=0)
  3601.         RETURN "Unauthorised private node"
  3602.       ENDIF
  3603.     ENDIF
  3604.     IF VAL(field$(1))<1 OR VAL(field$(1))>32767
  3605.       IF field$(0)="Zone" OR field$(0)="Region"
  3606.         xx$=field$(0)
  3607.       ELSE IF field$(0)="Host"
  3608.         xx$="Net"
  3609.       ELSE
  3610.         xx$="Node"
  3611.       ENDIF
  3612.       RETURN xx$+" number is not in range [1..32767]"
  3613.     ELSE IF field$(0)="" OR field$(0)="Hold" OR field$(0)="Down" OR field$(0)="Pvt"
  3614.       node%=VAL(field$(1))
  3615.       IF node!(node%)
  3616.         RETURN "Duplicate node number"
  3617.       ELSE
  3618.         node!(node%)=-1
  3619.       ENDIF
  3620.     ELSE IF field$(0)="Hub"
  3621.       uppcor%=1
  3622.       node%=VAL(field$(1))
  3623.       IF node!(node%)
  3624.         RETURN "Duplicate node number"
  3625.       ELSE
  3626.         node!(node%)=-1
  3627.       ENDIF
  3628.     ELSE IF field$(0)="Host"
  3629.       uppcor%=2
  3630.       IF net!(VAL(field$(1)))
  3631.         RETURN "Duplicate net number"
  3632.       ELSE
  3633.         ARRAYFILL node!(),0
  3634.         net%=VAL(field$(1))
  3635.         node%=0
  3636.         net!(net%)=-1
  3637.       ENDIF
  3638.     ELSE IF field$(0)="Region"
  3639.       uppcor%=3
  3640.       IF net!(VAL(field$(1)))
  3641.         RETURN "Duplicate net number"
  3642.       ELSE
  3643.         ARRAYFILL node!(),0
  3644.         net%=VAL(field$(1))
  3645.         node%=0
  3646.         net!(net%)=-1
  3647.       ENDIF
  3648.     ELSE IF field$(0)="Zone"
  3649.       uppcor%=4
  3650.       IF zone!(VAL(field$(1)))
  3651.         RETURN "Duplicate zone number"
  3652.       ELSE
  3653.         ARRAYFILL node!(),0
  3654.         ARRAYFILL net!(),0
  3655.         zone%=VAL(field$(1))
  3656.         net%=zone%
  3657.         node%=0
  3658.         zone!(zone%)=-1
  3659.         net!(net%)=-1
  3660.       ENDIF
  3661.     ENDIF
  3662.     IF (field$(0)<>"Pvt" AND field$(0)<>"Hold" AND field$(0)<>"Down") AND UPPER$(field$(5))="-UNPUBLISHED-"
  3663.       RETURN "Non-private nodes should have a phone number"
  3664.     ELSE
  3665.       ok!=FALSE
  3666.       FOR j%=1 TO nbps&
  3667.         IF VAL(field$(6))=bps%(j%)
  3668.           ok!=TRUE
  3669.         ENDIF
  3670.       NEXT j%
  3671.       IF NOT ok!
  3672.         RETURN """"+field$(6)+""" is an invalid BPS rate"
  3673.       ENDIF
  3674.     ENDIF
  3675.   ENDIF
  3676.   RETURN ""
  3677. ENDFUNC
  3678. > FUNCTION nameseg$(n%)
  3679.   LOCAL y$,z$
  3680.   IF @generic(seg$(n%))
  3681.     y$=seg$(n%)+"."+daynxt$
  3682.     z$=seg$(n%)+"."+daylst$
  3683.   ELSE
  3684.     y$=seg$(n%)
  3685.     z$=seg$(n%)
  3686.   ENDIF
  3687.   IF EXIST(upd$+y$)
  3688.     RETURN upd$+y$
  3689.   ELSE IF EXIST(mas$+y$)
  3690.     RETURN mas$+y$
  3691.   ELSE IF EXIST(mas$+z$)
  3692.     RETURN mas$+z$
  3693.   ENDIF
  3694.   RETURN ""
  3695. ENDFUNC
  3696. > FUNCTION fullreq
  3697.   LOCAL x$,x%
  3698.   IF fullreq!=-1
  3699.     RETURN fullreq%
  3700.   ENDIF
  3701.   log(":Scanning Netmail for full segment request")
  3702.   fullreq!=-1
  3703.   fullreq%=0
  3704.   timebar(0)
  3705.   IF EXIST(netmail$+".HDR")
  3706.     OPEN "R",#5,netmail$+".HDR",216
  3707.     msgs&=LOF(#5)\216
  3708.     FIELD #5,216 AS record$
  3709.     FOR m&=1 TO msgs&
  3710.       GET #5,m&
  3711.       IF AND(ASC(MID$(record$,178,1)),4)=0 AND AND(ASC(MID$(record$,177,1)),128)=0 !not Recv or Del
  3712.         IF @tr$(LEFT$(record$,36))="MakeDiff"
  3713.           IF @tr$(MID$(record$,37,36))="Coordinator"
  3714.             IF @tr$(MID$(record$,73,72))="Request for "+UPPER$(olist$)
  3715.               IF MID$(record$,201,8)=MKI$(dzone&)+MKI$(dnet&)+MKI$(dnode&)+MKI$(0)
  3716.                 IF MID$(record$,209,8)=MKI$(ozone&)+MKI$(onet&)+MKI$(onode&)+MKI$(0)
  3717.                   MID$(record$,178,1)=CHR$(OR(ASC(MID$(record$,178,1)),4)) ! set Recv
  3718.                   MID$(record$,177,1)=CHR$(OR(ASC(MID$(record$,177,1)),128)) ! set Del
  3719.                   fullreq%=-1
  3720.                   log(":Full segment request detected and deleted")
  3721.                   PUT #5,m&
  3722.                 ENDIF
  3723.               ENDIF
  3724.             ENDIF
  3725.           ENDIF
  3726.         ENDIF
  3727.       ENDIF
  3728.       timebar(m&/msgs&)
  3729.     NEXT m&
  3730.     CLOSE #5
  3731.   ENDIF
  3732.   timebar(1)
  3733.   RETURN fullreq%
  3734. ENDFUNC
  3735. > FUNCTION tr$(x$)
  3736.   ' More comprehensive trim function
  3737.   IF INSTR(x$,CHR$(0))
  3738.     RETURN TRIM$(LEFT$(x$,INSTR(x$,CHR$(0))-1))
  3739.   ELSE
  3740.     RETURN TRIM$(x$)
  3741.   ENDIF
  3742. ENDFUNC
  3743. > FUNCTION leapyear(y&)
  3744.   IF (y& MOD 100)>0
  3745.     IF (y& MOD 4)=0
  3746.       RETURN 1
  3747.     ELSE
  3748.       RETURN 0
  3749.     ENDIF
  3750.   ELSE
  3751.     IF (y& MOD 400)=0
  3752.       RETURN 1
  3753.     ELSE
  3754.       RETURN 0
  3755.     ENDIF
  3756.   ENDIF
  3757. ENDFUNC
  3758.