<> <> <> <<>> <> 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], PupStream, PupTypes USING[ telnetSoc ], ViewerIO USING[ CreateViewerStreams ]; GVWatcher: MONITOR IMPORTS BasicTime, Commander, GVNames, IO, Process, PupStream, ViewerIO = BEGIN serverScript: Rope.ROPE = "dtdsdpdhq\n"; serverList: Rope.ROPE = "gv.gv"; DoConnection: PROCEDURE[out: IO.STREAM, serverName: Rope.ROPE] = BEGIN addr: PupStream.PupAddress; serverStream: IO.STREAM _ NIL; setPageLength: [0..256) = 3; timingMark: [0..256) = 5; timingMarkReply: [0..256) = 6; UserToServer: PROCEDURE = BEGIN ENABLE ABORTED, PupStream.StreamClosing => GOTO return; serverStream.PutRope[serverScript]; serverStream.Flush[]; EXITS return => NULL; END; AcceptFromServer: PROC[serverStream: IO.STREAM] = BEGIN userToServer: PROCESS = FORK UserToServer[]; DO BEGIN ENABLE BEGIN ABORTED, PupStream.StreamClosing => { Process.Abort[userToServer] }; UNWIND => JOIN userToServer-- outside the Pup pkg monitor! --; IO.EndOfStream => GOTO mark; END; c: CHAR = serverStream.GetChar[]; IF c # IO.LF THEN out.PutChar[c]; EXITS mark => BEGIN value: [0..256) = PupStream.ConsumeMark[serverStream]; IF value = timingMark THEN PupStream.SendMark[serverStream, timingMarkReply]; END; END; ENDLOOP; END; out.PutF["\n\n----------\n\nConnecting to %g ... ", [rope[serverName]] ]; BEGIN connect: Rope.ROPE; info: GVNames.ConnectInfo; [info, connect] _ GVNames.GetConnect[serverName]; SELECT info FROM allDown => { out.PutRope["no R-Server available"]; GOTO failed }; notFound, group => { out.PutRope["not an individual"]; GOTO failed }; individual => NULL; ENDCASE => ERROR; out.PutF["%g ... ", [rope[connect]]]; addr _ PupStream.GetPupAddress[PupTypes.telnetSoc, connect ! PupStream.PupNameTrouble => BEGIN out.PutF["Can't find host name: %g.", [rope[e]]]; GOTO failed; END]; addr.socket _ PupTypes.telnetSoc; -- force socket number -- serverStream _ PupStream.PupByteStreamCreate [addr, PupStream.veryLongWait ! PupStream.StreamClosing => BEGIN out.PutF["Can't connect to host: %g.", [rope[text]]]; GOTO failed; END]; out.PutRope["open."]; END; AcceptFromServer[serverStream ! PupStream.StreamClosing => BEGIN out.PutF["\nConnection closed by %g", [rope[serverName]] ]; IF text # NIL THEN out.PutF[": %g", [rope[text]] ]; CONTINUE END ]; serverStream.Close[]; EXITS failed => NULL; END--DoConnection--; <
> DoIt: Commander.CommandProc = TRUSTED <<[cmd: Handle] RETURNS [result: REF _ NIL, msg: Rope.ROPE _ NIL]>> { Process.Detach[FORK ReallyDoit[]] }; ReallyDoit: PROC = BEGIN out: IO.STREAM = ViewerIO.CreateViewerStreams["GV Statistics watcher"].out; info: GVNames.MemberInfo = GVNames.GetMembers[serverList]; out.PutF["\nGrapevine Statistics Watcher started at %g%l", [time[BasicTime.Now[]]], [rope["f"]] ]; WITH i: info SELECT FROM allDown => out.PutRope["\nCan't expand server-list"]; notFound, individual => out.PutRope["\nIncorrect server-list"]; group => FOR l: LIST OF Rope.ROPE _ i.members, l.rest UNTIL l = NIL DO DoConnection[out, l.first]; ENDLOOP; ENDCASE => ERROR; out.PutRope["\n\n-----\n"]; END; Commander.Register[key: "GVWatcher", proc: DoIt, doc: "Get statistics from Grapevine servers"]; END.