2005-12-08 07:13:07 +00:00

370 lines
8.8 KiB
Java

/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
package org.alfresco.filesys.ftp;
import java.net.*;
import java.io.*;
/**
* FTP Data Session Class
* <p>
* A data connection is made when a PORT or PASV FTP command is received on the main control
* session.
* <p>
* The PORT command will actively connect to the specified address/port on the client. The PASV
* command will create a listening socket and wait for the client to connect.
*
* @author GKSpencer
*/
public class FTPDataSession implements Runnable
{
// FTP session that this data connection is associated with
private FTPSrvSession m_cmdSess;
// Connection details for active connection
private InetAddress m_clientAddr;
private int m_clientPort;
// Local port to use
private int m_localPort;
// Active data session socket
private Socket m_activeSock;
// Passive data session socket
private ServerSocket m_passiveSock;
// Adapter to bind the passive socket to
private InetAddress m_bindAddr;
// Transfer in progress and abort file transfer flags
private boolean m_transfer;
private boolean m_abort;
// Send/receive data byte count
private long m_bytCount;
/**
* Class constructor
* <p>
* Create a data connection that listens for an incoming connection.
*
* @param sess FTPSrvSession
* @exception IOException
*/
protected FTPDataSession(FTPSrvSession sess) throws IOException
{
// Set the associated command session
m_cmdSess = sess;
// Create a server socket to listen for the incoming connection
m_passiveSock = new ServerSocket(0, 1, null);
}
/**
* Class constructor
* <p>
* Create a data connection that listens for an incoming connection on the specified network
* adapter and local port.
*
* @param sess FTPSrvSession
* @param localPort int
* @param addr InetAddress
* @exception IOException
*/
protected FTPDataSession(FTPSrvSession sess, int localPort, InetAddress bindAddr) throws IOException
{
// Set the associated command session
m_cmdSess = sess;
// Create a server socket to listen for the incoming connection on the specified network
// adapter
m_localPort = localPort;
m_passiveSock = new ServerSocket(localPort, 1, bindAddr);
}
/**
* Class constructor
* <p>
* Create a data connection that listens for an incoming connection on the specified network
* adapter.
*
* @param sess FTPSrvSession
* @param addr InetAddress
* @exception IOException
*/
protected FTPDataSession(FTPSrvSession sess, InetAddress bindAddr) throws IOException
{
// Set the associated command session
m_cmdSess = sess;
// Create a server socket to listen for the incoming connection on the specified network
// adapter
m_passiveSock = new ServerSocket(0, 1, bindAddr);
}
/**
* Class constructor
* <p>
* Create a data connection to the specified client address and port.
*
* @param sess FTPSrvSession
* @param addr InetAddress
* @param port int
*/
protected FTPDataSession(FTPSrvSession sess, InetAddress addr, int port)
{
// Set the associated command session
m_cmdSess = sess;
// Save the client address/port details, the actual connection will be made later when
// the client requests/sends a file
m_clientAddr = addr;
m_clientPort = port;
}
/**
* Class constructor
* <p>
* Create a data connection to the specified client address and port, using the specified local
* port.
*
* @param sess FTPSrvSession
* @param localPort int
* @param addr InetAddress
* @param port int
*/
protected FTPDataSession(FTPSrvSession sess, int localPort, InetAddress addr, int port)
{
// Set the associated command session
m_cmdSess = sess;
// Save the local port
m_localPort = localPort;
// Save the client address/port details, the actual connection will be made later when
// the client requests/sends a file
m_clientAddr = addr;
m_clientPort = port;
}
/**
* Return the associated command session
*
* @return FTPSrvSession
*/
public final FTPSrvSession getCommandSession()
{
return m_cmdSess;
}
/**
* Return the local port
*
* @return int
*/
public final int getLocalPort()
{
if (m_passiveSock != null)
return m_passiveSock.getLocalPort();
else if (m_activeSock != null)
return m_activeSock.getLocalPort();
return -1;
}
/**
* Return the port that was allocated to the data session
*
* @return int
*/
protected final int getAllocatedPort()
{
return m_localPort;
}
/**
* Return the passive server socket address
*
* @return InetAddress
*/
public final InetAddress getPassiveAddress()
{
if (m_passiveSock != null)
{
// Get the server socket local address
InetAddress addr = m_passiveSock.getInetAddress();
if (addr.getHostAddress().compareTo("0.0.0.0") == 0)
{
try
{
addr = InetAddress.getLocalHost();
}
catch (UnknownHostException ex)
{
}
}
return addr;
}
return null;
}
/**
* Return the passive server socket port
*
* @return int
*/
public final int getPassivePort()
{
if (m_passiveSock != null)
return m_passiveSock.getLocalPort();
return -1;
}
/**
* Determine if a file transfer is active
*
* @return boolean
*/
public final boolean isTransferActive()
{
return m_transfer;
}
/**
* Abort an in progress file transfer
*/
public final void abortTransfer()
{
m_abort = true;
}
/**
* Return the transfer byte count
*
* @return long
*/
public final synchronized long getTransferByteCount()
{
return m_bytCount;
}
/**
* Return the data socket connected to the client
*
* @return Socket
* @exception IOException
*/
public final Socket getSocket() throws IOException
{
// Check for a passive connection, get the incoming socket connection
if (m_passiveSock != null)
m_activeSock = m_passiveSock.accept();
else
{
if (m_localPort != 0)
{
// Use the specified local port
m_activeSock = new Socket(m_clientAddr, m_clientPort, null, m_localPort);
}
else
m_activeSock = new Socket(m_clientAddr, m_clientPort);
}
// Set the socket to close immediately
m_activeSock.setSoLinger(false, 0);
m_activeSock.setTcpNoDelay(true);
// Return the data socket
return m_activeSock;
}
/**
* Close the data connection
*/
public final void closeSession()
{
// If the data connection is active close it
if (m_activeSock != null)
{
try
{
m_activeSock.close();
}
catch (Exception ex)
{
}
m_activeSock = null;
}
// Close the listening socket for a passive connection
if (m_passiveSock != null)
{
try
{
m_passiveSock.close();
}
catch (Exception ex)
{
}
m_passiveSock = null;
}
}
/**
* Run a file send/receive in a seperate thread
*/
public void run()
{
}
}