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.net.InetAddress;
25  import java.net.Socket;
26  import java.net.SocketException;
27  import java.util.ArrayList;
28  import java.util.Arrays;
29  
30  import org.apache.commons.net.MalformedServerReplyException;
31  import org.apache.commons.net.ProtocolCommandListener;
32  import org.apache.commons.net.ProtocolCommandSupport;
33  import org.apache.commons.net.SocketClient;
34  
35  /***
36   * FTP provides the basic the functionality necessary to implement your
37   * own FTP client.  It extends org.apache.commons.net.SocketClient since
38   * extending TelnetClient was causing unwanted behavior (like connections
39   * that did not time out properly).
40   * <p>
41   * To derive the full benefits of the FTP class requires some knowledge
42   * of the FTP protocol defined in RFC 959.  However, there is no reason
43   * why you should have to use the FTP class.  The
44   * {@link org.apache.commons.net.ftp.FTPClient} class,
45   * derived from FTP,
46   * implements all the functionality required of an FTP client.  The
47   * FTP class is made public to provide access to various FTP constants
48   * and to make it easier for adventurous programmers (or those with
49   * special needs) to interact with the FTP protocol and implement their
50   * own clients.  A set of methods with names corresponding to the FTP
51   * command names are provided to facilitate this interaction.
52   * <p>
53   * You should keep in mind that the FTP server may choose to prematurely
54   * close a connection if the client has been idle for longer than a
55   * given time period (usually 900 seconds).  The FTP class will detect a
56   * premature FTP server connection closing when it receives a
57   * {@link org.apache.commons.net.ftp.FTPReply#SERVICE_NOT_AVAILABLE FTPReply.SERVICE_NOT_AVAILABLE }
58   *  response to a command.
59   * When that occurs, the FTP class method encountering that reply will throw
60   * an {@link org.apache.commons.net.ftp.FTPConnectionClosedException}
61   * .  <code>FTPConectionClosedException</code>
62   * is a subclass of <code> IOException </code> and therefore need not be
63   * caught separately, but if you are going to catch it separately, its
64   * catch block must appear before the more general <code> IOException </code>
65   * catch block.  When you encounter an
66   * {@link org.apache.commons.net.ftp.FTPConnectionClosedException}
67   * , you must disconnect the connection with
68   * {@link #disconnect  disconnect() } to properly clean up the
69   * system resources used by FTP.  Before disconnecting, you may check the
70   * last reply code and text with
71   * {@link #getReplyCode  getReplyCode },
72   * {@link #getReplyString  getReplyString },
73   * and {@link #getReplyStrings  getReplyStrings}.
74   * You may avoid server disconnections while the client is idle by
75   * periodicaly sending NOOP commands to the server.
76   * <p>
77   * Rather than list it separately for each method, we mention here that
78   * every method communicating with the server and throwing an IOException
79   * can also throw a
80   * {@link org.apache.commons.net.MalformedServerReplyException}
81   * , which is a subclass
82   * of IOException.  A MalformedServerReplyException will be thrown when
83   * the reply received from the server deviates enough from the protocol
84   * specification that it cannot be interpreted in a useful manner despite
85   * attempts to be as lenient as possible.
86   * <p>
87   * <p>
88   * @author Daniel F. Savarese
89   * @author Rory Winston 
90   * @author Joseph Hindsley
91   * @see FTPClient
92   * @see FTPConnectionClosedException
93   * @see org.apache.commons.net.MalformedServerReplyException
94   * @version $Id: FTP.java 658520 2008-05-21 01:14:11Z sebb $
95   ***/
96  
97  public class FTP extends SocketClient
98  {
99      /*** The default FTP data port (20). ***/
100     public static final int DEFAULT_DATA_PORT = 20;
101     /*** The default FTP control port (21). ***/
102     public static final int DEFAULT_PORT = 21;
103 
104     /***
105      * A constant used to indicate the file(s) being transfered should
106      * be treated as ASCII.  This is the default file type.  All constants
107      * ending in <code>FILE_TYPE</code> are used to indicate file types.
108      ***/
109     public static final int ASCII_FILE_TYPE = 0;
110 
111     /***
112      * A constant used to indicate the file(s) being transfered should
113      * be treated as EBCDIC.  Note however that there are several different
114      * EBCDIC formats.  All constants ending in <code>FILE_TYPE</code>
115      * are used to indicate file types.
116      ***/
117     public static final int EBCDIC_FILE_TYPE = 1;
118 
119    
120     /***
121      * A constant used to indicate the file(s) being transfered should
122      * be treated as a binary image, i.e., no translations should be
123      * performed.  All constants ending in <code>FILE_TYPE</code> are used to
124      * indicate file types.
125      ***/
126     public static final int BINARY_FILE_TYPE = 2;
127     public static final int IMAGE_FILE_TYPE = 2;
128 
129     /***
130      * A constant used to indicate the file(s) being transfered should
131      * be treated as a local type.  All constants ending in
132      * <code>FILE_TYPE</code> are used to indicate file types.
133      ***/
134     public static final int LOCAL_FILE_TYPE = 3;
135 
136     /***
137      * A constant used for text files to indicate a non-print text format.
138      * This is the default format.
139      * All constants ending in <code>TEXT_FORMAT</code> are used to indicate
140      * text formatting for text transfers (both ASCII and EBCDIC).
141      ***/
142     public static final int NON_PRINT_TEXT_FORMAT = 4;
143 
144     /***
145      * A constant used to indicate a text file contains format vertical format
146      * control characters.
147      * All constants ending in <code>TEXT_FORMAT</code> are used to indicate
148      * text formatting for text transfers (both ASCII and EBCDIC).
149      ***/
150     public static final int TELNET_TEXT_FORMAT = 5;
151 
152     /***
153      * A constant used to indicate a text file contains ASA vertical format
154      * control characters.
155      * All constants ending in <code>TEXT_FORMAT</code> are used to indicate
156      * text formatting for text transfers (both ASCII and EBCDIC).
157      ***/
158     public static final int CARRIAGE_CONTROL_TEXT_FORMAT = 6;
159 
160     /***
161      * A constant used to indicate a file is to be treated as a continuous
162      * sequence of bytes.  This is the default structure.  All constants ending
163      * in <code>_STRUCTURE</code> are used to indicate file structure for
164      * file transfers.
165      ***/
166     public static final int FILE_STRUCTURE = 7;
167 
168     /***
169      * A constant used to indicate a file is to be treated as a sequence
170      * of records.  All constants ending in <code>_STRUCTURE</code>
171      * are used to indicate file structure for file transfers.
172      ***/
173     public static final int RECORD_STRUCTURE = 8;
174 
175     /***
176      * A constant used to indicate a file is to be treated as a set of
177      * independent indexed pages.  All constants ending in
178      * <code>_STRUCTURE</code> are used to indicate file structure for file
179      * transfers.
180      ***/
181     public static final int PAGE_STRUCTURE = 9;
182 
183     /***
184      * A constant used to indicate a file is to be transfered as a stream
185      * of bytes.  This is the default transfer mode.  All constants ending
186      * in <code>TRANSFER_MODE</code> are used to indicate file transfer
187      * modes.
188      ***/
189     public static final int STREAM_TRANSFER_MODE = 10;
190 
191     /***
192      * A constant used to indicate a file is to be transfered as a series
193      * of blocks.  All constants ending in <code>TRANSFER_MODE</code> are used
194      * to indicate file transfer modes.
195      ***/
196     public static final int BLOCK_TRANSFER_MODE = 11;
197 
198     /***
199      * A constant used to indicate a file is to be transfered as FTP
200      * compressed data.  All constants ending in <code>TRANSFER_MODE</code>
201      * are used to indicate file transfer modes.
202      ***/
203     public static final int COMPRESSED_TRANSFER_MODE = 12;
204 
205     // We have to ensure that the protocol communication is in ASCII
206     // but we use ISO-8859-1 just in case 8-bit characters cross
207     // the wire.
208     /**
209      * The default character encoding used for communicating over an
210      * FTP control connection.  The default encoding is an
211      * ASCII-compatible encoding.  Some FTP servers expect other
212      * encodings.  You can change the encoding used by an FTP instance
213      * with {@link #setControlEncoding setControlEncoding}.
214      */
215     public static final String DEFAULT_CONTROL_ENCODING = "ISO-8859-1";
216     private static final String __modes = "AEILNTCFRPSBC";
217 
218     private StringBuilder __commandBuffer = new StringBuilder();
219 
220     protected int _replyCode;
221     protected ArrayList<String> _replyLines;
222     protected boolean _newReplyString;
223     protected String _replyString;
224     protected String _controlEncoding;
225     
226     /**
227      * This is used to signal whether a block of multiline responses beginning
228      * with xxx must be terminated by the same numeric code xxx
229      * See section 4.2 of RFX 959 for details. 
230      */
231     protected boolean strictMultilineParsing = false;
232 
233     /**
234      * Wraps SocketClient._input_ to facilitate the writing of text
235      * to the FTP control connection.  Do not access the control
236      * connection via SocketClient._input_.  This member starts
237      * with a null value, is initialized in {@link #_connectAction_},
238      * and set to null in {@link #disconnect}.
239      */
240     protected BufferedReader _controlInput_;
241 
242     /**
243      * Wraps SocketClient._output_ to facilitate the reading of text
244      * from the FTP control connection.  Do not access the control
245      * connection via SocketClient._output_.  This member starts
246      * with a null value, is initialized in {@link #_connectAction_},
247      * and set to null in {@link #disconnect}.
248      */
249     protected BufferedWriter _controlOutput_;
250 
251     /***
252      * A ProtocolCommandSupport object used to manage the registering of
253      * ProtocolCommandListeners and te firing of ProtocolCommandEvents.
254      ***/
255     protected ProtocolCommandSupport _commandSupport_;
256 
257     /***
258      * The default FTP constructor.  Sets the default port to
259      * <code>DEFAULT_PORT</code> and initializes internal data structures
260      * for saving FTP reply information.
261      ***/
262     public FTP()
263     {
264         super();
265         setDefaultPort(DEFAULT_PORT);
266         _replyLines = new ArrayList<String>();
267         _newReplyString = false;
268         _replyString = null;
269         _commandSupport_ = new ProtocolCommandSupport(this);
270         _controlEncoding = DEFAULT_CONTROL_ENCODING;
271     }
272 
273     // The RFC-compliant multiline termination check
274     private boolean __strictCheck(String line, String code) {
275         return (!(line.startsWith(code) && line.charAt(3) == ' '));
276     }
277     
278     // The strict check is too strong a condition because of non-conforming ftp
279     // servers like ftp.funet.fi which sent 226 as the last line of a
280     // 426 multi-line reply in response to ls /.  We relax the condition to
281     // test that the line starts with a digit rather than starting with
282     // the code.
283     private boolean __lenientCheck(String line) {
284         return (!(line.length() >= 4 && line.charAt(3) != '-' &&
285                 Character.isDigit(line.charAt(0))));
286     }
287     
288     private void __getReply() throws IOException
289     {
290         int length;
291 
292         _newReplyString = true;
293         _replyLines.clear();
294 
295         String line = _controlInput_.readLine();
296 
297         if (line == null)
298             throw new FTPConnectionClosedException(
299                 "Connection closed without indication.");
300 
301         // In case we run into an anomaly we don't want fatal index exceptions
302         // to be thrown.
303         length = line.length();
304         if (length < 3)
305             throw new MalformedServerReplyException(
306                 "Truncated server reply: " + line);
307         
308         String code = null;
309         try
310         {
311             code = line.substring(0, 3);
312             _replyCode = Integer.parseInt(code);
313         }
314         catch (NumberFormatException e)
315         {
316             throw new MalformedServerReplyException(
317                 "Could not parse response code.\nServer Reply: " + line);
318         }
319 
320         _replyLines.add(line);
321 
322         // Get extra lines if message continues.
323         if (length > 3 && line.charAt(3) == '-')
324         {
325             do
326             {
327                 line = _controlInput_.readLine();
328 
329                 if (line == null)
330                     throw new FTPConnectionClosedException(
331                         "Connection closed without indication.");
332 
333                 _replyLines.add(line);
334 
335                 // The length() check handles problems that could arise from readLine()
336                 // returning too soon after encountering a naked CR or some other
337                 // anomaly.
338             }
339             while ( isStrictMultilineParsing() ? __strictCheck(line, code) : __lenientCheck(line));
340         }
341 
342         if (_commandSupport_.getListenerCount() > 0) {
343             _commandSupport_.fireReplyReceived(_replyCode, getReplyString());
344         }
345 
346         if (_replyCode == FTPReply.SERVICE_NOT_AVAILABLE) {
347             throw new FTPConnectionClosedException("FTP response 421 received.  Server closed connection.");
348         }
349     }
350 
351     /**
352      * Initiates control connections and gets initial reply.
353      * Initializes {@link #_controlInput_} and {@link #_controlOutput_}.
354      */
355     @Override
356     protected void _connectAction_() throws IOException
357     {
358         super._connectAction_();
359         _controlInput_ =
360             new BufferedReader(new InputStreamReader(_socket_.getInputStream(),
361                                                      getControlEncoding()));
362         _controlOutput_ =
363             new BufferedWriter(new OutputStreamWriter(_socket_.getOutputStream(),
364                                                       getControlEncoding()));
365         __getReply();
366         // If we received code 120, we have to fetch completion reply.
367         if (FTPReply.isPositivePreliminary(_replyCode))
368             __getReply();
369     }
370 
371 
372     /**
373      * Sets the character encoding used by the FTP control connection.
374      * Some FTP servers require that commands be issued in a non-ASCII
375      * encoding like UTF-8 so that filenames with multi-byte character
376      * representations (e.g, Big 8) can be specified.
377      *
378      * @param encoding The new character encoding for the control connection.
379      */
380     public void setControlEncoding(String encoding) {
381         _controlEncoding = encoding;
382     }
383 
384 
385     /**
386      * @return The character encoding used to communicate over the
387      * control connection.
388      */
389     public String getControlEncoding() {
390         return _controlEncoding;
391     }
392 
393 
394     /***
395      * Adds a ProtocolCommandListener.  Delegates this task to
396      * {@link #_commandSupport_  _commandSupport_ }.
397      * <p>
398      * @param listener  The ProtocolCommandListener to add.
399      ***/
400     public void addProtocolCommandListener(ProtocolCommandListener listener)
401     {
402         _commandSupport_.addProtocolCommandListener(listener);
403     }
404 
405     /***
406      * Removes a ProtocolCommandListener.  Delegates this task to
407      * {@link #_commandSupport_  _commandSupport_ }.
408      * <p>
409      * @param listener  The ProtocolCommandListener to remove.
410      ***/
411     public void removeProtocolCommandListener(ProtocolCommandListener listener)
412     {
413         _commandSupport_.removeProtocolCommandListener(listener);
414     }
415 
416 
417     /***
418      * Closes the control connection to the FTP server and sets to null
419      * some internal data so that the memory may be reclaimed by the
420      * garbage collector.  The reply text and code information from the
421      * last command is voided so that the memory it used may be reclaimed.
422      * Also sets {@link #_controlInput_} and {@link #_controlOutput_} to null.
423      * <p>
424      * @exception IOException If an error occurs while disconnecting.
425      ***/
426     @Override
427     public void disconnect() throws IOException
428     {
429         super.disconnect();
430         _controlInput_ = null;
431         _controlOutput_ = null;
432         _newReplyString = false;
433         _replyString = null;
434     }
435 
436 
437     /***
438      * Sends an FTP command to the server, waits for a reply and returns the
439      * numerical response code.  After invocation, for more detailed
440      * information, the actual reply text can be accessed by calling
441      * {@link #getReplyString  getReplyString } or
442      * {@link #getReplyStrings  getReplyStrings }.
443      * <p>
444      * @param command  The text representation of the  FTP command to send.
445      * @param args The arguments to the FTP command.  If this parameter is
446      *             set to null, then the command is sent with no argument.
447      * @return The integer value of the FTP reply code returned by the server
448      *         in response to the command.
449      * @exception FTPConnectionClosedException
450      *      If the FTP server prematurely closes the connection as a result
451      *      of the client being idle or some other reason causing the server
452      *      to send FTP reply code 421.  This exception may be caught either
453      *      as an IOException or independently as itself.
454      * @exception IOException  If an I/O error occurs while either sending the
455      *      command or receiving the server reply.
456      ***/
457     public int sendCommand(String command, String args) throws IOException
458     {
459         String message;
460 
461         __commandBuffer.setLength(0);
462         __commandBuffer.append(command);
463 
464         if (args != null)
465         {
466             __commandBuffer.append(' ');
467             __commandBuffer.append(args);
468         }
469         __commandBuffer.append(SocketClient.NETASCII_EOL);
470 
471         try{
472         _controlOutput_.write(message = __commandBuffer.toString());
473             _controlOutput_.flush();
474         }
475         catch (SocketException e)
476         {
477             if (!isConnected() || !socketIsConnected(_socket_))
478             {
479                 throw new FTPConnectionClosedException("Connection unexpectedly closed.");
480             }
481             else
482             {
483                 throw e;
484             }
485         }
486     
487 
488         if (_commandSupport_.getListenerCount() > 0)
489             _commandSupport_.fireCommandSent(command, message);
490 
491         __getReply();
492         return _replyCode;
493     }
494 
495     /**
496      * Checks if the socket is connected 
497      *
498      * @param socket
499      * @return true if connected
500      */
501     private boolean socketIsConnected(Socket socket)
502     {
503         if (socket == null)
504         {
505             return false;
506         }
507 
508         return socket.isConnected();
509         
510     }
511 
512     /***
513      * Sends an FTP command to the server, waits for a reply and returns the
514      * numerical response code.  After invocation, for more detailed
515      * information, the actual reply text can be accessed by calling
516      * {@link #getReplyString  getReplyString } or
517      * {@link #getReplyStrings  getReplyStrings }.
518      * <p>
519      * @param command  The FTPCommand constant corresponding to the FTP command
520      *                 to send.
521      * @param args The arguments to the FTP command.  If this parameter is
522      *             set to null, then the command is sent with no argument.
523      * @return The integer value of the FTP reply code returned by the server
524      *         in response to the command.
525      * @exception FTPConnectionClosedException
526      *      If the FTP server prematurely closes the connection as a result
527      *      of the client being idle or some other reason causing the server
528      *      to send FTP reply code 421.  This exception may be caught either
529      *      as an IOException or independently as itself.
530      * @exception IOException  If an I/O error occurs while either sending the
531      *      command or receiving the server reply.
532      ***/
533     public int sendCommand(int command, String args) throws IOException
534     {
535         return sendCommand(FTPCommand._commands[command], args);
536     }
537 
538 
539     /***
540      * Sends an FTP command with no arguments to the server, waits for a
541      * reply and returns the numerical response code.  After invocation, for
542      * more detailed information, the actual reply text can be accessed by
543      * calling {@link #getReplyString  getReplyString } or
544      * {@link #getReplyStrings  getReplyStrings }.
545      * <p>
546      * @param command  The text representation of the  FTP command to send.
547      * @return The integer value of the FTP reply code returned by the server
548      *         in response to the command.
549      * @exception FTPConnectionClosedException
550      *      If the FTP server prematurely closes the connection as a result
551      *      of the client being idle or some other reason causing the server
552      *      to send FTP reply code 421.  This exception may be caught either
553      *      as an IOException or independently as itself.
554      * @exception IOException  If an I/O error occurs while either sending the
555      *      command or receiving the server reply.
556      ***/
557     public int sendCommand(String command) throws IOException
558     {
559         return sendCommand(command, null);
560     }
561 
562 
563     /***
564      * Sends an FTP command with no arguments to the server, waits for a
565      * reply and returns the numerical response code.  After invocation, for
566      * more detailed information, the actual reply text can be accessed by
567      * calling {@link #getReplyString  getReplyString } or
568      * {@link #getReplyStrings  getReplyStrings }.
569      * <p>
570      * @param command  The FTPCommand constant corresponding to the FTP command
571      *                 to send.
572      * @return The integer value of the FTP reply code returned by the server
573      *         in response to the command.
574      * @exception FTPConnectionClosedException
575      *      If the FTP server prematurely closes the connection as a result
576      *      of the client being idle or some other reason causing the server
577      *      to send FTP reply code 421.  This exception may be caught either
578      *      as an IOException or independently as itself.
579      * @exception IOException  If an I/O error occurs while either sending the
580      *      command or receiving the server reply.
581      ***/
582     public int sendCommand(int command) throws IOException
583     {
584         return sendCommand(command, null);
585     }
586 
587 
588     /***
589      * Returns the integer value of the reply code of the last FTP reply.
590      * You will usually only use this method after you connect to the
591      * FTP server to check that the connection was successful since
592      * <code> connect </code> is of type void.
593      * <p>
594      * @return The integer value of the reply code of the last FTP reply.
595      ***/
596     public int getReplyCode()
597     {
598         return _replyCode;
599     }
600 
601     /***
602      * Fetches a reply from the FTP server and returns the integer reply
603      * code.  After calling this method, the actual reply text can be accessed
604      * from either  calling {@link #getReplyString  getReplyString } or
605      * {@link #getReplyStrings  getReplyStrings }.  Only use this
606      * method if you are implementing your own FTP client or if you need to
607      * fetch a secondary response from the FTP server.
608      * <p>
609      * @return The integer value of the reply code of the fetched FTP reply.
610      * @exception FTPConnectionClosedException
611      *      If the FTP server prematurely closes the connection as a result
612      *      of the client being idle or some other reason causing the server
613      *      to send FTP reply code 421.  This exception may be caught either
614      *      as an IOException or independently as itself.
615      * @exception IOException  If an I/O error occurs while receiving the
616      *                         server reply.
617      ***/
618     public int getReply() throws IOException
619     {
620         __getReply();
621         return _replyCode;
622     }
623 
624 
625     /***
626      * Returns the lines of text from the last FTP server response as an array
627      * of strings, one entry per line.  The end of line markers of each are
628      * stripped from each line.
629      * <p>
630      * @return The lines of text from the last FTP response as an array.
631      ***/
632     public String[] getReplyStrings()
633     {
634         String[] lines;
635         lines = new String[_replyLines.size()];
636         _replyLines.addAll(Arrays.asList(lines));
637         return lines;
638     }
639 
640     /***
641      * Returns the entire text of the last FTP server response exactly
642      * as it was received, including all end of line markers in NETASCII
643      * format.
644      * <p>
645      * @return The entire text from the last FTP response as a String.
646      ***/
647     public String getReplyString()
648     {
649         StringBuilder buffer;
650 
651         if (!_newReplyString) {
652             return _replyString;
653         }
654 
655         buffer = new StringBuilder(256);
656         
657         for (String line : _replyLines) {
658                 buffer.append(line);
659                 buffer.append(SocketClient.NETASCII_EOL);
660         }
661         
662          _newReplyString = false;
663 
664         return (_replyString = buffer.toString());
665     }
666 
667 
668     /***
669      * A convenience method to send the FTP USER command to the server,
670      * receive the reply, and return the reply code.
671      * <p>
672      * @param username  The username to login under.
673      * @return The reply code received from the server.
674      * @exception FTPConnectionClosedException
675      *      If the FTP server prematurely closes the connection as a result
676      *      of the client being idle or some other reason causing the server
677      *      to send FTP reply code 421.  This exception may be caught either
678      *      as an IOException or independently as itself.
679      * @exception IOException  If an I/O error occurs while either sending the
680      *      command or receiving the server reply.
681      ***/
682     public int user(String username) throws IOException
683     {
684         return sendCommand(FTPCommand.USER, username);
685     }
686 
687     /**
688      * A convenience method to send the FTP PASS command to the server,
689      * receive the reply, and return the reply code.
690      * @param password The plain text password of the username being logged into.
691      * @return The reply code received from the server.
692      * @exception FTPConnectionClosedException
693      *      If the FTP server prematurely closes the connection as a result
694      *      of the client being idle or some other reason causing the server
695      *      to send FTP reply code 421.  This exception may be caught either
696      *      as an IOException or independently as itself.
697      * @exception IOException  If an I/O error occurs while either sending the
698      *      command or receiving the server reply.
699      */
700     public int pass(String password) throws IOException
701     {
702         return sendCommand(FTPCommand.PASS, password);
703     }
704 
705     /***
706      * A convenience method to send the FTP ACCT command to the server,
707      * receive the reply, and return the reply code.
708      * <p>
709      * @param account  The account name to access.
710      * @return The reply code received from the server.
711      * @exception FTPConnectionClosedException
712      *      If the FTP server prematurely closes the connection as a result
713      *      of the client being idle or some other reason causing the server
714      *      to send FTP reply code 421.  This exception may be caught either
715      *      as an IOException or independently as itself.
716      * @exception IOException  If an I/O error occurs while either sending the
717      *      command or receiving the server reply.
718      ***/
719     public int acct(String account) throws IOException
720     {
721         return sendCommand(FTPCommand.ACCT, account);
722     }
723 
724 
725     /***
726      * A convenience method to send the FTP ABOR command to the server,
727      * receive the reply, and return the reply code.
728      * <p>
729      * @return The reply code received from the server.
730      * @exception FTPConnectionClosedException
731      *      If the FTP server prematurely closes the connection as a result
732      *      of the client being idle or some other reason causing the server
733      *      to send FTP reply code 421.  This exception may be caught either
734      *      as an IOException or independently as itself.
735      * @exception IOException  If an I/O error occurs while either sending the
736      *      command or receiving the server reply.
737      ***/
738     public int abor() throws IOException
739     {
740         return sendCommand(FTPCommand.ABOR);
741     }
742 
743     /***
744      * A convenience method to send the FTP CWD command to the server,
745      * receive the reply, and return the reply code.
746      * <p>
747      * @param directory The new working directory.
748      * @return The reply code received from the server.
749      * @exception FTPConnectionClosedException
750      *      If the FTP server prematurely closes the connection as a result
751      *      of the client being idle or some other reason causing the server
752      *      to send FTP reply code 421.  This exception may be caught either
753      *      as an IOException or independently as itself.
754      * @exception IOException  If an I/O error occurs while either sending the
755      *      command or receiving the server reply.
756      ***/
757     public int cwd(String directory) throws IOException
758     {
759         return sendCommand(FTPCommand.CWD, directory);
760     }
761 
762     /***
763      * A convenience method to send the FTP CDUP command to the server,
764      * receive the reply, and return the reply code.
765      * <p>
766      * @return The reply code received from the server.
767      * @exception FTPConnectionClosedException
768      *      If the FTP server prematurely closes the connection as a result
769      *      of the client being idle or some other reason causing the server
770      *      to send FTP reply code 421.  This exception may be caught either
771      *      as an IOException or independently as itself.
772      * @exception IOException  If an I/O error occurs while either sending the
773      *      command or receiving the server reply.
774      ***/
775     public int cdup() throws IOException
776     {
777         return sendCommand(FTPCommand.CDUP);
778     }
779 
780     /***
781      * A convenience method to send the FTP QUIT command to the server,
782      * receive the reply, and return the reply code.
783      * <p>
784      * @return The reply code received from the server.
785      * @exception FTPConnectionClosedException
786      *      If the FTP server prematurely closes the connection as a result
787      *      of the client being idle or some other reason causing the server
788      *      to send FTP reply code 421.  This exception may be caught either
789      *      as an IOException or independently as itself.
790      * @exception IOException  If an I/O error occurs while either sending the
791      *      command or receiving the server reply.
792      ***/
793     public int quit() throws IOException
794     {
795         return sendCommand(FTPCommand.QUIT);
796     }
797 
798     /***
799      * A convenience method to send the FTP REIN command to the server,
800      * receive the reply, and return the reply code.
801      * <p>
802      * @return The reply code received from the server.
803      * @exception FTPConnectionClosedException
804      *      If the FTP server prematurely closes the connection as a result
805      *      of the client being idle or some other reason causing the server
806      *      to send FTP reply code 421.  This exception may be caught either
807      *      as an IOException or independently as itself.
808      * @exception IOException  If an I/O error occurs while either sending the
809      *      command or receiving the server reply.
810      ***/
811     public int rein() throws IOException
812     {
813         return sendCommand(FTPCommand.REIN);
814     }
815 
816     /***
817      * A convenience method to send the FTP SMNT command to the server,
818      * receive the reply, and return the reply code.
819      * <p>
820      * @param dir  The directory name.
821      * @return The reply code received from the server.
822      * @exception FTPConnectionClosedException
823      *      If the FTP server prematurely closes the connection as a result
824      *      of the client being idle or some other reason causing the server
825      *      to send FTP reply code 421.  This exception may be caught either
826      *      as an IOException or independently as itself.
827      * @exception IOException  If an I/O error occurs while either sending the
828      *      command or receiving the server reply.
829      ***/
830     public int smnt(String dir) throws IOException
831     {
832         return sendCommand(FTPCommand.SMNT, dir);
833     }
834 
835     /***
836      * A convenience method to send the FTP PORT command to the server,
837      * receive the reply, and return the reply code.
838      * <p>
839      * @param host  The host owning the port.
840      * @param port  The new port.
841      * @return The reply code received from the server.
842      * @exception FTPConnectionClosedException
843      *      If the FTP server prematurely closes the connection as a result
844      *      of the client being idle or some other reason causing the server
845      *      to send FTP reply code 421.  This exception may be caught either
846      *      as an IOException or independently as itself.
847      * @exception IOException  If an I/O error occurs while either sending the
848      *      command or receiving the server reply.
849      ***/
850     public int port(InetAddress host, int port) throws IOException
851     {
852         int num;
853         StringBuffer info = new StringBuffer(24);
854 
855         info.append(host.getHostAddress().replace('.', ','));
856         num = port >>> 8;
857         info.append(',');
858         info.append(num);
859         info.append(',');
860         num = port & 0xff;
861         info.append(num);
862 
863         return sendCommand(FTPCommand.PORT, info.toString());
864     }
865 
866     /***
867      * A convenience method to send the FTP PASV command to the server,
868      * receive the reply, and return the reply code.  Remember, it's up
869      * to you to interpret the reply string containing the host/port
870      * information.
871      * <p>
872      * @return The reply code received from the server.
873      * @exception FTPConnectionClosedException
874      *      If the FTP server prematurely closes the connection as a result
875      *      of the client being idle or some other reason causing the server
876      *      to send FTP reply code 421.  This exception may be caught either
877      *      as an IOException or independently as itself.
878      * @exception IOException  If an I/O error occurs while either sending the
879      *      command or receiving the server reply.
880      ***/
881     public int pasv() throws IOException
882     {
883         return sendCommand(FTPCommand.PASV);
884     }
885 
886     /**
887      * A convenience method to send the FTP TYPE command for text files
888      * to the server, receive the reply, and return the reply code.
889      * @param fileType  The type of the file (one of the <code>FILE_TYPE</code>
890      *              constants).
891      * @param formatOrByteSize  The format of the file (one of the
892      *              <code>_FORMAT</code> constants.  In the case of
893      *              <code>LOCAL_FILE_TYPE</code>, the byte size.
894      * @return The reply code received from the server.
895      * @exception FTPConnectionClosedException
896      *      If the FTP server prematurely closes the connection as a result
897      *      of the client being idle or some other reason causing the server
898      *      to send FTP reply code 421.  This exception may be caught either
899      *      as an IOException or independently as itself.
900      * @exception IOException  If an I/O error occurs while either sending the
901      *      command or receiving the server reply.
902      */
903     public int type(int fileType, int formatOrByteSize) throws IOException
904     {
905         StringBuffer arg = new StringBuffer();
906 
907         arg.append(__modes.charAt(fileType));
908         arg.append(' ');
909         if (fileType == LOCAL_FILE_TYPE)
910             arg.append(formatOrByteSize);
911         else
912             arg.append(__modes.charAt(formatOrByteSize));
913 
914         return sendCommand(FTPCommand.TYPE, arg.toString());
915     }
916 
917 
918     /**
919      * A convenience method to send the FTP TYPE command to the server,
920      * receive the reply, and return the reply code.
921      * <p>
922      * @param fileType  The type of the file (one of the <code>FILE_TYPE</code>
923      *              constants).
924      * @return The reply code received from the server.
925      * @exception FTPConnectionClosedException
926      *      If the FTP server prematurely closes the connection as a result
927      *      of the client being idle or some other reason causing the server
928      *      to send FTP reply code 421.  This exception may be caught either
929      *      as an IOException or independently as itself.
930      * @exception IOException  If an I/O error occurs while either sending the
931      *      command or receiving the server reply.
932      */
933     public int type(int fileType) throws IOException
934     {
935         return sendCommand(FTPCommand.TYPE,
936                            __modes.substring(fileType, fileType + 1));
937     }
938 
939     /***
940      * A convenience method to send the FTP STRU command to the server,
941      * receive the reply, and return the reply code.
942      * <p>
943      * @param structure  The structure of the file (one of the
944      *         <code>_STRUCTURE</code> constants).
945      * @return The reply code received from the server.
946      * @exception FTPConnectionClosedException
947      *      If the FTP server prematurely closes the connection as a result
948      *      of the client being idle or some other reason causing the server
949      *      to send FTP reply code 421.  This exception may be caught either
950      *      as an IOException or independently as itself.
951      * @exception IOException  If an I/O error occurs while either sending the
952      *      command or receiving the server reply.
953      ***/
954     public int stru(int structure) throws IOException
955     {
956         return sendCommand(FTPCommand.STRU,
957                            __modes.substring(structure, structure + 1));
958     }
959 
960     /***
961      * A convenience method to send the FTP MODE command to the server,
962      * receive the reply, and return the reply code.
963      * <p>
964      * @param mode  The transfer mode to use (one of the
965      *         <code>TRANSFER_MODE</code> constants).
966      * @return The reply code received from the server.
967      * @exception FTPConnectionClosedException
968      *      If the FTP server prematurely closes the connection as a result
969      *      of the client being idle or some other reason causing the server
970      *      to send FTP reply code 421.  This exception may be caught either
971      *      as an IOException or independently as itself.
972      * @exception IOException  If an I/O error occurs while either sending the
973      *      command or receiving the server reply.
974      ***/
975     public int mode(int mode) throws IOException
976     {
977         return sendCommand(FTPCommand.MODE,
978                            __modes.substring(mode, mode + 1));
979     }
980 
981     /***
982      * A convenience method to send the FTP RETR command to the server,
983      * receive the reply, and return the reply code.  Remember, it is up
984      * to you to manage the data connection.  If you don't need this low
985      * level of access, use {@link org.apache.commons.net.ftp.FTPClient}
986      * , which will handle all low level details for you.
987      * <p>
988      * @param pathname  The pathname of the file to retrieve.
989      * @return The reply code received from the server.
990      * @exception 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      * @exception IOException  If an I/O error occurs while either sending the
996      *      command or receiving the server reply.
997      ***/
998     public int retr(String pathname) throws IOException
999     {
1000         return sendCommand(FTPCommand.RETR, pathname);
1001     }
1002 
1003     /***
1004      * A convenience method to send the FTP STOR command to the server,
1005      * receive the reply, and return the reply code.  Remember, it is up
1006      * to you to manage the data connection.  If you don't need this low
1007      * level of access, use {@link org.apache.commons.net.ftp.FTPClient}
1008      * , which will handle all low level details for you.
1009      * <p>
1010      * @param pathname  The pathname to use for the file when stored at
1011      *                  the remote end of the transfer.
1012      * @return The reply code received from the server.
1013      * @exception FTPConnectionClosedException
1014      *      If the FTP server prematurely closes the connection as a result
1015      *      of the client being idle or some other reason causing the server
1016      *      to send FTP reply code 421.  This exception may be caught either
1017      *      as an IOException or independently as itself.
1018      * @exception IOException  If an I/O error occurs while either sending the
1019      *      command or receiving the server reply.
1020      ***/
1021     public int stor(String pathname) throws IOException
1022     {
1023         return sendCommand(FTPCommand.STOR, pathname);
1024     }
1025 
1026     /***
1027      * A convenience method to send the FTP STOU command to the server,
1028      * receive the reply, and return the reply code.  Remember, it is up
1029      * to you to manage the data connection.  If you don't need this low
1030      * level of access, use {@link org.apache.commons.net.ftp.FTPClient}
1031      * , which will handle all low level details for you.
1032      * <p>
1033      * @return The reply code received from the server.
1034      * @exception FTPConnectionClosedException
1035      *      If the FTP server prematurely closes the connection as a result
1036      *      of the client being idle or some other reason causing the server
1037      *      to send FTP reply code 421.  This exception may be caught either
1038      *      as an IOException or independently as itself.
1039      * @exception IOException  If an I/O error occurs while either sending the
1040      *      command or receiving the server reply.
1041      ***/
1042     public int stou() throws IOException
1043     {
1044         return sendCommand(FTPCommand.STOU);
1045     }
1046 
1047     /***
1048      * A convenience method to send the FTP STOU command to the server,
1049      * receive the reply, and return the reply code.  Remember, it is up
1050      * to you to manage the data connection.  If you don't need this low
1051      * level of access, use {@link org.apache.commons.net.ftp.FTPClient}
1052      * , which will handle all low level details for you.
1053      * @param pathname  The base pathname to use for the file when stored at
1054      *                  the remote end of the transfer.  Some FTP servers
1055      *                  require this.
1056      * @return The reply code received from the server.
1057      * @exception FTPConnectionClosedException
1058      *      If the FTP server prematurely closes the connection as a result
1059      *      of the client being idle or some other reason causing the server
1060      *      to send FTP reply code 421.  This exception may be caught either
1061      *      as an IOException or independently as itself.
1062      * @exception IOException  If an I/O error occurs while either sending the
1063      *      command or receiving the server reply.
1064      */
1065     public int stou(String pathname) throws IOException
1066     {
1067         return sendCommand(FTPCommand.STOU, pathname);
1068     }
1069 
1070     /***
1071      * A convenience method to send the FTP APPE command to the server,
1072      * receive the reply, and return the reply code.  Remember, it is up
1073      * to you to manage the data connection.  If you don't need this low
1074      * level of access, use {@link org.apache.commons.net.ftp.FTPClient}
1075      * , which will handle all low level details for you.
1076      * <p>
1077      * @param pathname  The pathname to use for the file when stored at
1078      *                  the remote end of the transfer.
1079      * @return The reply code received from the server.
1080      * @exception FTPConnectionClosedException
1081      *      If the FTP server prematurely closes the connection as a result
1082      *      of the client being idle or some other reason causing the server
1083      *      to send FTP reply code 421.  This exception may be caught either
1084      *      as an IOException or independently as itself.
1085      * @exception IOException  If an I/O error occurs while either sending the
1086      *      command or receiving the server reply.
1087      ***/
1088     public int appe(String pathname) throws IOException
1089     {
1090         return sendCommand(FTPCommand.APPE, pathname);
1091     }
1092 
1093     /***
1094      * A convenience method to send the FTP ALLO command to the server,
1095      * receive the reply, and return the reply code.
1096      * <p>
1097      * @param bytes The number of bytes to allocate.
1098      * @return The reply code received from the server.
1099      * @exception FTPConnectionClosedException
1100      *      If the FTP server prematurely closes the connection as a result
1101      *      of the client being idle or some other reason causing the server
1102      *      to send FTP reply code 421.  This exception may be caught either
1103      *      as an IOException or independently as itself.
1104      * @exception IOException  If an I/O error occurs while either sending the
1105      *      command or receiving the server reply.
1106      ***/
1107     public int allo(int bytes) throws IOException
1108     {
1109         return sendCommand(FTPCommand.ALLO, Integer.toString(bytes));
1110     }
1111 
1112     /***
1113      * A convenience method to send the FTP ALLO command to the server,
1114      * receive the reply, and return the reply code.
1115      * <p>
1116      * @param bytes The number of bytes to allocate.
1117      * @param recordSize  The size of a record.
1118      * @return The reply code received from the server.
1119      * @exception FTPConnectionClosedException
1120      *      If the FTP server prematurely closes the connection as a result
1121      *      of the client being idle or some other reason causing the server
1122      *      to send FTP reply code 421.  This exception may be caught either
1123      *      as an IOException or independently as itself.
1124      * @exception IOException  If an I/O error occurs while either sending the
1125      *      command or receiving the server reply.
1126      ***/
1127     public int allo(int bytes, int recordSize) throws IOException
1128     {
1129         return sendCommand(FTPCommand.ALLO, Integer.toString(bytes) + " R " +
1130                            Integer.toString(recordSize));
1131     }
1132 
1133     /***
1134      * A convenience method to send the FTP REST command to the server,
1135      * receive the reply, and return the reply code.
1136      * <p>
1137      * @param marker The marker at which to restart a transfer.
1138      * @return The reply code received from the server.
1139      * @exception FTPConnectionClosedException
1140      *      If the FTP server prematurely closes the connection as a result
1141      *      of the client being idle or some other reason causing the server
1142      *      to send FTP reply code 421.  This exception may be caught either
1143      *      as an IOException or independently as itself.
1144      * @exception IOException  If an I/O error occurs while either sending the
1145      *      command or receiving the server reply.
1146      ***/
1147     public int rest(String marker) throws IOException
1148     {
1149         return sendCommand(FTPCommand.REST, marker);
1150     }
1151     
1152     
1153     /**
1154      * @since 2.0
1155      **/
1156     public int mdtm(String file) throws IOException 
1157     {
1158         return sendCommand(FTPCommand.MDTM, file);
1159     }
1160 
1161     /***
1162      * A convenience method to send the FTP RNFR command to the server,
1163      * receive the reply, and return the reply code.
1164      * <p>
1165      * @param pathname The pathname to rename from.
1166      * @return The reply code received from the server.
1167      * @exception FTPConnectionClosedException
1168      *      If the FTP server prematurely closes the connection as a result
1169      *      of the client being idle or some other reason causing the server
1170      *      to send FTP reply code 421.  This exception may be caught either
1171      *      as an IOException or independently as itself.
1172      * @exception IOException  If an I/O error occurs while either sending the
1173      *      command or receiving the server reply.
1174      ***/
1175     public int rnfr(String pathname) throws IOException
1176     {
1177         return sendCommand(FTPCommand.RNFR, pathname);
1178     }
1179 
1180     /***
1181      * A convenience method to send the FTP RNTO command to the server,
1182      * receive the reply, and return the reply code.
1183      * <p>
1184      * @param pathname The pathname to rename to
1185      * @return The reply code received from the server.
1186      * @exception FTPConnectionClosedException
1187      *      If the FTP server prematurely closes the connection as a result
1188      *      of the client being idle or some other reason causing the server
1189      *      to send FTP reply code 421.  This exception may be caught either
1190      *      as an IOException or independently as itself.
1191      * @exception IOException  If an I/O error occurs while either sending the
1192      *      command or receiving the server reply.
1193      ***/
1194     public int rnto(String pathname) throws IOException
1195     {
1196         return sendCommand(FTPCommand.RNTO, pathname);
1197     }
1198 
1199     /***
1200      * A convenience method to send the FTP DELE command to the server,
1201      * receive the reply, and return the reply code.
1202      * <p>
1203      * @param pathname The pathname to delete.
1204      * @return The reply code received from the server.
1205      * @exception FTPConnectionClosedException
1206      *      If the FTP server prematurely closes the connection as a result
1207      *      of the client being idle or some other reason causing the server
1208      *      to send FTP reply code 421.  This exception may be caught either
1209      *      as an IOException or independently as itself.
1210      * @exception IOException  If an I/O error occurs while either sending the
1211      *      command or receiving the server reply.
1212      ***/
1213     public int dele(String pathname) throws IOException
1214     {
1215         return sendCommand(FTPCommand.DELE, pathname);
1216     }
1217 
1218     /***
1219      * A convenience method to send the FTP RMD command to the server,
1220      * receive the reply, and return the reply code.
1221      * <p>
1222      * @param pathname The pathname of the directory to remove.
1223      * @return The reply code received from the server.
1224      * @exception FTPConnectionClosedException
1225      *      If the FTP server prematurely closes the connection as a result
1226      *      of the client being idle or some other reason causing the server
1227      *      to send FTP reply code 421.  This exception may be caught either
1228      *      as an IOException or independently as itself.
1229      * @exception IOException  If an I/O error occurs while either sending the
1230      *      command or receiving the server reply.
1231      ***/
1232     public int rmd(String pathname) throws IOException
1233     {
1234         return sendCommand(FTPCommand.RMD, pathname);
1235     }
1236 
1237     /***
1238      * A convenience method to send the FTP MKD command to the server,
1239      * receive the reply, and return the reply code.
1240      * <p>
1241      * @param pathname The pathname of the new directory to create.
1242      * @return The reply code received from the server.
1243      * @exception FTPConnectionClosedException
1244      *      If the FTP server prematurely closes the connection as a result
1245      *      of the client being idle or some other reason causing the server
1246      *      to send FTP reply code 421.  This exception may be caught either
1247      *      as an IOException or independently as itself.
1248      * @exception IOException  If an I/O error occurs while either sending the
1249      *      command or receiving the server reply.
1250      ***/
1251     public int mkd(String pathname) throws IOException
1252     {
1253         return sendCommand(FTPCommand.MKD, pathname);
1254     }
1255 
1256     /***
1257      * A convenience method to send the FTP PWD command to the server,
1258      * receive the reply, and return the reply code.
1259      * <p>
1260      * @return The reply code received from the server.
1261      * @exception FTPConnectionClosedException
1262      *      If the FTP server prematurely closes the connection as a result
1263      *      of the client being idle or some other reason causing the server
1264      *      to send FTP reply code 421.  This exception may be caught either
1265      *      as an IOException or independently as itself.
1266      * @exception IOException  If an I/O error occurs while either sending the
1267      *      command or receiving the server reply.
1268      ***/
1269     public int pwd() throws IOException
1270     {
1271         return sendCommand(FTPCommand.PWD);
1272     }
1273 
1274     /***
1275      * A convenience method to send the FTP LIST command to the server,
1276      * receive the reply, and return the reply code.  Remember, it is up
1277      * to you to manage the data connection.  If you don't need this low
1278      * level of access, use {@link org.apache.commons.net.ftp.FTPClient}
1279      * , which will handle all low level details for you.
1280      * <p>
1281      * @return The reply code received from the server.
1282      * @exception FTPConnectionClosedException
1283      *      If the FTP server prematurely closes the connection as a result
1284      *      of the client being idle or some other reason causing the server
1285      *      to send FTP reply code 421.  This exception may be caught either
1286      *      as an IOException or independently as itself.
1287      * @exception IOException  If an I/O error occurs while either sending the
1288      *      command or receiving the server reply.
1289      ***/
1290     public int list() throws IOException
1291     {
1292         return sendCommand(FTPCommand.LIST);
1293     }
1294 
1295     /***
1296      * A convenience method to send the FTP LIST command to the server,
1297      * receive the reply, and return the reply code.  Remember, it is up
1298      * to you to manage the data connection.  If you don't need this low
1299      * level of access, use {@link org.apache.commons.net.ftp.FTPClient}
1300      * , which will handle all low level details for you.
1301      * <p>
1302      * @param pathname  The pathname to list.
1303      * @return The reply code received from the server.
1304      * @exception FTPConnectionClosedException
1305      *      If the FTP server prematurely closes the connection as a result
1306      *      of the client being idle or some other reason causing the server
1307      *      to send FTP reply code 421.  This exception may be caught either
1308      *      as an IOException or independently as itself.
1309      * @exception IOException  If an I/O error occurs while either sending the
1310      *      command or receiving the server reply.
1311      ***/
1312     public int list(String pathname) throws IOException
1313     {
1314         return sendCommand(FTPCommand.LIST, pathname);
1315     }
1316 
1317     /***
1318      * A convenience method to send the FTP NLST command to the server,
1319      * receive the reply, and return the reply code.  Remember, it is up
1320      * to you to manage the data connection.  If you don't need this low
1321      * level of access, use {@link org.apache.commons.net.ftp.FTPClient}
1322      * , which will handle all low level details for you.
1323      * <p>
1324      * @return The reply code received from the server.
1325      * @exception FTPConnectionClosedException
1326      *      If the FTP server prematurely closes the connection as a result
1327      *      of the client being idle or some other reason causing the server
1328      *      to send FTP reply code 421.  This exception may be caught either
1329      *      as an IOException or independently as itself.
1330      * @exception IOException  If an I/O error occurs while either sending the
1331      *      command or receiving the server reply.
1332      ***/
1333     public int nlst() throws IOException
1334     {
1335         return sendCommand(FTPCommand.NLST);
1336     }
1337 
1338     /***
1339      * A convenience method to send the FTP NLST command to the server,
1340      * receive the reply, and return the reply code.  Remember, it is up
1341      * to you to manage the data connection.  If you don't need this low
1342      * level of access, use {@link org.apache.commons.net.ftp.FTPClient}
1343      * , which will handle all low level details for you.
1344      * <p>
1345      * @param pathname  The pathname to list.
1346      * @return The reply code received from the server.
1347      * @exception FTPConnectionClosedException
1348      *      If the FTP server prematurely closes the connection as a result
1349      *      of the client being idle or some other reason causing the server
1350      *      to send FTP reply code 421.  This exception may be caught either
1351      *      as an IOException or independently as itself.
1352      * @exception IOException  If an I/O error occurs while either sending the
1353      *      command or receiving the server reply.
1354      ***/
1355     public int nlst(String pathname) throws IOException
1356     {
1357         return sendCommand(FTPCommand.NLST, pathname);
1358     }
1359 
1360     /***
1361      * A convenience method to send the FTP SITE command to the server,
1362      * receive the reply, and return the reply code.
1363      * <p>
1364      * @param parameters  The site parameters to send.
1365      * @return The reply code received from the server.
1366      * @exception FTPConnectionClosedException
1367      *      If the FTP server prematurely closes the connection as a result
1368      *      of the client being idle or some other reason causing the server
1369      *      to send FTP reply code 421.  This exception may be caught either
1370      *      as an IOException or independently as itself.
1371      * @exception IOException  If an I/O error occurs while either sending the
1372      *      command or receiving the server reply.
1373      ***/
1374     public int site(String parameters) throws IOException
1375     {
1376         return sendCommand(FTPCommand.SITE, parameters);
1377     }
1378 
1379     /***
1380      * A convenience method to send the FTP SYST command to the server,
1381      * receive the reply, and return the reply code.
1382      * <p>
1383      * @return The reply code received from the server.
1384      * @exception FTPConnectionClosedException
1385      *      If the FTP server prematurely closes the connection as a result
1386      *      of the client being idle or some other reason causing the server
1387      *      to send FTP reply code 421.  This exception may be caught either
1388      *      as an IOException or independently as itself.
1389      * @exception IOException  If an I/O error occurs while either sending the
1390      *      command or receiving the server reply.
1391      ***/
1392     public int syst() throws IOException
1393     {
1394         return sendCommand(FTPCommand.SYST);
1395     }
1396 
1397     /***
1398      * A convenience method to send the FTP STAT command to the server,
1399      * receive the reply, and return the reply code.
1400      * <p>
1401      * @return The reply code received from the server.
1402      * @exception FTPConnectionClosedException
1403      *      If the FTP server prematurely closes the connection as a result
1404      *      of the client being idle or some other reason causing the server
1405      *      to send FTP reply code 421.  This exception may be caught either
1406      *      as an IOException or independently as itself.
1407      * @exception IOException  If an I/O error occurs while either sending the
1408      *      command or receiving the server reply.
1409      ***/
1410     public int stat() throws IOException
1411     {
1412         return sendCommand(FTPCommand.STAT);
1413     }
1414 
1415     /***
1416      * A convenience method to send the FTP STAT command to the server,
1417      * receive the reply, and return the reply code.
1418      * <p>
1419      * @param pathname  A pathname to list.
1420      * @return The reply code received from the server.
1421      * @exception FTPConnectionClosedException
1422      *      If the FTP server prematurely closes the connection as a result
1423      *      of the client being idle or some other reason causing the server
1424      *      to send FTP reply code 421.  This exception may be caught either
1425      *      as an IOException or independently as itself.
1426      * @exception IOException  If an I/O error occurs while either sending the
1427      *      command or receiving the server reply.
1428      ***/
1429     public int stat(String pathname) throws IOException
1430     {
1431         return sendCommand(FTPCommand.STAT, pathname);
1432     }
1433 
1434     /***
1435      * A convenience method to send the FTP HELP command to the server,
1436      * receive the reply, and return the reply code.
1437      * <p>
1438      * @return The reply code received from the server.
1439      * @exception FTPConnectionClosedException
1440      *      If the FTP server prematurely closes the connection as a result
1441      *      of the client being idle or some other reason causing the server
1442      *      to send FTP reply code 421.  This exception may be caught either
1443      *      as an IOException or independently as itself.
1444      * @exception IOException  If an I/O error occurs while either sending the
1445      *      command or receiving the server reply.
1446      ***/
1447     public int help() throws IOException
1448     {
1449         return sendCommand(FTPCommand.HELP);
1450     }
1451 
1452     /***
1453      * A convenience method to send the FTP HELP command to the server,
1454      * receive the reply, and return the reply code.
1455      * <p>
1456      * @param command  The command name on which to request help.
1457      * @return The reply code received from the server.
1458      * @exception FTPConnectionClosedException
1459      *      If the FTP server prematurely closes the connection as a result
1460      *      of the client being idle or some other reason causing the server
1461      *      to send FTP reply code 421.  This exception may be caught either
1462      *      as an IOException or independently as itself.
1463      * @exception IOException  If an I/O error occurs while either sending the
1464      *      command or receiving the server reply.
1465      ***/
1466     public int help(String command) throws IOException
1467     {
1468         return sendCommand(FTPCommand.HELP, command);
1469     }
1470 
1471     /***
1472      * A convenience method to send the FTP NOOP command to the server,
1473      * receive the reply, and return the reply code.
1474      * <p>
1475      * @return The reply code received from the server.
1476      * @exception FTPConnectionClosedException
1477      *      If the FTP server prematurely closes the connection as a result
1478      *      of the client being idle or some other reason causing the server
1479      *      to send FTP reply code 421.  This exception may be caught either
1480      *      as an IOException or independently as itself.
1481      * @exception IOException  If an I/O error occurs while either sending the
1482      *      command or receiving the server reply.
1483      ***/
1484     public int noop() throws IOException
1485     {
1486         return sendCommand(FTPCommand.NOOP);
1487     }
1488 
1489     /**
1490      * Return whether strict multiline parsing is enabled, as per RFX 959, section 4.2.
1491      * @return True if strict, false if lenient
1492      * @since 2.0
1493      */
1494     public boolean isStrictMultilineParsing() {
1495         return strictMultilineParsing;
1496     }
1497 
1498     /**
1499      * Set strict multiline parsing.
1500      * @param strictMultilineParsing
1501      * @since 2.0
1502      */
1503     public void setStrictMultilineParsing(boolean strictMultilineParsing) {
1504         this.strictMultilineParsing = strictMultilineParsing;
1505     }
1506 }
1507 
1508 /* Emacs configuration
1509  * Local variables:        **
1510  * mode:             java  **
1511  * c-basic-offset:   4     **
1512  * indent-tabs-mode: nil   **
1513  * End:                    **
1514  */