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(); // ----- Look for regular tar file if ($p_tar_mode == "tar") { // ----- Open file TrFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode"); if (($v_tar = @fopen($p_tarname, "rb")) == 0) { // ----- Error log PclErrorLog(-2, "Unable to open file '{$p_tarname}' in binary read mode"); // ----- Return TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); return PclErrorCode(); } // ----- Open a temporary file in write mode $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) { // ----- Close tar file fclose($v_tar); // ----- Error log PclErrorLog(-1, "Unable to open file '{$v_temp_tarname}' in binary write mode"); // ----- Return TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); return PclErrorCode(); } } else { // ----- Open the file in read mode TrFctMessage(__FILE__, __LINE__, 3, "Open file in gzip binary read mode"); if (($v_tar = @gzopen($p_tarname, "rb")) == 0) { // ----- Error log PclErrorLog(-2, "Unable to open file '{$p_tarname}' in binary read mode"); // ----- Return TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); return PclErrorCode(); } // ----- Open a temporary file in write mode $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) { // ----- Close tar file gzclose($v_tar); // ----- Error log PclErrorLog(-1, "Unable to open file '{$v_temp_tarname}' in binary write mode"); // ----- Return TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); return PclErrorCode(); } } // ----- Prepare the list of files for ($i = 0; $i < sizeof($p_file_list); $i++) { // ----- Reset the found list $v_found_list[$i] = 0; // ----- Calculate the stored filename $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]}'"); } // ----- Update file cache clearstatcache(); // ----- 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 current found filename $v_current_filename = ""; // ----- Reset delete tag $v_delete_file = FALSE; // ----- Read the first 512 block 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); fclose($v_temp_tar); } else { gzclose($v_tar); gzclose($v_temp_tar); } @unlink($v_temp_tarname); // ----- 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 filenames to update 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]}'"); // ----- Compare the file names 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])); // ----- Store found informations $v_found_file = TRUE; $v_current_filename = $p_file_list[$i]; // ----- Look if the file need to be updated 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; } // ----- Flag the name in order not to add the file at the end $v_found_list[$i] = 1; } else { TrFctMessage(__FILE__, __LINE__, 4, "File '{$p_file_list[$i]}' is not '{$v_header['filename']}'"); } } // ----- Copy files that do not need to be updated if (!$v_update_file) { TrFctMessage(__FILE__, __LINE__, 2, "Keep file '{$v_header['filename']}'"); // ----- Write the file header if ($p_tar_mode == "tar") { fputs($v_temp_tar, $v_binary_data, 512); } else { gzputs($v_temp_tar, $v_binary_data, 512); } // ----- Write the file data $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); } } // ----- File name and properties are logged if listing mode or file is extracted TrFctMessage(__FILE__, __LINE__, 2, "Memorize info about file '{$v_header['filename']}'"); // ----- Add the array describing the file into the list $p_list_detail[$v_nb] = $v_header; $p_list_detail[$v_nb][status] = $v_found_file ? "not_updated" : "ok"; // ----- Increment $v_nb++; } else { // ----- Trace TrFctMessage(__FILE__, __LINE__, 2, "Start update of file '{$v_current_filename}'"); // ----- Store the old file size $v_old_size = $v_header[size]; // ----- Add the file if (($v_result = PclTarHandleAddFile($v_temp_tar, $v_current_filename, $p_tar_mode, $v_header, $p_add_dir, $p_remove_dir)) != 1) { // ----- Close the tarfile if ($p_tar_mode == "tar") { fclose($v_tar); fclose($v_temp_tar); } else { gzclose($v_tar); gzclose($v_temp_tar); } @unlink($p_temp_tarname); // ----- Return status TrFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // ----- Trace TrFctMessage(__FILE__, __LINE__, 2, "Skip old file '{$v_header['filename']}'"); // ----- Jump to next file 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); } // ----- Add the array describing the file into the list $p_list_detail[$v_nb] = $v_header; $p_list_detail[$v_nb][status] = "updated"; // ----- Increment $v_nb++; } // ----- Look for end of file if ($p_tar_mode == "tar") { $v_end_of_file = feof($v_tar); } else { $v_end_of_file = gzeof($v_tar); } } // ----- Look for files that does not exists in the archive and need to be added for ($i = 0; $i < sizeof($p_file_list); $i++) { // ----- Look if file not found in the archive if (!$v_found_list[$i]) { TrFctMessage(__FILE__, __LINE__, 3, "File '{$p_file_list[$i]}' need to be added"); // ----- Add the file if (($v_result = PclTarHandleAddFile($v_temp_tar, $p_file_list[$i], $p_tar_mode, $v_header, $p_add_dir, $p_remove_dir)) != 1) { // ----- Close the tarfile if ($p_tar_mode == "tar") { fclose($v_tar); fclose($v_temp_tar); } else { gzclose($v_tar); gzclose($v_temp_tar); } @unlink($p_temp_tarname); // ----- Return status TrFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // ----- Add the array describing the file into the list $p_list_detail[$v_nb] = $v_header; $p_list_detail[$v_nb][status] = "added"; // ----- Increment $v_nb++; } else { TrFctMessage(__FILE__, __LINE__, 3, "File '{$p_file_list[$i]}' was already updated if needed"); } } // ----- Write the last empty buffer PclTarHandleFooter($v_temp_tar, $p_tar_mode); // ----- Close the tarfile if ($p_tar_mode == "tar") { fclose($v_tar); fclose($v_temp_tar); } else { gzclose($v_tar); gzclose($v_temp_tar); } // ----- Unlink tar file if (!@unlink($p_tarname)) { // ----- Error log PclErrorLog(-11, "Error while deleting archive name {$p_tarname}"); } // ----- Rename tar file if (!@rename($v_temp_tarname, $p_tarname)) { // ----- Error log PclErrorLog(-12, "Error while renaming temporary file {$v_temp_tarname} to archive name {$p_tarname}"); // ----- Return TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); return PclErrorCode(); } // ----- Return 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; }