Current File : /home/lecoinf/www/iwp/includes/bridge/fileSystem.php
<?php
/************************************************************
* Credits - WordPress
 ************************************************************/

function addTrailingSlash($string) {
	return removeTrailingSlash($string) . '/';
}

function removeTrailingSlash($string) {
	return rtrim($string, '/');
}

function isBinary( $text ) {
	return (bool) preg_match('|[^\x20-\x7E]|', $text); //chr(32)..chr(127)
}

if(!function_exists('appUpdateMsg')){
	function appUpdateMsg($msg, $isError=0){
		echo "\n".'<br>'.$msg;
	}
}

function getTempName($fileName = '', $dir = '') {
	if ( empty($dir) )
		$dir = getTempDir();
	$fileName = basename($fileName);
	if ( empty($fileName) )
		$fileName = time();

	$fileName = preg_replace('|\..*$|', '.tmp', $fileName);
	$fileName = $dir . getUniqueFileName($dir, $fileName);
	touch($fileName);
	return $fileName;
}

function getUniqueFileName( $dir, $fileName) {

	// separate the fileName into a name and extension
	$info = pathinfo($fileName);
	$ext = !empty($info['extension']) ? '.' . $info['extension'] : '';
	$name = basename($fileName, $ext);

	// edge case: if file is named '.ext', treat as an empty name
	if ( $name === $ext )
		$name = '';

	// Increment the file number until we have a unique file to save in $dir. Use callback if supplied.
	
	$number = '';

	// change '.ext' to lower case
	if ( $ext && strtolower($ext) != $ext ) {
		$ext2 = strtolower($ext);
		$fileName2 = preg_replace( '|' . preg_quote($ext) . '$|', $ext2, $fileName );

		// check for both lower and upper case extension or image sub-sizes may be overwritten
		while ( file_exists($dir . "/$fileName") || file_exists($dir . "/$fileName2") ) {
			$newNumber = $number + 1;
			$fileName = str_replace( "$number$ext", "$newNumber$ext", $fileName );
			$fileName2 = str_replace( "$number$ext2", "$newNumber$ext2", $fileName2 );
			$number = $newNumber;
		}
		return $fileName2;
	}

	while ( file_exists( $dir . "/$fileName" ) ) {
		if ( '' == "$number$ext" )
			$fileName = $fileName . ++$number . $ext;
		else
			$fileName = str_replace( "$number$ext", ++$number . $ext, $fileName );
	}
	

	return $fileName;
}

function getTempDir() {
	static $temp;
	if ( defined('TEMP_DIR') )
		return addTrailingSlash(TEMP_DIR);

	if ( $temp )
		return addTrailingSlash($temp);

	$temp = dirname(__FILE__).'/clone_temp/';//dirname(__FILE__) = clone_controller folder
	if ( is_dir($temp) && @is_writable($temp) ){
		//$isTrue = mkdir(dirname(__FILE__).'/clone_temp/');
		// if ($isTrue)
		return $temp;
	}

	if  ( function_exists('sys_get_temp_dir') ) {
		$temp = sys_get_temp_dir();
		if ( @is_writable($temp) )
			return addTrailingSlash($temp);
	}

	$temp = ini_get('upload_tmp_dir');
	if ( is_dir($temp) && @is_writable($temp) )
		return addTrailingSlash($temp);

	$temp = '/tmp/';
	if ( is_dir($temp) && @is_writable($temp) )
		return addTrailingSlash($temp);
	
	
	die(status('Unable to write files. Please set 777 permission to "/clone_controller/clone_temp" directory in the clone destination and try again.', $success=false, $return=true));
	
	return addTrailingSlash($temp);
}

function getTempDirFromFTP(){//currently not used

	//try creating new folder in FTP with write permission
	$FTPOpt = array('hostname' => APP_FTP_HOST, 'port' => APP_FTP_PORT, 'username' => APP_FTP_USER, 'password' => APP_FTP_PASS, 'base' => APP_FTP_BASE, 'connectionType' => (defined('APP_FTP_SSL') && APP_FTP_SSL) ? 'ftps' : '');//same array used in getFileSystemMethod()
	
	if ( ! defined('FS_CONNECT_TIMEOUT') )
		define('FS_CONNECT_TIMEOUT', 30);
	if ( ! defined('FS_TIMEOUT') )
		define('FS_TIMEOUT', 30);	
	
	$FTPObj = new filesystemFTPExt($FTPOpt);
	if(!$FTPObj->connect()){//FTP will close at the end of getTempDirFromFTP()
		return false;
	}
	if($FTPObj->chdir(removeTrailingSlash(APP_FTP_BASE).'/clone_controller')){
		$temp = removeTrailingSlash(dirname(__FILE__)).'/clone_temp';//clone_controller/clone_temp folder
		if(!$FTPObj->mkDir(removeTrailingSlash(APP_FTP_BASE).'/clone_controller/clone_temp')){
			return false;
		}
		if ( is_dir($temp) && @is_writable($temp) ){
			return addTrailingSlash($temp);
		}
		if($FTPObj->chmod(removeTrailingSlash(APP_FTP_BASE).'/clone_controller/clone_temp', 0777)){
			if ( is_dir($temp) && @is_writable($temp) )
			return addTrailingSlash($temp);
		}
	}
	return false;
}

function downloadURL($URL, $filename, $prevMultiCallResponse = array(), $wpContentURL = false){
	if(empty($prevMultiCallResponse['file'])){
		if (strpos($URL, 'db.gz')) {
			$file = dirname(__FILE__).'/clone_temp/'.$URL;
			touch($file);
		}elseif (strpos($URL, 'more.zip')) {
			$file = dirname(__FILE__).'/clone_temp/'.$URL;
			touch($file);
		}else{
			$file = getTempName($filename);
		}
	} else{
		$file = $prevMultiCallResponse['file'];
	}
	
	$downloadResponseHeaders = array();	
	$downloaded = false;
	$downloaded = multiCallDownloadUsingCURL($URL, $file, $downloadResponseHeaders, $prevMultiCallResponse, $wpContentURL);
	
	if(!$downloaded){
		//Check fsockopen is allowed
		if (!function_exists('fsockopen')){
			die(status("Please enable fsockopen on your server.", false ,true));
		}

		iwp_mmb_auto_print('downloading_in_curl');

		$downloaded = multiCallDownloadUsingFsock($URL, $file, $downloadResponseHeaders, $prevMultiCallResponse);
	}
	
	if(!$downloaded){
		die(status('The file could not be downloaded. Change "/clone_controller/clone_temp" directory permission to 777 and try again.', false ,true));
	}
	else{
		checkdownloadResponseHeaders($downloadResponseHeaders);//it using die when invalid file download
	}
	return $downloaded;
}

function multiCallDownloadUsingCURL($URL, $file, &$downloadResponseHeaders, $prevResult = array(), $wpContentURL= false){
	if (!function_exists('curl_init') || !function_exists('curl_exec')){
		return false;
	}
	if(empty($prevResult['file'])){
		$fp = fopen ($file, 'wb');
	} else{
		$file = $prevResult['file'];
		$fp = fopen ($file, 'rb+');
		fseek($fp, $prevResult['startRange']);
	}
	if(!$fp){
		return false;
	}

	$isBreak = false;
	$isMultiPart = false;

	$startRange = (empty($prevResult['startRange']) && empty($prevResult['file']))? 0 : $prevResult['startRange'];
	$endRange = (empty($prevResult['endRange']) && empty($prevResult['file']))? 10000000 : $prevResult['endRange'];
	if ($wpContentURL && !strpos($URL, $GLOBALS['WPVersionName'])) {
		$URL = $wpContentURL.'/infinitewp/backups/'.$URL;
		if (!empty($GLOBALS['URLParseData'])) {
			$URL = buildFolderAuthURL($GLOBALS['URLParseData'], $URL);
		}
	}
	$totalFileSize = curl_get_file_size($URL, $startRange);
	if (strpos($URL, $GLOBALS['WPVersionName'])) {
		$endRange = $totalFileSize;
	}
	status("Downloading file... ", $success=true, $return=false);
	status("Total size of the file ".$totalFileSize, $success=true, $return=false);
	status("Download start from ".$startRange, $success=true, $return=false);
	if ($_REQUEST['oneShotdownlaod']) {
		$endRange = $totalFileSize;
	}

	do{
		$ch = curl_init($URL);
		curl_setopt($ch, CURLOPT_TIMEOUT, 60);
		curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36');
		curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
	    curl_setopt($ch, CURLOPT_MAXREDIRS, 5);
		curl_setopt($ch, CURLOPT_HTTPHEADER, array(
													'Connection: Keep-Alive',
													'Keep-Alive: 115'
												));
		$rangeVariable = $startRange . '-' . $endRange;
		curl_setopt($ch, CURLOPT_RANGE, $rangeVariable);
		curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
		curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false );
		curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false );
		$callResponse = curl_exec($ch);
		//write in file
		$currentOffest = (empty($startRange)) ? 0 : $startRange;
		@fseek($fp, $currentOffest, SEEK_SET);
		@fwrite($fp, $callResponse);
		$info = curl_getinfo($ch);
		curl_close($ch);

		if($info['http_code'] == '206'){
			//multiCallDownloadUsingCURL($URL, $file, $downloadResponseHeaders);
			$isMultiPart = true;
			$startRange = ftell($fp);
			$endRange = ($startRange + 10000000);
			if($endRange >= $totalFileSize){
				$endRange = $totalFileSize;
			}
			if($startRange == $endRange){
				$isMultiPart = false;
			}
		}
		$rangeVariable = $startRange . '-' . $endRange;
		$isBreak = check_for_clone_break();
	}
	while(!($isBreak) && $isMultiPart);

	fclose($fp);
	$currentResult = array();
	initialize_response_array($currentResult);
	$currentResult['file'] = $file;
	$currentResult['startRange'] = $startRange;
	$currentResult['endRange'] = $endRange;
	status("File Downloaded size:".$startRange, $success=true, $return=false);

	if($isBreak == true){
		$currentResult['status'] = 'partiallyCompleted';
		$currentResult['isDownloadMultiCall'] = true;
	}

	if(!$isMultiPart){
		$currentResult['isDownloadMultiCall'] = false;
	}
	$downloadResponseHeaders[] = "HTTP/1.1 ".$info['http_code']." SOMETHING";
	$downloadResponseHeaders[] = "Content-Type: ".$info['content_type'];
	return $currentResult;
}

function curl_get_file_size($url, $startRange = 0) {
  // Assume failure.

  $result = -1;

  $curl = curl_init( $url );

  // Issue a HEAD request and follow any redirects.
  curl_setopt( $curl, CURLOPT_NOBODY, true );
  curl_setopt( $curl, CURLOPT_HEADER, true );
  curl_setopt( $curl, CURLOPT_RETURNTRANSFER, true );
  curl_setopt( $curl, CURLOPT_FOLLOWLOCATION, true );
  curl_setopt( $curl, CURLOPT_SSL_VERIFYHOST, false );
  curl_setopt( $curl, CURLOPT_SSL_VERIFYPEER, false );
  curl_setopt( $curl, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:16.0) Gecko Firefox/16.0' );
  if ($startRange == 0) {
	status("************* Get file size cURL verbose starts here *************", true, false);
	curl_setopt($curl, CURLOPT_VERBOSE, true);
	curl_setopt($curl, CURLOPT_STDERR, $GLOBALS["LOG_FILE_HANDLE"]);
	# code...
  }
  $data = curl_exec( $curl );
  $curlInfo = array();
  $curlInfo['info'] = curl_getinfo($curl);
  if(curl_errno($curl)){
  	$curlInfo['errorNo'] = curl_errno($curl);
  	$curlInfo['error'] = curl_error($curl);
  }
  curl_close( $curl );
  if ($startRange == 0) {
	status("************* Get file size cURL verbose ends here *************", true, false);
  }
  if( $data ) {
    $content_length = "unknown";
    $status = "unknown";

    if( preg_match( "/Content-Length: (\d+)/", $data, $matches ) ) {
      $content_length = (int)$matches[1];
    }
    if ($content_length == 'unknown' && preg_match( "/content-length: (\d+)/", $data, $matches )) {
    	$content_length = (int)$matches[1];
    }
    $status = $curlInfo['info']['http_code'];
    // http://en.wikipedia.org/wiki/List_of_HTTP_status_codes
    if( $status == 200 || ($status > 300 && $status <= 308) ) {
      $result = $content_length;
    }
  }
  if ($result == -1) {
  	$headers = @get_headers($url, 1);
	status("************* Get file size fallback get_headers *************", true, false);
	if (!empty($headers["Content-Length"]) && $headers["Content-Length"]>0) {
		return $headers["Content-Length"];
	}
  }
  if ($result == -1) {
  		$content_length = (int)$curlInfo['info']['download_content_length'];
		status("************* Get file size fallback content_length *************", true, false);
  		if ($content_length >0) {
  			return $content_length;
  		}
  }
  return $result;
}

