<> <> DIRECTORY Arpa, ArpaExtras, ArpaName, ArpaNameCache, ArpaNameSupport, ArpaNameLogSupport, ArpaNameQuery, BasicTime USING [GMT, Now, Period], Buttons USING [Button, ButtonProc, Create, Destroy, SetDisplayStyle], Commander USING [CommandProc, Register], Containers USING [ChildXBound, ChildYBound, Create], ConvertExtras USING [ArpaAddressFromRope, RopeFromArpaAddress], IO USING [Flush, PutF, PutRope, STREAM, Value], Labels USING [Create], Loader USING [BCDBuildTime], Rope USING [Cat, Equal, IsEmpty, ROPE], Rules USING [Create], TypeScript USING [ChangeLooks, Create], ViewerClasses USING [Viewer], ViewerIO USING [CreateViewerStreams], ViewerOps USING [AddProp, ComputeColumn, CreateViewer, MoveViewer, OpenIcon, SetOpenHeight], ViewerTools USING [GetContents, MakeNewTextViewer, SetContents, SetSelection]; ArpaNameCacheTool: CEDAR MONITOR IMPORTS ArpaExtras, ArpaName, ArpaNameCache, ArpaNameLogSupport, ArpaNameSupport, BasicTime, Buttons, Commander, Containers, ConvertExtras, IO, Labels, Loader, Rope, Rules, TypeScript, ViewerIO, ViewerOps, ViewerTools = BEGIN ROPE: TYPE = Rope.ROPE; STREAM: TYPE = IO.STREAM; Viewer: TYPE = ViewerClasses.Viewer; <> buttonHeight: INTEGER _ 0; buttonWidth: INTEGER _ 0; ClientData: TYPE = REF ClientDataRep; ClientDataRep: TYPE = RECORD [ log: STREAM _ NIL, in: STREAM _ NIL, key: Viewer, value: Viewer]; sequenceNumber: CARDINAL _ 0; NameEntry: TYPE = ArpaNameCache.NameEntry; AliasEntry: TYPE = ArpaNameCache.AliasEntry; MXEntry: TYPE = ArpaNameCache.MXEntry; BogusNameEntry: TYPE = ArpaNameCache.BogusNameEntry; DownNameEntry: TYPE = ArpaNameCache.DownNameEntry; AddressEntry: TYPE = ArpaNameCache.AddressEntry; BogusAddressEntry: TYPE = ArpaNameCache.BogusAddressEntry; DownAddressEntry: TYPE = ArpaNameCache.DownAddressEntry; DownServerEntry: TYPE = ArpaNameCache.DownServerEntry; ZoneEntry: TYPE = ArpaNameCache.ZoneEntry; SoaEntry: TYPE = ArpaNameCache.SoaEntry; Create: Commander.CommandProc = { CreateOne[]; }; CreateOne: PROC = { data: ClientData _ NEW[ClientDataRep _ []]; viewer, buttons, log: Viewer _ NIL; viewer _ ViewerOps.CreateViewer [ flavor: $Container, info: [name: "ArpaNameCacheTool", column: left, iconic: TRUE, scrollable: FALSE]]; ViewerOps.AddProp[viewer, $ArpaNameCacheTool, data]; { -- Kludge to find Button size temp: Buttons.Button = Buttons.Create[ info: [name: "Aliases:", parent: viewer, border: FALSE, wx: 0, wy: 0], proc: NIL, clientData: NIL, fork: FALSE, paint: FALSE]; buttonWidth _ temp.ww; buttonHeight _ temp.wh; Buttons.Destroy[temp]; }; log _ TypeScript.Create[ [name: "ArpaNameCacheTool.log", wy: 27+4, parent: viewer, border: FALSE], FALSE]; [data.in, data.log] _ ViewerIO.CreateViewerStreams [ name: "ArpaNameCacheTool.log", backingFile: "ArpaNameCacheTool.log", viewer: log, editedStream: FALSE]; Containers.ChildXBound[viewer, log]; Containers.ChildYBound[viewer, log]; CreateButtons[data, viewer, log]; TypeScript.ChangeLooks[log, 'f]; IO.PutF[data.log, "ArpaNameCache Tool of %G.\n", [time[Loader.BCDBuildTime[Create]]]]; IF FALSE THEN ViewerOps.OpenIcon[viewer]; }; CreateButtons: PROC[data: ClientData, parent, log: Viewer] = { child: Viewer _ NIL; kids: Viewer = Containers.Create[ info: [parent: parent, border: FALSE, scrollable: FALSE, wx: 0, wy: -9999, ww: 9999, wh: 0] ]; Containers.ChildXBound[parent, kids]; child _ MakeRule[kids, child]; child _ data.key _ MakeLabeledText[ parent: kids, sibling: child, name: "Key:", data: "Xerox.COM", prev: data.key]; child _ data.value _ MakeLabeledText[ parent: kids, sibling: child, name: "Value:", data: "[a.b.c.d]", prev: data.value]; child _ MakeRule[kids, child]; child _ MakeLabel[kids, child, "Query:"]; child _ MakeButton[kids, child, data, "N=>A", N2A]; child _ MakeButton[kids, child, data, "N=>MX", N2MX]; child _ MakeButton[kids, child, data, "N=>N", N2N]; child _ MakeButton[kids, child, data, "N=>S", N2Servers]; child _ MakeButton[kids, child, data, "N=>I", N2Info]; child _ MakeButton[kids, child, data, "A=>N", A2N]; child _ MakeLabel[kids, child, "Cache:"]; child _ MakeButton[kids, child, data, "PrSlot", PrintSlot]; child _ MakeButton[kids, child, data, "PrOne", PrintOne]; child _ MakeButton[kids, child, data, "PrAll", Quick]; <> <> <> <> <> <> <> <<>> child _ MakeButton[kids, child, data, "ZapSlot", FlushEntry]; child _ MakeButton[kids, child, data, "ZapOne", FlushCache]; child _ MakeButton[kids, child, data, "ZapAll", Zap]; child _ MakeButton[kids, child, data, "AddV", AddV]; child _ MakeRule[kids, child]; { kidsY: INTEGER = 2; kidsH: INTEGER = child.wy + child.wh + 2; ViewerOps.MoveViewer[viewer: log, x: 0, y: kidsY + kidsH, w: log.ww, h: parent.ch - (kids.wy + kidsH), paint: FALSE]; ViewerOps.SetOpenHeight[parent, kidsY + kidsH + 12 * buttonHeight]; IF ~parent.iconic THEN ViewerOps.ComputeColumn[parent.column]; ViewerOps.MoveViewer[viewer: kids, x: kids.wx, y: kidsY, w: kids.ww, h: kidsH]; }; }; Zap: Buttons.ButtonProc = { <> data: ClientData _ NARROW[clientData]; log: IO.STREAM _ data.log; ArpaNameCache.FlushAll[]; IO.PutRope[log, "Zapped all name and server caches.\n\n"]; }; AddV: Buttons.ButtonProc = { <> data: ClientData _ NARROW[clientData]; log: IO.STREAM _ data.log; key: ROPE _ ViewerTools.GetContents[data.key]; value: ROPE _ ViewerTools.GetContents[data.value]; addr: Arpa.Address _ ConvertExtras.ArpaAddressFromRope[value]; addrList: LIST OF Arpa.Address _ LIST[addr]; IF Rope.IsEmpty[key] THEN RETURN; IF Rope.IsEmpty[value] THEN RETURN; IF addrList.first = Arpa.nullAddress THEN RETURN; [] _ ArpaNameCache.UpdateName[key, ArpaExtras.MyAddress[], 1333, FALSE, addrList]; IO.PutRope[log, key]; PrintListOfAddresses[log, " => ", addrList]; }; FlushCache: Buttons.ButtonProc = { <> data: ClientData _ NARROW[clientData]; log: IO.STREAM _ data.log; cacheRope: ROPE _ ViewerTools.GetContents[data.key]; cache: ArpaNameCache.CacheType; IF Rope.IsEmpty[cacheRope] THEN RETURN; SELECT TRUE FROM Rope.Equal[cacheRope, "name", FALSE] => cache _ name; Rope.Equal[cacheRope, "alias", FALSE] => cache _ alias; Rope.Equal[cacheRope, "mx", FALSE] => cache _ mx; Rope.Equal[cacheRope, "zone", FALSE] => cache _ zone; Rope.Equal[cacheRope, "soa", FALSE] => cache _ soa; Rope.Equal[cacheRope, "downName", FALSE] => cache _ downName; Rope.Equal[cacheRope, "bogusName", FALSE] => cache _ bogusName; Rope.Equal[cacheRope, "address", FALSE] => cache _ address; Rope.Equal[cacheRope, "downAddress", FALSE] => cache _ downAddress; Rope.Equal[cacheRope, "bogusAddress", FALSE] => cache _ bogusAddress; Rope.Equal[cacheRope, "downServer", FALSE] => cache _ downServer; ENDCASE; ArpaNameCache.FlushCache[cache]; IO.PutRope[log, "Zapped "]; IO.PutRope[log, cacheRope]; IO.PutRope[log, " cache.\n\n"]; }; FlushEntry: Buttons.ButtonProc = { <> data: ClientData _ NARROW[clientData]; log: IO.STREAM _ data.log; entry: ROPE _ ViewerTools.GetContents[data.key]; IF Rope.IsEmpty[entry] THEN RETURN; FOR cache: ArpaNameCache.CacheType IN [ArpaNameCache.CacheType.FIRST..ArpaNameCache.CacheType.LAST] DO ArpaNameCache.Delete[entry, cache]; ENDLOOP; IO.PutRope[log, "Zapped entry.\n\n"]; }; N2A: Buttons.ButtonProc = { <> data: ClientData _ NARROW[clientData]; log: IO.STREAM _ data.log; query: ROPE _ ViewerTools.GetContents[data.key]; addresses: LIST OF Arpa.Address; status: ArpaName.ReplyStatus; [addresses, status, ] _ ArpaName.NameToAddressList[query]; SELECT status FROM bogus => {IO.PutRope[log, Rope.Cat[query, " => bogus\n"]]; RETURN}; down => {IO.PutRope[log, Rope.Cat[query, " => down\n"]]; RETURN}; other => {IO.PutRope[log, Rope.Cat[query, " => other\n"]]; RETURN}; ENDCASE; IO.PutRope[log, query]; PrintListOfAddresses[log, " => ", addresses]; }; N2N: Buttons.ButtonProc = { <> data: ClientData _ NARROW[clientData]; log: IO.STREAM _ data.log; query: ROPE _ ViewerTools.GetContents[data.key]; name: ROPE; status: ArpaName.ReplyStatus; [name, status, ] _ ArpaName.AliasToName[query]; SELECT status FROM bogus => {IO.PutRope[log, Rope.Cat[query, " => bogus\n"]]; RETURN}; down => {IO.PutRope[log, Rope.Cat[query, " => down\n"]]; RETURN}; other => {IO.PutRope[log, Rope.Cat[query, " => other\n"]]; RETURN}; ENDCASE; IO.PutF[log, "%G => %G.\n", [rope[query]], [rope[name]]]; }; N2Servers: Buttons.ButtonProc = { <> data: ClientData _ NARROW[clientData]; log: IO.STREAM _ data.log; query: ROPE _ ViewerTools.GetContents[data.key]; status: ArpaName.ReplyStatus; servers: LIST OF ROPE; [servers, status, ] _ ArpaName.DomainServers[query]; SELECT status FROM bogus => {IO.PutRope[log, Rope.Cat[query, " => bogus\n"]]; RETURN}; down => {IO.PutRope[log, Rope.Cat[query, " => down\n"]]; RETURN}; other => {IO.PutRope[log, Rope.Cat[query, " => other\n"]]; RETURN}; ENDCASE; IO.PutF[log, "%G => ", [rope[query]]]; PrintListOfNames[log, "servers are: ", servers]; IO.PutRope[log, "\n"]; }; N2Info: Buttons.ButtonProc = { <> data: ClientData _ NARROW[clientData]; log: IO.STREAM _ data.log; query: ROPE _ ViewerTools.GetContents[data.key]; status: ArpaName.ReplyStatus; contact: ROPE; primaryServer: ROPE; [contact, primaryServer, status, ] _ ArpaName.DomainInfo[query]; SELECT status FROM bogus => {IO.PutRope[log, Rope.Cat[query, " => bogus\n"]]; RETURN}; down => {IO.PutRope[log, Rope.Cat[query, " => down\n"]]; RETURN}; other => {IO.PutRope[log, Rope.Cat[query, " => other\n"]]; RETURN}; ENDCASE; IO.PutF[log, "%G => ", [rope[query]]]; IO.PutF[log, " contact: %G, ", [rope[contact]]]; IO.PutF[log, " server: %G.\n", [rope[primaryServer]]]; IO.PutRope[log, "\n"]; }; N2MX: Buttons.ButtonProc = { <> data: ClientData _ NARROW[clientData]; log: IO.STREAM _ data.log; query: ROPE _ ViewerTools.GetContents[data.key]; status: ArpaName.ReplyStatus; mxEntry: ArpaNameCache.MXEntry _ NIL; Log: PROC [rope: ROPE] ~ { IO.PutRope[log, rope]; IO.Flush[log]}; status _ ArpaName.NameToMailHostList[query].status; SELECT status FROM bogus => {IO.PutRope[log, Rope.Cat[query, " => bogus\n"]]; RETURN}; down => {IO.PutRope[log, Rope.Cat[query, " => down\n"]]; RETURN}; other => {IO.PutRope[log, Rope.Cat[query, " => other\n"]]; RETURN}; ENDCASE; [,, mxEntry] _ ArpaNameCache.FetchMX[query]; IF mxEntry # NIL THEN ArpaNameLogSupport.MXSummaryLine[mxEntry, FALSE, TRUE, Log]; }; A2N: Buttons.ButtonProc = { <> data: ClientData _ NARROW[clientData]; log: IO.STREAM _ data.log; query: ROPE _ ViewerTools.GetContents[data.key]; where: LIST OF Arpa.Address _ ArpaName.NameToAddressList[query].addrs; name: Rope.ROPE; status: ArpaName.ReplyStatus; [where, status,] _ ArpaName.NameToAddressList[query]; SELECT status FROM bogus => {IO.PutRope[log, Rope.Cat[query, " => bogus\n"]]; RETURN}; down => {IO.PutRope[log, Rope.Cat[query, " => down\n"]]; RETURN}; other => {IO.PutRope[log, Rope.Cat[query, " => other\n"]]; RETURN}; ENDCASE; IF where = NIL THEN { IO.PutF[log, "\"Query\" needs to be a valid Address.\n"]; RETURN[]; }; name _ ArpaName.AddressToName[where.first].name; IO.PutF[log, "%G => %G.\n", [rope[ConvertExtras.RopeFromArpaAddress[where.first]]], [rope[name]]]; }; PrintOne: Buttons.ButtonProc = { <> ENABLE UNWIND => NULL; data: ClientData _ NARROW[clientData]; log: IO.STREAM _ data.log; cacheRope: ROPE _ ViewerTools.GetContents[data.key]; cache: ArpaNameCache.CacheType; SummaryEnum: ArpaNameCache.EnumerateProc = { <> WITH val SELECT FROM e: ArpaNameCache.NameEntry => ArpaNameLogSupport.NameSummaryLine[e, FALSE, TRUE, Log]; e: ArpaNameCache.AliasEntry => ArpaNameLogSupport.AliasSummaryLine[e, FALSE, TRUE, Log]; e: ArpaNameCache.AddressEntry => ArpaNameLogSupport.AddressSummaryLine[e, FALSE, TRUE, Log]; e: ArpaNameCache.MXEntry => ArpaNameLogSupport.MXSummaryLine[e, FALSE, TRUE, Log]; e: ArpaNameCache.ZoneEntry => ArpaNameLogSupport.ZoneSummaryLine[e, FALSE, TRUE, Log]; e: ArpaNameCache.SoaEntry => ArpaNameLogSupport.SoaSummaryLine[e, FALSE, TRUE, Log]; e: ArpaNameCache.BogusNameEntry => ArpaNameLogSupport.BogusNameSummaryLine[e, FALSE, TRUE, Log]; e: ArpaNameCache.BogusAddressEntry => ArpaNameLogSupport.BogusAddressSummaryLine[e, FALSE, TRUE, Log]; e: ArpaNameCache.DownNameEntry => ArpaNameLogSupport.DownNameSummaryLine[e, FALSE, TRUE, Log]; e: ArpaNameCache.DownAddressEntry => ArpaNameLogSupport.DownAddressSummaryLine[e, FALSE, TRUE, Log]; e: ArpaNameCache.DownServerEntry => ArpaNameLogSupport.DownServerSummaryLine[e, FALSE, TRUE, Log]; ENDCASE; }; Log: PROC [rope: ROPE] ~ { IO.PutRope[log, rope]; IO.Flush[log]}; IF Rope.IsEmpty[cacheRope] THEN RETURN; IO.PutRope[log, "\n"]; IO.PutRope[log, cacheRope]; IO.PutRope[log, " cache Summary:\n"]; SELECT TRUE FROM Rope.Equal[cacheRope, "name", FALSE] => cache _ name; Rope.Equal[cacheRope, "alias", FALSE] => cache _ alias; Rope.Equal[cacheRope, "mx", FALSE] => cache _ mx; Rope.Equal[cacheRope, "zone", FALSE] => cache _ zone; Rope.Equal[cacheRope, "soa", FALSE] => cache _ soa; Rope.Equal[cacheRope, "downName", FALSE] => cache _ downName; Rope.Equal[cacheRope, "bogusName", FALSE] => cache _ bogusName; Rope.Equal[cacheRope, "address", FALSE] => cache _ address; Rope.Equal[cacheRope, "downAddress", FALSE] => cache _ downAddress; Rope.Equal[cacheRope, "bogusAddress", FALSE] => cache _ bogusAddress; Rope.Equal[cacheRope, "downServer", FALSE] => cache _ downServer; ENDCASE; IF ArpaNameCache.CountCache[cache] = 0 THEN IO.PutRope[log, "empty."] ELSE { IO.PutRope[log, "\n"]; ArpaNameCache.EnumerateCache[cache, SummaryEnum]}; }; Quick: Buttons.ButtonProc = { <> ENABLE UNWIND => NULL; data: ClientData _ NARROW[clientData]; log: IO.STREAM _ data.log; SummaryEnum: ArpaNameCache.EnumerateProc = { <> WITH val SELECT FROM e: ArpaNameCache.NameEntry => ArpaNameLogSupport.NameSummaryLine[e, FALSE, TRUE, Log]; e: ArpaNameCache.AliasEntry => ArpaNameLogSupport.AliasSummaryLine[e, FALSE, TRUE, Log]; e: ArpaNameCache.AddressEntry => ArpaNameLogSupport.AddressSummaryLine[e, FALSE, TRUE, Log]; e: ArpaNameCache.MXEntry => ArpaNameLogSupport.MXSummaryLine[e, FALSE, TRUE, Log]; e: ArpaNameCache.ZoneEntry => ArpaNameLogSupport.ZoneSummaryLine[e, FALSE, TRUE, Log]; e: ArpaNameCache.SoaEntry => ArpaNameLogSupport.SoaSummaryLine[e, FALSE, TRUE, Log]; e: ArpaNameCache.BogusNameEntry => ArpaNameLogSupport.BogusNameSummaryLine[e, FALSE, TRUE, Log]; e: ArpaNameCache.BogusAddressEntry => ArpaNameLogSupport.BogusAddressSummaryLine[e, FALSE, TRUE, Log]; e: ArpaNameCache.DownNameEntry => ArpaNameLogSupport.DownNameSummaryLine[e, FALSE, TRUE, Log]; e: ArpaNameCache.DownAddressEntry => ArpaNameLogSupport.DownAddressSummaryLine[e, FALSE, TRUE, Log]; e: ArpaNameCache.DownServerEntry => ArpaNameLogSupport.DownServerSummaryLine[e, FALSE, TRUE, Log]; ENDCASE; }; Log: PROC [rope: ROPE] ~ { IO.PutRope[log, rope]; IO.Flush[log]}; IO.PutRope[log, "\nCache Summary:\n"]; IO.PutRope[log, "\nNames: "]; IF ArpaNameCache.CountCache[name] = 0 THEN IO.PutRope[log, "empty."] ELSE { IO.PutRope[log, "\n"]; ArpaNameCache.EnumerateCache[name, SummaryEnum]}; IO.PutRope[log, "\nAliases:"]; IF ArpaNameCache.CountCache[alias] = 0 THEN IO.PutRope[log, "empty."] ELSE { IO.PutRope[log, "\n"]; ArpaNameCache.EnumerateCache[alias, SummaryEnum]}; IO.PutRope[log, "\nMXs:"]; IF ArpaNameCache.CountCache[mx] = 0 THEN IO.PutRope[log, "empty."] ELSE { IO.PutRope[log, "\n"]; ArpaNameCache.EnumerateCache[mx, SummaryEnum]}; IO.PutRope[log, "\nZoneServers:"]; IF ArpaNameCache.CountCache[zone] = 0 THEN IO.PutRope[log, "empty."] ELSE { IO.PutRope[log, "\n"]; ArpaNameCache.EnumerateCache[zone, SummaryEnum]}; IO.PutRope[log, "\nZoneInfo:"]; IF ArpaNameCache.CountCache[soa] = 0 THEN IO.PutRope[log, "empty."] ELSE { IO.PutRope[log, "\n"]; ArpaNameCache.EnumerateCache[soa, SummaryEnum]}; IO.PutRope[log, "\nBogus Names:"]; IF ArpaNameCache.CountCache[bogusName] = 0 THEN IO.PutRope[log, "empty."] ELSE { IO.PutRope[log, "\n"]; ArpaNameCache.EnumerateCache[bogusName, SummaryEnum]}; IO.PutRope[log, "\nDown Names:"]; IF ArpaNameCache.CountCache[downName] = 0 THEN IO.PutRope[log, "empty."] ELSE { IO.PutRope[log, "\n"]; ArpaNameCache.EnumerateCache[downName, SummaryEnum]}; IO.PutRope[log, "\nAddresses:"]; IF ArpaNameCache.CountCache[address] = 0 THEN IO.PutRope[log, "empty."] ELSE { IO.PutRope[log, "\n"]; ArpaNameCache.EnumerateCache[address, SummaryEnum]}; IO.PutRope[log, "\nBogus Addresses:"]; IF ArpaNameCache.CountCache[bogusAddress] = 0 THEN IO.PutRope[log, "empty."] ELSE { IO.PutRope[log, "\n"]; ArpaNameCache.EnumerateCache[bogusAddress, SummaryEnum]}; IO.PutRope[log, "\nDown Addresses:"]; IF ArpaNameCache.CountCache[downAddress] = 0 THEN IO.PutRope[log, "empty."] ELSE { IO.PutRope[log, "\n"]; ArpaNameCache.EnumerateCache[downAddress, SummaryEnum]}; IO.PutRope[log, "\nDown Servers:"]; IF ArpaNameCache.CountCache[downServer] = 0 THEN IO.PutRope[log, "empty."] ELSE { IO.PutRope[log, "\n"]; ArpaNameCache.EnumerateCache[downServer, SummaryEnum]}; IO.PutRope[log, "\n\n"]; IO.Flush[log]; }; PrintSlot: Buttons.ButtonProc = { <> ENABLE UNWIND => NULL; this: NameEntry; alias: AliasEntry; mx: MXEntry; bogusName: BogusNameEntry; downName: DownNameEntry; zone: ZoneEntry; soa: SoaEntry; address: AddressEntry; downAddress: DownAddressEntry; bogusAddress: BogusAddressEntry; downServer: DownServerEntry; data: ClientData _ NARROW[clientData]; log: IO.STREAM _ data.log; found: BOOLEAN _ FALSE; query: ROPE _ ViewerTools.GetContents[data.key]; SELECT ArpaNameSupport.IsAddressRope[query] FROM FALSE => { this _ ArpaNameCache.FetchName[query].entry; alias _ ArpaNameCache.FetchAlias[query].entry; mx _ ArpaNameCache.FetchMX[query].entry; bogusName _ ArpaNameCache.FetchBogusName[query].entry; downName _ ArpaNameCache.FetchDownName[query].entry; zone _ ArpaNameCache.FetchZone[query].entry; soa _ ArpaNameCache.FetchSoa[query].entry; }; TRUE => { address _ ArpaNameCache.FetchAddressRope[query].entry; downAddress _ ArpaNameCache.FetchDownAddressRope[query].entry; bogusAddress _ ArpaNameCache.FetchBogusAddressRope[query].entry; downServer _ ArpaNameCache.FetchDownServerRope[query].entry; }; ENDCASE; IO.PutRope[log, "\n"]; IF this # NIL THEN { now: BasicTime.GMT _ BasicTime.Now[]; source: ROPE _ ArpaName.AddressToName[this.source].name; expires: INT _ BasicTime.Period[from: now, to: this.expires]; found _ TRUE; IO.PutF[log, "Name Loaded: %G, From: %G", [time[this.loaded]], [rope[source]]]; IF ~this.authoritative THEN IO.PutF[log, ", NOT Authoritative **"]; IO.PutRope[log, ".\n"]; IO.PutF[log, " Referenced: %G, Expires: %G, TTL: %G.\n", [time[this.referenced]], [integer[expires]],[integer[this.ttl]]]; IO.PutF[log, " Name: %G.\n", [rope[this.key]]]; PrintListOfAddresses[log, " Addresses: ", this.addresses]; IO.PutRope[log, "\n"];}; IF alias # NIL THEN { now: BasicTime.GMT _ BasicTime.Now[]; source: ROPE _ ArpaName.AddressToName[alias.source].name; expires: INT _ BasicTime.Period[from: now, to: alias.expires]; found _ TRUE; IO.PutF[log, "Alias Loaded: %G, From: %G", [time[alias.loaded]], [rope[source]]]; IF ~alias.authoritative THEN IO.PutF[log, ", NOT Authoritative **"]; IO.PutRope[log, ".\n"]; IO.PutF[log, " Referenced: %G, Expires: %G, TTL: %G.\n", [time[alias.referenced]], [integer[expires]], [integer[alias.ttl]]]; IO.PutF[log, " Alias: %G.\n", [rope[alias.key]]]; IO.PutF[log, " Canonical Name: %G.\n", [rope[alias.canonicalName]]]; IO.PutRope[log, "\n"];}; IF mx # NIL THEN { now: BasicTime.GMT _ BasicTime.Now[]; source: ROPE _ ArpaName.AddressToName[mx.source].name; expires: INT _ BasicTime.Period[from: now, to: mx.expires]; found _ TRUE; IO.PutF[log, "MX Loaded: %G, From: %G", [time[mx.loaded]], [rope[source]]]; IF ~mx.authoritative THEN IO.PutF[log, ", NOT Authoritative **"]; IO.PutRope[log, ".\n"]; IO.PutF[log, " Referenced: %G, Expires: %G, TTL: %G.\n", [time[mx.referenced]], [integer[expires]], [integer[mx.ttl]]]; IO.PutF[log, " Name: %G.\n", [rope[mx.key]]]; FOR list: LIST OF ArpaNameQuery.MailForwardRecord _ mx.mxList, list.rest UNTIL list = NIL DO IO.PutF[log, " MX Host: %G", [rope[list.first.host]]]; IO.PutF[log,", Preference: %G", [integer[list.first.preference]]]; IO.PutRope[log, "\n"]; ENDLOOP; IO.PutRope[log, "\n"]; }; IF bogusName # NIL THEN { now: BasicTime.GMT _ BasicTime.Now[]; source: ROPE _ ArpaName.AddressToName[bogusName.source].name; expires: INT _ BasicTime.Period[from: now, to: bogusName.expires]; found _ TRUE; IO.PutF[log, "Bogus Name Loaded: %G, From: %G", [time[bogusName.loaded]], [rope[source]]]; IF ~bogusName.authoritative THEN IO.PutF[log, ", NOT Authoritative **"]; IO.PutRope[log, ".\n"]; IO.PutF[log, " Referenced: %G, Expires: %G, TTL: %G.\n", [time[bogusName.referenced]], [integer[expires]], [integer[bogusName.ttl]]]; IO.PutF[log, " Bogus Name: %G.\n", [rope[bogusName.key]]]; IO.PutRope[log, "\n"];}; IF downName # NIL THEN { now: BasicTime.GMT _ BasicTime.Now[]; expires: INT _ BasicTime.Period[from: now, to: downName.expires]; found _ TRUE; IO.PutF[log, "Down Name Loaded: %G", [time[downName.loaded]]]; IO.PutRope[log, ".\n"]; IO.PutF[log, " Referenced: %G, Expires: %G, TTL: %G.\n", [time[downName.referenced]], [integer[expires]], [integer[downName.ttl]]]; IO.PutF[log, " Down Name: %G.\n", [rope[downName.key]]]; IO.PutRope[log, "\n"];}; IF zone # NIL THEN { now: BasicTime.GMT _ BasicTime.Now[]; source: ROPE _ ArpaName.AddressToName[zone.source].name; expires: INT _ BasicTime.Period[from: now, to: zone.expires]; found _ TRUE; IO.PutF[log, "Zone Loaded: %G, From: %G", [time[zone.loaded]], [rope[source]]]; IF ~zone.authoritative THEN IO.PutF[log, ", NOT Authoritative **"]; IO.PutRope[log, ".\n"]; IO.PutF[log, " Referenced: %G, Expires: %G, TTL: %G.\n", [time[zone.referenced]], [integer[expires]], [integer[zone.ttl]]]; IO.PutF[log, " Zone: %G.\n", [rope[zone.key]]]; PrintListOfNames[log, " Servers: ", zone.servers]; IO.PutRope[log, "\n"];}; IF soa # NIL THEN { now: BasicTime.GMT _ BasicTime.Now[]; source: ROPE _ ArpaName.AddressToName[soa.source].name; expires: INT _ BasicTime.Period[from: now, to: soa.expires]; found _ TRUE; IO.PutF[log, "Soa Loaded: %G, From: %G", [time[soa.loaded]], [rope[source]]]; IF ~soa.authoritative THEN IO.PutF[log, ", NOT Authoritative **"]; IO.PutRope[log, ".\n"]; IO.PutF[log, " Referenced: %G, Expires: %G, TTL: %G.\n", [time[soa.referenced]], [integer[expires]], [integer[soa.ttl]]]; IO.PutF[log, " Soa: %G.\n", [rope[soa.key]]]; IO.PutF[log, " Domain contact: %G.\n", [rope[soa.soaRef.domainContact]]]; IO.PutF[log, " Primary server: %G.\n", [rope[soa.soaRef.primaryServer]]]; IO.PutRope[log, "\n"];}; IF address # NIL THEN { now: BasicTime.GMT _ BasicTime.Now[]; source: ROPE _ ArpaName.AddressToName[address.source].name; expires: INT _ BasicTime.Period[from: now, to: address.expires]; found _ TRUE; IO.PutF[log, "Address Loaded: %G, From: %G", [time[address.loaded]], [rope[source]]]; IF ~address.authoritative THEN IO.PutF[log, ", NOT Authoritative **"]; IO.PutRope[log, ".\n"]; IO.PutF[log, " Referenced: %G, Expires: %G, TTL: %G.\n", [time[address.referenced]], [integer[expires]], [integer[address.ttl]]]; IO.PutF[log, " Address: %G.\n", [rope[address.key]]]; PrintListOfNames[log, " Name: ", address.names]; IO.PutRope[log, "\n"];}; IF downAddress # NIL THEN { now: BasicTime.GMT _ BasicTime.Now[]; source: ROPE _ ArpaName.AddressToName[downAddress.source].name; expires: INT _ BasicTime.Period[from: now, to: downAddress.expires]; found _ TRUE; IO.PutF[log, "Address Loaded: %G, From: %G", [time[downAddress.loaded]], [rope[source]]]; IF ~downAddress.authoritative THEN IO.PutF[log, ", NOT Authoritative **"]; IO.PutRope[log, ".\n"]; IO.PutF[log, " Referenced: %G, Expires: %G, TTL: %G.\n", [time[downAddress.referenced]], [integer[expires]], [integer[downAddress.ttl]]]; IO.PutF[log, " Down Address: %G.\n", [rope[downAddress.key]]]; IO.PutF[log, " Name: %G.\n", [rope[ArpaName.AddressRopeToName[downAddress.key].name]]]; IO.PutRope[log, "\n"];}; IF bogusAddress # NIL THEN { now: BasicTime.GMT _ BasicTime.Now[]; source: ROPE _ ArpaName.AddressToName[bogusAddress.source].name; expires: INT _ BasicTime.Period[from: now, to: bogusAddress.expires]; found _ TRUE; IO.PutF[log, "Address Loaded: %G, From: %G", [time[bogusAddress.loaded]], [rope[source]]]; IF ~bogusAddress.authoritative THEN IO.PutF[log, ", NOT Authoritative **"]; IO.PutRope[log, ".\n"]; IO.PutF[log, " Referenced: %G, Expires: %G, TTL: %G.\n", [time[bogusAddress.referenced]], [integer[expires]], [integer[bogusAddress.ttl]]]; IO.PutF[log, " Bogus Address: %G.\n", [rope[bogusAddress.key]]]; IO.PutRope[log, "\n"];}; IF downServer # NIL THEN { now: BasicTime.GMT _ BasicTime.Now[]; source: ROPE _ ArpaName.AddressToName[downServer.source].name; expires: INT _ BasicTime.Period[from: now, to: downServer.expires]; found _ TRUE; IO.PutF[log, "Address Loaded: %G, From: %G", [time[downServer.loaded]], [rope[source]]]; IF ~downServer.authoritative THEN IO.PutF[log, ", NOT Authoritative **"]; IO.PutRope[log, ".\n"]; IO.PutF[log, " Referenced: %G, Expires: %G, TTL: %G.\n", [time[downServer.referenced]], [integer[expires]], [integer[downServer.ttl]]]; IO.PutF[log, " Down Server: %G.\n", [rope[downServer.key]]]; IO.PutF[log, " Name: %G.\n", [rope[ArpaName.AddressRopeToName[downServer.key].name]]]; IO.PutRope[log, "\n"];}; IF ~found THEN IO.PutRope[log, "Entry not found.\n"]; IO.PutRope[log, "\n"]; IO.Flush[log]; }; Addrs: Buttons.ButtonProc = { <> ENABLE UNWIND => NULL; data: ClientData _ NARROW[clientData]; log: IO.STREAM _ data.log; <> <> <> <<>> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <<>> IO.Flush[log]; }; Aliases: Buttons.ButtonProc = { <> ENABLE UNWIND => NULL; data: ClientData _ NARROW[clientData]; log: IO.STREAM _ data.log; <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <<>> IO.Flush[log]; }; MXs: Buttons.ButtonProc = { <> ENABLE UNWIND => NULL; data: ClientData _ NARROW[clientData]; log: IO.STREAM _ data.log; <> <> <<>> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <<>> IO.Flush[log]; }; Bogus: Buttons.ButtonProc = { <> ENABLE UNWIND => NULL; data: ClientData _ NARROW[clientData]; log: IO.STREAM _ data.log; <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <<>> <> <> <> <> <> <> <> <> <> <> <> <> <> <<>> IO.Flush[log]; }; Down: Buttons.ButtonProc = { <> ENABLE UNWIND => NULL; data: ClientData _ NARROW[clientData]; log: IO.STREAM _ data.log; <> <> <> <<>> <> <> <> <> <> <> <> <> <> <> <> <> <> <<>> <> <> <> <> <> <> <> <> <> <> <> <> <<>> <> <> <> <> <> <> <> <> <> <> <> <> IO.Flush[log]; }; Names: Buttons.ButtonProc = { <> ENABLE UNWIND => NULL; data: ClientData _ NARROW[clientData]; log: IO.STREAM _ data.log; <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <<>> IO.Flush[log]; }; Zones: Buttons.ButtonProc = { <> ENABLE UNWIND => NULL; data: ClientData _ NARROW[clientData]; log: IO.STREAM _ data.log; <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <<>> IO.Flush[log]; }; ListLength: PROCEDURE [arg: REF ANY] RETURNS [length: INT _ 0] = TRUSTED { FOR list: LIST OF REF ANY _ LOOPHOLE[arg], list.rest UNTIL list = NIL DO length _ length + 1; ENDLOOP; }; PrintListOfRopes: PROC [log: IO.STREAM, header: ROPE, ropes: LIST OF ROPE] = { IO.PutRope[log, header]; FOR list: LIST OF ROPE _ ropes, list.rest UNTIL list = NIL DO IF list # ropes THEN IO.PutRope[log, ", "]; IO.PutF[log, "\"%G\"", [rope[list.first]]]; ENDLOOP; IO.PutRope[log, "\n"]; }; PrintListOfAddresses: PROC [log: IO.STREAM, header: ROPE, addresses: LIST OF Arpa.Address] = { IO.PutRope[log, header]; FOR list: LIST OF Arpa.Address _ addresses, list.rest UNTIL list = NIL DO IF list # addresses THEN IO.PutRope[log, ", "]; IO.PutRope[log, ConvertExtras.RopeFromArpaAddress[list.first]]; ENDLOOP; IO.PutRope[log, "\n"]; }; PrintListOfNames: PROC [log: IO.STREAM, header: ROPE _ NIL, names: LIST OF ROPE] = { IF header # NIL THEN IO.PutRope[log, header]; FOR list: LIST OF ROPE _ names, list.rest UNTIL list = NIL DO IF list # names THEN IO.PutRope[log, ", "]; IO.PutRope[log, list.first]; ENDLOOP; IO.PutRope[log, "\n"]; }; MakeRule: PROC [parent, sibling: Viewer] RETURNS [child: Viewer] = { child _ Rules.Create[ info: [parent: parent, border: FALSE, wy: IF sibling = NIL THEN 0 ELSE sibling.wy + sibling.wh + 2, wx: 0, ww: parent.ww, wh: 1], paint: FALSE ]; Containers.ChildXBound[parent, child]; }; MakeButton: PROC [parent, sibling: Viewer, data: REF ANY, name: ROPE, proc: Buttons.ButtonProc] RETURNS[child: Viewer] = { child _ Buttons.Create[ info: [name: name, parent: parent, border: TRUE, wy: sibling.wy, wx: sibling.wx + buttonWidth - 1, ww: buttonWidth], proc: proc, clientData: data, fork: TRUE, paint: FALSE]; }; BoolProc: TYPE = PROC [parent: Viewer, clientData: REF, value: BOOL]; Bool: TYPE = REF BoolRec; BoolRec: TYPE = RECORD [ value: REF BOOL, change: BoolProc, clientData: REF, button: Viewer ]; MakeBool: PROC [parent, sibling: Viewer, clientData: REF _ NIL, name: ROPE, init: REF BOOL, change: BoolProc _ NIL, x, y: INTEGER _ 0] RETURNS [child: Viewer] = { bool: Bool _ NEW [BoolRec _ [ value: IF init # NIL THEN init ELSE NEW [BOOL _ TRUE], change: change, clientData: clientData, button: NIL ] ]; IF y = 0 THEN y _ sibling.wy + sibling.wh; IF x = 0 THEN x _ 2; child _ Buttons.Create[ info: [name: name, parent: parent, border: TRUE, wx: x, wy: y], proc: BoolHelper, clientData: bool, fork: TRUE, paint: TRUE]; bool.button _ child; IF bool.value^ THEN Buttons.SetDisplayStyle[child, $WhiteOnBlack]; }; BoolHelper: Buttons.ButtonProc = { <> self: Buttons.Button = NARROW[parent]; bool: Bool = NARROW[clientData]; bool.value^ _ ~bool.value^; IF bool.value^ THEN Buttons.SetDisplayStyle[bool.button, $WhiteOnBlack] ELSE Buttons.SetDisplayStyle[bool.button, $BlackOnWhite]; IF bool.change # NIL THEN bool.change[self.parent, bool.clientData, bool.value^]; }; MakeLabel: PROC [parent, sibling: Viewer, name: ROPE] RETURNS [child: Viewer] = { child _ Labels.Create[ info: [name: name, parent: parent, border: FALSE, wy: sibling.wy + sibling.wh + (IF sibling.class.flavor = $Button THEN -1 ELSE 2), wx: 2], paint: FALSE ]; }; MakeLabeledText: PROC [ parent, sibling: Viewer, name, data: ROPE, prev: Viewer, newline: BOOL _ TRUE] RETURNS [child: Viewer] = { x: INTEGER = IF newline THEN 2 ELSE sibling.wx + sibling.ww + 10; y: INTEGER = IF newline THEN sibling.wy + sibling.wh + 1 ELSE sibling.wy; child _ ViewerTools.MakeNewTextViewer[ info: [parent: parent, wh: buttonHeight, ww: 999, scrollable: TRUE, data: IF prev = NIL THEN data ELSE ViewerTools.GetContents[prev], border: FALSE, wx: x + buttonWidth + 2, wy: y], paint: FALSE ]; Containers.ChildXBound[parent, child]; [] _ Buttons.Create[ info: [name: name, parent: parent, wh: buttonHeight, border: FALSE, wx: x, wy: y], proc: LabeledTextProc, clientData: child, fork: FALSE, paint: FALSE]; RETURN[child]; }; LabeledTextProc: Buttons.ButtonProc = { <> text: Viewer = NARROW[clientData]; SELECT mouseButton FROM red => ViewerTools.SetSelection[text, NIL]; yellow => NULL; blue => { ViewerTools.SetContents[text, NIL]; ViewerTools.SetSelection[text, NIL] }; ENDCASE => ERROR; }; Commander.Register["ArpaNameCacheTool", Create, "ArpaName Cache Tool."]; END.