📄 pcltar.lib.php
字号:
// ----- 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_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]))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -