/* FTPConnection.java --
   Copyright (C) 2003, 2004  Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package gnu.java.net.protocol.ftp;

import gnu.java.lang.CPStringBuilder;

import gnu.java.net.CRLFInputStream;
import gnu.java.net.CRLFOutputStream;
import gnu.java.net.EmptyX509TrustManager;
import gnu.java.net.LineInputStream;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.BindException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ProtocolException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.GeneralSecurityException;
import java.util.ArrayList;
import java.util.List;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;

/**
 * An FTP client connection, or PI.
 * This implements RFC 959, with the following exceptions:
 * <ul>
 * <li>STAT, HELP, SITE, SMNT, and ACCT commands are not supported.</li>
 * <li>the TYPE command does not allow alternatives to the default bytesize
 * (Non-print), and local bytesize is not supported.</li>
 * </ul>
 *
 * @author Chris Burdess (dog@gnu.org)
 */
public class FTPConnection
{

  /**
   * The default FTP transmission control port.
   */
  public static final int FTP_PORT = 21;

  /**
   * The FTP data port.
   */
  public static final int FTP_DATA_PORT = 20;

  // -- FTP vocabulary --
  protected static final String USER = "USER";
  protected static final String PASS = "PASS";
  protected static final String ACCT = "ACCT";
  protected static final String CWD = "CWD";
  protected static final String CDUP = "CDUP";
  protected static final String SMNT = "SMNT";
  protected static final String REIN = "REIN";
  protected static final String QUIT = "QUIT";

  protected static final String PORT = "PORT";
  protected static final String PASV = "PASV";
  protected static final String TYPE = "TYPE";
  protected static final String STRU = "STRU";
  protected static final String MODE = "MODE";

  protected static final String RETR = "RETR";
  protected static final String STOR = "STOR";
  protected static final String STOU = "STOU";
  protected static final String APPE = "APPE";
  protected static final String ALLO = "ALLO";
  protected static final String REST = "REST";
  protected static final String RNFR = "RNFR";
  protected static final String RNTO = "RNTO";
  protected static final String ABOR = "ABOR";
  protected static final String DELE = "DELE";
  protected static final String RMD = "RMD";
  protected static final String MKD = "MKD";
  protected static final String PWD = "PWD";
  protected static final String LIST = "LIST";
  protected static final String NLST = "NLST";
  protected static final String SITE = "SITE";
  protected static final String SYST = "SYST";
  protected static final String STAT = "STAT";
  protected static final String HELP = "HELP";
  protected static final String NOOP = "NOOP";

  protected static final String AUTH = "AUTH";
  protected static final String PBSZ = "PBSZ";
  protected static final String PROT = "PROT";
  protected static final String CCC = "CCC";
  protected static final String TLS = "TLS";

  public static final int TYPE_ASCII = 1;
  public static final int TYPE_EBCDIC = 2;
  public static final int TYPE_BINARY = 3;

  public static final int STRUCTURE_FILE = 1;
  public static final int STRUCTURE_RECORD = 2;
  public static final int STRUCTURE_PAGE = 3;

  public static final int MODE_STREAM = 1;
  public static final int MODE_BLOCK = 2;
  public static final int MODE_COMPRESSED = 3;

  // -- Telnet constants --
  private static final String US_ASCII = "US-ASCII";

  /**
   * The socket used to communicate with the server.
   */
  protected Socket socket;

  /**
   * The socket input stream.
   */
  protected LineInputStream in;

  /**
   * The socket output stream.
   */
  protected CRLFOutputStream out;

  /**
   * The timeout when attempting to connect a socket.
   */
  protected int connectionTimeout;

  /**
   * The read timeout on sockets.
   */
  protected int timeout;

  /**
   * If true, print debugging information.
   */
  protected boolean debug;

  /**
   * The current data transfer process in use by this connection.
   */
  protected DTP dtp;

  /**
   * The current representation type.
   */
  protected int representationType = TYPE_ASCII;

  /**
   * The current file structure type.
   */
  protected int fileStructure = STRUCTURE_FILE;

  /**
   * The current transfer mode.
   */
  protected int transferMode = MODE_STREAM;

  /**
   * If true, use passive mode.
   */
  protected boolean passive = false;

  /**
   * Creates a new connection to the server using the default port.
   * @param hostname the hostname of the server to connect to
   */
  public FTPConnection(String hostname)
    throws UnknownHostException, IOException
  {
    this(hostname, -1, 0, 0, false);
  }

