16 class Tar extends \Magento\Framework\Archive\AbstractArchive implements \Magento\Framework\Archive\ArchiveInterface
75 $this->_writer =
new File($this->_destinationFilePath);
76 $this->_writer->open(
'w');
88 return 'a100name/a8mode/a8uid/a8gid/a12size/a12mtime/a8checksum/a1type/a100symlink/a6magic/a2version/' .
89 'a32uname/a32gname/a8devmajor/a8devminor/a155prefix/a12closer';
99 if ($this->_writer instanceof
File) {
100 $this->_writer->close();
101 $this->_writer =
null;
114 if (!$this->_writer) {
129 $this->_reader->open(
'r');
141 if ($this->_reader instanceof
File) {
142 $this->_reader->close();
143 $this->_reader =
null;
156 if (!$this->_reader) {
171 $this->_skipRoot = $skipRoot;
183 $file = str_replace(
'\\',
'/', $file);
184 $this->_currentFile = $file . (!is_link($file) &&
is_dir($file) && substr($file, -1) !=
'/' ?
'/' :
'');
196 $this->_destinationFilePath = $destinationFilePath;
220 $this->_currentPath =
$path . (substr(
$path, -1) !=
'/' ?
'/' :
'');
222 $this->_currentPath = dirname(
$path) .
'/';
245 protected function _createTar($skipRoot =
false, $finalize =
false)
254 $dirFiles = scandir($file, SCANDIR_SORT_NONE);
256 if (
false === $dirFiles) {
257 throw new \Magento\Framework\Exception\LocalizedException(
258 new \
Magento\Framework\
Phrase(
'Can\'t scan dir: %1', [$file])
262 array_shift($dirFiles);
264 array_shift($dirFiles);
267 foreach ($dirFiles as
$item) {
273 $this->
_getWriter()->write(str_repeat(
"\0", self::TAR_BLOCK_SIZE * 12));
291 if (
is_file($currentFile) && !is_link($currentFile)) {
292 $fileReader =
new File($currentFile);
293 $fileReader->open(
'r');
295 while (!$fileReader->eof()) {
296 $archiveWriter->write($fileReader->read());
299 $fileReader->close();
304 $appendZerosCount = (self::TAR_BLOCK_SIZE - $fileSize %
self::TAR_BLOCK_SIZE) % self::TAR_BLOCK_SIZE;
305 $archiveWriter->write(str_repeat(
"\0", $appendZerosCount));
323 $infoFile = stat($file);
324 $nameFile = str_replace(
$path,
'', $file);
325 $nameFile = str_replace(
'\\',
'/', $nameFile);
328 if (!$long && strlen($nameFile) > 100) {
330 $longHeader .= str_pad($nameFile, floor((strlen($nameFile) + 512 - 1) / 512) * 512,
"\0");
333 $header[
'100-name'] = $long ?
'././@LongLink' : substr($nameFile, 0, 100);
334 $header[
'8-mode'] = $long ?
' ' : str_pad(
335 substr(sprintf(
"%07o", $infoFile[
'mode']), -4),
340 $header[
'8-uid'] = $long || $infoFile[
'uid'] == 0 ?
"\0\0\0\0\0\0\0" : sprintf(
"%07o", $infoFile[
'uid']);
341 $header[
'8-gid'] = $long || $infoFile[
'gid'] == 0 ?
"\0\0\0\0\0\0\0" : sprintf(
"%07o", $infoFile[
'gid']);
342 $header[
'12-size'] = $long ? sprintf(
349 $header[
'12-mtime'] = $long ?
'00000000000' : sprintf(
"%011o", $infoFile[
'mtime']);
350 $header[
'8-check'] = sprintf(
'% 8s',
'');
351 $header[
'1-type'] = $long ?
'L' : (is_link($file) ? 2 : (
is_dir($file) ? 5 : 0));
352 $header[
'100-symlink'] = is_link($file) ? readlink($file) :
'';
353 $header[
'6-magic'] =
'ustar ';
354 $header[
'2-version'] =
' ';
355 $a =
function_exists(
'posix_getpwuid') ? posix_getpwuid(fileowner($file)) : [
'name' =>
''];
356 $header[
'32-uname'] = $a[
'name'];
357 $a =
function_exists(
'posix_getgrgid') ? posix_getgrgid(filegroup($file)) : [
'name' =>
''];
358 $header[
'32-gname'] = $a[
'name'];
359 $header[
'8-devmajor'] =
'';
360 $header[
'8-devminor'] =
'';
361 $header[
'155-prefix'] =
'';
362 $header[
'12-closer'] =
'';
365 foreach ($header as $key =>
$element) {
366 $length = explode(
'-', $key);
371 for (
$i = 0;
$i < 512;
$i++) {
372 $checksum += ord(substr($packedHeader,
$i, 1));
374 $packedHeader = substr_replace($packedHeader, sprintf(
"%07o", $checksum) .
"\0", 148, 8);
376 return $longHeader . $packedHeader;
394 while (!$archiveReader->eof()) {
401 $currentFile = $destination . $header[
'name'];
402 $dirname = dirname($currentFile);
404 if (in_array($header[
'type'], [
"0", chr(0),
''])) {
405 if (!file_exists($dirname)) {
406 $mkdirResult = @
mkdir($dirname, 0777,
true);
408 if (
false === $mkdirResult) {
409 throw new \Magento\Framework\Exception\LocalizedException(
410 new \
Magento\Framework\
Phrase(
'Failed to create directory %1', [$dirname])
416 $list[] = $currentFile;
417 }
elseif ($header[
'type'] ==
'5') {
418 if (!file_exists($dirname)) {
419 $mkdirResult = @
mkdir($currentFile, $header[
'mode'],
true);
421 if (
false === $mkdirResult) {
422 throw new \Magento\Framework\Exception\LocalizedException(
423 new \
Magento\Framework\
Phrase(
'Failed to create directory %1', [$currentFile])
427 $list[] = $currentFile .
'/';
428 }
elseif ($header[
'type'] ==
'2') {
430 @symlink($header[
'symlink'], $currentFile);
445 $headerBlock = $archiveReader->read(self::TAR_BLOCK_SIZE);
447 if (strlen($headerBlock) < self::TAR_BLOCK_SIZE) {
451 $header =
unpack(self::_getFormatParseHeader(), $headerBlock);
453 $header[
'mode'] = octdec($header[
'mode']);
454 $header[
'uid'] = octdec($header[
'uid']);
455 $header[
'gid'] = octdec($header[
'gid']);
456 $header[
'size'] = octdec($header[
'size']);
457 $header[
'mtime'] = octdec($header[
'mtime']);
458 $header[
'checksum'] = octdec($header[
'checksum']);
460 if ($header[
'type'] ==
"5") {
465 $headerBlock = substr_replace($headerBlock,
' ', 148, 8);
467 for (
$i = 0;
$i < 512;
$i++) {
468 $checksum += ord(substr($headerBlock,
$i, 1));
471 $checksumOk = $header[
'checksum'] == $checksum;
472 if (isset($header[
'name']) && $checksumOk) {
473 $header[
'name'] = trim($header[
'name']);
474 if (!($header[
'name'] ==
'././@LongLink' && $header[
'type'] ==
'L')) {
478 $realNameBlockSize = floor(
479 ($header[
'size'] + self::TAR_BLOCK_SIZE - 1) / self::TAR_BLOCK_SIZE
481 $realNameBlock = $archiveReader->read($realNameBlockSize);
482 $realName = substr($realNameBlock, 0, $header[
'size']);
485 $headerMain[
'name'] = trim($realName);
501 $fileWriter =
new File($destination);
502 $fileWriter->open(
'w', $fileHeader[
'mode']);
506 $filesize = $fileHeader[
'size'];
509 while ($filesize > $bytesExtracted && !$archiveReader->eof()) {
510 $block = $archiveReader->read(self::TAR_BLOCK_SIZE);
511 $nonExtractedBytesCount = $filesize - $bytesExtracted;
513 $data = substr(
$block, 0, $nonExtractedBytesCount);
514 $fileWriter->write(
$data);
516 $bytesExtracted += strlen(
$block);
576 while (!$archiveReader->eof()) {
578 if ($header[
'name'] == $file) {
579 $extractedFile = $destination . basename($header[
'name']);
584 if ($header[
'type'] != 5) {
586 ($header[
'size'] + self::TAR_BLOCK_SIZE - 1) / self::TAR_BLOCK_SIZE
588 $archiveReader->read($skipBytes);
593 return $extractedFile;
elseif(isset( $params[ 'redirect_parent']))
static _getFormatParseHeader()
unpack($source, $destination)
_composeHeader($long=false)
_packAndWriteCurrentFile()
_extractAndWriteFile($fileHeader, $destination)
extract($file, $source, $destination)
pack($source, $destination, $skipRoot=false)
mkdir($pathname, $mode=0777, $recursive=false, $context=null)
_createTar($skipRoot=false, $finalize=false)
_unpackCurrentTar($destination)
_setDestinationFilePath($destinationFilePath)