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