  /**
   * Creates a new connection to the server.
   * @param hostname the hostname of the server to connect to
   * @param port the port to connect to(if &lt;=0, use default port)
   */
  public FTPConnection(String hostname, int port)
    throws UnknownHostException, IOException
  {
    this(hostname, port, 0, 0, false);
  }

  /**
   * Creates a new connection to the server.
   * @param hostname the hostname of the server to connect to
   * @param port the port to connect to(if &lt;=0, use default port)
   * @param connectionTimeout the connection timeout, in milliseconds
   * @param timeout the I/O timeout, in milliseconds
   * @param debug print debugging information
   */
  public FTPConnection(String hostname, int port,
                        int connectionTimeout, int timeout, boolean debug)
    throws UnknownHostException, IOException
  {
    this.connectionTimeout = connectionTimeout;
    this.timeout = timeout;
    this.debug = debug;
    if (port <= 0)
      {
        port = FTP_PORT;
      }

    // Set up socket
    socket = new Socket();
    InetSocketAddress address = new InetSocketAddress(hostname, port);
    if (connectionTimeout > 0)
      {
        socket.connect(address, connectionTimeout);
      }
    else
      {
        socket.connect(address);
      }
    if (timeout > 0)
      {
        socket.setSoTimeout(timeout);
      }

    InputStream in = socket.getInputStream();
    in = new BufferedInputStream(in);
    in = new CRLFInputStream(in);
    this.in = new LineInputStream(in);
    OutputStream out = socket.getOutputStream();
    out = new BufferedOutputStream(out);
    this.out = new CRLFOutputStream(out);

    // Read greeting
    FTPResponse response = getResponse();
    switch (response.getCode())
      {
      case 220:                  // hello
        break;
      default:
        throw new FTPException(response);
      }
  }

  /**
   * Authenticate using the specified username and password.
   * If the username suffices for the server, the password will not be used
   * and may be null.
   * @param username the username
   * @param password the optional password
   * @return true on success, false otherwise
   */
  public boolean authenticate(String username, String password)
    throws IOException
  {
    String cmd = USER + ' ' + username;
    send(cmd);
    FTPResponse response = getResponse();
    switch (response.getCode())
      {
      case 230:                  // User logged in
        return true;
      case 331:                 // User name okay, need password
        break;
      case 332:                 // Need account for login
      case 530:                 // No such user
        return false;
      default:
        throw new FTPException(response);
      }
    cmd = PASS + ' ' + password;
    send(cmd);
    response = getResponse();
    switch (response.getCode())
      {
      case 230:                  // User logged in
      case 202:                  // Superfluous
        return true;
      case 332:                  // Need account for login
      case 530:                  // Bad password
        return false;
      default:
        throw new FTPException(response);
      }
  }

  /**
   * Negotiates TLS over the current connection.
   * See IETF draft-murray-auth-ftp-ssl-15.txt for details.
   * @param confidential whether to provide confidentiality for the
   * connection
   */
  public boolean starttls(boolean confidential)
    throws IOException
  {
    return starttls(confidential, new EmptyX509TrustManager());
  }

