-- 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.