ftp_base

PemFTP base class.

Defined (1)

The class is defined in the following location(s).

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