  /**
   * Negotiates TLS over the current connection.
   * See IETF draft-murray-auth-ftp-ssl-15.txt for details.
   * @param confidential whether to provide confidentiality for the
   * connection
   * @param tm the trust manager used to validate the server certificate.
   */
  public boolean starttls(boolean confidential, TrustManager tm)
    throws IOException
  {
    try
      {
        // Use SSLSocketFactory to negotiate a TLS session and wrap the
        // current socket.
        SSLContext context = SSLContext.getInstance("TLS");
        // We don't require strong validation of the server certificate
        TrustManager[] trust = new TrustManager[] { tm };
        context.init(null, trust, null);
        SSLSocketFactory factory = context.getSocketFactory();

        send(AUTH + ' ' + TLS);
        FTPResponse response = getResponse();
        switch (response.getCode())
          {
          case 500:
          case 502:
          case 504:
          case 534:
          case 431:
            return false;
          case 234:
            break;
          default:
            throw new FTPException(response);
          }

        String hostname = socket.getInetAddress().getHostName();
        int port = socket.getPort();
        SSLSocket ss =
         (SSLSocket) factory.createSocket(socket, hostname, port, true);
        String[] protocols = { "TLSv1", "SSLv3" };
        ss.setEnabledProtocols(protocols);
        ss.setUseClientMode(true);
        ss.startHandshake();

        // PBSZ:PROT sequence
        send(PBSZ + ' ' + Integer.MAX_VALUE);
        response = getResponse();
        switch (response.getCode())
          {
          case 501: // syntax error
          case 503: // not authenticated
            return false;
          case 200:
            break;
          default:
            throw new FTPException(response);
          }
        send(PROT + ' ' +(confidential ? 'P' : 'C'));
        response = getResponse();
        switch (response.getCode())
          {
          case 503: // not authenticated
          case 504: // invalid level
          case 536: // level not supported
            return false;
          case 200:
            break;
          default:
            throw new FTPException(response);
          }

        if (confidential)
          {
            // Set up streams
            InputStream in = ss.getInputStream();
            in = new BufferedInputStream(in);
            in = new CRLFInputStream(in);
            this.in = new LineInputStream(in);
            OutputStream out = ss.getOutputStream();
            out = new BufferedOutputStream(out);
            this.out = new CRLFOutputStream(out);
          }
        return true;
      }
    catch (GeneralSecurityException e)
      {
        return false;
      }
  }

  /**
   * Changes directory to the specified path.
   * @param path an absolute or relative pathname
   * @return true on success, false if the specified path does not exist
   */
  public boolean changeWorkingDirectory(String path)
    throws IOException
  {
    // Do nothing if the path is empty.
    if (path.length() == 0)
      return true;
    String cmd = CWD + ' ' + path;
    send(cmd);
    FTPResponse response = getResponse();
    switch (response.getCode())
      {
      case 250:
        return true;
      case 550:
        return false;
      default:
        throw new FTPException(response);
      }
  }

  /**
   * Changes directory to the parent of the current working directory.
   * @return true on success, false otherwise
   */
  public boolean changeToParentDirectory()
    throws IOException
  {
    send(CDUP);
    FTPResponse response = getResponse();
    switch (response.getCode())
      {
      case 250:
        return true;
      case 550:
        return false;
      default:
        throw new FTPException(response);
      }
  }

  /**
   * Terminates an authenticated login.
   * If file transfer is in progress, it remains active for result response
   * only.
   */
  public void reinitialize()
    throws IOException
  {
    send(REIN);
    FTPResponse response = getResponse();
    switch (response.getCode())
      {
      case 220:
        if (dtp != null)
          {
            dtp.complete();
            dtp = null;
          }
        break;
      default:
        throw new FTPException(response);
      }
  }

  /**
   * Terminates the control connection.
   * The file transfer connection remains open for result response only.
   * This connection is invalid and no further commands may be issued.
   */
  public void logout()
    throws IOException
  {
    send(QUIT);
    try
      {
        getResponse();            // not required
      }
    catch (IOException e)
      {
      }
    if (dtp != null)
      {
        dtp.complete();
        dtp = null;
      }
    try
      {
        socket.close();
      }
    catch (IOException e)
      {
      }
  }

