-- 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.