/wp-admin/includes/class-ftp.php

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