X-Git-Url: http://git.nikiroo.be/?a=blobdiff_plain;f=src%2Fjexer%2Fnet%2FTelnetSocket.java;h=ac8a2782b0ed672e2166026ffe46439a4bc2681b;hb=12b90437b5f22c2ae6e9b9b14c3b62b60f6143e5;hp=2724e54953409ff83670a1c6adb2cddc40f8bf19;hpb=005ec49709aab8590ee9571f17a67440969c6248;p=nikiroo-utils.git diff --git a/src/jexer/net/TelnetSocket.java b/src/jexer/net/TelnetSocket.java index 2724e54..ac8a278 100644 --- a/src/jexer/net/TelnetSocket.java +++ b/src/jexer/net/TelnetSocket.java @@ -1,29 +1,27 @@ -/** +/* * Jexer - Java Text User Interface * - * License: LGPLv3 or later - * - * This module is licensed under the GNU Lesser General Public License - * Version 3. Please see the file "COPYING" in this directory for more - * information about the GNU Lesser General Public License Version 3. + * The MIT License (MIT) * - * Copyright (C) 2015 Kevin Lamonte + * Copyright (C) 2019 Kevin Lamonte * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 3 of - * the License, or (at your option) any later version. + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, see - * http://www.gnu.org/licenses/, or write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA - * 02110-1301 USA + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. * * @author Kevin Lamonte [kevin.lamonte@gmail.com] * @version 1 @@ -40,12 +38,36 @@ import java.net.Socket; * establish an 8-bit clean no echo channel and expose window resize events * to the Jexer ECMA48 backend. */ -public final class TelnetSocket extends Socket { +public class TelnetSocket extends Socket { - /** - * The wrapped socket. - */ - private Socket socket; + // ------------------------------------------------------------------------ + // Constants -------------------------------------------------------------- + // ------------------------------------------------------------------------ + + // Telnet protocol special characters. Note package private access. + static final int TELNET_SE = 240; + static final int TELNET_NOP = 241; + static final int TELNET_DM = 242; + static final int TELNET_BRK = 243; + static final int TELNET_IP = 244; + static final int TELNET_AO = 245; + static final int TELNET_AYT = 246; + static final int TELNET_EC = 247; + static final int TELNET_EL = 248; + static final int TELNET_GA = 249; + static final int TELNET_SB = 250; + static final int TELNET_WILL = 251; + static final int TELNET_WONT = 252; + static final int TELNET_DO = 253; + static final int TELNET_DONT = 254; + static final int TELNET_IAC = 255; + static final int C_NUL = 0x00; + static final int C_LF = 0x0A; + static final int C_CR = 0x0D; + + // ------------------------------------------------------------------------ + // Variables -------------------------------------------------------------- + // ------------------------------------------------------------------------ /** * The telnet-aware socket InputStream. @@ -53,135 +75,98 @@ public final class TelnetSocket extends Socket { private TelnetInputStream input; /** - * The telnet-aware socket OutputStream. Note package private access: - * input sends stuff to output. + * The telnet-aware socket OutputStream. */ - TelnetOutputStream output; + private TelnetOutputStream output; - // Telnet protocol special characters. Note package private access. - public static final int TELNET_SE = 240; - public static final int TELNET_NOP = 241; - public static final int TELNET_DM = 242; - public static final int TELNET_BRK = 243; - public static final int TELNET_IP = 244; - public static final int TELNET_AO = 245; - public static final int TELNET_AYT = 246; - public static final int TELNET_EC = 247; - public static final int TELNET_EL = 248; - public static final int TELNET_GA = 249; - public static final int TELNET_SB = 250; - public static final int TELNET_WILL = 251; - public static final int TELNET_WONT = 252; - public static final int TELNET_DO = 253; - public static final int TELNET_DONT = 254; - public static final int TELNET_IAC = 255; - public static final int C_NUL = 0x00; - public static final int C_LF = 0x0A; - public static final int C_CR = 0x0D; - - /** - * Telnet protocol speaks to a Network Virtual Terminal (NVT). - */ - class TelnetState { - - // General status flags outside the NVT spec - boolean doInit; - boolean isServer; - - // NVT flags - boolean echoMode; - boolean binaryMode; - boolean goAhead; - boolean doTermType; - boolean doTermSpeed; - boolean doNAWS; - boolean doEnvironment; - String terminal = ""; - - // Flags used by the TelnetInputStream - boolean iac; - boolean dowill; - int dowillType; - boolean subnegEnd; - boolean isEof; - boolean eofMsg; - boolean readCR; - - // Flags used by the TelnetOutputStream - boolean writeCR; - - /** - * Constuctor calls reset(). - */ - public TelnetState() { - reset(); - } - /** - * Reset NVT to default state as per RFC 854. - */ - public void reset() { - echoMode = false; - binaryMode = false; - goAhead = true; - doTermType = true; - doTermSpeed = true; - doNAWS = true; - doEnvironment = true; - doInit = true; - isServer = true; - - iac = false; - dowill = false; - subnegEnd = false; - isEof = false; - eofMsg = false; - readCR = false; - - writeCR = false; - } - } + /** + * If true, this is a server socket (i.e. created by accept()). + */ + boolean isServer = true; /** - * State of the protocol. Note package private access. + * If true, telnet ECHO mode is set such that local echo is off and + * remote echo is on. This is appropriate for server sockets. */ - TelnetState nvt; + boolean echoMode = false; /** - * See if telnet server/client is in ASCII mode. - * - * @return if true, this connection is in ASCII mode + * If true, telnet BINARY mode is enabled. We always want this to + * ensure a Unicode-safe stream. */ - public boolean isAscii() { - return (!nvt.binaryMode); - } + boolean binaryMode = false; /** - * Creates a Socket that knows the telnet protocol. - * - * @param socket the underlying Socket + * If true, the SUPPRESS-GO-AHEAD option is enabled. We always want + * this. */ - TelnetSocket(Socket socket) throws IOException { - super(); - nvt = new TelnetState(); - this.socket = socket; + boolean goAhead = true; + + /** + * If true, request the client terminal type. + */ + boolean doTermType = true; + + /** + * If true, request the client terminal speed. + */ + boolean doTermSpeed = true; + + /** + * If true, request the Negotiate About Window Size option to + * determine the client text width/height. + */ + boolean doNAWS = true; - output = new TelnetOutputStream(this, super.getOutputStream()); - input = new TelnetInputStream(this, super.getInputStream(), output); + /** + * If true, request the New Environment option to obtain the client + * LOGNAME, USER, and LANG variables. + */ + boolean doEnvironment = true; + + /** + * The terminal type reported by the client. + */ + String terminalType = ""; - // Initiate the telnet protocol negotiation. - input.telnetSendOptions(); + /** + * The terminal speed reported by the client. + */ + String terminalSpeed = ""; + + // ------------------------------------------------------------------------ + // Constructors ----------------------------------------------------------- + // ------------------------------------------------------------------------ + + /** + * Creates a Socket that knows the telnet protocol. Note package private + * access, this is only used by TelnetServerSocket. + * + * @throws IOException if an I/O error occurs + */ + TelnetSocket() throws IOException { + super(); } - // Socket interface ------------------------------------------------------- + // ------------------------------------------------------------------------ + // Socket ----------------------------------------------------------------- + // ------------------------------------------------------------------------ /** * Returns an input stream for this socket. * * @return the input stream + * @throws IOException if an I/O error occurs */ @Override public InputStream getInputStream() throws IOException { + if (input == null) { + assert (output == null); + output = new TelnetOutputStream(this, super.getOutputStream()); + input = new TelnetInputStream(this, super.getInputStream(), output); + input.telnetSendOptions(); + } return input; } @@ -189,10 +174,30 @@ public final class TelnetSocket extends Socket { * Returns an output stream for this socket. * * @return the output stream + * @throws IOException if an I/O error occurs */ @Override public OutputStream getOutputStream() throws IOException { + if (output == null) { + assert (input == null); + output = new TelnetOutputStream(this, super.getOutputStream()); + input = new TelnetInputStream(this, super.getInputStream(), output); + input.telnetSendOptions(); + } return output; } + // ------------------------------------------------------------------------ + // TelnetSocket ----------------------------------------------------------- + // ------------------------------------------------------------------------ + + /** + * See if telnet server/client is in ASCII mode. + * + * @return if true, this connection is in ASCII mode + */ + public boolean isAscii() { + return (!binaryMode); + } + }