function multiCallDownloadUsingFsock($infile, $outfile, &$downloadResponseHeaders, $prevResult = array()){
    $chunksize = 512;  // 1 Meg

    /**
     * parse_url breaks a part a URL into it's parts, i.e. host, path,
     * query string, etc.
     */
    $parts     = parse_url($infile);
    $i_handle  = fsockopen($parts['host'], 80, $errstr, $errcode, 5);
	if(empty($prevResult)){
		$o_handle = fopen ($outfile, 'wb');
	} else{
		$o_handle  = fopen($outfile, 'rb+');
    }
    if ($i_handle == false || $o_handle == false) {
        return false;
    }
    if (!empty($parts['query'])) {
        $parts['path'] .= '?' . $parts['query'];
    }

    /**
     * Send the request to the server for the file
     */
    $request = "GET {$parts['path']} HTTP/1.0\r\n";
    $request .= "Host: {$parts['host']}\r\n";
	$request .= "User-agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:16.0) Gecko Firefox/16.0". "\r\n";
    $request .= "Keep-Alive: 115\r\n";
    $request .= "Connection: keep-alive\r\n\r\n";
    fwrite($i_handle, $request);

    /**
     * Now read the headers from the remote server. We'll need
     * to get the content length.
     */
    $headers = array();
    while (!feof($i_handle)) {
        $line = fgets($i_handle);
        if ($line == "\r\n")
            break;
        $headers[] = $line;
    }
	$downloadResponseHeaders = $headers;
  /**
     * Look for the Content-Length header, and get the size
     * of the remote file.
     */
    $length = 0;
    foreach ($headers as $header) {
        if (stripos($header, 'Content-Length:') === 0) {
            $length = (int) str_replace('Content-Length: ', '', $header);
            break;
        }
    }

    /**
     * Start reading in the remote file, and writing it to the
     * local file one chunk at a time.
     */
    $cnt = 0;
	$is_break = false;

	$iOffset = empty($prevResult['iOffset']) ? 0 : $prevResult['iOffset'];
	$oOffset = empty($prevResult['oOffset']) ? 0 : $prevResult['oOffset'];
	if(!empty($prevResult['iOffset'])){
		fseek($i_handle, $iOffset);
		fseek($o_handle, $oOffset);
	}
	$count = empty($prevResult['count']) ? 0 : $prevResult['count'];
    while (!feof($i_handle) && !$is_break) {
		$count++;
        iwp_mmb_auto_print('fsock_download');
        $buf   = '';
        $buf   = fread($i_handle, $chunksize);
        $bytes = fwrite($o_handle, $buf);
        if ($bytes == false) {
	return false;
        }
        $cnt += $bytes;
        /**
         * We're done reading when we've reached the content length
         */
		$is_break = check_for_clone_break();
        if ($length && $cnt >= $length || $is_break){
            break;
		}
    }

	$currentResult = array();
	initialize_response_array($currentResult);
	$currentResult['file'] = $outfile;
	$currentResult['iOffset'] = ftell($i_handle);
	$currentResult['oOffset'] = ftell($o_handle);
	$currentResult['cloneDownloadType'] = 'fsock';
	$currentResult['count'] = $count;
	if($is_break == true){
		$currentResult['status'] = 'partiallyCompleted';
		$currentResult['isDownloadMultiCall'] = true;
	}
    fclose($i_handle);
    fclose($o_handle);
    return $currentResult;
}

function downloadUsingCURL($URL, $file, &$downloadResponseHeaders){
	
	if (!function_exists('curl_init') || !function_exists('curl_exec')) return false;
	
	$fp = fopen ($file, 'w');
	if(!$fp){ return false; }
	$ch = curl_init($URL);
	curl_setopt($ch, CURLOPT_TIMEOUT, 60);
	curl_setopt($ch, CURLOPT_FILE, $fp);
	curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:16.0) Gecko Firefox/16.0');
	curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
	curl_setopt($ch, CURLOPT_MAXREDIRS, 5);

	curl_setopt($ch, CURLOPT_HTTPHEADER, array(
												'Connection: Keep-Alive',
												'Keep-Alive: 115'
											));
	
	$callResponse = curl_exec($ch);
	$info = curl_getinfo($ch);
	curl_close($ch);
	fclose($fp);

	if($callResponse == 1){
		$downloadResponseHeaders[] = "HTTP/1.1 ".$info['http_code']." SOMETHING";
		$downloadResponseHeaders[] = "Content-Type: ".$info['content_type'];
		return true;
	}
	return false;
	
}

function downloadUsingFsock($infile, $outfile, &$downloadResponseHeaders){
	$chunksize = 1024 * 1024;  // 1 Meg
	
	/**
	 * parse_url breaks a part a URL into it's parts, i.e. host, path,
	 * query string, etc.
	 */
	$parts     = parse_url($infile);
	$i_handle  = fsockopen($parts['host'], 80, $errstr, $errcode, 5);
	$o_handle  = fopen($outfile, 'wb');
	
	if ($i_handle == false || $o_handle == false) {
		return false;
	}
	
	if (!empty($parts['query'])) {
		$parts['path'] .= '?' . $parts['query'];
	}
	
	/**
	 * Send the request to the server for the file
	 */
	$request = "GET {$parts['path']} HTTP/1.0\r\n";
	$request .= "Host: {$parts['host']}\r\n";
	$request .= "User-agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:16.0) Gecko Firefox/16.0". "\r\n";
	$request .= "Keep-Alive: 115\r\n";
	$request .= "Connection: keep-alive\r\n\r\n";
	fwrite($i_handle, $request);
	
	/**
	 * Now read the headers from the remote server. We'll need
	 * to get the content length.
	 */
	$headers = array();
	while (!feof($i_handle)) {
		$line = fgets($i_handle);
		if ($line == "\r\n")
			break;
		$headers[] = $line;
	}
	$downloadResponseHeaders = $headers;
	
  /**
	 * Look for the Content-Length header, and get the size
	 * of the remote file.
	 */
	$length = 0;
	foreach ($headers as $header) {
		if (stripos($header, 'Content-Length:') === 0) {
			$length = (int) str_replace('Content-Length: ', '', $header);
			break;
		}
	}
	
	/**
	 * Start reading in the remote file, and writing it to the
	 * local file one chunk at a time.
	 */
	$cnt = 0;
	while (!feof($i_handle)) {
		iwp_mmb_auto_print('fsock_download');
		$buf   = '';
		$buf   = fread($i_handle, $chunksize);
		$bytes = fwrite($o_handle, $buf);
		if ($bytes == false) {
			return false;
		}
		$cnt += $bytes;
		
		/**
		 * We're done reading when we've reached the content length
		 */
		if ($length && $cnt >= $length)
			break;
	}
	fclose($i_handle);
	fclose($o_handle);
	return $cnt;
}

function checkdownloadResponseHeaders($headers){
	$httpCodeChecked = false;
	foreach($headers as $line){
	  if(!$httpCodeChecked && stripos($line, 'HTTP/') !== false){
		  $matches = array();
		  preg_match('#HTTP/\d+\.\d+ (\d+)#', $line, $matches);
		  $httpCode = (int)$matches[1];
		  if($httpCode != 200 && $httpCode != 206){
			  die(status("Error while downloading the zip file HTTP error: ".$httpCode.".", false ,true));
		  }
		  $httpCodeChecked = true;
	  }

	  if(stripos($line, 'Content-Type') !== false){
		   //$contentType = trim(str_ireplace('Content-Type:', '', $line));
		   //if(strtolower($contentType) != 'application/zip')
		   if(stripos($line, 'application/zip') === false){
			  //die(status("Invalid zip type, please check file is downloadable.", false ,true));
			  $GLOBALS['downloadPossibleError'] = " Please check file is downloadable.";
		  }
	  }
	}
	return true;
}

function getFileSystemMethod($args = array(), $context = false) {
	//$method = defined('FS_METHOD') ? FS_METHOD : false; //Please ensure that this is either 'direct', 'ssh', 'ftpext' or 'ftpsockets'
	if (!empty($args['hostname']) && $GLOBALS['needFileSystem'] != true) {
		$method = 'direct';
	}
	if ($context == false && ! $method && $GLOBALS['needFileSystem'] != true) {
		$method = 'direct';
	}

	//if ( ! $method && isset($args['connectionType']) && 'ssh' == $args['connectionType'] && extension_loaded('ssh2') && function_exists('stream_get_contents') ) $method = 'ssh2';
	if ( ! $method && defined('APP_FTP_USE_SFTP') && APP_FTP_USE_SFTP == 1 ) $method = 'SFTPExt';
	if ( ! $method && extension_loaded('ftp') ) $method = 'FTPExt';
	//if ( ! $method && ( extension_loaded('sockets') || function_exists('fsockopen') ) ) $method = 'ftpsockets'; //Sockets: Socket extension; PHP Mode: FSockopen / fwrite / fread
	return $method;
}

function initFileSystem($args = false, $context = false){
	
	if(empty($args)){
		$args = array('hostname' => APP_FTP_HOST, 'port' => APP_FTP_PORT, 'username' => APP_FTP_USER, 'password' => APP_FTP_PASS, 'base' => APP_FTP_BASE, 'connectionType' => (defined('APP_FTP_SSL') && APP_FTP_SSL) ? 'ftps' : '', 'passive' => APP_FTP_PASV, 'hostKey' => APP_FTP_KEY);
	}

	$method = getFileSystemMethod($args, $context);

	if (!$method)
		return false;

	$method = "fileSystem".ucfirst($method);
	
	appUpdateMsg('Using '.$method.' file system..');
	
	$GLOBALS['FileSystemObj'] = new $method($args);

	//Define the timeouts for the connections. Only available after the construct is called to allow for per-transport overriding of the default.
	if ( ! defined('FS_CONNECT_TIMEOUT') )
		define('FS_CONNECT_TIMEOUT', 30);
	if ( ! defined('FS_TIMEOUT') )
		define('FS_TIMEOUT', 30);

	//if ( is_error($FileSystemObj->errors) && $FileSystemObj->errors->get_error_code() )
	//	return false;

	if ( !$GLOBALS['FileSystemObj']->connect() )
		return false; //There was an error connecting to the server.

	// Set the permission constants if not already set.
	if ( ! defined('FS_CHMOD_DIR') )
		define('FS_CHMOD_DIR', 0755 );
	if ( ! defined('FS_CHMOD_FILE') )
		define('FS_CHMOD_FILE', 0644 );

	return true;
}


function directToAnyFSCopyDir($from, $to, $skipList = array() ) {//$from => direct file system, $to => automatic filesystem

	$tempWorkingDirFS = new filesystemDirect('');	

	$dirList = $tempWorkingDirFS->dirList($from);

	$from = addTrailingSlash($from);
	$to = addTrailingSlash($to);
	
	$to = $GLOBALS['FileSystemObj']->findFolder($to);
	if($to === false){
		die(status("Could not find the directory(".$to.") using file system", $success=false, $return=true));	
	}	
	$to = addTrailingSlash($to);

	$skipRegex = '';
	foreach ( (array)$skipList as $key => $skipFile )
		$skipRegex .= preg_quote($skipFile, '!') . '|';

	if ( !empty($skipRegex) )
		$skipRegex = '!(' . rtrim($skipRegex, '|') . ')$!i';

	foreach ( (array) $dirList as $filename => $fileinfo ) {
				iwp_mmb_auto_print('tmp_dir_to_destination_copy', "Files Moved : ".$to . $filename);
		if ( !empty($skipRegex) )
			if ( preg_match($skipRegex, $from . $filename) )
				continue;

		if ( 'f' == $fileinfo['type'] ) {
			if ( ! directToAnyFSCopyFile($from . $filename, $to . $filename, true, FS_CHMOD_FILE) ) {
				// If copy failed, chmod file to 0644 and try again.
				$GLOBALS['FileSystemObj']->chmod($to . $filename, 0644);
				if ( ! directToAnyFSCopyFile($from . $filename, $to . $filename, true, FS_CHMOD_FILE) ){
					die(status("Could not copy file: ".$from . $filename." ".$to . $filename, $success=false, $return=true));
					return false;//Could not copy file. $from . $filename $to . $filename
				}
			}
		} elseif ( 'd' == $fileinfo['type'] ) {
			if ( !$GLOBALS['FileSystemObj']->isDir($to . $filename) ) {
				if ( !$GLOBALS['FileSystemObj']->mkDir($to . $filename, FS_CHMOD_DIR) ){
					die(status("Could not create directory: ". $to . $filename, $success=false, $return=true));
					return false; //Could not create directory., $to . $filename
				}
			}
			$result = directToAnyFSCopyDir($from . $filename, $to . $filename, $skipList);
			if ( !$result )
				return false;
		}
	}
	return true;
}

function multicallFSCopyDirNew($from, $to, $skipList = array()){
	$tempWorkingDirFS = new filesystemDirect('');	

	$dirList = $tempWorkingDirFS->dirList($from);
	$from = addTrailingSlash($from);
	$to = addTrailingSlash($to);

	$from = $GLOBALS['FileSystemObj']->findFolder($from);
	$to = $GLOBALS['FileSystemObj']->findFolder($to);
	if($to === false){
		die(status("Could not find the directory(".$to.") using file system", $success=false, $return=true));	
	}	
	$from = addTrailingSlash($from);
	$to = addTrailingSlash($to);

	foreach ((array) $dirList as $filename => $fileinfo )  {

		$result = $GLOBALS['FileSystemObj'] ->chmod($from . $filename, 0777, true);
		$result = $GLOBALS['FileSystemObj'] ->move($from . $filename, $to . $filename, true);
		if (empty($result)) {
			die(status('Unable to move files.', $success=false, $return=true));
		}
	}
	return true;

}

