From fa2c560da3df273672806893a2f660982c0011f0 Mon Sep 17 00:00:00 2001 From: Andreas Gohr <andi@splitbrain.org> Date: Sat, 21 Jan 2017 14:58:03 +0100 Subject: [PATCH] removed deprecated Tar and Zip classes --- inc/Tar.class.php | 648 ------------------------------------------- inc/ZipLib.class.php | 576 -------------------------------------- 2 files changed, 1224 deletions(-) delete mode 100644 inc/Tar.class.php delete mode 100644 inc/ZipLib.class.php diff --git a/inc/Tar.class.php b/inc/Tar.class.php deleted file mode 100644 index 57c280d79..000000000 --- a/inc/Tar.class.php +++ /dev/null @@ -1,648 +0,0 @@ -<?php -/** - * This class allows the extraction of existing and the creation of new Unix TAR archives. - * To keep things simple, the modification of existing archives is not supported. It handles - * uncompressed, gzip and bzip2 compressed tar files. - * - * Long pathnames (>100 chars) are supported in POSIX ustar and GNU longlink formats. - * - * To list the contents of an existing TAR archive, open() it and use contents() on it: - * - * $tar = new Tar(); - * $tar->open('myfile.tgz'); - * $toc = $tar->contents(); - * print_r($toc); - * - * To extract the contents of an existing TAR archive, open() it and use extract() on it: - * - * $tar = new Tar(); - * $tar->open('myfile.tgz'); - * $tar->extract('/tmp'); - * - * To create a new TAR archive directly on the filesystem (low memory requirements), create() it, - * add*() files and close() it: - * - * $tar = new Tar(); - * $tar->create('myfile.tgz'); - * $tar->addFile(...); - * $tar->addData(...); - * ... - * $tar->close(); - * - * To create a TAR archive directly in memory, create() it, add*() files and then either save() - * or getData() it: - * - * $tar = new Tar(); - * $tar->create(); - * $tar->addFile(...); - * $tar->addData(...); - * ... - * $tar->save('myfile.tgz'); // compresses and saves it - * echo $tar->getArchive(Tar::COMPRESS_GZIP); // compresses and returns it - * - * @author Andreas Gohr <andi@splitbrain.org> - * @author Bouchon <tarlib@bouchon.org> (Maxg) - * @license GPL 2 - * @deprecated 2015-05-15 - use splitbrain\PHPArchive\Tar instead - */ -class Tar { - - const COMPRESS_AUTO = 0; - const COMPRESS_NONE = 1; - const COMPRESS_GZIP = 2; - const COMPRESS_BZIP = 3; - - protected $file = ''; - protected $comptype = Tar::COMPRESS_AUTO; - /** @var resource|int */ - protected $fh; - protected $memory = ''; - protected $closed = true; - protected $writeaccess = false; - - /** - * Open an existing TAR file for reading - * - * @param string $file - * @param int $comptype - * @throws TarIOException - */ - public function open($file, $comptype = Tar::COMPRESS_AUTO) { - // determine compression - if($comptype == Tar::COMPRESS_AUTO) $comptype = $this->filetype($file); - $this->compressioncheck($comptype); - - $this->comptype = $comptype; - $this->file = $file; - - if($this->comptype === Tar::COMPRESS_GZIP) { - $this->fh = @gzopen($this->file, 'rb'); - } elseif($this->comptype === Tar::COMPRESS_BZIP) { - $this->fh = @bzopen($this->file, 'r'); - } else { - $this->fh = @fopen($this->file, 'rb'); - } - - if(!$this->fh) throw new TarIOException('Could not open file for reading: '.$this->file); - $this->closed = false; - } - - /** - * Read the contents of a TAR archive - * - * This function lists the files stored in the archive, and returns an indexed array of associative - * arrays containing for each file the following information: - * - * checksum Tar Checksum of the file - * filename The full name of the stored file (up to 100 c.) - * mode UNIX permissions in DECIMAL, not octal - * uid The Owner ID - * gid The Group ID - * size Uncompressed filesize - * mtime Timestamp of last modification - * typeflag Empty for files, set for folders - * link Is it a symlink? - * uname Owner name - * gname Group name - * - * The archive is closed afer reading the contents, because rewinding is not possible in bzip2 streams. - * Reopen the file with open() again if you want to do additional operations - * - * @return array - * @throws TarIOException - */ - public function contents() { - if($this->closed || !$this->file) throw new TarIOException('Can not read from a closed archive'); - - $result = array(); - while($read = $this->readbytes(512)) { - $header = $this->parseHeader($read); - if(!is_array($header)) continue; - - $this->skipbytes(ceil($header['size'] / 512) * 512); - $result[] = $header; - } - - $this->close(); - return $result; - } - - /** - * Extract an existing TAR archive - * - * The $strip parameter allows you to strip a certain number of path components from the filenames - * found in the tar file, similar to the --strip-components feature of GNU tar. This is triggered when - * an integer is passed as $strip. - * Alternatively a fixed string prefix may be passed in $strip. If the filename matches this prefix, - * the prefix will be stripped. It is recommended to give prefixes with a trailing slash. - * - * By default this will extract all files found in the archive. You can restrict the output using the $include - * and $exclude parameter. Both expect a full regular expression (including delimiters and modifiers). If - * $include is set only files that match this expression will be extracted. Files that match the $exclude - * expression will never be extracted. Both parameters can be used in combination. Expressions are matched against - * stripped filenames as described above. - * - * The archive is closed afer reading the contents, because rewinding is not possible in bzip2 streams. - * Reopen the file with open() again if you want to do additional operations - * - * @param string $outdir the target directory for extracting - * @param int|string $strip either the number of path components or a fixed prefix to strip - * @param string $exclude a regular expression of files to exclude - * @param string $include a regular expression of files to include - * @throws TarIOException - * @return array - */ - function extract($outdir, $strip = '', $exclude = '', $include = '') { - if($this->closed || !$this->file) throw new TarIOException('Can not read from a closed archive'); - - $outdir = rtrim($outdir, '/'); - io_mkdir_p($outdir); - $striplen = strlen($strip); - - $extracted = array(); - - while($dat = $this->readbytes(512)) { - // read the file header - $header = $this->parseHeader($dat); - if(!is_array($header)) continue; - if(!$header['filename']) continue; - - // strip prefix - $filename = $this->cleanPath($header['filename']); - if(is_int($strip)) { - // if $strip is an integer we strip this many path components - $parts = explode('/', $filename); - if(!$header['typeflag']) { - $base = array_pop($parts); // keep filename itself - } else { - $base = ''; - } - $filename = join('/', array_slice($parts, $strip)); - if($base) $filename .= "/$base"; - } else { - // ifstrip is a string, we strip a prefix here - if(substr($filename, 0, $striplen) == $strip) $filename = substr($filename, $striplen); - } - - // check if this should be extracted - $extract = true; - if(!$filename) { - $extract = false; - } else { - if($include) { - if(preg_match($include, $filename)) { - $extract = true; - } else { - $extract = false; - } - } - if($exclude && preg_match($exclude, $filename)) { - $extract = false; - } - } - - // Now do the extraction (or not) - if($extract) { - $extracted[] = $header; - - $output = "$outdir/$filename"; - $directory = ($header['typeflag']) ? $output : dirname($output); - io_mkdir_p($directory); - - // is this a file? - if(!$header['typeflag']) { - $fp = fopen($output, "wb"); - if(!$fp) throw new TarIOException('Could not open file for writing: '.$output); - - $size = floor($header['size'] / 512); - for($i = 0; $i < $size; $i++) { - fwrite($fp, $this->readbytes(512), 512); - } - if(($header['size'] % 512) != 0) fwrite($fp, $this->readbytes(512), $header['size'] % 512); - - fclose($fp); - touch($output, $header['mtime']); - chmod($output, $header['perm']); - } else { - $this->skipbytes(ceil($header['size'] / 512) * 512); // the size is usually 0 for directories - } - } else { - $this->skipbytes(ceil($header['size'] / 512) * 512); - } - } - - $this->close(); - return $extracted; - } - - /** - * Create a new TAR file - * - * If $file is empty, the tar file will be created in memory - * - * @param string $file - * @param int $comptype - * @param int $complevel - * @throws TarIOException - * @throws TarIllegalCompressionException - */ - public function create($file = '', $comptype = Tar::COMPRESS_AUTO, $complevel = 9) { - // determine compression - if($comptype == Tar::COMPRESS_AUTO) $comptype = $this->filetype($file); - $this->compressioncheck($comptype); - - $this->comptype = $comptype; - $this->file = $file; - $this->memory = ''; - $this->fh = 0; - - if($this->file) { - if($this->comptype === Tar::COMPRESS_GZIP) { - $this->fh = @gzopen($this->file, 'wb'.$complevel); - } elseif($this->comptype === Tar::COMPRESS_BZIP) { - $this->fh = @bzopen($this->file, 'w'); - } else { - $this->fh = @fopen($this->file, 'wb'); - } - - if(!$this->fh) throw new TarIOException('Could not open file for writing: '.$this->file); - } - $this->writeaccess = true; - $this->closed = false; - } - - /** - * Add a file to the current TAR archive using an existing file in the filesystem - * - * @todo handle directory adding - * - * @param string $file the original file - * @param string $name the name to use for the file in the archive - * @throws TarIOException - */ - public function addFile($file, $name = '') { - if($this->closed) throw new TarIOException('Archive has been closed, files can no longer be added'); - - if(!$name) $name = $file; - $name = $this->cleanPath($name); - - $fp = fopen($file, 'rb'); - if(!$fp) throw new TarIOException('Could not open file for reading: '.$file); - - // create file header and copy all stat info from the original file - clearstatcache(false, $file); - $stat = stat($file); - $this->writeFileHeader( - $name, - $stat[4], - $stat[5], - fileperms($file), - filesize($file), - filemtime($file) - ); - - while(!feof($fp)) { - $data = fread($fp, 512); - if($data === false) break; - if($data === '') break; - $packed = pack("a512", $data); - $this->writebytes($packed); - } - fclose($fp); - } - - /** - * Add a file to the current TAR archive using the given $data as content - * - * @param string $name - * @param string $data - * @param int $uid - * @param int $gid - * @param int $perm - * @param int $mtime - * @throws TarIOException - */ - public function addData($name, $data, $uid = 0, $gid = 0, $perm = 0666, $mtime = 0) { - if($this->closed) throw new TarIOException('Archive has been closed, files can no longer be added'); - - $name = $this->cleanPath($name); - $len = strlen($data); - - $this->writeFileHeader( - $name, - $uid, - $gid, - $perm, - $len, - ($mtime) ? $mtime : time() - ); - - for($s = 0; $s < $len; $s += 512) { - $this->writebytes(pack("a512", substr($data, $s, 512))); - } - } - - /** - * Add the closing footer to the archive if in write mode, close all file handles - * - * After a call to this function no more data can be added to the archive, for - * read access no reading is allowed anymore - * - * "Physically, an archive consists of a series of file entries terminated by an end-of-archive entry, which - * consists of two 512 blocks of zero bytes" - * - * @link http://www.gnu.org/software/tar/manual/html_chapter/tar_8.html#SEC134 - */ - public function close() { - if($this->closed) return; // we did this already - - // write footer - if($this->writeaccess) { - $this->writebytes(pack("a512", "")); - $this->writebytes(pack("a512", "")); - } - - // close file handles - if($this->file) { - if($this->comptype === Tar::COMPRESS_GZIP) { - gzclose($this->fh); - } elseif($this->comptype === Tar::COMPRESS_BZIP) { - bzclose($this->fh); - } else { - fclose($this->fh); - } - - $this->file = ''; - $this->fh = 0; - } - - $this->closed = true; - } - - /** - * Returns the created in-memory archive data - * - * This implicitly calls close() on the Archive - * - * @param int $comptype - * @param int $complevel - * @return mixed|string - */ - public function getArchive($comptype = Tar::COMPRESS_AUTO, $complevel = 9) { - $this->close(); - - if($comptype === Tar::COMPRESS_AUTO) $comptype = $this->comptype; - $this->compressioncheck($comptype); - - if($comptype === Tar::COMPRESS_GZIP) return gzcompress($this->memory, $complevel); - if($comptype === Tar::COMPRESS_BZIP) return bzcompress($this->memory); - return $this->memory; - } - - /** - * Save the created in-memory archive data - * - * Note: It more memory effective to specify the filename in the create() function and - * let the library work on the new file directly. - * - * @param string $file - * @param int $comptype - * @param int $complevel - * @throws TarIOException - */ - public function save($file, $comptype = Tar::COMPRESS_AUTO, $complevel = 9) { - if($comptype === Tar::COMPRESS_AUTO) $comptype = $this->filetype($file); - - if(!file_put_contents($file, $this->getArchive($comptype, $complevel))) { - throw new TarIOException('Could not write to file: '.$file); - } - } - - /** - * Read from the open file pointer - * - * @param int $length bytes to read - * @return string - */ - protected function readbytes($length) { - if($this->comptype === Tar::COMPRESS_GZIP) { - return @gzread($this->fh, $length); - } elseif($this->comptype === Tar::COMPRESS_BZIP) { - return @bzread($this->fh, $length); - } else { - return @fread($this->fh, $length); - } - } - - /** - * Write to the open filepointer or memory - * - * @param string $data - * @throws TarIOException - * @return int number of bytes written - */ - protected function writebytes($data) { - if(!$this->file) { - $this->memory .= $data; - $written = strlen($data); - } elseif($this->comptype === Tar::COMPRESS_GZIP) { - $written = @gzwrite($this->fh, $data); - } elseif($this->comptype === Tar::COMPRESS_BZIP) { - $written = @bzwrite($this->fh, $data); - } else { - $written = @fwrite($this->fh, $data); - } - if($written === false) throw new TarIOException('Failed to write to archive stream'); - return $written; - } - - /** - * Skip forward in the open file pointer - * - * This is basically a wrapper around seek() (and a workaround for bzip2) - * - * @param int $bytes seek to this position - */ - function skipbytes($bytes) { - if($this->comptype === Tar::COMPRESS_GZIP) { - @gzseek($this->fh, $bytes, SEEK_CUR); - } elseif($this->comptype === Tar::COMPRESS_BZIP) { - // there is no seek in bzip2, we simply read on - @bzread($this->fh, $bytes); - } else { - @fseek($this->fh, $bytes, SEEK_CUR); - } - } - - /** - * Write a file header - * - * @param string $name - * @param int $uid - * @param int $gid - * @param int $perm - * @param int $size - * @param int $mtime - * @param string $typeflag Set to '5' for directories - */ - protected function writeFileHeader($name, $uid, $gid, $perm, $size, $mtime, $typeflag = '') { - // handle filename length restrictions - $prefix = ''; - $namelen = strlen($name); - if($namelen > 100) { - $file = basename($name); - $dir = dirname($name); - if(strlen($file) > 100 || strlen($dir) > 155) { - // we're still too large, let's use GNU longlink - $this->writeFileHeader('././@LongLink', 0, 0, 0, $namelen, 0, 'L'); - for($s = 0; $s < $namelen; $s += 512) { - $this->writebytes(pack("a512", substr($name, $s, 512))); - } - $name = substr($name, 0, 100); // cut off name - } else { - // we're fine when splitting, use POSIX ustar - $prefix = $dir; - $name = $file; - } - } - - // values are needed in octal - $uid = sprintf("%6s ", decoct($uid)); - $gid = sprintf("%6s ", decoct($gid)); - $perm = sprintf("%6s ", decoct($perm)); - $size = sprintf("%11s ", decoct($size)); - $mtime = sprintf("%11s", decoct($mtime)); - - $data_first = pack("a100a8a8a8a12A12", $name, $perm, $uid, $gid, $size, $mtime); - $data_last = pack("a1a100a6a2a32a32a8a8a155a12", $typeflag, '', 'ustar', '', '', '', '', '', $prefix, ""); - - for($i = 0, $chks = 0; $i < 148; $i++) - $chks += ord($data_first[$i]); - - for($i = 156, $chks += 256, $j = 0; $i < 512; $i++, $j++) - $chks += ord($data_last[$j]); - - $this->writebytes($data_first); - - $chks = pack("a8", sprintf("%6s ", decoct($chks))); - $this->writebytes($chks.$data_last); - } - - /** - * Decode the given tar file header - * - * @param string $block a 512 byte block containign the header data - * @return false|array - */ - protected function parseHeader($block) { - if(!$block || strlen($block) != 512) return false; - - for($i = 0, $chks = 0; $i < 148; $i++) - $chks += ord($block[$i]); - - for($i = 156, $chks += 256; $i < 512; $i++) - $chks += ord($block[$i]); - - $header = @unpack("a100filename/a8perm/a8uid/a8gid/a12size/a12mtime/a8checksum/a1typeflag/a100link/a6magic/a2version/a32uname/a32gname/a8devmajor/a8devminor/a155prefix", $block); - if(!$header) return false; - - $return = array(); - $return['checksum'] = OctDec(trim($header['checksum'])); - if($return['checksum'] != $chks) return false; - - $return['filename'] = trim($header['filename']); - $return['perm'] = OctDec(trim($header['perm'])); - $return['uid'] = OctDec(trim($header['uid'])); - $return['gid'] = OctDec(trim($header['gid'])); - $return['size'] = OctDec(trim($header['size'])); - $return['mtime'] = OctDec(trim($header['mtime'])); - $return['typeflag'] = $header['typeflag']; - $return['link'] = trim($header['link']); - $return['uname'] = trim($header['uname']); - $return['gname'] = trim($header['gname']); - - // Handle ustar Posix compliant path prefixes - if(trim($header['prefix'])) $return['filename'] = trim($header['prefix']).'/'.$return['filename']; - - // Handle Long-Link entries from GNU Tar - if($return['typeflag'] == 'L') { - // following data block(s) is the filename - $filename = trim($this->readbytes(ceil($header['size'] / 512) * 512)); - // next block is the real header - $block = $this->readbytes(512); - $return = $this->parseHeader($block); - // overwrite the filename - $return['filename'] = $filename; - } - - return $return; - } - - /** - * Cleans up a path and removes relative parts, also strips leading slashes - * - * @param string $path - * @return string - */ - public function cleanPath($path) { - $path=explode('/', $path); - $newpath=array(); - foreach($path as $p) { - if ($p === '' || $p === '.') continue; - if ($p==='..') { - array_pop($newpath); - continue; - } - array_push($newpath, $p); - } - return trim(implode('/', $newpath), '/'); - } - - /** - * Checks if the given compression type is available and throws an exception if not - * - * @param int $comptype - * @throws TarIllegalCompressionException - */ - protected function compressioncheck($comptype) { - if($comptype === Tar::COMPRESS_GZIP && !function_exists('gzopen')) { - throw new TarIllegalCompressionException('No gzip support available'); - } - - if($comptype === Tar::COMPRESS_BZIP && !function_exists('bzopen')) { - throw new TarIllegalCompressionException('No bzip2 support available'); - } - } - - /** - * Guesses the wanted compression from the given filename extension - * - * You don't need to call this yourself. It's used when you pass Tar::COMPRESS_AUTO somewhere - * - * @param string $file - * @return int - */ - public function filetype($file) { - $file = strtolower($file); - if(substr($file, -3) == '.gz' || substr($file, -4) == '.tgz') { - $comptype = Tar::COMPRESS_GZIP; - } elseif(substr($file, -4) == '.bz2' || substr($file, -4) == '.tbz') { - $comptype = Tar::COMPRESS_BZIP; - } else { - $comptype = Tar::COMPRESS_NONE; - } - return $comptype; - } -} - -/** - * Class TarIOException - */ -class TarIOException extends Exception { -} - -/** - * Class TarIllegalCompressionException - */ -class TarIllegalCompressionException extends Exception { -} diff --git a/inc/ZipLib.class.php b/inc/ZipLib.class.php deleted file mode 100644 index 1358ca45e..000000000 --- a/inc/ZipLib.class.php +++ /dev/null @@ -1,576 +0,0 @@ -<?php - -/** - * @author bouchon - * @link http://dev.maxg.info - * @link http://forum.maxg.info - * - * Modified for Dokuwiki - * @deprecated 2015-05-15 - use splitbrain\PHPArchive\Zip instead - * @author Christopher Smith <chris@jalakai.co.uk> - */ -class ZipLib { - - var $datasec; - var $ctrl_dir = array(); - var $eof_ctrl_dir = "\x50\x4b\x05\x06\x00\x00\x00\x00"; - var $old_offset = 0; - var $dirs = Array("."); - - /** - * @param string $zip_name filename path to file - * @return array|int - */ - function get_List($zip_name) { - $zip = @fopen($zip_name, 'rb'); - if(!$zip) return(0); - $centd = $this->ReadCentralDir($zip,$zip_name); - - @rewind($zip); - @fseek($zip, $centd['offset']); - - $ret = array(); - for ($i=0; $i<$centd['entries']; $i++) { - $header = $this->ReadCentralFileHeaders($zip); - $header['index'] = $i; - - $info = array(); - $info['filename'] = $header['filename']; - $info['stored_filename'] = $header['stored_filename']; - $info['size'] = $header['size']; - $info['compressed_size'] = $header['compressed_size']; - $info['crc'] = strtoupper(dechex( $header['crc'] )); - $info['mtime'] = $header['mtime']; - $info['comment'] = $header['comment']; - $info['folder'] = ($header['external']==0x41FF0010||$header['external']==16)?1:0; - $info['index'] = $header['index']; - $info['status'] = $header['status']; - $ret[]=$info; - - unset($header); - } - return $ret; - } - - /** - * @param array $files array filled with array(string filename, string data) - * @param bool $compact - * @return array - */ - function Add($files,$compact) { - if(!is_array($files[0])) $files=Array($files); - - $ret = array(); - for($i=0;$files[$i];$i++){ - $fn = $files[$i]; - if(!in_Array(dirname($fn[0]),$this->dirs)) - $this->add_Dir(dirname($fn[0])); - if(utf8_basename($fn[0])) - $ret[utf8_basename($fn[0])]=$this->add_File($fn[1],$fn[0],$compact); - } - return $ret; - } - - /** - * Zips recursively the $folder directory, from the $basedir directory - * - * @param string $folder filename path to file - * @param string|null $basedir - * @param string|null $parent - */ - function Compress($folder, $basedir=null, $parent=null) { - $full_path = $basedir."/".$parent.$folder; - $zip_path = $parent.$folder; - if ($zip_path) { - $zip_path .= "/"; - $this->add_dir($zip_path); - } - $dir = new DirectoryIterator($full_path); - foreach($dir as $file) { - /** @var DirectoryIterator $file */ - if(!$file->isDot()) { - $filename = $file->getFilename(); - if($file->isDir()) { - $this->Compress($filename, $basedir, $zip_path); - } else { - $content = join('', file($full_path.'/'.$filename)); - $this->add_File($content, $zip_path.$filename); - } - } - } - } - - /** - * Returns the Zip file - * - * @return string - */ - function get_file() { - $data = implode('', $this -> datasec); - $ctrldir = implode('', $this -> ctrl_dir); - - return $data . $ctrldir . $this -> eof_ctrl_dir . - pack('v', count($this->ctrl_dir)).pack('v', count($this->ctrl_dir)). - pack('V', strlen($ctrldir)) . pack('V', strlen($data)) . "\x00\x00"; - } - - /** - * @param string $name the name of the directory - */ - function add_dir($name) { - $name = str_replace("\\", "/", $name); - $fr = "\x50\x4b\x03\x04\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00"; - - $fr .= pack("V",0).pack("V",0).pack("V",0).pack("v", strlen($name) ); - $fr .= pack("v", 0 ).$name.pack("V", 0).pack("V", 0).pack("V", 0); - $this -> datasec[] = $fr; - - $new_offset = strlen(implode("", $this->datasec)); - - $cdrec = "\x50\x4b\x01\x02\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00"; - $cdrec .= pack("V",0).pack("V",0).pack("V",0).pack("v", strlen($name) ); - $cdrec .= pack("v", 0 ).pack("v", 0 ).pack("v", 0 ).pack("v", 0 ); - $ext = "\xff\xff\xff\xff"; - $cdrec .= pack("V", 16 ).pack("V", $this -> old_offset ).$name; - - $this -> ctrl_dir[] = $cdrec; - $this -> old_offset = $new_offset; - $this -> dirs[] = $name; - } - - /** - * Add a file named $name from a string $data - * - * @param string $data - * @param string $name filename - * @param bool $compact - * @return bool - */ - function add_File($data, $name, $compact = true) { - $name = str_replace('\\', '/', $name); - $dtime = dechex($this->DosTime()); - - $hexdtime = pack('H*',$dtime[6].$dtime[7]. - $dtime[4].$dtime[5]. - $dtime[2].$dtime[3]. - $dtime[0].$dtime[1]); - - if($compact){ - $fr = "\x50\x4b\x03\x04\x14\x00\x00\x00\x08\x00".$hexdtime; - }else{ - $fr = "\x50\x4b\x03\x04\x0a\x00\x00\x00\x00\x00".$hexdtime; - } - $unc_len = strlen($data); - $crc = crc32($data); - - if($compact){ - $zdata = gzcompress($data); - $c_len = strlen($zdata); - $zdata = substr(substr($zdata, 0, strlen($zdata) - 4), 2); - }else{ - $zdata = $data; - } - $c_len=strlen($zdata); - $fr .= pack('V', $crc).pack('V', $c_len).pack('V', $unc_len); - $fr .= pack('v', strlen($name)).pack('v', 0).$name.$zdata; - - $fr .= pack('V', $crc).pack('V', $c_len).pack('V', $unc_len); - - $this -> datasec[] = $fr; - $new_offset = strlen(implode('', $this->datasec)); - if($compact) { - $cdrec = "\x50\x4b\x01\x02\x00\x00\x14\x00\x00\x00\x08\x00"; - } else { - $cdrec = "\x50\x4b\x01\x02\x14\x00\x0a\x00\x00\x00\x00\x00"; - } - $cdrec .= $hexdtime.pack('V', $crc).pack('V', $c_len).pack('V', $unc_len); - $cdrec .= pack('v', strlen($name) ).pack('v', 0 ).pack('v', 0 ); - $cdrec .= pack('v', 0 ).pack('v', 0 ).pack('V', 32 ); - $cdrec .= pack('V', $this -> old_offset ); - - $this -> old_offset = $new_offset; - $cdrec .= $name; - $this -> ctrl_dir[] = $cdrec; - return true; - } - - /** - * @return int - */ - function DosTime() { - $timearray = getdate(); - if ($timearray['year'] < 1980) { - $timearray['year'] = 1980; - $timearray['mon'] = 1; - $timearray['mday'] = 1; - $timearray['hours'] = 0; - $timearray['minutes'] = 0; - $timearray['seconds'] = 0; - } - return (($timearray['year'] - 1980) << 25) | - ($timearray['mon'] << 21) | - ($timearray['mday'] << 16) | - ($timearray['hours'] << 11) | - ($timearray['minutes'] << 5) | - ($timearray['seconds'] >> 1); - } - - /** - * Extract a zip file $zn to the $to directory - * - * @param string $zn filename - * @param string $to filename path to file - * @param array $index - * @return array|int - */ - function Extract ( $zn, $to, $index = Array(-1) ) { - if(!@is_dir($to)) $this->_mkdir($to); - $zip = @fopen($zn,'rb'); - if(!$zip) return(-1); - $cdir = $this->ReadCentralDir($zip,$zn); - $pos_entry = $cdir['offset']; - - if(!is_array($index)){ - $index = array($index); - } - for($i=0; isset($index[$i]);$i++){ - if(intval($index[$i])!=$index[$i]||$index[$i]>$cdir['entries']) - return(-1); - } - - $stat = array(); - for ($i=0; $i<$cdir['entries']; $i++) { - @fseek($zip, $pos_entry); - $header = $this->ReadCentralFileHeaders($zip); - $header['index'] = $i; - $pos_entry = ftell($zip); - @rewind($zip); - fseek($zip, $header['offset']); - if(in_array("-1",$index)||in_array($i,$index)){ - $stat[$header['filename']]=$this->ExtractFile($header, $to, $zip); - } - } - fclose($zip); - return $stat; - } - - /** - * @param resource $zip - * @param array $header - * @return array - */ - function ReadFileHeader($zip, $header) { - $binary_data = fread($zip, 30); - $data = unpack('vchk/vid/vversion/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len', $binary_data); - - $header['filename'] = fread($zip, $data['filename_len']); - if ($data['extra_len'] != 0) { - $header['extra'] = fread($zip, $data['extra_len']); - } else { - $header['extra'] = ''; - } - - $header['compression'] = $data['compression']; - foreach (array('size','compressed_size','crc') as $hd) { // On ODT files, these headers are 0. Keep the previous value. - if ($data[$hd] != 0) $header[$hd] = $data[$hd]; - } - $header['flag'] = $data['flag']; - $header['mdate'] = $data['mdate']; - $header['mtime'] = $data['mtime']; - - if ($header['mdate'] && $header['mtime']){ - $hour = ($header['mtime']&0xF800)>>11; - $minute = ($header['mtime']&0x07E0)>>5; - $seconde = ($header['mtime']&0x001F)*2; - $year = (($header['mdate']&0xFE00)>>9)+1980; - $month = ($header['mdate']&0x01E0)>>5; - $day = $header['mdate']&0x001F; - $header['mtime'] = mktime($hour, $minute, $seconde, $month, $day, $year); - } else { - $header['mtime'] = time(); - } - - $header['stored_filename'] = $header['filename']; - $header['status'] = "ok"; - return $header; - } - - /** - * @param resource $zip - * @return array - */ - function ReadCentralFileHeaders($zip){ - $binary_data = fread($zip, 46); - $header = unpack('vchkid/vid/vversion/vversion_extracted/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len/vcomment_len/vdisk/vinternal/Vexternal/Voffset', $binary_data); - - if ($header['filename_len'] != 0){ - $header['filename'] = fread($zip,$header['filename_len']); - }else{ - $header['filename'] = ''; - } - - if ($header['extra_len'] != 0){ - $header['extra'] = fread($zip, $header['extra_len']); - }else{ - $header['extra'] = ''; - } - - if ($header['comment_len'] != 0){ - $header['comment'] = fread($zip, $header['comment_len']); - }else{ - $header['comment'] = ''; - } - - if ($header['mdate'] && $header['mtime']) { - $hour = ($header['mtime'] & 0xF800) >> 11; - $minute = ($header['mtime'] & 0x07E0) >> 5; - $seconde = ($header['mtime'] & 0x001F)*2; - $year = (($header['mdate'] & 0xFE00) >> 9) + 1980; - $month = ($header['mdate'] & 0x01E0) >> 5; - $day = $header['mdate'] & 0x001F; - $header['mtime'] = mktime($hour, $minute, $seconde, $month, $day, $year); - } else { - $header['mtime'] = time(); - } - - $header['stored_filename'] = $header['filename']; - $header['status'] = 'ok'; - if (substr($header['filename'], -1) == '/') $header['external'] = 0x41FF0010; - - return $header; - } - - /** - * @param resource $zip - * @param string $zip_name filename path to file - * @return array - */ - function ReadCentralDir($zip,$zip_name) { - $size = filesize($zip_name); - if ($size < 277){ - $maximum_size = $size; - } else { - $maximum_size=277; - } - - @fseek($zip, $size-$maximum_size); - $pos = ftell($zip); - $bytes = 0x00000000; - - while ($pos < $size) { - $byte = @fread($zip, 1); - $bytes=(($bytes << 8) & 0xFFFFFFFF) | Ord($byte); - if ($bytes == 0x504b0506){ - $pos++; - break; - } - $pos++; - } - - $data=unpack('vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size', - fread($zip, 18)); - - $centd = array(); - if ($data['comment_size'] != 0){ - $centd['comment'] = fread($zip, $data['comment_size']); - } else { - $centd['comment'] = ''; - } - $centd['entries'] = $data['entries']; - $centd['disk_entries'] = $data['disk_entries']; - $centd['offset'] = $data['offset']; - $centd['disk_start'] = $data['disk_start']; - $centd['size'] = $data['size']; - $centd['disk'] = $data['disk']; - return $centd; - } - - /** - * @param array $header - * @param string $to filename path to file - * @param resource $zip - * @return bool|int - */ - function ExtractFile($header,$to,$zip) { - $header = $this->readfileheader($zip, $header); - - if(substr($to,-1)!="/") $to.="/"; - if(substr($header['filename'],-1)=="/") { - $this->_mkdir($to.$header['filename']); - return +2; - } - - if (!$this->_mkdir($to.dirname($header['filename']))) return (-1); - - if (!array_key_exists("external", $header) || (!($header['external']==0x41FF0010)&&!($header['external']==16))) { - if ($header['compression']==0) { - $fp = @fopen($to.$header['filename'], 'wb'); - if(!$fp) return(-1); - $size = $header['compressed_size']; - - while ($size != 0) { - $read_size = ($size < 2048 ? $size : 2048); - $buffer = fread($zip, $read_size); - $binary_data = pack('a'.$read_size, $buffer); - @fwrite($fp, $binary_data, $read_size); - $size -= $read_size; - } - fclose($fp); - touch($to.$header['filename'], $header['mtime']); - - }else{ - if (!is_dir(dirname($to.$header['filename']))) $this->_mkdir(dirname($to.$header['filename'])); - $fp = fopen($to.$header['filename'].'.gz','wb'); - if(!$fp) return(-1); - $binary_data = pack('va1a1Va1a1', 0x8b1f, Chr($header['compression']), - Chr(0x00), time(), Chr(0x00), Chr(3)); - - fwrite($fp, $binary_data, 10); - $size = $header['compressed_size']; - - while ($size != 0) { - $read_size = ($size < 1024 ? $size : 1024); - $buffer = fread($zip, $read_size); - $binary_data = pack('a'.$read_size, $buffer); - @fwrite($fp, $binary_data, $read_size); - $size -= $read_size; - } - - $binary_data = pack('VV', $header['crc'], $header['size']); - fwrite($fp, $binary_data,8); - fclose($fp); - - $gzp = @gzopen($to.$header['filename'].'.gz','rb'); - if(!$gzp){ - @gzclose($gzp); - @unlink($to.$header['filename']); - die("Archive is compressed whereas ZLIB is not enabled."); - } - $fp = @fopen($to.$header['filename'],'wb'); - if(!$fp) return(-1); - $size = $header['size']; - - while ($size != 0) { - $read_size = ($size < 2048 ? $size : 2048); - $buffer = gzread($gzp, $read_size); - $binary_data = pack('a'.$read_size, $buffer); - @fwrite($fp, $binary_data, $read_size); - $size -= $read_size; - } - fclose($fp); - gzclose($gzp); - - touch($to.$header['filename'], $header['mtime']); - @unlink($to.$header['filename'].'.gz'); - } - } - return true; - } - - /** - * centralize mkdir calls and use dokuwiki io functions - * - * @author Christopher Smith <chris@jalakai.co.uk> - * - * @param string $d filename path to file - * @return bool|int|string - */ - function _mkdir($d) { - return io_mkdir_p($d); - } - - /** - * @param string $zn - * @param string $name - * @return null|string - */ - function ExtractStr($zn, $name) { - $zip = @fopen($zn,'rb'); - if(!$zip) return(null); - $cdir = $this->ReadCentralDir($zip,$zn); - $pos_entry = $cdir['offset']; - - for ($i=0; $i<$cdir['entries']; $i++) { - @fseek($zip, $pos_entry); - $header = $this->ReadCentralFileHeaders($zip); - $header['index'] = $i; - $pos_entry = ftell($zip); - @rewind($zip); - fseek($zip, $header['offset']); - if ($name == $header['stored_filename'] || $name == $header['filename']) { - $str = $this->ExtractStrFile($header, $zip); - fclose($zip); - return $str; - } - - } - fclose($zip); - return null; - } - - /** - * @param array $header - * @param resource $zip - * @return null|string - */ - function ExtractStrFile($header,$zip) { - $hdr = $this->readfileheader($zip, $header); - $binary_data = ''; - if (!($header['external']==0x41FF0010) && !($header['external']==16)) { - if ($header['compression']==0) { - while ($size != 0) { - $read_size = ($size < 2048 ? $size : 2048); - $buffer = fread($zip, $read_size); - $binary_data .= pack('a'.$read_size, $buffer); - $size -= $read_size; - } - return $binary_data; - } else { - $size = $header['compressed_size']; - if ($size == 0) { - return ''; - } - //Just in case - if ($size > ($this->_ret_bytes(ini_get('memory_limit'))/2)) { - die("Compressed file is to huge to be uncompress in memory."); - } - while ($size != 0) - { - $read_size = ($size < 2048 ? $size : 2048); - $buffer = fread($zip, $read_size); - $binary_data .= pack('a'.$read_size, $buffer); - $size -= $read_size; - } - $str = gzinflate($binary_data, $header['size']); - if ($header['crc'] == crc32($str)) { - return $str; - } else { - die("Crc Error"); - } - } - } - return null; - } - - /** - * @param string $val - * @return int|string - */ - function _ret_bytes($val) { - $val = trim($val); - $last = $val{strlen($val)-1}; - switch($last) { - case 'k': - case 'K': - return (int) $val * 1024; - break; - case 'm': - case 'M': - return (int) $val * 1048576; - break; - default: - return $val; - } - } -} - -- GitLab