-- File: TestTranslation.mesa - last edit:
-- AOF 4-Feb-88 11:14:50
-- HGM 25-Jun-85 15:37:15
-- Copyright (C) 1984, 1985, 1988 by Xerox Corporation. All rights reserved.
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],
NSBuffer USING [Body, Buffer],
NSTypes USING [],
NSConstants USING [pupAddressTranslation],
PupDefs USING [AppendPupAddress, PupAddress],
Socket USING [
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;
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;
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: NSBuffer.Buffer;
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[socket: System.nullSocketNumber, receive: 10];
Socket.SetWaitTime[soc, 500]; -- milli-seconds
him ← Socket.BroadcastAddressFromSocket[NSConstants.pupAddressTranslation];
FOR i: CARDINAL IN [0..10) UNTIL hit DO
body: NSBuffer.Body ← (b ← Socket.GetSendBuffer[soc]).ns;
Socket.SetDestination[b, him];
body.packetType ← pupAddrTransPacket;
body.nsWords[0] ← body.nsWords[1] ← i;
body.nsWords[2] ← translationRequest;
Socket.SetPacketWords[b, 3 + SIZE[System.HostNumber]];
where ← LOOPHOLE[@body.nsWords[3]];
where↑ ← who;
Socket.PutPacket[soc, b];
DO
b ← Socket.GetPacket[
soc ! Socket.TimeOut => {IF ~hit THEN Put.Char[log, '?]; EXIT}];
body ← b.ns;
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
(body.nsWords[2] = translationError) =>
BEGIN
n: CARDINAL ← Socket.GetPacketBytes[b];
text: LONG POINTER TO PACKED ARRAY [0..0) OF CHARACTER;
text ← LOOPHOLE[@body.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 (body.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[@body.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: NSBuffer.Buffer;
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[socket: System.nullSocketNumber, receive: 10];
Socket.SetWaitTime[soc, 5000]; -- milli-seconds
FOR i: CARDINAL IN [0..10) UNTIL hit DO
body: NSBuffer.Body ← (b ← Socket.GetSendBuffer[soc]).ns;
Socket.SetDestination[b, him];
body.packetType ← pupAddrTransPacket;
body.nsWords[0] ← body.nsWords[1] ← i;
body.nsWords[2] ← translationRequest;
Socket.SetPacketWords[b, 3 + SIZE[System.HostNumber]];
where ← LOOPHOLE[@body.nsWords[3]];
where↑ ← who;
Socket.PutPacket[soc, b];
DO
b ← Socket.GetPacket[
soc ! Socket.TimeOut => {IF ~hit THEN Put.Char[log, '?]; EXIT}];
body ← b.ns;
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
(body.nsWords[2] = translationError) =>
BEGIN
n: CARDINAL ← Socket.GetPacketBytes[b];
text: LONG POINTER TO PACKED ARRAY [0..0) OF CHARACTER;
text ← LOOPHOLE[@body.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 (body.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[@body.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...