commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bre...@apache.org
Subject cvs commit: jakarta-commons-sandbox/net/src/java/org/apache/commons/net/telnet Telnet.java TelnetClient.java TelnetCommand.java TelnetInputStream.java TelnetOption.java TelnetOutputStream.java
Date Wed, 03 Apr 2002 04:41:43 GMT
brekke      02/04/02 20:41:43

  Added:       net/src/java/org/apache/commons/net/telnet Telnet.java
                        TelnetClient.java TelnetCommand.java
                        TelnetInputStream.java TelnetOption.java
                        TelnetOutputStream.java
  Log:
  Move com.oroinc.net.telnet to org.apache.commons.net.telnet
  
  Revision  Changes    Path
  1.1                  jakarta-commons-sandbox/net/src/java/org/apache/commons/net/telnet/Telnet.java
  
  Index: Telnet.java
  ===================================================================
  package org.apache.commons.net.telnet;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Commons" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Turbine", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import java.io.*;
  import java.net.*;
  
  /***
   *
   * <p>
   *
   * <p>
   * <p>
   * @author Daniel F. Savarese
   ***/
  
  class Telnet extends org.apache.commons.net.SocketClient {
    static final boolean debug = /*true;*/ false;
  
    static final byte[] _COMMAND_DO = {
      (byte)TelnetCommand.IAC, (byte)TelnetCommand.DO
    };
  
    static final byte[] _COMMAND_DONT = {
      (byte)TelnetCommand.IAC, (byte)TelnetCommand.DONT
    };
  
    static final byte[] _COMMAND_WILL = {
      (byte)TelnetCommand.IAC, (byte)TelnetCommand.WILL
    };
  
    static final byte[] _COMMAND_WONT = {
      (byte)TelnetCommand.IAC, (byte)TelnetCommand.WONT
    };
  
    static final byte[] _COMMAND_SB = {
      (byte)TelnetCommand.IAC, (byte)TelnetCommand.SB
    };
  
    static final byte[] _COMMAND_SE = {
      (byte)TelnetCommand.IAC, (byte)TelnetCommand.SE
    };
  
    static final int _WILL_MASK = 0x01, _DO_MASK = 0x02,
                     _REQUESTED_WILL_MASK = 0x04, _REQUESTED_DO_MASK = 0x08;
  
    /* public */ static final int DEFAULT_PORT = 23;
  
    int[] _doResponse, _willResponse, _options;
  
    /* public */ Telnet() {
      setDefaultPort(DEFAULT_PORT);
      _doResponse   = new int[TelnetOption.MAX_OPTION_VALUE + 1];
      _willResponse = new int[TelnetOption.MAX_OPTION_VALUE + 1];
      _options      = new int[TelnetOption.MAX_OPTION_VALUE + 1];
    }
  
  
    boolean _stateIsWill(int option) {
      return ((_options[option] & _WILL_MASK) != 0);
    }
  
    boolean _stateIsWont(int option) { return !_stateIsWill(option); }
  
    boolean _stateIsDo(int option) {
      return ((_options[option] & _DO_MASK) != 0);
    }
  
    boolean _stateIsDont(int option) { return !_stateIsDo(option); }
  
    boolean _requestedWill(int option) {
      return ((_options[option] & _REQUESTED_WILL_MASK) != 0);
    }
  
    boolean _requestedWont(int option) { return !_requestedWill(option); }
  
    boolean _requestedDo(int option) {
      return ((_options[option] & _REQUESTED_DO_MASK) != 0);
    }
  
    boolean _requestedDont(int option) { return !_requestedDo(option); }
  
    void _setWill(int option)     { _options[option] |= _WILL_MASK; }
    void _setDo(int option)       { _options[option] |= _DO_MASK; }
    void _setWantWill(int option) { _options[option] |= _REQUESTED_WILL_MASK; }
    void _setWantDo(int option)   { _options[option] |= _REQUESTED_DO_MASK; }
  
    void _setWont(int option)     { _options[option] &= ~_WILL_MASK; }
    void _setDont(int option)     { _options[option] &= ~_DO_MASK; }
    void _setWantWont(int option) { _options[option] &= ~_REQUESTED_WILL_MASK; }
    void _setWantDont(int option) { _options[option] &= ~_REQUESTED_DO_MASK; }
  
  
    void _processDo(int option) throws IOException {
      boolean acceptNewState = false;
  
      if(_willResponse[option] > 0) {
        --_willResponse[option];
        if(_willResponse[option] > 0 && _stateIsWill(option))
  	--_willResponse[option];
      }
  
      if(_willResponse[option] == 0) {
        if(_requestedWont(option)) {
  
  	switch(option) {
  
  	default: break;
  	  
  	}
  
  
  	if(acceptNewState) {
  	  _setWantWill(option);
  	  _sendWill(option);
  	} else {
  	  ++_willResponse[option];
  	  _sendWont(option);
  	}
        } else {
  	// Other end has acknowledged option.
  
  	switch(option) {
  
  	default: break;
  	  
  	}
  
        }
      }
  
      _setWill(option);
    }
  
  
    void _processDont(int option) throws IOException {
      if(_willResponse[option] > 0) {
        --_willResponse[option];
        if(_willResponse[option] > 0 && _stateIsWont(option))
  	--_willResponse[option];
      }
  
      if(_willResponse[option] == 0 && _requestedWill(option)) {
  
        switch(option) {
  
        default: break;
  	
        }
  
        _setWantWont(option);
  
        if(_stateIsWill(option))
  	_sendWont(option);
      }
  
      _setWont(option);
    }
  
  
    void _processWill(int option) throws IOException {
      boolean acceptNewState = false;
  
      if(_doResponse[option] > 0) {
        --_doResponse[option];
        if(_doResponse[option] > 0 && _stateIsDo(option))
  	--_doResponse[option];
      }
  
      if(_doResponse[option] == 0 && _requestedDont(option)) {
  
        switch(option) {
  
        default: break;
  	  
        }
  
  
        if(acceptNewState) {
  	_setWantDo(option);
  	_sendDo(option);
        } else {
  	++_doResponse[option];
  	_sendDont(option);
        }
      }
  
      _setDo(option);
    }
  
  
    void _processWont(int option) throws IOException {
      if(_doResponse[option] > 0) {
        --_doResponse[option];
        if(_doResponse[option] > 0 && _stateIsDont(option))
  	--_doResponse[option];
      }
  
      if(_doResponse[option] == 0 && _requestedDo(option)) {
  
        switch(option) {
  
        default: break;
  	
        }
  
        _setWantDont(option);
  
        if(_stateIsDo(option))
  	_sendDont(option);
      }
  
      _setDont(option);
    }
  
  
    protected void _connectAction_() throws IOException {
      super._connectAction_();
      _input_  = new BufferedInputStream(_input_);
      _output_ = new BufferedOutputStream(_output_);
    }
  
  
    final synchronized void _sendDo(int option) throws IOException {
      if(debug)
        System.err.println("DO: " + TelnetOption.getOption(option));
      _output_.write(_COMMAND_DO);
      _output_.write(option);
    }
  
    final synchronized void _requestDo(int option) throws IOException {
      if((_doResponse[option] == 0 && _stateIsDo(option)) ||
         _requestedDo(option))
        return;
      _setWantDo(option);
      ++_doResponse[option];
      _sendDo(option);
    }
  
    final synchronized void _sendDont(int option) throws IOException {
      if(debug)
        System.err.println("DONT: " + TelnetOption.getOption(option));
      _output_.write(_COMMAND_DONT);
      _output_.write(option);
    }
  
    final synchronized void _requestDont(int option) throws IOException {
      if((_doResponse[option] == 0 && _stateIsDont(option)) ||
         _requestedDont(option))
        return;
      _setWantDont(option);
      ++_doResponse[option];
      _sendDont(option);
    }
  
  
    final synchronized void _sendWill(int option) throws IOException {
      if(debug)
        System.err.println("WILL: " + TelnetOption.getOption(option));
      _output_.write(_COMMAND_WILL);
      _output_.write(option);
    }
  
    final synchronized void _requestWill(int option) throws IOException {
      if((_willResponse[option] == 0 && _stateIsWill(option)) ||
         _requestedWill(option))
        return;
      _setWantWill(option);
      ++_doResponse[option];
      _sendWill(option);
    }
  
    final synchronized void _sendWont(int option) throws IOException {
      if(debug)
        System.err.println("WONT: " + TelnetOption.getOption(option));
      _output_.write(_COMMAND_WONT);
      _output_.write(option);
    }
  
    final synchronized void _requestWont(int option) throws IOException {
      if((_willResponse[option] == 0 && _stateIsWont(option)) ||
         _requestedWont(option))
        return;
      _setWantWont(option);
      ++_doResponse[option];
      _sendWont(option);
    }
  
    final synchronized void _sendByte(int b) throws IOException {
      _output_.write(b);
    }
  }
  
  
  
  1.1                  jakarta-commons-sandbox/net/src/java/org/apache/commons/net/telnet/TelnetClient.java
  
  Index: TelnetClient.java
  ===================================================================
  package org.apache.commons.net.telnet;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Commons" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Turbine", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import java.net.*;
  import java.io.*;
  
  import org.apache.commons.io.*;
  
  /***
   * The TelnetClient class implements the simple network virtual
   * terminal (NVT) for the Telnet protocol according to RFC 854.  It
   * does not implement any of the extra Telnet options because it
   * is meant to be used within a Java program providing automated
   * access to Telnet accessible resources.  A telnet client implementing
   * extra options and meant for use with a terminal emulator can be
   * found in <b>NetComponents Pro <sup><font size=-1>TM</font></sup></b>
   * <p>
   * The class can be used by first connecting to a server using the
   * SocketClient
   * <a href="org.apache.commons.net.SocketClient.html#connect">connect</a>
   * method.  Then an InputStream and OutputStream for sending and
   * receiving data over the Telnet connection can be obtained by
   * using the <a href="#getInputStream"> getInputStream() </a> and
   * <a href="#getOutputStream"> getOutputStream() </a> methods.
   * When you finish using the streams, you must call
   * <a href="#disconnect"> disconnect </a> rather than simply
   * closing the streams.
   * <p>
   * <p>
   * @author Daniel F. Savarese
   ***/
  
  public class TelnetClient extends Telnet {
    private InputStream  __input;
    private OutputStream __output;
  
    /***
     * Default TelnetClient constructor.
     ***/
    public TelnetClient() {
      __input = null;
      __output = null;
    }
  
    void _flushOutputStream() throws IOException { _output_.flush(); }
    void _closeOutputStream() throws IOException { _output_.close(); }
  
    /***
     * Handles special connection requirements.
     * <p>
     * @exception IOException  If an error occurs during connection setup.
     ***/
    protected void _connectAction_() throws IOException {
      super._connectAction_();
      InputStream input;
      TelnetInputStream tmp;
  
      if(FromNetASCIIInputStream.isConversionRequired())
        input = new FromNetASCIIInputStream(_input_);
      else
        input = _input_;
  
  
      tmp = new TelnetInputStream(input, this);
      tmp._start();
      // __input CANNOT refer to the TelnetInputStream.  We run into
      // blocking problems when some classes use TelnetInputStream, so
      // we wrap it with a BufferedInputStream which we know is safe.
      // This blocking behavior requires further investigation, but right
      // now it looks like classes like InputStreamReader are not implemented
      // in a safe manner.
      __input = new BufferedInputStream(tmp);
      __output = new ToNetASCIIOutputStream(new TelnetOutputStream(this));
    }
  
    /***
     * Disconnects the telnet session, closing the input and output streams
     * as well as the socket.  If you have references to the
     * input and output streams of the telnet connection, you should not
     * close them yourself, but rather call disconnect to properly close
     * the connection.
     ***/
    public void disconnect() throws IOException {
      __input.close();
      __output.close();
      super.disconnect();
    }
  
    /***
     * Returns the telnet connection output stream.  You should not close the
     * stream when you finish with it.  Rather, you should call
     * <a href="#disconnect"> disconnect </a>.
     * <p>
     * @return The telnet connection output stream.
     ***/
    public OutputStream getOutputStream() { return __output; }
  
    /***
     * Returns the telnet connection input stream.  You should not close the
     * stream when you finish with it.  Rather, you should call
     * <a href="#disconnect"> disconnect </a>.
     * <p>
     * @return The telnet connection input stream.
     ***/
    public InputStream  getInputStream()  { return __input; }
  }
  
  
  
  1.1                  jakarta-commons-sandbox/net/src/java/org/apache/commons/net/telnet/TelnetCommand.java
  
  Index: TelnetCommand.java
  ===================================================================
  package org.apache.commons.net.telnet;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Commons" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Turbine", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  /***
   * The TelnetCommand class cannot be instantiated and only serves as a
   * storehouse for telnet command constants.
   * <p>
   * <p>
   * @author Daniel F. Savarese
   * @see Telnet
   * @see TelnetClient
   ***/
  
  public final class TelnetCommand {
    /*** The maximum value a command code can have.  This value is 255. ***/
    public static final int MAX_COMMAND_VALUE = 255;
  
    /*** Interpret As Command code.  Value is 255 according to RFC 854. ***/
    public static final int IAC   = 255;
  
    /*** Don't use option code.  Value is 254 according to RFC 854. ***/
    public static final int DONT  = 254;
  
    /*** Request to use option code.  Value is 253 according to RFC 854. ***/
    public static final int DO    = 253;
  
    /*** Refuse to use option code.  Value is 252 according to RFC 854. ***/
    public static final int WONT  = 252;
  
    /*** Agree to use option code.  Value is 251 according to RFC 854. ***/
    public static final int WILL  = 251;
  
    /*** Start subnegotiation code.  Value is 250 according to RFC 854. ***/
    public static final int SB    = 250;
  
    /*** Go Ahead code.  Value is 249 according to RFC 854. ***/
    public static final int GA    = 249;
  
    /*** Erase Line code.  Value is 248 according to RFC 854. ***/
    public static final int EL    = 248;
  
    /*** Erase Character code.  Value is 247 according to RFC 854. ***/
    public static final int EC    = 247;
  
    /*** Are You There code.  Value is 246 according to RFC 854. ***/
    public static final int AYT   = 246;
  
    /*** Abort Output code.  Value is 245 according to RFC 854. ***/
    public static final int AO    = 245;
  
    /*** Interrupt Process code.  Value is 244 according to RFC 854. ***/
    public static final int IP    = 244;
  
    /*** Break code.  Value is 243 according to RFC 854. ***/
    public static final int BREAK = 243;
  
    /*** Data mark code.  Value is 242 according to RFC 854. ***/
    public static final int DM    = 242;
  
    /*** No Operation code.  Value is 241 according to RFC 854. ***/
    public static final int NOP   = 241;
  
    /*** End subnegotiation code.  Value is 240 according to RFC 854. ***/
    public static final int SE    = 240;
  
    /*** End of record code.  Value is 239. ***/
    public static final int EOR   = 239;
  
    /*** Abort code.  Value is 238. ***/
    public static final int ABORT = 238;
  
    /*** Suspend process code.  Value is 237. ***/
    public static final int SUSP  = 237;
  
    /*** End of file code.  Value is 236. ***/
    public static final int EOF   = 236;
  
    /*** Synchronize code.  Value is 242. ***/
    public static final int SYNCH = 242;
  
    /*** String representations of commands. ***/
    private static final String __commandString[] = {
      "IAC", "DONT", "DO", "WONT", "WILL", "SB", "GA", "EL", "EC", "AYT", 
      "AO", "IP", "BRK", "DMARK", "NOP", "SE", "EOR", "ABORT", "SUSP", "EOF"
    };
  
    private static final int __FIRST_COMMAND = IAC;
    private static final int __LAST_COMMAND  = EOF;
  
    /***
     * Returns the string representation of the telnet protocol command
     * corresponding to the given command code.
     * <p>
     * @param The command code of the telnet protocol command.
     * @return The string representation of the telnet protocol command.
     ***/
    public static final String getCommand(int code) {
      return __commandString[__FIRST_COMMAND - code];
    }
  
    /***
     * Determines if a given command code is valid.  Returns true if valid,
     * false if not.
     * <p>
     * @param code  The command code to test.
     * @return True if the command code is valid, false if not.
     **/
    public static final boolean isValidCommand(int code) {
      return (code <= __FIRST_COMMAND && code >= __LAST_COMMAND);
    }
  
    // Cannot be instantiated
    private TelnetCommand() { }
  }
  
  
  
  1.1                  jakarta-commons-sandbox/net/src/java/org/apache/commons/net/telnet/TelnetInputStream.java
  
  Index: TelnetInputStream.java
  ===================================================================
  package org.apache.commons.net.telnet;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Commons" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Turbine", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import java.io.*;
  
  /***
   *
   * <p>
   *
   * <p>
   * <p>
   * @author Daniel F. Savarese
   ***/
  
  
  final class TelnetInputStream extends BufferedInputStream implements Runnable {
    static final int _STATE_DATA = 0, _STATE_IAC = 1, _STATE_WILL = 2,
      _STATE_WONT = 3, _STATE_DO = 4, _STATE_DONT = 5, _STATE_SB = 6,
      _STATE_SE = 7, _STATE_CR = 8;
  
    private boolean __hasReachedEOF, __isClosed;
    private boolean __readIsWaiting;
    private int __receiveState, __queueHead, __queueTail, __bytesAvailable;
    private int[] __queue;
    private TelnetClient __client;
    private Thread __thread;
    private IOException __ioException;
  
    TelnetInputStream(InputStream input, TelnetClient client) {
      super(input);
      __client        = client;
      __receiveState  = _STATE_DATA;
      __isClosed = true;
      __hasReachedEOF = false;
      // Make it 1025, because when full, one slot will go unused, and we
      // want a 1024 byte buffer just to have a round number (base 2 that is)
      //__queue         = new int[1025];
      __queue         = new int[2049];
      __queueHead      = 0;
      __queueTail      = 0;
      __bytesAvailable = 0;
      __ioException    = null;
      __readIsWaiting  = false;
      __thread         = new Thread(this);
    }
  
    void _start() {
      int priority;
      __isClosed = false;
      // Need to set a higher priority in case JVM does not use pre-emptive
      // threads.  This should prevent scheduler induced deadlock (rather than
      // deadlock caused by a bug in this code).
      priority = Thread.currentThread().getPriority() + 1;
      if(priority > Thread.MAX_PRIORITY)
        priority = Thread.MAX_PRIORITY;
      __thread.setPriority(priority);
      __thread.setDaemon(true);
      __thread.start();
    }
  
  
    // synchronized(__client) critical sections are to protect against
    // TelnetOutputStream writing through the telnet client at same time
    // as a processDo/Will/etc. command invoked from TelnetInputStream
    // tries to write.
    private int __read() throws IOException {
      int ch;
  
    _loop:
      while(true) {
        // Exit only when we reach end of stream.
        if((ch = super.read()) < 0)
  	return -1;
  
        ch = (ch & 0xff);
  
      _mainSwitch:
        switch(__receiveState) {
  
        case _STATE_CR:
  	if(ch == '\0') {
  	  // Strip null
  	  continue;
  	}
  	// How do we handle newline after cr?
  	//  else if (ch == '\n' && _requestedDont(TelnetOption.ECHO) &&
  	    
  	// Handle as normal data by falling through to _STATE_DATA case
  
        case _STATE_DATA:
  	if(ch == TelnetCommand.IAC) {
  	  __receiveState = _STATE_IAC;
  	  continue;
  	}
  
  
  	if(ch == '\r') {
  	  synchronized(__client) {	  
  	    if(__client._requestedDont(TelnetOption.BINARY))
  	      __receiveState = _STATE_CR;
  	    else
  	      __receiveState = _STATE_DATA;
  	  }
  	} else
  	  __receiveState = _STATE_DATA;
  	break;
  
        case _STATE_IAC:
  	switch(ch) {
  	case TelnetCommand.WILL: __receiveState = _STATE_WILL; continue;
  	case TelnetCommand.WONT: __receiveState = _STATE_WONT; continue;
  	case TelnetCommand.DO:   __receiveState = _STATE_DO;   continue;
  	case TelnetCommand.DONT: __receiveState = _STATE_DONT; continue;
  	case TelnetCommand.IAC:
  	  __receiveState = _STATE_DATA;
  	  break;
  	default: break;
  	}
  	__receiveState = _STATE_DATA;
  	continue;
        case _STATE_WILL:
  	synchronized(__client) {
  	  __client._processWill(ch);
  	  __client._flushOutputStream();
  	}
  	__receiveState = _STATE_DATA;
  	continue;
        case _STATE_WONT:
  	synchronized(__client) {
  	  __client._processWont(ch);
  	  __client._flushOutputStream();
  	}
  	__receiveState = _STATE_DATA;
  	continue;
        case _STATE_DO:
  	synchronized(__client) {
  	  __client._processDo(ch);
  	  __client._flushOutputStream();
  	}
  	__receiveState = _STATE_DATA;
  	continue;
        case _STATE_DONT:
  	synchronized(__client) {
  	  __client._processDont(ch);
  	  __client._flushOutputStream();
  	}
  	__receiveState = _STATE_DATA;
  	continue;
        }
  
        break;
      }
  
      return ch;
    }
  
  
  
    public int read() throws IOException {
      // Critical section because we're altering __bytesAvailable,
      // __queueHead, and the contents of _queue in addition to
      // testing value of __hasReachedEOF.
      synchronized(__queue) {
  
        while(true) {
  	if(__ioException != null) {
  	  IOException e;
  	  e = __ioException;
  	  __ioException = null;
  	  throw e;
  	}
  
  	if(__bytesAvailable == 0) {
  	  // Return -1 if at end of file
  	  if(__hasReachedEOF)
  	    return -1;
  
  	  // Otherwise, we have to wait for queue to get something
  	  __queue.notify();
  	  try {
  	    //System.out.println("READ WAIT");
  	    __readIsWaiting = true;
  	    __queue.wait();
  	    __readIsWaiting = false;
  	    //System.out.println("READ END WAIT");
  	  } catch(InterruptedException e) {
  	    throw new IOException("Fatal thread interruption during read.");
  	  }
  	  continue;
  	} else {
  	  int ch;
  
  	  ch = __queue[__queueHead];
  
  	  if(++__queueHead >= __queue.length)
  	    __queueHead = 0;
  
  	  --__bytesAvailable;
  
  	  return ch;
  	}
        }
      }
    }
  
  
    /***
     * Reads the next number of bytes from the stream into an array and
     * returns the number of bytes read.  Returns -1 if the end of the
     * stream has been reached.
     * <p>
     * @param buffer  The byte array in which to store the data.
     * @return The number of bytes read. Returns -1 if the
     *          end of the message has been reached.
     * @exception IOException If an error occurs in reading the underlying
     *            stream.
     ***/
    public int read(byte buffer[]) throws IOException {
      return read(buffer, 0, buffer.length);
    }                 
  
   
    /***
     * Reads the next number of bytes from the stream into an array and returns
     * the number of bytes read.  Returns -1 if the end of the
     * message has been reached.  The characters are stored in the array
     * starting from the given offset and up to the length specified.
     * <p>
     * @param buffer The byte array in which to store the data.
     * @param offset  The offset into the array at which to start storing data.
     * @param length   The number of bytes to read.
     * @return The number of bytes read. Returns -1 if the
     *          end of the stream has been reached.
     * @exception IOException If an error occurs while reading the underlying
     *            stream.
     ***/
    public int read(byte buffer[], int offset, int length) throws IOException {
      int ch, off;
  
      if(length < 1)
        return 0;
  
      // Critical section because run() may change __bytesAvailable
      synchronized(__queue) {
        if(length > __bytesAvailable)
  	length = __bytesAvailable;
      }
  
      if((ch = read()) == -1)
        return -1;
  
      off = offset;
  
      do {
        buffer[offset++] = (byte)ch;
      } while(--length > 0 && (ch = read()) != -1);
  
      return (offset - off);
    }
  
  
    /*** Returns false.  Mark is not supported. ***/
    public boolean markSupported() { return false; }
  
    public int available() throws IOException {
      // Critical section because run() may change __bytesAvailable
      synchronized(__queue) {
        return __bytesAvailable;
      }
    }
  
  
    // Cannot be synchronized.  Will cause deadlock if run() is blocked
    // in read because BufferedInputStream read() is synchronized.
    public void close() throws IOException {
      // Completely disregard the fact thread may still be running.
      // We can't afford to block on this close by waiting for
      // thread to terminate because few if any JVM's will actually
      // interrupt a system read() from the interrupt() method.
      super.close();
  
      synchronized(__queue) {
        __hasReachedEOF = true;
        if(__thread.isAlive()) {
  	__isClosed = true;
  	__thread.interrupt();
        }
        __queue.notifyAll();
      }
      /*
      while(__thread.isAlive()) {
        __thread.interrupt();
        try {
  	__thread.join();
        } catch(InterruptedException e) {
  	// If this happens, we just continue to loop
        }
      }
      */
    }
  
    public void run() {
      int ch;
  
      try {
      _outerLoop:
        while(!__isClosed) {
  	try {
  	  if((ch = __read()) < 0)
  	    break;
  	} catch(InterruptedIOException e) {
  	  synchronized(__queue) {
  	    __ioException = e;
  	    __queue.notify();
  	    try {
  	      //System.out.println("THREAD WAIT B");
  	      __queue.wait();
  	      //System.out.println("THREAD END WAIT B");
  	    } catch(InterruptedException interrupted) {
  	      if(__isClosed)
  		break _outerLoop;
  	    }
  	    continue;
  	  }
  	}
  
  
  	// Critical section because we're altering __bytesAvailable,
  	// __queueTail, and the contents of _queue.
  	synchronized(__queue) {
  	  while(__bytesAvailable >= __queue.length - 1) {
  	    __queue.notify();
  	    try {
  	      //System.out.println("THREAD WAIT");
  	      __queue.wait();
  	      //System.out.println("THREAD END WAIT");
  	    } catch(InterruptedException e) {
  	      if(__isClosed)
  		break _outerLoop;
  	    }
  	  }
  
  	  // Need to do this in case we're not full, but block on a read 
  	  if(__readIsWaiting) {
  	    //System.out.println("NOTIFY");
  	    __queue.notify();
  	  }
  
  	  __queue[__queueTail] = ch;
  	  ++__bytesAvailable;
  
  	  if(++__queueTail >= __queue.length)
  	    __queueTail = 0;
  	}
        }
      } catch(IOException e) {
        synchronized(__queue) {
  	__ioException = e;
        }
      }
  
      synchronized(__queue) {
        __isClosed = true; // Possibly redundant
        __hasReachedEOF = true;
        __queue.notify();
      }
    }
  
  
  }
  
  
  
  1.1                  jakarta-commons-sandbox/net/src/java/org/apache/commons/net/telnet/TelnetOption.java
  
  Index: TelnetOption.java
  ===================================================================
  package org.apache.commons.net.telnet;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Commons" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Turbine", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  /***
   * The TelnetOption class cannot be instantiated and only serves as a
   * storehouse for telnet option constants.
   * <p>
   * Details regarding Telnet option specification can be found in RFC 855.
   * <p>
   * <p>
   * @author Daniel F. Savarese
   * @see Telnet
   * @see TelnetClient
   ***/
  
  public class TelnetOption {
    /*** The maximum value an option code can have.  This value is 255. ***/
    public static final int MAX_OPTION_VALUE = 255;
  
    public static int BINARY = 0;
  
    public static int ECHO   = 1;
  
    public static int PREPARE_TO_RECONNECT     = 2;
  
    public static int SUPPRESS_GO_AHEAD        = 3;
  
    public static int APPROXIMATE_MESSAGE_SIZE = 4;
  
    public static int STATUS      = 5;
  
    public static int TIMING_MARK = 6;
  
    public static int REMOTE_CONTROLLED_TRANSMISSION = 7;
  
    public static int NEGOTIATE_OUTPUT_LINE_WIDTH    = 8;
  
    public static int NEGOTIATE_OUTPUT_PAGE_SIZE     = 9;
  
    public static int NEGOTIATE_CARRIAGE_RETURN      = 10;
  
    public static int NEGOTIATE_HORIZONTAL_TAB_STOP  = 11;
  
    public static int NEGOTIATE_HORIZONTAL_TAB       = 12;
  
    public static int NEGOTIATE_FORMFEED             = 13;
  
    public static int NEGOTIATE_VERTICAL_TAB_STOP    = 14;
  
    public static int NEGOTIATE_VERTICAL_TAB     = 15;
  
    public static int NEGOTIATE_LINEFEED         = 16;
  
    public static int EXTENDED_ASCII             = 17;
  
    public static int FORCE_LOGOUT               = 18;
  
    public static int BYTE_MACRO                 = 19;
  
    public static int DATA_ENTRY_TERMINAL        = 20;
  
    public static int SUPDUP                     = 21;
  
    public static int SUPDUP_OUTPUT              = 22;
  
    public static int SEND_LOCATION              = 23;
  
    public static int TERMINAL_TYPE              = 24;
  
    public static int END_OF_RECORD              = 25;
  
    public static int TACACS_USER_IDENTIFICATION = 26;
  
    public static int OUTPUT_MARKING             = 27;
  
    public static int TERMINAL_LOCATION_NUMBER   = 28;
  
    public static int REGIME_3270                = 29;
  
    public static int X3_PAD                     = 30;
  
    public static int WINDOW_SIZE                = 31;
  
    public static int TERMINAL_SPEED             = 32;
  
    public static int REMOTE_FLOW_CONTROL        = 33;
  
    public static int LINEMODE                   = 34;
  
    public static int X_DISPLAY_LOCATION         = 35;
  
    public static int OLD_ENVIRONMENT_VARIABLES  = 36;
  
    public static int AUTHENTICATION             = 37;
  
    public static int ENCRYPTION                 = 38;
  
    public static int NEW_ENVIRONMENT_VARIABLES  = 39;
  
    public static int EXTENDED_OPTIONS_LIST      = 255;
  
    private static int __FIRST_OPTION = BINARY;
    private static int __LAST_OPTION  = NEW_ENVIRONMENT_VARIABLES;
  
    private static final String __optionString[] = {
      "BINARY", "ECHO", "RCP", "SUPPRESS GO AHEAD", "NAME", "STATUS",
      "TIMING MARK", "RCTE","NAOL", "NAOP", "NAOCRD", "NAOHTS", "NAOHTD",
      "NAOFFD", "NAOVTS", "NAOVTD", "NAOLFD", "EXTEND ASCII", "LOGOUT",
      "BYTE MACRO", "DATA ENTRY TERMINAL", "SUPDUP", "SUPDUP OUTPUT",
      "SEND LOCATION", "TERMINAL TYPE", "END OF RECORD", "TACACS UID",
      "OUTPUT MARKING", "TTYLOC", "3270 REGIME", "X.3 PAD", "NAWS", "TSPEED",
      "LFLOW", "LINEMODE", "XDISPLOC", "OLD-ENVIRON", "AUTHENTICATION",
      "ENCRYPT", "NEW-ENVIRON"
    };
  
  
    /***
     * Returns the string representation of the telnet protocol option
     * corresponding to the given option code.
     * <p>
     * @param The option code of the telnet protocol option
     * @return The string representation of the telnet protocol option.
     ***/
    public static final String getOption(int code) {
      return __optionString[code];
    }
  
  
    /***
     * Determines if a given option code is valid.  Returns true if valid,
     * false if not.
     * <p>
     * @param code  The option code to test.
     * @return True if the option code is valid, false if not.
     **/
    public static final boolean isValidOption(int code) {
      return (code <= __LAST_OPTION);
    }
  
    // Cannot be instantiated
    private TelnetOption() { }
  }
  
  
  
  1.1                  jakarta-commons-sandbox/net/src/java/org/apache/commons/net/telnet/TelnetOutputStream.java
  
  Index: TelnetOutputStream.java
  ===================================================================
  package org.apache.commons.net.telnet;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Commons" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Turbine", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import java.io.*;
  
  /***
   *
   * <p>
   *
   * <p>
   * <p>
   * @author Daniel F. Savarese
   ***/
  
  
  final class TelnetOutputStream extends OutputStream {
    private TelnetClient __client;
    private boolean __convertCRtoCRLF = true;
    private boolean __lastWasCR = false;
  
    TelnetOutputStream(TelnetClient client) {
      __client = client;
    }
  
  
    /***
     * Writes a byte to the stream.
     * <p>
     * @param ch The byte to write.
     * @exception IOException If an error occurs while writing to the underlying
     *            stream.
     ***/
    public void write(int ch) throws IOException {
  
      synchronized(__client) {
        ch &= 0xff;
  
        if(__client._requestedWont(TelnetOption.BINARY)) {
  	if(__lastWasCR) {
  	  if(__convertCRtoCRLF) {
  	    __client._sendByte('\n');
  	    if(ch == '\n') {
  	      __lastWasCR = false;
  	      return;
  	    }
  	  } else if(ch != '\n')
  	    __client._sendByte('\0');
  	}
  
  	__lastWasCR = false;
  
  	switch(ch) {
  	case '\r':
  	  __client._sendByte('\r');
  	  __lastWasCR = true;
  	  break;
  	case TelnetCommand.IAC:
  	  __client._sendByte(TelnetCommand.IAC);
  	  __client._sendByte(TelnetCommand.IAC);
  	  break;
  	default:
  	  __client._sendByte(ch);
  	  break;
  	}
        } else if(ch == TelnetCommand.IAC) {
  	__client._sendByte(ch);
  	__client._sendByte(TelnetCommand.IAC);
        } else
  	__client._sendByte(ch);
      }
    }
  
  
    /***
     * Writes a byte array to the stream.
     * <p>
     * @param buffer  The byte array to write.
     * @exception IOException If an error occurs while writing to the underlying
     *            stream.
     ***/
    public void write(byte buffer[]) throws IOException {
      write(buffer, 0, buffer.length);
    }                 
  
  
    /***
     * Writes a number of bytes from a byte array to the stream starting from
     * a given offset.
     * <p>
     * @param buffer  The byte array to write.
     * @param offset  The offset into the array at which to start copying data.
     * @param length  The number of bytes to write.
     * @exception IOException If an error occurs while writing to the underlying
     *            stream.
     ***/
    public void write(byte buffer[], int offset, int length) throws IOException {
      synchronized(__client) {
        while(length-- > 0)
  	write(buffer[offset++]);
      }
    }
  
    /*** Flushes the stream. ***/
    public void flush() throws IOException { __client._flushOutputStream(); }
  
    /*** Closes the stream. ***/
    public void close() throws IOException { __client._closeOutputStream(); }
  }
  
  
  

--
To unsubscribe, e-mail:   <mailto:commons-dev-unsubscribe@jakarta.apache.org>
For additional commands, e-mail: <mailto:commons-dev-help@jakarta.apache.org>


Mime
View raw message