public function DownloadNewTemplates2() { if(!isset($_REQUEST['template'])) { $GLOBALS['ErrorMessage'] = GetLang('InvalidTemplate'); return false; } // Include the File_Archive package GetLib('class.zip'); GetLib('class.file'); $FileClass = new FileClass(); $key = ''; if(isset($_REQUEST['key'])) { $key = $_REQUEST['key']; } $downloadUrls = $this->GenerateTemplateDownloadURLs($_REQUEST['template'], $key); $url = $downloadUrls['url']; $streamUrl = $downloadUrls['streamUrl']; // Get the information about this template from the remote server $response = PostToRemoteFileAndGetResponse($url); // A remote connection couldn't be established if($response === null) { $GLOBALS['ErrorMessage'] = GetLang('InvalidTemplate'); return false; } $templateXML = @simplexml_load_string($response); if(!is_object($templateXML)) { $GLOBALS['ErrorMessage'] = GetLang('InvalidTemplate'); return false; } if(isset($templateXML->error)) { switch(strval($templateXML->error)) { case "invalid": $GLOBALS['ErrorMessage'] = GetLang('InvalidKey'); return false; case "invalid_domain": $GLOBALS['ErrorMessage'] = GetLang('InvalidKeyDomain'); return false; case "invalid_tpl": $GLOBALS['ErrorMessage'] = GetLang('InvalidKeyTemplate'); return false; case "invalid_tpl2": $GLOBALS['ErrorMessage'] = GetLang('InvalidKeyTemplate2'); return false; default: $GLOBALS['ErrorMessage'] = GetLang('InvalidTemplate'); return false; } } // If safemode is enabled, simply redirect to the stream URL to download the ZIP if($this->safeMode) { header("Location: ".$streamUrl); exit; } // Template is valid, so download the zip file $data = PostToRemoteFileAndGetResponse($streamUrl, '', false); if($data === null) { $GLOBALS['ErrorMessage'] = GetLang('InvalidTemplate'); return false; } $tmp_dir = ISC_BASE_PATH . "/cache/"; $filename = $this->_GenRandFileName(); $tmpFile = $tmp_dir . $filename . ".zip"; // If we can't write to the temporary directory, show a message if(!CheckDirWritable($tmp_dir)) { $GLOBALS['ErrorMessage'] = GetLang('TempDirWriteError'); return false; } // Cannot write the temporary file if(!$fp = @fopen($tmpFile, "wb+")) { $GLOBALS['ErrorMessage'] = GetLang("TempDirWriteError"); return false; } // Write the contents if(!@fwrite($fp, $data)) { $GLOBALS['ErrorMessage'] = GetLang("TempDirWriteError"); return false; } @fclose($fp); $templateName = strval($templateXML->name); // If this is an update for the template, remove the old one first $templatePath = ISC_BASE_PATH."/templates/".basename($_REQUEST['template']); if(is_dir($templatePath)) { $FileClass->SetDir(''); $deleted = $FileClass->DeleteDir($templatePath, true); // Couldn't remove old template first if(!$deleted) { $GLOBALS['ErrorMessage'] = sprintf(GetLang("TemplateUnlinkError"), $templateName); return false; } } // Extract the new template $archive = new PclZip($tmpFile); if($archive->extract(PCLZIP_OPT_PATH, ISC_BASE_PATH."/templates") === 0) { $GLOBALS['ErrorMessage'] = GetLang('TemplateDirWriteError'); return false; } // Remove the temporary file @unlink($tmpFile); // Set the file permissions on the new template $file = new FileClass; $file->SetLoadDir(ISC_BASE_PATH."/templates"); $file->ChangeMode(basename($templatePath), ISC_WRITEABLE_DIR_PERM, ISC_WRITEABLE_FILE_PERM, true); $file->CloseHandle(); return true; }
function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, &$p_options) { //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::privExtractFile', "path='$p_path', remove_path='$p_remove_path', remove_all_path='".($p_remove_all_path?'true':'false')."'"); $v_result = 1; // ----- Read the file header if (($v_result = $this->privReadFileHeader($v_header)) != 1) { // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Found file '".$v_header['filename']."', size '".$v_header['size']."'"); // ----- Check that the file header is coherent with $p_entry info if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) { // TBC } // ----- Look for all path to remove if ($p_remove_all_path == true) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "All path is removed"); // ----- Get the basename of the path $p_entry['filename'] = basename($p_entry['filename']); } else { if ($p_remove_path != "") { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Look for some path to remove"); if (PclZipUtilPathInclusion($p_remove_path, $p_entry['filename']) == 2) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "The folder is the same as the removed path '".$p_entry['filename']."'"); // ----- Change the file status $p_entry['status'] = "filtered"; // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } $p_remove_path_size = strlen($p_remove_path); if (substr($p_entry['filename'], 0, $p_remove_path_size) == $p_remove_path) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Found path '$p_remove_path' to remove in file '".$p_entry['filename']."'"); // ----- Remove the path $p_entry['filename'] = substr($p_entry['filename'], $p_remove_path_size); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Resulting file is '".$p_entry['filename']."'"); } } } // ----- Add the path if ($p_path != '') { $p_entry['filename'] = $p_path . "/" . $p_entry['filename']; } // ----- Look for pre-extract callback if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "A pre-callback '".$p_options[PCLZIP_CB_PRE_EXTRACT]."()') is defined for the extraction"); // ----- Generate a local information $v_local_header = array(); $this->privConvertHeader2FileInfo($p_entry, $v_local_header); // ----- Call the callback // Here I do not use call_user_func() because I need to send a reference to the // header. eval('$v_result = ' . $p_options[PCLZIP_CB_PRE_EXTRACT] . '(PCLZIP_CB_PRE_EXTRACT, $v_local_header);'); if ($v_result == 0) { // ----- Change the file status $p_entry['status'] = "skipped"; $v_result = 1; } // ----- Look for abort result if ($v_result == 2) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "User callback abort the extraction"); // ----- This status is internal and will be changed in 'skipped' $p_entry['status'] = "aborted"; $v_result = PCLZIP_ERR_USER_ABORTED; } // ----- Update the informations // Only some fields can be modified $p_entry['filename'] = $v_local_header['filename']; //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "New filename is '".$p_entry['filename']."'"); } //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting file (with path) '".$p_entry['filename']."', size '$v_header[size]'"); // ----- Look if extraction should be done if ($p_entry['status'] == 'ok') { // ----- Look for specific actions while the file exist if (file_exists($p_entry['filename'])) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File '".$p_entry['filename']."' already exists"); // ----- Look if file is a directory if (is_dir($p_entry['filename'])) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Existing file '".$p_entry['filename']."' is a directory"); // ----- Change the file status $p_entry['status'] = "already_a_directory"; // ----- Look for PCLZIP_OPT_STOP_ON_ERROR // For historical reason first PclZip implementation does not stop // when this kind of error occurs. if (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]) && $p_options[PCLZIP_OPT_STOP_ON_ERROR] === true) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "PCLZIP_OPT_STOP_ON_ERROR is selected, extraction will be stopped"); PclZip::privErrorLog(PCLZIP_ERR_ALREADY_A_DIRECTORY, "Filename '" . $p_entry['filename'] . "' is " . "already used by an existing directory"); //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); return PclZip::errorCode(); } } else { if (!CheckDirWritable($p_entry['filename'])) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Existing file '".$p_entry['filename']."' is write protected"); // ----- Change the file status $p_entry['status'] = "write_protected"; // ----- Look for PCLZIP_OPT_STOP_ON_ERROR // For historical reason first PclZip implementation does not stop // when this kind of error occurs. if (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]) && $p_options[PCLZIP_OPT_STOP_ON_ERROR] === true) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "PCLZIP_OPT_STOP_ON_ERROR is selected, extraction will be stopped"); PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, "Filename '" . $p_entry['filename'] . "' exists " . "and is write protected"); //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); return PclZip::errorCode(); } } else { if (filemtime($p_entry['filename']) > $p_entry['mtime']) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Existing file '".$p_entry['filename']."' is newer (".date("l dS of F Y h:i:s A", filemtime($p_entry['filename'])).") than the extracted file (".date("l dS of F Y h:i:s A", $p_entry['mtime']).")"); // ----- Change the file status if (isset($p_options[PCLZIP_OPT_REPLACE_NEWER]) && $p_options[PCLZIP_OPT_REPLACE_NEWER] === true) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "PCLZIP_OPT_REPLACE_NEWER is selected, file will be replaced"); } else { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File will not be replaced"); $p_entry['status'] = "newer_exist"; // ----- Look for PCLZIP_OPT_STOP_ON_ERROR // For historical reason first PclZip implementation does not stop // when this kind of error occurs. if (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]) && $p_options[PCLZIP_OPT_STOP_ON_ERROR] === true) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "PCLZIP_OPT_STOP_ON_ERROR is selected, extraction will be stopped"); PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, "Newer version of '" . $p_entry['filename'] . "' exists " . "and option PCLZIP_OPT_REPLACE_NEWER is not selected"); //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo()); return PclZip::errorCode(); } } } else { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Existing file '".$p_entry['filename']."' is older than the extrated one - will be replaced by the extracted one (".date("l dS of F Y h:i:s A", filemtime($p_entry['filename'])).") than the extracted file (".date("l dS of F Y h:i:s A", $p_entry['mtime']).")"); } } } } else { if (($p_entry['external'] & 0x10) == 0x10 || substr($p_entry['filename'], -1) == '/') { $v_dir_to_check = $p_entry['filename']; } else { if (!strstr($p_entry['filename'], "/")) { $v_dir_to_check = ""; } else { $v_dir_to_check = dirname($p_entry['filename']); } } if (($v_result = $this->privDirCheck($v_dir_to_check, ($p_entry['external'] & 0x10) == 0x10)) != 1) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Unable to create path for '".$p_entry['filename']."'"); // ----- Change the file status $p_entry['status'] = "path_creation_fail"; // ----- Return ////--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); //return $v_result; $v_result = 1; } } } // ----- Look if extraction should be done if ($p_entry['status'] == 'ok') { // ----- Do the extraction (if not a folder) if (!(($p_entry['external'] & 0x10) == 0x10)) { // ----- Look for not compressed file if ($p_entry['compression'] == 0) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting an un-compressed file"); // ----- Opening destination file if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Error while opening '".$p_entry['filename']."' in write binary mode"); // ----- Change the file status $p_entry['status'] = "write_error"; // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Read '".$p_entry['size']."' bytes"); // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks $v_size = $p_entry['compressed_size']; while ($v_size != 0) { $v_read_size = $v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE; //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Read $v_read_size bytes"); $v_buffer = fread($this->zip_fd, $v_read_size); $v_binary_data = pack('a' . $v_read_size, $v_buffer); @fwrite($v_dest_file, $v_binary_data, $v_read_size); $v_size -= $v_read_size; } // ----- Closing the destination file fclose($v_dest_file); // ----- Change the file mtime touch($p_entry['filename'], $p_entry['mtime']); } else { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting a compressed file (Compression method ".$p_entry['compression'].")"); // ----- TBC // Need to be finished if (($p_entry['flag'] & 1) == 1) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File is encrypted"); /* // ----- Read the encryption header //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Read 12 encryption header bytes"); $v_encryption_header = @fread($this->zip_fd, 12); // ----- Read the encrypted & compressed file in a buffer //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Read '".($p_entry['compressed_size']-12)."' compressed & encrypted bytes"); $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']-12); // ----- Decrypt the buffer $this->privDecrypt($v_encryption_header, $v_buffer, $p_entry['compressed_size']-12, $p_entry['crc']); //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Buffer is '".$v_buffer."'"); */ } else { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Read '".$p_entry['compressed_size']."' compressed bytes"); // ----- Read the compressed file in a buffer (one shot) $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']); } // ----- Decompress the file $v_file_content = @gzinflate($v_buffer); unset($v_buffer); if ($v_file_content === FALSE) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Unable to inflate compressed file"); // ----- Change the file status // TBC $p_entry['status'] = "error"; //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // ----- Opening destination file if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Error while opening '".$p_entry['filename']."' in write binary mode"); // ----- Change the file status $p_entry['status'] = "write_error"; //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // ----- Write the uncompressed data @fwrite($v_dest_file, $v_file_content, $p_entry['size']); unset($v_file_content); // ----- Closing the destination file @fclose($v_dest_file); // ----- Change the file mtime @touch($p_entry['filename'], $p_entry['mtime']); } // ----- Look for chmod option if (isset($p_options[PCLZIP_OPT_SET_CHMOD])) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "chmod option activated '".$p_options[PCLZIP_OPT_SET_CHMOD]."'"); // ----- Change the mode of the file @sts_chmod($p_entry['filename'], $p_options[PCLZIP_OPT_SET_CHMOD]); } //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extraction done"); } } // ----- Change abort status if ($p_entry['status'] == "aborted") { $p_entry['status'] = "skipped"; } elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "A post-callback '".$p_options[PCLZIP_CB_POST_EXTRACT]."()') is defined for the extraction"); // ----- Generate a local information $v_local_header = array(); $this->privConvertHeader2FileInfo($p_entry, $v_local_header); // ----- Call the callback // Here I do not use call_user_func() because I need to send a reference to the // header. eval('$v_result = ' . $p_options[PCLZIP_CB_POST_EXTRACT] . '(PCLZIP_CB_POST_EXTRACT, $v_local_header);'); // ----- Look for abort result if ($v_result == 2) { //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "User callback abort the extraction"); $v_result = PCLZIP_ERR_USER_ABORTED; } } // ----- Return //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result); return $v_result; }