View Javadoc

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