commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From s...@apache.org
Subject svn commit: r922747 [2/2] - /commons/proper/net/branches/NET_2_0/src/main/java/org/apache/commons/net/ftp/FTPClient.java
Date Sun, 14 Mar 2010 03:22:56 GMT

Modified: commons/proper/net/branches/NET_2_0/src/main/java/org/apache/commons/net/ftp/FTPClient.java
URL: http://svn.apache.org/viewvc/commons/proper/net/branches/NET_2_0/src/main/java/org/apache/commons/net/ftp/FTPClient.java?rev=922747&r1=922746&r2=922747&view=diff
==============================================================================
--- commons/proper/net/branches/NET_2_0/src/main/java/org/apache/commons/net/ftp/FTPClient.java (original)
+++ commons/proper/net/branches/NET_2_0/src/main/java/org/apache/commons/net/ftp/FTPClient.java Sun Mar 14 03:22:56 2010
@@ -111,8 +111,8 @@ import org.apache.commons.net.io.Util;
  * for EBCDIC.  To transfer EBCDIC and other unsupported file types you
  * must create your own filter InputStreams and OutputStreams and wrap
  * them around the streams returned or required by the FTPClient methods.
- * FTPClient uses the {@link ToNetASCIIOutputStream NetASCII}  
- * filter streams to provide transparent handling of ASCII files.  We will 
+ * FTPClient uses the {@link ToNetASCIIOutputStream NetASCII}
+ * filter streams to provide transparent handling of ASCII files.  We will
  * consider incorporating EBCDIC support if there is enough demand.
  * <p>
  * <code> FTP.NON_PRINT_TEXT_FORMAT </code>,
@@ -214,14 +214,14 @@ import org.apache.commons.net.io.Util;
  *    }
  * </pre>
  * <p>
- * For examples of using FTPClient on servers whose directory listings 
- * <ul> 
+ * For examples of using FTPClient on servers whose directory listings
+ * <ul>
  * <li>use languages other than English</li>
  * <li>use date formats other than the American English "standard" <code>MM d yyyy</code></li>
- * <li>are in different timezones and you need accurate timestamps for dependency checking 
+ * <li>are in different timezones and you need accurate timestamps for dependency checking
  *     as in Ant</li>
  * </ul>see {@link  FTPClientConfig  FTPClientConfig}.
- * <p> 
+ * <p>
  * @author Daniel F. Savarese
  * @author Rory Winston
  * @see FTP
@@ -230,1513 +230,1513 @@ import org.apache.commons.net.io.Util;
  * @see FTPFileEntryParserFactory
  * @see DefaultFTPFileEntryParserFactory
  * @see FTPClientConfig
