-- 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...