Support Joomla!

Joomla! 1.5 Documentation

Packages

Package: Joomla-Framework

Developer Network License

The Joomla! Developer Network content is © copyright 2006 by the individual contributors and can be used in accordance with the Creative Commons License, Attribution- NonCommercial- ShareAlike 2.5
Source code for file /joomla/client/ftp.php

Documentation is available at ftp.php

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

Documentation generated on Mon, 05 Mar 2007 21:02:06 +0000 by phpDocumentor 1.3.1