View Javadoc

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