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