| 1 16 package org.apache.commons.net.ftp; 17 import java.io.BufferedInputStream ; 18 import java.io.BufferedOutputStream ; 19 import java.io.BufferedReader ; 20 import java.io.IOException ; 21 import java.io.InputStream ; 22 import java.io.InputStreamReader ; 23 import java.io.OutputStream ; 24 import java.net.InetAddress ; 25 import java.net.ServerSocket ; 26 import java.net.Socket ; 27 import java.util.Vector ; 28 29 import org.apache.commons.net.MalformedServerReplyException; 30 import org.apache.commons.net.ftp.parser.DefaultFTPFileEntryParserFactory; 31 import org.apache.commons.net.ftp.parser.FTPFileEntryParserFactory; 32 import org.apache.commons.net.ftp.parser.ParserInitializationException; 33 import org.apache.commons.net.io.CopyStreamEvent; 34 import org.apache.commons.net.io.CopyStreamException; 35 import org.apache.commons.net.io.FromNetASCIIInputStream; 36 import org.apache.commons.net.io.ToNetASCIIOutputStream; 37 import org.apache.commons.net.io.Util; 38 39 236 public class FTPClient extends FTP 237 implements Configurable 238 { 239 246 public static final int ACTIVE_LOCAL_DATA_CONNECTION_MODE = 0; 247 253 public static final int ACTIVE_REMOTE_DATA_CONNECTION_MODE = 1; 254 260 public static final int PASSIVE_LOCAL_DATA_CONNECTION_MODE = 2; 261 268 public static final int PASSIVE_REMOTE_DATA_CONNECTION_MODE = 3; 269 270 private int __dataConnectionMode, __dataTimeout; 271 private int __passivePort; 272 private String __passiveHost; 273 private int __fileType, __fileFormat, __fileStructure, __fileTransferMode; 274 private boolean __remoteVerificationEnabled; 275 private long __restartOffset; 276 private FTPFileEntryParserFactory __parserFactory; 277 private int __bufferSize; 278 279 private String __systemName; 282 283 private FTPFileEntryParser __entryParser; 286 287 private FTPClientConfig __configuration; 288 289 298 public FTPClient() 299 { 300 __initDefaults(); 301 __dataTimeout = -1; 302 __remoteVerificationEnabled = true; 303 __parserFactory = new DefaultFTPFileEntryParserFactory(); 304 __configuration = null; 305 } 306 307 308 private void __initDefaults() 309 { 310 __dataConnectionMode = ACTIVE_LOCAL_DATA_CONNECTION_MODE; 311 __passiveHost = null; 312 __passivePort = -1; 313 __fileType = FTP.ASCII_FILE_TYPE; 314 __fileStructure = FTP.FILE_STRUCTURE; 315 __fileFormat = FTP.NON_PRINT_TEXT_FORMAT; 316 __fileTransferMode = FTP.STREAM_TRANSFER_MODE; 317 __restartOffset = 0; 318 __systemName = null; 319 __entryParser = null; 320 __bufferSize = Util.DEFAULT_COPY_BUFFER_SIZE; 321 } 322 323 private String __parsePathname(String reply) 324 { 325 int begin, end; 326 327 begin = reply.indexOf('"') + 1; 328 end = reply.indexOf('"', begin); 329 330 return reply.substring(begin, end); 331 } 332 333 334 private void __parsePassiveModeReply(String reply) 335 throws MalformedServerReplyException 336 { 337 int i, index, lastIndex; 338 String octet1, octet2; 339 StringBuffer host; 340 341 reply = reply.substring(reply.indexOf('(') + 1, 342 reply.indexOf(')')).trim(); 343 344 host = new StringBuffer (24); 345 lastIndex = 0; 346 index = reply.indexOf(','); 347 host.append(reply.substring(lastIndex, index)); 348 349 for (i = 0; i < 3; i++) 350 { 351 host.append('.'); 352 lastIndex = index + 1; 353 index = reply.indexOf(',', lastIndex); 354 host.append(reply.substring(lastIndex, index)); 355 } 356 357 lastIndex = index + 1; 358 index = reply.indexOf(',', lastIndex); 359 360 octet1 = reply.substring(lastIndex, index); 361 octet2 = reply.substring(index + 1); 362 363 try 365 { 366 index = Integer.parseInt(octet1); 367 lastIndex = Integer.parseInt(octet2); 368 } 369 catch (NumberFormatException e) 370 { 371 throw new MalformedServerReplyException( 372 "Could not parse passive host information.\nServer Reply: " + reply); 373 } 374 375 index <<= 8; 376 index |= lastIndex; 377 378 __passiveHost = host.toString(); 379 __passivePort = index; 380 } 381 382 private boolean __storeFile(int command, String remote, InputStream local) 383 throws IOException  384 { 385 OutputStream output; 386 Socket socket; 387 388 if ((socket = _openDataConnection_(command, remote)) == null) 389 return false; 390 391 output = new BufferedOutputStream (socket.getOutputStream(), 392 getBufferSize() 393 ); 394 if (__fileType == ASCII_FILE_TYPE) 395 output = new ToNetASCIIOutputStream(output); 396 try 398 { 399 Util.copyStream(local, output, getBufferSize(), 400 CopyStreamEvent.UNKNOWN_STREAM_SIZE, null, 401 false); 402 } 403 catch (IOException e) 404 { 405 try 406 { 407 socket.close(); 408 } 409 catch (IOException f) 410 {} 411 throw e; 412 } 413 output.close(); 414 socket.close(); 415 return completePendingCommand(); 416 } 417 418 private OutputStream __storeFileStream(int command, String remote) 419 throws IOException  420 { 421 OutputStream output; 422 Socket socket; 423 424 if ((socket = _openDataConnection_(command, remote)) == null) 425 return null; 426 427 output = socket.getOutputStream(); 428 if (__fileType == ASCII_FILE_TYPE) { 429 output = new BufferedOutputStream (output, 437 getBufferSize()); 438 output = new ToNetASCIIOutputStream(output); 439 440 } 441 return new org.apache.commons.net.io.SocketOutputStream(socket, output); 442 } 443 444 445 463 protected Socket _openDataConnection_(int command, String arg) 464 throws IOException  465 { 466 Socket socket; 467 468 if (__dataConnectionMode != ACTIVE_LOCAL_DATA_CONNECTION_MODE && 469 __dataConnectionMode != PASSIVE_LOCAL_DATA_CONNECTION_MODE) 470 return null; 471 472 if (__dataConnectionMode == ACTIVE_LOCAL_DATA_CONNECTION_MODE) 473 { 474 ServerSocket server; 475 server = _socketFactory_.createServerSocket(0, 1, getLocalAddress()); 476 477 if (!FTPReply.isPositiveCompletion(port(getLocalAddress(), 478 server.getLocalPort()))) 479 { 480 server.close(); 481 return null; 482 } 483 484 if ((__restartOffset > 0) && !restart(__restartOffset)) 485 { 486 server.close(); 487 return null; 488 } 489 490 if (!FTPReply.isPositivePreliminary(sendCommand(command, arg))) 491 { 492 server.close(); 493 return null; 494 } 495 496 if (__dataTimeout >= 0) 501 server.setSoTimeout(__dataTimeout); 502 socket = server.accept(); 503 server.close(); 504 } 505 else 506 { 508 if (pasv() != FTPReply.ENTERING_PASSIVE_MODE) 509 return null; 510 511 __parsePassiveModeReply((String )_replyLines.elementAt(0)); 512 513 socket = _socketFactory_.createSocket(__passiveHost, __passivePort); 514 if ((__restartOffset > 0) && !restart(__restartOffset)) 515 { 516 socket.close(); 517 return null; 518 } 519 520 if (!FTPReply.isPositivePreliminary(sendCommand(command, arg))) 521 { 522 socket.close(); 523 return null; 524 } 525 } 526 527 if (__remoteVerificationEnabled && !verifyRemote(socket)) 528 { 529 InetAddress host1, host2; 530 531 host1 = socket.getInetAddress(); 532 host2 = getRemoteAddress(); 533 534 socket.close(); 535 536 throw new IOException ( 537 "Host attempting data connection " + host1.getHostAddress() + 538 " is not same as server " + host2.getHostAddress()); 539 } 540 541 if (__dataTimeout >= 0) 542 socket.setSoTimeout(__dataTimeout); 543 544 return socket; 545 } 546 547 548 protected void _connectAction_() throws IOException  549 { 550 super._connectAction_(); 551 __initDefaults(); 552 } 553 554 555 563 public void setDataTimeout(int timeout) 564 { 565 __dataTimeout = timeout; 566 } 567 568 577 public void setParserFactory(FTPFileEntryParserFactory parserFactory) { 578 __parserFactory = parserFactory; 579 } 580 581 582 588 public void disconnect() throws IOException  589 { 590 super.disconnect(); 591 __initDefaults(); 592 } 593 594 595 604 public void setRemoteVerificationEnabled(boolean enable) 605 { 606 __remoteVerificationEnabled = enable; 607 } 608 609 616 public boolean isRemoteVerificationEnabled() 617 { 618 return __remoteVerificationEnabled; 619 } 620 621 635 public boolean login(String username, String password) throws IOException  636 { 637 user(username); 638 639 if (FTPReply.isPositiveCompletion(_replyCode)) 640 return true; 641 642 if (!FTPReply.isPositiveIntermediate(_replyCode)) 645 return false; 646 647 return FTPReply.isPositiveCompletion(pass(password)); 648 } 649 650 651 668 public boolean login(String username, String password, String account) 669 throws IOException  670 { 671 user(username); 672 673 if (FTPReply.isPositiveCompletion(_replyCode)) 674 return true; 675 676 if (!FTPReply.isPositiveIntermediate(_replyCode)) 679 return false; 680 681 pass(password); 682 683 if (FTPReply.isPositiveCompletion(_replyCode)) 684 return true; 685 686 if (!FTPReply.isPositiveIntermediate(_replyCode)) 687 return false; 688 689 return FTPReply.isPositiveCompletion(acct(account)); 690 } 691 692 704 public boolean logout() throws IOException  705 { 706 return FTPReply.isPositiveCompletion(quit()); 707 } 708 709 710 723 public boolean changeWorkingDirectory(String pathname) throws IOException  724 { 725 return FTPReply.isPositiveCompletion(cwd(pathname)); 726 } 727 728 729 741 public boolean changeToParentDirectory() throws IOException  742 { 743 return FTPReply.isPositiveCompletion(cdup()); 744 } 745 746 747 760 public boolean structureMount(String pathname) throws IOException  761 { 762 return FTPReply.isPositiveCompletion(smnt(pathname)); 763 } 764 765 778 boolean reinitialize() throws IOException  779 { 780 rein(); 781 782 if (FTPReply.isPositiveCompletion(_replyCode) || 783 (FTPReply.isPositivePreliminary(_replyCode) && 784 FTPReply.isPositiveCompletion(getReply()))) 785 { 786 787 __initDefaults(); 788 789 return true; 790 } 791 792 return false; 793 } 794 795 796 805 public void enterLocalActiveMode() 806 { 807 __dataConnectionMode = ACTIVE_LOCAL_DATA_CONNECTION_MODE; 808 __passiveHost = null; 809 __passivePort = -1; 810 } 811 812 813 825 public void enterLocalPassiveMode() 826 { 827 __dataConnectionMode = PASSIVE_LOCAL_DATA_CONNECTION_MODE; 828 __passiveHost = null; 831 __passivePort = -1; 832 } 833 834 835 859 public boolean enterRemoteActiveMode(InetAddress host, int port) 860 throws IOException  861 { 862 if (FTPReply.isPositiveCompletion(port(host, port))) 863 { 864 __dataConnectionMode = ACTIVE_REMOTE_DATA_CONNECTION_MODE; 865 __passiveHost = null; 866 __passivePort = -1; 867 return true; 868 } 869 return false; 870 } 871 872 894 public boolean enterRemotePassiveMode() throws IOException  895 { 896 if (pasv() != FTPReply.ENTERING_PASSIVE_MODE) 897 return false; 898 899 __dataConnectionMode = PASSIVE_REMOTE_DATA_CONNECTION_MODE; 900 __parsePassiveModeReply((String )_replyLines.elementAt(0)); 901 902 return true; 903 } 904 905 917 public String getPassiveHost() 918 { 919 return __passiveHost; 920 } 921 922 934 public int getPassivePort() 935 { 936 return __passivePort; 937 } 938 939 940 947 public int getDataConnectionMode() 948 { 949 return __dataConnectionMode; 950 } 951 952 953 |