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(); } ?>