📄 class.em_unzip.php
字号:
// Store the index $v_header['index'] = $i; // Store the file position $v_pos_entry = ftell($this->_zip_fd); // Go to the file position @rewind($this->_zip_fd); if (@fseek($this->_zip_fd, $v_header['offset'])) { // Close the zip file $this->_closeFd(); // Error log $this->_errorLog(ARCHIVE_ZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size'); // Return return em_unzip::errorCode(); } // Extracting the file if (($v_result = $this->_extractFile($v_header, $p_path, $p_remove_path, $p_remove_all_path, $p_params)) != 1) { // Close the zip file $this->_closeFd(); return $v_result; } // Get the only interesting attributes if (($v_result = $this->_convertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) { // Close the zip file $this->_closeFd(); return $v_result; } } // Close the zip file $this->_closeFd(); // Return return $v_result; } /** * em_unzip::_extractFile() * * { Description } * */ function _extractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, &$p_params) { $v_result=1; // Read the file header $v_header = ''; if (($v_result = $this->_readFileHeader($v_header)) != 1) { // Return return $v_result; } // Check that the file header is coherent with $p_entry info // TBC // Look for all path to remove if ($p_remove_all_path == true) { // Get the basename of the path $p_entry['filename'] = basename($p_entry['filename']); } // Look for path to remove else if ($p_remove_path != "") { //if (strcmp($p_remove_path, $p_entry['filename'])==0) if ($this->_tool_PathInclusion($p_remove_path, $p_entry['filename']) == 2) { // Change the file status $p_entry['status'] = "filtered"; // Return return $v_result; } $p_remove_path_size = strlen($p_remove_path); if (substr($p_entry['filename'], 0, $p_remove_path_size) == $p_remove_path) { // Remove the path $p_entry['filename'] = substr($p_entry['filename'], $p_remove_path_size); } } // Add the path if ($p_path != '') { $p_entry['filename'] = $p_path."/".$p_entry['filename']; } // Look for pre-extract callback if ( (isset($p_params[ARCHIVE_ZIP_PARAM_PRE_EXTRACT])) && ($p_params[ARCHIVE_ZIP_PARAM_PRE_EXTRACT] != '')) { // Generate a local information $v_local_header = array(); $this->_convertHeader2FileInfo($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_params[ARCHIVE_ZIP_PARAM_PRE_EXTRACT].'(ARCHIVE_ZIP_PARAM_PRE_EXTRACT, $v_local_header);'); if ($v_result == 0) { // Change the file status $p_entry['status'] = "skipped"; $v_result = 1; } // Update the informations // Only some fields can be modified $p_entry['filename'] = $v_local_header['filename']; } // Trace // 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'])) { // Look if file is a directory if (is_dir($p_entry['filename'])) { // Change the file status $p_entry['status'] = "already_a_directory"; // Return //return $v_result; } // Look if file is write protected else if (!is_writeable($p_entry['filename'])) { // Change the file status $p_entry['status'] = "write_protected"; // Return //return $v_result; } // Look if the extracted file is older else if (filemtime($p_entry['filename']) > $p_entry['mtime']) { // Change the file status $p_entry['status'] = "newer_exist"; // Return //return $v_result; } } // Check the directory availability and create it if necessary else { if ((($p_entry['external']&0x00000010)==0x00000010) || (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->_dirCheck($v_dir_to_check, (($p_entry['external']&0x00000010)==0x00000010))) != 1) { // Change the file status $p_entry['status'] = "path_creation_fail"; // Return //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']&0x00000010)==0x00000010)) { // Look for not compressed file if ($p_entry['compressed_size'] == $p_entry['size']) { // Opening destination file if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) { // Change the file status $p_entry['status'] = "write_error"; // Return return $v_result; } // Read the file by ARCHIVE_ZIP_READ_BLOCK_SIZE octets blocks $v_size = $p_entry['compressed_size']; while ($v_size != 0) { $v_read_size = ($v_size < ARCHIVE_ZIP_READ_BLOCK_SIZE ? $v_size : ARCHIVE_ZIP_READ_BLOCK_SIZE); $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 { // Trace // Opening destination file if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) { // Change the file status $p_entry['status'] = "write_error"; return $v_result; } // 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); // 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_params[ARCHIVE_ZIP_PARAM_SET_CHMOD])) && ($p_params[ARCHIVE_ZIP_PARAM_SET_CHMOD] != 0)) { // Change the mode of the file chmod($p_entry['filename'], $p_params[ARCHIVE_ZIP_PARAM_SET_CHMOD]); } } } // Look for post-extract callback if ( (isset($p_params[ARCHIVE_ZIP_PARAM_POST_EXTRACT])) && ($p_params[ARCHIVE_ZIP_PARAM_POST_EXTRACT] != '')) { // Generate a local information $v_local_header = array(); $this->_convertHeader2FileInfo($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_params[ARCHIVE_ZIP_PARAM_POST_EXTRACT].'(ARCHIVE_ZIP_PARAM_POST_EXTRACT, $v_local_header);'); } // Return return $v_result; } /** * em_unzip::_readFileHeader() * * { Description } * */ function _readFileHeader(&$p_header) { $v_result=1; // Read the 4 bytes signature $v_binary_data = @fread($this->_zip_fd, 4); $v_data = unpack('Vid', $v_binary_data); // Check signature if ($v_data['id'] != 0x04034b50) { // Error log $this->_errorLog(ARCHIVE_ZIP_ERR_BAD_FORMAT, 'Invalid archive structure'); // Return return em_unzip::errorCode(); } // Read the first 42 bytes of the header $v_binary_data = fread($this->_zip_fd, 26); // Look for invalid block size if (strlen($v_binary_data) != 26) { $p_header['filename'] = ""; $p_header['status'] = "invalid_header"; // Error log $this->_errorLog(ARCHIVE_ZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data)); // Return return em_unzip::errorCode(); } // Extract the values $v_data = unpack('vversion/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len', $v_binary_data); // Get filename $p_header['filename'] = fread($this->_zip_fd, $v_data['filename_len']); // Get extra_fields if ($v_data['extra_len'] != 0) { $p_header['extra'] = fread($this->_zip_fd, $v_data['extra_len']); } else { $p_header['extra'] = ''; } // Extract properties $p_header['compression'] = $v_data['compression']; $p_header['size'] = $v_data['size']; $p_header['compressed_size'] = $v_data['compressed_size']; $p_header['crc'] = $v_data['crc']; $p_header['flag'] = $v_data['flag']; // Recuperate date in UNIX format $p_header['mdate'] = $v_data['mdate']; $p_header['mtime'] = $v_data['mtime']; if ($p_header['mdate'] && $p_header['mtime']) { // Extract time $v_hour = ($p_header['mtime'] & 0xF800) >> 11; $v_minute = ($p_header['mtime'] & 0x07E0) >> 5; $v_seconde = ($p_header['mtime'] & 0x001F)*2; // Extract date $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980; $v_month = ($p_header['mdate'] & 0x01E0) >> 5; $v_day = $p_header['mdate'] & 0x001F; // Get UNIX date format $p_header['mtime'] = mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year); } else { $p_header['mtime'] = time(); } // Other informations // TBC //for(reset($v_data); $key = key($v_data); next($v_data)) { //} // Set the stored filename $p_header['stored_filename'] = $p_header['filename']; // Set the status field $p_header['status'] = "ok"; // Return return $v_result; } /** * em_unzip::_readCentralFileHeader() * * { Description } * */ function _readCentralFileHeader(&$p_header) { $v_result=1; // Read the 4 bytes signature $v_binary_data = @fread($this->_zip_fd, 4); $v_data = unpack('Vid', $v_binary_data); // Check signature if ($v_data['id'] != 0x02014b50) { // Error log $this->_errorLog(ARCHIVE_ZIP_ERR_BAD_FORMAT, 'Invalid archive structure'); // Return return em_unzip::errorCode(); } // Read the first 42 bytes of the header $v_binary_data = fread($this->_zip_fd, 42); // Look for invalid block size if (strlen($v_binary_data) != 42) { $p_header['filename'] = ""; $p_header['status'] = "invalid_header"; // Error log $this->_errorLog(ARCHIVE_ZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data)); // Return return em_unzip::errorCode(); } // Extract the values $p_header = unpack('vversion/vversion_extracted/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len/vcomment_len/vdisk/vinternal/Vexternal/Voffset', $v_binary_data); // Get filename if ($p_header['filename_len'] != 0) $p_header['filename'] = fread($this->_zip_fd, $p_header['filename_len']); else $p_header['filename'] = ''; // Get extra if ($p_header['extra_len'] != 0) $p_header['extra'] = fread($this->_zip_fd, $p_header['extra_len']); else $p_header['extra'] = ''; // Get comment if ($p_header['comment_len'] != 0) $p_header['comment'] = fread($this->_zip_fd, $p_header['comment_len']); else $p_header['comment'] = ''; // Extract properties // Recuperate date in UNIX format if ($p_header['mdate'] && $p_header['mtime']) { // Extract time $v_hour = ($p_header['mtime'] & 0xF800) >> 11; $v_minute = ($p_header['mtime'] & 0x07E0) >> 5; $v_seconde = ($p_header['mtime'] & 0x001F)*2; // Extract date $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980; $v_month = ($p_header['mdate'] & 0x01E0) >> 5; $v_day = $p_header['mdate'] & 0x001F; // Get UNIX date format $p_header['mtime'] = mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year); } else { $p_header['mtime'] = time(); } // Set the stored filename $p_header['stored_filename'] = $p_header['filename'];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -