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