RemoteViewersHostSpy.mesa
Copyright Ó 1990, 1992 by Xerox Corporation. All rights reserved.
Wes Irish, March 10, 1989 10:07:58 am PST
Last tweaked by Mike Spreitzer on September 12, 1990 11:55 am PDT
DIRECTORY BasicTime, Commander, Convert,
IO, NetAddressing, Process, PupStream, PupStreamCellarWindow, RemoteViewersHostBackdoor, Rope, TypeScript, ViewerClasses, ViewerOps;
RemoteViewersHostSpy:
CEDAR
PROGRAM
IMPORTS BasicTime, Commander, Convert, IO, NetAddressing, Process, PupStream, PupStreamCellarWindow, RemoteViewersHostBackdoor, Rope, TypeScript, ViewerOps
=
BEGIN
Viewer: TYPE ~ ViewerClasses.Viewer;
STREAM: TYPE ~ IO.STREAM;
ROPE: TYPE ~ Rope.ROPE;
Stats: TYPE ~ PupStreamCellarWindow.Stats;
StatsLabels: TYPE ~ PupStreamCellarWindow.StatsLabels;
StatsInfoList: TYPE = LIST OF StatsInfoObject;
StatsInfoObject:
TYPE =
RECORD [inLabel, outLabel:
ROPE, index:
INT ¬ -1];
updateInterval: INT ¬ 15; -- seconds between updates
script: Viewer ¬ NIL;
statsInfoList: StatsInfoList ¬
LIST [
["packetsPushed", "snd"],
["inOrderPackets", "rcv"],
["packetsRetransmitted", "rtr"],
["oldPackets", "dup"],
["resourceLimitsErrors", "res"]
["funnyPacketType", "funnyPacketType"],
["acksDefered", "acksDefered"],
["oldAcks", "oldAcks"],
["futurePackets", "futurePackets"],
["clumpsRetransmitted", "clumpsRetransmitted"],
];
DoViewer:
PROC [stream:
STREAM, address: NetAddressing.Address] ~ {
PutRope[IO.PutFR["Connection Established from: %g", [rope[NetAddressing.FormatAddress[address, FALSE]]]]];
IF address.kind # pup
THEN {
PutRope["Sorry, no Stats available for this transport.\n"];
RETURN;
};
{ENABLE IO.Error, PupStream.StreamClosing => CONTINUE;
prevStats: Stats ¬ PupStreamCellarWindow.GetStreamStats[stream];
DO
Process.PauseMsec[updateInterval*1000];
PupStream.CheckConnection[stream];
{stats: Stats ¬ PupStreamCellarWindow.GetStreamStats[stream];
PutRope[CreateStatsRope[stream, stats, prevStats]];
prevStats ¬ stats;
}ENDLOOP;
};
PutRope["Connection Closed since last sampling.\n"];
RETURN};
CreateStatsRope:
PROC [stream:
STREAM, stats, prevStats: Stats]
RETURNS [rope:
ROPE] ~ {
FOR info: StatsInfoList ¬ statsInfoList, info.rest
WHILE info #
NIL
DO
IF info.first.index < 0 THEN LOOP;
rope ¬ Rope.Cat[rope, IO.PutFR["%g: %g/%g", [rope[info.first.outLabel]], [cardinal[stats[info.first.index]-prevStats[info.first.index]]], [cardinal[stats[info.first.index]]]]];
IF info.rest # NIL THEN rope ¬ Rope.Cat[rope, ", "];
ENDLOOP;
RETURN};
PutRope:
PROC [rope:
ROPE, stampIt:
BOOL ¬
TRUE] ~ {
IF script = NIL OR script.destroyed THEN RETURN;
IF stampIt THEN rope ¬ Rope.Cat[IO.PutFR["%g: ", [rope[Convert.RopeFromTime[from: BasicTime.Now[], start: hours, end: seconds, includeDayOfWeek: FALSE, useAMPM: TRUE, includeZone: FALSE]]]], rope];
script.name ¬ rope;
TypeScript.PutRope[script, rope];
TypeScript.PutChar[script, '\n];
ViewerOps.PaintViewer[script, caption];
};
HostStatsProc: Commander.CommandProc = {
GetViewer[];
RETURN};
GetViewer:
PROC ~ {
IF script #
NIL
AND script.destroyed
THEN {
script ¬ NIL;
};
IF script =
NIL
THEN {
s: Viewer ~ TypeScript.Create[info: [name: "Host Spy", label: "Host Spy", column: right, iconic: TRUE]];
ViewerOps.SetOpenHeight[s, -12];
ViewerOps.OpenIcon[icon: s, bottom: FALSE];
script ¬ s;
};
};
SetUpStatsInfoList:
PROC ~ {
statsLabels: StatsLabels ¬ PupStreamCellarWindow.GetStreamStatsLabels[];
GetIndex:
PROC [label:
ROPE]
RETURNS [index:
INT ¬ -1] ~ {
FOR i:
CARDINAL
IN [0..statsLabels.length)
DO
IF Rope.Equal[s1: label, s2: statsLabels[i], case: FALSE] THEN RETURN[i];
ENDLOOP;
};
FOR info: StatsInfoList ¬ statsInfoList, info.rest
WHILE info #
NIL
DO
info.first.index ¬ GetIndex[info.first.inLabel];
ENDLOOP;
};
Start:
PROC ~ {
SetUpStatsInfoList[];
RemoteViewersHostBackdoor.SetSpy[DoViewer];
Commander.Register[key: "HostSpy", proc: HostStatsProc, doc: "Create a viewer for spying on the host side of a RemoteTerminal session."];
RETURN};
Start[];
END.