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