Unpacking {$tar_file} to {$destination_dir}\n";
$files = $this->read($tar_file);
foreach($files as $file) {
$destination_file = $destination_dir . $file['name'];
$file_directory = dirname($destination_file);
if(!is_dir($file_directory)) {
if($verbose) echo "
creating directory: {$file_directory}
\n";
mkdir($file_directory, 0777, true);
}
if($verbose) echo "unpacking: {$file['name']} to {$destination_file}
\n";
flush();
$fh = fopen($destination_file, 'w');
fwrite($fh, $file['raw'], $file['size']);
fclose($fh);
}
if($verbose) echo "done!
";
}
public function read($tar_file)
{
if(!file_exists($tar_file)) {
throw new Exception("{$tar_file} does not exist!");
}
if(!$file = fopen($tar_file, 'rb')) {
throw new Exception("{$tar_file} can not be read!");
}
$header = 'a100name/a8mode/a8uid/a8gid/a12size/a12mtime/a8chksum/a1typeflag/a100linkname/a6magic/a2version/a32uname/a32gname/a8devmajor/a8devminor/a155prefix';
$files = array();
while(!feof($file)) {
$buffer = fread($file, 512);
$checksum = 0;
for($i = 0; $i < 148; $i++) {
$checksum += ord(substr($buffer, $i, 1));
}
for($i = 148; $i < 156; $i++) {
$checksum += 32;
}
for ($i = 156; $i < 512; $i++) {
$checksum += ord(substr($buffer, $i, 1));
}
$file_info = unpack($header, $buffer);
$octal_values = array('mode', 'uid', 'gid', 'size', 'mtime', 'chksum', 'devmajor', 'devminor');
$file_info = array_map('trim', $file_info);
foreach($file_info as $key => $value) {
if(in_array($key, $octal_values)) {
$file_info[$key] = octdec($file_info[$key]);
}
}
$file_info['name'] = ($file_info['prefix']) ? "{$file_info['prefix']}/{$file_info['name']}" : substr($file_info['name'], 2);
$file_info['typeflag'] = (substr($file_info['name'], -1, 1) == '/') ? 5 : $file_info['typeflag'] ;
if(($buffer == str_repeat('\0', 512)) || ($file_info['name'] == null) || (($file_info['chksum'] == 0) && ($checksum == 256))) {
break;
}
if($file_info['size'] > 0) {
$file_info['raw'] = fread($file, $file_info['size']);
if(strlen($file_info['raw']) != $file_info['size']) {
throw new Exception("Oh noes, {$file_info['name']} raw data does not match the reported file size of {$file_info['size']}!");
}
}
$diffrence = $file_info['size'] % 512;
if($diffrence != 0) {
fread($file, 512 - $diffrence);
}
array_push($files, $file_info);
}
fclose($file);
return $files;
}
}
$install_dir = dirname(__FILE__) . '/test/';
$tar_file = $install_dir . 'install.tar';
$tar = new Tar();
try {
$tar->unpack($tar_file, $install_dir, true);
} catch(Exception $e) {
echo 'error: ' . $e->getMessage();
}
?>