99){ PclErrorLog(-5, "File name is too long (max. 99) : '$p_filename'"); TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); return PclErrorCode(); } TrFctMessage(__FILE__, __LINE__, 4, "File position before header =" . ($p_mode == "tar"?ftell($p_tar):gztell($p_tar))); if (($v_result = PclTarHandleAddFile($p_tar, $p_filename, $p_mode, $v_header, $p_add_dir, $p_remove_dir)) != 1){ TrFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } $p_list_detail[$v_nb++] = $v_header; if (is_dir($p_filename)){ TrFctMessage(__FILE__, __LINE__, 2, "$p_filename is a directory"); if ($p_filename != ".") $v_path = $p_filename . "/"; else $v_path = ""; $p_hdir = opendir($p_filename); $p_hitem = readdir($p_hdir); // '.' directory $p_hitem = readdir($p_hdir); // '..' directory while ($p_hitem = readdir($p_hdir)){ if (is_file($v_path . $p_hitem)){ TrFctMessage(__FILE__, __LINE__, 4, "Add the file '" . $v_path . $p_hitem . "'"); if (($v_result = PclTarHandleAddFile($p_tar, $v_path . $p_hitem, $p_mode, $v_header, $p_add_dir, $p_remove_dir)) != 1){ TrFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } $p_list_detail[$v_nb++] = $v_header; } else{ TrFctMessage(__FILE__, __LINE__, 4, "'" . $v_path . $p_hitem . "' is a directory"); $p_temp_list[0] = $v_path . $p_hitem; $v_result = PclTarHandleAddList($p_tar, $p_temp_list, $p_mode, $p_list_detail, $p_add_dir, $p_remove_dir); } } unset($p_temp_list); unset($p_hdir); unset($p_hitem); }else{ TrFctMessage(__FILE__, __LINE__, 4, "File position after blocks =" . ($p_mode == "tar"?ftell($p_tar):gztell($p_tar))); } } TrFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } function PclTarHandleAddFile($p_tar, $p_filename, $p_mode, &$p_header, $p_add_dir, $p_remove_dir) { TrFctStart(__FILE__, __LINE__, "PclTarHandleAddFile", "tar='$p_tar', filename='$p_filename', p_mode='$p_mode', add_dir='$p_add_dir', remove_dir='$p_remove_dir'"); $v_result = 1; if ($p_tar == 0){ PclErrorLog(-3, "Invalid file descriptor in file " . __FILE__ . ", line " . __LINE__); TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); return PclErrorCode(); } if ($p_filename == ""){ PclErrorLog(-3, "Invalid file list parameter (invalid or empty list)"); TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); return PclErrorCode(); } $v_stored_filename = $p_filename; if ($p_remove_dir != ""){ if (substr($p_remove_dir, -1) != '/') $p_remove_dir .= "/"; if ((substr($p_filename, 0, 2) == "./") || (substr($p_remove_dir, 0, 2) == "./")){ if ((substr($p_filename, 0, 2) == "./") && (substr($p_remove_dir, 0, 2) != "./")) $p_remove_dir = "./" . $p_remove_dir; if ((substr($p_filename, 0, 2) != "./") && (substr($p_remove_dir, 0, 2) == "./")) $p_remove_dir = substr($p_remove_dir, 2); } if (substr($p_filename, 0, strlen($p_remove_dir)) == $p_remove_dir){ $v_stored_filename = substr($p_filename, strlen($p_remove_dir)); TrFctMessage(__FILE__, __LINE__, 3, "Remove path '$p_remove_dir' in file '$p_filename' = '$v_stored_filename'"); } } if ($p_add_dir != ""){ if (substr($p_add_dir, -1) == "/") $v_stored_filename = $p_add_dir . $v_stored_filename; else $v_stored_filename = $p_add_dir . "/" . $v_stored_filename; TrFctMessage(__FILE__, __LINE__, 3, "Add path '$p_add_dir' in file '$p_filename' = '$v_stored_filename'"); } if (strlen($v_stored_filename) > 99){ PclErrorLog(-5, "Stored file name is too long (max. 99) : '$v_stored_filename'"); TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); return PclErrorCode(); } if (is_file($p_filename)){ if (($v_file = fopen($p_filename, "rb")) == 0){ PclErrorLog(-2, "Unable to open file '$p_filename' in binary read mode"); TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); return PclErrorCode(); } if (($v_result = PclTarHandleHeader($p_tar, $p_filename, $p_mode, $p_header, $v_stored_filename)) != 1){ TrFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } TrFctMessage(__FILE__, __LINE__, 4, "File position after header =" . ($p_mode == "tar"?ftell($p_tar):gztell($p_tar))); $i = 0; while (($v_buffer = fread($v_file, 512)) != ""){ $v_binary_data = pack("a512", "$v_buffer"); if ($p_mode == "tar") fputs($p_tar, $v_binary_data); else gzputs($p_tar, $v_binary_data); $i++; } TrFctMessage(__FILE__, __LINE__, 2, "$i 512 bytes blocks"); fclose($v_file); TrFctMessage(__FILE__, __LINE__, 4, "File position after blocks =" . ($p_mode == "tar"?ftell($p_tar):gztell($p_tar))); } else{ if (($v_result = PclTarHandleHeader($p_tar, $p_filename, $p_mode, $p_header, $v_stored_filename)) != 1){ TrFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } TrFctMessage(__FILE__, __LINE__, 4, "File position after header =" . ($p_mode == "tar"?ftell($p_tar):gztell($p_tar))); } TrFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } 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; if (($p_tar == 0) || ($p_filename == "")){ PclErrorLog(-3, "Invalid file descriptor in file " . __FILE__ . ", line " . __LINE__); TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); return PclErrorCode(); } 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)); $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"); $v_mtime_data = filemtime($p_filename); TrFctMessage(__FILE__, __LINE__, 2, "File mtime : $v_mtime_data"); $v_mtime = sprintf("%11s", DecOct($v_mtime_data)); if (is_dir($p_filename)){ $v_typeflag = "5"; $v_size = 0; }else{ $v_typeflag = ""; 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"); $v_linkname = ""; $v_magic = ""; $v_version = ""; $v_uname = ""; $v_gname = ""; $v_devmajor = ""; $v_devminor = ""; $v_prefix = ""; $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, ""); $v_checksum = 0; for ($i = 0; $i < 148; $i++){ $v_checksum += ord(substr($v_binary_data_first, $i, 1)); } for ($i = 148; $i < 156; $i++){ $v_checksum += ord(' '); } 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"); if ($p_mode == "tar") fputs($p_tar, $v_binary_data_first, 148); else gzputs($p_tar, $v_binary_data_first, 148); $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); if ($p_mode == "tar") fputs($p_tar, $v_binary_data_last, 356); else gzputs($p_tar, $v_binary_data_last, 356); $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"; TrFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } function PclTarHandleFooter($p_tar, $p_mode) { TrFctStart(__FILE__, __LINE__, "PclTarHandleFooter", "tar='$p_tar', p_mode=$p_mode"); $v_result = 1; $v_binary_data = pack("a512", ""); if ($p_mode == "tar") fputs($p_tar, $v_binary_data); else gzputs($p_tar, $v_binary_data); TrFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } 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; $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; } if (($p_remove_path != "") && (substr($p_remove_path, -1) != '/')){ $p_remove_path .= '/'; } $p_remove_path_size = strlen($p_remove_path); switch ($p_mode){ case "complete" : $v_extract_all = true; $v_listing = false; break; case "partial" : $v_extract_all = false; $v_listing = false; break; case "list" : $v_extract_all = false; $v_listing = true; break; default : PclErrorLog(-3, "Invalid extract mode ($p_mode)"); TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); return PclErrorCode(); } 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"); } if ($v_tar == 0){ PclErrorLog(-2, "Unable to open archive '$p_tarname' in binary read mode"); TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); return PclErrorCode(); } While (!($v_end_of_file = ($p_tar_mode == "tar"?feof($v_tar):gzeof($v_tar)))){ TrFctMessage(__FILE__, __LINE__, 3, "Looking for next header ..."); clearstatcache(); $v_extract_file = false; $v_extraction_stopped = 0; if ($p_tar_mode == "tar") $v_binary_data = fread($v_tar, 512); else $v_binary_data = gzread($v_tar, 512); if (($v_result = PclTarHandleReadHeader($v_binary_data, $v_header)) != 1){ if ($p_tar_mode == "tar") fclose($v_tar); else gzclose($v_tar); TrFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } 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]'"); if ((!$v_extract_all) && (is_array($p_file_list))){ TrFctMessage(__FILE__, __LINE__, 2, "Look if the file '$v_header[filename]' need to be extracted"); $v_extract_file = false; 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] . "'"); if (substr($p_file_list[$i], -1) == "/"){ TrFctMessage(__FILE__, __LINE__, 3, "Compare file '$v_header[filename]' with directory '$p_file_list[$i]'"); if ((strlen($v_header["filename"]) > strlen($p_file_list[$i])) && (substr($v_header["filename"], 0, strlen($p_file_list[$i])) == $p_file_list[$i])){ TrFctMessage(__FILE__, __LINE__, 2, "File '$v_header[filename]' is in directory '$p_file_list[$i]' : extract it"); $v_extract_file = true; break; } } else if ($p_file_list[$i] == $v_header["filename"]){ TrFctMessage(__FILE__, __LINE__, 2, "File '$v_header[filename]' should be extracted"); $v_extract_file = true; break; } } if (!$v_extract_file){ TrFctMessage(__FILE__, __LINE__, 2, "File '$v_header[filename]' should not be extracted"); } }else{ $v_extract_file = true; } if (($v_extract_file) && (!$v_listing)){ 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]'"); $v_header["filename"] = substr($v_header["filename"], $p_remove_path_size); TrFctMessage(__FILE__, __LINE__, 3, "Reslting file is '$v_header[filename]'"); } if (($p_path != "./") && ($p_path != "/")){ 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]"); } if (substr($v_header["filename"], 0, 1) == "/") $v_header["filename"] = $p_path . $v_header["filename"]; else $v_header["filename"] = $p_path . "/" . $v_header["filename"]; } TrFctMessage(__FILE__, __LINE__, 2, "Extracting file (with path) '$v_header[filename]', size '$v_header[size]'"); if (file_exists($v_header["filename"])){ TrFctMessage(__FILE__, __LINE__, 2, "File '$v_header[filename]' already exists"); if (is_dir($v_header["filename"])){ TrFctMessage(__FILE__, __LINE__, 2, "Existing file '$v_header[filename]' is a directory"); $v_header["status"] = "already_a_directory"; $v_extraction_stopped = 1; $v_extract_file = 0; } else if (!is_writeable($v_header["filename"])){ TrFctMessage(__FILE__, __LINE__, 2, "Existing file '$v_header[filename]' is write protected"); $v_header["status"] = "write_protected"; $v_extraction_stopped = 1; $v_extract_file = 0; } else if (filemtime($v_header["filename"]) > $v_header["mtime"]){ TrFctMessage(__FILE__, __LINE__, 2, "Existing file '$v_header[filename]' is newer (" . date("l dS of F Y h:i:s A", filemtime($v_header[filename])) . ") than the extracted file (" . date("l dS of F Y h:i:s A", $v_header[mtime]) . ")"); $v_header["status"] = "newer_exist"; $v_extraction_stopped = 1; $v_extract_file = 0; } } else{ if ($v_header["typeflag"] == "5") $v_dir_to_check = $v_header["filename"]; else if (!strstr($v_header["filename"], "/")) $v_dir_to_check = ""; else $v_dir_to_check = dirname($v_header["filename"]); if (($v_result = PclTarHandlerDirCheck($v_dir_to_check)) != 1){ TrFctMessage(__FILE__, __LINE__, 2, "Unable to create path for '$v_header[filename]'"); $v_header["status"] = "path_creation_fail"; $v_extraction_stopped = 1; $v_extract_file = 0; } } if (($v_extract_file) && ($v_header["typeflag"] != "5")){ if (($v_dest_file = @fopen($v_header["filename"], "wb")) == 0){ TrFctMessage(__FILE__, __LINE__, 2, "Error while opening '$v_header[filename]' in write binary mode"); $v_header["status"] = "write_error"; TrFctMessage(__FILE__, __LINE__, 2, "Jump to next file"); if ($p_tar_mode == "tar") fseek($v_tar, ftell($v_tar) + (ceil(($v_header[size] / 512)) * 512)); else gzseek($v_tar, gztell($v_tar) + (ceil(($v_header[size] / 512)) * 512)); }else{ TrFctMessage(__FILE__, __LINE__, 2, "Start extraction of '$v_header[filename]'"); $n = floor($v_header["size"] / 512); for ($i = 0; $i < $n; $i++){ TrFctMessage(__FILE__, __LINE__, 3, "Read complete 512 bytes block number " . ($i + 1)); if ($p_tar_mode == "tar") $v_content = fread($v_tar, 512); else $v_content = gzread($v_tar, 512); fwrite($v_dest_file, $v_content, 512); } if (($v_header["size"] % 512) != 0){ TrFctMessage(__FILE__, __LINE__, 3, "Read last " . ($v_header["size"] % 512) . " bytes in a 512 block"); if ($p_tar_mode == "tar") $v_content = fread($v_tar, 512); else $v_content = gzread($v_tar, 512); fwrite($v_dest_file, $v_content, ($v_header["size"] % 512)); } fclose($v_dest_file); @touch($v_header["filename"], $v_header["mtime"]); } clearstatcache(); if (filesize($v_header["filename"]) != $v_header["size"]){ if ($p_tar_mode == "tar") fclose($v_tar); else gzclose($v_tar); PclErrorLog(-7, "Extracted file '$v_header[filename]' does not have the correct file size '" . filesize($v_filename) . "' ('$v_header[size]' expected). Archive may be corrupted."); TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); return PclErrorCode(); } TrFctMessage(__FILE__, __LINE__, 2, "Extraction done"); }else{ TrFctMessage(__FILE__, __LINE__, 2, "Extraction of file '$v_header[filename]' skipped."); TrFctMessage(__FILE__, __LINE__, 2, "Jump to next file"); if ($p_tar_mode == "tar") fseek($v_tar, ftell($v_tar) + (ceil(($v_header["size"] / 512)) * 512)); else gzseek($v_tar, gztell($v_tar) + (ceil(($v_header["size"] / 512)) * 512)); } } else{ TrFctMessage(__FILE__, __LINE__, 2, "Jump file '$v_header[filename]'"); TrFctMessage(__FILE__, __LINE__, 4, "Position avant jump [" . ($p_tar_mode == "tar"?ftell($v_tar):gztell($v_tar)) . "]"); if ($p_tar_mode == "tar") fseek($v_tar, ($p_tar_mode == "tar"?ftell($v_tar):gztell($v_tar)) + (ceil(($v_header[size] / 512)) * 512)); else gzseek($v_tar, gztell($v_tar) + (ceil(($v_header[size] / 512)) * 512)); TrFctMessage(__FILE__, __LINE__, 4, "Position apr�s jump [" . ($p_tar_mode == "tar"?ftell($v_tar):gztell($v_tar)) . "]"); } if ($p_tar_mode == "tar") $v_end_of_file = feof($v_tar); else $v_end_of_file = gzeof($v_tar); if ($v_listing || $v_extract_file || $v_extraction_stopped){ TrFctMessage(__FILE__, __LINE__, 2, "Memorize info about file '$v_header[filename]'"); if (($v_file_dir = dirname($v_header["filename"])) == $v_header["filename"]) $v_file_dir = ""; if ((substr($v_header["filename"], 0, 1) == "/") && ($v_file_dir == "")) $v_file_dir = "/"; $p_list_detail[$v_nb] = $v_header; $v_nb++; } } if ($p_tar_mode == "tar") fclose($v_tar); else gzclose($v_tar); TrFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } function PclTarHandleExtractByIndexList($p_tarname, $p_index_string, &$p_list_detail, $p_path, $p_remove_path, $p_tar_mode) { TrFctStart(__FILE__, __LINE__, "PclTarHandleExtractByIndexList", "archive='$p_tarname', index_string='$p_index_string', list, path=$p_path, remove_path='$p_remove_path', tar_mode=$p_tar_mode"); $v_result = 1; $v_nb = 0; if (($p_path == "") || ((substr($p_path, 0, 1) != "/") && (substr($p_path, 0, 3) != "../") && (substr($p_path, 0, 2) != "./"))) $p_path = "./" . $p_path; if (($p_remove_path != "") && (substr($p_remove_path, -1) != '/')){ $p_remove_path .= '/'; } $p_remove_path_size = strlen($p_remove_path); 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"); } if ($v_tar == 0){ PclErrorLog(-2, "Unable to open archive '$p_tarname' in binary read mode"); TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); return PclErrorCode(); } $v_list = explode(",", $p_index_string); sort($v_list); $v_index = 0; for ($i = 0; ($i < sizeof($v_list)) && ($v_result); $i++){ TrFctMessage(__FILE__, __LINE__, 3, "Looking for index part '$v_list[$i]'"); $v_index_list = explode("-", $v_list[$i]); $v_size_index_list = sizeof($v_index_list); if ($v_size_index_list == 1){ TrFctMessage(__FILE__, __LINE__, 3, "Only one index '$v_index_list[0]'"); $v_result = PclTarHandleExtractByIndex($v_tar, $v_index, $v_index_list[0], $v_index_list[0], $p_list_detail, $p_path, $p_remove_path, $p_tar_mode); }else if ($v_size_index_list == 2){ TrFctMessage(__FILE__, __LINE__, 3, "Two indexes '$v_index_list[0]' and '$v_index_list[1]'"); $v_result = PclTarHandleExtractByIndex($v_tar, $v_index, $v_index_list[0], $v_index_list[1], $p_list_detail, $p_path, $p_remove_path, $p_tar_mode); } } if ($p_tar_mode == "tar") fclose($v_tar); else gzclose($v_tar); TrFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } function PclTarHandleExtractByIndex($p_tar, &$p_index_current, $p_index_start, $p_index_stop, &$p_list_detail, $p_path, $p_remove_path, $p_tar_mode) { TrFctStart(__FILE__, __LINE__, "PclTarHandleExtractByIndex", "archive_descr='$p_tar', index_current=$p_index_current, index_start='$p_index_start', index_stop='$p_index_stop', list, path=$p_path, remove_path='$p_remove_path', tar_mode=$p_tar_mode"); $v_result = 1; $v_nb = 0; $v_tar = $p_tar; $v_nb = sizeof($p_list_detail); While (!($v_end_of_file = ($p_tar_mode == "tar"?feof($v_tar):gzeof($v_tar)))){ TrFctMessage(__FILE__, __LINE__, 3, "Looking for next file ..."); TrFctMessage(__FILE__, __LINE__, 3, "Index current=$p_index_current, range=[$p_index_start, $p_index_stop])"); if ($p_index_current > $p_index_stop){ TrFctMessage(__FILE__, __LINE__, 2, "Stop extraction, past stop index"); break; } clearstatcache(); $v_extract_file = false; $v_extraction_stopped = 0; if ($p_tar_mode == "tar") $v_binary_data = fread($v_tar, 512); else $v_binary_data = gzread($v_tar, 512); if (($v_result = PclTarHandleReadHeader($v_binary_data, $v_header)) != 1){ TrFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } 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]'"); if (($p_index_current >= $p_index_start) && ($p_index_current <= $p_index_stop)){ TrFctMessage(__FILE__, __LINE__, 2, "File '$v_header[filename]' is in the range to be extracted"); $v_extract_file = true; }else{ TrFctMessage(__FILE__, __LINE__, 2, "File '$v_header[filename]' is out of the range"); $v_extract_file = false; } if ($v_extract_file){ if (($v_result = PclTarHandleExtractFile($v_tar, $v_header, $p_path, $p_remove_path, $p_tar_mode)) != 1){ TrFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } } else{ TrFctMessage(__FILE__, __LINE__, 2, "Jump file '$v_header[filename]'"); TrFctMessage(__FILE__, __LINE__, 4, "Position avant jump [" . ($p_tar_mode == "tar"?ftell($v_tar):gztell($v_tar)) . "]"); if ($p_tar_mode == "tar") fseek($v_tar, ($p_tar_mode == "tar"?ftell($v_tar):gztell($v_tar)) + (ceil(($v_header[size] / 512)) * 512)); else gzseek($v_tar, gztell($v_tar) + (ceil(($v_header[size] / 512)) * 512)); TrFctMessage(__FILE__, __LINE__, 4, "Position apr�s jump [" . ($p_tar_mode == "tar"?ftell($v_tar):gztell($v_tar)) . "]"); } if ($p_tar_mode == "tar") $v_end_of_file = feof($v_tar); else $v_end_of_file = gzeof($v_tar); if ($v_extract_file){ TrFctMessage(__FILE__, __LINE__, 2, "Memorize info about file '$v_header[filename]'"); if (($v_file_dir = dirname($v_header[filename])) == $v_header[filename]) $v_file_dir = ""; if ((substr($v_header[filename], 0, 1) == "/") && ($v_file_dir == "")) $v_file_dir = "/"; $p_list_detail[$v_nb] = $v_header; $v_nb++; } $p_index_current++; } TrFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } function PclTarHandleExtractFile($p_tar, &$v_header, $p_path, $p_remove_path, $p_tar_mode) { TrFctStart(__FILE__, __LINE__, "PclTarHandleExtractFile", "archive_descr='$p_tar', path=$p_path, remove_path='$p_remove_path', tar_mode=$p_tar_mode"); $v_result = 1; $v_tar = $p_tar; $v_extract_file = 1; $p_remove_path_size = strlen($p_remove_path); 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]'"); $v_header[filename] = substr($v_header[filename], $p_remove_path_size); TrFctMessage(__FILE__, __LINE__, 3, "Resulting file is '$v_header[filename]'"); } if (($p_path != "./") && ($p_path != "/")){ 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]"); } if (substr($v_header[filename], 0, 1) == "/") $v_header[filename] = $p_path . $v_header[filename]; else $v_header[filename] = $p_path . "/" . $v_header[filename]; } TrFctMessage(__FILE__, __LINE__, 2, "Extracting file (with path) '$v_header[filename]', size '$v_header[size]'"); if (file_exists($v_header[filename])){ TrFctMessage(__FILE__, __LINE__, 2, "File '$v_header[filename]' already exists"); if (is_dir($v_header[filename])){ TrFctMessage(__FILE__, __LINE__, 2, "Existing file '$v_header[filename]' is a directory"); $v_header[status] = "already_a_directory"; $v_extraction_stopped = 1; $v_extract_file = 0; } else if (!is_writeable($v_header[filename])){ TrFctMessage(__FILE__, __LINE__, 2, "Existing file '$v_header[filename]' is write protected"); $v_header[status] = "write_protected"; $v_extraction_stopped = 1; $v_extract_file = 0; } else if (filemtime($v_header[filename]) > $v_header[mtime]){ TrFctMessage(__FILE__, __LINE__, 2, "Existing file '$v_header[filename]' is newer (" . date("l dS of F Y h:i:s A", filemtime($v_header[filename])) . ") than the extracted file (" . date("l dS of F Y h:i:s A", $v_header[mtime]) . ")"); $v_header[status] = "newer_exist"; $v_extraction_stopped = 1; $v_extract_file = 0; } } else{ if ($v_header[typeflag] == "5") $v_dir_to_check = $v_header[filename]; else if (!strstr($v_header[filename], "/")) $v_dir_to_check = ""; else $v_dir_to_check = dirname($v_header[filename]); if (($v_result = PclTarHandlerDirCheck($v_dir_to_check)) != 1){ TrFctMessage(__FILE__, __LINE__, 2, "Unable to create path for '$v_header[filename]'"); $v_header[status] = "path_creation_fail"; $v_extraction_stopped = 1; $v_extract_file = 0; } } if (($v_extract_file) && ($v_header[typeflag] != "5")){ if (($v_dest_file = @fopen($v_header[filename], "wb")) == 0){ TrFctMessage(__FILE__, __LINE__, 2, "Error while opening '$v_header[filename]' in write binary mode"); $v_header[status] = "write_error"; TrFctMessage(__FILE__, __LINE__, 2, "Jump to next file"); if ($p_tar_mode == "tar") fseek($v_tar, ftell($v_tar) + (ceil(($v_header[size] / 512)) * 512)); else gzseek($v_tar, gztell($v_tar) + (ceil(($v_header[size] / 512)) * 512)); }else{ TrFctMessage(__FILE__, __LINE__, 2, "Start extraction of '$v_header[filename]'"); $n = floor($v_header[size] / 512); for ($i = 0; $i < $n; $i++){ TrFctMessage(__FILE__, __LINE__, 3, "Read complete 512 bytes block number " . ($i + 1)); if ($p_tar_mode == "tar") $v_content = fread($v_tar, 512); else $v_content = gzread($v_tar, 512); fwrite($v_dest_file, $v_content, 512); } if (($v_header[size] % 512) != 0){ TrFctMessage(__FILE__, __LINE__, 3, "Read last " . ($v_header[size] % 512) . " bytes in a 512 block"); if ($p_tar_mode == "tar") $v_content = fread($v_tar, 512); else $v_content = gzread($v_tar, 512); fwrite($v_dest_file, $v_content, ($v_header[size] % 512)); } fclose($v_dest_file); @touch($v_header[filename], $v_header[mtime]); } clearstatcache(); if (filesize($v_header[filename]) != $v_header[size]){ PclErrorLog(-7, "Extracted file '$v_header[filename]' does not have the correct file size '" . filesize($v_filename) . "' ('$v_header[size]' expected). Archive may be corrupted."); TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); return PclErrorCode(); } TrFctMessage(__FILE__, __LINE__, 2, "Extraction done"); }else{ TrFctMessage(__FILE__, __LINE__, 2, "Extraction of file '$v_header[filename]' skipped."); TrFctMessage(__FILE__, __LINE__, 2, "Jump to next file"); if ($p_tar_mode == "tar") fseek($v_tar, ftell($v_tar) + (ceil(($v_header[size] / 512)) * 512)); else gzseek($v_tar, gztell($v_tar) + (ceil(($v_header[size] / 512)) * 512)); } TrFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } function PclTarHandleDelete($p_tarname, $p_file_list, &$p_list_detail, $p_tar_mode) { TrFctStart(__FILE__, __LINE__, "PclTarHandleDelete", "archive='$p_tarname', list, tar_mode=$p_tar_mode"); $v_result = 1; $v_nb = 0; if ($p_tar_mode == "tar"){ TrFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode"); if (($v_tar = @fopen($p_tarname, "rb")) == 0){ PclErrorLog(-2, "Unable to open file '$p_tarname' in binary read mode"); TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); return PclErrorCode(); } $v_temp_tarname = uniqid("pcltar-") . ".tmp"; TrFctMessage(__FILE__, __LINE__, 2, "Creating temporary archive file $v_temp_tarname"); if (($v_temp_tar = @fopen($v_temp_tarname, "wb")) == 0){ fclose($v_tar); PclErrorLog(-1, "Unable to open file '$v_temp_tarname' in binary write mode"); TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); return PclErrorCode(); } } else{ TrFctMessage(__FILE__, __LINE__, 3, "Open file in gzip binary read mode"); if (($v_tar = @gzopen($p_tarname, "rb")) == 0){ PclErrorLog(-2, "Unable to open file '$p_tarname' in binary read mode"); TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); return PclErrorCode(); } $v_temp_tarname = uniqid("pcltar-") . ".tmp"; TrFctMessage(__FILE__, __LINE__, 2, "Creating temporary archive file $v_temp_tarname"); if (($v_temp_tar = @gzopen($v_temp_tarname, "wb")) == 0){ gzclose($v_tar); PclErrorLog(-1, "Unable to open file '$v_temp_tarname' in binary write mode"); TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); return PclErrorCode(); } } While (!($v_end_of_file = ($p_tar_mode == "tar"?feof($v_tar):gzeof($v_tar)))){ TrFctMessage(__FILE__, __LINE__, 3, "Looking for next header ..."); clearstatcache(); $v_delete_file = false; if ($p_tar_mode == "tar") $v_binary_data = fread($v_tar, 512); else $v_binary_data = gzread($v_tar, 512); if (($v_result = PclTarHandleReadHeader($v_binary_data, $v_header)) != 1){ if ($p_tar_mode == "tar"){ fclose($v_tar); fclose($v_temp_tar); }else{ gzclose($v_tar); gzclose($v_temp_tar); } @unlink($v_temp_tarname); TrFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } 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]'"); for ($i = 0, $v_delete_file = false; ($i < sizeof($p_file_list)) && (!$v_delete_file); $i++){ if (($v_len = strcmp($p_file_list[$i], $v_header[filename])) <= 0){ if ($v_len == 0){ TrFctMessage(__FILE__, __LINE__, 3, "Found that '$v_header[filename]' need to be deleted"); $v_delete_file = true; }else{ TrFctMessage(__FILE__, __LINE__, 3, "Look if '$v_header[filename]' is a file in $p_file_list[$i]"); if (substr($v_header[filename], strlen($p_file_list[$i]), 1) == "/"){ TrFctMessage(__FILE__, __LINE__, 3, "'$v_header[filename]' is a file in $p_file_list[$i]"); $v_delete_file = true; } } } } if (!$v_delete_file){ TrFctMessage(__FILE__, __LINE__, 2, "Keep file '$v_header[filename]'"); if ($p_tar_mode == "tar"){ fputs($v_temp_tar, $v_binary_data, 512); }else{ gzputs($v_temp_tar, $v_binary_data, 512); } $n = ceil($v_header[size] / 512); for ($i = 0; $i < $n; $i++){ TrFctMessage(__FILE__, __LINE__, 3, "Read complete 512 bytes block number " . ($i + 1)); if ($p_tar_mode == "tar"){ $v_content = fread($v_tar, 512); fwrite($v_temp_tar, $v_content, 512); }else{ $v_content = gzread($v_tar, 512); gzwrite($v_temp_tar, $v_content, 512); } } TrFctMessage(__FILE__, __LINE__, 2, "Memorize info about file '$v_header[filename]'"); $p_list_detail[$v_nb] = $v_header; $p_list_detail[$v_nb][status] = "ok"; $v_nb++; } else{ TrFctMessage(__FILE__, __LINE__, 2, "Start deletion of '$v_header[filename]'"); TrFctMessage(__FILE__, __LINE__, 4, "Position avant jump [" . ($p_tar_mode == "tar"?ftell($v_tar):gztell($v_tar)) . "]"); if ($p_tar_mode == "tar") fseek($v_tar, ftell($v_tar) + (ceil(($v_header[size] / 512)) * 512)); else gzseek($v_tar, gztell($v_tar) + (ceil(($v_header[size] / 512)) * 512)); TrFctMessage(__FILE__, __LINE__, 4, "Position apr�s jump [" . ($p_tar_mode == "tar"?ftell($v_tar):gztell($v_tar)) . "]"); } if ($p_tar_mode == "tar") $v_end_of_file = feof($v_tar); else $v_end_of_file = gzeof($v_tar); } PclTarHandleFooter($v_temp_tar, $p_tar_mode); if ($p_tar_mode == "tar"){ fclose($v_tar); fclose($v_temp_tar); }else{ gzclose($v_tar); gzclose($v_temp_tar); } if (!@unlink($p_tarname)){ PclErrorLog(-11, "Error while deleting archive name $p_tarname"); } if (!@rename($v_temp_tarname, $p_tarname)){ PclErrorLog(-12, "Error while renaming temporary file $v_temp_tarname to archive name $p_tarname"); TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); return PclErrorCode(); } TrFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } function PclTarHandleUpdate($p_tarname, $p_file_list, &$p_list_detail, $p_tar_mode, $p_add_dir, $p_remove_dir) { TrFctStart(__FILE__, __LINE__, "PclTarHandleUpdate", "archive='$p_tarname', list, tar_mode=$p_tar_mode"); $v_result = 1; $v_nb = 0; $v_found_list = array(); if ($p_tar_mode == "tar"){ TrFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode"); if (($v_tar = @fopen($p_tarname, "rb")) == 0){ PclErrorLog(-2, "Unable to open file '$p_tarname' in binary read mode"); TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); return PclErrorCode(); } $v_temp_tarname = uniqid("pcltar-") . ".tmp"; TrFctMessage(__FILE__, __LINE__, 2, "Creating temporary archive file $v_temp_tarname"); if (($v_temp_tar = @fopen($v_temp_tarname, "wb")) == 0){ fclose($v_tar); PclErrorLog(-1, "Unable to open file '$v_temp_tarname' in binary write mode"); TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); return PclErrorCode(); } } else{ TrFctMessage(__FILE__, __LINE__, 3, "Open file in gzip binary read mode"); if (($v_tar = @gzopen($p_tarname, "rb")) == 0){ PclErrorLog(-2, "Unable to open file '$p_tarname' in binary read mode"); TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); return PclErrorCode(); } $v_temp_tarname = uniqid("pcltar-") . ".tmp"; TrFctMessage(__FILE__, __LINE__, 2, "Creating temporary archive file $v_temp_tarname"); if (($v_temp_tar = @gzopen($v_temp_tarname, "wb")) == 0){ gzclose($v_tar); PclErrorLog(-1, "Unable to open file '$v_temp_tarname' in binary write mode"); TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); return PclErrorCode(); } } for ($i = 0; $i < sizeof($p_file_list); $i++){ $v_found_list[$i] = 0; $v_stored_list[$i] = $p_file_list[$i]; if ($p_remove_dir != ""){ if (substr($p_file_list[$i], -1) != '/') $p_remove_dir .= "/"; if (substr($p_file_list[$i], 0, strlen($p_remove_dir)) == $p_remove_dir){ $v_stored_list[$i] = substr($p_file_list[$i], strlen($p_remove_dir)); TrFctMessage(__FILE__, __LINE__, 3, "Remove path '$p_remove_dir' in file '$p_file_list[$i]' = '$v_stored_list[$i]'"); } } if ($p_add_dir != ""){ if (substr($p_add_dir, -1) == "/") $v_stored_list[$i] = $p_add_dir . $v_stored_list[$i]; else $v_stored_list[$i] = $p_add_dir . "/" . $v_stored_list[$i]; TrFctMessage(__FILE__, __LINE__, 3, "Add path '$p_add_dir' in file '$p_file_list[$i]' = '$v_stored_list[$i]'"); } $v_stored_list[$i] = PclTarHandlePathReduction($v_stored_list[$i]); TrFctMessage(__FILE__, __LINE__, 3, "After reduction '$v_stored_list[$i]'"); } clearstatcache(); While (!($v_end_of_file = ($p_tar_mode == "tar"?feof($v_tar):gzeof($v_tar)))){ TrFctMessage(__FILE__, __LINE__, 3, "Looking for next header ..."); clearstatcache(); $v_current_filename = ""; $v_delete_file = false; if ($p_tar_mode == "tar") $v_binary_data = fread($v_tar, 512); else $v_binary_data = gzread($v_tar, 512); if (($v_result = PclTarHandleReadHeader($v_binary_data, $v_header)) != 1){ if ($p_tar_mode == "tar"){ fclose($v_tar); fclose($v_temp_tar); }else{ gzclose($v_tar); gzclose($v_temp_tar); } @unlink($v_temp_tarname); TrFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } 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]'"); for ($i = 0, $v_update_file = false, $v_found_file = false; ($i < sizeof($v_stored_list)) && (!$v_update_file); $i++){ TrFctMessage(__FILE__, __LINE__, 4, "Compare with file '$v_stored_list[$i]'"); if ($v_stored_list[$i] == $v_header[filename]){ TrFctMessage(__FILE__, __LINE__, 3, "File '$v_stored_list[$i]' is present in archive"); TrFctMessage(__FILE__, __LINE__, 3, "File '$v_stored_list[$i]' mtime=" . filemtime($p_file_list[$i]) . " " . date("l dS of F Y h:i:s A", filemtime($p_file_list[$i]))); TrFctMessage(__FILE__, __LINE__, 3, "Archived mtime=" . $v_header[mtime] . " " . date("l dS of F Y h:i:s A", $v_header[mtime])); $v_found_file = true; $v_current_filename = $p_file_list[$i]; if (filemtime($p_file_list[$i]) > $v_header[mtime]){ TrFctMessage(__FILE__, __LINE__, 3, "File '$p_file_list[$i]' need to be updated"); $v_update_file = true; }else{ TrFctMessage(__FILE__, __LINE__, 3, "File '$p_file_list[$i]' does not need to be updated"); $v_update_file = false; } $v_found_list[$i] = 1; }else{ TrFctMessage(__FILE__, __LINE__, 4, "File '$p_file_list[$i]' is not '$v_header[filename]'"); } } if (!$v_update_file){ TrFctMessage(__FILE__, __LINE__, 2, "Keep file '$v_header[filename]'"); if ($p_tar_mode == "tar"){ fputs($v_temp_tar, $v_binary_data, 512); }else{ gzputs($v_temp_tar, $v_binary_data, 512); } $n = ceil($v_header[size] / 512); for ($j = 0; $j < $n; $j++){ TrFctMessage(__FILE__, __LINE__, 3, "Read complete 512 bytes block number " . ($j + 1)); if ($p_tar_mode == "tar"){ $v_content = fread($v_tar, 512); fwrite($v_temp_tar, $v_content, 512); }else{ $v_content = gzread($v_tar, 512); gzwrite($v_temp_tar, $v_content, 512); } } TrFctMessage(__FILE__, __LINE__, 2, "Memorize info about file '$v_header[filename]'"); $p_list_detail[$v_nb] = $v_header; $p_list_detail[$v_nb][status] = ($v_found_file?"not_updated":"ok"); $v_nb++; } else{ TrFctMessage(__FILE__, __LINE__, 2, "Start update of file '$v_current_filename'"); $v_old_size = $v_header[size]; if (($v_result = PclTarHandleAddFile($v_temp_tar, $v_current_filename, $p_tar_mode, $v_header, $p_add_dir, $p_remove_dir)) != 1){ if ($p_tar_mode == "tar"){ fclose($v_tar); fclose($v_temp_tar); }else{ gzclose($v_tar); gzclose($v_temp_tar); } @unlink($p_temp_tarname); TrFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } TrFctMessage(__FILE__, __LINE__, 2, "Skip old file '$v_header[filename]'"); if ($p_tar_mode == "tar") fseek($v_tar, ftell($v_tar) + (ceil(($v_old_size / 512)) * 512)); else gzseek($v_tar, gztell($v_tar) + (ceil(($v_old_size / 512)) * 512)); $p_list_detail[$v_nb] = $v_header; $p_list_detail[$v_nb][status] = "updated"; $v_nb++; } if ($p_tar_mode == "tar") $v_end_of_file = feof($v_tar); else $v_end_of_file = gzeof($v_tar); } for ($i = 0; $i < sizeof($p_file_list); $i++){ if (!$v_found_list[$i]){ TrFctMessage(__FILE__, __LINE__, 3, "File '$p_file_list[$i]' need to be added"); if (($v_result = PclTarHandleAddFile($v_temp_tar, $p_file_list[$i], $p_tar_mode, $v_header, $p_add_dir, $p_remove_dir)) != 1){ if ($p_tar_mode == "tar"){ fclose($v_tar); fclose($v_temp_tar); }else{ gzclose($v_tar); gzclose($v_temp_tar); } @unlink($p_temp_tarname); TrFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } $p_list_detail[$v_nb] = $v_header; $p_list_detail[$v_nb][status] = "added"; $v_nb++; }else{ TrFctMessage(__FILE__, __LINE__, 3, "File '$p_file_list[$i]' was already updated if needed"); } } PclTarHandleFooter($v_temp_tar, $p_tar_mode); if ($p_tar_mode == "tar"){ fclose($v_tar); fclose($v_temp_tar); }else{ gzclose($v_tar); gzclose($v_temp_tar); } if (!@unlink($p_tarname)){ PclErrorLog(-11, "Error while deleting archive name $p_tarname"); } if (!@rename($v_temp_tarname, $p_tarname)){ PclErrorLog(-12, "Error while renaming temporary file $v_temp_tarname to archive name $p_tarname"); TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); return PclErrorCode(); } TrFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } function PclTarHandleReadHeader($v_binary_data, &$v_header) { TrFctStart(__FILE__, __LINE__, "PclTarHandleReadHeader", ""); $v_result = 1; if (strlen($v_binary_data) == 0){ $v_header[filename] = ""; $v_header[status] = "empty"; TrFctEnd(__FILE__, __LINE__, $v_result, "End of archive found"); return $v_result; } if (strlen($v_binary_data) != 512){ $v_header[filename] = ""; $v_header[status] = "invalid_header"; TrFctMessage(__FILE__, __LINE__, 2, "Invalid block size : " . strlen($v_binary_data)); PclErrorLog(-10, "Invalid block size : " . strlen($v_binary_data)); TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); return PclErrorCode(); } $v_checksum = 0; for ($i = 0; $i < 148; $i++){ $v_checksum += ord(substr($v_binary_data, $i, 1)); } for ($i = 148; $i < 156; $i++){ $v_checksum += ord(' '); } for ($i = 156; $i < 512; $i++){ $v_checksum += ord(substr($v_binary_data, $i, 1)); } TrFctMessage(__FILE__, __LINE__, 3, "Calculated checksum : $v_checksum"); TrFctMessage(__FILE__, __LINE__, 2, "Header : '$v_binary_data'"); $v_data = unpack("a100filename/a8mode/a8uid/a8gid/a12size/a12mtime/a8checksum/a1typeflag/a100link/a6magic/a2version/a32uname/a32gname/a8devmajor/a8devminor", $v_binary_data); $v_header["checksum"] = OctDec(trim($v_data["checksum"])); TrFctMessage(__FILE__, __LINE__, 3, "File checksum : $v_header[checksum]"); if ($v_header["checksum"] != $v_checksum){ TrFctMessage(__FILE__, __LINE__, 2, "File checksum is invalid : $v_checksum calculated, $v_header[checksum] expected"); $v_header["filename"] = ""; $v_header["status"] = "invalid_header"; if (($v_checksum == 256) && ($v_header["checksum"] == 0)){ $v_header["status"] = "empty"; TrFctEnd(__FILE__, __LINE__, $v_result, "End of archive found"); return $v_result; } PclErrorLog(-13, "Invalid checksum : $v_checksum calculated, " . $v_header["checksum"] . " expected"); TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); return PclErrorCode(); } TrFctMessage(__FILE__, __LINE__, 2, "File checksum is valid ($v_checksum)"); $v_header["filename"] = trim($v_data["filename"]); TrFctMessage(__FILE__, __LINE__, 2, "Name : '$v_header[filename]'"); $v_header["mode"] = OctDec(trim($v_data["mode"])); TrFctMessage(__FILE__, __LINE__, 2, "Mode : '" . DecOct($v_header["mode"]) . "'"); $v_header["uid"] = OctDec(trim($v_data["uid"])); TrFctMessage(__FILE__, __LINE__, 2, "Uid : '$v_header[uid]'"); $v_header["gid"] = OctDec(trim($v_data["gid"])); TrFctMessage(__FILE__, __LINE__, 2, "Gid : '$v_header[gid]'"); $v_header["size"] = OctDec(trim($v_data["size"])); TrFctMessage(__FILE__, __LINE__, 2, "Size : '$v_header[size]'"); $v_header["mtime"] = OctDec(trim($v_data["mtime"])); TrFctMessage(__FILE__, __LINE__, 2, "Date : " . date("l dS of F Y h:i:s A", $v_header["mtime"])); if (($v_header["typeflag"] = $v_data["typeflag"]) == "5"){ $v_header["size"] = 0; TrFctMessage(__FILE__, __LINE__, 2, "Size (folder) : '$v_header[size]'"); } TrFctMessage(__FILE__, __LINE__, 2, "File typeflag : $v_header[typeflag]"); $v_header["status"] = "ok"; TrFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } function PclTarHandlerDirCheck($p_dir) { $v_result = 1; TrFctStart(__FILE__, __LINE__, "PclTarHandlerDirCheck", "$p_dir"); if ((is_dir($p_dir)) || ($p_dir == "")){ TrFctEnd(__FILE__, __LINE__, "'$p_dir' is a directory"); return 1; } $p_parent_dir = dirname($p_dir); TrFctMessage(__FILE__, __LINE__, 3, "Parent directory is '$p_parent_dir'"); if ($p_parent_dir != $p_dir){ if ($p_parent_dir != ""){ if (($v_result = PclTarHandlerDirCheck($p_parent_dir)) != 1){ TrFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } } } TrFctMessage(__FILE__, __LINE__, 3, "Create directory '$p_dir'"); if (!@mkdir($p_dir, 0777)){ PclErrorLog(-8, "Unable to create directory '$p_dir'"); TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); return PclErrorCode(); } TrFctEnd(__FILE__, __LINE__, $v_result, "Directory '$p_dir' created"); return $v_result; } function PclTarHandleExtension($p_tarname) { TrFctStart(__FILE__, __LINE__, "PclTarHandleExtension", "tar=$p_tarname"); if ((substr($p_tarname, -7) == ".tar.gz") || (substr($p_tarname, -4) == ".tgz")){ TrFctMessage(__FILE__, __LINE__, 2, "Archive is a gzip tar"); $v_tar_mode = "tgz"; }else if (substr($p_tarname, -4) == ".tar"){ TrFctMessage(__FILE__, __LINE__, 2, "Archive is a tar"); $v_tar_mode = "tar"; }else{ PclErrorLog(-9, "Invalid archive extension"); TrFctMessage(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); $v_tar_mode = ""; } TrFctEnd(__FILE__, __LINE__, $v_tar_mode); return $v_tar_mode; } function PclTarHandlePathReduction($p_dir) { TrFctStart(__FILE__, __LINE__, "PclTarHandlePathReduction", "dir='$p_dir'"); $v_result = ""; if ($p_dir != ""){ $v_list = explode("/", $p_dir); for ($i = sizeof($v_list)-1; $i >= 0; $i--){ if ($v_list[$i] == "."){ }else if ($v_list[$i] == ".."){ $i--; }else if (($v_list[$i] == "") && ($i != (sizeof($v_list)-1)) && ($i != 0)){ }else{ $v_result = $v_list[$i] . ($i != (sizeof($v_list)-1)?"/" . $v_result:""); } } } TrFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } } ?>