From 0cb434686ca05708dc53aba7254e882741de7477 Mon Sep 17 00:00:00 2001 From: Roeland Jago Douma Date: Mon, 2 May 2016 07:23:14 +0200 Subject: Move OC_Archive_XX to PSR-4 * Fix code * Fix tests --- lib/private/Archive/TAR.php | 390 +++++++++++++++++++++++++++++++++++++++++ lib/private/Archive/ZIP.php | 230 ++++++++++++++++++++++++ lib/private/archive/tar.php | 388 ---------------------------------------- lib/private/archive/zip.php | 228 ------------------------ lib/private/legacy/archive.php | 9 +- 5 files changed, 626 insertions(+), 619 deletions(-) create mode 100644 lib/private/Archive/TAR.php create mode 100644 lib/private/Archive/ZIP.php delete mode 100644 lib/private/archive/tar.php delete mode 100644 lib/private/archive/zip.php (limited to 'lib/private') diff --git a/lib/private/Archive/TAR.php b/lib/private/Archive/TAR.php new file mode 100644 index 00000000000..e233bdeb9cc --- /dev/null +++ b/lib/private/Archive/TAR.php @@ -0,0 +1,390 @@ + + * @author Christian Weiske + * @author Christopher Schäpers + * @author Felix Moeller + * @author Frank Karlitschek + * @author Joas Schilling + * @author Jörn Friedrich Dreyer + * @author Morris Jobke + * @author Remco Brenninkmeijer + * @author Robin Appelman + * @author Robin McCorkell + * @author Thomas Müller + * + * @copyright Copyright (c) 2016, ownCloud, Inc. + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see + * + */ + +namespace OC\Archive; + +class TAR extends \OC_Archive { + const PLAIN = 0; + const GZIP = 1; + const BZIP = 2; + + private $fileList; + private $cachedHeaders; + + /** + * @var \Archive_Tar tar + */ + private $tar = null; + private $path; + + /** + * @param string $source + */ + function __construct($source) { + $types = array(null, 'gz', 'bz2'); + $this->path = $source; + $this->tar = new \Archive_Tar($source, $types[self::getTarType($source)]); + } + + /** + * try to detect the type of tar compression + * + * @param string $file + * @return integer + */ + static public function getTarType($file) { + if (strpos($file, '.')) { + $extension = substr($file, strrpos($file, '.')); + switch ($extension) { + case '.gz': + case '.tgz': + return self::GZIP; + case '.bz': + case '.bz2': + return self::BZIP; + case '.tar': + return self::PLAIN; + default: + return self::PLAIN; + } + } else { + return self::PLAIN; + } + } + + /** + * add an empty folder to the archive + * + * @param string $path + * @return bool + */ + function addFolder($path) { + $tmpBase = \OC::$server->getTempManager()->getTemporaryFolder(); + if (substr($path, -1, 1) != '/') { + $path .= '/'; + } + if ($this->fileExists($path)) { + return false; + } + $parts = explode('/', $path); + $folder = $tmpBase; + foreach ($parts as $part) { + $folder .= '/' . $part; + if (!is_dir($folder)) { + mkdir($folder); + } + } + $result = $this->tar->addModify(array($tmpBase . $path), '', $tmpBase); + rmdir($tmpBase . $path); + $this->fileList = false; + $this->cachedHeaders = false; + return $result; + } + + /** + * add a file to the archive + * + * @param string $path + * @param string $source either a local file or string data + * @return bool + */ + function addFile($path, $source = '') { + if ($this->fileExists($path)) { + $this->remove($path); + } + if ($source and $source[0] == '/' and file_exists($source)) { + $source = file_get_contents($source); + } + $result = $this->tar->addString($path, $source); + $this->fileList = false; + $this->cachedHeaders = false; + return $result; + } + + /** + * rename a file or folder in the archive + * + * @param string $source + * @param string $dest + * @return bool + */ + function rename($source, $dest) { + //no proper way to delete, rename entire archive, rename file and remake archive + $tmp = \OCP\Files::tmpFolder(); + $this->tar->extract($tmp); + rename($tmp . $source, $tmp . $dest); + $this->tar = null; + unlink($this->path); + $types = array(null, 'gz', 'bz'); + $this->tar = new \Archive_Tar($this->path, $types[self::getTarType($this->path)]); + $this->tar->createModify(array($tmp), '', $tmp . '/'); + $this->fileList = false; + $this->cachedHeaders = false; + return true; + } + + /** + * @param string $file + */ + private function getHeader($file) { + if (!$this->cachedHeaders) { + $this->cachedHeaders = $this->tar->listContent(); + } + foreach ($this->cachedHeaders as $header) { + if ($file == $header['filename'] + or $file . '/' == $header['filename'] + or '/' . $file . '/' == $header['filename'] + or '/' . $file == $header['filename'] + ) { + return $header; + } + } + return null; + } + + /** + * get the uncompressed size of a file in the archive + * + * @param string $path + * @return int + */ + function filesize($path) { + $stat = $this->getHeader($path); + return $stat['size']; + } + + /** + * get the last modified time of a file in the archive + * + * @param string $path + * @return int + */ + function mtime($path) { + $stat = $this->getHeader($path); + return $stat['mtime']; + } + + /** + * get the files in a folder + * + * @param string $path + * @return array + */ + function getFolder($path) { + $files = $this->getFiles(); + $folderContent = array(); + $pathLength = strlen($path); + foreach ($files as $file) { + if ($file[0] == '/') { + $file = substr($file, 1); + } + if (substr($file, 0, $pathLength) == $path and $file != $path) { + $result = substr($file, $pathLength); + if ($pos = strpos($result, '/')) { + $result = substr($result, 0, $pos + 1); + } + if (array_search($result, $folderContent) === false) { + $folderContent[] = $result; + } + } + } + return $folderContent; + } + + /** + * get all files in the archive + * + * @return array + */ + function getFiles() { + if ($this->fileList) { + return $this->fileList; + } + if (!$this->cachedHeaders) { + $this->cachedHeaders = $this->tar->listContent(); + } + $files = array(); + foreach ($this->cachedHeaders as $header) { + $files[] = $header['filename']; + } + $this->fileList = $files; + return $files; + } + + /** + * get the content of a file + * + * @param string $path + * @return string + */ + function getFile($path) { + return $this->tar->extractInString($path); + } + + /** + * extract a single file from the archive + * + * @param string $path + * @param string $dest + * @return bool + */ + function extractFile($path, $dest) { + $tmp = \OCP\Files::tmpFolder(); + if (!$this->fileExists($path)) { + return false; + } + if ($this->fileExists('/' . $path)) { + $success = $this->tar->extractList(array('/' . $path), $tmp); + } else { + $success = $this->tar->extractList(array($path), $tmp); + } + if ($success) { + rename($tmp . $path, $dest); + } + \OCP\Files::rmdirr($tmp); + return $success; + } + + /** + * extract the archive + * + * @param string $dest + * @return bool + */ + function extract($dest) { + return $this->tar->extract($dest); + } + + /** + * check if a file or folder exists in the archive + * + * @param string $path + * @return bool + */ + function fileExists($path) { + $files = $this->getFiles(); + if ((array_search($path, $files) !== false) or (array_search($path . '/', $files) !== false)) { + return true; + } else { + $folderPath = $path; + if (substr($folderPath, -1, 1) != '/') { + $folderPath .= '/'; + } + $pathLength = strlen($folderPath); + foreach ($files as $file) { + if (strlen($file) > $pathLength and substr($file, 0, $pathLength) == $folderPath) { + return true; + } + } + } + if ($path[0] != '/') { //not all programs agree on the use of a leading / + return $this->fileExists('/' . $path); + } else { + return false; + } + } + + /** + * remove a file or folder from the archive + * + * @param string $path + * @return bool + */ + function remove($path) { + if (!$this->fileExists($path)) { + return false; + } + $this->fileList = false; + $this->cachedHeaders = false; + //no proper way to delete, extract entire archive, delete file and remake archive + $tmp = \OCP\Files::tmpFolder(); + $this->tar->extract($tmp); + \OCP\Files::rmdirr($tmp . $path); + $this->tar = null; + unlink($this->path); + $this->reopen(); + $this->tar->createModify(array($tmp), '', $tmp); + return true; + } + + /** + * get a file handler + * + * @param string $path + * @param string $mode + * @return resource + */ + function getStream($path, $mode) { + if (strrpos($path, '.') !== false) { + $ext = substr($path, strrpos($path, '.')); + } else { + $ext = ''; + } + $tmpFile = \OCP\Files::tmpFile($ext); + if ($this->fileExists($path)) { + $this->extractFile($path, $tmpFile); + } elseif ($mode == 'r' or $mode == 'rb') { + return false; + } + if ($mode == 'r' or $mode == 'rb') { + return fopen($tmpFile, $mode); + } else { + \OC\Files\Stream\Close::registerCallback($tmpFile, array($this, 'writeBack')); + self::$tempFiles[$tmpFile] = $path; + return fopen('close://' . $tmpFile, $mode); + } + } + + private static $tempFiles = array(); + + /** + * write back temporary files + */ + function writeBack($tmpFile) { + if (isset(self::$tempFiles[$tmpFile])) { + $this->addFile(self::$tempFiles[$tmpFile], $tmpFile); + unlink($tmpFile); + } + } + + /** + * reopen the archive to ensure everything is written + */ + private function reopen() { + if ($this->tar) { + $this->tar->_close(); + $this->tar = null; + } + $types = array(null, 'gz', 'bz'); + $this->tar = new \Archive_Tar($this->path, $types[self::getTarType($this->path)]); + } +} diff --git a/lib/private/Archive/ZIP.php b/lib/private/Archive/ZIP.php new file mode 100644 index 00000000000..1d35e178923 --- /dev/null +++ b/lib/private/Archive/ZIP.php @@ -0,0 +1,230 @@ + + * @author Christopher Schäpers + * @author Felix Moeller + * @author Frank Karlitschek + * @author Joas Schilling + * @author Jörn Friedrich Dreyer + * @author Morris Jobke + * @author Robin Appelman + * @author Thomas Müller + * + * @copyright Copyright (c) 2016, ownCloud, Inc. + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see + * + */ + +namespace OC\Archive; + +class ZIP extends \OC_Archive{ + /** + * @var \ZipArchive zip + */ + private $zip=null; + private $path; + + /** + * @param string $source + */ + function __construct($source) { + $this->path=$source; + $this->zip=new \ZipArchive(); + if($this->zip->open($source, \ZipArchive::CREATE)) { + }else{ + \OCP\Util::writeLog('files_archive', 'Error while opening archive '.$source, \OCP\Util::WARN); + } + } + /** + * add an empty folder to the archive + * @param string $path + * @return bool + */ + function addFolder($path) { + return $this->zip->addEmptyDir($path); + } + /** + * add a file to the archive + * @param string $path + * @param string $source either a local file or string data + * @return bool + */ + function addFile($path, $source='') { + if($source and $source[0]=='/' and file_exists($source)) { + $result=$this->zip->addFile($source, $path); + }else{ + $result=$this->zip->addFromString($path, $source); + } + if($result) { + $this->zip->close();//close and reopen to save the zip + $this->zip->open($this->path); + } + return $result; + } + /** + * rename a file or folder in the archive + * @param string $source + * @param string $dest + * @return boolean|null + */ + function rename($source, $dest) { + $source=$this->stripPath($source); + $dest=$this->stripPath($dest); + $this->zip->renameName($source, $dest); + } + /** + * get the uncompressed size of a file in the archive + * @param string $path + * @return int + */ + function filesize($path) { + $stat=$this->zip->statName($path); + return $stat['size']; + } + /** + * get the last modified time of a file in the archive + * @param string $path + * @return int + */ + function mtime($path) { + return filemtime($this->path); + } + /** + * get the files in a folder + * @param string $path + * @return array + */ + function getFolder($path) { + $files=$this->getFiles(); + $folderContent=array(); + $pathLength=strlen($path); + foreach($files as $file) { + if(substr($file, 0, $pathLength)==$path and $file!=$path) { + if(strrpos(substr($file, 0, -1), '/')<=$pathLength) { + $folderContent[]=substr($file, $pathLength); + } + } + } + return $folderContent; + } + /** + * get all files in the archive + * @return array + */ + function getFiles() { + $fileCount=$this->zip->numFiles; + $files=array(); + for($i=0;$i<$fileCount;$i++) { + $files[]=$this->zip->getNameIndex($i); + } + return $files; + } + /** + * get the content of a file + * @param string $path + * @return string + */ + function getFile($path) { + return $this->zip->getFromName($path); + } + /** + * extract a single file from the archive + * @param string $path + * @param string $dest + * @return boolean|null + */ + function extractFile($path, $dest) { + $fp = $this->zip->getStream($path); + file_put_contents($dest, $fp); + } + /** + * extract the archive + * @param string $dest + * @return bool + */ + function extract($dest) { + return $this->zip->extractTo($dest); + } + /** + * check if a file or folder exists in the archive + * @param string $path + * @return bool + */ + function fileExists($path) { + return ($this->zip->locateName($path)!==false) or ($this->zip->locateName($path.'/')!==false); + } + /** + * remove a file or folder from the archive + * @param string $path + * @return bool + */ + function remove($path) { + if($this->fileExists($path.'/')) { + return $this->zip->deleteName($path.'/'); + }else{ + return $this->zip->deleteName($path); + } + } + /** + * get a file handler + * @param string $path + * @param string $mode + * @return resource + */ + function getStream($path, $mode) { + if($mode=='r' or $mode=='rb') { + return $this->zip->getStream($path); + } else { + //since we can't directly get a writable stream, + //make a temp copy of the file and put it back + //in the archive when the stream is closed + if(strrpos($path, '.')!==false) { + $ext=substr($path, strrpos($path, '.')); + }else{ + $ext=''; + } + $tmpFile=\OCP\Files::tmpFile($ext); + \OC\Files\Stream\Close::registerCallback($tmpFile, array($this, 'writeBack')); + if($this->fileExists($path)) { + $this->extractFile($path, $tmpFile); + } + self::$tempFiles[$tmpFile]=$path; + return fopen('close://'.$tmpFile, $mode); + } + } + + private static $tempFiles=array(); + /** + * write back temporary files + */ + function writeBack($tmpFile) { + if(isset(self::$tempFiles[$tmpFile])) { + $this->addFile(self::$tempFiles[$tmpFile], $tmpFile); + unlink($tmpFile); + } + } + + /** + * @param string $path + * @return string + */ + private function stripPath($path) { + if(!$path || $path[0]=='/') { + return substr($path, 1); + }else{ + return $path; + } + } +} diff --git a/lib/private/archive/tar.php b/lib/private/archive/tar.php deleted file mode 100644 index 20e2e05f238..00000000000 --- a/lib/private/archive/tar.php +++ /dev/null @@ -1,388 +0,0 @@ - - * @author Christian Weiske - * @author Christopher Schäpers - * @author Felix Moeller - * @author Frank Karlitschek - * @author Joas Schilling - * @author Jörn Friedrich Dreyer - * @author Morris Jobke - * @author Remco Brenninkmeijer - * @author Robin Appelman - * @author Robin McCorkell - * @author Thomas Müller - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see - * - */ - -class OC_Archive_TAR extends OC_Archive { - const PLAIN = 0; - const GZIP = 1; - const BZIP = 2; - - private $fileList; - private $cachedHeaders; - - /** - * @var Archive_Tar tar - */ - private $tar = null; - private $path; - - /** - * @param string $source - */ - function __construct($source) { - $types = array(null, 'gz', 'bz2'); - $this->path = $source; - $this->tar = new Archive_Tar($source, $types[self::getTarType($source)]); - } - - /** - * try to detect the type of tar compression - * - * @param string $file - * @return integer - */ - static public function getTarType($file) { - if (strpos($file, '.')) { - $extension = substr($file, strrpos($file, '.')); - switch ($extension) { - case '.gz': - case '.tgz': - return self::GZIP; - case '.bz': - case '.bz2': - return self::BZIP; - case '.tar': - return self::PLAIN; - default: - return self::PLAIN; - } - } else { - return self::PLAIN; - } - } - - /** - * add an empty folder to the archive - * - * @param string $path - * @return bool - */ - function addFolder($path) { - $tmpBase = \OC::$server->getTempManager()->getTemporaryFolder(); - if (substr($path, -1, 1) != '/') { - $path .= '/'; - } - if ($this->fileExists($path)) { - return false; - } - $parts = explode('/', $path); - $folder = $tmpBase; - foreach ($parts as $part) { - $folder .= '/' . $part; - if (!is_dir($folder)) { - mkdir($folder); - } - } - $result = $this->tar->addModify(array($tmpBase . $path), '', $tmpBase); - rmdir($tmpBase . $path); - $this->fileList = false; - $this->cachedHeaders = false; - return $result; - } - - /** - * add a file to the archive - * - * @param string $path - * @param string $source either a local file or string data - * @return bool - */ - function addFile($path, $source = '') { - if ($this->fileExists($path)) { - $this->remove($path); - } - if ($source and $source[0] == '/' and file_exists($source)) { - $source = file_get_contents($source); - } - $result = $this->tar->addString($path, $source); - $this->fileList = false; - $this->cachedHeaders = false; - return $result; - } - - /** - * rename a file or folder in the archive - * - * @param string $source - * @param string $dest - * @return bool - */ - function rename($source, $dest) { - //no proper way to delete, rename entire archive, rename file and remake archive - $tmp = OCP\Files::tmpFolder(); - $this->tar->extract($tmp); - rename($tmp . $source, $tmp . $dest); - $this->tar = null; - unlink($this->path); - $types = array(null, 'gz', 'bz'); - $this->tar = new Archive_Tar($this->path, $types[self::getTarType($this->path)]); - $this->tar->createModify(array($tmp), '', $tmp . '/'); - $this->fileList = false; - $this->cachedHeaders = false; - return true; - } - - /** - * @param string $file - */ - private function getHeader($file) { - if (!$this->cachedHeaders) { - $this->cachedHeaders = $this->tar->listContent(); - } - foreach ($this->cachedHeaders as $header) { - if ($file == $header['filename'] - or $file . '/' == $header['filename'] - or '/' . $file . '/' == $header['filename'] - or '/' . $file == $header['filename'] - ) { - return $header; - } - } - return null; - } - - /** - * get the uncompressed size of a file in the archive - * - * @param string $path - * @return int - */ - function filesize($path) { - $stat = $this->getHeader($path); - return $stat['size']; - } - - /** - * get the last modified time of a file in the archive - * - * @param string $path - * @return int - */ - function mtime($path) { - $stat = $this->getHeader($path); - return $stat['mtime']; - } - - /** - * get the files in a folder - * - * @param string $path - * @return array - */ - function getFolder($path) { - $files = $this->getFiles(); - $folderContent = array(); - $pathLength = strlen($path); - foreach ($files as $file) { - if ($file[0] == '/') { - $file = substr($file, 1); - } - if (substr($file, 0, $pathLength) == $path and $file != $path) { - $result = substr($file, $pathLength); - if ($pos = strpos($result, '/')) { - $result = substr($result, 0, $pos + 1); - } - if (array_search($result, $folderContent) === false) { - $folderContent[] = $result; - } - } - } - return $folderContent; - } - - /** - * get all files in the archive - * - * @return array - */ - function getFiles() { - if ($this->fileList) { - return $this->fileList; - } - if (!$this->cachedHeaders) { - $this->cachedHeaders = $this->tar->listContent(); - } - $files = array(); - foreach ($this->cachedHeaders as $header) { - $files[] = $header['filename']; - } - $this->fileList = $files; - return $files; - } - - /** - * get the content of a file - * - * @param string $path - * @return string - */ - function getFile($path) { - return $this->tar->extractInString($path); - } - - /** - * extract a single file from the archive - * - * @param string $path - * @param string $dest - * @return bool - */ - function extractFile($path, $dest) { - $tmp = OCP\Files::tmpFolder(); - if (!$this->fileExists($path)) { - return false; - } - if ($this->fileExists('/' . $path)) { - $success = $this->tar->extractList(array('/' . $path), $tmp); - } else { - $success = $this->tar->extractList(array($path), $tmp); - } - if ($success) { - rename($tmp . $path, $dest); - } - OCP\Files::rmdirr($tmp); - return $success; - } - - /** - * extract the archive - * - * @param string $dest - * @return bool - */ - function extract($dest) { - return $this->tar->extract($dest); - } - - /** - * check if a file or folder exists in the archive - * - * @param string $path - * @return bool - */ - function fileExists($path) { - $files = $this->getFiles(); - if ((array_search($path, $files) !== false) or (array_search($path . '/', $files) !== false)) { - return true; - } else { - $folderPath = $path; - if (substr($folderPath, -1, 1) != '/') { - $folderPath .= '/'; - } - $pathLength = strlen($folderPath); - foreach ($files as $file) { - if (strlen($file) > $pathLength and substr($file, 0, $pathLength) == $folderPath) { - return true; - } - } - } - if ($path[0] != '/') { //not all programs agree on the use of a leading / - return $this->fileExists('/' . $path); - } else { - return false; - } - } - - /** - * remove a file or folder from the archive - * - * @param string $path - * @return bool - */ - function remove($path) { - if (!$this->fileExists($path)) { - return false; - } - $this->fileList = false; - $this->cachedHeaders = false; - //no proper way to delete, extract entire archive, delete file and remake archive - $tmp = OCP\Files::tmpFolder(); - $this->tar->extract($tmp); - OCP\Files::rmdirr($tmp . $path); - $this->tar = null; - unlink($this->path); - $this->reopen(); - $this->tar->createModify(array($tmp), '', $tmp); - return true; - } - - /** - * get a file handler - * - * @param string $path - * @param string $mode - * @return resource - */ - function getStream($path, $mode) { - if (strrpos($path, '.') !== false) { - $ext = substr($path, strrpos($path, '.')); - } else { - $ext = ''; - } - $tmpFile = OCP\Files::tmpFile($ext); - if ($this->fileExists($path)) { - $this->extractFile($path, $tmpFile); - } elseif ($mode == 'r' or $mode == 'rb') { - return false; - } - if ($mode == 'r' or $mode == 'rb') { - return fopen($tmpFile, $mode); - } else { - \OC\Files\Stream\Close::registerCallback($tmpFile, array($this, 'writeBack')); - self::$tempFiles[$tmpFile] = $path; - return fopen('close://' . $tmpFile, $mode); - } - } - - private static $tempFiles = array(); - - /** - * write back temporary files - */ - function writeBack($tmpFile) { - if (isset(self::$tempFiles[$tmpFile])) { - $this->addFile(self::$tempFiles[$tmpFile], $tmpFile); - unlink($tmpFile); - } - } - - /** - * reopen the archive to ensure everything is written - */ - private function reopen() { - if ($this->tar) { - $this->tar->_close(); - $this->tar = null; - } - $types = array(null, 'gz', 'bz'); - $this->tar = new Archive_Tar($this->path, $types[self::getTarType($this->path)]); - } -} diff --git a/lib/private/archive/zip.php b/lib/private/archive/zip.php deleted file mode 100644 index 0d8d3b7ce76..00000000000 --- a/lib/private/archive/zip.php +++ /dev/null @@ -1,228 +0,0 @@ - - * @author Christopher Schäpers - * @author Felix Moeller - * @author Frank Karlitschek - * @author Joas Schilling - * @author Jörn Friedrich Dreyer - * @author Morris Jobke - * @author Robin Appelman - * @author Thomas Müller - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see - * - */ - -class OC_Archive_ZIP extends OC_Archive{ - /** - * @var ZipArchive zip - */ - private $zip=null; - private $path; - - /** - * @param string $source - */ - function __construct($source) { - $this->path=$source; - $this->zip=new ZipArchive(); - if($this->zip->open($source, ZipArchive::CREATE)) { - }else{ - OCP\Util::writeLog('files_archive', 'Error while opening archive '.$source, OCP\Util::WARN); - } - } - /** - * add an empty folder to the archive - * @param string $path - * @return bool - */ - function addFolder($path) { - return $this->zip->addEmptyDir($path); - } - /** - * add a file to the archive - * @param string $path - * @param string $source either a local file or string data - * @return bool - */ - function addFile($path, $source='') { - if($source and $source[0]=='/' and file_exists($source)) { - $result=$this->zip->addFile($source, $path); - }else{ - $result=$this->zip->addFromString($path, $source); - } - if($result) { - $this->zip->close();//close and reopen to save the zip - $this->zip->open($this->path); - } - return $result; - } - /** - * rename a file or folder in the archive - * @param string $source - * @param string $dest - * @return boolean|null - */ - function rename($source, $dest) { - $source=$this->stripPath($source); - $dest=$this->stripPath($dest); - $this->zip->renameName($source, $dest); - } - /** - * get the uncompressed size of a file in the archive - * @param string $path - * @return int - */ - function filesize($path) { - $stat=$this->zip->statName($path); - return $stat['size']; - } - /** - * get the last modified time of a file in the archive - * @param string $path - * @return int - */ - function mtime($path) { - return filemtime($this->path); - } - /** - * get the files in a folder - * @param string $path - * @return array - */ - function getFolder($path) { - $files=$this->getFiles(); - $folderContent=array(); - $pathLength=strlen($path); - foreach($files as $file) { - if(substr($file, 0, $pathLength)==$path and $file!=$path) { - if(strrpos(substr($file, 0, -1), '/')<=$pathLength) { - $folderContent[]=substr($file, $pathLength); - } - } - } - return $folderContent; - } - /** - * get all files in the archive - * @return array - */ - function getFiles() { - $fileCount=$this->zip->numFiles; - $files=array(); - for($i=0;$i<$fileCount;$i++) { - $files[]=$this->zip->getNameIndex($i); - } - return $files; - } - /** - * get the content of a file - * @param string $path - * @return string - */ - function getFile($path) { - return $this->zip->getFromName($path); - } - /** - * extract a single file from the archive - * @param string $path - * @param string $dest - * @return boolean|null - */ - function extractFile($path, $dest) { - $fp = $this->zip->getStream($path); - file_put_contents($dest, $fp); - } - /** - * extract the archive - * @param string $dest - * @return bool - */ - function extract($dest) { - return $this->zip->extractTo($dest); - } - /** - * check if a file or folder exists in the archive - * @param string $path - * @return bool - */ - function fileExists($path) { - return ($this->zip->locateName($path)!==false) or ($this->zip->locateName($path.'/')!==false); - } - /** - * remove a file or folder from the archive - * @param string $path - * @return bool - */ - function remove($path) { - if($this->fileExists($path.'/')) { - return $this->zip->deleteName($path.'/'); - }else{ - return $this->zip->deleteName($path); - } - } - /** - * get a file handler - * @param string $path - * @param string $mode - * @return resource - */ - function getStream($path, $mode) { - if($mode=='r' or $mode=='rb') { - return $this->zip->getStream($path); - } else { - //since we can't directly get a writable stream, - //make a temp copy of the file and put it back - //in the archive when the stream is closed - if(strrpos($path, '.')!==false) { - $ext=substr($path, strrpos($path, '.')); - }else{ - $ext=''; - } - $tmpFile=OCP\Files::tmpFile($ext); - \OC\Files\Stream\Close::registerCallback($tmpFile, array($this, 'writeBack')); - if($this->fileExists($path)) { - $this->extractFile($path, $tmpFile); - } - self::$tempFiles[$tmpFile]=$path; - return fopen('close://'.$tmpFile, $mode); - } - } - - private static $tempFiles=array(); - /** - * write back temporary files - */ - function writeBack($tmpFile) { - if(isset(self::$tempFiles[$tmpFile])) { - $this->addFile(self::$tempFiles[$tmpFile], $tmpFile); - unlink($tmpFile); - } - } - - /** - * @param string $path - * @return string - */ - private function stripPath($path) { - if(!$path || $path[0]=='/') { - return substr($path, 1); - }else{ - return $path; - } - } -} diff --git a/lib/private/legacy/archive.php b/lib/private/legacy/archive.php index 62512d1448a..aebc586d721 100644 --- a/lib/private/legacy/archive.php +++ b/lib/private/legacy/archive.php @@ -28,6 +28,9 @@ * */ +use OC\Archive\TAR; +use OC\Archive\ZIP; + abstract class OC_Archive{ /** * Open any of the supported archive types @@ -40,11 +43,11 @@ abstract class OC_Archive{ switch($mime) { case 'application/zip': - return new OC_Archive_ZIP($path); + return new ZIP($path); case 'application/x-gzip': - return new OC_Archive_TAR($path); + return new TAR($path); case 'application/x-bzip2': - return new OC_Archive_TAR($path); + return new TAR($path); } } -- cgit v1.2.3