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