📄 tar.php
字号:
<?php
class tar
{
var $tar_header_length = "512";
var $tar_unpack_header = "a100filename/a8mode/a8uid/a8gid/a12size/a12mtime/a8chksum/a1typeflag/a100linkname/a6magic/a2version/a32uname/a32gname/a8devmajor/a8devminor/a155/prefix";
var $tar_pack_header = "A100 A8 A8 A8 A12 A12 A8 A1 A100 A6 A2 A32 A32 A8 A8 A155";
var $current_dir = "";
var $unpack_dir = "";
var $pack_dir = "";
var $error = "";
var $work_dir = array( );
var $tar_in_mem = array( );
var $tar_filename = "";
var $filehandle = "";
var $warnings = array( );
var $attributes = array( );
var $tarfile_name = "";
var $tarfile_path = "";
var $tarfile_path_name = "";
var $workfiles = array( );
function tar( )
{
global $HTTP_SERVER_VARS;
if ( $this_dir = getcwd( ) )
{
$this->current_dir = $this_dir;
}
else if ( isset( $HTTP_SERVER_VARS['DOCUMENT_ROOT'] ) )
{
$this->current_dir = $HTTP_SERVER_VARS['DOCUMENT_ROOT'];
}
else
{
$this->current_dir = "./";
}
$this->attributes = array( "over_write_existing" => 0, "over_write_newer" => 0, "remove_tar_file" => 0, "remove_original_files" => 0 );
}
function new_tar( $tarpath, $tarname )
{
$this->tarfile_name = $tarname;
$this->tarfile_path = $tarpath;
$this->tarfile_path = preg_replace( "#[/\\\\]\$#", "", $this->tarfile_path );
$this->tarfile_path_name = $this->tarfile_path."/".$this->tarfile_name;
}
function over_write_existing( )
{
$this->attributes['over_write_existing'] = 1;
}
function over_write_newer( )
{
$this->attributes['over_write_newer'] = 1;
}
function remove_tar_file( )
{
$this->attributes['remove_tar_file'] = 1;
}
function remove_original_files( )
{
$this->attributes['remove_original_files'] = 1;
}
function current_dir( $dir = "" )
{
$this->current_dir = $dir;
}
function list_files( $advanced = "" )
{
$data = $this->read_tar( );
$final = array( );
foreach ( $data as $d )
{
if ( $advanced == 1 )
{
$final[] = array(
"name" => $d['name'],
"size" => $d['size'],
"mtime" => $d['mtime'],
"mode" => substr( decoct( $d['mode'] ), -4 )
);
}
else
{
$final[] = $d['name'];
}
}
return $final;
}
function add_directory( $dir )
{
$this->error = "";
if ( !is_dir( $dir ) )
{
$this->error = "Extract files error: Destination directory ({$to_dir}) does not exist";
return FALSE;
}
$cur_dir = getcwd( );
chdir( $dir );
$this->get_dir_contents( "./" );
$this->add_files( $this->workfiles, $dir );
chdir( $cur_dir );
}
function get_dir_contents( $dir )
{
$dir = preg_replace( "#/\$#", "", $dir );
if ( file_exists( $dir ) )
{
if ( is_dir( $dir ) )
{
$handle = opendir( $dir );
while ( ( $filename = readdir( $handle ) ) !== false )
{
if ( $filename != "." && $filename != ".." )
{
if ( is_dir( $dir."/".$filename ) )
{
$this->get_dir_contents( $dir."/".$filename );
}
else
{
$this->workfiles[] = $dir."/".$filename;
}
}
}
closedir( $handle );
}
else
{
$this->error = "{$dir} is not a directory";
return FALSE;
}
}
else
{
$this->error = "Could not locate {$dir}";
return;
}
}
function extract_files( $to_dir, $files = "" )
{
$this->error = "";
if ( !is_dir( $to_dir ) )
{
$this->error = "Extract files error: Destination directory ({$to_dir}) does not exist";
}
else
{
chdir( $to_dir );
$cur_dir = getcwd( );
$to_dir_slash = $to_dir."/";
$in_files = $this->read_tar( );
if ( $this->error != "" )
{
return;
}
foreach ( $in_files as $k => $file )
{
if ( is_array( $files ) && !in_array( $file['name'], $files ) )
{
continue;
}
chdir( $cur_dir );
if ( preg_match( "#/#", $file['name'] ) )
{
$path_info = explode( "/", $file['name'] );
$file_name = array_pop( $path_info );
}
else
{
$path_info = array( );
$file_name = $file['name'];
}
if ( 0 < count( $path_info ) )
{
foreach ( $path_info as $dir_component )
{
if ( $dir_component == "" )
{
}
else
{
if ( file_exists( $dir_component ) && !is_dir( $dir_component ) )
{
$this->warnings[] = "WARNING: {$dir_component} exists, but is not a directory";
}
else
{
if ( !is_dir( $dir_component ) )
{
mkdir( $dir_component, 511 );
chmod( $dir_component, 511 );
}
if ( !chdir( $dir_component ) )
{
$this->warnings[] = "ERROR: CHDIR to {$dir_component} FAILED!";
}
}
}
}
}
if ( $file['typeflag'] == 0 || !$file['typeflag'] || $file['typeflag'] == "" )
{
if ( $FH = fopen( $file_name, "wb" ) )
{
fputs( $FH, $file['data'], strlen( $file['data'] ) );
fclose( $FH );
}
else
{
$this->warnings[] = "Could not write data to {$file_name}";
}
}
else if ( $file['typeflag'] == 5 )
{
if ( file_exists( $file_name ) && !is_dir( $file_name ) )
{
$this->warnings[] = "{$file_name} exists, but is not a directory";
}
else if ( !is_dir( $file_name ) )
{
mkdir( $file_name, 511 );
}
}
else if ( $file['typeflag'] == 6 )
{
$this->warnings[] = "Cannot handle named pipes";
continue;
}
else if ( $file['typeflag'] == 1 )
{
$this->warnings[] = "Cannot handle system links";
}
else if ( $file['typeflag'] == 4 )
{
$this->warnings[] = "Cannot handle device files";
}
else if ( $file['typeflag'] == 3 )
{
$this->warnings[] = "Cannot handle device files";
}
else
{
$this->warnings[] = "Unknown typeflag found";
}
if ( !chmod( $file_name, $file['mode'] ) )
{
$this->warnings[] = "ERROR: CHMOD {$mode} on {$file_name} FAILED!";
}
@touch( $file_name, $file['mtime'] );
}
@chdir( $this->current_dir );
}
}
function add_files( $files, $root_path = "" )
{
if ( $root_path != "" )
{
chdir( $root_path );
}
$count = 0;
foreach ( $files as $file )
{
if ( preg_match( "/\\.ds_store/i", $file ) )
{
}
else
{
$typeflag = 0;
$data = "";
$linkname = "";
$stat = stat( $file );
if ( !is_array( $stat ) )
{
$this->warnings[] = "Error: Stat failed on {$file}";
}
else
{
$mode = fileperms( $file );
$uid = $stat[4];
$gid = $stat[5];
$rdev = $stat[6];
$size = filesize( $file );
$mtime = filemtime( $file );
if ( is_file( $file ) )
{
$typeflag = 0;
if ( $FH = fopen( $file, "rb" ) )
{
$data = fread( $FH, filesize( $file ) );
fclose( $FH );
}
else
{
$this->warnings[] = "ERROR: Failed to open {$file}";
continue;
}
}
else if ( is_link( $file ) )
{
$typeflag = 1;
$linkname = @readlink( $file );
}
else if ( is_dir( $file ) )
{
$typeflag = 5;
}
else
{
$typeflag = 9;
}
$this->tar_in_mem[] = array(
"name" => $file,
"mode" => $mode,
"uid" => $uid,
"gid" => $gid,
"size" => strlen( $data ),
"mtime" => $mtime,
"chksum" => " ",
"typeflag" => $typeflag,
"linkname" => $linkname,
"magic" => "ustar\x00",
"version" => "00",
"uname" => "unknown",
"gname" => "unknown",
"devmajor" => "",
"devminor" => "",
"prefix" => "",
"data" => $data
);
@clearstatcache( );
++$count;
}
}
}
@chdir( $this->current_dir );
return $count;
}
function write_tar( )
{
if ( $this->tarfile_path_name == "" )
{
$this->error = "No filename or path was specified to create a new tar file";
}
else if ( count( $this->tar_in_mem ) < 1 )
{
$this->error = "No data to write to the new tar file";
}
else
{
$tardata = "";
foreach ( $this->tar_in_mem as $file )
{
$prefix = "";
$tmp = "";
$last = "";
if ( 99 < strlen( $file['name'] ) )
{
$pos = strrpos( $file['name'], "/" );
if ( is_string( $pos ) && !$pos )
{
$this->error[] = "Filename {$file['name']} exceeds the length allowed by GNU Tape ARchives";
}
else
{
$prefix = substr( $file['name'], 0, $pos );
$file['name'] = substr( $file['name'], $pos + 1 );
if ( 154 < strlen( $prefix ) )
{
$this->error[] = "File path exceeds the length allowed by GNU Tape ARchives";
continue;
}
}
}
$mode = sprintf( "%6s ", decoct( $file['mode'] ) );
$uid = sprintf( "%6s ", decoct( $file['uid'] ) );
$gid = sprintf( "%6s ", decoct( $file['gid'] ) );
$size = sprintf( "%11s ", decoct( $file['size'] ) );
$mtime = sprintf( "%11s ", decoct( $file['mtime'] ) );
$tmp = pack( "a100a8a8a8a12a12", $file['name'], $mode, $uid, $gid, $size, $mtime );
$last = pack( "a1", $file['typeflag'] );
$last .= pack( "a100", $file['linkname'] );
$last .= pack( "a6", "ustar" );
$last .= pack( "a2", "" );
$last .= pack( "a32", $file['uname'] );
$last .= pack( "a32", $file['gname'] );
$last .= pack( "a8", "" );
$last .= pack( "a8", "" );
$last .= pack( "a155", $prefix );
$test_len = $tmp.$last."12345678";
$last .= $this->internal_build_string( "\x00", $this->tar_header_length - strlen( $test_len ) );
$checksum = 0;
$i = 0;
for ( ; $i < 148; ++$i )
{
$checksum += ord( substr( $tmp, $i, 1 ) );
}
$i = 148;
for ( ; $i < 156; ++$i )
{
$checksum += ord( " " );
}
$i = 156;
$j = 0;
for ( ; $i < 512; ++$i, ++$j )
{
$checksum += ord( substr( $last, $j, 1 ) );
}
$checksum = sprintf( "%6s ", decoct( $checksum ) );
$tmp .= pack( "a8", $checksum );
$tmp .= $last;
$tmp .= $file['data'];
if ( 0 < $file['size'] && $file['size'] % 512 != 0 )
{
$homer = $this->internal_build_string( "\x00", 512 - $file['size'] % 512 );
$tmp .= $homer;
}
$tardata .= $tmp;
}
$tardata .= pack( "a512", "" );
$FH = fopen( $this->tarfile_path_name, "wb" );
fputs( $FH, $tardata, strlen( $tardata ) );
fclose( $FH );
@chmod( $this->tarfile_path_name, 511 );
}
}
function read_tar( )
{
$filename = $this->tarfile_path_name;
if ( $filename == "" )
{
$this->error = "No filename specified when attempting to read a tar file";
return array( );
}
if ( !file_exists( $filename ) )
{
$this->error = "Cannot locate the file ".$filename;
return array( );
}
$tar_info = array( );
$this->tar_filename = $filename;
if ( !( $FH = fopen( $filename, "rb" ) ) )
{
$this->error = "Cannot open {$filename} for reading";
return array( );
}
$this->tar_unpack_header = preg_replace( "/\\s/", "", $this->tar_unpack_header );
while ( !feof( $FH ) )
{
$buffer = fread( $FH, $this->tar_header_length );
$checksum = 0;
$i = 0;
for ( ; $i < 148; ++$i )
{
$checksum += ord( substr( $buffer, $i, 1 ) );
}
$i = 148;
for ( ; $i < 156; ++$i )
{
$checksum += ord( " " );
}
$i = 156;
for ( ; $i < 512; ++$i )
{
$checksum += ord( substr( $buffer, $i, 1 ) );
}
$fa = unpack( $this->tar_unpack_header, $buffer );
$name = trim( $fa[filename] );
$mode = octdec( trim( $fa[mode] ) );
$uid = octdec( trim( $fa[uid] ) );
$gid = octdec( trim( $fa[gid] ) );
$size = octdec( trim( $fa[size] ) );
$mtime = octdec( trim( $fa[mtime] ) );
$chksum = octdec( trim( $fa[chksum] ) );
$typeflag = trim( $fa[typeflag] );
$linkname = trim( $fa[linkname] );
$magic = trim( $fa[magic] );
$version = trim( $fa[version] );
$uname = trim( $fa[uname] );
$gname = trim( $fa[gname] );
$devmajor = octdec( trim( $fa[devmajor] ) );
$devminor = octdec( trim( $fa[devminor] ) );
$prefix = trim( $fa[prefix] );
if ( $checksum == 256 && $chksum == 0 )
{
}
else
{
if ( $prefix )
{
$name = $prefix."/".$name;
}
if ( preg_match( "#/\$#", $name ) && !$name )
{
$typeflag = 5;
}
$test = $this->internal_build_string( "\\0", 512 );
if ( $buffer == $test )
{
}
else
{
$data = fread( $FH, $size );
if ( strlen( $data ) != $size )
{
$this->error = "Read error on tar file";
fclose( $FH );
return array( );
}
$diff = $size % 512;
if ( $diff != 0 )
{
$crap = fread( $FH, 512 - $diff );
}
if ( $name == "" )
{
}
else
{
$tar_info[] = array(
"name" => $name,
"mode" => $mode,
"uid" => $uid,
"gid" => $gid,
"size" => $size,
"mtime" => $mtime,
"chksum" => $chksum,
"typeflag" => $typeflag,
"linkname" => $linkname,
"magic" => $magic,
"version" => $version,
"uname" => $uname,
"gname" => $gname,
"devmajor" => $devmajor,
"devminor" => $devminor,
"prefix" => $prefix,
"data" => $data
);
}
}
}
}
fclose( $FH );
return $tar_info;
}
function internal_build_string( $string = "", $times = 0 )
{
$return = "";
$i = 0;
for ( ; $i < $times; ++$i )
{
$return .= $string;
}
return $return;
}
}
?>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -