-- Copyright (C) 1984 by Xerox Corporation. All rights reserved. -- TestTranslation.mesa, HGM, 4-Nov-84 8:57:31 DIRECTORY AddressTranslation USING [Error, PrintError, StringToNetworkAddress], Format USING [HostNumber, StringProc], FormSW USING [ AllocateItemDescriptor, ClientItemsProcType, CommandItem, ItemHandle, newLine, ProcType, StringItem], Heap USING [systemZone], MsgSW USING [Post], Put USING [Char, CR, Line, NetworkAddress, Text], Runtime USING [GetBcdTime], SpecialSystem USING [GetProcessorID], String USING [AppendString], System USING [HostNumber, NetworkAddress, nullSocketNumber, SocketNumber], Time USING [Append, Unpack], Tool USING [ Create, UnusedLogName, MakeFormSW, MakeFileSW, MakeMsgSW, MakeSWsProc], ToolWindow USING [TransitionProcType], Unformat USING [Error, HostNumber, NetworkAddress], Window USING [Handle], Buffer USING [NSBuffer], NSTypes USING [], NSConstants USING [pupAddressTranslation], PupDefs USING [AppendPupAddress, PupAddress], Socket USING [ AssignNetworkAddress, BroadcastAddressFromSocket, ChannelHandle, Create, Delete, GetPacket, GetPacketBytes, GetSendBuffer, GetSource, PutPacket, ReturnBuffer, SetDestination, SetPacketWords, SetWaitTime, TimeOut]; TestTranslation: PROGRAM IMPORTS AddressTranslation, Format, FormSW, Heap, MsgSW, Put, Runtime, SpecialSystem, String, Time, Tool, Unformat, Socket, PupDefs = BEGIN z: UNCOUNTED ZONE = Heap.systemZone; -- From PupAddressTranslationServer.mesa translationRequest: CARDINAL = 1; translationResponse: CARDINAL = 2; translationError: CARDINAL = 3; -- global variable declarations msg, log, form: Window.Handle ← NIL; machine, server: LONG STRING ← NIL; localAddr: System.NetworkAddress; Init: PROCEDURE = BEGIN herald: STRING = [100]; String.AppendString[herald, "TestTranslation of "L]; Time.Append[herald, Time.Unpack[Runtime.GetBcdTime[]]]; [] ← Tool.Create[ name: herald, makeSWsProc: MakeSWs, clientTransition: Transition]; END; MakeSWs: Tool.MakeSWsProc = BEGIN logFileName: STRING = [40]; msg ← Tool.MakeMsgSW[window: window, lines: 1]; form ← Tool.MakeFormSW[window: window, formProc: MakeItemArray]; Tool.UnusedLogName[logFileName, "TestTranslation.log$"L]; log ← Tool.MakeFileSW[window: window, name: logFileName]; END; MakeItemArray: FormSW.ClientItemsProcType = BEGIN nItems: CARDINAL = 4; i: INTEGER ← -1; items ← FormSW.AllocateItemDescriptor[nItems]; items[i ← i + 1] ← FormSW.CommandItem[ tag: "LocalBroadcast"L, place: FormSW.newLine, proc: LocalBroadcast]; items[i ← i + 1] ← FormSW.CommandItem[tag: "AskRemote"L, proc: AskRemote]; items[i ← i + 1] ← FormSW.StringItem[tag: "Server"L, string: @server, inHeap: TRUE]; items[i ← i + 1] ← FormSW.StringItem[ tag: "Machine"L, string: @machine, place: FormSW.newLine, inHeap: TRUE]; IF (i + 1) # nItems THEN ERROR; RETURN[items, TRUE]; END; Transition: ToolWindow.TransitionProcType = BEGIN SELECT TRUE FROM old = inactive => BEGIN AppendMe: PROCEDURE [s: LONG STRING, clientData: LONG POINTER] = BEGIN String.AppendString[machine, s]; END; localAddr ← Socket.AssignNetworkAddress[]; server ← z.NEW[StringBody[40]]; String.AppendString[server, "0#*#"L]; machine ← z.NEW[StringBody[40]]; Format.HostNumber[AppendMe, LOOPHOLE[SpecialSystem.GetProcessorID[]], octal]; END; new = inactive => BEGIN z.FREE[@server]; z.FREE[@machine]; END; ENDCASE; END; LocalBroadcast: FormSW.ProcType = BEGIN him: System.NetworkAddress; who: System.HostNumber; soc: Socket.ChannelHandle; where: LONG POINTER TO System.HostNumber; b: Buffer.NSBuffer; errFlag, hit: BOOLEAN ← FALSE; MsgSW.Post[msg, ""L]; who ← Unformat.HostNumber[machine ! Unformat.Error => BEGIN Put.Line[msg, "Can't parse Machine"L]; errFlag ← TRUE; CONTINUE; END]; IF errFlag THEN RETURN; MsgSW.Post[msg, "Here we go...."L]; soc ← Socket.Create[local: localAddr, receive: 10]; Socket.SetWaitTime[soc, 500]; -- milli-seconds him ← Socket.BroadcastAddressFromSocket[NSConstants.pupAddressTranslation]; FOR i: CARDINAL IN [0..10) UNTIL hit DO b ← Socket.GetSendBuffer[soc]; Socket.SetDestination[b, him]; b.ns.packetType ← pupAddrTransPacket; b.ns.nsWords[0] ← b.ns.nsWords[1] ← i; b.ns.nsWords[2] ← translationRequest; Socket.SetPacketWords[b, 3 + SIZE[System.HostNumber]]; where ← LOOPHOLE[@b.ns.nsWords[3]]; where↑ ← who; Socket.PutPacket[soc, b]; DO b ← Socket.GetPacket[ soc ! Socket.TimeOut => BEGIN IF ~hit THEN Put.Char[log, '?]; EXIT; END]; IF him # Socket.GetSource[b] THEN BEGIN Put.Text[log, "Response from: "L]; Put.NetworkAddress[log, Socket.GetSource[b], octal]; Put.Line[log, NIL]; END; SELECT TRUE FROM (b.ns.nsWords[2] = translationError) => BEGIN n: CARDINAL ← Socket.GetPacketBytes[b]; text: LONG POINTER TO PACKED ARRAY [0..0) OF CHARACTER; text ← LOOPHOLE[@b.ns.nsWords[0]]; FOR i: CARDINAL IN [6..n) DO Put.Char[log, text[i]]; ENDLOOP; Put.CR[log]; END; Socket.GetPacketBytes[b] # 2*(3 + SIZE[PupDefs.PupAddress]) OR (b.ns.nsWords[2] # translationResponse) => BEGIN Put.Char[log, '#]; END; ENDCASE => BEGIN -- the response we were looking for temp: STRING = [50]; answer: LONG POINTER TO PupDefs.PupAddress; answer ← LOOPHOLE[@b.ns.nsWords[3]]; hit ← TRUE; Put.Text[log, "Answer: "L]; PupDefs.AppendPupAddress[temp, answer↑]; Put.Line[log, temp]; Put.CR[log]; END; Socket.ReturnBuffer[b]; ENDLOOP; ENDLOOP; Put.CR[log]; Socket.Delete[soc]; MsgSW.Post[msg, ""L]; END; AskRemote: FormSW.ProcType = BEGIN him: System.NetworkAddress; who: System.HostNumber; soc: Socket.ChannelHandle; where: LONG POINTER TO System.HostNumber; b: Buffer.NSBuffer; errFlag, hit: BOOLEAN ← FALSE; MsgSW.Post[msg, ""L]; him ← GetAddress[server, NSConstants.pupAddressTranslation ! Trouble => BEGIN Put.Line[msg, reason]; errFlag ← TRUE; CONTINUE; END]; who ← Unformat.HostNumber[machine ! Unformat.Error => BEGIN Put.Line[msg, "Can't parse Machine"L]; errFlag ← TRUE; CONTINUE; END]; IF errFlag THEN RETURN; MsgSW.Post[msg, "Here we go...."L]; soc ← Socket.Create[local: localAddr, receive: 10]; Socket.SetWaitTime[soc, 5000]; -- milli-seconds FOR i: CARDINAL IN [0..10) UNTIL hit DO b ← Socket.GetSendBuffer[soc]; Socket.SetDestination[b, him]; b.ns.packetType ← pupAddrTransPacket; b.ns.nsWords[0] ← b.ns.nsWords[1] ← i; b.ns.nsWords[2] ← translationRequest; Socket.SetPacketWords[b, 3 + SIZE[System.HostNumber]]; where ← LOOPHOLE[@b.ns.nsWords[3]]; where↑ ← who; Socket.PutPacket[soc, b]; DO b ← Socket.GetPacket[ soc ! Socket.TimeOut => BEGIN IF ~hit THEN Put.Char[log, '?]; EXIT; END]; IF him # Socket.GetSource[b] THEN BEGIN Put.Text[log, "Response from: "L]; Put.NetworkAddress[log, Socket.GetSource[b], octal]; Put.Line[log, NIL]; END; SELECT TRUE FROM (b.ns.nsWords[2] = translationError) => BEGIN n: CARDINAL ← Socket.GetPacketBytes[b]; text: LONG POINTER TO PACKED ARRAY [0..0) OF CHARACTER; text ← LOOPHOLE[@b.ns.nsWords[0]]; FOR i: CARDINAL IN [6..n) DO Put.Char[log, text[i]]; ENDLOOP; Put.CR[log]; END; Socket.GetPacketBytes[b] # 2*(3 + SIZE[PupDefs.PupAddress]) OR (b.ns.nsWords[2] # translationResponse) => BEGIN Put.Char[log, '#]; END; ENDCASE => BEGIN -- the response we were looking for temp: STRING = [50]; answer: LONG POINTER TO PupDefs.PupAddress; answer ← LOOPHOLE[@b.ns.nsWords[3]]; hit ← TRUE; Put.Text[log, "Answer: "L]; PupDefs.AppendPupAddress[temp, answer↑]; Put.Line[log, temp]; Put.CR[log]; END; Socket.ReturnBuffer[b]; ENDLOOP; ENDLOOP; Put.CR[log]; Socket.Delete[soc]; MsgSW.Post[msg, ""L]; END; Trouble: ERROR [reason: LONG STRING] = CODE; GetAddress: PROCEDURE [host: LONG STRING, socket: System.SocketNumber] RETURNS [addr: System.NetworkAddress] = BEGIN localFailed: BOOLEAN ← FALSE; IF host = NIL THEN ERROR Trouble["NIL => Address Fault"L]; addr ← Unformat.NetworkAddress[host, octal ! Unformat.Error => BEGIN localFailed ← TRUE; CONTINUE; END ]; IF localFailed THEN BEGIN addr ← AddressTranslation.StringToNetworkAddress[host ! AddressTranslation.Error => BEGIN temp: STRING = [200]; proc: Format.StringProc = {String.AppendString[temp, s]}; AddressTranslation.PrintError[errorRecord, proc]; ERROR Trouble[temp]; END].addr; addr.socket ← socket; -- CH returns trash in socket END; IF addr.socket = System.nullSocketNumber THEN addr.socket ← socket; END; Init[]; -- this gets string out of global frame END...