function multicallFSCopyDir($from, $to, $skipList = array()){
	$tempWorkingDirFS = new filesystemDirect('');	

	$dirList = $tempWorkingDirFS->dirList($from);

	$from = addTrailingSlash($from);
	$to = addTrailingSlash($to);
	
	$to = $GLOBALS['FileSystemObj']->findFolder($to);
	if($to === false){
		die(status("Could not find the directory(".$to.") using file system", $success=false, $return=true));	
	}	
	$to = addTrailingSlash($to);
	$skipRegex = '';
	foreach ( (array)$skipList as $key => $skipFile )
		$skipRegex .= preg_quote($skipFile, '!') . '|';

	if ( !empty($skipRegex) )
		$skipRegex = '!(' . rtrim($skipRegex, '|') . ')$!i';

	foreach ( (array) $dirList as $filename => $fileinfo ) {
				iwp_mmb_auto_print('tmp_dir_to_destination_copy', "Files Moved : ".$to . $filename);
		if ( !empty($skipRegex) )
			if ( preg_match($skipRegex, $from . $filename) )
				continue;
		if ( 'f' == $fileinfo['type'] ) {
			if ( ! directToAnyFSCopyFile($from . $filename, $to . $filename, true, FS_CHMOD_FILE) ) {
				// If copy failed, chmod file to 0644 and try again.
				$GLOBALS['FileSystemObj']->chmod($to . $filename, 0644);
				if ( ! directToAnyFSCopyFile($from . $filename, $to . $filename, true, FS_CHMOD_FILE) ){
					// die(status("Could not copy file: ".$from . $filename." ".$to . $filename, $success=false, $return=true));
					// return false;//Could not copy file. $from . $filename $to . $filename
				}else{
					$tempWorkingDirFS->delete($from . $filename );//recursive function will not try to copy agin in multicall
					$tempWorkingDirFS->delete($from);// recursive function will not try to list again already copied dir
				}
			}else{
					$tempWorkingDirFS->delete($from . $filename );//recursive function will not try to copy agin in multicall
					$tempWorkingDirFS->delete($from);// recursive function will not try to list again already copied dir

			}
		} elseif ( 'd' == $fileinfo['type'] ) {
			if ( !$GLOBALS['FileSystemObj']->isDir($to . $filename) ) {
				if ( !$GLOBALS['FileSystemObj']->mkDir($to . $filename, FS_CHMOD_DIR) ){
					die(status("Could not create directory: ". $to . $filename, $success=false, $return=true));
					return false; //Could not create directory., $to . $filename
				}
			}
			$result = multicallFSCopyDir($from . $filename, $to . $filename, $skipList);
			
			if ( !$result )
				return false;

		}
		$isBreak = check_for_clone_break();
		if ($isBreak) {
			$response_arr['break'] = true;
			return $response_arr;
		}
	}	
	return true;
}
function directToAnyFSCopyFile($source, $destination, $overwrite = false, $mode = false){
		//echo "<br>Final file : ".$destination;
		iwp_mmb_auto_print('tmp_dir_to_destination_copy', "Files Moved : ".$destination);
	if($GLOBALS['FileSystemObj']->method == 'direct'){
		return $GLOBALS['FileSystemObj']->copy($source, $destination, $overwrite, $mode);
	}
	elseif($GLOBALS['FileSystemObj']->method == 'FTPExt' || $GLOBALS['FileSystemObj']->method == 'ftpsockets' || $GLOBALS['FileSystemObj']->method == 'ssh2' || $GLOBALS['FileSystemObj']->method == 'sftp'){
		if ( ! $overwrite && $GLOBALS['FileSystemObj']->exists($destination) )
			return false;
		//$content = $this->get_contents($source);
//		if ( false === $content)
//			return false;
			
		//put content	
		//$tempfile = wp_tempnam($file);

		$sourceHandle = fopen($source, 'r');
		if ( ! $sourceHandle )
			return false;

		//fwrite($temp, $contents);
		//fseek($temp, 0); //Skip back to the start of the file being written to
		
		$sampleContent = fread($sourceHandle, (1024 * 1024 * 2));//1024 * 1024 * 2 => 2MB
		fseek($sourceHandle, 0); //Skip back to the start of the file being written to

		$type = isBinary($sampleContent) ? FTP_BINARY : FTP_ASCII;
		
		if($GLOBALS['FileSystemObj']->method == 'FTPExt'){
			$ret = ftp_fput($GLOBALS['FileSystemObj']->link, $destination, $sourceHandle, $type);
		} elseif($GLOBALS['FileSystemObj']->method == 'ssh2' || $GLOBALS['FileSystemObj']->method == 'sftp') {
			$ret = $GLOBALS['FileSystemObj']->putContents($destination, $sampleContent, $mode);
		}
		//elseif($GLOBALS['FileSystemObj']->method == 'ftpsockets'){
//			$GLOBALS['FileSystemObj']->ftp->SetType($type);
//			$ret = $GLOBALS['FileSystemObj']->ftp->fput($destination, $sourceHandle);
//		}
		unset($sampleContent);
		fclose($sourceHandle);
		unlink($source);//to immediately save system space
		//unlink($tempfile);
		
		if($mode){
			$GLOBALS['FileSystemObj']->chmod($destination, $mode);
		}

		return $ret;
		
		//return $this->put_contents($destination, $content, $mode);
	}
}



//==========================================================================>


class filesystemBase {
	
	var $verbose = false;
	
	var $cache = array();
	
	var $method = '';

	/**
	 * Locates a folder on the remote filesystem.
	 *
	 * Assumes that on Windows systems, Stripping off the Drive letter is OK
	 * Sanitizes \\ to / in windows filepaths.
	 *
	 * @access public
	 *
	 * @param string $folder the folder to locate
	 * @return string The location of the remote path.
	 */
	function findFolder($folder) {

		if (( stripos($this->method, 'ftp') !== false) || 'ssh2' == $this->method || 'sftp' == $this->method ) {
			$folder = str_replace(dirname(dirname(__FILE__)), APP_FTP_BASE, $folder);//dirname(dirname(__FILE__)) => one folder up to clone_controller
			$folder = str_replace('//', '/', $folder);//removing any // in the path
			return addTrailingSlash($folder);
		} elseif ( 'direct' == $this->method ) {
			$folder = str_replace('\\', '/', $folder); //Windows path sanitisation
			return addTrailingSlash($folder);
		}
		return false;
	}
	/**
	 * Returns the *nix style file permissions for a file
	 *
	 * From the PHP documentation page for fileperms()
	 *
	 * @link http://docs.php.net/fileperms
	 * @access public
	 *
	 * @param string $file string filename
	 * @return int octal representation of permissions
	 */
	function getHChmod($file){
		$perms = $this->getChmod($file);
		if (($perms & 0xC000) == 0xC000) // Socket
			$info = 's';
		elseif (($perms & 0xA000) == 0xA000) // Symbolic Link
			$info = 'l';
		elseif (($perms & 0x8000) == 0x8000) // Regular
			$info = '-';
		elseif (($perms & 0x6000) == 0x6000) // Block special
			$info = 'b';
		elseif (($perms & 0x4000) == 0x4000) // Directory
			$info = 'd';
		elseif (($perms & 0x2000) == 0x2000) // Character special
			$info = 'c';
		elseif (($perms & 0x1000) == 0x1000) // FIFO pipe
			$info = 'p';
		else // Unknown
			$info = 'u';

		// Owner
		$info .= (($perms & 0x0100) ? 'r' : '-');
		$info .= (($perms & 0x0080) ? 'w' : '-');
		$info .= (($perms & 0x0040) ?
					(($perms & 0x0800) ? 's' : 'x' ) :
					(($perms & 0x0800) ? 'S' : '-'));

		// Group
		$info .= (($perms & 0x0020) ? 'r' : '-');
		$info .= (($perms & 0x0010) ? 'w' : '-');
		$info .= (($perms & 0x0008) ?
					(($perms & 0x0400) ? 's' : 'x' ) :
					(($perms & 0x0400) ? 'S' : '-'));

		// World
		$info .= (($perms & 0x0004) ? 'r' : '-');
		$info .= (($perms & 0x0002) ? 'w' : '-');
		$info .= (($perms & 0x0001) ?
					(($perms & 0x0200) ? 't' : 'x' ) :
					(($perms & 0x0200) ? 'T' : '-'));
		return $info;
	}

	/**
	 * Converts *nix style file permissions to a octal number.
	 *
	 * Converts '-rw-r--r--' to 0644
	 * From "info at rvgate dot nl"'s comment on the PHP documentation for chmod()
	 *
	 * @link http://docs.php.net/manual/en/function.chmod.php#49614
	 * @access public
	 *
	 * @param string $mode string *nix style file permission
	 * @return int octal representation
	 */
	function getNumChmodFromH($mode) {
		$realMode = '';
		$legal =  array('', 'w', 'r', 'x', '-');
		$attArray = preg_split('//', $mode);

		for ($i=0; $i < count($attArray); $i++)
		   if ($key = array_search($attArray[$i], $legal))
			   $realMode .= $legal[$key];

		$mode = str_pad($realMode, 9, '-');
		$trans = array('-'=>'0', 'r'=>'4', 'w'=>'2', 'x'=>'1');
		$mode = strtr($mode,$trans);

		$newmode = '';
		$newmode .= $mode[0] + $mode[1] + $mode[2];
		$newmode .= $mode[3] + $mode[4] + $mode[5];
		$newmode .= $mode[6] + $mode[7] + $mode[8];
		return $newmode;
	}
	
	
	
	/**
	 * Unzips a specified ZIP file to a location on the Filesystem via the WordPress Filesystem Abstraction.
	 * Does not extract a root-level __MACOSX directory, if present.
	 *
	 * Attempts to increase the PHP Memory limit to 256M before uncompressing,
	 * However, The most memory required shouldn't be much larger than the Archive itself.
	 *
	 *
	 * @param string $file Full path and filename of zip archive
	 * @param string $to Full path on the filesystem to extract archive to
	 * @return mixed WP_Error on failure, True on success
	 */
	function unZipFile($file, $to) {
	
		if ( ! $GLOBALS['FileSystemObj'] || !is_object($GLOBALS['FileSystemObj']) ){
			//return new WP_Error('fs_unavailable', __('Could not access filesystem.'));
			appUpdateMsg('Could not access file system.', true);
		}
	
		// Unzip can use a lot of memory, but not this much hopefully
		@ini_set('memory_limit', '256M');
	
		$neededDirs = array();
		$to = addTrailingSlash($to);
	
		// Determine any parent dir's needed (of the upgrade directory)
		if ( ! $GLOBALS['FileSystemObj']->isDir($to) ) { //Only do parents if no children exist
			$path = preg_split('![/\\\]!', removeTrailingSlash($to));
			for ( $i = count($path); $i >= 0; $i-- ) {
				if ( empty($path[$i]) )
					continue;
	
				$dir = implode('/', array_slice($path, 0, $i+1) );
				if ( preg_match('!^[a-z]:$!i', $dir) ) // Skip it if it looks like a Windows Drive letter.
					continue;
	
				if ( ! $GLOBALS['FileSystemObj']->isDir($dir) )
					$neededDirs[] = $dir;
				else
					break; // A folder exists, therefor, we dont need the check the levels below this
			}
		}
	
		if ( class_exists('ZipArchive') ) {
			$result = $this->zipArchiveUnZip($file, $to, $neededDirs);
			if ( true === $result ) {
				return $result;
			} elseif ( $result != 'incompatible_archive' ) {
				return $result;
			}
		}
		// Fall through to PclZip if ZipArchive is not available, or encountered an error opening the file.
		return $this->pclZipUnZip($file, $to, $neededDirs);
	}
	
	/**
	 * This function should not be called directly, use unzip_file instead. Attempts to unzip an archive using the ZipArchive class.
	 *
	 * @see unzip_file
	 * @access private
	 *
	 * @param string $file Full path and filename of zip archive
	 * @param string $to Full path on the filesystem to extract archive to
	 * @param array $neededDirs A partial list of required folders needed to be created.
	 * @return mixed WP_Error on failure, True on success
	 */
	function zipArchiveUnZip($file, $to, $neededDirs = array() ) {
		//global $GLOBALS['FileSystemObj'];
		$z = new ZipArchive();
	
		// PHP4-compat - php4 classes can't contain constants
		$zopen = $z->open($file, /* ZIPARCHIVE::CHECKCONS */ 4);
		if ( true !== $zopen ){
			//return new WP_Error('incompatible_archive', __('Incompatible Archive.'));
			//appUpdateMsg('Incompatible Archive', true);
			return 'incompatible_archive';
		}
	
		for ( $i = 0; $i < $z->numFiles; $i++ ) {
			if ( ! $info = $z->statIndex($i) ){
				//return new WP_Error('stat_failed', __('Could not retrieve file from archive.'));
				appUpdateMsg('Could not retrieve file from archive.', true);
				return false;
			}
	
			if ( '__MACOSX/' === substr($info['name'], 0, 9) ) // Skip the OS X-created __MACOSX directory
				continue;
	
			if ( '/' == substr($info['name'], -1) ) // directory
				$neededDirs[] = $to . removeTrailingSlash($info['name']);
			else
				$neededDirs[] = $to . removeTrailingSlash(dirname($info['name']));
		}
	
		$neededDirs = array_unique($neededDirs);
		foreach ( $neededDirs as $dir ) {
			// Check the parent folders of the folders all exist within the creation array.
			if ( removeTrailingSlash($to) == $dir ) // Skip over the working directory, We know this exists (or will exist)
				continue;
			if ( strpos($dir, $to) === false ) // If the directory is not within the working directory, Skip it
				continue;
	
			$parentFolder = dirname($dir);
			while ( !empty($parentFolder) && removeTrailingSlash($to) != $parentFolder && !in_array($parentFolder, $neededDirs) ) {
				$neededDirs[] = $parentFolder;
				$parentFolder = dirname($parentFolder);
			}
		}
		asort($neededDirs);
	
		// Create those directories if need be:
		foreach ( $neededDirs as $_dir ) {
			if ( ! $GLOBALS['FileSystemObj']->mkDir($_dir, FS_CHMOD_DIR) && ! $GLOBALS['FileSystemObj']->isDir($_dir) ){ // Only check to see if the Dir exists upon creation failure. Less I/O this way.
				//return new WP_Error('mkdir_failed', __('Could not create directory.'), $_dir);
				appUpdateMsg('Could not create directory '.$_dir, true);
				return false;
			}
		}
		unset($neededDirs);
	
		for ( $i = 0; $i < $z->numFiles; $i++ ) {
			if ( ! $info = $z->statIndex($i) ){
				//return new WP_Error('stat_failed', __('Could not retrieve file from archive.'));
				appUpdateMsg('Could not retrieve file from archive', true);
				return false;
			}
	
			if ( '/' == substr($info['name'], -1) ) // directory
				continue;
	
			if ( '__MACOSX/' === substr($info['name'], 0, 9) ) // Don't extract the OS X-created __MACOSX directory files
				continue;
	
			$contents = $z->getFromIndex($i);
			if ( false === $contents ){
				//return new WP_Error('extract_failed', __('Could not extract file from archive.'), $info['name']);
				appUpdateMsg('Could not extract '.$info['name'].' file from archive.', true);
				return false;
			}
	
			if ( ! $GLOBALS['FileSystemObj']->putContents( $to . $info['name'], $contents, FS_CHMOD_FILE) ){
				//return new WP_Error('copy_failed', __('Could not copy file.'), $to . $info['name']);
				appUpdateMsg('Could not copy file '.$to . $info['name'], true);
				return false;
			}
		}
	
		$z->close();
	
		return true;
	}
	
