-- Copyright (C) 1984, 1985 by Xerox Corporation. All rights reserved. -- OthelloOpsTime.mesa, HGM, 3-Jul-85 0:57:47 DIRECTORY Buffer USING [NSBuffer], Environment, NSConstants USING [timeServerSocket], NSTypes USING [wordsPerExchangeHeader], OthelloOps USING [TimeServerErrorType], ProcessorFace USING [GreenwichMeanTime, SetGreenwichMeanTime], Socket USING [ BroadcastAddressFromSocket, ChannelHandle, Create, Delete, GetPacket, GetPacketBytes, GetSendBuffer, BroadcastPacketToAllConnectedNets, ReturnBuffer, SetDestination, SetPacketWords, SetWaitTime, TimeOut], System USING [ gmtEpoch, GetGreenwichMeanTime, GreenwichMeanTime, LocalTimeParameters, NetworkAddress, nullSocketNumber, WestEast], TimeServerFormat USING [TSPacket, WireToGMT, Version]; OthelloOpsTime: PROGRAM IMPORTS ProcessorFace, Socket, System, TimeServerFormat EXPORTS OthelloOps = BEGIN IsTimeValid: PUBLIC PROC RETURNS [valid: BOOLEAN] = { RETURN[System.GetGreenwichMeanTime[]#System.gmtEpoch]}; SetProcessorTime: PUBLIC PROC [time: System.GreenwichMeanTime] = { ProcessorFace.SetGreenwichMeanTime[time]}; TimeServerError: PUBLIC ERROR [error: OthelloOps.TimeServerErrorType] = CODE; GetTimeFromTimeServer: PUBLIC PROC RETURNS[ serverTime: System.GreenwichMeanTime, serverLTPs: System.LocalTimeParameters] = { isValid: BOOLEAN; [isValid, serverTime, serverLTPs] ← GetNSTime[]; IF ~isValid THEN ERROR TimeServerError[noResponse]; RETURN}; GetNSTime: PROC RETURNS [ valid: BOOLEAN ← FALSE, time: System.GreenwichMeanTime, ltp: System.LocalTimeParameters] = BEGIN wordsInRequest: CARDINAL = SIZE[timeRequest TimeServerFormat.TSPacket]; wordsInAnswer: CARDINAL = SIZE[timeResponse TimeServerFormat.TSPacket]; request: LONG POINTER TO timeRequest TimeServerFormat.TSPacket; answer: LONG POINTER TO timeResponse TimeServerFormat.TSPacket; soc: Socket.ChannelHandle; soc ← Socket.Create[socket: System.nullSocketNumber, receive: 1]; Socket.SetWaitTime[soc, 700]; -- milli-seconds FOR i: CARDINAL IN [0..3) DO him: System.NetworkAddress ← Socket.BroadcastAddressFromSocket[ NSConstants.timeServerSocket]; b: Buffer.NSBuffer ← Socket.GetSendBuffer[soc]; Socket.SetDestination[b, him]; b.ns.packetType ← packetExchange; b.ns.exchangeID ← [0, i]; b.ns.exchangeType ← timeService; request ← LOOPHOLE[@b.ns.exchangeBody]; request↑ ← [TimeServerFormat.Version, timeRequest[]]; Socket.SetPacketWords[b, NSTypes.wordsPerExchangeHeader + wordsInRequest]; Socket.BroadcastPacketToAllConnectedNets[soc, b]; DO b ← Socket.GetPacket[soc ! Socket.TimeOut => EXIT]; answer ← LOOPHOLE[@b.ns.exchangeBody]; SELECT TRUE FROM b.ns.packetType # packetExchange OR Socket.GetPacketBytes[b] # 2*(NSTypes.wordsPerExchangeHeader + wordsInAnswer) OR (b.ns.exchangeType # timeService) OR answer.version # TimeServerFormat.Version OR answer.type # timeResponse => NULL; ENDCASE => BEGIN OPEN t: LOOPHOLE[time, Environment.LongNumber]; valid ← TRUE; time ← TimeServerFormat.WireToGMT[answer.time]; ltp ← [ zone: answer.zoneH, direction: answer.zoneS, zoneMinutes: answer.zoneM, beginDST: answer.beginDST, endDST: answer.endDST]; Socket.ReturnBuffer[b]; GOTO Done; END; Socket.ReturnBuffer[b]; ENDLOOP; REPEAT Done => NULL; ENDLOOP; Socket.Delete[soc]; END; END....