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

Save This Page
Home » commons-net-2.0-src » org.apache.commons.net.ftp » [javadoc | source]