	/**
	 * This function should not be called directly, use unzip_file instead. Attempts to unzip an archive using the PclZip library.
	 *
	 * @since 3.0.0
	 * @see unzip_file
	 * @access private
	 *
	 * @param string $file Full path and filename of zip archive
	 * @param string $to Full path on the filesystem to extract archive to
	 * @param array $neededDirs A partial list of required folders needed to be created.
	 * @return mixed WP_Error on failure, True on success
	 */
	function pclZipUnZip($file, $to, $neededDirs = array()) {
		//global $GLOBALS['FileSystemObj'];
		// See #15789 - PclZip uses string functions on binary data, If it's overloaded with Multibyte safe functions the results are incorrect.
		if ( ini_get('mbstring.func_overload') && function_exists('mb_internal_encoding') ) {
			$previous_encoding = mb_internal_encoding();
			mb_internal_encoding('ISO-8859-1');
		}
	
		require_once(APP_ROOT . '/lib/pclzip.php');
	
		$archive = new PclZip($file);
	
		$archive_files = $archive->extract(PCLZIP_OPT_EXTRACT_AS_STRING);
	
		if ( isset($previous_encoding) )
			mb_internal_encoding($previous_encoding);
	
		// Is the archive valid?
		if ( !is_array($archive_files) ){
			//return new WP_Error('incompatible_archive', __('Incompatible Archive.'), $archive->errorInfo(true));
			appUpdateMsg('Incompatible Archive '.$archive->errorInfo(true), true);
			return false;
		}
	
		if ( 0 == count($archive_files) ){
			//return new WP_Error('empty_archive', __('Empty archive.'));
			appUpdateMsg('Empty archive', true);
			return false;
		}
	
		// Determine any children directories needed (From within the archive)
		foreach ( $archive_files as $file ) {
			if ( '__MACOSX/' === substr($file['filename'], 0, 9) ) // Skip the OS X-created __MACOSX directory
				continue;
	
			$neededDirs[] = $to . removeTrailingSlash( $file['folder'] ? $file['filename'] : dirname($file['filename']) );
		}
	
		$neededDirs = array_unique($neededDirs);
		foreach ( $neededDirs as $dir ) {
			// Check the parent folders of the folders all exist within the creation array.
			if ( removeTrailingSlash($to) == $dir ) // Skip over the working directory, We know this exists (or will exist)
				continue;
			if ( strpos($dir, $to) === false ) // If the directory is not within the working directory, Skip it
				continue;
	
			$parentFolder = dirname($dir);
			while ( !empty($parentFolder) && removeTrailingSlash($to) != $parentFolder && !in_array($parentFolder, $neededDirs) ) {
				$neededDirs[] = $parentFolder;
				$parentFolder = dirname($parentFolder);
			}
		}
		asort($neededDirs);
	
		// Create those directories if need be:
		foreach ( $neededDirs as $_dir ) {
			if ( ! $GLOBALS['FileSystemObj']->mkDir($_dir, FS_CHMOD_DIR) && ! $GLOBALS['FileSystemObj']->isDir($_dir) ){ // Only check to see if the dir exists upon creation failure. Less I/O this way.
				//return new WP_Error('mkdir_failed', __('Could not create directory.'), $_dir);
				appUpdateMsg('Could not create directory '.$_dir, true);
				return false;
			}
		}
		unset($neededDirs);
	
		// Extract the files from the zip
		foreach ( $archive_files as $file ) {
			if ( $file['folder'] )
				continue;
	
			if ( '__MACOSX/' === substr($file['filename'], 0, 9) ) // Don't extract the OS X-created __MACOSX directory files
				continue;
	
			if ( ! $GLOBALS['FileSystemObj']->putContents( $to . $file['filename'], $file['content'], FS_CHMOD_FILE) ){
				//return new WP_Error('copy_failed', __('Could not copy file.'), $to . $file['filename']);
				appUpdateMsg('Could not copy file '.$to . $file['filename'], true);
				return false;
			}
		}
		return true;
	}
	
	/**
	 * Copies a directory from one location to another via the WordPress Filesystem Abstraction.
	 *
	 * @param string $from source directory
	 * @param string $to destination directory
	 * @param array $skipList a list of files/folders to skip copying
	 * @return mixed WP_Error on failure, True on success.
	 */
	function copyDir($from, $to, $skipList = array() ) {
		//global $GLOBALS['FileSystemObj'];
	
		$dirlist = $GLOBALS['FileSystemObj']->dirList($from);
	
		$from = addTrailingSlash($from);
		$to = addTrailingSlash($to);
	
		$skipRegex = '';
		foreach ( (array)$skipList as $key => $skipFile )
			$skipRegex .= preg_quote($skipFile, '!') . '|';
	
		if ( !empty($skipRegex) )
			$skipRegex = '!(' . rtrim($skipRegex, '|') . ')$!i';
	
		foreach ( (array) $dirlist as $filename => $fileinfo ) {
			if ( !empty($skipRegex) )
				if ( preg_match($skipRegex, $from . $filename) )
					continue;
	
			if ( 'f' == $fileinfo['type'] ) {
				if ( ! $GLOBALS['FileSystemObj']->copy($from . $filename, $to . $filename, true, FS_CHMOD_FILE) ) {
					// If copy failed, chmod file to 0644 and try again.
					$GLOBALS['FileSystemObj']->chmod($to . $filename, 0644);
					if ( ! $GLOBALS['FileSystemObj']->copy($from . $filename, $to . $filename, true, FS_CHMOD_FILE) ){
						//return new WP_Error('copy_failed', __('Could not copy file.'), $to . $filename);
						appUpdateMsg('Could not copy file '.$to . $file['filename'], true);
						return false;
					}
				}
			} elseif ( 'd' == $fileinfo['type'] ) {
				if ( !$GLOBALS['FileSystemObj']->isDir($to . $filename) ) {
					if ( !$GLOBALS['FileSystemObj']->mkDir($to . $filename, FS_CHMOD_DIR) ){
						//return new WP_Error('mkdir_failed', __('Could not create directory.'), $to . $filename);
						appUpdateMsg('Could not create directory '.$to . $filename, true);
						return false;
					}
				}
				$result = $this->copyDir($from . $filename, $to . $filename, $skipList);
				if ( $result == false )
					return $result;
			}
		}
		return true;
	}
}


//==========================================================================>


class filesystemDirect extends filesystemBase {

	function __construct($arg) {
		$this->method = 'direct';
		//$this->errors = new WP_Error();
		
	}

	function connect() {
		return true;
	}
	/**
	 * Reads entire file into a string
	 *
	 * @param string $file Name of the file to read.
	 * @return string|bool The function returns the read data or false on failure.
	 */
	function getContents($file) {
		return @file_get_contents($file);
	}
	/**
	 * Reads entire file into an array
	 *
	 * @param string $file Path to the file.
	 * @return array|bool the file contents in an array or false on failure.
	 */
	function getContentsArray($file) {
		return @file($file);
	}
	/**
	 * Write a string to a file
	 *
	 * @param string $file Remote path to the file where to write the data.
	 * @param string $contents The data to write.
	 * @param int $mode (optional) The file permissions as octal number, usually 0644.
	 * @return bool False upon failure.
	 */
	function putContents($file, $contents, $mode = false ) {
		if ( ! ($fp = @fopen($file, 'w')) )
			return false;
		@fwrite($fp, $contents);
		@fclose($fp);
		$this->chmod($file, $mode);
		return true;
	}
	/**
	 * Gets the current working directory
	 *
	 * @return string|bool the current working directory on success, or false on failure.
	 */
	function cwd() {
		return @getcwd();
	}
	/**
	 * Change directory
	 *
	 * @param string $dir The new current directory.
	 * @return bool Returns true on success or false on failure.
	 */
	function chdir($dir) {
		return @chdir($dir);
	}
	/**
	 * Changes file group
	 *
	 * @param string $file Path to the file.
	 * @param mixed $group A group name or number.
	 * @param bool $recursive (optional) If set True changes file group recursively. Defaults to False.
	 * @return bool Returns true on success or false on failure.
	 */
	function chgrp($file, $group, $recursive = false) {
		if ( ! $this->exists($file) )
			return false;
		if ( ! $recursive )
			return @chgrp($file, $group);
		if ( ! $this->isDir($file) )
			return @chgrp($file, $group);
		//Is a directory, and we want recursive
		$file = addTrailingSlash($file);
		$fileList = $this->dirList($file);
		foreach ($fileList as $fileName)
			$this->chgrp($file . $fileName, $group, $recursive);

		return true;
	}
	/**
	 * Changes filesystem permissions
	 *
	 * @param string $file Path to the file.
	 * @param int $mode (optional) The permissions as octal number, usually 0644 for files, 0755 for dirs.
	 * @param bool $recursive (optional) If set True changes file group recursively. Defaults to False.
	 * @return bool Returns true on success or false on failure.
	 */
	function chmod($file, $mode = false, $recursive = false) {
		if ( ! $mode ) {
			if ( $this->isFile($file) )
				$mode = FS_CHMOD_FILE;
			elseif ( $this->isDir($file) )
				$mode = FS_CHMOD_DIR;
			else
				return false;
		}

		if ( ! $recursive || ! $this->isDir($file) )
			return @chmod($file, $mode);
		//Is a directory, and we want recursive
		$file = addTrailingSlash($file);
		$fileList = $this->dirList($file);
		foreach ( (array)$fileList as $fileName => $filemeta)
			$this->chmod($file . $fileName, $mode, $recursive);

		return true;
	}
	/**
	 * Changes file owner
	 *
	 * @param string $file Path to the file.
	 * @param mixed $owner A user name or number.
	 * @param bool $recursive (optional) If set True changes file owner recursively. Defaults to False.
	 * @return bool Returns true on success or false on failure.
	 */
	function chown($file, $owner, $recursive = false) {
		if ( ! $this->exists($file) )
			return false;
		if ( ! $recursive )
			return @chown($file, $owner);
		if ( ! $this->isDir($file) )
			return @chown($file, $owner);
		//Is a directory, and we want recursive
		$fileList = $this->dirList($file);
		foreach ($fileList as $fileName) {
			$this->chown($file . '/' . $fileName, $owner, $recursive);
		}
		return true;
	}
	/**
	 * Gets file owner
	 *
	 * @param string $file Path to the file.
	 * @return string Username of the user.
	 */
	function owner($file) {
		$owneruid = @fileowner($file);
		if ( ! $owneruid )
			return false;
		if ( ! function_exists('posix_getpwuid') )
			return $owneruid;
		$ownerarray = posix_getpwuid($owneruid);
		return $ownerarray['name'];
	}
	/**
	 * Gets file permissions
	 *
	 * FIXME does not handle errors in fileperms()
	 *
	 * @param string $file Path to the file.
	 * @return string Mode of the file (last 4 digits).
	 */
	function getChmod($file) {
		return substr(decoct(@fileperms($file)),3);
	}
	function group($file) {
		$gid = @filegroup($file);
		if ( ! $gid )
			return false;
		if ( ! function_exists('posix_getgrgid') )
			return $gid;
		$grouparray = posix_getgrgid($gid);
		return $grouparray['name'];
	}

	function copy($source, $destination, $overwrite = false, $mode = false) {
		if ( ! $overwrite && $this->exists($destination) )
			return false;

		$rtval = copy($source, $destination);
		if ( $mode )
			$this->chmod($destination, $mode);
		return $rtval;
	}

	function move($source, $destination, $overwrite = false) {
		if ( ! $overwrite && $this->exists($destination) )
			return false;

		// try using rename first. if that fails (for example, source is read only) try copy
		if ( @rename($source, $destination) )
			return true;

		if ( $this->copy($source, $destination, $overwrite) && $this->exists($destination) ) {
			$this->delete($source);
			return true;
		} else {
			return false;
		}
	}

	function delete($file, $recursive = false, $type = false) {
		if ( empty($file) ) //Some filesystems report this as /, which can cause non-expected recursive deletion of all files in the filesystem.
			return false;
		$file = str_replace('\\', '/', $file); //for win32, occasional problems deleting files otherwise

		if ( 'f' == $type || $this->isFile($file) )
			return @unlink($file);
		if ( ! $recursive && $this->isDir($file) )
			return @rmdir($file);

		//At this point its a folder, and we're in recursive mode
		$file = addTrailingSlash($file);
		$fileList = $this->dirList($file, true);

		$retval = true;
		if ( is_array($fileList) ) //false if no files, So check first.
			foreach ($fileList as $fileName => $fileinfo){
				iwp_mmb_auto_print('recursive_delete');
				if ( ! $this->delete($file . $fileName, $recursive, $fileinfo['type']) )
					$retval = false;
			}
		if ( file_exists($file) && ! @rmdir($file) )
			$retval = false;
		return $retval;
	}

	function exists($file) {
		return @file_exists($file);
	}

	function isFile($file) {
		return @is_file($file);
	}

	function isDir($path) {
		return @is_dir($path);
	}

	function isReadable($file) {
		return @is_readable($file);
	}

	function isWritable($file) {
		return @is_writable($file);
	}

	function atime($file) {
		return @fileatime($file);
	}

	function mtime($file) {
		return @filemtime($file);
	}
	function size($file) {
		return @filesize($file);
	}

	function touch($file, $time = 0, $atime = 0) {
		if ($time == 0)
			$time = time();
		if ($atime == 0)
			$atime = time();
		return @touch($file, $time, $atime);
	}

