-- Copyright (C) 1983, 1985 by Xerox Corporation. All rights reserved.
-- TimeServersParmTajo.mesa, HGM, 15-Jun-85 15:52:11
-- Please don't forget to update the herald...
DIRECTORY
Ascii USING [CR],
CmFile USING [Handle, TableError],
FormSW USING [
ClientItemsProcType, Display, ProcType, AllocateItemDescriptor, newLine,
CommandItem, NumberItem],
Inline USING [LowHalf],
Process USING [Detach, Pause, SecondsToTicks, Ticks],
Put USING [Text],
String USING [AppendChar, AppendDecimal, AppendString, AppendLongDecimal],
StringLookUp USING [noMatch, TableDesc],
System USING [
GetLocalTimeParameters, LocalTimeParameters, NetworkAddress, nullNetworkAddress, WestEast],
TemporarySetGMT USING [adjustableClockRate, SetClockRate],
Time USING [AppendCurrent],
Token USING [Boolean, Decimal, LongDecimal],
Tool USING [Create, MakeSWsProc, MakeMsgSW, MakeFormSW],
ToolWindow USING [TransitionProcType],
Window USING [Handle],
Indirect USING [Close, NextValue, OpenSection],
PupTimeServer USING [PupTimeServerOff, PupTimeServerOn],
PupTimeServerOps USING [parmsOk, correction],
TimeServerOps USING [SetClockDrift, SetClockWobble, Start, StartReset, Stop],
Trouble USING [Bug];
TimeServersParmTajo: PROGRAM
IMPORTS
CmFile, FormSW, Inline, Process, Put, String,
System, TemporarySetGMT, Time, Token, Tool,
Indirect, PupTimeServer, PupTimeServerOps, TimeServerOps, Trouble =
BEGIN
msg, form: PUBLIC Window.Handle ← NIL;
Init: PROCEDURE =
BEGIN
herald: STRING = "Time Servers of 3-Nov-84 12:27:07"L;
[] ← Tool.Create[
name: herald, makeSWsProc: MakeSWs,
clientTransition: ClientTransition, initialState: inactive];
END;
FindParameters: PROCEDURE =
BEGIN
ok: BOOLEAN ← TRUE;
flakey, disableNSTimeServer: BOOLEAN ← FALSE;
dstSpecified, zoneSpecified: BOOLEAN ← FALSE;
driftSpecified, wobbleSpecified, correctionSpecified: BOOLEAN ← FALSE;
parms: System.LocalTimeParameters ← System.GetLocalTimeParameters[];
cmFile: CmFile.Handle;
Option: TYPE = MACHINE DEPENDENT{
correction(0), drift, wobble, dst, zone, flakey, disableNSTimeServer,
noMatch(StringLookUp.noMatch)};
DefinedOption: TYPE = Option [correction..disableNSTimeServer];
CheckType: PROCEDURE [h: CmFile.Handle, table: StringLookUp.TableDesc]
RETURNS [index: CARDINAL] = Indirect.NextValue;
MyNextValue: PROCEDURE [
h: CmFile.Handle,
table: LONG DESCRIPTOR FOR ARRAY DefinedOption OF LONG STRING]
RETURNS [index: Option] = LOOPHOLE[CheckType];
optionTable: ARRAY DefinedOption OF LONG STRING ← [
correction: "Correction"L, drift: "Drift"L, wobble: "Wobble"L,
dst: "DST"L, zone: "Zone"L, flakey: "Flakey"L,
disableNSTimeServer: "Disable NS Time Server"L];
PupTimeServerOps.parmsOk ← FALSE;
cmFile ← Indirect.OpenSection["TimeServer"L];
IF cmFile = NIL THEN
BEGIN
Message["Can't find [TimeServer] section in parameter file"L];
RETURN;
END;
DO
text: STRING = [200];
option: Option;
option ← MyNextValue[cmFile, DESCRIPTOR[optionTable] !
CmFile.TableError =>
BEGIN
IF name[0] # '; THEN Message["Unrecognized parameter: ", name];
RETRY;
END];
SELECT option FROM
noMatch => EXIT;
correction =>
BEGIN
correction: LONG INTEGER ← Token.LongDecimal[cmFile];
String.AppendLongDecimal[text, correction];
Message["The crystal correction is "L, text, " milliseconds per day"L];
SetCorrection[correction];
PupTimeServerOps.correction ← Inline.LowHalf[correction/1000];
correctionSpecified ← TRUE;
END;
drift =>
BEGIN
drift: CARDINAL ← Token.Decimal[cmFile];
String.AppendLongDecimal[text, drift];
Message["The clock drift is "L, text, " milliseconds per day"L];
TimeServerOps.SetClockDrift[86400, drift];
driftSpecified ← TRUE;
END;
wobble =>
BEGIN
wobble: CARDINAL ← Token.Decimal[cmFile];
String.AppendLongDecimal[text, wobble];
Message["The clock wobble is "L, text, " milliseconds per quarter day"L];
TimeServerOps.SetClockWobble[86400/4, wobble];
wobbleSpecified ← TRUE;
END;
dst => -- <begin day> <end day>
BEGIN
first: CARDINAL ← Token.Decimal[cmFile];
last: CARDINAL ← Token.Decimal[cmFile];
IF first # parms.beginDST OR last # parms.endDST THEN
BEGIN Message["The DST info on this disk is wrong"L]; ok ← FALSE; END;
String.AppendString[text, "DST: begin="L];
String.AppendDecimal[text, first];
String.AppendString[text, ", last="L];
String.AppendDecimal[text, last];
Message[text];
dstSpecified ← TRUE;
END;
zone => -- <sign> <hours>:<minutes>
BEGIN
hours: INTEGER ← Token.Decimal[cmFile];
minutes: CARDINAL ← Token.Decimal[cmFile];
westEast: System.WestEast ← IF hours < 0 THEN east ELSE west;
hours ← ABS[hours];
IF westEast # parms.direction OR hours # parms.zone
OR minutes # parms.zoneMinutes THEN
BEGIN
Message["The time zone info on this disk is wrong"L];
ok ← FALSE;
END;
String.AppendString[text, "ZONE: hours="L];
String.AppendDecimal[text, hours];
String.AppendString[
text, IF westEast = west THEN "(west)"L ELSE "(east)"L];
String.AppendString[text, ", minutes="L];
String.AppendDecimal[text, minutes];
Message[text];
zoneSpecified ← TRUE;
END;
flakey =>
BEGIN
IF Token.Boolean[cmFile] THEN
BEGIN
Message["This clock is Flakey"L];
Process.Detach[FORK Flakey[]];
flakey ← TRUE;
END
ELSE Message["This clock is not Flakey"L];
END;
disableNSTimeServer =>
BEGIN
IF Token.Boolean[cmFile] THEN
BEGIN
Message["Turning OFF the NS Time Server"L];
disableNSTimeServer ← TRUE;
END
ELSE Message["Didn't turn OFF the NS Time Server"L];
END;
ENDCASE => ERROR;
ENDLOOP;
Indirect.Close[cmFile];
ok ← ok AND dstSpecified AND zoneSpecified AND correctionSpecified
AND driftSpecified AND wobbleSpecified;
PupTimeServerOps.parmsOk ← ok AND ~flakey;
IF ok AND ~disableNSTimeServer THEN
TimeServerOps.Start[]
ELSE TimeServerOps.Stop[]; -- Created and Started by START Trap
END;
SetCorrection: PROCEDURE [arg: LONG INTEGER] =
BEGIN
IF arg # 0 THEN
BEGIN
secondsPerDay: LONG CARDINAL = 86400;
delta: LONG INTEGER ← arg;
bottom: LONG CARDINAL ← 1000*secondsPerDay;
IF ~TemporarySetGMT.adjustableClockRate THEN
Trouble.Bug["The clock on this machine is not adjustable"L];
-- Yetch, what a pile of crap
-- 640 works on D0s (or at least some of them)
-- Beware, Dicentras need a smaller number: 274
UNTIL ABS[delta] < 640 DO -- Avoid overflow
delta ← delta/2;
bottom ← bottom/2;
ENDLOOP;
TemporarySetGMT.SetClockRate[bottom, bottom + delta];
END;
END;
Message: PROCEDURE [one, two, three: LONG STRING ← NIL] =
BEGIN
text: STRING = [100];
Time.AppendCurrent[text];
String.AppendString[text, " TimeServer: "L];
String.AppendString[text, one];
IF two # NIL THEN String.AppendString[text, two];
IF three # NIL THEN String.AppendString[text, three];
LogString[text];
END;
UpdatePicture: PUBLIC PROCEDURE =
BEGIN
IF form = NIL THEN RETURN;
FormSW.Display[form];
END;
Start: FormSW.ProcType =
BEGIN
PupTimeServer.PupTimeServerOn[];
END;
Stop: FormSW.ProcType =
BEGIN
PupTimeServer.PupTimeServerOff[];
END;
NSReset: FormSW.ProcType =
BEGIN
where: System.NetworkAddress = System.nullNetworkAddress;
TimeServerOps.StartReset[where];
END;
LogString: PROCEDURE [text: LONG STRING] =
BEGIN
String.AppendChar[text, '.];
String.AppendChar[text, Ascii.CR];
Put.Text[NIL, text];
IF msg # NIL THEN Put.Text[msg, text];
END;
MakeSWs: Tool.MakeSWsProc =
BEGIN
msg ← Tool.MakeMsgSW[window: window, lines: 5];
form ← Tool.MakeFormSW[window: window, formProc: MakeForm];
END;
startIX: CARDINAL = 0;
stopIX: CARDINAL = 1;
MakeForm: FormSW.ClientItemsProcType =
BEGIN
nParams: CARDINAL = 4;
items ← FormSW.AllocateItemDescriptor[nParams];
items[0] ← FormSW.CommandItem[
tag: "PupStart"L, proc: Start, place: FormSW.newLine];
items[1] ← FormSW.CommandItem[tag: "PupStop"L, proc: Stop];
items[2] ← FormSW.NumberItem[
tag: "Correction"L, value: @PupTimeServerOps.correction, boxWidth: 50,
place: FormSW.newLine, readOnly: TRUE];
items[3] ← FormSW.CommandItem[
tag: "NS Reset"L, proc: NSReset, place: FormSW.newLine];
RETURN[items, TRUE];
END;
ClientTransition: ToolWindow.TransitionProcType =
BEGIN
IF new = inactive THEN msg ← form ← NIL;
SELECT TRUE FROM
old = inactive =>
BEGIN
END;
new = inactive =>
BEGIN
END;
ENDCASE;
END;
Flakey: PROCEDURE =
BEGIN
halfHour: Process.Ticks = Process.SecondsToTicks[30*60];
DO
Process.Pause[halfHour];
TimeServerOps.StartReset[System.nullNetworkAddress];
ENDLOOP;
END;
-- Initialization
Init[];
FindParameters[];
PupTimeServer.PupTimeServerOn[];
END.