001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018package org.apache.commons.net.ftp;
019import java.io.BufferedReader;
020import java.io.BufferedWriter;
021import java.io.IOException;
022import java.io.InputStreamReader;
023import java.io.OutputStreamWriter;
024import java.net.InetAddress;
025import java.net.Socket;
026import java.net.SocketException;
027import java.util.ArrayList;
028import java.util.Arrays;
029
030import org.apache.commons.net.MalformedServerReplyException;
031import org.apache.commons.net.ProtocolCommandListener;
032import org.apache.commons.net.ProtocolCommandSupport;
033import org.apache.commons.net.SocketClient;
034
035/***
036 * FTP provides the basic the functionality necessary to implement your
037 * own FTP client.  It extends org.apache.commons.net.SocketClient since
038 * extending TelnetClient was causing unwanted behavior (like connections
039 * that did not time out properly).
040 * <p>
041 * To derive the full benefits of the FTP class requires some knowledge
042 * of the FTP protocol defined in RFC 959.  However, there is no reason
043 * why you should have to use the FTP class.  The
044 * {@link org.apache.commons.net.ftp.FTPClient} class,
045 * derived from FTP,
046 * implements all the functionality required of an FTP client.  The
047 * FTP class is made public to provide access to various FTP constants
048 * and to make it easier for adventurous programmers (or those with
049 * special needs) to interact with the FTP protocol and implement their
050 * own clients.  A set of methods with names corresponding to the FTP
051 * command names are provided to facilitate this interaction.
052 * <p>
053 * You should keep in mind that the FTP server may choose to prematurely
054 * close a connection if the client has been idle for longer than a
055 * given time period (usually 900 seconds).  The FTP class will detect a
056 * premature FTP server connection closing when it receives a
057 * {@link org.apache.commons.net.ftp.FTPReply#SERVICE_NOT_AVAILABLE FTPReply.SERVICE_NOT_AVAILABLE }
058 *  response to a command.
059 * When that occurs, the FTP class method encountering that reply will throw
060 * an {@link org.apache.commons.net.ftp.FTPConnectionClosedException}
061 * .  <code>FTPConectionClosedException</code>
062 * is a subclass of <code> IOException </code> and therefore need not be
063 * caught separately, but if you are going to catch it separately, its
064 * catch block must appear before the more general <code> IOException </code>
065 * catch block.  When you encounter an
066 * {@link org.apache.commons.net.ftp.FTPConnectionClosedException}
067 * , you must disconnect the connection with
068 * {@link #disconnect  disconnect() } to properly clean up the
069 * system resources used by FTP.  Before disconnecting, you may check the
070 * last reply code and text with
071 * {@link #getReplyCode  getReplyCode },
072 * {@link #getReplyString  getReplyString },
073 * and {@link #getReplyStrings  getReplyStrings}.
074 * You may avoid server disconnections while the client is idle by
075 * periodicaly sending NOOP commands to the server.
076 * <p>
077 * Rather than list it separately for each method, we mention here that
078 * every method communicating with the server and throwing an IOException
079 * can also throw a
080 * {@link org.apache.commons.net.MalformedServerReplyException}
081 * , which is a subclass
082 * of IOException.  A MalformedServerReplyException will be thrown when
083 * the reply received from the server deviates enough from the protocol
084 * specification that it cannot be interpreted in a useful manner despite
085 * attempts to be as lenient as possible.
086 * <p>
087 * <p>
088 * @author Daniel F. Savarese
089 * @author Rory Winston 
090 * @author Joseph Hindsley
091 * @see FTPClient
092 * @see FTPConnectionClosedException
093 * @see org.apache.commons.net.MalformedServerReplyException
094 * @version $Id: FTP.java 658520 2008-05-21 01:14:11Z sebb $
095 ***/
096
097public class FTP extends SocketClient
098{
099    /*** The default FTP data port (20). ***/
100    public static final int DEFAULT_DATA_PORT = 20;
101    /*** The default FTP control port (21). ***/
102    public static final int DEFAULT_PORT = 21;
103
104    /***
105     * A constant used to indicate the file(s) being transfered should
106     * be treated as ASCII.  This is the default file type.  All constants
107     * ending in <code>FILE_TYPE</code> are used to indicate file types.
108     ***/
109    public static final int ASCII_FILE_TYPE = 0;
110
111    /***
112     * A constant used to indicate the file(s) being transfered should
113     * be treated as EBCDIC.  Note however that there are several different
114     * EBCDIC formats.  All constants ending in <code>FILE_TYPE</code>
115     * are used to indicate file types.
116     ***/
117    public static final int EBCDIC_FILE_TYPE = 1;
118
119   
120    /***
121     * A constant used to indicate the file(s) being transfered should
122     * be treated as a binary image, i.e., no translations should be
123     * performed.  All constants ending in <code>FILE_TYPE</code> are used to
124     * indicate file types.
125     ***/
126    public static final int BINARY_FILE_TYPE = 2;
127
128    /***
129     * A constant used to indicate the file(s) being transfered should
130     * be treated as a local type.  All constants ending in
131     * <code>FILE_TYPE</code> are used to indicate file types.
132     ***/
133    public static final int LOCAL_FILE_TYPE = 3;
134
135    /***
136     * A constant used for text files to indicate a non-print text format.
137     * This is the default format.
138     * All constants ending in <code>TEXT_FORMAT</code> are used to indicate
139     * text formatting for text transfers (both ASCII and EBCDIC).
140     ***/
141    public static final int NON_PRINT_TEXT_FORMAT = 4;
142
143    /***
144     * A constant used to indicate a text file contains format vertical format
145     * control characters.
146     * All constants ending in <code>TEXT_FORMAT</code> are used to indicate
147     * text formatting for text transfers (both ASCII and EBCDIC).
148     ***/
149    public static final int TELNET_TEXT_FORMAT = 5;
150
151    /***
152     * A constant used to indicate a text file contains ASA vertical format
153     * control characters.
154     * All constants ending in <code>TEXT_FORMAT</code> are used to indicate
155     * text formatting for text transfers (both ASCII and EBCDIC).
156     ***/
157    public static final int CARRIAGE_CONTROL_TEXT_FORMAT = 6;
158
159    /***
160     * A constant used to indicate a file is to be treated as a continuous
161     * sequence of bytes.  This is the default structure.  All constants ending
162     * in <code>_STRUCTURE</code> are used to indicate file structure for
163     * file transfers.
164     ***/
165    public static final int FILE_STRUCTURE = 7;
166
167    /***
168     * A constant used to indicate a file is to be treated as a sequence
169     * of records.  All constants ending in <code>_STRUCTURE</code>
170     * are used to indicate file structure for file transfers.
171     ***/
172    public static final int RECORD_STRUCTURE = 8;
173
174    /***
175     * A constant used to indicate a file is to be treated as a set of
176     * independent indexed pages.  All constants ending in
177     * <code>_STRUCTURE</code> are used to indicate file structure for file
178     * transfers.
179     ***/
180    public static final int PAGE_STRUCTURE = 9;
181
182    /***
183     * A constant used to indicate a file is to be transfered as a stream
184     * of bytes.  This is the default transfer mode.  All constants ending
185     * in <code>TRANSFER_MODE</code> are used to indicate file transfer
186     * modes.
187     ***/
188    public static final int STREAM_TRANSFER_MODE = 10;
189
190    /***
191     * A constant used to indicate a file is to be transfered as a series
192     * of blocks.  All constants ending in <code>TRANSFER_MODE</code> are used
193     * to indicate file transfer modes.
194     ***/
195    public static final int BLOCK_TRANSFER_MODE = 11;
196
197    /***
198     * A constant used to indicate a file is to be transfered as FTP
199     * compressed data.  All constants ending in <code>TRANSFER_MODE</code>
200     * are used to indicate file transfer modes.
201     ***/
202    public static final int COMPRESSED_TRANSFER_MODE = 12;
203
204    // We have to ensure that the protocol communication is in ASCII
205    // but we use ISO-8859-1 just in case 8-bit characters cross
206    // the wire.
207    /**
208     * The default character encoding used for communicating over an
209     * FTP control connection.  The default encoding is an
210     * ASCII-compatible encoding.  Some FTP servers expect other
211     * encodings.  You can change the encoding used by an FTP instance
212     * with {@link #setControlEncoding setControlEncoding}.
213     */
214    public static final String DEFAULT_CONTROL_ENCODING = "ISO-8859-1";
215    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 */