Files
luos/workflow/engine/classes/TarFile.php

151 lines
6.2 KiB
PHP
Raw Normal View History

2017-08-11 11:10:27 -04:00
<?php
/**
* This class is derived from the class archive, is imployed to use files .
* tar
2017-08-11 12:33:30 -04:00
*/
class TarFile extends Archive
2017-08-11 11:10:27 -04:00
{
/**
* This function is the constructor of the class tar_file
*
* @param string $name
*/
2019-08-21 08:53:28 -04:00
public function __construct($name)
2017-08-11 11:10:27 -04:00
{
2019-08-21 08:53:28 -04:00
parent::__construct($name);
2017-08-11 11:10:27 -04:00
$this->options['type'] = "tar";
}
/**
* This function create a file .
* tar
*
* @return boolean
*/
2017-08-11 12:33:30 -04:00
public function create_tar()
2017-08-11 11:10:27 -04:00
{
$pwd = getcwd();
2017-08-11 12:33:30 -04:00
chdir($this->options['basedir']);
2017-08-11 11:10:27 -04:00
foreach ($this->files as $current) {
if ($current['name'] == $this->options['name']) {
continue;
}
2017-08-11 12:33:30 -04:00
if (strlen($current['name2']) > 99) {
$path = substr($current['name2'], 0, strpos($current['name2'], "/", strlen($current['name2']) - 100) + 1);
$current['name2'] = substr($current['name2'], strlen($path));
if (strlen($path) > 154 || strlen($current['name2']) > 99) {
2017-08-11 11:10:27 -04:00
$this->error[] = "Could not add {$path}{$current['name2']} to archive because the filename is too long.";
continue;
}
}
2017-08-11 12:33:30 -04:00
$block = pack("a100a8a8a8a12a12a8a1a100a6a2a32a32a8a8a155a12", $current['name2'], sprintf("%07o", $current['stat'][2]), sprintf("%07o", $current['stat'][4]), sprintf("%07o", $current['stat'][5]), sprintf("%011o", $current['type'] == 2 ? 0 : $current['stat'][7]), sprintf("%011o", $current['stat'][9]), " ", $current['type'], $current['type'] == 2 ? @readlink($current['name']) : "", "ustar ", " ", "Unknown", "Unknown", "", "", !empty($path) ? $path : "", "");
2017-08-11 11:10:27 -04:00
$checksum = 0;
2017-08-11 12:33:30 -04:00
for ($i = 0; $i < 512; $i++) {
$checksum += ord(substr($block, $i, 1));
2017-08-11 11:10:27 -04:00
}
2017-08-11 12:33:30 -04:00
$checksum = pack("a8", sprintf("%07o", $checksum));
$block = substr_replace($block, $checksum, 148, 8);
2017-08-11 11:10:27 -04:00
if ($current['type'] == 2 || $current['stat'][7] == 0) {
2017-08-11 12:33:30 -04:00
$this->add_data($block);
} elseif ($fp = @fopen($current['name'], "rb")) {
$this->add_data($block);
while ($temp = fread($fp, 1048576)) {
$this->add_data($temp);
2017-08-11 11:10:27 -04:00
}
if ($current['stat'][7] % 512 > 0) {
$temp = "";
2017-08-11 12:33:30 -04:00
for ($i = 0; $i < 512 - $current['stat'][7] % 512; $i++) {
2017-08-11 11:10:27 -04:00
$temp .= "\0";
}
2017-08-11 12:33:30 -04:00
$this->add_data($temp);
2017-08-11 11:10:27 -04:00
}
2017-08-11 12:33:30 -04:00
fclose($fp);
2017-08-11 11:10:27 -04:00
} else {
$this->error[] = "Could not open file {$current['name']} for reading. It was not added.";
}
}
2017-08-11 12:33:30 -04:00
$this->add_data(pack("a1024", ""));
chdir($pwd);
2017-08-11 11:10:27 -04:00
return 1;
}
/**
* This function is used for extract files of the class tar_file
*
* @return void
*/
2017-08-11 12:33:30 -04:00
public function extract_files()
2017-08-11 11:10:27 -04:00
{
$pwd = getcwd();
2017-08-11 12:33:30 -04:00
chdir($this->options['basedir']);
2017-08-11 11:10:27 -04:00
if ($fp = $this->open_archive()) {
if ($this->options['inmemory'] == 1) {
2017-08-11 12:33:30 -04:00
$this->files = array();
2017-08-11 11:10:27 -04:00
}
2017-08-11 12:33:30 -04:00
while ($block = fread($fp, 512)) {
$temp = unpack("a100name/a8mode/a8uid/a8gid/a12size/a12mtime/a8checksum/a1type/a100symlink/a6magic/a2temp/a32temp/a32temp/a8temp/a8temp/a155prefix/a12temp", $block);
$file = array('name' => $this->options['basedir'] . '/' . $temp['prefix'] . $temp['name'], 'stat' => array(2 => $temp['mode'], 4 => octdec($temp['uid']), 5 => octdec($temp['gid']), 7 => octdec($temp['size']), 9 => octdec($temp['mtime'])
), 'checksum' => octdec($temp['checksum']), 'type' => $temp['type'], 'magic' => $temp['magic']
2017-08-11 11:10:27 -04:00
);
if ($file['checksum'] == 0x00000000) {
break;
2017-08-11 12:33:30 -04:00
} elseif (substr($file['magic'], 0, 5) != "ustar") {
2017-08-11 11:10:27 -04:00
$this->error[] = "This script does not support extracting this type of tar file.";
break;
}
2017-08-11 12:33:30 -04:00
$block = substr_replace($block, " ", 148, 8);
2017-08-11 11:10:27 -04:00
$checksum = 0;
2017-08-11 12:33:30 -04:00
for ($i = 0; $i < 512; $i++) {
$checksum += ord(substr($block, $i, 1));
2017-08-11 11:10:27 -04:00
}
if ($file['checksum'] != $checksum) {
$this->error[] = "Could not extract from {$this->options['name']}, it is corrupt.";
}
if ($this->options['inmemory'] == 1) {
2017-08-11 12:33:30 -04:00
$file['data'] = fread($fp, $file['stat'][7]);
fread($fp, (512 - $file['stat'][7] % 512) == 512 ? 0 : (512 - $file['stat'][7] % 512));
unset($file['checksum'], $file['magic']);
2017-08-11 11:10:27 -04:00
$this->files[] = $file;
} elseif ($file['type'] == 5) {
2017-08-11 12:33:30 -04:00
if (!is_dir($file['name'])) {
mkdir($file['name'], 0775);
2017-08-11 11:10:27 -04:00
}
2017-08-11 12:33:30 -04:00
} elseif ($this->options['overwrite'] == 0 && file_exists($file['name'])) {
2017-08-11 11:10:27 -04:00
$this->error[] = "{$file['name']} already exist.";
continue;
} elseif ($file['type'] == 2) {
2017-08-11 12:33:30 -04:00
symlink($temp['symlink'], $file['name']);
} elseif ($new = @fopen($file['name'], "wb")) {
fwrite($new, fread($fp, $file['stat'][7]));
2017-08-11 11:10:27 -04:00
if ((512 - $file['stat'][7] % 512) != 512) {
2017-08-11 12:33:30 -04:00
fread($fp, (512 - $file['stat'][7] % 512));
2017-08-11 11:10:27 -04:00
}
2017-08-11 12:33:30 -04:00
fclose($new);
chmod($file['name'], 0777);
2017-08-11 11:10:27 -04:00
$this->files[] = $file['name'];
} else {
$this->error[] = "Could not open {$file['name']} for writing.";
continue;
}
2017-08-11 12:33:30 -04:00
@touch($file['name'], $file['stat'][9]);
unset($file);
2017-08-11 11:10:27 -04:00
}
} else {
$this->error[] = "Could not open file {$this->options['name']}";
}
2017-08-11 12:33:30 -04:00
chdir($pwd);
2017-08-11 11:10:27 -04:00
}
/**
* This function open a archive of the class tar_file
*
* @return void
*/
2017-08-11 12:33:30 -04:00
public function open_archive()
2017-08-11 11:10:27 -04:00
{
2017-08-11 12:33:30 -04:00
return @fopen($this->options['name'], "rb");
2017-08-11 11:10:27 -04:00
}
}