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    
018    package org.apache.commons.net.ftp;
019    import java.io.BufferedReader;
020    import java.io.BufferedWriter;
021    import java.io.IOException;
022    import java.io.InputStreamReader;
023    import java.io.OutputStreamWriter;
024    import java.net.Inet4Address;
025    import java.net.Inet6Address;
026    import java.net.InetAddress;
027    import java.net.SocketException;
028    import java.net.SocketTimeoutException;
029    import java.util.ArrayList;
030    
031    import org.apache.commons.net.MalformedServerReplyException;
032    import org.apache.commons.net.ProtocolCommandSupport;
033    import org.apache.commons.net.SocketClient;
034    import 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    
097    public 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     */