DIRECTORY BasicTime USING [Now], Commander USING [CommandProc, Register], GVBasics USING [RName], GVNames USING [ConnectInfo, GetConnect, GetMembers, MemberInfo], IO USING [Close, EndOfStream, Flush, GetChar, LF, PutChar, PutF, PutRope, STREAM], Process USING [Abort, Detach], Rope USING [ROPE], Pup USING [Address], PupName USING [Error, NameLookup], PupStream USING [ConsumeMark, Create, SendMark, StreamClosing, waitForever], PupWKS USING [telnet], ViewerIO USING [CreateViewerStreams]; GVWatcher: CEDAR PROGRAM IMPORTS BasicTime, Commander, GVNames, IO, Process, PupName, PupStream, ViewerIO = { MemberInfo: TYPE = GVNames.MemberInfo; serverScript: Rope.ROPE = "dtdsdpdhq\n"; serverList: Rope.ROPE = "gv.gv"; DoConnection: PROC [out: IO.STREAM, serverName: Rope.ROPE] = { addr: Pup.Address; serverStream: IO.STREAM _ NIL; setPageLength: [0..256) = 3; timingMark: [0..256) = 5; timingMarkReply: [0..256) = 6; UserToServer: PROC = { ENABLE ABORTED, PupStream.StreamClosing => CONTINUE; IO.PutRope[serverStream, serverScript]; IO.Flush[serverStream]; }; AcceptFromServer: PROC [serverStream: IO.STREAM] = { userToServer: PROCESS; TRUSTED { userToServer _ FORK UserToServer[]; }; DO BEGIN ENABLE BEGIN ABORTED, PupStream.StreamClosing => TRUSTED { Process.Abort[userToServer]; }; UNWIND => TRUSTED { JOIN userToServer; }; -- outside the Pup pkg monitor! IO.EndOfStream => GOTO Mark; END; c: CHAR = IO.GetChar[serverStream]; IF c # IO.LF THEN IO.PutChar[out, c]; EXITS Mark => BEGIN value: [0..256) = PupStream.ConsumeMark[serverStream]; IF value = timingMark THEN PupStream.SendMark[serverStream, timingMarkReply]; END; END; ENDLOOP; }; IO.PutF[out, "\n\n----------\n\nConnecting to %g ... ", [rope[serverName]] ]; BEGIN connect: Rope.ROPE; info: GVNames.ConnectInfo; [info, connect] _ GVNames.GetConnect[serverName]; SELECT info FROM allDown => { IO.PutRope[out, "no R-Server available"]; GOTO Failed; }; notFound, group => { IO.PutRope[out, "not an individual"]; GOTO Failed; }; individual => NULL; ENDCASE => ERROR; IO.PutF[out, "%g ... ", [rope[connect]]]; addr _ PupName.NameLookup[connect, PupWKS.telnet ! PupName.Error => BEGIN IO.PutF[out, "Can't find host name: %g.", [rope[text]]]; GOTO Failed; END]; addr.socket _ PupWKS.telnet; -- force socket number serverStream _ PupStream.Create[addr, PupStream.waitForever, PupStream.waitForever ! PupStream.StreamClosing => BEGIN IO.PutF[out, "Can't connect to host: %g.", [rope[text]]]; GOTO Failed; END]; IO.PutRope[out, "open."]; END; AcceptFromServer[serverStream ! PupStream.StreamClosing => BEGIN IO.PutF[out, "\nConnection closed by %g", [rope[serverName]] ]; IF text # NIL THEN out.PutF[": %g", [rope[text]] ]; CONTINUE END ]; IO.Close[serverStream]; EXITS Failed => NULL; }; DoIt: Commander.CommandProc = { TRUSTED { Process.Detach[FORK ReallyDoit[]]; }; }; ReallyDoit: PROC = { out: IO.STREAM = ViewerIO.CreateViewerStreams["GV Statistics watcher"].out; info: MemberInfo = GVNames.GetMembers[serverList]; IO.PutF[ out, "\nGrapevine Statistics Watcher started at %g%l", [time[BasicTime.Now[]]], [rope["f"]] ]; SELECT info.type FROM allDown => IO.PutRope[out, "\nCan't expand server-list"]; notFound => IO.PutRope[out, "\nIncorrect server-list"]; individual => IO.PutRope[out, "\nIncorrect server-list"]; group => { group: group MemberInfo = NARROW[info, group MemberInfo]; FOR members: LIST OF Rope.ROPE _ group.members, members.rest UNTIL members = NIL DO DoConnection[out, members.first]; ENDLOOP; }; ENDCASE => ERROR; IO.PutRope[out, "\n\n-----\n"]; }; Commander.Register[key: "GVWatcher", proc: DoIt, doc: "Get statistics from Grapevine servers"]; }. GVWatcher - get statistics from each server Andrew Birrell, December 23, 1982 10:32 am Michael Schroeder, December 27, 1983 10:20 am Hal Murray, March 13, 1986 6:54:05 pm PST main procedure [cmd: Handle] RETURNS [result: REF _ NIL, msg: Rope.ROPE _ NIL] Κ ˜šœ+™+Jšœ*™*J™-Icode™)—J˜šΟk ˜ Jšœ œ˜Jšœ œ˜(Jšœ œ ˜Jšœœ3˜@Jšœœ%œœ˜RJšœœ˜Jšœœœ˜Jšœœ ˜Jšœœ˜"Jšœ œ=˜LJšœœ ˜Jšœ œ˜%—J˜JšΟn œœ˜J˜Jšœ œ+˜TJ˜Jšœ œ˜&J˜Jšœœ˜(J˜Jšœœ ˜ J˜š ž œœœœœ˜>J˜Jšœœœœ˜J˜J˜J˜J˜šž œœ˜Jšœœœ˜4Jšœ%˜'Jšœ˜Jšœ˜J˜—šžœœœœ˜4Jšœœ˜Jšœœ˜0šœ˜š˜Jš˜Jšœœ"˜MJšœœœΟc˜IJšœœ˜Jšœ˜—Jšœœœ˜#Jš œœœœœ˜%šœ˜ Jš˜J˜6Jšœœ3˜MJšœ˜—Jšœ˜—Jšœ˜Jšœ˜J˜—J˜JšœK˜Mš˜Jšœœ˜J˜J˜1šœ˜Jšœ œ(œ ˜FJšœœ$œ ˜J˜ Jšœ˜——Jšœœ˜Jšœ'˜)šœC˜CJš˜Jšœ6˜8Jšœ˜ Jšœ˜—JšœŸ˜3šœR˜Ršœ˜Jš˜Jšœ7˜9Jšœ˜ Jšœ˜——Jšœ˜—Jšœ˜˜:Jš˜Jšœ=˜?Jšœœœ!˜3Jš˜Jšœ˜—Jšœ˜Jšœ œ˜Jšœ˜J˜J˜—Jšœ™J˜Jšœ˜š œœ œœ œœ™?Jšœœ˜/Jšœ˜J˜—šž œœ˜Jšœœœ=˜KJ˜2šœ˜Jšœ˜Jšœ1˜1Jšœ˜Jšœ˜—šœ ˜Jšœ œ,˜9Jšœ œ)˜7Jšœœ)˜9šœ ˜ Jšœœ˜9š œ œœœœ œ˜SJšœ!˜!Jšœ˜—J˜—Jšœœ˜—Jšœ˜Jšœ˜J˜—Icode1šœ_˜_J˜Jšœ˜J˜J˜J˜—…—4B