1. /*
  2. * Copyright 2003-2004 The Apache Software Foundation
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package org.apache.commons.net.telnet;
  17. import java.io.BufferedInputStream;
  18. import java.io.IOException;
  19. import java.io.InputStream;
  20. import java.io.OutputStream;
  21. import org.apache.commons.net.io.FromNetASCIIInputStream;
  22. import org.apache.commons.net.io.ToNetASCIIOutputStream;
  23. /***
  24. * The TelnetClient class implements the simple network virtual
  25. * terminal (NVT) for the Telnet protocol according to RFC 854. It
  26. * does not implement any of the extra Telnet options because it
  27. * is meant to be used within a Java program providing automated
  28. * access to Telnet accessible resources.
  29. * <p>
  30. * The class can be used by first connecting to a server using the
  31. * SocketClient
  32. * <a href="org.apache.commons.net.SocketClient.html#connect">connect</a>
  33. * method. Then an InputStream and OutputStream for sending and
  34. * receiving data over the Telnet connection can be obtained by
  35. * using the <a href="#getInputStream"> getInputStream() </a> and
  36. * <a href="#getOutputStream"> getOutputStream() </a> methods.
  37. * When you finish using the streams, you must call
  38. * <a href="#disconnect"> disconnect </a> rather than simply
  39. * closing the streams.
  40. * <p>
  41. * <p>
  42. * @author Daniel F. Savarese
  43. * @author Bruno D'Avanzo
  44. ***/
  45. public class TelnetClient extends Telnet
  46. {
  47. private InputStream __input;
  48. private OutputStream __output;
  49. protected boolean readerThread = true;
  50. /***
  51. * Default TelnetClient constructor.
  52. ***/
  53. public TelnetClient()
  54. {
  55. /* TERMINAL-TYPE option (start)*/
  56. super ("VT100");
  57. /* TERMINAL-TYPE option (end)*/
  58. __input = null;
  59. __output = null;
  60. }
  61. /* TERMINAL-TYPE option (start)*/
  62. public TelnetClient(String termtype)
  63. {
  64. super (termtype);
  65. __input = null;
  66. __output = null;
  67. }
  68. /* TERMINAL-TYPE option (end)*/
  69. void _flushOutputStream() throws IOException
  70. {
  71. _output_.flush();
  72. }
  73. void _closeOutputStream() throws IOException
  74. {
  75. _output_.close();
  76. }
  77. /***
  78. * Handles special connection requirements.
  79. * <p>
  80. * @exception IOException If an error occurs during connection setup.
  81. ***/
  82. protected void _connectAction_() throws IOException
  83. {
  84. super._connectAction_();
  85. InputStream input;
  86. TelnetInputStream tmp;
  87. if (FromNetASCIIInputStream.isConversionRequired())
  88. input = new FromNetASCIIInputStream(_input_);
  89. else
  90. input = _input_;
  91. tmp = new TelnetInputStream(input, this);
  92. if(readerThread)
  93. {
  94. tmp._start();
  95. }
  96. // __input CANNOT refer to the TelnetInputStream. We run into
  97. // blocking problems when some classes use TelnetInputStream, so
  98. // we wrap it with a BufferedInputStream which we know is safe.
  99. // This blocking behavior requires further investigation, but right
  100. // now it looks like classes like InputStreamReader are not implemented
  101. // in a safe manner.
  102. __input = new BufferedInputStream(tmp);
  103. __output = new ToNetASCIIOutputStream(new TelnetOutputStream(this));
  104. }
  105. /***
  106. * Disconnects the telnet session, closing the input and output streams
  107. * as well as the socket. If you have references to the
  108. * input and output streams of the telnet connection, you should not
  109. * close them yourself, but rather call disconnect to properly close
  110. * the connection.
  111. ***/
  112. public void disconnect() throws IOException
  113. {
  114. __input.close();
  115. __output.close();
  116. super.disconnect();
  117. }
  118. /***
  119. * Returns the telnet connection output stream. You should not close the
  120. * stream when you finish with it. Rather, you should call
  121. * <a href="#disconnect"> disconnect </a>.
  122. * <p>
  123. * @return The telnet connection output stream.
  124. ***/
  125. public OutputStream getOutputStream()
  126. {
  127. return __output;
  128. }
  129. /***
  130. * Returns the telnet connection input stream. You should not close the
  131. * stream when you finish with it. Rather, you should call
  132. * <a href="#disconnect"> disconnect </a>.
  133. * <p>
  134. * @return The telnet connection input stream.
  135. ***/
  136. public InputStream getInputStream()
  137. {
  138. return __input;
  139. }
  140. /***
  141. * Returns the state of the option on the local side.
  142. * <p>
  143. * @param option - Option to be checked.
  144. * <p>
  145. * @return The state of the option on the local side.
  146. ***/
  147. public boolean getLocalOptionState(int option)
  148. {
  149. /* BUG (option active when not already acknowledged) (start)*/
  150. return (_stateIsWill(option) && _requestedWill(option));
  151. /* BUG (option active when not already acknowledged) (end)*/
  152. }
  153. /***
  154. * Returns the state of the option on the remote side.
  155. * <p>
  156. * @param option - Option to be checked.
  157. * <p>
  158. * @return The state of the option on the remote side.
  159. ***/
  160. public boolean getRemoteOptionState(int option)
  161. {
  162. /* BUG (option active when not already acknowledged) (start)*/
  163. return (_stateIsDo(option) && _requestedDo(option));
  164. /* BUG (option active when not already acknowledged) (end)*/
  165. }
  166. /* open TelnetOptionHandler functionality (end)*/
  167. /* Code Section added for supporting AYT (start)*/
  168. /***
  169. * Sends an Are You There sequence and waits for the result.
  170. * <p>
  171. * @throws InterruptedException
  172. * @throws IllegalArgumentException
  173. * @throws IOException
  174. * <p>
  175. * @param timeout - Time to wait for a response (millis.)
  176. * <p>
  177. * @return true if AYT received a response, false otherwise
  178. ***/
  179. public boolean sendAYT(long timeout)
  180. throws IOException, IllegalArgumentException, InterruptedException
  181. {
  182. return (_sendAYT(timeout));
  183. }
  184. /* Code Section added for supporting AYT (start)*/
  185. /* open TelnetOptionHandler functionality (start)*/
  186. /***
  187. * Registers a new TelnetOptionHandler for this telnet client to use.
  188. * <p>
  189. * @throws InvalidTelnetOptionException
  190. * <p>
  191. * @param opthand - option handler to be registered.
  192. ***/
  193. public void addOptionHandler(TelnetOptionHandler opthand)
  194. throws InvalidTelnetOptionException
  195. {
  196. super.addOptionHandler(opthand);
  197. }
  198. /* open TelnetOptionHandler functionality (end)*/
  199. /***
  200. * Unregisters a TelnetOptionHandler.
  201. * <p>
  202. * @throws InvalidTelnetOptionException
  203. * <p>
  204. * @param optcode - Code of the option to be unregistered.
  205. ***/
  206. public void deleteOptionHandler(int optcode)
  207. throws InvalidTelnetOptionException
  208. {
  209. super.deleteOptionHandler(optcode);
  210. }
  211. /* Code Section added for supporting spystreams (start)*/
  212. /***
  213. * Registers an OutputStream for spying what's going on in
  214. * the TelnetClient session.
  215. * <p>
  216. * @param spystream - OutputStream on which session activity
  217. * will be echoed.
  218. ***/
  219. public void registerSpyStream(OutputStream spystream)
  220. {
  221. super._registerSpyStream(spystream);
  222. }
  223. /***
  224. * Stops spying this TelnetClient.
  225. * <p>
  226. ***/
  227. public void stopSpyStream()
  228. {
  229. super._stopSpyStream();
  230. }
  231. /* Code Section added for supporting spystreams (end)*/
  232. /***
  233. * Registers a notification handler to which will be sent
  234. * notifications of received telnet option negotiation commands.
  235. * <p>
  236. * @param notifhand - TelnetNotificationHandler to be registered
  237. ***/
  238. public void registerNotifHandler(TelnetNotificationHandler notifhand)
  239. {
  240. super.registerNotifHandler(notifhand);
  241. }
  242. /***
  243. * Unregisters the current notification handler.
  244. * <p>
  245. ***/
  246. public void unregisterNotifHandler()
  247. {
  248. super.unregisterNotifHandler();
  249. }
  250. /***
  251. * Sets the status of the reader thread.
  252. * The reader thread status will apply to all subsequent connections
  253. * <p>
  254. * @param flag - true switches the reader thread on, false switches it off
  255. ***/
  256. public void setReaderThread(boolean flag)
  257. {
  258. readerThread = flag;
  259. }
  260. /***
  261. * Gets the status of the reader thread.
  262. * <p>
  263. * @return true if the reader thread is on, false otherwise
  264. ***/
  265. public boolean getReaderThread()
  266. {
  267. return (readerThread);
  268. }
  269. }