mirror of
https://github.com/lrsjng/h5ai.git
synced 2025-03-24 14:30:03 +01:00
Implement POSIX.1-1988 UStar support without having to go through GNU tar
This commit is contained in:
parent
1099b297b7
commit
24ae3bed4d
@ -57,7 +57,7 @@ class Archive {
|
||||
try {
|
||||
|
||||
if ($format === "tar") {
|
||||
$cmd = Archive::$TAR_PASSTHRU_CMD;
|
||||
return $this->create_tar();
|
||||
} else if ($format === "zip") {
|
||||
$cmd = Archive::$ZIP_PASSTHRU_CMD;
|
||||
} else {
|
||||
@ -77,6 +77,54 @@ class Archive {
|
||||
}
|
||||
|
||||
|
||||
private function create_tar() {
|
||||
|
||||
// POSIX.1-1988 UStar implementation, by @TvdW
|
||||
|
||||
$root_path = $this->app->get_root_abs_path();
|
||||
|
||||
foreach (array_values($this->files) as $file) {
|
||||
|
||||
// TAR supports filenames up to 253 chars, but the name should be split ubti a 154-byte prefix and 99-byte name
|
||||
assert(substr($file, 0, strlen($root_path)) == $root_path);
|
||||
$local_filename = normalize_path(substr($file, strlen($root_path) + 1));
|
||||
$filename_parts = array('', substr($local_filename, -99));
|
||||
if (strlen($local_filename) > 99) $filename_parts[0] = substr($local_filename, 0, -99);
|
||||
if (strlen($filename_parts[0]) > 154) $filename_parts[0] = substr($filename_parts[0], -154);
|
||||
|
||||
$size = filesize($file);
|
||||
|
||||
$file_header =
|
||||
str_pad($filename_parts[1], 100, "\0") // first filename part
|
||||
."0000755\0"."0000000\0"."0000000\0" // File mode and uid/gid
|
||||
.str_pad(decoct($size), 11, "0", STR_PAD_LEFT)."\0" // File size
|
||||
.str_pad(decoct(time()), 11, "0", STR_PAD_LEFT)."\0" // Modification time
|
||||
." " // checksum (filled in later)
|
||||
."0" // file type
|
||||
.str_repeat("\0", 100)
|
||||
."ustar 00"
|
||||
.str_repeat("\0", 92)
|
||||
.str_pad($filename_parts[0], 155, "\0");
|
||||
assert(strlen($file_header) == 512);
|
||||
|
||||
// Checksum
|
||||
$checksum = array_sum(array_map('ord', str_split($file_header)));
|
||||
$checksum = str_pad(decoct($checksum), 6, "0", STR_PAD_LEFT)."\0 ";
|
||||
$file_header = substr_replace($file_header, $checksum, 148, 8);
|
||||
|
||||
echo $file_header;
|
||||
readfile($file);
|
||||
|
||||
$pad_file = 512 - ($size % 512);
|
||||
if ($pad_file) echo str_repeat("\0", $pad_file);
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
private function add_hrefs($hrefs) {
|
||||
|
||||
foreach ($hrefs as $href) {
|
||||
@ -132,4 +180,4 @@ class Archive {
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
?>
|
||||
|
Loading…
x
Reference in New Issue
Block a user