-- File: PupListeners.mesa, Last Edit: HGM August 23, 1980 7:19 PM -- Copyright Xerox Corporation 1979, 1980 DIRECTORY Stream: FROM "Stream" USING [Handle], CommUtilDefs: FROM "CommUtilDefs" USING [ GlobalFrame, MyGlobalFrame, Copy, UnNew, Detach], PupRouterDefs: FROM "PupRouterDefs" USING [GetFirstPupSocket, PupRouterSocket], PupPktDefs: FROM "PupPktDefs" USING [PupPktStreamMake, PupPktStream], PupStream: FROM "PupStream" USING [ PupByteStreamMake, PupListener, PupListenerObject, RejectThisRequest], PupDefs: FROM "PupDefs" USING [ PupAddress, PupBuffer, PupSocketID, Tocks, PupRouterSendThis, SendErrorPup, SwapPupSourceAndDest, PupSocket, PupSocketMake, PupSocketKick, PupSocketDestroy, veryLongWait, SetPupContentsBytes, AppendStringBodyToPupBuffer, ReturnFreePupBuffer], PupTypes: FROM "PupTypes" USING [fillInPupAddress]; PupListeners: MONITOR IMPORTS CommUtilDefs, PupRouterDefs, PupPktDefs, PupStream, PupDefs EXPORTS PupPktDefs, PupStream = BEGIN OPEN PupRouterDefs, PupStream, PupDefs; myPupListener: PupListenerObject _ [LOOPHOLE[Listen]]; socket: PupSocket; timeout: Tocks; stop: BOOLEAN _ FALSE; proc: PROCESS; who: PROCEDURE [UNSPECIFIED,PupAddress]; check: PROCEDURE [PupAddress]; Kind: TYPE = {pkt, byte}; kind: Kind; DontReject: PUBLIC PROCEDURE [PupAddress] = BEGIN END; CreatePupByteStreamListener: PUBLIC PROCEDURE [ local: PupSocketID, proc: PROCEDURE[Stream.Handle,PupAddress], ticks: Tocks, filter: PROCEDURE [PupAddress] ] RETURNS [PupListener] = BEGIN RETURN[CreatePupListener[local,proc,ticks,byte,filter]]; END; CreatePupPktStreamListener: PUBLIC PROCEDURE [ local: PupSocketID, proc: PROCEDURE[PupPktDefs.PupPktStream,PupAddress], ticks: Tocks, filter: PROCEDURE [PupAddress] ] RETURNS [PupListener] = BEGIN RETURN[CreatePupListener[local,proc,ticks,pkt,filter]]; END; CreatePupListener: PROCEDURE [ local: PupSocketID, w: PROCEDURE[UNSPECIFIED,PupAddress], ticks: Tocks, k: Kind, f: PROCEDURE [PupAddress] ] RETURNS [PupListener] = BEGIN him: POINTER TO FRAME[PupListeners]; him _ CommUtilDefs.Copy[CommUtilDefs.MyGlobalFrame[]]; START him; -- Do initialization code him.socket _ PupSocketMake[local,PupTypes.fillInPupAddress,veryLongWait]; him.kind _ k; him.who _ w; him.check _ f; him.timeout _ ticks; him.proc _ FORK him.Listen[local]; RETURN[@him.myPupListener]; END; DestroyPupListener: PUBLIC PROCEDURE [ listener: PupListener ] = BEGIN him: POINTER TO FRAME[PupListeners] _ CommUtilDefs.GlobalFrame[listener^]; him.stop _ TRUE; PupSocketKick[him.socket]; JOIN him.proc; PupSocketDestroy[him.socket]; CommUtilDefs.UnNew[him]; END; Listen: PROCEDURE [local: PupSocketID] = BEGIN soc: PupRouterSocket; arg: UNSPECIFIED; b: PupBuffer; UNTIL stop DO b _ socket.get[]; IF b#NIL THEN BEGIN SELECT b.pupType FROM rfc => BEGIN OPEN PupStream; FOR soc_GetFirstPupSocket[],soc.next UNTIL soc=NIL DO -- check for duplicate 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; check[him ! RejectThisRequest => BEGIN SwapPupSourceAndDest[b]; b.pupType _ abort; SetPupContentsBytes[b,2]; AppendStringBodyToPupBuffer[b,error]; PupRouterSendThis[b]; GOTO Reject; END ]; ReturnFreePupBuffer[b]; SELECT kind FROM pkt => arg _ PupPktDefs.PupPktStreamMake[local,him,timeout,alreadyOpened,b.pupID]; byte => arg _ PupByteStreamMake[local,him,timeout,alreadyOpened,b.pupID]; ENDCASE => ERROR; CommUtilDefs.Detach[FORK 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"L]; END; ENDLOOP; END; -- initialization END. -- of PupListeners (1792)\2777t10 11t0 1068t10 27t0 11t10 21t0 39t10 17t0 11t10 21t0