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