-- File: GateInfo.mesa, Last Edit: HGM March 17, 1981 6:18 PM DIRECTORY Cursor USING [Defined, GetInfo, Set, Type], Menu USING [Handle, ItemObject, MCRType, Create, Instantiate], Process USING [Yield], Put USING [ CR, Char, Date, Decimal, Line, LongDecimal, LongNumber, Number, Text], TajoMisc USING [Quit], Time USING [Current], UserInput USING [GetDefaultWindow, userAbort, WaitForConfirmation], Window USING [Handle], George USING [CountFreeDiskPages], StatsDefs USING [ StatCounterIndex, StatGetCounter, StatPrintCurrent, StatSince, StatUpdate], BootServerDefs USING [ statFileSent, statFileSentSlow, statBootNew, statMicrocodeBooted], NameServerDefs USING [ GetDirectoryVersion, statName, statAddress, statXlation, statWhoAmI, statSend], TimeServerDefs USING [statAlto, statPilot, statPilotOld], AddressTranslation USING [AppendNetworkNumber, AppendSystemElement], Router USING [EnumerateRoutingTable, RoutingTableEntry], SpecialSystem USING [ HostNumber, GetProcessorID, NetworkAddress, NetworkNumber, ProcessorID], System USING [], BufferDefs USING [BuffersLeft], DriverDefs USING [Network, GetDeviceChain], ForwarderDefs USING [GetPointerToPupGateStats, statGateInfoReplies], GateDefs USING [GetVersionText, typescript], PupRouterDefs USING [RoutingTableEntry, EnumerateRoutingTable]; GateInfo: PROGRAM IMPORTS Cursor, Menu, Process, Put, TajoMisc, Time, UserInput, George, StatsDefs, BootServerDefs, NameServerDefs, TimeServerDefs, BufferDefs, DriverDefs, ForwarderDefs, GateDefs, PupRouterDefs, AddressTranslation, Router, SpecialSystem EXPORTS System = BEGIN items: ARRAY [0..5] OF Menu.ItemObject ← [ ["Gate", DoInfo], ["Pup RT", DoInfo], ["Oiscp RT", DoInfo], ["Recent", DoInfo], ["Total", DoInfo], ["Quit", DoInfo]]; gate: CARDINAL = 0; pupRoute: CARDINAL = 1; oiscpRoute: CARDINAL = 2; recent: CARDINAL = 3; total: CARDINAL = 4; quit: CARDINAL = 5; DoInfo: Menu.MCRType = BEGIN SELECT index FROM gate => PrintGateStats[NIL]; pupRoute => PrintPupRoutingTable[NIL]; oiscpRoute => PrintOiscpRoutingTable[NIL]; recent => StatsDefs.StatSince[NIL]; total => StatsDefs.StatPrintCurrent[NIL]; quit => Quit[]; ENDCASE => ERROR; END; SetupGateMenu: PROCEDURE = BEGIN menu: Menu.Handle ← Menu.Create[DESCRIPTOR[items], "Gate"]; Menu.Instantiate[menu, UserInput.GetDefaultWindow[]]; Menu.Instantiate[menu, GateDefs.typescript]; END; version: STRING = GateDefs.GetVersionText[]; firstNetwork: DriverDefs.Network = DriverDefs.GetDeviceChain[]; packets: POINTER TO ARRAY [0..0) OF LONG CARDINAL; bytes: POINTER TO ARRAY [0..0) OF LONG CARDINAL; nets: CARDINAL; PrintGateStats: PUBLIC PROCEDURE [wh: Window.Handle] = BEGIN PrintPacketsForwarded: PROCEDURE = BEGIN Line["Packets forwarded:"L]; Text[" Discard"L]; FOR to: DriverDefs.Network ← firstNetwork, to.next UNTIL to = NIL DO Text[" "L]; O4[to.netNumber.b]; ENDLOOP; CR[]; FOR from: DriverDefs.Network ← firstNetwork, from.next UNTIL from = NIL DO O4[from.netNumber.b]; Text[IF from.alive THEN " "L ELSE "*"L]; LD10Dash[packets[from.index + 0*nets]]; FOR to: DriverDefs.Network ← firstNetwork, to.next UNTIL to = NIL DO LD10Dash[packets[from.index + to.index*nets]]; ENDLOOP; CR[]; ENDLOOP; END; PrintBytesForwarded: PROCEDURE = BEGIN Line["KBytes forwarded:"L]; Text[" Discard"L]; FOR to: DriverDefs.Network ← firstNetwork, to.next UNTIL to = NIL DO Text[" "L]; O4[to.netNumber.b]; ENDLOOP; CR[]; FOR from: DriverDefs.Network ← firstNetwork, from.next UNTIL from = NIL DO O4[from.netNumber.b]; Text[IF from.alive THEN " "L ELSE "*"L]; LD10Dash[bytes[from.index + 0*nets]/1000]; FOR to: DriverDefs.Network ← firstNetwork, to.next UNTIL to = NIL DO LD10Dash[bytes[from.index + to.index*nets]/1000]; ENDLOOP; CR[]; ENDLOOP; END; PrintMaybe: PROCEDURE [s: STRING, x: StatsDefs.StatCounterIndex] = BEGIN n: LONG CARDINAL = StatsDefs.StatGetCounter[x]; IF n = 0 THEN RETURN; Text[s]; Text[": "L]; LD[n]; CR[]; END; O4: PROCEDURE [n: CARDINAL] = BEGIN Put.Number[wh, n, [8, FALSE, TRUE, 4]]; END; D: PROCEDURE [n: CARDINAL] = BEGIN Put.Decimal[wh, n]; END; LD: PROCEDURE [n: LONG CARDINAL] = BEGIN Put.LongDecimal[wh, n]; END; LDS: PROCEDURE [x: StatsDefs.StatCounterIndex] = BEGIN LD[StatsDefs.StatGetCounter[x]]; END; LD10Dash: PROCEDURE [n: LONG CARDINAL] = BEGIN IF n = 0 THEN Put.Text[wh, " - "L] ELSE Put.LongNumber[wh, n, [10, FALSE, TRUE, 10]]; END; PrintUpTime: PROCEDURE = BEGIN sec: LONG INTEGER ← StatsDefs.StatGetCounter[statSeconds]; min: LONG INTEGER; hours: LONG INTEGER; hours ← sec/3600; sec ← sec - hours*3600; min ← sec/60; sec ← sec - min*60; LD[hours]; Char[':]; LD[min]; Char[':]; LD[sec]; END; Line: PROCEDURE [s: STRING] = BEGIN Put.Line[wh, s]; END; Text: PROCEDURE [s: STRING] = BEGIN Put.Text[wh, s]; END; Char: PROCEDURE [c: CHARACTER] = BEGIN Put.Char[wh, c]; END; CR: PROCEDURE = BEGIN Put.CR[wh]; END; StatsDefs.StatUpdate[]; -- be sure time is up to date PutHeader[wh, version, FALSE]; Text[" up "L]; PrintUpTime[]; CR[]; Text["Echo: "L]; LDS[pupsEchoed]; Text[", Route: "L]; LDS[ForwarderDefs.statGateInfoReplies]; Text[", Boot: "L]; LDS[BootServerDefs.statFileSent]; Text[", MicroBoot: "L]; LDS[BootServerDefs.statMicrocodeBooted]; CR[]; Text["Name=>Address: "L]; LDS[NameServerDefs.statName]; Text[", Address=>Name: "L]; LDS[NameServerDefs.statAddress]; Text[", 48=>8: "L]; LDS[NameServerDefs.statXlation]; Text[", Old 48=>8: "L]; LDS[NameServerDefs.statWhoAmI]; CR[]; Text["Alto Time: "L]; LDS[TimeServerDefs.statAlto]; Text[", Pilot Time: "L]; LDS[TimeServerDefs.statPilot]; Text[", Old Pilot Time: "L]; LDS[TimeServerDefs.statPilotOld]; CR[]; DoSomeYields[]; Text["Directory version: "L]; D[NameServerDefs.GetDirectoryVersion[]]; Text[", FreePBIs: "L]; D[BufferDefs.BuffersLeft[] + 2]; Text[", Free Disk Pages: "L]; D[George.CountFreeDiskPages[]]; CR[]; DoSomeYields[]; PrintMaybe["Pup Network Directories sent"L, NameServerDefs.statSend]; PrintMaybe["Slow boot files sent"L, BootServerDefs.statFileSentSlow]; PrintMaybe["New boot files retrieved"L, BootServerDefs.statBootNew]; CR[]; DoSomeYields[]; IF packets#NIL THEN PrintPacketsForwarded[]; CR[]; DoSomeYields[]; IF bytes#NIL THEN PrintBytesForwarded[]; DoSomeYields[]; END; PrintPupRoutingTable: PUBLIC PROCEDURE [wh: Window.Handle] = BEGIN O3Z: PROCEDURE [n: CARDINAL] = BEGIN Put.Number[wh, n, [8, TRUE, TRUE, 3]]; END; O4: PROCEDURE [n: CARDINAL] = BEGIN Put.Number[wh, n, [8, FALSE, TRUE, 4]]; END; PrintOne: PROCEDURE [rte: PupRouterDefs.RoutingTableEntry] = BEGIN network: DriverDefs.Network ← rte.network; IF network = NIL THEN RETURN; nets ← nets + 1; IF UserInput.userAbort THEN RETURN; IF k = 0 THEN Put.Char[wh, '|]; O4[rte.net]; O4[network.netNumber.b]; Put.Char[wh, '#]; IF rte.hop # 0 THEN O3Z[rte.route] ELSE O3Z[network.hostNumber]; Put.Char[wh, '#]; O4[rte.hop]; Put.Text[wh, " |"L]; IF (k ← k + 1) = 3 THEN BEGIN Put.CR[wh]; k ← 0; DoSomeYields[]; END; END; k, nets: CARDINAL ← 0; PutHeader[wh, " Local Routing Table."L]; Put.Line[ wh, "| Net Via Hops | Net Via Hops | Net Via Hops |"L]; Put.Line[ wh, "|-------------------|-------------------|-------------------|"L]; PupRouterDefs.EnumerateRoutingTable[PrintOne]; IF k # 0 THEN Put.CR[wh]; IF nets > 1 THEN BEGIN Put.Text[wh, "There are "L]; Put.Decimal[wh, nets - 1]; Put.Line[wh, " active networks."L]; END; END; NetworkAddress: PUBLIC TYPE = SpecialSystem.NetworkAddress; PrintOiscpRoutingTable: PUBLIC PROCEDURE [wh: Window.Handle] = BEGIN O: PROCEDURE [n: CARDINAL] = BEGIN Put.Number[wh, n, [8, FALSE, FALSE, 0]]; END; O4: PROCEDURE [n: CARDINAL] = BEGIN Put.Number[wh, n, [8, FALSE, TRUE, 4]]; END; PrintOne: PROCEDURE [rte: Router.RoutingTableEntry] = BEGIN network: DriverDefs.Network ← rte.network; IF network = NIL THEN duds ← duds + 1 ELSE nets ← nets + 1; IF UserInput.userAbort THEN RETURN; PutNetNumber[wh, rte.destNetwork]; Put.Char[wh,' ]; IF rte.delay # 1 THEN PutNetAndHost[wh,network.netNumber, rte.route] ELSE PutNetAndHost[wh, network.netNumber, me]; O4[rte.delay]; O4[rte.timeUnits]; IF rte.network=NIL THEN Put.Char[wh,'~] ELSE Put.Char[wh,' ]; Put.CR[wh]; DoSomeYields[]; END; nets, duds: CARDINAL ← 0; me: SpecialSystem.ProcessorID = SpecialSystem.GetProcessorID[]; PutHeader[wh," Local OISCP Routing Table."L]; Put.Line[wh," Net Via Dly Tim"L]; Router.EnumerateRoutingTable[PrintOne]; IF nets > 1 THEN BEGIN Put.Text[wh,"There are "L]; Put.Decimal[wh,nets - 1]; Put.Line[wh," active networks."L]; END; IF duds > 0 THEN BEGIN Put.Text[wh,"There are "L]; Put.Decimal[wh,duds]; Put.Line[wh," dead slots."L]; END; END; PutHeader: PROCEDURE [wh: Window.Handle, s: STRING, cr: BOOLEAN ← TRUE] = BEGIN Put.CR[wh]; Put.Date[wh, Time.Current[], dateTime]; Put.Text[wh, " "L]; Put.Text[wh, s]; IF cr THEN Put.CR[wh]; END; PutNetNumber: PROCEDURE [wh: Window.Handle, net: SpecialSystem.NetworkNumber] = BEGIN temp: STRING = [50]; AddressTranslation.AppendNetworkNumber[temp, net]; temp.length ← temp.length - 1; -- flush # THROUGH [temp.length..5) DO Put.Char[wh, ' ]; ENDLOOP; Put.Text[wh, temp]; END; PutNetAndHost: PROCEDURE [ wh: Window.Handle, net: SpecialSystem.NetworkNumber, host: SpecialSystem.HostNumber] = BEGIN temp: STRING = [50]; AddressTranslation.AppendSystemElement[ temp, SpecialSystem.NetworkAddress[net,host,[0]]]; THROUGH [temp.length..25) DO Put.Char[wh, ' ]; ENDLOOP; Put.Text[wh, temp]; END; DoSomeYields: PROCEDURE = BEGIN THROUGH [0..100) DO Process.Yield[]; ENDLOOP; END; Quit: PROCEDURE = BEGIN IF ~Confirm[] THEN RETURN; Cursor.Set[hourGlass]; TajoMisc.Quit[]; END; Confirm: PROCEDURE RETURNS [okay: BOOLEAN] = BEGIN oldType: Cursor.Type = Cursor.GetInfo[].type; Cursor.Set[mouseRed]; okay ← UserInput.WaitForConfirmation[].okay; IF oldType IN Cursor.Defined THEN Cursor.Set[oldType]; END; -- Initialization [packets, bytes, nets] ← ForwarderDefs.GetPointerToPupGateStats[]; SetupGateMenu[]; END.