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