make.dangerous.tar.php.inc [plain text]
<?php
class danger_tarmaker
{
protected $archive;
protected $tmp;
protected $path;
protected $compress;
function __construct($path, $compress = 'zlib')
{
$this->compress = $compress;
if ($compress === 'bz2' && !function_exists('bzopen')) {
throw new PEAR2_Pyrus_Developer_Creator_Exception(
'bzip2 extension not available');
}
if ($compress === 'zlib' && !function_exists('gzopen')) {
throw new PEAR2_Pyrus_Developer_Creator_Exception(
'zlib extension not available');
}
$this->path = $path;
}
function addFile($path, $fileOrStream, $stat = null)
{
clearstatcache();
if ($stat === null) {
if (is_resource($fileOrStream)) {
$stat = fstat($fileOrStream);
} else {
$stat = array(
'mode' => 0x8000 + 0644,
'uid' => 0,
'gid' => 0,
'size' => strlen($fileOrStream),
'mtime' => time(),
);
}
}
$link = null;
if ($stat['mode'] & 0x4000) {
$type = 5; } else if ($stat['mode'] & 0x8000) {
$type = 0; } else if ($stat['mode'] & 0xA000) {
$type = 1; $link = @readlink($current);
} else {
$type = 9; }
$filePrefix = '';
if (strlen($path) > 255) {
throw new Exception(
"$path is too long, must be 255 characters or less"
);
} else if (strlen($path) > 100) {
$filePrefix = substr($path, 0, strlen($path)-100);
$path = substr($path, -100);
}
$block = pack('a100a8a8a8a12A12',
$path,
'12345678', sprintf('%6s ',decoct($stat['uid'])),
sprintf('%6s ',decoct($stat['gid'])),
sprintf('%11s ',decoct($stat['size'])),
sprintf('%11s ',decoct($stat['mtime']))
);
$blockend = pack('a1a100a6a2a32a32a8a8a155a12',
$type,
$link,
'ustar',
'00',
'Pyrus',
'Pyrus',
'',
'',
$filePrefix,
'123456789abc');
$checkheader = array_merge(str_split($block), str_split($blockend));
if (!function_exists('_pear2tarchecksum')) {
function _pear2tarchecksum($a, $b) {return $a + ord($b);}
}
$checksum = 256; $checksum += array_reduce($checkheader, '_pear2tarchecksum');
$checksum = pack('a8', sprintf('%6s ', decoct($checksum)));
fwrite($this->tmp, (binary)$block . $checksum . $blockend, 512);
if (is_resource($fileOrStream)) {
stream_copy_to_stream($fileOrStream, $this->tmp);
if ($stat['size'] % 512) {
fwrite($this->tmp, (binary)str_repeat("\0", 512 - $stat['size'] % 512));
}
} else {
fwrite($this->tmp, (binary)$fileOrStream);
if (strlen($fileOrStream) % 512) {
fwrite($this->tmp, (binary)str_repeat("\0", 512 - strlen($fileOrStream) % 512));
}
}
}
function init()
{
switch ($this->compress) {
case 'zlib' :
$this->tmp = gzopen($this->path, 'wb');
break;
case 'bz2' :
$this->tmp = bzopen($this->path, 'w');
break;
case 'none' :
$this->tmp = fopen($this->path, 'wb');
break;
default :
throw new Exception(
'unknown compression type ' . $this->compress);
}
}
function mkdir($dir)
{
$this->addFile($dir, "", array(
'mode' => 0x4000 + 0644,
'uid' => 0,
'gid' => 0,
'size' => 0,
'mtime' => time(),
));
}
function close()
{
fwrite($this->tmp, pack('a1024', ''));
fclose($this->tmp);
}
}