-- Copyright (C) 1984 by Xerox Corporation. All rights reserved. -- NetDirBuilderMain.Mesa, HGM, 1-Jul-84 1:38:58 DIRECTORY Ascii USING [CR], Environment USING [], Process USING [SetTimeout, MsecToTicks], Put USING [Char, Text, Line, Decimal], String USING [AppendChar, AppendString, EqualString], Time USING [AppendCurrent], UserInput USING [ResetUserAbort, UserAbort], Window USING [Handle], Buffer USING [AccessHandle, DestroyPool, GetBuffer, MakePool, ReturnBuffer], NameServerDefs USING [ StartProbingForDirectory, PupDirServerOn, PupDirServerOff, PupNameServerOff], PupDefs USING [ AppendHostName, defaultNumberOfNetworks, GetHopsToNetwork, GetPupContentsBytes, MsToTocks, PupBuffer, PupRouterSendThis, PupSocket, PupSocketMake, SecondsToTocks, SetPupContentsWords, PupSocketDestroy, PupPackageMake, PupPackageDestroy], PupTypes USING [ PupAddress, allNets, allHosts, fillInPupAddress, fillInSocketID, miscSrvSoc], NetDirDefs, NetDirBuilderOps USING []; NetDirBuilderMain: MONITOR IMPORTS Process, Put, String, Time, UserInput, Buffer, NameServerDefs, PupDefs EXPORTS NameServerDefs, NetDirBuilderOps = BEGIN OPEN NetDirDefs; debug: PUBLIC BOOLEAN ← FALSE; -- If debug is on, this program should produce a new directory that is EXACTLY like the current one. If you are changing the way this program operates (rather than the format/contents of the output file), turn debug on and run it. Then FTP Compare can be used to verify that your changes have not done anything horrible. log: PUBLIC Window.Handle ← NIL; UpdatePicture: PUBLIC PROCEDURE = {}; -- Avoid binder's complaints version: CARDINAL ← 0; GetNewVersionNumber: PUBLIC PROCEDURE RETURNS [CARDINAL] = BEGIN RETURN[version]; END; FindVersionNumber: PUBLIC PROCEDURE [banzai: LONG STRING] RETURNS [BOOLEAN] = BEGIN OPEN PupDefs, PupTypes; pool: Buffer.AccessHandle ← Buffer.MakePool[send: 1, receive: 10]; socket: PupSocket; b: PupBuffer; Announce["Probing for current version number..."]; IF ~debug THEN Put.Line[ log, " This takes a while since we are searching the whole internet."L]; version ← 0; PupPackageMake[]; socket ← PupSocketMake[fillInSocketID, fillInPupAddress, MsToTocks[250]]; THROUGH [0..5) DO IF debug AND version # 0 THEN EXIT; FOR net: CARDINAL IN [0..defaultNumberOfNetworks) DO IF GetHopsToNetwork[[net]] > 100 THEN LOOP; b ← Buffer.GetBuffer[pup, pool, send]; b.pup.source ← socket.getLocalAddress[]; b.pup.dest ← [[net], PupTypes.allHosts, PupTypes.miscSrvSoc]; b.pup.pupType ← netDirVersion; b.pup.pupWords[0] ← 0; b.pup.pupWords[1] ← 0; SetPupContentsWords[b, 2]; PupRouterSendThis[b]; UNTIL b = NIL DO b ← socket.get[]; IF b # NIL THEN BEGIN IF b.pup.pupType = netDirVersion THEN BEGIN IF b.pup.pupWords[0] > version THEN version ← b.pup.pupWords[0]; IF GetPupContentsBytes[b] > 2 THEN IF b.pup.pupWords[1] > version THEN version ← b.pup.pupWords[1]; END; Buffer.ReturnBuffer[b]; END; ENDLOOP; ENDLOOP; ENDLOOP; PupSocketDestroy[socket]; Buffer.DestroyPool[pool]; PupPackageDestroy[]; IF version = 0 THEN BEGIN IF ~String.EqualString[banzai, "BANZAI"L] THEN RETURN[FALSE]; Put.Line[ log, "*** Creating a new directory. I hope you know what you are doing."L]; version ← 1; END; IF ~debug THEN version ← version + 1; Put.Text[log, "The new version number will be "]; Put.Decimal[log, version]; Put.Line[log, "."]; RETURN[TRUE]; END; SendOutDirectories: PUBLIC ENTRY PROCEDURE = BEGIN OPEN PupDefs, PupTypes; pool: Buffer.AccessHandle ← Buffer.MakePool[send: 1, receive: 10]; socket: PupSocket; b: PupBuffer; cycle, stop: CARDINAL ← 0; pause: CONDITION; Announce["Starting Directory Server..."]; Process.SetTimeout[@pause, Process.MsecToTicks[10000]]; PupDefs.PupPackageMake[]; socket ← PupSocketMake[fillInSocketID, fillInPupAddress, SecondsToTocks[2]]; NameServerDefs.PupDirServerOn[]; NameServerDefs.StartProbingForDirectory[]; UserInput.ResetUserAbort[log]; UNTIL stop > 10 OR UserInput.UserAbort[log] DO -- Note: We can't simply send one copy of the new directory, because an IFS might take it, and they won't send it on to others unless the name server is activated. stop ← stop + 1; b ← Buffer.GetBuffer[pup, pool, send]; b.pup.source ← socket.getLocalAddress[]; b.pup.dest ← [PupTypes.allNets, PupTypes.allHosts, PupTypes.miscSrvSoc]; b.pup.pupType ← netDirVersion; b.pup.pupWords[0] ← 0; b.pup.pupWords[1] ← 0; SetPupContentsWords[b, 2]; PupRouterSendThis[b]; DO b ← socket.get[]; IF b # NIL THEN BEGIN IF b.pup.pupType = netDirVersion THEN BEGIN old, new: BOOLEAN ← FALSE; IF b.pup.pupWords[0] < version THEN old ← TRUE; IF GetPupContentsBytes[b] > 2 AND b.pup.pupWords[1] < version THEN new ← TRUE; IF old OR new THEN stop ← 0; IF (old OR new) AND cycle > 5 AND (cycle MOD 3) = 0 THEN BEGIN text: STRING = [100]; Time.AppendCurrent[text]; String.AppendString[text, " Waiting for "L]; PupDefs.AppendHostName[text, b.pup.source]; IF old AND ~new THEN String.AppendString[text, " (old only)"L]; IF ~old AND new THEN String.AppendString[text, " (new only)"L]; String.AppendChar[text, '.]; String.AppendChar[text, Ascii.CR]; Put.Text[log, text]; END; END; Buffer.ReturnBuffer[b]; END; IF b = NIL THEN EXIT; ENDLOOP; WAIT pause; cycle ← cycle + 1; ENDLOOP; PupSocketDestroy[socket]; Buffer.DestroyPool[pool]; NameServerDefs.PupDirServerOff[]; NameServerDefs.PupDirServerOff[]; -- It may turn itself on automatically NameServerDefs.PupNameServerOff[]; PupDefs.PupPackageDestroy[]; Announce["Finished!"]; END; Announce: PROCEDURE [s: LONG STRING] = BEGIN text: STRING = [30]; Time.AppendCurrent[text]; Put.Text[log, text]; Put.Char[log, ' ]; Put.Char[log, ' ]; Put.Line[log, s]; END; END.