<?php
/**
*
* @package Duplicator
* @copyright (c) 2021, Snapcreek LLC
*/
namespace Duplicator\Libs\DupArchive\Headers;
use Duplicator\Libs\Snap\SnapIO;
use Exception;
/**
* File header
*/
class DupArchiveFileHeader extends DupArchiveReaderFileHeader
{
const MAX_SIZE_FOR_HASHING = 1000000000;
public $fileSize = 0;
public $mtime = 0;
public $permissions = '';
public $hash = '';
public $relativePathLength = 0;
public $relativePath = '';
/**
* create header from file
*
* @param string $filepath file path
* @param string $relativeFilePath relative file path in archive
*
* @return static
*/
public static function createFromFile($filepath, $relativeFilePath)
{
$instance = new static();
$instance->fileSize = SnapIO::filesize($filepath);
$instance->permissions = substr(sprintf('%o', fileperms($filepath)), -4);
$instance->mtime = SnapIO::filemtime($filepath);
if ($instance->fileSize > self::MAX_SIZE_FOR_HASHING) {
$instance->hash = "00000000000000000000000000000000";
} else {
$instance->hash = hash_file('crc32b', $filepath);
}
$instance->relativePath = $relativeFilePath;
$instance->relativePathLength = strlen($instance->relativePath);
return $instance;
}
/**
* create header from src
*
* @param string $src source string
* @param string $relativeFilePath relative path in archvie
* @param int $forceSize if 0 size is auto of content is filled of \0 char to size
*
* @return static
*/
public static function createFromSrc($src, $relativeFilePath, $forceSize = 0)
{
$instance = new static();
$instance->fileSize = strlen($src);
$instance->permissions = '0644';
$instance->mtime = time();
$srcLen = strlen($src);
if ($forceSize > 0 && $srcLen < $forceSize) {
$charsToAdd = $forceSize - $srcLen;
$src .= str_repeat("\0", $charsToAdd);
}
if ($instance->fileSize > self::MAX_SIZE_FOR_HASHING) {
$instance->hash = "00000000000000000000000000000000";
} else {
$instance->hash = hash('crc32b', $src);
}
$instance->relativePath = $relativeFilePath;
$instance->relativePathLength = strlen($instance->relativePath);
return $instance;
}
/**
* Write header in archive
*
* @param resource $archiveHandle archive resource
*
* @return int bytes written
*/
public function writeToArchive($archiveHandle)
{
$headerString = '<F><FS>' .
$this->fileSize . '</FS><MT>' .
$this->mtime . '</MT><P>' .
$this->permissions . '</P><HA>' .
$this->hash . '</HA><RPL>' .
$this->relativePathLength . '</RPL><RP>' .
$this->relativePath . '</RP></F>';
//SnapIO::fwrite($archiveHandle, $headerString);
$bytes_written = @fwrite($archiveHandle, $headerString);
if ($bytes_written === false) {
throw new Exception('Error writing to file.');
} else {
return $bytes_written;
}
}
}
|