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);