-- Copyright (C) 1984, 1985 by Xerox Corporation. All rights reserved. -- GateInfoNoDisk.mesa, HGM, 6-Aug-85 23:47:49 DIRECTORY Process USING [Yield], Put USING [CR, Char, Date, Line, LongNumber, Number, Text], Time USING [Current], Window USING [Handle], Buffer USING [], BufferOps USING [GetStatistics, Statistics], Driver USING [Network, GetDeviceChain], EchoServer USING [GetCounters], ForwarderDefs USING [ Counters, GetPointerToBadPupStats, GetPointerToPupGateStats, statGateInfoReplies], GateDefs USING [GetVersionText], CpuIdle USING [GetSmoothedCpuUtilization], Inr USING [ForwardingStats], NameServerDefs USING [ GetNewDirectoryVersion, GetOldDirectoryVersion, statName, statAddress, statXlation, statSend], Protocol1 USING [GetContext], PupRouterDefs USING [NetworkContext], PupTimeServer USING [GetAltoTimeRequests], Stats USING [ StatCounterIndex, StatGetCounter, StatPrintCurrent, StatSince, StatUpdate], TimeServerOps USING [GetOldTimeRequests, GetTimeRequests], OthelloDefs USING [CommandProcessor, IndexTooLarge, MyNameIs, RegisterCommandProc]; GateInfoNoDisk: PROGRAM IMPORTS Process, Put, Time, BufferOps, Driver, EchoServer, ForwarderDefs, GateDefs, CpuIdle, Inr, NameServerDefs, Protocol1, PupTimeServer, Stats, TimeServerOps, OthelloDefs EXPORTS Buffer = BEGIN Network: PUBLIC TYPE = Driver.Network; version: LONG STRING = GateDefs.GetVersionText[]; firstNetwork: Driver.Network = Driver.GetDeviceChain[]; packets: LONG POINTER TO ForwarderDefs.Counters; bytes: LONG POINTER TO ForwarderDefs.Counters; bad: LONG POINTER TO ForwarderDefs.Counters; nets: CARDINAL; PrintGateStats: PUBLIC PROCEDURE [wh: Window.Handle] = BEGIN PupForwardingStats: PROCEDURE RETURNS [p, b: LONG CARDINAL ← 0] = BEGIN FOR from: Driver.Network ← firstNetwork, from.next UNTIL from = NIL DO FOR to: Driver.Network ← firstNetwork, to.next UNTIL to = NIL DO p ← p + packets[from.index + to.index*nets]; b ← b + bytes[from.index + to.index*nets]; ENDLOOP; ENDLOOP; END; PrintPacketsForwarded: PROCEDURE = BEGIN Line["Packets forwarded:"L]; Text[" Discard"L]; FOR to: Driver.Network ← firstNetwork, to.next UNTIL to = NIL DO toContext: PupRouterDefs.NetworkContext ← Protocol1.GetContext[to, pup]; Text[" "L]; O4[toContext.pupNetNumber]; ENDLOOP; IF bad # NIL THEN FOR network: Driver.Network ← firstNetwork, network.next UNTIL network = NIL DO IF bad[network.index] # 0 THEN BEGIN Text[" Bad"L]; EXIT; END; ENDLOOP; CR[]; FOR from: Driver.Network ← firstNetwork, from.next UNTIL from = NIL DO fromContext: PupRouterDefs.NetworkContext ← Protocol1.GetContext[from, pup]; O4[fromContext.pupNetNumber]; Text[IF from.alive THEN " "L ELSE "*"L]; LD10Dash[packets[from.index + 0*nets]]; FOR to: Driver.Network ← firstNetwork, to.next UNTIL to = NIL DO LD10Dash[packets[from.index + to.index*nets]]; ENDLOOP; IF bad # NIL AND (bad[from.index] # 0) THEN LD10Dash[bad[from.index]]; CR[]; ENDLOOP; END; PrintBytesForwarded: PROCEDURE = BEGIN Line["KBytes forwarded:"L]; Text[" Discard"L]; FOR to: Driver.Network ← firstNetwork, to.next UNTIL to = NIL DO toContext: PupRouterDefs.NetworkContext ← Protocol1.GetContext[to, pup]; Text[" "L]; O4[toContext.pupNetNumber]; ENDLOOP; CR[]; FOR from: Driver.Network ← firstNetwork, from.next UNTIL from = NIL DO fromContext: PupRouterDefs.NetworkContext ← Protocol1.GetContext[from, pup]; O4[fromContext.pupNetNumber]; Text[IF from.alive THEN " "L ELSE "*"L]; LD10Dash[bytes[from.index + 0*nets]/1000]; FOR to: Driver.Network ← firstNetwork, to.next UNTIL to = NIL DO LD10Dash[bytes[from.index + to.index*nets]/1000]; ENDLOOP; CR[]; ENDLOOP; END; PrintMaybe: PROCEDURE [s: LONG STRING, x: Stats.StatCounterIndex] = BEGIN n: LONG CARDINAL = Stats.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.Number[wh, n, [10, FALSE, TRUE, 0]]; END; LD: PROCEDURE [n: LONG CARDINAL] = BEGIN Put.LongNumber[wh, n, [10, FALSE, TRUE, 0]]; END; LDS: PROCEDURE [x: Stats.StatCounterIndex] = BEGIN LD[Stats.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 ← Stats.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: LONG STRING] = BEGIN Put.Line[wh, s]; END; Text: PROCEDURE [s: LONG STRING] = BEGIN Put.Text[wh, s]; END; Char: PROCEDURE [c: CHARACTER] = BEGIN Put.Char[wh, c]; END; CR: PROCEDURE = BEGIN Put.CR[wh]; END; Stats.StatUpdate[]; -- be sure time is up to date PutHeader[wh, version, FALSE]; CR[]; Text["UP = "L]; PrintUpTime[]; Text[", CPU = "]; D[CpuIdle.GetSmoothedCpuUtilization[]]; Text["%"]; CR[]; BEGIN packets, bytes: LONG CARDINAL; [packets, bytes] ← EchoServer.GetCounters[]; Text["Echo: "L]; LD[packets]; Text[" packets, "L]; LD[bytes]; Text[" bytes"L]; Text[", Time: "L]; LD[TimeServerOps.GetTimeRequests[]]; Text[", Old Time: "L]; LD[TimeServerOps.GetOldTimeRequests[]]; CR[]; END; BEGIN seconds: LONG CARDINAL = Stats.StatGetCounter[statSeconds]; packets, bytes: LONG CARDINAL; [packets, bytes] ← Inr.ForwardingStats[]; Text["NS: "L]; LD[packets]; Text[" packets, "L]; LD[bytes]; Text[" bytes"L]; IF seconds # 0 THEN BEGIN Text[", "L]; LD[packets/seconds]; Text[" packets/second, "L]; LD[bytes/(seconds/8)]; Text[" bits/second"L]; END; CR[]; [packets, bytes] ← PupForwardingStats[]; Text["Pup: "L]; LD[packets]; Text[" packets, "L]; LD[bytes]; Text[" bytes"L]; IF seconds # 0 THEN BEGIN Text[", "L]; LD[packets/seconds]; Text[" packets/second, "L]; LD[bytes/(seconds/8)]; Text[" bits/second"L]; END; CR[]; END; Text["PupEcho: "L]; LDS[pupsEchoed]; Text[", Route: "L]; LDS[ForwarderDefs.statGateInfoReplies]; Text[", Alto Time: "L]; LD[PupTimeServer.GetAltoTimeRequests[]]; CR[]; Text["Name=>Address: "L]; LDS[NameServerDefs.statName]; Text[", Address=>Name: "L]; LDS[NameServerDefs.statAddress]; Text[", 48=>8: "L]; LDS[NameServerDefs.statXlation]; CR[]; DoSomeYields[]; BEGIN version: CARDINAL; inTransit: BOOLEAN; Text["Directory version: "L]; [version, inTransit] ← NameServerDefs.GetOldDirectoryVersion[]; D[version]; IF inTransit THEN Text["(In Transit)"L]; [version, inTransit] ← NameServerDefs.GetNewDirectoryVersion[]; Text["/"L]; D[version]; END; BEGIN info: ARRAY BufferOps.Statistics OF CARDINAL ← BufferOps.GetStatistics[]; Text[", Buffers: "L]; D[info[available]]; Text["/"L]; D[info[allocated]]; Text["/"L]; D[info[requested]]; END; CR[]; DoSomeYields[]; PrintMaybe["Pup Network Directories sent"L, NameServerDefs.statSend]; CR[]; DoSomeYields[]; IF packets # NIL THEN PrintPacketsForwarded[]; CR[]; DoSomeYields[]; IF bytes # NIL THEN PrintBytesForwarded[]; DoSomeYields[]; END; PutHeader: PROCEDURE [wh: Window.Handle, s: LONG 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; DoSomeYields: PROCEDURE = BEGIN THROUGH [0..100) DO Process.Yield[]; ENDLOOP; END; Commands: PROC [index: CARDINAL] = BEGIN Push: PROCEDURE [s: LONG STRING, clientData: LONG POINTER] = BEGIN Put.Line[NIL, s]; END; SELECT index FROM 0 => BEGIN OthelloDefs.MyNameIs[ myNameIs: "Gate Info"L, myHelpIs: "Print Pup Gateway Forwarding Matrix"L]; PrintGateStats[NIL]; END; 1 => BEGIN OthelloDefs.MyNameIs[ myNameIs: "Stats Recent"L, myHelpIs: "Print Statistics accumulated since the last time they were printed"L]; Stats.StatSince[Push]; END; 2 => BEGIN OthelloDefs.MyNameIs[ myNameIs: "Stats Totals"L, myHelpIs: "Print Statistics accumulated since we were booted"L]; Stats.StatPrintCurrent[Push]; END; ENDCASE => OthelloDefs.IndexTooLarge; END; -- Initialization commandProcessor: OthelloDefs.CommandProcessor ← [Commands]; [packets, bytes, nets] ← ForwarderDefs.GetPointerToPupGateStats[]; bad ← ForwarderDefs.GetPointerToBadPupStats[]; OthelloDefs.RegisterCommandProc[@commandProcessor]; END.