	function mkDir($path, $chmod = false, $chown = false, $chgrp = false) {
		// safe mode fails with a trailing slash under certain PHP versions.
		$path = removeTrailingSlash($path);
		if ( empty($path) )
			return false;

		if ( ! $chmod )
			$chmod = FS_CHMOD_DIR;

		if ( ! @mkdir($path) )
			return false;
		$this->chmod($path, $chmod);
		if ( $chown )
			$this->chown($path, $chown);
		if ( $chgrp )
			$this->chgrp($path, $chgrp);
		return true;
	}

	function rmDir($path, $recursive = false) {
		return $this->delete($path, $recursive);
	}

	function dirList($path, $includeHidden = true, $recursive = false) {
		if ( $this->isFile($path) ) {
			$limitFile = basename($path);
			$path = dirname($path);
		} else {
			$limitFile = false;
		}

		if ( ! $this->isDir($path) )
			return false;

		$dir = @dir($path);
		if ( ! $dir )
			return false;

		$ret = array();

		while (false !== ($entry = $dir->read()) ) {
			$struc = array();
			$struc['name'] = $entry;

			if ( '.' == $struc['name'] || '..' == $struc['name'] )
				continue;

			if ( ! $includeHidden && '.' == $struc['name'][0] )
				continue;

			if ( $limitFile && $struc['name'] != $limitFile)
				continue;

			$struc['perms'] 	= $this->getHChmod($path.'/'.$entry);
			$struc['permsn']	= $this->getNumChmodFromH($struc['perms']);
			$struc['number'] 	= false;
			$struc['owner']    	= $this->owner($path.'/'.$entry);
			$struc['group']    	= $this->group($path.'/'.$entry);
			$struc['size']    	= $this->size($path.'/'.$entry);
			$struc['lastmodunix']= $this->mtime($path.'/'.$entry);
			$struc['lastmod']   = @date('M j',$struc['lastmodunix']);
			$struc['time']    	= @date('h:i:s',$struc['lastmodunix']);
			$struc['type']		= $this->isDir($path.'/'.$entry) ? 'd' : 'f';

			if ( 'd' == $struc['type'] ) {
				if ( $recursive )
					$struc['files'] = $this->dirList($path . '/' . $struc['name'], $includeHidden, $recursive);
				else
					$struc['files'] = array();
			}

			$ret[ $struc['name'] ] = $struc;
		}
		$dir->close();
		unset($dir);
		return $ret;
	}
}




//==========================================================================>


class filesystemFTPExt extends filesystemBase {
	var $link;
	var $errors = null;
	var $options = array();

	function __construct($opt='') {
		$this->method = 'FTPExt';
		//$this->errors = new WP_Error();

		//Check if possible to use ftp functions.
		if ( ! extension_loaded('ftp') ) {
			//$this->errors->add('no_ftp_ext', __('The ftp PHP extension is not available'));
			appUpdateMsg('The FTP PHP extension is not available', true);
			return false;
		}

		// Set defaults:
		//This Class uses the timeout on a per-connection basis, Others use it on a per-action basis.

		if ( ! defined('FS_TIMEOUT') )
			define('FS_TIMEOUT', 240);

		if ( empty($opt['port']) )
			$this->options['port'] = 21;
		else
			$this->options['port'] = $opt['port'];

		if ( empty($opt['hostname']) ){
			//$this->errors->add('empty_hostname', __('FTP hostname is required'));
			appUpdateMsg('FTP hostname is required');
		}
		else
			$this->options['hostname'] = $opt['hostname'];

		if ( ! empty($opt['base']) )
			$this->baseDir = $opt['base'];

		// Check if the options provided are OK.
		if ( empty($opt['username']) ){
			//$this->errors->add('empty_username', __('FTP username is required'));
			appUpdateMsg('FTP username is required');
		}
		else
			$this->options['username'] = $opt['username'];

		if ( empty($opt['password']) ){
			//$this->errors->add('empty_password', __('FTP password is required'));
			appUpdateMsg('FTP password is required');
		}
		else
			$this->options['password'] = $opt['password'];

		$this->options['ssl'] = false;
		if ( 'ftps' == $opt['connectionType'] )
			$this->options['ssl'] = true;

		if($opt['passive']){
			$this->options['passive'] = $opt['passive'];
		}
	}

	function connect() {
		if(!$this->options['hostname'] || !$this->options['username'] || !$this->options['password']){
			appUpdateMsg(sprintf('FTP hostname/username/password is missing"'));
			return false;
		}
		
		if ( isset($this->options['ssl']) && $this->options['ssl'] && function_exists('ftp_ssl_connect') )
			$this->link = @ftp_ssl_connect($this->options['hostname'], $this->options['port'], FS_CONNECT_TIMEOUT);
		else		
			$this->link = ftp_connect($this->options['hostname'], $this->options['port'], FS_CONNECT_TIMEOUT);

		if ( ! $this->link ) {
			//$this->errors->add('connect', sprintf(__('Failed to connect to FTP Server %1$s:%2$s'), $this->options['hostname'], $this->options['port']));
			appUpdateMsg(sprintf('Failed to connect to the FTP server "%1$s:%2$s"', $this->options['hostname'], $this->options['port']));
			return false;
		}

		if ( ! @ftp_login($this->link,$this->options['username'], $this->options['password']) ) {
			//$this->errors->add('auth', sprintf(__('Username/Password incorrect for %s'), $this->options['username']));
			appUpdateMsg(sprintf('FTP username or password incorrect for "%s"', $this->options['username']));
			return false;
		}

		//Set the Connection to use Passive FTP
		if($this->options['passive']){
			@ftp_pasv( $this->link, true );
		}
		if ( @ftp_get_option($this->link, FTP_TIMEOUT_SEC) < FS_TIMEOUT )
			@ftp_set_option($this->link, FTP_TIMEOUT_SEC, FS_TIMEOUT);

		return true;
	}

	function getContents($file, $type = '', $resumePos = 0 ) {
		if ( empty($type) )
			$type = FTP_BINARY;

		$tempfile = getTempName($file);
		$temp = fopen($tempfile, 'w+');

		if ( ! $temp )
			return false;

		if ( ! @ftp_fget($this->link, $temp, $file, $type, $resumePos) )
			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);
		unlink($tempfile);
		return $contents;
	}
	function getContentsArray($file) {
		return explode("\n", $this->getContents($file));
	}

	function putContents($file, $contents, $mode = false ) {
		$tempfile = getTempName($file);
		$temp = fopen($tempfile, 'w+');
		if ( ! $temp )
			return false;

		fwrite($temp, $contents);
		fseek($temp, 0); //Skip back to the start of the file being written to

		$type = isBinary($contents) ? FTP_BINARY : FTP_ASCII;
		$ret = @ftp_fput($this->link, $file, $temp, $type);

		fclose($temp);
		unlink($tempfile);

		$this->chmod($file, $mode);

		return $ret;
	}
	function cwd() {
		$cwd = @ftp_pwd($this->link);
		if ( $cwd )
			$cwd = addTrailingSlash($cwd);
		return $cwd;
	}
	function chdir($dir) {
		return @ftp_chdir($this->link, $dir);
	}
	function chgrp($file, $group, $recursive = false ) {
		return false;
	}
	function chmod($file, $mode = false, $recursive = false) {
		if ( ! $mode ) {
			if ( $this->isFile($file) )
				$mode = FS_CHMOD_FILE;
			elseif ( $this->isDir($file) )
				$mode = FS_CHMOD_DIR;
			else
				return false;
		}

		// chmod any sub-objects if recursive.
		if ( $recursive && $this->isDir($file) ) {
			$fileList = $this->dirList($file);
			foreach ( (array)$fileList as $fileName => $filemeta )
				$this->chmod($file . '/' . $fileName, $mode, $recursive);
		}

		// chmod the file or directory
		if ( ! function_exists('ftp_chmod') )
			return (bool)@ftp_site($this->link, sprintf('CHMOD %o %s', $mode, $file));
		return (bool)@ftp_chmod($this->link, $mode, $file);
	}
	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 group($file) {
		$dir = $this->dirList($file);
		return $dir[$file]['group'];
	}
	function copy($source, $destination, $overwrite = false, $mode = false) {
		if ( ! $overwrite && $this->exists($destination) )
			return false;
		$content = $this->getContents($source);
		if ( false === $content)
			return false;
		return $this->putContents($destination, $content, $mode);
	}
	function move($source, $destination, $overwrite = false) {
		if ($overwrite) {
			$this->delete($destination, true);
		}
		return ftp_rename($this->link, $source, $destination);
	}

	function delete($file, $recursive = false, $type = false) {
		if(!$this->link){
			return false;
		}
		if ( empty($file) )
			return false;
		if ( 'f' == $type || $this->isFile($file) )
			return @ftp_delete($this->link, $file);
		if ( !$recursive )
			return @ftp_rmdir($this->link, $file);

		$fileList = $this->dirList( addTrailingSlash($file) );
		if ( !empty($fileList) )
			foreach ( $fileList as $deleteFile ){
				iwp_mmb_auto_print('recursive_delete');
				$this->delete( addTrailingSlash($file) . $deleteFile['name'], $recursive, $deleteFile['type'] );
			}
		return @ftp_rmdir($this->link, $file);
	}

	function exists($file) {
		$list = @ftp_nlist($this->link, $file);
		return !empty($list); //empty list = no file, so invert.
	}
	function isFile($file) {
		return $this->exists($file) && !$this->isDir($file);
	}
	function isDir($path) {
		$cwd = $this->cwd();
		$result = @ftp_chdir($this->link, addTrailingSlash($path) );
		if ( $result && $path == $this->cwd() || $this->cwd() != $cwd ) {
			@ftp_chdir($this->link, $cwd);
			return true;
		}
		return false;
	}
	function isReadable($file) {
		//Get dir list, Check if the file is readable by the current user??
		return true;
	}
	function isWritable($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 ftp_mdtm($this->link, $file);
	}
	function size($file) {
		return ftp_size($this->link, $file);
	}
	function touch($file, $time = 0, $atime = 0) {
		return false;
	}
	function mkDir($path, $chmod = false, $chown = false, $chgrp = false) {
		$path = removeTrailingSlash($path);
		if ( empty($path) )
			return false;

		if ( !@ftp_mkdir($this->link, $path) )
			return false;
		$this->chmod($path, $chmod);
		if ( $chown )
			$this->chown($path, $chown);
		if ( $chgrp )
			$this->chgrp($path, $chgrp);
		return true;
	}
	function rmDir($path, $recursive = false) {
		return $this->delete($path, $recursive);
	}

	function parseListing($line) {
		static $isWindows;
		if ( is_null($isWindows) )
			$isWindows = stripos( ftp_systype($this->link), 'win') !== false;

		if ( $isWindows && preg_match('/([0-9]{2})-([0-9]{2})-([0-9]{2}) +([0-9]{2}):([0-9]{2})(AM|PM) +([0-9]+|<DIR>) +(.+)/', $line, $lucifer) ) {
			$b = array();
			if ( $lucifer[3] < 70 )
				$lucifer[3] +=2000;
			else
				$lucifer[3] += 1900; // 4digit year fix
			$b['isdir'] = ( $lucifer[7] == '<DIR>');
			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];
		} elseif ( !$isWindows && $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 = '.', $includeHidden = true, $recursive = false) {
		if ( $this->isFile($path) ) {
			$limitFile = basename($path);
			$path = dirname($path) . '/';
		} else {
			$limitFile = false;
		}

		$pwd = @ftp_pwd($this->link);
		if ( ! @ftp_chdir($this->link, $path) ) // Cant change to folder = folder doesn't exist
			return false;
		$list = @ftp_rawlist($this->link, '-a', false);
		@ftp_chdir($this->link, $pwd);

		if ( empty($list) ) // Empty array = non-existent folder (real folder will show . at least)
			return false;

		$dirList = array();
		foreach ( $list as $k => $v ) {
			$entry = $this->parseListing($v);
			if ( empty($entry) )
				continue;

			if ( '.' == $entry['name'] || '..' == $entry['name'] )
				continue;

			if ( ! $includeHidden && '.' == $entry['name'][0] )
				continue;

			if ( $limitFile && $entry['name'] != $limitFile)
				continue;

			$dirList[ $entry['name'] ] = $entry;
		}

		$ret = array();
		foreach ( (array)$dirList as $struc ) {
			if ( 'd' == $struc['type'] ) {
				if ( $recursive )
					$struc['files'] = $this->dirList($path . '/' . $struc['name'], $includeHidden, $recursive);
				else
					$struc['files'] = array();
			}

			$ret[ $struc['name'] ] = $struc;
		}
		return $ret;
	}
	function close() {
		if ( $this->link )
			ftp_close($this->link);
	}

	function __destruct() {
		if ( $this->link )
			ftp_close($this->link);
	}
}

class filesystemSSH2Ext extends filesystemBase {

	var $link = false;
	var $sftp_link = false;
	var $keys = false;
	var $options = array();

	function __construct($opt='') {
		$this->method = 'ssh2';
		//$this->errors = new WP_Error();

		//Check if possible to use ssh2 functions.
		if ( ! extension_loaded('ssh2') ) {
			//$this->errors->add('no_ssh2_ext', __('The ssh2 PHP extension is not available'));
			appUpdateMsg('The ssh2 PHP extension is not available', true);
			return false;
		}
		if ( !function_exists('stream_get_contents') ) {
			//$this->errors->add('ssh2_php_requirement', __('The ssh2 PHP extension is available, however, we require the PHP5 function <code>stream_get_contents()</code>'));
			appUpdateMsg('The ssh2 PHP extension is available, however, we require the PHP5 function <code>stream_get_contents()</code>', true);
			return false;
		}

		// Set defaults:
		if ( empty($opt['port']) )
			$this->options['port'] = 22;
		else
			$this->options['port'] = $opt['port'];

		if ( empty($opt['hostname']) )
			//$this->errors->add('empty_hostname', __('SSH2 hostname is required'));
			appUpdateMsg('SSH2 hostname is required', true);
		else
			$this->options['hostname'] = $opt['hostname'];

		if ( ! empty($opt['base']) )
			$this->wp_base = $opt['base'];

		// Check if the options provided are OK.
		if ( !empty ($opt['public_key']) && !empty ($opt['private_key']) ) {
			$this->options['public_key'] = $opt['public_key'];
			$this->options['private_key'] = $opt['private_key'];

			$this->options['hostkey'] = array('hostkey' => 'ssh-rsa');

			$this->keys = true;
		} elseif ( empty ($opt['username']) ) {
			//$this->errors->add('empty_username', __('SSH2 username is required'));
			appUpdateMsg('SSH2 username is required', true);
		}

		if ( !empty($opt['username']) )
			$this->options['username'] = $opt['username'];

		if ( empty ($opt['password']) ) {
			if ( !$this->keys )	//password can be blank if we are using keys
				//$this->errors->add('empty_password', __('SSH2 password is required'));
				appUpdateMsg('SSH2 password is required', true);
		} else {
			$this->options['password'] = $opt['password'];
		}

	}

