    001    /*
    002     * Licensed to the Apache Software Foundation (ASF) under one or more
    003     * contributor license agreements.  See the NOTICE file distributed with
    004     * this work for additional information regarding copyright ownership.
    005     * The ASF licenses this file to You under the Apache License, Version 2.0
    006     * (the "License"); you may not use this file except in compliance with
    007     * the License.  You may obtain a copy of the License at
    008     *
    009     *      http://www.apache.org/licenses/LICENSE-2.0
    010     *
    011     * Unless required by applicable law or agreed to in writing, software
    012     * distributed under the License is distributed on an "AS IS" BASIS,
    013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    014     * See the License for the specific language governing permissions and
    015     * limitations under the License.
    016     */
    017
    018    package org.apache.commons.net.ftp;
    019    import java.io.BufferedReader;
    020    import java.io.BufferedWriter;
    021    import java.io.IOException;
    022    import java.io.InputStreamReader;
    023    import java.io.OutputStreamWriter;
    024    import java.net.Inet4Address;
    025    import java.net.Inet6Address;
    026    import java.net.InetAddress;
    027    import java.net.SocketException;
    028    import java.net.SocketTimeoutException;
    029    import java.util.ArrayList;
    030
    031    import org.apache.commons.net.MalformedServerReplyException;
    032    import org.apache.commons.net.ProtocolCommandSupport;
    033    import org.apache.commons.net.SocketClient;
    034    import org.apache.commons.net.io.CRLFLineReader;
    035
    036    /***
    037     * FTP provides the basic the functionality necessary to implement your
    038     * own FTP client.  It extends org.apache.commons.net.SocketClient since
    039     * extending TelnetClient was causing unwanted behavior (like connections
    040     * that did not time out properly).
    041     * <p>
    042     * To derive the full benefits of the FTP class requires some knowledge
    043     * of the FTP protocol defined in RFC 959.  However, there is no reason
    044     * why you should have to use the FTP class.  The
    045     * {@link org.apache.commons.net.ftp.FTPClient} class,
    046     * derived from FTP,
    047     * implements all the functionality required of an FTP client.  The
    048     * FTP class is made public to provide access to various FTP constants
    049     * and to make it easier for adventurous programmers (or those with
    050     * special needs) to interact with the FTP protocol and implement their
    051     * own clients.  A set of methods with names corresponding to the FTP
    052     * command names are provided to facilitate this interaction.
    053     * <p>
    054     * You should keep in mind that the FTP server may choose to prematurely
    055     * close a connection if the client has been idle for longer than a
    056     * given time period (usually 900 seconds).  The FTP class will detect a
    057     * premature FTP server connection closing when it receives a
    058     * {@link org.apache.commons.net.ftp.FTPReply#SERVICE_NOT_AVAILABLE FTPReply.SERVICE_NOT_AVAILABLE }
    059     *  response to a command.
    060     * When that occurs, the FTP class method encountering that reply will throw
    061     * an {@link org.apache.commons.net.ftp.FTPConnectionClosedException}
    062     * .  <code>FTPConectionClosedException</code>
    063     * is a subclass of <code> IOException </code> and therefore need not be
    064     * caught separately, but if you are going to catch it separately, its
    065     * catch block must appear before the more general <code> IOException </code>
    066     * catch block.  When you encounter an
    067     * {@link org.apache.commons.net.ftp.FTPConnectionClosedException}
    068     * , you must disconnect the connection with
    069     * {@link #disconnect  disconnect() } to properly clean up the
    070     * system resources used by FTP.  Before disconnecting, you may check the
    071     * last reply code and text with
    072     * {@link #getReplyCode  getReplyCode },
    073     * {@link #getReplyString  getReplyString },
    074     * and {@link #getReplyStrings  getReplyStrings}.
    075     * You may avoid server disconnections while the client is idle by
    076     * periodicaly sending NOOP commands to the server.
    077     * <p>
    078     * Rather than list it separately for each method, we mention here that
    079     * every method communicating with the server and throwing an IOException
    080     * can also throw a
    081     * {@link org.apache.commons.net.MalformedServerReplyException}
    082     * , which is a subclass
    083     * of IOException.  A MalformedServerReplyException will be thrown when
    084     * the reply received from the server deviates enough from the protocol
    085     * specification that it cannot be interpreted in a useful manner despite
    086     * attempts to be as lenient as possible.
    087     * <p>
    088     * <p>
    089     * @author Rory Winston
    090     * @author Joseph Hindsley
    091     * @see FTPClient
    092     * @see FTPConnectionClosedException
    093     * @see org.apache.commons.net.MalformedServerReplyException
    094     * @version $Id: FTP.java 1230358 2012-01-12 01:51:02Z sebb $
    095     ***/
    096
    097    public class FTP extends SocketClient
    098    {
    099        /*** The default FTP data port (20). ***/
    100        public static final int DEFAULT_DATA_PORT = 20;
    101        /*** The default FTP control port (21). ***/
    102        public static final int DEFAULT_PORT = 21;
    103
    104        /***
    105         * A constant used to indicate the file(s) being transfered should
    106         * be treated as ASCII.  This is the default file type.  All constants
    107         * ending in <code>FILE_TYPE</code> are used to indicate file types.
    108         ***/
    109        public static final int ASCII_FILE_TYPE = 0;
    110
    111        /***
    112         * A constant used to indicate the file(s) being transfered should
    113         * be treated as EBCDIC.  Note however that there are several different
    114         * EBCDIC formats.  All constants ending in <code>FILE_TYPE</code>
    115         * are used to indicate file types.
    116         ***/
    117        public static final int EBCDIC_FILE_TYPE = 1;
    118
    119
    120        /***
    121         * A constant used to indicate the file(s) being transfered should
    122         * be treated as a binary image, i.e., no translations should be
    123         * performed.  All constants ending in <code>FILE_TYPE</code> are used to
    124         * indicate file types.
    125         ***/
    126        public static final int BINARY_FILE_TYPE = 2;
    127
    128        /***
    129         * A constant used to indicate the file(s) being transfered should
    130         * be treated as a local type.  All constants ending in
    131         * <code>FILE_TYPE</code> are used to indicate file types.
    132         ***/
    133        public static final int LOCAL_FILE_TYPE = 3;
    134
    135        /***
    136         * A constant used for text files to indicate a non-print text format.
    137         * This is the default format.
    138         * All constants ending in <code>TEXT_FORMAT</code> are used to indicate
    139         * text formatting for text transfers (both ASCII and EBCDIC).
    140         ***/
    141        public static final int NON_PRINT_TEXT_FORMAT = 4;
    142
    143        /***
    144         * A constant used to indicate a text file contains format vertical format
    145         * control characters.
    146         * All constants ending in <code>TEXT_FORMAT</code> are used to indicate
    147         * text formatting for text transfers (both ASCII and EBCDIC).
    148         ***/
    149        public static final int TELNET_TEXT_FORMAT = 5;
    150
    151        /***
    152         * A constant used to indicate a text file contains ASA vertical format
    153         * control characters.
    154         * All constants ending in <code>TEXT_FORMAT</code> are used to indicate
    155         * text formatting for text transfers (both ASCII and EBCDIC).
    156         ***/
    157        public static final int CARRIAGE_CONTROL_TEXT_FORMAT = 6;
    158
    159        /***
    160         * A constant used to indicate a file is to be treated as a continuous
    161         * sequence of bytes.  This is the default structure.  All constants ending
    162         * in <code>_STRUCTURE</code> are used to indicate file structure for
    163         * file transfers.
    164         ***/
    165        public static final int FILE_STRUCTURE = 7;
    166
    167        /***
    168         * A constant used to indicate a file is to be treated as a sequence
    169         * of records.  All constants ending in <code>_STRUCTURE</code>
    170         * are used to indicate file structure for file transfers.
    171         ***/
    172        public static final int RECORD_STRUCTURE = 8;
    173
    174        /***
    175         * A constant used to indicate a file is to be treated as a set of
    176         * independent indexed pages.  All constants ending in
    177         * <code>_STRUCTURE</code> are used to indicate file structure for file
    178         * transfers.
    179         ***/
    180        public static final int PAGE_STRUCTURE = 9;
    181
    182        /***
    183         * A constant used to indicate a file is to be transfered as a stream
    184         * of bytes.  This is the default transfer mode.  All constants ending
    185         * in <code>TRANSFER_MODE</code> are used to indicate file transfer
    186         * modes.
    187         ***/
    188        public static final int STREAM_TRANSFER_MODE = 10;
    189
    190        /***
    191         * A constant used to indicate a file is to be transfered as a series
    192         * of blocks.  All constants ending in <code>TRANSFER_MODE</code> are used
    193         * to indicate file transfer modes.
    194         ***/
    195        public static final int BLOCK_TRANSFER_MODE = 11;
    196
    197        /***
    198         * A constant used to indicate a file is to be transfered as FTP
    199         * compressed data.  All constants ending in <code>TRANSFER_MODE</code>
    200         * are used to indicate file transfer modes.
    201         ***/
    202        public static final int COMPRESSED_TRANSFER_MODE = 12;
    203
    204        // We have to ensure that the protocol communication is in ASCII
    205        // but we use ISO-8859-1 just in case 8-bit characters cross
    206        // the wire.
    207        /**
    208         * The default character encoding used for communicating over an
    209         * FTP control connection.  The default encoding is an
    210         * ASCII-compatible encoding.  Some FTP servers expect other
    211         * encodings.  You can change the encoding used by an FTP instance
    212         * with {@link #setControlEncoding setControlEncoding}.
    213         */
    214        public static final String DEFAULT_CONTROL_ENCODING = "ISO-8859-1";
    215        private static final String __modes = "AEILNTCFRPSBC";
    216
    217        protected int _replyCode;
    218        protected ArrayList<String> _replyLines;
    219        protected boolean _newReplyString;
    220        protected String _replyString;
    221        protected String _controlEncoding;
    222
    223        /**
    224         * A ProtocolCommandSupport object used to manage the registering of
    225         * ProtocolCommandListeners and te firing of ProtocolCommandEvents.
    226         */
    227        protected ProtocolCommandSupport _commandSupport_;
    228
    229        /**
    230         * This is used to signal whether a block of multiline responses beginning
    231         * with xxx must be terminated by the same numeric code xxx
    232         * See section 4.2 of RFC 959 for details.
    233         */
    234        protected boolean strictMultilineParsing = false;
    235
    236        /**
    237         * Wraps SocketClient._input_ to facilitate the reading of text
    238         * from the FTP control connection.  Do not access the control
    239         * connection via SocketClient._input_.  This member starts
    240         * with a null value, is initialized in {@link #_connectAction_},
    241         * and set to null in {@link #disconnect}.
    242         */
    243        protected BufferedReader _controlInput_;
    244
    245        /**
    246         * Wraps SocketClient._output_ to facilitate the writing of text
    247         * to the FTP control connection.  Do not access the control
    248         * connection via SocketClient._output_.  This member starts
    249         * with a null value, is initialized in {@link #_connectAction_},
    250         * and set to null in {@link #disconnect}.
    251         */
    252        protected BufferedWriter _controlOutput_;
    253
    254        /***
    255         * The default FTP constructor.  Sets the default port to
    256         * <code>DEFAULT_PORT</code> and initializes internal data structures
    257         * for saving FTP reply information.
    258         ***/
    259        public FTP()
    260        {
    261            super();
    262            setDefaultPort(DEFAULT_PORT);
    263            _replyLines = new ArrayList<String>();
    264            _newReplyString = false;
    265            _replyString = null;
    266            _controlEncoding = DEFAULT_CONTROL_ENCODING;
    267            _commandSupport_ = new ProtocolCommandSupport(this);
    268        }
    269
    270        // The RFC-compliant multiline termination check
    271        private boolean __strictCheck(String line, String code) {
    272            return (!(line.startsWith(code) && line.charAt(3) == ' '));
    273        }
    274
    275        // The strict check is too strong a condition because of non-conforming ftp
    276        // servers like ftp.funet.fi which sent 226 as the last line of a
    277        // 426 multi-line reply in response to ls /.  We relax the condition to
    278        // test that the line starts with a digit rather than starting with
    279        // the code.
    280        private boolean __lenientCheck(String line) {
    281            return (!(line.length() >= 4 && line.charAt(3) != '-' &&
    282                    Character.isDigit(line.charAt(0))));
    283        }
    284
    285        /**
    286         * Get the reply, and pass it to command listeners
    287         */
    288        private void __getReply()  throws IOException
    289        {
    290            __getReply(true);
    291        }
    292
    293        /**
    294         * Get the reply, but don't pass it to command listeners.
    295         * Used for keep-alive processing only.
    296         * @since 3.0
    297         */
    298        protected void __getReplyNoReport()  throws IOException
    299        {
    300            __getReply(false);
    301        }
    302
    303        private void __getReply(boolean reportReply) throws IOException
    304        {
    305            int length;
    306
    307            _newReplyString = true;
    308            _replyLines.clear();
    309
    310            String line = _controlInput_.readLine();
    311
    312            if (line == null) {
    313                throw new FTPConnectionClosedException(
    314                        "Connection closed without indication.");
    315            }
    316
    317            // In case we run into an anomaly we don't want fatal index exceptions
    318            // to be thrown.
    319            length = line.length();
    320            if (length < 3) {
    321                throw new MalformedServerReplyException(
    322                    "Truncated server reply: " + line);
    323            }
    324
    325            String code = null;
    326            try
    327            {
    328                code = line.substring(0, 3);
    329                _replyCode = Integer.parseInt(code);
    330            }
    331            catch (NumberFormatException e)
    332            {
    333                throw new MalformedServerReplyException(
    334                    "Could not parse response code.\nServer Reply: " + line);
    335            }
    336
    337            _replyLines.add(line);
    338
    339            // Get extra lines if message continues.
    340            if (length > 3 && line.charAt(3) == '-')
    341            {
    342                do
    343                {
    344                    line = _controlInput_.readLine();
    345
    346                    if (line == null) {
    347                        throw new FTPConnectionClosedException(
    348                            "Connection closed without indication.");
    349                    }
    350
    351                    _replyLines.add(line);
    352
    353                    // The length() check handles problems that could arise from readLine()
    354                    // returning too soon after encountering a naked CR or some other
    355                    // anomaly.
    356                }
    357                while ( isStrictMultilineParsing() ? __strictCheck(line, code) : __lenientCheck(line));
    358            }
    359
    360            fireReplyReceived(_replyCode, getReplyString());
    361
    362            if (_replyCode == FTPReply.SERVICE_NOT_AVAILABLE) {
    363                throw new FTPConnectionClosedException("FTP response 421 received.  Server closed connection.");
    364            }
    365        }
    366
    367        /**
    368         * Initiates control connections and gets initial reply.
    369         * Initializes {@link #_controlInput_} and {@link #_controlOutput_}.
    370         */
    371        @Override
    372        protected void _connectAction_() throws IOException
    373        {
    374            super._connectAction_(); // sets up _input_ and _output_
    375            _controlInput_ =
    376                new CRLFLineReader(new InputStreamReader(_input_, getControlEncoding()));
    377            _controlOutput_ =
    378                new BufferedWriter(new OutputStreamWriter(_output_, getControlEncoding()));
    379            if (connectTimeout > 0) { // NET-385
    380                int original = _socket_.getSoTimeout();
    381                _socket_.setSoTimeout(connectTimeout);
    382                try {
    383                    __getReply();
    384                    // If we received code 120, we have to fetch completion reply.
    385                    if (FTPReply.isPositivePreliminary(_replyCode)) {
    386                        __getReply();
    387                    }
    388                } catch (SocketTimeoutException e) {
    389                    IOException ioe = new IOException("Timed out waiting for initial connect reply");
    390                    ioe.initCause(e);
    391                    throw ioe;
    392                } finally {
    393                    _socket_.setSoTimeout(original);
    394                }
    395            } else {
    396                __getReply();
    397                // If we received code 120, we have to fetch completion reply.
    398                if (FTPReply.isPositivePreliminary(_replyCode)) {
    399                    __getReply();
    400                }
    401            }
    402        }
    403
    404
    405        /**
    406         * Sets the character encoding used by the FTP control connection.
    407         * Some FTP servers require that commands be issued in a non-ASCII
    408         * encoding like UTF-8 so that filenames with multi-byte character
    409         * representations (e.g, Big 8) can be specified.
    410         *
    411         * @param encoding The new character encoding for the control connection.
    412         */
    413        public void setControlEncoding(String encoding) {
    414            _controlEncoding = encoding;
    415        }
    416
    417
    418        /**
    419         * @return The character encoding used to communicate over the
    420         * control connection.
    421         */
    422        public String getControlEncoding() {
    423            return _controlEncoding;
    424        }
    425
    426
    427        /***
    428         * Closes the control connection to the FTP server and sets to null
    429         * some internal data so that the memory may be reclaimed by the
    430         * garbage collector.  The reply text and code information from the
    431         * last command is voided so that the memory it used may be reclaimed.
    432         * Also sets {@link #_controlInput_} and {@link #_controlOutput_} to null.
    433         * <p>
    434         * @exception IOException If an error occurs while disconnecting.
    435         ***/
    436        @Override
    437        public void disconnect() throws IOException
    438        {
    439            super.disconnect();
    440            _controlInput_ = null;
    441            _controlOutput_ = null;
    442            _newReplyString = false;
    443            _replyString = null;
    444        }
    445
    446
    447        /***
    448         * Sends an FTP command to the server, waits for a reply and returns the
    449         * numerical response code.  After invocation, for more detailed
    450         * information, the actual reply text can be accessed by calling
    451         * {@link #getReplyString  getReplyString } or
    452         * {@link #getReplyStrings  getReplyStrings }.
    453         * <p>
    454         * @param command  The text representation of the  FTP command to send.
    455         * @param args The arguments to the FTP command.  If this parameter is
    456         *             set to null, then the command is sent with no argument.
    457         * @return The integer value of the FTP reply code returned by the server
    458         *         in response to the command.
    459         * @exception FTPConnectionClosedException
    460         *      If the FTP server prematurely closes the connection as a result
    461         *      of the client being idle or some other reason causing the server
    462         *      to send FTP reply code 421.  This exception may be caught either
    463         *      as an IOException or independently as itself.
    464         * @exception IOException  If an I/O error occurs while either sending the
    465         *      command or receiving the server reply.
    466         ***/
    467        public int sendCommand(String command, String args) throws IOException
    468        {
    469            if (_controlOutput_ == null) {
    470                throw new IOException("Connection is not open");
    471            }
    472
    473            final String message = __buildMessage(command, args);
    474
    475            __send(message);
    476
    477            fireCommandSent(command, message);
    478
    479            __getReply();
    480            return _replyCode;
    481        }
    482
    483        private String __buildMessage(String command, String args) {
    484            final StringBuilder __commandBuffer = new StringBuilder();
    485
    486            __commandBuffer.append(command);
    487
    488            if (args != null)
    489            {
    490                __commandBuffer.append(' ');
    491                __commandBuffer.append(args);
    492            }
    493            __commandBuffer.append(SocketClient.NETASCII_EOL);
    494            return __commandBuffer.toString();
    495        }
    496
    497        private void __send(String message) throws IOException,
    498                FTPConnectionClosedException, SocketException {
    499            try{
    500                _controlOutput_.write(message);
    501                _controlOutput_.flush();
    502            }
    503            catch (SocketException e)
    504            {
    505                if (!isConnected())
    506                {
    507                    throw new FTPConnectionClosedException("Connection unexpectedly closed.");
    508                }
    509                else
    510                {
    511                    throw e;
    512                }
    513            }
    514        }
    515
    516        /**
    517         * Send a noop and get the reply without reporting to the command listener.
    518         * Intended for use with keep-alive.
    519         *
    520         * @throws IOException
    521         * @since 3.0
    522         */
    523        protected void __noop() throws IOException {
    524            String msg = __buildMessage(FTPCommand.getCommand(FTPCommand.NOOP), null);
    525            __send(msg);
    526            __getReplyNoReport(); // This may timeout
    527        }
    528
    529        /***
    530         * Sends an FTP command to the server, waits for a reply and returns the
    531         * numerical response code.  After invocation, for more detailed
    532         * information, the actual reply text can be accessed by calling
    533         * {@link #getReplyString  getReplyString } or
    534         * {@link #getReplyStrings  getReplyStrings }.
    535         * <p>
    536         * @param command  The FTPCommand constant corresponding to the FTP command
    537         *                 to send.
    538         * @param args The arguments to the FTP command.  If this parameter is
    539         *             set to null, then the command is sent with no argument.
    540         * @return The integer value of the FTP reply code returned by the server
    541         *         in response to the command.
    542         * @exception FTPConnectionClosedException
    543         *      If the FTP server prematurely closes the connection as a result
    544         *      of the client being idle or some other reason causing the server
    545         *      to send FTP reply code 421.  This exception may be caught either
    546         *      as an IOException or independently as itself.
    547         * @exception IOException  If an I/O error occurs while either sending the
    548         *      command or receiving the server reply.
    549         ***/
    550        public int sendCommand(int command, String args) throws IOException
    551        {
    552            return sendCommand(FTPCommand.getCommand(command), args);
    553        }
    554
    555
    556        /***
    557         * Sends an FTP command with no arguments to the server, waits for a
    558         * reply and returns the numerical response code.  After invocation, for
    559         * more detailed information, the actual reply text can be accessed by
    560         * calling {@link #getReplyString  getReplyString } or
    561         * {@link #getReplyStrings  getReplyStrings }.
    562         * <p>
    563         * @param command  The text representation of the  FTP command to send.
    564         * @return The integer value of the FTP reply code returned by the server
    565         *         in response to the command.
    566         * @exception FTPConnectionClosedException
    567         *      If the FTP server prematurely closes the connection as a result
    568         *      of the client being idle or some other reason causing the server
    569         *      to send FTP reply code 421.  This exception may be caught either
    570         *      as an IOException or independently as itself.
    571         * @exception IOException  If an I/O error occurs while either sending the
    572         *      command or receiving the server reply.
    573         ***/
    574        public int sendCommand(String command) throws IOException
    575        {
    576            return sendCommand(command, null);
    577        }
    578
    579
    580        /***
    581         * Sends an FTP command with no arguments to the server, waits for a
    582         * reply and returns the numerical response code.  After invocation, for
    583         * more detailed information, the actual reply text can be accessed by
    584         * calling {@link #getReplyString  getReplyString } or
    585         * {@link #getReplyStrings  getReplyStrings }.
    586         * <p>
    587         * @param command  The FTPCommand constant corresponding to the FTP command
    588         *                 to send.
    589         * @return The integer value of the FTP reply code returned by the server
    590         *         in response to the command.
    591         * @exception FTPConnectionClosedException
    592         *      If the FTP server prematurely closes the connection as a result
    593         *      of the client being idle or some other reason causing the server
    594         *      to send FTP reply code 421.  This exception may be caught either
    595         *      as an IOException or independently as itself.
    596         * @exception IOException  If an I/O error occurs while either sending the
    597         *      command or receiving the server reply.
    598         ***/
    599        public int sendCommand(int command) throws IOException
    600        {
    601            return sendCommand(command, null);
    602        }
    603
    604
    605        /***
    606         * Returns the integer value of the reply code of the last FTP reply.
    607         * You will usually only use this method after you connect to the
    608         * FTP server to check that the connection was successful since
    609         * <code> connect </code> is of type void.
    610         * <p>
    611         * @return The integer value of the reply code of the last FTP reply.
    612         ***/
    613        public int getReplyCode()
    614        {
    615            return _replyCode;
    616        }
    617
    618        /***
    619         * Fetches a reply from the FTP server and returns the integer reply
    620         * code.  After calling this method, the actual reply text can be accessed
    621         * from either  calling {@link #getReplyString  getReplyString } or
    622         * {@link #getReplyStrings  getReplyStrings }.  Only use this
    623         * method if you are implementing your own FTP client or if you need to
    624         * fetch a secondary response from the FTP server.
    625         * <p>
    626         * @return The integer value of the reply code of the fetched FTP reply.
    627         * @exception FTPConnectionClosedException
    628         *      If the FTP server prematurely closes the connection as a result
    629         *      of the client being idle or some other reason causing the server
    630         *      to send FTP reply code 421.  This exception may be caught either
    631         *      as an IOException or independently as itself.
    632         * @exception IOException  If an I/O error occurs while receiving the
    633         *                         server reply.
    634         ***/
    635        public int getReply() throws IOException
    636        {
    637            __getReply();
    638            return _replyCode;
    639        }
    640
    641
    642        /***
    643         * Returns the lines of text from the last FTP server response as an array
    644         * of strings, one entry per line.  The end of line markers of each are
    645         * stripped from each line.
    646         * <p>
    647         * @return The lines of text from the last FTP response as an array.
    648         ***/
    649        public String[] getReplyStrings()
    650        {
    651            return _replyLines.toArray(new String[_replyLines.size()]);
    652        }
    653
    654        /***
    655         * Returns the entire text of the last FTP server response exactly
    656         * as it was received, including all end of line markers in NETASCII
    657         * format.
    658         * <p>
    659         * @return The entire text from the last FTP response as a String.
    660         ***/
    661        public String getReplyString()
    662        {
    663            StringBuilder buffer;
    664
    665            if (!_newReplyString) {
    666                return _replyString;
    667            }
    668
    669            buffer = new StringBuilder(256);
    670
    671            for (String line : _replyLines) {
    672                    buffer.append(line);
    673                    buffer.append(SocketClient.NETASCII_EOL);
    674            }
    675
    676             _newReplyString = false;
    677
    678            return (_replyString = buffer.toString());
    679        }
    680
    681
    682        /***
    683         * A convenience method to send the FTP USER command to the server,
    684         * receive the reply, and return the reply code.
    685         * <p>
    686         * @param username  The username to login under.
    687         * @return The reply code received from the server.
    688         * @exception FTPConnectionClosedException
    689         *      If the FTP server prematurely closes the connection as a result
    690         *      of the client being idle or some other reason causing the server
    691         *      to send FTP reply code 421.  This exception may be caught either
    692         *      as an IOException or independently as itself.
    693         * @exception IOException  If an I/O error occurs while either sending the
    694         *      command or receiving the server reply.
    695         ***/
    696        public int user(String username) throws IOException
    697        {
    698            return sendCommand(FTPCommand.USER, username);
    699        }
    700
    701        /**
    702         * A convenience method to send the FTP PASS command to the server,
    703         * receive the reply, and return the reply code.
    704         * @param password The plain text password of the username being logged into.
    705         * @return The reply code received from the server.
    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 the
    712         *      command or receiving the server reply.
    713         */
    714        public int pass(String password) throws IOException
    715        {
    716            return sendCommand(FTPCommand.PASS, password);
    717        }
    718
    719        /***
    720         * A convenience method to send the FTP ACCT command to the server,
    721         * receive the reply, and return the reply code.
    722         * <p>
    723         * @param account  The account name to access.
    724         * @return The reply code received from the server.
    725         * @exception FTPConnectionClosedException
    726         *      If the FTP server prematurely closes the connection as a result
    727         *      of the client being idle or some other reason causing the server
    728         *      to send FTP reply code 421.  This exception may be caught either
    729         *      as an IOException or independently as itself.
    730         * @exception IOException  If an I/O error occurs while either sending the
    731         *      command or receiving the server reply.
    732         ***/
    733        public int acct(String account) throws IOException
    734        {
    735            return sendCommand(FTPCommand.ACCT, account);
    736        }
    737
    738
    739        /***
    740         * A convenience method to send the FTP ABOR command to the server,
    741         * receive the reply, and return the reply code.
    742         * <p>
    743         * @return The reply code received from the server.
    744         * @exception FTPConnectionClosedException
    745         *      If the FTP server prematurely closes the connection as a result
    746         *      of the client being idle or some other reason causing the server
    747         *      to send FTP reply code 421.  This exception may be caught either
    748         *      as an IOException or independently as itself.
    749         * @exception IOException  If an I/O error occurs while either sending the
    750         *      command or receiving the server reply.
    751         ***/
    752        public int abor() throws IOException
    753        {
    754            return sendCommand(FTPCommand.ABOR);
    755        }
    756
    757        /***
    758         * A convenience method to send the FTP CWD command to the server,
    759         * receive the reply, and return the reply code.
    760         * <p>
    761         * @param directory The new working directory.
    762         * @return The reply code received from the server.
    763         * @exception FTPConnectionClosedException
    764         *      If the FTP server prematurely closes the connection as a result
    765         *      of the client being idle or some other reason causing the server
    766         *      to send FTP reply code 421.  This exception may be caught either
    767         *      as an IOException or independently as itself.
    768         * @exception IOException  If an I/O error occurs while either sending the
    769         *      command or receiving the server reply.
    770         ***/
    771        public int cwd(String directory) throws IOException
    772        {
    773            return sendCommand(FTPCommand.CWD, directory);
    774        }
    775
    776        /***
    777         * A convenience method to send the FTP CDUP command to the server,
    778         * receive the reply, and return the reply code.
    779         * <p>
    780         * @return The reply code received from the server.
    781         * @exception FTPConnectionClosedException
    782         *      If the FTP server prematurely closes the connection as a result
    783         *      of the client being idle or some other reason causing the server
    784         *      to send FTP reply code 421.  This exception may be caught either
    785         *      as an IOException or independently as itself.
    786         * @exception IOException  If an I/O error occurs while either sending the
    787         *      command or receiving the server reply.
    788         ***/
    789        public int cdup() throws IOException
    790        {
    791            return sendCommand(FTPCommand.CDUP);
    792        }
    793
    794        /***
    795         * A convenience method to send the FTP QUIT command to the server,
    796         * receive the reply, and return the reply code.
    797         * <p>
    798         * @return The reply code received from the server.
    799         * @exception FTPConnectionClosedException
    800         *      If the FTP server prematurely closes the connection as a result
    801         *      of the client being idle or some other reason causing the server
    802         *      to send FTP reply code 421.  This exception may be caught either
    803         *      as an IOException or independently as itself.
    804         * @exception IOException  If an I/O error occurs while either sending the
    805         *      command or receiving the server reply.
    806         ***/
    807        public int quit() throws IOException
    808        {
    809            return sendCommand(FTPCommand.QUIT);
    810        }
    811
    812        /***
    813         * A convenience method to send the FTP REIN command to the server,
    814         * receive the reply, and return the reply code.
    815         * <p>
    816         * @return The reply code received from the server.
    817         * @exception FTPConnectionClosedException
    818         *      If the FTP server prematurely closes the connection as a result
    819         *      of the client being idle or some other reason causing the server
    820         *      to send FTP reply code 421.  This exception may be caught either
    821         *      as an IOException or independently as itself.
    822         * @exception IOException  If an I/O error occurs while either sending the
    823         *      command or receiving the server reply.
    824         ***/
    825        public int rein() throws IOException
    826        {
    827            return sendCommand(FTPCommand.REIN);
    828        }
    829
    830        /***
    831         * A convenience method to send the FTP SMNT command to the server,
    832         * receive the reply, and return the reply code.
    833         * <p>
    834         * @param dir  The directory name.
    835         * @return The reply code received from the server.
    836         * @exception FTPConnectionClosedException
    837         *      If the FTP server prematurely closes the connection as a result
    838         *      of the client being idle or some other reason causing the server
    839         *      to send FTP reply code 421.  This exception may be caught either
    840         *      as an IOException or independently as itself.
    841         * @exception IOException  If an I/O error occurs while either sending the
    842         *      command or receiving the server reply.
    843         ***/
    844        public int smnt(String dir) throws IOException
    845        {
    846            return sendCommand(FTPCommand.SMNT, dir);
    847        }
    848
    849        /***
    850         * A convenience method to send the FTP PORT command to the server,
    851         * receive the reply, and return the reply code.
    852         * <p>
    853         * @param host  The host owning the port.
    854         * @param port  The new port.
    855         * @return The reply code received from the server.
    856         * @exception FTPConnectionClosedException
    857         *      If the FTP server prematurely closes the connection as a result
    858         *      of the client being idle or some other reason causing the server
    859         *      to send FTP reply code 421.  This exception may be caught either
    860         *      as an IOException or independently as itself.
    861         * @exception IOException  If an I/O error occurs while either sending the
    862         *      command or receiving the server reply.
    863         ***/
    864        public int port(InetAddress host, int port) throws IOException
    865        {
    866            int num;
    867            StringBuilder info = new StringBuilder(24);
    868
    869            info.append(host.getHostAddress().replace('.', ','));
    870            num = port >>> 8;
    871            info.append(',');
    872            info.append(num);
    873            info.append(',');
    874            num = port & 0xff;
    875            info.append(num);
    876
    877            return sendCommand(FTPCommand.PORT, info.toString());
    878        }
    879
    880        /***
    881         * A convenience method to send the FTP EPRT command to the server,
    882         * receive the reply, and return the reply code.
    883         *
    884         * Examples:
    885         * <code>
    886         * <ul>
    887         * <li>EPRT |1|132.235.1.2|6275|</li>
    888         * <li>EPRT |2|1080::8:800:200C:417A|5282|</li>
    889         * </ul>
    890         * </code>
    891         * <p>
    892         * @see "http://www.faqs.org/rfcs/rfc2428.html"
    893         *
    894         * @param host  The host owning the port.
    895         * @param port  The new port.
    896         * @return The reply code received from the server.
    897         * @exception FTPConnectionClosedException
    898         *      If the FTP server prematurely closes the connection as a result
    899         *      of the client being idle or some other reason causing the server
    900         *      to send FTP reply code 421.  This exception may be caught either
    901         *      as an IOException or independently as itself.
    902         * @exception IOException  If an I/O error occurs while either sending the
    903         *      command or receiving the server reply.
    904         * @since 2.2
    905         ***/
    906        public int eprt(InetAddress host, int port) throws IOException
    907        {
    908            int num;
    909            StringBuilder info = new StringBuilder();
    910            String h;
    911
    912            // If IPv6, trim the zone index
    913            h = host.getHostAddress();
    914            num = h.indexOf("%");
    915            if (num > 0) {
    916                h = h.substring(0, num);
    917            }
    918
    919            info.append("|");
    920
    921            if (host instanceof Inet4Address) {
    922                info.append("1");
    923            } else if (host instanceof Inet6Address) {
    924                info.append("2");
    925            }
    926            info.append("|");
    927            info.append(h);
    928            info.append("|");
    929            info.append(port);
    930            info.append("|");
    931
    932            return sendCommand(FTPCommand.EPRT, info.toString());
    933        }
    934
    935        /***
    936         * A convenience method to send the FTP PASV command to the server,
    937         * receive the reply, and return the reply code.  Remember, it's up
    938         * to you to interpret the reply string containing the host/port
    939         * information.
    940         * <p>
    941         * @return The reply code received from the server.
    942         * @exception FTPConnectionClosedException
    943         *      If the FTP server prematurely closes the connection as a result
    944         *      of the client being idle or some other reason causing the server
    945         *      to send FTP reply code 421.  This exception may be caught either
    946         *      as an IOException or independently as itself.
    947         * @exception IOException  If an I/O error occurs while either sending the
    948         *      command or receiving the server reply.
    949         ***/
    950        public int pasv() throws IOException
    951        {
    952            return sendCommand(FTPCommand.PASV);
    953        }
    954
    955         /***
    956         * A convenience method to send the FTP EPSV command to the server,
    957         * receive the reply, and return the reply code.  Remember, it's up
    958         * to you to interpret the reply string containing the host/port
    959         * information.
    960         * <p>
    961         * @return The reply code received from the server.
    962         * @exception FTPConnectionClosedException
    963         *      If the FTP server prematurely closes the connection as a result
    964         *      of the client being idle or some other reason causing the server
    965         *      to send FTP reply code 421.  This exception may be caught either
    966         *      as an IOException or independently as itself.
    967         * @exception IOException  If an I/O error occurs while either sending the
    968         *      command or receiving the server reply.
    969         * @since 2.2
    970         ***/
    971        public int epsv() throws IOException
    972        {
    973            return sendCommand(FTPCommand.EPSV);
    974        }
    975
    976        /**
    977         * A convenience method to send the FTP TYPE command for text files
    978         * to the server, receive the reply, and return the reply code.
    979         * @param fileType  The type of the file (one of the <code>FILE_TYPE</code>
    980         *              constants).
    981         * @param formatOrByteSize  The format of the file (one of the
    982         *              <code>_FORMAT</code> constants.  In the case of
    983         *              <code>LOCAL_FILE_TYPE</code>, the byte size.
    984         * @return The reply code received from the server.
    985         * @exception FTPConnectionClosedException
    986         *      If the FTP server prematurely closes the connection as a result
    987         *      of the client being idle or some other reason causing the server
    988         *      to send FTP reply code 421.  This exception may be caught either
    989         *      as an IOException or independently as itself.
    990         * @exception IOException  If an I/O error occurs while either sending the
    991         *      command or receiving the server reply.
    992         */
    993        public int type(int fileType, int formatOrByteSize) throws IOException
    994        {
    995            StringBuilder arg = new StringBuilder();
    996
    997            arg.append(__modes.charAt(fileType));
    998            arg.append(' ');
    999            if (fileType == LOCAL_FILE_TYPE) {
    1000                arg.append(formatOrByteSize);
    1001            } else {
    1002                arg.append(__modes.charAt(formatOrByteSize));
    1003            }
    1004
    1005            return sendCommand(FTPCommand.TYPE, arg.toString());
    1006        }
    1007
    1008
    1009        /**
    1010         * A convenience method to send the FTP TYPE command to the server,
    1011         * receive the reply, and return the reply code.
    1012         * <p>
    1013         * @param fileType  The type of the file (one of the <code>FILE_TYPE</code>
    1014         *              constants).
    1015         * @return The reply code received from the server.
    1016         * @exception FTPConnectionClosedException
    1017         *      If the FTP server prematurely closes the connection as a result
    1018         *      of the client being idle or some other reason causing the server
    1019         *      to send FTP reply code 421.  This exception may be caught either
    1020         *      as an IOException or independently as itself.
    1021         * @exception IOException  If an I/O error occurs while either sending the
    1022         *      command or receiving the server reply.
    1023         */
    1024        public int type(int fileType) throws IOException
    1025        {
    1026            return sendCommand(FTPCommand.TYPE,
    1027                               __modes.substring(fileType, fileType + 1));
    1028        }
    1029
    1030        /***
    1031         * A convenience method to send the FTP STRU command to the server,
    1032         * receive the reply, and return the reply code.
    1033         * <p>
    1034         * @param structure  The structure of the file (one of the
    1035         *         <code>_STRUCTURE</code> constants).
    1036         * @return The reply code received from the server.
    1037         * @exception FTPConnectionClosedException
    1038         *      If the FTP server prematurely closes the connection as a result
    1039         *      of the client being idle or some other reason causing the server
    1040         *      to send FTP reply code 421.  This exception may be caught either
    1041         *      as an IOException or independently as itself.
    1042         * @exception IOException  If an I/O error occurs while either sending the
    1043         *      command or receiving the server reply.
    1044         ***/
    1045        public int stru(int structure) throws IOException
    1046        {
    1047            return sendCommand(FTPCommand.STRU,
    1048                               __modes.substring(structure, structure + 1));
    1049        }
    1050
    1051        /***
    1052         * A convenience method to send the FTP MODE command to the server,
    1053         * receive the reply, and return the reply code.
    1054         * <p>
    1055         * @param mode  The transfer mode to use (one of the
    1056         *         <code>TRANSFER_MODE</code> constants).
    1057         * @return The reply code received from the server.
    1058         * @exception FTPConnectionClosedException
    1059         *      If the FTP server prematurely closes the connection as a result
    1060         *      of the client being idle or some other reason causing the server
    1061         *      to send FTP reply code 421.  This exception may be caught either
    1062         *      as an IOException or independently as itself.
    1063         * @exception IOException  If an I/O error occurs while either sending the
    1064         *      command or receiving the server reply.
    1065         ***/
    1066        public int mode(int mode) throws IOException
    1067        {
    1068            return sendCommand(FTPCommand.MODE,
    1069                               __modes.substring(mode, mode + 1));
    1070        }
    1071
    1072        /***
    1073         * A convenience method to send the FTP RETR command to the server,
    1074         * receive the reply, and return the reply code.  Remember, it is up
    1075         * to you to manage the data connection.  If you don't need this low
    1076         * level of access, use {@link org.apache.commons.net.ftp.FTPClient}
    1077         * , which will handle all low level details for you.
    1078         * <p>
    1079         * @param pathname  The pathname of the file to retrieve.
    1080         * @return The reply code received from the server.
    1081         * @exception FTPConnectionClosedException
    1082         *      If the FTP server prematurely closes the connection as a result
    1083         *      of the client being idle or some other reason causing the server
    1084         *      to send FTP reply code 421.  This exception may be caught either
    1085         *      as an IOException or independently as itself.
    1086         * @exception IOException  If an I/O error occurs while either sending the
    1087         *      command or receiving the server reply.
    1088         ***/
    1089        public int retr(String pathname) throws IOException
    1090        {
    1091            return sendCommand(FTPCommand.RETR, pathname);
    1092        }
    1093
    1094        /***
    1095         * A convenience method to send the FTP STOR command to the server,
    1096         * receive the reply, and return the reply code.  Remember, it is up
    1097         * to you to manage the data connection.  If you don't need this low
    1098         * level of access, use {@link org.apache.commons.net.ftp.FTPClient}
    1099         * , which will handle all low level details for you.
    1100         * <p>
    1101         * @param pathname  The pathname to use for the file when stored at
    1102         *                  the remote end of the transfer.
    1103         * @return The reply code received from the server.
    1104         * @exception FTPConnectionClosedException
    1105         *      If the FTP server prematurely closes the connection as a result
    1106         *      of the client being idle or some other reason causing the server
    1107         *      to send FTP reply code 421.  This exception may be caught either
    1108         *      as an IOException or independently as itself.
    1109         * @exception IOException  If an I/O error occurs while either sending the
    1110         *      command or receiving the server reply.
    1111         ***/
    1112        public int stor(String pathname) throws IOException
    1113        {
    1114            return sendCommand(FTPCommand.STOR, pathname);
    1115        }
    1116
    1117        /***
    1118         * A convenience method to send the FTP STOU command to the server,
    1119         * receive the reply, and return the reply code.  Remember, it is up
    1120         * to you to manage the data connection.  If you don't need this low
    1121         * level of access, use {@link org.apache.commons.net.ftp.FTPClient}
    1122         * , which will handle all low level details for you.
    1123         * <p>
    1124         * @return The reply code received from the server.
    1125         * @exception FTPConnectionClosedException
    1126         *      If the FTP server prematurely closes the connection as a result
    1127         *      of the client being idle or some other reason causing the server
    1128         *      to send FTP reply code 421.  This exception may be caught either
    1129         *      as an IOException or independently as itself.
    1130         * @exception IOException  If an I/O error occurs while either sending the
    1131         *      command or receiving the server reply.
    1132         ***/
    1133        public int stou() throws IOException
    1134        {
    1135            return sendCommand(FTPCommand.STOU);
    1136        }
    1137
    1138        /***
    1139         * A convenience method to send the FTP STOU command to the server,
    1140         * receive the reply, and return the reply code.  Remember, it is up
    1141         * to you to manage the data connection.  If you don't need this low
    1142         * level of access, use {@link org.apache.commons.net.ftp.FTPClient}
    1143         * , which will handle all low level details for you.
    1144         * @param pathname  The base pathname to use for the file when stored at
    1145         *                  the remote end of the transfer.  Some FTP servers
    1146         *                  require this.
    1147         * @return The reply code received from the server.
    1148         * @exception FTPConnectionClosedException
    1149         *      If the FTP server prematurely closes the connection as a result
    1150         *      of the client being idle or some other reason causing the server
    1151         *      to send FTP reply code 421.  This exception may be caught either
    1152         *      as an IOException or independently as itself.
    1153         * @exception IOException  If an I/O error occurs while either sending the
    1154         *      command or receiving the server reply.
    1155         */
    1156        public int stou(String pathname) throws IOException
    1157        {
    1158            return sendCommand(FTPCommand.STOU, pathname);
    1159        }
    1160
    1161        /***
    1162         * A convenience method to send the FTP APPE command to the server,
    1163         * receive the reply, and return the reply code.  Remember, it is up
    1164         * to you to manage the data connection.  If you don't need this low
    1165         * level of access, use {@link org.apache.commons.net.ftp.FTPClient}
    1166         * , which will handle all low level details for you.
    1167         * <p>
    1168         * @param pathname  The pathname to use for the file when stored at
    1169         *                  the remote end of the transfer.
    1170         * @return The reply code received from the server.
    1171         * @exception FTPConnectionClosedException
    1172         *      If the FTP server prematurely closes the connection as a result
    1173         *      of the client being idle or some other reason causing the server
    1174         *      to send FTP reply code 421.  This exception may be caught either
    1175         *      as an IOException or independently as itself.
    1176         * @exception IOException  If an I/O error occurs while either sending the
    1177         *      command or receiving the server reply.
    1178         ***/
    1179        public int appe(String pathname) throws IOException
    1180        {
    1181            return sendCommand(FTPCommand.APPE, pathname);
    1182        }
    1183
    1184        /***
    1185         * A convenience method to send the FTP ALLO command to the server,
    1186         * receive the reply, and return the reply code.
    1187         * <p>
    1188         * @param bytes The number of bytes to allocate.
    1189         * @return The reply code received from the server.
    1190         * @exception FTPConnectionClosedException
    1191         *      If the FTP server prematurely closes the connection as a result
    1192         *      of the client being idle or some other reason causing the server
    1193         *      to send FTP reply code 421.  This exception may be caught either
    1194         *      as an IOException or independently as itself.
    1195         * @exception IOException  If an I/O error occurs while either sending the
    1196         *      command or receiving the server reply.
    1197         ***/
    1198        public int allo(int bytes) throws IOException
    1199        {
    1200            return sendCommand(FTPCommand.ALLO, Integer.toString(bytes));
    1201        }
    1202
    1203        /**
    1204         * A convenience method to send the FTP FEAT command to the server, receive the reply,
    1205         * and return the reply code.
    1206         * @return The reply code received by the server
    1207         * @throws IOException  If an I/O error occurs while either sending the
    1208         *      command or receiving the server reply.
    1209         * @since 2.2
    1210         */
    1211        public int feat() throws IOException
    1212        {
    1213            return sendCommand(FTPCommand.FEAT);
    1214        }
    1215
    1216        /***
    1217         * A convenience method to send the FTP ALLO command to the server,
    1218         * receive the reply, and return the reply code.
    1219         * <p>
    1220         * @param bytes The number of bytes to allocate.
    1221         * @param recordSize  The size of a record.
    1222         * @return The reply code received from the server.
    1223         * @exception FTPConnectionClosedException
    1224         *      If the FTP server prematurely closes the connection as a result
    1225         *      of the client being idle or some other reason causing the server
    1226         *      to send FTP reply code 421.  This exception may be caught either
    1227         *      as an IOException or independently as itself.
    1228         * @exception IOException  If an I/O error occurs while either sending the
    1229         *      command or receiving the server reply.
    1230         ***/
    1231        public int allo(int bytes, int recordSize) throws IOException
    1232        {
    1233            return sendCommand(FTPCommand.ALLO, Integer.toString(bytes) + " R " +
    1234                               Integer.toString(recordSize));
    1235        }
    1236
    1237        /***
    1238         * A convenience method to send the FTP REST command to the server,
    1239         * receive the reply, and return the reply code.
    1240         * <p>
    1241         * @param marker The marker at which to restart a transfer.
    1242         * @return The reply code received from the server.
    1243         * @exception FTPConnectionClosedException
    1244         *      If the FTP server prematurely closes the connection as a result
    1245         *      of the client being idle or some other reason causing the server
    1246         *      to send FTP reply code 421.  This exception may be caught either
    1247         *      as an IOException or independently as itself.
    1248         * @exception IOException  If an I/O error occurs while either sending the
    1249         *      command or receiving the server reply.
    1250         ***/
    1251        public int rest(String marker) throws IOException
    1252        {
    1253            return sendCommand(FTPCommand.REST, marker);
    1254        }
    1255
    1256
    1257        /**
    1258         * @since 2.0
    1259         **/
    1260        public int mdtm(String file) throws IOException
    1261        {
    1262            return sendCommand(FTPCommand.MDTM, file);
    1263        }
    1264
    1265
    1266        /**
    1267         * A convenience method to send the FTP MFMT command to the server,
    1268         * receive the reply, and return the reply code.
    1269         * <p>
    1270         * @param pathname The pathname for which mtime is to be changed
    1271         * @param timeval Timestamp in <code>YYYYMMDDhhmmss</code> format
    1272         * @return The reply code received from the server.
    1273         * @exception FTPConnectionClosedException
    1274         *      If the FTP server prematurely closes the connection as a result
    1275         *      of the client being idle or some other reason causing the server
    1276         *      to send FTP reply code 421.  This exception may be caught either
    1277         *      as an IOException or independently as itself.
    1278         * @exception IOException  If an I/O error occurs while either sending the
    1279         *      command or receiving the server reply.
    1280         * @since 2.2
    1281         * @see <a href="http://tools.ietf.org/html/draft-somers-ftp-mfxx-04">http://tools.ietf.org/html/draft-somers-ftp-mfxx-04</a>
    1282         **/
    1283        public int mfmt(String pathname, String timeval) throws IOException
    1284        {
    1285            return sendCommand(FTPCommand.MFMT, timeval + " " + pathname);
    1286        }
    1287
    1288
    1289        /***
    1290         * A convenience method to send the FTP RNFR command to the server,
    1291         * receive the reply, and return the reply code.
    1292         * <p>
    1293         * @param pathname The pathname to rename from.
    1294         * @return The reply code received from the server.
    1295         * @exception FTPConnectionClosedException
    1296         *      If the FTP server prematurely closes the connection as a result
    1297         *      of the client being idle or some other reason causing the server
    1298         *      to send FTP reply code 421.  This exception may be caught either
    1299         *      as an IOException or independently as itself.
    1300         * @exception IOException  If an I/O error occurs while either sending the
    1301         *      command or receiving the server reply.
    1302         ***/
    1303        public int rnfr(String pathname) throws IOException
    1304        {
    1305            return sendCommand(FTPCommand.RNFR, pathname);
    1306        }
    1307
    1308        /***
    1309         * A convenience method to send the FTP RNTO command to the server,
    1310         * receive the reply, and return the reply code.
    1311         * <p>
    1312         * @param pathname The pathname to rename to
    1313         * @return The reply code received from the server.
    1314         * @exception FTPConnectionClosedException
    1315         *      If the FTP server prematurely closes the connection as a result
    1316         *      of the client being idle or some other reason causing the server
    1317         *      to send FTP reply code 421.  This exception may be caught either
    1318         *      as an IOException or independently as itself.
    1319         * @exception IOException  If an I/O error occurs while either sending the
    1320         *      command or receiving the server reply.
    1321         ***/
    1322        public int rnto(String pathname) throws IOException
    1323        {
    1324            return sendCommand(FTPCommand.RNTO, pathname);
    1325        }
    1326
    1327        /***
    1328         * A convenience method to send the FTP DELE command to the server,
    1329         * receive the reply, and return the reply code.
    1330         * <p>
    1331         * @param pathname The pathname to delete.
    1332         * @return The reply code received from the server.
    1333         * @exception FTPConnectionClosedException
    1334         *      If the FTP server prematurely closes the connection as a result
    1335         *      of the client being idle or some other reason causing the server
    1336         *      to send FTP reply code 421.  This exception may be caught either
    1337         *      as an IOException or independently as itself.
    1338         * @exception IOException  If an I/O error occurs while either sending the
    1339         *      command or receiving the server reply.
    1340         ***/
    1341        public int dele(String pathname) throws IOException
    1342        {
    1343            return sendCommand(FTPCommand.DELE, pathname);
    1344        }
    1345
    1346        /***
    1347         * A convenience method to send the FTP RMD command to the server,
    1348         * receive the reply, and return the reply code.
    1349         * <p>
    1350         * @param pathname The pathname of the directory to remove.
    1351         * @return The reply code received from the server.
    1352         * @exception FTPConnectionClosedException
    1353         *      If the FTP server prematurely closes the connection as a result
    1354         *      of the client being idle or some other reason causing the server
    1355         *      to send FTP reply code 421.  This exception may be caught either
    1356         *      as an IOException or independently as itself.
    1357         * @exception IOException  If an I/O error occurs while either sending the
    1358         *      command or receiving the server reply.
    1359         ***/
    1360        public int rmd(String pathname) throws IOException
    1361        {
    1362            return sendCommand(FTPCommand.RMD, pathname);
    1363        }
    1364
    1365        /***
    1366         * A convenience method to send the FTP MKD command to the server,
    1367         * receive the reply, and return the reply code.
    1368         * <p>
    1369         * @param pathname The pathname of the new directory to create.
    1370         * @return The reply code received from the server.
    1371         * @exception FTPConnectionClosedException
    1372         *      If the FTP server prematurely closes the connection as a result
    1373         *      of the client being idle or some other reason causing the server
    1374         *      to send FTP reply code 421.  This exception may be caught either
    1375         *      as an IOException or independently as itself.
    1376         * @exception IOException  If an I/O error occurs while either sending the
    1377         *      command or receiving the server reply.
    1378         ***/
    1379        public int mkd(String pathname) throws IOException
    1380        {
    1381            return sendCommand(FTPCommand.MKD, pathname);
    1382        }
    1383
    1384        /***
    1385         * A convenience method to send the FTP PWD command to the server,
    1386         * receive the reply, and return the reply code.
    1387         * <p>
    1388         * @return The reply code received from the server.
    1389         * @exception FTPConnectionClosedException
    1390         *      If the FTP server prematurely closes the connection as a result
    1391         *      of the client being idle or some other reason causing the server
    1392         *      to send FTP reply code 421.  This exception may be caught either
    1393         *      as an IOException or independently as itself.
    1394         * @exception IOException  If an I/O error occurs while either sending the
    1395         *      command or receiving the server reply.
    1396         ***/
    1397        public int pwd() throws IOException
    1398        {
    1399            return sendCommand(FTPCommand.PWD);
    1400        }
    1401
    1402        /***
    1403         * A convenience method to send the FTP LIST command to the server,
    1404         * receive the reply, and return the reply code.  Remember, it is up
    1405         * to you to manage the data connection.  If you don't need this low
    1406         * level of access, use {@link org.apache.commons.net.ftp.FTPClient}
    1407         * , which will handle all low level details for you.
    1408         * <p>
    1409         * @return The reply code received from the server.
    1410         * @exception FTPConnectionClosedException
    1411         *      If the FTP server prematurely closes the connection as a result
    1412         *      of the client being idle or some other reason causing the server
    1413         *      to send FTP reply code 421.  This exception may be caught either
    1414         *      as an IOException or independently as itself.
    1415         * @exception IOException  If an I/O error occurs while either sending the
    1416         *      command or receiving the server reply.
    1417         ***/
    1418        public int list() throws IOException
    1419        {
    1420            return sendCommand(FTPCommand.LIST);
    1421        }
    1422
    1423        /***
    1424         * A convenience method to send the FTP LIST command to the server,
    1425         * receive the reply, and return the reply code.  Remember, it is up
    1426         * to you to manage the data connection.  If you don't need this low
    1427         * level of access, use {@link org.apache.commons.net.ftp.FTPClient}
    1428         * , which will handle all low level details for you.
    1429         * <p>
    1430         * @param pathname  The pathname to list,
    1431         * may be {@code null} in which case the command is sent with no parameters
    1432         * @return The reply code received from the server.
    1433         * @exception FTPConnectionClosedException
    1434         *      If the FTP server prematurely closes the connection as a result
    1435         *      of the client being idle or some other reason causing the server
    1436         *      to send FTP reply code 421.  This exception may be caught either
    1437         *      as an IOException or independently as itself.
    1438         * @exception IOException  If an I/O error occurs while either sending the
    1439         *      command or receiving the server reply.
    1440         ***/
    1441        public int list(String pathname) throws IOException
    1442        {
    1443            return sendCommand(FTPCommand.LIST, pathname);
    1444        }
    1445
    1446        /**
    1447         * A convenience method to send the FTP MLSD command to the server,
    1448         * receive the reply, and return the reply code.  Remember, it is up
    1449         * to you to manage the data connection.  If you don't need this low
    1450         * level of access, use {@link org.apache.commons.net.ftp.FTPClient}
    1451         * , which will handle all low level details for you.
    1452         * <p>
    1453         * @return The reply code received from the server.
    1454         * @exception FTPConnectionClosedException
    1455         *      If the FTP server prematurely closes the connection as a result
    1456         *      of the client being idle or some other reason causing the server
    1457         *      to send FTP reply code 421.  This exception may be caught either
    1458         *      as an IOException or independently as itself.
    1459         * @exception IOException  If an I/O error occurs while either sending the
    1460         *      command or receiving the server reply.
    1461         * @since 3.0
    1462         */
    1463        public int mlsd() throws IOException
    1464        {
    1465            return sendCommand(FTPCommand.MLSD);
    1466        }
    1467
    1468        /**
    1469         * A convenience method to send the FTP MLSD command to the server,
    1470         * receive the reply, and return the reply code.  Remember, it is up
    1471         * to you to manage the data connection.  If you don't need this low
    1472         * level of access, use {@link org.apache.commons.net.ftp.FTPClient}
    1473         * , which will handle all low level details for you.
    1474         * <p>
    1475         * @param path the path to report on
    1476         * @return The reply code received from the server,
    1477         * may be {@code null} in which case the command is sent with no parameters
    1478         * @exception FTPConnectionClosedException
    1479         *      If the FTP server prematurely closes the connection as a result
    1480         *      of the client being idle or some other reason causing the server
    1481         *      to send FTP reply code 421.  This exception may be caught either
    1482         *      as an IOException or independently as itself.
    1483         * @exception IOException  If an I/O error occurs while either sending the
    1484         *      command or receiving the server reply.
    1485         * @since 3.0
    1486         */
    1487        public int mlsd(String path) throws IOException
    1488        {
    1489            return sendCommand(FTPCommand.MLSD, path);
    1490        }
    1491
    1492        /**
    1493         * A convenience method to send the FTP MLST command to the server,
    1494         * receive the reply, and return the reply code.  Remember, it is up
    1495         * to you to manage the data connection.  If you don't need this low
    1496         * level of access, use {@link org.apache.commons.net.ftp.FTPClient}
    1497         * , which will handle all low level details for you.
    1498         * <p>
    1499         * @return The reply code received from the server.
    1500         * @exception FTPConnectionClosedException
    1501         *      If the FTP server prematurely closes the connection as a result
    1502         *      of the client being idle or some other reason causing the server
    1503         *      to send FTP reply code 421.  This exception may be caught either
    1504         *      as an IOException or independently as itself.
    1505         * @exception IOException  If an I/O error occurs while either sending the
    1506         *      command or receiving the server reply.
    1507         * @since 3.0
    1508         */
    1509        public int mlst() throws IOException
    1510        {
    1511            return sendCommand(FTPCommand.MLST);
    1512        }
    1513
    1514        /**
    1515         * A convenience method to send the FTP MLST command to the server,
    1516         * receive the reply, and return the reply code.  Remember, it is up
    1517         * to you to manage the data connection.  If you don't need this low
    1518         * level of access, use {@link org.apache.commons.net.ftp.FTPClient}
    1519         * , which will handle all low level details for you.
    1520         * <p>
    1521         * @param path the path to report on
    1522         * @return The reply code received from the server,
    1523         * may be {@code null} in which case the command is sent with no parameters
    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 the
    1530         *      command or receiving the server reply.
    1531         * @since 3.0
    1532         */
    1533        public int mlst(String path) throws IOException
    1534        {
    1535            return sendCommand(FTPCommand.MLST, path);
    1536        }
    1537
    1538        /***
    1539         * A convenience method to send the FTP NLST command to the server,
    1540         * receive the reply, and return the reply code.  Remember, it is up
    1541         * to you to manage the data connection.  If you don't need this low
    1542         * level of access, use {@link org.apache.commons.net.ftp.FTPClient}
    1543         * , which will handle all low level details for you.
    1544         * <p>
    1545         * @return The reply code received from the server.
    1546         * @exception FTPConnectionClosedException
    1547         *      If the FTP server prematurely closes the connection as a result
    1548         *      of the client being idle or some other reason causing the server
    1549         *      to send FTP reply code 421.  This exception may be caught either
    1550         *      as an IOException or independently as itself.
    1551         * @exception IOException  If an I/O error occurs while either sending the
    1552         *      command or receiving the server reply.
    1553         ***/
    1554        public int nlst() throws IOException
    1555        {
    1556            return sendCommand(FTPCommand.NLST);
    1557        }
    1558
    1559        /***
    1560         * A convenience method to send the FTP NLST command to the server,
    1561         * receive the reply, and return the reply code.  Remember, it is up
    1562         * to you to manage the data connection.  If you don't need this low
    1563         * level of access, use {@link org.apache.commons.net.ftp.FTPClient}
    1564         * , which will handle all low level details for you.
    1565         * <p>
    1566         * @param pathname  The pathname to list,
    1567         * may be {@code null} in which case the command is sent with no parameters
    1568         * @return The reply code received from the server.
    1569         * @exception FTPConnectionClosedException
    1570         *      If the FTP server prematurely closes the connection as a result
    1571         *      of the client being idle or some other reason causing the server
    1572         *      to send FTP reply code 421.  This exception may be caught either
    1573         *      as an IOException or independently as itself.
    1574         * @exception IOException  If an I/O error occurs while either sending the
    1575         *      command or receiving the server reply.
    1576         ***/
    1577        public int nlst(String pathname) throws IOException
    1578        {
    1579            return sendCommand(FTPCommand.NLST, pathname);
    1580        }
    1581
    1582        /***
    1583         * A convenience method to send the FTP SITE command to the server,
    1584         * receive the reply, and return the reply code.
    1585         * <p>
    1586         * @param parameters  The site parameters to send.
    1587         * @return The reply code received from the server.
    1588         * @exception FTPConnectionClosedException
    1589         *      If the FTP server prematurely closes the connection as a result
    1590         *      of the client being idle or some other reason causing the server
    1591         *      to send FTP reply code 421.  This exception may be caught either
    1592         *      as an IOException or independently as itself.
    1593         * @exception IOException  If an I/O error occurs while either sending the
    1594         *      command or receiving the server reply.
    1595         ***/
    1596        public int site(String parameters) throws IOException
    1597        {
    1598            return sendCommand(FTPCommand.SITE, parameters);
    1599        }
    1600
    1601        /***
    1602         * A convenience method to send the FTP SYST command to the server,
    1603         * receive the reply, and return the reply code.
    1604         * <p>
    1605         * @return The reply code received from the server.
    1606         * @exception FTPConnectionClosedException
    1607         *      If the FTP server prematurely closes the connection as a result
    1608         *      of the client being idle or some other reason causing the server
    1609         *      to send FTP reply code 421.  This exception may be caught either
    1610         *      as an IOException or independently as itself.
    1611         * @exception IOException  If an I/O error occurs while either sending the
    1612         *      command or receiving the server reply.
    1613         ***/
    1614        public int syst() throws IOException
    1615        {
    1616            return sendCommand(FTPCommand.SYST);
    1617        }
    1618
    1619        /***
    1620         * A convenience method to send the FTP STAT command to the server,
    1621         * receive the reply, and return the reply code.
    1622         * <p>
    1623         * @return The reply code received from the server.
    1624         * @exception FTPConnectionClosedException
    1625         *      If the FTP server prematurely closes the connection as a result
    1626         *      of the client being idle or some other reason causing the server
    1627         *      to send FTP reply code 421.  This exception may be caught either
    1628         *      as an IOException or independently as itself.
    1629         * @exception IOException  If an I/O error occurs while either sending the
    1630         *      command or receiving the server reply.
    1631         ***/
    1632        public int stat() throws IOException
    1633        {
    1634            return sendCommand(FTPCommand.STAT);
    1635        }
    1636
    1637        /***
    1638         * A convenience method to send the FTP STAT command to the server,
    1639         * receive the reply, and return the reply code.
    1640         * <p>
    1641         * @param pathname  A pathname to list.
    1642         * @return The reply code received from the server.
    1643         * @exception FTPConnectionClosedException
    1644         *      If the FTP server prematurely closes the connection as a result
    1645         *      of the client being idle or some other reason causing the server
    1646         *      to send FTP reply code 421.  This exception may be caught either
    1647         *      as an IOException or independently as itself.
    1648         * @exception IOException  If an I/O error occurs while either sending the
    1649         *      command or receiving the server reply.
    1650         ***/
    1651        public int stat(String pathname) throws IOException
    1652        {
    1653            return sendCommand(FTPCommand.STAT, pathname);
    1654        }
    1655
    1656        /***
    1657         * A convenience method to send the FTP HELP command to the server,
    1658         * receive the reply, and return the reply code.
    1659         * <p>
    1660         * @return The reply code received from the server.
    1661         * @exception FTPConnectionClosedException
    1662         *      If the FTP server prematurely closes the connection as a result
    1663         *      of the client being idle or some other reason causing the server
    1664         *      to send FTP reply code 421.  This exception may be caught either
    1665         *      as an IOException or independently as itself.
    1666         * @exception IOException  If an I/O error occurs while either sending the
    1667         *      command or receiving the server reply.
    1668         ***/
    1669        public int help() throws IOException
    1670        {
    1671            return sendCommand(FTPCommand.HELP);
    1672        }
    1673
    1674        /***
    1675         * A convenience method to send the FTP HELP command to the server,
    1676         * receive the reply, and return the reply code.
    1677         * <p>
    1678         * @param command  The command name on which to request help.
    1679         * @return The reply code received from the server.
    1680         * @exception FTPConnectionClosedException
    1681         *      If the FTP server prematurely closes the connection as a result
    1682         *      of the client being idle or some other reason causing the server
    1683         *      to send FTP reply code 421.  This exception may be caught either
    1684         *      as an IOException or independently as itself.
    1685         * @exception IOException  If an I/O error occurs while either sending the
    1686         *      command or receiving the server reply.
    1687         ***/
    1688        public int help(String command) throws IOException
    1689        {
    1690            return sendCommand(FTPCommand.HELP, command);
    1691        }
    1692
    1693        /***
    1694         * A convenience method to send the FTP NOOP command to the server,
    1695         * receive the reply, and return the reply code.
    1696         * <p>
    1697         * @return The reply code received from the server.
    1698         * @exception FTPConnectionClosedException
    1699         *      If the FTP server prematurely closes the connection as a result
    1700         *      of the client being idle or some other reason causing the server
    1701         *      to send FTP reply code 421.  This exception may be caught either
    1702         *      as an IOException or independently as itself.
    1703         * @exception IOException  If an I/O error occurs while either sending the
    1704         *      command or receiving the server reply.
    1705         ***/
    1706        public int noop() throws IOException
    1707        {
    1708            return sendCommand(FTPCommand.NOOP);
    1709        }
    1710
    1711        /**
    1712         * Return whether strict multiline parsing is enabled, as per RFC 959, section 4.2.
    1713         * @return True if strict, false if lenient
    1714         * @since 2.0
    1715         */
    1716        public boolean isStrictMultilineParsing() {
    1717            return strictMultilineParsing;
    1718        }
    1719
    1720        /**
    1721         * Set strict multiline parsing.
    1722         * @param strictMultilineParsing
    1723         * @since 2.0
    1724         */
    1725        public void setStrictMultilineParsing(boolean strictMultilineParsing) {
    1726            this.strictMultilineParsing = strictMultilineParsing;
    1727        }
    1728
    1729        /**
    1730         * Provide command support to super-class
    1731         */
    1732        @Override
    1733        protected ProtocolCommandSupport getCommandSupport() {
    1734            return _commandSupport_;
    1735        }
    1736    }
    1737
    1738    /* Emacs configuration
    1739     * Local variables:        **
    1740     * mode:             java  **
    1741     * c-basic-offset:   4     **
    1742     * indent-tabs-mode: nil   **
    1743     * End:                    **
    1744     */