DIRECTORY IO USING [STREAM], Process USING [Detach], PupRouterDefs USING [GetFirstPupSocket, PupRouterSocket], PupStream USING [ PupByteStreamMake, RejectThisRequest], PupDefs USING [PupAddress, PupBuffer, PupSocketID, Tocks, PupRouterSendThis, SendErrorPup, SwapPupSourceAndDest, ReturnFreePupBuffer, PupSocket, PupSocketMake, PupSocketKick, PupSocketDestroy, veryLongWait, SetPupContentsBytes, AppendRopeToPupBuffer], PupTypes USING [fillInPupAddress]; PupListeners: MONITOR IMPORTS Process, PupRouterDefs, PupStream, PupDefs EXPORTS PupStream = BEGIN OPEN PupRouterDefs, PupStream, PupDefs; PupListener: TYPE = REF PupListenerObject; PupListenerObject: PUBLIC TYPE = RECORD[ socket: PupSocket, timeout: Tocks, stop: BOOLEAN, who: PROCEDURE [IO.STREAM, PupAddress], check: PROCEDURE [PupAddress], proc: PROCESS ]; DontReject: PUBLIC SAFE PROCEDURE [PupAddress] = CHECKED BEGIN END; CreatePupByteStreamListener: PUBLIC SAFE PROCEDURE [ local: PupSocketID, proc: PROCEDURE [IO.STREAM, PupAddress], ticks: Tocks, filter: PROCEDURE [PupAddress]] RETURNS [PupListener] = TRUSTED BEGIN him: PupListener = NEW[PupListenerObject]; him.socket _ PupSocketMake[local, PupTypes.fillInPupAddress, veryLongWait]; him.timeout _ ticks; him.stop _ FALSE; him.who _ proc; him.check _ filter; him.proc _ FORK Listen[him, local]; RETURN[him]; END; DestroyPupListener: PUBLIC SAFE PROCEDURE [listener: PupListener] = TRUSTED BEGIN listener.stop _ TRUE; PupSocketKick[listener.socket]; JOIN listener.proc; PupSocketDestroy[listener.socket]; END; Listen: PROCEDURE [listener: PupListener, local: PupSocketID] = BEGIN soc: PupRouterSocket; arg: IO.STREAM; b: PupBuffer; UNTIL listener.stop DO b _ listener.socket.get[]; IF b # NIL THEN BEGIN SELECT b.pupType FROM rfc => BEGIN OPEN PupStream; FOR soc _ GetFirstPupSocket[], soc.next UNTIL soc = NIL DO IF soc.remote # b.source THEN LOOP; IF soc.id # b.pupID THEN LOOP; b.address _ soc.local; SwapPupSourceAndDest[b]; PupRouterSendThis[b]; EXIT; ENDLOOP; IF soc = NIL THEN BEGIN -- not a duplicate, make a new connection him: PupAddress _ b.address; listener.check[ him ! RejectThisRequest => BEGIN b.pupType _ abort; SwapPupSourceAndDest[b]; SetPupContentsBytes[b, 2]; AppendRopeToPupBuffer[b, error]; PupRouterSendThis[b]; GOTO Reject; END]; ReturnFreePupBuffer[b]; arg _ PupByteStreamMake[ local, him, listener.timeout, alreadyOpened, b.pupID]; Process.Detach[FORK listener.who[arg, him]]; END; EXITS Reject => NULL; END; echoMe => BEGIN b.pupType _ iAmEcho; SwapPupSourceAndDest[b]; PupRouterSendThis[b]; END; ENDCASE => SendErrorPup[b, LOOPHOLE[100B], "RFC expected"]; END; ENDLOOP; END; END. -- of PupListeners žPupListeners.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Andrew Birrell May 12, 1983 10:56 am check for duplicate initialization Κ½˜codešœ™Kšœ Οmœ1™