	function connect() {
		if ( ! $this->keys ) {
			$this->link = @ssh2_connect($this->options['hostname'], $this->options['port']);
		} else {
			$this->link = @ssh2_connect($this->options['hostname'], $this->options['port'], $this->options['hostkey']);
		}

		if ( ! $this->link ) {
			//$this->errors->add('connect', sprintf(__('Failed to connect to SSH2 Server %1$s:%2$s'), $this->options['hostname'], $this->options['port']));
			appUpdateMsg(sprintf('Failed to connect to SSH2 Server %1$s:%2$s', $this->options['hostname'], $this->options['port']), true);
			return false;
		}

		if ( !$this->keys ) {
			if ( ! @ssh2_auth_password($this->link, $this->options['username'], $this->options['password']) ) {
				//$this->errors->add('auth', sprintf(__('Username/Password incorrect for %s'), $this->options['username']));
				appUpdateMsg(sprintf('Username/Password incorrect for %s', $this->options['username']), true);
				return false;
			}
		} else {
			if ( ! @ssh2_auth_pubkey_file($this->link, $this->options['username'], $this->options['public_key'], $this->options['private_key'], $this->options['password'] ) ) {
				//$this->errors->add('auth', sprintf(__('Public and Private keys incorrect for %s'), $this->options['username']));
				appUpdateMsg(sprintf('Public and Private keys incorrect for %s', $this->options['username']), true);
				return false;
			}
		}

		$this->sftp_link = ssh2_sftp($this->link);

		return true;
	}

	function runCommand( $command, $returnbool = false) {

		if ( ! $this->link )
			return false;

		if ( ! ($stream = ssh2_exec($this->link, $command)) ) {
			//$this->errors->add('command', sprintf(__('Unable to perform command: %s'), $command));
			appUpdateMsg(sprintf('Unable to perform command: %s', $command), true);
		} else {
			stream_set_blocking( $stream, true );
			stream_set_timeout( $stream, FS_TIMEOUT );
			$data = stream_get_contents( $stream );
			fclose( $stream );

			if ( $returnbool )
				return ( $data === false ) ? false : '' != trim($data);
			else
				return $data;
		}
		return false;
	}

	function getContents( $file ) {
		$file = ltrim($file, '/');
		return file_get_contents('ssh2.sftp://' . $this->sftp_link . '/' . $file);
	}

	function getContentsArray($file) {
		$file = ltrim($file, '/');
		return file('ssh2.sftp://' . $this->sftp_link . '/' . $file);
	}

	function putContents($file, $contents, $mode = false ) {
		$ret = file_put_contents( 'ssh2.sftp://' . $this->sftp_link . '/' . ltrim( $file, '/' ), $contents );

		if ( $ret !== strlen( $contents ) )
			return false;

		$this->chmod($file, $mode);

		return true;
	}

	function cwd() {
		$cwd = $this->runCommand('pwd');
		if ( $cwd )
			$cwd = addTrailingSlash($cwd);
		return $cwd;
	}

	function chdir($dir) {
		return $this->runCommand('cd ' . $dir, true);
	}

	function chgrp($file, $group, $recursive = false ) {
		if ( ! $this->exists($file) )
			return false;
		if ( ! $recursive || ! $this->is_dir($file) )
			return $this->runCommand(sprintf('chgrp %s %s', escapeshellarg($group), escapeshellarg($file)), true);
		return $this->runCommand(sprintf('chgrp -R %s %s', escapeshellarg($group), escapeshellarg($file)), true);
	}

	function chmod($file, $mode = false, $recursive = false) {
		if ( ! $this->exists($file) )
			return false;

		if ( ! $mode ) {
			if ( $this->is_file($file) )
				$mode = FS_CHMOD_FILE;
			elseif ( $this->is_dir($file) )
				$mode = FS_CHMOD_DIR;
			else
				return false;
		}

		if ( ! $recursive || ! $this->is_dir($file) )
			return $this->runCommand(sprintf('chmod %o %s', $mode, escapeshellarg($file)), true);
		return $this->runCommand(sprintf('chmod -R %o %s', $mode, escapeshellarg($file)), true);
	}

	/**
	 * Change the ownership of a file / folder.
	 *
	 * @since Unknown
	 *
	 * @param string $file    Path to the file.
	 * @param mixed  $owner   A user name or number.
	 * @param bool $recursive Optional. If set True changes file owner recursivly. Defaults to False.
	 * @return bool Returns true on success or false on failure.
	 */
	function chown( $file, $owner, $recursive = false ) {
		if ( ! $this->exists($file) )
			return false;
		if ( ! $recursive || ! $this->is_dir($file) )
			return $this->runCommand(sprintf('chown %s %s', escapeshellarg($owner), escapeshellarg($file)), true);
		return $this->runCommand(sprintf('chown -R %s %s', escapeshellarg($owner), escapeshellarg($file)), true);
	}

	function owner($file) {
		$owneruid = @fileowner('ssh2.sftp://' . $this->sftp_link . '/' . ltrim($file, '/'));
		if ( ! $owneruid )
			return false;
		if ( ! function_exists('posix_getpwuid') )
			return $owneruid;
		$ownerarray = posix_getpwuid($owneruid);
		return $ownerarray['name'];
	}

	function getchmod($file) {
		return substr(decoct(@fileperms( 'ssh2.sftp://' . $this->sftp_link . '/' . ltrim($file, '/') )),3);
	}

	function group($file) {
		$gid = @filegroup('ssh2.sftp://' . $this->sftp_link . '/' . ltrim($file, '/'));
		if ( ! $gid )
			return false;
		if ( ! function_exists('posix_getgrgid') )
			return $gid;
		$grouparray = posix_getgrgid($gid);
		return $grouparray['name'];
	}

	function copy($source, $destination, $overwrite = false, $mode = false) {
		if ( ! $overwrite && $this->exists($destination) )
			return false;
		$content = $this->getContents($source);
		if ( false === $content)
			return false;
		return $this->putContents($destination, $content, $mode);
	}

	function move($source, $destination, $overwrite = false) {
		return @ssh2_sftp_rename($this->link, $source, $destination);
	}

	function delete($file, $recursive = false, $type = false) {
		if ( 'f' == $type || $this->isFile($file) )
			return ssh2_sftp_unlink($this->sftp_link, $file);
		if ( ! $recursive )
			 return ssh2_sftp_rmdir($this->sftp_link, $file);
		$filelist = $this->dirlist($file);
		if ( is_array($filelist) ) {
			foreach ( $filelist as $filename => $fileinfo) {
				iwp_mmb_auto_print('recursive_delete');
				$this->delete($file . '/' . $filename, $recursive, $fileinfo['type']);
			}
		}
		return ssh2_sftp_rmdir($this->sftp_link, $file);
	}

	function exists($file) {
		$file = ltrim($file, '/');
		return file_exists('ssh2.sftp://' . $this->sftp_link . '/' . $file);
	}

	function isFile($file) {
		$file = ltrim($file, '/');
		return is_file('ssh2.sftp://' . $this->sftp_link . '/' . $file);
	}

	function isDir($path) {
		$path = ltrim($path, '/');
		return is_dir('ssh2.sftp://' . $this->sftp_link . '/' . $path);
	}

	function isReadable($file) {
		$file = ltrim($file, '/');
		return is_readable('ssh2.sftp://' . $this->sftp_link . '/' . $file);
	}

	function isWritable($file) {
		$file = ltrim($file, '/');
		return is_writable('ssh2.sftp://' . $this->sftp_link . '/' . $file);
	}

	function atime($file) {
		$file = ltrim($file, '/');
		return fileatime('ssh2.sftp://' . $this->sftp_link . '/' . $file);
	}

	function mtime($file) {
		$file = ltrim($file, '/');
		return filemtime('ssh2.sftp://' . $this->sftp_link . '/' . $file);
	}

	function size($file) {
		$file = ltrim($file, '/');
		return filesize('ssh2.sftp://' . $this->sftp_link . '/' . $file);
	}

	function touch($file, $time = 0, $atime = 0) {
		//Not implemented.
	}

	function mkdir($path, $chmod = false, $chown = false, $chgrp = false) {
		$path = removeTrailingSlash($path);
		if ( empty($path) )
			return false;

		if ( ! $chmod )
			$chmod = FS_CHMOD_DIR;
		if ( ! ssh2_sftp_mkdir($this->sftp_link, $path, $chmod, true) )
			return false;
		if ( $chown )
			$this->chown($path, $chown);
		if ( $chgrp )
			$this->chgrp($path, $chgrp);
		return true;
	}

	function rmdir($path, $recursive = false) {
		return $this->delete($path, $recursive);
	}

	function dirlist($path, $include_hidden = true, $recursive = false) {
		if ( $this->isFile($path) ) {
			$limit_file = basename($path);
			$path = dirname($path);
		} else {
			$limit_file = false;
		}

		if ( ! $this->isDir($path) )
			return false;

		$ret = array();
		$dir = @dir('ssh2.sftp://' . $this->sftp_link .'/' . ltrim($path, '/') );

		if ( ! $dir )
			return false;

		while (false !== ($entry = $dir->read()) ) {
			$struc = array();
			$struc['name'] = $entry;

			if ( '.' == $struc['name'] || '..' == $struc['name'] )
				continue; //Do not care about these folders.

			if ( ! $include_hidden && '.' == $struc['name'][0] )
				continue;

			if ( $limit_file && $struc['name'] != $limit_file )
				continue;

			$struc['perms'] 	= $this->gethchmod($path.'/'.$entry);
			$struc['permsn']	= $this->getnumchmodfromh($struc['perms']);
			$struc['number'] 	= false;
			$struc['owner']    	= $this->owner($path.'/'.$entry);
			$struc['group']    	= $this->group($path.'/'.$entry);
			$struc['size']    	= $this->size($path.'/'.$entry);
			$struc['lastmodunix']= $this->mtime($path.'/'.$entry);
			$struc['lastmod']   = date('M j',$struc['lastmodunix']);
			$struc['time']    	= date('h:i:s',$struc['lastmodunix']);
			$struc['type']		= $this->isDir($path.'/'.$entry) ? 'd' : 'f';

			if ( 'd' == $struc['type'] ) {
				if ( $recursive )
					$struc['files'] = $this->dirlist($path . '/' . $struc['name'], $include_hidden, $recursive);
				else
					$struc['files'] = array();
			}

			$ret[ $struc['name'] ] = $struc;
		}
		$dir->close();
		unset($dir);
		return $ret;
	}
}

class filesystemSFTPExt extends filesystemBase {

	var $link = false;
	var $sftp_link = false;
	var $keys = false;
	var $options = array();

	function __construct($opt='') {
		$this->method = 'sftp';
		 include dirname(__FILE__).'/phpseclib/vendor/autoload.php';
		//$this->errors = new WP_Error();

		
		// Set defaults:
		if ( empty($opt['port']) )
			$this->options['port'] = 22;
		else
			$this->options['port'] = $opt['port'];

		if ( empty($opt['hostname']) )
			//$this->errors->add('empty_hostname', __('SSH2 hostname is required'));
			appUpdateMsg('SSH2 hostname is required', true);
		else
			$this->options['hostname'] = $opt['hostname'];

		if ( ! empty($opt['base']) )
			$this->wp_base = $opt['base'];

		if ( empty ($opt['username']) ) {
			//$this->errors->add('empty_username', __('SSH2 username is required'));
			appUpdateMsg('SFTP username is required', true);
		}

		if ( !empty($opt['username']) )
			$this->options['username'] = $opt['username'];

		if ( empty ($opt['password']) && empty ($opt['hostKey'])) {
			if ( !$this->keys )	//password can be blank if we are using keys
				//$this->errors->add('empty_password', __('SSH2 password is required'));
				appUpdateMsg('SSH2 password is required', true);
		} else {
			if (!empty($opt['password'])) {
				$this->options['password'] = $opt['password'];
			}
			if (!empty($opt['hostKey'])) {
				$this->options['hostKey'] = $opt['hostKey'];
			}
		}

	}

	function connect() {
		$this->link = new \phpseclib\Net\SFTP($this->options['hostname'], $this->options['port']);
		
		 if (!empty($this->options['hostKey'])) {
			
			$rsa = new  \phpseclib\Crypt\RSA();
			if (false === $rsa->loadKey($this->options['hostKey'])) {
				appUpdateMsg('The key provided was not in a valid format, or was corrupt', true);
			}
			$this->options['password'] = $rsa;
	    }

		if ( ! $this->link ) {
			//$this->errors->add('connect', sprintf(__('Failed to connect to SSH2 Server %1$s:%2$s'), $this->options['hostname'], $this->options['port']));
			appUpdateMsg(sprintf('Failed to connect to SSH2 Server %1$s:%2$s', $this->options['hostname'], $this->options['port']), true);
			return false;
		}

		if ( ! $this->link->login($this->options['username'], $this->options['password']) ) {
			appUpdateMsg(sprintf('Username/Password incorrect for %s', $this->options['username']), true);
			return false;
		}

		return true;
	}

