Support Joomla!

Packages

Package: Joomla-Framework

License

Content on this site is copyright © 2005 - 2008 Open Source Matters Inc and can be used in accordance with the Joomla! Electronic Documentation License. Some parts of this website may be subject to other licenses.
Source code for file /joomla/client/ftp.php

Documentation is available at ftp.php

  1. <?php
  2. /**
  3. @version        $Id: ftp.php 10707 2008-08-21 09:52:47Z eddieajau $
  4. @package        Joomla.Framework
  5. @subpackage    Client
  6. @copyright    Copyright (C) 2005 - 2008 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_OS03)) === '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'))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_OS03)) === 'WIN'{
  153.             $this->_OS 'WIN';
  154.         elseif (strtoupper(substr(PHP_OS03)) === '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[$signaturenew 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->_connFTP_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 '.$userarray(331503))) {
  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 '.$pass230)) {
  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 '.$path250)) {
  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 '.$from350)) {
  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 '.$to250)) {
  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.' '.$patharray(200250))) {
  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 '.$path250)) {
  592.             if (!$this->_putCmd('RMD '.$path250)) {
  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 '.$path257)) {
  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 '.$point350)) {
  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->_conntrue=== 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$bufferFTP_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 '.$patharray (150125))) {
  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->_conntrue=== 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($tmp8192);
  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 '.$remotearray (150125))) {
  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->_dataconn4096);
  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->_conntrue=== 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 '.$remotearray (150125))) {
  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->_dataconn4096);
  828.             $ret fwrite($fp$buffer4096);
  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->_conntrue=== 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 '.$remotearray (150125))) {
  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($fp4096);
  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->_conntrue=== 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 '.$remotearray (150125))) {
  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->_conntrue=== 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'.$patharray (150125))) {
  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->_dataconn4096);
  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-1PREG_SPLIT_NO_EMPTY);
  1075.         $data preg_replace('#^'.preg_quote(substr($path1)'#').'[/\\\\]?#'''$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->_conntrue=== 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'.$patharray (150125))) {
  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->_dataconn4096);
  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]06)) == '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});
  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});
  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->_conn4096);
  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->_conn4096);
  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[5256 $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. }

Documentation generated on Sat, 14 Nov 2009 11:13:26 +0000 by phpDocumentor 1.3.1