- * 
+ *
  * @see org.apache.commons.net.MalformedServerReplyException
  **/
 public class FTPClient extends FTP
 implements Configurable
 {
-	/***
-	 * A constant indicating the FTP session is expecting all transfers
-	 * to occur between the client (local) and server and that the server
-	 * should connect to the client's data port to initiate a data transfer.
-	 * This is the default data connection mode when and FTPClient instance
-	 * is created.
-	 ***/
-	public static final int ACTIVE_LOCAL_DATA_CONNECTION_MODE = 0;
-	/***
-	 * A constant indicating the FTP session is expecting all transfers
-	 * to occur between two remote servers and that the server
-	 * the client is connected to should connect to the other server's
-	 * data port to initiate a data transfer.
-	 ***/
-	public static final int ACTIVE_REMOTE_DATA_CONNECTION_MODE = 1;
-	/***
-	 * A constant indicating the FTP session is expecting all transfers
-	 * to occur between the client (local) and server and that the server
-	 * is in passive mode, requiring the client to connect to the
-	 * server's data port to initiate a transfer.
-	 ***/
-	public static final int PASSIVE_LOCAL_DATA_CONNECTION_MODE = 2;
-	/***
-	 * A constant indicating the FTP session is expecting all transfers
-	 * to occur between two remote servers and that the server
-	 * the client is connected to is in passive mode, requiring the other
-	 * server to connect to the first server's data port to initiate a data
-	 * transfer.
-	 ***/
-	public static final int PASSIVE_REMOTE_DATA_CONNECTION_MODE = 3;
-
-	private int __dataConnectionMode, __dataTimeout;
-	private int __passivePort;
-	private String __passiveHost;
-	private Random __random;
-	private int __activeMinPort, __activeMaxPort;    
-	private InetAddress __activeExternalHost;
-	private int __fileType, __fileFormat, __fileStructure, __fileTransferMode;
-	private boolean __remoteVerificationEnabled;
-	private long __restartOffset;
-	private FTPFileEntryParserFactory __parserFactory;
-	private int __bufferSize;
-	private boolean __listHiddenFiles;
-
-	// __systemName is a cached value that should not be referenced directly
-	// except when assigned in getSystemName and __initDefaults.
-	private String __systemName;
-
-	// __entryParser is a cached value that should not be referenced directly
-	// except when assigned in listFiles(String, String) and __initDefaults.
-	private FTPFileEntryParser __entryParser;
-
-	private FTPClientConfig __configuration;
-
-	/** Pattern for PASV mode responses */ 
-	private static final String __parms = "\\d{1,3},\\d{1,3},\\d{1,3},\\d{1,3},\\d{1,3},\\d{1,3}";
-	private static final java.util.regex.Pattern __parms_pat;
-	static {
-		__parms_pat = java.util.regex.Pattern.compile(__parms);
-	}
-
-	/***
-	 * Default FTPClient constructor.  Creates a new FTPClient instance
-	 * with the data connection mode set to
-	 * <code> ACTIVE_LOCAL_DATA_CONNECTION_MODE </code>, the file type
-	 * set to <code> FTP.ASCII_FILE_TYPE </code>, the
-	 * file format set to <code> FTP.NON_PRINT_TEXT_FORMAT </code>,
-	 * the file structure set to <code> FTP.FILE_STRUCTURE </code>, and
-	 * the transfer mode set to <code> FTP.STREAM_TRANSFER_MODE </code>.
-	 ***/
-	public FTPClient()
-	{
-		__initDefaults();
-		__dataTimeout = -1;
-		__remoteVerificationEnabled = true;
-		__parserFactory = new DefaultFTPFileEntryParserFactory();
-		__configuration      = null;
-		__listHiddenFiles = false;
-		__random = new Random();
-	}
-
-
-	private void __initDefaults()
-	{
-		__dataConnectionMode = ACTIVE_LOCAL_DATA_CONNECTION_MODE;
-		__passiveHost        = null;
-		__passivePort        = -1;
-		__activeExternalHost = null;
-		__activeMinPort = 0;
-		__activeMaxPort = 0;
-		__fileType           = FTP.ASCII_FILE_TYPE;
-		__fileStructure      = FTP.FILE_STRUCTURE;
-		__fileFormat         = FTP.NON_PRINT_TEXT_FORMAT;
-		__fileTransferMode   = FTP.STREAM_TRANSFER_MODE;
-		__restartOffset      = 0;
-		__systemName         = null;
-		__entryParser        = null;
-		__bufferSize         = Util.DEFAULT_COPY_BUFFER_SIZE;
-	}
-
-	private String __parsePathname(String reply)
-	{
-		int begin, end;
-
-		begin = reply.indexOf('"') + 1;
-		end = reply.indexOf('"', begin);
-
-		return reply.substring(begin, end);
-	}
-
-
-	private void __parsePassiveModeReply(String reply)
-	throws MalformedServerReplyException
-	{
-		java.util.regex.Matcher m = __parms_pat.matcher(reply);
-		if (!m.find()) {
-			throw new MalformedServerReplyException(
-					"Could not parse passive host information.\nServer Reply: " + reply);
-		}
-		reply = m.group();
-		String parts[] = m.group().split(",");
-
-		__passiveHost = parts[0] + '.' + parts[1] + '.' + parts[2] + '.' + parts[3];
-
-		try
-		{
-			int oct1 = Integer.parseInt(parts[4]);
-			int oct2 = Integer.parseInt(parts[5]);
-			__passivePort = (oct1 << 8) | oct2;
-		}
-		catch (NumberFormatException e)
-		{
-			throw new MalformedServerReplyException(
-					"Could not parse passive host information.\nServer Reply: " + reply);
-		}
-
-	}
-
-	private void __parseExtendedPassiveModeReply(String reply)
-	throws MalformedServerReplyException
-	{
-		int port;
-
-		reply = reply.substring(reply.indexOf('(') + 1,
-				reply.indexOf(')')).trim();
-
-		char delim1, delim2, delim3, delim4;
-		delim1 = reply.charAt(0);
-		delim2 = reply.charAt(1);
-		delim3 = reply.charAt(2);
-		delim4 = reply.charAt(reply.length()-1);
-
-		if (!(delim1 == delim2) || !(delim2 == delim3)
-				|| !(delim3 == delim4))
-			throw new MalformedServerReplyException(
-					"Could not parse extended passive host information.\nServer Reply: " + reply);
-		try
-		{
-			port = Integer.parseInt(reply.substring(3, reply.length()-1));
-		}
-		catch (NumberFormatException e)
-		{
-			throw new MalformedServerReplyException(
-					"Could not parse extended passive host information.\nServer Reply: " + reply);
-		}
-
-
-		// in EPSV mode, the passive host address is implicit
-		__passiveHost = getRemoteAddress().getHostAddress();
-		__passivePort = port;
-	}
-
-	private boolean __storeFile(int command, String remote, InputStream local)
-	throws IOException
-	{
-		OutputStream output;
-		Socket socket;
-
-		if ((socket = _openDataConnection_(command, remote)) == null)
-			return false;
-
-		output = new BufferedOutputStream(socket.getOutputStream(),
-				getBufferSize()
-		);
-		if (__fileType == ASCII_FILE_TYPE)
-			output = new ToNetASCIIOutputStream(output);
-		// Treat everything else as binary for now
-		try
-		{
-			Util.copyStream(local, output, getBufferSize(),
-					CopyStreamEvent.UNKNOWN_STREAM_SIZE, null,
-					false);
-		}
-		catch (IOException e)
-		{
-			try
-			{
-				socket.close();
-			}
-			catch (IOException f)
-			{}
-			throw e;
-		}
-		output.close();
-		socket.close();
-		return completePendingCommand();
-	}
-
-	private OutputStream __storeFileStream(int command, String remote)
-	throws IOException
-	{
-		OutputStream output;
-		Socket socket;
-
-		if ((socket = _openDataConnection_(command, remote)) == null)
-			return null;
-
-		output = socket.getOutputStream();
-		if (__fileType == ASCII_FILE_TYPE) {
-			// We buffer ascii transfers because the buffering has to
-			// be interposed between ToNetASCIIOutputSream and the underlying
-			// socket output stream.  We don't buffer binary transfers
-			// because we don't want to impose a buffering policy on the
-			// programmer if possible.  Programmers can decide on their
-			// own if they want to wrap the SocketOutputStream we return
-			// for file types other than ASCII.
-			output = new BufferedOutputStream(output,
-					getBufferSize());
-			output = new ToNetASCIIOutputStream(output);
-
-		}
-		return new org.apache.commons.net.io.SocketOutputStream(socket, output);
-	}
-
-
-	/**
-	 * Establishes a data connection with the FTP server, returning
-	 * a Socket for the connection if successful.  If a restart
-	 * offset has been set with {@link #setRestartOffset(long)},
-	 * a REST command is issued to the server with the offset as
-	 * an argument before establishing the data connection.  Active
-	 * mode connections also cause a local PORT command to be issued.
-	 * <p>
-	 * @param command  The text representation of the FTP command to send.
-	 * @param arg The arguments to the FTP command.  If this parameter is
-	 *             set to null, then the command is sent with no argument.
-	 * @return A Socket corresponding to the established data connection.
-	 *         Null is returned if an FTP protocol error is reported at
-	 *         any point during the establishment and initialization of
-	 *         the connection.
-	 * @exception IOException  If an I/O error occurs while either sending a
-	 *      command to the server or receiving a reply from the server.
-	 */
-	protected Socket _openDataConnection_(int command, String arg)
-	throws IOException
-	{
-		Socket socket;
-
-		if (__dataConnectionMode != ACTIVE_LOCAL_DATA_CONNECTION_MODE &&
-				__dataConnectionMode != PASSIVE_LOCAL_DATA_CONNECTION_MODE)
-			return null;
-
-		if (__dataConnectionMode == ACTIVE_LOCAL_DATA_CONNECTION_MODE)
-		{
-			ServerSocket server = _serverSocketFactory_.createServerSocket(getActivePort(), 1, getHostAddress());
-
-			// try EPRT first. If that fails, and the connection is over IPv4
-			// fallback to PORT
-			if (!FTPReply.isPositiveCompletion(eprt(getHostAddress(),
-					getActivePort())))
-			{
-				if (getRemoteAddress() instanceof Inet6Address)
-				{
-					server.close();
-					return null;
-				}
-
-				if (!FTPReply.isPositiveCompletion(port(getHostAddress(),
-						server.getLocalPort())))
-				{
-					server.close();
-					return null;
-				}
-			}
-
-			if ((__restartOffset > 0) && !restart(__restartOffset))
-			{
-				server.close();
-				return null;
-			}
-
-			if (!FTPReply.isPositivePreliminary(sendCommand(command, arg)))
-			{
-				server.close();
-				return null;
-			}
-
-			// For now, let's just use the data timeout value for waiting for
-			// the data connection.  It may be desirable to let this be a
-			// separately configurable value.  In any case, we really want
-			// to allow preventing the accept from blocking indefinitely.
-			if (__dataTimeout >= 0)
-				server.setSoTimeout(__dataTimeout);
-			try {
-				socket = server.accept();
-			} finally {
-				server.close();
-			}
-		}
-		else
-		{ // We must be in PASSIVE_LOCAL_DATA_CONNECTION_MODE
-
-			// If we are over an IPv6 connection, try EPSV
-			if (getRemoteAddress() instanceof Inet6Address) {
-				if (epsv() != FTPReply.ENTERING_EPSV_MODE) 
-					return null;
-				__parseExtendedPassiveModeReply((String)_replyLines.get(0));
-			}
-			else {
-				if (pasv() != FTPReply.ENTERING_PASSIVE_MODE)
-					return null;
-				__parsePassiveModeReply((String)_replyLines.get(0));
-			}
-
-			socket = _socketFactory_.createSocket(__passiveHost, __passivePort);
-			if ((__restartOffset > 0) && !restart(__restartOffset))
-			{
-				socket.close();
-				return null;
-			}
-
-			if (!FTPReply.isPositivePreliminary(sendCommand(command, arg)))
-			{
-				socket.close();
-				return null;
-			}
-		}
-
-		if (__remoteVerificationEnabled && !verifyRemote(socket))
-		{
-			InetAddress host1, host2;
-
-			host1 = socket.getInetAddress();
-			host2 = getRemoteAddress();
-
-			socket.close();
-
-			throw new IOException(
-					"Host attempting data connection " + host1.getHostAddress() +
-					" is not same as server " + host2.getHostAddress());
-		}
-
-		if (__dataTimeout >= 0)
-			socket.setSoTimeout(__dataTimeout);
-
-		return socket;
-	}
-
-
-	@Override
-	protected void _connectAction_() throws IOException
-	{
-		super._connectAction_();
-		__initDefaults();
-	}
-
-
-	/***
-	 * Sets the timeout in milliseconds to use when reading from the
-	 * data connection.  This timeout will be set immediately after
-	 * opening the data connection.
-	 * <p>
-	 * @param  timeout The default timeout in milliseconds that is used when
-	 *        opening a data connection socket.
-	 ***/
-	public void setDataTimeout(int timeout)
-	{
-		__dataTimeout = timeout;
-	}
-
-	/**
-	 * set the factory used for parser creation to the supplied factory object.
-	 *
-	 * @param parserFactory
-	 *               factory object used to create FTPFileEntryParsers
-	 *
-	 * @see org.apache.commons.net.ftp.parser.FTPFileEntryParserFactory
-	 * @see org.apache.commons.net.ftp.parser.DefaultFTPFileEntryParserFactory
-	 */
-	public void setParserFactory(FTPFileEntryParserFactory parserFactory) {
-		__parserFactory = parserFactory;
-	}
-
-
-	/***
-	 * Closes the connection to the FTP server and restores
-	 * connection parameters to the default values.
-	 * <p>
-	 * @exception IOException If an error occurs while disconnecting.
-	 ***/
-	@Override
-	public void disconnect() throws IOException
-	{
-		super.disconnect();
-		__initDefaults();
-	}
-
-
-	/***
-	 * Enable or disable verification that the remote host taking part
-	 * of a data connection is the same as the host to which the control
-	 * connection is attached.  The default is for verification to be
-	 * enabled.  You may set this value at any time, whether the
-	 * FTPClient is currently connected or not.
-	 * <p>
-	 * @param enable True to enable verification, false to disable verification.
-	 ***/
-	public void setRemoteVerificationEnabled(boolean enable)
-	{
-		__remoteVerificationEnabled = enable;
-	}
-
-	/***
-	 * Return whether or not verification of the remote host participating
-	 * in data connections is enabled.  The default behavior is for
-	 * verification to be enabled.
-	 * <p>
-	 * @return True if verification is enabled, false if not.
-	 ***/
-	public boolean isRemoteVerificationEnabled()
-	{
-		return __remoteVerificationEnabled;
-	}
-
-	/***
-	 * Login to the FTP server using the provided username and password.
-	 * <p>
-	 * @param username The username to login under.
-	 * @param password The password to use.
-	 * @return True if successfully completed, false if not.
-	 * @exception FTPConnectionClosedException
-	 *      If the FTP server prematurely closes the connection as a result
-	 *      of the client being idle or some other reason causing the server
-	 *      to send FTP reply code 421.  This exception may be caught either
-	 *      as an IOException or independently as itself.
-	 * @exception IOException  If an I/O error occurs while either sending a
-	 *      command to the server or receiving a reply from the server.
-	 ***/
-	public boolean login(String username, String password) throws IOException
-	{
-
-		user(username);
-
-		if (FTPReply.isPositiveCompletion(_replyCode))
-			return true;
-
-		// If we get here, we either have an error code, or an intermmediate
-		// reply requesting password.
-		if (!FTPReply.isPositiveIntermediate(_replyCode))
-			return false;
-
-		return FTPReply.isPositiveCompletion(pass(password));
-	}
-
-
-	/***
-	 * Login to the FTP server using the provided username, password,
-	 * and account.  If no account is required by the server, only
-	 * the username and password, the account information is not used.
-	 * <p>
-	 * @param username The username to login under.
-	 * @param password The password to use.
-	 * @param account  The account to use.
-	 * @return True if successfully completed, false if not.
-	 * @exception FTPConnectionClosedException
-	 *      If the FTP server prematurely closes the connection as a result
-	 *      of the client being idle or some other reason causing the server
-	 *      to send FTP reply code 421.  This exception may be caught either
-	 *      as an IOException or independently as itself.
-	 * @exception IOException  If an I/O error occurs while either sending a
-	 *      command to the server or receiving a reply from the server.
-	 ***/
-	public boolean login(String username, String password, String account)
-	throws IOException
-	{
-		user(username);
-
-		if (FTPReply.isPositiveCompletion(_replyCode))
-			return true;
-
-		// If we get here, we either have an error code, or an intermmediate
-		// reply requesting password.
-		if (!FTPReply.isPositiveIntermediate(_replyCode))
-			return false;
-
-		pass(password);
-
-		if (FTPReply.isPositiveCompletion(_replyCode))
-			return true;
-
-		if (!FTPReply.isPositiveIntermediate(_replyCode))
-			return false;
-
-		return FTPReply.isPositiveCompletion(acct(account));
-	}
-
-	/***
-	 * Logout of the FTP server by sending the QUIT command.
-	 * <p>
-	 * @return True if successfully completed, false if not.
-	 * @exception FTPConnectionClosedException
-	 *      If the FTP server prematurely closes the connection as a result
-	 *      of the client being idle or some other reason causing the server
-	 *      to send FTP reply code 421.  This exception may be caught either
-	 *      as an IOException or independently as itself.
-	 * @exception IOException  If an I/O error occurs while either sending a
-	 *      command to the server or receiving a reply from the server.
-	 ***/
-	public boolean logout() throws IOException
-	{
-		return FTPReply.isPositiveCompletion(quit());
-	}
-
-
-	/***
-	 * Change the current working directory of the FTP session.
-	 * <p>
-	 * @param pathname  The new current working directory.
-	 * @return True if successfully completed, false if not.
-	 * @exception FTPConnectionClosedException
-	 *      If the FTP server prematurely closes the connection as a result
-	 *      of the client being idle or some other reason causing the server
-	 *      to send FTP reply code 421.  This exception may be caught either
-	 *      as an IOException or independently as itself.
-	 * @exception IOException  If an I/O error occurs while either sending a
-	 *      command to the server or receiving a reply from the server.
-	 ***/
-	public boolean changeWorkingDirectory(String pathname) throws IOException
-	{
-		return FTPReply.isPositiveCompletion(cwd(pathname));
-	}
-
-
-	/***
-	 * Change to the parent directory of the current working directory.
-	 * <p>
-	 * @return True if successfully completed, false if not.
-	 * @exception FTPConnectionClosedException
-	 *      If the FTP server prematurely closes the connection as a result
-	 *      of the client being idle or some other reason causing the server
-	 *      to send FTP reply code 421.  This exception may be caught either
-	 *      as an IOException or independently as itself.
-	 * @exception IOException  If an I/O error occurs while either sending a
-	 *      command to the server or receiving a reply from the server.
-	 ***/
-	public boolean changeToParentDirectory() throws IOException
-	{
-		return FTPReply.isPositiveCompletion(cdup());
-	}
-
-
-	/***
-	 * Issue the FTP SMNT command.
-	 * <p>
-	 * @param pathname The pathname to mount.
-	 * @return True if successfully completed, false if not.
-	 * @exception FTPConnectionClosedException
-	 *      If the FTP server prematurely closes the connection as a result
-	 *      of the client being idle or some other reason causing the server
-	 *      to send FTP reply code 421.  This exception may be caught either
-	 *      as an IOException or independently as itself.
-	 * @exception IOException  If an I/O error occurs while either sending a
-	 *      command to the server or receiving a reply from the server.
-	 ***/
-	public boolean structureMount(String pathname) throws IOException
-	{
-		return FTPReply.isPositiveCompletion(smnt(pathname));
-	}
-
-	/***
-	 * Reinitialize the FTP session.  Not all FTP servers support this
-	 * command, which issues the FTP REIN command.
-	 * <p>
-	 * @return True if successfully completed, false if not.
-	 * @exception FTPConnectionClosedException
-	 *      If the FTP server prematurely closes the connection as a result
-	 *      of the client being idle or some other reason causing the server
-	 *      to send FTP reply code 421.  This exception may be caught either
-	 *      as an IOException or independently as itself.
-	 * @exception IOException  If an I/O error occurs while either sending a
-	 *      command to the server or receiving a reply from the server.
-	 ***/
-	boolean reinitialize() throws IOException
-	{
-		rein();
-
-		if (FTPReply.isPositiveCompletion(_replyCode) ||
-				(FTPReply.isPositivePreliminary(_replyCode) &&
-						FTPReply.isPositiveCompletion(getReply())))
-		{
-
-			__initDefaults();
-
-			return true;
-		}
-
-		return false;
-	}
-
-
-	/***
-	 * Set the current data connection mode to
-	 * <code>ACTIVE_LOCAL_DATA_CONNECTION_MODE</code>.  No communication
-	 * with the FTP server is conducted, but this causes all future data
-	 * transfers to require the FTP server to connect to the client's
-	 * data port.  Additionally, to accommodate differences between socket
-	 * implementations on different platforms, this method causes the
-	 * client to issue a PORT command before every data transfer.
-	 ***/
-	public void enterLocalActiveMode()
-	{
-		__dataConnectionMode = ACTIVE_LOCAL_DATA_CONNECTION_MODE;
-		__passiveHost = null;
-		__passivePort = -1;
-	}
-
-
-	/***
-	 * Set the current data connection mode to
-	 * <code> PASSIVE_LOCAL_DATA_CONNECTION_MODE </code>.  Use this
-	 * method only for data transfers between the client and server.
-	 * This method causes a PASV command to be issued to the server
-	 * before the opening of every data connection, telling the server to
-	 * open a data port to which the client will connect to conduct
-	 * data transfers.  The FTPClient will stay in
-	 * <code> PASSIVE_LOCAL_DATA_CONNECTION_MODE </code> until the
-	 * mode is changed by calling some other method such as
-	 * {@link #enterLocalActiveMode  enterLocalActiveMode() }
-	 ***/
-	public void enterLocalPassiveMode()
-	{
-		__dataConnectionMode = PASSIVE_LOCAL_DATA_CONNECTION_MODE;
-		// These will be set when just before a data connection is opened
-		// in _openDataConnection_()
-		__passiveHost = null;
-		__passivePort = -1;
-	}
-
-
-	/***
-	 * Set the current data connection mode to
-	 * <code> ACTIVE_REMOTE_DATA_CONNECTION </code>.  Use this method only
-	 * for server to server data transfers.  This method issues a PORT
-	 * command to the server, indicating the other server and port to which
-	 * it should connect for data transfers.  You must call this method
-	 * before EVERY server to server transfer attempt.  The FTPClient will
-	 * NOT automatically continue to issue PORT commands.  You also
-	 * must remember to call
-	 * {@link #enterLocalActiveMode  enterLocalActiveMode() } if you
-	 * wish to return to the normal data connection mode.
-	 * <p>
-	 * @param host The passive mode server accepting connections for data
-	 *             transfers.
-	 * @param port The passive mode server's data port.
-	 * @return True if successfully completed, false if not.
-	 * @exception FTPConnectionClosedException
-	 *      If the FTP server prematurely closes the connection as a result
-	 *      of the client being idle or some other reason causing the server
-	 *      to send FTP reply code 421.  This exception may be caught either
-	 *      as an IOException or independently as itself.
-	 * @exception IOException  If an I/O error occurs while either sending a
-	 *      command to the server or receiving a reply from the server.
-	 ***/
-	public boolean enterRemoteActiveMode(InetAddress host, int port)
-	throws IOException
-	{
-		if (FTPReply.isPositiveCompletion(port(host, port)))
-		{
-			__dataConnectionMode = ACTIVE_REMOTE_DATA_CONNECTION_MODE;
-			__passiveHost = null;
-			__passivePort = -1;
-			return true;
-		}
-		return false;
-	}
-
-	/***
-	 * Set the current data connection mode to
-	 * <code> PASSIVE_REMOTE_DATA_CONNECTION_MODE </code>.  Use this
-	 * method only for server to server data transfers.
-	 * This method issues a PASV command to the server, telling it to
-	 * open a data port to which the active server will connect to conduct
-	 * data transfers.  You must call this method
-	 * before EVERY server to server transfer attempt.  The FTPClient will
-	 * NOT automatically continue to issue PASV commands.  You also
-	 * must remember to call
-	 * {@link #enterLocalActiveMode  enterLocalActiveMode() } if you
-	 * wish to return to the normal data connection mode.
-	 * <p>
-	 * @return True if successfully completed, false if not.
-	 * @exception FTPConnectionClosedException
-	 *      If the FTP server prematurely closes the connection as a result
-	 *      of the client being idle or some other reason causing the server
-	 *      to send FTP reply code 421.  This exception may be caught either
-	 *      as an IOException or independently as itself.
-	 * @exception IOException  If an I/O error occurs while either sending a
-	 *      command to the server or receiving a reply from the server.
-	 ***/
-	public boolean enterRemotePassiveMode() throws IOException
-	{
-		if (pasv() != FTPReply.ENTERING_PASSIVE_MODE)
-			return false;
-
-		__dataConnectionMode = PASSIVE_REMOTE_DATA_CONNECTION_MODE;
-		__parsePassiveModeReply(_replyLines.get(0));
-
-		return true;
-	}
-
-	/***
-	 * Returns the hostname or IP address (in the form of a string) returned
-	 * by the server when entering passive mode.  If not in passive mode,
-	 * returns null.  This method only returns a valid value AFTER a
-	 * data connection has been opened after a call to
-	 * {@link #enterLocalPassiveMode enterLocalPassiveMode()}.
-	 * This is because FTPClient sends a PASV command to the server only
-	 * just before opening a data connection, and not when you call
-	 * {@link #enterLocalPassiveMode enterLocalPassiveMode()}.
-	 * <p>
-	 * @return The passive host name if in passive mode, otherwise null.
-	 ***/
-	public String getPassiveHost()
-	{
-		return __passiveHost;
-	}
-
-	/***
-	 * If in passive mode, returns the data port of the passive host.
-	 * This method only returns a valid value AFTER a
-	 * data connection has been opened after a call to
-	 * {@link #enterLocalPassiveMode enterLocalPassiveMode()}.
-	 * This is because FTPClient sends a PASV command to the server only
-	 * just before opening a data connection, and not when you call
-	 * {@link #enterLocalPassiveMode enterLocalPassiveMode()}.
-	 * <p>
-	 * @return The data port of the passive server.  If not in passive
-	 *         mode, undefined.
-	 ***/
-	public int getPassivePort()
-	{
-		return __passivePort;
-	}
-
-
-	/***
-	 * Returns the current data connection mode (one of the
-	 * <code> _DATA_CONNECTION_MODE </code> constants.
-	 * <p>
-	 * @return The current data connection mode (one of the
-	 * <code> _DATA_CONNECTION_MODE </code> constants.
-	 ***/
-	public int getDataConnectionMode()
-	{
-		return __dataConnectionMode;
-	}
-
-	/**
-	 * Get the client port for active mode.
-	 * <p>
-	 * @return The client port for active mode.
-	 */
-	private int getActivePort()
-	{
-		if (__activeMinPort > 0 && __activeMaxPort > __activeMinPort)
-		{
-			// Get a random port between the min and max port range
-			return __random.nextInt(__activeMaxPort - __activeMinPort + 1) + __activeMinPort;
-		}
-		else
-		{
-			// default port
-			return 0;
-		}
-	}
-
-	/**
-	 * Get the host address for active mode.
-	 * <p> 
-	 * @return The host address for active mode.
-	 */
-	private InetAddress getHostAddress()
-	{
-		if (__activeExternalHost != null)
-		{
-			return __activeExternalHost;
-		}
-		else
-		{
-			// default local address
-			return getLocalAddress();
-		}
-	}
-
-	/***
-	 * Set the client side port range in active mode.
-	 * <p> 
-	 * @param minPort The lowest available port (inclusive).
-	 * @param maxPort The highest available port (inclusive).
-	 ***/
-	public void setActivePortRange(int minPort, int maxPort)
-	{
-		this.__activeMinPort = minPort;
-		this.__activeMaxPort = maxPort;
-	}
-
-	/***
-	 * Set the external IP address in active mode.
-	 * Useful when there are multiple network cards.
-	 * <p> 
-	 * @param ipAddress The external IP address of this machine.
-	 * @throws UnknownHostException
-	 ***/
-	public void setActiveExternalIPAddress(String ipAddress) throws UnknownHostException
-	{
-		this.__activeExternalHost = InetAddress.getByName(ipAddress);
-	}
-
-
-	/***
-	 * Sets the file type to be transferred.  This should be one of
-	 * <code> FTP.ASCII_FILE_TYPE </code>, <code> FTP.BINARY_FILE_TYPE</code>,
-	 * etc.  The file type only needs to be set when you want to change the
-	 * type.  After changing it, the new type stays in effect until you change
-	 * it again.  The default file type is <code> FTP.ASCII_FILE_TYPE </code>
-	 * if this method is never called.
-	 * <p>
-	 * @param fileType The <code> _FILE_TYPE </code> constant indcating the
-	 *                 type of file.
-	 * @return True if successfully completed, false if not.
-	 * @exception FTPConnectionClosedException
-	 *      If the FTP server prematurely closes the connection as a result
-	 *      of the client being idle or some other reason causing the server
-	 *      to send FTP reply code 421.  This exception may be caught either
-	 *      as an IOException or independently as itself.
-	 * @exception IOException  If an I/O error occurs while either sending a
-	 *      command to the server or receiving a reply from the server.
-	 ***/
-	public boolean setFileType(int fileType) throws IOException
-	{
-		if (FTPReply.isPositiveCompletion(type(fileType)))
-		{
-			__fileType = fileType;
-			__fileFormat = FTP.NON_PRINT_TEXT_FORMAT;
-			return true;
-		}
-		return false;
-	}
-
-
-	/***
-	 * Sets the file type to be transferred and the format.  The type should be
-	 * one of  <code> FTP.ASCII_FILE_TYPE </code>,
-	 * <code> FTP.BINARY_FILE_TYPE </code>, etc.  The file type only needs to
-	 * be set when you want to change the type.  After changing it, the new
-	 * type stays in effect until you change it again.  The default file type
-	 * is <code> FTP.ASCII_FILE_TYPE </code> if this method is never called.
-	 * The format should be one of the FTP class <code> TEXT_FORMAT </code>
-	 * constants, or if the type is <code> FTP.LOCAL_FILE_TYPE </code>, the
-	 * format should be the byte size for that type.  The default format
-	 * is <code> FTP.NON_PRINT_TEXT_FORMAT </code> if this method is never
-	 * called.
-	 * <p>
-	 * @param fileType The <code> _FILE_TYPE </code> constant indcating the
-	 *                 type of file.
-	 * @param formatOrByteSize  The format of the file (one of the
-	 *              <code>_FORMAT</code> constants.  In the case of
-	 *              <code>LOCAL_FILE_TYPE</code>, the byte size.
-	 * <p>
-	 * @return True if successfully completed, false if not.
-	 * @exception FTPConnectionClosedException
-	 *      If the FTP server prematurely closes the connection as a result
-	 *      of the client being idle or some other reason causing the server
-	 *      to send FTP reply code 421.  This exception may be caught either
-	 *      as an IOException or independently as itself.
-	 * @exception IOException  If an I/O error occurs while either sending a
-	 *      command to the server or receiving a reply from the server.
-	 ***/
-	public boolean setFileType(int fileType, int formatOrByteSize)
-	throws IOException
-	{
-		if (FTPReply.isPositiveCompletion(type(fileType, formatOrByteSize)))
-		{
-			__fileType = fileType;
-			__fileFormat = formatOrByteSize;
-			return true;
-		}
-		return false;
-	}
-
-
-	/***
-	 * Sets the file structure.  The default structure is
-	 * <code> FTP.FILE_STRUCTURE </code> if this method is never called.
-	 * <p>
-	 * @param structure  The structure of the file (one of the FTP class
-	 *         <code>_STRUCTURE</code> constants).
-	 * @return True if successfully completed, false if not.
-	 * @exception FTPConnectionClosedException
-	 *      If the FTP server prematurely closes the connection as a result
-	 *      of the client being idle or some other reason causing the server
-	 *      to send FTP reply code 421.  This exception may be caught either
-	 *      as an IOException or independently as itself.
-	 * @exception IOException  If an I/O error occurs while either sending a
-	 *      command to the server or receiving a reply from the server.
-	 ***/
-	public boolean setFileStructure(int structure) throws IOException
-	{
-		if (FTPReply.isPositiveCompletion(stru(structure)))
-		{
-			__fileStructure = structure;
-			return true;
-		}
-		return false;
-	}
-
-
-	/***
-	 * Sets the transfer mode.  The default transfer mode
-	 * <code> FTP.STREAM_TRANSFER_MODE </code> if this method is never called.
-	 * <p>
-	 * @param mode  The new transfer mode to use (one of the FTP class
-	 *         <code>_TRANSFER_MODE</code> constants).
-	 * @return True if successfully completed, false if not.
-	 * @exception FTPConnectionClosedException
-	 *      If the FTP server prematurely closes the connection as a result
-	 *      of the client being idle or some other reason causing the server
-	 *      to send FTP reply code 421.  This exception may be caught either
-	 *      as an IOException or independently as itself.
-	 * @exception IOException  If an I/O error occurs while either sending a
-	 *      command to the server or receiving a reply from the server.
-	 ***/
-	public boolean setFileTransferMode(int mode) throws IOException
-	{
-		if (FTPReply.isPositiveCompletion(mode(mode)))
-		{
-			__fileTransferMode = mode;
-			return true;
-		}
-		return false;
-	}
-
-
-	/***
-	 * Initiate a server to server file transfer.  This method tells the
-	 * server to which the client is connected to retrieve a given file from
-	 * the other server.
-	 * <p>
-	 * @param filename  The name of the file to retrieve.
-	 * @return True if successfully completed, false if not.
-	 * @exception FTPConnectionClosedException
-	 *      If the FTP server prematurely closes the connection as a result
-	 *      of the client being idle or some other reason causing the server
-	 *      to send FTP reply code 421.  This exception may be caught either
-	 *      as an IOException or independently as itself.
-	 * @exception IOException  If an I/O error occurs while either sending a
-	 *      command to the server or receiving a reply from the server.
-	 ***/
-	public boolean remoteRetrieve(String filename) throws IOException
-	{
-		if (__dataConnectionMode == ACTIVE_REMOTE_DATA_CONNECTION_MODE ||
-				__dataConnectionMode == PASSIVE_REMOTE_DATA_CONNECTION_MODE)
-			return FTPReply.isPositivePreliminary(retr(filename));
-		return false;
-	}
-
-
-	/***
-	 * Initiate a server to server file transfer.  This method tells the
-	 * server to which the client is connected to store a file on
-	 * the other server using the given filename.  The other server must
-	 * have had a <code> remoteRetrieve </code> issued to it by another
-	 * FTPClient.
-	 * <p>
-	 * @param filename  The name to call the file that is to be stored.
-	 * @return True if successfully completed, false if not.
-	 * @exception FTPConnectionClosedException
-	 *      If the FTP server prematurely closes the connection as a result
-	 *      of the client being idle or some other reason causing the server
-	 *      to send FTP reply code 421.  This exception may be caught either
-	 *      as an IOException or independently as itself.
-	 * @exception IOException  If an I/O error occurs while either sending a
-	 *      command to the server or receiving a reply from the server.
-	 ***/
-	public boolean remoteStore(String filename) throws IOException
-	{
-		if (__dataConnectionMode == ACTIVE_REMOTE_DATA_CONNECTION_MODE ||
-				__dataConnectionMode == PASSIVE_REMOTE_DATA_CONNECTION_MODE)
-			return FTPReply.isPositivePreliminary(stor(filename));
-		return false;
-	}
-
-
-	/***
-	 * Initiate a server to server file transfer.  This method tells the
-	 * server to which the client is connected to store a file on
-	 * the other server using a unique filename based on the given filename.
-	 * The other server must have had a <code> remoteRetrieve </code> issued
-	 * to it by another FTPClient.
-	 * <p>
-	 * @param filename  The name on which to base the filename of the file
-	 *                  that is to be stored.
-	 * @return True if successfully completed, false if not.
-	 * @exception FTPConnectionClosedException
-	 *      If the FTP server prematurely closes the connection as a result
-	 *      of the client being idle or some other reason causing the server
-	 *      to send FTP reply code 421.  This exception may be caught either
-	 *      as an IOException or independently as itself.
-	 * @exception IOException  If an I/O error occurs while either sending a
-	 *      command to the server or receiving a reply from the server.
-	 ***/
-	public boolean remoteStoreUnique(String filename) throws IOException
-	{
-		if (__dataConnectionMode == ACTIVE_REMOTE_DATA_CONNECTION_MODE ||
-				__dataConnectionMode == PASSIVE_REMOTE_DATA_CONNECTION_MODE)
-			return FTPReply.isPositivePreliminary(stou(filename));
-		return false;
-	}
-
-
-	/***
-	 * Initiate a server to server file transfer.  This method tells the
-	 * server to which the client is connected to store a file on
-	 * the other server using a unique filename.
-	 * The other server must have had a <code> remoteRetrieve </code> issued
-	 * to it by another FTPClient.  Many FTP servers require that a base
-	 * filename be given from which the unique filename can be derived.  For
-	 * those servers use the other version of <code> remoteStoreUnique</code>
-	 * <p>
-	 * @return True if successfully completed, false if not.
-	 * @exception FTPConnectionClosedException
-	 *      If the FTP server prematurely closes the connection as a result
-	 *      of the client being idle or some other reason causing the server
-	 *      to send FTP reply code 421.  This exception may be caught either
-	 *      as an IOException or independently as itself.
-	 * @exception IOException  If an I/O error occurs while either sending a
-	 *      command to the server or receiving a reply from the server.
-	 ***/
-	public boolean remoteStoreUnique() throws IOException
-	{
-		if (__dataConnectionMode == ACTIVE_REMOTE_DATA_CONNECTION_MODE ||
-				__dataConnectionMode == PASSIVE_REMOTE_DATA_CONNECTION_MODE)
-			return FTPReply.isPositivePreliminary(stou());
-		return false;
-	}
-
-	// For server to server transfers
-	/***
-	 * Initiate a server to server file transfer.  This method tells the
-	 * server to which the client is connected to append to a given file on
-	 * the other server.  The other server must have had a
-	 * <code> remoteRetrieve </code> issued to it by another FTPClient.
-	 * <p>
-	 * @param filename  The name of the file to be appended to, or if the
-	 *        file does not exist, the name to call the file being stored.
-	 * <p>
-	 * @return True if successfully completed, false if not.
-	 * @exception FTPConnectionClosedException
-	 *      If the FTP server prematurely closes the connection as a result
-	 *      of the client being idle or some other reason causing the server
-	 *      to send FTP reply code 421.  This exception may be caught either
-	 *      as an IOException or independently as itself.
-	 * @exception IOException  If an I/O error occurs while either sending a
-	 *      command to the server or receiving a reply from the server.
-	 ***/
-	public boolean remoteAppend(String filename) throws IOException
-	{
-		if (__dataConnectionMode == ACTIVE_REMOTE_DATA_CONNECTION_MODE ||
-				__dataConnectionMode == PASSIVE_REMOTE_DATA_CONNECTION_MODE)
-			return FTPReply.isPositivePreliminary(stor(filename));
-		return false;
-	}
-
-	/***
-	 * There are a few FTPClient methods that do not complete the
-	 * entire sequence of FTP commands to complete a transaction.  These
-	 * commands require some action by the programmer after the reception
-	 * of a positive intermediate command.  After the programmer's code
-	 * completes its actions, it must call this method to receive
-	 * the completion reply from the server and verify the success of the
-	 * entire transaction.
-	 * <p>
-	 * For example,
-	 * <pre>
-	 * InputStream input;
-	 * OutputStream output;
-	 * input  = new FileInputStream("foobaz.txt");
-	 * output = ftp.storeFileStream("foobar.txt")
-	 * if(!FTPReply.isPositiveIntermediate(ftp.getReplyCode())) {
-	 *     input.close();
-	 *     output.close();
-	 *     ftp.logout();
-	 *     ftp.disconnect();
-	 *     System.err.println("File transfer failed.");
-	 *     System.exit(1);
-	 * }
-	 * Util.copyStream(input, output);
-	 * input.close();
-	 * output.close();
-	 * // Must call completePendingCommand() to finish command.
-	 * if(!ftp.completePendingCommand()) {
-	 *     ftp.logout();
-	 *     ftp.disconnect();
-	 *     System.err.println("File transfer failed.");
-	 *     System.exit(1);
-	 * }
-	 * </pre>
-	 * <p>
-	 * @return True if successfully completed, false if not.
-	 * @exception FTPConnectionClosedException
-	 *      If the FTP server prematurely closes the connection as a result
-	 *      of the client being idle or some other reason causing the server
-	 *      to send FTP reply code 421.  This exception may be caught either
-	 *      as an IOException or independently as itself.
-	 * @exception IOException  If an I/O error occurs while either sending a
-	 *      command to the server or receiving a reply from the server.
-	 ***/
-	public boolean completePendingCommand() throws IOException
-	{
-		return FTPReply.isPositiveCompletion(getReply());
-	}
-
-
-	/***
-	 * Retrieves a named file from the server and writes it to the given
-	 * OutputStream.  This method does NOT close the given OutputStream.
-	 * If the current file type is ASCII, line separators in the file are
-	 * converted to the local representation.
-	 * <p>
-	 * @param remote  The name of the remote file.
-	 * @param local   The local OutputStream to which to write the file.
-	 * @return True if successfully completed, false if not.
-	 * @exception FTPConnectionClosedException
-	 *      If the FTP server prematurely closes the connection as a result
-	 *      of the client being idle or some other reason causing the server
-	 *      to send FTP reply code 421.  This exception may be caught either
-	 *      as an IOException or independently as itself.
-	 * @exception CopyStreamException  If an I/O error occurs while actually
-	 *      transferring the file.  The CopyStreamException allows you to
-	 *      determine the number of bytes transferred and the IOException
-	 *      causing the error.  This exception may be caught either
-	 *      as an IOException or independently as itself.
-	 * @exception IOException  If an I/O error occurs while either sending a
-	 *      command to the server or receiving a reply from the server.
-	 ***/
-	public boolean retrieveFile(String remote, OutputStream local)
-	throws IOException
-	{
-		InputStream input;
-		Socket socket;
-
-		if ((socket = _openDataConnection_(FTPCommand.RETR, remote)) == null)
-			return false;
-
-		input = new BufferedInputStream(socket.getInputStream(),
-				getBufferSize());
-		if (__fileType == ASCII_FILE_TYPE)
-			input = new FromNetASCIIInputStream(input);
-		// Treat everything else as binary for now
-		try
-		{
-			Util.copyStream(input, local, getBufferSize(),
-					CopyStreamEvent.UNKNOWN_STREAM_SIZE, null,
-					false);
-		}
-		catch (IOException e)
-		{
-			try
-			{
-				socket.close();
-			}
-			catch (IOException f)
-			{}
-			throw e;
-		}
-		socket.close();
-		return completePendingCommand();
-	}
-
-	/***
-	 * Returns an InputStream from which a named file from the server
-	 * can be read.  If the current file type is ASCII, the returned
-	 * InputStream will convert line separators in the file to
-	 * the local representation.  You must close the InputStream when you
-	 * finish reading from it.  The InputStream itself will take care of
-	 * closing the parent data connection socket upon being closed.  To
-	 * finalize the file transfer you must call
-	 * {@link #completePendingCommand  completePendingCommand } and
-	 * check its return value to verify success.
-	 * <p>
-	 * @param remote  The name of the remote file.
-	 * @return An InputStream from which the remote file can be read.  If
-	 *      the data connection cannot be opened (e.g., the file does not
-	 *      exist), null is returned (in which case you may check the reply
-	 *      code to determine the exact reason for failure).
-	 * @exception FTPConnectionClosedException
-	 *      If the FTP server prematurely closes the connection as a result
-	 *      of the client being idle or some other reason causing the server
-	 *      to send FTP reply code 421.  This exception may be caught either
-	 *      as an IOException or independently as itself.
-	 * @exception IOException  If an I/O error occurs while either sending a
-	 *      command to the server or receiving a reply from the server.
-	 ***/
-	public InputStream retrieveFileStream(String remote) throws IOException
-	{
-		InputStream input;
-		Socket socket;
-
-		if ((socket = _openDataConnection_(FTPCommand.RETR, remote)) == null)
-			return null;
-
-		input = socket.getInputStream();
-		if (__fileType == ASCII_FILE_TYPE) {
-			// We buffer ascii transfers because the buffering has to
-			// be interposed between FromNetASCIIOutputSream and the underlying
-			// socket input stream.  We don't buffer binary transfers
-			// because we don't want to impose a buffering policy on the
-			// programmer if possible.  Programmers can decide on their
-			// own if they want to wrap the SocketInputStream we return
-			// for file types other than ASCII.
-			input = new BufferedInputStream(input,
-					getBufferSize());
-			input = new FromNetASCIIInputStream(input);
-		}
-		return new org.apache.commons.net.io.SocketInputStream(socket, input);
-	}
-
-
-	/***
-	 * Stores a file on the server using the given name and taking input
-	 * from the given InputStream.  This method does NOT close the given
-	 * InputStream.  If the current file type is ASCII, line separators in
-	 * the file are transparently converted to the NETASCII format (i.e.,
-	 * you should not attempt to create a special InputStream to do this).
-	 * <p>
-	 * @param remote  The name to give the remote file.
-	 * @param local   The local InputStream from which to read the file.
-	 * @return True if successfully completed, false if not.
-	 * @exception FTPConnectionClosedException
-	 *      If the FTP server prematurely closes the connection as a result
-	 *      of the client being idle or some other reason causing the server
-	 *      to send FTP reply code 421.  This exception may be caught either
-	 *      as an IOException or independently as itself.
-	 * @exception CopyStreamException  If an I/O error occurs while actually
-	 *      transferring the file.  The CopyStreamException allows you to
-	 *      determine the number of bytes transferred and the IOException
-	 *      causing the error.  This exception may be caught either
-	 *      as an IOException or independently as itself.
-	 * @exception IOException  If an I/O error occurs while either sending a
-	 *      command to the server or receiving a reply from the server.
-	 ***/
-	public boolean storeFile(String remote, InputStream local)
-	throws IOException
-	{
-		return __storeFile(FTPCommand.STOR, remote, local);
-	}
-
-
-	/***
-	 * Returns an OutputStream through which data can be written to store
-	 * a file on the server using the given name.  If the current file type
-	 * is ASCII, the returned OutputStream will convert line separators in
-	 * the file to the NETASCII format  (i.e., you should not attempt to
-	 * create a special OutputStream to do this).  You must close the
-	 * OutputStream when you finish writing to it.  The OutputStream itself
-	 * will take care of closing the parent data connection socket upon being
-	 * closed.  To finalize the file transfer you must call
-	 * {@link #completePendingCommand  completePendingCommand } and
-	 * check its return value to verify success.
-	 * <p>
-	 * @param remote  The name to give the remote file.
-	 * @return An OutputStream through which the remote file can be written.  If
-	 *      the data connection cannot be opened (e.g., the file does not
-	 *      exist), null is returned (in which case you may check the reply
-	 *      code to determine the exact reason for failure).
-	 * @exception FTPConnectionClosedException
-	 *      If the FTP server prematurely closes the connection as a result
-	 *      of the client being idle or some other reason causing the server
-	 *      to send FTP reply code 421.  This exception may be caught either
-	 *      as an IOException or independently as itself.
-	 * @exception IOException  If an I/O error occurs while either sending a
-	 *      command to the server or receiving a reply from the server.
-	 ***/
-	public OutputStream storeFileStream(String remote) throws IOException
-	{
-		return __storeFileStream(FTPCommand.STOR, remote);
-	}
-
-	/***
-	 * Appends to a file on the server with the given name, taking input
-	 * from the given InputStream.  This method does NOT close the given
-	 * InputStream.  If the current file type is ASCII, line separators in
-	 * the file are transparently converted to the NETASCII format (i.e.,
-	 * you should not attempt to create a special InputStream to do this).
-	 * <p>
-	 * @param remote  The name of the remote file.
-	 * @param local   The local InputStream from which to read the data to
-	 *                be appended to the remote file.
-	 * @return True if successfully completed, false if not.
-	 * @exception FTPConnectionClosedException
-	 *      If the FTP server prematurely closes the connection as a result
-	 *      of the client being idle or some other reason causing the server
-	 *      to send FTP reply code 421.  This exception may be caught either
-	 *      as an IOException or independently as itself.
-	 * @exception CopyStreamException  If an I/O error occurs while actually
-	 *      transferring the file.  The CopyStreamException allows you to
-	 *      determine the number of bytes transferred and the IOException
-	 *      causing the error.  This exception may be caught either
-	 *      as an IOException or independently as itself.
-	 * @exception IOException  If an I/O error occurs while either sending a
-	 *      command to the server or receiving a reply from the server.
-	 ***/
-	public boolean appendFile(String remote, InputStream local)
-	throws IOException
-	{
-		return __storeFile(FTPCommand.APPE, remote, local);
-	}
-
-	/***
-	 * Returns an OutputStream through which data can be written to append
-	 * to a file on the server with the given name.  If the current file type
-	 * is ASCII, the returned OutputStream will convert line separators in
-	 * the file to the NETASCII format  (i.e., you should not attempt to
-	 * create a special OutputStream to do this).  You must close the
-	 * OutputStream when you finish writing to it.  The OutputStream itself
-	 * will take care of closing the parent data connection socket upon being
-	 * closed.  To finalize the file transfer you must call
-	 * {@link #completePendingCommand  completePendingCommand } and
-	 * check its return value to verify success.
-	 * <p>
-	 * @param remote  The name of the remote file.
-	 * @return An OutputStream through which the remote file can be appended.
-	 *      If the data connection cannot be opened (e.g., the file does not
-	 *      exist), null is returned (in which case you may check the reply
-	 *      code to determine the exact reason for failure).
-	 * @exception FTPConnectionClosedException
-	 *      If the FTP server prematurely closes the connection as a result
-	 *      of the client being idle or some other reason causing the server
-	 *      to send FTP reply code 421.  This exception may be caught either
-	 *      as an IOException or independently as itself.
-	 * @exception IOException  If an I/O error occurs while either sending a
-	 *      command to the server or receiving a reply from the server.
-	 ***/
-	public OutputStream appendFileStream(String remote) throws IOException
-	{
-		return __storeFileStream(FTPCommand.APPE, remote);
-	}
-
-	/***
-	 * Stores a file on the server using a unique name derived from the
-	 * given name and taking input
-	 * from the given InputStream.  This method does NOT close the given
-	 * InputStream.  If the current file type is ASCII, line separators in
-	 * the file are transparently converted to the NETASCII format (i.e.,
-	 * you should not attempt to create a special InputStream to do this).
-	 * <p>
-	 * @param remote  The name on which to base the unique name given to
-	 *                the remote file.
-	 * @param local   The local InputStream from which to read the file.
-	 * @return True if successfully completed, false if not.
-	 * @exception FTPConnectionClosedException
-	 *      If the FTP server prematurely closes the connection as a result
-	 *      of the client being idle or some other reason causing the server
-	 *      to send FTP reply code 421.  This exception may be caught either
-	 *      as an IOException or independently as itself.
-	 * @exception CopyStreamException  If an I/O error occurs while actually
-	 *      transferring the file.  The CopyStreamException allows you to
-	 *      determine the number of bytes transferred and the IOException
-	 *      causing the error.  This exception may be caught either
-	 *      as an IOException or independently as itself.
-	 * @exception IOException  If an I/O error occurs while either sending a
-	 *      command to the server or receiving a reply from the server.
-	 ***/
-	public boolean storeUniqueFile(String remote, InputStream local)
-	throws IOException
-	{
-		return __storeFile(FTPCommand.STOU, remote, local);
-	}
-
-
-	/***
-	 * Returns an OutputStream through which data can be written to store
-	 * a file on the server using a unique name derived from the given name.
-	 * If the current file type
-	 * is ASCII, the returned OutputStream will convert line separators in
-	 * the file to the NETASCII format  (i.e., you should not attempt to
-	 * create a special OutputStream to do this).  You must close the
-	 * OutputStream when you finish writing to it.  The OutputStream itself
-	 * will take care of closing the parent data connection socket upon being
-	 * closed.  To finalize the file transfer you must call
-	 * {@link #completePendingCommand  completePendingCommand } and
-	 * check its return value to verify success.
-	 * <p>
-	 * @param remote  The name on which to base the unique name given to
-	 *                the remote file.
-	 * @return An OutputStream through which the remote file can be written.  If
-	 *      the data connection cannot be opened (e.g., the file does not
-	 *      exist), null is returned (in which case you may check the reply
-	 *      code to determine the exact reason for failure).
-	 * @exception FTPConnectionClosedException
-	 *      If the FTP server prematurely closes the connection as a result
-	 *      of the client being idle or some other reason causing the server
-	 *      to send FTP reply code 421.  This exception may be caught either
-	 *      as an IOException or independently as itself.
-	 * @exception IOException  If an I/O error occurs while either sending a
-	 *      command to the server or receiving a reply from the server.
-	 ***/
-	public OutputStream storeUniqueFileStream(String remote) throws IOException
-	{
-		return __storeFileStream(FTPCommand.STOU, remote);
-	}
-
-	/**
-	 * Stores a file on the server using a unique name assigned by the
-	 * server and taking input from the given InputStream.  This method does
-	 * NOT close the given
-	 * InputStream.  If the current file type is ASCII, line separators in
-	 * the file are transparently converted to the NETASCII format (i.e.,
-	 * you should not attempt to create a special InputStream to do this).
-	 * <p>
-	 * @param local   The local InputStream from which to read the file.
-	 * @return True if successfully completed, false if not.
-	 * @exception FTPConnectionClosedException
-	 *      If the FTP server prematurely closes the connection as a result
-	 *      of the client being idle or some other reason causing the server
-	 *      to send FTP reply code 421.  This exception may be caught either
-	 *      as an IOException or independently as itself.
-	 * @exception CopyStreamException  If an I/O error occurs while actually
-	 *      transferring the file.  The CopyStreamException allows you to
-	 *      determine the number of bytes transferred and the IOException
-	 *      causing the error.  This exception may be caught either
-	 *      as an IOException or independently as itself.
-	 * @exception IOException  If an I/O error occurs while either sending a
-	 *      command to the server or receiving a reply from the server.
-	 */
-	public boolean storeUniqueFile(InputStream local) throws IOException
-	{
-		return __storeFile(FTPCommand.STOU, null, local);
-	}
-
-	/**
-	 * Returns an OutputStream through which data can be written to store
-	 * a file on the server using a unique name assigned by the server.
-	 * If the current file type
-	 * is ASCII, the returned OutputStream will convert line separators in
-	 * the file to the NETASCII format  (i.e., you should not attempt to
-	 * create a special OutputStream to do this).  You must close the
-	 * OutputStream when you finish writing to it.  The OutputStream itself
-	 * will take care of closing the parent data connection socket upon being
-	 * closed.  To finalize the file transfer you must call
-	 * {@link #completePendingCommand  completePendingCommand } and
-	 * check its return value to verify success.
-	 * <p>
-	 * @return An OutputStream through which the remote file can be written.  If
-	 *      the data connection cannot be opened (e.g., the file does not
-	 *      exist), null is returned (in which case you may check the reply
-	 *      code to determine the exact reason for failure).
-	 * @exception FTPConnectionClosedException
-	 *      If the FTP server prematurely closes the connection as a result
-	 *      of the client being idle or some other reason causing the server
-	 *      to send FTP reply code 421.  This exception may be caught either
-	 *      as an IOException or independently as itself.
-	 * @exception IOException  If an I/O error occurs while either sending a
-	 *      command to the server or receiving a reply from the server.
-	 */
-	public OutputStream storeUniqueFileStream() throws IOException
-	{
-		return __storeFileStream(FTPCommand.STOU, null);
-	}
-
-	/***
-	 * Reserve a number of bytes on the server for the next file transfer.
-	 * <p>
-	 * @param bytes  The number of bytes which the server should allocate.
-	 * @return True if successfully completed, false if not.
-	 * @exception FTPConnectionClosedException
-	 *      If the FTP server prematurely closes the connection as a result
-	 *      of the client being idle or some other reason causing the server
-	 *      to send FTP reply code 421.  This exception may be caught either
-	 *      as an IOException or independently as itself.
-	 * @exception IOException  If an I/O error occurs while either sending a
-	 *      command to the server or receiving a reply from the server.
-	 ***/
-	public boolean allocate(int bytes) throws IOException
-	{
-		return FTPReply.isPositiveCompletion(allo(bytes));
-	}
-
-	/**
-	 * Query the server for supported features. The server may reply with a list of server-supported exensions.
-	 * For example, a typical client-server interaction might be (from RFC 	2289):
-	 * <pre>
+    /***
+     * A constant indicating the FTP session is expecting all transfers
+     * to occur between the client (local) and server and that the server
+     * should connect to the client's data port to initiate a data transfer.
+     * This is the default data connection mode when and FTPClient instance
+     * is created.
+     ***/
+    public static final int ACTIVE_LOCAL_DATA_CONNECTION_MODE = 0;
+    /***
+     * A constant indicating the FTP session is expecting all transfers
+     * to occur between two remote servers and that the server
+     * the client is connected to should connect to the other server's
+     * data port to initiate a data transfer.
+     ***/
+    public static final int ACTIVE_REMOTE_DATA_CONNECTION_MODE = 1;
+    /***
+     * A constant indicating the FTP session is expecting all transfers
+     * to occur between the client (local) and server and that the server
+     * is in passive mode, requiring the client to connect to the
+     * server's data port to initiate a transfer.
+     ***/
+    public static final int PASSIVE_LOCAL_DATA_CONNECTION_MODE = 2;
+    /***
+     * A constant indicating the FTP session is expecting all transfers
+     * to occur between two remote servers and that the server
+     * the client is connected to is in passive mode, requiring the other
+     * server to connect to the first server's data port to initiate a data
+     * transfer.
+     ***/
+    public static final int PASSIVE_REMOTE_DATA_CONNECTION_MODE = 3;
+
+    private int __dataConnectionMode, __dataTimeout;
+    private int __passivePort;
+    private String __passiveHost;
+    private Random __random;
+    private int __activeMinPort, __activeMaxPort;
+    private InetAddress __activeExternalHost;
+    private int __fileType, __fileFormat, __fileStructure, __fileTransferMode;
+    private boolean __remoteVerificationEnabled;
+    private long __restartOffset;
+    private FTPFileEntryParserFactory __parserFactory;
+    private int __bufferSize;
+    private boolean __listHiddenFiles;
+
+    // __systemName is a cached value that should not be referenced directly
+    // except when assigned in getSystemName and __initDefaults.
+    private String __systemName;
+
+    // __entryParser is a cached value that should not be referenced directly
+    // except when assigned in listFiles(String, String) and __initDefaults.
+    private FTPFileEntryParser __entryParser;
+
+    private FTPClientConfig __configuration;
+
+    /** Pattern for PASV mode responses */
+    private static final String __parms = "\\d{1,3},\\d{1,3},\\d{1,3},\\d{1,3},\\d{1,3},\\d{1,3}";
+    private static final java.util.regex.Pattern __parms_pat;
+    static {
+        __parms_pat = java.util.regex.Pattern.compile(__parms);
+    }
+
+    /***
+     * Default FTPClient constructor.  Creates a new FTPClient instance
+     * with the data connection mode set to
+     * <code> ACTIVE_LOCAL_DATA_CONNECTION_MODE </code>, the file type
+     * set to <code> FTP.ASCII_FILE_TYPE </code>, the
+     * file format set to <code> FTP.NON_PRINT_TEXT_FORMAT </code>,
+     * the file structure set to <code> FTP.FILE_STRUCTURE </code>, and
+     * the transfer mode set to <code> FTP.STREAM_TRANSFER_MODE </code>.
+     ***/
+    public FTPClient()
+    {
+        __initDefaults();
+        __dataTimeout = -1;
+        __remoteVerificationEnabled = true;
+        __parserFactory = new DefaultFTPFileEntryParserFactory();
+        __configuration      = null;
+        __listHiddenFiles = false;
+        __random = new Random();
+    }
+
+
+    private void __initDefaults()
+    {
+        __dataConnectionMode = ACTIVE_LOCAL_DATA_CONNECTION_MODE;
+        __passiveHost        = null;
+        __passivePort        = -1;
+        __activeExternalHost = null;
+        __activeMinPort = 0;
+        __activeMaxPort = 0;
+        __fileType           = FTP.ASCII_FILE_TYPE;
+        __fileStructure      = FTP.FILE_STRUCTURE;
+        __fileFormat         = FTP.NON_PRINT_TEXT_FORMAT;
+        __fileTransferMode   = FTP.STREAM_TRANSFER_MODE;
+        __restartOffset      = 0;
+        __systemName         = null;
+        __entryParser        = null;
+        __bufferSize         = Util.DEFAULT_COPY_BUFFER_SIZE;
+    }
+
+    private String __parsePathname(String reply)
+    {
+        int begin, end;
+
+        begin = reply.indexOf('"') + 1;
+        end = reply.indexOf('"', begin);
+
+        return reply.substring(begin, end);
+    }
+
+
+    private void __parsePassiveModeReply(String reply)
+    throws MalformedServerReplyException
+    {
+        java.util.regex.Matcher m = __parms_pat.matcher(reply);
+        if (!m.find()) {
+            throw new MalformedServerReplyException(
+                    "Could not parse passive host information.\nServer Reply: " + reply);
+        }
+        reply = m.group();
+        String parts[] = m.group().split(",");
+
+        __passiveHost = parts[0] + '.' + parts[1] + '.' + parts[2] + '.' + parts[3];
+
+        try
+        {
+            int oct1 = Integer.parseInt(parts[4]);
+            int oct2 = Integer.parseInt(parts[5]);
+            __passivePort = (oct1 << 8) | oct2;
+        }
+        catch (NumberFormatException e)
+        {
+            throw new MalformedServerReplyException(
+                    "Could not parse passive host information.\nServer Reply: " + reply);
+        }
+
+    }
+
+    private void __parseExtendedPassiveModeReply(String reply)
+    throws MalformedServerReplyException
+    {
+        int port;
+
+        reply = reply.substring(reply.indexOf('(') + 1,
+                reply.indexOf(')')).trim();
+
+        char delim1, delim2, delim3, delim4;
+        delim1 = reply.charAt(0);
+        delim2 = reply.charAt(1);
+        delim3 = reply.charAt(2);
+        delim4 = reply.charAt(reply.length()-1);
+
+        if (!(delim1 == delim2) || !(delim2 == delim3)
+                || !(delim3 == delim4))
+            throw new MalformedServerReplyException(
+                    "Could not parse extended passive host information.\nServer Reply: " + reply);
+        try
+        {
+            port = Integer.parseInt(reply.substring(3, reply.length()-1));
+        }
+        catch (NumberFormatException e)
+        {
+            throw new MalformedServerReplyException(
+                    "Could not parse extended passive host information.\nServer Reply: " + reply);
+        }
+
+
+        // in EPSV mode, the passive host address is implicit
+        __passiveHost = getRemoteAddress().getHostAddress();
+        __passivePort = port;
+    }
+
+    private boolean __storeFile(int command, String remote, InputStream local)
+    throws IOException
+    {
+        OutputStream output;
+        Socket socket;
+
+        if ((socket = _openDataConnection_(command, remote)) == null)
+            return false;
+
+        output = new BufferedOutputStream(socket.getOutputStream(),
+                getBufferSize()
+        );
+        if (__fileType == ASCII_FILE_TYPE)
+            output = new ToNetASCIIOutputStream(output);
+        // Treat everything else as binary for now
+        try
+        {
+            Util.copyStream(local, output, getBufferSize(),
+                    CopyStreamEvent.UNKNOWN_STREAM_SIZE, null,
+                    false);
+        }
+        catch (IOException e)
+        {
+            try
+            {
+                socket.close();
+            }
+            catch (IOException f)
+            {}
+            throw e;
+        }
+        output.close();
+        socket.close();
+        return completePendingCommand();
+    }
+
+    private OutputStream __storeFileStream(int command, String remote)
+    throws IOException
+    {
+        OutputStream output;
+        Socket socket;
+
+        if ((socket = _openDataConnection_(command, remote)) == null)
+            return null;
+
+        output = socket.getOutputStream();
+        if (__fileType == ASCII_FILE_TYPE) {
+            // We buffer ascii transfers because the buffering has to
+            // be interposed between ToNetASCIIOutputSream and the underlying
+            // socket output stream.  We don't buffer binary transfers
+            // because we don't want to impose a buffering policy on the
+            // programmer if possible.  Programmers can decide on their
+            // own if they want to wrap the SocketOutputStream we return
+            // for file types other than ASCII.
+            output = new BufferedOutputStream(output,
+                    getBufferSize());
+            output = new ToNetASCIIOutputStream(output);
+
+        }
+        return new org.apache.commons.net.io.SocketOutputStream(socket, output);
+    }
+
+
+    /**
+     * Establishes a data connection with the FTP server, returning
+     * a Socket for the connection if successful.  If a restart
+     * offset has been set with {@link #setRestartOffset(long)},
+     * a REST command is issued to the server with the offset as
+     * an argument before establishing the data connection.  Active
+     * mode connections also cause a local PORT command to be issued.
+     * <p>
+     * @param command  The text representation of the FTP command to send.
+     * @param arg The arguments to the FTP command.  If this parameter is
+     *             set to null, then the command is sent with no argument.
+     * @return A Socket corresponding to the established data connection.
+     *         Null is returned if an FTP protocol error is reported at
+     *         any point during the establishment and initialization of
+     *         the connection.
+     * @exception IOException  If an I/O error occurs while either sending a
+     *      command to the server or receiving a reply from the server.
+     */
+    protected Socket _openDataConnection_(int command, String arg)
+    throws IOException
+    {
+        Socket socket;
+
+        if (__dataConnectionMode != ACTIVE_LOCAL_DATA_CONNECTION_MODE &&
+                __dataConnectionMode != PASSIVE_LOCAL_DATA_CONNECTION_MODE)
+            return null;
+
+        if (__dataConnectionMode == ACTIVE_LOCAL_DATA_CONNECTION_MODE)
+        {
+            ServerSocket server = _serverSocketFactory_.createServerSocket(getActivePort(), 1, getHostAddress());
+
+            // try EPRT first. If that fails, and the connection is over IPv4
+            // fallback to PORT
+            if (!FTPReply.isPositiveCompletion(eprt(getHostAddress(),
+                    getActivePort())))
+            {
+                if (getRemoteAddress() instanceof Inet6Address)
+                {
+                    server.close();
+                    return null;
+                }
+
+                if (!FTPReply.isPositiveCompletion(port(getHostAddress(),
+                        server.getLocalPort())))
+                {
+                    server.close();
+                    return null;
+                }
+            }
+
+            if ((__restartOffset > 0) && !restart(__restartOffset))
+            {
+                server.close();
+                return null;
+            }
+
+            if (!FTPReply.isPositivePreliminary(sendCommand(command, arg)))
+            {
+                server.close();
+                return null;
+            }
+
+            // For now, let's just use the data timeout value for waiting for
+            // the data connection.  It may be desirable to let this be a
+            // separately configurable value.  In any case, we really want
+            // to allow preventing the accept from blocking indefinitely.
+            if (__dataTimeout >= 0)
+                server.setSoTimeout(__dataTimeout);
+            try {
+                socket = server.accept();
+            } finally {
+                server.close();
+            }
+        }
+        else
+        { // We must be in PASSIVE_LOCAL_DATA_CONNECTION_MODE
+
+            // If we are over an IPv6 connection, try EPSV
+            if (getRemoteAddress() instanceof Inet6Address) {
+                if (epsv() != FTPReply.ENTERING_EPSV_MODE)
+                    return null;
+                __parseExtendedPassiveModeReply((String)_replyLines.get(0));
+            }
+            else {
+                if (pasv() != FTPReply.ENTERING_PASSIVE_MODE)
+                    return null;
+                __parsePassiveModeReply((String)_replyLines.get(0));
+            }
+
+            socket = _socketFactory_.createSocket(__passiveHost, __passivePort);
+            if ((__restartOffset > 0) && !restart(__restartOffset))
+            {
+                socket.close();
+                return null;
+            }
+
+            if (!FTPReply.isPositivePreliminary(sendCommand(command, arg)))
+            {
+                socket.close();
+                return null;
+            }
+        }
+
+        if (__remoteVerificationEnabled && !verifyRemote(socket))
+        {
+            InetAddress host1, host2;
+
+            host1 = socket.getInetAddress();
+            host2 = getRemoteAddress();
+
+            socket.close();
+
+            throw new IOException(
+                    "Host attempting data connection " + host1.getHostAddress() +
+                    " is not same as server " + host2.getHostAddress());
+        }
+
+        if (__dataTimeout >= 0)
+            socket.setSoTimeout(__dataTimeout);
+
+        return socket;
+    }
+
+
+    @Override
+    protected void _connectAction_() throws IOException
+    {
+        super._connectAction_();
+        __initDefaults();
+    }
+
+
+    /***
+     * Sets the timeout in milliseconds to use when reading from the
+     * data connection.  This timeout will be set immediately after
+     * opening the data connection.
+     * <p>
+     * @param  timeout The default timeout in milliseconds that is used when
+     *        opening a data connection socket.
+     ***/
+    public void setDataTimeout(int timeout)
+    {
+        __dataTimeout = timeout;
+    }
+
+    /**
+     * set the factory used for parser creation to the supplied factory object.
+     *
+     * @param parserFactory
+     *               factory object used to create FTPFileEntryParsers
+     *
+     * @see org.apache.commons.net.ftp.parser.FTPFileEntryParserFactory
+     * @see org.apache.commons.net.ftp.parser.DefaultFTPFileEntryParserFactory
+     */
+    public void setParserFactory(FTPFileEntryParserFactory parserFactory) {
+        __parserFactory = parserFactory;
+    }
+
+
+    /***
+     * Closes the connection to the FTP server and restores
+     * connection parameters to the default values.
+     * <p>
+     * @exception IOException If an error occurs while disconnecting.
+     ***/
+    @Override
+    public void disconnect() throws IOException
+    {
+        super.disconnect();
+        __initDefaults();
+    }
+
+
+    /***
+     * Enable or disable verification that the remote host taking part
+     * of a data connection is the same as the host to which the control
+     * connection is attached.  The default is for verification to be
+     * enabled.  You may set this value at any time, whether the
+     * FTPClient is currently connected or not.
+     * <p>
+     * @param enable True to enable verification, false to disable verification.
+     ***/
+    public void setRemoteVerificationEnabled(boolean enable)
+    {
+        __remoteVerificationEnabled = enable;
+    }
+
+    /***
+     * Return whether or not verification of the remote host participating
+     * in data connections is enabled.  The default behavior is for
+     * verification to be enabled.
+     * <p>
+     * @return True if verification is enabled, false if not.
+     ***/
+    public boolean isRemoteVerificationEnabled()
+    {
+        return __remoteVerificationEnabled;
+    }
+
+    /***
+     * Login to the FTP server using the provided username and password.
+     * <p>
+     * @param username The username to login under.
+     * @param password The password to use.
+     * @return True if successfully completed, false if not.
+     * @exception FTPConnectionClosedException
+     *      If the FTP server prematurely closes the connection as a result
+     *      of the client being idle or some other reason causing the server
+     *      to send FTP reply code 421.  This exception may be caught either
+     *      as an IOException or independently as itself.
+     * @exception IOException  If an I/O error occurs while either sending a
+     *      command to the server or receiving a reply from the server.
+     ***/
+    public boolean login(String username, String password) throws IOException
+    {
+
+        user(username);
+
+        if (FTPReply.isPositiveCompletion(_replyCode))
+            return true;
+
+        // If we get here, we either have an error code, or an intermmediate
+        // reply requesting password.
+        if (!FTPReply.isPositiveIntermediate(_replyCode))
+            return false;
+
+        return FTPReply.isPositiveCompletion(pass(password));
+    }
+
+
+    /***
+     * Login to the FTP server using the provided username, password,
+     * and account.  If no account is required by the server, only
+     * the username and password, the account information is not used.
+     * <p>
+     * @param username The username to login under.
+     * @param password The password to use.
+     * @param account  The account to use.
+     * @return True if successfully completed, false if not.
+     * @exception FTPConnectionClosedException
+     *      If the FTP server prematurely closes the connection as a result
+     *      of the client being idle or some other reason causing the server
+     *      to send FTP reply code 421.  This exception may be caught either
+     *      as an IOException or independently as itself.
+     * @exception IOException  If an I/O error occurs while either sending a
+     *      command to the server or receiving a reply from the server.
+     ***/
+    public boolean login(String username, String password, String account)
+    throws IOException
+    {
+        user(username);
+
+        if (FTPReply.isPositiveCompletion(_replyCode))
+            return true;
+
+        // If we get here, we either have an error code, or an intermmediate
+        // reply requesting password.
+        if (!FTPReply.isPositiveIntermediate(_replyCode))
+            return false;
+
+        pass(password);
+
+        if (FTPReply.isPositiveCompletion(_replyCode))
+            return true;
+
+        if (!FTPReply.isPositiveIntermediate(_replyCode))
+            return false;
+
+        return FTPReply.isPositiveCompletion(acct(account));
+    }
+
+    /***
+     * Logout of the FTP server by sending the QUIT command.
+     * <p>
+     * @return True if successfully completed, false if not.
+     * @exception FTPConnectionClosedException
+     *      If the FTP server prematurely closes the connection as a result
+     *      of the client being idle or some other reason causing the server
+     *      to send FTP reply code 421.  This exception may be caught either
+     *      as an IOException or independently as itself.
+     * @exception IOException  If an I/O error occurs while either sending a
+     *      command to the server or receiving a reply from the server.
+     ***/
+    public boolean logout() throws IOException
+    {
+        return FTPReply.isPositiveCompletion(quit());
+    }
+
+
+    /***
+     * Change the current working directory of the FTP session.
+     * <p>
+     * @param pathname  The new current working directory.
+     * @return True if successfully completed, false if not.
+     * @exception FTPConnectionClosedException
+     *      If the FTP server prematurely closes the connection as a result
+     *      of the client being idle or some other reason causing the server
+     *      to send FTP reply code 421.  This exception may be caught either
+     *      as an IOException or independently as itself.
+     * @exception IOException  If an I/O error occurs while either sending a
+     *      command to the server or receiving a reply from the server.
+     ***/
+    public boolean changeWorkingDirectory(String pathname) throws IOException
+    {
+        return FTPReply.isPositiveCompletion(cwd(pathname));
+    }
+
+
+    /***
+     * Change to the parent directory of the current working directory.
+     * <p>
+     * @return True if successfully completed, false if not.
+     * @exception FTPConnectionClosedException
+     *      If the FTP server prematurely closes the connection as a result
+     *      of the client being idle or some other reason causing the server
+     *      to send FTP reply code 421.  This exception may be caught either
+     *      as an IOException or independently as itself.
+     * @exception IOException  If an I/O error occurs while either sending a
+     *      command to the server or receiving a reply from the server.
+     ***/
+    public boolean changeToParentDirectory() throws IOException
+    {
+        return FTPReply.isPositiveCompletion(cdup());
+    }
+
+
+    /***
+     * Issue the FTP SMNT command.
+     * <p>
+     * @param pathname The pathname to mount.
+     * @return True if successfully completed, false if not.
+     * @exception FTPConnectionClosedException
+     *      If the FTP server prematurely closes the connection as a result
+     *      of the client being idle or some other reason causing the server
+     *      to send FTP reply code 421.  This exception may be caught either
+     *      as an IOException or independently as itself.
+     * @exception IOException  If an I/O error occurs while either sending a
+     *      command to the server or receiving a reply from the server.
+     ***/
+    public boolean structureMount(String pathname) throws IOException
+    {
+        return FTPReply.isPositiveCompletion(smnt(pathname));
+    }
+
+    /***
+     * Reinitialize the FTP session.  Not all FTP servers support this
+     * command, which issues the FTP REIN command.
+     * <p>
+     * @return True if successfully completed, false if not.
+     * @exception FTPConnectionClosedException
+     *      If the FTP server prematurely closes the connection as a result
+     *      of the client being idle or some other reason causing the server
+     *      to send FTP reply code 421.  This exception may be caught either
+     *      as an IOException or independently as itself.
+     * @exception IOException  If an I/O error occurs while either sending a
+     *      command to the server or receiving a reply from the server.
+     ***/
+    boolean reinitialize() throws IOException
+    {
+        rein();
+
+        if (FTPReply.isPositiveCompletion(_replyCode) ||
+                (FTPReply.isPositivePreliminary(_replyCode) &&
+                        FTPReply.isPositiveCompletion(getReply())))
+        {
+
+            __initDefaults();
+
+            return true;
+        }
+
+        return false;
+    }
+
+
+    /***
+     * Set the current data connection mode to
+     * <code>ACTIVE_LOCAL_DATA_CONNECTION_MODE</code>.  No communication
+     * with the FTP server is conducted, but this causes all future data
+     * transfers to require the FTP server to connect to the client's
+     * data port.  Additionally, to accommodate differences between socket
+     * implementations on different platforms, this method causes the
+     * client to issue a PORT command before every data transfer.
+     ***/
+    public void enterLocalActiveMode()
+    {
+        __dataConnectionMode = ACTIVE_LOCAL_DATA_CONNECTION_MODE;
+        __passiveHost = null;
+        __passivePort = -1;
+    }
+
+
+    /***
+     * Set the current data connection mode to
+     * <code> PASSIVE_LOCAL_DATA_CONNECTION_MODE </code>.  Use this
+     * method only for data transfers between the client and server.
+     * This method causes a PASV command to be issued to the server
+     * before the opening of every data connection, telling the server to
+     * open a data port to which the client will connect to conduct
+     * data transfers.  The FTPClient will stay in
+     * <code> PASSIVE_LOCAL_DATA_CONNECTION_MODE </code> until the
+     * mode is changed by calling some other method such as
+     * {@link #enterLocalActiveMode  enterLocalActiveMode() }
+     ***/
+    public void enterLocalPassiveMode()
+    {
+        __dataConnectionMode = PASSIVE_LOCAL_DATA_CONNECTION_MODE;
+        // These will be set when just before a data connection is opened
+        // in _openDataConnection_()
+        __passiveHost = null;
+        __passivePort = -1;
+    }
+
+
+    /***
+     * Set the current data connection mode to
+     * <code> ACTIVE_REMOTE_DATA_CONNECTION </code>.  Use this method only
+     * for server to server data transfers.  This method issues a PORT
+     * command to the server, indicating the other server and port to which
+     * it should connect for data transfers.  You must call this method
+     * before EVERY server to server transfer attempt.  The FTPClient will
+     * NOT automatically continue to issue PORT commands.  You also
+     * must remember to call
+     * {@link #enterLocalActiveMode  enterLocalActiveMode() } if you
+     * wish to return to the normal data connection mode.
+     * <p>
+     * @param host The passive mode server accepting connections for data
+     *             transfers.
+     * @param port The passive mode server's data port.
+     * @return True if successfully completed, false if not.
+     * @exception FTPConnectionClosedException
+     *      If the FTP server prematurely closes the connection as a result
+     *      of the client being idle or some other reason causing the server
+     *      to send FTP reply code 421.  This exception may be caught either
+     *      as an IOException or independently as itself.
+     * @exception IOException  If an I/O error occurs while either sending a
+     *      command to the server or receiving a reply from the server.
+     ***/
+    public boolean enterRemoteActiveMode(InetAddress host, int port)
+    throws IOException
+    {
+        if (FTPReply.isPositiveCompletion(port(host, port)))
+        {
+            __dataConnectionMode = ACTIVE_REMOTE_DATA_CONNECTION_MODE;
+            __passiveHost = null;
+            __passivePort = -1;
+            return true;
+        }
+        return false;
+    }
+
+    /***
+     * Set the current data connection mode to
+     * <code> PASSIVE_REMOTE_DATA_CONNECTION_MODE </code>.  Use this
+     * method only for server to server data transfers.
+     * This method issues a PASV command to the server, telling it to
+     * open a data port to which the active server will connect to conduct
+     * data transfers.  You must call this method
+     * before EVERY server to server transfer attempt.  The FTPClient will
+     * NOT automatically continue to issue PASV commands.  You also
+     * must remember to call
+     * {@link #enterLocalActiveMode  enterLocalActiveMode() } if you
+     * wish to return to the normal data connection mode.
+     * <p>
+     * @return True if successfully completed, false if not.
+     * @exception FTPConnectionClosedException
+     *      If the FTP server prematurely closes the connection as a result
+     *      of the client being idle or some other reason causing the server
+     *      to send FTP reply code 421.  This exception may be caught either
+     *      as an IOException or independently as itself.
+     * @exception IOException  If an I/O error occurs while either sending a
+     *      command to the server or receiving a reply from the server.
+     ***/
+    public boolean enterRemotePassiveMode() throws IOException
+    {
+        if (pasv() != FTPReply.ENTERING_PASSIVE_MODE)
+            return false;
+
+        __dataConnectionMode = PASSIVE_REMOTE_DATA_CONNECTION_MODE;
+        __parsePassiveModeReply(_replyLines.get(0));
+
+        return true;
+    }
+
+    /***
+     * Returns the hostname or IP address (in the form of a string) returned
+     * by the server when entering passive mode.  If not in passive mode,
+     * returns null.  This method only returns a valid value AFTER a

[... 2511 lines stripped ...]


Mime
View raw message