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