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