home *** CD-ROM | disk | FTP | other *** search
/ Cricao de Sites - 650 Layouts Prontos / WebMasters.iso / Blogs / wordpress2.6.exe / wordpress2.6 / wp-admin / includes / class-ftp.php < prev    next >
Encoding:
PHP Script  |  2008-03-16  |  25.3 KB  |  843 lines

  1. <?php
  2. /**
  3.  * PemFTP - A Ftp implementation in pure PHP
  4.  *
  5.  * @package PemFTP
  6.  * @since 2.5
  7.  *
  8.  * @version 1.0
  9.  * @copyright Alexey Dotsenko
  10.  * @author Alexey Dotsenko
  11.  * @link http://www.phpclasses.org/browse/package/1743.html Site
  12.  * @license LGPL License http://www.opensource.org/licenses/lgpl-license.html
  13.  */
  14. if(!defined('CRLF')) define('CRLF',"\r\n");
  15. if(!defined("FTP_AUTOASCII")) define("FTP_AUTOASCII", -1);
  16. if(!defined("FTP_BINARY")) define("FTP_BINARY", 1);
  17. if(!defined("FTP_ASCII")) define("FTP_ASCII", 0);
  18. if(!defined('FTP_FORCE')) define('FTP_FORCE', TRUE);
  19. define('FTP_OS_Unix','u');
  20. define('FTP_OS_Windows','w');
  21. define('FTP_OS_Mac','m');
  22.  
  23. class ftp_base {
  24.     /* Public variables */
  25.     var $LocalEcho;
  26.     var $Verbose;
  27.     var $OS_local;
  28.     var $OS_remote;
  29.  
  30.     /* Private variables */
  31.     var $_lastaction;
  32.     var $_errors;
  33.     var $_type;
  34.     var $_umask;
  35.     var $_timeout;
  36.     var $_passive;
  37.     var $_host;
  38.     var $_fullhost;
  39.     var $_port;
  40.     var $_datahost;
  41.     var $_dataport;
  42.     var $_ftp_control_sock;
  43.     var $_ftp_data_sock;
  44.     var $_ftp_temp_sock;
  45.     var $_ftp_buff_size;
  46.     var $_login;
  47.     var $_password;
  48.     var $_connected;
  49.     var $_ready;
  50.     var $_code;
  51.     var $_message;
  52.     var $_can_restore;
  53.     var $_port_available;
  54.     var $_curtype;
  55.     var $_features;
  56.  
  57.     var $_error_array;
  58.     var $AuthorizedTransferMode;
  59.     var $OS_FullName;
  60.     var $_eol_code;
  61.     var $AutoAsciiExt;
  62.  
  63.     /* Constructor */
  64.     function ftp_base($port_mode=FALSE) {
  65.         $this->__construct($port_mode);
  66.     }
  67.  
  68.     function __construct($port_mode=FALSE, $verb=FALSE, $le=FALSE) {
  69.         $this->LocalEcho=$le;
  70.         $this->Verbose=$verb;
  71.         $this->_lastaction=NULL;
  72.         $this->_error_array=array();
  73.         $this->_eol_code=array(FTP_OS_Unix=>"\n", FTP_OS_Mac=>"\r", FTP_OS_Windows=>"\r\n");
  74.         $this->AuthorizedTransferMode=array(FTP_AUTOASCII, FTP_ASCII, FTP_BINARY);
  75.         $this->OS_FullName=array(FTP_OS_Unix => 'UNIX', FTP_OS_Windows => 'WINDOWS', FTP_OS_Mac => 'MACOS');
  76.         $this->AutoAsciiExt=array("ASP","BAT","C","CPP","CSS","CSV","JS","H","HTM","HTML","SHTML","INI","LOG","PHP3","PHTML","PL","PERL","SH","SQL","TXT");
  77.         $this->_port_available=($port_mode==TRUE);
  78.         $this->SendMSG("Staring FTP client class".($this->_port_available?"":" without PORT mode support"));
  79.         $this->_connected=FALSE;
  80.         $this->_ready=FALSE;
  81.         $this->_can_restore=FALSE;
  82.         $this->_code=0;
  83.         $this->_message="";
  84.         $this->_ftp_buff_size=4096;
  85.         $this->_curtype=NULL;
  86.         $this->SetUmask(0022);
  87.         $this->SetType(FTP_AUTOASCII);
  88.         $this->SetTimeout(30);
  89.         $this->Passive(!$this->_port_available);
  90.         $this->_login="anonymous";
  91.         $this->_password="anon@ftp.com";
  92.         $this->_features=array();
  93.         $this->OS_local=FTP_OS_Unix;
  94.         $this->OS_remote=FTP_OS_Unix;
  95.         $this->features=array();
  96.         if(strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') $this->OS_local=FTP_OS_Windows;
  97.         elseif(strtoupper(substr(PHP_OS, 0, 3)) === 'MAC') $this->OS_local=FTP_OS_Mac;
  98.     }
  99.  
  100. // <!-- --------------------------------------------------------------------------------------- -->
  101. // <!--       Public functions                                                                  -->
  102. // <!-- --------------------------------------------------------------------------------------- -->
  103.  
  104.     function parselisting($line) {
  105.         $is_windows = ($this->OS_remote == FTP_OS_Windows);
  106.         if ($is_windows && preg_match("/([0-9]{2})-([0-9]{2})-([0-9]{2}) +([0-9]{2}):([0-9]{2})(AM|PM) +([0-9]+|<DIR>) +(.+)/",$line,$lucifer)) {
  107.             $b = array();
  108.             if ($lucifer[3]<70) { $lucifer[3]+=2000; } else { $lucifer[3]+=1900; } // 4digit year fix
  109.             $b['isdir'] = ($lucifer[7]=="<DIR>");
  110.             if ( $b['isdir'] )
  111.                 $b['type'] = 'd';
  112.             else
  113.                 $b['type'] = 'f';
  114.             $b['size'] = $lucifer[7];
  115.             $b['month'] = $lucifer[1];
  116.             $b['day'] = $lucifer[2];
  117.             $b['year'] = $lucifer[3];
  118.             $b['hour'] = $lucifer[4];
  119.             $b['minute'] = $lucifer[5];
  120.             $b['time'] = @mktime($lucifer[4]+(strcasecmp($lucifer[6],"PM")==0?12:0),$lucifer[5],0,$lucifer[1],$lucifer[2],$lucifer[3]);
  121.             $b['am/pm'] = $lucifer[6];
  122.             $b['name'] = $lucifer[8];
  123.         } else if (!$is_windows && $lucifer=preg_split("/[ ]/",$line,9,PREG_SPLIT_NO_EMPTY)) {
  124.             //echo $line."\n";
  125.             $lcount=count($lucifer);
  126.             if ($lcount<8) return '';
  127.             $b = array();
  128.             $b['isdir'] = $lucifer[0]{0} === "d";
  129.             $b['islink'] = $lucifer[0]{0} === "l";
  130.             if ( $b['isdir'] )
  131.                 $b['type'] = 'd';
  132.             elseif ( $b['islink'] )
  133.                 $b['type'] = 'l';
  134.             else
  135.                 $b['type'] = 'f';
  136.             $b['perms'] = $lucifer[0];
  137.             $b['number'] = $lucifer[1];
  138.             $b['owner'] = $lucifer[2];
  139.             $b['group'] = $lucifer[3];
  140.             $b['size'] = $lucifer[4];
  141.             if ($lcount==8) {
  142.                 sscanf($lucifer[5],"%d-%d-%d",$b['year'],$b['month'],$b['day']);
  143.                 sscanf($lucifer[6],"%d:%d",$b['hour'],$b['minute']);
  144.                 $b['time'] = @mktime($b['hour'],$b['minute'],0,$b['month'],$b['day'],$b['year']);
  145.                 $b['name'] = $lucifer[7];
  146.             } else {
  147.                 $b['month'] = $lucifer[5];
  148.                 $b['day'] = $lucifer[6];
  149.                 if (preg_match("/([0-9]{2}):([0-9]{2})/",$lucifer[7],$l2)) {
  150.                     $b['year'] = date("Y");
  151.                     $b['hour'] = $l2[1];
  152.                     $b['minute'] = $l2[2];
  153.                 } else {
  154.                     $b['year'] = $lucifer[7];
  155.                     $b['hour'] = 0;
  156.                     $b['minute'] = 0;
  157.                 }
  158.                 $b['time'] = strtotime(sprintf("%d %s %d %02d:%02d",$b['day'],$b['month'],$b['year'],$b['hour'],$b['minute']));
  159.                 $b['name'] = $lucifer[8];
  160.             }
  161.         }
  162.  
  163.         return $b;
  164.     }
  165.  
  166.     function SendMSG($message = "", $crlf=true) {
  167.         if ($this->Verbose) {
  168.             echo $message.($crlf?CRLF:"");
  169.             flush();
  170.         }
  171.         return TRUE;
  172.     }
  173.  
  174.     function SetType($mode=FTP_AUTOASCII) {
  175.         if(!in_array($mode, $this->AuthorizedTransferMode)) {
  176.             $this->SendMSG("Wrong type");
  177.             return FALSE;
  178.         }
  179.         $this->_type=$mode;
  180.         $this->SendMSG("Transfer type: ".($this->_type==FTP_BINARY?"binary":($this->_type==FTP_ASCII?"ASCII":"auto ASCII") ) );
  181.         return TRUE;
  182.     }
  183.  
  184.     function _settype($mode=FTP_ASCII) {
  185.         if($this->_ready) {
  186.             if($mode==FTP_BINARY) {
  187.                 if($this->_curtype!=FTP_BINARY) {
  188.                     if(!$this->_exec("TYPE I", "SetType")) return FALSE;
  189.                     $this->_curtype=FTP_BINARY;
  190.                 }
  191.             } elseif($this->_curtype!=FTP_ASCII) {
  192.                 if(!$this->_exec("TYPE A", "SetType")) return FALSE;
  193.                 $this->_curtype=FTP_ASCII;
  194.             }
  195.         } else return FALSE;
  196.         return TRUE;
  197.     }
  198.  
  199.     function Passive($pasv=NULL) {
  200.         if(is_null($pasv)) $this->_passive=!$this->_passive;
  201.         else $this->_passive=$pasv;
  202.         if(!$this->_port_available and !$this->_passive) {
  203.             $this->SendMSG("Only passive connections available!");
  204.             $this->_passive=TRUE;
  205.             return FALSE;
  206.         }
  207.         $this->SendMSG("Passive mode ".($this->_passive?"on":"off"));
  208.         return TRUE;
  209.     }
  210.  
  211.     function SetServer($host, $port=21, $reconnect=true) {
  212.         if(!is_long($port)) {
  213.             $this->verbose=true;
  214.             $this->SendMSG("Incorrect port syntax");
  215.             return FALSE;
  216.         } else {
  217.             $ip=@gethostbyname($host);
  218.             $dns=@gethostbyaddr($host);
  219.             if(!$ip) $ip=$host;
  220.             if(!$dns) $dns=$host;
  221.             if(ip2long($ip) === -1) {
  222.                 $this->SendMSG("Wrong host name/address \"".$host."\"");
  223.                 return FALSE;
  224.             }
  225.             $this->_host=$ip;
  226.             $this->_fullhost=$dns;
  227.             $this->_port=$port;
  228.             $this->_dataport=$port-1;
  229.         }
  230.         $this->SendMSG("Host \"".$this->_fullhost."(".$this->_host."):".$this->_port."\"");
  231.         if($reconnect){
  232.             if($this->_connected) {
  233.                 $this->SendMSG("Reconnecting");
  234.                 if(!$this->quit(FTP_FORCE)) return FALSE;
  235.                 if(!$this->connect()) return FALSE;
  236.             }
  237.         }
  238.         return TRUE;
  239.     }
  240.  
  241.     function SetUmask($umask=0022) {
  242.         $this->_umask=$umask;
  243.         umask($this->_umask);
  244.         $this->SendMSG("UMASK 0".decoct($this->_umask));
  245.         return TRUE;
  246.     }
  247.  
  248.     function SetTimeout($timeout=30) {
  249.         $this->_timeout=$timeout;
  250.         $this->SendMSG("Timeout ".$this->_timeout);
  251.         if($this->_connected)
  252.             if(!$this->_settimeout($this->_ftp_control_sock)) return FALSE;
  253.         return TRUE;
  254.     }
  255.  
  256.     function connect($server=NULL) {
  257.         if(!empty($server)) {
  258.             if(!$this->SetServer($server)) return false;
  259.         }
  260.         if($this->_ready) return true;
  261.         $this->SendMsg('Local OS : '.$this->OS_FullName[$this->OS_local]);
  262.         if(!($this->_ftp_control_sock = $this->_connect($this->_host, $this->_port))) {
  263.             $this->SendMSG("Error : Cannot connect to remote host \"".$this->_fullhost." :".$this->_port."\"");
  264.             return FALSE;
  265.         }
  266.         $this->SendMSG("Connected to remote host \"".$this->_fullhost.":".$this->_port."\". Waiting for greeting.");
  267.         do {
  268.             if(!$this->_readmsg()) return FALSE;
  269.             if(!$this->_checkCode()) return FALSE;
  270.             $this->_lastaction=time();
  271.         } while($this->_code<200);
  272.         $this->_ready=true;
  273.         $syst=$this->systype();
  274.         if(!$syst) $this->SendMSG("Can't detect remote OS");
  275.         else {
  276.             if(preg_match("/win|dos|novell/i", $syst[0])) $this->OS_remote=FTP_OS_Windows;
  277.             elseif(preg_match("/os/i", $syst[0])) $this->OS_remote=FTP_OS_Mac;
  278.             elseif(preg_match("/(li|u)nix/i", $syst[0])) $this->OS_remote=FTP_OS_Unix;
  279.             else $this->OS_remote=FTP_OS_Mac;
  280.             $this->SendMSG("Remote OS: ".$this->OS_FullName[$this->OS_remote]);
  281.         }
  282.         if(!$this->features()) $this->SendMSG("Can't get features list. All supported - disabled");
  283.         else $this->SendMSG("Supported features: ".implode(", ", array_keys($this->_features)));
  284.         return TRUE;
  285.     }
  286.  
  287.     function quit($force=false) {
  288.         if($this->_ready) {
  289.             if(!$this->_exec("QUIT") and !$force) return FALSE;
  290.             if(!$this->_checkCode() and !$force) return FALSE;
  291.             $this->_ready=false;
  292.             $this->SendMSG("Session finished");
  293.         }
  294.         $this->_quit();
  295.         return TRUE;
  296.     }
  297.  
  298.     function login($user=NULL, $pass=NULL) {
  299.         if(!is_null($user)) $this->_login=$user;
  300.         else $this->_login="anonymous";
  301.         if(!is_null($pass)) $this->_password=$pass;
  302.         else $this->_password="anon@anon.com";
  303.         if(!$this->_exec("USER ".$this->_login, "login")) return FALSE;
  304.         if(!$this->_checkCode()) return FALSE;
  305.         if($this->_code!=230) {
  306.             if(!$this->_exec((($this->_code==331)?"PASS ":"ACCT ").$this->_password, "login")) return FALSE;
  307.             if(!$this->_checkCode()) return FALSE;
  308.         }
  309.         $this->SendMSG("Authentication succeeded");
  310.         if(empty($this->_features)) {
  311.             if(!$this->features()) $this->SendMSG("Can't get features list. All supported - disabled");
  312.             else $this->SendMSG("Supported features: ".implode(", ", array_keys($this->_features)));
  313.         }
  314.         return TRUE;
  315.     }
  316.  
  317.     function pwd() {
  318.         if(!$this->_exec("PWD", "pwd")) return FALSE;
  319.         if(!$this->_checkCode()) return FALSE;
  320.         return ereg_replace("^[0-9]{3} \"(.+)\".+", "\\1", $this->_message);
  321.     }
  322.  
  323.     function cdup() {
  324.         if(!$this->_exec("CDUP", "cdup")) return FALSE;
  325.         if(!$this->_checkCode()) return FALSE;
  326.         return true;
  327.     }
  328.  
  329.     function chdir($pathname) {
  330.         if(!$this->_exec("CWD ".$pathname, "chdir")) return FALSE;
  331.         if(!$this->_checkCode()) return FALSE;
  332.         return TRUE;
  333.     }
  334.  
  335.     function rmdir($pathname) {
  336.         if(!$this->_exec("RMD ".$pathname, "rmdir")) return FALSE;
  337.         if(!$this->_checkCode()) return FALSE;
  338.         return TRUE;
  339.     }
  340.  
  341.     function mkdir($pathname) {
  342.         if(!$this->_exec("MKD ".$pathname, "mkdir")) return FALSE;
  343.         if(!$this->_checkCode()) return FALSE;
  344.         return TRUE;
  345.     }
  346.  
  347.     function rename($from, $to) {
  348.         if(!$this->_exec("RNFR ".$from, "rename")) return FALSE;
  349.         if(!$this->_checkCode()) return FALSE;
  350.         if($this->_code==350) {
  351.             if(!$this->_exec("RNTO ".$to, "rename")) return FALSE;
  352.             if(!$this->_checkCode()) return FALSE;
  353.         } else return FALSE;
  354.         return TRUE;
  355.     }
  356.  
  357.     function filesize($pathname) {
  358.         if(!isset($this->_features["SIZE"])) {
  359.             $this->PushError("filesize", "not supported by server");
  360.             return FALSE;
  361.         }
  362.         if(!$this->_exec("SIZE ".$pathname, "filesize")) return FALSE;
  363.         if(!$this->_checkCode()) return FALSE;
  364.         return ereg_replace("^[0-9]{3} ([0-9]+)".CRLF, "\\1", $this->_message);
  365.     }
  366.  
  367.     function abort() {
  368.         if(!$this->_exec("ABOR", "abort")) return FALSE;
  369.         if(!$this->_checkCode()) {
  370.             if($this->_code!=426) return FALSE;
  371.             if(!$this->_readmsg("abort")) return FALSE;
  372.             if(!$this->_checkCode()) return FALSE;
  373.         }
  374.         return true;
  375.     }
  376.  
  377.     function mdtm($pathname) {
  378.         if(!isset($this->_features["MDTM"])) {
  379.             $this->PushError("mdtm", "not supported by server");
  380.             return FALSE;
  381.         }
  382.         if(!$this->_exec("MDTM ".$pathname, "mdtm")) return FALSE;
  383.         if(!$this->_checkCode()) return FALSE;
  384.         $mdtm = ereg_replace("^[0-9]{3} ([0-9]+)".CRLF, "\\1", $this->_message);
  385.         $date = sscanf($mdtm, "%4d%2d%2d%2d%2d%2d");
  386.         $timestamp = mktime($date[3], $date[4], $date[5], $date[1], $date[2], $date[0]);
  387.         return $timestamp;
  388.     }
  389.  
  390.     function systype() {
  391.         if(!$this->_exec("SYST", "systype")) return FALSE;
  392.         if(!$this->_checkCode()) return FALSE;
  393.         $DATA = explode(" ", $this->_message);
  394.         return array($DATA[1], $DATA[3]);
  395.     }
  396.  
  397.     function delete($pathname) {
  398.         if(!$this->_exec("DELE ".$pathname, "delete")) return FALSE;
  399.         if(!$this->_checkCode()) return FALSE;
  400.         return TRUE;
  401.     }
  402.  
  403.     function site($command, $fnction="site") {
  404.         if(!$this->_exec("SITE ".$command, $fnction)) return FALSE;
  405.         if(!$this->_checkCode()) return FALSE;
  406.         return TRUE;
  407.     }
  408.  
  409.     function chmod($pathname, $mode) {
  410.         if(!$this->site( sprintf('CHMOD %o %s', $mode, $pathname), "chmod")) return FALSE;
  411.         return TRUE;
  412.     }
  413.  
  414.     function restore($from) {
  415.         if(!isset($this->_features["REST"])) {
  416.             $this->PushError("restore", "not supported by server");
  417.             return FALSE;
  418.         }
  419.         if($this->_curtype!=FTP_BINARY) {
  420.             $this->PushError("restore", "can't restore in ASCII mode");
  421.             return FALSE;
  422.         }
  423.         if(!$this->_exec("REST ".$from, "resore")) return FALSE;
  424.         if(!$this->_checkCode()) return FALSE;
  425.         return TRUE;
  426.     }
  427.  
  428.     function features() {
  429.         if(!$this->_exec("FEAT", "features")) return FALSE;
  430.         if(!$this->_checkCode()) return FALSE;
  431.         $f=preg_split("/[".CRLF."]+/", preg_replace("/[0-9]{3}[ -].*[".CRLF."]+/", "", $this->_message), -1, PREG_SPLIT_NO_EMPTY);
  432.         $this->_features=array();
  433.         foreach($f as $k=>$v) {
  434.             $v=explode(" ", trim($v));
  435.             $this->_features[array_shift($v)]=$v;;
  436.         }
  437.         return true;
  438.     }
  439.  
  440.     function rawlist($pathname="", $arg="") {
  441.         return $this->_list(($arg?" ".$arg:"").($pathname?" ".$pathname:""), "LIST", "rawlist");
  442.     }
  443.  
  444.     function nlist($pathname="") {
  445.         return $this->_list(($arg?" ".$arg:"").($pathname?" ".$pathname:""), "NLST", "nlist");
  446.     }
  447.  
  448.     function is_exists($pathname) {
  449.         return $this->file_exists($pathname);
  450.     }
  451.  
  452.     function file_exists($pathname) {
  453.         $exists=true;
  454.         if(!$this->_exec("RNFR ".$pathname, "rename")) $exists=FALSE;
  455.         else {
  456.             if(!$this->_checkCode()) $exists=FALSE;
  457.             $this->abort();
  458.         }
  459.         if($exists) $this->SendMSG("Remote file ".$pathname." exists");
  460.         else $this->SendMSG("Remote file ".$pathname." does not exist");
  461.         return $exists;
  462.     }
  463.  
  464.     function fget($fp, $remotefile,$rest=0) {
  465.         if($this->_can_restore and $rest!=0) fseek($fp, $rest);
  466.         $pi=pathinfo($remotefile);
  467.         if($this->_type==FTP_ASCII or ($this->_type==FTP_AUTOASCII and in_array(strtoupper($pi["extension"]), $this->AutoAsciiExt))) $mode=FTP_ASCII;
  468.         else $mode=FTP_BINARY;
  469.         if(!$this->_data_prepare($mode)) {
  470.             return FALSE;
  471.         }
  472.         if($this->_can_restore and $rest!=0) $this->restore($rest);
  473.         if(!$this->_exec("RETR ".$remotefile, "get")) {
  474.             $this->_data_close();
  475.             return FALSE;
  476.         }
  477.         if(!$this->_checkCode()) {
  478.             $this->_data_close();
  479.             return FALSE;
  480.         }
  481.         $out=$this->_data_read($mode, $fp);
  482.         $this->_data_close();
  483.         if(!$this->_readmsg()) return FALSE;
  484.         if(!$this->_checkCode()) return FALSE;
  485.         return $out;
  486.     }
  487.  
  488.     function get($remotefile, $localfile=NULL, $rest=0) {
  489.         if(is_null($localfile)) $localfile=$remotefile;
  490.         if (@file_exists($localfile)) $this->SendMSG("Warning : local file will be overwritten");
  491.         $fp = @fopen($localfile, "w");
  492.         if (!$fp) {
  493.             $this->PushError("get","can't open local file", "Cannot create \"".$localfile."\"");
  494.             return FALSE;
  495.         }
  496.         if($this->_can_restore and $rest!=0) fseek($fp, $rest);
  497.         $pi=pathinfo($remotefile);
  498.         if($this->_type==FTP_ASCII or ($this->_type==FTP_AUTOASCII and in_array(strtoupper($pi["extension"]), $this->AutoAsciiExt))) $mode=FTP_ASCII;
  499.         else $mode=FTP_BINARY;
  500.         if(!$this->_data_prepare($mode)) {
  501.             fclose($fp);
  502.             return FALSE;
  503.         }
  504.         if($this->_can_restore and $rest!=0) $this->restore($rest);
  505.         if(!$this->_exec("RETR ".$remotefile, "get")) {
  506.             $this->_data_close();
  507.             fclose($fp);
  508.             return FALSE;
  509.         }
  510.         if(!$this->_checkCode()) {
  511.             $this->_data_close();
  512.             fclose($fp);
  513.             return FALSE;
  514.         }
  515.         $out=$this->_data_read($mode, $fp);
  516.         fclose($fp);
  517.         $this->_data_close();
  518.         if(!$this->_readmsg()) return FALSE;
  519.         if(!$this->_checkCode()) return FALSE;
  520.         return $out;
  521.     }
  522.  
  523.     function fput($remotefile, $fp) {
  524.         if($this->_can_restore and $rest!=0) fseek($fp, $rest);
  525.         $pi=pathinfo($remotefile);
  526.         if($this->_type==FTP_ASCII or ($this->_type==FTP_AUTOASCII and in_array(strtoupper($pi["extension"]), $this->AutoAsciiExt))) $mode=FTP_ASCII;
  527.         else $mode=FTP_BINARY;
  528.         if(!$this->_data_prepare($mode)) {
  529.             return FALSE;
  530.         }
  531.         if($this->_can_restore and $rest!=0) $this->restore($rest);
  532.         if(!$this->_exec("STOR ".$remotefile, "put")) {
  533.             $this->_data_close();
  534.             return FALSE;
  535.         }
  536.         if(!$this->_checkCode()) {
  537.             $this->_data_close();
  538.             return FALSE;
  539.         }
  540.         $ret=$this->_data_write($mode, $fp);
  541.         $this->_data_close();
  542.         if(!$this->_readmsg()) return FALSE;
  543.         if(!$this->_checkCode()) return FALSE;
  544.         return $ret;
  545.     }
  546.  
  547.     function put($localfile, $remotefile=NULL, $rest=0) {
  548.         if(is_null($remotefile)) $remotefile=$localfile;
  549.         if (!file_exists($localfile)) {
  550.             $this->PushError("put","can't open local file", "No such file or directory \"".$localfile."\"");
  551.             return FALSE;
  552.         }
  553.         $fp = @fopen($localfile, "r");
  554.  
  555.         if (!$fp) {
  556.             $this->PushError("put","can't open local file", "Cannot read file \"".$localfile."\"");
  557.             return FALSE;
  558.         }
  559.         if($this->_can_restore and $rest!=0) fseek($fp, $rest);
  560.         $pi=pathinfo($localfile);
  561.         if($this->_type==FTP_ASCII or ($this->_type==FTP_AUTOASCII and in_array(strtoupper($pi["extension"]), $this->AutoAsciiExt))) $mode=FTP_ASCII;
  562.         else $mode=FTP_BINARY;
  563.         if(!$this->_data_prepare($mode)) {
  564.             fclose($fp);
  565.             return FALSE;
  566.         }
  567.         if($this->_can_restore and $rest!=0) $this->restore($rest);
  568.         if(!$this->_exec("STOR ".$remotefile, "put")) {
  569.             $this->_data_close();
  570.             fclose($fp);
  571.             return FALSE;
  572.         }
  573.         if(!$this->_checkCode()) {
  574.             $this->_data_close();
  575.             fclose($fp);
  576.             return FALSE;
  577.         }
  578.         $ret=$this->_data_write($mode, $fp);
  579.         fclose($fp);
  580.         $this->_data_close();
  581.         if(!$this->_readmsg()) return FALSE;
  582.         if(!$this->_checkCode()) return FALSE;
  583.         return $ret;
  584.     }
  585.  
  586.     function mput($local=".", $remote=NULL, $continious=false) {
  587.         $local=realpath($local);
  588.         if(!@file_exists($local)) {
  589.             $this->PushError("mput","can't open local folder", "Cannot stat folder \"".$local."\"");
  590.             return FALSE;
  591.         }
  592.         if(!is_dir($local)) return $this->put($local, $remote);
  593.         if(empty($remote)) $remote=".";
  594.         elseif(!$this->file_exists($remote) and !$this->mkdir($remote)) return FALSE;
  595.         if($handle = opendir($local)) {
  596.             $list=array();
  597.             while (false !== ($file = readdir($handle))) {
  598.                 if ($file != "." && $file != "..") $list[]=$file;
  599.             }
  600.             closedir($handle);
  601.         } else {
  602.             $this->PushError("mput","can't open local folder", "Cannot read folder \"".$local."\"");
  603.             return FALSE;
  604.         }
  605.         if(empty($list)) return TRUE;
  606.         $ret=true;
  607.         foreach($list as $el) {
  608.             if(is_dir($local."/".$el)) $t=$this->mput($local."/".$el, $remote."/".$el);
  609.             else $t=$this->put($local."/".$el, $remote."/".$el);
  610.             if(!$t) {
  611.                 $ret=FALSE;
  612.                 if(!$continious) break;
  613.             }
  614.         }
  615.         return $ret;
  616.  
  617.     }
  618.  
  619.     function mget($remote, $local=".", $continious=false) {
  620.         $list=$this->rawlist($remote, "-lA");
  621.         if($list===false) {
  622.             $this->PushError("mget","can't read remote folder list", "Can't read remote folder \"".$remote."\" contents");
  623.             return FALSE;
  624.         }
  625.         if(empty($list)) return true;
  626.         if(!@file_exists($local)) {
  627.             if(!@mkdir($local)) {
  628.                 $this->PushError("mget","can't create local folder", "Cannot create folder \"".$local."\"");
  629.                 return FALSE;
  630.             }
  631.         }
  632.         foreach($list as $k=>$v) {
  633.             $list[$k]=$this->parselisting($v);
  634.             if($list[$k]["name"]=="." or $list[$k]["name"]=="..") unset($list[$k]);
  635.         }
  636.         $ret=true;
  637.         foreach($list as $el) {
  638.             if($el["type"]=="d") {
  639.                 if(!$this->mget($remote."/".$el["name"], $local."/".$el["name"], $continious)) {
  640.                     $this->PushError("mget", "can't copy folder", "Can't copy remote folder \"".$remote."/".$el["name"]."\" to local \"".$local."/".$el["name"]."\"");
  641.                     $ret=false;
  642.                     if(!$continious) break;
  643.                 }
  644.             } else {
  645.                 if(!$this->get($remote."/".$el["name"], $local."/".$el["name"])) {
  646.                     $this->PushError("mget", "can't copy file", "Can't copy remote file \"".$remote."/".$el["name"]."\" to local \"".$local."/".$el["name"]."\"");
  647.                     $ret=false;
  648.                     if(!$continious) break;
  649.                 }
  650.             }
  651.             @chmod($local."/".$el["name"], $el["perms"]);
  652.             $t=strtotime($el["date"]);
  653.             if($t!==-1 and $t!==false) @touch($local."/".$el["name"], $t);
  654.         }
  655.         return $ret;
  656.     }
  657.  
  658.     function mdel($remote, $continious=false) {
  659.         $list=$this->rawlist($remote, "-la");
  660.         if($list===false) {
  661.             $this->PushError("mdel","can't read remote folder list", "Can't read remote folder \"".$remote."\" contents");
  662.             return false;
  663.         }
  664.  
  665.         foreach($list as $k=>$v) {
  666.             $list[$k]=$this->parselisting($v);
  667.             if($list[$k]["name"]=="." or $list[$k]["name"]=="..") unset($list[$k]);
  668.         }
  669.         $ret=true;
  670.  
  671.         foreach($list as $el) {
  672.             if ( empty($el) )
  673.                 continue;
  674.  
  675.             if($el["type"]=="d") {
  676.                 if(!$this->mdel($remote."/".$el["name"], $continious)) {
  677.                     $ret=false;
  678.                     if(!$continious) break;
  679.                 }
  680.             } else {
  681.                 if (!$this->delete($remote."/".$el["name"])) {
  682.                     $this->PushError("mdel", "can't delete file", "Can't delete remote file \"".$remote."/".$el["name"]."\"");
  683.                     $ret=false;
  684.                     if(!$continious) break;
  685.                 }
  686.             }
  687.         }
  688.  
  689.         if(!$this->rmdir($remote)) {
  690.             $this->PushError("mdel", "can't delete folder", "Can't delete remote folder \"".$remote."/".$el["name"]."\"");
  691.             $ret=false;
  692.         }
  693.         return $ret;
  694.     }
  695.  
  696.     function mmkdir($dir, $mode = 0777) {
  697.         if(empty($dir)) return FALSE;
  698.         if($this->is_exists($dir) or $dir == "/" ) return TRUE;
  699.         if(!$this->mmkdir(dirname($dir), $mode)) return false;
  700.         $r=$this->mkdir($dir, $mode);
  701.         $this->chmod($dir,$mode);
  702.         return $r;
  703.     }
  704.  
  705.     function glob($pattern, $handle=NULL) {
  706.         $path=$output=null;
  707.         if(PHP_OS=='WIN32') $slash='\\';
  708.         else $slash='/';
  709.         $lastpos=strrpos($pattern,$slash);
  710.         if(!($lastpos===false)) {
  711.             $path=substr($pattern,0,-$lastpos-1);
  712.             $pattern=substr($pattern,$lastpos);
  713.         } else $path=getcwd();
  714.         if(is_array($handle) and !empty($handle)) {
  715.             while($dir=each($handle)) {
  716.                 if($this->glob_pattern_match($pattern,$dir))
  717.                 $output[]=$dir;
  718.             }
  719.         } else {
  720.             $handle=@opendir($path);
  721.             if($handle===false) return false;
  722.             while($dir=readdir($handle)) {
  723.                 if($this->glob_pattern_match($pattern,$dir))
  724.                 $output[]=$dir;
  725.             }
  726.             closedir($handle);
  727.         }
  728.         if(is_array($output)) return $output;
  729.         return false;
  730.     }
  731.  
  732.     function glob_pattern_match($pattern,$string) {
  733.         $out=null;
  734.         $chunks=explode(';',$pattern);
  735.         foreach($chunks as $pattern) {
  736.             $escape=array('$','^','.','{','}','(',')','[',']','|');
  737.             while(strpos($pattern,'**')!==false)
  738.                 $pattern=str_replace('**','*',$pattern);
  739.             foreach($escape as $probe)
  740.                 $pattern=str_replace($probe,"\\$probe",$pattern);
  741.             $pattern=str_replace('?*','*',
  742.                 str_replace('*?','*',
  743.                     str_replace('*',".*",
  744.                         str_replace('?','.{1,1}',$pattern))));
  745.             $out[]=$pattern;
  746.         }
  747.         if(count($out)==1) return($this->glob_regexp("^$out[0]$",$string));
  748.         else {
  749.             foreach($out as $tester)
  750.                 if($this->my_regexp("^$tester$",$string)) return true;
  751.         }
  752.         return false;
  753.     }
  754.  
  755.     function glob_regexp($pattern,$probe) {
  756.         $sensitive=(PHP_OS!='WIN32');
  757.         return ($sensitive?
  758.             ereg($pattern,$probe):
  759.             eregi($pattern,$probe)
  760.         );
  761.     }
  762.  
  763.     function dirlist($remote) {
  764.         $list=$this->rawlist($remote, "-la");
  765.         if($list===false) {
  766.             $this->PushError("dirlist","can't read remote folder list", "Can't read remote folder \"".$remote."\" contents");
  767.             return false;
  768.         }
  769.  
  770.         $dirlist = array();
  771.         foreach($list as $k=>$v) {
  772.             $entry=$this->parselisting($v);
  773.             if ( empty($entry) )
  774.                 continue;
  775.  
  776.             if($entry["name"]=="." or $entry["name"]=="..")
  777.                 continue;
  778.  
  779.             $dirlist[$entry['name']] = $entry;
  780.         }
  781.  
  782.         return $dirlist;
  783.     }
  784. // <!-- --------------------------------------------------------------------------------------- -->
  785. // <!--       Private functions                                                                 -->
  786. // <!-- --------------------------------------------------------------------------------------- -->
  787.     function _checkCode() {
  788.         return ($this->_code<400 and $this->_code>0);
  789.     }
  790.  
  791.     function _list($arg="", $cmd="LIST", $fnction="_list") {
  792.         if(!$this->_data_prepare()) return false;
  793.         if(!$this->_exec($cmd.$arg, $fnction)) {
  794.             $this->_data_close();
  795.             return FALSE;
  796.         }
  797.         if(!$this->_checkCode()) {
  798.             $this->_data_close();
  799.             return FALSE;
  800.         }
  801.         $out="";
  802.         if($this->_code<200) {
  803.             $out=$this->_data_read();
  804.             $this->_data_close();
  805.             if(!$this->_readmsg()) return FALSE;
  806.             if(!$this->_checkCode()) return FALSE;
  807.             if($out === FALSE ) return FALSE;
  808.             $out=preg_split("/[".CRLF."]+/", $out, -1, PREG_SPLIT_NO_EMPTY);
  809. //            $this->SendMSG(implode($this->_eol_code[$this->OS_local], $out));
  810.         }
  811.         return $out;
  812.     }
  813.  
  814. // <!-- --------------------------------------------------------------------------------------- -->
  815. // <!-- Partie : gestion des erreurs                                                            -->
  816. // <!-- --------------------------------------------------------------------------------------- -->
  817. // Gnre une erreur pour traitement externe  la classe
  818.     function PushError($fctname,$msg,$desc=false){
  819.         $error=array();
  820.         $error['time']=time();
  821.         $error['fctname']=$fctname;
  822.         $error['msg']=$msg;
  823.         $error['desc']=$desc;
  824.         if($desc) $tmp=' ('.$desc.')'; else $tmp='';
  825.         $this->SendMSG($fctname.': '.$msg.$tmp);
  826.         return(array_push($this->_error_array,$error));
  827.     }
  828.  
  829. // Rcupre une erreur externe
  830.     function PopError(){
  831.         if(count($this->_error_array)) return(array_pop($this->_error_array));
  832.             else return(false);
  833.     }
  834. }
  835.  
  836. $mod_sockets=TRUE;
  837. if (!extension_loaded('sockets')) {
  838.     $prefix = (PHP_SHLIB_SUFFIX == 'dll') ? 'php_' : '';
  839.     if(!@dl($prefix . 'sockets.' . PHP_SHLIB_SUFFIX)) $mod_sockets=FALSE;
  840. }
  841. require_once "class-ftp-".($mod_sockets?"sockets":"pure").".php";
  842. ?>
  843.