Java Source Code: org.apache.commons.net.ftp.FTPClient


   1: /*
   2:  * Copyright 2001-2005 The Apache Software Foundation
   3:  *
   4:  * Licensed under the Apache License, Version 2.0 (the "License");
   5:  * you may not use this file except in compliance with the License.
   6:  * You may obtain a copy of the License at
   7:  *
   8:  *     http://www.apache.org/licenses/LICENSE-2.0
   9:  *
  10:  * Unless required by applicable law or agreed to in writing, software
  11:  * distributed under the License is distributed on an "AS IS" BASIS,
  12:  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13:  * See the License for the specific language governing permissions and
  14:  * limitations under the License.
  15:  */
  16: package org.apache.commons.net.ftp;
  17: import java.io.BufferedInputStream;
  18: import java.io.BufferedOutputStream;
  19: import java.io.BufferedReader;
  20: import java.io.IOException;
  21: import java.io.InputStream;
  22: import java.io.InputStreamReader;
  23: import java.io.OutputStream;
  24: import java.net.InetAddress;
  25: import java.net.ServerSocket;
  26: import java.net.Socket;
  27: import java.util.Vector;
  28: 
  29: import org.apache.commons.net.MalformedServerReplyException;
  30: import org.apache.commons.net.ftp.parser.DefaultFTPFileEntryParserFactory;
  31: import org.apache.commons.net.ftp.parser.FTPFileEntryParserFactory;
  32: import org.apache.commons.net.ftp.parser.ParserInitializationException;
  33: import org.apache.commons.net.io.CopyStreamEvent;
  34: import org.apache.commons.net.io.CopyStreamException;
  35: import org.apache.commons.net.io.FromNetASCIIInputStream;
  36: import org.apache.commons.net.io.ToNetASCIIOutputStream;
  37: import org.apache.commons.net.io.Util;
  38: 
  39: /***
  40:  * FTPClient encapsulates all the functionality necessary to store and
  41:  * retrieve files from an FTP server.  This class takes care of all
  42:  * low level details of interacting with an FTP server and provides
  43:  * a convenient higher level interface.  As with all classes derived
  44:  * from {@link org.apache.commons.net.SocketClient},
  45:  * you must first connect to the server with
  46:  * {@link org.apache.commons.net.SocketClient#connect  connect }
  47:  * before doing anything, and finally
  48:  * {@link org.apache.commons.net.SocketClient#disconnect  disconnect }
  49:  * after you're completely finished interacting with the server.
  50:  * Then you need to check the FTP reply code to see if the connection
  51:  * was successful.  For example:
  52:  * <pre>
  53:  *    boolean error = false;
  54:	   *    try {
  55: *      int reply;
  56: *      ftp.connect("ftp.foobar.com");
  57: *      System.out.println("Connected to " + server + ".");
  58: *      System.out.print(ftp.getReplyString());
  59: *
  60: *      // After connection attempt, you should check the reply code to verify
  61: *      // success.
  62: *      reply = ftp.getReplyCode();
  63: *
  64:	   *      if(!FTPReply.isPositiveCompletion(reply)) {
  65: *        ftp.disconnect();
  66: *        System.err.println("FTP server refused connection.");
  67: *        System.exit(1);
  68: *      }
  69: *      ... // transfer files
  70: *      ftp.logout();
  71: *    } catch(IOException e) {
  72: *      error = true;
  73: *      e.printStackTrace();
  74: *    } finally {
  75:	   *      if(ftp.isConnected()) {
  76:	   *        try {
  77: *          ftp.disconnect();
  78: *        } catch(IOException ioe) {
  79: *          // do nothing
  80: *        }
  81: *      }
  82: *      System.exit(error ? 1 : 0);
  83: *    }
  84: * </pre>
  85: * <p>
  86: * Immediately after connecting is the only real time you need to check the
  87: * reply code (because connect is of type void).  The convention for all the
  88: * FTP command methods in FTPClient is such that they either return a
  89: * boolean value or some other value.
  90: * The boolean methods return true on a successful completion reply from
  91: * the FTP server and false on a reply resulting in an error condition or
  92: * failure.  The methods returning a value other than boolean return a value
  93: * containing the higher level data produced by the FTP command, or null if a
  94: * reply resulted in an error condition or failure.  If you want to access
  95: * the exact FTP reply code causing a success or failure, you must call
  96: * {@link org.apache.commons.net.ftp.FTP#getReplyCode  getReplyCode } after
  97: * a success or failure.
  98: * <p>
  99: * The default settings for FTPClient are for it to use
 100: * <code> FTP.ASCII_FILE_TYPE </code>,
 101: * <code> FTP.NON_PRINT_TEXT_FORMAT </code>,
 102: * <code> FTP.STREAM_TRANSFER_MODE </code>, and
 103: * <code> FTP.FILE_STRUCTURE </code>.  The only file types directly supported
 104: * are <code> FTP.ASCII_FILE_TYPE </code> and
 105: * <code> FTP.IMAGE_FILE_TYPE </code> (which is the same as
 106: * <code> FTP.BINARY_FILE_TYPE </code>).  Because there are at lest 4
 107: * different EBCDIC encodings, we have opted not to provide direct support
 108: * for EBCDIC.  To transfer EBCDIC and other unsupported file types you
 109: * must create your own filter InputStreams and OutputStreams and wrap
 110: * them around the streams returned or required by the FTPClient methods.
 111: * FTPClient uses the {@link ToNetASCIIOutputStream NetASCII}  
 112: * filter streams to provide transparent handling of ASCII files.  We will 
 113: * consider incorporating EBCDIC support if there is enough demand.
 114: * <p>
 115: * <code> FTP.NON_PRINT_TEXT_FORMAT </code>,
 116: * <code> FTP.STREAM_TRANSFER_MODE </code>, and
 117: * <code> FTP.FILE_STRUCTURE </code> are the only supported formats,
 118: * transfer modes, and file structures.
 119: * <p>
 120: * Because the handling of sockets on different platforms can differ
 121: * significantly, the FTPClient automatically issues a new PORT command
 122: * prior to every transfer requiring that the server connect to the client's
 123: * data port.  This ensures identical problem-free behavior on Windows, Unix,
 124: * and Macintosh platforms.  Additionally, it relieves programmers from
 125: * having to issue the PORT command themselves and dealing with platform
 126: * dependent issues.
 127: * <p>
 128: * Additionally, for security purposes, all data connections to the
 129: * client are verified to ensure that they originated from the intended
 130: * party (host and port).  If a data connection is initiated by an unexpected
 131: * party, the command will close the socket and throw an IOException.  You
 132: * may disable this behavior with
 133: * {@link #setRemoteVerificationEnabled setRemoteVerificationEnabled()}.
 134: * <p>
 135: * You should keep in mind that the FTP server may choose to prematurely
 136: * close a connection if the client has been idle for longer than a
 137: * given time period (usually 900 seconds).  The FTPClient class will detect a
 138: * premature FTP server connection closing when it receives a
 139: * {@link org.apache.commons.net.ftp.FTPReply#SERVICE_NOT_AVAILABLE FTPReply.SERVICE_NOT_AVAILABLE }
 140: *  response to a command.
 141: * When that occurs, the FTP class method encountering that reply will throw
 142: * an {@link org.apache.commons.net.ftp.FTPConnectionClosedException}
 143: * .
 144: * <code>FTPConnectionClosedException</code>
 145: * is a subclass of <code> IOException </code> and therefore need not be
 146: * caught separately, but if you are going to catch it separately, its
 147: * catch block must appear before the more general <code> IOException </code>
 148: * catch block.  When you encounter an
 149: * {@link org.apache.commons.net.ftp.FTPConnectionClosedException}
 150: * , you must disconnect the connection with
 151: * {@link #disconnect  disconnect() } to properly clean up the
 152: * system resources used by FTPClient.  Before disconnecting, you may check the
 153: * last reply code and text with
 154: * {@link org.apache.commons.net.ftp.FTP#getReplyCode  getReplyCode },
 155: * {@link org.apache.commons.net.ftp.FTP#getReplyString  getReplyString },
 156: * and
 157: * {@link org.apache.commons.net.ftp.FTP#getReplyStrings  getReplyStrings}.
 158: * You may avoid server disconnections while the client is idle by
 159: * periodicaly sending NOOP commands to the server.
 160: * <p>
 161: * Rather than list it separately for each method, we mention here that
 162: * every method communicating with the server and throwing an IOException
 163: * can also throw a
 164: * {@link org.apache.commons.net.MalformedServerReplyException}
 165: * , which is a subclass
 166: * of IOException.  A MalformedServerReplyException will be thrown when
 167: * the reply received from the server deviates enough from the protocol
 168: * specification that it cannot be interpreted in a useful manner despite
 169: * attempts to be as lenient as possible.
 170: * <p>
 171: * Listing API Examples
 172: * Both paged and unpaged examples of directory listings are available,
 173: * as follows:
 174: * <p>
 175: * Unpaged (whole list) access, using a parser accessible by auto-detect:
 176: * <pre>
 177: *    FTPClient f=FTPClient();
 178: *    f.connect(server);
 179: *    f.login(username, password);
 180: *    FTPFile[] files = listFiles(directory);
 181: * </pre>
 182: * <p>
 183: * Paged access, using a parser not accessible by auto-detect.  The class
 184: * defined in the first parameter of initateListParsing should be derived
 185: * from org.apache.commons.net.FTPFileEntryParser:
 186: * <pre>
 187: *    FTPClient f=FTPClient();
 188: *    f.connect(server);
 189: *    f.login(username, password);
 190: *    FTPListParseEngine engine =
 191: *       f.initiateListParsing("com.whatever.YourOwnParser", directory);
 192: *
 193:	   *    while (engine.hasNext()) {
 194: *       FTPFile[] files = engine.getNext(25);  // "page size" you want
 195: *       //do whatever you want with these files, display them, etc.
 196: *       //expensive FTPFile objects not created until needed.
 197: *    }
 198: * </pre>
 199: * <p>
 200: * Paged access, using a parser accessible by auto-detect:
 201: * <pre>
 202: *    FTPClient f=FTPClient();
 203: *    f.connect(server);
 204: *    f.login(username, password);
 205: *    FTPListParseEngine engine = f.initiateListParsing(directory);
 206: *
 207:	   *    while (engine.hasNext()) {
 208: *       FTPFile[] files = engine.getNext(25);  // "page size" you want
 209: *       //do whatever you want with these files, display them, etc.
 210: *       //expensive FTPFile objects not created until needed.
 211: *    }
 212: * </pre>
 213: * <p>
 214: * For examples of using FTPClient on servers whose directory listings 
 215: * <ul> 
 216: * <li>use languages other than English</li>
 217: * <li>use date formats other than the American English "standard" <code>MM d yyyy</code></li>
 218: * <li>are in different timezones and you need accurate timestamps for dependency checking 
 219: *     as in Ant</li>
 220: * </ul>see {@link  FTPClientConfig  FTPClientConfig}.
 221: * <p>
 222: * NOTE: If you experience problems with unwanted firing of <pre>setSoTimeout()</pre> 
 223: * during periods of client inactivity, this can be alleviated by calling <pre>setReaderThread(false)</pre>.
 224: * For more details, see <a href="http://issues.apache.org/bugzilla/show_bug.cgi?id=31122">this thread</a>. 
 225: * </p>
 226: * <p> 
 227: * @author Daniel F. Savarese
 228: * @see FTP
 229: * @see FTPConnectionClosedException
 230: * @see FTPFileEntryParser
 231: * @see FTPFileEntryParserFactory
 232: * @see DefaultFTPFileEntryParserFactory
 233: * @see FTPClientConfig
 234: * @see org.apache.commons.net.MalformedServerReplyException
 235: **/
 236:public class FTPClient extends FTP
 237:implements Configurable
 238:	  {
 239:    /***
 240:     * A constant indicating the FTP session is expecting all transfers
 241:     * to occur between the client (local) and server and that the server
 242:     * should connect to the client's data port to initiate a data transfer.
 243:     * This is the default data connection mode when and FTPClient instance
 244:     * is created.
 245:     ***/
 246:    public static final int ACTIVE_LOCAL_DATA_CONNECTION_MODE = 0;
 247:    /***
 248:     * A constant indicating the FTP session is expecting all transfers
 249:     * to occur between two remote servers and that the server
 250:     * the client is connected to should connect to the other server's
 251:     * data port to initiate a data transfer.
 252:     ***/
 253:    public static final int ACTIVE_REMOTE_DATA_CONNECTION_MODE = 1;
 254:    /***
 255:     * A constant indicating the FTP session is expecting all transfers
 256:     * to occur between the client (local) and server and that the server
 257:     * is in passive mode, requiring the client to connect to the
 258:     * server's data port to initiate a transfer.
 259:     ***/
 260:    public static final int PASSIVE_LOCAL_DATA_CONNECTION_MODE = 2;
 261:    /***
 262:     * A constant indicating the FTP session is expecting all transfers
 263:     * to occur between two remote servers and that the server
 264:     * the client is connected to is in passive mode, requiring the other
 265:     * server to connect to the first server's data port to initiate a data
 266:     * transfer.
 267:     ***/
 268:    public static final int PASSIVE_REMOTE_DATA_CONNECTION_MODE = 3;
 269:
 270:    private int __dataConnectionMode, __dataTimeout;
 271:    private int __passivePort;
 272:    private String __passiveHost;
 273:    private int __fileType, __fileFormat, __fileStructure, __fileTransferMode;
 274:    private boolean __remoteVerificationEnabled;
 275:    private long __restartOffset;
 276:    private FTPFileEntryParserFactory __parserFactory;
 277:    private int __bufferSize;
 278:
 279:    // __systemName is a cached value that should not be referenced directly
 280:    // except when assigned in getSystemName and __initDefaults.
 281:    private String __systemName;
 282:
 283:    // __entryParser is a cached value that should not be referenced directly
 284:    // except when assigned in listFiles(String, String) and __initDefaults.
 285:    private FTPFileEntryParser __entryParser;
 286:    
 287:    private FTPClientConfig __configuration;
 288:
 289:    /***
 290:     * Default FTPClient constructor.  Creates a new FTPClient instance
 291:     * with the data connection mode set to
 292:     * <code> ACTIVE_LOCAL_DATA_CONNECTION_MODE </code>, the file type
 293:     * set to <code> FTP.ASCII_FILE_TYPE </code>, the
 294:     * file format set to <code> FTP.NON_PRINT_TEXT_FORMAT </code>,
 295:     * the file structure set to <code> FTP.FILE_STRUCTURE </code>, and
 296:     * the transfer mode set to <code> FTP.STREAM_TRANSFER_MODE </code>.
 297:     ***/
 298:    public FTPClient()
 299:	      {
 300:        __initDefaults();
 301:        __dataTimeout = -1;
 302:        __remoteVerificationEnabled = true;
 303:        __parserFactory = new DefaultFTPFileEntryParserFactory();
 304:        __configuration      = null;
 305:    }
 306:
 307:
 308:    private void __initDefaults()
 309:	      {
 310:        __dataConnectionMode = ACTIVE_LOCAL_DATA_CONNECTION_MODE;
 311:        __passiveHost        = null;
 312:        __passivePort        = -1;
 313:        __fileType           = FTP.ASCII_FILE_TYPE;
 314:        __fileStructure      = FTP.FILE_STRUCTURE;
 315:        __fileFormat         = FTP.NON_PRINT_TEXT_FORMAT;
 316:        __fileTransferMode   = FTP.STREAM_TRANSFER_MODE;
 317:        __restartOffset      = 0;
 318:        __systemName         = null;
 319:        __entryParser        = null;
 320:        __bufferSize          = Util.DEFAULT_COPY_BUFFER_SIZE;
 321:    }
 322:    
 323:    private String __parsePathname(String reply)
 324:	      {
 325:        int begin, end;
 326:
 327:        begin = reply.indexOf('"') + 1;
 328:        end = reply.indexOf('"', begin);
 329:
 330:        return reply.substring(begin, end);
 331:    }
 332:
 333:
 334:    private void __parsePassiveModeReply(String reply)
 335:    throws MalformedServerReplyException
 336:	      {
 337:        int i, index, lastIndex;
 338:        String octet1, octet2;
 339:        StringBuffer host;
 340:
 341:        reply = reply.substring(reply.indexOf('(') + 1,
 342:                                reply.indexOf(')')).trim();
 343:
 344:        host = new StringBuffer(24);
 345:        lastIndex = 0;
 346:        index = reply.indexOf(',');
 347:        host.append(reply.substring(lastIndex, index));
 348:
 349:        for (i = 0; i < 3; i++)
 350:	          {
 351:            host.append('.');
 352:            lastIndex = index + 1;
 353:            index = reply.indexOf(',', lastIndex);
 354:            host.append(reply.substring(lastIndex, index));
 355:        }
 356:
 357:        lastIndex = index + 1;
 358:        index = reply.indexOf(',', lastIndex);
 359:
 360:        octet1 = reply.substring(lastIndex, index);
 361:        octet2 = reply.substring(index + 1);
 362:
 363:        // index and lastIndex now used as temporaries
 364:        try
 365:	          {
 366:            index = Integer.parseInt(octet1);
 367:            lastIndex = Integer.parseInt(octet2);
 368:        }
 369:        catch (NumberFormatException e)
 370:	          {
 371:            throw new MalformedServerReplyException(
 372:                "Could not parse passive host information.\nServer Reply: " + reply);
 373:        }
 374:
 375:        index <<= 8;
 376:        index |= lastIndex;
 377:
 378:        __passiveHost = host.toString();
 379:        __passivePort = index;
 380:    }
 381:
 382:    private boolean __storeFile(int command, String remote, InputStream local)
 383:    throws IOException
 384:	      {
 385:        OutputStream output;
 386:        Socket socket;
 387:
 388:        if ((socket = _openDataConnection_(command, remote)) == null)
 389:            return false;
 390:
 391:        output = new BufferedOutputStream(socket.getOutputStream(),
 392:                                          getBufferSize()
 393:                                          );
 394:        if (__fileType == ASCII_FILE_TYPE)
 395:            output = new ToNetASCIIOutputStream(output);
 396:        // Treat everything else as binary for now
 397:        try
 398:	          {
 399:            Util.copyStream(local, output, getBufferSize(),
 400:                            CopyStreamEvent.UNKNOWN_STREAM_SIZE, null,
 401:                            false);
 402:        }
 403:        catch (IOException e)
 404:	          {
 405:            try
 406:	              {
 407:                socket.close();
 408:            }
 409:            catch (IOException f)
 410:            {}
 411:            throw e;
 412:        }
 413:        output.close();
 414:        socket.close();
 415:        return completePendingCommand();
 416:    }
 417:
 418:    private OutputStream __storeFileStream(int command, String remote)
 419:    throws IOException
 420:	      {
 421:        OutputStream output;
 422:        Socket socket;
 423:
 424:        if ((socket = _openDataConnection_(command, remote)) == null)
 425:            return null;
 426:
 427:        output = socket.getOutputStream();
 428:	          if (__fileType == ASCII_FILE_TYPE) {
 429:          // We buffer ascii transfers because the buffering has to
 430:          // be interposed between ToNetASCIIOutputSream and the underlying
 431:          // socket output stream.  We don't buffer binary transfers
 432:          // because we don't want to impose a buffering policy on the
 433:          // programmer if possible.  Programmers can decide on their
 434:          // own if they want to wrap the SocketOutputStream we return
 435:          // for file types other than ASCII.
 436:          output = new BufferedOutputStream(output,
 437:                                            getBufferSize());
 438:          output = new ToNetASCIIOutputStream(output);
 439:
 440:        }
 441:        return new org.apache.commons.net.io.SocketOutputStream(socket, output);
 442:    }
 443:
 444:
 445:    /**
 446:     * Establishes a data connection with the FTP server, returning
 447:     * a Socket for the connection if successful.  If a restart
 448:     * offset has been set with {@link #setRestartOffset(long)},
 449:     * a REST command is issued to the server with the offset as
 450:     * an argument before establishing the data connection.  Active
 451:     * mode connections also cause a local PORT command to be issued.
 452:     * <p>
 453:     * @param command  The text representation of the FTP command to send.
 454:     * @param arg The arguments to the FTP command.  If this parameter is
 455:     *             set to null, then the command is sent with no argument.
 456:     * @return A Socket corresponding to the established data connection.
 457:     *         Null is returned if an FTP protocol error is reported at
 458:     *         any point during the establishment and initialization of
 459:     *         the connection.
 460:     * @exception IOException  If an I/O error occurs while either sending a
 461:     *      command to the server or receiving a reply from the server.
 462:     */
 463:    protected Socket _openDataConnection_(int command, String arg)
 464:      throws IOException
 465:	      {
 466:        Socket socket;
 467:
 468:        if (__dataConnectionMode != ACTIVE_LOCAL_DATA_CONNECTION_MODE &&
 469:                __dataConnectionMode != PASSIVE_LOCAL_DATA_CONNECTION_MODE)
 470:            return null;
 471:
 472:        if (__dataConnectionMode == ACTIVE_LOCAL_DATA_CONNECTION_MODE)
 473:	          {
 474:            ServerSocket server;
 475:            server = _socketFactory_.createServerSocket(0, 1, getLocalAddress());
 476:
 477:            if (!FTPReply.isPositiveCompletion(port(getLocalAddress(),
 478:                                                    server.getLocalPort())))
 479:	              {
 480:                server.close();
 481:                return null;
 482:            }
 483:
 484:            if ((__restartOffset > 0) && !restart(__restartOffset))
 485:	              {
 486:                server.close();
 487:                return null;
 488:            }
 489:
 490:            if (!FTPReply.isPositivePreliminary(sendCommand(command, arg)))
 491:	              {
 492:                server.close();
 493:                return null;
 494:            }
 495:
 496:            // For now, let's just use the data timeout value for waiting for
 497:            // the data connection.  It may be desirable to let this be a
 498:            // separately configurable value.  In any case, we really want
 499:            // to allow preventing the accept from blocking indefinitely.
 500:            if (__dataTimeout >= 0)
 501:                server.setSoTimeout(__dataTimeout);
 502:            socket = server.accept();
 503:            server.close();
 504:        }
 505:        else
 506:	          { // We must be in PASSIVE_LOCAL_DATA_CONNECTION_MODE
 507:
 508:            if (pasv() != FTPReply.ENTERING_PASSIVE_MODE)
 509:                return null;
 510:
 511:            __parsePassiveModeReply((String)_replyLines.elementAt(0));
 512:
 513:            socket = _socketFactory_.createSocket(__passiveHost, __passivePort);
 514:            if ((__restartOffset > 0) && !restart(__restartOffset))
 515:	              {
 516:                socket.close();
 517:                return null;
 518:            }
 519:
 520:            if (!FTPReply.isPositivePreliminary(sendCommand(command, arg)))
 521:	              {
 522:                socket.close();
 523:                return null;
 524:            }
 525:        }
 526:
 527:        if (__remoteVerificationEnabled && !verifyRemote(socket))
 528:	          {
 529:            InetAddress host1, host2;
 530:
 531:            host1 = socket.getInetAddress();
 532:            host2 = getRemoteAddress();
 533:
 534:            socket.close();
 535:
 536:            throw new IOException(
 537:                "Host attempting data connection " + host1.getHostAddress() +
 538:                " is not same as server " + host2.getHostAddress());
 539:        }
 540:
 541:        if (__dataTimeout >= 0)
 542:            socket.setSoTimeout(__dataTimeout);
 543:
 544:        return socket;
 545:    }
 546:
 547:
 548:    protected void _connectAction_() throws IOException
 549:	      {
 550:        super._connectAction_();
 551:        __initDefaults();
 552:    }
 553:
 554:
 555:    /***
 556:     * Sets the timeout in milliseconds to use when reading from the
 557:     * data connection.  This timeout will be set immediately after
 558:     * opening the data connection.
 559:     * <p>
 560:     * @param  timeout The default timeout in milliseconds that is used when
 561:     *        opening a data connection socket.
 562:     ***/
 563:    public void setDataTimeout(int timeout)
 564:	      {
 565:        __dataTimeout = timeout;
 566:    }
 567:
 568:    /**
 569:     * set the factory used for parser creation to the supplied factory object.
 570:     *
 571:     * @param parserFactory
 572:     *               factory object used to create FTPFileEntryParsers
 573:     *
 574:     * @see org.apache.commons.net.ftp.parser.FTPFileEntryParserFactory
 575:     * @see org.apache.commons.net.ftp.parser.DefaultFTPFileEntryParserFactory
 576:     */
 577:	      public void setParserFactory(FTPFileEntryParserFactory parserFactory) {
 578:        __parserFactory = parserFactory;
 579:    }
 580:
 581:
 582:    /***
 583:     * Closes the connection to the FTP server and restores
 584:     * connection parameters to the default values.
 585:     * <p>
 586:     * @exception IOException If an error occurs while disconnecting.
 587:     ***/
 588:    public void disconnect() throws IOException
 589:	      {
 590:        super.disconnect();
 591:        __initDefaults();
 592:    }
 593:
 594:
 595:    /***
 596:     * Enable or disable verification that the remote host taking part
 597:     * of a data connection is the same as the host to which the control
 598:     * connection is attached.  The default is for verification to be
 599:     * enabled.  You may set this value at any time, whether the
 600:     * FTPClient is currently connected or not.
 601:     * <p>
 602:     * @param enable True to enable verification, false to disable verification.
 603:     ***/
 604:    public void setRemoteVerificationEnabled(boolean enable)
 605:	      {
 606:        __remoteVerificationEnabled = enable;
 607:    }
 608:
 609:    /***
 610:     * Return whether or not verification of the remote host participating
 611:     * in data connections is enabled.  The default behavior is for
 612:     * verification to be enabled.
 613:     * <p>
 614:     * @return True if verification is enabled, false if not.
 615:     ***/
 616:    public boolean isRemoteVerificationEnabled()
 617:	      {
 618:        return __remoteVerificationEnabled;
 619:    }
 620:
 621:    /***
 622:     * Login to the FTP server using the provided username and password.
 623:     * <p>
 624:     * @param username The username to login under.
 625:     * @param password The password to use.
 626:     * @return True if successfully completed, false if not.
 627:     * @exception FTPConnectionClosedException
 628:     *      If the FTP server prematurely closes the connection as a result
 629:     *      of the client being idle or some other reason causing the server
 630:     *      to send FTP reply code 421.  This exception may be caught either
 631:     *      as an IOException or independently as itself.
 632:     * @exception IOException  If an I/O error occurs while either sending a
 633:     *      command to the server or receiving a reply from the server.
 634:     ***/
 635:    public boolean login(String username, String password) throws IOException
 636:	      {
 637:        user(username);
 638:
 639:        if (FTPReply.isPositiveCompletion(_replyCode))
 640:            return true;
 641:
 642:        // If we get here, we either have an error code, or an intermmediate
 643:        // reply requesting password.
 644:        if (!FTPReply.isPositiveIntermediate(_replyCode))
 645:            return false;
 646:
 647:        return FTPReply.isPositiveCompletion(pass(password));
 648:    }
 649:
 650:
 651:    /***
 652:     * Login to the FTP server using the provided username, password,
 653:     * and account.  If no account is required by the server, only
 654:     * the username and password, the account information is not used.
 655:     * <p>
 656:     * @param username The username to login under.
 657:     * @param password The password to use.
 658:     * @param account  The account to use.
 659:     * @return True if successfully completed, false if not.
 660:     * @exception FTPConnectionClosedException
 661:     *      If the FTP server prematurely closes the connection as a result
 662:     *      of the client being idle or some other reason causing the server
 663:     *      to send FTP reply code 421.  This exception may be caught either
 664:     *      as an IOException or independently as itself.
 665:     * @exception IOException  If an I/O error occurs while either sending a
 666:     *      command to the server or receiving a reply from the server.
 667:     ***/
 668:    public boolean login(String username, String password, String account)
 669:    throws IOException
 670:	      {
 671:        user(username);
 672:
 673:        if (FTPReply.isPositiveCompletion(_replyCode))
 674:            return true;
 675:
 676:        // If we get here, we either have an error code, or an intermmediate
 677:        // reply requesting password.
 678:        if (!FTPReply.isPositiveIntermediate(_replyCode))
 679:            return false;
 680:
 681:        pass(password);
 682:
 683:        if (FTPReply.isPositiveCompletion(_replyCode))
 684:            return true;
 685:
 686:        if (!FTPReply.isPositiveIntermediate(_replyCode))
 687:            return false;
 688:
 689:        return FTPReply.isPositiveCompletion(acct(account));
 690:    }
 691:
 692:    /***
 693:     * Logout of the FTP server by sending the QUIT command.
 694:     * <p>
 695:     * @return True if successfully completed, false if not.
 696:     * @exception FTPConnectionClosedException
 697:     *      If the FTP server prematurely closes the connection as a result
 698:     *      of the client being idle or some other reason causing the server
 699:     *      to send FTP reply code 421.  This exception may be caught either
 700:     *      as an IOException or independently as itself.
 701:     * @exception IOException  If an I/O error occurs while either sending a
 702:     *      command to the server or receiving a reply from the server.
 703:     ***/
 704:    public boolean logout() throws IOException
 705:	      {
 706:        return FTPReply.isPositiveCompletion(quit());
 707:    }
 708:
 709:
 710:    /***
 711:     * Change the current working directory of the FTP session.
 712:     * <p>
 713:     * @param pathname  The new current working directory.
 714:     * @return True if successfully completed, false if not.
 715:     * @exception FTPConnectionClosedException
 716:     *      If the FTP server prematurely closes the connection as a result
 717:     *      of the client being idle or some other reason causing the server
 718:     *      to send FTP reply code 421.  This exception may be caught either
 719:     *      as an IOException or independently as itself.
 720:     * @exception IOException  If an I/O error occurs while either sending a
 721:     *      command to the server or receiving a reply from the server.
 722:     ***/
 723:    public boolean changeWorkingDirectory(String pathname) throws IOException
 724:	      {
 725:        return FTPReply.isPositiveCompletion(cwd(pathname));
 726:    }
 727:
 728:
 729:    /***
 730:     * Change to the parent directory of the current working directory.
 731:     * <p>
 732:     * @return True if successfully completed, false if not.
 733:     * @exception FTPConnectionClosedException
 734:     *      If the FTP server prematurely closes the connection as a result
 735:     *      of the client being idle or some other reason causing the server
 736:     *      to send FTP reply code 421.  This exception may be caught either
 737:     *      as an IOException or independently as itself.
 738:     * @exception IOException  If an I/O error occurs while either sending a
 739:     *      command to the server or receiving a reply from the server.
 740:     ***/
 741:    public boolean changeToParentDirectory() throws IOException
 742:	      {
 743:        return FTPReply.isPositiveCompletion(cdup());
 744:    }
 745:
 746:
 747:    /***
 748:     * Issue the FTP SMNT command.
 749:     * <p>
 750:     * @param pathname The pathname to mount.
 751:     * @return True if successfully completed, false if not.
 752:     * @exception FTPConnectionClosedException
 753:     *      If the FTP server prematurely closes the connection as a result
 754:     *      of the client being idle or some other reason causing the server
 755:     *      to send FTP reply code 421.  This exception may be caught either
 756:     *      as an IOException or independently as itself.
 757:     * @exception IOException  If an I/O error occurs while either sending a
 758:     *      command to the server or receiving a reply from the server.
 759:     ***/
 760:    public boolean structureMount(String pathname) throws IOException
 761:	      {
 762:        return FTPReply.isPositiveCompletion(smnt(pathname));
 763:    }
 764:
 765:    /***
 766:     * Reinitialize the FTP session.  Not all FTP servers support this
 767:     * command, which issues the FTP REIN command.
 768:     * <p>
 769:     * @return True if successfully completed, false if not.
 770:     * @exception FTPConnectionClosedException
 771:     *      If the FTP server prematurely closes the connection as a result
 772:     *      of the client being idle or some other reason causing the server
 773:     *      to send FTP reply code 421.  This exception may be caught either
 774:     *      as an IOException or independently as itself.
 775:     * @exception IOException  If an I/O error occurs while either sending a
 776:     *      command to the server or receiving a reply from the server.
 777:     ***/
 778:    boolean reinitialize() throws IOException
 779:	      {
 780:        rein();
 781:
 782:        if (FTPReply.isPositiveCompletion(_replyCode) ||
 783:                (FTPReply.isPositivePreliminary(_replyCode) &&
 784:                 FTPReply.isPositiveCompletion(getReply())))
 785:	          {
 786:
 787:            __initDefaults();
 788:
 789:            return true;
 790:        }
 791:
 792:        return false;
 793:    }
 794:
 795:
 796:    /***
 797:     * Set the current data connection mode to
 798:     * <code>ACTIVE_LOCAL_DATA_CONNECTION_MODE</code>.  No communication
 799:     * with the FTP server is conducted, but this causes all future data
 800:     * transfers to require the FTP server to connect to the client's
 801:     * data port.  Additionally, to accommodate differences between socket
 802:     * implementations on different platforms, this method causes the
 803:     * client to issue a PORT command before every data transfer.
 804:     ***/
 805:    public void enterLocalActiveMode()
 806:	      {
 807:        __dataConnectionMode = ACTIVE_LOCAL_DATA_CONNECTION_MODE;
 808:        __passiveHost = null;
 809:        __passivePort = -1;
 810:    }
 811:
 812:
 813:    /***
 814:     * Set the current data connection mode to
 815:     * <code> PASSIVE_LOCAL_DATA_CONNECTION_MODE </code>.  Use this
 816:     * method only for data transfers between the client and server.
 817:     * This method causes a PASV command to be issued to the server
 818:     * before the opening of every data connection, telling the server to
 819:     * open a data port to which the client will connect to conduct
 820:     * data transfers.  The FTPClient will stay in
 821:     * <code> PASSIVE_LOCAL_DATA_CONNECTION_MODE </code> until the
 822:     * mode is changed by calling some other method such as
 823:     * {@link #enterLocalActiveMode  enterLocalActiveMode() }
 824:     ***/
 825:    public void enterLocalPassiveMode()
 826:	      {
 827:        __dataConnectionMode = PASSIVE_LOCAL_DATA_CONNECTION_MODE;
 828:        // These will be set when just before a data connection is opened
 829:        // in _openDataConnection_()
 830:        __passiveHost = null;
 831:        __passivePort = -1;
 832:    }
 833:
 834:
 835:    /***
 836:     * Set the current data connection mode to
 837:     * <code> ACTIVE_REMOTE_DATA_CONNECTION </code>.  Use this method only
 838:     * for server to server data transfers.  This method issues a PORT
 839:     * command to the server, indicating the other server and port to which
 840:     * it should connect for data transfers.  You must call this method
 841:     * before EVERY server to server transfer attempt.  The FTPClient will
 842:     * NOT automatically continue to issue PORT commands.  You also
 843:     * must remember to call
 844:     * {@link #enterLocalActiveMode  enterLocalActiveMode() } if you
 845:     * wish to return to the normal data connection mode.
 846:     * <p>
 847:     * @param host The passive mode server accepting connections for data
 848:     *             transfers.
 849:     * @param port The passive mode server's data port.
 850:     * @return True if successfully completed, false if not.
 851:     * @exception FTPConnectionClosedException
 852:     *      If the FTP server prematurely closes the connection as a result
 853:     *      of the client being idle or some other reason causing the server
 854:     *      to send FTP reply code 421.  This exception may be caught either
 855:     *      as an IOException or independently as itself.
 856:     * @exception IOException  If an I/O error occurs while either sending a
 857:     *      command to the server or receiving a reply from the server.
 858:     ***/
 859:    public boolean enterRemoteActiveMode(InetAddress host, int port)
 860:    throws IOException
 861:	      {
 862:        if (FTPReply.isPositiveCompletion(port(host, port)))
 863:	          {
 864:            __dataConnectionMode = ACTIVE_REMOTE_DATA_CONNECTION_MODE;
 865:            __passiveHost = null;
 866:            __passivePort = -1;
 867:            return true;
 868:        }
 869:        return false;
 870:    }
 871:
 872:    /***
 873:     * Set the current data connection mode to
 874:     * <code> PASSIVE_REMOTE_DATA_CONNECTION_MODE </code>.  Use this
 875:     * method only for server to server data transfers.
 876:     * This method issues a PASV command to the server, telling it to
 877:     * open a data port to which the active server will connect to conduct
 878:     * data transfers.  You must call this method
 879:     * before EVERY server to server transfer attempt.  The FTPClient will
 880:     * NOT automatically continue to issue PASV commands.  You also
 881:     * must remember to call
 882:     * {@link #enterLocalActiveMode  enterLocalActiveMode() } if you
 883:     * wish to return to the normal data connection mode.
 884:     * <p>
 885:     * @return True if successfully completed, false if not.
 886:     * @exception FTPConnectionClosedException
 887:     *      If the FTP server prematurely closes the connection as a result
 888:     *      of the client being idle or some other reason causing the server
 889:     *      to send FTP reply code 421.  This exception may be caught either
 890:     *      as an IOException or independently as itself.
 891:     * @exception IOException  If an I/O error occurs while either sending a
 892:     *      command to the server or receiving a reply from the server.
 893:     ***/
 894:    public boolean enterRemotePassiveMode() throws IOException
 895:	      {
 896:        if (pasv() != FTPReply.ENTERING_PASSIVE_MODE)
 897:            return false;
 898:
 899:        __dataConnectionMode = PASSIVE_REMOTE_DATA_CONNECTION_MODE;
 900:        __parsePassiveModeReply((String)_replyLines.elementAt(0));
 901:
 902:        return true;
 903:    }
 904:
 905:    /***
 906:     * Returns the hostname or IP address (in the form of a string) returned
 907:     * by the server when entering passive mode.  If not in passive mode,
 908:     * returns null.  This method only returns a valid value AFTER a
 909:     * data connection has been opened after a call to
 910:     * {@link #enterLocalPassiveMode enterLocalPassiveMode()}.
 911:     * This is because FTPClient sends a PASV command to the server only
 912:     * just before opening a data connection, and not when you call
 913:     * {@link #enterLocalPassiveMode enterLocalPassiveMode()}.
 914:     * <p>
 915:     * @return The passive host name if in passive mode, otherwise null.
 916:     ***/
 917:    public String getPassiveHost()
 918:	      {
 919:        return __passiveHost;
 920:    }
 921:
 922:    /***
 923:     * If in passive mode, returns the data port of the passive host.
 924:     * This method only returns a valid value AFTER a
 925:     * data connection has been opened after a call to
 926:     * {@link #enterLocalPassiveMode enterLocalPassiveMode()}.
 927:     * This is because FTPClient sends a PASV command to the server only
 928:     * just before opening a data connection, and not when you call
 929:     * {@link #enterLocalPassiveMode enterLocalPassiveMode()}.
 930:     * <p>
 931:     * @return The data port of the passive server.  If not in passive
 932:     *         mode, undefined.
 933:     ***/
 934:    public int getPassivePort()
 935:	      {
 936:        return __passivePort;
 937:    }
 938:
 939:
 940:    /***
 941:     * Returns the current data connection mode (one of the
 942:     * <code> _DATA_CONNECTION_MODE </code> constants.
 943:     * <p>
 944:     * @return The current data connection mode (one of the
 945:     * <code> _DATA_CONNECTION_MODE </code> constants.
 946:     ***/
 947:    public int getDataConnectionMode()
 948:	      {
 949:        return __dataConnectionMode;
 950:    }
 951:
 952:
 953:    /***
 954:     * Sets the file type to be transferred.  This should be one of
 955:     * <code> FTP.ASCII_FILE_TYPE </code>, <code> FTP.IMAGE_FILE_TYPE </code>,
 956:     * etc.  The file type only needs to be set when you want to change the
 957:     * type.  After changing it, the new type stays in effect until you change
 958:     * it again.  The default file type is <code> FTP.ASCII_FILE_TYPE </code>
 959:     * if this method is never called.
 960:     * <p>
 961:     * @param fileType The <code> _FILE_TYPE </code> constant indcating the
 962:     *                 type of file.
 963:     * @return True if successfully completed, false if not.
 964:     * @exception FTPConnectionClosedException
 965:     *      If the FTP server prematurely closes the connection as a result
 966:     *      of the client being idle or some other reason causing the server
 967:     *      to send FTP reply code 421.  This exception may be caught either
 968:     *      as an IOException or independently as itself.
 969:     * @exception IOException  If an I/O error occurs while either sending a
 970:     *      command to the server or receiving a reply from the server.
 971:     ***/
 972:    public boolean setFileType(int fileType) throws IOException
 973:	      {
 974:        if (FTPReply.isPositiveCompletion(type(fileType)))
 975:	          {
 976:            __fileType = fileType;
 977:            __fileFormat = FTP.NON_PRINT_TEXT_FORMAT;
 978:            return true;
 979:        }
 980:        return false;
 981:    }
 982:
 983:
 984:    /***
 985:     * Sets the file type to be transferred and the format.  The type should be
 986:     * one of  <code> FTP.ASCII_FILE_TYPE </code>,
 987:     * <code> FTP.IMAGE_FILE_TYPE </code>, etc.  The file type only needs to
 988:     * be set when you want to change the type.  After changing it, the new
 989:     * type stays in effect until you change it again.  The default file type
 990:     * is <code> FTP.ASCII_FILE_TYPE </code> if this method is never called.
 991:     * The format should be one of the FTP class <code> TEXT_FORMAT </code>
 992:     * constants, or if the type is <code> FTP.LOCAL_FILE_TYPE </code>, the
 993:     * format should be the byte size for that type.  The default format
 994:     * is <code> FTP.NON_PRINT_TEXT_FORMAT </code> if this method is never
 995:     * called.
 996:     * <p>
 997:     * @param fileType The <code> _FILE_TYPE </code> constant indcating the
 998:     *                 type of file.
 999:     * @param formatOrByteSize  The format of the file (one of the
1000:     *              <code>_FORMAT</code> constants.  In the case of
1001:     *              <code>LOCAL_FILE_TYPE</code>, the byte size.
1002:     * <p>
1003:     * @return True if successfully completed, false if not.
1004:     * @exception FTPConnectionClosedException
1005:     *      If the FTP server prematurely closes the connection as a result
1006:     *      of the client being idle or some other reason causing the server
1007:     *      to send FTP reply code 421.  This exception may be caught either
1008:     *      as an IOException or independently as itself.
1009:     * @exception IOException  If an I/O error occurs while either sending a
1010:     *      command to the server or receiving a reply from the server.
1011:     ***/
1012:    public boolean setFileType(int fileType, int formatOrByteSize)
1013:    throws IOException
1014:	      {
1015:        if (FTPReply.isPositiveCompletion(type(fileType, formatOrByteSize)))
1016:	          {
1017:            __fileType = fileType;
1018:            __fileFormat = formatOrByteSize;
1019:            return true;
1020:        }
1021:        return false;
1022:    }
1023:
1024:
1025:    /***
1026:     * Sets the file structure.  The default structure is
1027:     * <code> FTP.FILE_STRUCTURE </code> if this method is never called.
1028:     * <p>
1029:     * @param structure  The structure of the file (one of the FTP class
1030:     *         <code>_STRUCTURE</code> constants).
1031:     * @return True if successfully completed, false if not.
1032:     * @exception FTPConnectionClosedException
1033:     *      If the FTP server prematurely closes the connection as a result
1034:     *      of the client being idle or some other reason causing the server
1035:     *      to send FTP reply code 421.  This exception may be caught either
1036:     *      as an IOException or independently as itself.
1037:     * @exception IOException  If an I/O error occurs while either sending a
1038:     *      command to the server or receiving a reply from the server.
1039:     ***/
1040:    public boolean setFileStructure(int structure) throws IOException
1041:	      {
1042:        if (FTPReply.isPositiveCompletion(stru(structure)))
1043:	          {
1044:            __fileStructure = structure;
1045:            return true;
1046:        }
1047:        return false;
1048:    }
1049:
1050:
1051:    /***
1052:     * Sets the transfer mode.  The default transfer mode
1053:     * <code> FTP.STREAM_TRANSFER_MODE </code> if this method is never called.
1054:     * <p>
1055:     * @param mode  The new transfer mode to use (one of the FTP class
1056:     *         <code>_TRANSFER_MODE</code> constants).
1057:     * @return True if successfully completed, false if not.
1058:     * @exception FTPConnectionClosedException
1059:     *      If the FTP server prematurely closes the connection as a result
1060:     *      of the client being idle or some other reason causing the server
1061:     *      to send FTP reply code 421.  This exception may be caught either
1062:     *      as an IOException or independently as itself.
1063:     * @exception IOException  If an I/O error occurs while either sending a
1064:     *      command to the server or receiving a reply from the server.
1065:     ***/
1066:    public boolean setFileTransferMode(int mode) throws IOException
1067:	      {
1068:        if (FTPReply.isPositiveCompletion(mode(mode)))
1069:	          {
1070:            __fileTransferMode = mode;
1071:            return true;
1072:        }
1073:        return false;
1074:    }
1075:
1076:
1077:    /***
1078:     * Initiate a server to server file transfer.  This method tells the
1079:     * server to which the client is connected to retrieve a given file from
1080:     * the other server.
1081:     * <p>
1082:     * @param filename  The name of the file to retrieve.
1083:     * @return True if successfully completed, false if not.
1084:     * @exception FTPConnectionClosedException
1085:     *      If the FTP server prematurely closes the connection as a result
1086:     *      of the client being idle or some other reason causing the server
1087:     *      to send FTP reply code 421.  This exception may be caught either
1088:     *      as an IOException or independently as itself.
1089:     * @exception IOException  If an I/O error occurs while either sending a
1090:     *      command to the server or receiving a reply from the server.
1091:     ***/
1092:    public boolean remoteRetrieve(String filename) throws IOException
1093:	      {
1094:        if (__dataConnectionMode == ACTIVE_REMOTE_DATA_CONNECTION_MODE ||
1095:                __dataConnectionMode == PASSIVE_REMOTE_DATA_CONNECTION_MODE)
1096:            return FTPReply.isPositivePreliminary(retr(filename));
1097:        return false;
1098:    }
1099:
1100:
1101:    /***
1102:     * Initiate a server to server file transfer.  This method tells the
1103:     * server to which the client is connected to store a file on
1104:     * the other server using the given filename.  The other server must
1105:     * have had a <code> remoteRetrieve </code> issued to it by another
1106:     * FTPClient.
1107:     * <p>
1108:     * @param filename  The name to call the file that is to be stored.
1109:     * @return True if successfully completed, false if not.
1110:     * @exception FTPConnectionClosedException
1111:     *      If the FTP server prematurely closes the connection as a result
1112:     *      of the client being idle or some other reason causing the server
1113:     *      to send FTP reply code 421.  This exception may be caught either
1114:     *      as an IOException or independently as itself.
1115:     * @exception IOException  If an I/O error occurs while either sending a
1116:     *      command to the server or receiving a reply from the server.
1117:     ***/
1118:    public boolean remoteStore(String filename) throws IOException
1119:	      {
1120:        if (__dataConnectionMode == ACTIVE_REMOTE_DATA_CONNECTION_MODE ||
1121:                __dataConnectionMode == PASSIVE_REMOTE_DATA_CONNECTION_MODE)
1122:            return FTPReply.isPositivePreliminary(stor(filename));
1123:        return false;
1124:    }
1125:
1126:
1127:    /***
1128:     * Initiate a server to server file transfer.  This method tells the
1129:     * server to which the client is connected to store a file on
1130:     * the other server using a unique filename based on the given filename.
1131:     * The other server must have had a <code> remoteRetrieve </code> issued
1132:     * to it by another FTPClient.
1133:     * <p>
1134:     * @param filename  The name on which to base the filename of the file
1135:     *                  that is to be stored.
1136:     * @return True if successfully completed, false if not.
1137:     * @exception FTPConnectionClosedException
1138:     *      If the FTP server prematurely closes the connection as a result
1139:     *      of the client being idle or some other reason causing the server
1140:     *      to send FTP reply code 421.  This exception may be caught either
1141:     *      as an IOException or independently as itself.
1142:     * @exception IOException  If an I/O error occurs while either sending a
1143:     *      command to the server or receiving a reply from the server.
1144:     ***/
1145:    public boolean remoteStoreUnique(String filename) throws IOException
1146:	      {
1147:        if (__dataConnectionMode == ACTIVE_REMOTE_DATA_CONNECTION_MODE ||
1148:                __dataConnectionMode == PASSIVE_REMOTE_DATA_CONNECTION_MODE)
1149:            return FTPReply.isPositivePreliminary(stou(filename));
1150:        return false;
1151:    }
1152:
1153:
1154:    /***
1155:     * Initiate a server to server file transfer.  This method tells the
1156:     * server to which the client is connected to store a file on
1157:     * the other server using a unique filename.
1158:     * The other server must have had a <code> remoteRetrieve </code> issued
1159:     * to it by another FTPClient.  Many FTP servers require that a base
1160:     * filename be given from which the unique filename can be derived.  For
1161:     * those servers use the other version of <code> remoteStoreUnique</code>
1162:     * <p>
1163:     * @return True if successfully completed, false if not.
1164:     * @exception FTPConnectionClosedException
1165:     *      If the FTP server prematurely closes the connection as a result
1166:     *      of the client being idle or some other reason causing the server
1167:     *      to send FTP reply code 421.  This exception may be caught either
1168:     *      as an IOException or independently as itself.
1169:     * @exception IOException  If an I/O error occurs while either sending a
1170:     *      command to the server or receiving a reply from the server.
1171:     ***/
1172:    public boolean remoteStoreUnique() throws IOException
1173:	      {
1174:        if (__dataConnectionMode == ACTIVE_REMOTE_DATA_CONNECTION_MODE ||
1175:                __dataConnectionMode == PASSIVE_REMOTE_DATA_CONNECTION_MODE)
1176:            return FTPReply.isPositivePreliminary(stou());
1177:        return false;
1178:    }
1179:
1180:    // For server to server transfers
1181:    /***
1182:     * Initiate a server to server file transfer.  This method tells the
1183:     * server to which the client is connected to append to a given file on
1184:     * the other server.  The other server must have had a
1185:     * <code> remoteRetrieve </code> issued to it by another FTPClient.
1186:     * <p>
1187:     * @param filename  The name of the file to be appended to, or if the
1188:     *        file does not exist, the name to call the file being stored.
1189:     * <p>
1190:     * @return True if successfully completed, false if not.
1191:     * @exception FTPConnectionClosedException
1192:     *      If the FTP server prematurely closes the connection as a result
1193:     *      of the client being idle or some other reason causing the server
1194:     *      to send FTP reply code 421.  This exception may be caught either
1195:     *      as an IOException or independently as itself.
1196:     * @exception IOException  If an I/O error occurs while either sending a
1197:     *      command to the server or receiving a reply from the server.
1198:     ***/
1199:    public boolean remoteAppend(String filename) throws IOException
1200:	      {
1201:        if (__dataConnectionMode == ACTIVE_REMOTE_DATA_CONNECTION_MODE ||
1202:                __dataConnectionMode == PASSIVE_REMOTE_DATA_CONNECTION_MODE)
1203:            return FTPReply.isPositivePreliminary(stor(filename));
1204:        return false;
1205:    }
1206:
1207:    /***
1208:     * There are a few FTPClient methods that do not complete the
1209:     * entire sequence of FTP commands to complete a transaction.  These
1210:     * commands require some action by the programmer after the reception
1211:     * of a positive intermediate command.  After the programmer's code
1212:     * completes its actions, it must call this method to receive
1213:     * the completion reply from the server and verify the success of the
1214:     * entire transaction.
1215:     * <p>
1216:     * For example,
1217:     * <pre>
1218:     * InputStream input;
1219:     * OutputStream output;
1220:     * input  = new FileInputStream("foobaz.txt");
1221:     * output = ftp.storeFileStream("foobar.txt")
1222:	       * if(!FTPReply.isPositiveIntermediate(ftp.getReplyCode())) {
1223:     *     input.close();
1224:     *     output.close();
1225:     *     ftp.logout();
1226:     *     ftp.disconnect();
1227:     *     System.err.println("File transfer failed.");
1228:     *     System.exit(1);
1229:     * }
1230:     * Util.copyStream(input, output);
1231:     * input.close();
1232:     * output.close();
1233:     * // Must call completePendingCommand() to finish command.
1234:	       * if(!ftp.completePendingCommand()) {
1235:     *     ftp.logout();
1236:     *     ftp.disconnect();
1237:     *     System.err.println("File transfer failed.");
1238:     *     System.exit(1);
1239:     * }
1240:     * </pre>
1241:     * <p>
1242:     * @return True if successfully completed, false if not.
1243:     * @exception FTPConnectionClosedException
1244:     *      If the FTP server prematurely closes the connection as a result
1245:     *      of the client being idle or some other reason causing the server
1246:     *      to send FTP reply code 421.  This exception may be caught either
1247:     *      as an IOException or independently as itself.
1248:     * @exception IOException  If an I/O error occurs while either sending a
1249:     *      command to the server or receiving a reply from the server.
1250:     ***/
1251:    public boolean completePendingCommand() throws IOException
1252:	      {
1253:        return FTPReply.isPositiveCompletion(getReply());
1254:    }
1255:
1256:
1257:    /***
1258:     * Retrieves a named file from the server and writes it to the given
1259:     * OutputStream.  This method does NOT close the given OutputStream.
1260:     * If the current file type is ASCII, line separators in the file are
1261:     * converted to the local representation.
1262:     * <p>
1263:     * @param remote  The name of the remote file.
1264:     * @param local   The local OutputStream to which to write the file.
1265:     * @return True if successfully completed, false if not.
1266:     * @exception FTPConnectionClosedException
1267:     *      If the FTP server prematurely closes the connection as a result
1268:     *      of the client being idle or some other reason causing the server
1269:     *      to send FTP reply code 421.  This exception may be caught either
1270:     *      as an IOException or independently as itself.
1271:     * @exception CopyStreamException  If an I/O error occurs while actually
1272:     *      transferring the file.  The CopyStreamException allows you to
1273:     *      determine the number of bytes transferred and the IOException
1274:     *      causing the error.  This exception may be caught either
1275:     *      as an IOException or independently as itself.
1276:     * @exception IOException  If an I/O error occurs while either sending a
1277:     *      command to the server or receiving a reply from the server.
1278:     ***/
1279:    public boolean retrieveFile(String remote, OutputStream local)
1280:    throws IOException
1281:	      {
1282:        InputStream input;
1283:        Socket socket;
1284:
1285:        if ((socket = _openDataConnection_(FTPCommand.RETR, remote)) == null)
1286:            return false;
1287:
1288:        input = new BufferedInputStream(socket.getInputStream(),
1289:                                        getBufferSize());
1290:        if (__fileType == ASCII_FILE_TYPE)
1291:          input = new FromNetASCIIInputStream(input);
1292:        // Treat everything else as binary for now
1293:        try
1294:	          {
1295:            Util.copyStream(input, local, getBufferSize(),
1296:                            CopyStreamEvent.UNKNOWN_STREAM_SIZE, null,
1297:                            false);
1298:        }
1299:        catch (IOException e)
1300:	          {
1301:            try
1302:	              {
1303:                socket.close();
1304:            }
1305:            catch (IOException f)
1306:            {}
1307:            throw e;
1308:        }
1309:        socket.close();
1310:        return completePendingCommand();
1311:    }
1312:
1313:    /***
1314:     * Returns an InputStream from which a named file from the server
1315:     * can be read.  If the current file type is ASCII, the returned
1316:     * InputStream will convert line separators in the file to
1317:     * the local representation.  You must close the InputStream when you
1318:     * finish reading from it.  The InputStream itself will take care of
1319:     * closing the parent data connection socket upon being closed.  To
1320:     * finalize the file transfer you must call
1321:     * {@link #completePendingCommand  completePendingCommand } and
1322:     * check its return value to verify success.
1323:     * <p>
1324:     * @param remote  The name of the remote file.
1325:     * @return An InputStream from which the remote file can be read.  If
1326:     *      the data connection cannot be opened (e.g., the file does not
1327:     *      exist), null is returned (in which case you may check the reply
1328:     *      code to determine the exact reason for failure).
1329:     * @exception FTPConnectionClosedException
1330:     *      If the FTP server prematurely closes the connection as a result
1331:     *      of the client being idle or some other reason causing the server
1332:     *      to send FTP reply code 421.  This exception may be caught either
1333:     *      as an IOException or independently as itself.
1334:     * @exception IOException  If an I/O error occurs while either sending a
1335:     *      command to the server or receiving a reply from the server.
1336:     ***/
1337:    public InputStream retrieveFileStream(String remote) throws IOException
1338:	      {
1339:        InputStream input;
1340:        Socket socket;
1341:
1342:        if ((socket = _openDataConnection_(FTPCommand.RETR, remote)) == null)
1343:            return null;
1344:
1345:        input = socket.getInputStream();
1346:	          if (__fileType == ASCII_FILE_TYPE) {
1347:          // We buffer ascii transfers because the buffering has to
1348:          // be interposed between FromNetASCIIOutputSream and the underlying
1349:          // socket input stream.  We don't buffer binary transfers
1350:          // because we don't want to impose a buffering policy on the
1351:          // programmer if possible.  Programmers can decide on their
1352:          // own if they want to wrap the SocketInputStream we return
1353:          // for file types other than ASCII.
1354:          input = new BufferedInputStream(input,
1355:                                          getBufferSize());
1356:          input = new FromNetASCIIInputStream(input);
1357:        }
1358:        return new org.apache.commons.net.io.SocketInputStream(socket, input);
1359:    }
1360:
1361:
1362:    /***
1363:     * Stores a file on the server using the given name and taking input
1364:     * from the given InputStream.  This method does NOT close the given
1365:     * InputStream.  If the current file type is ASCII, line separators in
1366:     * the file are transparently converted to the NETASCII format (i.e.,
1367:     * you should not attempt to create a special InputStream to do this).
1368:     * <p>
1369:     * @param remote  The name to give the remote file.
1370:     * @param local   The local InputStream from which to read the file.
1371:     * @return True if successfully completed, false if not.
1372:     * @exception FTPConnectionClosedException
1373:     *      If the FTP server prematurely closes the connection as a result
1374:     *      of the client being idle or some other reason causing the server
1375:     *      to send FTP reply code 421.  This exception may be caught either
1376:     *      as an IOException or independently as itself.
1377:     * @exception CopyStreamException  If an I/O error occurs while actually
1378:     *      transferring the file.  The CopyStreamException allows you to
1379:     *      determine the number of bytes transferred and the IOException
1380:     *      causing the error.  This exception may be caught either
1381:     *      as an IOException or independently as itself.
1382:     * @exception IOException  If an I/O error occurs while either sending a
1383:     *      command to the server or receiving a reply from the server.
1384:     ***/
1385:    public boolean storeFile(String remote, InputStream local)
1386:    throws IOException
1387:	      {
1388:        return __storeFile(FTPCommand.STOR, remote, local);
1389:    }
1390:
1391:
1392:    /***
1393:     * Returns an OutputStream through which data can be written to store
1394:     * a file on the server using the given name.  If the current file type
1395:     * is ASCII, the returned OutputStream will convert line separators in
1396:     * the file to the NETASCII format  (i.e., you should not attempt to
1397:     * create a special OutputStream to do this).  You must close the
1398:     * OutputStream when you finish writing to it.  The OutputStream itself
1399:     * will take care of closing the parent data connection socket upon being
1400:     * closed.  To finalize the file transfer you must call
1401:     * {@link #completePendingCommand  completePendingCommand } and
1402:     * check its return value to verify success.
1403:     * <p>
1404:     * @param remote  The name to give the remote file.
1405:     * @return An OutputStream through which the remote file can be written.  If
1406:     *      the data connection cannot be opened (e.g., the file does not
1407:     *      exist), null is returned (in which case you may check the reply
1408:     *      code to determine the exact reason for failure).
1409:     * @exception FTPConnectionClosedException
1410:     *      If the FTP server prematurely closes the connection as a result
1411:     *      of the client being idle or some other reason causing the server
1412:     *      to send FTP reply code 421.  This exception may be caught either
1413:     *      as an IOException or independently as itself.
1414:     * @exception IOException  If an I/O error occurs while either sending a
1415:     *      command to the server or receiving a reply from the server.
1416:     ***/
1417:    public OutputStream storeFileStream(String remote) throws IOException
1418:	      {
1419:        return __storeFileStream(FTPCommand.STOR, remote);
1420:    }
1421:
1422:    /***
1423:     * Appends to a file on the server with the given name, taking input
1424:     * from the given InputStream.  This method does NOT close the given
1425:     * InputStream.  If the current file type is ASCII, line separators in
1426:     * the file are transparently converted to the NETASCII format (i.e.,
1427:     * you should not attempt to create a special InputStream to do this).
1428:     * <p>
1429:     * @param remote  The name of the remote file.
1430:     * @param local   The local InputStream from which to read the data to
1431:     *                be appended to the remote file.
1432:     * @return True if successfully completed, false if not.
1433:     * @exception FTPConnectionClosedException
1434:     *      If the FTP server prematurely closes the connection as a result
1435:     *      of the client being idle or some other reason causing the server
1436:     *      to send FTP reply code 421.  This exception may be caught either
1437:     *      as an IOException or independently as itself.
1438:     * @exception CopyStreamException  If an I/O error occurs while actually
1439:     *      transferring the file.  The CopyStreamException allows you to
1440:     *      determine the number of bytes transferred and the IOException
1441:     *      causing the error.  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 a
1444:     *      command to the server or receiving a reply from the server.
1445:     ***/
1446:    public boolean appendFile(String remote, InputStream local)
1447:    throws IOException
1448:	      {
1449:        return __storeFile(FTPCommand.APPE, remote, local);
1450:    }
1451:
1452:    /***
1453:     * Returns an OutputStream through which data can be written to append
1454:     * to a file on the server with the given name.  If the current file type
1455:     * is ASCII, the returned OutputStream will convert line separators in
1456:     * the file to the NETASCII format  (i.e., you should not attempt to
1457:     * create a special OutputStream to do this).  You must close the
1458:     * OutputStream when you finish writing to it.  The OutputStream itself
1459:     * will take care of closing the parent data connection socket upon being
1460:     * closed.  To finalize the file transfer you must call
1461:     * {@link #completePendingCommand  completePendingCommand } and
1462:     * check its return value to verify success.
1463:     * <p>
1464:     * @param remote  The name of the remote file.
1465:     * @return An OutputStream through which the remote file can be appended.
1466:     *      If the data connection cannot be opened (e.g., the file does not
1467:     *      exist), null is returned (in which case you may check the reply
1468:     *      code to determine the exact reason for failure).
1469:     * @exception FTPConnectionClosedException
1470:     *      If the FTP server prematurely closes the connection as a result
1471:     *      of the client being idle or some other reason causing the server
1472:     *      to send FTP reply code 421.  This exception may be caught either
1473:     *      as an IOException or independently as itself.
1474:     * @exception IOException  If an I/O error occurs while either sending a
1475:     *      command to the server or receiving a reply from the server.
1476:     ***/
1477:    public OutputStream appendFileStream(String remote) throws IOException
1478:	      {
1479:        return __storeFileStream(FTPCommand.APPE, remote);
1480:    }
1481:
1482:    /***
1483:     * Stores a file on the server using a unique name derived from the
1484:     * given name and taking input
1485:     * from the given InputStream.  This method does NOT close the given
1486:     * InputStream.  If the current file type is ASCII, line separators in
1487:     * the file are transparently converted to the NETASCII format (i.e.,
1488:     * you should not attempt to create a special InputStream to do this).
1489:     * <p>
1490:     * @param remote  The name on which to base the unique name given to
1491:     *                the remote file.
1492:     * @param local   The local InputStream from which to read the file.
1493:     * @return True if successfully completed, false if not.
1494:     * @exception FTPConnectionClosedException
1495:     *      If the FTP server prematurely closes the connection as a result
1496:     *      of the client being idle or some other reason causing the server
1497:     *      to send FTP reply code 421.  This exception may be caught either
1498:     *      as an IOException or independently as itself.
1499:     * @exception CopyStreamException  If an I/O error occurs while actually
1500:     *      transferring the file.  The CopyStreamException allows you to
1501:     *      determine the number of bytes transferred and the IOException
1502:     *      causing the error.  This exception may be caught either
1503:     *      as an IOException or independently as itself.
1504:     * @exception IOException  If an I/O error occurs while either sending a
1505:     *      command to the server or receiving a reply from the server.
1506:     ***/
1507:    public boolean storeUniqueFile(String remote, InputStream local)
1508:    throws IOException
1509:	      {
1510:        return __storeFile(FTPCommand.STOU, remote, local);
1511:    }
1512:
1513:
1514:    /***
1515:     * Returns an OutputStream through which data can be written to store
1516:     * a file on the server using a unique name derived from the given name.
1517:     * If the current file type
1518:     * is ASCII, the returned OutputStream will convert line separators in
1519:     * the file to the NETASCII format  (i.e., you should not attempt to
1520:     * create a special OutputStream to do this).  You must close the
1521:     * OutputStream when you finish writing to it.  The OutputStream itself
1522:     * will take care of closing the parent data connection socket upon being
1523:     * closed.  To finalize the file transfer you must call
1524:     * {@link #completePendingCommand  completePendingCommand } and
1525:     * check its return value to verify success.
1526:     * <p>
1527:     * @param remote  The name on which to base the unique name given to
1528:     *                the remote file.
1529:     * @return An OutputStream through which the remote file can be written.  If
1530:     *      the data connection cannot be opened (e.g., the file does not
1531:     *      exist), null is returned (in which case you may check the reply
1532:     *      code to determine the exact reason for failure).
1533:     * @exception FTPConnectionClosedException
1534:     *      If the FTP server prematurely closes the connection as a result
1535:     *      of the client being idle or some other reason causing the server
1536:     *      to send FTP reply code 421.  This exception may be caught either
1537:     *      as an IOException or independently as itself.
1538:     * @exception IOException  If an I/O error occurs while either sending a
1539:     *      command to the server or receiving a reply from the server.
1540:     ***/
1541:    public OutputStream storeUniqueFileStream(String remote) throws IOException
1542:	      {
1543:        return __storeFileStream(FTPCommand.STOU, remote);
1544:    }
1545:
1546:    /**
1547:     * Stores a file on the server using a unique name assigned by the
1548:     * server and taking input from the given InputStream.  This method does
1549:     * NOT close the given
1550:     * InputStream.  If the current file type is ASCII, line separators in
1551:     * the file are transparently converted to the NETASCII format (i.e.,
1552:     * you should not attempt to create a special InputStream to do this).
1553:     * <p>
1554:     * @param local   The local InputStream from which to read the file.
1555:     * @return True if successfully completed, false if not.
1556:     * @exception FTPConnectionClosedException
1557:     *      If the FTP server prematurely closes the connection as a result
1558:     *      of the client being idle or some other reason causing the server
1559:     *      to send FTP reply code 421.  This exception may be caught either
1560:     *      as an IOException or independently as itself.
1561:     * @exception CopyStreamException  If an I/O error occurs while actually
1562:     *      transferring the file.  The CopyStreamException allows you to
1563:     *      determine the number of bytes transferred and the IOException
1564:     *      causing the error.  This exception may be caught either
1565:     *      as an IOException or independently as itself.
1566:     * @exception IOException  If an I/O error occurs while either sending a
1567:     *      command to the server or receiving a reply from the server.
1568:     */
1569:    public boolean storeUniqueFile(InputStream local) throws IOException
1570:	      {
1571:        return __storeFile(FTPCommand.STOU, null, local);
1572:    }
1573:
1574:    /**
1575:     * Returns an OutputStream through which data can be written to store
1576:     * a file on the server using a unique name assigned by the server.
1577:     * If the current file type
1578:     * is ASCII, the returned OutputStream will convert line separators in
1579:     * the file to the NETASCII format  (i.e., you should not attempt to
1580:     * create a special OutputStream to do this).  You must close the
1581:     * OutputStream when you finish writing to it.  The OutputStream itself
1582:     * will take care of closing the parent data connection socket upon being
1583:     * closed.  To finalize the file transfer you must call
1584:     * {@link #completePendingCommand  completePendingCommand } and
1585:     * check its return value to verify success.
1586:     * <p>
1587:     * @return An OutputStream through which the remote file can be written.  If
1588:     *      the data connection cannot be opened (e.g., the file does not
1589:     *      exist), null is returned (in which case you may check the reply
1590:     *      code to determine the exact reason for failure).
1591:     * @exception FTPConnectionClosedException
1592:     *      If the FTP server prematurely closes the connection as a result
1593:     *      of the client being idle or some other reason causing the server
1594:     *      to send FTP reply code 421.  This exception may be caught either
1595:     *      as an IOException or independently as itself.
1596:     * @exception IOException  If an I/O error occurs while either sending a
1597:     *      command to the server or receiving a reply from the server.
1598:     */
1599:    public OutputStream storeUniqueFileStream() throws IOException
1600:	      {
1601:        return __storeFileStream(FTPCommand.STOU, null);
1602:    }
1603:
1604:    /***
1605:     * Reserve a number of bytes on the server for the next file transfer.
1606:     * <p>
1607:     * @param bytes  The number of bytes which the server should allocate.
1608:     * @return True if successfully completed, false if not.
1609:     * @exception FTPConnectionClosedException
1610:     *      If the FTP server prematurely closes the connection as a result
1611:     *      of the client being idle or some other reason causing the server
1612:     *      to send FTP reply code 421.  This exception may be caught either
1613:     *      as an IOException or independently as itself.
1614:     * @exception IOException  If an I/O error occurs while either sending a
1615:     *      command to the server or receiving a reply from the server.
1616:     ***/
1617:    public boolean allocate(int bytes) throws IOException
1618:	      {
1619:        return FTPReply.isPositiveCompletion(allo(bytes));
1620:    }
1621:
1622:
1623:    /**
1624:     * Reserve space on the server for the next file transfer.
1625:     * <p>
1626:     * @param bytes  The number of bytes which the server should allocate.
1627:     * @param recordSize  The size of a file record.
1628:     * @return True if successfully completed, false if not.
1629:     * @exception FTPConnectionClosedException
1630:     *      If the FTP server prematurely closes the connection as a result
1631:     *      of the client being idle or some other reason causing the server
1632:     *      to send FTP reply code 421.  This exception may be caught either
1633:     *      as an IOException or independently as itself.
1634:     * @exception IOException  If an I/O error occurs while either sending a
1635:     *      command to the server or receiving a reply from the server.
1636:     */
1637:    public boolean allocate(int bytes, int recordSize) throws IOException
1638:	      {
1639:        return FTPReply.isPositiveCompletion(allo(bytes, recordSize));
1640:    }
1641:
1642:
1643:    /***
1644:     * Restart a <code>STREAM_TRANSFER_MODE</code> file transfer starting
1645:     * from the given offset.  This will only work on FTP servers supporting
1646:     * the REST comand for the stream transfer mode.  However, most FTP
1647:     * servers support this.  Any subsequent file transfer will start
1648:     * reading or writing the remote file from the indicated offset.
1649:     * <p>
1650:     * @param offset  The offset into the remote file at which to start the
1651:     *           next file transfer.
1652:     * @return True if successfully completed, false if not.
1653:     * @exception FTPConnectionClosedException
1654:     *      If the FTP server prematurely closes the connection as a result
1655:     *      of the client being idle or some other reason causing the server
1656:     *      to send FTP reply code 421.  This exception may be caught either
1657:     *      as an IOException or independently as itself.
1658:     * @exception IOException  If an I/O error occurs while either sending a
1659:     *      command to the server or receiving a reply from the server.
1660:     ***/
1661:    private boolean restart(long offset) throws IOException
1662:	      {
1663:        __restartOffset = 0;
1664:        return FTPReply.isPositiveIntermediate(rest(Long.toString(offset)));
1665:    }
1666:
1667:    /***
1668:     * Sets the restart offset.  The restart command is sent to the server
1669:     * only before sending the file transfer command.  When this is done,
1670:     * the restart marker is reset to zero.
1671:     * <p>
1672:     * @param offset  The offset into the remote file at which to start the
1673:     *           next file transfer.  This must be a value greater than or
1674:     *           equal to zero.
1675:     ***/
1676:    public void setRestartOffset(long offset)
1677:	      {
1678:        if (offset >= 0)
1679:            __restartOffset = offset;
1680:    }
1681:
1682:    /***
1683:     * Fetches the restart offset.
1684:     * <p>
1685:     * @return offset  The offset into the remote file at which to start the
1686:     *           next file transfer.
1687:     ***/
1688:    public long getRestartOffset()
1689:	      {
1690:        return __restartOffset;
1691:    }
1692:
1693:
1694:
1695:    /***
1696:     * Renames a remote file.
1697:     * <p>
1698:     * @param from  The name of the remote file to rename.
1699:     * @param to    The new name of the remote file.
1700:     * @return True if successfully completed, false if not.
1701:     * @exception FTPConnectionClosedException
1702:     *      If the FTP server prematurely closes the connection as a result
1703:     *      of the client being idle or some other reason causing the server
1704:     *      to send FTP reply code 421.  This exception may be caught either
1705:     *      as an IOException or independently as itself.
1706:     * @exception IOException  If an I/O error occurs while either sending a
1707:     *      command to the server or receiving a reply from the server.
1708:     ***/
1709:    public boolean rename(String from, String to) throws IOException
1710:	      {
1711:        if (!FTPReply.isPositiveIntermediate(rnfr(from)))
1712:            return false;
1713:
1714:        return FTPReply.isPositiveCompletion(rnto(to));
1715:    }
1716:
1717:
1718:    /***
1719:     * Abort a transfer in progress.
1720:     * <p>
1721:     * @return True if successfully completed, false if not.
1722:     * @exception FTPConnectionClosedException
1723:     *      If the FTP server prematurely closes the connection as a result
1724:     *      of the client being idle or some other reason causing the server
1725:     *      to send FTP reply code 421.  This exception may be caught either
1726:     *      as an IOException or independently as itself.
1727:     * @exception IOException  If an I/O error occurs while either sending a
1728:     *      command to the server or receiving a reply from the server.
1729:     ***/
1730:    public boolean abort() throws IOException
1731:	      {
1732:        return FTPReply.isPositiveCompletion(abor());
1733:    }
1734:
1735:    /***
1736:     * Deletes a file on the FTP server.
1737:     * <p>
1738:     * @param pathname   The pathname of the file to be deleted.
1739:     * @return True if successfully completed, false if not.
1740:     * @exception FTPConnectionClosedException
1741:     *      If the FTP server prematurely closes the connection as a result
1742:     *      of the client being idle or some other reason causing the server
1743:     *      to send FTP reply code 421.  This exception may be caught either
1744:     *      as an IOException or independently as itself.
1745:     * @exception IOException  If an I/O error occurs while either sending a
1746:     *      command to the server or receiving a reply from the server.
1747:     ***/
1748:    public boolean deleteFile(String pathname) throws IOException
1749:	      {
1750:        return FTPReply.isPositiveCompletion(dele(pathname));
1751:    }
1752:
1753:
1754:    /***
1755:     * Removes a directory on the FTP server (if empty).
1756:     * <p>
1757:     * @param pathname  The pathname of the directory to remove.
1758:     * @return True if successfully completed, false if not.
1759:     * @exception FTPConnectionClosedException
1760:     *      If the FTP server prematurely closes the connection as a result
1761:     *      of the client being idle or some other reason causing the server
1762:     *      to send FTP reply code 421.  This exception may be caught either
1763:     *      as an IOException or independently as itself.
1764:     * @exception IOException  If an I/O error occurs while either sending a
1765:     *      command to the server or receiving a reply from the server.
1766:     ***/
1767:    public boolean removeDirectory(String pathname) throws IOException
1768:	      {
1769:        return FTPReply.isPositiveCompletion(rmd(pathname));
1770:    }
1771:
1772:
1773:    /***
1774:     * Creates a new subdirectory on the FTP server in the current directory
1775:     * (if a relative pathname is given) or where specified (if an absolute
1776:     * pathname is given).
1777:     * <p>
1778:     * @param pathname The pathname of the directory to create.
1779:     * @return True if successfully completed, false if not.
1780:     * @exception FTPConnectionClosedException
1781:     *      If the FTP server prematurely closes the connection as a result
1782:     *      of the client being idle or some other reason causing the server
1783:     *      to send FTP reply code 421.  This exception may be caught either
1784:     *      as an IOException or independently as itself.
1785:     * @exception IOException  If an I/O error occurs while either sending a
1786:     *      command to the server or receiving a reply from the server.
1787:     ***/
1788:    public boolean makeDirectory(String pathname) throws IOException
1789:	      {
1790:        return FTPReply.isPositiveCompletion(mkd(pathname));
1791:    }
1792:
1793:
1794:    /***
1795:     * Returns the pathname of the current working directory.
1796:     * <p>
1797:     * @return The pathname of the current working directory.  If it cannot
1798:     *         be obtained, returns null.
1799:     * @exception FTPConnectionClosedException
1800:     *      If the FTP server prematurely closes the connection as a result
1801:     *      of the client being idle or some other reason causing the server
1802:     *      to send FTP reply code 421.  This exception may be caught either
1803:     *      as an IOException or independently as itself.
1804:     * @exception IOException  If an I/O error occurs while either sending a
1805:     *      command to the server or receiving a reply from the server.
1806:     ***/
1807:    public String printWorkingDirectory() throws IOException
1808:	      {
1809:        if (pwd() != FTPReply.PATHNAME_CREATED)
1810:            return null;
1811:
1812:        return __parsePathname((String)_replyLines.elementAt(0));
1813:    }
1814:
1815:
1816:    /**
1817:     * Send a site specific command.
1818:     * @param arguments The site specific command and arguments.
1819:     * @return True if successfully completed, false if not.
1820:     * @exception FTPConnectionClosedException
1821:     *      If the FTP server prematurely closes the connection as a result
1822:     *      of the client being idle or some other reason causing the server
1823:     *      to send FTP reply code 421.  This exception may be caught either
1824:     *      as an IOException or independently as itself.
1825:     * @exception IOException  If an I/O error occurs while either sending a
1826:     *      command to the server or receiving a reply from the server.
1827:     */
1828:    public boolean sendSiteCommand(String arguments) throws IOException
1829:	      {
1830:        return FTPReply.isPositiveCompletion(site(arguments));
1831:    }
1832:
1833:
1834:    /***
1835:     * Fetches the system type name from the server and returns the string.
1836:     * This value is cached for the duration of the connection after the
1837:     * first call to this method.  In other words, only the first time
1838:     * that you invoke this method will it issue a SYST command to the
1839:     * FTP server.  FTPClient will remember the value and return the
1840:     * cached value until a call to disconnect.
1841:     * <p>
1842:     * @return The system type name obtained from the server.  null if the
1843:     *       information could not be obtained.
1844:     * @exception FTPConnectionClosedException
1845:     *      If the FTP server prematurely closes the connection as a result
1846:     *      of the client being idle or some other reason causing the server
1847:     *      to send FTP reply code 421.  This exception may be caught either
1848:     *      as an IOException or independently as itself.
1849:     * @exception IOException  If an I/O error occurs while either sending a
1850:     *  command to the server or receiving a reply from the server.
1851:     ***/
1852:    public String getSystemName() throws IOException
1853:	      {
1854:      //if (syst() == FTPReply.NAME_SYSTEM_TYPE)
1855:      // Technically, we should expect a NAME_SYSTEM_TYPE response, but
1856:      // in practice FTP servers deviate, so we soften the condition to
1857:      // a positive completion.
1858:        if (__systemName == null && FTPReply.isPositiveCompletion(syst()))
1859:            __systemName = ((String)_replyLines.elementAt(0)).substring(4);
1860:
1861:        return __systemName;
1862:    }
1863:
1864:
1865:    /***
1866:     * Fetches the system help information from the server and returns the
1867:     * full string.
1868:     * <p>
1869:     * @return The system help string obtained from the server.  null if the
1870:     *       information could not be obtained.
1871:     * @exception FTPConnectionClosedException
1872:     *      If the FTP server prematurely closes the connection as a result
1873:     *      of the client being idle or some other reason causing the server
1874:     *      to send FTP reply code 421.  This exception may be caught either
1875:     *      as an IOException or independently as itself.
1876:     * @exception IOException  If an I/O error occurs while either sending a
1877:     *  command to the server or receiving a reply from the server.
1878:     ***/
1879:    public String listHelp() throws IOException
1880:	      {
1881:        if (FTPReply.isPositiveCompletion(help()))
1882:            return getReplyString();
1883:        return null;
1884:    }
1885:
1886:
1887:    /**
1888:     * Fetches the help information for a given command from the server and
1889:     * returns the full string.
1890:     * @param command The command on which to ask for help.
1891:     * @return The command help string obtained from the server.  null if the
1892:     *       information could not be obtained.
1893:     * @exception FTPConnectionClosedException
1894:     *      If the FTP server prematurely closes the connection as a result
1895:     *      of the client being idle or some other reason causing the server
1896:     *      to send FTP reply code 421.  This exception may be caught either
1897:     *      as an IOException or independently as itself.
1898:     * @exception IOException  If an I/O error occurs while either sending a
1899:     *  command to the server or receiving a reply from the server.
1900:     */
1901:    public String listHelp(String command) throws IOException
1902:	      {
1903:        if (FTPReply.isPositiveCompletion(help(command)))
1904:            return getReplyString();
1905:        return null;
1906:    }
1907:
1908:
1909:    /***
1910:     * Sends a NOOP command to the FTP server.  This is useful for preventing
1911:     * server timeouts.
1912:     * <p>
1913:     * @return True if successfully completed, false if not.
1914:     * @exception FTPConnectionClosedException
1915:     *      If the FTP server prematurely closes the connection as a result
1916:     *      of the client being idle or some other reason causing the server
1917:     *      to send FTP reply code 421.  This exception may be caught either
1918:     *      as an IOException or independently as itself.
1919:     * @exception IOException  If an I/O error occurs while either sending a
1920:     *      command to the server or receiving a reply from the server.
1921:     ***/
1922:    public boolean sendNoOp() throws IOException
1923:	      {
1924:        return FTPReply.isPositiveCompletion(noop());
1925:    }
1926:
1927:
1928:    /***
1929:     * Obtain a list of filenames in a directory (or just the name of a given
1930:     * file, which is not particularly useful).  This information is obtained
1931:     * through the NLST command.  If the given pathname is a directory and
1932:     * contains no files,  a zero length array is returned only
1933:     * if the FTP server returned a positive completion code, otherwise
1934:     * null is returned (the FTP server returned a 550 error No files found.).
1935:     * If the directory is not empty, an array of filenames in the directory is
1936:     * returned. If the pathname corresponds
1937:     * to a file, only that file will be listed.  The server may or may not
1938:     * expand glob expressions.
1939:     * <p>
1940:     * @param pathname  The file or directory to list.
1941:     * @return The list of filenames contained in the given path.  null if
1942:     *     the list could not be obtained.  If there are no filenames in
1943:     *     the directory, a zero-length array is returned.
1944:     * @exception FTPConnectionClosedException
1945:     *      If the FTP server prematurely closes the connection as a result
1946:     *      of the client being idle or some other reason causing the server
1947:     *      to send FTP reply code 421.  This exception may be caught either
1948:     *      as an IOException or independently as itself.
1949:     * @exception IOException  If an I/O error occurs while either sending a
1950:     *      command to the server or receiving a reply from the server.
1951:     ***/
1952:    public String[] listNames(String pathname) throws IOException
1953:	      {
1954:        String line;
1955:        Socket socket;
1956:        BufferedReader reader;
1957:        Vector results;
1958:
1959:        if ((socket = _openDataConnection_(FTPCommand.NLST, pathname)) == null)
1960:            return null;
1961:
1962:        reader =
1963:            new BufferedReader(new InputStreamReader(socket.getInputStream(), getControlEncoding()));
1964:
1965:        results = new Vector();
1966:        while ((line = reader.readLine()) != null)
1967:            results.addElement(line);
1968:        reader.close();
1969:        socket.close();
1970:
1971:        if (completePendingCommand())
1972:	          {
1973:            String[] result;
1974:            result = new String[results.size()];
1975:            results.copyInto(result);
1976:            return result;
1977:        }
1978:
1979:        return null;
1980:    }
1981:
1982:
1983:    /***
1984:     * Obtain a list of filenames in the current working directory
1985:     * This information is obtained through the NLST command.  If the current
1986:     * directory contains no files, a zero length array is returned only
1987:     * if the FTP server returned a positive completion code, otherwise,
1988:     * null is returned (the FTP server returned a 550 error No files found.).
1989:     * If the directory is not empty, an array of filenames in the directory is
1990:     * returned.
1991:     * <p>
1992:     * @return The list of filenames contained in the current working
1993:     *     directory.  null if the list could not be obtained.
1994:     *     If there are no filenames in the directory, a zero-length array
1995:     *     is returned.
1996:     * @exception FTPConnectionClosedException
1997:     *      If the FTP server prematurely closes the connection as a result
1998:     *      of the client being idle or some other reason causing the server
1999:     *      to send FTP reply code 421.  This exception may be caught either
2000:     *      as an IOException or independently as itself.
2001:     * @exception IOException  If an I/O error occurs while either sending a
2002:     *      command to the server or receiving a reply from the server.
2003:     ***/
2004:    public String[] listNames() throws IOException
2005:	      {
2006:        return listNames(null);
2007:    }
2008:
2009:
2010:    /**
2011:     * Using the supplied <code>parserKey</code>, obtain a list
2012:     * of file information for the current working directory or for just a
2013:     * single file.
2014:     * <p>
2015:     * If <code>key</code> is null, this object will try to autodetect
2016:     * the system-type/parser-type by calling the SYST command.
2017:     * <p>
2018:     * Under the DefaultFTPFileEntryParserFactory, which is used unless a
2019:     * different factory has been specified, the key
2020:     * can be either a recognized System type for which a parser has been
2021:     * defined, or the fully qualified class name of a class that implements
2022:     * org.apache.commons.net.ftp.FTPFileEntryParser.
2023:     * <p>
2024:     * This information is obtained through the LIST command.  The contents of
2025:     * the returned array is determined by the<code> FTPFileEntryParser </code>
2026:     * used.
2027:     * <p>
2028:     * @param parserKey This is a "handle" which the parser factory used
2029:     *                  must be able to resolve into a class implementing
2030:     *                  FTPFileEntryParser.
2031:     *                  <p>
2032:     *                  In the DefaultFTPFileEntryParserFactory, this
2033:     *                  may either be a specific key identifying a server type,
2034:     *                  which is used to identify a parser type,
2035:     *                  or the fully qualified class name of the parser.  See
2036:     *                  DefaultFTPFileEntryParserFactory.createFileEntryParser
2037:     *                  for full details.
2038:     *                  <p>
2039:     *                  If this parameter is null, will attempt to generate a key
2040:     *                  by running the SYST command.  This should cause no problem
2041:     *                  with the functionality implemented in the
2042:     *                  DefaultFTPFileEntryParserFactory, but may not map so well
2043:     *                  to an alternative user-created factory.  If that is the
2044:     *                  case, calling this routine with a null parameter and a
2045:     *                  custom parser factory may not be advisable.
2046:     *                  <p>
2047:     * @param pathname  The file or directory to list.  Since the server may
2048:     *                  or may not expand glob expressions, using them here
2049:     *                  is not recommended and may well cause this method to
2050:     *                  fail.
2051:     *
2052:     * @return The list of file information contained in the given path in
2053:     *         the format determined by the parser represented by the
2054:     *         <code> parserKey </code> parameter.
2055:     *         <p><b> 
2056:     *            NOTE:</b> This array may contain null members if any of the 
2057:     *         individual file listings failed to parse.  The caller should 
2058:     *         check each entry for null before referencing it.
2059:     * @exception FTPConnectionClosedException
2060:     *                   If the FTP server prematurely closes the connection
2061:     *                   as a result of the client being idle or some other
2062:     *                   reason causing the server to send FTP reply code 421.
2063:     *                   This exception may be caught either as an IOException
2064:     *                   or independently as itself.
2065:     * @exception IOException
2066:     *                   If an I/O error occurs while either sending a
2067:     *                   command to the server or receiving a reply
2068:     *                   from the server.
2069:     * @exception ParserInitializationException
2070:     *                   Thrown if the parserKey parameter cannot be
2071:     *                   resolved by the selected parser factory.
2072:     *                   In the DefaultFTPEntryParserFactory, this will
2073:     *                   happen when parserKey is neither
2074:     *                   the fully qualified class name of a class
2075:     *                   implementing the interface
2076:     *                   org.apache.commons.net.ftp.FTPFileEntryParser
2077:     *                   nor a string containing one of the recognized keys
2078:     *                   mapping to such a parser or if class loader
2079:     *                   security issues prevent its being loaded.
2080:     * @see org.apache.commons.net.ftp.parser.DefaultFTPFileEntryParserFactory
2081:     * @see org.apache.commons.net.ftp.parser.FTPFileEntryParserFactory
2082:     * @see org.apache.commons.net.ftp.FTPFileEntryParser
2083:     * @deprecated use {@link  #listFiles()  listFiles()} or 
2084:     * {@link  #listFiles(String)  listFiles(String)} instead and specify the
2085:     * parser Key in an {@link  #FTPClientConfig  FTPClientConfig} object instead.
2086:     */
2087:    public FTPFile[] listFiles(String parserKey, String pathname)
2088:    throws IOException
2089:	      {
2090:        FTPListParseEngine engine =
2091:            initiateListParsing(parserKey, pathname);
2092:        return engine.getFiles();
2093:    }
2094:
2095:
2096:    /**
2097:     * Using the default system autodetect mechanism, obtain a
2098:     * list of file information for the current working directory
2099:     * or for just a single file.
2100:     * <p>
2101:     * This information is obtained through the LIST command.  The contents of
2102:     * the returned array is determined by the<code> FTPFileEntryParser </code>
2103:     * used.
2104:     * <p>
2105:     * @param pathname  The file or directory to list.  Since the server may
2106:     *                  or may not expand glob expressions, using them here
2107:     *                  is not recommended and may well cause this method to
2108:     *                  fail.
2109:     *
2110:     * @return The list of file information contained in the given path in
2111:     *         the format determined by the autodetection mechanism
2112:     * @exception FTPConnectionClosedException
2113:     *                   If the FTP server prematurely closes the connection
2114:     *                   as a result of the client being idle or some other
2115:     *                   reason causing the server to send FTP reply code 421.
2116:     *                   This exception may be caught either as an IOException
2117:     *                   or independently as itself.
2118:     * @exception IOException
2119:     *                   If an I/O error occurs while either sending a
2120:     *                   command to the server or receiving a reply
2121:     *                   from the server.
2122:     * @exception ParserInitializationException
2123:     *                   Thrown if the parserKey parameter cannot be
2124:     *                   resolved by the selected parser factory.
2125:     *                   In the DefaultFTPEntryParserFactory, this will
2126:     *                   happen when parserKey is neither
2127:     *                   the fully qualified class name of a class
2128:     *                   implementing the interface
2129:     *                   org.apache.commons.net.ftp.FTPFileEntryParser
2130:     *                   nor a string containing one of the recognized keys
2131:     *                   mapping to such a parser or if class loader
2132:     *                   security issues prevent its being loaded.
2133:     * @see org.apache.commons.net.ftp.parser.DefaultFTPFileEntryParserFactory
2134:     * @see org.apache.commons.net.ftp.parser.FTPFileEntryParserFactory
2135:     * @see org.apache.commons.net.ftp.FTPFileEntryParser
2136:     */
2137:    public FTPFile[] listFiles(String pathname)
2138:    throws IOException
2139:	      {
2140:        String key = null;
2141:        FTPListParseEngine engine =
2142:            initiateListParsing(key, pathname);
2143:        return engine.getFiles();
2144:
2145:    }
2146:    /**
2147:     * Using the default system autodetect mechanism, obtain a
2148:     * list of file information for the current working directory.
2149:     * <p>
2150:     * This information is obtained through the LIST command.  The contents of
2151:     * the returned array is determined by the<code> FTPFileEntryParser </code>
2152:     * used.
2153:     * <p>
2154:     * @return The list of file information contained in the current directory
2155:     *         in the format determined by the autodetection mechanism.  
2156:     *         <p><b> 
2157:     *            NOTE:</b> This array may contain null members if any of the 
2158:     *         individual file listings failed to parse.  The caller should 
2159:     *         check each entry for null before referencing it.
2160:     * @exception FTPConnectionClosedException
2161:     *                   If the FTP server prematurely closes the connection
2162:     *                   as a result of the client being idle or some other
2163:     *                   reason causing the server to send FTP reply code 421.
2164:     *                   This exception may be caught either as an IOException
2165:     *                   or independently as itself.
2166:     * @exception IOException
2167:     *                   If an I/O error occurs while either sending a
2168:     *                   command to the server or receiving a reply
2169:     *                   from the server.
2170:     * @exception ParserInitializationException
2171:     *                   Thrown if the parserKey parameter cannot be
2172:     *                   resolved by the selected parser factory.
2173:     *                   In the DefaultFTPEntryParserFactory, this will
2174:     *                   happen when parserKey is neither
2175:     *                   the fully qualified class name of a class
2176:     *                   implementing the interface
2177:     *                   org.apache.commons.net.ftp.FTPFileEntryParser
2178:     *                   nor a string containing one of the recognized keys
2179:     *                   mapping to such a parser or if class loader
2180:     *                   security issues prevent its being loaded.
2181:     * @see org.apache.commons.net.ftp.parser.DefaultFTPFileEntryParserFactory
2182:     * @see org.apache.commons.net.ftp.parser.FTPFileEntryParserFactory
2183:     * @see org.apache.commons.net.ftp.FTPFileEntryParser
2184:     */
2185:    public FTPFile[] listFiles()
2186:    throws IOException
2187:	      {
2188:        return listFiles((String) null);
2189:    }
2190:
2191:    /**
2192:     * Using the default autodetect mechanism, initialize an FTPListParseEngine
2193:     * object containing a raw file information for the current working
2194:     * directory on the server
2195:     * This information is obtained through the LIST command.  This object
2196:     * is then capable of being iterated to return a sequence of FTPFile
2197:     * objects with information filled in by the
2198:     * <code> FTPFileEntryParser </code> used.
2199:     * <p>
2200:     * This method differs from using the listFiles() methods in that
2201:     * expensive FTPFile objects are not created until needed which may be
2202:     * an advantage on large lists.
2203:     *
2204:     * @return A FTPListParseEngine object that holds the raw information and
2205:     * is capable of providing parsed FTPFile objects, one for each file
2206:     * containing information contained in the given path in the format
2207:     * determined by the <code> parser </code> parameter.   Null will be
2208:     * returned if a data connection cannot be opened.  If the current working
2209:     * directory contains no files, an empty array will be the return.
2210:     *
2211:     * @exception FTPConnectionClosedException
2212:     *                   If the FTP server prematurely closes the connection as a result
2213:     *                   of the client being idle or some other reason causing the server
2214:     *                   to send FTP reply code 421.  This exception may be caught either
2215:     *                   as an IOException or independently as itself.
2216:     * @exception IOException
2217:     *                   If an I/O error occurs while either sending a
2218:     *                   command to the server or receiving a reply from the server.
2219:     * @exception ParserInitializationException
2220:     *                   Thrown if the autodetect mechanism cannot
2221:     *                   resolve the type of system we are connected with.
2222:     * @see FTPListParseEngine
2223:     */
2224:    public FTPListParseEngine initiateListParsing()
2225:    throws IOException
2226:	      {
2227:        return initiateListParsing((String) null);
2228:    }
2229:
2230:    /**
2231:     * Using the default autodetect mechanism, initialize an FTPListParseEngine
2232:     * object containing a raw file information for the supplied directory.
2233:     * This information is obtained through the LIST command.  This object
2234:     * is then capable of being iterated to return a sequence of FTPFile
2235:     * objects with information filled in by the
2236:     * <code> FTPFileEntryParser </code> used.
2237:     * <p>
2238:     * The server may or may not expand glob expressions.  You should avoid
2239:     * using glob expressions because the return format for glob listings
2240:     * differs from server to server and will likely cause this method to fail.
2241:     * <p>
2242:     * This method differs from using the listFiles() methods in that
2243:     * expensive FTPFile objects are not created until needed which may be
2244:     * an advantage on large lists.
2245:     * <p>
2246:     * <pre>
2247:     *    FTPClient f=FTPClient();
2248:     *    f.connect(server);
2249:     *    f.login(username, password);
2250:     *    FTPListParseEngine engine = f.initiateListParsing(directory);
2251:     *
2252:	       *    while (engine.hasNext()) {
2253:     *       FTPFile[] files = engine.getNext(25);  // "page size" you want
2254:     *       //do whatever you want with these files, display them, etc.
2255:     *       //expensive FTPFile objects not created until needed.
2256:     *    }
2257:     * </pre>
2258:     *
2259:     * @return A FTPListParseEngine object that holds the raw information and
2260:     * is capable of providing parsed FTPFile objects, one for each file
2261:     * containing information contained in the given path in the format
2262:     * determined by the <code> parser </code> parameter.   Null will be
2263:     * returned if a data connection cannot be opened.  If the current working
2264:     * directory contains no files, an empty array will be the return.
2265:     *
2266:     * @exception FTPConnectionClosedException
2267:     *                   If the FTP server prematurely closes the connection as a result
2268:     *                   of the client being idle or some other reason causing the server
2269:     *                   to send FTP reply code 421.  This exception may be caught either
2270:     *                   as an IOException or independently as itself.
2271:     * @exception IOException
2272:     *                   If an I/O error occurs while either sending a
2273:     *                   command to the server or receiving a reply from the server.
2274:     * @exception ParserInitializationException
2275:     *                   Thrown if the autodetect mechanism cannot
2276:     *                   resolve the type of system we are connected with.
2277:     * @see FTPListParseEngine
2278:     */
2279:    public FTPListParseEngine initiateListParsing(
2280:            String pathname)
2281:    throws IOException
2282:	      {
2283:        String key = null;
2284:        return initiateListParsing(key, pathname);
2285:    }
2286:
2287:    /**
2288:     * Using the supplied parser key, initialize an FTPListParseEngine
2289:     * object containing a raw file information for the supplied directory.
2290:     * This information is obtained through the LIST command.  This object
2291:     * is then capable of being iterated to return a sequence of FTPFile
2292:     * objects with information filled in by the
2293:     * <code> FTPFileEntryParser </code> used.
2294:     * <p>
2295:     * The server may or may not expand glob expressions.  You should avoid
2296:     * using glob expressions because the return format for glob listings
2297:     * differs from server to server and will likely cause this method to fail.
2298:     * <p>
2299:     * This method differs from using the listFiles() methods in that
2300:     * expensive FTPFile objects are not created until needed which may be
2301:     * an advantage on large lists.
2302:     *
2303:     * @param parserKey A string representing a designated code or fully-qualified
2304:     * class name of an  <code> FTPFileEntryParser </code> that should be
2305:     *               used to parse each server file listing.
2306:     *
2307:     * @return A FTPListParseEngine object that holds the raw information and
2308:     * is capable of providing parsed FTPFile objects, one for each file
2309:     * containing information contained in the given path in the format
2310:     * determined by the <code> parser </code> parameter.   Null will be
2311:     * returned if a data connection cannot be opened.  If the current working
2312:     * directory contains no files, an empty array will be the return.
2313:     *
2314:     * @exception FTPConnectionClosedException
2315:     *                   If the FTP server prematurely closes the connection as a result
2316:     *                   of the client being idle or some other reason causing the server
2317:     *                   to send FTP reply code 421.  This exception may be caught either
2318:     *                   as an IOException or independently as itself.
2319:     * @exception IOException
2320:     *                   If an I/O error occurs while either sending a
2321:     *                   command to the server or receiving a reply from the server.
2322:     * @exception ParserInitializationException
2323:     *                   Thrown if the parserKey parameter cannot be
2324:     *                   resolved by the selected parser factory.
2325:     *                   In the DefaultFTPEntryParserFactory, this will
2326:     *                   happen when parserKey is neither
2327:     *                   the fully qualified class name of a class
2328:     *                   implementing the interface
2329:     *                   org.apache.commons.net.ftp.FTPFileEntryParser
2330:     *                   nor a string containing one of the recognized keys
2331:     *                   mapping to such a parser or if class loader
2332:     *                   security issues prevent its being loaded.
2333:     * @see FTPListParseEngine
2334:     */
2335:    public FTPListParseEngine initiateListParsing(
2336:            String parserKey, String pathname)
2337:    throws IOException
2338:	      {
2339:        // We cache the value to avoid creation of a new object every
2340:        // time a file listing is generated.
2341:	          if(__entryParser == null) {
2342:	              if (null != parserKey) {
2343:                // if a parser key was supplied in the parameters, 
2344:                // use that to create the paraser
2345:                __entryParser = 
2346:                    __parserFactory.createFileEntryParser(parserKey);
2347:                
2348:            } else {
2349:                // if no parserKey was supplied, check for a configuration
2350:                // in the params, and if non-null, use that.
2351:	                  if (null != __configuration) {
2352:                    __entryParser = 
2353:                        __parserFactory.createFileEntryParser(__configuration);
2354:                } else {
2355:                    // if a parserKey hasn't been supplied, and a configuration
2356:                    // hasn't been supplied, then autodetect by calling
2357:                    // the SYST command and use that to choose the parser.
2358:                    __entryParser = 
2359:                        __parserFactory.createFileEntryParser(getSystemName());
2360:                 }
2361:            }
2362:        }
2363:
2364:        return initiateListParsing(__entryParser, pathname);
2365:
2366:    }
2367:
2368:
2369:    /**
2370:     * private method through which all listFiles() and
2371:     * initiateListParsing methods pass once a parser is determined.
2372:     *
2373:     * @exception FTPConnectionClosedException
2374:     *                   If the FTP server prematurely closes the connection as a result
2375:     *                   of the client being idle or some other reason causing the server
2376:     *                   to send FTP reply code 421.  This exception may be caught either
2377:     *                   as an IOException or independently as itself.
2378:     * @exception IOException
2379:     *                   If an I/O error occurs while either sending a
2380:     *                   command to the server or receiving a reply from the server.
2381:     * @see FTPListParseEngine
2382:     */
2383:    private FTPListParseEngine initiateListParsing(
2384:            FTPFileEntryParser parser, String pathname)
2385:    throws IOException
2386:	      {
2387:        Socket socket;
2388:
2389:        FTPListParseEngine engine = new FTPListParseEngine(parser);
2390:        if ((socket = _openDataConnection_(FTPCommand.LIST, pathname)) == null)
2391:	          {
2392:            return engine;
2393:        }
2394:
2395:
2396:        engine.readServerList(socket.getInputStream(), getControlEncoding());
2397:
2398:        socket.close();
2399:
2400:        completePendingCommand();
2401:        return engine;
2402:    }
2403:
2404:    /***
2405:     * Issue the FTP STAT command to the server.
2406:     * <p>
2407:     * @return The status information returned by the server.
2408:     * @exception FTPConnectionClosedException
2409:     *      If the FTP server prematurely closes the connection as a result
2410:     *      of the client being idle or some other reason causing the server
2411:     *      to send FTP reply code 421.  This exception may be caught either
2412:     *      as an IOException or independently as itself.
2413:     * @exception IOException  If an I/O error occurs while either sending a
2414:     *      command to the server or receiving a reply from the server.
2415:     ***/
2416:    public String getStatus() throws IOException
2417:	      {
2418:        if (FTPReply.isPositiveCompletion(stat()))
2419:            return getReplyString();
2420:        return null;
2421:    }
2422:
2423:
2424:    /***
2425:     * Issue the FTP STAT command to the server for a given pathname.  This
2426:     * should produce a listing of the file or directory.
2427:     * <p>
2428:     * @return The status information returned by the server.
2429:     * @exception FTPConnectionClosedException
2430:     *      If the FTP server prematurely closes the connection as a result
2431:     *      of the client being idle or some other reason causing the server
2432:     *      to send FTP reply code 421.  This exception may be caught either
2433:     *      as an IOException or independently as itself.
2434:     * @exception IOException  If an I/O error occurs while either sending a
2435:     *      command to the server or receiving a reply from the server.
2436:     ***/
2437:    public String getStatus(String pathname) throws IOException
2438:	      {
2439:        if (FTPReply.isPositiveCompletion(stat(pathname)))
2440:            return getReplyString();
2441:        return null;
2442:    }
2443:
2444:    /**
2445:     * Using a programmer specified <code> FTPFileListParser </code>, obtain a
2446:     * list of file information for a directory or information for
2447:     * just a single file.  This information is obtained through the LIST
2448:     * command.  The contents of the returned array is determined by the
2449:     * <code> FTPFileListParser </code> used.
2450:     * The server may or may not expand glob expressions.  You should avoid
2451:     * using glob expressions because the return format for glob listings
2452:     * differs from server to server and will likely cause this method to fail.
2453:     * <p>
2454:     * @param parser The <code> FTPFileListParser </code> that should be
2455:     *         used to parse the server file listing.
2456:     * @param pathname  The file or directory to list.
2457:     * @return The list of file information contained in the given path in
2458:     *         the format determined by the <code> parser </code> parameter.
2459:     *         <p><b> 
2460:     *            NOTE:</b> This array may contain null members if any of the 
2461:     *         individual file listings failed to parse.  The caller should 
2462:     *         check each entry for null before referencing it.
2463:     * @exception FTPConnectionClosedException
2464:     *      If the FTP server prematurely closes the connection as a result
2465:     *      of the client being idle or some other reason causing the server
2466:     *      to send FTP reply code 421.  This exception may be caught either
2467:     *      as an IOException or independently as itself.
2468:     * @exception IOException  If an I/O error occurs while either sending a
2469:     *      command to the server or receiving a reply from the server.
2470:     *
2471:     * @return The list of file information contained in the given path in
2472:     *         the format determined by<code> parserKey </code>parameter.
2473:     *         <p><b> 
2474:     *            NOTE:</b> This array may contain null members if any of the 
2475:     *         individual file listings failed to parse.  The caller should 
2476:     *         check each entry for null before referencing it.
2477:     *
2478:     * @exception IOException
2479:     * @since 5 Jan 2004
2480:     * @deprecated use listFiles(String parserKey, String pathname) instead
2481:     */
2482:    public FTPFile[] listFiles(FTPFileListParser parser, String pathname)
2483:    throws IOException
2484:	      {
2485:        Socket socket;
2486:        FTPFile[] results;
2487:
2488:        if ((socket = _openDataConnection_(FTPCommand.LIST, pathname)) == null)
2489:            return new FTPFile[0];
2490:
2491:        results = parser.parseFileList(socket.getInputStream(), getControlEncoding());
2492:
2493:        socket.close();
2494:
2495:        completePendingCommand();
2496:
2497:        return results;
2498:    }
2499:
2500:
2501:    /**
2502:     * Using a programmer specified <code> FTPFileListParser </code>,
2503:     * obtain a list of file information for the current working directory.
2504:     * This information is obtained through the LIST command.
2505:     * The contents of the array returned is determined by the
2506:     * <code> FTPFileListParser </code> used.
2507:     * <p>
2508:     *
2509:     * @param parser The <code> FTPFileListParser </code> that should be
2510:     *               used to parse the server file listing.
2511:     *
2512:     * @return The list of file information contained in the given path in
2513:     *         the format determined by the <code> parser </code> parameter.
2514:     *         <p><b> 
2515:     *            NOTE:</b> This array may contain null members if any of the 
2516:     *         individual file listings failed to parse.  The caller should 
2517:     *         check each entry for null before referencing it.
2518:     * @exception FTPConnectionClosedException
2519:     *                   If the FTP server prematurely closes the connection as a result
2520:     *                   of the client being idle or some other reason causing the server
2521:     *                   to send FTP reply code 421.  This exception may be caught either
2522:     *                   as an IOException or independently as itself.
2523:     * @exception IOException
2524:     *                   If an I/O error occurs while either sending a
2525:     *                   command to the server or receiving a reply from the server.
2526:     * @exception IOException
2527:     * @since 5 Jan 2004
2528:     * @deprecated use listFiles(String parserKey) instead.
2529:     */
2530:    public FTPFile[] listFiles(FTPFileListParser parser) throws IOException
2531:	      {
2532:        return listFiles(parser, null);
2533:    }
2534:
2535:
2536:    /**
2537:     * Using a programmer specified <code> FTPFileEntryParser </code>,
2538:     * initialize an object containing a raw file information for the
2539:     * current working directory.  This information is obtained through
2540:     * the LIST command.  This object is then capable of being iterated to
2541:     * return a sequence of FTPFile objects with information filled in by the
2542:     * <code> FTPFileEntryParser </code> used.
2543:     * <p>
2544:     * The server may or may not expand glob expressions.  You should avoid
2545:     * using glob expressions because the return format for glob listings
2546:     * differs from server to server and will likely cause this method to fail.
2547:     * <p>
2548:     * This method differs from using the listFiles() methods in that
2549:     * expensive FTPFile objects are not created until needed which may be
2550:     * an advantage on large lists.
2551:     *
2552:     * @param parser The <code> FTPFileEntryParser </code> that should be
2553:     *               used to parse each server file listing.
2554:     *
2555:     * @return An iteratable object that holds the raw information and is
2556:     *         capable of providing parsed FTPFile objects, one for each file containing
2557:     *         information contained in the given path in the format determined by the
2558:     *         <code> parser </code> parameter.   Null will be returned if a
2559:     *         data connection cannot be opened.  If the current working directory
2560:     *         contains no files, an empty array will be the return.
2561:     * <pre>
2562:     *    FTPClient f=FTPClient();
2563:     *    f.connect(server);
2564:     *    f.login(username, password);
2565:     *    FTPFileList list = f.createFileList(directory, parser);
2566:     *    FTPFileIterator iter = list.iterator();
2567:     *
2568:	       *    while (iter.hasNext()) {
2569:     *       FTPFile[] files = iter.getNext(25);  // "page size" you want
2570:     *       //do whatever you want with these files, display them, etc.
2571:     *       //expensive FTPFile objects not created until needed.
2572:     *    }
2573:     * </pre>
2574:     *
2575:     * @exception FTPConnectionClosedException
2576:     *                   If the FTP server prematurely closes the connection as a result
2577:     *                   of the client being idle or some other reason causing the server
2578:     *                   to send FTP reply code 421.  This exception may be caught either
2579:     *                   as an IOException or independently as itself.
2580:     * @exception IOException
2581:     *                   If an I/O error occurs while either sending a
2582:     *                   command to the server or receiving a reply from the server.
2583:     * @deprecated - use initiateListParsing(FTPFileEntryParser) method instead.
2584:     * @see FTPFileList
2585:     */
2586:    public FTPFileList createFileList(FTPFileEntryParser parser) throws IOException
2587:	      {
2588:        return createFileList(null, parser);
2589:    }
2590:
2591:    /**
2592:     * Using a programmer specified <code> FTPFileEntryParser </code>,
2593:     * initialize an object containing a raw file information for a directory
2594:     * or information for a single file.  This information is obtained through
2595:     * the LIST command.  This object is then capable of being iterated to
2596:     * return a sequence of FTPFile objects with information filled in by the
2597:     * <code> FTPFileEntryParser </code> used.
2598:     * The server may or may not expand glob expressions.  You should avoid
2599:     * using glob expressions because the return format for glob listings
2600:     * differs from server to server and will likely cause this method to fail.
2601:     * <p>
2602:     * @param parser The <code> FTPFileEntryParser </code> that should be
2603:     *         used to parse each server file listing.
2604:     * @param pathname  The file or directory to list.
2605:     * @return An iteratable object that holds the raw information and is
2606:     * capable of providing parsed FTPFile objects, one for each file containing
2607:     * information contained in the given path in the format determined by the
2608:     * <code> parser </code> parameter.  Null will be returned if a
2609:     * data connection cannot be opened.  If the supplied path contains
2610:     * no files, an empty array will be the return.
2611:     * @exception FTPConnectionClosedException
2612:     *      If the FTP server prematurely closes the connection as a result
2613:     *      of the client being idle or some other reason causing the server
2614:     *      to send FTP reply code 421.  This exception may be caught either
2615:     *      as an IOException or independently as itself.
2616:     * @exception IOException  If an I/O error occurs while either sending a
2617:     *      command to the server or receiving a reply from the server.
2618:     * @deprecated - use initiateListParsing(String, FTPFileEntryParser)
2619:     * method instead.
2620:     * @see FTPFileList
2621:     */
2622:    public FTPFileList createFileList(String pathname,
2623:            FTPFileEntryParser parser)
2624:    throws IOException
2625:	      {
2626:        Socket socket;
2627:
2628:        if ((socket = _openDataConnection_(FTPCommand.LIST, pathname)) == null)
2629:	          {
2630:            return null;
2631:        }
2632:
2633:        FTPFileList list = FTPFileList.create(socket.getInputStream(), parser);
2634:
2635:        socket.close();
2636:
2637:        completePendingCommand();
2638:        return list;
2639:    }
2640:    
2641:    /**
2642:     * Set the internal buffer size.
2643:     *  
2644:     * @param bufSize The size of the buffer
2645:     */
2646:	      public void setBufferSize(int bufSize) {
2647:        __bufferSize = bufSize;
2648:    }
2649:    
2650:    /**
2651:     * Retrieve the current internal buffer size.
2652:     * @return The current buffer size.
2653:     */
2654:	      public int getBufferSize() {
2655:        return __bufferSize;
2656:    }
2657:
2658:
2659:    /** 
2660:     * Implementation of the {@link Configurable Configurable} interface. 
2661:     * In the case of this class, configuring merely makes the config object available for the
2662:     * factory methods that construct parsers.
2663:     * @param config {@link FTPClientConfig FTPClientConfig} object used to 
2664:     * provide non-standard configurations to the parser.
2665:     * @since 1.4
2666:     */
2667:	      public void configure(FTPClientConfig config) {
2668:        this.__configuration = config;
2669:    }
2670:    
2671:}
2672:
2673:/* Emacs configuration
2674: * Local variables:        **
2675: * mode:             java  **
2676: * c-basic-offset:   4     **
2677: * indent-tabs-mode: nil   **
2678: * End:                    **
2679: */