//*****************************************************************************
//*
//* (c) Copyright 2002. Glub Tech, Incorporated. All Rights Reserved.
//*
//* $Id: FTP.java 37 2009-05-11 22:46:15Z gary $
//*
//*****************************************************************************
package com.glub.secureftp.bean;
import com.glub.util.*;
import java.io.*;
import java.net.*;
import java.util.*;
import org.apache.regexp.*;
/**
* The <code>FTP</code> class is responsible for handling the basic operations
* of the File Transfer Protocol.
*
* @author Gary Cohen
* @version $Revision: 48 $, $Date: 2010-12-23 22:24:36 -0800 (Thu, 23 Dec 2010) $
* @since 2.5.10
*/
public class FTP {
/** The version of the bean. **/
private static final String VERSION = "2.5.14";
/** The datestamp of the bean. **/
private static String DATESTAMP = null;
/** Used to set the data transfer mode to <code>ascii</code>. */
public static final short ASCII_TRANSFER_MODE = 0;
/** Used to set the data transfer mode to <code>binary</code>; also
* known as <code>image</code>.
*/
public static final short BINARY_TRANSFER_MODE = 1;
/** Used to set the data transfer mode to <code>auto</code>. This mode
* attempts to guess which transfer mode (ascii or binary) to set
* based on file type.
*/
public static final short AUTO_TRANSFER_MODE = 2;
/** Used to set the data transfer mode to <code>ebcdic</code>. */
public static final short EBCDIC_TRANSFER_MODE = 3;
/** Used to set the data connection type to <code>passive</code>. */
public static final short PASV_CONNECTION_TYPE = 0;
/** Used to set the data connection type to <code>passive</code>. */
public static final short PASSIVE_CONNECTION_TYPE= PASV_CONNECTION_TYPE;
/** Used to set the data connection type to <code>active</code>. */
public static final short ACTIVE_CONNECTION_TYPE = 1;
/** This value is used to hold the hostname currently connected to. */
private String hostName = null;
/** This value is used to hold the port currently connected to. */
private int port = 21;
/** This value is used to hold the username we are currently connected as. */
private String user = null;
/** This value is used to hold the user's password. */
private String password = null;
/** This value is used to hold the user's account (if one exists). */
private String account = null;
/** This is the control socket (or the command socket). */
private Socket controlSocket = null;
/** If mode z is enabled, this is true. */
protected boolean modeZEnabled = false;
/** If we are connected, this is true. */
protected boolean isConnected = false;
/** If we are logged in, this is true. */
protected boolean isLoggedIn = false;
/** This value is used to specify the trasnfer mode (ascii or binary). */
private short transferMode = ASCII_TRANSFER_MODE;
/** This value is used to specify the data connection type. */
private short connectionType = PASV_CONNECTION_TYPE;
/**
* This value is used to help the list engine determine how the handle
* the list data from the server.
*/
private short listStyle = FTPServerInfo.LIST_STYLE_UNKNOWN;
/**
* This value sets whether or not we have tried to determine the listing
* style.
*/
private boolean listStyleSet = false;
/** This value is used for our regular expressions (used in list). */
private RECompiler compiler = new RECompiler();
/** This value is used for our regular expressions (used in list). */
private RE unixMatcher = new RE();
private RE winMatcher = new RE();
private RE netwareMatcher = new RE();
private RE enginMatcher = new RE();
/** This value denotes if the server supports the SIZE command */
private boolean systemSupportsFileSizeCmd = true;
/** This value denotes if the server supports the REST command */
private boolean systemSupportsRestCmd = true;
/** This value denotes if the server supports the PRET command */
private boolean systemSupportsPretCmd = true;
/** This value denotes if the server supports the OPTS command */
private boolean systemSupportsOptsUTF8Cmd = true;
/** This value denotes if the server should send the UTF8 listing */
private boolean sendStringDataUTF8 = false;
/** These values are used if an active port range is specifed */
protected int lastPortFromRange = 0;
protected int minPortInRange = 0;
protected int maxPortInRange = 0;
/** This stream is used to print the responses returned from the server. */
protected OutputStream recvCmdStream = null;
/** This stream is used to print the commands sent to the server. */
protected OutputStream sendCmdStream = null;
/** This handles the FTP commands. */
protected FTPCommand command = null;
/** Verify the jar is signed by Glub Tech */
//private final boolean verifyJar = verifyJar();
/** Force passive connections to use the same IP as the control channel */
private boolean forcePasvToUseControlIP = false;
/** Debug output */
private boolean debug = GTOverride.getBoolean("glub.debug");
/**
* Create a new <code>FTP</code> object without response notification.
*
* @param hostInfo the HostInfo to connect to.
*/
public FTP( HostInfo hostInfo ) {
this( hostInfo.getHostName(), hostInfo.getPort(), null, null );
}
/**
* Create a new <code>FTP</code> object without response notification.
*
* @param host the hostname to connect to.
* @param port the port to connect to.
*/
public FTP( String host, int port ) {
this( host, port, null, null );
}
/**
* Create a new <code>FTP</code> object with response notification.
*
* @param hostInfo the HostInfo to connect to.
* @param sendCmdStream the commands sent to the server.
* Pass <code>null</code> if not interested
* in this data.
* @param recvCmdStream the responses returned from the server.
* Pass <code>null</code> if not interested
* in this data.
*/
public FTP( HostInfo hostInfo,
OutputStream sendCmdStream, OutputStream recvCmdStream ) {
this( hostInfo.getHostName(), hostInfo.getPort(), sendCmdStream,
recvCmdStream );
}
/**
* Create a new <code>FTP</code> object with response notification.
*
* @param host the hostname to connect to.
* @param port the port to connect to.
* @param sendCmdStream the commands sent to the server.
* Pass <code>null</code> if not interested
* in this data.
* @param recvCmdStream the responses returned from the server.
* Pass <code>null</code> if not interested
* in this data.
*/
public FTP( String host, int port,
OutputStream sendCmdStream, OutputStream recvCmdStream ) {
setHostName(host);
setPort(port);
setSendCmdStream( sendCmdStream );
setRecvCmdStream( recvCmdStream );
}
/**
* Connect to the FTP host and port. If the port was not set, we default
* to 21.
*
* @throws FTPConnectException if the connection fails.
* @throws FTPException if the FTP server returns an error code.
* @throws IOException if there are socket problems.
* @throws UnknownHostException if the host could not be found.
* @throws IllegalArgumentException if <code>hostName</code> is
* <code>null</code>.
*/
public void connect() throws FTPConnectException, FTPException, IOException,
UnknownHostException, IllegalArgumentException {
_connect();
}
/**
* Login to the FTP server.
*
* @param user the username to login as.
* @param pass the password to login as.
*
* @throws IOException if there is a socket problem.
* @throws FTPBadLoginException if there is a problem logging in.
* @throws FTPConnectException if this is called prior to
* <code>connect</code>
* @throws FTPException if the FTP server returns an error code.
* @throws IllegalArgumentException if there is a problem with any of the
* passed in args.
*
* @see #connect()
*/
public void login( String user, String pass )
throws IOException, FTPBadLoginException, FTPConnectException,
FTPException, IllegalArgumentException {
login( user, pass, null );
}
/**
* Login to the FTP server.
*
* @param user the username to login as.
* @param pass the password to login as.
* @param acct the account to use.
*
* @throws IOException if there is a socket problem.
* @throws FTPBadLoginException if there is a problem logging in.
* @throws FTPConnectException if this is called prior to
* <code>connect</code>
* @throws FTPException if the FTP server returns an error code.
* @throws IllegalArgumentException if there is a problem with any of the
* passed in args.
*
* @see #connect()
*/
public void login( String user, String pass, String acct )
throws IOException, FTPBadLoginException, FTPConnectException,
FTPException, IllegalArgumentException {
_login( user, pass, acct );
}
/**
* Logout from the FTP server.
*
* @throws IOException if there is a socket problem.
* @throws FTPException if the FTP server returns an error code.
*/
public void logout() throws IOException, FTPException {
_logout();
}
/**
* Sends the username to the FTP server.
*
* @param user the username.
*
* @throws FTPNeedPasswordException if a password is required.
* @throws FTPNeedAccountException if an accound is required.
* @throws FTPBadLoginException if there is a problem logging in.
* @throws FTPException if the FTP server returns an error code.
* @throws IllegalArgumentException if there is a problem with the username.
*/
public void sendUserName( String user ) throws FTPNeedPasswordException,
FTPNeedAccountException,
FTPBadLoginException,
FTPException,
IllegalArgumentException {
_sendUserName( user );
}
/**
* Sends the password to the FTP server.
*
* @param pass the password.
*
* @throws FTPNeedAccountException if an accound is required.
* @throws FTPBadLoginException if there is a problem logging in.
* @throws FTPException if the FTP server returns an error code.
* @throws IllegalArgumentException if there is a problem with the password.
*/
public void sendPassword( String pass ) throws FTPNeedAccountException,
FTPBadLoginException,
FTPException,
IllegalArgumentException {
_sendPassword( pass );
}
/**
* Sends the account to the FTP server.
*
* @param acct the account.
*
* @throws FTPBadLoginException if there is a problem logging in.
* @throws FTPException if the FTP server returns an error code.
* @throws IllegalArgumentException if there is a problem with the account.
*/
public void sendAccount( String acct ) throws FTPBadLoginException,
FTPException,
IllegalArgumentException {
_sendAccount( acct );
}
/**
* List the current remote directory, including hidden files. Subject
* to availiblity on certain servers.
* <p>
* Based on what <code>getConnectionType</code> returns, either
* <code>pasv</code> or <code>port</code> will be sent in this routine.
*
* @return a list of <code>RemoteFile</code> objects as a
* <code>RemoteFileList</code>.
*
* @throws FTPException if the FTP server returns an error code.
* @throws IOException if there is a socket problem.
*
* @see RemoteFile
* @see #getConnectionType()
* @see #setConnectionType(short)
* @see #pasv()
* @see #port(HostInfo)
*/
public RemoteFileList listAll() throws FTPException, IOException {
return list( (String)null, null, true );
}
/**
* List the current remote directory.
* <p>
* Based on what <code>getConnectionType</code> returns, either
* <code>pasv</code> or <code>port</code> will be sent in this routine.
*
* @return a list of <code>RemoteFile</code> objects as a
* <code>RemoteFileList</code>.
*
* @throws FTPException if the FTP server returns an error code.
* @throws IOException if there is a socket problem.
*
* @see RemoteFile
* @see #getConnectionType()
* @see #setConnectionType(short)
* @see #pasv()
* @see #port(HostInfo)
*/
public RemoteFileList list() throws FTPException, IOException {
return list( (String)null, null, false );
}
/**
* List the current remote directory with the ability to abort the listing.
* <p>
* Based on what <code>getConnectionType</code> returns, either
* <code>pasv</code> or <code>port</code> will be sent in this routine.
*
* @return a list of <code>RemoteFile</code> objects as a
* <code>RemoteFileList</code>.
*
* @param abort an Object that allows for the abortion of the
* <code>list</code>.
*
* @throws FTPException if the FTP server returns an error code.
* @throws IOException if there is a socket problem.
*
* @see RemoteFile
* @see #getConnectionType()
* @see #setConnectionType(short)
* @see #pasv()
* @see #port(HostInfo)
*/
public RemoteFileList list( FTPAbortableTransfer abort ) throws FTPException,
IOException {
return list( (String)null, abort, false );
}
/**
* List the current remote directory including hidden files with the
* ability to abort the listing.
* <p>
* Based on what <code>getConnectionType</code> returns, either
* <code>pasv</code> or <code>port</code> will be sent in this routine.
*
* @return a list of <code>RemoteFile</code> objects as a
* <code>RemoteFileList</code>.
*
* @param abort an Object that allows for the abortion of the
* <code>list</code>.
*
* @throws FTPException if the FTP server returns an error code.
* @throws IOException if there is a socket problem.
*
* @see RemoteFile
* @see #getConnectionType()
* @see #setConnectionType(short)
* @see #pasv()
* @see #port(HostInfo)
*/
public RemoteFileList listAll( FTPAbortableTransfer abort )
throws FTPException, IOException {
return list( (String)null, abort, true );
}
/**
* List items on the remote FTP server.
* <p>
* Based on what <code>getConnectionType</code> returns, either
* <code>pasv</code> or <code>port</code> will be sent in this routine.
*
* @param file a <code>RemoteFile</code> you
* want to to list from the FTP server.
* Pass <code>null</code> to list the current directory.
*
* @return a list of <code>RemoteFile</code> objects as a
* <code>RemoteFileList</code>.
*
* @throws FTPException if the FTP server returns an error code.
* @throws IOException if there is a socket problem.
*
* @see RemoteFile
* @see #getConnectionType()
* @see #setConnectionType(short)
* @see #pasv()
* @see #port(HostInfo)
*/
public RemoteFileList list( RemoteFile file )
throws FTPException, IOException {
return list( file, null, false );
}
/**
* List items on the remote FTP server.
* <p>
* Based on what <code>getConnectionType</code> returns, either
* <code>pasv</code> or <code>port</code> will be sent in this routine.
*
* @param itemsToList a space-delimited <code>String</code> of items you
* want to to list from the FTP server.
* Pass <code>null</code> to list the current directory.
*
* @return a list of <code>RemoteFile</code> objects as a
* <code>RemoteFileList</code>.
*
* @throws FTPException if the FTP server returns an error code.
* @throws IOException if there is a socket problem.
*
* @see RemoteFile
* @see #getConnectionType()
* @see #setConnectionType(short)
* @see #pasv()
* @see #port(HostInfo)
*/
public RemoteFileList list( String itemsToList )
throws FTPException, IOException {
return list( itemsToList, null, false );
}
/**
* List items on the remote FTP server with the ability to abort the listing.
* <p>
* Based on what <code>getConnectionType</code> returns, either
* <code>pasv</code> or <code>port</code> will be sent in this routine.
*
* @param file a <code>RemoteFile</code> want to to list from the
* FTP server.
* @param abort an Object that allows for the abortion of the
* <code>list</code>.
* @param showHidden flag to show hidden files (only useful for empty list)
*
* @return a list of <code>RemoteFile</code> objects as a
* <code>RemoteFileList</code>.
*
* @throws FTPException if the FTP server returns an error code.
* @throws IOException if there is a socket problem.
*
* @see RemoteFile
* @see #getConnectionType()
* @see #setConnectionType(short)
* @see #pasv()
* @see #port(HostInfo)
*/
public RemoteFileList list( RemoteFile file, FTPAbortableTransfer abort,
boolean showHidden )
throws FTPException, IOException {
String itemToList = file.getFileName();
boolean setPWD = false;
if ( null != file.getMetaData("pwd") ) {
itemToList = file.getMetaData("pwd") + itemToList;
setPWD = true;
}
// in case there are spaces in the name
itemToList = Util.searchAndReplace( itemToList, " ", "*", true );
RemoteFileList result = list( itemToList, abort, showHidden );
if ( setPWD ) {
String pwd = pwd();
if ( file.isDirectory() ) {
pwd += "/" + file.getFileName() + "/";
}
for ( int i = 0; i < result.size(); i++ ) {
result.getFile(i).setMetaData("pwd", pwd);
}
}
return result;
}
/**
* List items on the remote FTP server with the ability to abort the listing.
* <p>
* Based on what <code>getConnectionType</code> returns, either
* <code>pasv</code> or <code>port</code> will be sent in this routine.
*
* @param itemsToList a space-delimited <code>String</code> of items you
* want to to list from the FTP server.
* Pass <code>null</code> to list the current directory.
* @param abort an Object that allows for the abortion of the
* <code>list</code>.
* @param showHidden flag to show hidden files (only useful for empty list)
*
* @return a list of <code>RemoteFile</code> objects as a
* <code>RemoteFileList</code>.
*
* @throws FTPException if the FTP server returns an error code.
* @throws IOException if there is a socket problem.
*
* @see RemoteFile
* @see #getConnectionType()
* @see #setConnectionType(short)
* @see #pasv()
* @see #port(HostInfo)
*/
public RemoteFileList list( String itemsToList, FTPAbortableTransfer abort,
boolean showHidden )
throws FTPException, IOException {
aboutToTransferData();
return _list( itemsToList, abort, showHidden );
}
/**
* Retrieve a file from the FTP server.
* <p>
* Based on what <code>getConnectionType</code> returns, either
* <code>pasv</code> or <code>port</code> will be sent in this routine.
*
* @param remoteFile the name of the remote file that
* exists on the FTP server.
* @param outputFile a local file that will act as storage for the
* downloaded file. If this parameter is
* <code>null</code>, a local file will be created with
* the remote file's name in the current local
* directory as specified by <code>user.dir</code>.
* @param restartXfer restart an interrupted transfer (if available).
*
* @throws FTPRestartNotSupportedException if the FTP server doesn't support
* restarting incomplete file xfer.
* @throws FTPException if the FTP server returns an error code.
* @throws IOException if there is a socket or file problem.
*
* @see #getConnectionType()
* @see #setConnectionType(short)
* @see #pasv()
* @see #port(HostInfo)
*/
public void retrieve( String remoteFile, File outputFile,
boolean restartXfer )
throws FTPRestartNotSupportedException,
FTPException, IOException {
retrieve( new RemoteFile(remoteFile), outputFile, restartXfer, null, null );
}
/**
* Retrieve a file from the FTP server.
* <p>
* Based on what <code>getConnectionType</code> returns, either
* <code>pasv</code> or <code>port</code> will be sent in this routine.
*
* @param remoteFile the RemoteFile that exists on the FTP server.
* @param outputFile a local file that will act as storage for the
* downloaded file. If this parameter is
* <code>null</code>, a local file will be created with
* the remote file's name in the current local
* directory as specified by <code>user.dir</code>.
* @param restartXfer restart an interrupted transfer (if available).
*
* @throws FTPRestartNotSupportedException if the FTP server doesn't support
* restarting incomplete file xfer.
* @throws FTPException if the FTP server returns an error code.
* @throws IOException if there is a socket or file problem.
*
* @see #getConnectionType()
* @see #setConnectionType(short)
* @see #pasv()
* @see #port(HostInfo)
*/
public void retrieve( RemoteFile remoteFile, File outputFile,
boolean restartXfer )
throws FTPRestartNotSupportedException,
FTPException, IOException {
retrieve( remoteFile, outputFile, restartXfer, null, null );
}
/**
* Retrieve a file from the FTP server.
* <p>
* Based on what <code>getConnectionType</code> returns, either
* <code>pasv</code> or <code>port</code> will be sent in this routine.
*
* @param remoteFile the name of the remote file that
* exists on the FTP server.
* @param outputStream an output stream that will act as storage for the
* downloaded file.
*
* @throws FTPRestartNotSupportedException if the FTP server doesn't support
* restarting incomplete file xfer.
* @throws FTPException if the FTP server returns an error code.
* @throws IOException if there is a socket or file problem.
*
* @see #getConnectionType()
* @see #setConnectionType(short)
* @see #pasv()
* @see #port(HostInfo)
*/
public void retrieve( String remoteFile, OutputStream outputStream )
throws FTPRestartNotSupportedException,
FTPException, IOException {
retrieve( new RemoteFile(remoteFile), outputStream, null, null );
}
/**
* Retrieve a file from the FTP server.
* <p>
* Based on what <code>getConnectionType</code> returns, either
* <code>pasv</code> or <code>port</code> will be sent in this routine.
*
* @param remoteFile the RemoteFile that exists on the FTP server.
* @param outputStream an output stream that will act as storage for the
* downloaded file.
*
* @throws FTPRestartNotSupportedException if the FTP server doesn't support
* restarting incomplete file xfer.
* @throws FTPException if the FTP server returns an error code.
* @throws IOException if there is a socket or file problem.
*
* @see #getConnectionType()
* @see #setConnectionType(short)
* @see #pasv()
* @see #port(HostInfo)
*/
public void retrieve( RemoteFile remoteFile, OutputStream outputStream )
throws FTPRestartNotSupportedException,
FTPException, IOException {
retrieve( remoteFile, outputStream, null, null );
}
/**
* Retrieve a file from the FTP server with the ability to abort the transfer.
* <p>
* Based on what <code>getConnectionType</code> returns, either
* <code>pasv</code> or <code>port</code> will be sent in this routine.
*
* @param remoteFile the name of the remote file that
* exists on the FTP server.
* @param outputFile a local file that will act as storage for the
* downloaded file. If this parameter is
* <code>null</code>, a local file will be created with
* the remote file's name in the current local
* directory as specified by <code>user.dir</code>.
* @param restartXfer restart an interrupted transfer (if available).
* @param abort an Object that allows for the abortion of the
* <code>retrieve</code>.
*
* @throws FTPRestartNotSupportedException if the FTP server doesn't support
* restarting incomplete file xfer.
* @throws FTPException if the FTP server returns an error code.
* @throws IOException if there is a socket or file problem.
*
* @see #getConnectionType()
* @see #setConnectionType(short)
* @see #pasv()
* @see #port(HostInfo)
*/
public void retrieve( String remoteFile, File outputFile, boolean restartXfer,
FTPAbortableTransfer abort )
throws FTPRestartNotSupportedException,
FTPException, IOException {
retrieve( new RemoteFile(remoteFile), outputFile, restartXfer,
null, abort );
}
/**
* Retrieve a file from the FTP server with the ability to abort the transfer.
* <p>
* Based on what <code>getConnectionType</code> returns, either
* <code>pasv</code> or <code>port</code> will be sent in this routine.
*
* @param remoteFile the RemoteFile that exists on the FTP server.
* @param outputFile a local file that will act as storage for the
* downloaded file. If this parameter is
* <code>null</code>, a local file will be created with
* the remote file's name in the current local
* directory as specified by <code>user.dir</code>.
* @param restartXfer restart an interrupted transfer (if available).
* @param abort an Object that allows for the abortion of the
* <code>retrieve</code>.
*
* @throws FTPRestartNotSupportedException if the FTP server doesn't support
* restarting incomplete file xfer.
* @throws FTPException if the FTP server returns an error code.
* @throws IOException if there is a socket or file problem.
*
* @see #getConnectionType()
* @see #setConnectionType(short)
* @see #pasv()
* @see #port(HostInfo)
*/
public void retrieve( RemoteFile remoteFile, File outputFile,
boolean restartXfer, FTPAbortableTransfer abort )
throws FTPRestartNotSupportedException,
FTPException, IOException {
retrieve( remoteFile, outputFile, restartXfer, null, abort );
}
/**
* Retrieve a file from the FTP server with the ability to abort the transfer.
* <p>
* Based on what <code>getConnectionType</code> returns, either
* <code>pasv</code> or <code>port</code> will be sent in this routine.
*
* @param remoteFile the name of the remote file that
* exists on the FTP server.
* @param outputStream an output stream that will act as storage for the
* downloaded file.
* @param abort an Object that allows for the abortion of the
* <code>retrieve</code>.
*
* @throws FTPRestartNotSupportedException if the FTP server doesn't support
* restarting incomplete file xfer.
* @throws FTPException if the FTP server returns an error code.
* @throws IOException if there is a socket or file problem.
*
* @see #getConnectionType()
* @see #setConnectionType(short)
* @see #pasv()
* @see #port(HostInfo)
*/
public void retrieve( String remoteFile, OutputStream outputStream,
FTPAbortableTransfer abort )
throws FTPRestartNotSupportedException,
FTPException, IOException {
retrieve( new RemoteFile(remoteFile), outputStream, null, abort );
}
/**
* Retrieve a file from the FTP server with the ability to abort the transfer.
* <p>
* Based on what <code>getConnectionType</code> returns, either
* <code>pasv</code> or <code>port</code> will be sent in this routine.
*
* @param remoteFile the RemoteFile that exists on the FTP server.
* @param outputStream an output stream that will act as storage for the
* downloaded file.
* @param abort an Object that allows for the abortion of the
* <code>retrieve</code>.
*
* @throws FTPRestartNotSupportedException if the FTP server doesn't support
* restarting incomplete file xfer.
* @throws FTPException if the FTP server returns an error code.
* @throws IOException if there is a socket or file problem.
*
* @see #getConnectionType()
* @see #setConnectionType(short)
* @see #pasv()
* @see #port(HostInfo)
*/
public void retrieve( RemoteFile remoteFile, OutputStream outputStream,
FTPAbortableTransfer abort )
throws FTPRestartNotSupportedException,
FTPException, IOException {
retrieve( remoteFile, outputStream, null, abort );
}
/**
* Retrieve a file from the FTP server with progress information.
* <p>
* Based on what <code>getConnectionType</code> returns, either
* <code>pasv</code> or <code>port</code> will be sent in this routine.
*
* @param remoteFile the name of the remote file that
* exists on the FTP server.
* @param outputFile a local file that will act as storage for the
* downloaded file. If this parameter is
* <code>null</code>, a local file will be created with
* the remote file's name in the current local
* directory as specified by <code>user.dir</code>.
* @param restartXfer restart an interrupted transfer (if available).
* @param progress a <code>Progress</code> object which is used to update
* download status.
*
* @throws FTPRestartNotSupportedException if the FTP server doesn't support
* restarting incomplete file xfer.
* @throws FTPException if the FTP server returns an error code.
* @throws IOException if there is a socket or file problem.
*
* @see #getConnectionType()
* @see #setConnectionType(short)
* @see #pasv()
* @see #port(HostInfo)
*/
public void retrieve( String remoteFile, File outputFile, boolean restartXfer,
Progress progress )
throws FTPRestartNotSupportedException,
FTPException, IOException {
retrieve( new RemoteFile(remoteFile), outputFile, restartXfer,
progress, null );
}
/**
* Retrieve a file from the FTP server with progress information.
* <p>
* Based on what <code>getConnectionType</code> returns, either
* <code>pasv</code> or <code>port</code> will be sent in this routine.
*
* @param remoteFile the RemoteFile that exists on the FTP server.
* @param outputFile a local file that will act as storage for the
* downloaded file. If this parameter is
* <code>null</code>, a local file will be created with
* the remote file's name in the current local
* directory as specified by <code>user.dir</code>.
* @param restartXfer restart an interrupted transfer (if available).
* @param progress a <code>Progress</code> object which is used to update
* download status.
*
* @throws FTPRestartNotSupportedException if the FTP server doesn't support
* restarting incomplete file xfer.
* @throws FTPException if the FTP server returns an error code.
* @throws IOException if there is a socket or file problem.
*
* @see #getConnectionType()
* @see #setConnectionType(short)
* @see #pasv()
* @see #port(HostInfo)
*/
public void retrieve( RemoteFile remoteFile, File outputFile,
boolean restartXfer, Progress progress )
throws FTPRestartNotSupportedException,
FTPException, IOException {
retrieve( remoteFile, outputFile, restartXfer, progress, null );
}
/**
* Retrieve a file from the FTP server with progress information.
* <p>
* Based on what <code>getConnectionType</code> returns, either
* <code>pasv</code> or <code>port</code> will be sent in this routine.
*
* @param remoteFile the name of the remote file that
* exists on the FTP server.
* @param outputStream an output stream that will act as storage for the
* downloaded file.
* @param progress a <code>Progress</code> object which is used to
* update download status.
*
* @throws FTPRestartNotSupportedException if the FTP server doesn't support
* restarting incomplete file xfer.
* @throws FTPException if the FTP server returns an error code.
* @throws IOException if there is a socket or file problem.
*
* @see #getConnectionType()
* @see #setConnectionType(short)
* @see #pasv()
* @see #port(HostInfo)
*/
public void retrieve( String remoteFile, OutputStream outputStream,
Progress progress )
throws FTPRestartNotSupportedException,
FTPException, IOException {
retrieve( new RemoteFile(remoteFile), outputStream, progress, null );
}
/**
* Retrieve a file from the FTP server with progress information.
* <p>
* Based on what <code>getConnectionType</code> returns, either
* <code>pasv</code> or <code>port</code> will be sent in this routine.
*
* @param remoteFile the RemoteFile that exists on the FTP server.
* @param outputStream an output stream that will act as storage for the
* downloaded file.
* @param progress a <code>Progress</code> object which is used to
* update download status.
*
* @throws FTPRestartNotSupportedException if the FTP server doesn't support
* restarting incomplete file xfer.
* @throws FTPException if the FTP server returns an error code.
* @throws IOException if there is a socket or file problem.
*
* @see #getConnectionType()
* @see #setConnectionType(short)
* @see #pasv()
* @see #port(HostInfo)
*/
public void retrieve( RemoteFile remoteFile, OutputStream outputStream,
Progress progress )
throws FTPRestartNotSupportedException,
FTPException, IOException {
retrieve( remoteFile, outputStream, progress, null );
}
/**
* Retrieve a file from the FTP server with progress information and
* the ability to abort the transfer.
* <p>
* Based on what <code>getConnectionType</code> returns, either
* <code>pasv</code> or <code>port</code> will be sent in this routine.
*
* @param remoteFile the name of the remote file that
* exists on the FTP server.
* @param outputFile a local file that will act as storage for the
* downloaded file. If this parameter is
* <code>null</code>, a local file will be created with
* the remote file's name in the current local
* directory as specified by <code>user.dir</code>.
* @param restartXfer restart an interrupted transfer (if available).
* @param progress a <code>Progress</code> object which is used to update
* download status.
* @param abort an Object that allows for the abortion of the
* <code>retrieve</code>.
*
* @throws FTPRestartNotSupportedException if the FTP server doesn't support
* restarting incomplete file xfer.
* @throws FTPException if the FTP server returns an error code.
* @throws IOException if there is a socket or file problem.
*
* @see #getConnectionType()
* @see #setConnectionType(short)
* @see #pasv()
* @see #port(HostInfo)
*/
public void retrieve( String remoteFile, File outputFile, boolean restartXfer,
Progress progress, FTPAbortableTransfer abort )
throws FTPRestartNotSupportedException,
FTPException, IOException {
retrieve( new RemoteFile(remoteFile), outputFile, restartXfer,
progress, abort );
}
/**
* Retrieve a file from the FTP server with progress information and
* the ability to abort the transfer.
* <p>
* Based on what <code>getConnectionType</code> returns, either
* <code>pasv</code> or <code>port</code> will be sent in this routine.
*
* @param remoteFile the RemoteFile that exists on the FTP server.
* @param outputFile a local file that will act as storage for the
* downloaded file. If this parameter is
* <code>null</code>, a local file will be created with
* the remote file's name in the current local
* directory as specified by <code>user.dir</code>.
* @param restartXfer restart an interrupted transfer (if available).
* @param progress a <code>Progress</code> object which is used to update
* download status.
* @param abort an Object that allows for the abortion of the
* <code>retrieve</code>.
*
* @throws FTPRestartNotSupportedException if the FTP server doesn't support
* restarting incomplete file xfer.
* @throws FTPException if the FTP server returns an error code.
* @throws IOException if there is a socket or file problem.
*
* @see #getConnectionType()
* @see #setConnectionType(short)
* @see #pasv()
* @see #port(HostInfo)
*/
public void retrieve( RemoteFile remoteFile, File outputFile,
boolean restartXfer,
Progress progress, FTPAbortableTransfer abort )
throws FTPRestartNotSupportedException,
FTPException, IOException {
aboutToTransferData();
_retrieve( remoteFile, outputFile, restartXfer, progress, abort );
}
/**
* Retrieve a file from the FTP server with progress information and
* the ability to abort the transfer.
* <p>
* Based on what <code>getConnectionType</code> returns, either
* <code>pasv</code> or <code>port</code> will be sent in this routine.
*
* @param remoteFile the name of the remote file that
* exists on the FTP server.
* @param outputStream an output stream that will act as storage for the
* downloaded file.
* @param progress a <code>Progress</code> object which is used to
* update download status.
* @param abort an Object that allows for the abortion of the
* <code>retrieve</code>.
*
* @throws FTPRestartNotSupportedException if the FTP server doesn't support
* restarting incomplete file xfer.
* @throws FTPException if the FTP server returns an error code.
* @throws IOException if there is a socket or file problem.
*
* @see #getConnectionType()
* @see #setConnectionType(short)
* @see #pasv()
* @see #port(HostInfo)
*/
public void retrieve( String remoteFile, OutputStream outputStream,
Progress progress, FTPAbortableTransfer abort )
throws FTPRestartNotSupportedException,
FTPException, IOException {
retrieve( new RemoteFile(remoteFile), outputStream, progress, abort );
}
/**
* Retrieve a file from the FTP server with progress information and
* the ability to abort the transfer.
* <p>
* Based on what <code>getConnectionType</code> returns, either
* <code>pasv</code> or <code>port</code> will be sent in this routine.
*
* @param remoteFile the RemoteFile that exists on the FTP server.
* @param outputStream an output stream that will act as storage for the
* downloaded file.
* @param progress a <code>Progress</code> object which is used to
* update download status.
* @param abort an Object that allows for the abortion of the
* <code>retrieve</code>.
*
* @throws FTPRestartNotSupportedException if the FTP server doesn't support
* restarting incomplete file xfer.
* @throws FTPException if the FTP server returns an error code.
* @throws IOException if there is a socket or file problem.
*
* @see #getConnectionType()
* @see #setConnectionType(short)
* @see #pasv()
* @see #port(HostInfo)
*/
public void retrieve( RemoteFile remoteFile, OutputStream outputStream,
Progress progress, FTPAbortableTransfer abort )
throws FTPRestartNotSupportedException,
FTPException, IOException {
aboutToTransferData();
_retrieveByStream( remoteFile, outputStream, false, progress, abort, 0 );
}
/**
* Store a file to the FTP server.
* <p>
* Based on what <code>getConnectionType</code> returns, either
* <code>pasv</code> or <code>port</code> will be sent in this routine.
*
* @param file the local file you want to upload.
* @param restartXfer restart an interrupted transfer (if available).
*
* @throws FTPRestartNotSupportedException if the FTP server doesn't support
* restarting incomplete file xfer.
* @throws FTPException if the FTP server returns an error code.
* @throws IOException if there is a socket or file problem.
* @throws IllegalArgumentException if there are argument related problems.
*
* @see #getConnectionType()
* @see #setConnectionType(short)
* @see #pasv()
* @see #port(HostInfo)
*/
public void store( File file, boolean restartXfer )
throws FTPRestartNotSupportedException,
FTPException, IOException,
IllegalArgumentException {
store( file, null, restartXfer, null, null );
}
/**
* Store a file to the FTP server with a specific filename.
* <p>
* Based on what <code>getConnectionType</code> returns, either
* <code>pasv</code> or <code>port</code> will be sent in this routine.
*
* @param file the local file you want to upload.
* @param name the name you want to save the file as.
* @param restartXfer restart an interrupted transfer (if available).
*
* @throws FTPRestartNotSupportedException if the FTP server doesn't support
* restarting incomplete file xfer.
* @throws FTPException if the FTP server returns an error code.
* @throws IOException if there is a socket or file problem.
* @throws IllegalArgumentException if there are argument related problems.
*
* @see #getConnectionType()
* @see #setConnectionType(short)
* @see #pasv()
* @see #port(HostInfo)
*/
public void store( File file, String name, boolean restartXfer )
throws FTPRestartNotSupportedException,
FTPException, IOException,
IllegalArgumentException {
store( file, name, restartXfer, null, null );
}
/**
* Store a file to the FTP server.
* <p>
* Based on what <code>getConnectionType</code> returns, either
* <code>pasv</code> or <code>port</code> will be sent in this routine.
*
* @param inputStream the "local file" input stream you want to upload.
*
* @throws FTPRestartNotSupportedException if the FTP server doesn't support
* restarting incomplete file xfer.
* @throws FTPException if the FTP server returns an error code.
* @throws IOException if there is a socket or file problem.
* @throws IllegalArgumentException if there are argument related problems.
*
* @see #getConnectionType()
* @see #setConnectionType(short)
* @see #pasv()
* @see #port(HostInfo)
*/
public void store( InputStream inputStream )
throws FTPRestartNotSupportedException,
FTPException, IOException,
IllegalArgumentException {
store( inputStream, 0, null, null, null );
}
/**
* Store a file to the FTP server with a specific filename.
* <p>
* Based on what <code>getConnectionType</code> returns, either
* <code>pasv</code> or <code>port</code> will be sent in this routine.
*
* @param inputStream the "local file" input stream you want to upload.
* @param name the name you want to save the file as.
*
* @throws FTPRestartNotSupportedException if the FTP server doesn't support
* restarting incomplete file xfer.
* @throws FTPException if the FTP server returns an error code.
* @throws IOException if there is a socket or file problem.
* @throws IllegalArgumentException if there are argument related problems.
*
* @see #getConnectionType()
* @see #setConnectionType(short)
* @see #pasv()
* @see #port(HostInfo)
*/
public void store( InputStream inputStream, String name )
throws FTPRestartNotSupportedException,
FTPException, IOException,
IllegalArgumentException {
store( inputStream, 0, name, null, null );
}
/**
* Store a file to the FTP server with the ability to abort the data transfer.
* <p>
* Based on what <code>getConnectionType</code> returns, either
* <code>pasv</code> or <code>port</code> will be sent in this routine.
*
* @param file the local file you want to upload.
* @param restartXfer restart an interrupted transfer (if available).
* @param abort an Object that allows for the abortion of the
* <code>store</code>.
*
* @throws FTPRestartNotSupportedException if the FTP server doesn't support
* restarting incomplete file xfer.
* @throws FTPException if the FTP server returns an error code.
* @throws IOException if there is a socket or file problem.
* @throws IllegalArgumentException if there are argument related problems.
*
* @see #getConnectionType()
* @see #setConnectionType(short)
* @see #pasv()
* @see #port(HostInfo)
*/
public void store( File file, boolean restartXfer,
FTPAbortableTransfer abort )
throws FTPRestartNotSupportedException, FTPException,
IOException, IllegalArgumentException {
store( file, null, restartXfer, null, abort );
}
/**
* Store a file to the FTP server with a specific filename and
* with the ability to abort the data transfer.
* <p>
* Based on what <code>getConnectionType</code> returns, either
* <code>pasv</code> or <code>port</code> will be sent in this routine.
*
* @param file the local file you want to upload.
* @param name the name you want to save the file as.
* @param restartXfer restart an interrupted transfer (if available).
* @param abort an Object that allows for the abortion of the
* <code>store</code>.
*
* @throws FTPRestartNotSupportedException if the FTP server doesn't support
* restarting incomplete file xfer.
* @throws FTPException if the FTP server returns an error code.
* @throws IOException if there is a socket or file problem.
* @throws IllegalArgumentException if there are argument related problems.
*
* @see #getConnectionType()
* @see #setConnectionType(short)
* @see #pasv()
* @see #port(HostInfo)
*/
public void store( File file, String name, boolean restartXfer,
FTPAbortableTransfer abort )
throws FTPRestartNotSupportedException, FTPException,
IOException, IllegalArgumentException {
store( file, name, restartXfer, null, abort );
}
/**
* Store a file to the FTP server with the ability to abort the data transfer.
* <p>
* Based on what <code>getConnectionType</code> returns, either
* <code>pasv</code> or <code>port</code> will be sent in this routine.
*
* @param inputStream the "local file" input stream you want to upload.
* @param abort an Object that allows for the abortion of the
* <code>store</code>.
*
* @throws FTPRestartNotSupportedException if the FTP server doesn't support
* restarting incomplete file xfer.
* @throws FTPException if the FTP server returns an error code.
* @throws IOException if there is a socket or file problem.
* @throws IllegalArgumentException if there are argument related problems.
*
* @see #getConnectionType()
* @see #setConnectionType(short)
* @see #pasv()
* @see #port(HostInfo)
*/
public void store( InputStream inputStream, FTPAbortableTransfer abort )
throws FTPRestartNotSupportedException, FTPException,
IOException, IllegalArgumentException {
store( inputStream, 0, null, null, abort );
}
/**
* Store a file to the FTP server with a specific filename and
* with the ability to abort the data transfer.
* <p>
* Based on what <code>getConnectionType</code> returns, either
* <code>pasv</code> or <code>port</code> will be sent in this routine.
*
* @param inputStream the "local file" input stream you want to upload.
* @param name the name you want to save the file as.
* @param abort an Object that allows for the abortion of the
* <code>store</code>.
*
* @throws FTPRestartNotSupportedException if the FTP server doesn't support
* restarting incomplete file xfer.
* @throws FTPException if the FTP server returns an error code.
* @throws IOException if there is a socket or file problem.
* @throws IllegalArgumentException if there are argument related problems.
*
* @see #getConnectionType()
* @see #setConnectionType(short)
* @see #pasv()
* @see #port(HostInfo)
*/
public void store( InputStream inputStream, String name,
FTPAbortableTransfer abort )
throws FTPRestartNotSupportedException, FTPException,
IOException, IllegalArgumentException {
store( inputStream, 0, name, null, abort );
}
/**
* Store a file to the FTP server with progress information.
* <p>
* Based on what <code>getConnectionType</code> returns, either
* <code>pasv</code> or <code>port</code> will be sent in this routine.
*
* @param file the local file you want to upload.
* @param restartXfer restart an interrupted transfer (if available).
* @param progress a <code>Progress</code> object which is used to update
* upload status.
*
* @throws FTPRestartNotSupportedException if the FTP server doesn't support
* restarting incomplete file xfer.
* @throws FTPException if the FTP server returns an error code.
* @throws IOException if there is a socket or file problem.
* @throws IllegalArgumentException if there are argument related problems.
*
* @see #getConnectionType()
* @see #setConnectionType(short)
* @see #pasv()
* @see #port(HostInfo)
*/
public void store( File file, boolean restartXfer, Progress progress )
throws FTPRestartNotSupportedException, FTPException,
IOException, IllegalArgumentException {
store( file, null, restartXfer, progress, null );
}
/**
* Store a file to the FTP server with a specific filename and
* with progress information.
* <p>
* Based on what <code>getConnectionType</code> returns, either
* <code>pasv</code> or <code>port</code> will be sent in this routine.
*
* @param file the local file you want to upload.
* @param name the name you want to save the file as.
* @param restartXfer restart an interrupted transfer (if available).
* @param progress a <code>Progress</code> object which is used to update
* upload status.
*
* @throws FTPRestartNotSupportedException if the FTP server doesn't support
* restarting incomplete file xfer.
* @throws FTPException if the FTP server returns an error code.
* @throws IOException if there is a socket or file problem.
* @throws IllegalArgumentException if there are argument related problems.
*
* @see #getConnectionType()
* @see #setConnectionType(short)
* @see #pasv()
* @see #port(HostInfo)
*/
public void store( File file, String name, boolean restartXfer,
Progress progress )
throws FTPRestartNotSupportedException, FTPException,
IOException, IllegalArgumentException {
store( file, name, restartXfer, progress, null );
}
/**
* Store a file to the FTP server with progress information.
* <p>
* Based on what <code>getConnectionType</code> returns, either
* <code>pasv</code> or <code>port</code> will be sent in this routine.
*
* @param inputStream the "local file" input stream you want to upload.
* @param localFileSize the size of the "local file".
* @param progress a <code>Progress</code> object which is used to
* update upload status.
*
* @throws FTPRestartNotSupportedException if the FTP server doesn't support
* restarting incomplete file xfer.
* @throws FTPException if the FTP server returns an error code.
* @throws IOException if there is a socket or file problem.
* @throws IllegalArgumentException if there are argument related problems.
*
* @see #getConnectionType()
* @see #setConnectionType(short)
* @see #pasv()
* @see #port(HostInfo)
*/
public void store( InputStream inputStream, long localFileSize,
Progress progress )
throws FTPRestartNotSupportedException, FTPException,
IOException, IllegalArgumentException {
store( inputStream, localFileSize, null, progress, null );
}
/**
* Store a file to the FTP server with a specific filename and
* with progress information.
* <p>
* Based on what <code>getConnectionType</code> returns, either
* <code>pasv</code> or <code>port</code> will be sent in this routine.
*
* @param inputStream the "local file" input stream you want to upload.
* @param localFileSize the size of the "local file".
* @param name the name you want to save the file as.
* @param progress a <code>Progress</code> object which is used to
* update upload status.
*
* @throws FTPRestartNotSupportedException if the FTP server doesn't support
* restarting incomplete file xfer.
* @throws FTPException if the FTP server returns an error code.
* @throws IOException if there is a socket or file problem.
* @throws IllegalArgumentException if there are argument related problems.
*
* @see #getConnectionType()
* @see #setConnectionType(short)
* @see #pasv()
* @see #port(HostInfo)
*/
public void store( InputStream inputStream, long localFileSize, String name,
Progress progress )
throws FTPRestartNotSupportedException, FTPException,
IOException, IllegalArgumentException {
store( inputStream, localFileSize, name, progress, null );
}
/**
* Store a file to the FTP server with progress information and the ability
* to abort the data transfer.
* <p>
* Based on what <code>getConnectionType</code> returns, either
* <code>pasv</code> or <code>port</code> will be sent in this routine.
*
* @param file the local file you want to upload.
* @param restartXfer restart an interrupted transfer (if available).
* @param progress a <code>Progress</code> object which is used to update
* upload status.
* @param abort an Object that allows for the abortion of the
* <code>store</code>.
*
* @throws FTPRestartNotSupportedException if the FTP server doesn't support
* restarting incomplete file xfer.
* @throws FTPException if the FTP server returns an error code.
* @throws IOException if there is a socket or file problem.
* @throws IllegalArgumentException if there are argument related problems.
*
* @see #getConnectionType()
* @see #setConnectionType(short)
* @see #pasv()
* @see #port(HostInfo)
*/
public void store( File file, boolean restartXfer, Progress progress,
FTPAbortableTransfer abort )
throws FTPRestartNotSupportedException, FTPException,
IOException, IllegalArgumentException {
store( file, null, restartXfer, progress, abort );
}
/**
* Store a file to the FTP server with a specific filename and
* progress information and the ability to abort the data transfer.
* <p>
* Based on what <code>getConnectionType</code> returns, either
* <code>pasv</code> or <code>port</code> will be sent in this routine.
*
* @param file the local file you want to upload.
* @param name the name you want to save the file as.
* @param restartXfer restart an interrupted transfer (if available).
* @param progress a <code>Progress</code> object which is used to update
* upload status.
* @param abort an Object that allows for the abortion of the
* <code>store</code>.
*
* @throws FTPRestartNotSupportedException if the FTP server doesn't support
* restarting incomplete file xfer.
* @throws FTPException if the FTP server returns an error code.
* @throws IOException if there is a socket or file problem.
* @throws IllegalArgumentException if there are argument related problems.
*
* @see #getConnectionType()
* @see #setConnectionType(short)
* @see #pasv()
* @see #port(HostInfo)
*/
public void store( File file, String name, boolean restartXfer,
Progress progress, FTPAbortableTransfer abort )
throws FTPRestartNotSupportedException, FTPException,
IOException, IllegalArgumentException {
aboutToTransferData();
_store( file, name, restartXfer, progress, abort );
}
/**
* Store a file to the FTP server with progress information and the ability
* to abort the data transfer.
* <p>
* Based on what <code>getConnectionType</code> returns, either
* <code>pasv</code> or <code>port</code> will be sent in this routine.
*
* @param inputStream the "local file" input stream you want to upload.
* @param localFileSize the size of the "local file".
* @param progress a <code>Progress</code> object which is used to
* update upload status.
* @param abort an Object that allows for the abortion of the
* <code>store</code>.
*
* @throws FTPRestartNotSupportedException if the FTP server doesn't support
* restarting incomplete file xfer.
* @throws FTPException if the FTP server returns an error code.
* @throws IOException if there is a socket or file problem.
* @throws IllegalArgumentException if there are argument related problems.
*
* @see #getConnectionType()
* @see #setConnectionType(short)
* @see #pasv()
* @see #port(HostInfo)
*/
public void store( InputStream inputStream, long localFileSize,
Progress progress, FTPAbortableTransfer abort )
throws FTPRestartNotSupportedException, FTPException,
IOException, IllegalArgumentException {
store( inputStream, localFileSize, null, progress, abort );
}
/**
* Store a file to the FTP server with a specific filename and
* progress information and the ability to abort the data transfer.
* <p>
* Based on what <code>getConnectionType</code> returns, either
* <code>pasv</code> or <code>port</code> will be sent in this routine.
*
* @param inputStream the "local file" input stream you want to upload.
* @param localFileSize the size of the "local file".
* @param name the name you want to save the file as.
* @param progress a <code>Progress</code> object which is used to
* update upload status.
* @param abort an Object that allows for the abortion of the
* <code>store</code>.
*
* @throws FTPRestartNotSupportedException if the FTP server doesn't support
* restarting incomplete file xfer.
* @throws FTPException if the FTP server returns an error code.
* @throws IOException if there is a socket or file problem.
* @throws IllegalArgumentException if there are argument related problems.
*
* @see #getConnectionType()
* @see #setConnectionType(short)
* @see #pasv()
* @see #port(HostInfo)
*/
public void store( InputStream inputStream, long localFileSize, String name,
Progress progress, FTPAbortableTransfer abort )
throws FTPRestartNotSupportedException, FTPException,
IOException, IllegalArgumentException {
aboutToTransferData();
_storeByStream( inputStream, name, false, progress, abort,
-1L, localFileSize );
}
/**
* Append to a file on the FTP server.
* <p>
* Based on what <code>getConnectionType</code> returns, either
* <code>pasv</code> or <code>port</code> will be sent in this routine.
*
* @param file the local file you want to upload.
* @param appendTo the remote file name you want to append to.
*
* @throws FTPException if the FTP server returns an error code.
* @throws IOException if there is a socket or file problem.
* @throws IllegalArgumentException if there are argument related problems.
*
* @see #getConnectionType()
* @see #setConnectionType(short)
* @see #pasv()
* @see #port(HostInfo)
*/
public void append( File file, String appendTo )
throws FTPException, IOException {
append( file, new RemoteFile(appendTo), null, null );
}
/**
* Append to a file on the FTP server.
* <p>
* Based on what <code>getConnectionType</code> returns, either
* <code>pasv</code> or <code>port</code> will be sent in this routine.
*
* @param file the local file you want to upload.
* @param appendTo the <code>RemoteFile</code> you want to append to.
*
* @throws FTPException if the FTP server returns an error code.
* @throws IOException if there is a socket or file problem.
* @throws IllegalArgumentException if there are argument related problems.
*
* @see #getConnectionType()
* @see #setConnectionType(short)
* @see #pasv()
* @see #port(HostInfo)
*/
public void append( File file, RemoteFile appendTo )
throws FTPException, IOException {
append( file, appendTo, null, null );
}
/**
* Append to a file on the FTP server.
* <p>
* Based on what <code>getConnectionType</code> returns, either
* <code>pasv</code> or <code>port</code> will be sent in this routine.
*
* @param inputStream the "local file" stream you want to upload.
* @param appendTo the remote file name you want to append to.
*
* @throws FTPException if the FTP server returns an error code.
* @throws IOException if there is a socket or file problem.
* @throws IllegalArgumentException if there are argument related problems.
*
* @see #getConnectionType()
* @see #setConnectionType(short)
* @see #pasv()
* @see #port(HostInfo)
*/
public void append( InputStream inputStream, String appendTo )
throws FTPException, IOException,
IllegalArgumentException {
append( inputStream, 0, new RemoteFile(appendTo), null,
null );
}
/**
* Append to a file on the FTP server.
* <p>
* Based on what <code>getConnectionType</code> returns, either
* <code>pasv</code> or <code>port</code> will be sent in this routine.
*
* @param inputStream the "local file" stream you want to upload.
* @param appendTo the <code>RemoteFile</code> you want to append to.
*
* @throws FTPException if the FTP server returns an error code.
* @throws IOException if there is a socket or file problem.
* @throws IllegalArgumentException if there are argument related problems.
*
* @see #getConnectionType()
* @see #setConnectionType(short)
* @see #pasv()
* @see #port(HostInfo)
*/
public void append( InputStream inputStream, RemoteFile appendTo )
throws FTPException, IOException,
IllegalArgumentException {
append( inputStream, 0, appendTo, null, null );
}
/**
* Append to a file on the FTP server with the ability to abort the data
* transfer.
* <p>
* Based on what <code>getConnectionType</code> returns, either
* <code>pasv</code> or <code>port</code> will be sent in this routine.
*
* @param file the local file you want to upload.
* @param appendTo the remote file name you want to append to.
* @param abort an Object that allows for the abortion of the
* <code>append</code>.
*
* @throws FTPException if the FTP server returns an error code.
* @throws IOException if there is a socket or file problem.
* @throws IllegalArgumentException if there are argument related problems.
*
* @see #getConnectionType()
* @see #setConnectionType(short)
* @see #pasv()
* @see #port(HostInfo)
*/
public void append( File file, String appendTo, FTPAbortableTransfer abort )
throws FTPException, IOException {
append( file, new RemoteFile(appendTo), null, abort );
}
/**
* Append to a file on the FTP server with the ability to abort the data
* transfer.
* <p>
* Based on what <code>getConnectionType</code> returns, either
* <code>pasv</code> or <code>port</code> will be sent in this routine.
*
* @param file the local file you want to upload.
* @param appendTo the <code>RemoteFile</code> you want to append to.
* @param abort an Object that allows for the abortion of the
* <code>append</code>.
*
* @throws FTPException if the FTP server returns an error code.
* @throws IOException if there is a socket or file problem.
* @throws IllegalArgumentException if there are argument related problems.
*
* @see #getConnectionType()
* @see #setConnectionType(short)
* @see #pasv()
* @see #port(HostInfo)
*/
public void append( File file, RemoteFile appendTo,
FTPAbortableTransfer abort ) throws FTPException,
IOException {
append( file, appendTo, null, abort );
}
/**
* Append to a file on the FTP server with the ability to abort the data
* transfer.
* <p>
* Based on what <code>getConnectionType</code> returns, either
* <code>pasv</code> or <code>port</code> will be sent in this routine.
*
* @param inputStream the "local file" stream you want to upload.
* @param appendTo the remote file name you want to append to.
* @param abort an Object that allows for the abortion of the
* <code>append</code>.
*
* @throws FTPException if the FTP server returns an error code.
* @throws IOException if there is a socket or file problem.
* @throws IllegalArgumentException if there are argument related problems.
*
* @see #getConnectionType()
* @see #setConnectionType(short)
* @see #pasv()
* @see #port(HostInfo)
*/
public void append( InputStream inputStream, String appendTo,
FTPAbortableTransfer abort ) throws FTPException,
IOException,
IllegalArgumentException {
append( inputStream, 0, new RemoteFile(appendTo), null, abort );
}
/**
* Append to a file on the FTP server with the ability to abort the data
* transfer.
* <p>
* Based on what <code>getConnectionType</code> returns, either
* <code>pasv</code> or <code>port</code> will be sent in this routine.
*
* @param inputStream the "local file" stream you want to upload.
* @param appendTo the <code>RemoteFile</code> you want to append to.
* @param abort an Object that allows for the abortion of the
* <code>append</code>.
*
* @throws FTPException if the FTP server returns an error code.
* @throws IOException if there is a socket or file problem.
* @throws IllegalArgumentException if there are argument related problems.
*
* @see #getConnectionType()
* @see #setConnectionType(short)
* @see #pasv()
* @see #port(HostInfo)
*/
public void append( InputStream inputStream, RemoteFile appendTo,
FTPAbortableTransfer abort )
throws FTPException,
IOException,
IllegalArgumentException {
append( inputStream, 0, appendTo, null, abort );
}
/**
* Append to a file on the FTP server with progress information.
* <p>
* Based on what <code>getConnectionType</code> returns, either
* <code>pasv</code> or <code>port</code> will be sent in this routine.
*
* @param file the local file you want to upload.
* @param appendTo the remote file name you want to append to.
* @param progress a <code>Progress</code> object which is used to update
* upload status.
*
* @throws FTPException if the FTP server returns an error code.
* @throws IOException if there is a socket or file problem.
* @throws IllegalArgumentException if there are argument related problems.
*
* @see #getConnectionType()
* @see #setConnectionType(short)
* @see #pasv()
* @see #port(HostInfo)
*/
public void append( File file, String appendTo, Progress progress )
throws FTPException,
IOException,
IllegalArgumentException {
append( file, new RemoteFile(appendTo), progress, null );
}
/**
* Append to a file on the FTP server with progress information.
* <p>
* Based on what <code>getConnectionType</code> returns, either
* <code>pasv</code> or <code>port</code> will be sent in this routine.
*
* @param file the local file you want to upload.
* @param appendTo the <code>RemoteFile</code> you want to append to.
* @param progress a <code>Progress</code> object which is used to update
* upload status.
*
* @throws FTPException if the FTP server returns an error code.
* @throws IOException if there is a socket or file problem.
* @throws IllegalArgumentException if there are argument related problems.
*
* @see #getConnectionType()
* @see #setConnectionType(short)
* @see #pasv()
* @see #port(HostInfo)
*/
public void append( File file, RemoteFile appendTo, Progress progress )
throws FTPException,
IOException,
IllegalArgumentException {
append( file, appendTo, progress, null );
}
/**
* Append to a file on the FTP server with progress information.
* <p>
* Based on what <code>getConnectionType</code> returns, either
* <code>pasv</code> or <code>port</code> will be sent in this routine.
*
* @param inputStream the "local file" stream you want to upload.
* @param localFileSize the size of the "local file"
* @param appendTo the remote file name you want to append to.
* @param progress a <code>Progress</code> object which is used to
* update upload status.
*
* @throws FTPException if the FTP server returns an error code.
* @throws IOException if there is a socket or file problem.
* @throws IllegalArgumentException if there are argument related problems.
*
* @see #getConnectionType()
* @see #setConnectionType(short)
* @see #pasv()
* @see #port(HostInfo)
*/
public void append( InputStream inputStream, long localFileSize,
String appendTo, Progress progress )
throws FTPException,
IOException,
IllegalArgumentException {
append( inputStream, localFileSize, new RemoteFile(appendTo), progress,
null );
}
/**
* Append to a file on the FTP server with progress information.
* <p>
* Based on what <code>getConnectionType</code> returns, either
* <code>pasv</code> or <code>port</code> will be sent in this routine.
*
* @param inputStream the "local file" stream you want to upload.
* @param localFileSize the size of the "local file"
* @param appendTo the <code>RemoteFile</code> you want to append to.
* @param progress a <code>Progress</code> object which is used to
* update upload status.
*
* @throws FTPException if the FTP server returns an error code.
* @throws IOException if there is a socket or file problem.
* @throws IllegalArgumentException if there are argument related problems.
*
* @see #getConnectionType()
* @see #setConnectionType(short)
* @see #pasv()
* @see #port(HostInfo)
*/
public void append( InputStream inputStream, long localFileSize,
RemoteFile appendTo, Progress progress )
throws FTPException,
IOException,
IllegalArgumentException {
append( inputStream, localFileSize, appendTo, progress, null );
}
/**
* Append to a file on the FTP server with progress information and the
* ability to abort the data transfer.
* <p>
* Based on what <code>getConnectionType</code> returns, either
* <code>pasv</code> or <code>port</code> will be sent in this routine.
*
* @param file the local file you want to upload.
* @param appendTo the remote file name you want to append to.
* @param progress a <code>Progress</code> object which is used to update
* upload status.
* @param abort an Object that allows for the abortion of the
* <code>append</code>.
*
* @throws FTPException if the FTP server returns an error code.
* @throws IOException if there is a socket or file problem.
* @throws IllegalArgumentException if there are argument related problems.
*
* @see #getConnectionType()
* @see #setConnectionType(short)
* @see #pasv()
* @see #port(HostInfo)
*/
public void append( File file, String appendTo, Progress progress,
FTPAbortableTransfer abort )
throws FTPException,
IOException,
IllegalArgumentException {
append( file, new RemoteFile(appendTo), progress, abort );
}
/**
* Append to a file on the FTP server with progress information and the
* ability to abort the data transfer.
* <p>
* Based on what <code>getConnectionType</code> returns, either
* <code>pasv</code> or <code>port</code> will be sent in this routine.
*
* @param file the local file you want to upload.
* @param appendTo the <code>RemoteFile</code> you want to append to.
* @param progress a <code>Progress</code> object which is used to update
* upload status.
* @param abort an Object that allows for the abortion of the
* <code>append</code>.
*
* @throws FTPException if the FTP server returns an error code.
* @throws IOException if there is a socket or file problem.
* @throws IllegalArgumentException if there are argument related problems.
*
* @see #getConnectionType()
* @see #setConnectionType(short)
* @see #pasv()
* @see #port(HostInfo)
*/
public void append( File file, RemoteFile appendTo, Progress progress,
FTPAbortableTransfer abort )
throws FTPException,
IOException,
IllegalArgumentException {
aboutToTransferData();
_append( file, appendTo, progress, abort );
}
/**
* Append to a file on the FTP server with progress information and the
* ability to abort the data transfer.
* <p>
* Based on what <code>getConnectionType</code> returns, either
* <code>pasv</code> or <code>port</code> will be sent in this routine.
*
* @param inputStream the "local file" stream you want to upload.
* @param localFileSize the size of the "local file"
* @param appendTo the remote file name you want to append to.
* @param progress a <code>Progress</code> object which is used to
* update upload status.
* @param abort an Object that allows for the abortion of the
* <code>append</code>.
*
* @throws FTPException if the FTP server returns an error code.
* @throws IOException if there is a socket or file problem.
* @throws IllegalArgumentException if there are argument related problems.
*
* @see #getConnectionType()
* @see #setConnectionType(short)
* @see #pasv()
* @see #port(HostInfo)
*/
public void append( InputStream inputStream, long localFileSize,
String appendTo, Progress progress,
FTPAbortableTransfer abort )
throws FTPException,
IOException,
IllegalArgumentException {
append( inputStream, localFileSize, new RemoteFile(appendTo), progress,
abort );
}
/**
* Append to a file on the FTP server with progress information and the
* ability to abort the data transfer.
* <p>
* Based on what <code>getConnectionType</code> returns, either
* <code>pasv</code> or <code>port</code> will be sent in this routine.
*
* @param inputStream the "local file" stream you want to upload.
* @param localFileSize the size of the "local file"
* @param appendTo the <code>RemoteFile</code> you want to append to.
* @param progress a <code>Progress</code> object which is used to
* update upload status.
* @param abort an Object that allows for the abortion of the
* <code>append</code>.
*
* @throws FTPException if the FTP server returns an error code.
* @throws IOException if there is a socket or file problem.
* @throws IllegalArgumentException if there are argument related problems.
*
* @see #getConnectionType()
* @see #setConnectionType(short)
* @see #pasv()
* @see #port(HostInfo)
*/
public void append( InputStream inputStream, long localFileSize,
RemoteFile appendTo, Progress progress,
FTPAbortableTransfer abort )
throws FTPException,
IOException,
IllegalArgumentException {
aboutToTransferData();
_appendByStream( inputStream, appendTo, progress, abort, localFileSize );
}
/**
* Send a raw command to the FTP server.
*
* @param rawCmd the command sent to the FTP server.
*
* @throws FTPException if the FTP server returns an error code.
*/
public void raw( String rawCmd ) throws FTPException {
_raw( rawCmd );
}
/**
* Send a noop command to the FTP server.
*
* @throws FTPException if the FTP server returns an error code.
*/
public void noop() throws FTPException {
_noop();
}
/**
* Abort a data transfer from the FTP server.
*
* @param abort an Object that will has information that
* will allow for the abortion of a transfer.
*
* @throws FTPException if the FTP server returns an error code.
* @throws IllegalArgumentException if there is a problem with the
* <code>abort</code> argument.
*/
public void abort( FTPAbortableTransfer abort )
throws FTPException, IllegalArgumentException {
_abort( abort );
}
/**
* Set server to treat string data in UTF8 format
*
* @param on enable UTF8 support.
*
* @throws FTPException if the FTP server returns an error code.
*/
public void setStringDataAsUTF8( boolean on ) throws FTPException {
if ( systemSupportsOptsUTF8Cmd ) {
getFTPCommand().raw( "CLNT Secure FTP" );
_optsUTF8( on );
sendStringDataUTF8 = on;
}
else
throw new FTPException( "System does not support OPTS UTF8 command." );
}
/**
* Whether or not the server is treating the string data as UTF8
*
* @return true if server treats string as UTF8
*/
public boolean stringDataAsUTF8() { return sendStringDataUTF8; }
/**
* Send a pre transfer command.
*/
private void _pret( int pretType, String arg ) throws FTPException {
try {
String pretMsg = "";
switch( pretType ) {
case PRET.LIST:
pretMsg = "PRET LIST";
break;
case PRET.NLIST:
pretMsg = "PRET NLST";
break;
case PRET.RETRIEVE:
pretMsg = "PRET RETR " + arg;
break;
case PRET.APPEND:
pretMsg = "PRET APPE " + arg;
break;
case PRET.STORE:
pretMsg = "PRET STOR " + arg;
break;
}
if ( pretMsg.length() > 0 ) {
OutputStreamWriter recvCmdWriter = getFTPCommand().recvCmdWriter;
OutputStreamWriter sendCmdWriter = getFTPCommand().sendCmdWriter;
getFTPCommand().recvCmdWriter = null;
getFTPCommand().sendCmdWriter = null;
getFTPCommand().raw( pretMsg );
getFTPCommand().recvCmdWriter = recvCmdWriter;
getFTPCommand().sendCmdWriter = sendCmdWriter;
int code = getFTPCommand().getReplyCode();
if ( code >= 200 && code < 300 ) {
// we're ok
}
else {
systemSupportsPretCmd = false;
}
}
}
catch ( FTPConnectionLostException cle ) {
isConnected = false;
isLoggedIn = false;
throw cle;
}
}
/**
* Send an option command.
*/
private void _optsUTF8( boolean state ) throws FTPException {
try {
String msg = "OPTS UTF8 " + ((state) ? "ON" : "OFF");
getFTPCommand().raw( msg );
int code = getFTPCommand().getReplyCode();
if ( code >= 200 && code < 300 ) {
// we're ok
}
else {
systemSupportsOptsUTF8Cmd = false;
}
}
catch ( FTPConnectionLostException cle ) {
isConnected = false;
isLoggedIn = false;
throw cle;
}
}
/**
* Setup a pasv data connection.
*
* @return a <code>HostInfo<code> object that is used for the data transfer.
*
* @throws FTPException if the FTP server returns an error code.
*/
protected HostInfo pasv() throws FTPException {
HostInfo retInfo = null;
try {
retInfo = getFTPCommand().pasv();
}
catch ( FTPConnectionLostException cle ) {
isConnected = false;
isLoggedIn = false;
throw cle;
}
connectionType = PASV_CONNECTION_TYPE;
return retInfo;
}
/**
* Setup an active data connection.
*
* @param hostInfo a <code>HostInfo</code> object that describes the
* host information used for the data transfer.
*
* @throws FTPException if the FTP server returns an error code.
*/
protected void port( HostInfo hostInfo ) throws FTPException {
try {
getFTPCommand().port( hostInfo );
}
catch ( FTPConnectionLostException cle ) {
isConnected = false;
isLoggedIn = false;
throw cle;
}
connectionType = ACTIVE_CONNECTION_TYPE;
}
/**
* Change to a remote directory on the FTP server.
*
* @param dir the name of the remote directory to change to.
*
* @throws FTPNotADirectoryException if the <code>dir</code> arg is not
* a directory.
* @throws FTPNoSuchFileException if the <code>dir</code> arg could not
* be found on the server.
* @throws FTPException if the FTP server returns an error code.
* @throws IllegalArgumentException if there is a problem with the
* <code>dir</code> argument.
*/
public void chdir( String dir ) throws FTPNotADirectoryException,
FTPNoSuchFileException, FTPException,
IllegalArgumentException {
RemoteFile newDir = new RemoteFile( dir );
chdir( newDir );
}
/**
* Change to a remote directory on the FTP server.
*
* @param dir the remote directory to change to.
*
* @throws FTPNotADirectoryException if the <code>dir</code> arg is not
* a directory.
* @throws FTPNoSuchFileException if the <code>dir</code> arg could not
* be found on the server.
* @throws FTPException if the FTP server returns an error code.
* @throws IllegalArgumentException if there is a problem with the
* <code>dir</code> argument.
*/
public void chdir( RemoteFile dir ) throws FTPNotADirectoryException,
FTPNoSuchFileException, FTPException,
IllegalArgumentException {
_chdir( dir );
}
/**
* Get the server's remote help.
*
* @param item a space-delimited <code>String</code> of items to get
* help on.
*
* @throws FTPException if the FTP server returns an error code.
*/
public String help( String item ) throws FTPException {
return _help( item );
}
/**
* Get the current directory on the FTP server.
*
* @return the path of the current working directory.
*
* @throws FTPException if the FTP server returns an error code.
*/
public String pwd() throws FTPException {
return _pwd();
}
/**
* Set the data transfer mode to ascii.
*
* @throws FTPException if the FTP server returns an error code.
*/
public void ascii() throws FTPException {
_ascii();
}
/**
* Set the data transfer mode to ebcdic.
*
* @throws FTPException if the FTP server returns an error code.
*/
public void ebcdic() throws FTPException {
_ebcdic();
}
/**
* Set the data transfer mode to auto.
*/
public void auto() {
_auto();
}
/**
* Set the data transfer mode to binary (or image).
*
* @throws FTPException if the FTP server returns an error code.
*/
public void binary() throws FTPException {
_binary();
}
/**
* Set mode z (on-the-fly compression) data transfer.
*
* @throws FTPException if the FTP server returns an error code.
*/
public void modeZ() throws FTPException {
_modeZ();
}
/**
* Delete a file from the FTP server.
*
* @param fileName the file to delete on the server.
*
* @throws FTPException if the FTP server returns an error code.
* @throws IllegalArgumentException if there is a problem with the
* <code>fileName</code> argument.
*/
public void delete( String fileName ) throws FTPException,
IllegalArgumentException {
delete( new RemoteFile(fileName) );
}
/**
* Delete a file from the FTP server.
*
* @param fileName the file to delete on the server.
*
* @throws FTPException if the FTP server returns an error code.
* @throws IllegalArgumentException if there is a problem with the
* <code>fileName</code> argument.
*/
public void delete( RemoteFile fileName ) throws FTPException,
IllegalArgumentException {
_delete( fileName );
}
/**
* Rename a file on the FTP server.
*
* @param from the old name of the file.
* @param to the new name of the file.
*
* @throws FTPException if the FTP server returns an error code.
* @throws IllegalArgumentException if there is a problem with the
* <code>from</code> or <code>to</code>
* arguments.
*/
public void rename( String from, String to ) throws FTPException,
IllegalArgumentException {
_rename( from, to );
}
/**
* Get the size of a file on the FTP server.
*
* @param file the name of the file.
*
* @return the size or <code>-1</code> if the size could not be
* determined.
*
* @exception FTPNoSuchFileException if <code>file</code> is not found.
* @exception FTPException if the FTP server returns an error code.
* @exception IllegalArgumentException if <code>file</code> is missing.
*/
public long size( String file ) throws FTPNoSuchFileException, FTPException,
IllegalArgumentException {
return size( new RemoteFile(file) );
}
/**
* Get the size of a file on the FTP server.
*
* @param file the name of the file.
*
* @return the size or <code>-1</code> if the size could not be
* determined.
*
* @exception FTPNoSuchFileException if <code>file</code> is not found.
* @exception FTPException if the FTP server returns an error code.
* @exception IllegalArgumentException if <code>file</code> is missing.
*/
public long size( RemoteFile file ) throws FTPNoSuchFileException,
FTPException,
IllegalArgumentException {
return _size( file );
}
/**
* Get the modification time of a file on the FTP server.
*
* @param file the name of the file.
*
* @return the file time or <code>null</code> if the time could not be
* determined.
*
* @exception FTPNoSuchFileException if <code>file</code> is not found.
* @exception FTPException if the FTP server returns an error code.
* @exception IllegalArgumentException if <code>file</code> is missing.
*/
public Date time( String file ) throws FTPNoSuchFileException,
FTPException,
IllegalArgumentException {
return time( new RemoteFile(file) );
}
/**
* Get the modification time of a file on the FTP server.
*
* @param file the name of the file.
*
* @return the file time or <code>null</code> if the time could not be
* determined.
*
* @exception FTPNoSuchFileException if <code>file</code> is not found.
* @exception FTPException if the FTP server returns an error code.
* @exception IllegalArgumentException if <code>file</code> is missing.
*/
public Date time( RemoteFile file ) throws FTPNoSuchFileException,
FTPException,
IllegalArgumentException {
return _time( file );
}
/**
* Make a new directory on the FTP server.
*
* @param newDir the name of the new directory.
*
* @throws FTPAccessDeniedException if the directory couldn't be created
* due to access restrictions.
* @throws FTPException if the FTP server returns an error code.
* @throws IllegalArgumentException if there is a problem with the
* <code>newDir</code> argument.
*/
public void mkdir( String newDir ) throws FTPException,
FTPAccessDeniedException,
IllegalArgumentException {
_mkdir( newDir );
}
/**
* Remote a directory from the FTP server.
*
* @param dir the directory to delete on the server.
*
* @throws FTPException if the FTP server returns an error code.
* @throws IllegalArgumentException if there is a problem with the
* <code>dir</code> argument.
*/
public void rmdir( String dir ) throws FTPException,
IllegalArgumentException {
RemoteFile rf = new RemoteFile(dir);
rf.setPermissions("d---------");
rmdir( rf );
}
/**
* Remote a directory from the FTP server.
*
* @param dir the directory to delete on the server.
*
* @throws FTPException if the FTP server returns an error code.
* @throws IllegalArgumentException if there is a problem with the
* <code>dir</code> argument.
*/
public void rmdir( RemoteFile dir ) throws FTPException,
IllegalArgumentException {
_rmdir( dir );
}
/**
* Change up one directory on the FTP server.
*
* @throws FTPException if the FTP server returns an error code.
*/
public void cdup() throws FTPException {
_cdup();
}
/**
* Make a new control socket.
*
* @param hostInfo a <code>HostInfo</code> object that
* describes where to make the socket.
*
* @return a new instance of a socket.
*
* @throws IOException if there is a socket problem.
*/
protected Socket makeControlSocket( HostInfo hostInfo ) throws IOException {
return new Socket( hostInfo.getInetAddress(), hostInfo.getPort() );
}
/**
* Make a new data socket.
*
* @param hostInfo a <code>HostInfo</code> object that
* describes where to make the socket.
*
* @return a new instance of a socket.
*
* @throws IOException if there is a socket problem.
*/
protected Socket makeDataSocket( HostInfo hostInfo ) throws IOException {
return new Socket( hostInfo.getInetAddress(), hostInfo.getPort() );
}
/**
* Make a new data server socket.
*
* @param hostInfo a <code>HostInfo</code> object that
* describes where to make the socket.
*
* @return a new instance of a server socket.
*
* @throws IOException if there is a socket problem.
*/
protected ServerSocket makeDataServerSocket( HostInfo hostInfo )
throws IOException {
return new ServerSocket( hostInfo.getPort(), 4, hostInfo.getInetAddress() );
}
/**
* Set a range of ports to use during active (port) data connections.
*
* @param minPort the <code>minPort</code> specifies
* the minimum port used for active transfers
* @param maxPort the <code>maxPort</code> specifies
* the maximum port used for active transfers
*
* @throws Exception if the min/max ports are invalid
*/
public void setActivePortRange( int minPort, int maxPort )
throws Exception {
if ( minPort < 0 || maxPort < 0 || minPort >= maxPort ) {
throw new Exception( "The port range is invalid." );
}
minPortInRange = minPort;
maxPortInRange = maxPort;
lastPortFromRange = (int)(Math.random() * (maxPort - minPort + 1) + minPort);
}
protected int getPortFromRange() {
int result = 0;
if ( lastPortFromRange == 0 ) {
result = 0;
}
else if ( lastPortFromRange + 1 > maxPortInRange ) {
lastPortFromRange = minPortInRange;
result = lastPortFromRange;
}
else {
result = lastPortFromRange++;
}
return result;
}
/**
* The data transfer mode is either auto, ascii, or binary (image).
*
* @return the transfer mode
*
* @see #AUTO_TRANSFER_MODE
* @see #ASCII_TRANSFER_MODE
* @see #BINARY_TRANSFER_MODE
* @see #EBCDIC_TRANSFER_MODE
*/
public short getTransferMode() { return transferMode; }
/**
* The data connection type is either passive or active.
*
* @return the connection type
*
* @see #PASV_CONNECTION_TYPE
* @see #ACTIVE_CONNECTION_TYPE
*/
public int getConnectionType() { return connectionType; }
/**
* Set the data connection type.
*
* @param type the connection type.
*
* @see #PASV_CONNECTION_TYPE
* @see #ACTIVE_CONNECTION_TYPE
*/
public void setConnectionType( short type ) { connectionType = type; }
/**
* Whether or not currently connected.
*
* @return true if connected.
*/
public boolean isConnected() { return isConnected; }
/**
* Whether or not currently logged in.
*
* @return true if logged in.
*/
public boolean isLoggedIn() { return isLoggedIn; }
/**
* Whether or not the server supports restarting broken data transfers.
*
* @return true if supported by server.
*/
public boolean isTransferRestartable() {
return _isTransferRestartable();
}
/**
* Get the hostname of the FTP server.
*
* @return the hostname.
*/
public String getHostName() { return hostName; }
/**
* Set the hostname of the FTP server.
*
* @param hostName the hostname of the FTP server.
*/
public void setHostName( String hostName ) { this.hostName = hostName; }
/**
* Get the port of the FTP server.
*
* @return the port.
*/
public int getPort() { return port; }
/**
* Set the port of the FTP server.
*
* @param port the port of the FTP server.
*/
public void setPort( int port ) { this.port = port; }
/**
* Get the username.
*
* @return the username.
*/
public String getUser() { return user; }
/**
* Set the username.
*
* @param user the username.
*/
public void setUser( String user ) { this.user = user; }
/**
* Get the password.
*
* @return the password.
*/
public String getPassword() { return password; }
/**
* Set the password.
*
* @param password the password.
*/
public void setPassword( String password ) { this.password = password; }
/**
* Get the account name.
*
* @return the account name.
*/
public String getAccount() { return account; }
/**
* Set the account name.
*
* @param account the account name.
*/
public void setAccount( String account ) { this.account = account; }
/**
* Get the control socket.
*
* @return the control socket.
*/
public Socket getControlSocket() { return controlSocket; }
/**
* Set the control socket.
*
* @param controlSocket the control socket.
*/
protected void setControlSocket( Socket controlSocket ) throws IOException {
this.controlSocket = controlSocket;
BufferedReader inputReader =
new BufferedReader(new InputStreamReader(controlSocket.getInputStream()));
PrintWriter outputWriter = new PrintWriter(controlSocket.getOutputStream());
// recreate the FTPCommand object with the new streams
command = makeFTPCommand( inputReader, outputWriter );
}
/**
* Set the stream responsible for handling respones from the FTP server.
*
* @param recvCmdStream the server response stream.
* Pass <code>null</code> to unset this stream.
*/
public void setRecvCmdStream( OutputStream recvCmdStream ) {
this.recvCmdStream = recvCmdStream;
if ( null != getFTPCommand() ) {
getFTPCommand().setRecvCmdStream( recvCmdStream );
}
}
/**
* Set the stream responsible for handling commands sent to the FTP server.
*
* @param sendCmdStream the commands sent stream.
* Pass <code>null</code> to unset this stream.
*/
public void setSendCmdStream( OutputStream sendCmdStream ) {
this.sendCmdStream = sendCmdStream;
if ( null != getFTPCommand() ) {
getFTPCommand().setSendCmdStream( sendCmdStream );
}
}
/**
* Get the server listing style of the FTP server.
*
* @return the list style for the server type
*
* @see FTPServerInfo#LIST_STYLE_UNKNOWN
* @see FTPServerInfo#LIST_STYLE_UNIX
* @see FTPServerInfo#LIST_STYLE_WINDOWS
* @see FTPServerInfo#LIST_STYLE_NETWARE
*/
public short getListStyle() {
return listStyle;
}
/**
* Set the server type to help with the listing style of the FTP server.
*
* @param listStyle the list style for the server type
* (UNIX, NETWARE, Windows, Unknown)
*
* @see FTPServerInfo#LIST_STYLE_UNKNOWN
* @see FTPServerInfo#LIST_STYLE_UNIX
* @see FTPServerInfo#LIST_STYLE_WINDOWS
* @see FTPServerInfo#LIST_STYLE_NETWARE
*/
public void setListStyle( short listStyle ) {
this.listStyle = listStyle;
}
/**
* Set the Socks IV server proxy.
*
* @param host the hostname of the proxy.
* Pass <code>null</code> to unset the proxy.
* @param port the port of the proxy.
*/
public void setSocksIVProxy( String host, int port ) {
_setSocksProxy( host, port );
}
/**
* Set the Socks V server proxy.
*
* @param host the hostname of the proxy.
* Pass <code>null</code> to unset the proxy.
* @param port the port of the proxy.
* @param username the socks username (can be null for no auth)
* @param password the socks password (can be null for no auth)
*/
public void setSocksVProxy( String host, int port, String username,
String password ) {
Properties systemProps = System.getProperties();
if ( null != username ) {
systemProps.put("java.net.socks.username", username);
}
else {
systemProps.remove("java.net.socks.username");
}
if ( null != password ) {
systemProps.put("java.net.socks.password", password);
}
else {
systemProps.remove("java.net.socks.password");
}
_setSocksProxy( host, port );
}
/**
* Get the <code>FTPCommand</code> object.
*
* @return an <code>FTPCommand</code> object.
*/
public FTPCommand getFTPCommand() { return command; }
/**
* Set the <code>FTPCommand</code> object.
*
* @param inputReader the <code>BufferedReader</code> comes from
* the input stream of the control socket.
* @param outputWriter the <code>PrintWriter</code> comes from
* the output stream of the control socket.
*
* @return a new instance of an <code>FTPCommand</code> object.
*/
protected FTPCommand makeFTPCommand( BufferedReader inputReader,
PrintWriter outputWriter ) {
return new FTPCommand( inputReader, outputWriter,
sendCmdStream, recvCmdStream );
}
/** The version of the bean. */
public static String getVersion() {
return VERSION;
}
/** The datestamp of the bean. */
public static String getDateStamp() {
return getDateStampFromFile();
}
/*
*
* The methods below are here for obfuscation purposes.
*
*/
private void _connect() throws FTPConnectException, FTPException,
IOException,
UnknownHostException, IllegalArgumentException {
if ( null == getHostName() )
throw new IllegalArgumentException( "Missing host name" );
HostInfo controlInfo = new HostInfo( getHostName(), getPort() );
try {
if ( debug )
System.out.print( "Making control socket... " );
controlSocket = makeControlSocket( controlInfo );
if ( debug )
System.out.println( "done" );
// set timeout of 60 seconds
controlSocket.setSoTimeout( 60000 );
}
catch ( IOException ioe ) {
throw new FTPConnectException("Connection failed.");
}
BufferedReader inputReader =
new BufferedReader(new InputStreamReader(controlSocket.getInputStream()));
PrintWriter outputWriter = new PrintWriter(controlSocket.getOutputStream());
// get login messages
String banner = "";
StringBuffer fullBanner = new StringBuffer();
boolean continueReadingBanner = false;
do {
try {
if ( debug )
System.out.println( "Reading banner" );
banner = inputReader.readLine();
if ( debug )
System.out.println( banner );
}
catch ( SocketTimeoutException ste ) {
if (inputReader != null)
inputReader.close();
if (outputWriter != null)
outputWriter.close();
controlSocket.close();
controlSocket = null;
throw ste;
}
catch ( IOException ioe ) {
if (inputReader != null)
inputReader.close();
if (outputWriter != null)
outputWriter.close();
if (controlSocket != null)
controlSocket.close();
throw ioe;
}
controlSocket.setSoTimeout( 0 );
continueReadingBanner = false;
if ( null != banner ) {
try {
String sErrorCode = "unknown";
int errorCode = 0;
if ( banner.length() > 3 ) {
sErrorCode = banner.substring(0, 3);
}
try {
errorCode = Integer.parseInt( sErrorCode );
}
catch ( NumberFormatException nfe ) {
// we should always have an error code... but if the banner is
// incorrectly formatted just assume it's ok
errorCode = 220;
continueReadingBanner = true;
}
if ( banner.length() > 3 && errorCode != 220 ) {
String msg = banner.substring(3, banner.length()-1).trim();
throw new FTPConnectException(msg);
}
if ( null != recvCmdStream ) {
Util.outputStreamPrintln(recvCmdStream, banner, true);
}
}
catch ( IOException ioe ) {}
fullBanner.append( banner );
fullBanner.append( "\r\n" );
if ( banner.length() >= 4 && banner.charAt(3) == '-' ) {
continueReadingBanner = true;
}
}
}
while ( null != banner && continueReadingBanner );
if ( null == banner ) {
throw new FTPConnectException("Connection failed.");
}
command = makeFTPCommand( inputReader, outputWriter );
listStyle = FTPServerInfo.lookupListStyleByBanner( fullBanner.toString() );
isConnected = true;
}
private void _login( String user, String pass, String acct )
throws IOException, FTPBadLoginException, FTPConnectException,
FTPException, IllegalArgumentException {
if ( !isConnected ) {
throw new FTPConnectException("Not connected.");
}
try {
sendUserName( user );
}
catch ( FTPNeedPasswordException npe ) {
try {
sendPassword( pass );
}
catch ( FTPNeedAccountException nae ) {
sendAccount( acct );
}
}
catch ( FTPNeedAccountException nae ) {
sendAccount( acct );
}
isLoggedIn = true;
}
private void _logout() throws IOException, FTPException {
try {
getFTPCommand().quit();
}
catch (FTPException fe) {
// if we fail here, let it go... there were bigger issues
}
isConnected = false;
isLoggedIn = false;
getControlSocket().close();
}
private void _sendUserName( String user ) throws FTPNeedPasswordException,
FTPNeedAccountException,
FTPBadLoginException,
FTPException,
IllegalArgumentException {
setUser( user );
try {
getFTPCommand().user( getUser() );
}
catch ( FTPConnectionLostException cle ) {
isConnected = false;
isLoggedIn = false;
throw cle;
}
isLoggedIn = false;
}
private void _sendPassword( String pass ) throws FTPNeedAccountException,
FTPBadLoginException,
FTPException,
IllegalArgumentException {
setPassword( pass );
try {
getFTPCommand().pass( getPassword() );
}
catch ( FTPConnectionLostException cle ) {
isConnected = false;
isLoggedIn = false;
throw cle;
}
isLoggedIn = true;
}
private void _sendAccount( String acct ) throws FTPBadLoginException,
FTPException,
IllegalArgumentException {
setAccount( acct );
try {
getFTPCommand().acct( getAccount() );
}
catch ( FTPConnectionLostException cle ) {
isConnected = false;
isLoggedIn = false;
throw cle;
}
isLoggedIn = true;
}
private RemoteFileList _list( String itemsToList, FTPAbortableTransfer abort,
boolean showHidden )
throws FTPException, IOException {
HostInfo hostInfo = null;
FTPRead data = null;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintWriter pw = new PrintWriter( baos );
if ( !listStyleSet && FTPServerInfo.LIST_STYLE_UNKNOWN == listStyle ) {
try {
String systemType = getFTPCommand().syst();
if ( systemType != null && systemType.length() > 0 ) {
listStyle = FTPServerInfo.lookupListStyleBySyst( systemType );
}
}
catch ( FTPException fe ) {}
finally { listStyleSet = true; }
}
short lastTransferMode = getTransferMode();
ascii();
if ( PASV_CONNECTION_TYPE == connectionType ) {
if ( systemSupportsPretCmd ) {
_pret( PRET.LIST, null );
}
hostInfo = pasv();
Socket dataSocket = makeDataSocket( hostInfo );
data = new FTPRead( dataSocket, pw );
}
else {
hostInfo = new HostInfo( getControlSocket().getLocalAddress(), getPortFromRange() );
ServerSocket dataServerSocket = makeDataServerSocket( hostInfo );
/*
hostInfo = new HostInfo(dataServerSocket.getInetAddress().getLocalHost(),
dataServerSocket.getLocalPort());
*/
hostInfo.setPort( dataServerSocket.getLocalPort() );
port( hostInfo );
data = new FTPRead( dataServerSocket, pw );
}
data.setZLibCompressed( modeZEnabled );
RemoteFileList returnList = new RemoteFileList();
if ( abort != null ) {
data.setControlSocket( getControlSocket() );
abort.setFTPData( data );
}
if ( FTPServerInfo.LIST_STYLE_UNKNOWN != listStyle ) {
try {
getFTPCommand().list( itemsToList, data, showHidden );
}
catch ( FTPConnectionLostException cle ) {
isConnected = false;
isLoggedIn = false;
throw cle;
}
finally {
switch ( lastTransferMode ) {
case ASCII_TRANSFER_MODE:
break;
case EBCDIC_TRANSFER_MODE:
transferMode = EBCDIC_TRANSFER_MODE;
break;
case BINARY_TRANSFER_MODE:
binary();
break;
case AUTO_TRANSFER_MODE:
auto();
break;
}
}
}
else {
try {
getFTPCommand().nlst( itemsToList, data );
}
catch ( FTPConnectionLostException cle ) {
isConnected = false;
isLoggedIn = false;
throw cle;
}
finally {
switch ( lastTransferMode ) {
case ASCII_TRANSFER_MODE:
case EBCDIC_TRANSFER_MODE:
break;
case BINARY_TRANSFER_MODE:
binary();
break;
case AUTO_TRANSFER_MODE:
auto();
break;
}
}
}
REProgram pattern = null;
try {
/*
1 2 3 4 5 6 7 8 9
-r-xr-xr-x 1 owner group 500000000 Apr 9 1999 JWW.TST
d--------- 1 owner group 0 Aug 12 2:23 WUTemp
*/
pattern =
compiler.compile( "^(\\S+)\\s+(\\d+)*\\s?(\\S+)\\s+(\\S+)?\\s.*\\s+" +
"(\\S+)\\s+(\\S+)\\s+(\\d\\d?)\\s+(\\d?\\d:?\\d\\d) (.+)$" );
}
catch ( RESyntaxException rese ) {}
catch ( java.lang.Error je ) {}
unixMatcher.setProgram(pattern);
try {
/*
1 2 3 4 5 6
11108 Feb 24 2009 16:42:59 AESTest.c
*/
pattern =
compiler.compile( "^\\s+(\\S+)\\s+(\\S+)\\s+(\\d\\d?)\\s+(\\d\\d\\d\\d)\\s+(\\d?\\d:\\d\\d:\\d\\d)\\s+(.+)$" );
}
catch ( RESyntaxException rese ) {}
catch ( java.lang.Error je ) {}
enginMatcher.setProgram(pattern);
try {
pattern = compiler.compile( "^(\\S+\\s+\\S+)\\s+(\\S+)\\s+(.+)$" );
}
catch ( RESyntaxException rese ) {}
catch ( java.lang.Error je ) {}
winMatcher.setProgram(pattern);
try {
/*
1 2 3 4 5 6 7
- [RWCEAFMS] user 232960 Jun 16 16:00 File.txt
d [RWCEAFMS] user 512 Jun 21 00:53 Dir
*/
pattern =
compiler.compile( "^(\\S)\\s+\\[RWCEAFMS\\]\\s+(\\S+)\\s+(\\S+)\\s+" +
"(\\S+)\\s+(\\d\\d?)\\s+(\\d?\\d:?\\d\\d) (.+)$" );
}
catch ( RESyntaxException rese ) {}
catch ( java.lang.Error je ) {}
netwareMatcher.setProgram(pattern);
String listEncoding = new String(baos.toString().getBytes("UTF8"), "UTF8");
String listEncodingOverride =
GTOverride.getString("glub.override.list_encoding");
if (listEncodingOverride == null) {
listEncodingOverride =
GTOverride.getString("glub.list_encoding.override");
}
if (listEncodingOverride != null) {
listEncoding =
new String(baos.toString().getBytes(listEncodingOverride),
listEncodingOverride);
}
StringReader stringReader = new StringReader(listEncoding);
BufferedReader listReader = new BufferedReader(stringReader);
String subdir = "";
String line = null;
boolean skipTotalLine = true;
boolean hadErrors = false;
for ( int i = 0; (line = listReader.readLine()) != null; i++ ) {
String mode = null;
int link = 0;
String user = null;
String group = null;
long size = -1;
Calendar date = null;
String month = null;
String day = null;
String year = null;
String file = null;
if ( line.indexOf("file or directory") >= 0 ) {
//return new RemoteFileList();
hadErrors = true;
}
if ( line.indexOf(": Permission denied") >= 0 ) {
throw new FTPPermissionDeniedException();
}
if ( skipTotalLine && line.trim().startsWith("total") ) {
skipTotalLine = false;
continue;
}
else if ( line.trim().length() == 0 ) {
continue;
}
if ( FTPServerInfo.LIST_STYLE_UNIX == listStyle ) {
if ( unixMatcher.match(line) ) {
mode = unixMatcher.getParen(1);
if ( unixMatcher.getParen(2) != null ) {
link = Integer.parseInt(unixMatcher.getParen(2));
}
user = unixMatcher.getParen(3);
group = unixMatcher.getParen(4);
try {
String strSize = unixMatcher.getParen(5);
// strip out any commas in the number (stupid /devices dir)
strSize = Util.searchAndReplace( strSize, ",", "", true );
size = Long.parseLong( strSize );
}
catch ( NumberFormatException nfe ) {
size = -1;
}
month = unixMatcher.getParen(6);
day = unixMatcher.getParen(7);
year = unixMatcher.getParen(8);
file = unixMatcher.getParen(9);
date = Util.getDate( year, month, day );
}
else if ( line.trim().endsWith(":") ) {
line = line.trim();
skipTotalLine = true;
subdir = line.trim().substring(0, line.length() - 1) + "/";
mode = "d?????????";
size = -1;
file = "";
}
else if ( !hadErrors && winMatcher.match(line) ) {
// stupid windows machine not really displaying in unix list format
listStyle = FTPServerInfo.LIST_STYLE_WINDOWS;
}
else if ( !hadErrors && enginMatcher.match(line) ) {
// not standard unix server listing
listStyle = FTPServerInfo.LIST_STYLE_ENGIN;
}
else if ( !hadErrors ) {
// machine not really displaying in unix list format
listStyle = FTPServerInfo.LIST_STYLE_UNKNOWN;
return _list( itemsToList, abort, showHidden );
}
}
if ( FTPServerInfo.LIST_STYLE_ENGIN == listStyle ) {
if ( enginMatcher.match(line) ) {
mode = "-?????????";
try {
size = Long.parseLong( enginMatcher.getParen(1) );
}
catch ( NumberFormatException nfe ) {
size = -1;
}
month = enginMatcher.getParen(2);
day = enginMatcher.getParen(3);
year = enginMatcher.getParen(4);
String timestamp = enginMatcher.getParen(5);
file = enginMatcher.getParen(6);
date = Util.getDate( year, month, day );
}
}
if ( FTPServerInfo.LIST_STYLE_NETWARE == listStyle ) {
if ( netwareMatcher.match(line) ) {
mode = netwareMatcher.getParen(1);
mode += "?????????";
user = netwareMatcher.getParen(2);
try {
String strSize = netwareMatcher.getParen(3);
// strip out any commas in the number (stupid /devices dir)
strSize = Util.searchAndReplace( strSize, ",", "", true );
size = Long.parseLong( strSize );
}
catch ( NumberFormatException nfe ) {
size = -1;
}
month = netwareMatcher.getParen(4);
day = netwareMatcher.getParen(5);
year = netwareMatcher.getParen(6);
file = netwareMatcher.getParen(7);
date = Util.getDate( year, month, day );
}
}
if ( FTPServerInfo.LIST_STYLE_WINDOWS == listStyle ) {
if ( winMatcher.match(line) ) {
date = Util.getWindowsDate( winMatcher.getParen(1) );
String sSize = winMatcher.getParen(2);
if ( sSize.trim().equals("<DIR>") ) {
mode = "d?????????";
size = 0;
}
else {
mode = "-?????????";
try {
size = Long.parseLong(winMatcher.getParen(2));
}
catch ( NumberFormatException nfe ) {
size = -1;
}
}
file = winMatcher.getParen(3);
}
}
if ( !hadErrors && FTPServerInfo.LIST_STYLE_UNIX != listStyle &&
FTPServerInfo.LIST_STYLE_WINDOWS != listStyle &&
FTPServerInfo.LIST_STYLE_ENGIN != listStyle &&
FTPServerInfo.LIST_STYLE_NETWARE != listStyle ) {
file = line;
size = -1;
}
if ( subdir.length() > 0 && file != null && (file.equals(".") || file.equals("..")) ) {
continue;
}
if ( file != null ) {
RemoteFile rf = new RemoteFile(mode, link, user, group,
size, date, subdir + file, line);
returnList.add( rf );
}
}
if ( hadErrors ) {
returnList = new RemoteFileList();
}
else if ( returnList.size() == 0 ) {
returnList.add( new RemoteFile(".") );
}
return returnList;
}
private void _retrieve( RemoteFile remoteFile, File outputFile,
boolean restartXfer,
Progress progress, FTPAbortableTransfer abort )
throws FTPRestartNotSupportedException,
FTPException, IOException {
if ( outputFile == null ) {
String newOutFile = remoteFile.getFileName();
StringTokenizer tok = new StringTokenizer( newOutFile, "/" );
while ( tok.hasMoreTokens() ) {
newOutFile = tok.nextToken();
}
outputFile = new File( newOutFile );
}
FileOutputStream fos = null;
RandomAccessFile raf = null;
if ( !systemSupportsRestCmd ) {
restartXfer = false;
}
long localFileSize = 0;
if ( restartXfer ) {
raf = new RandomAccessFile( outputFile, "rw" );
localFileSize = raf.length();
if ( remoteFile.getFileSize() == localFileSize ) {
localFileSize = 0;
}
raf.setLength( localFileSize );
/*
// give a little room for error
if ( localFileSize > 3 ) {
localFileSize -= 3;
}
*/
raf.seek( localFileSize );
fos = new FileOutputStream( raf.getFD() );
}
else {
fos = new FileOutputStream( outputFile );
}
try {
_retrieveByStream( remoteFile, fos, restartXfer, progress, abort,
localFileSize );
}
finally {
if ( null != raf ) {
try {
raf.close();
}
catch ( IOException ioe ) {}
}
}
}
private void _retrieveByStream( RemoteFile remoteFile, OutputStream os,
boolean restartXfer, Progress progress,
FTPAbortableTransfer abort,
long localFileSize )
throws FTPRestartNotSupportedException,
FTPException, IOException {
if ( os == null ) {
throw new IllegalArgumentException("Missing file output stream.");
}
String remoteFileName = remoteFile.getFileName();
long remoteFileSize = remoteFile.getFileSize();
if ( !systemSupportsRestCmd ) {
restartXfer = false;
}
try {
if ( restartXfer && systemSupportsFileSizeCmd && remoteFileSize == -1 ) {
remoteFileSize = getFTPCommand().size( remoteFileName );
}
}
catch ( FTPNoSuchFileException nsfe ) {}
catch ( FTPException fe ) {
systemSupportsFileSizeCmd = false;
}
FTPRead data = null;
HostInfo hostInfo = null;
short xferMode = transferMode;
String encodingOverride =
GTOverride.getString("glub.xfer_encoding.override");
if ( AUTO_TRANSFER_MODE == transferMode ) {
if ( FileTypeDecider.isAscii(remoteFileName) ) {
xferMode = ASCII_TRANSFER_MODE;
ascii();
}
else {
xferMode = BINARY_TRANSFER_MODE;
binary();
}
transferMode = AUTO_TRANSFER_MODE;
}
if ( PASV_CONNECTION_TYPE == connectionType ) {
if ( systemSupportsPretCmd ) {
_pret( PRET.RETRIEVE, remoteFileName );
}
hostInfo = pasv();
Socket dataSocket = makeDataSocket( hostInfo );
if ( ASCII_TRANSFER_MODE == xferMode ) {
data = new FTPRead( dataSocket, new PrintWriter(os),
progress, localFileSize, remoteFileSize, encodingOverride );
}
else if ( EBCDIC_TRANSFER_MODE == xferMode ) {
data = new FTPRead( dataSocket, new PrintWriter(os),
progress, localFileSize, remoteFileSize, "Cp1047" );
}
else {
data = new FTPRead( dataSocket, os, progress, localFileSize,
remoteFileSize );
}
}
else {
hostInfo = new HostInfo( getControlSocket().getLocalAddress(), getPortFromRange() );
ServerSocket dataServerSocket = makeDataServerSocket( hostInfo );
/*
hostInfo = new HostInfo(dataServerSocket.getInetAddress().getLocalHost(),
dataServerSocket.getLocalPort());
*/
hostInfo.setPort( dataServerSocket.getLocalPort() );
port( hostInfo );
if ( ASCII_TRANSFER_MODE == xferMode ) {
data = new FTPRead( dataServerSocket, new PrintWriter(os),
progress, localFileSize, remoteFileSize, encodingOverride );
}
else if ( EBCDIC_TRANSFER_MODE == xferMode ) {
data = new FTPRead( dataServerSocket, new PrintWriter(os),
progress, localFileSize, remoteFileSize, "Cp1047" );
}
else {
data = new FTPRead( dataServerSocket, os, progress, localFileSize,
remoteFileSize );
}
}
data.setZLibCompressed( modeZEnabled );
if ( abort != null ) {
data.setControlSocket( getControlSocket() );
abort.setFTPData( data );
}
if ( restartXfer ) {
try {
getFTPCommand().rest( localFileSize );
}
catch ( FTPConnectionLostException cle ) {
try {
os.close();
}
catch ( IOException ioe ) {}
isConnected = false;
isLoggedIn = false;
throw cle;
}
catch ( FTPException fe ) {
try {
os.close();
}
catch ( IOException ioe ) {}
systemSupportsRestCmd = false;
throw new FTPRestartNotSupportedException( fe.getMessage() );
}
}
if ( null != remoteFile.getMetaData("pwd") ) {
remoteFileName = remoteFile.getMetaData("pwd") + remoteFileName;
}
try {
getFTPCommand().retrieve( remoteFileName, data );
}
catch ( FTPConnectionLostException cle ) {
isConnected = false;
isLoggedIn = false;
throw cle;
}
finally {
try {
os.close();
}
catch ( IOException ioe ) {}
}
}
private void _store( File file, String name, boolean restartXfer,
Progress progress, FTPAbortableTransfer abort )
throws FTPRestartNotSupportedException, FTPException,
IOException, IllegalArgumentException {
if ( file == null ) {
throw new IllegalArgumentException("Missing local file.");
}
FileInputStream fis = null;
long remoteFileSize = 0;
String remoteFileName = name;
if ( null == remoteFileName ) {
remoteFileName = file.getName();
}
RandomAccessFile raf = null;
if ( !systemSupportsRestCmd ) {
restartXfer = false;
}
if ( restartXfer ) {
raf = new RandomAccessFile( file, "r" );
try {
if ( systemSupportsFileSizeCmd ) {
remoteFileSize = getFTPCommand().size( remoteFileName );
}
}
catch ( FTPNoSuchFileException fnfe ) {
// if the file is not found, that's ok... there's just nothing
// to restart
remoteFileSize = 0;
}
catch ( FTPConnectionLostException cle ) {
isConnected = false;
isLoggedIn = false;
raf.close();
throw cle;
}
catch ( FTPException fe ) {
systemSupportsFileSizeCmd = false;
}
if ( remoteFileSize >= file.length() ) {
remoteFileSize = 0;
}
/*
else if ( remoteFileSize > 3 ) {
// give a little room for error
remoteFileSize -= 3;
}
*/
raf.seek( remoteFileSize );
fis = new FileInputStream( raf.getFD() );
}
else {
fis = new FileInputStream( file );
}
try {
_storeByStream( fis, remoteFileName, restartXfer, progress, abort,
remoteFileSize, file.length() );
}
finally {
try {
if ( null != raf ) {
raf.close();
}
}
catch ( IOException ioe ) {}
}
}
private void _storeByStream( InputStream is, String remoteFileName,
boolean restartXfer, Progress progress,
FTPAbortableTransfer abort, long remoteFileSize,
long localFileSize )
throws FTPRestartNotSupportedException,
FTPException, IOException,
IllegalArgumentException {
HostInfo hostInfo = null;
FTPWrite data = null;
String encodingOverride =
GTOverride.getString("glub.xfer_encoding.override");
if ( is == null ) {
throw new IllegalArgumentException("Missing file input stream.");
}
if ( !systemSupportsRestCmd ) {
restartXfer = false;
}
if ( !restartXfer ) {
remoteFileSize = 0;
}
if ( systemSupportsFileSizeCmd && null != progress &&
remoteFileSize == -1 ) {
try {
remoteFileSize = getFTPCommand().size( remoteFileName );
}
catch ( FTPNoSuchFileException fnfe ) {
// if the file is not found, that's ok
remoteFileSize = 0;
}
catch ( FTPConnectionLostException cle ) {
isConnected = false;
isLoggedIn = false;
throw cle;
}
catch ( FTPException fe ) {
systemSupportsFileSizeCmd = false;
}
}
short xferMode = transferMode;
if ( AUTO_TRANSFER_MODE == transferMode ) {
if ( FileTypeDecider.isAscii(remoteFileName) ) {
xferMode = ASCII_TRANSFER_MODE;
ascii();
}
else {
xferMode = BINARY_TRANSFER_MODE;
binary();
}
transferMode = AUTO_TRANSFER_MODE;
}
if ( PASV_CONNECTION_TYPE == connectionType ) {
if ( systemSupportsPretCmd ) {
_pret( PRET.STORE, remoteFileName );
}
hostInfo = pasv();
Socket dataSocket = makeDataSocket( hostInfo );
if ( ASCII_TRANSFER_MODE == xferMode ) {
data = new FTPWrite( dataSocket,
new BufferedReader(new InputStreamReader(is)),
progress, remoteFileSize, localFileSize, encodingOverride );
}
else if ( EBCDIC_TRANSFER_MODE == xferMode ) {
data = new FTPWrite( dataSocket,
new BufferedReader(new InputStreamReader(is)),
progress, remoteFileSize, localFileSize, "Cp1047" );
}
else {
data = new FTPWrite( dataSocket, is, progress,
remoteFileSize, localFileSize );
}
}
else {
hostInfo = new HostInfo( getControlSocket().getLocalAddress(), getPortFromRange() );
ServerSocket dataServerSocket = makeDataServerSocket( hostInfo );
/*
hostInfo = new HostInfo(dataServerSocket.getInetAddress().getLocalHost(),
dataServerSocket.getLocalPort());
*/
hostInfo.setPort( dataServerSocket.getLocalPort() );
port( hostInfo );
if ( ASCII_TRANSFER_MODE == xferMode ) {
data = new FTPWrite( dataServerSocket,
new BufferedReader(new InputStreamReader(is)),
progress, remoteFileSize, localFileSize, encodingOverride );
}
else if ( EBCDIC_TRANSFER_MODE == xferMode ) {
data = new FTPWrite( dataServerSocket,
new BufferedReader(new InputStreamReader(is)),
progress, remoteFileSize, localFileSize, "Cp1047" );
}
else {
data = new FTPWrite( dataServerSocket, is, progress,
remoteFileSize, localFileSize );
}
}
data.setZLibCompressed( modeZEnabled );
if ( abort != null ) {
data.setControlSocket( getControlSocket() );
abort.setFTPData( data );
}
if ( remoteFileSize <= 0 ) {
restartXfer = false;
}
if ( restartXfer ) {
try {
getFTPCommand().rest( remoteFileSize );
}
catch ( FTPConnectionLostException cle ) {
try {
is.close();
}
catch ( IOException ioe ) {}
isConnected = false;
isLoggedIn = false;
throw cle;
}
catch ( FTPException fe ) {
try {
is.close();
}
catch ( IOException ioe ) {}
systemSupportsRestCmd = false;
throw new FTPRestartNotSupportedException( fe.getMessage() );
}
}
try {
if ( restartXfer ) {
getFTPCommand().append( remoteFileName, data );
}
else {
getFTPCommand().store( remoteFileName, data );
}
}
catch ( FTPConnectionLostException cle ) {
isConnected = false;
isLoggedIn = false;
throw cle;
}
finally {
try {
is.close();
}
catch ( IOException ioe ) {}
}
}
private void _append( File file, RemoteFile appendTo, Progress progress,
FTPAbortableTransfer abort )
throws FTPException,
IOException,
IllegalArgumentException {
if ( file == null ) {
throw new IllegalArgumentException("Missing local file.");
}
else if ( appendTo == null ||
appendTo.getFileName().length() == 0 ) {
throw new IllegalArgumentException("Missing file to append to.");
}
FileInputStream fis = new FileInputStream( file );
_appendByStream( fis, appendTo, progress, abort, file.length() );
}
private void _appendByStream( InputStream is, RemoteFile appendTo,
Progress progress, FTPAbortableTransfer abort,
long localFileLength )
throws FTPException,
IOException,
IllegalArgumentException {
if ( is == null ) {
throw new IllegalArgumentException("Missing input stream.");
}
HostInfo hostInfo = null;
FTPWrite data = null;
String encodingOverride =
GTOverride.getString("glub.xfer_encoding.override");
short xferMode = transferMode;
if ( AUTO_TRANSFER_MODE == transferMode ) {
if ( FileTypeDecider.isAscii(appendTo.getFileName()) ) {
xferMode = ASCII_TRANSFER_MODE;
ascii();
}
else {
xferMode = BINARY_TRANSFER_MODE;
binary();
}
transferMode = AUTO_TRANSFER_MODE;
}
if ( PASV_CONNECTION_TYPE == connectionType ) {
if ( systemSupportsPretCmd ) {
_pret( PRET.APPEND, appendTo.getFileName() );
}
hostInfo = pasv();
Socket dataSocket = makeDataSocket( hostInfo );
if ( ASCII_TRANSFER_MODE == xferMode ) {
data = new FTPWrite( dataSocket,
new BufferedReader(new InputStreamReader(is)),
progress, 0, localFileLength, encodingOverride );
}
else if ( EBCDIC_TRANSFER_MODE == xferMode ) {
data = new FTPWrite( dataSocket,
new BufferedReader(new InputStreamReader(is)),
progress, 0, localFileLength, "Cp1047" );
}
else {
data = new FTPWrite( dataSocket, is, progress, 0, localFileLength );
}
}
else {
hostInfo = new HostInfo( getControlSocket().getLocalAddress(), getPortFromRange() );
ServerSocket dataServerSocket = makeDataServerSocket( hostInfo );
/*
hostInfo = new HostInfo(dataServerSocket.getInetAddress().getLocalHost(),
dataServerSocket.getLocalPort());
*/
hostInfo.setPort( dataServerSocket.getLocalPort() );
port( hostInfo );
if ( ASCII_TRANSFER_MODE == xferMode ) {
data = new FTPWrite( dataServerSocket,
new BufferedReader(new InputStreamReader(is)),
progress, 0, localFileLength, encodingOverride );
}
else if ( EBCDIC_TRANSFER_MODE == xferMode ) {
data = new FTPWrite( dataServerSocket,
new BufferedReader(new InputStreamReader(is)),
progress, 0, localFileLength, "Cp1047" );
}
else {
data = new FTPWrite( dataServerSocket, is, progress, 0,
localFileLength );
}
}
data.setZLibCompressed( modeZEnabled );
if ( abort != null ) {
data.setControlSocket( getControlSocket() );
abort.setFTPData( data );
}
try {
getFTPCommand().append( appendTo.getFileName(), data );
}
catch ( FTPConnectionLostException cle ) {
isConnected = false;
isLoggedIn = false;
throw cle;
}
}
private void _raw( String rawCmd ) throws FTPException {
try {
getFTPCommand().raw( rawCmd );
}
catch ( FTPConnectionLostException cle ) {
isConnected = false;
isLoggedIn = false;
throw cle;
}
}
private void _noop() throws FTPException {
try {
getFTPCommand().noop();
}
catch ( FTPConnectionLostException cle ) {
isConnected = false;
isLoggedIn = false;
throw cle;
}
}
private void _abort( FTPAbortableTransfer abort )
throws FTPException, IllegalArgumentException {
if ( abort == null ) {
throw new IllegalArgumentException( "Missing item to abort." );
}
FTPData data = abort.getFTPData();
if ( data == null ) {
throw new IllegalArgumentException( "Missing FTPData to abort." );
}
try {
getFTPCommand().abort( abort.getFTPData() );
}
catch ( FTPConnectionLostException cle ) {
isConnected = false;
isLoggedIn = false;
throw cle;
}
}
private void _chdir( RemoteFile dir ) throws FTPNotADirectoryException,
FTPNoSuchFileException,
FTPPermissionDeniedException,
FTPException,
IllegalArgumentException {
String fullDir = dir.getFileName();
if ( null != dir.getMetaData("pwd") ) {
fullDir = dir.getMetaData("pwd") + fullDir;
}
try {
getFTPCommand().chdir( fullDir );
}
catch ( FTPConnectionLostException cle ) {
isConnected = false;
isLoggedIn = false;
throw cle;
}
}
private String _help( String item ) throws FTPException {
try {
return getFTPCommand().help( item );
}
catch ( FTPConnectionLostException cle ) {
isConnected = false;
isLoggedIn = false;
throw cle;
}
}
private String _pwd() throws FTPException {
try {
return getFTPCommand().pwd();
}
catch ( FTPConnectionLostException cle ) {
isConnected = false;
isLoggedIn = false;
throw cle;
}
}
private void _ascii() throws FTPException {
try {
getFTPCommand().type( 'A' );
}
catch ( FTPConnectionLostException cle ) {
isConnected = false;
isLoggedIn = false;
throw cle;
}
transferMode = ASCII_TRANSFER_MODE;
}
private void _ebcdic() throws FTPException {
OutputStream holdStream = recvCmdStream;
getFTPCommand().setRecvCmdStream( null );
_ascii();
getFTPCommand().setRecvCmdStream( holdStream );
transferMode = EBCDIC_TRANSFER_MODE;
if ( null != recvCmdStream ) {
try {
Util.outputStreamPrintln(recvCmdStream, "200 Type set to EBCDIC.", true);
} catch (IOException ioe){}
}
}
private void _auto() {
transferMode = AUTO_TRANSFER_MODE;
if ( null != recvCmdStream ) {
try {
Util.outputStreamPrintln(recvCmdStream, "TYPE O", false);
Util.outputStreamPrintln(recvCmdStream, "200 Type set to Auto.", true);
} catch (IOException ioe){}
}
}
private void _binary() throws FTPException {
try {
getFTPCommand().type( 'I' );
}
catch ( FTPConnectionLostException cle ) {
isConnected = false;
isLoggedIn = false;
throw cle;
}
transferMode = BINARY_TRANSFER_MODE;
}
private void _modeZ() throws FTPException {
try {
getFTPCommand().modeZ();
modeZEnabled = true;
}
catch ( FTPConnectionLostException cle ) {
isConnected = false;
isLoggedIn = false;
modeZEnabled = false;
throw cle;
}
catch ( FTPException e ) {
modeZEnabled = false;
throw e;
}
}
private void _delete( RemoteFile file ) throws FTPException,
IllegalArgumentException {
String fileName = file.getFileName();
if ( null != file.getMetaData("pwd") ) {
fileName = file.getMetaData("pwd") + fileName;
}
try {
getFTPCommand().delete( fileName );
}
catch ( FTPConnectionLostException cle ) {
isConnected = false;
isLoggedIn = false;
throw cle;
}
}
private void _rename( String from, String to ) throws FTPException,
IllegalArgumentException {
try {
getFTPCommand().rename( from, to );
}
catch ( FTPConnectionLostException cle ) {
isConnected = false;
isLoggedIn = false;
throw cle;
}
}
private long _size( RemoteFile file ) throws FTPNoSuchFileException,
FTPException,
IllegalArgumentException {
if ( file.getFileSize() >= 0 ) {
return file.getFileSize();
}
try {
return getFTPCommand().size( file.getFileName() );
}
catch ( FTPConnectionLostException cle ) {
isConnected = false;
isLoggedIn = false;
throw cle;
}
}
private Date _time( RemoteFile file ) throws FTPNoSuchFileException,
FTPException,
IllegalArgumentException {
try {
String fileName = file.getFileName();
Date result = getFTPCommand().mdtm( fileName );
return result;
}
catch ( FTPConnectionLostException cle ) {
isConnected = false;
isLoggedIn = false;
throw cle;
}
}
private void _mkdir( String newDir ) throws FTPException,
FTPAccessDeniedException,
IllegalArgumentException {
try {
getFTPCommand().mkdir( newDir );
}
catch ( FTPConnectionLostException cle ) {
isConnected = false;
isLoggedIn = false;
throw cle;
}
}
private void _rmdir( RemoteFile dir ) throws FTPException,
IllegalArgumentException {
if ( !dir.isDirectory() && !dir.isLink() ) {
throw new IllegalArgumentException("File is not a directory.");
}
String dirName = dir.getFileName();
if ( null != dir.getMetaData("pwd") ) {
dirName = dir.getMetaData("pwd") + dirName;
}
try {
getFTPCommand().rmdir( dirName );
}
catch ( FTPConnectionLostException cle ) {
isConnected = false;
isLoggedIn = false;
throw cle;
}
}
private void _cdup() throws FTPException {
try {
getFTPCommand().cdup();
}
catch ( FTPConnectionLostException cle ) {
isConnected = false;
isLoggedIn = false;
throw cle;
}
}
private boolean _isTransferRestartable() {
boolean result = false;
try {
getFTPCommand().rest(0);
result = true;
}
catch ( FTPException fe ) {}
return result;
}
private void _setSocksProxy( String host, int port ) {
Properties systemProps = System.getProperties();
if ( host != null && host.trim().length() > 0 ) {
systemProps.put("socksProxySet", "true");
systemProps.put("socksProxyHost", host.trim());
systemProps.put("socksProxyPort", (new Integer(port)).toString());
}
else {
systemProps.put("socksProxySet", "false");
systemProps.remove("socksProxyHost");
systemProps.remove("socksProxyPort");
}
System.setProperties( systemProps );
}
/*
private boolean verifyJar() {
// until the url for the jar can be retrieved from a war file, we should
// not do this - gary - 8/13/2003
// java 1.2 doesn't support rsa signed jar files
if (System.getProperty("java.version").startsWith("1.2")) {
return true;
}
else {
return JarUtil.verifyJar( this.getClass(), "Secure FTP Bean" );
}
return true;
}
*/
/**
* Forces passive data transfers to use the control socket IP address.
*
* @param on true if to use control socket IP, false if off.
*/
public void forcePasvToUseControlIP( boolean on ) {
forcePasvToUseControlIP = on;
}
/**
* Called before data transfers begin.
*/
protected void aboutToTransferData() {
getFTPCommand().forcePasvToUseControlIP( forcePasvToUseControlIP );
if ( forcePasvToUseControlIP ) {
String controlIP = getControlSocket().getInetAddress().getHostAddress();
getFTPCommand().setControlIP( controlIP );
}
}
private static String getDateStampFromFile() {
if ( DATESTAMP == null ) {
Class c = FTP.class;
InputStream buildFileStream = c.getResourceAsStream("build.info");
if ( buildFileStream != null ) {
try {
Properties buildProp = new Properties();
buildProp.load( buildFileStream );
DATESTAMP = buildProp.getProperty("build.date");
}
catch ( Exception ioe ) { DATESTAMP = "unknown"; }
}
else {
DATESTAMP = "unknown";
}
}
return DATESTAMP;
}
}
class FileTypeDecider {
private static String[] textExtensions = {
"txt", "html", "htm", "xhtml", "pl", "sh", "xml", "java", "xsd", "bat",
"cpp", "c", "hpp", "h", "vb", "ccs", "dss", "lsp", "pgr", "htc", "rtx",
"tsv", "wml", "wmls", "hdml", "etx", "talk", "spc", "xsl", "sgml", "sgm",
"rtf", "asc", "bas", "xaml", "php", "properties"
};
private static Hashtable text = setupHash();
private static Hashtable setupHash() {
text = new Hashtable();
for (int i = 0; i < textExtensions.length; i++) {
text.put( textExtensions[i], new Boolean(true) );
}
return text;
}
private static String getFileExtension( String filename ) {
int index = filename.lastIndexOf('.');
if (index >= 0)
return filename.substring(index + 1);
else
return null;
}
public static boolean isAscii( String filename ) {
String temp = getFileExtension( filename );
return (temp != null && text.get(temp) != null);
}
}