-- Laurel subsystem - Grapevine-watcher -- -- GVWatcher.mesa (derived from Chat.mesa) -- Andrew Birrell, 18-Feb-82 11:26:48 DIRECTORY Ascii USING[ CR ], IODefs USING[ WriteChar, WriteLine, WriteString ], LaurelExecDefs, NameInfoDefs USING[ Close, ConnectInfo, Enumerate, GetConnect, GetMembers, MemberInfo ], ProcessDefs USING[ Abort ], PupDefs, PupStream, PupTypes, Stream, Time USING[ AppendCurrent ]; GVWatcher: MONITOR IMPORTS IODefs, LaurelExecDefs, NameInfoDefs, ProcessDefs, PupStream, Stream, Time = BEGIN OPEN IODefs; serverScript: STRING = "dsdpdhq "; serverList: STRING = "gv.gv"; DoConnection: PROCEDURE[serverName: STRING] RETURNS[done: BOOLEAN] = BEGIN addr: PupDefs.PupAddress; serverStream: Stream.Handle _ NIL; setPageLength: Stream.SubSequenceType = 3; timingMark: Stream.SubSequenceType = 5; timingMarkReply: Stream.SubSequenceType = 6; UserToServer: PROCEDURE = BEGIN ENABLE ABORTED, PupStream.StreamClosing => GOTO return; SendStringToServer[serverScript]; EXITS return => NULL; END; AcceptFromServer: PROC[serverStream: Stream.Handle] = BEGIN userToServer: PROCESS = FORK UserToServer[]; DO ENABLE BEGIN ABORTED, PupStream.StreamClosing => { ProcessDefs.Abort[userToServer] }; UNWIND => JOIN userToServer-- outside the Pup pkg monitor! --; END; buffer: STRING _ [200]; why: Stream.CompletionCode; mySST: Stream.SubSequenceType; [buffer.length, why, mySST] _ Stream.GetBlock[serverStream, [@buffer.text, 0, buffer.maxlength]]; WriteString[buffer]; IF why = sstChange AND mySST = timingMark THEN Stream.SetSST[serverStream, timingMarkReply]; ENDLOOP; END; SendStringToServer: PROCEDURE[s: STRING] = BEGIN FOR i: CARDINAL IN [0 .. s.length) DO Stream.PutChar[serverStream, s[i]]; ENDLOOP; Stream.SendNow[serverStream]; END; WriteCRStringHost: PROCEDURE[s: STRING] = BEGIN WriteChar[Ascii.CR]; WriteString[s]; WriteString[serverName]; END; FinishStringWithErrorMsg: PROCEDURE[errorMsg: STRING] = BEGIN IF errorMsg # NIL THEN BEGIN WriteString[": "L]; WriteString[errorMsg]; END; WriteChar['.]; END; done _ FALSE; WriteString[" ---------- "]; WriteCRStringHost["Connecting to "L]; WriteString[" ... "L]; BEGIN connect: STRING = [64]; info: NameInfoDefs.ConnectInfo = NameInfoDefs.GetConnect[serverName, connect]; SELECT info FROM allDown => { WriteString["no R-Server available"L]; GOTO failed }; notFound, group => { WriteString["not an individual"L]; GOTO failed }; individual => NULL; ENDCASE => ERROR; -- remove socket number, if any -- FOR i: CARDINAL DECREASING IN [0..connect.length) DO IF connect[i] = '# THEN { connect.length _ i+1; EXIT }; IF connect[i] = '+ THEN { connect.length _ i; EXIT }; ENDLOOP; WriteString[connect]; WriteString[" ... "L]; addr.socket _ PupTypes.telnetSoc; -- default socket number -- PupStream.GetPupAddress[@addr, connect ! PupStream.PupNameTrouble => BEGIN WriteString["Can't find host name"L]; FinishStringWithErrorMsg[e]; GOTO failed; END]; serverStream _ PupStream.PupByteStreamCreate [addr, PupDefs.veryLongWait ! PupStream.StreamClosing => BEGIN WriteString["Can't connect to host"L]; FinishStringWithErrorMsg[text]; GOTO failed; END]; WriteLine["open."L]; END; Stream.SetInputOptions[serverStream, [TRUE,FALSE,FALSE,FALSE,FALSE] ]; AcceptFromServer[serverStream ! PupStream.StreamClosing => BEGIN WriteCRStringHost["Connection closed by "L]; FinishStringWithErrorMsg[text]; CONTINUE END ]; serverStream.delete[serverStream]; EXITS failed => NULL; END--DoConnection--; WriteHerald: PROCEDURE = BEGIN s: STRING = [22]; -- 18-Feb-82 11:45:46 PST -- WriteChar[Ascii.CR]; WriteString["Grapevine Statistics Watcher, started at "L]; Time.AppendCurrent[s,TRUE]; WriteString[s]; END; -- of WriteHerald -- -- main program LaurelExecDefs.MakeMenuCommandCallable[newMail]; LaurelExecDefs.MakeMenuCommandCallable[user]; LaurelExecDefs.MakeMenuCommandCallable[mailFile]; LaurelExecDefs.MakeMenuCommandCallable[display]; LaurelExecDefs.MakeMenuCommandCallable[delete]; LaurelExecDefs.MakeMenuCommandCallable[undelete]; LaurelExecDefs.MakeMenuCommandCallable[moveTo]; LaurelExecDefs.MakeMenuCommandCallable[copy]; WriteHerald[]; BEGIN info: NameInfoDefs.MemberInfo = NameInfoDefs.GetMembers[serverList]; WITH i: info SELECT FROM allDown => WriteString["Can't expand server-list"L]; notFound, individual => WriteString["Incorrect server-list"L]; group => BEGIN NameInfoDefs.Enumerate[i.members, DoConnection]; NameInfoDefs.Close[i.members]; END; ENDCASE => ERROR; END; WriteString[" ----- "]; END.