-- Copyright (C) 1984, 1985 by Xerox Corporation. All rights reserved.
-- NetDirBuilderMain.Mesa, HGM, 25-Jun-85 8:31:12
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.