-- File: TestTimeServer.mesa -- HGM, March 14, 1981 1:45 PM DIRECTORY AddressTranslation USING [AppendNetworkAddress, StringToNetworkAddress], BufferDefs USING [BufferAccessHandle, OisBuffer], FormSW USING [ AllocateItemDescriptor, ClientItemsProcType, CommandItem, ItemHandle, newLine, ProcType, StringItem], InlineDefs USING [BcplLongNumber, BcplToMesaLongNumber], MsgSW USING [Post], OISCP USING [ OiscpPackageDestroy, OiscpPackageMake, GetFreeSendOisBufferFromPool, ReturnFreeOisBuffer, GetOisPacketTextLength, SetOisPacketTextLength], OISCPConstants USING [unknownSocketID, timeServerSocket], Put USING [Char, CR, Date, Decimal, Line, Text], SpecialSystem USING [NetworkAddress], Socket USING [ Abort, AssignNetworkAddress, Create, Delete, GetPacket, PutPacket, SetWaitTime, TimeOut, TransferStatus], SocketInternal USING [GetBufferPool, SocketHandle], Storage USING [Free, FreeStringNil, String], String USING [AppendString], System USING [], Time USING [Packed], TimeDefs USING [WestEast], Tool USING [ Create, UnusedLogName, MakeFormSW, MakeFileSW, MakeMsgSW, MakeSWsProc], ToolWindow USING [TransitionProcType], Window USING [Handle]; TestTimeServer: PROGRAM IMPORTS FormSW, InlineDefs, MsgSW, Put, String, AddressTranslation, OISCP, Socket, SocketInternal, Storage, Tool EXPORTS Socket, System SHARES BufferDefs = BEGIN -- From TimeServer.mesa timeRequest: CARDINAL = 1; timeResponse: CARDINAL = 2; -- EXPORTED TYPE(S) NetworkAddress: PUBLIC TYPE = SpecialSystem.NetworkAddress; ChannelHandle: PUBLIC TYPE = SocketInternal.SocketHandle; -- global variable declarations msg, log, form: Window.Handle _ NIL; remoteAddress: STRING _ NIL; localAddr: SpecialSystem.NetworkAddress; Init: PROCEDURE = BEGIN [] _ Tool.Create[ name: "TestTimeServer of March 14, 1981"L, makeSWsProc: MakeThisTool, clientTransition: Transition]; END; MakeThisTool: Tool.MakeSWsProc = BEGIN logFileName: STRING = [40]; msg _ Tool.MakeMsgSW[window: window, lines: 1]; form _ Tool.MakeFormSW[window: window, formProc: MakeItemArray]; Tool.UnusedLogName[logFileName, "TestTimeServer.log$"L]; log _ Tool.MakeFileSW[window: window, name: logFileName]; END; MakeItemArray: FormSW.ClientItemsProcType = BEGIN nItems: CARDINAL = 2; i: INTEGER _ -1; items _ FormSW.AllocateItemDescriptor[nItems]; items[i _ i + 1] _ FormSW.CommandItem[ tag: "Poke"L, place: FormSW.newLine, proc: Poke]; items[i _ i + 1] _ FormSW.StringItem[ tag: "RemoteAddress"L, string: @remoteAddress, inHeap: TRUE]; IF (i + 1) # nItems THEN ERROR; RETURN[items, TRUE]; END; Transition: ToolWindow.TransitionProcType = BEGIN IF old = inactive THEN -- tool is becomming active BEGIN OISCP.OiscpPackageMake[]; localAddr _ Socket.AssignNetworkAddress[]; remoteAddress _ Storage.String[40]; String.AppendString[remoteAddress,"0#*#"L]; END ELSE IF new = inactive THEN BEGIN remoteAddress _ Storage.FreeStringNil[remoteAddress]; OISCP.OiscpPackageDestroy[]; END; END; Poke: FormSW.ProcType = BEGIN remoteAddr: SpecialSystem.NetworkAddress; cH: ChannelHandle; myBufferAccessHandle: BufferDefs.BufferAccessHandle; b: BufferDefs.OisBuffer; status: Socket.TransferStatus; errFlag, hit: BOOLEAN _ FALSE; MsgSW.Post[msg, ""L]; remoteAddr _ AddressTranslation.StringToNetworkAddress[remoteAddress ! ANY => BEGIN MsgSW.Post[msg, "RemoteAddress is incorrectly specified; try again."L]; errFlag _ TRUE; CONTINUE; END]; IF errFlag THEN RETURN; IF remoteAddr.socket=OISCPConstants.unknownSocketID THEN remoteAddr.socket _ OISCPConstants.timeServerSocket; cH _ Socket.Create[localAddr]; myBufferAccessHandle _ SocketInternal.GetBufferPool[cH]; Socket.SetWaitTime[cH, 1500]; -- milli-seconds FOR i: CARDINAL IN [0..10) UNTIL hit DO b _ OISCP.GetFreeSendOisBufferFromPool[myBufferAccessHandle]; OISCP.SetOisPacketTextLength[b, 2*3]; b.ois.transCntlAndPktTp.packetType _ echo; b.ois.destination _ remoteAddr; b.ois.oisWords[0] _ b.ois.oisWords[1] _ i; b.ois.oisWords[2] _ timeRequest; Socket.PutPacket[cH, b]; DO b _ Socket.GetPacket[ cH ! Socket.TimeOut => BEGIN IF ~hit THEN Put.Char[log, '?]; EXIT; END]; status _ LOOPHOLE[b.status]; SELECT TRUE FROM (status # goodCompletion) => BEGIN -- some kind of error occurred --PrintSocketEchoError[b, status]; Put.Char[log, 'e]; END; OISCP.GetOisPacketTextLength[b] # 2*(3 + SIZE[WireTimeFormat]) OR (b.ois.oisWords[2] # timeResponse) => BEGIN Put.Char[log, '#]; END; ENDCASE => BEGIN -- the response we were looking for wtf: LONG POINTER TO WireTimeFormat = LOOPHOLE[@b.ois.oisWords[3]]; now: Time.Packed _ LOOPHOLE[InlineDefs.BcplToMesaLongNumber[wtf.time]]; temp: STRING = [50]; hit _ TRUE; Put.Text[log, "Response from: "L]; AddressTranslation.AppendNetworkAddress[temp, b.ois.source]; Put.Line[log, temp]; Put.Text[log, "Time: "L]; Put.Date[log, now, full]; Put.Text[log, ", Zone: "L]; Put.Text[log, SELECT wtf.zoneS FROM west => "W"L, east => "E"L, ENDCASE => ERROR]; Put.Decimal[log, wtf.zoneH]; Put.Char[log, ':]; Put.Decimal[log, wtf.zoneM]; Put.Text[log, ", DST: "L]; Put.Decimal[log, wtf.beginDST]; Put.Text[log, ", "L]; Put.Decimal[log, wtf.endDST]; Put.CR[log]; END; OISCP.ReturnFreeOisBuffer[b]; ENDLOOP; ENDLOOP; Put.CR[log]; Socket.Abort[cH]; Socket.Delete[cH]; MsgSW.Post[msg, ""L]; END; WireTimeFormat: TYPE = RECORD [ time: InlineDefs.BcplLongNumber, -- word 0 and 1 zoneS: TimeDefs.WestEast, -- start of word 2 zoneH: [0..177B], zoneM: [0..377B], -- end of word 2 beginDST: WORD, -- word 3 endDST: WORD, -- word 4 spare: ARRAY [5..8) OF WORD _ ALL[0]]; Init[]; -- this gets string out of global frame END...