/* * 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 *
* A data connection is made when a PORT or PASV FTP command is received on the main control * session. *
* 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 *
* 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 *
* 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 *
* 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 *
* 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 *
* 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() { } }