PupEchoServerImpl.mesa
Copyright © 1986 by Xerox Corporation. All rights reserved.
Hal Murray, June 3, 1986 2:23:45 pm PDT
This is the default server that is part of the standard PupPackage.
DIRECTORY
Endian USING [FFromCard],
Booting USING [switches],
Checksum USING [ComputeChecksum],
GermSwap USING [], -- Needed by Booting.switches
Process USING [priorityNormal, SetPriority],
PupBuffer USING [Buffer, EchoStatsResponse, echoStatsVersion, noChecksum, WordsWithoutChecksum],
PupSocket USING [CreateServer, Destroy, FreeBuffer, Get, GetUserBytes, Socket, Kick, SetUserSize, waitForever],
PupSocketBackdoor USING [ReturnErrorNoFree, ReturnToSenderNoFree, SetDirectReceive, SetSoftwareChecksumming],
PupType USING [echoStatsRequest, echoStatsReply],
PupWKS USING [echo];
PupEchoServerImpl: CEDAR MONITOR
IMPORTS Booting, Checksum, Endian, Process, PupBuffer, PupSocket, PupSocketBackdoor =
BEGIN
Buffer: TYPE = PupBuffer.Buffer;
Socket: TYPE = PupSocket.Socket;
pupsEchoed: LONG CARDINAL ← 0;
bytesEchoed: LONG CARDINAL ← 0;
pupsWithBadSoftwareChecksum: LONG CARDINAL ← 0;
server: PROCESSNIL;
pleaseStop: BOOLFALSE;
socket: Socket ← NIL;
Start: PUBLIC ENTRY PROC = {
IF server # NIL THEN RETURN;
pleaseStop ← FALSE;
server ← FORK Server[];
};
Stop: PUBLIC ENTRY PROC = {
IF server = NIL THEN RETURN;
pleaseStop ← TRUE;
IF server # NIL THEN { PupSocket.Kick[socket]; TRUSTED { JOIN server; }; };
server ← NIL;
};
Server: PROC = {
Process.SetPriority[Process.priorityNormal];
socket ← PupSocket.CreateServer[
local: PupWKS.echo,
recvBuffers: 99,
getTimeout: PupSocket.waitForever];
PupSocketBackdoor.SetSoftwareChecksumming[socket: socket, send: TRUE, recv: FALSE];
PupSocketBackdoor.SetDirectReceive[socket, ProcessRequest, NIL];
UNTIL pleaseStop DO
b: Buffer ← PupSocket.Get[socket];
IF b # NIL THEN b ← ProcessRequest[socket, b, NIL];
IF b # NIL THEN PupSocket.FreeBuffer[b];
ENDLOOP;
PupSocket.Destroy[socket];
socket ← NIL;
};
ProcessRequest: PROC [socket: Socket, b: Buffer, user: REF ANY] RETURNS [Buffer] = {
SELECT b.type FROM
echoMe => TRUSTED {
Checkum code copied from PupSocketImpl.TakeThis
words: CARDINAL = PupBuffer.WordsWithoutChecksum[b.byteLength];
checksumLoc: LONG POINTER ← @b.byteLength + words;
hisChecksum: WORD ← checksumLoc^;
IF hisChecksum # PupBuffer.noChecksum THEN {
checksum: WORD ← Checksum.ComputeChecksum[0, words, @b.byteLength];
IF checksum # hisChecksum THEN {
BumpBadStats[];
b.ovh.socket ← NIL;
PupSocketBackdoor.ReturnErrorNoFree[b, badChecksum, "Bad software checksum"];
RETURN[b]; }; };
b.type ← iAmEcho;
BumpStats[PupSocket.GetUserBytes[b]];
b.ovh.socket ← NIL;
PupSocketBackdoor.ReturnToSenderNoFree[b]; };
PupType.echoStatsRequest => {
b.type ← PupType.echoStatsReply;
b.echoStats ← [
version: PupBuffer.echoStatsVersion,
pupsEchoed: Endian.FFromCard[pupsEchoed]];
PupSocket.SetUserSize[b, SIZE[PupBuffer.EchoStatsResponse]];
b.ovh.socket ← NIL;
PupSocketBackdoor.ReturnToSenderNoFree[b]; };
ENDCASE => NULL;
RETURN[b];
};

BumpBadStats: ENTRY PROC = INLINE {
pupsWithBadSoftwareChecksum ← pupsWithBadSoftwareChecksum.SUCC;
};

BumpStats: ENTRY PROC [bytes: NAT] = INLINE {
bytesEchoed ← bytesEchoed + bytes;
pupsEchoed ← pupsEchoed.SUCC;
};
IF ~Booting.switches[c] THEN Start[];
END.