	function runCommand( $command, $returnbool = false) {

		$validSFTPCommands = array(
		/*
		sftp CLI commands:
		 'cd',
		 'chgrp',
		 'chmod',
		 'chown',
		 'df',
		 'get',
		 'ln',
		 'ls',
		 'mkdir',
		 'put',
		 'pwd',
		 'rename',
		 'rm',
		 'rmdir',
		 'symlink'
		*/
		// Available Net_SFTP commands:
		 'pwd',
		 'chmod', // ignored though
		 'chgrp', // ignored though
		 'chown'  // ignored though
		);
		if ( ! $this->link )
			return false;
				$cmdline = preg_split('/[[:blank:]]+/', $command);
		if ( ! in_array(($cmd=$cmdline[0]), $validSFTPCommands) )
			return false;
				if (substr($cmd, 0, 2) == 'ch') return true;
		$data = $this->link->$cmd();
		if ( $returnbool )
			return ( $data === false ) ? false : '' != trim($data);
		else
			return $data;
	}

		// strip FTP_BASE part of path; reduce to relative path
	function fixPath($file) {
		if (defined('FTP_BASE')) {
				if (substr($file, 0, ($l=strlen(FTP_BASE))) == FTP_BASE)
					$file = ltrim(substr($file, $l), '/');
		}
		return $file;
	}
		
	function getContents( $file ) {
		return $this->link->get($this->fixPath($file));
	}

	function getContentsArray($file) {
		return preg_split("/\n+/", $this->getContents($file));
	}

	function putContents($file, $contents, $mode = 2, $start = -1, $local_start = -1, $progressCallback = null ) {
		$file = $this->fixPath($file);
		$ret = $this->link->put($file, $contents, $mode, $start, $local_start, $progressCallback);
		return false !== $ret;

	}

	function cwd() {
		$cwd = $this->runCommand('pwd');
		if ( $cwd )
			$cwd = addTrailingSlash($cwd);
		return $cwd;
	}

	function chdir($dir) {
		return $this->link->chdir($this->fixPath($dir));
	}

	function chgrp($file, $group, $recursive = false ) {
		return true; // not supported
	}

	function chmod($file, $mode = false, $recursive = false) {
		return $this->link->chmod($mode, $file, $recursive); // SFTP does support chmod, better though to configure the right (default) permissions on the server side
	}

	/**
	 * Change the ownership of a file / folder.
	 *
	 * @since Unknown
	 *
	 * @param string $file    Path to the file.
	 * @param mixed  $owner   A user name or number.
	 * @param bool $recursive Optional. If set True changes file owner recursivly. Defaults to False.
	 * @return bool Returns true on success or false on failure.
	 */
	function chown( $file, $owner, $recursive = false ) {
		return true; // not supported
	}
		
		function stat($file) {
			$file = $this->fixPath($file);
			$stat = $this->link->stat($file);
			if ($stat !== false) {
				if (!isset($stat['permissions'])) {
					return false;
				}
				$stat['size'] = $this->link->size($file);
			}
			else {
			}
			return $stat;
		}

	function owner($file) {
		$stat = $this->stat($file);
		if ( ! $stat )
			return false;
		if ( ! isset($stat['uid']) )
			return false;
		$owneruid = $stat['uid'];
		if ( ! function_exists('posix_getpwuid') )
			return $owneruid;
		$ownerarray = posix_getpwuid($owneruid);
		return $ownerarray['name'];
	}

	function getchmod($file) {
		$stat = $this->stat($file);
		return substr(($stat['permissions'] & 000777), -3);
	}

	function group($file) {
		$stat = $this->stat($file);
		if ( ! $stat )
			return false;
		if ( ! isset($stat['gid']) )
			return false;
		$ownergid = $stat['gid'];
		if ( ! function_exists('posix_getgrgid') )
			return $gid;
		$grouparray = posix_getgrgid($ownergid);
		return $grouparray['name'];
	}

	function copy($source, $destination, $overwrite = false, $mode = false) {
		if ( ! $overwrite && $this->exists($destination) )
			return false;
		$content = $this->getContents($source);
		if ( false === $content)
			return false;
		return $this->putContents($destination, $content, $mode);
	}


	function move($source, $destination, $overwrite = false) {
		if ($overwrite) {
			$this->delete($destination, true);
		}
		return $this->link->rename($this->fixPath($source), $this->fixPath($destination));
	}


	function delete($file, $recursive = false, $type = false) {
		$file = $this->fixPath($file);
		if ( 'f' === $type || $this->isFile($file) ) {
			return $this->link->delete($file);
		}
		if ( ! $recursive ) {
			 return $this->link->rmdir($file);
		}
		//At this point its a folder, and we're in recursive mode
		$file = addTrailingSlash($file);
		$filelist = $this->dirlist($file, true);
		$retval = true;
		if ( is_array($filelist) ) //false if no files, So check first.
			foreach ($filelist as $filename => $fileinfo){
				iwp_mmb_auto_print('recursive_delete');
				if ( ! $this->delete($file . $filename, $recursive, $fileinfo['type']) )
					$retval = false;
			}

		if ( $this->exists($file) && ! $this->link->rmdir($file) )
			$retval = false;
		return $retval;
	}


	function exists($file) {
		return $this->stat($file) !== false;
	}
		
		function S_ISDIR($stat) {
		return( ($stat['permissions'] & 040000) == 040000 );
	}
	

	function S_ISREG($stat) {
		return( ($stat['permissions'] & 0100000) == 0100000 );
	}

	function isFile($file) {
		return $this->S_ISREG($this->stat($file));
	}


	function isDir($path) {
		return $this->S_ISDIR($this->stat($path));
	}


	function isReadable($file) {
		$stat = $this->stat($file);
		$perms = $stat['permissions'];
		return ($perms & 0x000400);
	}


	function isWritable($file) {
		$stat = $this->stat($file);
		$perms = $stat['permissions'];
		return ($perms & 0x000200);
	}


	function atime($file) {
		$stat = $this->stat($file);
		return $stat['atime'];
	}


	function mtime($file) {
		$stat = $this->stat($file);
		return $stat['mtime'];
	}

	function size($file) {
		$stat = $this->stat($file);
		return $stat['size'];
	}


	function touch($file, $time = 0, $atime = 0) {
		return $this->link->touch($file, $time, $atime);
	}


	function mkdir($path, $chmod = false, $chown = false, $chgrp = false) {
		return $this->link->mkdir($path);
	}


	function rmdir($path, $recursive = false) {
		return $this->delete($path, $recursive);
	}

	function dirlist($path, $include_hidden = true, $recursive = false) {
		if ( $this->isFile($path) ) {
			$limit_file = basename($path);
			$path = dirname($path);
		} else {
			$limit_file = false;
		}

		if ( ! $this->isDir($path) )
			return false;

		$ret = array();
		$curdir = $this->fixPath($path);
		$dir = $this->link->nlist($curdir);

		if ( ! $dir )
			return false;

		foreach ($dir as $entry) {
			$struc = $this->stat($curdir.'/'.$entry);
			$struc['name'] = $entry;


			if ( '.' == $struc['name'] || '..' == $struc['name'] )
				continue; //Do not care about these folders.

			if ( ! $include_hidden && '.' == $struc['name'][0] )
				continue;

			if ( $limit_file && $struc['name'] != $limit_file )
				continue;

			$struc['perms'] 	= $this->gethchmod($path.'/'.$entry);
			$struc['permsn']	= $struc['permissions'] & 000777;
			$struc['number'] 	= false;
			$struc['owner']    	= $this->owner($path.'/'.$entry);
			$struc['group']    	= $this->group($path.'/'.$entry);
			$struc['size']    	= $this->size($path.'/'.$entry);
			$struc['lastmodunix']= $this->mtime($path.'/'.$entry);
			$struc['lastmod']   = date('M j',$struc['lastmodunix']);
			$struc['time']    	= date('h:i:s',$struc['lastmodunix']);
			$struc['type']		= $this->isDir($path.'/'.$entry) ? 'd' : 'f';

			if ( 'd' == $struc['type'] ) {
				if ( $recursive )
					$struc['files'] = $this->dirlist($path . '/' . $struc['name'], $include_hidden, $recursive);
				else
					$struc['files'] = array();
			}

			$ret[ $struc['name'] ] = $struc;
		}
		return $ret;
	}
	

	function lastError() {
	  return $this->link->getLastSFTPError();
	}


	function getErrors() {
	  return $this->link->getSFTPErrors();
	}
}

class IWP_Seek_Iterator{

	public $iterator_common;
	public $external_obj;
	public $iterator_loop_limit;
	public $path;
	public $type;
	public $query;
	public $processed_files;
	public $app_functions;
	public $is_recursive;
	public $exclude_class_obj;

	public function __construct($type = false, $iterator_loop_limit = 1000){
	    $this->type = $type;
	    $this->iterator_loop_limit = $iterator_loop_limit;
	}

	public function get_seekable_files_obj($path){

	    $temp_path = $path;

	    // IWP_add_abspath($path);

	    $path = is_valid_path($path);

	    if( is_array($path) ) {
	        return $path;
	    }

	    $this->path = $temp_path;

	    return new DirectoryIterator($path);
	}

	public function process_iterator($path, $offset = false, $is_recursive = false){

	    $iterator = $this->get_seekable_files_obj($path);

	    if (empty($iterator)) {
	        return ;
	    }

	    $this->seek = empty($offset) ? array() : explode('-', $offset);

	    $this->counter = 0;
	    $this->is_recursive = $is_recursive;

	    if ($is_recursive) {
	        $this->recursive_iterator($iterator, false);
	    } else {
	        $this->iterator($iterator);
	    }
	}

	public function process_file($iterator, $key){
		process_file($iterator, $this->is_recursive, $this->path, $key, $this->counter, $this->iterator_loop_limit);
	}

	private function extra_check_query(){
	    if (!empty($this->query)) {
	        insert_into_current_process($this->query);
	        $this->query = '';
	    }
	}

	public function iterator($iterator){
	    //Moving satelite into position.
	    $this->seek_offset($iterator);

	    while ($iterator->valid()) {

	        $this->counter++;

	        $recursive_path = $iterator->getPathname();

	        //Dont recursive iterator if its a dir or dot
	        if ($iterator->isDot() || !$iterator->isReadable()  || $iterator->isDir()) {

	            //move to next file
	            $iterator->next();

	            continue;
	        }

	        $key = $iterator->key();

	        $this->process_file( $iterator, $key );

	        //move to next file
	        $iterator->next();
	    }

	    $this->extra_check_query();
	}


	public function recursive_iterator($iterator, $key_recursive) {

	    $this->seek_offset($iterator);

	    while ($iterator->valid()) {

	        //Forming current path from iterator
	        $recursive_path = $iterator->getPathname();

	        //Mapping keys
	        $key = ($key_recursive !== false ) ? $key_recursive . '-' . $iterator->key() : $iterator->key() ;

	        //Do recursive iterator if its a dir
	        if (!$iterator->isDot() && $iterator->isReadable() && $iterator->isDir() ) {

	            if (1) {//exclude
	                //create new object for new dir
	                $sub_iterator = new DirectoryIterator($recursive_path);

	                $this->recursive_iterator($sub_iterator, $key);

	            } else{
	            }

	        }

	        //Ignore dots paths
	        if(!$iterator->isDot()){
	            $this->process_file( $iterator, $key );
	        }

	        //move to next file
	        $iterator->next();
	    }

	    $this->extra_check_query();
	}

	private function seek_offset(&$iterator){

	    if(!count($this->seek)){
	        return false;
	    }

	    //Moving satelite into position.
	    $iterator->seek($this->seek[0]);

	    //remove positions from the array after moved satelite
	    unset($this->seek[0]);

	    //reset array index
	    $this->seek = array_values($this->seek);

	}
}

function process_copy_files_req($status){
    if ($status === 'db_clone_over') {
        $this->logger->log("Copying Files is started.", 'staging_progress', $this->staging_id);
    }

    $this->same_server_update_keys('same_server_staging_status', 'copy_files_progress');
    $iter_count = $this->same_server_copy();

    $this->same_server_update_keys('same_server_staging_status', 'copy_files_over');

    $this->logger->log("All files are copied to staging location succesfully.", 'staging_progress', $this->staging_id);

    IWP_manual_debug('', 'end_copy_files_staging');
}

function same_server_copy(){
    scan_entire_site();
    copy_selected_folders();
}

function scan_entire_site(){
    $dir = get_root_dir_folders();
    save_dir_list($dir);
    // $dir = get_wp_content_dir_folders();
    // save_dir_list($dir);
    // $dir = get_uploads_dir_folders();
    // save_dir_list($dir);
    // get_db_backup_file();
    // save_dir_list();
    save_deep_dir_list();
}

function get_root_dir_folders(){
    $files_obj = get_files_obj_by_path(IWP_ABSPATH);
    return add_dir_list($files_obj);
}


function get_wp_content_dir_folders(){
    $files_obj = get_files_obj_by_path(IWP_WP_CONTENT_DIR);
    return add_dir_list($files_obj);
}

function get_uploads_dir_folders(){
    $files_obj = get_files_obj_by_path(IWP_UPLOADS_DIR);
    return add_dir_list($files_obj);
}

function add_dir_list($files_obj){
    foreach ($files_obj as $key => $file_obj) {

        $file = $file_obj->getPathname();
        $file = iwp_wp_normalize_path($file);

        if (!IWP_is_dir($file)) {
            /// $this->files[] = $file;
        } else {
            // IWP_remove_abspath($file);
            $dir[] = $file;
        }
    }
    return $dir;
}

function save_dir_list($dir){
    $qry = '';
    $deep_dirs = array(
        IWP_ABSPATH,
        IWP_STAGING_DIR,
    );
    foreach ($dir as $dir) {
        if (in_array($dir, $deep_dirs)) {
            continue;
        }


        $qry .= empty($qry) ? "('" : ",('" ;
        $qry .= iwp_wp_normalize_path($dir) . "', '0')";

    }
    insert_into_iterator_process($qry);
}

