telnet daemon working
[nikiroo-utils.git] / src / jexer / net / TelnetSocket.java
1 /**
2 * Jexer - Java Text User Interface
3 *
4 * License: LGPLv3 or later
5 *
6 * This module is licensed under the GNU Lesser General Public License
7 * Version 3. Please see the file "COPYING" in this directory for more
8 * information about the GNU Lesser General Public License Version 3.
9 *
10 * Copyright (C) 2015 Kevin Lamonte
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public License
14 * as published by the Free Software Foundation; either version 3 of
15 * the License, or (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with this program; if not, see
24 * http://www.gnu.org/licenses/, or write to the Free Software
25 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
26 * 02110-1301 USA
27 *
28 * @author Kevin Lamonte [kevin.lamonte@gmail.com]
29 * @version 1
30 */
31 package jexer.net;
32
33 import java.io.InputStream;
34 import java.io.IOException;
35 import java.io.OutputStream;
36 import java.net.Socket;
37
38 /**
39 * This class provides a Socket that performs the telnet protocol to both
40 * establish an 8-bit clean no echo channel and expose window resize events
41 * to the Jexer ECMA48 backend.
42 */
43 public final class TelnetSocket extends Socket {
44
45 /**
46 * The telnet-aware socket InputStream.
47 */
48 private TelnetInputStream input;
49
50 /**
51 * The telnet-aware socket OutputStream.
52 */
53 private TelnetOutputStream output;
54
55 // Telnet protocol special characters. Note package private access.
56 static final int TELNET_SE = 240;
57 static final int TELNET_NOP = 241;
58 static final int TELNET_DM = 242;
59 static final int TELNET_BRK = 243;
60 static final int TELNET_IP = 244;
61 static final int TELNET_AO = 245;
62 static final int TELNET_AYT = 246;
63 static final int TELNET_EC = 247;
64 static final int TELNET_EL = 248;
65 static final int TELNET_GA = 249;
66 static final int TELNET_SB = 250;
67 static final int TELNET_WILL = 251;
68 static final int TELNET_WONT = 252;
69 static final int TELNET_DO = 253;
70 static final int TELNET_DONT = 254;
71 static final int TELNET_IAC = 255;
72 static final int C_NUL = 0x00;
73 static final int C_LF = 0x0A;
74 static final int C_CR = 0x0D;
75
76 /**
77 * If true, this is a server socket (i.e. created by accept()).
78 */
79 boolean isServer = true;
80
81 /**
82 * If true, telnet ECHO mode is set such that local echo is off and
83 * remote echo is on. This is appropriate for server sockets.
84 */
85 boolean echoMode = false;
86
87 /**
88 * If true, telnet BINARY mode is enabled. We always want this to
89 * ensure a Unicode-safe stream.
90 */
91 boolean binaryMode = false;
92
93 /**
94 * If true, the SUPPRESS-GO-AHEAD option is enabled. We always want
95 * this.
96 */
97 boolean goAhead = true;
98
99 /**
100 * If true, request the client terminal type.
101 */
102 boolean doTermType = true;
103
104 /**
105 * If true, request the client terminal speed.
106 */
107 boolean doTermSpeed = true;
108
109 /**
110 * If true, request the Negotiate About Window Size option to
111 * determine the client text width/height.
112 */
113 boolean doNAWS = true;
114
115 /**
116 * If true, request the New Environment option to obtain the client
117 * LOGNAME, USER, and LANG variables.
118 */
119 boolean doEnvironment;
120
121 /**
122 * The terminal type reported by the client.
123 */
124 String terminalType = "";
125
126 /**
127 * The terminal speed reported by the client.
128 */
129 String terminalSpeed = "";
130
131 /**
132 * See if telnet server/client is in ASCII mode.
133 *
134 * @return if true, this connection is in ASCII mode
135 */
136 public boolean isAscii() {
137 return (!binaryMode);
138 }
139
140 /**
141 * Creates a Socket that knows the telnet protocol. Note package private
142 * access, this is only used by TelnetServerSocket.
143 *
144 * @throws IOException if an I/O error occurs
145 */
146 TelnetSocket() throws IOException {
147 super();
148 }
149
150 // Socket interface -------------------------------------------------------
151
152 /**
153 * Returns an input stream for this socket.
154 *
155 * @return the input stream
156 * @throws IOException if an I/O error occurs
157 */
158 @Override
159 public InputStream getInputStream() throws IOException {
160 if (input == null) {
161 assert (output == null);
162 output = new TelnetOutputStream(this, super.getOutputStream());
163 input = new TelnetInputStream(this, super.getInputStream(), output);
164 input.telnetSendOptions();
165 }
166 return input;
167 }
168
169 /**
170 * Returns an output stream for this socket.
171 *
172 * @return the output stream
173 * @throws IOException if an I/O error occurs
174 */
175 @Override
176 public OutputStream getOutputStream() throws IOException {
177 if (output == null) {
178 assert (input == null);
179 output = new TelnetOutputStream(this, super.getOutputStream());
180 input = new TelnetInputStream(this, super.getInputStream(), output);
181 input.telnetSendOptions();
182 }
183 return output;
184 }
185
186 }