    1   /* ClientFTP.java
    2    *
    3    * $Id: ClientFTP.java 4573 2006-08-31 22:31:23Z paul_jack $
    4    *
    5    * Created on Jun 5, 2003
    6    *
    7    * Copyright (C) 2003 Internet Archive.
    8    *
    9    * This file is part of the Heritrix web crawler (crawler.archive.org).
    10   *
    11   * Heritrix is free software; you can redistribute it and/or modify
    12   * it under the terms of the GNU Lesser Public License as published by
    13   * the Free Software Foundation; either version 2.1 of the License, or
    14   * any later version.
    15   *
    16   * Heritrix is distributed in the hope that it will be useful,
    17   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    18   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    19   * GNU Lesser Public License for more details.
    20   *
    21   * You should have received a copy of the GNU Lesser Public License
    22   * along with Heritrix; if not, write to the Free Software
    23   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    24   */
    25  package org.archive.net;
    26
    27
    28  import java.io.IOException;
    29  import java.net.Socket;
    30
    31  import org.apache.commons.net.ftp.FTPClient;
    32  import org.apache.commons.net.ftp.FTPReply;
    33
    34
    35  /***
    36   * Client for FTP operations.  This class is necessary only because the
    37   * {@link #_openDataConnection_(int, String)} method is protected in
    38   * the superclass, and we need to call it directly to handle directory
    39   * listings.  (The code that provides directory listings in the
    40   * superclass doesn't scale:  It reads the entire directory into
    41   * an in-memory list).
    42   *
    43   * <p>Additionally, "strict" methods are provided for the other operations
    44   * we use.  Maddeningly, the superclass never raises exceptions.  If an
    45   * FTP operation fails, then the superclass methods generally return false.
    46   * A developer then needs to check the {@link FTP#getReplyCode()}
    47   * method to see what actually went wrong.  The "strict" methods provided
    48   * by this class invoke the superclass method, check if the success flag
    49   * is false, and then raise an {@link FTPException} with the value of
    50   * {@link FTP#getReplyCode()}.
    51   *
    52   * @author pjack
    53   */
    54  public class ClientFTP extends FTPClient {
    55
    56
    57      /***
    58       * Constructs a new <code>ClientFTP</code>.
    59       */
    60      public ClientFTP() {
    61      }
    62
    63
    64      /***
    65       * Connects to the FTP server at the given host and port.
    66       *
    67       * @param host    the host of the FTP server to connect to
    68       * @param port    the port the FTP server listens on
    69       * @throws IOException  if the connection cannot be made due to IO error
    70       * @throws FTPException  if the server refuses the connection
    71       */
    72      public void connectStrict(String host, int port) throws IOException {
    73          this.connect(host, port);
    74          int reply = this.getReplyCode();
    75          if (!FTPReply.isPositiveCompletion(reply)) {
    76              throw new FTPException(reply);
    77          }
    78      }
    79
    80
    81      /***
    82       * Login to the FTP server with the given username and password.
    83       *
    84       * @param user   the username to login under
    85       * @param pass   the password to use
    86       * @throws IOException   if a network error occurs
    87       * @throws FTPException  if the login is rejected by the server
    88       * @throws org.apache.commons.net.ftp.FTPConnectionClosedException
    89       *   if the FTP server prematurely closes the connection (for
    90       *   instance, if the client was idle for too long)
    91       */
    92      public void loginStrict(String user, String pass) throws IOException {
    93          boolean r = this.login(user, pass);
    94          if (!r) {
    95              throw new FTPException(this.getReplyCode());
    96          }
    97      }
    98
    99
    100     /***
    101      * Tells the FTP server to send binary files.
    102      *
    103      * @throws IOException   if a network error occurs
    104      * @throws FTPException  if the server rejects the command
    105      * @throws org.apache.commons.net.ftp.FTPConnectionClosedException
    106      *   if the FTP server prematurely closes the connection (for
    107      *   instance, if the client was idle for too long)
    108      */
    109     public void setBinary() throws IOException {
    110         boolean r = super.setFileType(BINARY_FILE_TYPE);
    111         if (!r) {
    112             throw new FTPException(getReplyCode());
    113         }
    114     }
    115
    116
    117     /***
    118      * Opens a data connection.
    119      *
    120      * @param command  the data command (eg, RETR or LIST)
    121      * @param path     the path of the file to retrieve
    122      * @return  the socket to read data from
    123      * @throws  IOException  if a network error occurs
    124      * @throws  FTPException  if a protocol error occurs
    125      */
    126     public Socket openDataConnection(int command, String path)
    127     throws IOException {
    128         Socket socket = _openDataConnection_(command, path);
    129         if (socket == null) {
    130             throw new FTPException(this.getReplyCode());
    131         }
    132         return socket;
    133     }
    134
    135
    136 }