  /**
   * Initialise the data transfer process.
   */
  protected void initialiseDTP()
    throws IOException
  {
    if (dtp != null)
      {
        dtp.complete();
        dtp = null;
      }

    InetAddress localhost = socket.getLocalAddress();
    if (passive)
      {
        send(PASV);
        FTPResponse response = getResponse();
        switch (response.getCode())
          {
          case 227:
            String message = response.getMessage();
            try
              {
                int start = message.indexOf(',');
                char c = message.charAt(start - 1);
                while (c >= 0x30 && c <= 0x39)
                  {
                    c = message.charAt((--start) - 1);
                  }
                int mid1 = start;
                for (int i = 0; i < 4; i++)
                  {
                    mid1 = message.indexOf(',', mid1 + 1);
                  }
                int mid2 = message.indexOf(',', mid1 + 1);
                if (mid1 == -1 || mid2 < mid1)
                  {
                    throw new ProtocolException("Malformed 227: " +
                                                 message);
                  }
                int end = mid2;
                c = message.charAt(end + 1);
                while (c >= 0x30 && c <= 0x39)
                  {
                    c = message.charAt((++end) + 1);
                  }

                String address =
                  message.substring(start, mid1).replace(',', '.');
                int port_hi =
                  Integer.parseInt(message.substring(mid1 + 1, mid2));
                int port_lo =
                  Integer.parseInt(message.substring(mid2 + 1, end + 1));
                int port = (port_hi << 8) | port_lo;

                /*System.out.println("Entering passive mode: " + address +
                  ":" + port);*/
                dtp = new PassiveModeDTP(address, port, localhost,
                                          connectionTimeout, timeout);
                break;
              }
            catch (ArrayIndexOutOfBoundsException e)
              {
                throw new ProtocolException(e.getMessage() + ": " +
                                             message);
              }
            catch (NumberFormatException e)
              {
                throw new ProtocolException(e.getMessage() + ": " +
                                             message);
              }
          default:
            throw new FTPException(response);
          }
      }
    else
      {
        // Get the local port
        int port = socket.getLocalPort() + 1;
        int tries = 0;
        // Bind the active mode DTP
        while (dtp == null)
          {
            try
              {
                dtp = new ActiveModeDTP(localhost, port,
                                         connectionTimeout, timeout);
                /*System.out.println("Listening on: " + port);*/
              }
            catch (BindException e)
              {
                port++;
                tries++;
                if (tries > 9)
                  {
                    throw e;
                  }
              }
          }

        // Send PORT command
        CPStringBuilder buf = new CPStringBuilder(PORT);
        buf.append(' ');
        // Construct the address/port string form
        byte[] address = localhost.getAddress();
        for (int i = 0; i < address.length; i++)
          {
            int a =(int) address[i];
            if (a < 0)
              {
                a += 0x100;
              }
            buf.append(a);
            buf.append(',');
          }
        int port_hi =(port & 0xff00) >> 8;
        int port_lo =(port & 0x00ff);
        buf.append(port_hi);
        buf.append(',');
        buf.append(port_lo);
        send(buf.toString());
        // Get response
        FTPResponse response = getResponse();
        switch (response.getCode())
          {
          case 200:                // OK
            break;
          default:
            dtp.abort();
            dtp = null;
            throw new FTPException(response);
          }
      }
    dtp.setTransferMode(transferMode);
  }

  /**
   * Set passive mode.
   * @param flag true if we should use passive mode, false otherwise
   */
  public void setPassive(boolean flag)
    throws IOException
  {
    if (passive != flag)
      {
        passive = flag;
        initialiseDTP();
      }
  }

  /**
   * Returns the current representation type of the transfer data.
   * @return TYPE_ASCII, TYPE_EBCDIC, or TYPE_BINARY
   */
  public int getRepresentationType()
  {
    return representationType;
  }

  /**
   * Sets the desired representation type of the transfer data.
   * @param type TYPE_ASCII, TYPE_EBCDIC, or TYPE_BINARY
   */
  public void setRepresentationType(int type)
    throws IOException
  {
    CPStringBuilder buf = new CPStringBuilder(TYPE);
    buf.append(' ');
    switch (type)
      {
      case TYPE_ASCII:
        buf.append('A');
        break;
      case TYPE_EBCDIC:
        buf.append('E');
        break;
      case TYPE_BINARY:
        buf.append('I');
        break;
      default:
        throw new IllegalArgumentException(Integer.toString(type));
      }
    //buf.append(' ');
    //buf.append('N');
    send(buf.toString());
    FTPResponse response = getResponse();
    switch (response.getCode())
      {
      case 200:
        representationType = type;
        break;
      default:
        throw new FTPException(response);
      }
  }

  /**
   * Returns the current file structure type.
   * @return STRUCTURE_FILE, STRUCTURE_RECORD, or STRUCTURE_PAGE
   */
  public int getFileStructure()
  {
    return fileStructure;
  }

  /**
   * Sets the desired file structure type.
   * @param structure STRUCTURE_FILE, STRUCTURE_RECORD, or STRUCTURE_PAGE
   */
  public void setFileStructure(int structure)
    throws IOException
  {
    CPStringBuilder buf = new CPStringBuilder(STRU);
    buf.append(' ');
    switch (structure)
      {
      case STRUCTURE_FILE:
        buf.append('F');
        break;
      case STRUCTURE_RECORD:
        buf.append('R');
        break;
      case STRUCTURE_PAGE:
        buf.append('P');
        break;
      default:
        throw new IllegalArgumentException(Integer.toString(structure));
      }
    send(buf.toString());
    FTPResponse response = getResponse();
    switch (response.getCode())
      {
      case 200:
        fileStructure = structure;
        break;
      default:
        throw new FTPException(response);
      }
  }

