You are here

private function TarArchiveReader::readHeader in Backup and Migrate 8.4

Read a tar file header block.

Parameters

$block:

array $header:

Return value

array

Throws

\BackupMigrate\Core\Exception\BackupMigrateException

2 calls to TarArchiveReader::readHeader()
TarArchiveReader::extractAllToDirectory in lib/backup_migrate_core/src/Service/TarArchiveReader.php
TarArchiveReader::readLongHeader in lib/backup_migrate_core/src/Service/TarArchiveReader.php
Read a tar file header block for files with long names.

File

lib/backup_migrate_core/src/Service/TarArchiveReader.php, line 248

Class

TarArchiveReader
Class TarArchiveReader.

Namespace

BackupMigrate\Core\Service

Code

private function readHeader($block, $header = []) {
  if (strlen($block) == 0) {
    $header['filename'] = '';
    return TRUE;
  }
  if (strlen($block) != 512) {
    $header['filename'] = '';
    throw new BackupMigrateException('Invalid block size: %size bytes', [
      '%size' => strlen($block),
    ]);
  }
  if (!is_array($header)) {
    $header = [];
  }

  // Calculate the checksum.
  $checksum = 0;

  // First part of the header.
  for ($i = 0; $i < 148; $i++) {
    $checksum += ord(substr($block, $i, 1));
  }

  // Ignore the checksum value and replace it by ' ' (space).
  for ($i = 148; $i < 156; $i++) {
    $checksum += ord(' ');
  }

  // Last part of the header.
  for ($i = 156; $i < 512; $i++) {
    $checksum += ord(substr($block, $i, 1));
  }
  if (version_compare(PHP_VERSION, "5.5.0-dev") < 0) {
    $fmt = "a100filename/a8mode/a8uid/a8gid/a12size/a12mtime/" . "a8checksum/a1typeflag/a100link/a6magic/a2version/" . "a32uname/a32gname/a8devmajor/a8devminor/a131prefix";
  }
  else {
    $fmt = "Z100filename/Z8mode/Z8uid/Z8gid/Z12size/Z12mtime/" . "Z8checksum/Z1typeflag/Z100link/Z6magic/Z2version/" . "Z32uname/Z32gname/Z8devmajor/Z8devminor/Z131prefix";
  }
  $data = unpack($fmt, $block);
  if (strlen($data["prefix"]) > 0) {
    $data["filename"] = "{$data['prefix']}/{$data['filename']}";
  }

  // Extract the checksum.
  $header['checksum'] = octdec(trim($data['checksum']));
  if ($header['checksum'] != $checksum) {
    $header['filename'] = '';

    // Look for last block (empty block).
    if ($checksum == 256 && $header['checksum'] == 0) {
      return $header;
    }
    throw new BackupMigrateException('Invalid checksum for file %filename', [
      '%filename' => $data['filename'],
    ]);
  }

  // Extract the properties.
  $header['filename'] = rtrim($data['filename'], "\0");
  $header['mode'] = octdec(trim($data['mode']));
  $header['uid'] = octdec(trim($data['uid']));
  $header['gid'] = octdec(trim($data['gid']));
  $header['size'] = octdec(trim($data['size']));
  $header['mtime'] = octdec(trim($data['mtime']));
  if (($header['typeflag'] = $data['typeflag']) == "5") {
    $header['size'] = 0;
  }
  $header['link'] = trim($data['link']);

  // Look for long filename.
  if ($header['typeflag'] == 'L') {
    $header = $this
      ->readLongHeader($header);
  }
  return $header;
}