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