View Javadoc

    1   /*
    2    * Copyright 2001-2005 The Apache Software Foundation
    3    *
    4    * Licensed under the Apache License, Version 2.0 (the "License");
    5    * you may not use this file except in compliance with the License.
    6    * You may obtain a copy of the License at
    7    *
    8    *     http://www.apache.org/licenses/LICENSE-2.0
    9    *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  package org.apache.commons.net.ftp;
    17  import java.io.BufferedInputStream;
    18  import java.io.BufferedOutputStream;
    19  import java.io.BufferedReader;
    20  import java.io.IOException;
    21  import java.io.InputStream;
    22  import java.io.InputStreamReader;
    23  import java.io.OutputStream;
    24  import java.net.InetAddress;
    25  import java.net.ServerSocket;
    26  import java.net.Socket;
    27  import java.util.Vector;
    28
    29  import org.apache.commons.net.MalformedServerReplyException;
    30  import org.apache.commons.net.ftp.parser.DefaultFTPFileEntryParserFactory;
    31  import org.apache.commons.net.ftp.parser.FTPFileEntryParserFactory;
    32  import org.apache.commons.net.ftp.parser.ParserInitializationException;
    33  import org.apache.commons.net.io.CopyStreamEvent;
    34  import org.apache.commons.net.io.CopyStreamException;
    35  import org.apache.commons.net.io.FromNetASCIIInputStream;
    36  import org.apache.commons.net.io.ToNetASCIIOutputStream;
    37  import org.apache.commons.net.io.Util;
    38
    39  /****
    40   * FTPClient encapsulates all the functionality necessary to store and
    41   * retrieve files from an FTP server.  This class takes care of all
    42   * low level details of interacting with an FTP server and provides
    43   * a convenient higher level interface.  As with all classes derived
    44   * from {@link org.apache.commons.net.SocketClient},
    45   * you must first connect to the server with
    46   * {@link org.apache.commons.net.SocketClient#connect  connect }
    47   * before doing anything, and finally
    48   * {@link org.apache.commons.net.SocketClient#disconnect  disconnect }
    49   * after you're completely finished interacting with the server.
    50   * Then you need to check the FTP reply code to see if the connection
    51   * was successful.  For example:
    52   * <pre>
    53   *    boolean error = false;
    54   *    try {
    55   *      int reply;
    56   *      ftp.connect("ftp.foobar.com");
    57   *      System.out.println("Connected to " + server + ".");
    58   *      System.out.print(ftp.getReplyString());
    59   *
    60   *      // After connection attempt, you should check the reply code to verify
    61   *      // success.
    62   *      reply = ftp.getReplyCode();
    63   *
    64   *      if(!FTPReply.isPositiveCompletion(reply)) {
    65   *        ftp.disconnect();
    66   *        System.err.println("FTP server refused connection.");
    67   *        System.exit(1);
    68   *      }
    69   *      ... // transfer files
    70   *      ftp.logout();
    71   *    } catch(IOException e) {
    72   *      error = true;
    73   *      e.printStackTrace();
    74   *    } finally {
    75   *      if(ftp.isConnected()) {
    76   *        try {
    77   *          ftp.disconnect();
    78   *        } catch(IOException ioe) {
    79   *          // do nothing
    80   *        }
    81   *      }
    82   *      System.exit(error ? 1 : 0);
    83   *    }
    84   * </pre>
    85   * <p>
    86   * Immediately after connecting is the only real time you need to check the
    87   * reply code (because connect is of type void).  The convention for all the
    88   * FTP command methods in FTPClient is such that they either return a
    89   * boolean value or some other value.
    90   * The boolean methods return true on a successful completion reply from
    91   * the FTP server and false on a reply resulting in an error condition or
    92   * failure.  The methods returning a value other than boolean return a value
    93   * containing the higher level data produced by the FTP command, or null if a
    94   * reply resulted in an error condition or failure.  If you want to access
    95   * the exact FTP reply code causing a success or failure, you must call
    96   * {@link org.apache.commons.net.ftp.FTP#getReplyCode  getReplyCode } after
    97   * a success or failure.
    98   * <p>
    99   * The default settings for FTPClient are for it to use
    100  * <code> FTP.ASCII_FILE_TYPE </code>,
    101  * <code> FTP.NON_PRINT_TEXT_FORMAT </code>,
    102  * <code> FTP.STREAM_TRANSFER_MODE </code>, and
    103  * <code> FTP.FILE_STRUCTURE </code>.  The only file types directly supported
    104  * are <code> FTP.ASCII_FILE_TYPE </code> and
    105  * <code> FTP.IMAGE_FILE_TYPE </code> (which is the same as
    106  * <code> FTP.BINARY_FILE_TYPE </code>).  Because there are at lest 4
    107  * different EBCDIC encodings, we have opted not to provide direct support
    108  * for EBCDIC.  To transfer EBCDIC and other unsupported file types you
    109  * must create your own filter InputStreams and OutputStreams and wrap
    110  * them around the streams returned or required by the FTPClient methods.
    111  * FTPClient uses the {@link ToNetASCIIOutputStream NetASCII}
    112  * filter streams to provide transparent handling of ASCII files.  We will
    113  * consider incorporating EBCDIC support if there is enough demand.
    114  * <p>
    115  * <code> FTP.NON_PRINT_TEXT_FORMAT </code>,
    116  * <code> FTP.STREAM_TRANSFER_MODE </code>, and
    117  * <code> FTP.FILE_STRUCTURE </code> are the only supported formats,
    118  * transfer modes, and file structures.
    119  * <p>
    120  * Because the handling of sockets on different platforms can differ
    121  * significantly, the FTPClient automatically issues a new PORT command
    122  * prior to every transfer requiring that the server connect to the client's
    123  * data port.  This ensures identical problem-free behavior on Windows, Unix,
    124  * and Macintosh platforms.  Additionally, it relieves programmers from
    125  * having to issue the PORT command themselves and dealing with platform
    126  * dependent issues.
    127  * <p>
    128  * Additionally, for security purposes, all data connections to the
    129  * client are verified to ensure that they originated from the intended
    130  * party (host and port).  If a data connection is initiated by an unexpected
    131  * party, the command will close the socket and throw an IOException.  You
    132  * may disable this behavior with
    133  * {@link #setRemoteVerificationEnabled setRemoteVerificationEnabled()}.
    134  * <p>
    135  * You should keep in mind that the FTP server may choose to prematurely
    136  * close a connection if the client has been idle for longer than a
    137  * given time period (usually 900 seconds).  The FTPClient class will detect a
    138  * premature FTP server connection closing when it receives a
    139  * {@link org.apache.commons.net.ftp.FTPReply#SERVICE_NOT_AVAILABLE FTPReply.SERVICE_NOT_AVAILABLE }
    140  *  response to a command.
    141  * When that occurs, the FTP class method encountering that reply will throw
    142  * an {@link org.apache.commons.net.ftp.FTPConnectionClosedException}
    143  * .
    144  * <code>FTPConnectionClosedException</code>
    145  * is a subclass of <code> IOException </code> and therefore need not be
    146  * caught separately, but if you are going to catch it separately, its
    147  * catch block must appear before the more general <code> IOException </code>
    148  * catch block.  When you encounter an
    149  * {@link org.apache.commons.net.ftp.FTPConnectionClosedException}
    150  * , you must disconnect the connection with
    151  * {@link #disconnect  disconnect() } to properly clean up the
    152  * system resources used by FTPClient.  Before disconnecting, you may check the
    153  * last reply code and text with
    154  * {@link org.apache.commons.net.ftp.FTP#getReplyCode  getReplyCode },
    155  * {@link org.apache.commons.net.ftp.FTP#getReplyString  getReplyString },
    156  * and
    157  * {@link org.apache.commons.net.ftp.FTP#getReplyStrings  getReplyStrings}.
    158  * You may avoid server disconnections while the client is idle by
    159  * periodicaly sending NOOP commands to the server.
    160  * <p>
    161  * Rather than list it separately for each method, we mention here that
    162  * every method communicating with the server and throwing an IOException
    163  * can also throw a
    164  * {@link org.apache.commons.net.MalformedServerReplyException}
    165  * , which is a subclass
    166  * of IOException.  A MalformedServerReplyException will be thrown when
    167  * the reply received from the server deviates enough from the protocol
    168  * specification that it cannot be interpreted in a useful manner despite
    169  * attempts to be as lenient as possible.
    170  * <p>
    171  * Listing API Examples
    172  * Both paged and unpaged examples of directory listings are available,
    173  * as follows:
    174  * <p>
    175  * Unpaged (whole list) access, using a parser accessible by auto-detect:
    176  * <pre>
    177  *    FTPClient f=FTPClient();
    178  *    f.connect(server);
    179  *    f.login(username, password);
    180  *    FTPFile[] files = listFiles(directory);
    181  * </pre>
    182  * <p>
    183  * Paged access, using a parser not accessible by auto-detect.  The class
    184  * defined in the first parameter of initateListParsing should be derived
    185  * from org.apache.commons.net.FTPFileEntryParser:
    186  * <pre>
    187  *    FTPClient f=FTPClient();
    188  *    f.connect(server);
    189  *    f.login(username, password);
    190  *    FTPListParseEngine engine =
    191  *       f.initiateListParsing("com.whatever.YourOwnParser", directory);
    192  *
    193  *    while (engine.hasNext()) {
    194  *       FTPFile[] files = engine.getNext(25);  // "page size" you want
    195  *       //do whatever you want with these files, display them, etc.
    196  *       //expensive FTPFile objects not created until needed.
    197  *    }
    198  * </pre>
    199  * <p>
    200  * Paged access, using a parser accessible by auto-detect:
    201  * <pre>
    202  *    FTPClient f=FTPClient();
    203  *    f.connect(server);
    204  *    f.login(username, password);
    205  *    FTPListParseEngine engine = f.initiateListParsing(directory);
    206  *
    207  *    while (engine.hasNext()) {
    208  *       FTPFile[] files = engine.getNext(25);  // "page size" you want
    209  *       //do whatever you want with these files, display them, etc.
    210  *       //expensive FTPFile objects not created until needed.
    211  *    }
    212  * </pre>
    213  * <p>
    214  * For examples of using FTPClient on servers whose directory listings
    215  * <ul>
    216  * <li>use languages other than English</li>
    217  * <li>use date formats other than the American English "standard" <code>MM d yyyy</code></li>
    218  * <li>are in different timezones and you need accurate timestamps for dependency checking
    219  *     as in Ant</li>
    220  * </ul>see {@link  FTPClientConfig  FTPClientConfig}.
    221  * <p>
    222  * NOTE: If you experience problems with unwanted firing of <pre>setSoTimeout()</pre>
    223  * during periods of client inactivity, this can be alleviated by calling <pre>setReaderThread(false)</pre>.
    224  * For more details, see <a href="http://issues.apache.org/bugzilla/show_bug.cgi?id=31122">this thread</a>.
    225  * </p>
    226  * <p>
    227  * @author Daniel F. Savarese
    228  * @see FTP
    229  * @see FTPConnectionClosedException
    230  * @see FTPFileEntryParser
    231  * @see FTPFileEntryParserFactory
    232  * @see DefaultFTPFileEntryParserFactory
    233  * @see FTPClientConfig
    234  * @see org.apache.commons.net.MalformedServerReplyException
    235  **/
    236 public class FTPClient extends FTP
    237 implements Configurable
    238 {
    239     /****
    240      * A constant indicating the FTP session is expecting all transfers
    241      * to occur between the client (local) and server and that the server
    242      * should connect to the client's data port to initiate a data transfer.
    243      * This is the default data connection mode when and FTPClient instance
    244      * is created.
    245      ***/
    246     public static final int ACTIVE_LOCAL_DATA_CONNECTION_MODE = 0;
    247     /****
    248      * A constant indicating the FTP session is expecting all transfers
    249      * to occur between two remote servers and that the server
    250      * the client is connected to should connect to the other server's
    251      * data port to initiate a data transfer.
    252      ***/
    253     public static final int ACTIVE_REMOTE_DATA_CONNECTION_MODE = 1;
    254     /****
    255      * A constant indicating the FTP session is expecting all transfers
    256      * to occur between the client (local) and server and that the server
    257      * is in passive mode, requiring the client to connect to the
    258      * server's data port to initiate a transfer.
    259      ***/
    260     public static final int PASSIVE_LOCAL_DATA_CONNECTION_MODE = 2;
    261     /****
    262      * A constant indicating the FTP session is expecting all transfers
    263      * to occur between two remote servers and that the server
    264      * the client is connected to is in passive mode, requiring the other
    265      * server to connect to the first server's data port to initiate a data
    266      * transfer.
    267      ***/
    268     public static final int PASSIVE_REMOTE_DATA_CONNECTION_MODE = 3;
    269
    270     private int __dataConnectionMode, __dataTimeout;
    271     private int __passivePort;
    272     private String __passiveHost;
    273     private int __fileType, __fileFormat, __fileStructure, __fileTransferMode;
    274     private boolean __remoteVerificationEnabled;
    275     private long __restartOffset;
    276     private FTPFileEntryParserFactory __parserFactory;
    277     private int __bufferSize;
    278
    279     // __systemName is a cached value that should not be referenced directly
    280     // except when assigned in getSystemName and __initDefaults.
    281     private String __systemName;
    282
    283     // __entryParser is a cached value that should not be referenced directly
    284     // except when assigned in listFiles(String, String) and __initDefaults.
    285     private FTPFileEntryParser __entryParser;
    286
    287     private FTPClientConfig __configuration;
    288
    289     /****
    290      * Default FTPClient constructor.  Creates a new FTPClient instance
    291      * with the data connection mode set to
    292      * <code> ACTIVE_LOCAL_DATA_CONNECTION_MODE </code>, the file type
    293      * set to <code> FTP.ASCII_FILE_TYPE </code>, the
    294      * file format set to <code> FTP.NON_PRINT_TEXT_FORMAT </code>,
    295      * the file structure set to <code> FTP.FILE_STRUCTURE </code>, and
    296      * the transfer mode set to <code> FTP.STREAM_TRANSFER_MODE </code>.
    297      ***/
    298     public FTPClient()
    299     {
    300         __initDefaults();
    301         __dataTimeout = -1;
    302         __remoteVerificationEnabled = true;
    303         __parserFactory = new DefaultFTPFileEntryParserFactory();
    304         __configuration      = null;
    305     }
    306
    307
    308     private void __initDefaults()
    309     {
    310         __dataConnectionMode = ACTIVE_LOCAL_DATA_CONNECTION_MODE;
    311         __passiveHost        = null;
    312         __passivePort        = -1;
    313         __fileType           = FTP.ASCII_FILE_TYPE;
    314         __fileStructure      = FTP.FILE_STRUCTURE;
    315         __fileFormat         = FTP.NON_PRINT_TEXT_FORMAT;
    316         __fileTransferMode   = FTP.STREAM_TRANSFER_MODE;
    317         __restartOffset      = 0;
    318         __systemName         = null;
    319         __entryParser        = null;
    320         __bufferSize 		 = Util.DEFAULT_COPY_BUFFER_SIZE;
    321     }
    322
    323     private String __parsePathname(String reply)
    324     {
    325         int begin, end;
    326
    327         begin = reply.indexOf('"') + 1;
    328         end = reply.indexOf('"', begin);
    329
    330         return reply.substring(begin, end);
    331     }
    332
    333
    334     private void __parsePassiveModeReply(String reply)
    335     throws MalformedServerReplyException
    336     {
    337         int i, index, lastIndex;
    338         String octet1, octet2;
    339         StringBuffer host;
    340
    341         reply = reply.substring(reply.indexOf('(') + 1,
    342                                 reply.indexOf(')')).trim();
    343
    344         host = new StringBuffer(24);
    345         lastIndex = 0;
    346         index = reply.indexOf(',');
    347         host.append(reply.substring(lastIndex, index));
    348
    349         for (i = 0; i < 3; i++)
    350         {
    351             host.append('.');
    352             lastIndex = index + 1;
    353             index = reply.indexOf(',', lastIndex);
    354             host.append(reply.substring(lastIndex, index));
    355         }
    356
    357         lastIndex = index + 1;
    358         index = reply.indexOf(',', lastIndex);
    359
    360         octet1 = reply.substring(lastIndex, index);
    361         octet2 = reply.substring(index + 1);
    362
    363         // index and lastIndex now used as temporaries
    364         try
    365         {
    366             index = Integer.parseInt(octet1);
    367             lastIndex = Integer.parseInt(octet2);
    368         }
    369         catch (NumberFormatException e)
    370         {
    371             throw new MalformedServerReplyException(
    372                 "Could not parse passive host information.\nServer Reply: " + reply);
    373         }
    374
    375         index <<= 8;
    376         index |= lastIndex;
    377
    378         __passiveHost = host.toString();
    379         __passivePort = index;
    380     }
    381
    382     private boolean __storeFile(int command, String remote, InputStream local)
    383     throws IOException
    384     {
    385         OutputStream output;
    386         Socket socket;
    387
    388         if ((socket = _openDataConnection_(command, remote)) == null)
    389             return false;
    390
    391         output = new BufferedOutputStream(socket.getOutputStream(),
    392                                           getBufferSize()
    393                                           );
    394         if (__fileType == ASCII_FILE_TYPE)
    395             output = new ToNetASCIIOutputStream(output);
    396         // Treat everything else as binary for now
    397         try
    398         {
    399             Util.copyStream(local, output, getBufferSize(),
    400                             CopyStreamEvent.UNKNOWN_STREAM_SIZE, null,
    401                             false);
    402         }
    403         catch (IOException e)
    404         {
    405             try
    406             {
    407                 socket.close();
    408             }
    409             catch (IOException f)
    410             {}
    411             throw e;
    412         }
    413         output.close();
    414         socket.close();
    415         return completePendingCommand();
    416     }
    417
    418     private OutputStream __storeFileStream(int command, String remote)
    419     throws IOException
    420     {
    421         OutputStream output;
    422         Socket socket;
    423
    424         if ((socket = _openDataConnection_(command, remote)) == null)
    425             return null;
    426
    427         output = socket.getOutputStream();
    428         if (__fileType == ASCII_FILE_TYPE) {
    429           // We buffer ascii transfers because the buffering has to
    430           // be interposed between ToNetASCIIOutputSream and the underlying
    431           // socket output stream.  We don't buffer binary transfers
    432           // because we don't want to impose a buffering policy on the
    433           // programmer if possible.  Programmers can decide on their
    434           // own if they want to wrap the SocketOutputStream we return
    435           // for file types other than ASCII.
    436           output = new BufferedOutputStream(output,
    437                                             getBufferSize());
    438           output = new ToNetASCIIOutputStream(output);
    439
    440         }
    441         return new org.apache.commons.net.io.SocketOutputStream(socket, output);
    442     }
    443
    444
    445     /***
    446      * Establishes a data connection with the FTP server, returning
    447      * a Socket for the connection if successful.  If a restart
    448      * offset has been set with {@link #setRestartOffset(long)},
    449      * a REST command is issued to the server with the offset as
    450      * an argument before establishing the data connection.  Active
    451      * mode connections also cause a local PORT command to be issued.
    452      * <p>
    453      * @param command  The text representation of the FTP command to send.
    454      * @param arg The arguments to the FTP command.  If this parameter is
    455      *             set to null, then the command is sent with no argument.
    456      * @return A Socket corresponding to the established data connection.
    457      *         Null is returned if an FTP protocol error is reported at
    458      *         any point during the establishment and initialization of
    459      *         the connection.
    460      * @exception IOException  If an I/O error occurs while either sending a
    461      *      command to the server or receiving a reply from the server.
    462      */
    463     protected Socket _openDataConnection_(int command, String arg)
    464       throws IOException
    465     {
    466         Socket socket;
    467
    468         if (__dataConnectionMode != ACTIVE_LOCAL_DATA_CONNECTION_MODE &&
    469                 __dataConnectionMode != PASSIVE_LOCAL_DATA_CONNECTION_MODE)
    470             return null;
    471
    472         if (__dataConnectionMode == ACTIVE_LOCAL_DATA_CONNECTION_MODE)
    473         {
    474             ServerSocket server;
    475             server = _socketFactory_.createServerSocket(0, 1, getLocalAddress());
    476
    477             if (!FTPReply.isPositiveCompletion(port(getLocalAddress(),
    478                                                     server.getLocalPort())))
    479             {
    480                 server.close();
    481                 return null;
    482             }
    483
    484             if ((__restartOffset > 0) && !restart(__restartOffset))
    485             {
    486                 server.close();
    487                 return null;
    488             }
    489
    490             if (!FTPReply.isPositivePreliminary(sendCommand(command, arg)))
    491             {
    492                 server.close();
    493                 return null;
    494             }
    495
    496             // For now, let's just use the data timeout value for waiting for
    497             // the data connection.  It may be desirable to let this be a
    498             // separately configurable value.  In any case, we really want
    499             // to allow preventing the accept from blocking indefinitely.
    500             if (__dataTimeout >= 0)
    501                 server.setSoTimeout(__dataTimeout);
    502             socket = server.accept();
    503             server.close();
    504         }
    505         else
    506         { // We must be in PASSIVE_LOCAL_DATA_CONNECTION_MODE
    507
    508             if (pasv() != FTPReply.ENTERING_PASSIVE_MODE)
    509                 return null;
    510
    511             __parsePassiveModeReply((String)_replyLines.elementAt(0));
    512
    513             socket = _socketFactory_.createSocket(__passiveHost, __passivePort);
    514             if ((__restartOffset > 0) && !restart(__restartOffset))
    515             {
    516                 socket.close();
    517                 return null;
    518             }
    519
    520             if (!FTPReply.isPositivePreliminary(sendCommand(command, arg)))
    521             {
    522                 socket.close();
    523                 return null;
    524             }
    525         }
    526
    527         if (__remoteVerificationEnabled && !verifyRemote(socket))
    528         {
    529             InetAddress host1, host2;
    530
    531             host1 = socket.getInetAddress();
    532             host2 = getRemoteAddress();
    533
    534             socket.close();
    535
    536             throw new IOException(
    537                 "Host attempting data connection " + host1.getHostAddress() +
    538                 " is not same as server " + host2.getHostAddress());
    539         }
    540
    541         if (__dataTimeout >= 0)
    542             socket.setSoTimeout(__dataTimeout);
    543
    544         return socket;
    545     }
    546
    547
    548     protected void _connectAction_() throws IOException
    549     {
    550         super._connectAction_();
    551         __initDefaults();
    552     }
    553
    554
    555     /****
    556      * Sets the timeout in milliseconds to use when reading from the
    557      * data connection.  This timeout will be set immediately after
    558      * opening the data connection.
    559      * <p>
    560      * @param  timeout The default timeout in milliseconds that is used when
    561      *        opening a data connection socket.
    562      ***/
    563     public void setDataTimeout(int timeout)
    564     {
    565         __dataTimeout = timeout;
    566     }
    567
    568     /***
    569      * set the factory used for parser creation to the supplied factory object.
    570      *
    571      * @param parserFactory
    572      *               factory object used to create FTPFileEntryParsers
    573      *
    574      * @see org.apache.commons.net.ftp.parser.FTPFileEntryParserFactory
    575      * @see org.apache.commons.net.ftp.parser.DefaultFTPFileEntryParserFactory
    576      */
    577     public void setParserFactory(FTPFileEntryParserFactory parserFactory) {
    578         __parserFactory = parserFactory;
    579     }
    580
    581
    582     /****
    583      * Closes the connection to the FTP server and restores
    584      * connection parameters to the default values.
    585      * <p>
    586      * @exception IOException If an error occurs while disconnecting.
    587      ***/
    588     public void disconnect() throws IOException
    589     {
    590         super.disconnect();
    591         __initDefaults();
    592     }
    593
    594
    595     /****
    596      * Enable or disable verification that the remote host taking part
    597      * of a data connection is the same as the host to which the control
    598      * connection is attached.  The default is for verification to be
    599      * enabled.  You may set this value at any time, whether the
    600      * FTPClient is currently connected or not.
    601      * <p>
    602      * @param enable True to enable verification, false to disable verification.
    603      ***/
    604     public void setRemoteVerificationEnabled(boolean enable)
    605     {
    606         __remoteVerificationEnabled = enable;
    607     }
    608
    609     /****
    610      * Return whether or not verification of the remote host participating
    611      * in data connections is enabled.  The default behavior is for
    612      * verification to be enabled.
    613      * <p>
    614      * @return True if verification is enabled, false if not.
    615      ***/
    616     public boolean isRemoteVerificationEnabled()
    617     {
    618         return __remoteVerificationEnabled;
    619     }
    620
    621     /****
    622      * Login to the FTP server using the provided username and password.
    623      * <p>
    624      * @param username The username to login under.
    625      * @param password The password to use.
    626      * @return True if successfully completed, false if not.
    627      * @exception FTPConnectionClosedException
    628      *      If the FTP server prematurely closes the connection as a result
    629      *      of the client being idle or some other reason causing the server
    630      *      to send FTP reply code 421.  This exception may be caught either
    631      *      as an IOException or independently as itself.
    632      * @exception IOException  If an I/O error occurs while either sending a
    633      *      command to the server or receiving a reply from the server.
    634      ***/
    635     public boolean login(String username, String password) throws IOException
    636     {
    637         user(username);
    638
    639         if (FTPReply.isPositiveCompletion(_replyCode))
    640             return true;
    641
    642         // If we get here, we either have an error code, or an intermmediate
    643         // reply requesting password.
    644         if (!FTPReply.isPositiveIntermediate(_replyCode))
    645             return false;
    646
    647         return FTPReply.isPositiveCompletion(pass(password));
    648     }
    649
    650
    651     /****
    652      * Login to the FTP server using the provided username, password,
    653      * and account.  If no account is required by the server, only
    654      * the username and password, the account information is not used.
    655      * <p>
    656      * @param username The username to login under.
    657      * @param password The password to use.
    658      * @param account  The account to use.
    659      * @return True if successfully completed, false if not.
    660      * @exception FTPConnectionClosedException
    661      *      If the FTP server prematurely closes the connection as a result
    662      *      of the client being idle or some other reason causing the server
    663      *      to send FTP reply code 421.  This exception may be caught either
    664      *      as an IOException or independently as itself.
    665      * @exception IOException  If an I/O error occurs while either sending a
    666      *      command to the server or receiving a reply from the server.
    667      ***/
    668     public boolean login(String username, String password, String account)
    669     throws IOException
    670     {
    671         user(username);
    672
    673         if (FTPReply.isPositiveCompletion(_replyCode))
    674             return true;
    675
    676         // If we get here, we either have an error code, or an intermmediate
    677         // reply requesting password.
    678         if (!FTPReply.isPositiveIntermediate(_replyCode))
    679             return false;
    680
    681         pass(password);
    682
    683         if (FTPReply.isPositiveCompletion(_replyCode))
    684             return true;
    685
    686         if (!FTPReply.isPositiveIntermediate(_replyCode))
    687             return false;
    688
    689         return FTPReply.isPositiveCompletion(acct(account));
    690     }
    691
    692     /****
    693      * Logout of the FTP server by sending the QUIT command.
    694      * <p>
    695      * @return True if successfully completed, false if not.
    696      * @exception FTPConnectionClosedException
    697      *      If the FTP server prematurely closes the connection as a result
    698      *      of the client being idle or some other reason causing the server
    699      *      to send FTP reply code 421.  This exception may be caught either
    700      *      as an IOException or independently as itself.
    701      * @exception IOException  If an I/O error occurs while either sending a
    702      *      command to the server or receiving a reply from the server.
    703      ***/
    704     public boolean logout() throws IOException
    705     {
    706         return FTPReply.isPositiveCompletion(quit());
    707     }
    708
    709
    710     /****
    711      * Change the current working directory of the FTP session.
    712      * <p>
    713      * @param pathname  The new current working directory.
    714      * @return True if successfully completed, false if not.
    715      * @exception FTPConnectionClosedException
    716      *      If the FTP server prematurely closes the connection as a result
    717      *      of the client being idle or some other reason causing the server
    718      *      to send FTP reply code 421.  This exception may be caught either
    719      *      as an IOException or independently as itself.
    720      * @exception IOException  If an I/O error occurs while either sending a
    721      *      command to the server or receiving a reply from the server.
    722      ***/
    723     public boolean changeWorkingDirectory(String pathname) throws IOException
    724     {
    725         return FTPReply.isPositiveCompletion(cwd(pathname));
    726     }
    727
    728
    729     /****
    730      * Change to the parent directory of the current working directory.
    731      * <p>
    732      * @return True if successfully completed, false if not.
    733      * @exception FTPConnectionClosedException
    734      *      If the FTP server prematurely closes the connection as a result
    735      *      of the client being idle or some other reason causing the server
    736      *      to send FTP reply code 421.  This exception may be caught either
    737      *      as an IOException or independently as itself.
    738      * @exception IOException  If an I/O error occurs while either sending a
    739      *      command to the server or receiving a reply from the server.
    740      ***/
    741     public boolean changeToParentDirectory() throws IOException
    742     {
    743         return FTPReply.isPositiveCompletion(cdup());
    744     }
    745
    746
    747     /****
    748      * Issue the FTP SMNT command.
    749      * <p>
    750      * @param pathname The pathname to mount.
    751      * @return True if successfully completed, false if not.
    752      * @exception FTPConnectionClosedException
    753      *      If the FTP server prematurely closes the connection as a result
    754      *      of the client being idle or some other reason causing the server
    755      *      to send FTP reply code 421.  This exception may be caught either
    756      *      as an IOException or independently as itself.
    757      * @exception IOException  If an I/O error occurs while either sending a
    758      *      command to the server or receiving a reply from the server.
    759      ***/
    760     public boolean structureMount(String pathname) throws IOException
    761     {
    762         return FTPReply.isPositiveCompletion(smnt(pathname));
    763     }
    764
    765     /****
    766      * Reinitialize the FTP session.  Not all FTP servers support this
    767      * command, which issues the FTP REIN command.
    768      * <p>
    769      * @return True if successfully completed, false if not.
    770      * @exception FTPConnectionClosedException
    771      *      If the FTP server prematurely closes the connection as a result
    772      *      of the client being idle or some other reason causing the server
    773      *      to send FTP reply code 421.  This exception may be caught either
    774      *      as an IOException or independently as itself.
    775      * @exception IOException  If an I/O error occurs while either sending a
    776      *      command to the server or receiving a reply from the server.
    777      ***/
    778     boolean reinitialize() throws IOException
    779     {
    780         rein();
    781
    782         if (FTPReply.isPositiveCompletion(_replyCode) ||
    783                 (FTPReply.isPositivePreliminary(_replyCode) &&
    784                  FTPReply.isPositiveCompletion(getReply())))
    785         {
    786
    787             __initDefaults();
    788
    789             return true;
    790         }
    791
    792         return false;
    793     }
    794
    795
    796     /****
    797      * Set the current data connection mode to
    798      * <code>ACTIVE_LOCAL_DATA_CONNECTION_MODE</code>.  No communication
    799      * with the FTP server is conducted, but this causes all future data
    800      * transfers to require the FTP server to connect to the client's
    801      * data port.  Additionally, to accommodate differences between socket
    802      * implementations on different platforms, this method causes the
    803      * client to issue a PORT command before every data transfer.
    804      ***/
    805     public void enterLocalActiveMode()
    806     {
    807         __dataConnectionMode = ACTIVE_LOCAL_DATA_CONNECTION_MODE;
    808         __passiveHost = null;
    809         __passivePort = -1;
    810     }
    811
    812
    813     /****
    814      * Set the current data connection mode to
    815      * <code> PASSIVE_LOCAL_DATA_CONNECTION_MODE </code>.  Use this
    816      * method only for data transfers between the client and server.
    817      * This method causes a PASV command to be issued to the server
    818      * before the opening of every data connection, telling the server to
    819      * open a data port to which the client will connect to conduct
    820      * data transfers.  The FTPClient will stay in
    821      * <code> PASSIVE_LOCAL_DATA_CONNECTION_MODE </code> until the
    822      * mode is changed by calling some other method such as
    823      * {@link #enterLocalActiveMode  enterLocalActiveMode() }
    824      ***/
    825     public void enterLocalPassiveMode()
    826     {
    827         __dataConnectionMode = PASSIVE_LOCAL_DATA_CONNECTION_MODE;
    828         // These will be set when just before a data connection is opened
    829         // in _openDataConnection_()
    830         __passiveHost = null;
    831         __passivePort = -1;
    832     }
    833
    834
    835     /****
    836      * Set the current data connection mode to
    837      * <code> ACTIVE_REMOTE_DATA_CONNECTION </code>.  Use this method only
    838      * for server to server data transfers.  This method issues a PORT
    839      * command to the server, indicating the other server and port to which
    840      * it should connect for data transfers.  You must call this method
    841      * before EVERY server to server transfer attempt.  The FTPClient will
    842      * NOT automatically continue to issue PORT commands.  You also
    843      * must remember to call
    844      * {@link #enterLocalActiveMode  enterLocalActiveMode() } if you
    845      * wish to return to the normal data connection mode.
    846      * <p>
    847      * @param host The passive mode server accepting connections for data
    848      *             transfers.
    849      * @param port The passive mode server's data port.
    850      * @return True if successfully completed, false if not.
    851      * @exception FTPConnectionClosedException
    852      *      If the FTP server prematurely closes the connection as a result
    853      *      of the client being idle or some other reason causing the server
    854      *      to send FTP reply code 421.  This exception may be caught either
    855      *      as an IOException or independently as itself.
    856      * @exception IOException  If an I/O error occurs while either sending a
    857      *      command to the server or receiving a reply from the server.
    858      ***/
    859     public boolean enterRemoteActiveMode(InetAddress host, int port)
    860     throws IOException
    861     {
    862         if (FTPReply.isPositiveCompletion(port(host, port)))
    863         {
    864             __dataConnectionMode = ACTIVE_REMOTE_DATA_CONNECTION_MODE;
    865             __passiveHost = null;
    866             __passivePort = -1;
    867             return true;
    868         }
    869         return false;
    870     }
    871
    872     /****
    873      * Set the current data connection mode to
    874      * <code> PASSIVE_REMOTE_DATA_CONNECTION_MODE </code>.  Use this
    875      * method only for server to server data transfers.
    876      * This method issues a PASV command to the server, telling it to
    877      * open a data port to which the active server will connect to conduct
    878      * data transfers.  You must call this method
    879      * before EVERY server to server transfer attempt.  The FTPClient will
    880      * NOT automatically continue to issue PASV commands.  You also
    881      * must remember to call
    882      * {@link #enterLocalActiveMode  enterLocalActiveMode() } if you
    883      * wish to return to the normal data connection mode.
    884      * <p>
    885      * @return True if successfully completed, false if not.
    886      * @exception FTPConnectionClosedException
    887      *      If the FTP server prematurely closes the connection as a result
    888      *      of the client being idle or some other reason causing the server
    889      *      to send FTP reply code 421.  This exception may be caught either
    890      *      as an IOException or independently as itself.
    891      * @exception IOException  If an I/O error occurs while either sending a
    892      *      command to the server or receiving a reply from the server.
    893      ***/
    894     public boolean enterRemotePassiveMode() throws IOException
    895     {
    896         if (pasv() != FTPReply.ENTERING_PASSIVE_MODE)
    897             return false;
    898
    899         __dataConnectionMode = PASSIVE_REMOTE_DATA_CONNECTION_MODE;
    900         __parsePassiveModeReply((String)_replyLines.elementAt(0));
    901
    902         return true;
    903     }
    904
    905     /****
    906      * Returns the hostname or IP address (in the form of a string) returned
    907      * by the server when entering passive mode.  If not in passive mode,
    908      * returns null.  This method only returns a valid value AFTER a
    909      * data connection has been opened after a call to
    910      * {@link #enterLocalPassiveMode enterLocalPassiveMode()}.
    911      * This is because FTPClient sends a PASV command to the server only
    912      * just before opening a data connection, and not when you call
    913      * {@link #enterLocalPassiveMode enterLocalPassiveMode()}.
    914      * <p>
    915      * @return The passive host name if in passive mode, otherwise null.
    916      ***/
    917     public String getPassiveHost()
    918     {
    919         return __passiveHost;
    920     }
    921
    922     /****
    923      * If in passive mode, returns the data port of the passive host.
    924      * This method only returns a valid value AFTER a
    925      * data connection has been opened after a call to
    926      * {@link #enterLocalPassiveMode enterLocalPassiveMode()}.
    927      * This is because FTPClient sends a PASV command to the server only
    928      * just before opening a data connection, and not when you call
    929      * {@link #enterLocalPassiveMode enterLocalPassiveMode()}.
    930      * <p>
    931      * @return The data port of the passive server.  If not in passive
    932      *         mode, undefined.
    933      ***/
    934     public int getPassivePort()
    935     {
    936         return __passivePort;
    937     }
    938
    939
    940     /****
    941      * Returns the current data connection mode (one of the
    942      * <code> _DATA_CONNECTION_MODE </code> constants.
    943      * <p>
    944      * @return The current data connection mode (one of the
    945      * <code> _DATA_CONNECTION_MODE </code> constants.
    946      ***/
    947     public int getDataConnectionMode()
    948     {
    949         return __dataConnectionMode;
    950     }
    951
    952
    953     /****
    954      * Sets the file type to be transferred.  This should be one of
    955      * <code> FTP.ASCII_FILE_TYPE </code>, <code> FTP.IMAGE_FILE_TYPE </code>,
    956      * etc.  The file type only needs to be set when you want to change the
    957      * type.  After changing it, the new type stays in effect until you change
    958      * it again.  The default file type is <code> FTP.ASCII_FILE_TYPE </code>
    959      * if this method is never called.
    960      * <p>
    961      * @param fileType The <code> _FILE_TYPE </code> constant indcating the
    962      *                 type of file.
    963      * @return True if successfully completed, false if not.
    964      * @exception FTPConnectionClosedException
    965      *      If the FTP server prematurely closes the connection as a result
    966      *      of the client being idle or some other reason causing the server
    967      *      to send FTP reply code 421.  This exception may be caught either
    968      *      as an IOException or independently as itself.
    969      * @exception IOException  If an I/O error occurs while either sending a
    970      *      command to the server or receiving a reply from the server.
    971      ***/
    972     public boolean setFileType(int fileType) throws IOException
    973     {
    974         if (FTPReply.isPositiveCompletion(type(fileType)))
    975         {
    976             __fileType = fileType;
    977             __fileFormat = FTP.NON_PRINT_TEXT_FORMAT;
    978             return true;
    979         }
    980         return false;
    981     }
    982
    983
    984     /****
    985      * Sets the file type to be transferred and the format.  The type should be
    986      * one of  <code> FTP.ASCII_FILE_TYPE </code>,
    987      * <code> FTP.IMAGE_FILE_TYPE </code>, etc.  The file type only needs to
    988      * be set when you want to change the type.  After changing it, the new
    989      * type stays in effect until you change it again.  The default file type
    990      * is <code> FTP.ASCII_FILE_TYPE </code> if this method is never called.
    991      * The format should be one of the FTP class <code> TEXT_FORMAT </code>
    992      * constants, or if the type is <code> FTP.LOCAL_FILE_TYPE </code>, the
    993      * format should be the byte size for that type.  The default format
    994      * is <code> FTP.NON_PRINT_TEXT_FORMAT </code> if this method is never
    995      * called.
    996      * <p>
    997      * @param fileType The <code> _FILE_TYPE </code> constant indcating the
    998      *                 type of file.
    999      * @param formatOrByteSize  The format of the file (one of the
    1000      *              <code>_FORMAT</code> constants.  In the case of
    1001      *              <code>LOCAL_FILE_TYPE</code>, the byte size.
    1002      * <p>
    1003      * @return True if successfully completed, false if not.
    1004      * @exception FTPConnectionClosedException
    1005      *      If the FTP server prematurely closes the connection as a result
    1006      *      of the client being idle or some other reason causing the server
    1007      *      to send FTP reply code 421.  This exception may be caught either
    1008      *      as an IOException or independently as itself.
    1009      * @exception IOException  If an I/O error occurs while either sending a
    1010      *      command to the server or receiving a reply from the server.
    1011      ***/
    1012     public boolean setFileType(int fileType, int formatOrByteSize)
    1013     throws IOException
    1014     {
    1015         if (FTPReply.isPositiveCompletion(type(fileType, formatOrByteSize)))
    1016         {
    1017             __fileType = fileType;
    1018             __fileFormat = formatOrByteSize;
    1019             return true;
    1020         }
    1021         return false;
    1022     }
    1023
    1024
    1025     /****
    1026      * Sets the file structure.  The default structure is
    1027      * <code> FTP.FILE_STRUCTURE </code> if this method is never called.
    1028      * <p>
    1029      * @param structure  The structure of the file (one of the FTP class
    1030      *         <code>_STRUCTURE</code> constants).
    1031      * @return True if successfully completed, false if not.
    1032      * @exception FTPConnectionClosedException
    1033      *      If the FTP server prematurely closes the connection as a result
    1034      *      of the client being idle or some other reason causing the server
    1035      *      to send FTP reply code 421.  This exception may be caught either
    1036      *      as an IOException or independently as itself.
    1037      * @exception IOException  If an I/O error occurs while either sending a
    1038      *      command to the server or receiving a reply from the server.
    1039      ***/
    1040     public boolean setFileStructure(int structure) throws IOException
    1041     {
    1042         if (FTPReply.isPositiveCompletion(stru(structure)))
    1043         {
    1044             __fileStructure = structure;
    1045             return true;
    1046         }
    1047         return false;
    1048     }
    1049
    1050
    1051     /****
    1052      * Sets the transfer mode.  The default transfer mode
    1053      * <code> FTP.STREAM_TRANSFER_MODE </code> if this method is never called.
    1054      * <p>
    1055      * @param mode  The new transfer mode to use (one of the FTP class
    1056      *         <code>_TRANSFER_MODE</code> constants).
    1057      * @return True if successfully completed, false if not.
    1058      * @exception FTPConnectionClosedException
    1059      *      If the FTP server prematurely closes the connection as a result
    1060      *      of the client being idle or some other reason causing the server
    1061      *      to send FTP reply code 421.  This exception may be caught either
    1062      *      as an IOException or independently as itself.
    1063      * @exception IOException  If an I/O error occurs while either sending a
    1064      *      command to the server or receiving a reply from the server.
    1065      ***/
    1066     public boolean setFileTransferMode(int mode) throws IOException
    1067     {
    1068         if (FTPReply.isPositiveCompletion(mode(mode)))
    1069         {
    1070             __fileTransferMode = mode;
    1071             return true;
    1072         }
    1073         return false;
    1074     }
    1075
    1076
    1077     /****
    1078      * Initiate a server to server file transfer.  This method tells the
    1079      * server to which the client is connected to retrieve a given file from
    1080      * the other server.
    1081      * <p>
    1082      * @param filename  The name of the file to retrieve.
    1083      * @return True if successfully completed, false if not.
    1084      * @exception FTPConnectionClosedException
    1085      *      If the FTP server prematurely closes the connection as a result
    1086      *      of the client being idle or some other reason causing the server
    1087      *      to send FTP reply code 421.  This exception may be caught either
    1088      *      as an IOException or independently as itself.
    1089      * @exception IOException  If an I/O error occurs while either sending a
    1090      *      command to the server or receiving a reply from the server.
    1091      ***/
    1092     public boolean remoteRetrieve(String filename) throws IOException
    1093     {
    1094         if (__dataConnectionMode == ACTIVE_REMOTE_DATA_CONNECTION_MODE ||
    1095                 __dataConnectionMode == PASSIVE_REMOTE_DATA_CONNECTION_MODE)
    1096             return FTPReply.isPositivePreliminary(retr(filename));
    1097         return false;
    1098     }
    1099
    1100
    1101     /****
    1102      * Initiate a server to server file transfer.  This method tells the
    1103      * server to which the client is connected to store a file on
    1104      * the other server using the given filename.  The other server must
    1105      * have had a <code> remoteRetrieve </code> issued to it by another
    1106      * FTPClient.
    1107      * <p>
    1108      * @param filename  The name to call the file that is to be stored.
    1109      * @return True if successfully completed, false if not.
    1110      * @exception FTPConnectionClosedException
    1111      *      If the FTP server prematurely closes the connection as a result
    1112      *      of the client being idle or some other reason causing the server
    1113      *      to send FTP reply code 421.  This exception may be caught either
    1114      *      as an IOException or independently as itself.
    1115      * @exception IOException  If an I/O error occurs while either sending a
    1116      *      command to the server or receiving a reply from the server.
    1117      ***/
    1118     public boolean remoteStore(String filename) throws IOException
    1119     {
    1120         if (__dataConnectionMode == ACTIVE_REMOTE_DATA_CONNECTION_MODE ||
    1121                 __dataConnectionMode == PASSIVE_REMOTE_DATA_CONNECTION_MODE)
    1122             return FTPReply.isPositivePreliminary(stor(filename));
    1123         return false;
    1124     }
    1125
    1126
    1127     /****
    1128      * Initiate a server to server file transfer.  This method tells the
    1129      * server to which the client is connected to store a file on
    1130      * the other server using a unique filename based on the given filename.
    1131      * The other server must have had a <code> remoteRetrieve </code> issued
    1132      * to it by another FTPClient.
    1133      * <p>
    1134      * @param filename  The name on which to base the filename of the file
    1135      *                  that is to be stored.
    1136      * @return True if successfully completed, false if not.
    1137      * @exception FTPConnectionClosedException
    1138      *      If the FTP server prematurely closes the connection as a result
    1139      *      of the client being idle or some other reason causing the server
    1140      *      to send FTP reply code 421.  This exception may be caught either
    1141      *      as an IOException or independently as itself.
    1142      * @exception IOException  If an I/O error occurs while either sending a
    1143      *      command to the server or receiving a reply from the server.
    1144      ***/
    1145     public boolean remoteStoreUnique(String filename) throws IOException
    1146     {
    1147         if (__dataConnectionMode == ACTIVE_REMOTE_DATA_CONNECTION_MODE ||
    1148                 __dataConnectionMode == PASSIVE_REMOTE_DATA_CONNECTION_MODE)
    1149             return FTPReply.isPositivePreliminary(stou(filename));
    1150         return false;
    1151     }
    1152
    1153
    1154     /****
    1155      * Initiate a server to server file transfer.  This method tells the
    1156      * server to which the client is connected to store a file on
    1157      * the other server using a unique filename.
    1158      * The other server must have had a <code> remoteRetrieve </code> issued
    1159      * to it by another FTPClient.  Many FTP servers require that a base
    1160      * filename be given from which the unique filename can be derived.  For
    1161      * those servers use the other version of <code> remoteStoreUnique</code>
    1162      * <p>
    1163      * @return True if successfully completed, false if not.
    1164      * @exception FTPConnectionClosedException
    1165      *      If the FTP server prematurely closes the connection as a result
    1166      *      of the client being idle or some other reason causing the server
    1167      *      to send FTP reply code 421.  This exception may be caught either
    1168      *      as an IOException or independently as itself.
    1169      * @exception IOException  If an I/O error occurs while either sending a
    1170      *      command to the server or receiving a reply from the server.
    1171      ***/
    1172     public boolean remoteStoreUnique() throws IOException
    1173     {
    1174         if (__dataConnectionMode == ACTIVE_REMOTE_DATA_CONNECTION_MODE ||
    1175                 __dataConnectionMode == PASSIVE_REMOTE_DATA_CONNECTION_MODE)
    1176             return FTPReply.isPositivePreliminary(stou());
    1177         return false;
    1178     }
    1179
    1180     // For server to server transfers
    1181     /****
    1182      * Initiate a server to server file transfer.  This method tells the
    1183      * server to which the client is connected to append to a given file on
    1184      * the other server.  The other server must have had a
    1185      * <code> remoteRetrieve </code> issued to it by another FTPClient.
    1186      * <p>
    1187      * @param filename  The name of the file to be appended to, or if the
    1188      *        file does not exist, the name to call the file being stored.
    1189      * <p>
    1190      * @return True if successfully completed, false if not.
    1191      * @exception FTPConnectionClosedException
    1192      *      If the FTP server prematurely closes the connection as a result
    1193      *      of the client being idle or some other reason causing the server
    1194      *      to send FTP reply code 421.  This exception may be caught either
    1195      *      as an IOException or independently as itself.
    1196      * @exception IOException  If an I/O error occurs while either sending a
    1197      *      command to the server or receiving a reply from the server.
    1198      ***/
    1199     public boolean remoteAppend(String filename) throws IOException
    1200     {
    1201         if (__dataConnectionMode == ACTIVE_REMOTE_DATA_CONNECTION_MODE ||
    1202                 __dataConnectionMode == PASSIVE_REMOTE_DATA_CONNECTION_MODE)
    1203             return FTPReply.isPositivePreliminary(stor(filename));
    1204         return false;
    1205     }
    1206
    1207     /****
    1208      * There are a few FTPClient methods that do not complete the
    1209      * entire sequence of FTP commands to complete a transaction.  These
    1210      * commands require some action by the programmer after the reception
    1211      * of a positive intermediate command.  After the programmer's code
    1212      * completes its actions, it must call this method to receive
    1213      * the completion reply from the server and verify the success of the
    1214      * entire transaction.
    1215      * <p>
    1216      * For example,
    1217      * <pre>
    1218      * InputStream input;
    1219      * OutputStream output;
    1220      * input  = new FileInputStream("foobaz.txt");
    1221      * output = ftp.storeFileStream("foobar.txt")
    1222      * if(!FTPReply.isPositiveIntermediate(ftp.getReplyCode())) {
    1223      *     input.close();
    1224      *     output.close();
    1225      *     ftp.logout();
    1226      *     ftp.disconnect();
    1227      *     System.err.println("File transfer failed.");
    1228      *     System.exit(1);
    1229      * }
    1230      * Util.copyStream(input, output);
    1231      * input.close();
    1232      * output.close();
    1233      * // Must call completePendingCommand() to finish command.
    1234      * if(!ftp.completePendingCommand()) {
    1235      *     ftp.logout();
    1236      *     ftp.disconnect();
    1237      *     System.err.println("File transfer failed.");
    1238      *     System.exit(1);
    1239      * }
    1240      * </pre>
    1241      * <p>
    1242      * @return True if successfully completed, false if not.
    1243      * @exception FTPConnectionClosedException
    1244      *      If the FTP server prematurely closes the connection as a result
    1245      *      of the client being idle or some other reason causing the server
    1246      *      to send FTP reply code 421.  This exception may be caught either
    1247      *      as an IOException or independently as itself.
    1248      * @exception IOException  If an I/O error occurs while either sending a
    1249      *      command to the server or receiving a reply from the server.
    1250      ***/
    1251     public boolean completePendingCommand() throws IOException
    1252     {
    1253         return FTPReply.isPositiveCompletion(getReply());
    1254     }
    1255
    1256
    1257     /****
    1258      * Retrieves a named file from the server and writes it to the given
    1259      * OutputStream.  This method does NOT close the given OutputStream.
    1260      * If the current file type is ASCII, line separators in the file are
    1261      * converted to the local representation.
    1262      * <p>
    1263      * @param remote  The name of the remote file.
    1264      * @param local   The local OutputStream to which to write the file.
    1265      * @return True if successfully completed, false if not.
    1266      * @exception FTPConnectionClosedException
    1267      *      If the FTP server prematurely closes the connection as a result
    1268      *      of the client being idle or some other reason causing the server
    1269      *      to send FTP reply code 421.  This exception may be caught either
    1270      *      as an IOException or independently as itself.
    1271      * @exception CopyStreamException  If an I/O error occurs while actually
    1272      *      transferring the file.  The CopyStreamException allows you to
    1273      *      determine the number of bytes transferred and the IOException
    1274      *      causing the error.  This exception may be caught either
    1275      *      as an IOException or independently as itself.
    1276      * @exception IOException  If an I/O error occurs while either sending a
    1277      *      command to the server or receiving a reply from the server.
    1278      ***/
    1279     public boolean retrieveFile(String remote, OutputStream local)
    1280     throws IOException
    1281     {
    1282         InputStream input;
    1283         Socket socket;
    1284
    1285         if ((socket = _openDataConnection_(FTPCommand.RETR, remote)) == null)
    1286             return false;
    1287
    1288         input = new BufferedInputStream(socket.getInputStream(),
    1289                                         getBufferSize());
    1290         if (__fileType == ASCII_FILE_TYPE)
    1291           input = new FromNetASCIIInputStream(input);
    1292         // Treat everything else as binary for now
    1293         try
    1294         {
    1295             Util.copyStream(input, local, getBufferSize(),
    1296                             CopyStreamEvent.UNKNOWN_STREAM_SIZE, null,
    1297                             false);
    1298         }
    1299         catch (IOException e)
    1300         {
    1301             try
    1302             {
    1303                 socket.close();
    1304             }
    1305             catch (IOException f)
    1306             {}
    1307             throw e;
    1308         }
    1309         socket.close();
    1310         return completePendingCommand();
    1311     }
    1312
    1313     /****
    1314      * Returns an InputStream from which a named file from the server
    1315      * can be read.  If the current file type is ASCII, the returned
    1316      * InputStream will convert line separators in the file to
    1317      * the local representation.  You must close the InputStream when you
    1318      * finish reading from it.  The InputStream itself will take care of
    1319      * closing the parent data connection socket upon being closed.  To
    1320      * finalize the file transfer you must call
    1321      * {@link #completePendingCommand  completePendingCommand } and
    1322      * check its return value to verify success.
    1323      * <p>
    1324      * @param remote  The name of the remote file.
    1325      * @return An InputStream from which the remote file can be read.  If
    1326      *      the data connection cannot be opened (e.g., the file does not
    1327      *      exist), null is returned (in which case you may check the reply
    1328      *      code to determine the exact reason for failure).
    1329      * @exception FTPConnectionClosedException
    1330      *      If the FTP server prematurely closes the connection as a result
    1331      *      of the client being idle or some other reason causing the server
    1332      *      to send FTP reply code 421.  This exception may be caught either
    1333      *      as an IOException or independently as itself.
    1334      * @exception IOException  If an I/O error occurs while either sending a
    1335      *      command to the server or receiving a reply from the server.
    1336      ***/
    1337     public InputStream retrieveFileStream(String remote) throws IOException
    1338     {
    1339         InputStream input;
    1340         Socket socket;
    1341
    1342         if ((socket = _openDataConnection_(FTPCommand.RETR, remote)) == null)
    1343             return null;
    1344
    1345         input = socket.getInputStream();
    1346         if (__fileType == ASCII_FILE_TYPE) {
    1347           // We buffer ascii transfers because the buffering has to
    1348           // be interposed between FromNetASCIIOutputSream and the underlying
    1349           // socket input stream.  We don't buffer binary transfers
    1350           // because we don't want to impose a buffering policy on the
    1351           // programmer if possible.  Programmers can decide on their
    1352           // own if they want to wrap the SocketInputStream we return
    1353           // for file types other than ASCII.
    1354           input = new BufferedInputStream(input,
    1355                                           getBufferSize());
    1356           input = new FromNetASCIIInputStream(input);
    1357         }
    1358         return new org.apache.commons.net.io.SocketInputStream(socket, input);
    1359     }
    1360
    1361
    1362     /****
    1363      * Stores a file on the server using the given name and taking input
    1364      * from the given InputStream.  This method does NOT close the given
    1365      * InputStream.  If the current file type is ASCII, line separators in
    1366      * the file are transparently converted to the NETASCII format (i.e.,
    1367      * you should not attempt to create a special InputStream to do this).
    1368      * <p>
    1369      * @param remote  The name to give the remote file.
    1370      * @param local   The local InputStream from which to read the file.
    1371      * @return True if successfully completed, false if not.
    1372      * @exception FTPConnectionClosedException
    1373      *      If the FTP server prematurely closes the connection as a result
    1374      *      of the client being idle or some other reason causing the server
    1375      *      to send FTP reply code 421.  This exception may be caught either
    1376      *      as an IOException or independently as itself.
    1377      * @exception CopyStreamException  If an I/O error occurs while actually
    1378      *      transferring the file.  The CopyStreamException allows you to
    1379      *      determine the number of bytes transferred and the IOException
    1380      *      causing the error.  This exception may be caught either
    1381      *      as an IOException or independently as itself.
    1382      * @exception IOException  If an I/O error occurs while either sending a
    1383      *      command to the server or receiving a reply from the server.
    1384      ***/
    1385     public boolean storeFile(String remote, InputStream local)
    1386     throws IOException
    1387     {
    1388         return __storeFile(FTPCommand.STOR, remote, local);
    1389     }
    1390
    1391
    1392     /****
    1393      * Returns an OutputStream through which data can be written to store
    1394      * a file on the server using the given name.  If the current file type
    1395      * is ASCII, the returned OutputStream will convert line separators in
    1396      * the file to the NETASCII format  (i.e., you should not attempt to
    1397      * create a special OutputStream to do this).  You must close the
    1398      * OutputStream when you finish writing to it.  The OutputStream itself
    1399      * will take care of closing the parent data connection socket upon being
    1400      * closed.  To finalize the file transfer you must call
    1401      * {@link #completePendingCommand  completePendingCommand } and
    1402      * check its return value to verify success.
    1403      * <p>
    1404      * @param remote  The name to give the remote file.
    1405      * @return An OutputStream through which the remote file can be written.  If
    1406      *      the data connection cannot be opened (e.g., the file does not
    1407      *      exist), null is returned (in which case you may check the reply
    1408      *      code to determine the exact reason for failure).
    1409      * @exception FTPConnectionClosedException
    1410      *      If the FTP server prematurely closes the connection as a result
    1411      *      of the client being idle or some other reason causing the server
    1412      *      to send FTP reply code 421.  This exception may be caught either
    1413      *      as an IOException or independently as itself.
    1414      * @exception IOException  If an I/O error occurs while either sending a
    1415      *      command to the server or receiving a reply from the server.
    1416      ***/
    1417     public OutputStream storeFileStream(String remote) throws IOException
    1418     {
    1419         return __storeFileStream(FTPCommand.STOR, remote);
    1420     }
    1421
    1422     /****
    1423      * Appends to a file on the server with the given name, taking input
    1424      * from the given InputStream.  This method does NOT close the given
    1425      * InputStream.  If the current file type is ASCII, line separators in
    1426      * the file are transparently converted to the NETASCII format (i.e.,
    1427      * you should not attempt to create a special InputStream to do this).
    1428      * <p>
    1429      * @param remote  The name of the remote file.
    1430      * @param local   The local InputStream from which to read the data to
    1431      *                be appended to the remote file.
    1432      * @return True if successfully completed, false if not.
    1433      * @exception FTPConnectionClosedException
    1434      *      If the FTP server prematurely closes the connection as a result
    1435      *      of the client being idle or some other reason causing the server
    1436      *      to send FTP reply code 421.  This exception may be caught either
    1437      *      as an IOException or independently as itself.
    1438      * @exception CopyStreamException  If an I/O error occurs while actually
    1439      *      transferring the file.  The CopyStreamException allows you to
    1440      *      determine the number of bytes transferred and the IOException
    1441      *      causing the error.  This exception may be caught either
    1442      *      as an IOException or independently as itself.
    1443      * @exception IOException  If an I/O error occurs while either sending a
    1444      *      command to the server or receiving a reply from the server.
    1445      ***/
    1446     public boolean appendFile(String remote, InputStream local)
    1447     throws IOException
    1448     {
    1449         return __storeFile(FTPCommand.APPE, remote, local);
    1450     }
    1451
    1452     /****
    1453      * Returns an OutputStream through which data can be written to append
    1454      * to a file on the server with the given name.  If the current file type
    1455      * is ASCII, the returned OutputStream will convert line separators in
    1456      * the file to the NETASCII format  (i.e., you should not attempt to
    1457      * create a special OutputStream to do this).  You must close the
    1458      * OutputStream when you finish writing to it.  The OutputStream itself
    1459      * will take care of closing the parent data connection socket upon being
    1460      * closed.  To finalize the file transfer you must call
    1461      * {@link #completePendingCommand  completePendingCommand } and
    1462      * check its return value to verify success.
    1463      * <p>
    1464      * @param remote  The name of the remote file.
    1465      * @return An OutputStream through which the remote file can be appended.
    1466      *      If the data connection cannot be opened (e.g., the file does not
    1467      *      exist), null is returned (in which case you may check the reply
    1468      *      code to determine the exact reason for failure).
    1469      * @exception FTPConnectionClosedException
    1470      *      If the FTP server prematurely closes the connection as a result
    1471      *      of the client being idle or some other reason causing the server
    1472      *      to send FTP reply code 421.  This exception may be caught either
    1473      *      as an IOException or independently as itself.
    1474      * @exception IOException  If an I/O error occurs while either sending a
    1475      *      command to the server or receiving a reply from the server.
    1476      ***/
    1477     public OutputStream appendFileStream(String remote) throws IOException
    1478     {
    1479         return __storeFileStream(FTPCommand.APPE, remote);
    1480     }
    1481
    1482     /****
    1483      * Stores a file on the server using a unique name derived from the
    1484      * given name and taking input
    1485      * from the given InputStream.  This method does NOT close the given
    1486      * InputStream.  If the current file type is ASCII, line separators in
    1487      * the file are transparently converted to the NETASCII format (i.e.,
    1488      * you should not attempt to create a special InputStream to do this).
    1489      * <p>
    1490      * @param remote  The name on which to base the unique name given to
    1491      *                the remote file.
    1492      * @param local   The local InputStream from which to read the file.
    1493      * @return True if successfully completed, false if not.
    1494      * @exception FTPConnectionClosedException
    1495      *      If the FTP server prematurely closes the connection as a result
    1496      *      of the client being idle or some other reason causing the server
    1497      *      to send FTP reply code 421.  This exception may be caught either
    1498      *      as an IOException or independently as itself.
    1499      * @exception CopyStreamException  If an I/O error occurs while actually
    1500      *      transferring the file.  The CopyStreamException allows you to
    1501      *      determine the number of bytes transferred and the IOException
    1502      *      causing the error.  This exception may be caught either
    1503      *      as an IOException or independently as itself.
    1504      * @exception IOException  If an I/O error occurs while either sending a
    1505      *      command to the server or receiving a reply from the server.
    1506      ***/
    1507     public boolean storeUniqueFile(String remote, InputStream local)
    1508     throws IOException
    1509     {
    1510         return __storeFile(FTPCommand.STOU, remote, local);
    1511     }
    1512
    1513
    1514     /****
    1515      * Returns an OutputStream through which data can be written to store
    1516      * a file on the server using a unique name derived from the given name.
    1517      * If the current file type
    1518      * is ASCII, the returned OutputStream will convert line separators in
    1519      * the file to the NETASCII format  (i.e., you should not attempt to
    1520      * create a special OutputStream to do this).  You must close the
    1521      * OutputStream when you finish writing to it.  The OutputStream itself
    1522      * will take care of closing the parent data connection socket upon being
    1523      * closed.  To finalize the file transfer you must call
    1524      * {@link #completePendingCommand  completePendingCommand } and
    1525      * check its return value to verify success.
    1526      * <p>
    1527      * @param remote  The name on which to base the unique name given to
    1528      *                the remote file.
    1529      * @return An OutputStream through which the remote file can be written.  If
    1530      *      the data connection cannot be opened (e.g., the file does not
    1531      *      exist), null is returned (in which case you may check the reply
    1532      *      code to determine the exact reason for failure).
    1533      * @exception FTPConnectionClosedException
    1534      *      If the FTP server prematurely closes the connection as a result
    1535      *      of the client being idle or some other reason causing the server
    1536      *      to send FTP reply code 421.  This exception may be caught either
    1537      *      as an IOException or independently as itself.
    1538      * @exception IOException  If an I/O error occurs while either sending a
    1539      *      command to the server or receiving a reply from the server.
    1540      ***/
    1541     public OutputStream storeUniqueFileStream(String remote) throws IOException
    1542     {
    1543         return __storeFileStream(FTPCommand.STOU, remote);
    1544     }
    1545
    1546     /***
    1547      * Stores a file on the server using a unique name assigned by the
    1548      * server and taking input from the given InputStream.  This method does
    1549      * NOT close the given
    1550      * InputStream.  If the current file type is ASCII, line separators in
    1551      * the file are transparently converted to the NETASCII format (i.e.,
    1552      * you should not attempt to create a special InputStream to do this).
    1553      * <p>
    1554      * @param local   The local InputStream from which to read the file.
    1555      * @return True if successfully completed, false if not.
    1556      * @exception FTPConnectionClosedException
    1557      *      If the FTP server prematurely closes the connection as a result
    1558      *      of the client being idle or some other reason causing the server
    1559      *      to send FTP reply code 421.  This exception may be caught either
    1560      *      as an IOException or independently as itself.
    1561      * @exception CopyStreamException  If an I/O error occurs while actually
    1562      *      transferring the file.  The CopyStreamException allows you to
    1563      *      determine the number of bytes transferred and the IOException
    1564      *      causing the error.  This exception may be caught either
    1565      *      as an IOException or independently as itself.
    1566      * @exception IOException  If an I/O error occurs while either sending a
    1567      *      command to the server or receiving a reply from the server.
    1568      */
    1569     public boolean storeUniqueFile(InputStream local) throws IOException
    1570     {
    1571         return __storeFile(FTPCommand.STOU, null, local);
    1572     }
    1573
    1574     /***
    1575      * Returns an OutputStream through which data can be written to store
    1576      * a file on the server using a unique name assigned by the server.
    1577      * If the current file type
    1578      * is ASCII, the returned OutputStream will convert line separators in
    1579      * the file to the NETASCII format  (i.e., you should not attempt to
    1580      * create a special OutputStream to do this).  You must close the
    1581      * OutputStream when you finish writing to it.  The OutputStream itself
    1582      * will take care of closing the parent data connection socket upon being
    1583      * closed.  To finalize the file transfer you must call
    1584      * {@link #completePendingCommand  completePendingCommand } and
    1585      * check its return value to verify success.
    1586      * <p>
    1587      * @return An OutputStream through which the remote file can be written.  If
    1588      *      the data connection cannot be opened (e.g., the file does not
    1589      *      exist), null is returned (in which case you may check the reply
    1590      *      code to determine the exact reason for failure).
    1591      * @exception FTPConnectionClosedException
    1592      *      If the FTP server prematurely closes the connection as a result
    1593      *      of the client being idle or some other reason causing the server
    1594      *      to send FTP reply code 421.  This exception may be caught either
    1595      *      as an IOException or independently as itself.
    1596      * @exception IOException  If an I/O error occurs while either sending a
    1597      *      command to the server or receiving a reply from the server.
    1598      */
    1599     public OutputStream storeUniqueFileStream() throws IOException
    1600     {
    1601         return __storeFileStream(FTPCommand.STOU, null);
    1602     }
    1603
    1604     /****
    1605      * Reserve a number of bytes on the server for the next file transfer.
    1606      * <p>
    1607      * @param bytes  The number of bytes which the server should allocate.
    1608      * @return True if successfully completed, false if not.
    1609      * @exception FTPConnectionClosedException
    1610      *      If the FTP server prematurely closes the connection as a result
    1611      *      of the client being idle or some other reason causing the server
    1612      *      to send FTP reply code 421.  This exception may be caught either
    1613      *      as an IOException or independently as itself.
    1614      * @exception IOException  If an I/O error occurs while either sending a
    1615      *      command to the server or receiving a reply from the server.
    1616      ***/
    1617     public boolean allocate(int bytes) throws IOException
    1618     {
    1619         return FTPReply.isPositiveCompletion(allo(bytes));
    1620     }
    1621
    1622
    1623     /***
    1624      * Reserve space on the server for the next file transfer.
    1625      * <p>
    1626      * @param bytes  The number of bytes which the server should allocate.
    1627      * @param recordSize  The size of a file record.
    1628      * @return True if successfully completed, false if not.
    1629      * @exception FTPConnectionClosedException
    1630      *      If the FTP server prematurely closes the connection as a result
    1631      *      of the client being idle or some other reason causing the server
    1632      *      to send FTP reply code 421.  This exception may be caught either
    1633      *      as an IOException or independently as itself.
    1634      * @exception IOException  If an I/O error occurs while either sending a
    1635      *      command to the server or receiving a reply from the server.
    1636      */
    1637     public boolean allocate(int bytes, int recordSize) throws IOException
    1638     {
    1639         return FTPReply.isPositiveCompletion(allo(bytes, recordSize));
    1640     }
    1641
    1642
    1643     /****
    1644      * Restart a <code>STREAM_TRANSFER_MODE</code> file transfer starting
    1645      * from the given offset.  This will only work on FTP servers supporting
    1646      * the REST comand for the stream transfer mode.  However, most FTP
    1647      * servers support this.  Any subsequent file transfer will start
    1648      * reading or writing the remote file from the indicated offset.
    1649      * <p>
    1650      * @param offset  The offset into the remote file at which to start the
    1651      *           next file transfer.
    1652      * @return True if successfully completed, false if not.
    1653      * @exception FTPConnectionClosedException
    1654      *      If the FTP server prematurely closes the connection as a result
    1655      *      of the client being idle or some other reason causing the server
    1656      *      to send FTP reply code 421.  This exception may be caught either
    1657      *      as an IOException or independently as itself.
    1658      * @exception IOException  If an I/O error occurs while either sending a
    1659      *      command to the server or receiving a reply from the server.
    1660      ***/
    1661     private boolean restart(long offset) throws IOException
    1662     {
    1663         __restartOffset = 0;
    1664         return FTPReply.isPositiveIntermediate(rest(Long.toString(offset)));
    1665     }
    1666
    1667     /****
    1668      * Sets the restart offset.  The restart command is sent to the server
    1669      * only before sending the file transfer command.  When this is done,
    1670      * the restart marker is reset to zero.
    1671      * <p>
    1672      * @param offset  The offset into the remote file at which to start the
    1673      *           next file transfer.  This must be a value greater than or
    1674      *           equal to zero.
    1675      ***/
    1676     public void setRestartOffset(long offset)
    1677     {
    1678         if (offset >= 0)
    1679             __restartOffset = offset;
    1680     }
    1681
    1682     /****
    1683      * Fetches the restart offset.
    1684      * <p>
    1685      * @return offset  The offset into the remote file at which to start the
    1686      *           next file transfer.
    1687      ***/
    1688     public long getRestartOffset()
    1689     {
    1690         return __restartOffset;
    1691     }
    1692
    1693
    1694
    1695     /****
    1696      * Renames a remote file.
    1697      * <p>
    1698      * @param from  The name of the remote file to rename.
    1699      * @param to    The new name of the remote file.
    1700      * @return True if successfully completed, false if not.
    1701      * @exception FTPConnectionClosedException
    1702      *      If the FTP server prematurely closes the connection as a result
    1703      *      of the client being idle or some other reason causing the server
    1704      *      to send FTP reply code 421.  This exception may be caught either
    1705      *      as an IOException or independently as itself.
    1706      * @exception IOException  If an I/O error occurs while either sending a
    1707      *      command to the server or receiving a reply from the server.
    1708      ***/
    1709     public boolean rename(String from, String to) throws IOException
    1710     {
    1711         if (!FTPReply.isPositiveIntermediate(rnfr(from)))
    1712             return false;
    1713
    1714         return FTPReply.isPositiveCompletion(rnto(to));
    1715     }
    1716
    1717
    1718     /****
    1719      * Abort a transfer in progress.
    1720      * <p>
    1721      * @return True if successfully completed, false if not.
    1722      * @exception FTPConnectionClosedException
    1723      *      If the FTP server prematurely closes the connection as a result
    1724      *      of the client being idle or some other reason causing the server
    1725      *      to send FTP reply code 421.  This exception may be caught either
    1726      *      as an IOException or independently as itself.
    1727      * @exception IOException  If an I/O error occurs while either sending a
    1728      *      command to the server or receiving a reply from the server.
    1729      ***/
    1730     public boolean abort() throws IOException
    1731     {
    1732         return FTPReply.isPositiveCompletion(abor());
    1733     }
    1734
    1735     /****
    1736      * Deletes a file on the FTP server.
    1737      * <p>
    1738      * @param pathname   The pathname of the file to be deleted.
    1739      * @return True if successfully completed, false if not.
    1740      * @exception FTPConnectionClosedException
    1741      *      If the FTP server prematurely closes the connection as a result
    1742      *      of the client being idle or some other reason causing the server
    1743      *      to send FTP reply code 421.  This exception may be caught either
    1744      *      as an IOException or independently as itself.
    1745      * @exception IOException  If an I/O error occurs while either sending a
    1746      *      command to the server or receiving a reply from the server.
    1747      ***/
    1748     public boolean deleteFile(String pathname) throws IOException
    1749     {
    1750         return FTPReply.isPositiveCompletion(dele(pathname));
    1751     }
    1752
    1753
    1754     /****
    1755      * Removes a directory on the FTP server (if empty).
    1756      * <p>
    1757      * @param pathname  The pathname of the directory to remove.
    1758      * @return True if successfully completed, false if not.
    1759      * @exception FTPConnectionClosedException
    1760      *      If the FTP server prematurely closes the connection as a result
    1761      *      of the client being idle or some other reason causing the server
    1762      *      to send FTP reply code 421.  This exception may be caught either
    1763      *      as an IOException or independently as itself.
    1764      * @exception IOException  If an I/O error occurs while either sending a
    1765      *      command to the server or receiving a reply from the server.
    1766      ***/
    1767     public boolean removeDirectory(String pathname) throws IOException
    1768     {
    1769         return FTPReply.isPositiveCompletion(rmd(pathname));
    1770     }
    1771
    1772
    1773     /****
    1774      * Creates a new subdirectory on the FTP server in the current directory
    1775      * (if a relative pathname is given) or where specified (if an absolute
    1776      * pathname is given).
    1777      * <p>
    1778      * @param pathname The pathname of the directory to create.
    1779      * @return True if successfully completed, false if not.
    1780      * @exception FTPConnectionClosedException
    1781      *      If the FTP server prematurely closes the connection as a result
    1782      *      of the client being idle or some other reason causing the server
    1783      *      to send FTP reply code 421.  This exception may be caught either
    1784      *      as an IOException or independently as itself.
    1785      * @exception IOException  If an I/O error occurs while either sending a
    1786      *      command to the server or receiving a reply from the server.
    1787      ***/
    1788     public boolean makeDirectory(String pathname) throws IOException
    1789     {
    1790         return FTPReply.isPositiveCompletion(mkd(pathname));
    1791     }
    1792
    1793
    1794     /****
    1795      * Returns the pathname of the current working directory.
    1796      * <p>
    1797      * @return The pathname of the current working directory.  If it cannot
    1798      *         be obtained, returns null.
    1799      * @exception FTPConnectionClosedException
    1800      *      If the FTP server prematurely closes the connection as a result
    1801      *      of the client being idle or some other reason causing the server
    1802      *      to send FTP reply code 421.  This exception may be caught either
    1803      *      as an IOException or independently as itself.
    1804      * @exception IOException  If an I/O error occurs while either sending a
    1805      *      command to the server or receiving a reply from the server.
    1806      ***/
    1807     public String printWorkingDirectory() throws IOException
    1808     {
    1809         if (pwd() != FTPReply.PATHNAME_CREATED)
    1810             return null;
    1811
    1812         return __parsePathname((String)_replyLines.elementAt(0));
    1813     }
    1814
    1815
    1816     /***
    1817      * Send a site specific command.
    1818      * @param arguments The site specific command and arguments.
    1819      * @return True if successfully completed, false if not.
    1820      * @exception FTPConnectionClosedException
    1821      *      If the FTP server prematurely closes the connection as a result
    1822      *      of the client being idle or some other reason causing the server
    1823      *      to send FTP reply code 421.  This exception may be caught either
    1824      *      as an IOException or independently as itself.
    1825      * @exception IOException  If an I/O error occurs while either sending a
    1826      *      command to the server or receiving a reply from the server.
    1827      */
    1828     public boolean sendSiteCommand(String arguments) throws IOException
    1829     {
    1830         return FTPReply.isPositiveCompletion(site(arguments));
    1831     }
    1832
    1833
    1834     /****
    1835      * Fetches the system type name from the server and returns the string.
    1836      * This value is cached for the duration of the connection after the
    1837      * first call to this method.  In other words, only the first time
    1838      * that you invoke this method will it issue a SYST command to the
    1839      * FTP server.  FTPClient will remember the value and return the
    1840      * cached value until a call to disconnect.
    1841      * <p>
    1842      * @return The system type name obtained from the server.  null if the
    1843      *       information could not be obtained.
    1844      * @exception FTPConnectionClosedException
    1845      *      If the FTP server prematurely closes the connection as a result
    1846      *      of the client being idle or some other reason causing the server
    1847      *      to send FTP reply code 421.  This exception may be caught either
    1848      *      as an IOException or independently as itself.
    1849      * @exception IOException  If an I/O error occurs while either sending a
    1850      *  command to the server or receiving a reply from the server.
    1851      ***/
    1852     public String getSystemName() throws IOException
    1853     {
    1854       //if (syst() == FTPReply.NAME_SYSTEM_TYPE)
    1855       // Technically, we should expect a NAME_SYSTEM_TYPE response, but
    1856       // in practice FTP servers deviate, so we soften the condition to
    1857       // a positive completion.
    1858         if (__systemName == null && FTPReply.isPositiveCompletion(syst()))
    1859             __systemName = ((String)_replyLines.elementAt(0)).substring(4);
    1860
    1861         return __systemName;
    1862     }
    1863
    1864
    1865     /****
    1866      * Fetches the system help information from the server and returns the
    1867      * full string.
    1868      * <p>
    1869      * @return The system help string obtained from the server.  null if the
    1870      *       information could not be obtained.
    1871      * @exception FTPConnectionClosedException
    1872      *      If the FTP server prematurely closes the connection as a result
    1873      *      of the client being idle or some other reason causing the server
    1874      *      to send FTP reply code 421.  This exception may be caught either
    1875      *      as an IOException or independently as itself.
    1876      * @exception IOException  If an I/O error occurs while either sending a
    1877      *  command to the server or receiving a reply from the server.
    1878      ***/
    1879     public String listHelp() throws IOException
    1880     {
    1881         if (FTPReply.isPositiveCompletion(help()))
    1882             return getReplyString();
    1883         return null;
    1884     }
    1885
    1886
    1887     /***
    1888      * Fetches the help information for a given command from the server and
    1889      * returns the full string.
    1890      * @param command The command on which to ask for help.
    1891      * @return The command help string obtained from the server.  null if the
    1892      *       information could not be obtained.
    1893      * @exception FTPConnectionClosedException
    1894      *      If the FTP server prematurely closes the connection as a result
    1895      *      of the client being idle or some other reason causing the server
    1896      *      to send FTP reply code 421.  This exception may be caught either
    1897      *      as an IOException or independently as itself.
    1898      * @exception IOException  If an I/O error occurs while either sending a
    1899      *  command to the server or receiving a reply from the server.
    1900      */
    1901     public String listHelp(String command) throws IOException
    1902     {
    1903         if (FTPReply.isPositiveCompletion(help(command)))
    1904             return getReplyString();
    1905         return null;
    1906     }
    1907
    1908
    1909     /****
    1910      * Sends a NOOP command to the FTP server.  This is useful for preventing
    1911      * server timeouts.
    1912      * <p>
    1913      * @return True if successfully completed, false if not.
    1914      * @exception FTPConnectionClosedException
    1915      *      If the FTP server prematurely closes the connection as a result
    1916      *      of the client being idle or some other reason causing the server
    1917      *      to send FTP reply code 421.  This exception may be caught either
    1918      *      as an IOException or independently as itself.
    1919      * @exception IOException  If an I/O error occurs while either sending a
    1920      *      command to the server or receiving a reply from the server.
    1921      ***/
    1922     public boolean sendNoOp() throws IOException
    1923     {
    1924         return FTPReply.isPositiveCompletion(noop());
    1925     }
    1926
    1927
    1928     /****
    1929      * Obtain a list of filenames in a directory (or just the name of a given
    1930      * file, which is not particularly useful).  This information is obtained
    1931      * through the NLST command.  If the given pathname is a directory and
    1932      * contains no files,  a zero length array is returned only
    1933      * if the FTP server returned a positive completion code, otherwise
    1934      * null is returned (the FTP server returned a 550 error No files found.).
    1935      * If the directory is not empty, an array of filenames in the directory is
    1936      * returned. If the pathname corresponds
    1937      * to a file, only that file will be listed.  The server may or may not
    1938      * expand glob expressions.
    1939      * <p>
    1940      * @param pathname  The file or directory to list.
    1941      * @return The list of filenames contained in the given path.  null if
    1942      *     the list could not be obtained.  If there are no filenames in
    1943      *     the directory, a zero-length array is returned.
    1944      * @exception FTPConnectionClosedException
    1945      *      If the FTP server prematurely closes the connection as a result
    1946      *      of the client being idle or some other reason causing the server
    1947      *      to send FTP reply code 421.  This exception may be caught either
    1948      *      as an IOException or independently as itself.
    1949      * @exception IOException  If an I/O error occurs while either sending a
    1950      *      command to the server or receiving a reply from the server.
    1951      ***/
    1952     public String[] listNames(String pathname) throws IOException
    1953     {
    1954         String line;
    1955         Socket socket;
    1956         BufferedReader reader;
    1957         Vector results;
    1958
    1959         if ((socket = _openDataConnection_(FTPCommand.NLST, pathname)) == null)
    1960             return null;
    1961
    1962         reader =
    1963             new BufferedReader(new InputStreamReader(socket.getInputStream(), getControlEncoding()));
    1964
    1965         results = new Vector();
    1966         while ((line = reader.readLine()) != null)
    1967             results.addElement(line);
    1968         reader.close();
    1969         socket.close();
    1970
    1971         if (completePendingCommand())
    1972         {
    1973             String[] result;
    1974             result = new String[results.size()];
    1975             results.copyInto(result);
    1976             return result;
    1977         }
    1978
    1979         return null;
    1980     }
    1981
    1982
    1983     /****
    1984      * Obtain a list of filenames in the current working directory
    1985      * This information is obtained through the NLST command.  If the current
    1986      * directory contains no files, a zero length array is returned only
    1987      * if the FTP server returned a positive completion code, otherwise,
    1988      * null is returned (the FTP server returned a 550 error No files found.).
    1989      * If the directory is not empty, an array of filenames in the directory is
    1990      * returned.
    1991      * <p>
    1992      * @return The list of filenames contained in the current working
    1993      *     directory.  null if the list could not be obtained.
    1994      *     If there are no filenames in the directory, a zero-length array
    1995      *     is returned.
    1996      * @exception FTPConnectionClosedException
    1997      *      If the FTP server prematurely closes the connection as a result
    1998      *      of the client being idle or some other reason causing the server
    1999      *      to send FTP reply code 421.  This exception may be caught either
    2000      *      as an IOException or independently as itself.
    2001      * @exception IOException  If an I/O error occurs while either sending a
    2002      *      command to the server or receiving a reply from the server.
    2003      ***/
    2004     public String[] listNames() throws IOException
    2005     {
    2006         return listNames(null);
    2007     }
    2008
    2009
    2010     /***
    2011      * Using the supplied <code>parserKey</code>, obtain a list
    2012      * of file information for the current working directory or for just a
    2013      * single file.
    2014      * <p>
    2015      * If <code>key</code> is null, this object will try to autodetect
    2016      * the system-type/parser-type by calling the SYST command.
    2017      * <p>
    2018      * Under the DefaultFTPFileEntryParserFactory, which is used unless a
    2019      * different factory has been specified, the key
    2020      * can be either a recognized System type for which a parser has been
    2021      * defined, or the fully qualified class name of a class that implements
    2022      * org.apache.commons.net.ftp.FTPFileEntryParser.
    2023      * <p>
    2024      * This information is obtained through the LIST command.  The contents of
    2025      * the returned array is determined by the<code> FTPFileEntryParser </code>
    2026      * used.
    2027      * <p>
    2028      * @param parserKey This is a "handle" which the parser factory used
    2029      *                  must be able to resolve into a class implementing
    2030      *                  FTPFileEntryParser.
    2031      *                  <p>
    2032      *                  In the DefaultFTPFileEntryParserFactory, this
    2033      *                  may either be a specific key identifying a server type,
    2034      *                  which is used to identify a parser type,
    2035      *                  or the fully qualified class name of the parser.  See
    2036      *                  DefaultFTPFileEntryParserFactory.createFileEntryParser
    2037      *                  for full details.
    2038      *                  <p>
    2039      *                  If this parameter is null, will attempt to generate a key
    2040      *                  by running the SYST command.  This should cause no problem
    2041      *                  with the functionality implemented in the
    2042      *                  DefaultFTPFileEntryParserFactory, but may not map so well
    2043      *                  to an alternative user-created factory.  If that is the
    2044      *                  case, calling this routine with a null parameter and a
    2045      *                  custom parser factory may not be advisable.
    2046      *                  <p>
    2047      * @param pathname  The file or directory to list.  Since the server may
    2048      *                  or may not expand glob expressions, using them here
    2049      *                  is not recommended and may well cause this method to
    2050      *                  fail.
    2051      *
    2052      * @return The list of file information contained in the given path in
    2053      *         the format determined by the parser represented by the
    2054      *         <code> parserKey </code> parameter.
    2055      *         <p><b>
    2056      * 		   NOTE:</b> This array may contain null members if any of the
    2057      *         individual file listings failed to parse.  The caller should
    2058      *         check each entry for null before referencing it.
    2059      * @exception FTPConnectionClosedException
    2060      *                   If the FTP server prematurely closes the connection
    2061      *                   as a result of the client being idle or some other
    2062      *                   reason causing the server to send FTP reply code 421.
    2063      *                   This exception may be caught either as an IOException
    2064      *                   or independently as itself.
    2065      * @exception IOException
    2066      *                   If an I/O error occurs while either sending a
    2067      *                   command to the server or receiving a reply
    2068      *                   from the server.
    2069      * @exception ParserInitializationException
    2070      *                   Thrown if the parserKey parameter cannot be
    2071      *                   resolved by the selected parser factory.
    2072      *                   In the DefaultFTPEntryParserFactory, this will
    2073      *                   happen when parserKey is neither
    2074      *                   the fully qualified class name of a class
    2075      *                   implementing the interface
    2076      *                   org.apache.commons.net.ftp.FTPFileEntryParser
    2077      *                   nor a string containing one of the recognized keys
    2078      *                   mapping to such a parser or if class loader
    2079      *                   security issues prevent its being loaded.
    2080      * @see org.apache.commons.net.ftp.parser.DefaultFTPFileEntryParserFactory
    2081      * @see org.apache.commons.net.ftp.parser.FTPFileEntryParserFactory
    2082      * @see org.apache.commons.net.ftp.FTPFileEntryParser
    2083      * @deprecated use {@link  #listFiles()  listFiles()} or
    2084      * {@link  #listFiles(String)  listFiles(String)} instead and specify the
    2085      * parser Key in an {@link  #FTPClientConfig  FTPClientConfig} object instead.
    2086      */
    2087     public FTPFile[] listFiles(String parserKey, String pathname)
    2088     throws IOException
    2089     {
    2090         FTPListParseEngine engine =
    2091             initiateListParsing(parserKey, pathname);
    2092         return engine.getFiles();
    2093     }
    2094
    2095
    2096     /***
    2097      * Using the default system autodetect mechanism, obtain a
    2098      * list of file information for the current working directory
    2099      * or for just a single file.
    2100      * <p>
    2101      * This information is obtained through the LIST command.  The contents of
    2102      * the returned array is determined by the<code> FTPFileEntryParser </code>
    2103      * used.
    2104      * <p>
    2105      * @param pathname  The file or directory to list.  Since the server may
    2106      *                  or may not expand glob expressions, using them here
    2107      *                  is not recommended and may well cause this method to
    2108      *                  fail.
    2109      *
    2110      * @return The list of file information contained in the given path in
    2111      *         the format determined by the autodetection mechanism
    2112      * @exception FTPConnectionClosedException
    2113      *                   If the FTP server prematurely closes the connection
    2114      *                   as a result of the client being idle or some other
    2115      *                   reason causing the server to send FTP reply code 421.
    2116      *                   This exception may be caught either as an IOException
    2117      *                   or independently as itself.
    2118      * @exception IOException
    2119      *                   If an I/O error occurs while either sending a
    2120      *                   command to the server or receiving a reply
    2121      *                   from the server.
    2122      * @exception ParserInitializationException
    2123      *                   Thrown if the parserKey parameter cannot be
    2124      *                   resolved by the selected parser factory.
    2125      *                   In the DefaultFTPEntryParserFactory, this will
    2126      *                   happen when parserKey is neither
    2127      *                   the fully qualified class name of a class
    2128      *                   implementing the interface
    2129      *                   org.apache.commons.net.ftp.FTPFileEntryParser
    2130      *                   nor a string containing one of the recognized keys
    2131      *                   mapping to such a parser or if class loader
    2132      *                   security issues prevent its being loaded.
    2133      * @see org.apache.commons.net.ftp.parser.DefaultFTPFileEntryParserFactory
    2134      * @see org.apache.commons.net.ftp.parser.FTPFileEntryParserFactory
    2135      * @see org.apache.commons.net.ftp.FTPFileEntryParser
    2136      */
    2137     public FTPFile[] listFiles(String pathname)
    2138     throws IOException
    2139     {
    2140         String key = null;
    2141         FTPListParseEngine engine =
    2142             initiateListParsing(key, pathname);
    2143         return engine.getFiles();
    2144
    2145     }
    2146     /***
    2147      * Using the default system autodetect mechanism, obtain a
    2148      * list of file information for the current working directory.
    2149      * <p>
    2150      * This information is obtained through the LIST command.  The contents of
    2151      * the returned array is determined by the<code> FTPFileEntryParser </code>
    2152      * used.
    2153      * <p>
    2154      * @return The list of file information contained in the current directory
    2155      *         in the format determined by the autodetection mechanism.
    2156      *         <p><b>
    2157      * 		   NOTE:</b> This array may contain null members if any of the
    2158      *         individual file listings failed to parse.  The caller should
    2159      *         check each entry for null before referencing it.
    2160      * @exception FTPConnectionClosedException
    2161      *                   If the FTP server prematurely closes the connection
    2162      *                   as a result of the client being idle or some other
    2163      *                   reason causing the server to send FTP reply code 421.
    2164      *                   This exception may be caught either as an IOException
    2165      *                   or independently as itself.
    2166      * @exception IOException
    2167      *                   If an I/O error occurs while either sending a
    2168      *                   command to the server or receiving a reply
    2169      *                   from the server.
    2170      * @exception ParserInitializationException
    2171      *                   Thrown if the parserKey parameter cannot be
    2172      *                   resolved by the selected parser factory.
    2173      *                   In the DefaultFTPEntryParserFactory, this will
    2174      *                   happen when parserKey is neither
    2175      *                   the fully qualified class name of a class
    2176      *                   implementing the interface
    2177      *                   org.apache.commons.net.ftp.FTPFileEntryParser
    2178      *                   nor a string containing one of the recognized keys
    2179      *                   mapping to such a parser or if class loader
    2180      *                   security issues prevent its being loaded.
    2181      * @see org.apache.commons.net.ftp.parser.DefaultFTPFileEntryParserFactory
    2182      * @see org.apache.commons.net.ftp.parser.FTPFileEntryParserFactory
    2183      * @see org.apache.commons.net.ftp.FTPFileEntryParser
    2184      */
    2185     public FTPFile[] listFiles()
    2186     throws IOException
    2187     {
    2188         return listFiles((String) null);
    2189     }
    2190
    2191     /***
    2192      * Using the default autodetect mechanism, initialize an FTPListParseEngine
    2193      * object containing a raw file information for the current working
    2194      * directory on the server
    2195      * This information is obtained through the LIST command.  This object
    2196      * is then capable of being iterated to return a sequence of FTPFile
    2197      * objects with information filled in by the
    2198      * <code> FTPFileEntryParser </code> used.
    2199      * <p>
    2200      * This method differs from using the listFiles() methods in that
    2201      * expensive FTPFile objects are not created until needed which may be
    2202      * an advantage on large lists.
    2203      *
    2204      * @return A FTPListParseEngine object that holds the raw information and
    2205      * is capable of providing parsed FTPFile objects, one for each file
    2206      * containing information contained in the given path in the format
    2207      * determined by the <code> parser </code> parameter.   Null will be
    2208      * returned if a data connection cannot be opened.  If the current working
    2209      * directory contains no files, an empty array will be the return.
    2210      *
    2211      * @exception FTPConnectionClosedException
    2212      *                   If the FTP server prematurely closes the connection as a result
    2213      *                   of the client being idle or some other reason causing the server
    2214      *                   to send FTP reply code 421.  This exception may be caught either
    2215      *                   as an IOException or independently as itself.
    2216      * @exception IOException
    2217      *                   If an I/O error occurs while either sending a
    2218      *                   command to the server or receiving a reply from the server.
    2219      * @exception ParserInitializationException
    2220      *                   Thrown if the autodetect mechanism cannot
    2221      *                   resolve the type of system we are connected with.
    2222      * @see FTPListParseEngine
    2223      */
    2224     public FTPListParseEngine initiateListParsing()
    2225     throws IOException
    2226     {
    2227         return initiateListParsing((String) null);
    2228     }
    2229
    2230     /***
    2231      * Using the default autodetect mechanism, initialize an FTPListParseEngine
    2232      * object containing a raw file information for the supplied directory.
    2233      * This information is obtained through the LIST command.  This object
    2234      * is then capable of being iterated to return a sequence of FTPFile
    2235      * objects with information filled in by the
    2236      * <code> FTPFileEntryParser </code> used.
    2237      * <p>
    2238      * The server may or may not expand glob expressions.  You should avoid
    2239      * using glob expressions because the return format for glob listings
    2240      * differs from server to server and will likely cause this method to fail.
    2241      * <p>
    2242      * This method differs from using the listFiles() methods in that
    2243      * expensive FTPFile objects are not created until needed which may be
    2244      * an advantage on large lists.
    2245      * <p>
    2246      * <pre>
    2247      *    FTPClient f=FTPClient();
    2248      *    f.connect(server);
    2249      *    f.login(username, password);
    2250      *    FTPListParseEngine engine = f.initiateListParsing(directory);
    2251      *
    2252      *    while (engine.hasNext()) {
    2253      *       FTPFile[] files = engine.getNext(25);  // "page size" you want
    2254      *       //do whatever you want with these files, display them, etc.
    2255      *       //expensive FTPFile objects not created until needed.
    2256      *    }
    2257      * </pre>
    2258      *
    2259      * @return A FTPListParseEngine object that holds the raw information and
    2260      * is capable of providing parsed FTPFile objects, one for each file
    2261      * containing information contained in the given path in the format
    2262      * determined by the <code> parser </code> parameter.   Null will be
    2263      * returned if a data connection cannot be opened.  If the current working
    2264      * directory contains no files, an empty array will be the return.
    2265      *
    2266      * @exception FTPConnectionClosedException
    2267      *                   If the FTP server prematurely closes the connection as a result
    2268      *                   of the client being idle or some other reason causing the server
    2269      *                   to send FTP reply code 421.  This exception may be caught either
    2270      *                   as an IOException or independently as itself.
    2271      * @exception IOException
    2272      *                   If an I/O error occurs while either sending a
    2273      *                   command to the server or receiving a reply from the server.
    2274      * @exception ParserInitializationException
    2275      *                   Thrown if the autodetect mechanism cannot
    2276      *                   resolve the type of system we are connected with.
    2277      * @see FTPListParseEngine
    2278      */
    2279     public FTPListParseEngine initiateListParsing(
    2280             String pathname)
    2281     throws IOException
    2282     {
    2283         String key = null;
    2284         return initiateListParsing(key, pathname);
    2285     }
    2286
    2287     /***
    2288      * Using the supplied parser key, initialize an FTPListParseEngine
    2289      * object containing a raw file information for the supplied directory.
    2290      * This information is obtained through the LIST command.  This object
    2291      * is then capable of being iterated to return a sequence of FTPFile
    2292      * objects with information filled in by the
    2293      * <code> FTPFileEntryParser </code> used.
    2294      * <p>
    2295      * The server may or may not expand glob expressions.  You should avoid
    2296      * using glob expressions because the return format for glob listings
    2297      * differs from server to server and will likely cause this method to fail.
    2298      * <p>
    2299      * This method differs from using the listFiles() methods in that
    2300      * expensive FTPFile objects are not created until needed which may be
    2301      * an advantage on large lists.
    2302      *
    2303      * @param parserKey A string representing a designated code or fully-qualified
    2304      * class name of an  <code> FTPFileEntryParser </code> that should be
    2305      *               used to parse each server file listing.
    2306      *
    2307      * @return A FTPListParseEngine object that holds the raw information and
    2308      * is capable of providing parsed FTPFile objects, one for each file
    2309      * containing information contained in the given path in the format
    2310      * determined by the <code> parser </code> parameter.   Null will be
    2311      * returned if a data connection cannot be opened.  If the current working
    2312      * directory contains no files, an empty array will be the return.
    2313      *
    2314      * @exception FTPConnectionClosedException
    2315      *                   If the FTP server prematurely closes the connection as a result
    2316      *                   of the client being idle or some other reason causing the server
    2317      *                   to send FTP reply code 421.  This exception may be caught either
    2318      *                   as an IOException or independently as itself.
    2319      * @exception IOException
    2320      *                   If an I/O error occurs while either sending a
    2321      *                   command to the server or receiving a reply from the server.
    2322      * @exception ParserInitializationException
    2323      *                   Thrown if the parserKey parameter cannot be
    2324      *                   resolved by the selected parser factory.
    2325      *                   In the DefaultFTPEntryParserFactory, this will
    2326      *                   happen when parserKey is neither
    2327      *                   the fully qualified class name of a class
    2328      *                   implementing the interface
    2329      *                   org.apache.commons.net.ftp.FTPFileEntryParser
    2330      *                   nor a string containing one of the recognized keys
    2331      *                   mapping to such a parser or if class loader
    2332      *                   security issues prevent its being loaded.
    2333      * @see FTPListParseEngine
    2334      */
    2335     public FTPListParseEngine initiateListParsing(
    2336             String parserKey, String pathname)
    2337     throws IOException
    2338     {
    2339         // We cache the value to avoid creation of a new object every
    2340         // time a file listing is generated.
    2341         if(__entryParser == null) {
    2342             if (null != parserKey) {
    2343                 // if a parser key was supplied in the parameters,
    2344                 // use that to create the paraser
    2345         	    __entryParser =
    2346         	        __parserFactory.createFileEntryParser(parserKey);
    2347
    2348             } else {
    2349 	            // if no parserKey was supplied, check for a configuration
    2350 	        	// in the params, and if non-null, use that.
    2351             	if (null != __configuration) {
    2352             	    __entryParser =
    2353             	        __parserFactory.createFileEntryParser(__configuration);
    2354             	} else {
    2355                     // if a parserKey hasn't been supplied, and a configuration
    2356             	    // hasn't been supplied, then autodetect by calling
    2357                     // the SYST command and use that to choose the parser.
    2358             	    __entryParser =
    2359             	        __parserFactory.createFileEntryParser(getSystemName());
    2360              	}
    2361             }
    2362         }
    2363
    2364         return initiateListParsing(__entryParser, pathname);
    2365
    2366     }
    2367
    2368
    2369     /***
    2370      * private method through which all listFiles() and
    2371      * initiateListParsing methods pass once a parser is determined.
    2372      *
    2373      * @exception FTPConnectionClosedException
    2374      *                   If the FTP server prematurely closes the connection as a result
    2375      *                   of the client being idle or some other reason causing the server
    2376      *                   to send FTP reply code 421.  This exception may be caught either
    2377      *                   as an IOException or independently as itself.
    2378      * @exception IOException
    2379      *                   If an I/O error occurs while either sending a
    2380      *                   command to the server or receiving a reply from the server.
    2381      * @see FTPListParseEngine
    2382      */
    2383     private FTPListParseEngine initiateListParsing(
    2384             FTPFileEntryParser parser, String pathname)
    2385     throws IOException
    2386     {
    2387         Socket socket;
    2388
    2389         FTPListParseEngine engine = new FTPListParseEngine(parser);
    2390         if ((socket = _openDataConnection_(FTPCommand.LIST, pathname)) == null)
    2391         {
    2392             return engine;
    2393         }
    2394
    2395
    2396         engine.readServerList(socket.getInputStream(), getControlEncoding());
    2397
    2398         socket.close();
    2399
    2400         completePendingCommand();
    2401         return engine;
    2402     }
    2403
    2404     /****
    2405      * Issue the FTP STAT command to the server.
    2406      * <p>
    2407      * @return The status information returned by the server.
    2408      * @exception FTPConnectionClosedException
    2409      *      If the FTP server prematurely closes the connection as a result
    2410      *      of the client being idle or some other reason causing the server
    2411      *      to send FTP reply code 421.  This exception may be caught either
    2412      *      as an IOException or independently as itself.
    2413      * @exception IOException  If an I/O error occurs while either sending a
    2414      *      command to the server or receiving a reply from the server.
    2415      ***/
    2416     public String getStatus() throws IOException
    2417     {
    2418         if (FTPReply.isPositiveCompletion(stat()))
    2419             return getReplyString();
    2420         return null;
    2421     }
    2422
    2423
    2424     /****
    2425      * Issue the FTP STAT command to the server for a given pathname.  This
    2426      * should produce a listing of the file or directory.
    2427      * <p>
    2428      * @return The status information returned by the server.
    2429      * @exception FTPConnectionClosedException
    2430      *      If the FTP server prematurely closes the connection as a result
    2431      *      of the client being idle or some other reason causing the server
    2432      *      to send FTP reply code 421.  This exception may be caught either
    2433      *      as an IOException or independently as itself.
    2434      * @exception IOException  If an I/O error occurs while either sending a
    2435      *      command to the server or receiving a reply from the server.
    2436      ***/
    2437     public String getStatus(String pathname) throws IOException
    2438     {
    2439         if (FTPReply.isPositiveCompletion(stat(pathname)))
    2440             return getReplyString();
    2441         return null;
    2442     }
    2443
    2444     /***
    2445      * Using a programmer specified <code> FTPFileListParser </code>, obtain a
    2446      * list of file information for a directory or information for
    2447      * just a single file.  This information is obtained through the LIST
    2448      * command.  The contents of the returned array is determined by the
    2449      * <code> FTPFileListParser </code> used.
    2450      * The server may or may not expand glob expressions.  You should avoid
    2451      * using glob expressions because the return format for glob listings
    2452      * differs from server to server and will likely cause this method to fail.
    2453      * <p>
    2454      * @param parser The <code> FTPFileListParser </code> that should be
    2455      *         used to parse the server file listing.
    2456      * @param pathname  The file or directory to list.
    2457      * @return The list of file information contained in the given path in
    2458      *         the format determined by the <code> parser </code> parameter.
    2459      *         <p><b>
    2460      * 		   NOTE:</b> This array may contain null members if any of the
    2461      *         individual file listings failed to parse.  The caller should
    2462      *         check each entry for null before referencing it.
    2463      * @exception FTPConnectionClosedException
    2464      *      If the FTP server prematurely closes the connection as a result
    2465      *      of the client being idle or some other reason causing the server
    2466      *      to send FTP reply code 421.  This exception may be caught either
    2467      *      as an IOException or independently as itself.
    2468      * @exception IOException  If an I/O error occurs while either sending a
    2469      *      command to the server or receiving a reply from the server.
    2470      *
    2471      * @return The list of file information contained in the given path in
    2472      *         the format determined by<code> parserKey </code>parameter.
    2473      *         <p><b>
    2474      * 		   NOTE:</b> This array may contain null members if any of the
    2475      *         individual file listings failed to parse.  The caller should
    2476      *         check each entry for null before referencing it.
    2477      *
    2478      * @exception IOException
    2479      * @since 5 Jan 2004
    2480      * @deprecated use listFiles(String parserKey, String pathname) instead
    2481      */
    2482     public FTPFile[] listFiles(FTPFileListParser parser, String pathname)
    2483     throws IOException
    2484     {
    2485         Socket socket;
    2486         FTPFile[] results;
    2487
    2488         if ((socket = _openDataConnection_(FTPCommand.LIST, pathname)) == null)
    2489             return new FTPFile[0];
    2490
    2491         results = parser.parseFileList(socket.getInputStream(), getControlEncoding());
    2492
    2493         socket.close();
    2494
    2495         completePendingCommand();
    2496
    2497         return results;
    2498     }
    2499
    2500
    2501     /***
    2502      * Using a programmer specified <code> FTPFileListParser </code>,
    2503      * obtain a list of file information for the current working directory.
    2504      * This information is obtained through the LIST command.
    2505      * The contents of the array returned is determined by the
    2506      * <code> FTPFileListParser </code> used.
    2507      * <p>
    2508      *
    2509      * @param parser The <code> FTPFileListParser </code> that should be
    2510      *               used to parse the server file listing.
    2511      *
    2512      * @return The list of file information contained in the given path in
    2513      *         the format determined by the <code> parser </code> parameter.
    2514      *         <p><b>
    2515      * 		   NOTE:</b> This array may contain null members if any of the
    2516      *         individual file listings failed to parse.  The caller should
    2517      *         check each entry for null before referencing it.
    2518      * @exception FTPConnectionClosedException
    2519      *                   If the FTP server prematurely closes the connection as a result
    2520      *                   of the client being idle or some other reason causing the server
    2521      *                   to send FTP reply code 421.  This exception may be caught either
    2522      *                   as an IOException or independently as itself.
    2523      * @exception IOException
    2524      *                   If an I/O error occurs while either sending a
    2525      *                   command to the server or receiving a reply from the server.
    2526      * @exception IOException
    2527      * @since 5 Jan 2004
    2528      * @deprecated use listFiles(String parserKey) instead.
    2529      */
    2530     public FTPFile[] listFiles(FTPFileListParser parser) throws IOException
    2531     {
    2532         return listFiles(parser, null);
    2533     }
    2534
    2535
    2536     /***
    2537      * Using a programmer specified <code> FTPFileEntryParser </code>,
    2538      * initialize an object containing a raw file information for the
    2539      * current working directory.  This information is obtained through
    2540      * the LIST command.  This object is then capable of being iterated to
    2541      * return a sequence of FTPFile objects with information filled in by the
    2542      * <code> FTPFileEntryParser </code> used.
    2543      * <p>
    2544      * The server may or may not expand glob expressions.  You should avoid
    2545      * using glob expressions because the return format for glob listings
    2546      * differs from server to server and will likely cause this method to fail.
    2547      * <p>
    2548      * This method differs from using the listFiles() methods in that
    2549      * expensive FTPFile objects are not created until needed which may be
    2550      * an advantage on large lists.
    2551      *
    2552      * @param parser The <code> FTPFileEntryParser </code> that should be
    2553      *               used to parse each server file listing.
    2554      *
    2555      * @return An iteratable object that holds the raw information and is
    2556      *         capable of providing parsed FTPFile objects, one for each file containing
    2557      *         information contained in the given path in the format determined by the
    2558      *         <code> parser </code> parameter.   Null will be returned if a
    2559      *         data connection cannot be opened.  If the current working directory
    2560      *         contains no files, an empty array will be the return.
    2561      * <pre>
    2562      *    FTPClient f=FTPClient();
    2563      *    f.connect(server);
    2564      *    f.login(username, password);
    2565      *    FTPFileList list = f.createFileList(directory, parser);
    2566      *    FTPFileIterator iter = list.iterator();
    2567      *
    2568      *    while (iter.hasNext()) {
    2569      *       FTPFile[] files = iter.getNext(25);  // "page size" you want
    2570      *       //do whatever you want with these files, display them, etc.
    2571      *       //expensive FTPFile objects not created until needed.
    2572      *    }
    2573      * </pre>
    2574      *
    2575      * @exception FTPConnectionClosedException
    2576      *                   If the FTP server prematurely closes the connection as a result
    2577      *                   of the client being idle or some other reason causing the server
    2578      *                   to send FTP reply code 421.  This exception may be caught either
    2579      *                   as an IOException or independently as itself.
    2580      * @exception IOException
    2581      *                   If an I/O error occurs while either sending a
    2582      *                   command to the server or receiving a reply from the server.
    2583      * @deprecated - use initiateListParsing(FTPFileEntryParser) method instead.
    2584      * @see FTPFileList
    2585      */
    2586     public FTPFileList createFileList(FTPFileEntryParser parser) throws IOException
    2587     {
    2588         return createFileList(null, parser);
    2589     }
    2590
    2591     /***
    2592      * Using a programmer specified <code> FTPFileEntryParser </code>,
    2593      * initialize an object containing a raw file information for a directory
    2594      * or information for a single file.  This information is obtained through
    2595      * the LIST command.  This object is then capable of being iterated to
    2596      * return a sequence of FTPFile objects with information filled in by the
    2597      * <code> FTPFileEntryParser </code> used.
    2598      * The server may or may not expand glob expressions.  You should avoid
    2599      * using glob expressions because the return format for glob listings
    2600      * differs from server to server and will likely cause this method to fail.
    2601      * <p>
    2602      * @param parser The <code> FTPFileEntryParser </code> that should be
    2603      *         used to parse each server file listing.
    2604      * @param pathname  The file or directory to list.
    2605      * @return An iteratable object that holds the raw information and is
    2606      * capable of providing parsed FTPFile objects, one for each file containing
    2607      * information contained in the given path in the format determined by the
    2608      * <code> parser </code> parameter.  Null will be returned if a
    2609      * data connection cannot be opened.  If the supplied path contains
    2610      * no files, an empty array will be the return.
    2611      * @exception FTPConnectionClosedException
    2612      *      If the FTP server prematurely closes the connection as a result
    2613      *      of the client being idle or some other reason causing the server
    2614      *      to send FTP reply code 421.  This exception may be caught either
    2615      *      as an IOException or independently as itself.
    2616      * @exception IOException  If an I/O error occurs while either sending a
    2617      *      command to the server or receiving a reply from the server.
    2618      * @deprecated - use initiateListParsing(String, FTPFileEntryParser)
    2619      * method instead.
    2620      * @see FTPFileList
    2621      */
    2622     public FTPFileList createFileList(String pathname,
    2623             FTPFileEntryParser parser)
    2624     throws IOException
    2625     {
    2626         Socket socket;
    2627
    2628         if ((socket = _openDataConnection_(FTPCommand.LIST, pathname)) == null)
    2629         {
    2630             return null;
    2631         }
    2632
    2633         FTPFileList list = FTPFileList.create(socket.getInputStream(), parser);
    2634
    2635         socket.close();
    2636
    2637         completePendingCommand();
    2638         return list;
    2639     }
    2640
    2641     /***
    2642      * Set the internal buffer size.
    2643      *
    2644      * @param bufSize The size of the buffer
    2645      */
    2646     public void setBufferSize(int bufSize) {
    2647     	__bufferSize = bufSize;
    2648     }
    2649
    2650     /***
    2651      * Retrieve the current internal buffer size.
    2652      * @return The current buffer size.
    2653      */
    2654     public int getBufferSize() {
    2655     	return __bufferSize;
    2656     }
    2657
    2658
    2659     /***
    2660      * Implementation of the {@link Configurable Configurable} interface.
    2661      * In the case of this class, configuring merely makes the config object available for the
    2662      * factory methods that construct parsers.
    2663      * @param config {@link FTPClientConfig FTPClientConfig} object used to
    2664      * provide non-standard configurations to the parser.
    2665      * @since 1.4
    2666      */
    2667     public void configure(FTPClientConfig config) {
    2668     	this.__configuration = config;
    2669     }
    2670
    2671 }
    2672
    2673 /* Emacs configuration
    2674  * Local variables:        **
    2675  * mode:             java  **
    2676  * c-basic-offset:   4     **
    2677  * indent-tabs-mode: nil   **
    2678  * End:                    **
    2679  */