📄 pcltar.lib.php
字号:
// 1. The informations needed to compose the header are recuperated and formatted // 2. Two binary strings are composed for the first part of the header, before // and after checksum field. // 3. The checksum is calculated from the two binary strings // 4. The header is write in the tar file (first binary string, binary string // for checksum and last binary string). // Parameters : // $p_tar : a valid file descriptor, opened in write mode, // $p_filename : The name of the file the header is for, // $p_mode : The mode of the archive ("tar" or "tgz"). // $p_header : A pointer to a array where will be set the file properties // Return Values : // -------------------------------------------------------------------------------- function PclTarHandleHeader($p_tar, $p_filename, $p_mode, &$p_header, $p_stored_filename) { TrFctStart(__FILE__, __LINE__, "PclTarHandleHeader", "tar=$p_tar, file='$p_filename', mode='$p_mode', stored_filename='$p_stored_filename'"); $v_result=1; // ----- Check the parameters if (($p_tar == 0) || ($p_filename == "")) { // ----- Error log PclErrorLog(-3, "Invalid file descriptor in file ".__FILE__.", line ".__LINE__); // ----- Return TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); return PclErrorCode(); } // ----- Filename (reduce the path of stored name) if ($p_stored_filename == "") $p_stored_filename = $p_filename; $v_reduce_filename = PclTarHandlePathReduction($p_stored_filename); TrFctMessage(__FILE__, __LINE__, 2, "Filename (reduced) '$v_reduce_filename', strlen ".strlen($v_reduce_filename)); // ----- Get file info $v_info = stat($p_filename); $v_uid = sprintf("%6s ", DecOct($v_info[4])); $v_gid = sprintf("%6s ", DecOct($v_info[5])); TrFctMessage(__FILE__, __LINE__, 3, "uid=$v_uid, gid=$v_gid"); $v_perms = sprintf("%6s ", DecOct(fileperms($p_filename))); TrFctMessage(__FILE__, __LINE__, 3, "file permissions $v_perms"); // ----- File mtime $v_mtime_data = filemtime($p_filename); TrFctMessage(__FILE__, __LINE__, 2, "File mtime : $v_mtime_data"); $v_mtime = sprintf("%11s", DecOct($v_mtime_data)); // ----- File typeflag // '0' or '\0' is the code for regular file // '5' is directory if (is_dir($p_filename)) { $v_typeflag = "5"; $v_size = 0; } else { $v_typeflag = ""; // ----- Get the file size clearstatcache(); $v_size = filesize($p_filename); } TrFctMessage(__FILE__, __LINE__, 2, "File size : $v_size"); $v_size = sprintf("%11s ", DecOct($v_size)); TrFctMessage(__FILE__, __LINE__, 2, "File typeflag : $v_typeflag"); // ----- Linkname $v_linkname = ""; // ----- Magic $v_magic = ""; // ----- Version $v_version = ""; // ----- uname $v_uname = ""; // ----- gname $v_gname = ""; // ----- devmajor $v_devmajor = ""; // ----- devminor $v_devminor = ""; // ----- prefix $v_prefix = ""; // ----- Compose the binary string of the header in two parts arround the checksum position $v_binary_data_first = pack("a100a8a8a8a12A12", $v_reduce_filename, $v_perms, $v_uid, $v_gid, $v_size, $v_mtime); $v_binary_data_last = pack("a1a100a6a2a32a32a8a8a155a12", $v_typeflag, $v_linkname, $v_magic, $v_version, $v_uname, $v_gname, $v_devmajor, $v_devminor, $v_prefix, ""); // ----- Calculate the checksum $v_checksum = 0; // ..... First part of the header for ($i=0; $i<148; $i++) { $v_checksum += ord(substr($v_binary_data_first,$i,1)); } // ..... Ignore the checksum value and replace it by ' ' (space) for ($i=148; $i<156; $i++) { $v_checksum += ord(' '); } // ..... Last part of the header for ($i=156, $j=0; $i<512; $i++, $j++) { $v_checksum += ord(substr($v_binary_data_last,$j,1)); } TrFctMessage(__FILE__, __LINE__, 3, "Calculated checksum : $v_checksum"); // ----- Write the first 148 bytes of the header in the archive if ($p_mode == "tar") fputs($p_tar, $v_binary_data_first, 148); else gzputs($p_tar, $v_binary_data_first, 148); // ----- Write the calculated checksum $v_checksum = sprintf("%6s ", DecOct($v_checksum)); $v_binary_data = pack("a8", $v_checksum); if ($p_mode == "tar") fputs($p_tar, $v_binary_data, 8); else gzputs($p_tar, $v_binary_data, 8); // ----- Write the last 356 bytes of the header in the archive if ($p_mode == "tar") fputs($p_tar, $v_binary_data_last, 356); else gzputs($p_tar, $v_binary_data_last, 356); // ----- Set the properties in the header "structure" $p_header[filename] = $v_reduce_filename; $p_header[mode] = $v_perms; $p_header[uid] = $v_uid; $p_header[gid] = $v_gid; $p_header[size] = $v_size; $p_header[mtime] = $v_mtime; $p_header[typeflag] = $v_typeflag; $p_header[status] = "added"; // ----- Return TrFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : PclTarHandleFooter() // Description : // Parameters : // Return Values : // -------------------------------------------------------------------------------- function PclTarHandleFooter($p_tar, $p_mode) { TrFctStart(__FILE__, __LINE__, "PclTarHandleFooter", "tar='$p_tar', p_mode=$p_mode"); $v_result=1; // ----- Write the last 0 filled block for end of archive $v_binary_data = pack("a512", ""); if ($p_mode == "tar") fputs($p_tar, $v_binary_data); else gzputs($p_tar, $v_binary_data); // ----- Return TrFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : PclTarHandleExtract() // Description : // Parameters : // $p_tarname : Filename of the tar (or tgz) archive // $p_file_list : An array which contains the list of files to extract, this // array may be empty when $p_mode is 'complete' // $p_list_detail : An array where will be placed the properties of each extracted/listed file // $p_mode : 'complete' will extract all files from the archive, // 'partial' will look for files in $p_file_list // 'list' will only list the files from the archive without any extract // $p_path : Path to add while writing the extracted files // $p_tar_mode : 'tar' for GNU TAR archive, 'tgz' for compressed archive // $p_remove_path : Path to remove (from the file memorized path) while writing the // extracted files. If the path does not match the file path, // the file is extracted with its memorized path. // $p_remove_path does not apply to 'list' mode. // $p_path and $p_remove_path are commulative. // Return Values : // -------------------------------------------------------------------------------- function PclTarHandleExtract($p_tarname, $p_file_list, &$p_list_detail, $p_mode, $p_path, $p_tar_mode, $p_remove_path) { TrFctStart(__FILE__, __LINE__, "PclTarHandleExtract", "archive='$p_tarname', list, mode=$p_mode, path=$p_path, tar_mode=$p_tar_mode, remove_path='$p_remove_path'"); $v_result=1; $v_nb = 0; $v_extract_all = TRUE; $v_listing = FALSE; // ----- Check the path /* if (($p_path == "") || ((substr($p_path, 0, 1) != "/") && (substr($p_path, 0, 3) != "../"))) $p_path = "./".$p_path; */ $isWin = (substr(PHP_OS, 0, 3) == 'WIN'); if(!$isWin) { if (($p_path == "") || ((substr($p_path, 0, 1) != "/") && (substr($p_path, 0, 3) != "../"))) $p_path = "./".$p_path; } // ----- Look for path to remove format (should end by /) if (($p_remove_path != "") && (substr($p_remove_path, -1) != '/')) { $p_remove_path .= '/'; } $p_remove_path_size = strlen($p_remove_path); // ----- Study the mode switch ($p_mode) { case "complete" : // ----- Flag extract of all files $v_extract_all = TRUE; $v_listing = FALSE; break; case "partial" : // ----- Flag extract of specific files $v_extract_all = FALSE; $v_listing = FALSE; break; case "list" : // ----- Flag list of all files $v_extract_all = FALSE; $v_listing = TRUE; break; default : // ----- Error log PclErrorLog(-3, "Invalid extract mode ($p_mode)"); // ----- Return TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); return PclErrorCode(); } // ----- Open the tar file if ($p_tar_mode == "tar") { TrFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode"); $v_tar = fopen($p_tarname, "rb"); } else { TrFctMessage(__FILE__, __LINE__, 3, "Open file in gzip binary read mode"); $v_tar = @gzopen($p_tarname, "rb"); } // ----- Check that the archive is open if ($v_tar == 0) { // ----- Error log PclErrorLog(-2, "Unable to open archive '$p_tarname' in binary read mode"); // ----- Return TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); return PclErrorCode(); } // ----- Read the blocks While (!($v_end_of_file = ($p_tar_mode == "tar"?feof($v_tar):gzeof($v_tar)))) { TrFctMessage(__FILE__, __LINE__, 3, "Looking for next header ..."); // ----- Clear cache of file infos clearstatcache(); // ----- Reset extract tag $v_extract_file = FALSE; $v_extraction_stopped = 0; // ----- Read the 512 bytes header if ($p_tar_mode == "tar") $v_binary_data = fread($v_tar, 512); else $v_binary_data = gzread($v_tar, 512); // ----- Read the header properties if (($v_result = PclTarHandleReadHeader($v_binary_data, $v_header)) != 1) { // ----- Close the archive file if ($p_tar_mode == "tar") fclose($v_tar); else gzclose($v_tar); // ----- Return TrFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // ----- Look for empty blocks to skip if ($v_header["filename"] == "") { TrFctMessage(__FILE__, __LINE__, 2, "Empty block found. End of archive ?"); continue; } TrFctMessage(__FILE__, __LINE__, 2, "Found file '" . $v_header["filename"] . "', size '$v_header[size]'"); // ----- Look for partial extract if ((!$v_extract_all) && (is_array($p_file_list))) { TrFctMessage(__FILE__, __LINE__, 2, "Look if the file '$v_header[filename]' need to be extracted"); // ----- By default no unzip if the file is not found $v_extract_file = FALSE; // ----- Look into the file list for ($i=0; $i<sizeof($p_file_list); $i++) { TrFctMessage(__FILE__, __LINE__, 2, "Compare archived file '$v_header[filename]' from asked list file '".$p_file_list[$i]."'"); // ----- Look if it is a directory if (substr($p_file_list[$i], -1) == "/") { TrFctMessage(__FILE__, __LINE__, 3, "Compare file '$v_header[filename]' with directory '$p_file_list[$i]'"); // ----- Look if the directory is in the filename path if ((strlen($v_header["filename"]) > strlen($p_file_list[$i])) && (substr($v_header["filename"], 0, strlen($p_file_list[$i])) == $p_file_list[$i])) { // ----- The file is in the directory, so extract it TrFctMessage(__FILE__, __LINE__, 2, "File '$v_header[filename]' is in directory '$p_file_list[$i]' : extract it"); $v_extract_file = TRUE; // ----- End of loop break; } } // ----- It is a file, so compare the file names else if ($p_file_list[$i] == $v_header["filename"]) { // ----- File found TrFctMessage(__FILE__, __LINE__, 2, "File '$v_header[filename]' should be extracted"); $v_extract_file = TRUE; // ----- End of loop break; } } // ----- Trace if (!$v_extract_file) { TrFctMessage(__FILE__, __LINE__, 2, "File '$v_header[filename]' should not be extracted"); } } else { // ----- All files need to be extracted $v_extract_file = TRUE; } // ----- Look if this file need to be extracted if (($v_extract_file) && (!$v_listing)) { // ----- Look for path to remove if (($p_remove_path != "") && (substr($v_header["filename"], 0, $p_remove_path_size) == $p_remove_path)) { TrFctMessage(__FILE__, __LINE__, 3, "Found path '$p_remove_path' to remove in file '$v_header[filename]'"); // ----- Remove the path $v_header["filename"] = substr($v_header["filename"], $p_remove_path_size); TrFctMessage(__FILE__, __LINE__, 3, "Reslting file is '$v_header[filename]'"); } // ----- Add the path to the file if (($p_path != "./") && ($p_path != "/")) { // ----- Look for the path end '/' while (substr($p_path, -1) == "/") { TrFctMessage(__FILE__, __LINE__, 3, "Destination path [$p_path] ends by '/'"); $p_path = substr($p_path, 0, strlen($p_path)-1); TrFctMessage(__FILE__, __LINE__, 3, "Modified to [$p_path]"); } // ----- Add the path if (substr($v_header["filename"], 0, 1) == "/") $v_header["filename"] = $p_path.$v_hea
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -