* This file is licensed under the Affero General Public License version 3 or * later. * See the COPYING-README file. */ 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; public function __construct($arguments) { $this->datadir = $arguments['datadir']; if (substr($this->datadir, -1) !== '/') { $this->datadir .= '/'; } } public function __destruct() { } public function getId() { return 'local::' . $this->datadir; } public function mkdir($path) { return @mkdir($this->datadir . $path, 0777, true); } public function rmdir($path) { try { $it = new \RecursiveIteratorIterator( new \RecursiveDirectoryIterator($this->datadir . $path), \RecursiveIteratorIterator::CHILD_FIRST ); foreach ($it as $file) { /** * @var \SplFileInfo $file */ if (in_array($file->getBasename(), array('.', '..'))) { continue; } elseif ($file->isDir()) { rmdir($file->getPathname()); } elseif ($file->isFile() || $file->isLink()) { unlink($file->getPathname()); } } return rmdir($this->datadir . $path); } catch (\UnexpectedValueException $e) { return false; } } public function opendir($path) { return opendir($this->datadir . $path); } public function is_dir($path) { if (substr($path, -1) == '/') { $path = substr($path, 0, -1); } return is_dir($this->datadir . $path); } public function is_file($path) { return is_file($this->datadir . $path); } public function stat($path) { $fullPath = $this->datadir . $path; $statResult = stat($fullPath); if ($statResult['size'] < 0) { $size = self::getFileSizeFromOS($fullPath); $statResult['size'] = $size; $statResult[7] = $size; } return $statResult; } public function filetype($path) { $filetype = filetype($this->datadir . $path); if ($filetype == 'link') { $filetype = filetype(realpath($this->datadir . $path)); } return $filetype; } public function filesize($path) { if ($this->is_dir($path)) { return 0; } else { $fullPath = $this->datadir . $path; $fileSize = filesize($fullPath); if ($fileSize < 0) { return self::getFileSizeFromOS($fullPath); } return $fileSize; } } public function isReadable($path) { return is_readable($this->datadir . $path); } public function isUpdatable($path) { return is_writable($this->datadir . $path); } public function file_exists($path) { return file_exists($this->datadir . $path); } public function filemtime($path) { return filemtime($this->datadir . $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->datadir . $path, $mtime); } else { $result = touch($this->datadir . $path); } if ($result) { clearstatcache(true, $this->datadir . $path); } return $result; } public function file_get_contents($path) { return file_get_contents($this->datadir . $path); } public function file_put_contents($path, $data) { //trigger_error("$path = ".var_export($path, 1)); return file_put_contents($this->datadir . $path, $data); } public function unlink($path) { return $this->delTree($path); } public function rename($path1, $path2) { if (!$this->isUpdatable($path1)) { \OC_Log::write('core', 'unable to rename, file is not writable : ' . $path1, \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 ($return = rename($this->datadir . $path1, $this->datadir . $path2)) { } return $return; } public function copy($path1, $path2) { if ($this->is_dir($path2)) { if (!$this->file_exists($path2)) { $this->mkdir($path2); } $source = substr($path1, strrpos($path1, '/') + 1); $path2 .= $source; } return copy($this->datadir . $path1, $this->datadir . $path2); } public function fopen($path, $mode) { if ($return = fopen($this->datadir . $path, $mode)) { switch ($mode) { case 'r': break; case 'r+': case 'w+': case 'x+': case 'a+': break; case 'w': case 'x': case 'a': break; } } return $return; } /** * @param string $dir */ private function delTree($dir) { $dirRelative = $dir; $dir = $this->datadir . $dir; if (!file_exists($dir)) return true; if (!is_dir($dir) || is_link($dir)) return unlink($dir); foreach (scandir($dir) as $item) { if ($item == '.' || $item == '..') continue; if (is_file($dir . '/' . $item)) { if (unlink($dir . '/' . $item)) { } } elseif (is_dir($dir . '/' . $item)) { if (!$this->delTree($dirRelative . "/" . $item)) { return false; }; } } if ($return = rmdir($dir)) { } return $return; } /** * @param string $fullPath */ private static function getFileSizeFromOS($fullPath) { $name = strtolower(php_uname('s')); // Windows OS: we use COM to access the filesystem if (strpos($name, 'win') !== false) { if (class_exists('COM')) { $fsobj = new \COM("Scripting.FileSystemObject"); $f = $fsobj->GetFile($fullPath); return $f->Size; } } else if (strpos($name, 'bsd') !== false) { if (\OC_Helper::is_function_enabled('exec')) { return (float)exec('stat -f %z ' . escapeshellarg($fullPath)); } } else if (strpos($name, 'linux') !== false) { if (\OC_Helper::is_function_enabled('exec')) { return (float)exec('stat -c %s ' . escapeshellarg($fullPath)); } } else { \OC_Log::write('core', 'Unable to determine file size of "' . $fullPath . '". Unknown OS: ' . $name, \OC_Log::ERROR); } return 0; } public function hash($type, $path, $raw = false) { return hash_file($type, $this->datadir . $path, $raw); } public function free_space($path) { $space = @disk_free_space($this->datadir . $path); if ($space === false || is_null($space)) { return \OC\Files\SPACE_UNKNOWN; } return $space; } public function search($query) { return $this->searchInDir($query); } public function getLocalFile($path) { return $this->datadir . $path; } public function getLocalFolder($path) { return $this->datadir . $path; } /** * @param string $query */ protected function searchInDir($query, $dir = '') { $files = array(); foreach (scandir($this->datadir . $dir) as $item) { if ($item == '.' || $item == '..') continue; if (strstr(strtolower($item), strtolower($query)) !== false) { $files[] = $dir . '/' . $item; } if (is_dir($this->datadir . $dir . '/' . $item)) { $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) { return $this->filemtime($path) > $time; } /** * {@inheritdoc} */ public function isLocal() { return true; } } }