diff --git a/wp-admin/includes/class-ftp-pure.php b/wp-admin/includes/class-ftp-pure.php
new file mode 100644
index 0000000000..d8fad78ba0
--- /dev/null
+++ b/wp-admin/includes/class-ftp-pure.php
@@ -0,0 +1,163 @@
+__construct($verb, $le);
+ }
+
+ function __construct($verb=FALSE, $le=FALSE) {
+ parent::__construct(false, $verb, $le);
+ }
+
+//
+//
+//
+
+ function _settimeout($sock) {
+ if(!@stream_set_timeout($sock, $this->_timeout)) {
+ $this->PushError('_settimeout','socket set send timeout');
+ $this->_quit();
+ return FALSE;
+ }
+ return TRUE;
+ }
+
+ function _connect($host, $port) {
+ $this->SendMSG("Creating socket");
+ $sock = @fsockopen($host, $port, $errno, $errstr, $this->_timeout);
+ if (!$sock) {
+ $this->PushError('_connect','socket connect failed', $errstr." (".$errno.")");
+ return FALSE;
+ }
+ $this->_connected=true;
+ return $sock;
+ }
+
+ function _readmsg($fnction="_readmsg"){
+ if(!$this->_connected) {
+ $this->PushError($fnction, 'Connect first');
+ return FALSE;
+ }
+ $result=true;
+ $this->_message="";
+ $this->_code=0;
+ $go=true;
+ do {
+ $tmp=@fgets($this->_ftp_control_sock, 512);
+ if($tmp===false) {
+ $go=$result=false;
+ $this->PushError($fnction,'Read failed');
+ } else {
+ $this->_message.=$tmp;
+ if(preg_match("/^([0-9]{3})(-(.*[".CRLF."]{1,2})+\\1)? [^".CRLF."]+[".CRLF."]{1,2}$/", $this->_message, $regs)) $go=false;
+ }
+ } while($go);
+ if($this->LocalEcho) echo "GET < ".rtrim($this->_message, CRLF).CRLF;
+ $this->_code=(int)$regs[1];
+ return $result;
+ }
+
+ function _exec($cmd, $fnction="_exec") {
+ if(!$this->_ready) {
+ $this->PushError($fnction,'Connect first');
+ return FALSE;
+ }
+ if($this->LocalEcho) echo "PUT > ",$cmd,CRLF;
+ $status=@fputs($this->_ftp_control_sock, $cmd.CRLF);
+ if($status===false) {
+ $this->PushError($fnction,'socket write failed');
+ return FALSE;
+ }
+ $this->_lastaction=time();
+ if(!$this->_readmsg($fnction)) return FALSE;
+ return TRUE;
+ }
+
+ function _data_prepare($mode=FTP_ASCII) {
+ if(!$this->_settype($mode)) return FALSE;
+ if($this->_passive) {
+ if(!$this->_exec("PASV", "pasv")) {
+ $this->_data_close();
+ return FALSE;
+ }
+ if(!$this->_checkCode()) {
+ $this->_data_close();
+ return FALSE;
+ }
+ $ip_port = explode(",", ereg_replace("^.+ \\(?([0-9]{1,3},[0-9]{1,3},[0-9]{1,3},[0-9]{1,3},[0-9]+,[0-9]+)\\)?.*".CRLF."$", "\\1", $this->_message));
+ $this->_datahost=$ip_port[0].".".$ip_port[1].".".$ip_port[2].".".$ip_port[3];
+ $this->_dataport=(((int)$ip_port[4])<<8) + ((int)$ip_port[5]);
+ $this->SendMSG("Connecting to ".$this->_datahost.":".$this->_dataport);
+ $this->_ftp_data_sock=@fsockopen($this->_datahost, $this->_dataport, $errno, $errstr, $this->_timeout);
+ if(!$this->_ftp_data_sock) {
+ $this->PushError("_data_prepare","fsockopen fails", $errstr." (".$errno.")");
+ $this->_data_close();
+ return FALSE;
+ }
+ else $this->_ftp_data_sock;
+ } else {
+ $this->SendMSG("Only passive connections available!");
+ return FALSE;
+ }
+ return TRUE;
+ }
+
+ function _data_read($mode=FTP_ASCII, $fp=NULL) {
+ if(is_resource($fp)) $out=0;
+ else $out="";
+ if(!$this->_passive) {
+ $this->SendMSG("Only passive connections available!");
+ return FALSE;
+ }
+ while (!feof($this->_ftp_data_sock)) {
+ $block=fread($this->_ftp_data_sock, $this->_ftp_buff_size);
+ if($mode!=FTP_BINARY) $block=preg_replace("/\r\n|\r|\n/", $this->_eol_code[$this->OS_local], $block);
+ if(is_resource($fp)) $out+=fwrite($fp, $block, strlen($block));
+ else $out.=$block;
+ }
+ return $out;
+ }
+
+ function _data_write($mode=FTP_ASCII, $fp=NULL) {
+ if(is_resource($fp)) $out=0;
+ else $out="";
+ if(!$this->_passive) {
+ $this->SendMSG("Only passive connections available!");
+ return FALSE;
+ }
+ if(is_resource($fp)) {
+ while(!feof($fp)) {
+ $block=fread($fp, $this->_ftp_buff_size);
+ if(!$this->_data_write_block($mode, $block)) return false;
+ }
+ } elseif(!$this->_data_write_block($mode, $fp)) return false;
+ return TRUE;
+ }
+
+ function _data_write_block($mode, $block) {
+ if($mode!=FTP_BINARY) $block=preg_replace("/\r\n|\r|\n/", $this->_eol_code[$this->OS_remote], $block);
+ do {
+ if(($t=@fwrite($this->_ftp_data_sock, $block))===FALSE) {
+ $this->PushError("_data_write","Can't write to socket");
+ return FALSE;
+ }
+ $block=substr($block, $t);
+ } while(!empty($block));
+ return true;
+ }
+
+ function _data_close() {
+ @fclose($this->_ftp_data_sock);
+ $this->SendMSG("Disconnected data from remote host");
+ return TRUE;
+ }
+
+ function _quit($force=FALSE) {
+ if($this->_connected or $force) {
+ @fclose($this->_ftp_control_sock);
+ $this->_connected=false;
+ $this->SendMSG("Socket closed");
+ }
+ }
+}
+?>
diff --git a/wp-admin/includes/class-ftp-sockets.php b/wp-admin/includes/class-ftp-sockets.php
new file mode 100644
index 0000000000..5cd49f7adc
--- /dev/null
+++ b/wp-admin/includes/class-ftp-sockets.php
@@ -0,0 +1,224 @@
+__construct($verb, $le);
+ }
+
+ function __construct($verb=FALSE, $le=FALSE) {
+ parent::__construct(true, $verb, $le);
+ }
+
+//
+//
+//
+
+ function _settimeout($sock) {
+ if(!@socket_set_option($sock, SOL_SOCKET, SO_RCVTIMEO, array("sec"=>$this->_timeout, "usec"=>0))) {
+ $this->PushError('_connect','socket set receive timeout',socket_strerror(socket_last_error($sock)));
+ @socket_close($sock);
+ return FALSE;
+ }
+ if(!@socket_set_option($sock, SOL_SOCKET , SO_SNDTIMEO, array("sec"=>$this->_timeout, "usec"=>0))) {
+ $this->PushError('_connect','socket set send timeout',socket_strerror(socket_last_error($sock)));
+ @socket_close($sock);
+ return FALSE;
+ }
+ return true;
+ }
+
+ function _connect($host, $port) {
+ $this->SendMSG("Creating socket");
+ if(!($sock = @socket_create(AF_INET, SOCK_STREAM, SOL_TCP))) {
+ $this->PushError('_connect','socket create failed',socket_strerror(socket_last_error($sock)));
+ return FALSE;
+ }
+ if(!$this->_settimeout($sock)) return FALSE;
+ $this->SendMSG("Connecting to \"".$host.":".$port."\"");
+ if (!($res = @socket_connect($sock, $host, $port))) {
+ $this->PushError('_connect','socket connect failed',socket_strerror(socket_last_error($sock)));
+ @socket_close($sock);
+ return FALSE;
+ }
+ $this->_connected=true;
+ return $sock;
+ }
+
+ function _readmsg($fnction="_readmsg"){
+ if(!$this->_connected) {
+ $this->PushError($fnction,'Connect first');
+ return FALSE;
+ }
+ $result=true;
+ $this->_message="";
+ $this->_code=0;
+ $go=true;
+ do {
+ $tmp=@socket_read($this->_ftp_control_sock, 4096, PHP_BINARY_READ);
+ if($tmp===false) {
+ $go=$result=false;
+ $this->PushError($fnction,'Read failed', socket_strerror(socket_last_error($this->_ftp_control_sock)));
+ } else {
+ $this->_message.=$tmp;
+ $go = !preg_match("/^([0-9]{3})(-.+\\1)? [^".CRLF."]+".CRLF."$/Us", $this->_message, $regs);
+ }
+ } while($go);
+ if($this->LocalEcho) echo "GET < ".rtrim($this->_message, CRLF).CRLF;
+ $this->_code=(int)$regs[1];
+ return $result;
+ }
+
+ function _exec($cmd, $fnction="_exec") {
+ if(!$this->_ready) {
+ $this->PushError($fnction,'Connect first');
+ return FALSE;
+ }
+ if($this->LocalEcho) echo "PUT > ",$cmd,CRLF;
+ $status=@socket_write($this->_ftp_control_sock, $cmd.CRLF);
+ if($status===false) {
+ $this->PushError($fnction,'socket write failed', socket_strerror(socket_last_error($this->stream)));
+ return FALSE;
+ }
+ $this->_lastaction=time();
+ if(!$this->_readmsg($fnction)) return FALSE;
+ return TRUE;
+ }
+
+ function _data_prepare($mode=FTP_ASCII) {
+ if(!$this->_settype($mode)) return FALSE;
+ $this->SendMSG("Creating data socket");
+ $this->_ftp_data_sock = @socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
+ if ($this->_ftp_data_sock < 0) {
+ $this->PushError('_data_prepare','socket create failed',socket_strerror(socket_last_error($this->_ftp_data_sock)));
+ return FALSE;
+ }
+ if(!$this->_settimeout($this->_ftp_data_sock)) {
+ $this->_data_close();
+ return FALSE;
+ }
+ if($this->_passive) {
+ if(!$this->_exec("PASV", "pasv")) {
+ $this->_data_close();
+ return FALSE;
+ }
+ if(!$this->_checkCode()) {
+ $this->_data_close();
+ return FALSE;
+ }
+ $ip_port = explode(",", ereg_replace("^.+ \\(?([0-9]{1,3},[0-9]{1,3},[0-9]{1,3},[0-9]{1,3},[0-9]+,[0-9]+)\\)?.*".CRLF."$", "\\1", $this->_message));
+ $this->_datahost=$ip_port[0].".".$ip_port[1].".".$ip_port[2].".".$ip_port[3];
+ $this->_dataport=(((int)$ip_port[4])<<8) + ((int)$ip_port[5]);
+ $this->SendMSG("Connecting to ".$this->_datahost.":".$this->_dataport);
+ if(!@socket_connect($this->_ftp_data_sock, $this->_datahost, $this->_dataport)) {
+ $this->PushError("_data_prepare","socket_connect", socket_strerror(socket_last_error($this->_ftp_data_sock)));
+ $this->_data_close();
+ return FALSE;
+ }
+ else $this->_ftp_temp_sock=$this->_ftp_data_sock;
+ } else {
+ if(!@socket_getsockname($this->_ftp_control_sock, $addr, $port)) {
+ $this->PushError("_data_prepare","can't get control socket information", socket_strerror(socket_last_error($this->_ftp_control_sock)));
+ $this->_data_close();
+ return FALSE;
+ }
+ if(!@socket_bind($this->_ftp_data_sock,$addr)){
+ $this->PushError("_data_prepare","can't bind data socket", socket_strerror(socket_last_error($this->_ftp_data_sock)));
+ $this->_data_close();
+ return FALSE;
+ }
+ if(!@socket_listen($this->_ftp_data_sock)) {
+ $this->PushError("_data_prepare","can't listen data socket", socket_strerror(socket_last_error($this->_ftp_data_sock)));
+ $this->_data_close();
+ return FALSE;
+ }
+ if(!@socket_getsockname($this->_ftp_data_sock, $this->_datahost, $this->_dataport)) {
+ $this->PushError("_data_prepare","can't get data socket information", socket_strerror(socket_last_error($this->_ftp_data_sock)));
+ $this->_data_close();
+ return FALSE;
+ }
+ if(!$this->_exec('PORT '.str_replace('.',',',$this->_datahost.'.'.($this->_dataport>>8).'.'.($this->_dataport&0x00FF)), "_port")) {
+ $this->_data_close();
+ return FALSE;
+ }
+ if(!$this->_checkCode()) {
+ $this->_data_close();
+ return FALSE;
+ }
+ }
+ return TRUE;
+ }
+
+ function _data_read($mode=FTP_ASCII, $fp=NULL) {
+ $NewLine=$this->_eol_code[$this->OS_local];
+ if(is_resource($fp)) $out=0;
+ else $out="";
+ if(!$this->_passive) {
+ $this->SendMSG("Connecting to ".$this->_datahost.":".$this->_dataport);
+ $this->_ftp_temp_sock=socket_accept($this->_ftp_data_sock);
+ if($this->_ftp_temp_sock===FALSE) {
+ $this->PushError("_data_read","socket_accept", socket_strerror(socket_last_error($this->_ftp_temp_sock)));
+ $this->_data_close();
+ return FALSE;
+ }
+ }
+
+ while(($block=@socket_read($this->_ftp_temp_sock, $this->_ftp_buff_size, PHP_BINARY_READ))!==false) {
+ if($block==="") break;
+ if($mode!=FTP_BINARY) $block=preg_replace("/\r\n|\r|\n/", $this->_eol_code[$this->OS_local], $block);
+ if(is_resource($fp)) $out+=fwrite($fp, $block, strlen($block));
+ else $out.=$block;
+ }
+ return $out;
+ }
+
+ function _data_write($mode=FTP_ASCII, $fp=NULL) {
+ $NewLine=$this->_eol_code[$this->OS_local];
+ if(is_resource($fp)) $out=0;
+ else $out="";
+ if(!$this->_passive) {
+ $this->SendMSG("Connecting to ".$this->_datahost.":".$this->_dataport);
+ $this->_ftp_temp_sock=socket_accept($this->_ftp_data_sock);
+ if($this->_ftp_temp_sock===FALSE) {
+ $this->PushError("_data_write","socket_accept", socket_strerror(socket_last_error($this->_ftp_temp_sock)));
+ $this->_data_close();
+ return false;
+ }
+ }
+ if(is_resource($fp)) {
+ while(!feof($fp)) {
+ $block=fread($fp, $this->_ftp_buff_size);
+ if(!$this->_data_write_block($mode, $block)) return false;
+ }
+ } elseif(!$this->_data_write_block($mode, $fp)) return false;
+ return true;
+ }
+
+ function _data_write_block($mode, $block) {
+ if($mode!=FTP_BINARY) $block=preg_replace("/\r\n|\r|\n/", $this->_eol_code[$this->OS_remote], $block);
+ do {
+ if(($t=@socket_write($this->_ftp_temp_sock, $block))===FALSE) {
+ $this->PushError("_data_write","socket_write", socket_strerror(socket_last_error($this->_ftp_temp_sock)));
+ $this->_data_close();
+ return FALSE;
+ }
+ $block=substr($block, $t);
+ } while(!empty($block));
+ return true;
+ }
+
+ function _data_close() {
+ @socket_close($this->_ftp_temp_sock);
+ @socket_close($this->_ftp_data_sock);
+ $this->SendMSG("Disconnected data from remote host");
+ return TRUE;
+ }
+
+ function _quit() {
+ if($this->_connected) {
+ @socket_close($this->_ftp_control_sock);
+ $this->_connected=false;
+ $this->SendMSG("Socket closed");
+ }
+ }
+}
+?>
diff --git a/wp-admin/includes/class-ftp.php b/wp-admin/includes/class-ftp.php
index cd1c584783..634ac480bf 100644
--- a/wp-admin/includes/class-ftp.php
+++ b/wp-admin/includes/class-ftp.php
@@ -1,560 +1,830 @@
_resetError();
-
- $err_no = 0;
- $err_msg = "";
- $this->controlSocket = @fsockopen($host, $port, $err_no, $err_msg, $timeout) or $this->_setError(-1,"fsockopen failed");
- if ($err_no<>0) $this->setError($err_no,$err_msg);
-
- if ($this->_isError()) return false;
-
- @socket_set_timeout($this->controlSocket,$timeout) or $this->_setError(-1,"socket_set_timeout failed");
- if ($this->_isError()) return false;
-
- $this->_waitForResult();
- if ($this->_isError()) return false;
-
- return $this->getLastResult() == FTP_SERVICE_READY;
- }
-
- function isConnected() {
- return $this->controlSocket != NULL;
- }
-
- function disconnect() {
- if (!$this->isConnected()) return;
- @fclose($this->controlSocket);
- }
-
- function close() { //Closes an FTP connection
- $this->disconnect();
- }
-
- function login($user, $pass) { //Logs in to an FTP connection
- $this->_resetError();
-
- $this->_printCommand("USER $user");
- if ($this->_isError()) return false;
-
- $this->_waitForResult();
- if ($this->_isError()) return false;
-
- if ($this->getLastResult() == FTP_PASSWORD_NEEDED){
- $this->_printCommand("PASS $pass");
- if ($this->_isError()) return FALSE;
-
- $this->_waitForResult();
- if ($this->_isError()) return FALSE;
- }
-
- $result = $this->getLastResult() == FTP_USER_LOGGED_IN;
- return $result;
- }
-
- function cdup() { //Changes to the parent directory
- $this->_resetError();
-
- $this->_printCommand("CDUP");
- $this->_waitForResult();
- $lr = $this->getLastResult();
- if ($this->_isError()) return FALSE;
- return ($lr==FTP_FILE_ACTION_OK || $lr==FTP_COMMAND_OK);
- }
-
- function cwd($path) {
- $this->_resetError();
-
- $this->_printCommand("CWD $path");
- $this->_waitForResult();
- $lr = $this->getLastResult();
- if ($this->_isError()) return FALSE;
- return ($lr==FTP_FILE_ACTION_OK || $lr==FTP_COMMAND_OK);
- }
-
- function cd($path) {
- return $this->cwd($path);
- }
-
- function chdir($path) { //Changes directories on a FTP server
- return $this->cwd($path);
- }
-
- function chmod($mode,$filename) { //Set permissions on a file via FTP
- return $this->site("CHMOD $mode $filename");
- }
-
- function delete($filename) { //Deletes a file on the FTP server
- $this->_resetError();
-
- $this->_printCommand("DELE $filename");
- $this->_waitForResult();
- $lr = $this->getLastResult();
- if ($this->_isError()) return FALSE;
- return ($lr==FTP_FILE_ACTION_OK || $lr==FTP_COMMAND_OK);
- }
-
- function exec($cmd) { //Requests execution of a program on the FTP server
- return $this->site("EXEC $cmd");
- }
-
- function fget($fp,$remote,$mode=FTP_BINARY,$resumepos=0) { //Downloads a file from the FTP server and saves to an open file
- $this->_resetError();
-
- $type = "I";
- if ($mode==FTP_ASCII) $type = "A";
-
- $this->_printCommand("TYPE $type");
- $this->_waitForResult();
- $lr = $this->getLastResult();
- if ($this->_isError()) return FALSE;
-
- $result = $this->_download("RETR $remote");
- if ($result) {
- fwrite($fp,$result);
- }
- return $result;
- }
-
- function fput($remote,$resource,$mode=FTP_BINARY,$startpos=0) { //Uploads from an open file to the FTP server
- $this->_resetError();
-
- $type = "I";
- if ($mode==FTP_ASCII) $type = "A";
-
- $this->_printCommand("TYPE $type");
- $this->_waitForResult();
- $lr = $this->getLastResult();
- if ($this->_isError()) return FALSE;
-
- if ($startpos>0) fseek($resource,$startpos);
- $result = $this->_uploadResource("STOR $remote",$resource);
- return $result;
- }
-
- function get_option($option) { //Retrieves various runtime behaviours of the current FTP stream
- $this->_resetError();
-
- switch ($option) {
- case "FTP_TIMEOUT_SEC" : return FTP_TIMEOUT;
- case "PHP_FTP_OPT_AUTOSEEK" : return FALSE;
- }
- setError(-1,"Unknown option: $option");
- return false;
- }
-
- function get($locale,$remote,$mode=FTP_BINARY,$resumepos=0) { //Downloads a file from the FTP server
- if (!($fp = @fopen($locale,"wb"))) return FALSE;
- $result = $this->fget($fp,$remote,$mode,$resumepos);
- @fclose($fp);
- if (!$result) @unlink($locale);
- return $result;
- }
- function mdtm($name) { //Returns the last modified time of the given file
- $this->_resetError();
-
- $this->_printCommand("MDTM $name");
- $this->_waitForResult();
- $lr = $this->getLastResult();
- if ($this->_isError()) return FALSE;
- if ($lr!=FTP_FILE_STATUS) return FALSE;
- $subject = trim(substr($this->lastLine,4));
- $lucifer = array();
- if (preg_match("/([0-9][0-9][0-9][0-9])([0-9][0-9])([0-9][0-9])([0-9][0-9])([0-9][0-9])([0-9][0-9])/",$subject,$lucifer))
- return mktime($lucifer[4],$lucifer[5],$lucifer[6],$lucifer[2],$lucifer[3],$lucifer[1],0);
- return FALSE;
- }
-
- function mkdir($name) { //Creates a directory
- $this->_resetError();
-
- $this->_printCommand("MKD $name");
- $this->_waitForResult();
- $lr = $this->getLastResult();
- if ($this->_isError()) return FALSE;
- return ($lr==FTP_PATHNAME || $lr==FTP_FILE_ACTION_OK || $lr==FTP_COMMAND_OK);
- }
-
- function nb_continue() { //Continues retrieving/sending a file (non-blocking)
- $this->_resetError();
- // todo
- }
-
- function nb_fget() { //Retrieves a file from the FTP server and writes it to an open file (non-blocking)
- $this->_resetError();
- // todo
- }
-
- function nb_fput() { //Stores a file from an open file to the FTP server (non-blocking)
- $this->_resetError();
- // todo
- }
-
- function nb_get() { //Retrieves a file from the FTP server and writes it to a local file (non-blocking)
- $this->_resetError();
- // todo
- }
-
- function nb_put() { //Stores a file on the FTP server (non-blocking)
- $this->_resetError();
- // todo
- }
-
- function nlist($remote_filespec="") { //Returns a list of files in the given directory
- $this->_resetError();
- $result = $this->_download(trim("NLST $remote_filespec"));
- return ($result !== FALSE) ? explode("\n",str_replace("\r","",trim($result))) : $result;
- }
-
- function pasv($pasv) { //Turns passive mode on or off
- if (!$pasv) {
- $this->_setError("Active (PORT) mode is not supported");
- return false;
- }
- return true;
- }
-
- function put($remote,$local,$mode=FTP_BINARY,$startpos=0) { //Uploads a file to the FTP server
- if (!($fp = @fopen($local,"rb"))) return FALSE;
- $result = $this->fput($remote,$fp,$mode,$startpos);
- @fclose($fp);
- return $result;
- }
-
- function pwd() { //Returns the current directory name
- $this->_resetError();
-
- $this->_printCommand("PWD");
- $this->_waitForResult();
- $lr = $this->getLastResult();
- if ($this->_isError()) return FALSE;
- if ($lr!=FTP_PATHNAME) return FALSE;
- $subject = trim(substr($this->lastLine,4));
- $lucifer = array();
- if (preg_match("/\"(.*)\"/",$subject,$lucifer)) return $lucifer[1];
- return FALSE;
- }
-
- function quit() { //Alias of close
- $this->close();
- }
-
- function raw($cmd) { //Sends an arbitrary command to an FTP server
- $this->_resetError();
-
- $this->_printCommand($cmd);
- $this->_waitForResult();
- $this->getLastResult();
- return array($this->lastLine);
- }
-
- function rawlist($remote_filespec="") { //Returns a detailed list of files in the given directory
- $this->_resetError();
- $result = $this->_download(trim("LIST $remote_filespec"));
- return ($result !== FALSE) ? explode("\n",str_replace("\r","",trim($result))) : $result;
- }
-
- function ls($remote_filespec="") { //Returns a parsed rawlist in an assoc array
- $a = $this->rawlist($remote_filespec);
- if (!$a) return $a;
- $systype = $this->systype();
- $is_windows = stristr($systype,"WIN")!==FALSE;
- $b = array();
- while (list($i,$line) = each($a)) {
- if ($is_windows && preg_match("/([0-9]{2})-([0-9]{2})-([0-9]{2}) +([0-9]{2}):([0-9]{2})(AM|PM) +([0-9]+|
) +(.+)/",$line,$lucifer)) {
- $b[$i] = array();
- if ($lucifer[3]<70) { $lucifer[3]+=2000; } else { $lucifer[3]+=1900; } // 4digit year fix
- $b[$i]['isdir'] = ($lucifer[7]=="");
- $b[$i]['size'] = $lucifer[7];
- $b[$i]['month'] = $lucifer[1];
- $b[$i]['day'] = $lucifer[2];
- $b[$i]['year'] = $lucifer[3];
- $b[$i]['hour'] = $lucifer[4];
- $b[$i]['minute'] = $lucifer[5];
- $b[$i]['time'] = @mktime($lucifer[4]+(strcasecmp($lucifer[6],"PM")==0?12:0),$lucifer[5],0,$lucifer[1],$lucifer[2],$lucifer[3]);
- $b[$i]['am/pm'] = $lucifer[6];
- $b[$i]['name'] = $lucifer[8];
- } else if (!$is_windows && $lucifer=preg_split("/[ ]/",$line,9,PREG_SPLIT_NO_EMPTY)) {
- echo $line."\n";
- $lcount=count($lucifer);
- if ($lcount<8) continue;
- $b[$i] = array();
- $b[$i]['isdir'] = $lucifer[0]{0} === "d";
- $b[$i]['islink'] = $lucifer[0]{0} === "l";
- $b[$i]['perms'] = $lucifer[0];
- $b[$i]['number'] = $lucifer[1];
- $b[$i]['owner'] = $lucifer[2];
- $b[$i]['group'] = $lucifer[3];
- $b[$i]['size'] = $lucifer[4];
- if ($lcount==8) {
- sscanf($lucifer[5],"%d-%d-%d",$b[$i]['year'],$b[$i]['month'],$b[$i]['day']);
- sscanf($lucifer[6],"%d:%d",$b[$i]['hour'],$b[$i]['minute']);
- $b[$i]['time'] = @mktime($b[$i]['hour'],$b[$i]['minute'],0,$b[$i]['month'],$b[$i]['day'],$b[$i]['year']);
- $b[$i]['name'] = $lucifer[7];
- } else {
- $b[$i]['month'] = $lucifer[5];
- $b[$i]['day'] = $lucifer[6];
- if (preg_match("/([0-9]{2}):([0-9]{2})/",$lucifer[7],$l2)) {
- $b[$i]['year'] = date("Y");
- $b[$i]['hour'] = $l2[1];
- $b[$i]['minute'] = $l2[2];
- } else {
- $b[$i]['year'] = $lucifer[7];
- $b[$i]['hour'] = 0;
- $b[$i]['minute'] = 0;
- }
- $b[$i]['time'] = strtotime(sprintf("%d %s %d %02d:%02d",$b[$i]['day'],$b[$i]['month'],$b[$i]['year'],$b[$i]['hour'],$b[$i]['minute']));
- $b[$i]['name'] = $lucifer[8];
- }
- }
- }
- return $b;
- }
-
- function rename($from,$to) { //Renames a file on the FTP server
- $this->_resetError();
-
- $this->_printCommand("RNFR $from");
- $this->_waitForResult();
- $lr = $this->getLastResult();
- if ($this->_isError()) return FALSE;
- $this->_printCommand("RNTO $to");
- $this->_waitForResult();
- $lr = $this->getLastResult();
- if ($this->_isError()) return FALSE;
- return ($lr==FTP_FILE_ACTION_OK || $lr==FTP_COMMAND_OK);
- }
-
- function rmdir($name) { //Removes a directory
- $this->_resetError();
-
- $this->_printCommand("RMD $name");
- $this->_waitForResult();
- $lr = $this->getLastResult();
- if ($this->_isError()) return FALSE;
- return ($lr==FTP_FILE_ACTION_OK || $lr==FTP_COMMAND_OK);
- }
-
- function set_option() { //Set miscellaneous runtime FTP options
- $this->_resetError();
- $this->_setError(-1,"set_option not supported");
- return false;
- }
-
- function site($cmd) { //Sends a SITE command to the server
- $this->_resetError();
-
- $this->_printCommand("SITE $cmd");
- $this->_waitForResult();
- $lr = $this->getLastResult();
- if ($this->_isError()) return FALSE;
- return true;
- }
-
- function size($name) { //Returns the size of the given file
- $this->_resetError();
-
- $this->_printCommand("SIZE $name");
- $this->_waitForResult();
- $lr = $this->getLastResult();
- if ($this->_isError()) return FALSE;
- return $lr==FTP_FILE_STATUS ? trim(substr($this->lastLine,4)) : FALSE;
- }
-
- function ssl_connect() { //Opens an Secure SSL-FTP connection
- $this->_resetError();
- $this->_setError(-1,"ssl_connect not supported");
- return false;
- }
-
- function systype() { // Returns the system type identifier of the remote FTP server
- $this->_resetError();
-
- $this->_printCommand("SYST");
- $this->_waitForResult();
- $lr = $this->getLastResult();
- if ($this->_isError()) return FALSE;
- return $lr==FTP_NAME_SYSTEM_TYPE ? trim(substr($this->lastLine,4)) : FALSE;
- }
-
- function getLastResult() {
- $this->newResult = FALSE;
- return $this->lastResult;
- }
-
- /* private */
- function _hasNewResult() {
- return $this->newResult;
- }
-
- /* private */
- function _waitForResult() {
- while(!$this->_hasNewResult() && $this->_readln()!==FALSE && !$this->_isError()) { /* noop */ }
- }
-
- /* private */
- function _readln() {
- $line = fgets($this->controlSocket);
- if ($line === FALSE) {
- $this->_setError(-1,"fgets failed in _readln");
- return FALSE;
- }
- if (strlen($line)==0) return $line;
-
- $lucifer = array();
- if (preg_match("/^[0-9][0-9][0-9] /",$line,$lucifer)) {
- //its a resultline
- $this->lastResult = intval($lucifer[0]);
- $this->newResult = TRUE;
- if (substr($lucifer[0],0,1)=='5') {
- $this->_setError($this->lastResult,trim(substr($line,4)));
- }
- }
-
- $this->lastLine = trim($line);
- $this->lastLines[] = "< ".trim($line);
- return $line;
- }
-
- /* private */
- function _printCommand($line) {
- $this->lastLines[] = "> ".$line;
- fwrite($this->controlSocket,$line."\r\n");
- fflush($this->controlSocket);
- }
-
- /* private */
- function _pasv() {
- $this->_resetError();
- $this->_printCommand("PASV");
- $this->_waitForResult();
- $lr = $this->getLastResult();
- if ($this->_isError()) return FALSE;
- if ($lr!=FTP_PASSIVE_MODE) return FALSE;
- $subject = trim(substr($this->lastLine,4));
- $lucifer = array();
- if (preg_match("/\\((\d{1,3}),(\d{1,3}),(\d{1,3}),(\d{1,3}),(\d{1,3}),(\d{1,3})\\)/",$subject,$lucifer)) {
- $this->pasvAddr=$lucifer;
-
- $host = sprintf("%d.%d.%d.%d",$lucifer[1],$lucifer[2],$lucifer[3],$lucifer[4]);
- $port = $lucifer[5]*256 + $lucifer[6];
-
- $err_no=0;
- $err_msg="";
- $passiveConnection = fsockopen($host,$port,$err_no,$err_msg, FTP_TIMEOUT);
- if ($err_no!=0) {
- $this->_setError($err_no,$err_msg);
- return FALSE;
- }
-
- return $passiveConnection;
- }
- return FALSE;
- }
-
- /* private */
- function _download($cmd) {
- if (!($passiveConnection = $this->_pasv())) return FALSE;
- $this->_printCommand($cmd);
- $this->_waitForResult();
- $lr = $this->getLastResult();
- if (!$this->_isError()) {
- $result = "";
- while (!feof($passiveConnection)) {
- $result .= fgets($passiveConnection);
- }
- fclose($passiveConnection);
- $this->_waitForResult();
- $lr = $this->getLastResult();
- return ($lr==FTP_FILE_TRANSFER_OK) || ($lr==FTP_FILE_ACTION_OK) || ($lr==FTP_COMMAND_OK) ? $result : FALSE;
- } else {
- fclose($passiveConnection);
- return FALSE;
- }
- }
-
- /* upload */
- function _uploadResource($cmd,$resource) {
- if (!($passiveConnection = $this->_pasv())) return FALSE;
- $this->_printCommand($cmd);
- $this->_waitForResult();
- $lr = $this->getLastResult();
- if (!$this->_isError()) {
- $result = "";
- while (!feof($resource)) {
- $buf = fread($resource,1024);
- fwrite($passiveConnection,$buf);
- }
- fclose($passiveConnection);
- $this->_waitForResult();
- $lr = $this->getLastResult();
- return ($lr==FTP_FILE_TRANSFER_OK) || ($lr==FTP_FILE_ACTION_OK) || ($lr==FTP_COMMAND_OK) ? $result : FALSE;
- } else {
- fclose($passiveConnection);
- return FALSE;
- }
- }
-
- /* private */
- function _resetError() {
- $this->error_no = NULL;
- $this->error_msg = NULL;
- }
-
- /* private */
- function _setError($no,$msg) {
- if (is_array($this->error_no)) {
- $this->error_no[] = $no;
- $this->error_msg[] = $msg;
- } else if ($this->error_no!=NULL) {
- $this->error_no = array($this->error_no,$no);
- $this->error_msg = array($this->error_msg,$msg);
- } else {
- $this->error_no = $no;
- $this->error_msg = $msg;
- }
- }
-
- /* private */
- function _isError() {
- return ($this->error_no != NULL) && ($this->error_no !== 0);
- }
+ var $_error_array;
+ var $AuthorizedTransferMode;
+ var $OS_FullName;
+ var $_eol_code;
+ var $AutoAsciiExt;
+ /* Constructor */
+ function ftp_base($port_mode=FALSE) {
+ $this->__construct($port_mode);
}
-?>
\ No newline at end of file
+
+ function __construct($port_mode=FALSE, $verb=FALSE, $le=FALSE) {
+ $this->LocalEcho=$le;
+ $this->Verbose=$verb;
+ $this->_lastaction=NULL;
+ $this->_error_array=array();
+ $this->_eol_code=array(FTP_OS_Unix=>"\n", FTP_OS_Mac=>"\r", FTP_OS_Windows=>"\r\n");
+ $this->AuthorizedTransferMode=array(FTP_AUTOASCII, FTP_ASCII, FTP_BINARY);
+ $this->OS_FullName=array(FTP_OS_Unix => 'UNIX', FTP_OS_Windows => 'WINDOWS', FTP_OS_Mac => 'MACOS');
+ $this->AutoAsciiExt=array("ASP","BAT","C","CPP","CSS","CSV","JS","H","HTM","HTML","SHTML","INI","LOG","PHP3","PHTML","PL","PERL","SH","SQL","TXT");
+ $this->_port_available=($port_mode==TRUE);
+ $this->SendMSG("Staring FTP client class".($this->_port_available?"":" without PORT mode support"));
+ $this->_connected=FALSE;
+ $this->_ready=FALSE;
+ $this->_can_restore=FALSE;
+ $this->_code=0;
+ $this->_message="";
+ $this->_ftp_buff_size=4096;
+ $this->_curtype=NULL;
+ $this->SetUmask(0022);
+ $this->SetType(FTP_AUTOASCII);
+ $this->SetTimeout(30);
+ $this->Passive(!$this->_port_available);
+ $this->_login="anonymous";
+ $this->_password="anon@ftp.com";
+ $this->_features=array();
+ $this->OS_local=FTP_OS_Unix;
+ $this->OS_remote=FTP_OS_Unix;
+ $this->features=array();
+ if(strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') $this->OS_local=FTP_OS_Windows;
+ elseif(strtoupper(substr(PHP_OS, 0, 3)) === 'MAC') $this->OS_local=FTP_OS_Mac;
+ }
+
+//
+//
+//
+
+ function parselisting($line) {
+ $is_windows = ($this->OS_remote == FTP_OS_Windows);
+ if ($is_windows && preg_match("/([0-9]{2})-([0-9]{2})-([0-9]{2}) +([0-9]{2}):([0-9]{2})(AM|PM) +([0-9]+|) +(.+)/",$line,$lucifer)) {
+ $b = array();
+ if ($lucifer[3]<70) { $lucifer[3]+=2000; } else { $lucifer[3]+=1900; } // 4digit year fix
+ $b['isdir'] = ($lucifer[7]=="");
+ if ( $b['isdir'] )
+ $b['type'] = 'd';
+ else
+ $b['type'] = 'f';
+ $b['size'] = $lucifer[7];
+ $b['month'] = $lucifer[1];
+ $b['day'] = $lucifer[2];
+ $b['year'] = $lucifer[3];
+ $b['hour'] = $lucifer[4];
+ $b['minute'] = $lucifer[5];
+ $b['time'] = @mktime($lucifer[4]+(strcasecmp($lucifer[6],"PM")==0?12:0),$lucifer[5],0,$lucifer[1],$lucifer[2],$lucifer[3]);
+ $b['am/pm'] = $lucifer[6];
+ $b['name'] = $lucifer[8];
+ } else if (!$is_windows && $lucifer=preg_split("/[ ]/",$line,9,PREG_SPLIT_NO_EMPTY)) {
+ //echo $line."\n";
+ $lcount=count($lucifer);
+ if ($lcount<8) return '';
+ $b = array();
+ $b['isdir'] = $lucifer[0]{0} === "d";
+ $b['islink'] = $lucifer[0]{0} === "l";
+ if ( $b['isdir'] )
+ $b['type'] = 'd';
+ elseif ( $b['islink'] )
+ $b['type'] = 'l';
+ else
+ $b['type'] = 'f';
+ $b['perms'] = $lucifer[0];
+ $b['number'] = $lucifer[1];
+ $b['owner'] = $lucifer[2];
+ $b['group'] = $lucifer[3];
+ $b['size'] = $lucifer[4];
+ if ($lcount==8) {
+ sscanf($lucifer[5],"%d-%d-%d",$b['year'],$b['month'],$b['day']);
+ sscanf($lucifer[6],"%d:%d",$b['hour'],$b['minute']);
+ $b['time'] = @mktime($b['hour'],$b['minute'],0,$b['month'],$b['day'],$b['year']);
+ $b['name'] = $lucifer[7];
+ } else {
+ $b['month'] = $lucifer[5];
+ $b['day'] = $lucifer[6];
+ if (preg_match("/([0-9]{2}):([0-9]{2})/",$lucifer[7],$l2)) {
+ $b['year'] = date("Y");
+ $b['hour'] = $l2[1];
+ $b['minute'] = $l2[2];
+ } else {
+ $b['year'] = $lucifer[7];
+ $b['hour'] = 0;
+ $b['minute'] = 0;
+ }
+ $b['time'] = strtotime(sprintf("%d %s %d %02d:%02d",$b['day'],$b['month'],$b['year'],$b['hour'],$b['minute']));
+ $b['name'] = $lucifer[8];
+ }
+ }
+
+ return $b;
+ }
+
+ function SendMSG($message = "", $crlf=true) {
+ if ($this->Verbose) {
+ echo $message.($crlf?CRLF:"");
+ flush();
+ }
+ return TRUE;
+ }
+
+ function SetType($mode=FTP_AUTOASCII) {
+ if(!in_array($mode, $this->AuthorizedTransferMode)) {
+ $this->SendMSG("Wrong type");
+ return FALSE;
+ }
+ $this->_type=$mode;
+ $this->SendMSG("Transfer type: ".($this->_type==FTP_BINARY?"binary":($this->_type==FTP_ASCII?"ASCII":"auto ASCII") ) );
+ return TRUE;
+ }
+
+ function _settype($mode=FTP_ASCII) {
+ if($this->_ready) {
+ if($mode==FTP_BINARY) {
+ if($this->_curtype!=FTP_BINARY) {
+ if(!$this->_exec("TYPE I", "SetType")) return FALSE;
+ $this->_curtype=FTP_BINARY;
+ }
+ } elseif($this->_curtype!=FTP_ASCII) {
+ if(!$this->_exec("TYPE A", "SetType")) return FALSE;
+ $this->_curtype=FTP_ASCII;
+ }
+ } else return FALSE;
+ return TRUE;
+ }
+
+ function Passive($pasv=NULL) {
+ if(is_null($pasv)) $this->_passive=!$this->_passive;
+ else $this->_passive=$pasv;
+ if(!$this->_port_available and !$this->_passive) {
+ $this->SendMSG("Only passive connections available!");
+ $this->_passive=TRUE;
+ return FALSE;
+ }
+ $this->SendMSG("Passive mode ".($this->_passive?"on":"off"));
+ return TRUE;
+ }
+
+ function SetServer($host, $port=21, $reconnect=true) {
+ if(!is_long($port)) {
+ $this->verbose=true;
+ $this->SendMSG("Incorrect port syntax");
+ return FALSE;
+ } else {
+ $ip=@gethostbyname($host);
+ $dns=@gethostbyaddr($host);
+ if(!$ip) $ip=$host;
+ if(!$dns) $dns=$host;
+ if(ip2long($ip) === -1) {
+ $this->SendMSG("Wrong host name/address \"".$host."\"");
+ return FALSE;
+ }
+ $this->_host=$ip;
+ $this->_fullhost=$dns;
+ $this->_port=$port;
+ $this->_dataport=$port-1;
+ }
+ $this->SendMSG("Host \"".$this->_fullhost."(".$this->_host."):".$this->_port."\"");
+ if($reconnect){
+ if($this->_connected) {
+ $this->SendMSG("Reconnecting");
+ if(!$this->quit(FTP_FORCE)) return FALSE;
+ if(!$this->connect()) return FALSE;
+ }
+ }
+ return TRUE;
+ }
+
+ function SetUmask($umask=0022) {
+ $this->_umask=$umask;
+ umask($this->_umask);
+ $this->SendMSG("UMASK 0".decoct($this->_umask));
+ return TRUE;
+ }
+
+ function SetTimeout($timeout=30) {
+ $this->_timeout=$timeout;
+ $this->SendMSG("Timeout ".$this->_timeout);
+ if($this->_connected)
+ if(!$this->_settimeout($this->_ftp_control_sock)) return FALSE;
+ return TRUE;
+ }
+
+ function connect($server=NULL) {
+ if(!empty($server)) {
+ if(!$this->SetServer($server)) return false;
+ }
+ if($this->_ready) return true;
+ $this->SendMsg('Local OS : '.$this->OS_FullName[$this->OS_local]);
+ if(!($this->_ftp_control_sock = $this->_connect($this->_host, $this->_port))) {
+ $this->SendMSG("Error : Cannot connect to remote host \"".$this->_fullhost." :".$this->_port."\"");
+ return FALSE;
+ }
+ $this->SendMSG("Connected to remote host \"".$this->_fullhost.":".$this->_port."\". Waiting for greeting.");
+ do {
+ if(!$this->_readmsg()) return FALSE;
+ if(!$this->_checkCode()) return FALSE;
+ $this->_lastaction=time();
+ } while($this->_code<200);
+ $this->_ready=true;
+ $syst=$this->systype();
+ if(!$syst) $this->SendMSG("Can't detect remote OS");
+ else {
+ if(preg_match("/win|dos|novell/i", $syst[0])) $this->OS_remote=FTP_OS_Windows;
+ elseif(preg_match("/os/i", $syst[0])) $this->OS_remote=FTP_OS_Mac;
+ elseif(preg_match("/(li|u)nix/i", $syst[0])) $this->OS_remote=FTP_OS_Unix;
+ else $this->OS_remote=FTP_OS_Mac;
+ $this->SendMSG("Remote OS: ".$this->OS_FullName[$this->OS_remote]);
+ }
+ if(!$this->features()) $this->SendMSG("Can't get features list. All supported - disabled");
+ else $this->SendMSG("Supported features: ".implode(", ", array_keys($this->_features)));
+ return TRUE;
+ }
+
+ function quit($force=false) {
+ if($this->_ready) {
+ if(!$this->_exec("QUIT") and !$force) return FALSE;
+ if(!$this->_checkCode() and !$force) return FALSE;
+ $this->_ready=false;
+ $this->SendMSG("Session finished");
+ }
+ $this->_quit();
+ return TRUE;
+ }
+
+ function login($user=NULL, $pass=NULL) {
+ if(!is_null($user)) $this->_login=$user;
+ else $this->_login="anonymous";
+ if(!is_null($pass)) $this->_password=$pass;
+ else $this->_password="anon@anon.com";
+ if(!$this->_exec("USER ".$this->_login, "login")) return FALSE;
+ if(!$this->_checkCode()) return FALSE;
+ if($this->_code!=230) {
+ if(!$this->_exec((($this->_code==331)?"PASS ":"ACCT ").$this->_password, "login")) return FALSE;
+ if(!$this->_checkCode()) return FALSE;
+ }
+ $this->SendMSG("Authentication succeeded");
+ if(empty($this->_features)) {
+ if(!$this->features()) $this->SendMSG("Can't get features list. All supported - disabled");
+ else $this->SendMSG("Supported features: ".implode(", ", array_keys($this->_features)));
+ }
+ return TRUE;
+ }
+
+ function pwd() {
+ if(!$this->_exec("PWD", "pwd")) return FALSE;
+ if(!$this->_checkCode()) return FALSE;
+ return ereg_replace("^[0-9]{3} \"(.+)\" .+".CRLF, "\\1", $this->_message);
+ }
+
+ function cdup() {
+ if(!$this->_exec("CDUP", "cdup")) return FALSE;
+ if(!$this->_checkCode()) return FALSE;
+ return true;
+ }
+
+ function chdir($pathname) {
+ if(!$this->_exec("CWD ".$pathname, "chdir")) return FALSE;
+ if(!$this->_checkCode()) return FALSE;
+ return TRUE;
+ }
+
+ function rmdir($pathname) {
+ if(!$this->_exec("RMD ".$pathname, "rmdir")) return FALSE;
+ if(!$this->_checkCode()) return FALSE;
+ return TRUE;
+ }
+
+ function mkdir($pathname) {
+ if(!$this->_exec("MKD ".$pathname, "mkdir")) return FALSE;
+ if(!$this->_checkCode()) return FALSE;
+ return TRUE;
+ }
+
+ function rename($from, $to) {
+ if(!$this->_exec("RNFR ".$from, "rename")) return FALSE;
+ if(!$this->_checkCode()) return FALSE;
+ if($this->_code==350) {
+ if(!$this->_exec("RNTO ".$to, "rename")) return FALSE;
+ if(!$this->_checkCode()) return FALSE;
+ } else return FALSE;
+ return TRUE;
+ }
+
+ function filesize($pathname) {
+ if(!isset($this->_features["SIZE"])) {
+ $this->PushError("filesize", "not supported by server");
+ return FALSE;
+ }
+ if(!$this->_exec("SIZE ".$pathname, "filesize")) return FALSE;
+ if(!$this->_checkCode()) return FALSE;
+ return ereg_replace("^[0-9]{3} ([0-9]+)".CRLF, "\\1", $this->_message);
+ }
+
+ function abort() {
+ if(!$this->_exec("ABOR", "abort")) return FALSE;
+ if(!$this->_checkCode()) {
+ if($this->_code!=426) return FALSE;
+ if(!$this->_readmsg("abort")) return FALSE;
+ if(!$this->_checkCode()) return FALSE;
+ }
+ return true;
+ }
+
+ function mdtm($pathname) {
+ if(!isset($this->_features["MDTM"])) {
+ $this->PushError("mdtm", "not supported by server");
+ return FALSE;
+ }
+ if(!$this->_exec("MDTM ".$pathname, "mdtm")) return FALSE;
+ if(!$this->_checkCode()) return FALSE;
+ $mdtm = ereg_replace("^[0-9]{3} ([0-9]+)".CRLF, "\\1", $this->_message);
+ $date = sscanf($mdtm, "%4d%2d%2d%2d%2d%2d");
+ $timestamp = mktime($date[3], $date[4], $date[5], $date[1], $date[2], $date[0]);
+ return $timestamp;
+ }
+
+ function systype() {
+ if(!$this->_exec("SYST", "systype")) return FALSE;
+ if(!$this->_checkCode()) return FALSE;
+ $DATA = explode(" ", $this->_message);
+ return array($DATA[1], $DATA[3]);
+ }
+
+ function delete($pathname) {
+ if(!$this->_exec("DELE ".$pathname, "delete")) return FALSE;
+ if(!$this->_checkCode()) return FALSE;
+ return TRUE;
+ }
+
+ function site($command, $fnction="site") {
+ if(!$this->_exec("SITE ".$command, $fnction)) return FALSE;
+ if(!$this->_checkCode()) return FALSE;
+ return TRUE;
+ }
+
+ function chmod($pathname, $mode) {
+ if(!$this->site( sprintf('CHMOD %o %s', $mode, $pathname), "chmod")) return FALSE;
+ return TRUE;
+ }
+
+ function restore($from) {
+ if(!isset($this->_features["REST"])) {
+ $this->PushError("restore", "not supported by server");
+ return FALSE;
+ }
+ if($this->_curtype!=FTP_BINARY) {
+ $this->PushError("restore", "can't restore in ASCII mode");
+ return FALSE;
+ }
+ if(!$this->_exec("REST ".$from, "resore")) return FALSE;
+ if(!$this->_checkCode()) return FALSE;
+ return TRUE;
+ }
+
+ function features() {
+ if(!$this->_exec("FEAT", "features")) return FALSE;
+ if(!$this->_checkCode()) return FALSE;
+ $f=preg_split("/[".CRLF."]+/", preg_replace("/[0-9]{3}[ -].*[".CRLF."]+/", "", $this->_message), -1, PREG_SPLIT_NO_EMPTY);
+ $this->_features=array();
+ foreach($f as $k=>$v) {
+ $v=explode(" ", trim($v));
+ $this->_features[array_shift($v)]=$v;;
+ }
+ return true;
+ }
+
+ function rawlist($pathname="", $arg="") {
+ return $this->_list(($arg?" ".$arg:"").($pathname?" ".$pathname:""), "LIST", "rawlist");
+ }
+
+ function nlist($pathname="") {
+ return $this->_list(($arg?" ".$arg:"").($pathname?" ".$pathname:""), "NLST", "nlist");
+ }
+
+ function is_exists($pathname) {
+ return $this->file_exists($pathname);
+ }
+
+ function file_exists($pathname) {
+ $exists=true;
+ if(!$this->_exec("RNFR ".$pathname, "rename")) $exists=FALSE;
+ else {
+ if(!$this->_checkCode()) $exists=FALSE;
+ $this->abort();
+ }
+ if($exists) $this->SendMSG("Remote file ".$pathname." exists");
+ else $this->SendMSG("Remote file ".$pathname." does not exist");
+ return $exists;
+ }
+
+ function fget($fp, $remotefile,$rest=0) {
+ if($this->_can_restore and $rest!=0) fseek($fp, $rest);
+ $pi=pathinfo($remotefile);
+ if($this->_type==FTP_ASCII or ($this->_type==FTP_AUTOASCII and in_array(strtoupper($pi["extension"]), $this->AutoAsciiExt))) $mode=FTP_ASCII;
+ else $mode=FTP_BINARY;
+ if(!$this->_data_prepare($mode)) {
+ return FALSE;
+ }
+ if($this->_can_restore and $rest!=0) $this->restore($rest);
+ if(!$this->_exec("RETR ".$remotefile, "get")) {
+ $this->_data_close();
+ return FALSE;
+ }
+ if(!$this->_checkCode()) {
+ $this->_data_close();
+ return FALSE;
+ }
+ $out=$this->_data_read($mode, $fp);
+ $this->_data_close();
+ if(!$this->_readmsg()) return FALSE;
+ if(!$this->_checkCode()) return FALSE;
+ return $out;
+ }
+
+ function get($remotefile, $localfile=NULL, $rest=0) {
+ if(is_null($localfile)) $localfile=$remotefile;
+ if (@file_exists($localfile)) $this->SendMSG("Warning : local file will be overwritten");
+ $fp = @fopen($localfile, "w");
+ if (!$fp) {
+ $this->PushError("get","can't open local file", "Cannot create \"".$localfile."\"");
+ return FALSE;
+ }
+ if($this->_can_restore and $rest!=0) fseek($fp, $rest);
+ $pi=pathinfo($remotefile);
+ if($this->_type==FTP_ASCII or ($this->_type==FTP_AUTOASCII and in_array(strtoupper($pi["extension"]), $this->AutoAsciiExt))) $mode=FTP_ASCII;
+ else $mode=FTP_BINARY;
+ if(!$this->_data_prepare($mode)) {
+ fclose($fp);
+ return FALSE;
+ }
+ if($this->_can_restore and $rest!=0) $this->restore($rest);
+ if(!$this->_exec("RETR ".$remotefile, "get")) {
+ $this->_data_close();
+ fclose($fp);
+ return FALSE;
+ }
+ if(!$this->_checkCode()) {
+ $this->_data_close();
+ fclose($fp);
+ return FALSE;
+ }
+ $out=$this->_data_read($mode, $fp);
+ fclose($fp);
+ $this->_data_close();
+ if(!$this->_readmsg()) return FALSE;
+ if(!$this->_checkCode()) return FALSE;
+ return $out;
+ }
+
+ function fput($remotefile, $fp) {
+ if($this->_can_restore and $rest!=0) fseek($fp, $rest);
+ $pi=pathinfo($remotefile);
+ if($this->_type==FTP_ASCII or ($this->_type==FTP_AUTOASCII and in_array(strtoupper($pi["extension"]), $this->AutoAsciiExt))) $mode=FTP_ASCII;
+ else $mode=FTP_BINARY;
+ if(!$this->_data_prepare($mode)) {
+ return FALSE;
+ }
+ if($this->_can_restore and $rest!=0) $this->restore($rest);
+ if(!$this->_exec("STOR ".$remotefile, "put")) {
+ $this->_data_close();
+ return FALSE;
+ }
+ if(!$this->_checkCode()) {
+ $this->_data_close();
+ return FALSE;
+ }
+ $ret=$this->_data_write($mode, $fp);
+ $this->_data_close();
+ if(!$this->_readmsg()) return FALSE;
+ if(!$this->_checkCode()) return FALSE;
+ return $ret;
+ }
+
+ function put($localfile, $remotefile=NULL, $rest=0) {
+ if(is_null($remotefile)) $remotefile=$localfile;
+ if (!file_exists($localfile)) {
+ $this->PushError("put","can't open local file", "No such file or directory \"".$localfile."\"");
+ return FALSE;
+ }
+ $fp = @fopen($localfile, "r");
+
+ if (!$fp) {
+ $this->PushError("put","can't open local file", "Cannot read file \"".$localfile."\"");
+ return FALSE;
+ }
+ if($this->_can_restore and $rest!=0) fseek($fp, $rest);
+ $pi=pathinfo($localfile);
+ if($this->_type==FTP_ASCII or ($this->_type==FTP_AUTOASCII and in_array(strtoupper($pi["extension"]), $this->AutoAsciiExt))) $mode=FTP_ASCII;
+ else $mode=FTP_BINARY;
+ if(!$this->_data_prepare($mode)) {
+ fclose($fp);
+ return FALSE;
+ }
+ if($this->_can_restore and $rest!=0) $this->restore($rest);
+ if(!$this->_exec("STOR ".$remotefile, "put")) {
+ $this->_data_close();
+ fclose($fp);
+ return FALSE;
+ }
+ if(!$this->_checkCode()) {
+ $this->_data_close();
+ fclose($fp);
+ return FALSE;
+ }
+ $ret=$this->_data_write($mode, $fp);
+ fclose($fp);
+ $this->_data_close();
+ if(!$this->_readmsg()) return FALSE;
+ if(!$this->_checkCode()) return FALSE;
+ return $ret;
+ }
+
+ function mput($local=".", $remote=NULL, $continious=false) {
+ $local=realpath($local);
+ if(!@file_exists($local)) {
+ $this->PushError("mput","can't open local folder", "Cannot stat folder \"".$local."\"");
+ return FALSE;
+ }
+ if(!is_dir($local)) return $this->put($local, $remote);
+ if(empty($remote)) $remote=".";
+ elseif(!$this->file_exists($remote) and !$this->mkdir($remote)) return FALSE;
+ if($handle = opendir($local)) {
+ $list=array();
+ while (false !== ($file = readdir($handle))) {
+ if ($file != "." && $file != "..") $list[]=$file;
+ }
+ closedir($handle);
+ } else {
+ $this->PushError("mput","can't open local folder", "Cannot read folder \"".$local."\"");
+ return FALSE;
+ }
+ if(empty($list)) return TRUE;
+ $ret=true;
+ foreach($list as $el) {
+ if(is_dir($local."/".$el)) $t=$this->mput($local."/".$el, $remote."/".$el);
+ else $t=$this->put($local."/".$el, $remote."/".$el);
+ if(!$t) {
+ $ret=FALSE;
+ if(!$continious) break;
+ }
+ }
+ return $ret;
+
+ }
+
+ function mget($remote, $local=".", $continious=false) {
+ $list=$this->rawlist($remote, "-lA");
+ if($list===false) {
+ $this->PushError("mget","can't read remote folder list", "Can't read remote folder \"".$remote."\" contents");
+ return FALSE;
+ }
+ if(empty($list)) return true;
+ if(!@file_exists($local)) {
+ if(!@mkdir($local)) {
+ $this->PushError("mget","can't create local folder", "Cannot create folder \"".$local."\"");
+ return FALSE;
+ }
+ }
+ foreach($list as $k=>$v) {
+ $list[$k]=$this->parselisting($v);
+ if($list[$k]["name"]=="." or $list[$k]["name"]=="..") unset($list[$k]);
+ }
+ $ret=true;
+ foreach($list as $el) {
+ if($el["type"]=="d") {
+ if(!$this->mget($remote."/".$el["name"], $local."/".$el["name"], $continious)) {
+ $this->PushError("mget", "can't copy folder", "Can't copy remote folder \"".$remote."/".$el["name"]."\" to local \"".$local."/".$el["name"]."\"");
+ $ret=false;
+ if(!$continious) break;
+ }
+ } else {
+ if(!$this->get($remote."/".$el["name"], $local."/".$el["name"])) {
+ $this->PushError("mget", "can't copy file", "Can't copy remote file \"".$remote."/".$el["name"]."\" to local \"".$local."/".$el["name"]."\"");
+ $ret=false;
+ if(!$continious) break;
+ }
+ }
+ @chmod($local."/".$el["name"], $el["perms"]);
+ $t=strtotime($el["date"]);
+ if($t!==-1 and $t!==false) @touch($local."/".$el["name"], $t);
+ }
+ return $ret;
+ }
+
+ function mdel($remote, $continious=false) {
+ $list=$this->rawlist($remote, "-la");
+ if($list===false) {
+ $this->PushError("mdel","can't read remote folder list", "Can't read remote folder \"".$remote."\" contents");
+ return false;
+ }
+
+ foreach($list as $k=>$v) {
+ $list[$k]=$this->parselisting($v);
+ if($list[$k]["name"]=="." or $list[$k]["name"]=="..") unset($list[$k]);
+ }
+ $ret=true;
+
+ foreach($list as $el) {
+ if ( empty($el) )
+ continue;
+
+ if($el["type"]=="d") {
+ if(!$this->mdel($remote."/".$el["name"], $continious)) {
+ $ret=false;
+ if(!$continious) break;
+ }
+ } else {
+ if (!$this->delete($remote."/".$el["name"])) {
+ $this->PushError("mdel", "can't delete file", "Can't delete remote file \"".$remote."/".$el["name"]."\"");
+ $ret=false;
+ if(!$continious) break;
+ }
+ }
+ }
+
+ if(!$this->rmdir($remote)) {
+ $this->PushError("mdel", "can't delete folder", "Can't delete remote folder \"".$remote."/".$el["name"]."\"");
+ $ret=false;
+ }
+ return $ret;
+ }
+
+ function mmkdir($dir, $mode = 0777) {
+ if(empty($dir)) return FALSE;
+ if($this->is_exists($dir) or $dir == "/" ) return TRUE;
+ if(!$this->mmkdir(dirname($dir), $mode)) return false;
+ $r=$this->mkdir($dir, $mode);
+ $this->chmod($dir,$mode);
+ return $r;
+ }
+
+ function glob($pattern, $handle=NULL) {
+ $path=$output=null;
+ if(PHP_OS=='WIN32') $slash='\\';
+ else $slash='/';
+ $lastpos=strrpos($pattern,$slash);
+ if(!($lastpos===false)) {
+ $path=substr($pattern,0,-$lastpos-1);
+ $pattern=substr($pattern,$lastpos);
+ } else $path=getcwd();
+ if(is_array($handle) and !empty($handle)) {
+ while($dir=each($handle)) {
+ if($this->glob_pattern_match($pattern,$dir))
+ $output[]=$dir;
+ }
+ } else {
+ $handle=@opendir($path);
+ if($handle===false) return false;
+ while($dir=readdir($handle)) {
+ if($this->glob_pattern_match($pattern,$dir))
+ $output[]=$dir;
+ }
+ closedir($handle);
+ }
+ if(is_array($output)) return $output;
+ return false;
+ }
+
+ function glob_pattern_match($pattern,$string) {
+ $out=null;
+ $chunks=explode(';',$pattern);
+ foreach($chunks as $pattern) {
+ $escape=array('$','^','.','{','}','(',')','[',']','|');
+ while(strpos($pattern,'**')!==false)
+ $pattern=str_replace('**','*',$pattern);
+ foreach($escape as $probe)
+ $pattern=str_replace($probe,"\\$probe",$pattern);
+ $pattern=str_replace('?*','*',
+ str_replace('*?','*',
+ str_replace('*',".*",
+ str_replace('?','.{1,1}',$pattern))));
+ $out[]=$pattern;
+ }
+ if(count($out)==1) return($this->glob_regexp("^$out[0]$",$string));
+ else {
+ foreach($out as $tester)
+ if($this->my_regexp("^$tester$",$string)) return true;
+ }
+ return false;
+ }
+
+ function glob_regexp($pattern,$probe) {
+ $sensitive=(PHP_OS!='WIN32');
+ return ($sensitive?
+ ereg($pattern,$probe):
+ eregi($pattern,$probe)
+ );
+ }
+
+ function dirlist($remote) {
+ $list=$this->rawlist($remote, "-la");
+ if($list===false) {
+ $this->PushError("dirlist","can't read remote folder list", "Can't read remote folder \"".$remote."\" contents");
+ return false;
+ }
+
+ $dirlist = array();
+ foreach($list as $k=>$v) {
+ $entry=$this->parselisting($v);
+ if ( empty($entry) )
+ continue;
+
+ if($entry["name"]=="." or $entry["name"]=="..")
+ continue;
+
+ $dirlist[$entry['name']] = $entry;
+ }
+
+ return $dirlist;
+ }
+//
+//
+//
+ function _checkCode() {
+ return ($this->_code<400 and $this->_code>0);
+ }
+
+ function _list($arg="", $cmd="LIST", $fnction="_list") {
+ if(!$this->_data_prepare()) return false;
+ if(!$this->_exec($cmd.$arg, $fnction)) {
+ $this->_data_close();
+ return FALSE;
+ }
+ if(!$this->_checkCode()) {
+ $this->_data_close();
+ return FALSE;
+ }
+ $out="";
+ if($this->_code<200) {
+ $out=$this->_data_read();
+ $this->_data_close();
+ if(!$this->_readmsg()) return FALSE;
+ if(!$this->_checkCode()) return FALSE;
+ if($out === FALSE ) return FALSE;
+ $out=preg_split("/[".CRLF."]+/", $out, -1, PREG_SPLIT_NO_EMPTY);
+// $this->SendMSG(implode($this->_eol_code[$this->OS_local], $out));
+ }
+ return $out;
+ }
+
+//
+//
+//
+// Gnre une erreur pour traitement externe la classe
+ function PushError($fctname,$msg,$desc=false){
+ $error=array();
+ $error['time']=time();
+ $error['fctname']=$fctname;
+ $error['msg']=$msg;
+ $error['desc']=$desc;
+ if($desc) $tmp=' ('.$desc.')'; else $tmp='';
+ $this->SendMSG($fctname.': '.$msg.$tmp);
+ return(array_push($this->_error_array,$error));
+ }
+
+// Rcupre une erreur externe
+ function PopError(){
+ if(count($this->_error_array)) return(array_pop($this->_error_array));
+ else return(false);
+ }
+}
+
+$mod_sockets=TRUE;
+if (!extension_loaded('sockets')) {
+ $prefix = (PHP_SHLIB_SUFFIX == 'dll') ? 'php_' : '';
+ if(!@dl($prefix . 'sockets.' . PHP_SHLIB_SUFFIX)) $mod_sockets=FALSE;
+}
+require_once "class-ftp-".($mod_sockets?"sockets":"pure").".php";
+?>
diff --git a/wp-admin/includes/class-wp-filesystem-ftpext.php b/wp-admin/includes/class-wp-filesystem-ftpext.php
index f128ac0b30..2f5f75195f 100644
--- a/wp-admin/includes/class-wp-filesystem-ftpext.php
+++ b/wp-admin/includes/class-wp-filesystem-ftpext.php
@@ -166,9 +166,9 @@ class WP_Filesystem_FTPext{
$mode = $this->permission;
if( ! $mode )
return false;
- if( ! $this->exists($file) )
+ if ( ! $this->exists($file) )
return false;
- if( ! $recursive || ! $this->is_dir($file) ){
+ if ( ! $recursive || ! $this->is_dir($file) ){
if (!function_exists('ftp_chmod'))
return ftp_site($this->link, sprintf('CHMOD %o %s', $mode, $file));
return ftp_chmod($this->link,$mode,$file);
@@ -267,8 +267,9 @@ class WP_Filesystem_FTPext{
function copy($source,$destination,$overwrite=false){
if( ! $overwrite && $this->exists($destination) )
return false;
- $content = $this->get_contents($source);
- $this->put_contents($destination,$content);
+ if ( !$content = $this->get_contents($source) )
+ return false;
+ return $this->put_contents($destination,$content);
}
function move($source,$destination,$overwrite=false){
return ftp_rename($this->link,$source,$destination);
@@ -280,7 +281,7 @@ class WP_Filesystem_FTPext{
if ( !$recursive )
return @ftp_rmdir($this->link,$file);
$filelist = $this->dirlist($file);
- foreach ($filelist as $filename => $fileinfo) {
+ foreach ((array) $filelist as $filename => $fileinfo) {
$this->delete($file.'/'.$filename,$recursive);
}
return @ftp_rmdir($this->link,$file);
@@ -327,11 +328,11 @@ class WP_Filesystem_FTPext{
if( !ftp_mkdir($this->link, $path) )
return false;
if( $chmod )
- $this->chmod($chmod);
+ $this->chmod($path, $chmod);
if( $chown )
- $this->chown($chown);
+ $this->chown($path, $chown);
if( $chgrp )
- $this->chgrp($chgrp);
+ $this->chgrp($path, $chgrp);
return true;
}
function rmdir($path,$recursive=false){
@@ -343,6 +344,69 @@ class WP_Filesystem_FTPext{
//foreach($dir as $file)
}
+
+ function parselisting($line) {
+ $is_windows = ($this->OS_remote == FTP_OS_Windows);
+ if ($is_windows && preg_match("/([0-9]{2})-([0-9]{2})-([0-9]{2}) +([0-9]{2}):([0-9]{2})(AM|PM) +([0-9]+|) +(.+)/",$line,$lucifer)) {
+ $b = array();
+ if ($lucifer[3]<70) { $lucifer[3]+=2000; } else { $lucifer[3]+=1900; } // 4digit year fix
+ $b['isdir'] = ($lucifer[7]=="");
+ if ( $b['isdir'] )
+ $b['type'] = 'd';
+ else
+ $b['type'] = 'f';
+ $b['size'] = $lucifer[7];
+ $b['month'] = $lucifer[1];
+ $b['day'] = $lucifer[2];
+ $b['year'] = $lucifer[3];
+ $b['hour'] = $lucifer[4];
+ $b['minute'] = $lucifer[5];
+ $b['time'] = @mktime($lucifer[4]+(strcasecmp($lucifer[6],"PM")==0?12:0),$lucifer[5],0,$lucifer[1],$lucifer[2],$lucifer[3]);
+ $b['am/pm'] = $lucifer[6];
+ $b['name'] = $lucifer[8];
+ } else if (!$is_windows && $lucifer=preg_split("/[ ]/",$line,9,PREG_SPLIT_NO_EMPTY)) {
+ //echo $line."\n";
+ $lcount=count($lucifer);
+ if ($lcount<8) return '';
+ $b = array();
+ $b['isdir'] = $lucifer[0]{0} === "d";
+ $b['islink'] = $lucifer[0]{0} === "l";
+ if ( $b['isdir'] )
+ $b['type'] = 'd';
+ elseif ( $b['islink'] )
+ $b['type'] = 'l';
+ else
+ $b['type'] = 'f';
+ $b['perms'] = $lucifer[0];
+ $b['number'] = $lucifer[1];
+ $b['owner'] = $lucifer[2];
+ $b['group'] = $lucifer[3];
+ $b['size'] = $lucifer[4];
+ if ($lcount==8) {
+ sscanf($lucifer[5],"%d-%d-%d",$b['year'],$b['month'],$b['day']);
+ sscanf($lucifer[6],"%d:%d",$b['hour'],$b['minute']);
+ $b['time'] = @mktime($b['hour'],$b['minute'],0,$b['month'],$b['day'],$b['year']);
+ $b['name'] = $lucifer[7];
+ } else {
+ $b['month'] = $lucifer[5];
+ $b['day'] = $lucifer[6];
+ if (preg_match("/([0-9]{2}):([0-9]{2})/",$lucifer[7],$l2)) {
+ $b['year'] = date("Y");
+ $b['hour'] = $l2[1];
+ $b['minute'] = $l2[2];
+ } else {
+ $b['year'] = $lucifer[7];
+ $b['hour'] = 0;
+ $b['minute'] = 0;
+ }
+ $b['time'] = strtotime(sprintf("%d %s %d %02d:%02d",$b['day'],$b['month'],$b['year'],$b['hour'],$b['minute']));
+ $b['name'] = $lucifer[8];
+ }
+ }
+
+ return $b;
+ }
+
function dirlist($path='.',$incdot=false,$recursive=false){
if( $this->is_file($path) ){
$limitFile = basename($path);
@@ -352,40 +416,34 @@ class WP_Filesystem_FTPext{
}
//if( ! $this->is_dir($path) )
// return false;
- $list = ftp_rawlist($this->link,$path,false); //We'll do the recursive part ourseves...
- //var_dump($list);
- if( ! $list )
+ $list = ftp_rawlist($this->link , '-a ' . $path, false);
+ if ( $list === false )
return false;
- if( empty($list) )
+
+ $dirlist = array();
+ foreach ( $list as $k => $v ) {
+ $entry = $this->parselisting($v);
+ if ( empty($entry) )
+ continue;
+
+ if ( $entry["name"]=="." or $entry["name"]==".." )
+ continue;
+
+ $dirlist[$entry['name']] = $entry;
+ }
+
+ if ( ! $dirlist )
+ return false;
+ if ( empty($dirlist) )
return array();
$ret = array();
- foreach($list as $line){
- if (substr(strtolower($line), 0, 5) == 'total') continue;
- $struc = array();
- $current = preg_split("/[\s]+/",$line,9);
- $name_num = count($current) - 1;
- $struc['name'] = str_replace('//','',$current[$name_num]);
-
- if( '.' == $struc['name'][0] && !$incdot)
- continue;
- if( $limitFile && $struc['name'] != $limitFile)
- continue;
-
- $struc['perms'] = $current[0];
- $struc['permsn'] = $this->getnumchmodfromh($current[0]);
- $struc['number'] = $current[1];
- $struc['owner'] = $current[2];
- $struc['group'] = $current[3];
- $struc['size'] = $current[4];
- $struc['lastmod'] = $current[5].' '.$current[6];
- $struc['time'] = $current[7];
-
- $struc['type'] = ('d' == $struc['perms'][0] || 'l' == $struc['perms'][0] ) ? 'folder' : 'file';
- if('folder' == $struc['type'] ){
+ foreach ( $dirlist as $struc ) {
+
+ if ( 'd' == $struc['type'] ) {
$struc['files'] = array();
- if( $incdot ){
+ if ( $incdot ){
//We're including the doted starts
if( '.' != $struc['name'] && '..' != $struc['name'] ){ //Ok, It isnt a special folder
if ($recursive)
@@ -401,6 +459,7 @@ class WP_Filesystem_FTPext{
}
return $ret;
}
+
function __destruct(){
if( $this->link )
ftp_close($this->link);
diff --git a/wp-admin/includes/class-wp-filesystem-ftpsockets.php b/wp-admin/includes/class-wp-filesystem-ftpsockets.php
index e57a87002a..132e7b231a 100644
--- a/wp-admin/includes/class-wp-filesystem-ftpsockets.php
+++ b/wp-admin/includes/class-wp-filesystem-ftpsockets.php
@@ -29,7 +29,7 @@ class WP_Filesystem_ftpsockets{
//Check if possible to use ftp functions.
if( ! @include_once ABSPATH . 'wp-admin/includes/class-ftp.php' )
return false;
- $this->ftp = new FTP();
+ $this->ftp = new ftp();
//Set defaults:
if ( empty($opt['port']) )
@@ -60,8 +60,14 @@ class WP_Filesystem_ftpsockets{
function connect() {
if ( ! $this->ftp )
return false;
-
- if ( ! $this->ftp->connect($this->options['hostname'], $this->options['port'], $this->timeout) ) {
+
+ //$this->ftp->Verbose = true;
+
+ if ( ! $this->ftp->SetServer($this->options['hostname'], $this->options['port']) ) {
+ $this->errors->add('connect', sprintf(__('Failed to connect to FTP Server %1$s:%2$s'), $this->options['hostname'], $this->options['port']));
+ return false;
+ }
+ if ( ! $this->ftp->connect() ) {
$this->errors->add('connect', sprintf(__('Failed to connect to FTP Server %1$s:%2$s'), $this->options['hostname'], $this->options['port']));
return false;
}
@@ -71,6 +77,8 @@ class WP_Filesystem_ftpsockets{
return false;
}
+ $this->ftp->SetType(FTP_AUTOASCII);
+ $this->ftp->Passive(true);
return true;
}
@@ -113,26 +121,39 @@ class WP_Filesystem_ftpsockets{
//If we get this far, somethings gone wrong, change to / and restart the process.
return $this->find_base_dir('/',$echo);
}
+
function get_base_dir($base = '.'){
if( empty($this->wp_base) )
$this->wp_base = $this->find_base_dir($base);
return $this->wp_base;
}
+
function get_contents($file,$type='',$resumepos=0){
if( empty($type) ){
$extension = substr(strrchr($filename, "."), 1);
$type = isset($this->filetypes[ $extension ]) ? $this->filetypes[ $extension ] : FTP_AUTOASCII;
}
$this->ftp->SetType($type);
-
- return $this->ftp->get($file);
+ $temp = tmpfile();
+ if ( ! $this->ftp->fget($temp, $file) ) {
+ fclose($temp);
+ return false;
+ }
+ fseek($temp, 0); //Skip back to the start of the file being written to
+ $contents = '';
+ while ( !feof($temp) )
+ $contents .= fread($temp, 8192);
+ fclose($temp);
+ return $contents;
}
+
function get_contents_array($file){
return explode("\n",$this->get_contents($file));
}
+
function put_contents($file,$contents,$type=''){
if( empty($type) ){
- $extension = substr(strrchr($filename, "."), 1);
+ $extension = substr(strrchr($file, "."), 1);
$type = isset($this->filetypes[ $extension ]) ? $this->filetypes[ $extension ] : FTP_ASCII;
}
$this->ftp->SetType($type);
@@ -140,16 +161,19 @@ class WP_Filesystem_ftpsockets{
$temp = tmpfile();
fwrite($temp,$contents);
fseek($temp, 0); //Skip back to the start of the file being written to
- $ret = $this->ftp->put($temp, $file);
+ $ret = $this->ftp->fput($file, $temp);
fclose($temp);
return $ret;
}
+
function cwd(){
return $this->ftp->pwd();
}
+
function chgrp($file,$group,$recursive=false){
return false;
}
+
function chmod($file,$mode=false,$recursive=false){
if( ! $mode )
$mode = $this->permission;
@@ -167,17 +191,21 @@ class WP_Filesystem_ftpsockets{
}
return true;
}
+
function chown($file,$owner,$recursive=false){
return false;
}
+
function owner($file){
$dir = $this->dirlist($file);
return $dir[$file]['owner'];
}
+
function getchmod($file){
$dir = $this->dirlist($file);
return $dir[$file]['permsn'];
}
+
function gethchmod($file){
//From the PHP.net page for ...?
$perms = $this->getchmod($file);
@@ -229,6 +257,7 @@ class WP_Filesystem_ftpsockets{
(($perms & 0x0200) ? 'T' : '-'));
return $info;
}
+
function getnumchmodfromh($mode) {
$realmode = "";
$legal = array("","w","r","x","-");
@@ -247,16 +276,23 @@ class WP_Filesystem_ftpsockets{
$newmode .= $mode[6]+$mode[7]+$mode[8];
return $newmode;
}
+
function group($file){
$dir = $this->dirlist($file);
return $dir[$file]['group'];
}
+
function copy($source,$destination,$overwrite=false){
if( ! $overwrite && $this->exists($destination) )
return false;
+
$content = $this->get_contents($source);
- $this->put_contents($destination,$content);
+ if ( !$content )
+ return false;
+
+ return $this->put_contents($destination,$content);
}
+
function move($source,$destination,$overwrite=false){
return $this->ftp->rename($source,$destination);
}
@@ -266,69 +302,72 @@ class WP_Filesystem_ftpsockets{
return $this->ftp->delete($file);
if ( !$recursive )
return $this->ftp->rmdir($file);
- $filelist = $this->dirlist($file);
- foreach ($filelist as $filename) {
- $this->delete($file.'/'.$filename,$recursive);
- }
- return $this->ftp->rmdir($file);
+
+ return $this->ftp->mdel($file);
}
function exists($file){
return $this->ftp->is_exists($file);
}
+
function is_file($file){
- //return $this->ftp->file_exists($file);
- $list = $this->ftp->rawlist($file,'-a');
- if( ! $list )
- return false;
- return ($list[0] == '-');
+ return $this->is_dir($file) ? false : true;
}
+
function is_dir($path){
- $list = $this->ftp->rawlist($file,'-a');
- if( ! $list )
- return false;
- return true;
+ $cwd = $this->cwd();
+ if ( $this->ftp->chdir($path) ) {
+ $this->ftp->chdir($cwd);
+ return true;
+ }
+ return false;
}
+
function is_readable($file){
//Get dir list, Check if the file is writable by the current user??
return true;
}
+
function is_writable($file){
//Get dir list, Check if the file is writable by the current user??
return true;
}
+
function atime($file){
return false;
}
+
function mtime($file){
return $this->ftp->mdtm($file);
}
+
function size($file){
return $this->ftp->filesize($file);
}
+
function touch($file,$time=0,$atime=0){
return false;
}
+
function mkdir($path,$chmod=false,$chown=false,$chgrp=false){
if( ! $this->ftp->mkdir($path) )
return false;
if( $chmod )
- $this->chmod($chmod);
+ $this->chmod($path, $chmod);
if( $chown )
- $this->chown($chown);
+ $this->chown($path, $chown);
if( $chgrp )
- $this->chgrp($chgrp);
+ $this->chgrp($path, $chgrp);
return true;
}
+
function rmdir($path,$recursive=false){
if( ! $recursive )
return $this->ftp->rmdir($file);
- return false;
- //TODO: Recursive Directory delete, Have to delete files from the folder first.
- //$dir = $this->dirlist($path);
- //foreach($dir as $file)
-
+
+ return $this->ftp->mdel($path);
}
+
function dirlist($path='.',$incdot=false,$recursive=false){
if( $this->is_file($path) ){
$limitFile = basename($path);
@@ -338,38 +377,19 @@ class WP_Filesystem_ftpsockets{
}
//if( ! $this->is_dir($path) )
// return false;
- $list = $this->ftp->rawlist($path,'-a');
- //var_dump($list);
+ $list = $this->ftp->dirlist($path);
if( ! $list )
return false;
if( empty($list) )
return array();
$ret = array();
- foreach($list as $line){
- $struc = array();
- $current = preg_split("/[\s]+/",$line,9);
- $struc['name'] = str_replace('//','',$current[8]);
-
- if( '.' == $struc['name'][0] && !$incdot)
- continue;
- if( $limitFile && $struc['name'] != $limitFile)
- continue;
-
- $struc['perms'] = $current[0];
- $struc['permsn'] = $this->getnumchmodfromh($current[0]);
- $struc['number'] = $current[1];
- $struc['owner'] = $current[2];
- $struc['group'] = $current[3];
- $struc['size'] = $current[4];
- $struc['lastmod'] = $current[5].' '.$current[6];
- $struc['time'] = $current[7];
-
- $struc['type'] = ('d' == $struc['perms'][0] || 'l' == $struc['perms'][0] ) ? 'folder' : 'file';
- if('folder' == $struc['type'] ){
+ foreach ( $list as $struc ) {
+
+ if ( 'd' == $struc['type'] ) {
$struc['files'] = array();
- if( $incdot ){
+ if ( $incdot ){
//We're including the doted starts
if( '.' != $struc['name'] && '..' != $struc['name'] ){ //Ok, It isnt a special folder
if ($recursive)
@@ -385,6 +405,7 @@ class WP_Filesystem_ftpsockets{
}
return $ret;
}
+
function __destruct(){
$this->ftp->quit();
}
diff --git a/wp-admin/includes/file.php b/wp-admin/includes/file.php
index 98482f86ac..1d0252c02f 100644
--- a/wp-admin/includes/file.php
+++ b/wp-admin/includes/file.php
@@ -237,11 +237,11 @@ function unzip_file($file, $to) {
$path = explode('/', $to);
$tmppath = '';
for ( $j = 0; $j < count($path) - 1; $j++ ) {
+ $prevpath = $tmppath;
$tmppath .= $path[$j] . '/';
if ( ! $fs->is_dir($tmppath) ) {
- $fs->mkdir($tmppath);
- } else {
- $fs->setDefaultPermissions( $fs->getchmod($tmppath) );
+ //$fs->setDefaultPermissions( $fs->getchmod($tmppath) );
+ $fs->mkdir($tmppath, 0755);
}
}
@@ -253,13 +253,18 @@ function unzip_file($file, $to) {
for ( $j = 0; $j < count($path) - 1; $j++ ) {
$tmppath .= $path[$j] . '/';
if ( ! $fs->is_dir($to . $tmppath) )
- $fs->mkdir($to . $tmppath);
+ if ( !$fs->mkdir($to . $tmppath, 0755) )
+ return new WP_Error('mkdir_failed', __('Could not create directory'));
}
// We've made sure the folders are there, so let's extract the file now:
if ( ! $file['folder'] )
- $fs->put_contents( $to . $file['filename'], $file['content']);
+ if ( !$fs->put_contents( $to . $file['filename'], $file['content']) )
+ return new WP_Error('copy_failed', __('Could not copy file'));
+ $fs->chmod($to . $file['filename'], 0644);
}
+
+ return true;
}
function copy_dir($from, $to) {
@@ -271,13 +276,19 @@ function copy_dir($from, $to) {
$to = trailingslashit($to);
foreach ( (array) $dirlist as $filename => $fileinfo ) {
- if ( 'file' == $fileinfo['type'] ) {
- $wp_filesystem->copy($from . $filename, $to . $filename, true);
- } elseif ( 'folder' == $fileinfo['type'] ) {
- $wp_filesystem->mkdir($to . $filename);
- copy_dir($from . $filename, $to . $filename);
+ if ( 'f' == $fileinfo['type'] ) {
+ if ( ! $wp_filesystem->copy($from . $filename, $to . $filename, true) )
+ return false;
+ $wp_filesystem->chmod($to . $filename, 0644);
+ } elseif ( 'd' == $fileinfo['type'] ) {
+ if ( !$wp_filesystem->mkdir($to . $filename, 0755) )
+ return false;
+ if ( !copy_dir($from . $filename, $to . $filename) )
+ return false;
}
}
+
+ return true;
}
function WP_Filesystem( $args = false, $preference = false ) {
@@ -302,11 +313,13 @@ function WP_Filesystem( $args = false, $preference = false ) {
}
function get_filesystem_method() {
+ return 'ftpsockets';
+
$tempFile = tempnam(get_temp_dir(), 'WPU');
if ( getmyuid() == fileowner($tempFile) ) {
unlink($tempFile);
- //return 'direct';
+ return 'direct';
} else {
unlink($tempFile);
}
diff --git a/wp-admin/includes/update.php b/wp-admin/includes/update.php
index 70ece77a23..cacaa4eb7b 100644
--- a/wp-admin/includes/update.php
+++ b/wp-admin/includes/update.php
@@ -158,7 +158,8 @@ function wp_update_plugin($plugin, $feedback = '') {
$working_dir = ABSPATH . 'wp-content/upgrade/' . $name;
// Clean up working directory
- $wp_filesystem->delete($working_dir, true);
+ if ( is_dir($working_dir) )
+ $wp_filesystem->delete($working_dir, true);
apply_filters('update_feedback', __("Unpacking the update"));
// Unzip package to working directory
@@ -174,16 +175,23 @@ function wp_update_plugin($plugin, $feedback = '') {
// Remove the existing plugin.
apply_filters('update_feedback', __("Removing the old version of the plugin"));
- $wp_filesystem->delete(ABSPATH . PLUGINDIR . "/$plugin");
$plugin_dir = dirname(ABSPATH . PLUGINDIR . "/$plugin");
-
// If plugin is in its own directory, recursively delete the directory.
if ( '.' != $plugin_dir && ABSPATH . PLUGINDIR != $plugin_dir )
- $wp_filesystem->delete($plugin_dir, true);
+ $deleted = $wp_filesystem->delete($plugin_dir, true);
+ else
+ $deleted = $wp_filesystem->delete(ABSPATH . PLUGINDIR . "/$plugin");
+ if ( !$deleted ) {
+ $wp_filesystem->delete($working_dir, true);
+ return new WP_Error('delete_failed', __('Could not remove the old plugin'));
+ }
apply_filters('update_feedback', __("Installing the latest version"));
// Copy new version of plugin into place.
- copy_dir($working_dir, ABSPATH . PLUGINDIR);
+ if ( !copy_dir($working_dir, ABSPATH . PLUGINDIR) ) {
+ //$wp_filesystem->delete($working_dir, true);
+ return new WP_Error('install_failed', __('Installation failed'));
+ }
// Remove working directory
$wp_filesystem->delete($working_dir, true);