-- File: NameLookupTool.mesa, Last Edit: HGM January 23, 1981 12:32 AM -- Please don't forget to update the herald.... DIRECTORY InlineDefs USING [BcplToMesaLongNumber], Storage USING [Node, String, FreeNodeNil, FreeString], String USING [AppendString, AppendNumber], Time USING [AppendCurrent], Event USING [Item, Reason, AddNotifier], FormSW USING [ ClientItemsProcType, ProcType, AllocateItemDescriptor, newLine, CommandItem, StringItem], MsgSW USING [Post], Put USING [Char, CR, Text, Line, LongDecimal], Tool USING [Create, MakeSWsProc, MakeMsgSW, MakeFormSW, MakeFileSW], ToolWindow USING [TransitionProcType], Window USING [Handle], NameServerDefs USING [nameStatsRequest, nameStatsReply, NameStatsEntry], PupDefs USING [ PupPackageMake, PupPackageDestroy, GetFreePupBuffer, ReturnFreePupBuffer, PupBuffer, PupSocket, PupSocketDestroy, PupSocketMake, SecondsToTocks, GetPupContentsBytes, SetPupContentsWords, MoveStringBodyToPupBuffer, AppendPupAddress, AppendErrorPup, GetPupAddress, PupNameTrouble], PupTypes USING [PupAddress, fillInNetID, fillInSocketID, allHosts, miscSrvSoc]; NameLookupTool: PROGRAM IMPORTS InlineDefs, Storage, String, Time, Event, FormSW, MsgSW, Put, Tool, PupDefs = BEGIN OPEN PupDefs, PupTypes; msg, form, log: Window.Handle; eventItem: Event.Item ← [eventMask: 177777B, eventProc: Broom]; data: POINTER TO Data ← NIL; Data: TYPE = RECORD [ where: PupAddress, target: STRING, name: STRING, address: STRING]; Init: PROCEDURE = BEGIN [] ← Tool.Create[ name: "Name Lookup of November 16, 1980"L, makeSWsProc: MakeSWs, clientTransition: ClientTransition]; Event.AddNotifier[@eventItem]; END; NameToAddress: FormSW.ProcType = BEGIN soc: PupSocket; b: PupBuffer; hit: BOOLEAN ← FALSE; IF data.name = NIL OR data.name.length = 0 THEN BEGIN MsgSW.Post[msg, "Name needed"L]; RETURN; END; WriteCR[]; WriteCurrentDateAndTime[]; WriteString[" Name=>Address "L]; IF ~FindPath[] THEN RETURN; soc ← PupSocketMake[PupTypes.fillInSocketID, data.where, SecondsToTocks[2]]; THROUGH [0..10) UNTIL hit DO b ← GetFreePupBuffer[]; b.pupType ← nameLookup; MoveStringBodyToPupBuffer[b, data.name]; b.pupID ← [0, 0]; soc.put[b]; UNTIL (b ← soc.get[]) = NIL DO IF data.where # b.source THEN BEGIN WriteString["Reply from: "L]; PrintPupAddress[@b.source]; WriteCR[]; END; SELECT b.pupType FROM nameIs => BEGIN i, n: CARDINAL; addresses: LONG POINTER TO ARRAY [0..0) OF PupAddress ← LOOPHOLE[@b.pupBody]; hit ← TRUE; WriteString[data.name]; WriteString[" => "L]; n ← GetPupContentsBytes[b]/(2*SIZE[PupAddress]); FOR i IN [0..n) DO IF i # 0 THEN WriteString[", "L]; PrintPupAddress[@addresses[i]]; ENDLOOP; END; nameError => BEGIN hit ← TRUE; WriteString[data.name]; WriteString[" => ERROR: "L]; PrintBodyAsText[b]; END; ENDCASE => PrintErrorPup[b]; WriteCR[]; ReturnFreePupBuffer[b]; ENDLOOP; IF ~hit THEN MsgSW.Post[msg, "No Response that try."L]; ENDLOOP; PupSocketDestroy[soc]; END; AddressToName: FormSW.ProcType = BEGIN soc: PupSocket; b: PupBuffer; a: PupAddress ← [, , [0, 0]]; hit: BOOLEAN ← FALSE; IF data.address = NIL OR data.address.length = 0 THEN BEGIN MsgSW.Post[msg, "Address needed"L]; RETURN; END; GetPupAddress[ @a, data.address ! PupNameTrouble => BEGIN MsgSW.Post[msg, e]; WriteLine[e]; GOTO Trouble; END]; WriteCR[]; WriteCurrentDateAndTime[]; WriteString[" Address=>Name "L]; IF ~FindPath[] THEN RETURN; soc ← PupSocketMake[PupTypes.fillInSocketID, data.where, SecondsToTocks[2]]; THROUGH [0..10) UNTIL hit DO b ← GetFreePupBuffer[]; b.pupType ← addressLookup; b.pupID ← [0, 0]; b.address ← a; SetPupContentsWords[b, SIZE[PupAddress]]; soc.put[b]; UNTIL (b ← soc.get[]) = NIL DO IF data.where # b.source THEN BEGIN WriteString["Reply from: "L]; PrintPupAddress[@b.source]; WriteCR[]; END; SELECT b.pupType FROM addressIs => BEGIN hit ← TRUE; WriteString[data.address]; WriteString[" => "L]; PrintBodyAsText[b]; END; nameError => BEGIN hit ← TRUE; WriteString[data.address]; WriteString[" => ERROR: "L]; PrintBodyAsText[b]; END; ENDCASE => PrintErrorPup[b]; WriteLine["."L]; ReturnFreePupBuffer[b]; ENDLOOP; IF ~hit THEN MsgSW.Post[msg, "No Response that try."L]; ENDLOOP; PupSocketDestroy[soc]; EXITS Trouble => NULL; END; Stats: FormSW.ProcType = BEGIN soc: PupSocket; b: PupBuffer; hit: BOOLEAN ← FALSE; WriteCR[]; WriteCurrentDateAndTime[]; WriteString[" Pup Name Server Statistics "L]; IF ~FindPath[] THEN RETURN; soc ← PupSocketMake[PupTypes.fillInSocketID, data.where, SecondsToTocks[2]]; THROUGH [0..10) UNTIL hit DO b ← GetFreePupBuffer[]; b.pupType ← NameServerDefs.nameStatsRequest; b.pupID ← [0, 0]; b.pupWords[0] ← 0; SetPupContentsWords[b, 0]; soc.put[b]; UNTIL (b ← soc.get[]) = NIL DO IF data.where # b.source THEN BEGIN WriteString["Reply from: "L]; PrintPupAddress[@b.source]; WriteCR[]; END; SELECT b.pupType FROM NameServerDefs.nameStatsReply => BEGIN nse: LONG POINTER TO NameServerDefs.NameStatsEntry; hit ← TRUE; nse ← LOOPHOLE[@b.pupWords]; PrintInfo[ "Requests"L, InlineDefs.BcplToMesaLongNumber[nse.nameRequests]]; PrintInfo[ "Directories sent"L, InlineDefs.BcplToMesaLongNumber[ nse.directoriesSend]]; PrintInfo[ "Cache hits"L, InlineDefs.BcplToMesaLongNumber[nse.cacheHits]]; PrintInfo[ "Cache misses"L, InlineDefs.BcplToMesaLongNumber[nse.cacheMisses]]; END; ENDCASE => PrintErrorPup[b]; WriteCR[]; ReturnFreePupBuffer[b]; ENDLOOP; IF ~hit THEN MsgSW.Post[msg, "No Response that try."L]; ENDLOOP; PupSocketDestroy[soc]; END; PrintInfo: PROCEDURE [s: STRING, n: LONG CARDINAL] = BEGIN IF n = 0 THEN RETURN; WriteString[s]; WriteString[" = "L]; WriteLongDecimal[n]; WriteLine["."L]; END; Version: FormSW.ProcType = BEGIN soc: PupSocket; b: PupBuffer; hit: BOOLEAN ← FALSE; WriteCR[]; WriteCurrentDateAndTime[]; WriteString[" Pup Network Directory Version "L]; IF ~FindPath[] THEN RETURN; soc ← PupSocketMake[PupTypes.fillInSocketID, data.where, SecondsToTocks[2]]; THROUGH [0..10) UNTIL hit DO b ← GetFreePupBuffer[]; b.pupType ← netDirVersion; b.pupID ← [0, 0]; b.pupWords[0] ← 0; SetPupContentsWords[b, 1]; soc.put[b]; UNTIL (b ← soc.get[]) = NIL DO IF data.where # b.source THEN BEGIN WriteString["Reply from: "L]; PrintPupAddress[@b.source]; WriteCR[]; END; SELECT b.pupType FROM netDirVersion => BEGIN hit ← TRUE; WriteString["Pup Network Directory version is "L]; WriteDecimal[b.pupWords[0]]; END; ENDCASE => PrintErrorPup[b]; WriteLine["."L]; ReturnFreePupBuffer[b]; ENDLOOP; IF ~hit THEN MsgSW.Post[msg, "No Response that try."L]; ENDLOOP; PupSocketDestroy[soc]; END; FindPath: PROCEDURE RETURNS [BOOLEAN] = BEGIN OPEN data; data.where ← [fillInNetID, allHosts, miscSrvSoc]; IF data.target = NIL OR data.target.length = 0 THEN BEGIN WriteLine["via broadcasting on local net(s)."L]; RETURN[TRUE]; END ELSE BEGIN WriteString["from "L]; END; WriteString[target]; WriteChar['=]; GetPupAddress[ @where, target ! PupNameTrouble => BEGIN MsgSW.Post[msg, e]; WriteLine[e]; GOTO Trouble; END]; PrintPupAddress[@where]; WriteLine["."L]; RETURN[TRUE]; EXITS Trouble => RETURN[FALSE]; END; -- IO things WriteChar: PROCEDURE [c: CHARACTER] = BEGIN Put.Char[log, c]; END; WriteCR: PROCEDURE = BEGIN Put.CR[log]; END; WriteString: PROCEDURE [s: STRING] = BEGIN Put.Text[log, s]; END; WriteLine: PROCEDURE [s: STRING] = BEGIN Put.Line[log, s]; END; WriteDecimal: PROCEDURE [n: CARDINAL] = INLINE BEGIN WriteNumber[n, 10, 0]; END; WriteOctal: PROCEDURE [n: CARDINAL] = INLINE BEGIN WriteNumber[n, 8, 0]; END; WriteNumber: PROCEDURE [n, radix, width: CARDINAL] = INLINE BEGIN temp: STRING = [25]; String.AppendNumber[temp, n, radix]; THROUGH [temp.length..width) DO WriteChar[' ]; ENDLOOP; WriteString[temp]; END; WriteLongDecimal: PROCEDURE [n: LONG CARDINAL] = INLINE BEGIN Put.LongDecimal[log, n]; END; D8: PROCEDURE [n: CARDINAL] = BEGIN WriteNumber[n, 10, 8]; END; O3: PROCEDURE [n: CARDINAL] = BEGIN WriteNumber[n, 8, 3]; END; O3Z: PROCEDURE [n: CARDINAL] = BEGIN temp: STRING = [25]; String.AppendNumber[temp, n, 8]; THROUGH [temp.length..3) DO WriteChar['0]; ENDLOOP; WriteString[temp]; END; O4: PROCEDURE [n: CARDINAL] = BEGIN WriteNumber[n, 8, 4]; END; O6: PROCEDURE [n: CARDINAL] = BEGIN WriteNumber[n, 8, 3]; END; O9: PROCEDURE [n: CARDINAL] = BEGIN WriteNumber[n, 8, 9]; END; WriteCurrentDateAndTime: PROCEDURE = BEGIN temp: STRING = [20]; Time.AppendCurrent[temp]; WriteString[temp]; END; PrintPupAddress: PROCEDURE [a: LONG POINTER TO PupAddress] = BEGIN temp: STRING = [40]; AppendPupAddress[temp, a↑]; WriteString[temp]; END; PrintErrorPup: PROCEDURE [b: PupBuffer] = BEGIN temp: STRING = [200]; AppendErrorPup[temp, b]; WriteString[temp]; END; PrintBodyAsText: PROCEDURE [b: PupBuffer] = BEGIN FOR i: CARDINAL IN [0..GetPupContentsBytes[b]) DO WriteChar[b.pupChars[i]]; ENDLOOP; END; MakeSWs: Tool.MakeSWsProc = BEGIN msg ← Tool.MakeMsgSW[window: window, lines: 5]; form ← Tool.MakeFormSW[window: window, formProc: MakeForm]; log ← Tool.MakeFileSW[window: window, name: "EchoUser.log$"L]; END; startIX: CARDINAL = 0; stopIX: CARDINAL = 1; runningIX: CARDINAL = 2; MakeForm: FormSW.ClientItemsProcType = BEGIN nParams: CARDINAL = 7; items ← FormSW.AllocateItemDescriptor[nParams]; items[0] ← FormSW.CommandItem[ tag: "NameToAddress"L, proc: NameToAddress, place: FormSW.newLine]; items[1] ← FormSW.CommandItem[tag: "AddressToName"L, proc: AddressToName]; items[2] ← FormSW.CommandItem[tag: "Stats"L, proc: Stats]; items[3] ← FormSW.CommandItem[tag: "Version"L, proc: Version]; items[4] ← FormSW.StringItem[ tag: "Target"L, string: @data.target, place: FormSW.newLine]; items[5] ← FormSW.StringItem[ tag: "Name"L, string: @data.name, place: FormSW.newLine]; items[6] ← FormSW.StringItem[ tag: "Address"L, string: @data.address, place: FormSW.newLine]; RETURN[items, TRUE]; END; AlreadyActive: ERROR = CODE; NotActive: ERROR = CODE; ClientTransition: ToolWindow.TransitionProcType = BEGIN SELECT TRUE FROM old = inactive => BEGIN IF data # NIL THEN ERROR AlreadyActive; data ← Storage.Node[SIZE[Data]]; data↑ ← [where:, target: Storage.String[20], name: Storage.String[20], address: Storage.String[20]]; String.AppendString[data.target, "ME"L]; PupDefs.PupPackageMake[]; END; new = inactive => BEGIN IF data = NIL THEN ERROR NotActive; PupDefs.PupPackageDestroy[]; Storage.FreeString[data.target]; Storage.FreeString[data.name]; Storage.FreeString[data.address]; data ← Storage.FreeNodeNil[data]; END; ENDCASE; END; Broom: PROCEDURE [why: Event.Reason] = BEGIN SELECT why FROM makeImage, makeCheck => BEGIN IF data = NIL THEN RETURN; PupDefs.PupPackageDestroy[]; END; startImage, restartCheck, continueCheck => BEGIN IF data = NIL THEN RETURN; PupDefs.PupPackageMake[]; END; ENDCASE => NULL; END; -- Main Body Init[]; END.