diff options
author | Vincent Petry <pvince81@owncloud.com> | 2015-07-03 17:53:47 +0200 |
---|---|---|
committer | Vincent Petry <pvince81@owncloud.com> | 2015-07-03 17:53:47 +0200 |
commit | 3df27a01bea923237cfa9db0c2238e0fb022c06b (patch) | |
tree | d74365919a468ceb02bc16554012f20f5580cf97 /lib | |
parent | 7b9daf84eeef8e1d38a45f0a7595d062c9ce1dbe (diff) | |
parent | f55aa856ad74d1bbad61980aee3c00b971c8669c (diff) | |
download | nextcloud-server-3df27a01bea923237cfa9db0c2238e0fb022c06b.tar.gz nextcloud-server-3df27a01bea923237cfa9db0c2238e0fb022c06b.zip |
Merge pull request #17379 from owncloud/kill-file-mapper
Remove file mapper - was only use in Windows and never worked properly
Diffstat (limited to 'lib')
-rw-r--r-- | lib/private/files/mapper.php | 305 | ||||
-rw-r--r-- | lib/private/files/storage/local.php | 571 | ||||
-rw-r--r-- | lib/private/files/storage/mappedlocal.php | 456 |
3 files changed, 282 insertions, 1050 deletions
diff --git a/lib/private/files/mapper.php b/lib/private/files/mapper.php deleted file mode 100644 index 2c8760ba40e..00000000000 --- a/lib/private/files/mapper.php +++ /dev/null @@ -1,305 +0,0 @@ -<?php -/** - * @author infoneo <infoneo@yahoo.pl> - * @author Joas Schilling <nickvergessen@owncloud.com> - * @author Jörn Friedrich Dreyer <jfd@butonic.de> - * @author Lukas Reschke <lukas@owncloud.com> - * @author Robin McCorkell <rmccorkell@karoshi.org.uk> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @copyright Copyright (c) 2015, 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 <http://www.gnu.org/licenses/> - * - */ -namespace OC\Files; - -/** - * class Mapper is responsible to translate logical paths to physical paths and reverse - */ -class Mapper -{ - private $unchangedPhysicalRoot; - - public function __construct($rootDir) { - $this->unchangedPhysicalRoot = $rootDir; - } - - /** - * @param string $logicPath - * @param bool $create indicates if the generated physical name shall be stored in the database or not - * @return string the physical path - */ - public function logicToPhysical($logicPath, $create) { - $physicalPath = $this->resolveLogicPath($logicPath); - if ($physicalPath !== null) { - return $physicalPath; - } - - return $this->create($logicPath, $create); - } - - /** - * @param string $physicalPath - * @return string - */ - public function physicalToLogic($physicalPath) { - $logicPath = $this->resolvePhysicalPath($physicalPath); - if ($logicPath !== null) { - return $logicPath; - } - - $this->insert($physicalPath, $physicalPath); - return $physicalPath; - } - - /** - * @param string $path - * @param bool $isLogicPath indicates if $path is logical or physical - * @param boolean $recursive - * @return void - */ - public function removePath($path, $isLogicPath, $recursive) { - if ($recursive) { - $path=$path.'%'; - } - - if ($isLogicPath) { - \OC_DB::executeAudited('DELETE FROM `*PREFIX*file_map` WHERE `logic_path` LIKE ?', array($path)); - } else { - \OC_DB::executeAudited('DELETE FROM `*PREFIX*file_map` WHERE `physic_path` LIKE ?', array($path)); - } - } - - /** - * @param string $path1 - * @param string $path2 - * @throws \Exception - */ - public function copy($path1, $path2) - { - $path1 = $this->resolveRelativePath($path1); - $path2 = $this->resolveRelativePath($path2); - $physicPath1 = $this->logicToPhysical($path1, true); - $physicPath2 = $this->logicToPhysical($path2, true); - - $sql = 'SELECT * FROM `*PREFIX*file_map` WHERE `logic_path` LIKE ?'; - $result = \OC_DB::executeAudited($sql, array($path1.'%')); - $updateQuery = \OC_DB::prepare('UPDATE `*PREFIX*file_map`' - .' SET `logic_path` = ?' - .' , `logic_path_hash` = ?' - .' , `physic_path` = ?' - .' , `physic_path_hash` = ?' - .' WHERE `logic_path` = ?'); - while( $row = $result->fetchRow()) { - $currentLogic = $row['logic_path']; - $currentPhysic = $row['physic_path']; - $newLogic = $path2.$this->stripRootFolder($currentLogic, $path1); - $newPhysic = $physicPath2.$this->stripRootFolder($currentPhysic, $physicPath1); - if ($path1 !== $currentLogic) { - try { - \OC_DB::executeAudited($updateQuery, array($newLogic, md5($newLogic), $newPhysic, md5($newPhysic), - $currentLogic)); - } catch (\Exception $e) { - error_log('Mapper::Copy failed '.$currentLogic.' -> '.$newLogic.'\n'.$e); - throw $e; - } - } - } - } - - /** - * @param string $path - * @param string $root - * @return false|string - */ - public function stripRootFolder($path, $root) { - if (strpos($path, $root) !== 0) { - // throw exception ??? - return false; - } - if (strlen($path) > strlen($root)) { - return substr($path, strlen($root)); - } - - return ''; - } - - /** - * @param string $logicPath - * @return null - * @throws \OC\DatabaseException - */ - private function resolveLogicPath($logicPath) { - $logicPath = $this->resolveRelativePath($logicPath); - $sql = 'SELECT * FROM `*PREFIX*file_map` WHERE `logic_path_hash` = ?'; - $result = \OC_DB::executeAudited($sql, array(md5($logicPath))); - $result = $result->fetchRow(); - if ($result === false) { - return null; - } - - return $result['physic_path']; - } - - private function resolvePhysicalPath($physicalPath) { - $physicalPath = $this->resolveRelativePath($physicalPath); - $sql = \OC_DB::prepare('SELECT * FROM `*PREFIX*file_map` WHERE `physic_path_hash` = ?'); - $result = \OC_DB::executeAudited($sql, array(md5($physicalPath))); - $result = $result->fetchRow(); - - return $result['logic_path']; - } - - private function resolveRelativePath($path) { - $explodedPath = explode('/', $path); - $pathArray = array(); - foreach ($explodedPath as $pathElement) { - if (empty($pathElement) || ($pathElement == '.')) { - continue; - } elseif ($pathElement == '..') { - if (count($pathArray) == 0) { - return false; - } - array_pop($pathArray); - } else { - array_push($pathArray, $pathElement); - } - } - if (substr($path, 0, 1) == '/') { - $path = '/'; - } else { - $path = ''; - } - return $path.implode('/', $pathArray); - } - - /** - * @param string $logicPath - * @param bool $store - * @return string - */ - private function create($logicPath, $store) { - $logicPath = $this->resolveRelativePath($logicPath); - $index = 0; - - // create the slugified path - $physicalPath = $this->slugifyPath($logicPath); - - // detect duplicates - while ($this->resolvePhysicalPath($physicalPath) !== null) { - $physicalPath = $this->slugifyPath($logicPath, $index++); - } - - // insert the new path mapping if requested - if ($store) { - $this->insert($logicPath, $physicalPath); - } - - return $physicalPath; - } - - private function insert($logicPath, $physicalPath) { - $sql = 'INSERT INTO `*PREFIX*file_map` (`logic_path`, `physic_path`, `logic_path_hash`, `physic_path_hash`) - VALUES (?, ?, ?, ?)'; - \OC_DB::executeAudited($sql, array($logicPath, $physicalPath, md5($logicPath), md5($physicalPath))); - } - - /** - * @param string $path - * @param int $index - * @return string - */ - public function slugifyPath($path, $index = null) { - $path = $this->stripRootFolder($path, $this->unchangedPhysicalRoot); - - $pathElements = explode('/', $path); - $sluggedElements = array(); - - foreach ($pathElements as $pathElement) { - // remove empty elements - if (empty($pathElement)) { - continue; - } - - $sluggedElements[] = $this->slugify($pathElement); - } - - // apply index to file name - if ($index !== null) { - $last = array_pop($sluggedElements); - - // if filename contains periods - add index number before last period - if (preg_match('~\.[^\.]+$~i', $last, $extension)) { - array_push($sluggedElements, substr($last, 0, -(strlen($extension[0]))) . '-' . $index . $extension[0]); - } else { - // if filename doesn't contain periods add index ofter the last char - array_push($sluggedElements, $last . '-' . $index); - } - } - - $sluggedPath = $this->unchangedPhysicalRoot.implode('/', $sluggedElements); - return $this->resolveRelativePath($sluggedPath); - } - - /** - * Modifies a string to remove all non ASCII characters and spaces. - * - * @param string $text - * @return string - */ - private function slugify($text) { - $originalText = $text; - // replace non letter or digits or dots by - - $text = preg_replace('~[^\\pL\d\.]+~u', '-', $text); - - // trim - $text = trim($text, '-'); - - // transliterate - if (function_exists('iconv')) { - $text = iconv('utf-8', 'us-ascii//TRANSLIT//IGNORE', $text); - } - - // lowercase - $text = strtolower($text); - - // remove unwanted characters - $text = preg_replace('~[^-\w\.]+~', '', $text); - - // trim ending dots (for security reasons and win compatibility) - $text = preg_replace('~\.+$~', '', $text); - - if (empty($text) || \OC\Files\Filesystem::isFileBlacklisted($text)) { - /** - * Item slug would be empty. Previously we used uniqid() here. - * However this means that the behaviour is not reproducible, so - * when uploading files into a "empty" folder, the folders name is - * different. - * - * The other case is, that the slugified name would be a blacklisted - * filename. In this case we just use the same workaround by - * returning the secure md5 hash of the original name. - * - * - * If there would be a md5() hash collision, the deduplicate check - * will spot this and append an index later, so this should not be - * a problem. - */ - return md5($originalText); - } - - return $text; - } -} diff --git a/lib/private/files/storage/local.php b/lib/private/files/storage/local.php index 53465f8585e..839fb81d5a0 100644 --- a/lib/private/files/storage/local.php +++ b/lib/private/files/storage/local.php @@ -36,361 +36,354 @@ namespace OC\Files\Storage; -if (\OC_Util::runningOnWindows()) { - class Local extends MappedLocal { - - } -} else { - - /** - * for local filestore, we only have to map the paths - */ - class Local extends \OC\Files\Storage\Common { - protected $datadir; +/** + * for local filestore, we only have to map the paths + */ +class Local extends \OC\Files\Storage\Common { + protected $datadir; - public function __construct($arguments) { - $this->datadir = $arguments['datadir']; - if (substr($this->datadir, -1) !== '/') { - $this->datadir .= '/'; - } + public function __construct($arguments) { + $this->datadir = $arguments['datadir']; + if (substr($this->datadir, -1) !== '/') { + $this->datadir .= '/'; } + } - public function __destruct() { - } + public function __destruct() { + } - public function getId() { - return 'local::' . $this->datadir; - } + public function getId() { + return 'local::' . $this->datadir; + } - public function mkdir($path) { - return @mkdir($this->getSourcePath($path), 0777, true); - } + public function mkdir($path) { + return @mkdir($this->getSourcePath($path), 0777, true); + } - public function rmdir($path) { - if (!$this->isDeletable($path)) { - return false; - } - try { - $it = new \RecursiveIteratorIterator( - new \RecursiveDirectoryIterator($this->getSourcePath($path)), - \RecursiveIteratorIterator::CHILD_FIRST - ); + public function rmdir($path) { + if (!$this->isDeletable($path)) { + return false; + } + try { + $it = new \RecursiveIteratorIterator( + new \RecursiveDirectoryIterator($this->getSourcePath($path)), + \RecursiveIteratorIterator::CHILD_FIRST + ); + /** + * RecursiveDirectoryIterator on an NFS path isn't iterable with foreach + * This bug is fixed in PHP 5.5.9 or before + * See #8376 + */ + $it->rewind(); + while ($it->valid()) { /** - * RecursiveDirectoryIterator on an NFS path isn't iterable with foreach - * This bug is fixed in PHP 5.5.9 or before - * See #8376 + * @var \SplFileInfo $file */ - $it->rewind(); - while ($it->valid()) { - /** - * @var \SplFileInfo $file - */ - $file = $it->current(); - if (in_array($file->getBasename(), array('.', '..'))) { - $it->next(); - continue; - } elseif ($file->isDir()) { - rmdir($file->getPathname()); - } elseif ($file->isFile() || $file->isLink()) { - unlink($file->getPathname()); - } + $file = $it->current(); + if (in_array($file->getBasename(), array('.', '..'))) { $it->next(); + continue; + } elseif ($file->isDir()) { + rmdir($file->getPathname()); + } elseif ($file->isFile() || $file->isLink()) { + unlink($file->getPathname()); } - return rmdir($this->getSourcePath($path)); - } catch (\UnexpectedValueException $e) { - return false; + $it->next(); } + return rmdir($this->getSourcePath($path)); + } catch (\UnexpectedValueException $e) { + return false; } + } - public function opendir($path) { - return opendir($this->getSourcePath($path)); - } - - public function is_dir($path) { - if (substr($path, -1) == '/') { - $path = substr($path, 0, -1); - } - return is_dir($this->getSourcePath($path)); - } + public function opendir($path) { + return opendir($this->getSourcePath($path)); + } - public function is_file($path) { - return is_file($this->getSourcePath($path)); + public function is_dir($path) { + if (substr($path, -1) == '/') { + $path = substr($path, 0, -1); } + return is_dir($this->getSourcePath($path)); + } - public function stat($path) { - clearstatcache(); - $fullPath = $this->getSourcePath($path); - $statResult = stat($fullPath); - if (PHP_INT_SIZE === 4 && !$this->is_dir($path)) { - $filesize = $this->filesize($path); - $statResult['size'] = $filesize; - $statResult[7] = $filesize; - } - return $statResult; - } + public function is_file($path) { + return is_file($this->getSourcePath($path)); + } - public function filetype($path) { - $filetype = filetype($this->getSourcePath($path)); - if ($filetype == 'link') { - $filetype = filetype(realpath($this->getSourcePath($path))); - } - return $filetype; + public function stat($path) { + clearstatcache(); + $fullPath = $this->getSourcePath($path); + $statResult = stat($fullPath); + if (PHP_INT_SIZE === 4 && !$this->is_dir($path)) { + $filesize = $this->filesize($path); + $statResult['size'] = $filesize; + $statResult[7] = $filesize; } + return $statResult; + } - public function filesize($path) { - if ($this->is_dir($path)) { - return 0; - } - $fullPath = $this->getSourcePath($path); - if (PHP_INT_SIZE === 4) { - $helper = new \OC\LargeFileHelper; - return $helper->getFilesize($fullPath); - } - return filesize($fullPath); + public function filetype($path) { + $filetype = filetype($this->getSourcePath($path)); + if ($filetype == 'link') { + $filetype = filetype(realpath($this->getSourcePath($path))); } + return $filetype; + } - public function isReadable($path) { - return is_readable($this->getSourcePath($path)); + public function filesize($path) { + if ($this->is_dir($path)) { + return 0; } - - public function isUpdatable($path) { - return is_writable($this->getSourcePath($path)); + $fullPath = $this->getSourcePath($path); + if (PHP_INT_SIZE === 4) { + $helper = new \OC\LargeFileHelper; + return $helper->getFilesize($fullPath); } + return filesize($fullPath); + } - public function file_exists($path) { - return file_exists($this->getSourcePath($path)); - } + public function isReadable($path) { + return is_readable($this->getSourcePath($path)); + } - public function filemtime($path) { - clearstatcache($this->getSourcePath($path)); - return filemtime($this->getSourcePath($path)); - } + public function isUpdatable($path) { + return is_writable($this->getSourcePath($path)); + } - public function touch($path, $mtime = null) { - // sets the modification time of the file to the given value. - // If mtime is nil the current time is set. - // note that the access time of the file always changes to the current time. - if ($this->file_exists($path) and !$this->isUpdatable($path)) { - return false; - } - if (!is_null($mtime)) { - $result = touch($this->getSourcePath($path), $mtime); - } else { - $result = touch($this->getSourcePath($path)); - } - if ($result) { - clearstatcache(true, $this->getSourcePath($path)); - } + public function file_exists($path) { + return file_exists($this->getSourcePath($path)); + } - return $result; - } + public function filemtime($path) { + clearstatcache($this->getSourcePath($path)); + return filemtime($this->getSourcePath($path)); + } - public function file_get_contents($path) { - return file_get_contents($this->getSourcePath($path)); + public function touch($path, $mtime = null) { + // sets the modification time of the file to the given value. + // If mtime is nil the current time is set. + // note that the access time of the file always changes to the current time. + if ($this->file_exists($path) and !$this->isUpdatable($path)) { + return false; } - - public function file_put_contents($path, $data) { - return file_put_contents($this->getSourcePath($path), $data); + if (!is_null($mtime)) { + $result = touch($this->getSourcePath($path), $mtime); + } else { + $result = touch($this->getSourcePath($path)); } - - public function unlink($path) { - if ($this->is_dir($path)) { - return $this->rmdir($path); - } else if ($this->is_file($path)) { - return unlink($this->getSourcePath($path)); - } else { - return false; - } - + if ($result) { + clearstatcache(true, $this->getSourcePath($path)); } - public function rename($path1, $path2) { - $srcParent = dirname($path1); - $dstParent = dirname($path2); + return $result; + } - if (!$this->isUpdatable($srcParent)) { - \OC_Log::write('core', 'unable to rename, source directory is not writable : ' . $srcParent, \OC_Log::ERROR); - return false; - } + public function file_get_contents($path) { + return file_get_contents($this->getSourcePath($path)); + } - if (!$this->isUpdatable($dstParent)) { - \OC_Log::write('core', 'unable to rename, destination directory is not writable : ' . $dstParent, \OC_Log::ERROR); - return false; - } + public function file_put_contents($path, $data) { + return file_put_contents($this->getSourcePath($path), $data); + } - if (!$this->file_exists($path1)) { - \OC_Log::write('core', 'unable to rename, file does not exists : ' . $path1, \OC_Log::ERROR); - return false; - } + public function unlink($path) { + if ($this->is_dir($path)) { + return $this->rmdir($path); + } else if ($this->is_file($path)) { + return unlink($this->getSourcePath($path)); + } else { + return false; + } - if ($this->is_dir($path2)) { - $this->rmdir($path2); - } else if ($this->is_file($path2)) { - $this->unlink($path2); - } + } - if ($this->is_dir($path1)) { - // we cant move folders across devices, use copy instead - $stat1 = stat(dirname($this->getSourcePath($path1))); - $stat2 = stat(dirname($this->getSourcePath($path2))); - if ($stat1['dev'] !== $stat2['dev']) { - $result = $this->copy($path1, $path2); - if ($result) { - $result &= $this->rmdir($path1); - } - return $result; - } - } + public function rename($path1, $path2) { + $srcParent = dirname($path1); + $dstParent = dirname($path2); - return rename($this->getSourcePath($path1), $this->getSourcePath($path2)); + if (!$this->isUpdatable($srcParent)) { + \OC_Log::write('core', 'unable to rename, source directory is not writable : ' . $srcParent, \OC_Log::ERROR); + return false; } - public function copy($path1, $path2) { - if ($this->is_dir($path1)) { - return parent::copy($path1, $path2); - } else { - return copy($this->getSourcePath($path1), $this->getSourcePath($path2)); - } + if (!$this->isUpdatable($dstParent)) { + \OC_Log::write('core', 'unable to rename, destination directory is not writable : ' . $dstParent, \OC_Log::ERROR); + return false; } - public function fopen($path, $mode) { - return fopen($this->getSourcePath($path), $mode); + if (!$this->file_exists($path1)) { + \OC_Log::write('core', 'unable to rename, file does not exists : ' . $path1, \OC_Log::ERROR); + return false; } - public function hash($type, $path, $raw = false) { - return hash_file($type, $this->getSourcePath($path), $raw); + if ($this->is_dir($path2)) { + $this->rmdir($path2); + } else if ($this->is_file($path2)) { + $this->unlink($path2); } - public function free_space($path) { - $space = @disk_free_space($this->getSourcePath($path)); - if ($space === false || is_null($space)) { - return \OCP\Files\FileInfo::SPACE_UNKNOWN; + if ($this->is_dir($path1)) { + // we cant move folders across devices, use copy instead + $stat1 = stat(dirname($this->getSourcePath($path1))); + $stat2 = stat(dirname($this->getSourcePath($path2))); + if ($stat1['dev'] !== $stat2['dev']) { + $result = $this->copy($path1, $path2); + if ($result) { + $result &= $this->rmdir($path1); + } + return $result; } - return $space; } - public function search($query) { - return $this->searchInDir($query); - } + return rename($this->getSourcePath($path1), $this->getSourcePath($path2)); + } - public function getLocalFile($path) { - return $this->getSourcePath($path); + public function copy($path1, $path2) { + if ($this->is_dir($path1)) { + return parent::copy($path1, $path2); + } else { + return copy($this->getSourcePath($path1), $this->getSourcePath($path2)); } + } - public function getLocalFolder($path) { - return $this->getSourcePath($path); - } + public function fopen($path, $mode) { + return fopen($this->getSourcePath($path), $mode); + } - /** - * @param string $query - * @param string $dir - * @return array - */ - protected function searchInDir($query, $dir = '') { - $files = array(); - $physicalDir = $this->getSourcePath($dir); - foreach (scandir($physicalDir) as $item) { - if ($item == '.' || $item == '..') - continue; - $physicalItem = $physicalDir . '/' . $item; + public function hash($type, $path, $raw = false) { + return hash_file($type, $this->getSourcePath($path), $raw); + } - if (strstr(strtolower($item), strtolower($query)) !== false) { - $files[] = $dir . '/' . $item; - } - if (is_dir($physicalItem)) { - $files = array_merge($files, $this->searchInDir($query, $dir . '/' . $item)); - } - } - return $files; + public function free_space($path) { + $space = @disk_free_space($this->getSourcePath($path)); + if ($space === false || is_null($space)) { + return \OCP\Files\FileInfo::SPACE_UNKNOWN; } + return $space; + } - /** - * check if a file or folder has been updated since $time - * - * @param string $path - * @param int $time - * @return bool - */ - public function hasUpdated($path, $time) { - if ($this->file_exists($path)) { - return $this->filemtime($path) > $time; - } else { - return true; - } - } + public function search($query) { + return $this->searchInDir($query); + } + + public function getLocalFile($path) { + return $this->getSourcePath($path); + } + + public function getLocalFolder($path) { + return $this->getSourcePath($path); + } - /** - * Get the source path (on disk) of a given path - * - * @param string $path - * @return string - */ - public function getSourcePath($path) { - $fullPath = $this->datadir . $path; - return $fullPath; + /** + * @param string $query + * @param string $dir + * @return array + */ + protected function searchInDir($query, $dir = '') { + $files = array(); + $physicalDir = $this->getSourcePath($dir); + foreach (scandir($physicalDir) as $item) { + if ($item == '.' || $item == '..') + continue; + $physicalItem = $physicalDir . '/' . $item; + + if (strstr(strtolower($item), strtolower($query)) !== false) { + $files[] = $dir . '/' . $item; + } + if (is_dir($physicalItem)) { + $files = array_merge($files, $this->searchInDir($query, $dir . '/' . $item)); + } } + return $files; + } - /** - * {@inheritdoc} - */ - public function isLocal() { + /** + * check if a file or folder has been updated since $time + * + * @param string $path + * @param int $time + * @return bool + */ + public function hasUpdated($path, $time) { + if ($this->file_exists($path)) { + return $this->filemtime($path) > $time; + } else { return true; } + } - /** - * get the ETag for a file or folder - * - * @param string $path - * @return string - */ - public function getETag($path) { - if ($this->is_file($path)) { - $stat = $this->stat($path); - return md5( - $stat['mtime'] . - $stat['ino'] . - $stat['dev'] . - $stat['size'] - ); - } else { - return parent::getETag($path); - } + /** + * Get the source path (on disk) of a given path + * + * @param string $path + * @return string + */ + public function getSourcePath($path) { + $fullPath = $this->datadir . $path; + return $fullPath; + } + + /** + * {@inheritdoc} + */ + public function isLocal() { + return true; + } + + /** + * get the ETag for a file or folder + * + * @param string $path + * @return string + */ + public function getETag($path) { + if ($this->is_file($path)) { + $stat = $this->stat($path); + return md5( + $stat['mtime'] . + $stat['ino'] . + $stat['dev'] . + $stat['size'] + ); + } else { + return parent::getETag($path); } + } - /** - * @param \OCP\Files\Storage $sourceStorage - * @param string $sourceInternalPath - * @param string $targetInternalPath - * @return bool - */ - public function copyFromStorage(\OCP\Files\Storage $sourceStorage, $sourceInternalPath, $targetInternalPath) { - if($sourceStorage->instanceOfStorage('\OC\Files\Storage\Local')){ - /** - * @var \OC\Files\Storage\Local $sourceStorage - */ - $rootStorage = new Local(['datadir' => '/']); - return $rootStorage->copy($sourceStorage->getSourcePath($sourceInternalPath), $this->getSourcePath($targetInternalPath)); - } else { - return parent::copyFromStorage($sourceStorage, $sourceInternalPath, $targetInternalPath); - } + /** + * @param \OCP\Files\Storage $sourceStorage + * @param string $sourceInternalPath + * @param string $targetInternalPath + * @return bool + */ + public function copyFromStorage(\OCP\Files\Storage $sourceStorage, $sourceInternalPath, $targetInternalPath) { + if($sourceStorage->instanceOfStorage('\OC\Files\Storage\Local')){ + /** + * @var \OC\Files\Storage\Local $sourceStorage + */ + $rootStorage = new Local(['datadir' => '/']); + return $rootStorage->copy($sourceStorage->getSourcePath($sourceInternalPath), $this->getSourcePath($targetInternalPath)); + } else { + return parent::copyFromStorage($sourceStorage, $sourceInternalPath, $targetInternalPath); } + } - /** - * @param \OCP\Files\Storage $sourceStorage - * @param string $sourceInternalPath - * @param string $targetInternalPath - * @return bool - */ - public function moveFromStorage(\OCP\Files\Storage $sourceStorage, $sourceInternalPath, $targetInternalPath) { - if ($sourceStorage->instanceOfStorage('\OC\Files\Storage\Local')) { - /** - * @var \OC\Files\Storage\Local $sourceStorage - */ - $rootStorage = new Local(['datadir' => '/']); - return $rootStorage->rename($sourceStorage->getSourcePath($sourceInternalPath), $this->getSourcePath($targetInternalPath)); - } else { - return parent::moveFromStorage($sourceStorage, $sourceInternalPath, $targetInternalPath); - } + /** + * @param \OCP\Files\Storage $sourceStorage + * @param string $sourceInternalPath + * @param string $targetInternalPath + * @return bool + */ + public function moveFromStorage(\OCP\Files\Storage $sourceStorage, $sourceInternalPath, $targetInternalPath) { + if ($sourceStorage->instanceOfStorage('\OC\Files\Storage\Local')) { + /** + * @var \OC\Files\Storage\Local $sourceStorage + */ + $rootStorage = new Local(['datadir' => '/']); + return $rootStorage->rename($sourceStorage->getSourcePath($sourceInternalPath), $this->getSourcePath($targetInternalPath)); + } else { + return parent::moveFromStorage($sourceStorage, $sourceInternalPath, $targetInternalPath); } } } diff --git a/lib/private/files/storage/mappedlocal.php b/lib/private/files/storage/mappedlocal.php deleted file mode 100644 index 932320267e4..00000000000 --- a/lib/private/files/storage/mappedlocal.php +++ /dev/null @@ -1,456 +0,0 @@ -<?php -/** - * @author Andreas Fischer <bantu@owncloud.com> - * @author Arthur Schiwon <blizzz@owncloud.com> - * @author Bart Visscher <bartv@thisnet.nl> - * @author Clark Tomlinson <fallen013@gmail.com> - * @author Joas Schilling <nickvergessen@owncloud.com> - * @author Jörn Friedrich Dreyer <jfd@butonic.de> - * @author Lukas Reschke <lukas@owncloud.com> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Robin Appelman <icewind@owncloud.com> - * @author Scrutinizer Auto-Fixer <auto-fixer@scrutinizer-ci.com> - * @author Sjors van der Pluijm <sjors@desjors.nl> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * @author Tigran Mkrtchyan <tigran.mkrtchyan@desy.de> - * - * @copyright Copyright (c) 2015, 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 <http://www.gnu.org/licenses/> - * - */ -namespace OC\Files\Storage; - -/** - * for local filestore, we only have to map the paths - */ -class MappedLocal extends \OC\Files\Storage\Common { - protected $datadir; - private $mapper; - - public function __construct($arguments) { - $this->datadir = $arguments['datadir']; - if (substr($this->datadir, -1) !== '/') { - $this->datadir .= '/'; - } - - $this->mapper = new \OC\Files\Mapper($this->datadir); - } - - public function __destruct() { - } - - public function getId() { - return 'local::' . $this->datadir; - } - - public function mkdir($path) { - return @mkdir($this->getSourcePath($path), 0777, true); - } - - public function rmdir($path) { - if (!$this->isDeletable($path)) { - return false; - } - try { - $it = new \RecursiveIteratorIterator( - new \RecursiveDirectoryIterator($this->getSourcePath($path)), - \RecursiveIteratorIterator::CHILD_FIRST - ); - /** - * RecursiveDirectoryIterator on an NFS path isn't iterable with foreach - * This bug is fixed in PHP 5.5.9 or before - * See #8376 - */ - $it->rewind(); - while ($it->valid()) { - /** - * @var \SplFileInfo $file - */ - $file = $it->current(); - if (in_array($file->getBasename(), array('.', '..'))) { - $it->next(); - continue; - } elseif ($file->isDir()) { - rmdir($file->getPathname()); - } elseif ($file->isFile() || $file->isLink()) { - unlink($file->getPathname()); - } - $it->next(); - } - if ($result = @rmdir($this->getSourcePath($path))) { - $this->cleanMapper($path); - } - return $result; - } catch (\UnexpectedValueException $e) { - return false; - } - } - - public function opendir($path) { - $files = array('.', '..'); - $physicalPath = $this->getSourcePath($path); - - $logicalPath = $this->mapper->physicalToLogic($physicalPath); - $dh = opendir($physicalPath); - if (is_resource($dh)) { - while (($file = readdir($dh)) !== false) { - if ($file === '.' or $file === '..') { - continue; - } - - $logicalFilePath = $this->mapper->physicalToLogic($physicalPath . '/' . $file); - - $file = $this->mapper->stripRootFolder($logicalFilePath, $logicalPath); - $file = $this->stripLeading($file); - $files[] = $file; - } - } - - \OC\Files\Stream\Dir::register('local-win32' . $path, $files); - return opendir('fakedir://local-win32' . $path); - } - - public function is_dir($path) { - if (substr($path, -1) == '/') { - $path = substr($path, 0, -1); - } - return is_dir($this->getSourcePath($path)); - } - - public function is_file($path) { - return is_file($this->getSourcePath($path)); - } - - public function stat($path) { - clearstatcache(); - $fullPath = $this->getSourcePath($path); - $statResult = stat($fullPath); - if (PHP_INT_SIZE === 4 && !$this->is_dir($path)) { - $filesize = $this->filesize($path); - $statResult['size'] = $filesize; - $statResult[7] = $filesize; - } - return $statResult; - } - - public function filetype($path) { - $filetype = filetype($this->getSourcePath($path)); - if ($filetype == 'link') { - $filetype = filetype(realpath($this->getSourcePath($path))); - } - return $filetype; - } - - public function filesize($path) { - if ($this->is_dir($path)) { - return 0; - } - $fullPath = $this->getSourcePath($path); - if (PHP_INT_SIZE === 4) { - $helper = new \OC\LargeFileHelper; - return $helper->getFilesize($fullPath); - } - return filesize($fullPath); - } - - public function isReadable($path) { - return is_readable($this->getSourcePath($path)); - } - - public function isUpdatable($path) { - return is_writable($this->getSourcePath($path)); - } - - public function file_exists($path) { - return file_exists($this->getSourcePath($path)); - } - - public function filemtime($path) { - clearstatcache($this->getSourcePath($path)); - return filemtime($this->getSourcePath($path)); - } - - public function touch($path, $mtime = null) { - // sets the modification time of the file to the given value. - // If mtime is nil the current time is set. - // note that the access time of the file always changes to the current time. - if ($this->file_exists($path) and !$this->isUpdatable($path)) { - return false; - } - if (!is_null($mtime)) { - $result = touch($this->getSourcePath($path), $mtime); - } else { - $result = touch($this->getSourcePath($path)); - } - if ($result) { - clearstatcache(true, $this->getSourcePath($path)); - } - - return $result; - } - - public function file_get_contents($path) { - return file_get_contents($this->getSourcePath($path)); - } - - public function file_put_contents($path, $data) { - return file_put_contents($this->getSourcePath($path), $data); - } - - public function unlink($path) { - return $this->delTree($path); - } - - public function rename($path1, $path2) { - $srcParent = $this->dirname($path1); - $dstParent = $this->dirname($path2); - - if (!$this->isUpdatable($srcParent)) { - \OC_Log::write('core', 'unable to rename, source directory is not writable : ' . $srcParent, \OC_Log::ERROR); - return false; - } - - if (!$this->isUpdatable($dstParent)) { - \OC_Log::write('core', 'unable to rename, destination directory is not writable : ' . $dstParent, \OC_Log::ERROR); - return false; - } - - if (!$this->file_exists($path1)) { - \OC_Log::write('core', 'unable to rename, file does not exists : ' . $path1, \OC_Log::ERROR); - return false; - } - - if ($this->is_dir($path2)) { - $this->rmdir($path2); - } else if ($this->is_file($path2)) { - $this->unlink($path2); - } - - $physicPath1 = $this->getSourcePath($path1); - $physicPath2 = $this->getSourcePath($path2); - if ($return = rename($physicPath1, $physicPath2)) { - // mapper needs to create copies or all children - $this->copyMapping($path1, $path2); - $this->cleanMapper($physicPath1, false, true); - } - return $return; - } - - public function copy($path1, $path2) { - if ($this->is_dir($path1)) { - if ($this->is_dir($path2)) { - $this->rmdir($path2); - } else if ($this->is_file($path2)) { - $this->unlink($path2); - } - $dir = $this->opendir($path1); - $this->mkdir($path2); - while ($file = readdir($dir)) { - if (!\OC\Files\Filesystem::isIgnoredDir($file)) { - if (!$this->copy($path1 . '/' . $file, $path2 . '/' . $file)) { - return false; - } - } - } - closedir($dir); - return true; - } else { - if ($return = copy($this->getSourcePath($path1), $this->getSourcePath($path2))) { - $this->copyMapping($path1, $path2); - } - return $return; - } - } - - public function fopen($path, $mode) { - return fopen($this->getSourcePath($path), $mode); - } - - /** - * @param string $dir - * @param bool $isLogicPath - * @return bool - */ - private function delTree($dir, $isLogicPath = true) { - $dirRelative = $dir; - if ($isLogicPath) { - $dir = $this->getSourcePath($dir); - } - if (!file_exists($dir)) { - return true; - } - if (!is_dir($dir) || is_link($dir)) { - if ($return = unlink($dir)) { - $this->cleanMapper($dir, false); - return $return; - } - } - foreach (scandir($dir) as $item) { - if ($item == '.' || $item == '..') { - continue; - } - if (is_file($dir . '/' . $item)) { - if (unlink($dir . '/' . $item)) { - $this->cleanMapper($dir . '/' . $item, false); - } - } elseif (is_dir($dir . '/' . $item)) { - if (!$this->delTree($dir . "/" . $item, false)) { - return false; - }; - } - } - if ($return = rmdir($dir)) { - $this->cleanMapper($dir, false); - } - return $return; - } - - public function hash($type, $path, $raw = false) { - return hash_file($type, $this->getSourcePath($path), $raw); - } - - public function free_space($path) { - $space = @disk_free_space($this->getSourcePath($path)); - if ($space === false || is_null($space)) { - return \OCP\Files\FileInfo::SPACE_UNKNOWN; - } - return $space; - } - - public function search($query) { - return $this->searchInDir($query); - } - - public function getLocalFile($path) { - return $this->getSourcePath($path); - } - - public function getLocalFolder($path) { - return $this->getSourcePath($path); - } - - /** - * @param string $query - * @param string $dir - * @return array - */ - protected function searchInDir($query, $dir = '') { - $files = array(); - $physicalDir = $this->getSourcePath($dir); - foreach (scandir($physicalDir) as $item) { - if ($item == '.' || $item == '..') - continue; - $physicalItem = $this->mapper->physicalToLogic($physicalDir . '/' . $item); - $item = substr($physicalItem, strlen($physicalDir) + 1); - - if (strstr(strtolower($item), strtolower($query)) !== false) { - $files[] = $dir . '/' . $item; - } - if (is_dir($physicalItem)) { - $files = array_merge($files, $this->searchInDir($query, $dir . '/' . $item)); - } - } - return $files; - } - - /** - * check if a file or folder has been updated since $time - * - * @param string $path - * @param int $time - * @return bool - */ - public function hasUpdated($path, $time) { - if ($this->file_exists($path)) { - return $this->filemtime($path) > $time; - } else { - return true; - } - } - - /** - * Get the source path (on disk) of a given path - * - * @param string $path - * @return string - */ - protected function getSourcePath($path) { - $path = $this->stripLeading($path); - $fullPath = $this->datadir . $path; - return $this->mapper->logicToPhysical($fullPath, true); - } - - /** - * {@inheritdoc} - */ - public function isLocal() { - return true; - } - - /** - * @param string $path - * @return string - */ - private function dirName($path) { - $path = dirname($path); - if ($path === '.') { - return ''; - } else { - return $path; - } - } - - /** - * @param string $path - */ - private function cleanMapper($path, $isLogicPath = true, $recursive = true) { - $fullPath = $path; - if ($isLogicPath) { - $fullPath = $this->datadir . $path; - } - $this->mapper->removePath($fullPath, $isLogicPath, $recursive); - } - - /** - * @param string $path1 - * @param string $path2 - */ - private function copyMapping($path1, $path2) { - $path1 = $this->stripLeading($path1); - $path2 = $this->stripLeading($path2); - - $fullPath1 = $this->datadir . $path1; - $fullPath2 = $this->datadir . $path2; - - $this->mapper->copy($fullPath1, $fullPath2); - } - - /** - * @param string $path - */ - private function stripLeading($path) { - if (strpos($path, '/') === 0) { - $path = substr($path, 1); - } - if (strpos($path, '\\') === 0) { - $path = substr($path, 1); - } - if ($path === false) { - return ''; - } - - return $path; - } -} |