[ Index ]

PHP Cross Reference of Joomla 1.5.26 DE

title

Body

[close]

/libraries/joomla/client/ -> ftp.php (source)

   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  }


Generated: Wed Mar 28 15:54:07 2012 Cross-referenced by PHPXref 0.7.1