  /**
   * Returns the current transfer mode.
   * @return MODE_STREAM, MODE_BLOCK, or MODE_COMPRESSED
   */
  public int getTransferMode()
  {
    return transferMode;
  }

  /**
   * Sets the desired transfer mode.
   * @param mode MODE_STREAM, MODE_BLOCK, or MODE_COMPRESSED
   */
  public void setTransferMode(int mode)
    throws IOException
  {
    CPStringBuilder buf = new CPStringBuilder(MODE);
    buf.append(' ');
    switch (mode)
      {
      case MODE_STREAM:
        buf.append('S');
        break;
      case MODE_BLOCK:
        buf.append('B');
        break;
      case MODE_COMPRESSED:
        buf.append('C');
        break;
      default:
        throw new IllegalArgumentException(Integer.toString(mode));
      }
    send(buf.toString());
    FTPResponse response = getResponse();
    switch (response.getCode())
      {
      case 200:
        transferMode = mode;
        if (dtp != null)
          {
            dtp.setTransferMode(mode);
          }
        break;
      default:
        throw new FTPException(response);
      }
  }

  /**
   * Retrieves the specified file.
   * @param filename the filename of the file to retrieve
   * @return an InputStream containing the file content
   */
  public InputStream retrieve(String filename)
    throws IOException
  {
    if (dtp == null || transferMode == MODE_STREAM)
      {
        initialiseDTP();
      }
    /*
       int size = -1;
       String cmd = SIZE + ' ' + filename;
       send(cmd);
       FTPResponse response = getResponse();
       switch (response.getCode())
       {
       case 213:
       size = Integer.parseInt(response.getMessage());
       break;
       case 550: // File not found
       default:
       throw new FTPException(response);
       }
     */
    String cmd = RETR + ' ' + filename;
    send(cmd);
    FTPResponse response = getResponse();
    switch (response.getCode())
      {
      case 125:                  // Data connection already open; transfer starting
      case 150:                  // File status okay; about to open data connection
        return dtp.getInputStream();
      default:
        throw new FTPException(response);
      }
  }

  /**
   * Returns a stream for uploading a file.
   * If a file with the same filename already exists on the server, it will
   * be overwritten.
   * @param filename the name of the file to save the content as
   * @return an OutputStream to write the file data to
   */
  public OutputStream store(String filename)
    throws IOException
  {
    if (dtp == null || transferMode == MODE_STREAM)
      {
        initialiseDTP();
      }
    String cmd = STOR + ' ' + filename;
    send(cmd);
    FTPResponse response = getResponse();
    switch (response.getCode())
      {
      case 125:                  // Data connection already open; transfer starting
      case 150:                  // File status okay; about to open data connection
        return dtp.getOutputStream();
      default:
        throw new FTPException(response);
      }
  }

  /**
   * Returns a stream for uploading a file.
   * If a file with the same filename already exists on the server, the
   * content specified will be appended to the existing file.
   * @param filename the name of the file to save the content as
   * @return an OutputStream to write the file data to
   */
  public OutputStream append(String filename)
    throws IOException
  {
    if (dtp == null || transferMode == MODE_STREAM)
      {
        initialiseDTP();
      }
    String cmd = APPE + ' ' + filename;
    send(cmd);
    FTPResponse response = getResponse();
    switch (response.getCode())
      {
      case 125:                  // Data connection already open; transfer starting
      case 150:                  // File status okay; about to open data connection
        return dtp.getOutputStream();
      default:
        throw new FTPException(response);
      }
  }

  /**
   * This command may be required by some servers to reserve sufficient
   * storage to accommodate the new file to be transferred.
   * It should be immediately followed by a <code>store</code> or
   * <code>append</code>.
   * @param size the number of bytes of storage to allocate
   */
  public void allocate(long size)
    throws IOException
  {
    String cmd = ALLO + ' ' + size;
    send(cmd);
    FTPResponse response = getResponse();
    switch (response.getCode())
      {
      case 200:                  // OK
      case 202:                  // Superfluous
        break;
      default:
        throw new FTPException(response);
      }
  }

