| [ Index ] |
PHP Cross Reference of Joomla 1.5.26 DE |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * @version $Id: ftp.php 14401 2010-01-26 14:10:00Z louis $ 4 * @package Joomla.Framework 5 * @subpackage Client 6 * @copyright Copyright (C) 2005 - 2010 Open Source Matters. All rights reserved. 7 * @license GNU/GPL, see LICENSE.php 8 * Joomla! is free software and parts of it may contain or be derived from the 9 * GNU General Public License or other free or open source software licenses. 10 * See COPYRIGHT.php for copyright notices and details. 11 */ 12 13 // Check to ensure this file is within the rest of the framework 14 defined('JPATH_BASE') or die(); 15 16 /** Error Codes: 17 * - 30 : Unable to connect to host 18 * - 31 : Not connected 19 * - 32 : Unable to send command to server 20 * - 33 : Bad username 21 * - 34 : Bad password 22 * - 35 : Bad response 23 * - 36 : Passive mode failed 24 * - 37 : Data transfer error 25 * - 38 : Local filesystem error 26 */ 27 28 if (!defined('CRLF')) { 29 define('CRLF', "\r\n"); 30 } 31 if (!defined("FTP_AUTOASCII")) { 32 define("FTP_AUTOASCII", -1); 33 } 34 if (!defined("FTP_BINARY")) { 35 define("FTP_BINARY", 1); 36 } 37 if (!defined("FTP_ASCII")) { 38 define("FTP_ASCII", 0); 39 } 40 41 // Is FTP extension loaded? If not try to load it 42 if (!extension_loaded('ftp')) { 43 if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { 44 @ dl('php_ftp.dll'); 45 } else { 46 @ dl('ftp.so'); 47 } 48 } 49 if (!defined('FTP_NATIVE')) { 50 define('FTP_NATIVE', (function_exists('ftp_connect'))? 1 : 0); 51 } 52 53 /** 54 * FTP client class 55 * 56 * @package Joomla.Framework 57 * @subpackage Client 58 * @since 1.5 59 */ 60 class JFTP extends JObject 61 { 62 63 /** 64 * Server connection resource 65 * 66 * @access private 67 * @var socket resource 68 */ 69 var $_conn = null; 70 71 /** 72 * Data port connection resource 73 * 74 * @access private 75 * @var socket resource 76 */ 77 var $_dataconn = null; 78 79 /** 80 * Passive connection information 81 * 82 * @access private 83 * @var array 84 */ 85 var $_pasv = null; 86 87 /** 88 * Response Message 89 * 90 * @access private 91 * @var string 92 */ 93 var $_response = null; 94 95 /** 96 * Timeout limit 97 * 98 * @access private 99 * @var int 100 */ 101 var $_timeout = 15; 102 103 /** 104 * Transfer Type 105 * 106 * @access private 107 * @var int 108 */ 109 var $_type = null; 110 111 /** 112 * Native OS Type 113 * 114 * @access private 115 * @var string 116 */ 117 var $_OS = null; 118 119 /** 120 * Array to hold ascii format file extensions 121 * 122 * @final 123 * @access private 124 * @var array 125 */ 126 var $_autoAscii = array ("asp", "bat", "c", "cpp", "csv", "h", "htm", "html", "shtml", "ini", "inc", "log", "php", "php3", "pl", "perl", "sh", "sql", "txt", "xhtml", "xml"); 127 128 /** 129 * Array to hold native line ending characters 130 * 131 * @final 132 * @access private 133 * @var array 134 */ 135 var $_lineEndings = array ('UNIX' => "\n", 'MAC' => "\r", 'WIN' => "\r\n"); 136 137 /** 138 * JFTP object constructor 139 * 140 * @access protected 141 * @param array $options Associative array of options to set 142 * @since 1.5 143 */ 144 function __construct($options=array()) { 145 146 // If default transfer type is no set, set it to autoascii detect 147 if (!isset ($options['type'])) { 148 $options['type'] = FTP_BINARY; 149 } 150 $this->setOptions($options); 151 152 if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { 153 $this->_OS = 'WIN'; 154 } elseif (strtoupper(substr(PHP_OS, 0, 3)) === 'MAC') { 155 $this->_OS = 'MAC'; 156 } else { 157 $this->_OS = 'UNIX'; 158 } 159 160 if (FTP_NATIVE) { 161 // Import the generic buffer stream handler 162 jimport('joomla.utilities.buffer'); 163 // Autoloading fails for JBuffer as the class is used as a stream handler 164 JLoader::load('JBuffer'); 165 } 166 167 // Register faked "destructor" in PHP4 to close all connections we might have made 168 if (version_compare(PHP_VERSION, '5') == -1) { 169 register_shutdown_function(array(&$this, '__destruct')); 170 } 171 } 172 173 /** 174 * JFTP object destructor 175 * 176 * Closes an existing connection, if we have one 177 * 178 * @access protected 179 * @since 1.5 180 */ 181 function __destruct() { 182 if (is_resource($this->_conn)) { 183 $this->quit(); 184 } 185 } 186 187 /** 188 * Returns a reference to the global FTP connector object, only creating it 189 * if it doesn't already exist. 190 * 191 * This method must be invoked as: 192 * <pre> $ftp = &JFTP::getInstance($host);</pre> 193 * 194 * You may optionally specify a username and password in the parameters. If you do so, 195 * you may not login() again with different credentials using the same object. 196 * If you do not use this option, you must quit() the current connection when you 197 * are done, to free it for use by others. 198 * 199 * @param string $host Host to connect to 200 * @param string $port Port to connect to 201 * @param array $options Array with any of these options: type=>[FTP_AUTOASCII|FTP_ASCII|FTP_BINARY], timeout=>(int) 202 * @param string $user Username to use for a connection 203 * @param string $pass Password to use for a connection 204 * @return JFTP The FTP Client object. 205 * @since 1.5 206 */ 207 function &getInstance($host = '127.0.0.1', $port = '21', $options = null, $user = null, $pass = null) 208 { 209 static $instances = array(); 210 211 $signature = $user.':'.$pass.'@'.$host.":".$port; 212 213 // Create a new instance, or set the options of an existing one 214 if (!isset ($instances[$signature]) || !is_object($instances[$signature])) { 215 $instances[$signature] = new JFTP($options); 216 } else { 217 $instances[$signature]->setOptions($options); 218 } 219 220 // Connect to the server, and login, if requested 221 if (!$instances[$signature]->isConnected()) { 222 $return = $instances[$signature]->connect($host, $port); 223 if ($return && $user !== null && $pass !== null) { 224 $instances[$signature]->login($user, $pass); 225 } 226 } 227 228 return $instances[$signature]; 229 } 230 231 /** 232 * Set client options 233 * 234 * @access public 235 * @param array $options Associative array of options to set 236 * @return boolean True if successful 237 */ 238 function setOptions($options) { 239 240 if (isset ($options['type'])) { 241 $this->_type = $options['type']; 242 } 243 if (isset ($options['timeout'])) { 244 $this->_timeout = $options['timeout']; 245 } 246 return true; 247 } 248 249 /** 250 * Method to connect to a FTP server 251 * 252 * @access public 253 * @param string $host Host to connect to [Default: 127.0.0.1] 254 * @param string $port Port to connect on [Default: port 21] 255 * @return boolean True if successful 256 */ 257 function connect($host = '127.0.0.1', $port = 21) { 258 259 // Initialize variables 260 $errno = null; 261 $err = null; 262 263 // If already connected, return 264 if (is_resource($this->_conn)) { 265 return true; 266 } 267 268 // If native FTP support is enabled lets use it... 269 if (FTP_NATIVE) { 270 $this->_conn = @ftp_connect($host, $port, $this->_timeout); 271 if ($this->_conn === false) { 272 JError::raiseWarning('30', 'JFTP::connect: Could not connect to host "'.$host.'" on port '.$port); 273 return false; 274 } 275 // Set the timeout for this connection 276 ftp_set_option($this->_conn, FTP_TIMEOUT_SEC, $this->_timeout); 277 return true; 278 } 279 280 // Connect to the FTP server. 281 $this->_conn = @ fsockopen($host, $port, $errno, $err, $this->_timeout); 282 if (!$this->_conn) { 283 JError::raiseWarning('30', 'JFTP::connect: Could not connect to host "'.$host.'" on port '.$port, 'Socket error number '.$errno.' and error message: '.$err); 284 return false; 285 } 286 287 // Set the timeout for this connection 288 socket_set_timeout($this->_conn, $this->_timeout); 289 290 // Check for welcome response code 291 if (!$this->_verifyResponse(220)) { 292 JError::raiseWarning('35', 'JFTP::connect: Bad response', 'Server response: '.$this->_response.' [Expected: 220]'); 293 return false; 294 } 295 296 return true; 297 } 298 299 /** 300 * Method to determine if the object is connected to an FTP server 301 * 302 * @access public 303 * @return boolean True if connected 304 * @since 1.5 305 */ 306 function isConnected() 307 { 308 return is_resource($this->_conn); 309 } 310 311 /** 312 * Method to login to a server once connected 313 * 314 * @access public 315 * @param string $user Username to login to the server 316 * @param string $pass Password to login to the server 317 * @return boolean True if successful 318 */ 319 function login($user = 'anonymous', $pass = 'jftp@joomla.org') { 320 321 // If native FTP support is enabled lets use it... 322 if (FTP_NATIVE) { 323 if (@ftp_login($this->_conn, $user, $pass) === false) { 324 JError::raiseWarning('30', 'JFTP::login: Unable to login' ); 325 return false; 326 } 327 return true; 328 } 329 330 // Send the username 331 if (!$this->_putCmd('USER '.$user, array(331, 503))) { 332 JError::raiseWarning('33', 'JFTP::login: Bad Username', 'Server response: '.$this->_response.' [Expected: 331] Username sent: '.$user ); 333 return false; 334 } 335 336 // If we are already logged in, continue :) 337 if ($this->_responseCode == 503) { 338 return true; 339 } 340 341 // Send the password 342 if (!$this->_putCmd('PASS '.$pass, 230)) { 343 JError::raiseWarning('34', 'JFTP::login: Bad Password', 'Server response: '.$this->_response.' [Expected: 230] Password sent: '.str_repeat('*', strlen($pass))); 344 return false; 345 } 346 347 return true; 348 } 349 350 /** 351 * Method to quit and close the connection 352 * 353 * @access public 354 * @return boolean True if successful 355 */ 356 function quit() { 357 358 // If native FTP support is enabled lets use it... 359 if (FTP_NATIVE) { 360 @ftp_close($this->_conn); 361 return true; 362 } 363 364 // Logout and close connection 365 @fwrite($this->_conn, "QUIT\r\n"); 366 @fclose($this->_conn); 367 368 return true; 369 } 370 371 /** 372 * Method to retrieve the current working directory on the FTP server 373 * 374 * @access public 375 * @return string Current working directory 376 */ 377 function pwd() { 378 379 // If native FTP support is enabled lets use it... 380 if (FTP_NATIVE) { 381 if (($ret = @ftp_pwd($this->_conn)) === false) { 382 JError::raiseWarning('35', 'JFTP::pwd: Bad response' ); 383 return false; 384 } 385 return $ret; 386 } 387 388 // Initialize variables 389 $match = array (null); 390 391 // Send print working directory command and verify success 392 if (!$this->_putCmd('PWD', 257)) { 393 JError::raiseWarning('35', 'JFTP::pwd: Bad response', 'Server response: '.$this->_response.' [Expected: 257]' ); 394 return false; 395 } 396 397 // Match just the path 398 preg_match('/"[^"\r\n]*"/', $this->_response, $match); 399 400 // Return the cleaned path 401 return preg_replace("/\"/", "", $match[0]); 402 } 403 404 /** 405 * Method to system string from the FTP server 406 * 407 * @access public 408 * @return string System identifier string 409 */ 410 function syst() { 411 412 // If native FTP support is enabled lets use it... 413 if (FTP_NATIVE) { 414 if (($ret = @ftp_systype($this->_conn)) === false) { 415 JError::raiseWarning('35', 'JFTP::syst: Bad response' ); 416 return false; 417 } 418 } else { 419 // Send print working directory command and verify success 420 if (!$this->_putCmd('SYST', 215)) { 421 JError::raiseWarning('35', 'JFTP::syst: Bad response', 'Server response: '.$this->_response.' [Expected: 215]' ); 422 return false; 423 } 424 $ret = $this->_response; 425 } 426 427 // Match the system string to an OS 428 if (strpos(strtoupper($ret), 'MAC') !== false) { 429 $ret = 'MAC'; 430 } elseif (strpos(strtoupper($ret), 'WIN') !== false) { 431 $ret = 'WIN'; 432 } else { 433 $ret = 'UNIX'; 434 } 435 436 // Return the os type 437 return $ret; 438 } 439 440 /** 441 * Method to change the current working directory on the FTP server 442 * 443 * @access public 444 * @param string $path Path to change into on the server 445 * @return boolean True if successful 446 */ 447 function chdir($path) { 448 449 // If native FTP support is enabled lets use it... 450 if (FTP_NATIVE) { 451 if (@ftp_chdir($this->_conn, $path) === false) { 452 JError::raiseWarning('35', 'JFTP::chdir: Bad response' ); 453 return false; 454 } 455 return true; 456 } 457 458 // Send change directory command and verify success 459 if (!$this->_putCmd('CWD '.$path, 250)) { 460 JError::raiseWarning('35', 'JFTP::chdir: Bad response', 'Server response: '.$this->_response.' [Expected: 250] Path sent: '.$path ); 461 return false; 462 } 463 464 return true; 465 } 466 467 /** 468 * Method to reinitialize the server, ie. need to login again 469 * 470 * NOTE: This command not available on all servers 471 * 472 * @access public 473 * @return boolean True if successful 474 */ 475 function reinit() { 476 477 // If native FTP support is enabled lets use it... 478 if (FTP_NATIVE) { 479 if (@ftp_site($this->_conn, 'REIN') === false) { 480 JError::raiseWarning('35', 'JFTP::reinit: Bad response' ); 481 return false; 482 } 483 return true; 484 } 485 486 // Send reinitialize command to the server 487 if (!$this->_putCmd('REIN', 220)) { 488 JError::raiseWarning('35', 'JFTP::reinit: Bad response', 'Server response: '.$this->_response.' [Expected: 220]' ); 489 return false; 490 } 491 492 return true; 493 } 494 495 /** 496 * Method to rename a file/folder on the FTP server 497 * 498 * @access public 499 * @param string $from Path to change file/folder from 500 * @param string $to Path to change file/folder to 501 * @return boolean True if successful 502 */ 503 function rename($from, $to) { 504 505 // If native FTP support is enabled lets use it... 506 if (FTP_NATIVE) { 507 if (@ftp_rename($this->_conn, $from, $to) === false) { 508 JError::raiseWarning('35', 'JFTP::rename: Bad response' ); 509 return false; 510 } 511 return true; 512 } 513 514 // Send rename from command to the server 515 if (!$this->_putCmd('RNFR '.$from, 350)) { 516 JError::raiseWarning('35', 'JFTP::rename: Bad response', 'Server response: '.$this->_response.' [Expected: 320] From path sent: '.$from ); 517 return false; 518 } 519 520 // Send rename to command to the server 521 if (!$this->_putCmd('RNTO '.$to, 250)) { 522 JError::raiseWarning('35', 'JFTP::rename: Bad response', 'Server response: '.$this->_response.' [Expected: 250] To path sent: '.$to ); 523 return false; 524 } 525 526 return true; 527 } 528 529 /** 530 * Method to change mode for a path on the FTP server 531 * 532 * @access public 533 * @param string $path Path to change mode on 534 * @param string/int $mode Octal value to change mode to, e.g. '0777', 0777 or 511 535 * @return boolean True if successful 536 */ 537 function chmod($path, $mode) { 538 539 // If no filename is given, we assume the current directory is the target 540 if ($path == '') { 541 $path = '.'; 542 } 543 544 // Convert the mode to a string 545 if (is_int($mode)) { 546 $mode = decoct($mode); 547 } 548 549 // If native FTP support is enabled lets use it... 550 if (FTP_NATIVE) { 551 if (@ftp_site($this->_conn, 'CHMOD '.$mode.' '.$path) === false) { 552 if($this->_OS != 'WIN') { 553 JError::raiseWarning('35', 'JFTP::chmod: Bad response' ); 554 } 555 return false; 556 } 557 return true; 558 } 559 560 // Send change mode command and verify success [must convert mode from octal] 561 if (!$this->_putCmd('SITE CHMOD '.$mode.' '.$path, array(200, 250))) { 562 if($this->_OS != 'WIN') { 563 JError::raiseWarning('35', 'JFTP::chmod: Bad response', 'Server response: '.$this->_response.' [Expected: 200 or 250] Path sent: '.$path.' Mode sent: '.$mode); 564 } 565 return false; 566 } 567 return true; 568 } 569 570 /** 571 * Method to delete a path [file/folder] on the FTP server 572 * 573 * @access public 574 * @param string $path Path to delete 575 * @return boolean True if successful 576 */ 577 function delete($path) { 578 579 // If native FTP support is enabled lets use it... 580 if (FTP_NATIVE) { 581 if (@ftp_delete($this->_conn, $path) === false) { 582 if (@ftp_rmdir($this->_conn, $path) === false) { 583 JError::raiseWarning('35', 'JFTP::delete: Bad response' ); 584 return false; 585 } 586 } 587 return true; 588 } 589 590 // Send delete file command and if that doesn't work, try to remove a directory 591 if (!$this->_putCmd('DELE '.$path, 250)) { 592 if (!$this->_putCmd('RMD '.$path, 250)) { 593 JError::raiseWarning('35', 'JFTP::delete: Bad response', 'Server response: '.$this->_response.' [Expected: 250] Path sent: '.$path ); 594 return false; 595 } 596 } 597 return true; 598 } 599 600 /** 601 * Method to create a directory on the FTP server 602 * 603 * @access public 604 * @param string $path Directory to create 605 * @return boolean True if successful 606 */ 607 function mkdir($path) { 608 609 // If native FTP support is enabled lets use it... 610 if (FTP_NATIVE) { 611 if (@ftp_mkdir($this->_conn, $path) === false) { 612 JError::raiseWarning('35', 'JFTP::mkdir: Bad response' ); 613 return false; 614 } 615 return true; 616 } 617 618 // Send change directory command and verify success 619 if (!$this->_putCmd('MKD '.$path, 257)) { 620 JError::raiseWarning('35', 'JFTP::mkdir: Bad response', 'Server response: '.$this->_response.' [Expected: 257] Path sent: '.$path ); 621 return false; 622 } 623 return true; 624 } 625 626 /** 627 * Method to restart data transfer at a given byte 628 * 629 * @access public 630 * @param int $point Byte to restart transfer at 631 * @return boolean True if successful 632 */ 633 function restart($point) { 634 635 // If native FTP support is enabled lets use it... 636 if (FTP_NATIVE) { 637 if (@ftp_site($this->_conn, 'REST '.$point) === false) { 638 JError::raiseWarning('35', 'JFTP::restart: Bad response' ); 639 return false; 640 } 641 return true; 642 } 643 644 // Send restart command and verify success 645 if (!$this->_putCmd('REST '.$point, 350)) { 646 JError::raiseWarning('35', 'JFTP::restart: Bad response', 'Server response: '.$this->_response.' [Expected: 350] Restart point sent: '.$point ); 647 return false; 648 } 649 650 return true; 651 } 652 653 /** 654 * Method to create an empty file on the FTP server 655 * 656 * @access public 657 * @param string $path Path local file to store on the FTP server 658 * @return boolean True if successful 659 */ 660 function create($path) { 661 662 // If native FTP support is enabled lets use it... 663 if (FTP_NATIVE) { 664 // turn passive mode on 665 if (@ftp_pasv($this->_conn, true) === false) { 666 JError::raiseWarning('36', 'JFTP::create: Unable to use passive mode' ); 667 return false; 668 } 669 670 $buffer = fopen('buffer://tmp', 'r'); 671 if (@ftp_fput($this->_conn, $path, $buffer, FTP_ASCII) === false) { 672 JError::raiseWarning('35', 'JFTP::create: Bad response' ); 673 fclose($buffer); 674 return false; 675 } 676 fclose($buffer); 677 return true; 678 } 679 680 // Start passive mode 681 if (!$this->_passive()) { 682 JError::raiseWarning('36', 'JFTP::create: Unable to use passive mode' ); 683 return false; 684 } 685 686 if (!$this->_putCmd('STOR '.$path, array (150, 125))) { 687 @ fclose($this->_dataconn); 688 JError::raiseWarning('35', 'JFTP::create: Bad response', 'Server response: '.$this->_response.' [Expected: 150 or 125] Path sent: '.$path ); 689 return false; 690 } 691 692 // To create a zero byte upload close the data port connection 693 fclose($this->_dataconn); 694 695 if (!$this->_verifyResponse(226)) { 696 JError::raiseWarning('37', 'JFTP::create: Transfer Failed', 'Server response: '.$this->_response.' [Expected: 226] Path sent: '.$path ); 697 return false; 698 } 699 700 return true; 701 } 702 703 /** 704 * Method to read a file from the FTP server's contents into a buffer 705 * 706 * @access public 707 * @param string $remote Path to remote file to read on the FTP server 708 * @param string $buffer Buffer variable to read file contents into 709 * @return boolean True if successful 710 */ 711 function read($remote, &$buffer) { 712 713 // Determine file type 714 $mode = $this->_findMode($remote); 715 716 // If native FTP support is enabled lets use it... 717 if (FTP_NATIVE) { 718 // turn passive mode on 719 if (@ftp_pasv($this->_conn, true) === false) { 720 JError::raiseWarning('36', 'JFTP::read: Unable to use passive mode' ); 721 return false; 722 } 723 724 $tmp = fopen('buffer://tmp', 'br+'); 725 if (@ftp_fget($this->_conn, $tmp, $remote, $mode) === false) { 726 fclose($tmp); 727 JError::raiseWarning('35', 'JFTP::read: Bad response' ); 728 return false; 729 } 730 // Read tmp buffer contents 731 rewind($tmp); 732 $buffer = ''; 733 while (!feof($tmp)) { 734 $buffer .= fread($tmp, 8192); 735 } 736 fclose($tmp); 737 return true; 738 } 739 740 $this->_mode($mode); 741 742 // Start passive mode 743 if (!$this->_passive()) { 744 JError::raiseWarning('36', 'JFTP::read: Unable to use passive mode' ); 745 return false; 746 } 747 748 if (!$this->_putCmd('RETR '.$remote, array (150, 125))) { 749 @ fclose($this->_dataconn); 750 JError::raiseWarning('35', 'JFTP::read: Bad response', 'Server response: '.$this->_response.' [Expected: 150 or 125] Path sent: '.$remote ); 751 return false; 752 } 753 754 // Read data from data port connection and add to the buffer 755 $buffer = ''; 756 while (!feof($this->_dataconn)) { 757 $buffer .= fread($this->_dataconn, 4096); 758 } 759 760 // Close the data port connection 761 fclose($this->_dataconn); 762 763 // Let's try to cleanup some line endings if it is ascii 764 if ($mode == FTP_ASCII) { 765 $buffer = preg_replace("/".CRLF."/", $this->_lineEndings[$this->_OS], $buffer); 766 } 767 768 if (!$this->_verifyResponse(226)) { 769 JError::raiseWarning('37', 'JFTP::read: Transfer Failed', 'Server response: '.$this->_response.' [Expected: 226] Path sent: '.$remote ); 770 return false; 771 } 772 773 return true; 774 } 775 776 /** 777 * Method to get a file from the FTP server and save it to a local file 778 * 779 * @access public 780 * @param string $local Path to local file to save remote file as 781 * @param string $remote Path to remote file to get on the FTP server 782 * @return boolean True if successful 783 */ 784 function get($local, $remote) { 785 786 // Determine file type 787 $mode = $this->_findMode($remote); 788 789 // If native FTP support is enabled lets use it... 790 if (FTP_NATIVE) { 791 // turn passive mode on 792 if (@ftp_pasv($this->_conn, true) === false) { 793 JError::raiseWarning('36', 'JFTP::get: Unable to use passive mode' ); 794 return false; 795 } 796 797 if (@ftp_get($this->_conn, $local, $remote, $mode) === false) { 798 JError::raiseWarning('35', 'JFTP::get: Bad response' ); 799 return false; 800 } 801 return true; 802 } 803 804 $this->_mode($mode); 805 806 // Check to see if the local file can be opened for writing 807 $fp = fopen($local, "wb"); 808 if (!$fp) { 809 JError::raiseWarning('38', 'JFTP::get: Unable to open local file for writing', 'Local path: '.$local ); 810 return false; 811 } 812 813 // Start passive mode 814 if (!$this->_passive()) { 815 JError::raiseWarning('36', 'JFTP::get: Unable to use passive mode' ); 816 return false; 817 } 818 819 if (!$this->_putCmd('RETR '.$remote, array (150, 125))) { 820 @ fclose($this->_dataconn); 821 JError::raiseWarning('35', 'JFTP::get: Bad response', 'Server response: '.$this->_response.' [Expected: 150 or 125] Path sent: '.$remote ); 822 return false; 823 } 824 825 // Read data from data port connection and add to the buffer 826 while (!feof($this->_dataconn)) { 827 $buffer = fread($this->_dataconn, 4096); 828 $ret = fwrite($fp, $buffer, 4096); 829 } 830 831 // Close the data port connection and file pointer 832 fclose($this->_dataconn); 833 fclose($fp); 834 835 if (!$this->_verifyResponse(226)) { 836 JError::raiseWarning('37', 'JFTP::get: Transfer Failed', 'Server response: '.$this->_response.' [Expected: 226] Path sent: '.$remote ); 837 return false; 838 } 839 840 return true; 841 } 842 843 /** 844 * Method to store a file to the FTP server 845 * 846 * @access public 847 * @param string $local Path to local file to store on the FTP server 848 * @param string $remote FTP path to file to create 849 * @return boolean True if successful 850 */ 851 function store($local, $remote = null) { 852 853 // If remote file not given, use the filename of the local file in the current 854 // working directory 855 if ($remote == null) { 856 $remote = basename($local); 857 } 858 859 // Determine file type 860 $mode = $this->_findMode($remote); 861 862 // If native FTP support is enabled lets use it... 863 if (FTP_NATIVE) { 864 // turn passive mode on 865 if (@ftp_pasv($this->_conn, true) === false) { 866 JError::raiseWarning('36', 'JFTP::store: Unable to use passive mode' ); 867 return false; 868 } 869 870 if (@ftp_put($this->_conn, $remote, $local, $mode) === false) { 871 JError::raiseWarning('35', 'JFTP::store: Bad response' ); 872 return false; 873 } 874 return true; 875 } 876 877 $this->_mode($mode); 878 879 // Check to see if the local file exists and open for reading if so 880 if (@ file_exists($local)) { 881 $fp = fopen($local, "rb"); 882 if (!$fp) { 883 JError::raiseWarning('38', 'JFTP::store: Unable to open local file for reading', 'Local path: '.$local ); 884 return false; 885 } 886 } else { 887 JError::raiseWarning('38', 'JFTP::store: Unable to find local path', 'Local path: '.$local ); 888 return false; 889 } 890 891 // Start passive mode 892 if (!$this->_passive()) { 893 @ fclose($fp); 894 JError::raiseWarning('36', 'JFTP::store: Unable to use passive mode' ); 895 return false; 896 } 897 898 // Send store command to the FTP server 899 if (!$this->_putCmd('STOR '.$remote, array (150, 125))) { 900 @ fclose($fp); 901 @ fclose($this->_dataconn); 902 JError::raiseWarning('35', 'JFTP::store: Bad response', 'Server response: '.$this->_response.' [Expected: 150 or 125] Path sent: '.$remote ); 903 return false; 904 } 905 906 // Do actual file transfer, read local file and write to data port connection 907 while (!feof($fp)) { 908 $line = fread($fp, 4096); 909 do { 910 if (($result = @ fwrite($this->_dataconn, $line)) === false) { 911 JError::raiseWarning('37', 'JFTP::store: Unable to write to data port socket' ); 912 return false; 913 } 914 $line = substr($line, $result); 915 } while ($line != ""); 916 } 917 918 fclose($fp); 919 fclose($this->_dataconn); 920 921 if (!$this->_verifyResponse(226)) { 922 JError::raiseWarning('37', 'JFTP::store: Transfer Failed', 'Server response: '.$this->_response.' [Expected: 226] Path sent: '.$remote ); 923 return false; 924 } 925 926 return true; 927 } 928 929 /** 930 * Method to write a string to the FTP server 931 * 932 * @access public 933 * @param string $remote FTP path to file to write to 934 * @param string $buffer Contents to write to the FTP server 935 * @return boolean True if successful 936 */ 937 function write($remote, $buffer) { 938 939 // Determine file type 940 $mode = $this->_findMode($remote); 941 942 // If native FTP support is enabled lets use it... 943 if (FTP_NATIVE) { 944 // turn passive mode on 945 if (@ftp_pasv($this->_conn, true) === false) { 946 JError::raiseWarning('36', 'JFTP::write: Unable to use passive mode' ); 947 return false; 948 } 949 950 $tmp = fopen('buffer://tmp', 'br+'); 951 fwrite($tmp, $buffer); 952 rewind($tmp); 953 if (@ftp_fput($this->_conn, $remote, $tmp, $mode) === false) { 954 fclose($tmp); 955 JError::raiseWarning('35', 'JFTP::write: Bad response' ); 956 return false; 957 } 958 fclose($tmp); 959 return true; 960 } 961 962 // First we need to set the transfer mode 963 $this->_mode($mode); 964 965 // Start passive mode 966 if (!$this->_passive()) { 967 JError::raiseWarning('36', 'JFTP::write: Unable to use passive mode' ); 968 return false; 969 } 970 971 // Send store command to the FTP server 972 if (!$this->_putCmd('STOR '.$remote, array (150, 125))) { 973 JError::raiseWarning('35', 'JFTP::write: Bad response', 'Server response: '.$this->_response.' [Expected: 150 or 125] Path sent: '.$remote ); 974 @ fclose($this->_dataconn); 975 return false; 976 } 977 978 // Write buffer to the data connection port 979 do { 980 if (($result = @ fwrite($this->_dataconn, $buffer)) === false) { 981 JError::raiseWarning('37', 'JFTP::write: Unable to write to data port socket' ); 982 return false; 983 } 984 $buffer = substr($buffer, $result); 985 } while ($buffer != ""); 986 987 // Close the data connection port [Data transfer complete] 988 fclose($this->_dataconn); 989 990 // Verify that the server recieved the transfer 991 if (!$this->_verifyResponse(226)) { 992 JError::raiseWarning('37', 'JFTP::write: Transfer Failed', 'Server response: '.$this->_response.' [Expected: 226] Path sent: '.$remote ); 993 return false; 994 } 995 996 return true; 997 } 998 999 /** 1000 * Method to list the filenames of the contents of a directory on the FTP server 1001 * 1002 * Note: Some servers also return folder names. However, to be sure to list folders on all 1003 * servers, you should use listDetails() instead, if you also need to deal with folders 1004 * 1005 * @access public 1006 * @param string $path Path local file to store on the FTP server 1007 * @return string Directory listing 1008 */ 1009 function listNames($path = null) { 1010 1011 // Initialize variables 1012 $data = null; 1013 1014 // If native FTP support is enabled lets use it... 1015 if (FTP_NATIVE) { 1016 // turn passive mode on 1017 if (@ftp_pasv($this->_conn, true) === false) { 1018 JError::raiseWarning('36', 'JFTP::listNames: Unable to use passive mode' ); 1019 return false; 1020 } 1021 1022 if (($list = @ftp_nlist($this->_conn,$path)) === false) { 1023 // Workaround for empty directories on some servers 1024 if ($this->listDetails($path, 'files') === array()) { 1025 return array(); 1026 } 1027 JError::raiseWarning('35', 'JFTP::listNames: Bad response' ); 1028 return false; 1029 } 1030 $list = preg_replace('#^'.preg_quote($path, '#').'[/\\\\]?#', '', $list); 1031 if ($keys = array_merge(array_keys($list, '.'), array_keys($list, '..'))) { 1032 foreach ($keys as $key) { 1033 unset($list[$key]); 1034 } 1035 } 1036 return $list; 1037 } 1038 1039 /* 1040 * If a path exists, prepend a space 1041 */ 1042 if ($path != null) { 1043 $path = ' ' . $path; 1044 } 1045 1046 // Start passive mode 1047 if (!$this->_passive()) { 1048 JError::raiseWarning('36', 'JFTP::listNames: Unable to use passive mode' ); 1049 return false; 1050 } 1051 1052 if (!$this->_putCmd('NLST'.$path, array (150, 125))) { 1053 @ fclose($this->_dataconn); 1054 // Workaround for empty directories on some servers 1055 if ($this->listDetails($path, 'files') === array()) { 1056 return array(); 1057 } 1058 JError::raiseWarning('35', 'JFTP::listNames: Bad response', 'Server response: '.$this->_response.' [Expected: 150 or 125] Path sent: '.$path ); 1059 return false; 1060 } 1061 1062 // Read in the file listing. 1063 while (!feof($this->_dataconn)) { 1064 $data .= fread($this->_dataconn, 4096); 1065 } 1066 fclose($this->_dataconn); 1067 1068 // Everything go okay? 1069 if (!$this->_verifyResponse(226)) { 1070 JError::raiseWarning('37', 'JFTP::listNames: Transfer Failed', 'Server response: '.$this->_response.' [Expected: 226] Path sent: '.$path ); 1071 return false; 1072 } 1073 1074 $data = preg_split("/[".CRLF."]+/", $data, -1, PREG_SPLIT_NO_EMPTY); 1075 $data = preg_replace('#^'.preg_quote(substr($path, 1), '#').'[/\\\\]?#', '', $data); 1076 if ($keys = array_merge(array_keys($data, '.'), array_keys($data, '..'))) { 1077 foreach ($keys as $key) { 1078 unset($data[$key]); 1079 } 1080 } 1081 return $data; 1082 } 1083 1084 /** 1085 * Method to list the contents of a directory on the FTP server 1086 * 1087 * @access public 1088 * @param string $path Path local file to store on the FTP server 1089 * @param string $type Return type [raw|all|folders|files] 1090 * @param boolean $search Recursively search subdirectories 1091 * @return mixed : if $type is raw: string Directory listing, otherwise array of string with file-names 1092 */ 1093 function listDetails($path = null, $type = 'all') { 1094 1095 // Initialize variables 1096 $dir_list = array(); 1097 $data = null; 1098 $regs = null; 1099 // TODO: Deal with recurse -- nightmare 1100 // For now we will just set it to false 1101 $recurse = false; 1102 1103 // If native FTP support is enabled lets use it... 1104 if (FTP_NATIVE) { 1105 // turn passive mode on 1106 if (@ftp_pasv($this->_conn, true) === false) { 1107 JError::raiseWarning('36', 'JFTP::listDetails: Unable to use passive mode' ); 1108 return false; 1109 } 1110 1111 if (($contents = @ftp_rawlist($this->_conn, $path)) === false) { 1112 JError::raiseWarning('35', 'JFTP::listDetails: Bad response' ); 1113 return false; 1114 } 1115 } else { 1116 // Non Native mode 1117 1118 // Start passive mode 1119 if (!$this->_passive()) { 1120 JError::raiseWarning('36', 'JFTP::listDetails: Unable to use passive mode' ); 1121 return false; 1122 } 1123 1124 // If a path exists, prepend a space 1125 if ($path != null) { 1126 $path = ' ' . $path; 1127 } 1128 1129 // Request the file listing 1130 if (!$this->_putCmd(($recurse == true) ? 'LIST -R' : 'LIST'.$path, array (150, 125))) { 1131 JError::raiseWarning('35', 'JFTP::listDetails: Bad response', 'Server response: '.$this->_response.' [Expected: 150 or 125] Path sent: '.$path ); 1132 @ fclose($this->_dataconn); 1133 return false; 1134 } 1135 1136 // Read in the file listing. 1137 while (!feof($this->_dataconn)) { 1138 $data .= fread($this->_dataconn, 4096); 1139 } 1140 fclose($this->_dataconn); 1141 1142 // Everything go okay? 1143 if (!$this->_verifyResponse(226)) { 1144 JError::raiseWarning('37', 'JFTP::listDetails: Transfer Failed', 'Server response: '.$this->_response.' [Expected: 226] Path sent: '.$path ); 1145 return false; 1146 } 1147 1148 $contents = explode(CRLF, $data); 1149 } 1150 1151 // If only raw output is requested we are done 1152 if ($type == 'raw') { 1153 return $data; 1154 } 1155 1156 // If we received the listing of an emtpy directory, we are done as well 1157 if (empty($contents[0])) { 1158 return $dir_list; 1159 } 1160 1161 // If the server returned the number of results in the first response, let's dump it 1162 if (strtolower(substr($contents[0], 0, 6)) == 'total ') { 1163 array_shift($contents); 1164 if (!isset($contents[0]) || empty($contents[0])) { 1165 return $dir_list; 1166 } 1167 } 1168 1169 // Regular expressions for the directory listing parsing 1170 $regexps['UNIX'] = '([-dl][rwxstST-]+).* ([0-9]*) ([a-zA-Z0-9]+).* ([a-zA-Z0-9]+).* ([0-9]*) ([a-zA-Z]+[0-9: ]*[0-9])[ ]+(([0-9]{1,2}:[0-9]{2})|[0-9]{4}) (.+)'; 1171 $regexps['MAC'] = '([-dl][rwxstST-]+).* ?([0-9 ]* )?([a-zA-Z0-9]+).* ([a-zA-Z0-9]+).* ([0-9]*) ([a-zA-Z]+[0-9: ]*[0-9])[ ]+(([0-9]{2}:[0-9]{2})|[0-9]{4}) (.+)'; 1172 $regexps['WIN'] = '([0-9]{2})-([0-9]{2})-([0-9]{2}) +([0-9]{2}):([0-9]{2})(AM|PM) +([0-9]+|<DIR>) +(.+)'; 1173 1174 // Find out the format of the directory listing by matching one of the regexps 1175 $osType = null; 1176 foreach ($regexps as $k=>$v) { 1177 if (ereg($v, $contents[0])) { 1178 $osType = $k; 1179 $regexp = $v; 1180 break; 1181 } 1182 } 1183 if (!$osType) { 1184 JError::raiseWarning('SOME_ERROR_CODE', 'JFTP::listDetails: Unrecognized directory listing format' ); 1185 return false; 1186 } 1187 1188 /* 1189 * Here is where it is going to get dirty.... 1190 */ 1191 if ($osType == 'UNIX') { 1192 foreach ($contents as $file) { 1193 $tmp_array = null; 1194 if (ereg($regexp, $file, $regs)) { 1195 $fType = (int) strpos("-dl", $regs[1] { 0 }); 1196 //$tmp_array['line'] = $regs[0]; 1197 $tmp_array['type'] = $fType; 1198 $tmp_array['rights'] = $regs[1]; 1199 //$tmp_array['number'] = $regs[2]; 1200 $tmp_array['user'] = $regs[3]; 1201 $tmp_array['group'] = $regs[4]; 1202 $tmp_array['size'] = $regs[5]; 1203 $tmp_array['date'] = date("m-d", strtotime($regs[6])); 1204 $tmp_array['time'] = $regs[7]; 1205 $tmp_array['name'] = $regs[9]; 1206 } 1207 // If we just want files, do not add a folder 1208 if ($type == 'files' && $tmp_array['type'] == 1) { 1209 continue; 1210 } 1211 // If we just want folders, do not add a file 1212 if ($type == 'folders' && $tmp_array['type'] == 0) { 1213 continue; 1214 } 1215 if (is_array($tmp_array) && $tmp_array['name'] != '.' && $tmp_array['name'] != '..') { 1216 $dir_list[] = $tmp_array; 1217 } 1218 } 1219 } 1220 elseif ($osType == 'MAC') { 1221 foreach ($contents as $file) { 1222 $tmp_array = null; 1223 if (ereg($regexp, $file, $regs)) { 1224 $fType = (int) strpos("-dl", $regs[1] { 0 }); 1225 //$tmp_array['line'] = $regs[0]; 1226 $tmp_array['type'] = $fType; 1227 $tmp_array['rights'] = $regs[1]; 1228 //$tmp_array['number'] = $regs[2]; 1229 $tmp_array['user'] = $regs[3]; 1230 $tmp_array['group'] = $regs[4]; 1231 $tmp_array['size'] = $regs[5]; 1232 $tmp_array['date'] = date("m-d", strtotime($regs[6])); 1233 $tmp_array['time'] = $regs[7]; 1234 $tmp_array['name'] = $regs[9]; 1235 } 1236 // If we just want files, do not add a folder 1237 if ($type == 'files' && $tmp_array['type'] == 1) { 1238 continue; 1239 } 1240 // If we just want folders, do not add a file 1241 if ($type == 'folders' && $tmp_array['type'] == 0) { 1242 continue; 1243 } 1244 if (is_array($tmp_array) && $tmp_array['name'] != '.' && $tmp_array['name'] != '..') { 1245 $dir_list[] = $tmp_array; 1246 } 1247 } 1248 } else { 1249 foreach ($contents as $file) { 1250 $tmp_array = null; 1251 if (ereg($regexp, $file, $regs)) { 1252 $fType = (int) ($regs[7] == '<DIR>'); 1253 $timestamp = strtotime("$regs[3]-$regs[1]-$regs[2] $regs[4]:$regs[5]$regs[6]"); 1254 //$tmp_array['line'] = $regs[0]; 1255 $tmp_array['type'] = $fType; 1256 $tmp_array['rights'] = ''; 1257 //$tmp_array['number'] = 0; 1258 $tmp_array['user'] = ''; 1259 $tmp_array['group'] = ''; 1260 $tmp_array['size'] = (int) $regs[7]; 1261 $tmp_array['date'] = date('m-d', $timestamp); 1262 $tmp_array['time'] = date('H:i', $timestamp); 1263 $tmp_array['name'] = $regs[8]; 1264 } 1265 // If we just want files, do not add a folder 1266 if ($type == 'files' && $tmp_array['type'] == 1) { 1267 continue; 1268 } 1269 // If we just want folders, do not add a file 1270 if ($type == 'folders' && $tmp_array['type'] == 0) { 1271 continue; 1272 } 1273 if (is_array($tmp_array) && $tmp_array['name'] != '.' && $tmp_array['name'] != '..') { 1274 $dir_list[] = $tmp_array; 1275 } 1276 } 1277 } 1278 1279 return $dir_list; 1280 } 1281 1282 /** 1283 * Send command to the FTP server and validate an expected response code 1284 * 1285 * @access private 1286 * @param string $cmd Command to send to the FTP server 1287 * @param mixed $expected Integer response code or array of integer response codes 1288 * @return boolean True if command executed successfully 1289 */ 1290 function _putCmd($cmd, $expectedResponse) { 1291 1292 // Make sure we have a connection to the server 1293 if (!is_resource($this->_conn)) { 1294 JError::raiseWarning('31', 'JFTP::_putCmd: Not connected to the control port' ); 1295 return false; 1296 } 1297 1298 // Send the command to the server 1299 if (!fwrite($this->_conn, $cmd."\r\n")) { 1300 JError::raiseWarning('32', 'JFTP::_putCmd: Unable to send command: '.$cmd ); 1301 } 1302 1303 return $this->_verifyResponse($expectedResponse); 1304 } 1305 1306 /** 1307 * Verify the response code from the server and log response if flag is set 1308 * 1309 * @access private 1310 * @param mixed $expected Integer response code or array of integer response codes 1311 * @return boolean True if response code from the server is expected 1312 */ 1313 function _verifyResponse($expected) { 1314 1315 // Initialize variables 1316 $parts = null; 1317 1318 // Wait for a response from the server, but timeout after the set time limit 1319 $endTime = time() + $this->_timeout; 1320 $this->_response = ''; 1321 do { 1322 $this->_response .= fgets($this->_conn, 4096); 1323 } while (!preg_match("/^([0-9]{3})(-(.*".CRLF.")+\\1)? [^".CRLF."]+".CRLF."$/", $this->_response, $parts) && time() < $endTime); 1324 1325 // Catch a timeout or bad response 1326 if (!isset($parts[1])) { 1327 JError::raiseWarning('SOME_ERROR_CODE', 'JFTP::_verifyResponse: Timeout or unrecognized response while waiting for a response from the server', 'Server response: '.$this->_response); 1328 return false; 1329 } 1330 1331 // Separate the code from the message 1332 $this->_responseCode = $parts[1]; 1333 $this->_responseMsg = $parts[0]; 1334 1335 // Did the server respond with the code we wanted? 1336 if (is_array($expected)) { 1337 if (in_array($this->_responseCode, $expected)) { 1338 $retval = true; 1339 } else { 1340 $retval = false; 1341 } 1342 } else { 1343 if ($this->_responseCode == $expected) { 1344 $retval = true; 1345 } else { 1346 $retval = false; 1347 } 1348 } 1349 return $retval; 1350 } 1351 1352 /** 1353 * Set server to passive mode and open a data port connection 1354 * 1355 * @access private 1356 * @return boolean True if successful 1357 */ 1358 function _passive() { 1359 1360 //Initialize variables 1361 $match = array(); 1362 $parts = array(); 1363 $errno = null; 1364 $err = null; 1365 1366 // Make sure we have a connection to the server 1367 if (!is_resource($this->_conn)) { 1368 JError::raiseWarning('31', 'JFTP::_passive: Not connected to the control port' ); 1369 return false; 1370 } 1371 1372 // Request a passive connection - this means, we'll talk to you, you don't talk to us. 1373 @ fwrite($this->_conn, "PASV\r\n"); 1374 1375 // Wait for a response from the server, but timeout after the set time limit 1376 $endTime = time() + $this->_timeout; 1377 $this->_response = ''; 1378 do { 1379 $this->_response .= fgets($this->_conn, 4096); 1380 } while (!preg_match("/^([0-9]{3})(-(.*".CRLF.")+\\1)? [^".CRLF."]+".CRLF."$/", $this->_response, $parts) && time() < $endTime); 1381 1382 // Catch a timeout or bad response 1383 if (!isset($parts[1])) { 1384 JError::raiseWarning('SOME_ERROR_CODE', 'JFTP::_passive: Timeout or unrecognized response while waiting for a response from the server', 'Server response: '.$this->_response); 1385 return false; 1386 } 1387 1388 // Separate the code from the message 1389 $this->_responseCode = $parts[1]; 1390 $this->_responseMsg = $parts[0]; 1391 1392 // If it's not 227, we weren't given an IP and port, which means it failed. 1393 if ($this->_responseCode != '227') { 1394 JError::raiseWarning('36', 'JFTP::_passive: Unable to obtain IP and port for data transfer', 'Server response: '.$this->_responseMsg); 1395 return false; 1396 } 1397 1398 // Snatch the IP and port information, or die horribly trying... 1399 if (preg_match('~\((\d+),\s*(\d+),\s*(\d+),\s*(\d+),\s*(\d+)(?:,\s*(\d+))\)~', $this->_responseMsg, $match) == 0) { 1400 JError::raiseWarning('36', 'JFTP::_passive: IP and port for data transfer not valid', 'Server response: '.$this->_responseMsg); 1401 return false; 1402 } 1403 1404 // This is pretty simple - store it for later use ;). 1405 $this->_pasv = array ('ip' => $match[1].'.'.$match[2].'.'.$match[3].'.'.$match[4], 'port' => $match[5] * 256 + $match[6]); 1406 1407 // Connect, assuming we've got a connection. 1408 $this->_dataconn = @fsockopen($this->_pasv['ip'], $this->_pasv['port'], $errno, $err, $this->_timeout); 1409 if (!$this->_dataconn) { 1410 JError::raiseWarning('30', 'JFTP::_passive: Could not connect to host '.$this->_pasv['ip'].' on port '.$this->_pasv['port'].'. Socket error number '.$errno.' and error message: '.$err ); 1411 return false; 1412 } 1413 1414 // Set the timeout for this connection 1415 socket_set_timeout($this->_conn, $this->_timeout); 1416 1417 return true; 1418 } 1419 1420 /** 1421 * Method to find out the correct transfer mode for a specific file 1422 * 1423 * @access private 1424 * @param string $fileName Name of the file 1425 * @return integer Transfer-mode for this filetype [FTP_ASCII|FTP_BINARY] 1426 */ 1427 function _findMode($fileName) { 1428 if ($this->_type == FTP_AUTOASCII) { 1429 $dot = strrpos($fileName, '.') + 1; 1430 $ext = substr($fileName, $dot); 1431 1432 if (in_array($ext, $this->_autoAscii)) { 1433 $mode = FTP_ASCII; 1434 } else { 1435 $mode = FTP_BINARY; 1436 } 1437 } elseif ($this->_type == FTP_ASCII) { 1438 $mode = FTP_ASCII; 1439 } else { 1440 $mode = FTP_BINARY; 1441 } 1442 return $mode; 1443 } 1444 1445 /** 1446 * Set transfer mode 1447 * 1448 * @access private 1449 * @param int $mode Integer representation of data transfer mode [1:Binary|0:Ascii] 1450 * Defined constants can also be used [FTP_BINARY|FTP_ASCII] 1451 * @return boolean True if successful 1452 */ 1453 function _mode($mode) { 1454 if ($mode == FTP_BINARY) { 1455 if (!$this->_putCmd("TYPE I", 200)) { 1456 JError::raiseWarning('35', 'JFTP::_mode: Bad response', 'Server response: '.$this->_response.' [Expected: 200] Mode sent: Binary' ); 1457 return false; 1458 } 1459 } else { 1460 if (!$this->_putCmd("TYPE A", 200)) { 1461 JError::raiseWarning('35', 'JFTP::_mode: Bad response', 'Server response: '.$this->_response.' [Expected: 200] Mode sent: Ascii' ); 1462 return false; 1463 } 1464 } 1465 return true; 1466 } 1467 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Wed Mar 28 15:54:07 2012 | Cross-referenced by PHPXref 0.7.1 |