Merge commit '77d3a60869e7a780c6ae069e51530e1eacece5e2'
[fanfix.git] / src / jexer / net / TelnetSocket.java
CommitLineData
daa4106c 1/*
ea91242c
KL
2 * Jexer - Java Text User Interface
3 *
e16dda65 4 * The MIT License (MIT)
ea91242c 5 *
a69ed767 6 * Copyright (C) 2019 Kevin Lamonte
ea91242c 7 *
e16dda65
KL
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
ea91242c 14 *
e16dda65
KL
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
ea91242c 17 *
e16dda65
KL
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 * DEALINGS IN THE SOFTWARE.
ea91242c
KL
25 *
26 * @author Kevin Lamonte [kevin.lamonte@gmail.com]
27 * @version 1
28 */
29package jexer.net;
30
31import java.io.InputStream;
32import java.io.IOException;
33import java.io.OutputStream;
34import java.net.Socket;
35
36/**
37 * This class provides a Socket that performs the telnet protocol to both
38 * establish an 8-bit clean no echo channel and expose window resize events
39 * to the Jexer ECMA48 backend.
40 */
051e2913 41public class TelnetSocket extends Socket {
ea91242c 42
d36057df
KL
43 // ------------------------------------------------------------------------
44 // Constants --------------------------------------------------------------
45 // ------------------------------------------------------------------------
ea91242c
KL
46
47 // Telnet protocol special characters. Note package private access.
9b1afdde
KL
48 static final int TELNET_SE = 240;
49 static final int TELNET_NOP = 241;
50 static final int TELNET_DM = 242;
51 static final int TELNET_BRK = 243;
52 static final int TELNET_IP = 244;
53 static final int TELNET_AO = 245;
54 static final int TELNET_AYT = 246;
55 static final int TELNET_EC = 247;
56 static final int TELNET_EL = 248;
57 static final int TELNET_GA = 249;
58 static final int TELNET_SB = 250;
59 static final int TELNET_WILL = 251;
60 static final int TELNET_WONT = 252;
61 static final int TELNET_DO = 253;
62 static final int TELNET_DONT = 254;
63 static final int TELNET_IAC = 255;
64 static final int C_NUL = 0x00;
65 static final int C_LF = 0x0A;
66 static final int C_CR = 0x0D;
ea91242c 67
d36057df
KL
68 // ------------------------------------------------------------------------
69 // Variables --------------------------------------------------------------
70 // ------------------------------------------------------------------------
71
72 /**
73 * The telnet-aware socket InputStream.
74 */
75 private TelnetInputStream input;
76
77 /**
78 * The telnet-aware socket OutputStream.
79 */
80 private TelnetOutputStream output;
81
82
9b1afdde
KL
83 /**
84 * If true, this is a server socket (i.e. created by accept()).
85 */
86 boolean isServer = true;
87
88 /**
89 * If true, telnet ECHO mode is set such that local echo is off and
90 * remote echo is on. This is appropriate for server sockets.
91 */
92 boolean echoMode = false;
93
94 /**
95 * If true, telnet BINARY mode is enabled. We always want this to
96 * ensure a Unicode-safe stream.
97 */
98 boolean binaryMode = false;
99
100 /**
101 * If true, the SUPPRESS-GO-AHEAD option is enabled. We always want
102 * this.
103 */
104 boolean goAhead = true;
105
106 /**
107 * If true, request the client terminal type.
108 */
109 boolean doTermType = true;
110
111 /**
112 * If true, request the client terminal speed.
113 */
114 boolean doTermSpeed = true;
115
116 /**
117 * If true, request the Negotiate About Window Size option to
118 * determine the client text width/height.
119 */
120 boolean doNAWS = true;
121
122 /**
123 * If true, request the New Environment option to obtain the client
124 * LOGNAME, USER, and LANG variables.
125 */
09944e92 126 boolean doEnvironment = true;
9b1afdde
KL
127
128 /**
129 * The terminal type reported by the client.
130 */
131 String terminalType = "";
ea91242c
KL
132
133 /**
9b1afdde 134 * The terminal speed reported by the client.
ea91242c 135 */
9b1afdde 136 String terminalSpeed = "";
ea91242c 137
d36057df
KL
138 // ------------------------------------------------------------------------
139 // Constructors -----------------------------------------------------------
140 // ------------------------------------------------------------------------
ea91242c
KL
141
142 /**
9b1afdde
KL
143 * Creates a Socket that knows the telnet protocol. Note package private
144 * access, this is only used by TelnetServerSocket.
ea91242c 145 *
9b1afdde 146 * @throws IOException if an I/O error occurs
ea91242c 147 */
9b1afdde 148 TelnetSocket() throws IOException {
ea91242c 149 super();
ea91242c
KL
150 }
151
d36057df
KL
152 // ------------------------------------------------------------------------
153 // Socket -----------------------------------------------------------------
154 // ------------------------------------------------------------------------
ea91242c
KL
155
156 /**
157 * Returns an input stream for this socket.
158 *
159 * @return the input stream
9b1afdde 160 * @throws IOException if an I/O error occurs
ea91242c
KL
161 */
162 @Override
163 public InputStream getInputStream() throws IOException {
9b1afdde
KL
164 if (input == null) {
165 assert (output == null);
166 output = new TelnetOutputStream(this, super.getOutputStream());
167 input = new TelnetInputStream(this, super.getInputStream(), output);
168 input.telnetSendOptions();
169 }
ea91242c
KL
170 return input;
171 }
172
173 /**
174 * Returns an output stream for this socket.
175 *
176 * @return the output stream
9b1afdde 177 * @throws IOException if an I/O error occurs
ea91242c
KL
178 */
179 @Override
180 public OutputStream getOutputStream() throws IOException {
9b1afdde
KL
181 if (output == null) {
182 assert (input == null);
183 output = new TelnetOutputStream(this, super.getOutputStream());
184 input = new TelnetInputStream(this, super.getInputStream(), output);
185 input.telnetSendOptions();
186 }
ea91242c
KL
187 return output;
188 }
189
d36057df
KL
190 // ------------------------------------------------------------------------
191 // TelnetSocket -----------------------------------------------------------
192 // ------------------------------------------------------------------------
193
194 /**
195 * See if telnet server/client is in ASCII mode.
196 *
197 * @return if true, this connection is in ASCII mode
198 */
199 public boolean isAscii() {
200 return (!binaryMode);
201 }
202
ea91242c 203}