  /**
   * Renames a file.
   * @param oldName the current name of the file
   * @param newName the new name
   * @return true if successful, false otherwise
   */
  public boolean rename(String oldName, String newName)
    throws IOException
  {
    String cmd = RNFR + ' ' + oldName;
    send(cmd);
    FTPResponse response = getResponse();
    switch (response.getCode())
      {
      case 450:                  // File unavailable
      case 550:                  // File not found
        return false;
      case 350:                 // Pending
        break;
      default:
        throw new FTPException(response);
      }
    cmd = RNTO + ' ' + newName;
    send(cmd);
    response = getResponse();
    switch (response.getCode())
      {
      case 250:                  // OK
        return true;
      case 450:
      case 550:
        return false;
      default:
        throw new FTPException(response);
      }
  }

  /**
   * Aborts the transfer in progress.
   * @return true if a transfer was in progress, false otherwise
   */
  public boolean abort()
    throws IOException
  {
    send(ABOR);
    FTPResponse response = getResponse();
    // Abort client DTP
    if (dtp != null)
      {
        dtp.abort();
      }
    switch (response.getCode())
      {
      case 226:                  // successful abort
        return false;
      case 426:                 // interrupted
        response = getResponse();
        if (response.getCode() == 226)
          {
            return true;
          }
        // Otherwise fall through to throw exception
      default:
        throw new FTPException(response);
      }
  }

  /**
   * Causes the file specified to be deleted at the server site.
   * @param filename the file to delete
   */
  public boolean delete(String filename)
    throws IOException
  {
    String cmd = DELE + ' ' + filename;
    send(cmd);
    FTPResponse response = getResponse();
    switch (response.getCode())
      {
      case 250:                  // OK
        return true;
      case 450:                 // File unavailable
      case 550:                 // File not found
        return false;
      default:
        throw new FTPException(response);
      }
  }

  /**
   * Causes the directory specified to be deleted.
   * This may be an absolute or relative pathname.
   * @param pathname the directory to delete
   */
  public boolean removeDirectory(String pathname)
    throws IOException
  {
    String cmd = RMD + ' ' + pathname;
    send(cmd);
    FTPResponse response = getResponse();
    switch (response.getCode())
      {
      case 250:                  // OK
        return true;
      case 550:                 // File not found
        return false;
      default:
        throw new FTPException(response);
      }
  }

  /**
   * Causes the directory specified to be created at the server site.
   * This may be an absolute or relative pathname.
   * @param pathname the directory to create
   */
  public boolean makeDirectory(String pathname)
    throws IOException
  {
    String cmd = MKD + ' ' + pathname;
    send(cmd);
    FTPResponse response = getResponse();
    switch (response.getCode())
      {
      case 257:                  // Directory created
        return true;
      case 550:                 // File not found
        return false;
      default:
        throw new FTPException(response);
      }
  }

  /**
   * Returns the current working directory.
   */
  public String getWorkingDirectory()
    throws IOException
  {
    send(PWD);
    FTPResponse response = getResponse();
    switch (response.getCode())
      {
      case 257:
        String message = response.getMessage();
        if (message.charAt(0) == '"')
          {
            int end = message.indexOf('"', 1);
            if (end == -1)
              {
                throw new ProtocolException(message);
              }
            return message.substring(1, end);
          }
        else
          {
            int end = message.indexOf(' ');
            if (end == -1)
              {
                return message;
              }
            else
              {
                return message.substring(0, end);
              }
          }
      default:
        throw new FTPException(response);
      }
  }

  /**
   * Returns a listing of information about the specified pathname.
   * If the pathname specifies a directory or other group of files, the
   * server should transfer a list of files in the specified directory.
   * If the pathname specifies a file then the server should send current
   * information on the file.  A null argument implies the user's
   * current working or default directory.
   * @param pathname the context pathname, or null
   */
  public InputStream list(String pathname)
    throws IOException
  {
    if (dtp == null || transferMode == MODE_STREAM)
      {
        initialiseDTP();
      }
    if (pathname == null)
      {
        send(LIST);
      }
    else
      {
        String cmd = LIST + ' ' + pathname;
        send(cmd);
      }
    FTPResponse response = getResponse();
    switch (response.getCode())
      {
      case 125:                  // Data connection already open; transfer starting
      case 150:                  // File status okay; about to open data connection
        return dtp.getInputStream();
      default:
        throw new FTPException(response);
      }
  }

