Fixes for TJIDE
[fanfix.git] / src / jexer / net / TelnetSocket.java
... / ...
CommitLineData
1/*
2 * Jexer - Java Text User Interface
3 *
4 * The MIT License (MIT)
5 *
6 * Copyright (C) 2017 Kevin Lamonte
7 *
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:
14 *
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17 *
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.
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 */
41public final class TelnetSocket extends Socket {
42
43 /**
44 * The telnet-aware socket InputStream.
45 */
46 private TelnetInputStream input;
47
48 /**
49 * The telnet-aware socket OutputStream.
50 */
51 private TelnetOutputStream output;
52
53 // Telnet protocol special characters. Note package private access.
54 static final int TELNET_SE = 240;
55 static final int TELNET_NOP = 241;
56 static final int TELNET_DM = 242;
57 static final int TELNET_BRK = 243;
58 static final int TELNET_IP = 244;
59 static final int TELNET_AO = 245;
60 static final int TELNET_AYT = 246;
61 static final int TELNET_EC = 247;
62 static final int TELNET_EL = 248;
63 static final int TELNET_GA = 249;
64 static final int TELNET_SB = 250;
65 static final int TELNET_WILL = 251;
66 static final int TELNET_WONT = 252;
67 static final int TELNET_DO = 253;
68 static final int TELNET_DONT = 254;
69 static final int TELNET_IAC = 255;
70 static final int C_NUL = 0x00;
71 static final int C_LF = 0x0A;
72 static final int C_CR = 0x0D;
73
74 /**
75 * If true, this is a server socket (i.e. created by accept()).
76 */
77 boolean isServer = true;
78
79 /**
80 * If true, telnet ECHO mode is set such that local echo is off and
81 * remote echo is on. This is appropriate for server sockets.
82 */
83 boolean echoMode = false;
84
85 /**
86 * If true, telnet BINARY mode is enabled. We always want this to
87 * ensure a Unicode-safe stream.
88 */
89 boolean binaryMode = false;
90
91 /**
92 * If true, the SUPPRESS-GO-AHEAD option is enabled. We always want
93 * this.
94 */
95 boolean goAhead = true;
96
97 /**
98 * If true, request the client terminal type.
99 */
100 boolean doTermType = true;
101
102 /**
103 * If true, request the client terminal speed.
104 */
105 boolean doTermSpeed = true;
106
107 /**
108 * If true, request the Negotiate About Window Size option to
109 * determine the client text width/height.
110 */
111 boolean doNAWS = true;
112
113 /**
114 * If true, request the New Environment option to obtain the client
115 * LOGNAME, USER, and LANG variables.
116 */
117 boolean doEnvironment = true;
118
119 /**
120 * The terminal type reported by the client.
121 */
122 String terminalType = "";
123
124 /**
125 * The terminal speed reported by the client.
126 */
127 String terminalSpeed = "";
128
129 /**
130 * See if telnet server/client is in ASCII mode.
131 *
132 * @return if true, this connection is in ASCII mode
133 */
134 public boolean isAscii() {
135 return (!binaryMode);
136 }
137
138 /**
139 * Creates a Socket that knows the telnet protocol. Note package private
140 * access, this is only used by TelnetServerSocket.
141 *
142 * @throws IOException if an I/O error occurs
143 */
144 TelnetSocket() throws IOException {
145 super();
146 }
147
148 // Socket interface -------------------------------------------------------
149
150 /**
151 * Returns an input stream for this socket.
152 *
153 * @return the input stream
154 * @throws IOException if an I/O error occurs
155 */
156 @Override
157 public InputStream getInputStream() throws IOException {
158 if (input == null) {
159 assert (output == null);
160 output = new TelnetOutputStream(this, super.getOutputStream());
161 input = new TelnetInputStream(this, super.getInputStream(), output);
162 input.telnetSendOptions();
163 }
164 return input;
165 }
166
167 /**
168 * Returns an output stream for this socket.
169 *
170 * @return the output stream
171 * @throws IOException if an I/O error occurs
172 */
173 @Override
174 public OutputStream getOutputStream() throws IOException {
175 if (output == null) {
176 assert (input == null);
177 output = new TelnetOutputStream(this, super.getOutputStream());
178 input = new TelnetInputStream(this, super.getInputStream(), output);
179 input.telnetSendOptions();
180 }
181 return output;
182 }
183
184}