-- File: TelnetListenerImpl.mesa - last edit: -- JAV 4-May-87 13:34:02 -- Copyright (C) 1985, 1986, 1987 by Xerox Corporation. All rights reserved. DIRECTORY ArpaRouter USING [InternetAddress, Port], ArpaTelnetStream USING [Create, Handle], Heap USING [Create], Process USING [Abort, Detach, Pause, SecondsToTicks], TcpStream USING [Failed, Handle, Listen, Suspended], TelnetListener; TelnetListenerImpl: PROGRAM IMPORTS Heap, Process, TcpStream, ArpaTelnetStream EXPORTS TelnetListener = BEGIN numberOfListeners: CARDINAL ¬ 0; ConnectID: PUBLIC TYPE = LONG POINTER TO ListenerRecord; firstListener: LONG POINTER TO ListenerRecord ¬ NIL; lastListener: LONG POINTER TO ListenerRecord ¬ NIL; ListenerRecord: TYPE = RECORD [ next: LONG POINTER TO ListenerRecord ¬ NIL, connectProc: TelnetListener.ConnectProc, listenerProcess: PROCESS ¬ NIL]; ListenerZone: UNCOUNTED ZONE ¬ Heap.Create[1]; Listen: PUBLIC PROCEDURE [connect: TelnetListener.ConnectProc, portNumber: ArpaRouter.Port, suppressLF: BOOLEAN] RETURNS [connectionID: TelnetListener.ConnectID] = BEGIN listener: LONG POINTER TO ListenerRecord ¬ ListenerZone.NEW[ListenerRecord ¬ [NIL, connect, NIL]]; IF firstListener = NIL THEN firstListener ¬ listener; lastListener ¬ listener; lastListener.listenerProcess ¬ FORK CreateListener[portNumber, connect, suppressLF]; numberOfListeners ¬ numberOfListeners + 1; RETURN[lastListener] END; StopListening: PUBLIC PROCEDURE [connectionID: ConnectID] = BEGIN listener: ConnectID ¬ firstListener; previous: ConnectID ¬ NIL; DO IF connectionID = listener THEN EXIT; previous ¬ listener; listener ¬ listener.next; ENDLOOP; Process.Abort[listener.listenerProcess]; JOIN listener.listenerProcess; IF listener.next = NIL THEN lastListener ¬ previous ELSE previous.next ¬ listener.next; numberOfListeners ¬ numberOfListeners - 1; ListenerZone.FREE[@listener]; END; CreateListener: PROCEDURE [port: ArpaRouter.Port, connect: TelnetListener.ConnectProc, suppressLF: BOOLEAN] = BEGIN ENABLE ABORTED => GOTO Exit; listenHandle: TcpStream.Handle; remoteAddr: ArpaRouter.InternetAddress; DO listenHandle ¬ TcpStream.Listen[port ! TcpStream.Failed => LOOP]; [,remoteAddr , , ] ¬ listenHandle.findAddresses[]; Process.Detach[FORK ConnectUser[listenHandle, connect, remoteAddr, suppressLF]]; ENDLOOP; EXITS Exit => RETURN; END; ConnectUser: PROCEDURE [stream: TcpStream.Handle, connect: TelnetListener.ConnectProc, remoteAddr: ArpaRouter.InternetAddress, suppressLF: BOOLEAN] = BEGIN telnetStream: ArpaTelnetStream.Handle ¬ NIL; telnetStream ¬ ArpaTelnetStream.Create[stream, [TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE], suppressLF]; Process.Pause[Process.SecondsToTicks[2]]; connect[telnetStream, stream, remoteAddr ! TcpStream.Suspended => CONTINUE; TcpStream.Failed => CONTINUE; ABORTED => CONTINUE]; telnetStream.delete[telnetStream]; END; END...