--Telnet.mesa --LStewart August 17, 1978 10:42 AM DIRECTORY DisplayDefs: FROM "DisplayDefs" USING [SetSystemDisplaySize], IODefs: FROM "IODefs", ProcessDefs: FROM "ProcessDefs" USING [Yield], PupStream: FROM "PupStream", Stream: FROM "Stream", StreamDefs: FROM "StreamDefs"; Telnet: PROGRAM IMPORTS DisplayDefs, IODefs, PupStream, Stream, ProcessDefs = BEGIN OPEN IODefs, PupStream; ch: CHARACTER; myWhy: PupStream.CloseReason _ localClose; whyText: ARRAY PupStream.CloseReason OF STRING _ [ "localClose", "remoteClose", "noRouteToNetwork", "transmissionTimeout", "remoteReject" ]; listener: PupListener _ NIL; socNum: PupSocketID _ [0,1]; --telnet socket herald: STRING _ "Mesa Server Telnet"; -- user stuff s: STRING _ [80]; escapeChar: CHARACTER _ 032C; --control Z address: PupAddress; mySocket: PupSocketID _ [123,456]; keyStream: StreamDefs.StreamHandle _ GetInputStream[]; myStream: Stream.Handle; closed, pleaseStop, echoLF, serverStop, connected: BOOLEAN; rp: PROCESS; SendMark: PROCEDURE[bs: Stream.Handle, markType: INTEGER, data: INTEGER] = BEGIN Stream.SetSST[bs,LOOPHOLE[markType]]; Stream.PutByte[bs,LOOPHOLE[data]]; Stream.SendNow[bs]; END; Talk: PROCEDURE = BEGIN pleaseStop _ FALSE; rp _ FORK Read[]; Write[]; JOIN rp; END; Read: PROCEDURE = BEGIN c: CHARACTER; eatByte: BOOLEAN _ FALSE; UNTIL pleaseStop DO ENABLE BEGIN Stream.SSTChange => BEGIN IF sst=5 THEN --WARNING! This is dangerous!! BEGIN Stream.SetSST[myStream,6]; Stream.SendNow[myStream]; END; IF sst=1 THEN BEGIN WriteChar[CR];WriteLine["!Synch!"]; END; IF sst=6 THEN BEGIN WriteChar[CR];WriteLine["!TimingMarkReply!"]; END; IF sst IN [2..4] THEN BEGIN WriteChar[CR];WriteString["Mark Type "]; WriteDecimal[sst];WriteString[", Argument = "]; eatByte _ TRUE; END; RESUME; END; PupStream.StreamClosing => BEGIN pleaseStop _ closed _ TRUE; connected _ FALSE; myWhy _ why; EXIT; END; Stream.TimeOut => IF pleaseStop THEN EXIT ELSE RESUME; END; c _ LOOPHOLE[Stream.GetByte[myStream]]; IF eatByte THEN BEGIN WriteDecimal[LOOPHOLE[c]];WriteChar[CR]; eatByte _ FALSE; END ELSE IF c#LF THEN WriteChar[c]; ENDLOOP; END; Write: PROCEDURE = BEGIN c: CHARACTER; UNTIL pleaseStop DO ENABLE PupStream.StreamClosing => BEGIN closed _ pleaseStop _ TRUE; connected _ FALSE; myWhy _ why; EXIT; END; IF NOT keyStream.endof[keyStream] THEN BEGIN c _ ReadChar[]; IF c=escapeChar THEN pleaseStop _ TRUE ELSE BEGIN Stream.PutByte[myStream,LOOPHOLE[c]]; IF c=CR AND echoLF THEN Stream.PutByte[myStream,LOOPHOLE[LF]]; Stream.SendNow[myStream]; END; END; ProcessDefs.Yield[]; ENDLOOP; END; Echo: PROCEDURE [bs: Stream.Handle, remote: PupAddress] = BEGIN errstr: STRING _ [80]; c: CHARACTER; i: CARDINAL; eatByte: BOOLEAN _ FALSE; -- Mainline of server WriteString["Connection from "]; AppendPupAddress[errstr,@remote]; WriteString[errstr]; WriteLine[" accepted"]; BEGIN ENABLE PupStream.StreamClosing => BEGIN WriteString["Connection with "]; AppendPupAddress[errstr,@remote]; WriteString["closed because ... "]; WriteLine[whyText[why]]; bs.delete[bs]; GOTO ShortLife; END; FOR i IN [0..herald.length) DO Stream.PutByte[bs,LOOPHOLE[herald.text[i]]]; ENDLOOP; Stream.PutByte[bs,LOOPHOLE[CR]]; IF echoLF THEN Stream.PutByte[bs,LOOPHOLE[LF]]; Stream.SendNow[bs]; END; UNTIL serverStop DO ENABLE BEGIN PupStream.StreamClosing => BEGIN WriteString["Connection with "]; AppendPupAddress[errstr,@remote]; WriteString["closed because ... "]; WriteLine[whyText[why]]; bs.delete[bs]; EXIT; END; Stream.SSTChange => BEGIN IF sst=5 THEN --WARNING! This is dangerous!! BEGIN Stream.SetSST[bs,6]; Stream.SendNow[bs]; END; IF sst=1 THEN BEGIN WriteChar[CR];WriteLine["!Synch!"]; END; IF sst=6 THEN BEGIN WriteChar[CR];WriteLine["!TimingMarkReply!"]; END; IF sst IN [2..4] THEN BEGIN WriteChar[CR];WriteString["Mark Type "]; WriteDecimal[sst];WriteString[", Argument = "]; eatByte _ TRUE; END; IF serverStop THEN EXIT ELSE RESUME; END; Stream.TimeOut => IF serverStop THEN EXIT ELSE RESUME; END; c _ LOOPHOLE[Stream.GetByte[bs]]; IF eatByte THEN BEGIN WriteDecimal[LOOPHOLE[c]];WriteChar[CR]; eatByte _ FALSE; END ELSE BEGIN IF c#LF THEN BEGIN WriteChar[c]; Stream.PutByte[bs,LOOPHOLE[c]]; END; IF c=CR AND echoLF THEN Stream.PutByte[bs,LOOPHOLE[LF]]; Stream.SendNow[bs]; END; IF listener=NIL THEN EXIT; ENDLOOP; WriteLine["Server dying..."]; bs.delete[bs]; EXITS ShortLife => NULL; END; --Mainline code DisplayDefs.SetSystemDisplaySize[40,40]; AdjustBufferParms[30,266]; connected _ FALSE; PupPackageMake[]; WriteChar[CR]; WriteLine["Alto Mesa Telnet"]; DO -- loop until stopped by user typing q or Q (last case below). ENABLE PupNameTrouble => BEGIN WriteString[" ... Error: "]; WriteLine[e]; LOOP; END; WriteChar[CR]; WriteString["# "]; ch _ ReadChar[]; SELECT ch FROM 'c, 'C => BEGIN IF connected THEN BEGIN WriteString["Connection already open to: "]; s.length _ 0; AppendPupAddress[s,@address]; WriteString[s]; GOTO Reject; END; WriteString["Connection to "]; ReadID[s ! Rubout => GOTO Reject]; GetPupAddress[@address,s]; s.length _ 0; AppendPupAddress[s,@address]; WriteString[" (...= "]; WriteString[s]; WriteString[" ) is "]; myStream _ PupByteStreamCreate[mySocket,address,SecondsToTocks[1] ! StreamClosing => BEGIN WriteLine["incomplete"]; WriteString[" because:"]; WriteString[whyText[why]]; LOOP; END]; WriteLine["complete"];WriteChar[CR]; connected _ TRUE; SendMark[myStream,4,10]; --terminal type SendMark[myStream,2,80]; --line width SendMark[myStream,3,39]; --screen height EXITS Reject => NULL; END; 'd, 'D => BEGIN WriteString["Disconnect... "]; myStream.delete[myStream]; connected _ FALSE; WriteString["Connection Closed"]; END; 'e, 'E => BEGIN WriteString["Escape Character is "]; escapeChar _ ReadChar[]; WriteChar[escapeChar]; END; 'l, 'L => BEGIN WriteString["Linefeed Echo is "]; IF echoLF THEN BEGIN WriteString["Off"]; echoLF _ FALSE; END ELSE BEGIN WriteString["On"]; echoLF _ TRUE; END; END; 'n, 'N => BEGIN address: PupAddress; s: STRING _ [80]; WriteString["Name lookup of "]; ReadID[s! Rubout => GOTO Reject]; GetPupAddress[@address,s]; s.length _ 0; AppendPupAddress[s,@address]; WriteString[" ...= "]; WriteString[s]; EXITS Reject => NULL; END; 'q, 'Q => BEGIN PupPackageDestroy[]; WriteLine["Quit"]; WriteChar[CR]; STOP; PupPackageMake[]; END; 's, 'S => BEGIN WriteString["Server Telnet "]; IF listener=NIL THEN BEGIN serverStop _ FALSE; listener _ CreatePupByteStreamListener [socNum, Echo, SecondsToTocks[3]]; WriteString["On"]; END ELSE BEGIN serverStop _ TRUE; DestroyPupListener[listener]; listener_NIL; WriteString["Off"]; END; END; '? => BEGIN WriteLine["C(onnect), Q(uit), L(inefeed Echo On/Off)"]; WriteLine["N(ame lookup), S(erver On/Off),"]; WriteLine["D(isconnect), E(scape Char is)"]; END; ENDCASE => NULL; IF connected THEN BEGIN WriteLine[" #"]; Talk[]; END; ProcessDefs.Yield[]; ENDLOOP; END.(1792)\290b6B712b8B182b4B94b4B170b33B682t2 1t0 12t2 1t0 286b5B21t2 1t0 174t2 1t0 10t2 2t0 368b4B539t2 1t0 10t2 1t0 228t2 1t0 267t2 1t0 10t2 1t0 56b33B514t2 1t0 580b13B1198t2 1t0 16t2 2t0 885t2 1t0