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.