lid or empty list)"); // ----- Return TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); return PclErrorCode(); } // ----- Calculate the stored filename $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'"); } // ----- Check the path length if (strlen($v_stored_filename) > 99) { // ----- Error log PclErrorLog(-5, "Stored file name is too long (max. 99) : '$v_stored_filename'"); // ----- Return TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); return PclErrorCode(); } // ----- Look for a file if (is_file($p_filename)) { // ----- Open the source file if (($v_file = fopen($p_filename, "rb")) == 0) { // ----- Error log PclErrorLog(-2, "Unable to open file '$p_filename' in binary read mode"); // ----- Return TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); return PclErrorCode(); } // ----- Call the header generation if (($v_result = PclTarHandleHeader($p_tar, $p_filename, $p_mode, $p_header, $v_stored_filename)) != 1) { // ----- Return status 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))); // ----- Read the file by 512 octets blocks $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"); // ----- Close the file fclose($v_file); TrFctMessage(__FILE__, __LINE__, 4, "File position after blocks =".($p_mode=="tar"?ftell($p_tar):gztell($p_tar))); } // ----- Look for a directory else { // ----- Call the header generation if (($v_result = PclTarHandleHeader($p_tar, $p_filename, $p_mode, $p_header, $v_stored_filename)) != 1) { // ----- Return status 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))); } // ----- Return TrFctEnd(__FILE__, __LINE__, $v_result); return $v_result; } // -------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- // Function : PclTarHandleHeader() // Description : // This function creates in the TAR $p_tar, the TAR header for the file // $p_filename. // // 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_bina