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