  /**
   * Returns a directory listing. The pathname should specify a
   * directory or other system-specific file group descriptor; a null
   * argument implies the user's current working or default directory.
   * @param pathname the directory pathname, or null
   * @return a list of filenames(strings)
   */
  public List<String> nameList(String pathname)
    throws IOException
  {
    if (dtp == null || transferMode == MODE_STREAM)
      {
        initialiseDTP();
      }
    if (pathname == null)
      {
        send(NLST);
      }
    else
      {
        String cmd = NLST + ' ' + pathname;
        send(cmd);
      }
    FTPResponse response = getResponse();
    switch (response.getCode())
      {
      case 125:                  // Data connection already open; transfer starting
      case 150:                  // File status okay; about to open data connection
        InputStream in = dtp.getInputStream();
        in = new BufferedInputStream(in);
        in = new CRLFInputStream(in);     // TODO ensure that TYPE is correct
        LineInputStream li = new LineInputStream(in);
        ArrayList<String> ret = new ArrayList<String>();
        for (String line = li.readLine();
             line != null;
             line = li.readLine())
          {
            ret.add(line);
          }
        li.close();
        return ret;
      default:
        throw new FTPException(response);
      }
  }

  /**
   * Returns the type of operating system at the server.
   */
  public String system()
    throws IOException
  {
    send(SYST);
    FTPResponse response = getResponse();
    switch (response.getCode())
      {
      case 215:
        String message = response.getMessage();
        int end = message.indexOf(' ');
        if (end == -1)
          {
            return message;
          }
        else
          {
            return message.substring(0, end);
          }
      default:
        throw new FTPException(response);
      }
  }

  /**
   * Does nothing.
   * This method can be used to ensure that the connection does not time
   * out.
   */
  public void noop()
    throws IOException
  {
    send(NOOP);
    FTPResponse response = getResponse();
    switch (response.getCode())
      {
      case 200:
        break;
      default:
        throw new FTPException(response);
      }
  }

  // -- I/O --

  /**
   * Sends the specified command line to the server.
   * The CRLF sequence is automatically appended.
   * @param cmd the command line to send
   */
  protected void send(String cmd)
    throws IOException
  {
    byte[] data = cmd.getBytes(US_ASCII);
    out.write(data);
    out.writeln();
    out.flush();
  }

  /**
   * Reads the next response from the server.
   * If the server sends the "transfer complete" code, this is handled here,
   * and the next response is passed to the caller.
   */
  protected FTPResponse getResponse()
    throws IOException
  {
    FTPResponse response = readResponse();
    if (response.getCode() == 226)
      {
        if (dtp != null)
          {
            dtp.transferComplete();
          }
        response = readResponse();
      }
    return response;
  }

  /**
   * Reads and parses the next response from the server.
   */
  protected FTPResponse readResponse()
    throws IOException
  {
    String line = in.readLine();
    if (line == null)
      {
        throw new ProtocolException( "EOF");
      }
    if (line.length() < 4)
      {
        throw new ProtocolException(line);
      }
    int code = parseCode(line);
    if (code == -1)
      {
        throw new ProtocolException(line);
      }
    char c = line.charAt(3);
    if (c == ' ')
      {
        return new FTPResponse(code, line.substring(4));
      }
    else if (c == '-')
      {
        CPStringBuilder buf = new CPStringBuilder(line.substring(4));
        buf.append('\n');
        while(true)
          {
            line = in.readLine();
            if (line == null)
              {
                throw new ProtocolException("EOF");
              }
            if (line.length() >= 4 &&
                line.charAt(3) == ' ' &&
                parseCode(line) == code)
              {
                return new FTPResponse(code, line.substring(4),
                                        buf.toString());
              }
            else
              {
                buf.append(line);
                buf.append('\n');
              }
          }
      }
    else
      {
        throw new ProtocolException(line);
      }
  }

  /*
   * Parses the 3-digit numeric code at the beginning of the given line.
   * Returns -1 on failure.
   */
  static final int parseCode(String line)
  {
    char[] c = { line.charAt(0), line.charAt(1), line.charAt(2) };
    int ret = 0;
    for (int i = 0; i < 3; i++)
      {
        int digit =((int) c[i]) - 0x30;
        if (digit < 0 || digit > 9)
          {
            return -1;
          }
        // Computing integer powers is way too expensive in Java!
        switch (i)
          {
          case 0:
            ret +=(100 * digit);
            break;
          case 1:
            ret +=(10 * digit);
            break;
          case 2:
            ret += digit;
            break;
          }
      }
    return ret;
  }

}
