rendered paste body<?php
class Tar
{
public function unpack($tar_file, $destination_dir, $verbose = false)
{
$tar_file = str_replace('\\', '/', $tar_file);
$destination_dir = str_replace('\\', '/', $destination_dir);
if((!is_dir($destination_dir)) && (!mkdir($destination_dir))) {
throw new Exception("{$destination_dir} is not a directory and can not be made!");
}
if($verbose) echo "<h2>Unpacking <em>{$tar_file}</em> to <em>{$destination_dir}</em></h2>\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 "<p><strong>creating directory:</strong> <em>{$file_directory}</em></p>\n";
mkdir($file_directory, 0777, true);
}
if($verbose) echo "<p><strong>unpacking:</strong> <em>{$file['name']}</em> to <em>{$destination_file}</em></p>\n";
flush();
$fh = fopen($destination_file, 'w');
fwrite($fh, $file['raw'], $file['size']);
fclose($fh);
}
if($verbose) echo "<h3>done!</h3>";
}
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();
}
?>