File: //usr/local/CyberCP/public/snappymail/snappymail/v/2.38.2/app/libraries/snappymail/tar.php
<?php
namespace SnappyMail;
class TAR
{
public
$alias,
$filename;
const dec = array(
'mode', 'uid', 'gid', 'size', 'mtime', 'crc', 'type'
);
function __construct(string $filename, int $flags = 0, ?string $alias = null)
{
$this->filename = $filename;
$this->alias = $alias ?: $filename;
}
/**
* @param $files array|string|null
*/
public function extractTo(string $directory, $files = null, bool $overwrite = false) : bool
{
$fp = \gzopen($this->filename, 'rb');
if (!$fp) {
return false;
}
if ($files) {
$files = '#^(' . \implode('|', \array_map('preg_quote', \is_array($files) ? $files : [$files])) . ')#u';
}
\clearstatcache(true);
while (!\gzeof($fp)) {
$data = \gzread($fp, 512);
if (\gzeof($fp) || !\trim($data)) {
break;
}
if (\strlen($data) !== 512) {
\trigger_error("{$this->alias} invalid header at offset " . \gztell($fp));
return false;
}
$header = \unpack("a100filename/a8mode/a8uid/a8gid/a12size/a12mtime/a8crc/a1type/a100linkname/a6magic/a2version/a32uname/a32gname/a8devmajor/a8devminor/a155path", $data);
if (!\strlen(\trim($header['filename']))) {
\trigger_error("{$this->alias} invalid entry filename at offset " . \gztell($fp));
return false;
}
foreach ($header as $k => $v) {
$header[$k] = \in_array($k, self::dec) ? \octdec(\trim($v)) : \trim($v);
}
if ($header['crc'] > 0) {
$crc = 0;
for ($i = 0; $i < 148; ++$i) { $crc += \ord(\substr($data, $i, 1)); }
for ($i = 148; $i < 156; ++$i) { $crc += \ord(' '); }
for ($i = 156; $i < 512; ++$i) { $crc += \ord(\substr($data, $i, 1)); }
if ($header['crc'] !== $crc) {
\trigger_error("{$this->alias} checksum of '{$header['filename']}' incorrect");
return false;
}
}
if (\preg_match('#(^|/)PaxHeader/#', $header['filename'])) {
} else if (\substr($header['filename'], -1) !== '/') {
$filename = ($header['path'] ? $header['path'] . '/' : '') . $header['filename'];
if ($files && !\preg_match($files, $filename)) {
continue;
}
$filename = $directory . '/' . $filename;
if (\is_file($filename) && !$overwrite) {
continue;
}
$dir = \dirname($filename);
if (!\is_dir($dir) && !\mkdir($dir, 0777, true)) {
return false;
}
$target = \fopen($filename, 'wb');
if (!$target) {
return false;
}
$bytes = $header['size'];
$blocksize = \ceil($bytes / 512) * 512;
$blocks = \ceil($blocksize / 8192);
while ($blocks--) {
$data = \gzread($fp, \min($blocksize, 8192));
$length = \strlen($data);
if ($bytes < $length) {
$data = \substr($data, 0, $bytes);
}
\fwrite($target, $data);
$bytes -= $length;
$blocksize -= $length;
}
\fclose($target);
\chmod($filename, $header['mode']);
} else {
// Create directory
// \gzread($fp, $blocksize);
}
}
\gzclose($fp);
return true;
}
}