function save_deep_dir_list(){
    $deep_dirs = array(
        IWP_ABSPATH,
    );
    $qry = '';
    foreach ($deep_dirs as $dir) {
        $qry .= empty($qry) ? "('" : ",('" ;
        $qry .= iwp_wp_normalize_path($dir) . "', '0')";

    }

    insert_into_iterator_process($qry);
}

function insert_into_iterator_process($qry){
    $sql = "insert into IWP_processed_iterator ( `name`, `offset`  ) values $qry";
    $result = DB::doQuery($sql);
}

function get_files_obj_by_path($path, $recursive = false){

    // IWP_add_abspath($path);

    $path = is_valid_path($path);

    if( is_array($path) ) {
        return $path;
    }

    if($recursive){
        return new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path , RecursiveDirectoryIterator::SKIP_DOTS), RecursiveIteratorIterator::SELF_FIRST, RecursiveIteratorIterator::CATCH_GET_CHILD);
    }

    return new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path , RecursiveDirectoryIterator::SKIP_DOTS), RecursiveIteratorIterator::CATCH_GET_CHILD);
}

function IWP_add_abspath(&$file, $change_reference = true){

    $file = iwp_wp_normalize_path($file);

    $temp_file = IWP_add_trailing_slash($file);

    if (strpos($temp_file, IWP_ABSPATH) !== false) {
        return $file;
    }

    if ($change_reference) {
        $file = IWP_ABSPATH . ltrim($file, '/');
        return $file;
    }

    return IWP_ABSPATH . ltrim($file, '/');
}

function IWP_remove_abspath(&$file, $change_reference = true){

	$file = iwp_wp_normalize_path($file);

	if (strpos($file, IWP_ABSPATH) === false) {
		return IWP_RELATIVE_ABSPATH . ltrim($file, '/');
	}

	if ($change_reference) {
		$file = str_replace(IWP_ABSPATH, IWP_RELATIVE_ABSPATH, $file);
		return $file;
	}

	return str_replace(IWP_ABSPATH, IWP_RELATIVE_ABSPATH, $file);
}

if (!function_exists('iwp_wp_normalize_path')) {
    function iwp_wp_normalize_path( $path ) {
        $path = str_replace( '\\', '/', $path );
        $path = preg_replace( '|(?<=.)/+|', '/', $path );
        if ( ':' === substr( $path, 1, 1 ) ) {
            $path = ucfirst( $path );
        }
        return $path;
    }
}

function IWP_add_trailing_slash($string) {
    return IWP_remove_trailing_slash($string) . '/';
}

function IWP_remove_trailing_slash($string) {
    return rtrim($string, '/');
}

function is_valid_path($path){
    $default = array();

    if (empty($path)) {
        return $default;
    }

    $path = rtrim($path, '/');

    $path = iwp_wp_normalize_path($path);

    if (empty($path)) {
        return $default;
    }

    $basename = basename($path);

    if ($basename == '..' || $basename == '.') {
        return $default;
    }

    if (!is_readable($path)) {
        return $default;
    }

    return $path;
}

function IWP_is_dir($good_path){
    $good_path = iwp_wp_normalize_path($good_path);

    if (is_dir($good_path)) {
        return true;
    }

    $ext = pathinfo($good_path, PATHINFO_EXTENSION);

    if (!empty($ext)) {
        return false;
    }

    if (is_file($good_path)) {
        return false;
    }

    return true;
}

function copy_selected_folders(){
    initFileSystem();
    $break = false;
    $deep_dirs_array = array(
        IWP_ABSPATH,
    );

    while(!$break){
        $dir_meta = get_unfnished_folder();
        $deep_dirs = false;

        if (empty($dir_meta) || $dir_meta['offset'] === -1) {
            $break = true;
            continue;
        }

        if( array_search($dir_meta['name'], $deep_dirs_array) !== false ){
            $deep_dirs = true;
        }

        $file = $dir_meta['name'];

        if ($deep_dirs === false && skip_file($file) === true) {
            update_iterator($dir_meta['name'], -1);
            continue;
        }

        if(IWP_is_dir($file)){
            iwp_copy_dir($dir_meta['name'], $dir_meta['offset'], $deep_dirs);
        } else {
            iwp_copy_file($dir_meta['name'], $update_status = true);
        }
    }
}

function get_unfnished_folder() {
    $sql = "SELECT * FROM IWP_processed_iterator WHERE `offset` != -1 LIMIT 1";
    $response = DB::getArray($sql);
    // IWP_log($response, '--------$response--------');

    return empty($response) ? false : $response[0];
}

function skip_file($file){
    if(!is_readable($file)){
        return true;
    }

    // if (stripos($file . '/' , $same_staging_folder) !== false ) {
    //     return true;
    // }

    // if ($this->exclude_class_obj->is_excluded_file($file)) {
    //     return true;
    // }

    return false;
}

function update_iterator($table, $offset) {
        upsert(array(
            'name' => $table,
            'offset' => $offset,
        ));
}

function upsert($data) {
	$exists = DB::getField("IWP_processed_iterator", 'id',"name = '".$data['name']."'");
	if ($exists) {
    	DB::update("IWP_processed_iterator", $data,"name = '".$data['name']."'");
	}else{
    	DB::insert("IWP_processed_iterator", $data);
	}
}

function iwp_copy_file($live_file, $update_status = false){
    // initFileSystem();
    // IWP_add_abspath($live_file);

    $live_file = iwp_wp_normalize_path($live_file);


    $staging_file = same_server_replace_pathname($live_file);

    mkdir_by_path(dirname($staging_file));

    $size = filesize($live_file);
    if (!file_exists($staging_file) && $size > 1024 * 1024 * 2) {
        $copy_status = IWP_copy_large_file($live_file, $staging_file);
    } elseif(!file_exists($staging_file)) {
        $copy_status = $GLOBALS['FileSystemObj']->touch($staging_file);
        $copy_status = $GLOBALS['FileSystemObj']->copy($live_file, $staging_file, true, FS_CHMOD_FILE);
    }elseif(file_exists($staging_file) && defined('IWP_STAGING_DIR') && $staging_file == IWP_STAGING_DIR.'/.htaccess' && IWP_LiteSpeed::$isLiteSpeedHtaccess){
    	// .htaccess file already written so backup live site .htaccess file 
    	$location_name = IWP_STAGING_DIR.'/'.IWP_LiteSpeed::$htaccessFileName;
    	$copy_status = $GLOBALS['FileSystemObj']->touch($location_name);
    	$copy_status = $GLOBALS['FileSystemObj']->copy($live_file, $location_name, true, FS_CHMOD_FILE);
    }


    if (!$copy_status) {

    }

    if ($update_status) {
        update_iterator($live_file, -1);
    }
}

function same_server_replace_pathname($path){
	$dirname = iwp_wp_normalize_path(dirname(dirname(__FILE__)));
    return iwp_wp_normalize_path(str_replace(IWP_ABSPATH ,$dirname , $path));
}

function mkdir_by_path($path, $recursive = true){
    if (empty($path)) {
        return false;
    }
    $path = iwp_wp_normalize_path($path);

    if (file_exists($path)) {
        return false;
    }
    createRecursiveFileSystemFolder($path);
}

function createRecursiveFileSystemFolder($this_temp_folder, $this_absbath_length = null, $override_abspath_check = true) {
    // initFileSystem();

    $folders = explode('/', $this_temp_folder);
    foreach ($folders as $key => $folder) {
        $current_folder = '';
        for($i=0; $i<=$key; $i++){
            $sub_dir = (string) $folders[$i];
            if ($sub_dir === false || $sub_dir === '' || $sub_dir === NULL) {
                continue;
            }
            if (is_windows_machine_IWP() && empty($current_folder)) {
                $current_folder .= $sub_dir;
            } else {
                $current_folder .= '/'. $sub_dir;
            }
        }

        // if (empty($current_folder)){
        //     continue;
        // }

        // if($override_abspath_check && strpos($current_folder.'/', $home_path) === false) {
        //     continue;
        // }
        if (!file_exists($current_folder)) {
            if (!$GLOBALS['FileSystemObj']->mkDir($current_folder, 0755)) {
                $GLOBALS['FileSystemObj']->chmod(dirname($current_folder), 0755);
                if(!$GLOBALS['FileSystemObj']->mkDir($current_folder, 0755)){
                }
            }
        } else {

            if(strpos($current_folder, 'tCapsule') !== false && $GLOBALS['FileSystemObj']->chmod($current_folder, 0755)){
            } else {
            }
        }
    }
}

function is_windows_machine_IWP(){
    if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
        return true;
    }
    return false;
}

function IWP_copy_large_file($src, $dst) {
    $src = fopen($src, 'r');
    $dest = fopen($dst, 'w');

    // Try first method:
    while (! feof($src)){
        if (false === fwrite($dest, fread($src, 1024 * 1024 * 2))){
            $error = true;
        }
    }
    // Try second method if first one failed
    if (isset($error) && ($error === true)){
        while(!feof($src)){
            stream_copy_to_stream($src, $dest, 1024 );
        }
        fclose($src);
        fclose($dest);
        return true;
    }
    fclose($src);
    fclose($dest);
    return true;
}

function iwp_copy_dir($live_path, $offset, $deep_dirs){

    init_seek_iterator();

    $is_recursive = ($deep_dirs) ? false : true;

    try{
    	$obj = new IWP_Seek_Iterator();
        $obj->process_iterator($live_path, $offset, $is_recursive);
    } catch(Exception $e){

        $exception_msg = $e->getMessage();

        update_iterator($live_path, 0);
        die_with_json_encode(array('status' => 'continue', 'msg' => 'Seeking failed, Retrying...'));
    }
    update_iterator($live_path, -1);
}

function process_file($iterator, $is_recursive, $path, $key, &$counter, $iterator_loop_limit){
    $file = $iterator->getPathname();

    if (!$iterator->isReadable()) {
        return ;
    }

    $file = iwp_wp_normalize_path($file);

    if (!$is_recursive && IWP_is_dir($file)){
        return;
    }

    if (skip_file($file) === true) {
        check_timeout_iter_file($path,  $key, $counter, $iterator_loop_limit);
        return;
    }

    if(IWP_is_dir($file)){
        return;
    }

    iwp_copy_file($file);

    check_timeout_iter_file($path,  $key, $counter, $iterator_loop_limit);
}

function check_timeout_iter_file($path, $offset, &$temp_counter, $timeout_limit){

	if (++$temp_counter < $timeout_limit) {
		return false;
	}
    // if (!check_for_clone_break()) {
    //     return false;
    // }

    update_iterator($path, $offset);

    global $response_arr;

    $response_arr = array();

    initialize_response_array($response_arr);

    $response_arr['file_iterator'] = true;

    $response_arr['status'] = 'partiallyCompleted';

    $response_arr['break'] = true;

    $response_arr['peak_mem_usage'] = (memory_get_peak_usage(true)/1024/1024);

    status("Extract will continue next call", $success=true, $return=false);
    die(status("multicall", $success=true, $return=false, $response_arr));


    // die_with_json_encode(array('status' => 'continue', 'msg' => get_processing_files_count($type = 'internal_staging'), 'percentage' => 50));
}

function get_processing_files_count($type){
    $dir = get_unfnished_folder();

    if (empty($dir)) {
        return false;
    }

    $copying_file = str_replace(IWP_ABSPATH, '', $dir->name);

    switch ($type) {
        case 'internal_staging':
            $msg = 'Copying  - ';
            break;
        case 'backup':
            $msg = ' ';
            break;
        case 'restore':
            $msg = 'Preparing files to restore - ';
            break;
    }

    if(IWP_is_dir($copying_file) && !empty($dir->offset)){
        // return $msg . $copying_file . ' ('.$dir->offset.')';
        $folders_processed = substr($dir->offset, 0, strpos($dir->offset, '-'));
        $folders_processed = empty($folders_processed) ? '' : ' ( processed ' . $folders_processed . ' folders )';
        return $msg . $copying_file . $folders_processed;
    }

    return $msg . $copying_file;
}

function insert_into_current_process($qry){
    $sql = "insert into " . $this->wpdb->base_prefix . "IWP_current_process (file_path, status, file_hash) values $qry";
    $result = $this->wpdb->query($sql);
}

function init_seek_iterator(){
	if ($GLOBALS['needFileSystem'] == true) {
    	$timeout_limit = 1000;
	}else{
    	$timeout_limit = 2000;
	}
    $seek_file_iterator = new IWP_Seek_Iterator($type = 'LIVE_TO_STAGING', $timeout_limit);
}
Le coin du marchand VO vente véhicule entre professionnels

Accès réservé aux professionnels

Site regroupant des annonces de véhicules marchands en vente entre professionnels. Vendez, achetez vos V.O entre pros en toute simplicité et sans intermédiaires.

Déposez gratuitement vos annonces*

*Offre de lancement

Marques
Nous avons trouvé annonces pour vous.

Slide Slide Slide Slide Slide En savoir plus

A propos de nous

Le Coin du Marchand
VO

Le Coin du Marchand
VO

Parce que le métier de marchand V.O. est en perpétuelle évolution
Le coin du marchand V.O. a décidé de vous accompagner à travers cette plateforme qui vous propose un service de petites annonces pour la vente et l’achat de véhicules entre professionnels revendeurs.

Pour l’approvisionnement de votre parc, pour une recherche personnalisée ou vendre des véhicules stockés , assurez-vous des transactions uniquement entre pros.
L’accès à la plateforme est sécurisé et exclusivement réservé aux professionnels.

Soigneusement sélectionnées

Annonces Récentes

Pourquoi Nous Choisir

Professionnalisme

Plateforme regroupant les professionnels qui proposent des véhicules de divers modèles à la vente

Sur toute la France

Les ventes se font uniquement entre professionnels

Meilleurs Tarifs

Vous trouverez de très bonnes occasions de véhicules à des tarifs marchands

Partenaires

  • Développement
  • Bénéfices Mutuelles
  • Collaborations
  • Visibilité
  • Soutenir d’autres Projets

Newsletter

Abonnez-vous à notre newsletter et restez informé de nos offres

Copyright © 2023 Le Coin du Marchand VO | All Rights Reserved | Yanacom