summaryrefslogtreecommitdiffstats
path: root/lib/private/files
diff options
context:
space:
mode:
authorRoeland Jago Douma <rullzer@owncloud.com>2016-04-24 19:45:43 +0200
committerRoeland Jago Douma <rullzer@owncloud.com>2016-04-24 21:37:35 +0200
commitdedf392751e1b27163f9dd49b2a54f410727c823 (patch)
tree2d4d0265d7c574caed62dfe25cd718d79141be04 /lib/private/files
parentdc5c570d7caa3095a3cb4ab2b5a51bf772d7de4c (diff)
downloadnextcloud-server-dedf392751e1b27163f9dd49b2a54f410727c823.tar.gz
nextcloud-server-dedf392751e1b27163f9dd49b2a54f410727c823.zip
Move \OC\Files to PSR-4
Diffstat (limited to 'lib/private/files')
-rw-r--r--lib/private/files/cache/cache.php837
-rw-r--r--lib/private/files/cache/cacheentry.php114
-rw-r--r--lib/private/files/cache/failedcache.php142
-rw-r--r--lib/private/files/cache/homecache.php86
-rw-r--r--lib/private/files/cache/homepropagator.php50
-rw-r--r--lib/private/files/cache/movefromcachetrait.php87
-rw-r--r--lib/private/files/cache/propagator.php74
-rw-r--r--lib/private/files/cache/scanner.php503
-rw-r--r--lib/private/files/cache/storage.php189
-rw-r--r--lib/private/files/cache/updater.php228
-rw-r--r--lib/private/files/cache/watcher.php140
-rw-r--r--lib/private/files/cache/wrapper/cachejail.php300
-rw-r--r--lib/private/files/cache/wrapper/cachepermissionsmask.php46
-rw-r--r--lib/private/files/cache/wrapper/cachewrapper.php309
-rw-r--r--lib/private/files/config/cachedmountinfo.php107
-rw-r--r--lib/private/files/config/lazystoragemountinfo.php74
-rw-r--r--lib/private/files/config/mountprovidercollection.php108
-rw-r--r--lib/private/files/config/usermountcache.php290
-rw-r--r--lib/private/files/config/usermountcachelistener.php48
-rw-r--r--lib/private/files/fileinfo.php346
-rw-r--r--lib/private/files/filesystem.php928
-rw-r--r--lib/private/files/mount/manager.php165
-rw-r--r--lib/private/files/mount/mountpoint.php251
-rw-r--r--lib/private/files/mount/moveablemount.php44
-rw-r--r--lib/private/files/node/file.php176
-rw-r--r--lib/private/files/node/folder.php360
-rw-r--r--lib/private/files/node/hookconnector.php164
-rw-r--r--lib/private/files/node/lazyroot.php474
-rw-r--r--lib/private/files/node/node.php383
-rw-r--r--lib/private/files/node/nonexistingfile.php143
-rw-r--r--lib/private/files/node/nonexistingfolder.php172
-rw-r--r--lib/private/files/node/root.php357
-rw-r--r--lib/private/files/objectstore/homeobjectstorestorage.php68
-rw-r--r--lib/private/files/objectstore/noopscanner.php79
-rw-r--r--lib/private/files/objectstore/objectstorestorage.php407
-rw-r--r--lib/private/files/objectstore/swift.php154
-rw-r--r--lib/private/files/storage/common.php697
-rw-r--r--lib/private/files/storage/commontest.php84
-rw-r--r--lib/private/files/storage/dav.php817
-rw-r--r--lib/private/files/storage/failedstorage.php215
-rw-r--r--lib/private/files/storage/flysystem.php256
-rw-r--r--lib/private/files/storage/home.php114
-rw-r--r--lib/private/files/storage/local.php404
-rw-r--r--lib/private/files/storage/localtempfiletrait.php80
-rw-r--r--lib/private/files/storage/polyfill/copydirectory.php103
-rw-r--r--lib/private/files/storage/storage.php119
-rw-r--r--lib/private/files/storage/storagefactory.php107
-rw-r--r--lib/private/files/storage/temporary.php47
-rw-r--r--lib/private/files/storage/wrapper/availability.php461
-rw-r--r--lib/private/files/storage/wrapper/encryption.php993
-rw-r--r--lib/private/files/storage/wrapper/jail.php489
-rw-r--r--lib/private/files/storage/wrapper/permissionsmask.php131
-rw-r--r--lib/private/files/storage/wrapper/quota.php200
-rw-r--r--lib/private/files/storage/wrapper/wrapper.php608
-rw-r--r--lib/private/files/stream/close.php118
-rw-r--r--lib/private/files/stream/dir.php66
-rw-r--r--lib/private/files/stream/encryption.php500
-rw-r--r--lib/private/files/stream/oc.php153
-rw-r--r--lib/private/files/stream/quota.php156
-rw-r--r--lib/private/files/stream/staticstream.php170
-rw-r--r--lib/private/files/type/detection.php318
-rw-r--r--lib/private/files/type/loader.php173
-rw-r--r--lib/private/files/type/templatemanager.php61
-rw-r--r--lib/private/files/utils/scanner.php172
-rw-r--r--lib/private/files/view.php2058
65 files changed, 0 insertions, 18273 deletions
diff --git a/lib/private/files/cache/cache.php b/lib/private/files/cache/cache.php
deleted file mode 100644
index 53467c278d2..00000000000
--- a/lib/private/files/cache/cache.php
+++ /dev/null
@@ -1,837 +0,0 @@
-<?php
-/**
- * @author Andreas Fischer <bantu@owncloud.com>
- * @author Björn Schießle <schiessle@owncloud.com>
- * @author Florin Peter <github@florin-peter.de>
- * @author Jens-Christian Fischer <jens-christian.fischer@switch.ch>
- * @author Joas Schilling <nickvergessen@owncloud.com>
- * @author Jörn Friedrich Dreyer <jfd@butonic.de>
- * @author Lukas Reschke <lukas@owncloud.com>
- * @author Michael Gapczynski <GapczynskiM@gmail.com>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <icewind@owncloud.com>
- * @author Robin McCorkell <robin@mccorkell.me.uk>
- * @author Roeland Jago Douma <rullzer@owncloud.com>
- * @author TheSFReader <TheSFReader@gmail.com>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- * @author Vincent Petry <pvince81@owncloud.com>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OC\Files\Cache;
-
-use OCP\Files\Cache\ICache;
-use OCP\Files\Cache\ICacheEntry;
-use \OCP\Files\IMimeTypeLoader;
-use OCP\IDBConnection;
-
-/**
- * Metadata cache for a storage
- *
- * The cache stores the metadata for all files and folders in a storage and is kept up to date trough the following mechanisms:
- *
- * - Scanner: scans the storage and updates the cache where needed
- * - Watcher: checks for changes made to the filesystem outside of the ownCloud instance and rescans files and folder when a change is detected
- * - Updater: listens to changes made to the filesystem inside of the ownCloud instance and updates the cache where needed
- * - ChangePropagator: updates the mtime and etags of parent folders whenever a change to the cache is made to the cache by the updater
- */
-class Cache implements ICache {
- use MoveFromCacheTrait {
- MoveFromCacheTrait::moveFromCache as moveFromCacheFallback;
- }
-
- /**
- * @var array partial data for the cache
- */
- protected $partial = array();
-
- /**
- * @var string
- */
- protected $storageId;
-
- /**
- * @var Storage $storageCache
- */
- protected $storageCache;
-
- /** @var IMimeTypeLoader */
- protected $mimetypeLoader;
-
- /**
- * @var IDBConnection
- */
- protected $connection;
-
- /**
- * @param \OC\Files\Storage\Storage|string $storage
- */
- public function __construct($storage) {
- if ($storage instanceof \OC\Files\Storage\Storage) {
- $this->storageId = $storage->getId();
- } else {
- $this->storageId = $storage;
- }
- if (strlen($this->storageId) > 64) {
- $this->storageId = md5($this->storageId);
- }
-
- $this->storageCache = new Storage($storage);
- $this->mimetypeLoader = \OC::$server->getMimeTypeLoader();
- $this->connection = \OC::$server->getDatabaseConnection();
- }
-
- /**
- * Get the numeric storage id for this cache's storage
- *
- * @return int
- */
- public function getNumericStorageId() {
- return $this->storageCache->getNumericId();
- }
-
- /**
- * get the stored metadata of a file or folder
- *
- * @param string | int $file either the path of a file or folder or the file id for a file or folder
- * @return ICacheEntry|false the cache entry as array of false if the file is not found in the cache
- */
- public function get($file) {
- if (is_string($file) or $file == '') {
- // normalize file
- $file = $this->normalize($file);
-
- $where = 'WHERE `storage` = ? AND `path_hash` = ?';
- $params = array($this->getNumericStorageId(), md5($file));
- } else { //file id
- $where = 'WHERE `fileid` = ?';
- $params = array($file);
- }
- $sql = 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`,
- `storage_mtime`, `encrypted`, `etag`, `permissions`, `checksum`
- FROM `*PREFIX*filecache` ' . $where;
- $result = $this->connection->executeQuery($sql, $params);
- $data = $result->fetch();
-
- //FIXME hide this HACK in the next database layer, or just use doctrine and get rid of MDB2 and PDO
- //PDO returns false, MDB2 returns null, oracle always uses MDB2, so convert null to false
- if ($data === null) {
- $data = false;
- }
-
- //merge partial data
- if (!$data and is_string($file)) {
- if (isset($this->partial[$file])) {
- $data = $this->partial[$file];
- }
- return $data;
- } else {
- //fix types
- $data['fileid'] = (int)$data['fileid'];
- $data['parent'] = (int)$data['parent'];
- $data['size'] = 0 + $data['size'];
- $data['mtime'] = (int)$data['mtime'];
- $data['storage_mtime'] = (int)$data['storage_mtime'];
- $data['encryptedVersion'] = (int)$data['encrypted'];
- $data['encrypted'] = (bool)$data['encrypted'];
- $data['storage'] = $this->storageId;
- $data['mimetype'] = $this->mimetypeLoader->getMimetypeById($data['mimetype']);
- $data['mimepart'] = $this->mimetypeLoader->getMimetypeById($data['mimepart']);
- if ($data['storage_mtime'] == 0) {
- $data['storage_mtime'] = $data['mtime'];
- }
- $data['permissions'] = (int)$data['permissions'];
- return new CacheEntry($data);
- }
- }
-
- /**
- * get the metadata of all files stored in $folder
- *
- * @param string $folder
- * @return ICacheEntry[]
- */
- public function getFolderContents($folder) {
- $fileId = $this->getId($folder);
- return $this->getFolderContentsById($fileId);
- }
-
- /**
- * get the metadata of all files stored in $folder
- *
- * @param int $fileId the file id of the folder
- * @return ICacheEntry[]
- */
- public function getFolderContentsById($fileId) {
- if ($fileId > -1) {
- $sql = 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`,
- `storage_mtime`, `encrypted`, `etag`, `permissions`, `checksum`
- FROM `*PREFIX*filecache` WHERE `parent` = ? ORDER BY `name` ASC';
- $result = $this->connection->executeQuery($sql, [$fileId]);
- $files = $result->fetchAll();
- foreach ($files as &$file) {
- $file['mimetype'] = $this->mimetypeLoader->getMimetypeById($file['mimetype']);
- $file['mimepart'] = $this->mimetypeLoader->getMimetypeById($file['mimepart']);
- if ($file['storage_mtime'] == 0) {
- $file['storage_mtime'] = $file['mtime'];
- }
- $file['permissions'] = (int)$file['permissions'];
- $file['mtime'] = (int)$file['mtime'];
- $file['storage_mtime'] = (int)$file['storage_mtime'];
- $file['size'] = 0 + $file['size'];
- }
- return array_map(function (array $data) {
- return new CacheEntry($data);
- }, $files);
- } else {
- return array();
- }
- }
-
- /**
- * insert or update meta data for a file or folder
- *
- * @param string $file
- * @param array $data
- *
- * @return int file id
- * @throws \RuntimeException
- */
- public function put($file, array $data) {
- if (($id = $this->getId($file)) > -1) {
- $this->update($id, $data);
- return $id;
- } else {
- return $this->insert($file, $data);
- }
- }
-
- /**
- * insert meta data for a new file or folder
- *
- * @param string $file
- * @param array $data
- *
- * @return int file id
- * @throws \RuntimeException
- */
- public function insert($file, array $data) {
- // normalize file
- $file = $this->normalize($file);
-
- if (isset($this->partial[$file])) { //add any saved partial data
- $data = array_merge($this->partial[$file], $data);
- unset($this->partial[$file]);
- }
-
- $requiredFields = array('size', 'mtime', 'mimetype');
- foreach ($requiredFields as $field) {
- if (!isset($data[$field])) { //data not complete save as partial and return
- $this->partial[$file] = $data;
- return -1;
- }
- }
-
- $data['path'] = $file;
- $data['parent'] = $this->getParentId($file);
- $data['name'] = \OC_Util::basename($file);
-
- list($queryParts, $params) = $this->buildParts($data);
- $queryParts[] = '`storage`';
- $params[] = $this->getNumericStorageId();
-
- $queryParts = array_map(function ($item) {
- return trim($item, "`");
- }, $queryParts);
- $values = array_combine($queryParts, $params);
- if (\OC::$server->getDatabaseConnection()->insertIfNotExist('*PREFIX*filecache', $values, [
- 'storage',
- 'path_hash',
- ])
- ) {
- return (int)$this->connection->lastInsertId('*PREFIX*filecache');
- }
-
- // The file was created in the mean time
- if (($id = $this->getId($file)) > -1) {
- $this->update($id, $data);
- return $id;
- } else {
- throw new \RuntimeException('File entry could not be inserted with insertIfNotExist() but could also not be selected with getId() in order to perform an update. Please try again.');
- }
- }
-
- /**
- * update the metadata of an existing file or folder in the cache
- *
- * @param int $id the fileid of the existing file or folder
- * @param array $data [$key => $value] the metadata to update, only the fields provided in the array will be updated, non-provided values will remain unchanged
- */
- public function update($id, array $data) {
-
- if (isset($data['path'])) {
- // normalize path
- $data['path'] = $this->normalize($data['path']);
- }
-
- if (isset($data['name'])) {
- // normalize path
- $data['name'] = $this->normalize($data['name']);
- }
-
- list($queryParts, $params) = $this->buildParts($data);
- // duplicate $params because we need the parts twice in the SQL statement
- // once for the SET part, once in the WHERE clause
- $params = array_merge($params, $params);
- $params[] = $id;
-
- // don't update if the data we try to set is the same as the one in the record
- // some databases (Postgres) don't like superfluous updates
- $sql = 'UPDATE `*PREFIX*filecache` SET ' . implode(' = ?, ', $queryParts) . '=? ' .
- 'WHERE (' .
- implode(' <> ? OR ', $queryParts) . ' <> ? OR ' .
- implode(' IS NULL OR ', $queryParts) . ' IS NULL' .
- ') AND `fileid` = ? ';
- $this->connection->executeQuery($sql, $params);
-
- }
-
- /**
- * extract query parts and params array from data array
- *
- * @param array $data
- * @return array [$queryParts, $params]
- * $queryParts: string[], the (escaped) column names to be set in the query
- * $params: mixed[], the new values for the columns, to be passed as params to the query
- */
- protected function buildParts(array $data) {
- $fields = array(
- 'path', 'parent', 'name', 'mimetype', 'size', 'mtime', 'storage_mtime', 'encrypted',
- 'etag', 'permissions', 'checksum');
-
- $doNotCopyStorageMTime = false;
- if (array_key_exists('mtime', $data) && $data['mtime'] === null) {
- // this horrific magic tells it to not copy storage_mtime to mtime
- unset($data['mtime']);
- $doNotCopyStorageMTime = true;
- }
-
- $params = array();
- $queryParts = array();
- foreach ($data as $name => $value) {
- if (array_search($name, $fields) !== false) {
- if ($name === 'path') {
- $params[] = md5($value);
- $queryParts[] = '`path_hash`';
- } elseif ($name === 'mimetype') {
- $params[] = $this->mimetypeLoader->getId(substr($value, 0, strpos($value, '/')));
- $queryParts[] = '`mimepart`';
- $value = $this->mimetypeLoader->getId($value);
- } elseif ($name === 'storage_mtime') {
- if (!$doNotCopyStorageMTime && !isset($data['mtime'])) {
- $params[] = $value;
- $queryParts[] = '`mtime`';
- }
- } elseif ($name === 'encrypted') {
- if(isset($data['encryptedVersion'])) {
- $value = $data['encryptedVersion'];
- } else {
- // Boolean to integer conversion
- $value = $value ? 1 : 0;
- }
- }
- $params[] = $value;
- $queryParts[] = '`' . $name . '`';
- }
- }
- return array($queryParts, $params);
- }
-
- /**
- * get the file id for a file
- *
- * A file id is a numeric id for a file or folder that's unique within an owncloud instance which stays the same for the lifetime of a file
- *
- * File ids are easiest way for apps to store references to a file since unlike paths they are not affected by renames or sharing
- *
- * @param string $file
- * @return int
- */
- public function getId($file) {
- // normalize file
- $file = $this->normalize($file);
-
- $pathHash = md5($file);
-
- $sql = 'SELECT `fileid` FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path_hash` = ?';
- $result = $this->connection->executeQuery($sql, array($this->getNumericStorageId(), $pathHash));
- if ($row = $result->fetch()) {
- return $row['fileid'];
- } else {
- return -1;
- }
- }
-
- /**
- * get the id of the parent folder of a file
- *
- * @param string $file
- * @return int
- */
- public function getParentId($file) {
- if ($file === '') {
- return -1;
- } else {
- $parent = $this->getParentPath($file);
- return (int)$this->getId($parent);
- }
- }
-
- private function getParentPath($path) {
- $parent = dirname($path);
- if ($parent === '.') {
- $parent = '';
- }
- return $parent;
- }
-
- /**
- * check if a file is available in the cache
- *
- * @param string $file
- * @return bool
- */
- public function inCache($file) {
- return $this->getId($file) != -1;
- }
-
- /**
- * remove a file or folder from the cache
- *
- * when removing a folder from the cache all files and folders inside the folder will be removed as well
- *
- * @param string $file
- */
- public function remove($file) {
- $entry = $this->get($file);
- $sql = 'DELETE FROM `*PREFIX*filecache` WHERE `fileid` = ?';
- $this->connection->executeQuery($sql, array($entry['fileid']));
- if ($entry['mimetype'] === 'httpd/unix-directory') {
- $this->removeChildren($entry);
- }
- }
-
- /**
- * Get all sub folders of a folder
- *
- * @param array $entry the cache entry of the folder to get the subfolders for
- * @return array[] the cache entries for the subfolders
- */
- private function getSubFolders($entry) {
- $children = $this->getFolderContentsById($entry['fileid']);
- return array_filter($children, function ($child) {
- return $child['mimetype'] === 'httpd/unix-directory';
- });
- }
-
- /**
- * Recursively remove all children of a folder
- *
- * @param array $entry the cache entry of the folder to remove the children of
- * @throws \OC\DatabaseException
- */
- private function removeChildren($entry) {
- $subFolders = $this->getSubFolders($entry);
- foreach ($subFolders as $folder) {
- $this->removeChildren($folder);
- }
- $sql = 'DELETE FROM `*PREFIX*filecache` WHERE `parent` = ?';
- $this->connection->executeQuery($sql, array($entry['fileid']));
- }
-
- /**
- * Move a file or folder in the cache
- *
- * @param string $source
- * @param string $target
- */
- public function move($source, $target) {
- $this->moveFromCache($this, $source, $target);
- }
-
- /**
- * Get the storage id and path needed for a move
- *
- * @param string $path
- * @return array [$storageId, $internalPath]
- */
- protected function getMoveInfo($path) {
- return [$this->getNumericStorageId(), $path];
- }
-
- /**
- * Move a file or folder in the cache
- *
- * @param \OCP\Files\Cache\ICache $sourceCache
- * @param string $sourcePath
- * @param string $targetPath
- * @throws \OC\DatabaseException
- */
- public function moveFromCache(ICache $sourceCache, $sourcePath, $targetPath) {
- if ($sourceCache instanceof Cache) {
- // normalize source and target
- $sourcePath = $this->normalize($sourcePath);
- $targetPath = $this->normalize($targetPath);
-
- $sourceData = $sourceCache->get($sourcePath);
- $sourceId = $sourceData['fileid'];
- $newParentId = $this->getParentId($targetPath);
-
- list($sourceStorageId, $sourcePath) = $sourceCache->getMoveInfo($sourcePath);
- list($targetStorageId, $targetPath) = $this->getMoveInfo($targetPath);
-
- // sql for final update
- $moveSql = 'UPDATE `*PREFIX*filecache` SET `storage` = ?, `path` = ?, `path_hash` = ?, `name` = ?, `parent` =? WHERE `fileid` = ?';
-
- if ($sourceData['mimetype'] === 'httpd/unix-directory') {
- //find all child entries
- $sql = 'SELECT `path`, `fileid` FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path` LIKE ?';
- $result = $this->connection->executeQuery($sql, [$sourceStorageId, $this->connection->escapeLikeParameter($sourcePath) . '/%']);
- $childEntries = $result->fetchAll();
- $sourceLength = strlen($sourcePath);
- $this->connection->beginTransaction();
- $query = $this->connection->prepare('UPDATE `*PREFIX*filecache` SET `storage` = ?, `path` = ?, `path_hash` = ? WHERE `fileid` = ?');
-
- foreach ($childEntries as $child) {
- $newTargetPath = $targetPath . substr($child['path'], $sourceLength);
- $query->execute([$targetStorageId, $newTargetPath, md5($newTargetPath), $child['fileid']]);
- }
- $this->connection->executeQuery($moveSql, [$targetStorageId, $targetPath, md5($targetPath), basename($targetPath), $newParentId, $sourceId]);
- $this->connection->commit();
- } else {
- $this->connection->executeQuery($moveSql, [$targetStorageId, $targetPath, md5($targetPath), basename($targetPath), $newParentId, $sourceId]);
- }
- } else {
- $this->moveFromCacheFallback($sourceCache, $sourcePath, $targetPath);
- }
- }
-
- /**
- * remove all entries for files that are stored on the storage from the cache
- */
- public function clear() {
- $sql = 'DELETE FROM `*PREFIX*filecache` WHERE `storage` = ?';
- $this->connection->executeQuery($sql, array($this->getNumericStorageId()));
-
- $sql = 'DELETE FROM `*PREFIX*storages` WHERE `id` = ?';
- $this->connection->executeQuery($sql, array($this->storageId));
- }
-
- /**
- * Get the scan status of a file
- *
- * - Cache::NOT_FOUND: File is not in the cache
- * - Cache::PARTIAL: File is not stored in the cache but some incomplete data is known
- * - Cache::SHALLOW: The folder and it's direct children are in the cache but not all sub folders are fully scanned
- * - Cache::COMPLETE: The file or folder, with all it's children) are fully scanned
- *
- * @param string $file
- *
- * @return int Cache::NOT_FOUND, Cache::PARTIAL, Cache::SHALLOW or Cache::COMPLETE
- */
- public function getStatus($file) {
- // normalize file
- $file = $this->normalize($file);
-
- $pathHash = md5($file);
- $sql = 'SELECT `size` FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path_hash` = ?';
- $result = $this->connection->executeQuery($sql, array($this->getNumericStorageId(), $pathHash));
- if ($row = $result->fetch()) {
- if ((int)$row['size'] === -1) {
- return self::SHALLOW;
- } else {
- return self::COMPLETE;
- }
- } else {
- if (isset($this->partial[$file])) {
- return self::PARTIAL;
- } else {
- return self::NOT_FOUND;
- }
- }
- }
-
- /**
- * search for files matching $pattern
- *
- * @param string $pattern the search pattern using SQL search syntax (e.g. '%searchstring%')
- * @return ICacheEntry[] an array of cache entries where the name matches the search pattern
- */
- public function search($pattern) {
- // normalize pattern
- $pattern = $this->normalize($pattern);
-
-
- $sql = '
- SELECT `fileid`, `storage`, `path`, `parent`, `name`,
- `mimetype`, `mimepart`, `size`, `mtime`, `encrypted`,
- `etag`, `permissions`, `checksum`
- FROM `*PREFIX*filecache`
- WHERE `storage` = ? AND `name` ILIKE ?';
- $result = $this->connection->executeQuery($sql,
- [$this->getNumericStorageId(), $pattern]
- );
-
- $files = [];
- while ($row = $result->fetch()) {
- $row['mimetype'] = $this->mimetypeLoader->getMimetypeById($row['mimetype']);
- $row['mimepart'] = $this->mimetypeLoader->getMimetypeById($row['mimepart']);
- $files[] = $row;
- }
- return array_map(function(array $data) {
- return new CacheEntry($data);
- }, $files);
- }
-
- /**
- * search for files by mimetype
- *
- * @param string $mimetype either a full mimetype to search ('text/plain') or only the first part of a mimetype ('image')
- * where it will search for all mimetypes in the group ('image/*')
- * @return ICacheEntry[] an array of cache entries where the mimetype matches the search
- */
- public function searchByMime($mimetype) {
- if (strpos($mimetype, '/')) {
- $where = '`mimetype` = ?';
- } else {
- $where = '`mimepart` = ?';
- }
- $sql = 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted`, `etag`, `permissions`, `checksum`
- FROM `*PREFIX*filecache` WHERE ' . $where . ' AND `storage` = ?';
- $mimetype = $this->mimetypeLoader->getId($mimetype);
- $result = $this->connection->executeQuery($sql, array($mimetype, $this->getNumericStorageId()));
- $files = array();
- while ($row = $result->fetch()) {
- $row['mimetype'] = $this->mimetypeLoader->getMimetypeById($row['mimetype']);
- $row['mimepart'] = $this->mimetypeLoader->getMimetypeById($row['mimepart']);
- $files[] = $row;
- }
- return array_map(function (array $data) {
- return new CacheEntry($data);
- }, $files);
- }
-
- /**
- * Search for files by tag of a given users.
- *
- * Note that every user can tag files differently.
- *
- * @param string|int $tag name or tag id
- * @param string $userId owner of the tags
- * @return ICacheEntry[] file data
- */
- public function searchByTag($tag, $userId) {
- $sql = 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, ' .
- '`mimetype`, `mimepart`, `size`, `mtime`, ' .
- '`encrypted`, `etag`, `permissions`, `checksum` ' .
- 'FROM `*PREFIX*filecache` `file`, ' .
- '`*PREFIX*vcategory_to_object` `tagmap`, ' .
- '`*PREFIX*vcategory` `tag` ' .
- // JOIN filecache to vcategory_to_object
- 'WHERE `file`.`fileid` = `tagmap`.`objid` ' .
- // JOIN vcategory_to_object to vcategory
- 'AND `tagmap`.`type` = `tag`.`type` ' .
- 'AND `tagmap`.`categoryid` = `tag`.`id` ' .
- // conditions
- 'AND `file`.`storage` = ? ' .
- 'AND `tag`.`type` = \'files\' ' .
- 'AND `tag`.`uid` = ? ';
- if (is_int($tag)) {
- $sql .= 'AND `tag`.`id` = ? ';
- } else {
- $sql .= 'AND `tag`.`category` = ? ';
- }
- $result = $this->connection->executeQuery(
- $sql,
- [
- $this->getNumericStorageId(),
- $userId,
- $tag
- ]
- );
- $files = array();
- while ($row = $result->fetch()) {
- $files[] = $row;
- }
- return array_map(function (array $data) {
- return new CacheEntry($data);
- }, $files);
- }
-
- /**
- * Re-calculate the folder size and the size of all parent folders
- *
- * @param string|boolean $path
- * @param array $data (optional) meta data of the folder
- */
- public function correctFolderSize($path, $data = null) {
- $this->calculateFolderSize($path, $data);
- if ($path !== '') {
- $parent = dirname($path);
- if ($parent === '.' or $parent === '/') {
- $parent = '';
- }
- $this->correctFolderSize($parent);
- }
- }
-
- /**
- * calculate the size of a folder and set it in the cache
- *
- * @param string $path
- * @param array $entry (optional) meta data of the folder
- * @return int
- */
- public function calculateFolderSize($path, $entry = null) {
- $totalSize = 0;
- if (is_null($entry) or !isset($entry['fileid'])) {
- $entry = $this->get($path);
- }
- if (isset($entry['mimetype']) && $entry['mimetype'] === 'httpd/unix-directory') {
- $id = $entry['fileid'];
- $sql = 'SELECT SUM(`size`) AS f1, MIN(`size`) AS f2 ' .
- 'FROM `*PREFIX*filecache` ' .
- 'WHERE `parent` = ? AND `storage` = ?';
- $result = $this->connection->executeQuery($sql, array($id, $this->getNumericStorageId()));
- if ($row = $result->fetch()) {
- $result->closeCursor();
- list($sum, $min) = array_values($row);
- $sum = 0 + $sum;
- $min = 0 + $min;
- if ($min === -1) {
- $totalSize = $min;
- } else {
- $totalSize = $sum;
- }
- $update = array();
- if ($entry['size'] !== $totalSize) {
- $update['size'] = $totalSize;
- }
- if (count($update) > 0) {
- $this->update($id, $update);
- }
- } else {
- $result->closeCursor();
- }
- }
- return $totalSize;
- }
-
- /**
- * get all file ids on the files on the storage
- *
- * @return int[]
- */
- public function getAll() {
- $sql = 'SELECT `fileid` FROM `*PREFIX*filecache` WHERE `storage` = ?';
- $result = $this->connection->executeQuery($sql, array($this->getNumericStorageId()));
- $ids = array();
- while ($row = $result->fetch()) {
- $ids[] = $row['fileid'];
- }
- return $ids;
- }
-
- /**
- * find a folder in the cache which has not been fully scanned
- *
- * If multiple incomplete folders are in the cache, the one with the highest id will be returned,
- * use the one with the highest id gives the best result with the background scanner, since that is most
- * likely the folder where we stopped scanning previously
- *
- * @return string|bool the path of the folder or false when no folder matched
- */
- public function getIncomplete() {
- $query = $this->connection->prepare('SELECT `path` FROM `*PREFIX*filecache`'
- . ' WHERE `storage` = ? AND `size` = -1 ORDER BY `fileid` DESC', 1);
- $query->execute([$this->getNumericStorageId()]);
- if ($row = $query->fetch()) {
- return $row['path'];
- } else {
- return false;
- }
- }
-
- /**
- * get the path of a file on this storage by it's file id
- *
- * @param int $id the file id of the file or folder to search
- * @return string|null the path of the file (relative to the storage) or null if a file with the given id does not exists within this cache
- */
- public function getPathById($id) {
- $sql = 'SELECT `path` FROM `*PREFIX*filecache` WHERE `fileid` = ? AND `storage` = ?';
- $result = $this->connection->executeQuery($sql, array($id, $this->getNumericStorageId()));
- if ($row = $result->fetch()) {
- // Oracle stores empty strings as null...
- if ($row['path'] === null) {
- return '';
- }
- return $row['path'];
- } else {
- return null;
- }
- }
-
- /**
- * get the storage id of the storage for a file and the internal path of the file
- * unlike getPathById this does not limit the search to files on this storage and
- * instead does a global search in the cache table
- *
- * @param int $id
- * @deprecated use getPathById() instead
- * @return array first element holding the storage id, second the path
- */
- static public function getById($id) {
- $connection = \OC::$server->getDatabaseConnection();
- $sql = 'SELECT `storage`, `path` FROM `*PREFIX*filecache` WHERE `fileid` = ?';
- $result = $connection->executeQuery($sql, array($id));
- if ($row = $result->fetch()) {
- $numericId = $row['storage'];
- $path = $row['path'];
- } else {
- return null;
- }
-
- if ($id = Storage::getStorageId($numericId)) {
- return array($id, $path);
- } else {
- return null;
- }
- }
-
- /**
- * normalize the given path
- *
- * @param string $path
- * @return string
- */
- public function normalize($path) {
-
- return trim(\OC_Util::normalizeUnicode($path), '/');
- }
-}
diff --git a/lib/private/files/cache/cacheentry.php b/lib/private/files/cache/cacheentry.php
deleted file mode 100644
index 6d3c5d5b089..00000000000
--- a/lib/private/files/cache/cacheentry.php
+++ /dev/null
@@ -1,114 +0,0 @@
-<?php
-/**
- * @author Robin Appelman <icewind@owncloud.com>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OC\Files\Cache;
-
-use OCP\Files\Cache\ICacheEntry;
-
-/**
- * meta data for a file or folder
- */
-class CacheEntry implements ICacheEntry, \ArrayAccess {
- /**
- * @var array
- */
- private $data;
-
- public function __construct(array $data) {
- $this->data = $data;
- }
-
- public function offsetSet($offset, $value) {
- $this->data[$offset] = $value;
- }
-
- public function offsetExists($offset) {
- return isset($this->data[$offset]);
- }
-
- public function offsetUnset($offset) {
- unset($this->data[$offset]);
- }
-
- public function offsetGet($offset) {
- if (isset($this->data[$offset])) {
- return $this->data[$offset];
- } else {
- return null;
- }
- }
-
- public function getId() {
- return (int)$this->data['fileid'];
- }
-
- public function getStorageId() {
- return $this->data['storage'];
- }
-
-
- public function getPath() {
- return $this->data['path'];
- }
-
-
- public function getName() {
- return $this->data['name'];
- }
-
-
- public function getMimeType() {
- return $this->data['mimetype'];
- }
-
-
- public function getMimePart() {
- return $this->data['mimepart'];
- }
-
- public function getSize() {
- return $this->data['size'];
- }
-
- public function getMTime() {
- return $this->data['mtime'];
- }
-
- public function getStorageMTime() {
- return $this->data['storage_mtime'];
- }
-
- public function getEtag() {
- return $this->data['etag'];
- }
-
- public function getPermissions() {
- return $this->data['permissions'];
- }
-
- public function isEncrypted() {
- return isset($this->data['encrypted']) && $this->data['encrypted'];
- }
-
- public function getData() {
- return $this->data;
- }
-}
diff --git a/lib/private/files/cache/failedcache.php b/lib/private/files/cache/failedcache.php
deleted file mode 100644
index 0386ba3ca32..00000000000
--- a/lib/private/files/cache/failedcache.php
+++ /dev/null
@@ -1,142 +0,0 @@
-<?php
-/**
- * @author Robin Appelman <icewind@owncloud.com>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OC\Files\Cache;
-
-use OCP\Constants;
-use OCP\Files\Cache\ICache;
-
-/**
- * Storage placeholder to represent a missing precondition, storage unavailable
- */
-class FailedCache implements ICache {
- /** @var bool whether to show the failed storage in the ui */
- private $visible;
-
- /**
- * FailedCache constructor.
- *
- * @param bool $visible
- */
- public function __construct($visible = true) {
- $this->visible = $visible;
- }
-
-
- public function getNumericStorageId() {
- return -1;
- }
-
- public function get($file) {
- if ($file === '') {
- return new CacheEntry([
- 'fileid' => -1,
- 'size' => 0,
- 'mimetype' => 'httpd/unix-directory',
- 'mimepart' => 'httpd',
- 'permissions' => $this->visible ? Constants::PERMISSION_READ : 0,
- 'mtime' => time()
- ]);
- } else {
- return false;
- }
- }
-
- public function getFolderContents($folder) {
- return [];
- }
-
- public function getFolderContentsById($fileId) {
- return [];
- }
-
- public function put($file, array $data) {
- return;
- }
-
- public function insert($file, array $data) {
- return;
- }
-
- public function update($id, array $data) {
- return;
- }
-
- public function getId($file) {
- return -1;
- }
-
- public function getParentId($file) {
- return -1;
- }
-
- public function inCache($file) {
- return false;
- }
-
- public function remove($file) {
- return;
- }
-
- public function move($source, $target) {
- return;
- }
-
- public function moveFromCache(ICache $sourceCache, $sourcePath, $targetPath) {
- return;
- }
-
- public function clear() {
- return;
- }
-
- public function getStatus($file) {
- return ICache::NOT_FOUND;
- }
-
- public function search($pattern) {
- return [];
- }
-
- public function searchByMime($mimetype) {
- return [];
- }
-
- public function searchByTag($tag, $userId) {
- return [];
- }
-
- public function getAll() {
- return [];
- }
-
- public function getIncomplete() {
- return [];
- }
-
- public function getPathById($id) {
- return null;
- }
-
- public function normalize($path) {
- return $path;
- }
-}
diff --git a/lib/private/files/cache/homecache.php b/lib/private/files/cache/homecache.php
deleted file mode 100644
index ae92504ddd6..00000000000
--- a/lib/private/files/cache/homecache.php
+++ /dev/null
@@ -1,86 +0,0 @@
-<?php
-/**
- * @author Andreas Fischer <bantu@owncloud.com>
- * @author Björn Schießle <schiessle@owncloud.com>
- * @author Jörn Friedrich Dreyer <jfd@butonic.de>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <icewind@owncloud.com>
- * @author Vincent Petry <pvince81@owncloud.com>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OC\Files\Cache;
-
-use OCP\Files\Cache\ICacheEntry;
-
-class HomeCache extends Cache {
- /**
- * get the size of a folder and set it in the cache
- *
- * @param string $path
- * @param array $entry (optional) meta data of the folder
- * @return int
- */
- public function calculateFolderSize($path, $entry = null) {
- if ($path !== '/' and $path !== '' and $path !== 'files' and $path !== 'files_trashbin' and $path !== 'files_versions') {
- return parent::calculateFolderSize($path, $entry);
- } elseif ($path === '' or $path === '/') {
- // since the size of / isn't used (the size of /files is used instead) there is no use in calculating it
- return 0;
- }
-
- $totalSize = 0;
- if (is_null($entry)) {
- $entry = $this->get($path);
- }
- if ($entry && $entry['mimetype'] === 'httpd/unix-directory') {
- $id = $entry['fileid'];
- $sql = 'SELECT SUM(`size`) AS f1 ' .
- 'FROM `*PREFIX*filecache` ' .
- 'WHERE `parent` = ? AND `storage` = ? AND `size` >= 0';
- $result = \OC_DB::executeAudited($sql, array($id, $this->getNumericStorageId()));
- if ($row = $result->fetchRow()) {
- $result->closeCursor();
- list($sum) = array_values($row);
- $totalSize = 0 + $sum;
- $entry['size'] += 0;
- if ($entry['size'] !== $totalSize) {
- $this->update($id, array('size' => $totalSize));
- }
- }
- }
- return $totalSize;
- }
-
- /**
- * @param string $path
- * @return ICacheEntry
- */
- public function get($path) {
- $data = parent::get($path);
- if ($path === '' or $path === '/') {
- // only the size of the "files" dir counts
- $filesData = parent::get('files');
-
- if (isset($filesData['size'])) {
- $data['size'] = $filesData['size'];
- }
- }
- return $data;
- }
-}
diff --git a/lib/private/files/cache/homepropagator.php b/lib/private/files/cache/homepropagator.php
deleted file mode 100644
index 8edca9c0c87..00000000000
--- a/lib/private/files/cache/homepropagator.php
+++ /dev/null
@@ -1,50 +0,0 @@
-<?php
-/**
- * @author Robin Appelman <icewind@owncloud.com>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OC\Files\Cache;
-
-class HomePropagator extends Propagator {
- private $ignoredBaseFolders;
-
- /**
- * @param \OC\Files\Storage\Storage $storage
- */
- public function __construct(\OC\Files\Storage\Storage $storage) {
- parent::__construct($storage);
- $this->ignoredBaseFolders = ['files_encryption'];
- }
-
-
- /**
- * @param string $internalPath
- * @param int $time
- * @param int $sizeDifference number of bytes the file has grown
- * @return array[] all propagated entries
- */
- public function propagateChange($internalPath, $time, $sizeDifference = 0) {
- list($baseFolder) = explode('/', $internalPath, 2);
- if (in_array($baseFolder, $this->ignoredBaseFolders)) {
- return [];
- } else {
- return parent::propagateChange($internalPath, $time, $sizeDifference);
- }
- }
-}
diff --git a/lib/private/files/cache/movefromcachetrait.php b/lib/private/files/cache/movefromcachetrait.php
deleted file mode 100644
index 7d8ed7b5d21..00000000000
--- a/lib/private/files/cache/movefromcachetrait.php
+++ /dev/null
@@ -1,87 +0,0 @@
-<?php
-/**
- * @author Robin Appelman <icewind@owncloud.com>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OC\Files\Cache;
-
-use OCP\Files\Cache\ICache;
-use OCP\Files\Cache\ICacheEntry;
-
-/**
- * Fallback implementation for moveFromCache
- */
-trait MoveFromCacheTrait {
- /**
- * store meta data for a file or folder
- *
- * @param string $file
- * @param array $data
- *
- * @return int file id
- * @throws \RuntimeException
- */
- abstract public function put($file, array $data);
-
- /**
- * Move a file or folder in the cache
- *
- * @param \OCP\Files\Cache\ICache $sourceCache
- * @param string $sourcePath
- * @param string $targetPath
- */
- public function moveFromCache(ICache $sourceCache, $sourcePath, $targetPath) {
- $sourceEntry = $sourceCache->get($sourcePath);
-
- $this->copyFromCache($sourceCache, $sourceEntry, $targetPath);
-
- $sourceCache->remove($sourcePath);
- }
-
- /**
- * Copy a file or folder in the cache
- *
- * @param \OCP\Files\Cache\ICache $sourceCache
- * @param ICacheEntry $sourceEntry
- * @param string $targetPath
- */
- public function copyFromCache(ICache $sourceCache, ICacheEntry $sourceEntry, $targetPath) {
- $this->put($targetPath, $this->cacheEntryToArray($sourceEntry));
- if ($sourceEntry->getMimeType() === ICacheEntry::DIRECTORY_MIMETYPE) {
- $folderContent = $sourceCache->getFolderContentsById($sourceEntry->getId());
- foreach ($folderContent as $subEntry) {
- $subTargetPath = $targetPath . '/' . $subEntry->getName();
- $this->copyFromCache($sourceCache, $subEntry, $subTargetPath);
- }
- }
- }
-
- private function cacheEntryToArray(ICacheEntry $entry) {
- return [
- 'size' => $entry->getSize(),
- 'mtime' => $entry->getMTime(),
- 'storage_mtime' => $entry->getStorageMTime(),
- 'mimetype' => $entry->getMimeType(),
- 'mimepart' => $entry->getMimePart(),
- 'etag' => $entry->getEtag(),
- 'permissions' => $entry->getPermissions(),
- 'encrypted' => $entry->isEncrypted()
- ];
- }
-}
diff --git a/lib/private/files/cache/propagator.php b/lib/private/files/cache/propagator.php
deleted file mode 100644
index 50264e54d44..00000000000
--- a/lib/private/files/cache/propagator.php
+++ /dev/null
@@ -1,74 +0,0 @@
-<?php
-/**
- * @author Robin Appelman <icewind@owncloud.com>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OC\Files\Cache;
-
-use OCP\Files\Cache\IPropagator;
-
-/**
- * Propagate etags and mtimes within the storage
- */
-class Propagator implements IPropagator {
- /**
- * @var \OC\Files\Storage\Storage
- */
- protected $storage;
-
- /**
- * @param \OC\Files\Storage\Storage $storage
- */
- public function __construct(\OC\Files\Storage\Storage $storage) {
- $this->storage = $storage;
- }
-
-
- /**
- * @param string $internalPath
- * @param int $time
- * @param int $sizeDifference number of bytes the file has grown
- * @return array[] all propagated entries
- */
- public function propagateChange($internalPath, $time, $sizeDifference = 0) {
- $cache = $this->storage->getCache($internalPath);
-
- $parentId = $cache->getParentId($internalPath);
- $propagatedEntries = [];
- while ($parentId !== -1) {
- $entry = $cache->get($parentId);
- $propagatedEntries[] = $entry;
- if (!$entry) {
- return $propagatedEntries;
- }
- $mtime = max($time, $entry['mtime']);
-
- if ($entry['size'] === -1) {
- $newSize = -1;
- } else {
- $newSize = $entry['size'] + $sizeDifference;
- }
- $cache->update($parentId, ['mtime' => $mtime, 'etag' => $this->storage->getETag($entry['path']), 'size' => $newSize]);
-
- $parentId = $entry['parent'];
- }
-
- return $propagatedEntries;
- }
-}
diff --git a/lib/private/files/cache/scanner.php b/lib/private/files/cache/scanner.php
deleted file mode 100644
index 8730707f1c2..00000000000
--- a/lib/private/files/cache/scanner.php
+++ /dev/null
@@ -1,503 +0,0 @@
-<?php
-/**
- * @author Arthur Schiwon <blizzz@owncloud.com>
- * @author Björn Schießle <schiessle@owncloud.com>
- * @author Joas Schilling <nickvergessen@owncloud.com>
- * @author Jörn Friedrich Dreyer <jfd@butonic.de>
- * @author Lukas Reschke <lukas@owncloud.com>
- * @author Martin Mattel <martin.mattel@diemattels.at>
- * @author Michael Gapczynski <GapczynskiM@gmail.com>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Owen Winkler <a_github@midnightcircus.com>
- * @author Robin Appelman <icewind@owncloud.com>
- * @author Robin McCorkell <robin@mccorkell.me.uk>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- * @author Vincent Petry <pvince81@owncloud.com>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OC\Files\Cache;
-
-use OC\Files\Filesystem;
-use OC\Hooks\BasicEmitter;
-use OCP\Config;
-use OCP\Files\Cache\IScanner;
-use OCP\Files\Storage\ILockingStorage;
-use OCP\Lock\ILockingProvider;
-
-/**
- * Class Scanner
- *
- * Hooks available in scope \OC\Files\Cache\Scanner:
- * - scanFile(string $path, string $storageId)
- * - scanFolder(string $path, string $storageId)
- * - postScanFile(string $path, string $storageId)
- * - postScanFolder(string $path, string $storageId)
- *
- * @package OC\Files\Cache
- */
-class Scanner extends BasicEmitter implements IScanner {
- /**
- * @var \OC\Files\Storage\Storage $storage
- */
- protected $storage;
-
- /**
- * @var string $storageId
- */
- protected $storageId;
-
- /**
- * @var \OC\Files\Cache\Cache $cache
- */
- protected $cache;
-
- /**
- * @var boolean $cacheActive If true, perform cache operations, if false, do not affect cache
- */
- protected $cacheActive;
-
- /**
- * @var bool $useTransactions whether to use transactions
- */
- protected $useTransactions = true;
-
- /**
- * @var \OCP\Lock\ILockingProvider
- */
- protected $lockingProvider;
-
- public function __construct(\OC\Files\Storage\Storage $storage) {
- $this->storage = $storage;
- $this->storageId = $this->storage->getId();
- $this->cache = $storage->getCache();
- $this->cacheActive = !Config::getSystemValue('filesystem_cache_readonly', false);
- $this->lockingProvider = \OC::$server->getLockingProvider();
- }
-
- /**
- * Whether to wrap the scanning of a folder in a database transaction
- * On default transactions are used
- *
- * @param bool $useTransactions
- */
- public function setUseTransactions($useTransactions) {
- $this->useTransactions = $useTransactions;
- }
-
- /**
- * get all the metadata of a file or folder
- * *
- *
- * @param string $path
- * @return array an array of metadata of the file
- */
- protected function getData($path) {
- $data = $this->storage->getMetaData($path);
- if (is_null($data)) {
- \OCP\Util::writeLog('OC\Files\Cache\Scanner', "!!! Path '$path' is not accessible or present !!!", \OCP\Util::DEBUG);
- }
- return $data;
- }
-
- /**
- * scan a single file and store it in the cache
- *
- * @param string $file
- * @param int $reuseExisting
- * @param int $parentId
- * @param array | null $cacheData existing data in the cache for the file to be scanned
- * @param bool $lock set to false to disable getting an additional read lock during scanning
- * @return array an array of metadata of the scanned file
- * @throws \OC\ServerNotAvailableException
- * @throws \OCP\Lock\LockedException
- */
- public function scanFile($file, $reuseExisting = 0, $parentId = -1, $cacheData = null, $lock = true) {
-
- // only proceed if $file is not a partial file nor a blacklisted file
- if (!self::isPartialFile($file) and !Filesystem::isFileBlacklisted($file)) {
-
- //acquire a lock
- if ($lock) {
- if ($this->storage->instanceOfStorage('\OCP\Files\Storage\ILockingStorage')) {
- $this->storage->acquireLock($file, ILockingProvider::LOCK_SHARED, $this->lockingProvider);
- }
- }
-
- $data = $this->getData($file);
-
- if ($data) {
-
- // pre-emit only if it was a file. By that we avoid counting/treating folders as files
- if ($data['mimetype'] !== 'httpd/unix-directory') {
- $this->emit('\OC\Files\Cache\Scanner', 'scanFile', array($file, $this->storageId));
- \OC_Hook::emit('\OC\Files\Cache\Scanner', 'scan_file', array('path' => $file, 'storage' => $this->storageId));
- }
-
- $parent = dirname($file);
- if ($parent === '.' or $parent === '/') {
- $parent = '';
- }
- if ($parentId === -1) {
- $parentId = $this->cache->getId($parent);
- }
-
- // scan the parent if it's not in the cache (id -1) and the current file is not the root folder
- if ($file and $parentId === -1) {
- $parentData = $this->scanFile($parent);
- $parentId = $parentData['fileid'];
- }
- if ($parent) {
- $data['parent'] = $parentId;
- }
- if (is_null($cacheData)) {
- /** @var CacheEntry $cacheData */
- $cacheData = $this->cache->get($file);
- }
- if ($cacheData and $reuseExisting and isset($cacheData['fileid'])) {
- // prevent empty etag
- if (empty($cacheData['etag'])) {
- $etag = $data['etag'];
- } else {
- $etag = $cacheData['etag'];
- }
- $fileId = $cacheData['fileid'];
- $data['fileid'] = $fileId;
- // only reuse data if the file hasn't explicitly changed
- if (isset($data['storage_mtime']) && isset($cacheData['storage_mtime']) && $data['storage_mtime'] === $cacheData['storage_mtime']) {
- $data['mtime'] = $cacheData['mtime'];
- if (($reuseExisting & self::REUSE_SIZE) && ($data['size'] === -1)) {
- $data['size'] = $cacheData['size'];
- }
- if ($reuseExisting & self::REUSE_ETAG) {
- $data['etag'] = $etag;
- }
- }
- // Only update metadata that has changed
- $newData = array_diff_assoc($data, $cacheData->getData());
- } else {
- $newData = $data;
- $fileId = -1;
- }
- if (!empty($newData)) {
- // Reset the checksum if the data has changed
- $newData['checksum'] = '';
- $data['fileid'] = $this->addToCache($file, $newData, $fileId);
- }
- if (isset($cacheData['size'])) {
- $data['oldSize'] = $cacheData['size'];
- } else {
- $data['oldSize'] = 0;
- }
-
- if (isset($cacheData['encrypted'])) {
- $data['encrypted'] = $cacheData['encrypted'];
- }
-
- // post-emit only if it was a file. By that we avoid counting/treating folders as files
- if ($data['mimetype'] !== 'httpd/unix-directory') {
- $this->emit('\OC\Files\Cache\Scanner', 'postScanFile', array($file, $this->storageId));
- \OC_Hook::emit('\OC\Files\Cache\Scanner', 'post_scan_file', array('path' => $file, 'storage' => $this->storageId));
- }
-
- } else {
- $this->removeFromCache($file);
- }
-
- //release the acquired lock
- if ($lock) {
- if ($this->storage->instanceOfStorage('\OCP\Files\Storage\ILockingStorage')) {
- $this->storage->releaseLock($file, ILockingProvider::LOCK_SHARED, $this->lockingProvider);
- }
- }
-
- if ($data && !isset($data['encrypted'])) {
- $data['encrypted'] = false;
- }
- return $data;
- }
-
- return null;
- }
-
- protected function removeFromCache($path) {
- \OC_Hook::emit('Scanner', 'removeFromCache', array('file' => $path));
- $this->emit('\OC\Files\Cache\Scanner', 'removeFromCache', array($path));
- if ($this->cacheActive) {
- $this->cache->remove($path);
- }
- }
-
- /**
- * @param string $path
- * @param array $data
- * @param int $fileId
- * @return int the id of the added file
- */
- protected function addToCache($path, $data, $fileId = -1) {
- \OC_Hook::emit('Scanner', 'addToCache', array('file' => $path, 'data' => $data));
- $this->emit('\OC\Files\Cache\Scanner', 'addToCache', array($path, $this->storageId, $data));
- if ($this->cacheActive) {
- if ($fileId !== -1) {
- $this->cache->update($fileId, $data);
- return $fileId;
- } else {
- return $this->cache->put($path, $data);
- }
- } else {
- return -1;
- }
- }
-
- /**
- * @param string $path
- * @param array $data
- * @param int $fileId
- */
- protected function updateCache($path, $data, $fileId = -1) {
- \OC_Hook::emit('Scanner', 'addToCache', array('file' => $path, 'data' => $data));
- $this->emit('\OC\Files\Cache\Scanner', 'updateCache', array($path, $this->storageId, $data));
- if ($this->cacheActive) {
- if ($fileId !== -1) {
- $this->cache->update($fileId, $data);
- } else {
- $this->cache->put($path, $data);
- }
- }
- }
-
- /**
- * scan a folder and all it's children
- *
- * @param string $path
- * @param bool $recursive
- * @param int $reuse
- * @param bool $lock set to false to disable getting an additional read lock during scanning
- * @return array an array of the meta data of the scanned file or folder
- */
- public function scan($path, $recursive = self::SCAN_RECURSIVE, $reuse = -1, $lock = true) {
- if ($reuse === -1) {
- $reuse = ($recursive === self::SCAN_SHALLOW) ? self::REUSE_ETAG | self::REUSE_SIZE : self::REUSE_ETAG;
- }
- if ($lock) {
- if ($this->storage->instanceOfStorage('\OCP\Files\Storage\ILockingStorage')) {
- $this->storage->acquireLock($path, ILockingProvider::LOCK_SHARED, $this->lockingProvider);
- }
- }
- $data = $this->scanFile($path, $reuse, -1, null, $lock);
- if ($data and $data['mimetype'] === 'httpd/unix-directory') {
- $size = $this->scanChildren($path, $recursive, $reuse, $data, $lock);
- $data['size'] = $size;
- }
- if ($lock) {
- if ($this->storage->instanceOfStorage('\OCP\Files\Storage\ILockingStorage')) {
- $this->storage->releaseLock($path, ILockingProvider::LOCK_SHARED, $this->lockingProvider);
- }
- }
- return $data;
- }
-
- /**
- * Get the children currently in the cache
- *
- * @param int $folderId
- * @return array[]
- */
- protected function getExistingChildren($folderId) {
- $existingChildren = array();
- $children = $this->cache->getFolderContentsById($folderId);
- foreach ($children as $child) {
- $existingChildren[$child['name']] = $child;
- }
- return $existingChildren;
- }
-
- /**
- * Get the children from the storage
- *
- * @param string $folder
- * @return string[]
- */
- protected function getNewChildren($folder) {
- $children = array();
- if ($dh = $this->storage->opendir($folder)) {
- if (is_resource($dh)) {
- while (($file = readdir($dh)) !== false) {
- if (!Filesystem::isIgnoredDir($file)) {
- $children[] = $file;
- }
- }
- }
- }
- return $children;
- }
-
- /**
- * scan all the files and folders in a folder
- *
- * @param string $path
- * @param bool $recursive
- * @param int $reuse
- * @param array $folderData existing cache data for the folder to be scanned
- * @param bool $lock set to false to disable getting an additional read lock during scanning
- * @return int the size of the scanned folder or -1 if the size is unknown at this stage
- */
- protected function scanChildren($path, $recursive = self::SCAN_RECURSIVE, $reuse = -1, $folderData = null, $lock = true) {
- if ($reuse === -1) {
- $reuse = ($recursive === self::SCAN_SHALLOW) ? self::REUSE_ETAG | self::REUSE_SIZE : self::REUSE_ETAG;
- }
- $this->emit('\OC\Files\Cache\Scanner', 'scanFolder', array($path, $this->storageId));
- $size = 0;
- $childQueue = array();
- if (is_array($folderData) and isset($folderData['fileid'])) {
- $folderId = $folderData['fileid'];
- } else {
- $folderId = $this->cache->getId($path);
- }
- $existingChildren = $this->getExistingChildren($folderId);
- $newChildren = $this->getNewChildren($path);
-
- if ($this->useTransactions) {
- \OC::$server->getDatabaseConnection()->beginTransaction();
- }
- $exceptionOccurred = false;
- foreach ($newChildren as $file) {
- $child = ($path) ? $path . '/' . $file : $file;
- try {
- $existingData = isset($existingChildren[$file]) ? $existingChildren[$file] : null;
- $data = $this->scanFile($child, $reuse, $folderId, $existingData, $lock);
- if ($data) {
- if ($data['mimetype'] === 'httpd/unix-directory' and $recursive === self::SCAN_RECURSIVE) {
- $childQueue[$child] = $data;
- } else if ($data['size'] === -1) {
- $size = -1;
- } else if ($size !== -1) {
- $size += $data['size'];
- }
- }
- } catch (\Doctrine\DBAL\DBALException $ex) {
- // might happen if inserting duplicate while a scanning
- // process is running in parallel
- // log and ignore
- \OCP\Util::writeLog('core', 'Exception while scanning file "' . $child . '": ' . $ex->getMessage(), \OCP\Util::DEBUG);
- $exceptionOccurred = true;
- } catch (\OCP\Lock\LockedException $e) {
- if ($this->useTransactions) {
- \OC::$server->getDatabaseConnection()->rollback();
- }
- throw $e;
- }
- }
- $removedChildren = \array_diff(array_keys($existingChildren), $newChildren);
- foreach ($removedChildren as $childName) {
- $child = ($path) ? $path . '/' . $childName : $childName;
- $this->removeFromCache($child);
- }
- if ($this->useTransactions) {
- \OC::$server->getDatabaseConnection()->commit();
- }
- if ($exceptionOccurred) {
- // It might happen that the parallel scan process has already
- // inserted mimetypes but those weren't available yet inside the transaction
- // To make sure to have the updated mime types in such cases,
- // we reload them here
- \OC::$server->getMimeTypeLoader()->reset();
- }
-
- foreach ($childQueue as $child => $childData) {
- $childSize = $this->scanChildren($child, self::SCAN_RECURSIVE, $reuse, $childData, $lock);
- if ($childSize === -1) {
- $size = -1;
- } else if ($size !== -1) {
- $size += $childSize;
- }
- }
- if (!is_array($folderData) or !isset($folderData['size']) or $folderData['size'] !== $size) {
- $this->updateCache($path, array('size' => $size), $folderId);
- }
- $this->emit('\OC\Files\Cache\Scanner', 'postScanFolder', array($path, $this->storageId));
- return $size;
- }
-
- /**
- * check if the file should be ignored when scanning
- * NOTE: files with a '.part' extension are ignored as well!
- * prevents unfinished put requests to be scanned
- *
- * @param string $file
- * @return boolean
- */
- public static function isPartialFile($file) {
- if (pathinfo($file, PATHINFO_EXTENSION) === 'part') {
- return true;
- }
- if (strpos($file, '.part/') !== false) {
- return true;
- }
-
- return false;
- }
-
- /**
- * walk over any folders that are not fully scanned yet and scan them
- */
- public function backgroundScan() {
- if (!$this->cache->inCache('')) {
- $this->runBackgroundScanJob(function () {
- $this->scan('', self::SCAN_RECURSIVE, self::REUSE_ETAG);
- }, '');
- } else {
- $lastPath = null;
- while (($path = $this->cache->getIncomplete()) !== false && $path !== $lastPath) {
- $this->runBackgroundScanJob(function() use ($path) {
- $this->scan($path, self::SCAN_RECURSIVE, self::REUSE_ETAG);
- }, $path);
- // FIXME: this won't proceed with the next item, needs revamping of getIncomplete()
- // to make this possible
- $lastPath = $path;
- }
- }
- }
-
- private function runBackgroundScanJob(callable $callback, $path) {
- try {
- $callback();
- \OC_Hook::emit('Scanner', 'correctFolderSize', array('path' => $path));
- if ($this->cacheActive) {
- $this->cache->correctFolderSize($path);
- }
- } catch (\OCP\Files\StorageInvalidException $e) {
- // skip unavailable storages
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- // skip unavailable storages
- } catch (\OCP\Files\ForbiddenException $e) {
- // skip forbidden storages
- } catch (\OCP\Lock\LockedException $e) {
- // skip unavailable storages
- }
- }
-
- /**
- * Set whether the cache is affected by scan operations
- *
- * @param boolean $active The active state of the cache
- */
- public function setCacheActive($active) {
- $this->cacheActive = $active;
- }
-}
diff --git a/lib/private/files/cache/storage.php b/lib/private/files/cache/storage.php
deleted file mode 100644
index 90c451ecc21..00000000000
--- a/lib/private/files/cache/storage.php
+++ /dev/null
@@ -1,189 +0,0 @@
-<?php
-/**
- * @author Joas Schilling <nickvergessen@owncloud.com>
- * @author Jörn Friedrich Dreyer <jfd@butonic.de>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <icewind@owncloud.com>
- * @author Robin McCorkell <robin@mccorkell.me.uk>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- * @author Vincent Petry <pvince81@owncloud.com>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OC\Files\Cache;
-
-/**
- * Handle the mapping between the string and numeric storage ids
- *
- * Each storage has 2 different ids
- * a string id which is generated by the storage backend and reflects the configuration of the storage (e.g. 'smb://user@host/share')
- * and a numeric storage id which is referenced in the file cache
- *
- * A mapping between the two storage ids is stored in the database and accessible trough this class
- *
- * @package OC\Files\Cache
- */
-class Storage {
- private $storageId;
- private $numericId;
-
- /**
- * @param \OC\Files\Storage\Storage|string $storage
- * @param bool $isAvailable
- * @throws \RuntimeException
- */
- public function __construct($storage, $isAvailable = true) {
- if ($storage instanceof \OC\Files\Storage\Storage) {
- $this->storageId = $storage->getId();
- } else {
- $this->storageId = $storage;
- }
- $this->storageId = self::adjustStorageId($this->storageId);
-
- if ($row = self::getStorageById($this->storageId)) {
- $this->numericId = $row['numeric_id'];
- } else {
- $connection = \OC::$server->getDatabaseConnection();
- $available = $isAvailable ? 1 : 0;
- if ($connection->insertIfNotExist('*PREFIX*storages', ['id' => $this->storageId, 'available' => $available])) {
- $this->numericId = $connection->lastInsertId('*PREFIX*storages');
- } else {
- if ($row = self::getStorageById($this->storageId)) {
- $this->numericId = $row['numeric_id'];
- } else {
- throw new \RuntimeException('Storage could neither be inserted nor be selected from the database');
- }
- }
- }
- }
-
- /**
- * @param string $storageId
- * @return array|null
- */
- public static function getStorageById($storageId) {
- $sql = 'SELECT * FROM `*PREFIX*storages` WHERE `id` = ?';
- $result = \OC_DB::executeAudited($sql, array($storageId));
- return $result->fetchRow();
- }
-
- /**
- * Adjusts the storage id to use md5 if too long
- * @param string $storageId storage id
- * @return string unchanged $storageId if its length is less than 64 characters,
- * else returns the md5 of $storageId
- */
- public static function adjustStorageId($storageId) {
- if (strlen($storageId) > 64) {
- return md5($storageId);
- }
- return $storageId;
- }
-
- /**
- * Get the numeric id for the storage
- *
- * @return int
- */
- public function getNumericId() {
- return $this->numericId;
- }
-
- /**
- * Get the string id for the storage
- *
- * @param int $numericId
- * @return string|null either the storage id string or null if the numeric id is not known
- */
- public static function getStorageId($numericId) {
-
- $sql = 'SELECT `id` FROM `*PREFIX*storages` WHERE `numeric_id` = ?';
- $result = \OC_DB::executeAudited($sql, array($numericId));
- if ($row = $result->fetchRow()) {
- return $row['id'];
- } else {
- return null;
- }
- }
-
- /**
- * Get the numeric of the storage with the provided string id
- *
- * @param $storageId
- * @return int|null either the numeric storage id or null if the storage id is not knwon
- */
- public static function getNumericStorageId($storageId) {
- $storageId = self::adjustStorageId($storageId);
-
- if ($row = self::getStorageById($storageId)) {
- return $row['numeric_id'];
- } else {
- return null;
- }
- }
-
- /**
- * @return array|null [ available, last_checked ]
- */
- public function getAvailability() {
- if ($row = self::getStorageById($this->storageId)) {
- return [
- 'available' => ((int)$row['available'] === 1),
- 'last_checked' => $row['last_checked']
- ];
- } else {
- return null;
- }
- }
-
- /**
- * @param bool $isAvailable
- */
- public function setAvailability($isAvailable) {
- $sql = 'UPDATE `*PREFIX*storages` SET `available` = ?, `last_checked` = ? WHERE `id` = ?';
- $available = $isAvailable ? 1 : 0;
- \OC_DB::executeAudited($sql, array($available, time(), $this->storageId));
- }
-
- /**
- * Check if a string storage id is known
- *
- * @param string $storageId
- * @return bool
- */
- public static function exists($storageId) {
- return !is_null(self::getNumericStorageId($storageId));
- }
-
- /**
- * remove the entry for the storage
- *
- * @param string $storageId
- */
- public static function remove($storageId) {
- $storageId = self::adjustStorageId($storageId);
- $numericId = self::getNumericStorageId($storageId);
- $sql = 'DELETE FROM `*PREFIX*storages` WHERE `id` = ?';
- \OC_DB::executeAudited($sql, array($storageId));
-
- if (!is_null($numericId)) {
- $sql = 'DELETE FROM `*PREFIX*filecache` WHERE `storage` = ?';
- \OC_DB::executeAudited($sql, array($numericId));
- }
- }
-}
diff --git a/lib/private/files/cache/updater.php b/lib/private/files/cache/updater.php
deleted file mode 100644
index 3f80f2b6167..00000000000
--- a/lib/private/files/cache/updater.php
+++ /dev/null
@@ -1,228 +0,0 @@
-<?php
-/**
- * @author Björn Schießle <schiessle@owncloud.com>
- * @author Michael Gapczynski <GapczynskiM@gmail.com>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <icewind@owncloud.com>
- * @author Vincent Petry <pvince81@owncloud.com>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OC\Files\Cache;
-use OCP\Files\Cache\IUpdater;
-use OCP\Files\Storage\IStorage;
-
-/**
- * Update the cache and propagate changes
- *
- */
-class Updater implements IUpdater {
- /**
- * @var bool
- */
- protected $enabled = true;
-
- /**
- * @var \OC\Files\Storage\Storage
- */
- protected $storage;
-
- /**
- * @var \OC\Files\Cache\Propagator
- */
- protected $propagator;
-
- /**
- * @var Scanner
- */
- protected $scanner;
-
- /**
- * @var Cache
- */
- protected $cache;
-
- /**
- * @param \OC\Files\Storage\Storage $storage
- */
- public function __construct(\OC\Files\Storage\Storage $storage) {
- $this->storage = $storage;
- $this->propagator = $storage->getPropagator();
- $this->scanner = $storage->getScanner();
- $this->cache = $storage->getCache();
- }
-
- /**
- * Disable updating the cache trough this updater
- */
- public function disable() {
- $this->enabled = false;
- }
-
- /**
- * Re-enable the updating of the cache trough this updater
- */
- public function enable() {
- $this->enabled = true;
- }
-
- /**
- * Get the propagator for etags and mtime for the view the updater works on
- *
- * @return Propagator
- */
- public function getPropagator() {
- return $this->propagator;
- }
-
- /**
- * Propagate etag and mtime changes for the parent folders of $path up to the root of the filesystem
- *
- * @param string $path the path of the file to propagate the changes for
- * @param int|null $time the timestamp to set as mtime for the parent folders, if left out the current time is used
- */
- public function propagate($path, $time = null) {
- if (Scanner::isPartialFile($path)) {
- return;
- }
- $this->propagator->propagateChange($path, $time);
- }
-
- /**
- * Update the cache for $path and update the size, etag and mtime of the parent folders
- *
- * @param string $path
- * @param int $time
- */
- public function update($path, $time = null) {
- if (!$this->enabled or Scanner::isPartialFile($path)) {
- return;
- }
- if (is_null($time)) {
- $time = time();
- }
-
- $data = $this->scanner->scan($path, Scanner::SCAN_SHALLOW, -1, false);
- if (
- isset($data['oldSize']) && isset($data['size']) &&
- !$data['encrypted'] // encryption is a pita and touches the cache itself
- ) {
- $sizeDifference = $data['size'] - $data['oldSize'];
- } else {
- // scanner didn't provide size info, fallback to full size calculation
- $sizeDifference = 0;
- $this->cache->correctFolderSize($path, $data);
- }
- $this->correctParentStorageMtime($path);
- $this->propagator->propagateChange($path, $time, $sizeDifference);
- }
-
- /**
- * Remove $path from the cache and update the size, etag and mtime of the parent folders
- *
- * @param string $path
- */
- public function remove($path) {
- if (!$this->enabled or Scanner::isPartialFile($path)) {
- return;
- }
-
- $parent = dirname($path);
- if ($parent === '.') {
- $parent = '';
- }
-
- $this->cache->remove($path);
- $this->cache->correctFolderSize($parent);
- $this->correctParentStorageMtime($path);
- $this->propagator->propagateChange($path, time());
- }
-
- /**
- * Rename a file or folder in the cache and update the size, etag and mtime of the parent folders
- *
- * @param IStorage $sourceStorage
- * @param string $source
- * @param string $target
- */
- public function renameFromStorage(IStorage $sourceStorage, $source, $target) {
- if (!$this->enabled or Scanner::isPartialFile($source) or Scanner::isPartialFile($target)) {
- return;
- }
-
- $time = time();
-
- $sourceCache = $sourceStorage->getCache();
- $sourceUpdater = $sourceStorage->getUpdater();
- $sourcePropagator = $sourceStorage->getPropagator();
-
- if ($sourceCache->inCache($source)) {
- if ($this->cache->inCache($target)) {
- $this->cache->remove($target);
- }
-
- if ($sourceStorage === $this->storage) {
- $this->cache->move($source, $target);
- } else {
- $this->cache->moveFromCache($sourceCache, $source, $target);
- }
- }
-
- if (pathinfo($source, PATHINFO_EXTENSION) !== pathinfo($target, PATHINFO_EXTENSION)) {
- // handle mime type change
- $mimeType = $this->storage->getMimeType($target);
- $fileId = $this->cache->getId($target);
- $this->cache->update($fileId, ['mimetype' => $mimeType]);
- }
-
- $sourceCache->correctFolderSize($source);
- $this->cache->correctFolderSize($target);
- if ($sourceUpdater instanceof Updater) {
- $sourceUpdater->correctParentStorageMtime($source);
- }
- $this->correctParentStorageMtime($target);
- $this->updateStorageMTimeOnly($target);
- $sourcePropagator->propagateChange($source, $time);
- $this->propagator->propagateChange($target, $time);
- }
-
- private function updateStorageMTimeOnly($internalPath) {
- $fileId = $this->cache->getId($internalPath);
- if ($fileId !== -1) {
- $this->cache->update(
- $fileId, [
- 'mtime' => null, // this magic tells it to not overwrite mtime
- 'storage_mtime' => $this->storage->filemtime($internalPath)
- ]
- );
- }
- }
-
- /**
- * update the storage_mtime of the direct parent in the cache to the mtime from the storage
- *
- * @param string $internalPath
- */
- private function correctParentStorageMtime($internalPath) {
- $parentId = $this->cache->getParentId($internalPath);
- $parent = dirname($internalPath);
- if ($parentId != -1) {
- $this->cache->update($parentId, array('storage_mtime' => $this->storage->filemtime($parent)));
- }
- }
-}
diff --git a/lib/private/files/cache/watcher.php b/lib/private/files/cache/watcher.php
deleted file mode 100644
index a00e875a2d4..00000000000
--- a/lib/private/files/cache/watcher.php
+++ /dev/null
@@ -1,140 +0,0 @@
-<?php
-/**
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <icewind@owncloud.com>
- * @author Vincent Petry <pvince81@owncloud.com>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OC\Files\Cache;
-use OCP\Files\Cache\ICacheEntry;
-use OCP\Files\Cache\IWatcher;
-
-/**
- * check the storage backends for updates and change the cache accordingly
- */
-class Watcher implements IWatcher {
-
- protected $watchPolicy = self::CHECK_ONCE;
-
- protected $checkedPaths = array();
-
- /**
- * @var \OC\Files\Storage\Storage $storage
- */
- protected $storage;
-
- /**
- * @var Cache $cache
- */
- protected $cache;
-
- /**
- * @var Scanner $scanner ;
- */
- protected $scanner;
-
- /**
- * @param \OC\Files\Storage\Storage $storage
- */
- public function __construct(\OC\Files\Storage\Storage $storage) {
- $this->storage = $storage;
- $this->cache = $storage->getCache();
- $this->scanner = $storage->getScanner();
- }
-
- /**
- * @param int $policy either \OC\Files\Cache\Watcher::CHECK_NEVER, \OC\Files\Cache\Watcher::CHECK_ONCE, \OC\Files\Cache\Watcher::CHECK_ALWAYS
- */
- public function setPolicy($policy) {
- $this->watchPolicy = $policy;
- }
-
- /**
- * @return int either \OC\Files\Cache\Watcher::CHECK_NEVER, \OC\Files\Cache\Watcher::CHECK_ONCE, \OC\Files\Cache\Watcher::CHECK_ALWAYS
- */
- public function getPolicy() {
- return $this->watchPolicy;
- }
-
- /**
- * check $path for updates and update if needed
- *
- * @param string $path
- * @param ICacheEntry|null $cachedEntry
- * @return boolean true if path was updated
- */
- public function checkUpdate($path, $cachedEntry = null) {
- if (is_null($cachedEntry)) {
- $cachedEntry = $this->cache->get($path);
- }
- if ($this->needsUpdate($path, $cachedEntry)) {
- $this->update($path, $cachedEntry);
- return true;
- } else {
- return false;
- }
- }
-
- /**
- * Update the cache for changes to $path
- *
- * @param string $path
- * @param ICacheEntry $cachedData
- */
- public function update($path, $cachedData) {
- if ($this->storage->is_dir($path)) {
- $this->scanner->scan($path, Scanner::SCAN_SHALLOW);
- } else {
- $this->scanner->scanFile($path);
- }
- if ($cachedData['mimetype'] === 'httpd/unix-directory') {
- $this->cleanFolder($path);
- }
- $this->cache->correctFolderSize($path);
- }
-
- /**
- * Check if the cache for $path needs to be updated
- *
- * @param string $path
- * @param ICacheEntry $cachedData
- * @return bool
- */
- public function needsUpdate($path, $cachedData) {
- if ($this->watchPolicy === self::CHECK_ALWAYS or ($this->watchPolicy === self::CHECK_ONCE and array_search($path, $this->checkedPaths) === false)) {
- $this->checkedPaths[] = $path;
- return $this->storage->hasUpdated($path, $cachedData['storage_mtime']);
- }
- return false;
- }
-
- /**
- * remove deleted files in $path from the cache
- *
- * @param string $path
- */
- public function cleanFolder($path) {
- $cachedContent = $this->cache->getFolderContents($path);
- foreach ($cachedContent as $entry) {
- if (!$this->storage->file_exists($entry['path'])) {
- $this->cache->remove($entry['path']);
- }
- }
- }
-}
diff --git a/lib/private/files/cache/wrapper/cachejail.php b/lib/private/files/cache/wrapper/cachejail.php
deleted file mode 100644
index 88b0f23a1fc..00000000000
--- a/lib/private/files/cache/wrapper/cachejail.php
+++ /dev/null
@@ -1,300 +0,0 @@
-<?php
-/**
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <icewind@owncloud.com>
- * @author Robin McCorkell <robin@mccorkell.me.uk>
- * @author Vincent Petry <pvince81@owncloud.com>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OC\Files\Cache\Wrapper;
-
-/**
- * Jail to a subdirectory of the wrapped cache
- */
-class CacheJail extends CacheWrapper {
- /**
- * @var string
- */
- protected $root;
-
- /**
- * @param \OCP\Files\Cache\ICache $cache
- * @param string $root
- */
- public function __construct($cache, $root) {
- parent::__construct($cache);
- $this->root = $root;
- }
-
- protected function getSourcePath($path) {
- if ($path === '') {
- return $this->root;
- } else {
- return $this->root . '/' . ltrim($path, '/');
- }
- }
-
- /**
- * @param string $path
- * @return null|string the jailed path or null if the path is outside the jail
- */
- protected function getJailedPath($path) {
- $rootLength = strlen($this->root) + 1;
- if ($path === $this->root) {
- return '';
- } else if (substr($path, 0, $rootLength) === $this->root . '/') {
- return substr($path, $rootLength);
- } else {
- return null;
- }
- }
-
- /**
- * @param array $entry
- * @return array
- */
- protected function formatCacheEntry($entry) {
- if (isset($entry['path'])) {
- $entry['path'] = $this->getJailedPath($entry['path']);
- }
- return $entry;
- }
-
- protected function filterCacheEntry($entry) {
- $rootLength = strlen($this->root) + 1;
- return ($entry['path'] === $this->root) or (substr($entry['path'], 0, $rootLength) === $this->root . '/');
- }
-
- /**
- * get the stored metadata of a file or folder
- *
- * @param string /int $file
- * @return array|false
- */
- public function get($file) {
- if (is_string($file) or $file == '') {
- $file = $this->getSourcePath($file);
- }
- return parent::get($file);
- }
-
- /**
- * insert meta data for a new file or folder
- *
- * @param string $file
- * @param array $data
- *
- * @return int file id
- * @throws \RuntimeException
- */
- public function insert($file, array $data) {
- return $this->cache->insert($this->getSourcePath($file), $data);
- }
-
- /**
- * update the metadata in the cache
- *
- * @param int $id
- * @param array $data
- */
- public function update($id, array $data) {
- $this->cache->update($id, $data);
- }
-
- /**
- * get the file id for a file
- *
- * @param string $file
- * @return int
- */
- public function getId($file) {
- return $this->cache->getId($this->getSourcePath($file));
- }
-
- /**
- * get the id of the parent folder of a file
- *
- * @param string $file
- * @return int
- */
- public function getParentId($file) {
- if ($file === '') {
- return -1;
- } else {
- return $this->cache->getParentId($this->getSourcePath($file));
- }
- }
-
- /**
- * check if a file is available in the cache
- *
- * @param string $file
- * @return bool
- */
- public function inCache($file) {
- return $this->cache->inCache($this->getSourcePath($file));
- }
-
- /**
- * remove a file or folder from the cache
- *
- * @param string $file
- */
- public function remove($file) {
- $this->cache->remove($this->getSourcePath($file));
- }
-
- /**
- * Move a file or folder in the cache
- *
- * @param string $source
- * @param string $target
- */
- public function move($source, $target) {
- $this->cache->move($this->getSourcePath($source), $this->getSourcePath($target));
- }
-
- /**
- * remove all entries for files that are stored on the storage from the cache
- */
- public function clear() {
- $this->cache->remove($this->root);
- }
-
- /**
- * @param string $file
- *
- * @return int Cache::NOT_FOUND, Cache::PARTIAL, Cache::SHALLOW or Cache::COMPLETE
- */
- public function getStatus($file) {
- return $this->cache->getStatus($this->getSourcePath($file));
- }
-
- private function formatSearchResults($results) {
- $results = array_filter($results, array($this, 'filterCacheEntry'));
- $results = array_values($results);
- return array_map(array($this, 'formatCacheEntry'), $results);
- }
-
- /**
- * search for files matching $pattern
- *
- * @param string $pattern
- * @return array an array of file data
- */
- public function search($pattern) {
- $results = $this->cache->search($pattern);
- return $this->formatSearchResults($results);
- }
-
- /**
- * search for files by mimetype
- *
- * @param string $mimetype
- * @return array
- */
- public function searchByMime($mimetype) {
- $results = $this->cache->searchByMime($mimetype);
- return $this->formatSearchResults($results);
- }
-
- /**
- * search for files by mimetype
- *
- * @param string|int $tag name or tag id
- * @param string $userId owner of the tags
- * @return array
- */
- public function searchByTag($tag, $userId) {
- $results = $this->cache->searchByTag($tag, $userId);
- return $this->formatSearchResults($results);
- }
-
- /**
- * update the folder size and the size of all parent folders
- *
- * @param string|boolean $path
- * @param array $data (optional) meta data of the folder
- */
- public function correctFolderSize($path, $data = null) {
- $this->cache->correctFolderSize($this->getSourcePath($path), $data);
- }
-
- /**
- * get the size of a folder and set it in the cache
- *
- * @param string $path
- * @param array $entry (optional) meta data of the folder
- * @return int
- */
- public function calculateFolderSize($path, $entry = null) {
- return $this->cache->calculateFolderSize($this->getSourcePath($path), $entry);
- }
-
- /**
- * get all file ids on the files on the storage
- *
- * @return int[]
- */
- public function getAll() {
- // not supported
- return array();
- }
-
- /**
- * find a folder in the cache which has not been fully scanned
- *
- * If multiply incomplete folders are in the cache, the one with the highest id will be returned,
- * use the one with the highest id gives the best result with the background scanner, since that is most
- * likely the folder where we stopped scanning previously
- *
- * @return string|bool the path of the folder or false when no folder matched
- */
- public function getIncomplete() {
- // not supported
- return false;
- }
-
- /**
- * get the path of a file on this storage by it's id
- *
- * @param int $id
- * @return string|null
- */
- public function getPathById($id) {
- $path = $this->cache->getPathById($id);
- return $this->getJailedPath($path);
- }
-
- /**
- * Move a file or folder in the cache
- *
- * Note that this should make sure the entries are removed from the source cache
- *
- * @param \OCP\Files\Cache\ICache $sourceCache
- * @param string $sourcePath
- * @param string $targetPath
- */
- public function moveFromCache(\OCP\Files\Cache\ICache $sourceCache, $sourcePath, $targetPath) {
- if ($sourceCache === $this) {
- return $this->move($sourcePath, $targetPath);
- }
- return $this->cache->moveFromCache($sourceCache, $sourcePath, $targetPath);
- }
-}
diff --git a/lib/private/files/cache/wrapper/cachepermissionsmask.php b/lib/private/files/cache/wrapper/cachepermissionsmask.php
deleted file mode 100644
index b3a7bcb3a73..00000000000
--- a/lib/private/files/cache/wrapper/cachepermissionsmask.php
+++ /dev/null
@@ -1,46 +0,0 @@
-<?php
-/**
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <icewind@owncloud.com>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OC\Files\Cache\Wrapper;
-
-class CachePermissionsMask extends CacheWrapper {
- /**
- * @var int
- */
- protected $mask;
-
- /**
- * @param \OCP\Files\Cache\ICache $cache
- * @param int $mask
- */
- public function __construct($cache, $mask) {
- parent::__construct($cache);
- $this->mask = $mask;
- }
-
- protected function formatCacheEntry($entry) {
- if (isset($entry['permissions'])) {
- $entry['permissions'] &= $this->mask;
- }
- return $entry;
- }
-}
diff --git a/lib/private/files/cache/wrapper/cachewrapper.php b/lib/private/files/cache/wrapper/cachewrapper.php
deleted file mode 100644
index 8c77e3c340e..00000000000
--- a/lib/private/files/cache/wrapper/cachewrapper.php
+++ /dev/null
@@ -1,309 +0,0 @@
-<?php
-/**
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <icewind@owncloud.com>
- * @author Robin McCorkell <robin@mccorkell.me.uk>
- * @author Vincent Petry <pvince81@owncloud.com>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OC\Files\Cache\Wrapper;
-
-use OC\Files\Cache\Cache;
-use OCP\Files\Cache\ICacheEntry;
-use OCP\Files\Cache\ICache;
-
-class CacheWrapper extends Cache {
- /**
- * @var \OCP\Files\Cache\ICache
- */
- protected $cache;
-
- /**
- * @param \OCP\Files\Cache\ICache $cache
- */
- public function __construct($cache) {
- $this->cache = $cache;
- }
-
- /**
- * Make it easy for wrappers to modify every returned cache entry
- *
- * @param ICacheEntry $entry
- * @return ICacheEntry
- */
- protected function formatCacheEntry($entry) {
- return $entry;
- }
-
- /**
- * get the stored metadata of a file or folder
- *
- * @param string|int $file
- * @return ICacheEntry|false
- */
- public function get($file) {
- $result = $this->cache->get($file);
- if ($result) {
- $result = $this->formatCacheEntry($result);
- }
- return $result;
- }
-
- /**
- * get the metadata of all files stored in $folder
- *
- * @param string $folder
- * @return ICacheEntry[]
- */
- public function getFolderContents($folder) {
- // can't do a simple $this->cache->.... call here since getFolderContentsById needs to be called on this
- // and not the wrapped cache
- $fileId = $this->getId($folder);
- return $this->getFolderContentsById($fileId);
- }
-
- /**
- * get the metadata of all files stored in $folder
- *
- * @param int $fileId the file id of the folder
- * @return array
- */
- public function getFolderContentsById($fileId) {
- $results = $this->cache->getFolderContentsById($fileId);
- return array_map(array($this, 'formatCacheEntry'), $results);
- }
-
- /**
- * insert or update meta data for a file or folder
- *
- * @param string $file
- * @param array $data
- *
- * @return int file id
- * @throws \RuntimeException
- */
- public function put($file, array $data) {
- if (($id = $this->getId($file)) > -1) {
- $this->update($id, $data);
- return $id;
- } else {
- return $this->insert($file, $data);
- }
- }
-
- /**
- * insert meta data for a new file or folder
- *
- * @param string $file
- * @param array $data
- *
- * @return int file id
- * @throws \RuntimeException
- */
- public function insert($file, array $data) {
- return $this->cache->insert($file, $data);
- }
-
- /**
- * update the metadata in the cache
- *
- * @param int $id
- * @param array $data
- */
- public function update($id, array $data) {
- $this->cache->update($id, $data);
- }
-
- /**
- * get the file id for a file
- *
- * @param string $file
- * @return int
- */
- public function getId($file) {
- return $this->cache->getId($file);
- }
-
- /**
- * get the id of the parent folder of a file
- *
- * @param string $file
- * @return int
- */
- public function getParentId($file) {
- return $this->cache->getParentId($file);
- }
-
- /**
- * check if a file is available in the cache
- *
- * @param string $file
- * @return bool
- */
- public function inCache($file) {
- return $this->cache->inCache($file);
- }
-
- /**
- * remove a file or folder from the cache
- *
- * @param string $file
- */
- public function remove($file) {
- $this->cache->remove($file);
- }
-
- /**
- * Move a file or folder in the cache
- *
- * @param string $source
- * @param string $target
- */
- public function move($source, $target) {
- $this->cache->move($source, $target);
- }
-
- public function moveFromCache(ICache $sourceCache, $sourcePath, $targetPath) {
- $this->cache->moveFromCache($sourceCache, $sourcePath, $targetPath);
- }
-
- /**
- * remove all entries for files that are stored on the storage from the cache
- */
- public function clear() {
- $this->cache->clear();
- }
-
- /**
- * @param string $file
- *
- * @return int Cache::NOT_FOUND, Cache::PARTIAL, Cache::SHALLOW or Cache::COMPLETE
- */
- public function getStatus($file) {
- return $this->cache->getStatus($file);
- }
-
- /**
- * search for files matching $pattern
- *
- * @param string $pattern
- * @return ICacheEntry[] an array of file data
- */
- public function search($pattern) {
- $results = $this->cache->search($pattern);
- return array_map(array($this, 'formatCacheEntry'), $results);
- }
-
- /**
- * search for files by mimetype
- *
- * @param string $mimetype
- * @return ICacheEntry[]
- */
- public function searchByMime($mimetype) {
- $results = $this->cache->searchByMime($mimetype);
- return array_map(array($this, 'formatCacheEntry'), $results);
- }
-
- /**
- * search for files by tag
- *
- * @param string|int $tag name or tag id
- * @param string $userId owner of the tags
- * @return ICacheEntry[] file data
- */
- public function searchByTag($tag, $userId) {
- $results = $this->cache->searchByTag($tag, $userId);
- return array_map(array($this, 'formatCacheEntry'), $results);
- }
-
- /**
- * update the folder size and the size of all parent folders
- *
- * @param string|boolean $path
- * @param array $data (optional) meta data of the folder
- */
- public function correctFolderSize($path, $data = null) {
- $this->cache->correctFolderSize($path, $data);
- }
-
- /**
- * get the size of a folder and set it in the cache
- *
- * @param string $path
- * @param array $entry (optional) meta data of the folder
- * @return int
- */
- public function calculateFolderSize($path, $entry = null) {
- return $this->cache->calculateFolderSize($path, $entry);
- }
-
- /**
- * get all file ids on the files on the storage
- *
- * @return int[]
- */
- public function getAll() {
- return $this->cache->getAll();
- }
-
- /**
- * find a folder in the cache which has not been fully scanned
- *
- * If multiple incomplete folders are in the cache, the one with the highest id will be returned,
- * use the one with the highest id gives the best result with the background scanner, since that is most
- * likely the folder where we stopped scanning previously
- *
- * @return string|bool the path of the folder or false when no folder matched
- */
- public function getIncomplete() {
- return $this->cache->getIncomplete();
- }
-
- /**
- * get the path of a file on this storage by it's id
- *
- * @param int $id
- * @return string|null
- */
- public function getPathById($id) {
- return $this->cache->getPathById($id);
- }
-
- /**
- * Returns the numeric storage id
- *
- * @return int
- */
- public function getNumericStorageId() {
- return $this->cache->getNumericStorageId();
- }
-
- /**
- * get the storage id of the storage for a file and the internal path of the file
- * unlike getPathById this does not limit the search to files on this storage and
- * instead does a global search in the cache table
- *
- * @param int $id
- * @return array first element holding the storage id, second the path
- */
- static public function getById($id) {
- return parent::getById($id);
- }
-}
diff --git a/lib/private/files/config/cachedmountinfo.php b/lib/private/files/config/cachedmountinfo.php
deleted file mode 100644
index ce75cb66896..00000000000
--- a/lib/private/files/config/cachedmountinfo.php
+++ /dev/null
@@ -1,107 +0,0 @@
-<?php
-/**
- * @author Robin Appelman <icewind@owncloud.com>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OC\Files\Config;
-
-use OC\Files\Filesystem;
-use OCP\Files\Config\ICachedMountInfo;
-use OCP\Files\Node;
-use OCP\IUser;
-
-class CachedMountInfo implements ICachedMountInfo {
- /**
- * @var IUser
- */
- protected $user;
-
- /**
- * @var int
- */
- protected $storageId;
-
- /**
- * @var int
- */
- protected $rootId;
-
- /**
- * @var string
- */
- protected $mountPoint;
-
- /**
- * CachedMountInfo constructor.
- *
- * @param IUser $user
- * @param int $storageId
- * @param int $rootId
- * @param string $mountPoint
- */
- public function __construct(IUser $user, $storageId, $rootId, $mountPoint) {
- $this->user = $user;
- $this->storageId = $storageId;
- $this->rootId = $rootId;
- $this->mountPoint = $mountPoint;
- }
-
- /**
- * @return IUser
- */
- public function getUser() {
- return $this->user;
- }
-
- /**
- * @return int the numeric storage id of the mount
- */
- public function getStorageId() {
- return $this->storageId;
- }
-
- /**
- * @return int the fileid of the root of the mount
- */
- public function getRootId() {
- return $this->rootId;
- }
-
- /**
- * @return Node the root node of the mount
- */
- public function getMountPointNode() {
- // TODO injection etc
- Filesystem::initMountPoints($this->getUser()->getUID());
- $userNode = \OC::$server->getUserFolder($this->getUser()->getUID());
- $nodes = $userNode->getById($this->getRootId());
- if (count($nodes) > 0) {
- return $nodes[0];
- } else {
- return null;
- }
- }
-
- /**
- * @return string the mount point of the mount for the user
- */
- public function getMountPoint() {
- return $this->mountPoint;
- }
-}
diff --git a/lib/private/files/config/lazystoragemountinfo.php b/lib/private/files/config/lazystoragemountinfo.php
deleted file mode 100644
index 654c5b2b23e..00000000000
--- a/lib/private/files/config/lazystoragemountinfo.php
+++ /dev/null
@@ -1,74 +0,0 @@
-<?php
-/**
- * @author Robin Appelman <icewind@owncloud.com>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OC\Files\Config;
-
-use OC\Files\Filesystem;
-use OCP\Files\Config\ICachedMountInfo;
-use OCP\Files\Mount\IMountPoint;
-use OCP\Files\Node;
-use OCP\IUser;
-
-class LazyStorageMountInfo extends CachedMountInfo {
- /** @var IMountPoint */
- private $mount;
-
- /**
- * CachedMountInfo constructor.
- *
- * @param IUser $user
- * @param IMountPoint $mount
- */
- public function __construct(IUser $user, IMountPoint $mount) {
- $this->user = $user;
- $this->mount = $mount;
- }
-
- /**
- * @return int the numeric storage id of the mount
- */
- public function getStorageId() {
- if (!$this->storageId) {
- $this->storageId = $this->mount->getStorage()->getStorageCache()->getNumericId();
- }
- return parent::getStorageId();
- }
-
- /**
- * @return int the fileid of the root of the mount
- */
- public function getRootId() {
- if (!$this->rootId) {
- $this->rootId = $this->mount->getStorageRootId();
- }
- return parent::getRootId();
- }
-
- /**
- * @return string the mount point of the mount for the user
- */
- public function getMountPoint() {
- if (!$this->mountPoint) {
- $this->mountPoint = $this->mount->getMountPoint();
- }
- return parent::getMountPoint();
- }
-}
diff --git a/lib/private/files/config/mountprovidercollection.php b/lib/private/files/config/mountprovidercollection.php
deleted file mode 100644
index 499fa576fbc..00000000000
--- a/lib/private/files/config/mountprovidercollection.php
+++ /dev/null
@@ -1,108 +0,0 @@
-<?php
-/**
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <icewind@owncloud.com>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OC\Files\Config;
-
-use OC\Hooks\Emitter;
-use OC\Hooks\EmitterTrait;
-use OCP\Files\Config\IMountProviderCollection;
-use OCP\Files\Config\IMountProvider;
-use OCP\Files\Config\IUserMountCache;
-use OCP\Files\Mount\IMountPoint;
-use OCP\Files\Storage\IStorageFactory;
-use OCP\IUser;
-
-class MountProviderCollection implements IMountProviderCollection, Emitter {
- use EmitterTrait;
-
- /**
- * @var \OCP\Files\Config\IMountProvider[]
- */
- private $providers = array();
-
- /**
- * @var \OCP\Files\Storage\IStorageFactory
- */
- private $loader;
-
- /**
- * @var \OCP\Files\Config\IUserMountCache
- */
- private $mountCache;
-
- /**
- * @param \OCP\Files\Storage\IStorageFactory $loader
- * @param IUserMountCache $mountCache
- */
- public function __construct(IStorageFactory $loader, IUserMountCache $mountCache) {
- $this->loader = $loader;
- $this->mountCache = $mountCache;
- }
-
- /**
- * Get all configured mount points for the user
- *
- * @param \OCP\IUser $user
- * @return \OCP\Files\Mount\IMountPoint[]
- */
- public function getMountsForUser(IUser $user) {
- $loader = $this->loader;
- $mounts = array_map(function (IMountProvider $provider) use ($user, $loader) {
- return $provider->getMountsForUser($user, $loader);
- }, $this->providers);
- $mounts = array_filter($mounts, function ($result) {
- return is_array($result);
- });
- return array_reduce($mounts, function (array $mounts, array $providerMounts) {
- return array_merge($mounts, $providerMounts);
- }, array());
- }
-
- /**
- * Add a provider for mount points
- *
- * @param \OCP\Files\Config\IMountProvider $provider
- */
- public function registerProvider(IMountProvider $provider) {
- $this->providers[] = $provider;
- $this->emit('\OC\Files\Config', 'registerMountProvider', [$provider]);
- }
-
- /**
- * Cache mounts for user
- *
- * @param IUser $user
- * @param IMountPoint[] $mountPoints
- */
- public function registerMounts(IUser $user, array $mountPoints) {
- $this->mountCache->registerMounts($user, $mountPoints);
- }
-
- /**
- * Get the mount cache which can be used to search for mounts without setting up the filesystem
- *
- * @return IUserMountCache
- */
- public function getMountCache() {
- return $this->mountCache;
- }
-}
diff --git a/lib/private/files/config/usermountcache.php b/lib/private/files/config/usermountcache.php
deleted file mode 100644
index 05ca146f4be..00000000000
--- a/lib/private/files/config/usermountcache.php
+++ /dev/null
@@ -1,290 +0,0 @@
-<?php
-/**
- * @author Joas Schilling <nickvergessen@owncloud.com>
- * @author Robin Appelman <icewind@owncloud.com>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OC\Files\Config;
-
-use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
-use OC\Files\Filesystem;
-use OCA\Files_Sharing\SharedMount;
-use OCP\DB\QueryBuilder\IQueryBuilder;
-use OCP\Files\Config\ICachedMountInfo;
-use OCP\Files\Config\IUserMountCache;
-use OCP\Files\Mount\IMountPoint;
-use OCP\Files\NotFoundException;
-use OCP\ICache;
-use OCP\IDBConnection;
-use OCP\ILogger;
-use OCP\IUser;
-use OCP\IUserManager;
-
-/**
- * Cache mounts points per user in the cache so we can easilly look them up
- */
-class UserMountCache implements IUserMountCache {
- /**
- * @var IDBConnection
- */
- private $connection;
-
- /**
- * @var IUserManager
- */
- private $userManager;
-
- /** @var ICachedMountInfo[][] [$userId => [$cachedMountInfo, ....], ...] */
- private $mountsForUsers = [];
-
- /**
- * @var ILogger
- */
- private $logger;
-
- private $cacheInfoCache = [];
-
- /**
- * UserMountCache constructor.
- *
- * @param IDBConnection $connection
- * @param IUserManager $userManager
- * @param ILogger $logger
- */
- public function __construct(IDBConnection $connection, IUserManager $userManager, ILogger $logger) {
- $this->connection = $connection;
- $this->userManager = $userManager;
- $this->logger = $logger;
- }
-
- public function registerMounts(IUser $user, array $mounts) {
- // filter out non-proper storages coming from unit tests
- $mounts = array_filter($mounts, function (IMountPoint $mount) {
- return $mount instanceof SharedMount || $mount->getStorage() && $mount->getStorage()->getCache();
- });
- /** @var ICachedMountInfo[] $newMounts */
- $newMounts = array_map(function (IMountPoint $mount) use ($user) {
- // filter out any storages which aren't scanned yet since we aren't interested in files from those storages (yet)
- if ($mount->getStorageRootId() === -1) {
- return null;
- } else {
- return new LazyStorageMountInfo($user, $mount);
- }
- }, $mounts);
- $newMounts = array_values(array_filter($newMounts));
-
- $cachedMounts = $this->getMountsForUser($user);
- $mountDiff = function (ICachedMountInfo $mount1, ICachedMountInfo $mount2) {
- // since we are only looking for mounts for a specific user comparing on root id is enough
- return $mount1->getRootId() - $mount2->getRootId();
- };
-
- /** @var ICachedMountInfo[] $addedMounts */
- $addedMounts = array_udiff($newMounts, $cachedMounts, $mountDiff);
- /** @var ICachedMountInfo[] $removedMounts */
- $removedMounts = array_udiff($cachedMounts, $newMounts, $mountDiff);
-
- $changedMounts = array_uintersect($newMounts, $cachedMounts, function (ICachedMountInfo $mount1, ICachedMountInfo $mount2) {
- // filter mounts with the same root id and different mountpoints
- if ($mount1->getRootId() !== $mount2->getRootId()) {
- return -1;
- }
- return ($mount1->getMountPoint() !== $mount2->getMountPoint()) ? 0 : 1;
- });
-
- foreach ($addedMounts as $mount) {
- $this->addToCache($mount);
- $this->mountsForUsers[$user->getUID()][] = $mount;
- }
- foreach ($removedMounts as $mount) {
- $this->removeFromCache($mount);
- $index = array_search($mount, $this->mountsForUsers[$user->getUID()]);
- unset($this->mountsForUsers[$user->getUID()][$index]);
- }
- foreach ($changedMounts as $mount) {
- $this->setMountPoint($mount);
- }
- }
-
- private function addToCache(ICachedMountInfo $mount) {
- $this->connection->insertIfNotExist('*PREFIX*mounts', [
- 'storage_id' => $mount->getStorageId(),
- 'root_id' => $mount->getRootId(),
- 'user_id' => $mount->getUser()->getUID(),
- 'mount_point' => $mount->getMountPoint()
- ], ['root_id', 'user_id']);
- }
-
- private function setMountPoint(ICachedMountInfo $mount) {
- $builder = $this->connection->getQueryBuilder();
-
- $query = $builder->update('mounts')
- ->set('mount_point', $builder->createNamedParameter($mount->getMountPoint()))
- ->where($builder->expr()->eq('user_id', $builder->createNamedParameter($mount->getUser()->getUID())))
- ->andWhere($builder->expr()->eq('root_id', $builder->createNamedParameter($mount->getRootId(), IQueryBuilder::PARAM_INT)));
-
- $query->execute();
- }
-
- private function removeFromCache(ICachedMountInfo $mount) {
- $builder = $this->connection->getQueryBuilder();
-
- $query = $builder->delete('mounts')
- ->where($builder->expr()->eq('user_id', $builder->createNamedParameter($mount->getUser()->getUID())))
- ->andWhere($builder->expr()->eq('root_id', $builder->createNamedParameter($mount->getRootId(), IQueryBuilder::PARAM_INT)));
- $query->execute();
- }
-
- private function dbRowToMountInfo(array $row) {
- $user = $this->userManager->get($row['user_id']);
- return new CachedMountInfo($user, (int)$row['storage_id'], (int)$row['root_id'], $row['mount_point']);
- }
-
- /**
- * @param IUser $user
- * @return ICachedMountInfo[]
- */
- public function getMountsForUser(IUser $user) {
- if (!isset($this->mountsForUsers[$user->getUID()])) {
- $builder = $this->connection->getQueryBuilder();
- $query = $builder->select('storage_id', 'root_id', 'user_id', 'mount_point')
- ->from('mounts')
- ->where($builder->expr()->eq('user_id', $builder->createPositionalParameter($user->getUID())));
-
- $rows = $query->execute()->fetchAll();
-
- $this->mountsForUsers[$user->getUID()] = array_map([$this, 'dbRowToMountInfo'], $rows);
- }
- return $this->mountsForUsers[$user->getUID()];
- }
-
- /**
- * @param int $numericStorageId
- * @return CachedMountInfo[]
- */
- public function getMountsForStorageId($numericStorageId) {
- $builder = $this->connection->getQueryBuilder();
- $query = $builder->select('storage_id', 'root_id', 'user_id', 'mount_point')
- ->from('mounts')
- ->where($builder->expr()->eq('storage_id', $builder->createPositionalParameter($numericStorageId, IQueryBuilder::PARAM_INT)));
-
- $rows = $query->execute()->fetchAll();
-
- return array_map([$this, 'dbRowToMountInfo'], $rows);
- }
-
- /**
- * @param int $rootFileId
- * @return CachedMountInfo[]
- */
- public function getMountsForRootId($rootFileId) {
- $builder = $this->connection->getQueryBuilder();
- $query = $builder->select('storage_id', 'root_id', 'user_id', 'mount_point')
- ->from('mounts')
- ->where($builder->expr()->eq('root_id', $builder->createPositionalParameter($rootFileId, IQueryBuilder::PARAM_INT)));
-
- $rows = $query->execute()->fetchAll();
-
- return array_map([$this, 'dbRowToMountInfo'], $rows);
- }
-
- /**
- * @param $fileId
- * @return array
- * @throws \OCP\Files\NotFoundException
- */
- private function getCacheInfoFromFileId($fileId) {
- if (!isset($this->cacheInfoCache[$fileId])) {
- $builder = $this->connection->getQueryBuilder();
- $query = $builder->select('storage', 'path')
- ->from('filecache')
- ->where($builder->expr()->eq('fileid', $builder->createNamedParameter($fileId, IQueryBuilder::PARAM_INT)));
-
- $row = $query->execute()->fetch();
- if (is_array($row)) {
- $this->cacheInfoCache[$fileId] = [
- (int)$row['storage'],
- $row['path']
- ];
- } else {
- throw new NotFoundException('File with id "' . $fileId . '" not found');
- }
- }
- return $this->cacheInfoCache[$fileId];
- }
-
- /**
- * @param int $fileId
- * @return ICachedMountInfo[]
- * @since 9.0.0
- */
- public function getMountsForFileId($fileId) {
- try {
- list($storageId, $internalPath) = $this->getCacheInfoFromFileId($fileId);
- } catch (NotFoundException $e) {
- return [];
- }
- $mountsForStorage = $this->getMountsForStorageId($storageId);
-
- // filter mounts that are from the same storage but a different directory
- return array_filter($mountsForStorage, function (ICachedMountInfo $mount) use ($internalPath, $fileId) {
- if ($fileId === $mount->getRootId()) {
- return true;
- }
- try {
- list(, $internalMountPath) = $this->getCacheInfoFromFileId($mount->getRootId());
- } catch (NotFoundException $e) {
- return false;
- }
-
- return $internalMountPath === '' || substr($internalPath, 0, strlen($internalMountPath) + 1) === $internalMountPath . '/';
- });
-
- }
-
- /**
- * Remove all cached mounts for a user
- *
- * @param IUser $user
- */
- public function removeUserMounts(IUser $user) {
- $builder = $this->connection->getQueryBuilder();
-
- $query = $builder->delete('mounts')
- ->where($builder->expr()->eq('user_id', $builder->createNamedParameter($user->getUID())));
- $query->execute();
- }
-
- public function removeUserStorageMount($storageId, $userId) {
- $builder = $this->connection->getQueryBuilder();
-
- $query = $builder->delete('mounts')
- ->where($builder->expr()->eq('user_id', $builder->createNamedParameter($userId)))
- ->andWhere($builder->expr()->eq('storage_id', $builder->createNamedParameter($storageId, IQueryBuilder::PARAM_INT)));
- $query->execute();
- }
-
- public function remoteStorageMounts($storageId) {
- $builder = $this->connection->getQueryBuilder();
-
- $query = $builder->delete('mounts')
- ->where($builder->expr()->eq('storage_id', $builder->createNamedParameter($storageId, IQueryBuilder::PARAM_INT)));
- $query->execute();
- }
-}
diff --git a/lib/private/files/config/usermountcachelistener.php b/lib/private/files/config/usermountcachelistener.php
deleted file mode 100644
index 99673cf6285..00000000000
--- a/lib/private/files/config/usermountcachelistener.php
+++ /dev/null
@@ -1,48 +0,0 @@
-<?php
-/**
- * @author Robin Appelman <icewind@owncloud.com>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OC\Files\Config;
-
-use OC\User\Manager;
-use OCP\Files\Config\IUserMountCache;
-
-/**
- * Listen to hooks and update the mount cache as needed
- */
-class UserMountCacheListener {
- /**
- * @var IUserMountCache
- */
- private $userMountCache;
-
- /**
- * UserMountCacheListener constructor.
- *
- * @param IUserMountCache $userMountCache
- */
- public function __construct(IUserMountCache $userMountCache) {
- $this->userMountCache = $userMountCache;
- }
-
- public function listen(Manager $manager) {
- $manager->listen('\OC\User', 'postDelete', [$this->userMountCache, 'removeUserMounts']);
- }
-}
diff --git a/lib/private/files/fileinfo.php b/lib/private/files/fileinfo.php
deleted file mode 100644
index 5f32ad34bb3..00000000000
--- a/lib/private/files/fileinfo.php
+++ /dev/null
@@ -1,346 +0,0 @@
-<?php
-/**
- * @author Joas Schilling <nickvergessen@owncloud.com>
- * @author Lukas Reschke <lukas@owncloud.com>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <icewind@owncloud.com>
- * @author Robin McCorkell <robin@mccorkell.me.uk>
- * @author Roeland Jago Douma <rullzer@owncloud.com>
- * @author tbartenstein <tbartenstein@users.noreply.github.com>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- * @author Vincent Petry <pvince81@owncloud.com>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OC\Files;
-
-use OCP\Files\Cache\ICacheEntry;
-use OCP\IUser;
-
-class FileInfo implements \OCP\Files\FileInfo, \ArrayAccess {
- /**
- * @var array $data
- */
- private $data;
-
- /**
- * @var string $path
- */
- private $path;
-
- /**
- * @var \OC\Files\Storage\Storage $storage
- */
- private $storage;
-
- /**
- * @var string $internalPath
- */
- private $internalPath;
-
- /**
- * @var \OCP\Files\Mount\IMountPoint
- */
- private $mount;
-
- /**
- * @var IUser
- */
- private $owner;
-
- /**
- * @var string[]
- */
- private $childEtags = [];
-
- /**
- * @param string|boolean $path
- * @param Storage\Storage $storage
- * @param string $internalPath
- * @param array|ICacheEntry $data
- * @param \OCP\Files\Mount\IMountPoint $mount
- * @param \OCP\IUser|null $owner
- */
- public function __construct($path, $storage, $internalPath, $data, $mount, $owner= null) {
- $this->path = $path;
- $this->storage = $storage;
- $this->internalPath = $internalPath;
- $this->data = $data;
- $this->mount = $mount;
- $this->owner = $owner;
- }
-
- public function offsetSet($offset, $value) {
- $this->data[$offset] = $value;
- }
-
- public function offsetExists($offset) {
- return isset($this->data[$offset]);
- }
-
- public function offsetUnset($offset) {
- unset($this->data[$offset]);
- }
-
- public function offsetGet($offset) {
- if ($offset === 'type') {
- return $this->getType();
- } else if ($offset === 'etag') {
- return $this->getEtag();
- } elseif ($offset === 'permissions') {
- return $this->getPermissions();
- } elseif (isset($this->data[$offset])) {
- return $this->data[$offset];
- } else {
- return null;
- }
- }
-
- /**
- * @return string
- */
- public function getPath() {
- return $this->path;
- }
-
- /**
- * @return \OCP\Files\Storage
- */
- public function getStorage() {
- return $this->storage;
- }
-
- /**
- * @return string
- */
- public function getInternalPath() {
- return $this->internalPath;
- }
-
- /**
- * @return int
- */
- public function getId() {
- return $this->data['fileid'];
- }
-
- /**
- * @return string
- */
- public function getMimetype() {
- return $this->data['mimetype'];
- }
-
- /**
- * @return string
- */
- public function getMimePart() {
- return $this->data['mimepart'];
- }
-
- /**
- * @return string
- */
- public function getName() {
- return basename($this->getPath());
- }
-
- /**
- * @return string
- */
- public function getEtag() {
- if (count($this->childEtags) > 0) {
- $combinedEtag = $this->data['etag'] . '::' . implode('::', $this->childEtags);
- return md5($combinedEtag);
- } else {
- return $this->data['etag'];
- }
- }
-
- /**
- * @return int
- */
- public function getSize() {
- return isset($this->data['size']) ? $this->data['size'] : 0;
- }
-
- /**
- * @return int
- */
- public function getMTime() {
- return $this->data['mtime'];
- }
-
- /**
- * @return bool
- */
- public function isEncrypted() {
- return $this->data['encrypted'];
- }
-
- /**
- * Return the currently version used for the HMAC in the encryption app
- *
- * @return int
- */
- public function getEncryptedVersion() {
- return isset($this->data['encryptedVersion']) ? (int) $this->data['encryptedVersion'] : 1;
- }
-
- /**
- * @return int
- */
- public function getPermissions() {
- $perms = $this->data['permissions'];
- if (\OCP\Util::isSharingDisabledForUser() || ($this->isShared() && !\OC\Share\Share::isResharingAllowed())) {
- $perms = $perms & ~\OCP\Constants::PERMISSION_SHARE;
- }
- return $perms;
- }
-
- /**
- * @return \OCP\Files\FileInfo::TYPE_FILE|\OCP\Files\FileInfo::TYPE_FOLDER
- */
- public function getType() {
- if (!isset($this->data['type'])) {
- $this->data['type'] = ($this->getMimetype() === 'httpd/unix-directory') ? self::TYPE_FOLDER : self::TYPE_FILE;
- }
- return $this->data['type'];
- }
-
- public function getData() {
- return $this->data;
- }
-
- /**
- * @param int $permissions
- * @return bool
- */
- protected function checkPermissions($permissions) {
- return ($this->getPermissions() & $permissions) === $permissions;
- }
-
- /**
- * @return bool
- */
- public function isReadable() {
- return $this->checkPermissions(\OCP\Constants::PERMISSION_READ);
- }
-
- /**
- * @return bool
- */
- public function isUpdateable() {
- return $this->checkPermissions(\OCP\Constants::PERMISSION_UPDATE);
- }
-
- /**
- * Check whether new files or folders can be created inside this folder
- *
- * @return bool
- */
- public function isCreatable() {
- return $this->checkPermissions(\OCP\Constants::PERMISSION_CREATE);
- }
-
- /**
- * @return bool
- */
- public function isDeletable() {
- return $this->checkPermissions(\OCP\Constants::PERMISSION_DELETE);
- }
-
- /**
- * @return bool
- */
- public function isShareable() {
- return $this->checkPermissions(\OCP\Constants::PERMISSION_SHARE);
- }
-
- /**
- * Check if a file or folder is shared
- *
- * @return bool
- */
- public function isShared() {
- $sid = $this->getStorage()->getId();
- if (!is_null($sid)) {
- $sid = explode(':', $sid);
- return ($sid[0] === 'shared');
- }
-
- return false;
- }
-
- public function isMounted() {
- $sid = $this->getStorage()->getId();
- if (!is_null($sid)) {
- $sid = explode(':', $sid);
- return ($sid[0] !== 'home' and $sid[0] !== 'shared');
- }
-
- return false;
- }
-
- /**
- * Get the mountpoint the file belongs to
- *
- * @return \OCP\Files\Mount\IMountPoint
- */
- public function getMountPoint() {
- return $this->mount;
- }
-
- /**
- * Get the owner of the file
- *
- * @return \OCP\IUser
- */
- public function getOwner() {
- return $this->owner;
- }
-
- /**
- * Add a cache entry which is the child of this folder
- *
- * Sets the size, etag and size to for cross-storage childs
- *
- * @param array $data cache entry for the child
- * @param string $entryPath full path of the child entry
- */
- public function addSubEntry($data, $entryPath) {
- $this->data['size'] += isset($data['size']) ? $data['size'] : 0;
- if (isset($data['mtime'])) {
- $this->data['mtime'] = max($this->data['mtime'], $data['mtime']);
- }
- if (isset($data['etag'])) {
- // prefix the etag with the relative path of the subentry to propagate etag on mount moves
- $relativeEntryPath = substr($entryPath, strlen($this->getPath()));
- // attach the permissions to propagate etag on permision changes of submounts
- $permissions = isset($data['permissions']) ? $data['permissions'] : 0;
- $this->childEtags[] = $relativeEntryPath . '/' . $data['etag'] . $permissions;
- }
- }
-
- /**
- * @inheritdoc
- */
- public function getChecksum() {
- return $this->data['checksum'];
- }
-}
diff --git a/lib/private/files/filesystem.php b/lib/private/files/filesystem.php
deleted file mode 100644
index 7283c815c97..00000000000
--- a/lib/private/files/filesystem.php
+++ /dev/null
@@ -1,928 +0,0 @@
-<?php
-/**
- * @author Arthur Schiwon <blizzz@owncloud.com>
- * @author Bart Visscher <bartv@thisnet.nl>
- * @author Christopher Schäpers <kondou@ts.unde.re>
- * @author Florin Peter <github@florin-peter.de>
- * @author Georg Ehrke <georg@owncloud.com>
- * @author Joas Schilling <nickvergessen@owncloud.com>
- * @author Jörn Friedrich Dreyer <jfd@butonic.de>
- * @author Lukas Reschke <lukas@owncloud.com>
- * @author Michael Gapczynski <GapczynskiM@gmail.com>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <icewind@owncloud.com>
- * @author Robin McCorkell <robin@mccorkell.me.uk>
- * @author Roeland Jago Douma <rullzer@owncloud.com>
- * @author Sam Tuke <mail@samtuke.com>
- * @author Stephan Peijnik <speijnik@anexia-it.com>
- * @author Vincent Petry <pvince81@owncloud.com>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
- */
-
-/**
- * Class for abstraction of filesystem functions
- * This class won't call any filesystem functions for itself but will pass them to the correct OC_Filestorage object
- * this class should also handle all the file permission related stuff
- *
- * Hooks provided:
- * read(path)
- * write(path, &run)
- * post_write(path)
- * create(path, &run) (when a file is created, both create and write will be emitted in that order)
- * post_create(path)
- * delete(path, &run)
- * post_delete(path)
- * rename(oldpath,newpath, &run)
- * post_rename(oldpath,newpath)
- * copy(oldpath,newpath, &run) (if the newpath doesn't exists yes, copy, create and write will be emitted in that order)
- * post_rename(oldpath,newpath)
- * post_initMountPoints(user, user_dir)
- *
- * the &run parameter can be set to false to prevent the operation from occurring
- */
-
-namespace OC\Files;
-
-use OC\Files\Config\MountProviderCollection;
-use OC\Files\Mount\MountPoint;
-use OC\Files\Storage\StorageFactory;
-use OCP\Files\Config\IMountProvider;
-use OCP\Files\Mount\IMountPoint;
-use OCP\Files\NotFoundException;
-use OCP\IUserManager;
-
-class Filesystem {
-
- /**
- * @var Mount\Manager $mounts
- */
- private static $mounts;
-
- public static $loaded = false;
- /**
- * @var \OC\Files\View $defaultInstance
- */
- static private $defaultInstance;
-
- static private $usersSetup = array();
-
- static private $normalizedPathCache = array();
-
- static private $listeningForProviders = false;
-
- /**
- * classname which used for hooks handling
- * used as signalclass in OC_Hooks::emit()
- */
- const CLASSNAME = 'OC_Filesystem';
-
- /**
- * signalname emitted before file renaming
- *
- * @param string $oldpath
- * @param string $newpath
- */
- const signal_rename = 'rename';
-
- /**
- * signal emitted after file renaming
- *
- * @param string $oldpath
- * @param string $newpath
- */
- const signal_post_rename = 'post_rename';
-
- /**
- * signal emitted before file/dir creation
- *
- * @param string $path
- * @param bool $run changing this flag to false in hook handler will cancel event
- */
- const signal_create = 'create';
-
- /**
- * signal emitted after file/dir creation
- *
- * @param string $path
- * @param bool $run changing this flag to false in hook handler will cancel event
- */
- const signal_post_create = 'post_create';
-
- /**
- * signal emits before file/dir copy
- *
- * @param string $oldpath
- * @param string $newpath
- * @param bool $run changing this flag to false in hook handler will cancel event
- */
- const signal_copy = 'copy';
-
- /**
- * signal emits after file/dir copy
- *
- * @param string $oldpath
- * @param string $newpath
- */
- const signal_post_copy = 'post_copy';
-
- /**
- * signal emits before file/dir save
- *
- * @param string $path
- * @param bool $run changing this flag to false in hook handler will cancel event
- */
- const signal_write = 'write';
-
- /**
- * signal emits after file/dir save
- *
- * @param string $path
- */
- const signal_post_write = 'post_write';
-
- /**
- * signal emitted before file/dir update
- *
- * @param string $path
- * @param bool $run changing this flag to false in hook handler will cancel event
- */
- const signal_update = 'update';
-
- /**
- * signal emitted after file/dir update
- *
- * @param string $path
- * @param bool $run changing this flag to false in hook handler will cancel event
- */
- const signal_post_update = 'post_update';
-
- /**
- * signal emits when reading file/dir
- *
- * @param string $path
- */
- const signal_read = 'read';
-
- /**
- * signal emits when removing file/dir
- *
- * @param string $path
- */
- const signal_delete = 'delete';
-
- /**
- * parameters definitions for signals
- */
- const signal_param_path = 'path';
- const signal_param_oldpath = 'oldpath';
- const signal_param_newpath = 'newpath';
-
- /**
- * run - changing this flag to false in hook handler will cancel event
- */
- const signal_param_run = 'run';
-
- const signal_create_mount = 'create_mount';
- const signal_delete_mount = 'delete_mount';
- const signal_param_mount_type = 'mounttype';
- const signal_param_users = 'users';
-
- /**
- * @var \OC\Files\Storage\StorageFactory $loader
- */
- private static $loader;
-
- /**
- * @param string $wrapperName
- * @param callable $wrapper
- * @param int $priority
- */
- public static function addStorageWrapper($wrapperName, $wrapper, $priority = 50) {
- $mounts = self::getMountManager()->getAll();
- if (!self::getLoader()->addStorageWrapper($wrapperName, $wrapper, $priority, $mounts)) {
- // do not re-wrap if storage with this name already existed
- return;
- }
- }
-
- /**
- * Returns the storage factory
- *
- * @return \OCP\Files\Storage\IStorageFactory
- */
- public static function getLoader() {
- if (!self::$loader) {
- self::$loader = new StorageFactory();
- }
- return self::$loader;
- }
-
- /**
- * Returns the mount manager
- *
- * @return \OC\Files\Mount\Manager
- */
- public static function getMountManager($user = '') {
- if (!self::$mounts) {
- \OC_Util::setupFS($user);
- }
- return self::$mounts;
- }
-
- /**
- * get the mountpoint of the storage object for a path
- * ( note: because a storage is not always mounted inside the fakeroot, the
- * returned mountpoint is relative to the absolute root of the filesystem
- * and doesn't take the chroot into account )
- *
- * @param string $path
- * @return string
- */
- static public function getMountPoint($path) {
- if (!self::$mounts) {
- \OC_Util::setupFS();
- }
- $mount = self::$mounts->find($path);
- if ($mount) {
- return $mount->getMountPoint();
- } else {
- return '';
- }
- }
-
- /**
- * get a list of all mount points in a directory
- *
- * @param string $path
- * @return string[]
- */
- static public function getMountPoints($path) {
- if (!self::$mounts) {
- \OC_Util::setupFS();
- }
- $result = array();
- $mounts = self::$mounts->findIn($path);
- foreach ($mounts as $mount) {
- $result[] = $mount->getMountPoint();
- }
- return $result;
- }
-
- /**
- * get the storage mounted at $mountPoint
- *
- * @param string $mountPoint
- * @return \OC\Files\Storage\Storage
- */
- public static function getStorage($mountPoint) {
- if (!self::$mounts) {
- \OC_Util::setupFS();
- }
- $mount = self::$mounts->find($mountPoint);
- return $mount->getStorage();
- }
-
- /**
- * @param string $id
- * @return Mount\MountPoint[]
- */
- public static function getMountByStorageId($id) {
- if (!self::$mounts) {
- \OC_Util::setupFS();
- }
- return self::$mounts->findByStorageId($id);
- }
-
- /**
- * @param int $id
- * @return Mount\MountPoint[]
- */
- public static function getMountByNumericId($id) {
- if (!self::$mounts) {
- \OC_Util::setupFS();
- }
- return self::$mounts->findByNumericId($id);
- }
-
- /**
- * resolve a path to a storage and internal path
- *
- * @param string $path
- * @return array an array consisting of the storage and the internal path
- */
- static public function resolvePath($path) {
- if (!self::$mounts) {
- \OC_Util::setupFS();
- }
- $mount = self::$mounts->find($path);
- if ($mount) {
- return array($mount->getStorage(), rtrim($mount->getInternalPath($path), '/'));
- } else {
- return array(null, null);
- }
- }
-
- static public function init($user, $root) {
- if (self::$defaultInstance) {
- return false;
- }
- self::getLoader();
- self::$defaultInstance = new View($root);
-
- if (!self::$mounts) {
- self::$mounts = \OC::$server->getMountManager();
- }
-
- //load custom mount config
- self::initMountPoints($user);
-
- self::$loaded = true;
-
- return true;
- }
-
- static public function initMountManager() {
- if (!self::$mounts) {
- self::$mounts = \OC::$server->getMountManager();
- }
- }
-
- /**
- * Initialize system and personal mount points for a user
- *
- * @param string $user
- * @throws \OC\User\NoUserException if the user is not available
- */
- public static function initMountPoints($user = '') {
- if ($user == '') {
- $user = \OC_User::getUser();
- }
- if ($user === null || $user === false || $user === '') {
- throw new \OC\User\NoUserException('Attempted to initialize mount points for null user and no user in session');
- }
- if (isset(self::$usersSetup[$user])) {
- return;
- }
- $root = \OC_User::getHome($user);
-
- $userManager = \OC::$server->getUserManager();
- $userObject = $userManager->get($user);
-
- if (is_null($userObject)) {
- \OCP\Util::writeLog('files', ' Backends provided no user object for ' . $user, \OCP\Util::ERROR);
- throw new \OC\User\NoUserException('Backends provided no user object for ' . $user);
- }
-
- self::$usersSetup[$user] = true;
-
- $homeStorage = \OC::$server->getConfig()->getSystemValue('objectstore');
- if (!empty($homeStorage)) {
- // sanity checks
- if (empty($homeStorage['class'])) {
- \OCP\Util::writeLog('files', 'No class given for objectstore', \OCP\Util::ERROR);
- }
- if (!isset($homeStorage['arguments'])) {
- $homeStorage['arguments'] = array();
- }
- // instantiate object store implementation
- $homeStorage['arguments']['objectstore'] = new $homeStorage['class']($homeStorage['arguments']);
- // mount with home object store implementation
- $homeStorage['class'] = '\OC\Files\ObjectStore\HomeObjectStoreStorage';
- } else {
- $homeStorage = array(
- //default home storage configuration:
- 'class' => '\OC\Files\Storage\Home',
- 'arguments' => array()
- );
- }
- $homeStorage['arguments']['user'] = $userObject;
-
- // check for legacy home id (<= 5.0.12)
- if (\OC\Files\Cache\Storage::exists('local::' . $root . '/')) {
- $homeStorage['arguments']['legacy'] = true;
- }
-
- $mount = new MountPoint($homeStorage['class'], '/' . $user, $homeStorage['arguments'], self::getLoader());
- self::getMountManager()->addMount($mount);
-
- $home = \OC\Files\Filesystem::getStorage($user);
-
- self::mountCacheDir($user);
-
- // Chance to mount for other storages
- /** @var \OC\Files\Config\MountProviderCollection $mountConfigManager */
- $mountConfigManager = \OC::$server->getMountProviderCollection();
- if ($userObject) {
- $mounts = $mountConfigManager->getMountsForUser($userObject);
- array_walk($mounts, array(self::$mounts, 'addMount'));
- $mounts[] = $mount;
- $mountConfigManager->registerMounts($userObject, $mounts);
- }
-
- self::listenForNewMountProviders($mountConfigManager, $userManager);
- \OC_Hook::emit('OC_Filesystem', 'post_initMountPoints', array('user' => $user, 'user_dir' => $root));
- }
-
- /**
- * Get mounts from mount providers that are registered after setup
- *
- * @param MountProviderCollection $mountConfigManager
- * @param IUserManager $userManager
- */
- private static function listenForNewMountProviders(MountProviderCollection $mountConfigManager, IUserManager $userManager) {
- if (!self::$listeningForProviders) {
- self::$listeningForProviders = true;
- $mountConfigManager->listen('\OC\Files\Config', 'registerMountProvider', function (IMountProvider $provider) use ($userManager) {
- foreach (Filesystem::$usersSetup as $user => $setup) {
- $userObject = $userManager->get($user);
- if ($userObject) {
- $mounts = $provider->getMountsForUser($userObject, Filesystem::getLoader());
- array_walk($mounts, array(self::$mounts, 'addMount'));
- }
- }
- });
- }
- }
-
- /**
- * Mounts the cache directory
- *
- * @param string $user user name
- */
- private static function mountCacheDir($user) {
- $cacheBaseDir = \OC::$server->getConfig()->getSystemValue('cache_path', '');
- if ($cacheBaseDir !== '') {
- $cacheDir = rtrim($cacheBaseDir, '/') . '/' . $user;
- if (!file_exists($cacheDir)) {
- mkdir($cacheDir, 0770, true);
- }
- // mount external cache dir to "/$user/cache" mount point
- self::mount('\OC\Files\Storage\Local', array('datadir' => $cacheDir), '/' . $user . '/cache');
- }
- }
-
- /**
- * get the default filesystem view
- *
- * @return View
- */
- static public function getView() {
- return self::$defaultInstance;
- }
-
- /**
- * tear down the filesystem, removing all storage providers
- */
- static public function tearDown() {
- self::clearMounts();
- self::$defaultInstance = null;
- }
-
- /**
- * get the relative path of the root data directory for the current user
- *
- * @return string
- *
- * Returns path like /admin/files
- */
- static public function getRoot() {
- if (!self::$defaultInstance) {
- return null;
- }
- return self::$defaultInstance->getRoot();
- }
-
- /**
- * clear all mounts and storage backends
- */
- public static function clearMounts() {
- if (self::$mounts) {
- self::$usersSetup = array();
- self::$mounts->clear();
- }
- }
-
- /**
- * mount an \OC\Files\Storage\Storage in our virtual filesystem
- *
- * @param \OC\Files\Storage\Storage|string $class
- * @param array $arguments
- * @param string $mountpoint
- */
- static public function mount($class, $arguments, $mountpoint) {
- if (!self::$mounts) {
- \OC_Util::setupFS();
- }
- $mount = new Mount\MountPoint($class, $mountpoint, $arguments, self::getLoader());
- self::$mounts->addMount($mount);
- }
-
- /**
- * return the path to a local version of the file
- * we need this because we can't know if a file is stored local or not from
- * outside the filestorage and for some purposes a local file is needed
- *
- * @param string $path
- * @return string
- */
- static public function getLocalFile($path) {
- return self::$defaultInstance->getLocalFile($path);
- }
-
- /**
- * @param string $path
- * @return string
- */
- static public function getLocalFolder($path) {
- return self::$defaultInstance->getLocalFolder($path);
- }
-
- /**
- * return path to file which reflects one visible in browser
- *
- * @param string $path
- * @return string
- */
- static public function getLocalPath($path) {
- $datadir = \OC_User::getHome(\OC_User::getUser()) . '/files';
- $newpath = $path;
- if (strncmp($newpath, $datadir, strlen($datadir)) == 0) {
- $newpath = substr($path, strlen($datadir));
- }
- return $newpath;
- }
-
- /**
- * check if the requested path is valid
- *
- * @param string $path
- * @return bool
- */
- static public function isValidPath($path) {
- $path = self::normalizePath($path);
- if (!$path || $path[0] !== '/') {
- $path = '/' . $path;
- }
- if (strpos($path, '/../') !== false || strrchr($path, '/') === '/..') {
- return false;
- }
- return true;
- }
-
- /**
- * checks if a file is blacklisted for storage in the filesystem
- * Listens to write and rename hooks
- *
- * @param array $data from hook
- */
- static public function isBlacklisted($data) {
- if (isset($data['path'])) {
- $path = $data['path'];
- } else if (isset($data['newpath'])) {
- $path = $data['newpath'];
- }
- if (isset($path)) {
- if (self::isFileBlacklisted($path)) {
- $data['run'] = false;
- }
- }
- }
-
- /**
- * @param string $filename
- * @return bool
- */
- static public function isFileBlacklisted($filename) {
- $filename = self::normalizePath($filename);
-
- $blacklist = \OC::$server->getConfig()->getSystemValue('blacklisted_files', array('.htaccess'));
- $filename = strtolower(basename($filename));
- return in_array($filename, $blacklist);
- }
-
- /**
- * check if the directory should be ignored when scanning
- * NOTE: the special directories . and .. would cause never ending recursion
- *
- * @param String $dir
- * @return boolean
- */
- static public function isIgnoredDir($dir) {
- if ($dir === '.' || $dir === '..') {
- return true;
- }
- return false;
- }
-
- /**
- * following functions are equivalent to their php builtin equivalents for arguments/return values.
- */
- static public function mkdir($path) {
- return self::$defaultInstance->mkdir($path);
- }
-
- static public function rmdir($path) {
- return self::$defaultInstance->rmdir($path);
- }
-
- static public function opendir($path) {
- return self::$defaultInstance->opendir($path);
- }
-
- static public function readdir($path) {
- return self::$defaultInstance->readdir($path);
- }
-
- static public function is_dir($path) {
- return self::$defaultInstance->is_dir($path);
- }
-
- static public function is_file($path) {
- return self::$defaultInstance->is_file($path);
- }
-
- static public function stat($path) {
- return self::$defaultInstance->stat($path);
- }
-
- static public function filetype($path) {
- return self::$defaultInstance->filetype($path);
- }
-
- static public function filesize($path) {
- return self::$defaultInstance->filesize($path);
- }
-
- static public function readfile($path) {
- return self::$defaultInstance->readfile($path);
- }
-
- static public function isCreatable($path) {
- return self::$defaultInstance->isCreatable($path);
- }
-
- static public function isReadable($path) {
- return self::$defaultInstance->isReadable($path);
- }
-
- static public function isUpdatable($path) {
- return self::$defaultInstance->isUpdatable($path);
- }
-
- static public function isDeletable($path) {
- return self::$defaultInstance->isDeletable($path);
- }
-
- static public function isSharable($path) {
- return self::$defaultInstance->isSharable($path);
- }
-
- static public function file_exists($path) {
- return self::$defaultInstance->file_exists($path);
- }
-
- static public function filemtime($path) {
- return self::$defaultInstance->filemtime($path);
- }
-
- static public function touch($path, $mtime = null) {
- return self::$defaultInstance->touch($path, $mtime);
- }
-
- /**
- * @return string
- */
- static public function file_get_contents($path) {
- return self::$defaultInstance->file_get_contents($path);
- }
-
- static public function file_put_contents($path, $data) {
- return self::$defaultInstance->file_put_contents($path, $data);
- }
-
- static public function unlink($path) {
- return self::$defaultInstance->unlink($path);
- }
-
- static public function rename($path1, $path2) {
- return self::$defaultInstance->rename($path1, $path2);
- }
-
- static public function copy($path1, $path2) {
- return self::$defaultInstance->copy($path1, $path2);
- }
-
- static public function fopen($path, $mode) {
- return self::$defaultInstance->fopen($path, $mode);
- }
-
- /**
- * @return string
- */
- static public function toTmpFile($path) {
- return self::$defaultInstance->toTmpFile($path);
- }
-
- static public function fromTmpFile($tmpFile, $path) {
- return self::$defaultInstance->fromTmpFile($tmpFile, $path);
- }
-
- static public function getMimeType($path) {
- return self::$defaultInstance->getMimeType($path);
- }
-
- static public function hash($type, $path, $raw = false) {
- return self::$defaultInstance->hash($type, $path, $raw);
- }
-
- static public function free_space($path = '/') {
- return self::$defaultInstance->free_space($path);
- }
-
- static public function search($query) {
- return self::$defaultInstance->search($query);
- }
-
- /**
- * @param string $query
- */
- static public function searchByMime($query) {
- return self::$defaultInstance->searchByMime($query);
- }
-
- /**
- * @param string|int $tag name or tag id
- * @param string $userId owner of the tags
- * @return FileInfo[] array or file info
- */
- static public function searchByTag($tag, $userId) {
- return self::$defaultInstance->searchByTag($tag, $userId);
- }
-
- /**
- * check if a file or folder has been updated since $time
- *
- * @param string $path
- * @param int $time
- * @return bool
- */
- static public function hasUpdated($path, $time) {
- return self::$defaultInstance->hasUpdated($path, $time);
- }
-
- /**
- * Fix common problems with a file path
- *
- * @param string $path
- * @param bool $stripTrailingSlash
- * @param bool $isAbsolutePath
- * @return string
- */
- public static function normalizePath($path, $stripTrailingSlash = true, $isAbsolutePath = false) {
- /**
- * FIXME: This is a workaround for existing classes and files which call
- * this function with another type than a valid string. This
- * conversion should get removed as soon as all existing
- * function calls have been fixed.
- */
- $path = (string)$path;
-
- $cacheKey = json_encode([$path, $stripTrailingSlash, $isAbsolutePath]);
-
- if (isset(self::$normalizedPathCache[$cacheKey])) {
- return self::$normalizedPathCache[$cacheKey];
- }
-
- if ($path == '') {
- return '/';
- }
-
- //normalize unicode if possible
- $path = \OC_Util::normalizeUnicode($path);
-
- //no windows style slashes
- $path = str_replace('\\', '/', $path);
-
- // When normalizing an absolute path, we need to ensure that the drive-letter
- // is still at the beginning on windows
- $windows_drive_letter = '';
- if ($isAbsolutePath && \OC_Util::runningOnWindows() && preg_match('#^([a-zA-Z])$#', $path[0]) && $path[1] == ':' && $path[2] == '/') {
- $windows_drive_letter = substr($path, 0, 2);
- $path = substr($path, 2);
- }
-
- //add leading slash
- if ($path[0] !== '/') {
- $path = '/' . $path;
- }
-
- // remove '/./'
- // ugly, but str_replace() can't replace them all in one go
- // as the replacement itself is part of the search string
- // which will only be found during the next iteration
- while (strpos($path, '/./') !== false) {
- $path = str_replace('/./', '/', $path);
- }
- // remove sequences of slashes
- $path = preg_replace('#/{2,}#', '/', $path);
-
- //remove trailing slash
- if ($stripTrailingSlash and strlen($path) > 1 and substr($path, -1, 1) === '/') {
- $path = substr($path, 0, -1);
- }
-
- // remove trailing '/.'
- if (substr($path, -2) == '/.') {
- $path = substr($path, 0, -2);
- }
-
- $normalizedPath = $windows_drive_letter . $path;
- self::$normalizedPathCache[$cacheKey] = $normalizedPath;
-
- return $normalizedPath;
- }
-
- /**
- * get the filesystem info
- *
- * @param string $path
- * @param boolean $includeMountPoints whether to add mountpoint sizes,
- * defaults to true
- * @return \OC\Files\FileInfo|bool False if file does not exist
- */
- public static function getFileInfo($path, $includeMountPoints = true) {
- return self::$defaultInstance->getFileInfo($path, $includeMountPoints);
- }
-
- /**
- * change file metadata
- *
- * @param string $path
- * @param array $data
- * @return int
- *
- * returns the fileid of the updated file
- */
- public static function putFileInfo($path, $data) {
- return self::$defaultInstance->putFileInfo($path, $data);
- }
-
- /**
- * get the content of a directory
- *
- * @param string $directory path under datadirectory
- * @param string $mimetype_filter limit returned content to this mimetype or mimepart
- * @return \OC\Files\FileInfo[]
- */
- public static function getDirectoryContent($directory, $mimetype_filter = '') {
- return self::$defaultInstance->getDirectoryContent($directory, $mimetype_filter);
- }
-
- /**
- * Get the path of a file by id
- *
- * Note that the resulting path is not guaranteed to be unique for the id, multiple paths can point to the same file
- *
- * @param int $id
- * @throws NotFoundException
- * @return string
- */
- public static function getPath($id) {
- return self::$defaultInstance->getPath($id);
- }
-
- /**
- * Get the owner for a file or folder
- *
- * @param string $path
- * @return string
- */
- public static function getOwner($path) {
- return self::$defaultInstance->getOwner($path);
- }
-
- /**
- * get the ETag for a file or folder
- *
- * @param string $path
- * @return string
- */
- static public function getETag($path) {
- return self::$defaultInstance->getETag($path);
- }
-}
diff --git a/lib/private/files/mount/manager.php b/lib/private/files/mount/manager.php
deleted file mode 100644
index ba4a7f8d910..00000000000
--- a/lib/private/files/mount/manager.php
+++ /dev/null
@@ -1,165 +0,0 @@
-<?php
-/**
- * @author Björn Schießle <schiessle@owncloud.com>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <icewind@owncloud.com>
- * @author Robin McCorkell <robin@mccorkell.me.uk>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OC\Files\Mount;
-
-use \OC\Files\Filesystem;
-use OCP\Files\Mount\IMountManager;
-use OCP\Files\Mount\IMountPoint;
-
-class Manager implements IMountManager {
- /**
- * @var MountPoint[]
- */
- private $mounts = array();
-
- /**
- * @param IMountPoint $mount
- */
- public function addMount(IMountPoint $mount) {
- $this->mounts[$mount->getMountPoint()] = $mount;
- }
-
- /**
- * @param string $mountPoint
- */
- public function removeMount($mountPoint) {
- $mountPoint = Filesystem::normalizePath($mountPoint);
- if (strlen($mountPoint) > 1) {
- $mountPoint .= '/';
- }
- unset($this->mounts[$mountPoint]);
- }
-
- /**
- * @param string $mountPoint
- * @param string $target
- */
- public function moveMount($mountPoint, $target){
- $this->mounts[$target] = $this->mounts[$mountPoint];
- unset($this->mounts[$mountPoint]);
- }
-
- /**
- * Find the mount for $path
- *
- * @param string $path
- * @return MountPoint
- */
- public function find($path) {
- \OC_Util::setupFS();
- $path = $this->formatPath($path);
- if (isset($this->mounts[$path])) {
- return $this->mounts[$path];
- }
-
- \OC_Hook::emit('OC_Filesystem', 'get_mountpoint', array('path' => $path));
- $foundMountPoint = '';
- $mountPoints = array_keys($this->mounts);
- foreach ($mountPoints as $mountpoint) {
- if (strpos($path, $mountpoint) === 0 and strlen($mountpoint) > strlen($foundMountPoint)) {
- $foundMountPoint = $mountpoint;
- }
- }
- if (isset($this->mounts[$foundMountPoint])) {
- return $this->mounts[$foundMountPoint];
- } else {
- return null;
- }
- }
-
- /**
- * Find all mounts in $path
- *
- * @param string $path
- * @return MountPoint[]
- */
- public function findIn($path) {
- \OC_Util::setupFS();
- $path = $this->formatPath($path);
- $result = array();
- $pathLength = strlen($path);
- $mountPoints = array_keys($this->mounts);
- foreach ($mountPoints as $mountPoint) {
- if (substr($mountPoint, 0, $pathLength) === $path and strlen($mountPoint) > $pathLength) {
- $result[] = $this->mounts[$mountPoint];
- }
- }
- return $result;
- }
-
- public function clear() {
- $this->mounts = array();
- }
-
- /**
- * Find mounts by storage id
- *
- * @param string $id
- * @return MountPoint[]
- */
- public function findByStorageId($id) {
- \OC_Util::setupFS();
- if (strlen($id) > 64) {
- $id = md5($id);
- }
- $result = array();
- foreach ($this->mounts as $mount) {
- if ($mount->getStorageId() === $id) {
- $result[] = $mount;
- }
- }
- return $result;
- }
-
- /**
- * @return MountPoint[]
- */
- public function getAll() {
- return $this->mounts;
- }
-
- /**
- * Find mounts by numeric storage id
- *
- * @param int $id
- * @return MountPoint[]
- */
- public function findByNumericId($id) {
- $storageId = \OC\Files\Cache\Storage::getStorageId($id);
- return $this->findByStorageId($storageId);
- }
-
- /**
- * @param string $path
- * @return string
- */
- private function formatPath($path) {
- $path = Filesystem::normalizePath($path);
- if (strlen($path) > 1) {
- $path .= '/';
- }
- return $path;
- }
-}
diff --git a/lib/private/files/mount/mountpoint.php b/lib/private/files/mount/mountpoint.php
deleted file mode 100644
index 7b9294fc1e0..00000000000
--- a/lib/private/files/mount/mountpoint.php
+++ /dev/null
@@ -1,251 +0,0 @@
-<?php
-/**
- * @author Björn Schießle <schiessle@owncloud.com>
- * @author Jörn Friedrich Dreyer <jfd@butonic.de>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <icewind@owncloud.com>
- * @author Robin McCorkell <robin@mccorkell.me.uk>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- * @author Vincent Petry <pvince81@owncloud.com>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OC\Files\Mount;
-
-use \OC\Files\Filesystem;
-use OC\Files\Storage\StorageFactory;
-use OC\Files\Storage\Storage;
-use OCP\Files\Mount\IMountPoint;
-
-class MountPoint implements IMountPoint {
- /**
- * @var \OC\Files\Storage\Storage $storage
- */
- protected $storage = null;
- protected $class;
- protected $storageId;
-
- /**
- * Configuration options for the storage backend
- *
- * @var array
- */
- protected $arguments = array();
- protected $mountPoint;
-
- /**
- * Mount specific options
- *
- * @var array
- */
- protected $mountOptions = array();
-
- /**
- * @var \OC\Files\Storage\StorageFactory $loader
- */
- private $loader;
-
- /**
- * Specified whether the storage is invalid after failing to
- * instantiate it.
- *
- * @var bool
- */
- private $invalidStorage = false;
-
- /**
- * @param string|\OC\Files\Storage\Storage $storage
- * @param string $mountpoint
- * @param array $arguments (optional) configuration for the storage backend
- * @param \OCP\Files\Storage\IStorageFactory $loader
- * @param array $mountOptions mount specific options
- */
- public function __construct($storage, $mountpoint, $arguments = null, $loader = null, $mountOptions = null) {
- if (is_null($arguments)) {
- $arguments = array();
- }
- if (is_null($loader)) {
- $this->loader = new StorageFactory();
- } else {
- $this->loader = $loader;
- }
-
- if (!is_null($mountOptions)) {
- $this->mountOptions = $mountOptions;
- }
-
- $mountpoint = $this->formatPath($mountpoint);
- $this->mountPoint = $mountpoint;
- if ($storage instanceof Storage) {
- $this->class = get_class($storage);
- $this->storage = $this->loader->wrap($this, $storage);
- } else {
- // Update old classes to new namespace
- if (strpos($storage, 'OC_Filestorage_') !== false) {
- $storage = '\OC\Files\Storage\\' . substr($storage, 15);
- }
- $this->class = $storage;
- $this->arguments = $arguments;
- }
- }
-
- /**
- * get complete path to the mount point, relative to data/
- *
- * @return string
- */
- public function getMountPoint() {
- return $this->mountPoint;
- }
-
- /**
- * Sets the mount point path, relative to data/
- *
- * @param string $mountPoint new mount point
- */
- public function setMountPoint($mountPoint) {
- $this->mountPoint = $this->formatPath($mountPoint);
- }
-
- /**
- * create the storage that is mounted
- *
- * @return \OC\Files\Storage\Storage
- */
- private function createStorage() {
- if ($this->invalidStorage) {
- return null;
- }
-
- if (class_exists($this->class)) {
- try {
- return $this->loader->getInstance($this, $this->class, $this->arguments);
- } catch (\Exception $exception) {
- $this->invalidStorage = true;
- if ($this->mountPoint === '/') {
- // the root storage could not be initialized, show the user!
- throw new \Exception('The root storage could not be initialized. Please contact your local administrator.', $exception->getCode(), $exception);
- } else {
- \OCP\Util::writeLog('core', $exception->getMessage(), \OCP\Util::ERROR);
- }
- return null;
- }
- } else {
- \OCP\Util::writeLog('core', 'storage backend ' . $this->class . ' not found', \OCP\Util::ERROR);
- $this->invalidStorage = true;
- return null;
- }
- }
-
- /**
- * @return \OC\Files\Storage\Storage
- */
- public function getStorage() {
- if (is_null($this->storage)) {
- $this->storage = $this->createStorage();
- }
- return $this->storage;
- }
-
- /**
- * @return string
- */
- public function getStorageId() {
- if (!$this->storageId) {
- if (is_null($this->storage)) {
- $storage = $this->createStorage(); //FIXME: start using exceptions
- if (is_null($storage)) {
- return null;
- }
-
- $this->storage = $storage;
- }
- $this->storageId = $this->storage->getId();
- if (strlen($this->storageId) > 64) {
- $this->storageId = md5($this->storageId);
- }
- }
- return $this->storageId;
- }
-
- /**
- * @param string $path
- * @return string
- */
- public function getInternalPath($path) {
- if ($this->mountPoint === $path or $this->mountPoint . '/' === $path) {
- $internalPath = '';
- } else {
- $internalPath = substr($path, strlen($this->mountPoint));
- }
- // substr returns false instead of an empty string, we always want a string
- return (string)$internalPath;
- }
-
- /**
- * @param string $path
- * @return string
- */
- private function formatPath($path) {
- $path = Filesystem::normalizePath($path);
- if (strlen($path) > 1) {
- $path .= '/';
- }
- return $path;
- }
-
- /**
- * @param callable $wrapper
- */
- public function wrapStorage($wrapper) {
- $storage = $this->getStorage();
- // storage can be null if it couldn't be initialized
- if ($storage != null) {
- $this->storage = $wrapper($this->mountPoint, $storage, $this);
- }
- }
-
- /**
- * Get a mount option
- *
- * @param string $name Name of the mount option to get
- * @param mixed $default Default value for the mount option
- * @return mixed
- */
- public function getOption($name, $default) {
- return isset($this->mountOptions[$name]) ? $this->mountOptions[$name] : $default;
- }
-
- /**
- * Get all options for the mount
- *
- * @return array
- */
- public function getOptions() {
- return $this->mountOptions;
- }
-
- /**
- * Get the file id of the root of the storage
- *
- * @return int
- */
- public function getStorageRootId() {
- return (int)$this->getStorage()->getCache()->getId('');
- }
-}
diff --git a/lib/private/files/mount/moveablemount.php b/lib/private/files/mount/moveablemount.php
deleted file mode 100644
index 8a1bd7dd9c5..00000000000
--- a/lib/private/files/mount/moveablemount.php
+++ /dev/null
@@ -1,44 +0,0 @@
-<?php
-/**
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <icewind@owncloud.com>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OC\Files\Mount;
-
-/**
- * Defines the mount point to be (re)moved by the user
- */
-interface MoveableMount {
- /**
- * Move the mount point to $target
- *
- * @param string $target the target mount point
- * @return bool
- */
- public function moveMount($target);
-
- /**
- * Remove the mount points
- *
- * @return mixed
- * @return bool
- */
- public function removeMount();
-}
diff --git a/lib/private/files/node/file.php b/lib/private/files/node/file.php
deleted file mode 100644
index 9e0014abb0b..00000000000
--- a/lib/private/files/node/file.php
+++ /dev/null
@@ -1,176 +0,0 @@
-<?php
-/**
- * @author Joas Schilling <nickvergessen@owncloud.com>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <icewind@owncloud.com>
- * @author Roeland Jago Douma <rullzer@owncloud.com>
- * @author Vincent Petry <pvince81@owncloud.com>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OC\Files\Node;
-
-use OCP\Files\NotPermittedException;
-
-class File extends Node implements \OCP\Files\File {
- /**
- * @return string
- * @throws \OCP\Files\NotPermittedException
- */
- public function getContent() {
- if ($this->checkPermissions(\OCP\Constants::PERMISSION_READ)) {
- /**
- * @var \OC\Files\Storage\Storage $storage;
- */
- return $this->view->file_get_contents($this->path);
- } else {
- throw new NotPermittedException();
- }
- }
-
- /**
- * @param string $data
- * @throws \OCP\Files\NotPermittedException
- */
- public function putContent($data) {
- if ($this->checkPermissions(\OCP\Constants::PERMISSION_UPDATE)) {
- $this->sendHooks(array('preWrite'));
- $this->view->file_put_contents($this->path, $data);
- $this->fileInfo = null;
- $this->sendHooks(array('postWrite'));
- } else {
- throw new NotPermittedException();
- }
- }
-
- /**
- * @param string $mode
- * @return resource
- * @throws \OCP\Files\NotPermittedException
- */
- public function fopen($mode) {
- $preHooks = array();
- $postHooks = array();
- $requiredPermissions = \OCP\Constants::PERMISSION_READ;
- switch ($mode) {
- case 'r+':
- case 'rb+':
- case 'w+':
- case 'wb+':
- case 'x+':
- case 'xb+':
- case 'a+':
- case 'ab+':
- case 'w':
- case 'wb':
- case 'x':
- case 'xb':
- case 'a':
- case 'ab':
- $preHooks[] = 'preWrite';
- $postHooks[] = 'postWrite';
- $requiredPermissions |= \OCP\Constants::PERMISSION_UPDATE;
- break;
- }
-
- if ($this->checkPermissions($requiredPermissions)) {
- $this->sendHooks($preHooks);
- $result = $this->view->fopen($this->path, $mode);
- $this->sendHooks($postHooks);
- return $result;
- } else {
- throw new NotPermittedException();
- }
- }
-
- public function delete() {
- if ($this->checkPermissions(\OCP\Constants::PERMISSION_DELETE)) {
- $this->sendHooks(array('preDelete'));
- $fileInfo = $this->getFileInfo();
- $this->view->unlink($this->path);
- $nonExisting = new NonExistingFile($this->root, $this->view, $this->path, $fileInfo);
- $this->root->emit('\OC\Files', 'postDelete', array($nonExisting));
- $this->exists = false;
- $this->fileInfo = null;
- } else {
- throw new NotPermittedException();
- }
- }
-
- /**
- * @param string $targetPath
- * @throws \OCP\Files\NotPermittedException
- * @return \OC\Files\Node\Node
- */
- public function copy($targetPath) {
- $targetPath = $this->normalizePath($targetPath);
- $parent = $this->root->get(dirname($targetPath));
- if ($parent instanceof Folder and $this->isValidPath($targetPath) and $parent->isCreatable()) {
- $nonExisting = new NonExistingFile($this->root, $this->view, $targetPath);
- $this->root->emit('\OC\Files', 'preCopy', array($this, $nonExisting));
- $this->root->emit('\OC\Files', 'preWrite', array($nonExisting));
- $this->view->copy($this->path, $targetPath);
- $targetNode = $this->root->get($targetPath);
- $this->root->emit('\OC\Files', 'postCopy', array($this, $targetNode));
- $this->root->emit('\OC\Files', 'postWrite', array($targetNode));
- return $targetNode;
- } else {
- throw new NotPermittedException();
- }
- }
-
- /**
- * @param string $targetPath
- * @throws \OCP\Files\NotPermittedException
- * @return \OC\Files\Node\Node
- */
- public function move($targetPath) {
- $targetPath = $this->normalizePath($targetPath);
- $parent = $this->root->get(dirname($targetPath));
- if ($parent instanceof Folder and $this->isValidPath($targetPath) and $parent->isCreatable()) {
- $nonExisting = new NonExistingFile($this->root, $this->view, $targetPath);
- $this->root->emit('\OC\Files', 'preRename', array($this, $nonExisting));
- $this->root->emit('\OC\Files', 'preWrite', array($nonExisting));
- $this->view->rename($this->path, $targetPath);
- $targetNode = $this->root->get($targetPath);
- $this->root->emit('\OC\Files', 'postRename', array($this, $targetNode));
- $this->root->emit('\OC\Files', 'postWrite', array($targetNode));
- $this->path = $targetPath;
- $this->fileInfo = null;
- return $targetNode;
- } else {
- throw new NotPermittedException();
- }
- }
-
- /**
- * @param string $type
- * @param bool $raw
- * @return string
- */
- public function hash($type, $raw = false) {
- return $this->view->hash($type, $this->path, $raw);
- }
-
- /**
- * @inheritdoc
- */
- public function getChecksum() {
- return $this->getFileInfo()->getChecksum();
- }
-}
diff --git a/lib/private/files/node/folder.php b/lib/private/files/node/folder.php
deleted file mode 100644
index f4d7dae20a3..00000000000
--- a/lib/private/files/node/folder.php
+++ /dev/null
@@ -1,360 +0,0 @@
-<?php
-/**
- * @author Joas Schilling <nickvergessen@owncloud.com>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <icewind@owncloud.com>
- * @author Robin McCorkell <robin@mccorkell.me.uk>
- * @author Vincent Petry <pvince81@owncloud.com>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OC\Files\Node;
-
-use OCP\Files\FileInfo;
-use OCP\Files\NotFoundException;
-use OCP\Files\NotPermittedException;
-
-class Folder extends Node implements \OCP\Files\Folder {
- /**
- * @param string $path path relative to the folder
- * @return string
- * @throws \OCP\Files\NotPermittedException
- */
- public function getFullPath($path) {
- if (!$this->isValidPath($path)) {
- throw new NotPermittedException();
- }
- return $this->path . $this->normalizePath($path);
- }
-
- /**
- * @param string $path
- * @return string
- */
- public function getRelativePath($path) {
- if ($this->path === '' or $this->path === '/') {
- return $this->normalizePath($path);
- }
- if ($path === $this->path) {
- return '/';
- } else if (strpos($path, $this->path . '/') !== 0) {
- return null;
- } else {
- $path = substr($path, strlen($this->path));
- return $this->normalizePath($path);
- }
- }
-
- /**
- * check if a node is a (grand-)child of the folder
- *
- * @param \OC\Files\Node\Node $node
- * @return bool
- */
- public function isSubNode($node) {
- return strpos($node->getPath(), $this->path . '/') === 0;
- }
-
- /**
- * get the content of this directory
- *
- * @throws \OCP\Files\NotFoundException
- * @return Node[]
- */
- public function getDirectoryListing() {
- $folderContent = $this->view->getDirectoryContent($this->path);
-
- return array_map(function(FileInfo $info) {
- if ($info->getMimetype() === 'httpd/unix-directory') {
- return new Folder($this->root, $this->view, $info->getPath(), $info);
- } else {
- return new File($this->root, $this->view, $info->getPath(), $info);
- }
- }, $folderContent);
- }
-
- /**
- * @param string $path
- * @param FileInfo $info
- * @return File|Folder
- */
- protected function createNode($path, FileInfo $info = null) {
- if (is_null($info)) {
- $isDir = $this->view->is_dir($path);
- } else {
- $isDir = $info->getType() === FileInfo::TYPE_FOLDER;
- }
- if ($isDir) {
- return new Folder($this->root, $this->view, $path, $info);
- } else {
- return new File($this->root, $this->view, $path, $info);
- }
- }
-
- /**
- * Get the node at $path
- *
- * @param string $path
- * @return \OC\Files\Node\Node
- * @throws \OCP\Files\NotFoundException
- */
- public function get($path) {
- return $this->root->get($this->getFullPath($path));
- }
-
- /**
- * @param string $path
- * @return bool
- */
- public function nodeExists($path) {
- try {
- $this->get($path);
- return true;
- } catch (NotFoundException $e) {
- return false;
- }
- }
-
- /**
- * @param string $path
- * @return \OC\Files\Node\Folder
- * @throws \OCP\Files\NotPermittedException
- */
- public function newFolder($path) {
- if ($this->checkPermissions(\OCP\Constants::PERMISSION_CREATE)) {
- $fullPath = $this->getFullPath($path);
- $nonExisting = new NonExistingFolder($this->root, $this->view, $fullPath);
- $this->root->emit('\OC\Files', 'preWrite', array($nonExisting));
- $this->root->emit('\OC\Files', 'preCreate', array($nonExisting));
- $this->view->mkdir($fullPath);
- $node = new Folder($this->root, $this->view, $fullPath);
- $this->root->emit('\OC\Files', 'postWrite', array($node));
- $this->root->emit('\OC\Files', 'postCreate', array($node));
- return $node;
- } else {
- throw new NotPermittedException();
- }
- }
-
- /**
- * @param string $path
- * @return \OC\Files\Node\File
- * @throws \OCP\Files\NotPermittedException
- */
- public function newFile($path) {
- if ($this->checkPermissions(\OCP\Constants::PERMISSION_CREATE)) {
- $fullPath = $this->getFullPath($path);
- $nonExisting = new NonExistingFile($this->root, $this->view, $fullPath);
- $this->root->emit('\OC\Files', 'preWrite', array($nonExisting));
- $this->root->emit('\OC\Files', 'preCreate', array($nonExisting));
- $this->view->touch($fullPath);
- $node = new File($this->root, $this->view, $fullPath);
- $this->root->emit('\OC\Files', 'postWrite', array($node));
- $this->root->emit('\OC\Files', 'postCreate', array($node));
- return $node;
- } else {
- throw new NotPermittedException();
- }
- }
-
- /**
- * search for files with the name matching $query
- *
- * @param string $query
- * @return \OC\Files\Node\Node[]
- */
- public function search($query) {
- return $this->searchCommon('search', array('%' . $query . '%'));
- }
-
- /**
- * search for files by mimetype
- *
- * @param string $mimetype
- * @return Node[]
- */
- public function searchByMime($mimetype) {
- return $this->searchCommon('searchByMime', array($mimetype));
- }
-
- /**
- * search for files by tag
- *
- * @param string|int $tag name or tag id
- * @param string $userId owner of the tags
- * @return Node[]
- */
- public function searchByTag($tag, $userId) {
- return $this->searchCommon('searchByTag', array($tag, $userId));
- }
-
- /**
- * @param string $method cache method
- * @param array $args call args
- * @return \OC\Files\Node\Node[]
- */
- private function searchCommon($method, $args) {
- $files = array();
- $rootLength = strlen($this->path);
- $mount = $this->root->getMount($this->path);
- $storage = $mount->getStorage();
- $internalPath = $mount->getInternalPath($this->path);
- $internalPath = rtrim($internalPath, '/');
- if ($internalPath !== '') {
- $internalPath = $internalPath . '/';
- }
- $internalRootLength = strlen($internalPath);
-
- $cache = $storage->getCache('');
-
- $results = call_user_func_array(array($cache, $method), $args);
- foreach ($results as $result) {
- if ($internalRootLength === 0 or substr($result['path'], 0, $internalRootLength) === $internalPath) {
- $result['internalPath'] = $result['path'];
- $result['path'] = substr($result['path'], $internalRootLength);
- $result['storage'] = $storage;
- $files[] = new \OC\Files\FileInfo($this->path . '/' . $result['path'], $storage, $result['internalPath'], $result, $mount);
- }
- }
-
- $mounts = $this->root->getMountsIn($this->path);
- foreach ($mounts as $mount) {
- $storage = $mount->getStorage();
- if ($storage) {
- $cache = $storage->getCache('');
-
- $relativeMountPoint = substr($mount->getMountPoint(), $rootLength);
- $results = call_user_func_array(array($cache, $method), $args);
- foreach ($results as $result) {
- $result['internalPath'] = $result['path'];
- $result['path'] = $relativeMountPoint . $result['path'];
- $result['storage'] = $storage;
- $files[] = new \OC\Files\FileInfo($this->path . '/' . $result['path'], $storage, $result['internalPath'], $result, $mount);
- }
- }
- }
-
- return array_map(function(FileInfo $file) {
- return $this->createNode($file->getPath(), $file);
- }, $files);
- }
-
- /**
- * @param int $id
- * @return \OC\Files\Node\Node[]
- */
- public function getById($id) {
- $mounts = $this->root->getMountsIn($this->path);
- $mounts[] = $this->root->getMount($this->path);
- // reverse the array so we start with the storage this view is in
- // which is the most likely to contain the file we're looking for
- $mounts = array_reverse($mounts);
-
- $nodes = array();
- foreach ($mounts as $mount) {
- /**
- * @var \OC\Files\Mount\MountPoint $mount
- */
- if ($mount->getStorage()) {
- $cache = $mount->getStorage()->getCache();
- $internalPath = $cache->getPathById($id);
- if (is_string($internalPath)) {
- $fullPath = $mount->getMountPoint() . $internalPath;
- if (!is_null($path = $this->getRelativePath($fullPath))) {
- $nodes[] = $this->get($path);
- }
- }
- }
- }
- return $nodes;
- }
-
- public function getFreeSpace() {
- return $this->view->free_space($this->path);
- }
-
- public function delete() {
- if ($this->checkPermissions(\OCP\Constants::PERMISSION_DELETE)) {
- $this->sendHooks(array('preDelete'));
- $fileInfo = $this->getFileInfo();
- $this->view->rmdir($this->path);
- $nonExisting = new NonExistingFolder($this->root, $this->view, $this->path, $fileInfo);
- $this->root->emit('\OC\Files', 'postDelete', array($nonExisting));
- $this->exists = false;
- } else {
- throw new NotPermittedException();
- }
- }
-
- /**
- * @param string $targetPath
- * @throws \OCP\Files\NotPermittedException
- * @return \OC\Files\Node\Node
- */
- public function copy($targetPath) {
- $targetPath = $this->normalizePath($targetPath);
- $parent = $this->root->get(dirname($targetPath));
- if ($parent instanceof Folder and $this->isValidPath($targetPath) and $parent->isCreatable()) {
- $nonExisting = new NonExistingFolder($this->root, $this->view, $targetPath);
- $this->root->emit('\OC\Files', 'preCopy', array($this, $nonExisting));
- $this->root->emit('\OC\Files', 'preWrite', array($nonExisting));
- $this->view->copy($this->path, $targetPath);
- $targetNode = $this->root->get($targetPath);
- $this->root->emit('\OC\Files', 'postCopy', array($this, $targetNode));
- $this->root->emit('\OC\Files', 'postWrite', array($targetNode));
- return $targetNode;
- } else {
- throw new NotPermittedException();
- }
- }
-
- /**
- * @param string $targetPath
- * @throws \OCP\Files\NotPermittedException
- * @return \OC\Files\Node\Node
- */
- public function move($targetPath) {
- $targetPath = $this->normalizePath($targetPath);
- $parent = $this->root->get(dirname($targetPath));
- if ($parent instanceof Folder and $this->isValidPath($targetPath) and $parent->isCreatable()) {
- $nonExisting = new NonExistingFolder($this->root, $this->view, $targetPath);
- $this->root->emit('\OC\Files', 'preRename', array($this, $nonExisting));
- $this->root->emit('\OC\Files', 'preWrite', array($nonExisting));
- $this->view->rename($this->path, $targetPath);
- $targetNode = $this->root->get($targetPath);
- $this->root->emit('\OC\Files', 'postRename', array($this, $targetNode));
- $this->root->emit('\OC\Files', 'postWrite', array($targetNode));
- $this->path = $targetPath;
- return $targetNode;
- } else {
- throw new NotPermittedException();
- }
- }
-
- /**
- * Add a suffix to the name in case the file exists
- *
- * @param string $name
- * @return string
- * @throws NotPermittedException
- */
- public function getNonExistingName($name) {
- $uniqueName = \OC_Helper::buildNotExistingFileNameForView($this->getPath(), $name, $this->view);
- return trim($this->getRelativePath($uniqueName), '/');
- }
-}
diff --git a/lib/private/files/node/hookconnector.php b/lib/private/files/node/hookconnector.php
deleted file mode 100644
index 5c36ca3848e..00000000000
--- a/lib/private/files/node/hookconnector.php
+++ /dev/null
@@ -1,164 +0,0 @@
-<?php
-/**
- * @author Robin Appelman <icewind@owncloud.com>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OC\Files\Node;
-
-use OCP\Files\FileInfo;
-use OC\Files\Filesystem;
-use OC\Files\View;
-use OCP\Util;
-
-class HookConnector {
- /**
- * @var Root
- */
- private $root;
-
- /**
- * @var View
- */
- private $view;
-
- /**
- * @var FileInfo[]
- */
- private $deleteMetaCache = [];
-
- /**
- * HookConnector constructor.
- *
- * @param Root $root
- * @param View $view
- */
- public function __construct(Root $root, View $view) {
- $this->root = $root;
- $this->view = $view;
- }
-
- public function viewToNode() {
- Util::connectHook('OC_Filesystem', 'write', $this, 'write');
- Util::connectHook('OC_Filesystem', 'post_write', $this, 'postWrite');
-
- Util::connectHook('OC_Filesystem', 'create', $this, 'create');
- Util::connectHook('OC_Filesystem', 'post_create', $this, 'postCreate');
-
- Util::connectHook('OC_Filesystem', 'delete', $this, 'delete');
- Util::connectHook('OC_Filesystem', 'post_delete', $this, 'postDelete');
-
- Util::connectHook('OC_Filesystem', 'rename', $this, 'rename');
- Util::connectHook('OC_Filesystem', 'post_rename', $this, 'postRename');
-
- Util::connectHook('OC_Filesystem', 'copy', $this, 'copy');
- Util::connectHook('OC_Filesystem', 'post_copy', $this, 'postCopy');
-
- Util::connectHook('OC_Filesystem', 'touch', $this, 'touch');
- Util::connectHook('OC_Filesystem', 'post_touch', $this, 'postTouch');
- }
-
- public function write($arguments) {
- $node = $this->getNodeForPath($arguments['path']);
- $this->root->emit('\OC\Files', 'preWrite', [$node]);
- }
-
- public function postWrite($arguments) {
- $node = $this->getNodeForPath($arguments['path']);
- $this->root->emit('\OC\Files', 'postWrite', [$node]);
- }
-
- public function create($arguments) {
- $node = $this->getNodeForPath($arguments['path']);
- $this->root->emit('\OC\Files', 'preCreate', [$node]);
- }
-
- public function postCreate($arguments) {
- $node = $this->getNodeForPath($arguments['path']);
- $this->root->emit('\OC\Files', 'postCreate', [$node]);
- }
-
- public function delete($arguments) {
- $node = $this->getNodeForPath($arguments['path']);
- $this->deleteMetaCache[$node->getPath()] = $node->getFileInfo();
- $this->root->emit('\OC\Files', 'preDelete', [$node]);
- }
-
- public function postDelete($arguments) {
- $node = $this->getNodeForPath($arguments['path']);
- unset($this->deleteMetaCache[$node->getPath()]);
- $this->root->emit('\OC\Files', 'postDelete', [$node]);
- }
-
- public function touch($arguments) {
- $node = $this->getNodeForPath($arguments['path']);
- $this->root->emit('\OC\Files', 'preTouch', [$node]);
- }
-
- public function postTouch($arguments) {
- $node = $this->getNodeForPath($arguments['path']);
- $this->root->emit('\OC\Files', 'postTouch', [$node]);
- }
-
- public function rename($arguments) {
- $source = $this->getNodeForPath($arguments['oldpath']);
- $target = $this->getNodeForPath($arguments['newpath']);
- $this->root->emit('\OC\Files', 'preRename', [$source, $target]);
- }
-
- public function postRename($arguments) {
- $source = $this->getNodeForPath($arguments['oldpath']);
- $target = $this->getNodeForPath($arguments['newpath']);
- $this->root->emit('\OC\Files', 'postRename', [$source, $target]);
- }
-
- public function copy($arguments) {
- $source = $this->getNodeForPath($arguments['oldpath']);
- $target = $this->getNodeForPath($arguments['newpath']);
- $this->root->emit('\OC\Files', 'preCopy', [$source, $target]);
- }
-
- public function postCopy($arguments) {
- $source = $this->getNodeForPath($arguments['oldpath']);
- $target = $this->getNodeForPath($arguments['newpath']);
- $this->root->emit('\OC\Files', 'postCopy', [$source, $target]);
- }
-
- private function getNodeForPath($path) {
- $info = Filesystem::getView()->getFileInfo($path);
- if (!$info) {
-
- $fullPath = Filesystem::getView()->getAbsolutePath($path);
- if (isset($this->deleteMetaCache[$fullPath])) {
- $info = $this->deleteMetaCache[$fullPath];
- } else {
- $info = null;
- }
- if (Filesystem::is_dir($path)) {
- return new NonExistingFolder($this->root, $this->view, $fullPath, $info);
- } else {
- return new NonExistingFile($this->root, $this->view, $fullPath, $info);
- }
- }
- if ($info->getType() === FileInfo::TYPE_FILE) {
- return new File($this->root, $this->view, $info->getPath(), $info);
- } else {
- return new Folder($this->root, $this->view, $info->getPath(), $info);
- }
- }
-}
diff --git a/lib/private/files/node/lazyroot.php b/lib/private/files/node/lazyroot.php
deleted file mode 100644
index 9661f036579..00000000000
--- a/lib/private/files/node/lazyroot.php
+++ /dev/null
@@ -1,474 +0,0 @@
-<?php
-/**
- * @author Roeland Jago Douma <rullzer@owncloud.com>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
- */
-namespace OC\Files\Node;
-
-use OC\Files\Mount\MountPoint;
-use OCP\Files\IRootFolder;
-use OCP\Files\NotPermittedException;
-
-/**
- * Class LazyRoot
- *
- * This is a lazy wrapper around the root. So only
- * once it is needed this will get initialized.
- *
- * @package OC\Files\Node
- */
-class LazyRoot implements IRootFolder {
- /** @var \Closure */
- private $rootFolderClosure;
-
- /** @var IRootFolder */
- private $rootFolder;
-
- /**
- * LazyRoot constructor.
- *
- * @param \Closure $rootFolderClosure
- */
- public function __construct(\Closure $rootFolderClosure) {
- $this->rootFolderClosure = $rootFolderClosure;
- }
-
- /**
- * Magic method to first get the real rootFolder and then
- * call $method with $args on it
- *
- * @param $method
- * @param $args
- * @return mixed
- */
- public function __call($method, $args) {
- if ($this->rootFolder === null) {
- $this->rootFolder = call_user_func($this->rootFolderClosure);
- }
-
- return call_user_func_array([$this->rootFolder, $method], $args);
- }
-
- /**
- * @inheritDoc
- */
- public function getUser() {
- return $this->__call(__FUNCTION__, func_get_args());
- }
-
- /**
- * @inheritDoc
- */
- public function listen($scope, $method, callable $callback) {
- $this->__call(__FUNCTION__, func_get_args());
- }
-
- /**
- * @inheritDoc
- */
- public function removeListener($scope = null, $method = null, callable $callback = null) {
- $this->__call(__FUNCTION__, func_get_args());
- }
-
- /**
- * @inheritDoc
- */
- public function emit($scope, $method, $arguments = array()) {
- $this->__call(__FUNCTION__, func_get_args());
- }
-
- /**
- * @inheritDoc
- */
- public function mount($storage, $mountPoint, $arguments = array()) {
- $this->__call(__FUNCTION__, func_get_args());
- }
-
- /**
- * @inheritDoc
- */
- public function getMount($mountPoint) {
- return $this->__call(__FUNCTION__, func_get_args());
- }
-
- /**
- * @inheritDoc
- */
- public function getMountsIn($mountPoint) {
- return $this->__call(__FUNCTION__, func_get_args());
- }
-
- /**
- * @inheritDoc
- */
- public function getMountByStorageId($storageId) {
- return $this->__call(__FUNCTION__, func_get_args());
- }
-
- /**
- * @inheritDoc
- */
- public function getMountByNumericStorageId($numericId) {
- return $this->__call(__FUNCTION__, func_get_args());
- }
-
- /**
- * @inheritDoc
- */
- public function unMount($mount) {
- $this->__call(__FUNCTION__, func_get_args());
- }
-
- /**
- * @inheritDoc
- */
- public function get($path) {
- $this->__call(__FUNCTION__, func_get_args());
- }
-
- /**
- * @inheritDoc
- */
- public function rename($targetPath) {
- return $this->__call(__FUNCTION__, func_get_args());
- }
-
- /**
- * @inheritDoc
- */
- public function delete() {
- return $this->__call(__FUNCTION__, func_get_args());
- }
-
- /**
- * @inheritDoc
- */
- public function copy($targetPath) {
- return $this->__call(__FUNCTION__, func_get_args());
- }
-
- /**
- * @inheritDoc
- */
- public function touch($mtime = null) {
- $this->__call(__FUNCTION__, func_get_args());
- }
-
- /**
- * @inheritDoc
- */
- public function getStorage() {
- return $this->__call(__FUNCTION__, func_get_args());
- }
-
- /**
- * @inheritDoc
- */
- public function getPath() {
- return $this->__call(__FUNCTION__, func_get_args());
- }
-
- /**
- * @inheritDoc
- */
- public function getInternalPath() {
- return $this->__call(__FUNCTION__, func_get_args());
- }
-
- /**
- * @inheritDoc
- */
- public function getId() {
- return $this->__call(__FUNCTION__, func_get_args());
- }
-
- /**
- * @inheritDoc
- */
- public function stat() {
- return $this->__call(__FUNCTION__, func_get_args());
- }
-
- /**
- * @inheritDoc
- */
- public function getMTime() {
- return $this->__call(__FUNCTION__, func_get_args());
- }
-
- /**
- * @inheritDoc
- */
- public function getSize() {
- return $this->__call(__FUNCTION__, func_get_args());
- }
-
- /**
- * @inheritDoc
- */
- public function getEtag() {
- return $this->__call(__FUNCTION__, func_get_args());
- }
-
- /**
- * @inheritDoc
- */
- public function getPermissions() {
- return $this->__call(__FUNCTION__, func_get_args());
- }
-
- /**
- * @inheritDoc
- */
- public function isReadable() {
- return $this->__call(__FUNCTION__, func_get_args());
- }
-
- /**
- * @inheritDoc
- */
- public function isUpdateable() {
- return $this->__call(__FUNCTION__, func_get_args());
- }
-
- /**
- * @inheritDoc
- */
- public function isDeletable() {
- return $this->__call(__FUNCTION__, func_get_args());
- }
-
- /**
- * @inheritDoc
- */
- public function isShareable() {
- return $this->__call(__FUNCTION__, func_get_args());
- }
-
- /**
- * @inheritDoc
- */
- public function getParent() {
- return $this->__call(__FUNCTION__, func_get_args());
- }
-
- /**
- * @inheritDoc
- */
- public function getName() {
- return $this->__call(__FUNCTION__, func_get_args());
- }
-
- /**
- * @inheritDoc
- */
- public function getUserFolder($userId) {
- return $this->__call(__FUNCTION__, func_get_args());
- }
-
- /**
- * @inheritDoc
- */
- public function getMimetype() {
- return $this->__call(__FUNCTION__, func_get_args());
- }
-
- /**
- * @inheritDoc
- */
- public function getMimePart() {
- return $this->__call(__FUNCTION__, func_get_args());
- }
-
- /**
- * @inheritDoc
- */
- public function isEncrypted() {
- return $this->__call(__FUNCTION__, func_get_args());
- }
-
- /**
- * @inheritDoc
- */
- public function getType() {
- return $this->__call(__FUNCTION__, func_get_args());
- }
-
- /**
- * @inheritDoc
- */
- public function isShared() {
- return $this->__call(__FUNCTION__, func_get_args());
- }
-
- /**
- * @inheritDoc
- */
- public function isMounted() {
- return $this->__call(__FUNCTION__, func_get_args());
- }
-
- /**
- * @inheritDoc
- */
- public function getMountPoint() {
- return $this->__call(__FUNCTION__, func_get_args());
- }
-
- /**
- * @inheritDoc
- */
- public function getOwner() {
- return $this->__call(__FUNCTION__, func_get_args());
- }
-
- /**
- * @inheritDoc
- */
- public function getChecksum() {
- return $this->__call(__FUNCTION__, func_get_args());
- }
-
- /**
- * @inheritDoc
- */
- public function getFullPath($path) {
- return $this->__call(__FUNCTION__, func_get_args());
- }
-
- /**
- * @inheritDoc
- */
- public function getRelativePath($path) {
- return $this->__call(__FUNCTION__, func_get_args());
- }
-
- /**
- * @inheritDoc
- */
- public function isSubNode($node) {
- return $this->__call(__FUNCTION__, func_get_args());
- }
-
- /**
- * @inheritDoc
- */
- public function getDirectoryListing() {
- return $this->__call(__FUNCTION__, func_get_args());
- }
-
- /**
- * @inheritDoc
- */
- public function nodeExists($path) {
- return $this->__call(__FUNCTION__, func_get_args());
- }
-
- /**
- * @inheritDoc
- */
- public function newFolder($path) {
- return $this->__call(__FUNCTION__, func_get_args());
- }
-
- /**
- * @inheritDoc
- */
- public function newFile($path) {
- return $this->__call(__FUNCTION__, func_get_args());
- }
-
- /**
- * @inheritDoc
- */
- public function search($query) {
- return $this->__call(__FUNCTION__, func_get_args());
- }
-
- /**
- * @inheritDoc
- */
- public function searchByMime($mimetype) {
- return $this->__call(__FUNCTION__, func_get_args());
- }
-
- /**
- * @inheritDoc
- */
- public function searchByTag($tag, $userId) {
- return $this->__call(__FUNCTION__, func_get_args());
- }
-
- /**
- * @inheritDoc
- */
- public function getById($id) {
- return $this->__call(__FUNCTION__, func_get_args());
- }
-
- /**
- * @inheritDoc
- */
- public function getFreeSpace() {
- return $this->__call(__FUNCTION__, func_get_args());
- }
-
- /**
- * @inheritDoc
- */
- public function isCreatable() {
- return $this->__call(__FUNCTION__, func_get_args());
- }
-
- /**
- * @inheritDoc
- */
- public function getNonExistingName($name) {
- return $this->__call(__FUNCTION__, func_get_args());
- }
-
- /**
- * @inheritDoc
- */
- public function move($targetPath) {
- return $this->__call(__FUNCTION__, func_get_args());
- }
-
- /**
- * @inheritDoc
- */
- public function lock($type) {
- return $this->__call(__FUNCTION__, func_get_args());
- }
-
- /**
- * @inheritDoc
- */
- public function changeLock($targetType) {
- return $this->__call(__FUNCTION__, func_get_args());
- }
-
- /**
- * @inheritDoc
- */
- public function unlock($type) {
- return $this->__call(__FUNCTION__, func_get_args());
- }
-
-
-}
diff --git a/lib/private/files/node/node.php b/lib/private/files/node/node.php
deleted file mode 100644
index c4fabfc2e2e..00000000000
--- a/lib/private/files/node/node.php
+++ /dev/null
@@ -1,383 +0,0 @@
-<?php
-/**
- * @author Bernhard Posselt <dev@bernhard-posselt.com>
- * @author Joas Schilling <nickvergessen@owncloud.com>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <icewind@owncloud.com>
- * @author Roeland Jago Douma <rullzer@owncloud.com>
- * @author Vincent Petry <pvince81@owncloud.com>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OC\Files\Node;
-
-use OC\Files\Filesystem;
-use OCP\Files\FileInfo;
-use OCP\Files\InvalidPathException;
-use OCP\Files\NotFoundException;
-use OCP\Files\NotPermittedException;
-
-class Node implements \OCP\Files\Node {
- /**
- * @var \OC\Files\View $view
- */
- protected $view;
-
- /**
- * @var \OC\Files\Node\Root $root
- */
- protected $root;
-
- /**
- * @var string $path
- */
- protected $path;
-
- /**
- * @var \OCP\Files\FileInfo
- */
- protected $fileInfo;
-
- /**
- * @param \OC\Files\View $view
- * @param \OC\Files\Node\Root $root
- * @param string $path
- * @param FileInfo $fileInfo
- */
- public function __construct($root, $view, $path, $fileInfo = null) {
- $this->view = $view;
- $this->root = $root;
- $this->path = $path;
- $this->fileInfo = $fileInfo;
- }
-
- /**
- * Returns the matching file info
- *
- * @return FileInfo
- * @throws InvalidPathException
- * @throws NotFoundException
- */
- public function getFileInfo() {
- if (!Filesystem::isValidPath($this->path)) {
- throw new InvalidPathException();
- }
- if (!$this->fileInfo) {
- $fileInfo = $this->view->getFileInfo($this->path);
- if ($fileInfo instanceof FileInfo) {
- $this->fileInfo = $fileInfo;
- } else {
- throw new NotFoundException();
- }
- }
- return $this->fileInfo;
- }
-
- /**
- * @param string[] $hooks
- */
- protected function sendHooks($hooks) {
- foreach ($hooks as $hook) {
- $this->root->emit('\OC\Files', $hook, array($this));
- }
- }
-
- /**
- * @param int $permissions
- * @return bool
- */
- protected function checkPermissions($permissions) {
- return ($this->getPermissions() & $permissions) === $permissions;
- }
-
- /**
- * @param string $targetPath
- * @throws \OCP\Files\NotPermittedException
- * @return \OC\Files\Node\Node
- */
- public function move($targetPath) {
- return;
- }
-
- public function delete() {
- return;
- }
-
- /**
- * @param string $targetPath
- * @return \OC\Files\Node\Node
- */
- public function copy($targetPath) {
- return;
- }
-
- /**
- * @param int $mtime
- * @throws \OCP\Files\NotPermittedException
- */
- public function touch($mtime = null) {
- if ($this->checkPermissions(\OCP\Constants::PERMISSION_UPDATE)) {
- $this->sendHooks(array('preTouch'));
- $this->view->touch($this->path, $mtime);
- $this->sendHooks(array('postTouch'));
- if ($this->fileInfo) {
- if (is_null($mtime)) {
- $mtime = time();
- }
- $this->fileInfo['mtime'] = $mtime;
- }
- } else {
- throw new NotPermittedException();
- }
- }
-
- /**
- * @return \OC\Files\Storage\Storage
- * @throws \OCP\Files\NotFoundException
- */
- public function getStorage() {
- list($storage,) = $this->view->resolvePath($this->path);
- return $storage;
- }
-
- /**
- * @return string
- */
- public function getPath() {
- return $this->path;
- }
-
- /**
- * @return string
- */
- public function getInternalPath() {
- list(, $internalPath) = $this->view->resolvePath($this->path);
- return $internalPath;
- }
-
- /**
- * @return int
- * @throws InvalidPathException
- * @throws NotFoundException
- */
- public function getId() {
- return $this->getFileInfo()->getId();
- }
-
- /**
- * @return array
- */
- public function stat() {
- return $this->view->stat($this->path);
- }
-
- /**
- * @return int
- * @throws InvalidPathException
- * @throws NotFoundException
- */
- public function getMTime() {
- return $this->getFileInfo()->getMTime();
- }
-
- /**
- * @return int
- * @throws InvalidPathException
- * @throws NotFoundException
- */
- public function getSize() {
- return $this->getFileInfo()->getSize();
- }
-
- /**
- * @return string
- * @throws InvalidPathException
- * @throws NotFoundException
- */
- public function getEtag() {
- return $this->getFileInfo()->getEtag();
- }
-
- /**
- * @return int
- * @throws InvalidPathException
- * @throws NotFoundException
- */
- public function getPermissions() {
- return $this->getFileInfo()->getPermissions();
- }
-
- /**
- * @return bool
- * @throws InvalidPathException
- * @throws NotFoundException
- */
- public function isReadable() {
- return $this->getFileInfo()->isReadable();
- }
-
- /**
- * @return bool
- * @throws InvalidPathException
- * @throws NotFoundException
- */
- public function isUpdateable() {
- return $this->getFileInfo()->isUpdateable();
- }
-
- /**
- * @return bool
- * @throws InvalidPathException
- * @throws NotFoundException
- */
- public function isDeletable() {
- return $this->getFileInfo()->isDeletable();
- }
-
- /**
- * @return bool
- * @throws InvalidPathException
- * @throws NotFoundException
- */
- public function isShareable() {
- return $this->getFileInfo()->isShareable();
- }
-
- /**
- * @return bool
- * @throws InvalidPathException
- * @throws NotFoundException
- */
- public function isCreatable() {
- return $this->getFileInfo()->isCreatable();
- }
-
- /**
- * @return Node
- */
- public function getParent() {
- return $this->root->get(dirname($this->path));
- }
-
- /**
- * @return string
- */
- public function getName() {
- return basename($this->path);
- }
-
- /**
- * @param string $path
- * @return string
- */
- protected function normalizePath($path) {
- if ($path === '' or $path === '/') {
- return '/';
- }
- //no windows style slashes
- $path = str_replace('\\', '/', $path);
- //add leading slash
- if ($path[0] !== '/') {
- $path = '/' . $path;
- }
- //remove duplicate slashes
- while (strpos($path, '//') !== false) {
- $path = str_replace('//', '/', $path);
- }
- //remove trailing slash
- $path = rtrim($path, '/');
-
- return $path;
- }
-
- /**
- * check if the requested path is valid
- *
- * @param string $path
- * @return bool
- */
- public function isValidPath($path) {
- if (!$path || $path[0] !== '/') {
- $path = '/' . $path;
- }
- if (strstr($path, '/../') || strrchr($path, '/') === '/..') {
- return false;
- }
- return true;
- }
-
- public function isMounted() {
- return $this->getFileInfo()->isMounted();
- }
-
- public function isShared() {
- return $this->getFileInfo()->isShared();
- }
-
- public function getMimeType() {
- return $this->getFileInfo()->getMimetype();
- }
-
- public function getMimePart() {
- return $this->getFileInfo()->getMimePart();
- }
-
- public function getType() {
- return $this->getFileInfo()->getType();
- }
-
- public function isEncrypted() {
- return $this->getFileInfo()->isEncrypted();
- }
-
- public function getMountPoint() {
- return $this->getFileInfo()->getMountPoint();
- }
-
- public function getOwner() {
- return $this->getFileInfo()->getOwner();
- }
-
- public function getChecksum() {
- return;
- }
-
- /**
- * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
- * @throws \OCP\Lock\LockedException
- */
- public function lock($type) {
- $this->view->lockFile($this->path, $type);
- }
-
- /**
- * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
- * @throws \OCP\Lock\LockedException
- */
- public function changeLock($type) {
- $this->view->changeLock($this->path, $type);
- }
-
- /**
- * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
- * @throws \OCP\Lock\LockedException
- */
- public function unlock($type) {
- $this->view->unlockFile($this->path, $type);
- }
-}
diff --git a/lib/private/files/node/nonexistingfile.php b/lib/private/files/node/nonexistingfile.php
deleted file mode 100644
index c1d09bcc491..00000000000
--- a/lib/private/files/node/nonexistingfile.php
+++ /dev/null
@@ -1,143 +0,0 @@
-<?php
-/**
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <icewind@owncloud.com>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OC\Files\Node;
-
-use OCP\Files\NotFoundException;
-
-class NonExistingFile extends File {
- /**
- * @param string $newPath
- * @throws \OCP\Files\NotFoundException
- */
- public function rename($newPath) {
- throw new NotFoundException();
- }
-
- public function delete() {
- throw new NotFoundException();
- }
-
- public function copy($newPath) {
- throw new NotFoundException();
- }
-
- public function touch($mtime = null) {
- throw new NotFoundException();
- }
-
- public function getId() {
- if ($this->fileInfo) {
- return parent::getId();
- } else {
- throw new NotFoundException();
- }
- }
-
- public function stat() {
- throw new NotFoundException();
- }
-
- public function getMTime() {
- if ($this->fileInfo) {
- return parent::getMTime();
- } else {
- throw new NotFoundException();
- }
- }
-
- public function getSize() {
- if ($this->fileInfo) {
- return parent::getSize();
- } else {
- throw new NotFoundException();
- }
- }
-
- public function getEtag() {
- if ($this->fileInfo) {
- return parent::getEtag();
- } else {
- throw new NotFoundException();
- }
- }
-
- public function getPermissions() {
- if ($this->fileInfo) {
- return parent::getPermissions();
- } else {
- throw new NotFoundException();
- }
- }
-
- public function isReadable() {
- if ($this->fileInfo) {
- return parent::isReadable();
- } else {
- throw new NotFoundException();
- }
- }
-
- public function isUpdateable() {
- if ($this->fileInfo) {
- return parent::isUpdateable();
- } else {
- throw new NotFoundException();
- }
- }
-
- public function isDeletable() {
- if ($this->fileInfo) {
- return parent::isDeletable();
- } else {
- throw new NotFoundException();
- }
- }
-
- public function isShareable() {
- if ($this->fileInfo) {
- return parent::isShareable();
- } else {
- throw new NotFoundException();
- }
- }
-
- public function getContent() {
- throw new NotFoundException();
- }
-
- public function putContent($data) {
- throw new NotFoundException();
- }
-
- public function getMimeType() {
- if ($this->fileInfo) {
- return parent::getMimeType();
- } else {
- throw new NotFoundException();
- }
- }
-
- public function fopen($mode) {
- throw new NotFoundException();
- }
-}
diff --git a/lib/private/files/node/nonexistingfolder.php b/lib/private/files/node/nonexistingfolder.php
deleted file mode 100644
index 7d6576f1bd6..00000000000
--- a/lib/private/files/node/nonexistingfolder.php
+++ /dev/null
@@ -1,172 +0,0 @@
-<?php
-/**
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <icewind@owncloud.com>
- * @author Vincent Petry <pvince81@owncloud.com>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OC\Files\Node;
-
-use OCP\Files\NotFoundException;
-
-class NonExistingFolder extends Folder {
- /**
- * @param string $newPath
- * @throws \OCP\Files\NotFoundException
- */
- public function rename($newPath) {
- throw new NotFoundException();
- }
-
- public function delete() {
- throw new NotFoundException();
- }
-
- public function copy($newPath) {
- throw new NotFoundException();
- }
-
- public function touch($mtime = null) {
- throw new NotFoundException();
- }
-
- public function getId() {
- if ($this->fileInfo) {
- return parent::getId();
- } else {
- throw new NotFoundException();
- }
- }
-
- public function stat() {
- throw new NotFoundException();
- }
-
- public function getMTime() {
- if ($this->fileInfo) {
- return parent::getMTime();
- } else {
- throw new NotFoundException();
- }
- }
-
- public function getSize() {
- if ($this->fileInfo) {
- return parent::getSize();
- } else {
- throw new NotFoundException();
- }
- }
-
- public function getEtag() {
- if ($this->fileInfo) {
- return parent::getEtag();
- } else {
- throw new NotFoundException();
- }
- }
-
- public function getPermissions() {
- if ($this->fileInfo) {
- return parent::getPermissions();
- } else {
- throw new NotFoundException();
- }
- }
-
- public function isReadable() {
- if ($this->fileInfo) {
- return parent::isReadable();
- } else {
- throw new NotFoundException();
- }
- }
-
- public function isUpdateable() {
- if ($this->fileInfo) {
- return parent::isUpdateable();
- } else {
- throw new NotFoundException();
- }
- }
-
- public function isDeletable() {
- if ($this->fileInfo) {
- return parent::isDeletable();
- } else {
- throw new NotFoundException();
- }
- }
-
- public function isShareable() {
- if ($this->fileInfo) {
- return parent::isShareable();
- } else {
- throw new NotFoundException();
- }
- }
-
- public function get($path) {
- throw new NotFoundException();
- }
-
- public function getDirectoryListing() {
- throw new NotFoundException();
- }
-
- public function nodeExists($path) {
- return false;
- }
-
- public function newFolder($path) {
- throw new NotFoundException();
- }
-
- public function newFile($path) {
- throw new NotFoundException();
- }
-
- public function search($pattern) {
- throw new NotFoundException();
- }
-
- public function searchByMime($mime) {
- throw new NotFoundException();
- }
-
- public function searchByTag($tag, $userId) {
- throw new NotFoundException();
- }
-
- public function getById($id) {
- throw new NotFoundException();
- }
-
- public function getFreeSpace() {
- throw new NotFoundException();
- }
-
- public function isCreatable() {
- if ($this->fileInfo) {
- return parent::isCreatable();
- } else {
- throw new NotFoundException();
- }
- }
-}
diff --git a/lib/private/files/node/root.php b/lib/private/files/node/root.php
deleted file mode 100644
index 04866e60b87..00000000000
--- a/lib/private/files/node/root.php
+++ /dev/null
@@ -1,357 +0,0 @@
-<?php
-/**
- * @author Bernhard Posselt <dev@bernhard-posselt.com>
- * @author Joas Schilling <nickvergessen@owncloud.com>
- * @author Jörn Friedrich Dreyer <jfd@butonic.de>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <icewind@owncloud.com>
- * @author Roeland Jago Douma <rullzer@owncloud.com>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OC\Files\Node;
-
-use OC\Files\Mount\Manager;
-use OC\Files\Mount\MountPoint;
-use OCP\Files\NotFoundException;
-use OCP\Files\NotPermittedException;
-use OC\Hooks\PublicEmitter;
-use OCP\Files\IRootFolder;
-
-/**
- * Class Root
- *
- * Hooks available in scope \OC\Files
- * - preWrite(\OCP\Files\Node $node)
- * - postWrite(\OCP\Files\Node $node)
- * - preCreate(\OCP\Files\Node $node)
- * - postCreate(\OCP\Files\Node $node)
- * - preDelete(\OCP\Files\Node $node)
- * - postDelete(\OCP\Files\Node $node)
- * - preTouch(\OC\FilesP\Node $node, int $mtime)
- * - postTouch(\OCP\Files\Node $node)
- * - preCopy(\OCP\Files\Node $source, \OCP\Files\Node $target)
- * - postCopy(\OCP\Files\Node $source, \OCP\Files\Node $target)
- * - preRename(\OCP\Files\Node $source, \OCP\Files\Node $target)
- * - postRename(\OCP\Files\Node $source, \OCP\Files\Node $target)
- *
- * @package OC\Files\Node
- */
-class Root extends Folder implements IRootFolder {
-
- /**
- * @var \OC\Files\Mount\Manager $mountManager
- */
- private $mountManager;
-
- /**
- * @var \OC\Hooks\PublicEmitter
- */
- private $emitter;
-
- /**
- * @var \OC\User\User $user
- */
- private $user;
-
- /**
- * @param \OC\Files\Mount\Manager $manager
- * @param \OC\Files\View $view
- * @param \OC\User\User|null $user
- */
- public function __construct($manager, $view, $user) {
- parent::__construct($this, $view, '');
- $this->mountManager = $manager;
- $this->user = $user;
- $this->emitter = new PublicEmitter();
- }
-
- /**
- * Get the user for which the filesystem is setup
- *
- * @return \OC\User\User
- */
- public function getUser() {
- return $this->user;
- }
-
- /**
- * @param string $scope
- * @param string $method
- * @param callable $callback
- */
- public function listen($scope, $method, callable $callback) {
- $this->emitter->listen($scope, $method, $callback);
- }
-
- /**
- * @param string $scope optional
- * @param string $method optional
- * @param callable $callback optional
- */
- public function removeListener($scope = null, $method = null, callable $callback = null) {
- $this->emitter->removeListener($scope, $method, $callback);
- }
-
- /**
- * @param string $scope
- * @param string $method
- * @param Node[] $arguments
- */
- public function emit($scope, $method, $arguments = array()) {
- $this->emitter->emit($scope, $method, $arguments);
- }
-
- /**
- * @param \OC\Files\Storage\Storage $storage
- * @param string $mountPoint
- * @param array $arguments
- */
- public function mount($storage, $mountPoint, $arguments = array()) {
- $mount = new MountPoint($storage, $mountPoint, $arguments);
- $this->mountManager->addMount($mount);
- }
-
- /**
- * @param string $mountPoint
- * @return \OC\Files\Mount\MountPoint
- */
- public function getMount($mountPoint) {
- return $this->mountManager->find($mountPoint);
- }
-
- /**
- * @param string $mountPoint
- * @return \OC\Files\Mount\MountPoint[]
- */
- public function getMountsIn($mountPoint) {
- return $this->mountManager->findIn($mountPoint);
- }
-
- /**
- * @param string $storageId
- * @return \OC\Files\Mount\MountPoint[]
- */
- public function getMountByStorageId($storageId) {
- return $this->mountManager->findByStorageId($storageId);
- }
-
- /**
- * @param int $numericId
- * @return MountPoint[]
- */
- public function getMountByNumericStorageId($numericId) {
- return $this->mountManager->findByNumericId($numericId);
- }
-
- /**
- * @param \OC\Files\Mount\MountPoint $mount
- */
- public function unMount($mount) {
- $this->mountManager->remove($mount);
- }
-
- /**
- * @param string $path
- * @throws \OCP\Files\NotFoundException
- * @throws \OCP\Files\NotPermittedException
- * @return string
- */
- public function get($path) {
- $path = $this->normalizePath($path);
- if ($this->isValidPath($path)) {
- $fullPath = $this->getFullPath($path);
- $fileInfo = $this->view->getFileInfo($fullPath);
- if ($fileInfo) {
- return $this->createNode($fullPath, $fileInfo);
- } else {
- throw new NotFoundException($path);
- }
- } else {
- throw new NotPermittedException();
- }
- }
-
- //most operations can't be done on the root
-
- /**
- * @param string $targetPath
- * @throws \OCP\Files\NotPermittedException
- * @return \OC\Files\Node\Node
- */
- public function rename($targetPath) {
- throw new NotPermittedException();
- }
-
- public function delete() {
- throw new NotPermittedException();
- }
-
- /**
- * @param string $targetPath
- * @throws \OCP\Files\NotPermittedException
- * @return \OC\Files\Node\Node
- */
- public function copy($targetPath) {
- throw new NotPermittedException();
- }
-
- /**
- * @param int $mtime
- * @throws \OCP\Files\NotPermittedException
- */
- public function touch($mtime = null) {
- throw new NotPermittedException();
- }
-
- /**
- * @return \OC\Files\Storage\Storage
- * @throws \OCP\Files\NotFoundException
- */
- public function getStorage() {
- throw new NotFoundException();
- }
-
- /**
- * @return string
- */
- public function getPath() {
- return '/';
- }
-
- /**
- * @return string
- */
- public function getInternalPath() {
- return '';
- }
-
- /**
- * @return int
- */
- public function getId() {
- return null;
- }
-
- /**
- * @return array
- */
- public function stat() {
- return null;
- }
-
- /**
- * @return int
- */
- public function getMTime() {
- return null;
- }
-
- /**
- * @return int
- */
- public function getSize() {
- return null;
- }
-
- /**
- * @return string
- */
- public function getEtag() {
- return null;
- }
-
- /**
- * @return int
- */
- public function getPermissions() {
- return \OCP\Constants::PERMISSION_CREATE;
- }
-
- /**
- * @return bool
- */
- public function isReadable() {
- return false;
- }
-
- /**
- * @return bool
- */
- public function isUpdateable() {
- return false;
- }
-
- /**
- * @return bool
- */
- public function isDeletable() {
- return false;
- }
-
- /**
- * @return bool
- */
- public function isShareable() {
- return false;
- }
-
- /**
- * @return Node
- * @throws \OCP\Files\NotFoundException
- */
- public function getParent() {
- throw new NotFoundException();
- }
-
- /**
- * @return string
- */
- public function getName() {
- return '';
- }
-
- /**
- * Returns a view to user's files folder
- *
- * @param String $userId user ID
- * @return \OCP\Files\Folder
- */
- public function getUserFolder($userId) {
- \OC\Files\Filesystem::initMountPoints($userId);
- $dir = '/' . $userId;
- $folder = null;
-
- try {
- $folder = $this->get($dir);
- } catch (NotFoundException $e) {
- $folder = $this->newFolder($dir);
- }
-
- $dir = '/files';
- try {
- $folder = $folder->get($dir);
- } catch (NotFoundException $e) {
- $folder = $folder->newFolder($dir);
- \OC_Util::copySkeleton($userId, $folder);
- }
-
- return $folder;
-
- }
-}
diff --git a/lib/private/files/objectstore/homeobjectstorestorage.php b/lib/private/files/objectstore/homeobjectstorestorage.php
deleted file mode 100644
index 6a330e2dab3..00000000000
--- a/lib/private/files/objectstore/homeobjectstorestorage.php
+++ /dev/null
@@ -1,68 +0,0 @@
-<?php
-/**
- * @author Björn Schießle <schiessle@owncloud.com>
- * @author Jörn Friedrich Dreyer <jfd@butonic.de>
- * @author Morris Jobke <hey@morrisjobke.de>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OC\Files\ObjectStore;
-
-use OC\User\User;
-
-class HomeObjectStoreStorage extends ObjectStoreStorage implements \OCP\Files\IHomeStorage {
-
- /**
- * The home user storage requires a user object to create a unique storage id
- * @param array $params
- */
- public function __construct($params) {
- if ( ! isset($params['user']) || ! $params['user'] instanceof User) {
- throw new \Exception('missing user object in parameters');
- }
- $this->user = $params['user'];
- parent::__construct($params);
- }
-
- public function getId () {
- return 'object::user:' . $this->user->getUID();
- }
-
- /**
- * get the owner of a path
- *
- * @param string $path The path to get the owner
- * @return false|string uid
- */
- public function getOwner($path) {
- if (is_object($this->user)) {
- return $this->user->getUID();
- }
- return false;
- }
-
- /**
- * @param string $path, optional
- * @return \OC\User\User
- */
- public function getUser($path = null) {
- return $this->user;
- }
-
-
-} \ No newline at end of file
diff --git a/lib/private/files/objectstore/noopscanner.php b/lib/private/files/objectstore/noopscanner.php
deleted file mode 100644
index f5316175ecf..00000000000
--- a/lib/private/files/objectstore/noopscanner.php
+++ /dev/null
@@ -1,79 +0,0 @@
-<?php
-/**
- * @author Joas Schilling <nickvergessen@owncloud.com>
- * @author Jörn Friedrich Dreyer <jfd@butonic.de>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <icewind@owncloud.com>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OC\Files\ObjectStore;
-use \OC\Files\Cache\Scanner;
-use \OC\Files\Storage\Storage;
-
-class NoopScanner extends Scanner {
-
- public function __construct(Storage $storage) {
- //we don't need the storage, so do nothing here
- }
-
- /**
- * scan a single file and store it in the cache
- *
- * @param string $file
- * @param int $reuseExisting
- * @param int $parentId
- * @param array|null $cacheData existing data in the cache for the file to be scanned
- * @return array an array of metadata of the scanned file
- */
- public function scanFile($file, $reuseExisting = 0, $parentId = -1, $cacheData = null, $lock = true) {
- return array();
- }
-
- /**
- * scan a folder and all it's children
- *
- * @param string $path
- * @param bool $recursive
- * @param int $reuse
- * @return array with the meta data of the scanned file or folder
- */
- public function scan($path, $recursive = self::SCAN_RECURSIVE, $reuse = -1, $lock = true) {
- return array();
- }
-
- /**
- * scan all the files and folders in a folder
- *
- * @param string $path
- * @param bool $recursive
- * @param int $reuse
- * @param array $folderData existing cache data for the folder to be scanned
- * @return int the size of the scanned folder or -1 if the size is unknown at this stage
- */
- protected function scanChildren($path, $recursive = self::SCAN_RECURSIVE, $reuse = -1, $folderData = null, $lock = true) {
- return 0;
- }
-
- /**
- * walk over any folders that are not fully scanned yet and scan them
- */
- public function backgroundScan() {
- //noop
- }
-}
diff --git a/lib/private/files/objectstore/objectstorestorage.php b/lib/private/files/objectstore/objectstorestorage.php
deleted file mode 100644
index 8c643dbdcc7..00000000000
--- a/lib/private/files/objectstore/objectstorestorage.php
+++ /dev/null
@@ -1,407 +0,0 @@
-<?php
-/**
- * @author Joas Schilling <nickvergessen@owncloud.com>
- * @author Jörn Friedrich Dreyer <jfd@butonic.de>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <icewind@owncloud.com>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OC\Files\ObjectStore;
-
-use Icewind\Streams\IteratorDirectory;
-use OC\Files\Cache\CacheEntry;
-use OCP\Files\ObjectStore\IObjectStore;
-
-class ObjectStoreStorage extends \OC\Files\Storage\Common {
-
- /**
- * @var array
- */
- private static $tmpFiles = array();
- /**
- * @var \OCP\Files\ObjectStore\IObjectStore $objectStore
- */
- protected $objectStore;
- /**
- * @var string $id
- */
- protected $id;
- /**
- * @var \OC\User\User $user
- */
- protected $user;
-
- public function __construct($params) {
- if (isset($params['objectstore']) && $params['objectstore'] instanceof IObjectStore) {
- $this->objectStore = $params['objectstore'];
- } else {
- throw new \Exception('missing IObjectStore instance');
- }
- if (isset($params['storageid'])) {
- $this->id = 'object::store:' . $params['storageid'];
- } else {
- $this->id = 'object::store:' . $this->objectStore->getStorageId();
- }
- //initialize cache with root directory in cache
- if (!$this->is_dir('/')) {
- $this->mkdir('/');
- }
- }
-
- public function mkdir($path) {
- $path = $this->normalizePath($path);
-
- if ($this->file_exists($path)) {
- return false;
- }
-
- $mTime = time();
- $data = [
- 'mimetype' => 'httpd/unix-directory',
- 'size' => 0,
- 'mtime' => $mTime,
- 'storage_mtime' => $mTime,
- 'permissions' => \OCP\Constants::PERMISSION_ALL,
- ];
- if ($path === '') {
- //create root on the fly
- $data['etag'] = $this->getETag('');
- $this->getCache()->put('', $data);
- return true;
- } else {
- // if parent does not exist, create it
- $parent = $this->normalizePath(dirname($path));
- $parentType = $this->filetype($parent);
- if ($parentType === false) {
- if (!$this->mkdir($parent)) {
- // something went wrong
- return false;
- }
- } else if ($parentType === 'file') {
- // parent is a file
- return false;
- }
- // finally create the new dir
- $mTime = time(); // update mtime
- $data['mtime'] = $mTime;
- $data['storage_mtime'] = $mTime;
- $data['etag'] = $this->getETag($path);
- $this->getCache()->put($path, $data);
- return true;
- }
- }
-
- /**
- * @param string $path
- * @return string
- */
- private function normalizePath($path) {
- $path = trim($path, '/');
- //FIXME why do we sometimes get a path like 'files//username'?
- $path = str_replace('//', '/', $path);
-
- // dirname('/folder') returns '.' but internally (in the cache) we store the root as ''
- if (!$path || $path === '.') {
- $path = '';
- }
-
- return $path;
- }
-
- /**
- * Object Stores use a NoopScanner because metadata is directly stored in
- * the file cache and cannot really scan the filesystem. The storage passed in is not used anywhere.
- *
- * @param string $path
- * @param \OC\Files\Storage\Storage (optional) the storage to pass to the scanner
- * @return \OC\Files\ObjectStore\NoopScanner
- */
- public function getScanner($path = '', $storage = null) {
- if (!$storage) {
- $storage = $this;
- }
- if (!isset($this->scanner)) {
- $this->scanner = new NoopScanner($storage);
- }
- return $this->scanner;
- }
-
- public function getId() {
- return $this->id;
- }
-
- public function rmdir($path) {
- $path = $this->normalizePath($path);
-
- if (!$this->is_dir($path)) {
- return false;
- }
-
- $this->rmObjects($path);
-
- $this->getCache()->remove($path);
-
- return true;
- }
-
- private function rmObjects($path) {
- $children = $this->getCache()->getFolderContents($path);
- foreach ($children as $child) {
- if ($child['mimetype'] === 'httpd/unix-directory') {
- $this->rmObjects($child['path']);
- } else {
- $this->unlink($child['path']);
- }
- }
- }
-
- public function unlink($path) {
- $path = $this->normalizePath($path);
- $stat = $this->stat($path);
-
- if ($stat && isset($stat['fileid'])) {
- if ($stat['mimetype'] === 'httpd/unix-directory') {
- return $this->rmdir($path);
- }
- try {
- $this->objectStore->deleteObject($this->getURN($stat['fileid']));
- } catch (\Exception $ex) {
- if ($ex->getCode() !== 404) {
- \OCP\Util::writeLog('objectstore', 'Could not delete object: ' . $ex->getMessage(), \OCP\Util::ERROR);
- return false;
- } else {
- //removing from cache is ok as it does not exist in the objectstore anyway
- }
- }
- $this->getCache()->remove($path);
- return true;
- }
- return false;
- }
-
- public function stat($path) {
- $path = $this->normalizePath($path);
- $cacheEntry = $this->getCache()->get($path);
- if ($cacheEntry instanceof CacheEntry) {
- return $cacheEntry->getData();
- } else {
- return false;
- }
- }
-
- /**
- * Override this method if you need a different unique resource identifier for your object storage implementation.
- * The default implementations just appends the fileId to 'urn:oid:'. Make sure the URN is unique over all users.
- * You may need a mapping table to store your URN if it cannot be generated from the fileid.
- *
- * @param int $fileId the fileid
- * @return null|string the unified resource name used to identify the object
- */
- protected function getURN($fileId) {
- if (is_numeric($fileId)) {
- return 'urn:oid:' . $fileId;
- }
- return null;
- }
-
- public function opendir($path) {
- $path = $this->normalizePath($path);
-
- try {
- $files = array();
- $folderContents = $this->getCache()->getFolderContents($path);
- foreach ($folderContents as $file) {
- $files[] = $file['name'];
- }
-
- return IteratorDirectory::wrap($files);
- } catch (\Exception $e) {
- \OCP\Util::writeLog('objectstore', $e->getMessage(), \OCP\Util::ERROR);
- return false;
- }
- }
-
- public function filetype($path) {
- $path = $this->normalizePath($path);
- $stat = $this->stat($path);
- if ($stat) {
- if ($stat['mimetype'] === 'httpd/unix-directory') {
- return 'dir';
- }
- return 'file';
- } else {
- return false;
- }
- }
-
- public function fopen($path, $mode) {
- $path = $this->normalizePath($path);
-
- switch ($mode) {
- case 'r':
- case 'rb':
- $stat = $this->stat($path);
- if (is_array($stat)) {
- try {
- return $this->objectStore->readObject($this->getURN($stat['fileid']));
- } catch (\Exception $ex) {
- \OCP\Util::writeLog('objectstore', 'Could not get object: ' . $ex->getMessage(), \OCP\Util::ERROR);
- return false;
- }
- } else {
- return false;
- }
- case 'w':
- case 'wb':
- case 'a':
- case 'ab':
- case 'r+':
- case 'w+':
- case 'wb+':
- case 'a+':
- case 'x':
- case 'x+':
- case 'c':
- case 'c+':
- if (strrpos($path, '.') !== false) {
- $ext = substr($path, strrpos($path, '.'));
- } else {
- $ext = '';
- }
- $tmpFile = \OC::$server->getTempManager()->getTemporaryFile($ext);
- \OC\Files\Stream\Close::registerCallback($tmpFile, array($this, 'writeBack'));
- if ($this->file_exists($path)) {
- $source = $this->fopen($path, 'r');
- file_put_contents($tmpFile, $source);
- }
- self::$tmpFiles[$tmpFile] = $path;
-
- return fopen('close://' . $tmpFile, $mode);
- }
- return false;
- }
-
- public function file_exists($path) {
- $path = $this->normalizePath($path);
- return (bool)$this->stat($path);
- }
-
- public function rename($source, $target) {
- $source = $this->normalizePath($source);
- $target = $this->normalizePath($target);
- $this->remove($target);
- $this->getCache()->move($source, $target);
- $this->touch(dirname($target));
- return true;
- }
-
- public function getMimeType($path) {
- $path = $this->normalizePath($path);
- $stat = $this->stat($path);
- if (is_array($stat)) {
- return $stat['mimetype'];
- } else {
- return false;
- }
- }
-
- public function touch($path, $mtime = null) {
- if (is_null($mtime)) {
- $mtime = time();
- }
-
- $path = $this->normalizePath($path);
- $dirName = dirname($path);
- $parentExists = $this->is_dir($dirName);
- if (!$parentExists) {
- return false;
- }
-
- $stat = $this->stat($path);
- if (is_array($stat)) {
- // update existing mtime in db
- $stat['mtime'] = $mtime;
- $this->getCache()->update($stat['fileid'], $stat);
- } else {
- $mimeType = \OC::$server->getMimeTypeDetector()->detectPath($path);
- // create new file
- $stat = array(
- 'etag' => $this->getETag($path),
- 'mimetype' => $mimeType,
- 'size' => 0,
- 'mtime' => $mtime,
- 'storage_mtime' => $mtime,
- 'permissions' => \OCP\Constants::PERMISSION_ALL - \OCP\Constants::PERMISSION_CREATE,
- );
- $fileId = $this->getCache()->put($path, $stat);
- try {
- //read an empty file from memory
- $this->objectStore->writeObject($this->getURN($fileId), fopen('php://memory', 'r'));
- } catch (\Exception $ex) {
- $this->getCache()->remove($path);
- \OCP\Util::writeLog('objectstore', 'Could not create object: ' . $ex->getMessage(), \OCP\Util::ERROR);
- return false;
- }
- }
- return true;
- }
-
- public function writeBack($tmpFile) {
- if (!isset(self::$tmpFiles[$tmpFile])) {
- return;
- }
-
- $path = self::$tmpFiles[$tmpFile];
- $stat = $this->stat($path);
- if (empty($stat)) {
- // create new file
- $stat = array(
- 'permissions' => \OCP\Constants::PERMISSION_ALL - \OCP\Constants::PERMISSION_CREATE,
- );
- }
- // update stat with new data
- $mTime = time();
- $stat['size'] = filesize($tmpFile);
- $stat['mtime'] = $mTime;
- $stat['storage_mtime'] = $mTime;
- $stat['mimetype'] = \OC::$server->getMimeTypeDetector()->detect($tmpFile);
- $stat['etag'] = $this->getETag($path);
-
- $fileId = $this->getCache()->put($path, $stat);
- try {
- //upload to object storage
- $this->objectStore->writeObject($this->getURN($fileId), fopen($tmpFile, 'r'));
- } catch (\Exception $ex) {
- $this->getCache()->remove($path);
- \OCP\Util::writeLog('objectstore', 'Could not create object: ' . $ex->getMessage(), \OCP\Util::ERROR);
- throw $ex; // make this bubble up
- }
- }
-
- /**
- * external changes are not supported, exclusive access to the object storage is assumed
- *
- * @param string $path
- * @param int $time
- * @return false
- */
- public function hasUpdated($path, $time) {
- return false;
- }
-}
diff --git a/lib/private/files/objectstore/swift.php b/lib/private/files/objectstore/swift.php
deleted file mode 100644
index 4af09dca254..00000000000
--- a/lib/private/files/objectstore/swift.php
+++ /dev/null
@@ -1,154 +0,0 @@
-<?php
-/**
- * @author Jörn Friedrich Dreyer <jfd@butonic.de>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <icewind@owncloud.com>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OC\Files\ObjectStore;
-
-use Guzzle\Http\Exception\ClientErrorResponseException;
-use OCP\Files\ObjectStore\IObjectStore;
-use OpenCloud\OpenStack;
-use OpenCloud\Rackspace;
-
-class Swift implements IObjectStore {
- /**
- * @var \OpenCloud\OpenStack
- */
- private $client;
-
- /**
- * @var array
- */
- private $params;
-
- /**
- * @var \OpenCloud\ObjectStore\Service
- */
- private $objectStoreService;
-
- /**
- * @var \OpenCloud\ObjectStore\Resource\Container
- */
- private $container;
-
- public function __construct($params) {
- if (!isset($params['container'])) {
- $params['container'] = 'owncloud';
- }
- if (!isset($params['autocreate'])) {
- // should only be true for tests
- $params['autocreate'] = false;
- }
-
- if (isset($params['apiKey'])) {
- $this->client = new Rackspace($params['url'], $params);
- } else {
- $this->client = new OpenStack($params['url'], $params);
- }
- $this->params = $params;
- }
-
- protected function init() {
- if ($this->container) {
- return;
- }
-
- // the OpenCloud client library will default to 'cloudFiles' if $serviceName is null
- $serviceName = null;
- if (isset($this->params['serviceName'])) {
- $serviceName = $this->params['serviceName'];
- }
-
- // the OpenCloud client library will default to 'publicURL' if $urlType is null
- $urlType = null;
- if (isset($this->params['urlType'])) {
- $urlType = $this->params['urlType'];
- }
- $this->objectStoreService = $this->client->objectStoreService($serviceName, $this->params['region'], $urlType);
-
- try {
- $this->container = $this->objectStoreService->getContainer($this->params['container']);
- } catch (ClientErrorResponseException $ex) {
- // if the container does not exist and autocreate is true try to create the container on the fly
- if (isset($this->params['autocreate']) && $this->params['autocreate'] === true) {
- $this->container = $this->objectStoreService->createContainer($this->params['container']);
- } else {
- throw $ex;
- }
- }
- }
-
- /**
- * @return string the container name where objects are stored
- */
- public function getStorageId() {
- return $this->params['container'];
- }
-
- /**
- * @param string $urn the unified resource name used to identify the object
- * @param resource $stream stream with the data to write
- * @throws Exception from openstack lib when something goes wrong
- */
- public function writeObject($urn, $stream) {
- $this->init();
- $this->container->uploadObject($urn, $stream);
- }
-
- /**
- * @param string $urn the unified resource name used to identify the object
- * @return resource stream with the read data
- * @throws Exception from openstack lib when something goes wrong
- */
- public function readObject($urn) {
- $this->init();
- $object = $this->container->getObject($urn);
-
- // we need to keep a reference to objectContent or
- // the stream will be closed before we can do anything with it
- /** @var $objectContent \Guzzle\Http\EntityBody * */
- $objectContent = $object->getContent();
- $objectContent->rewind();
-
- $stream = $objectContent->getStream();
- // save the object content in the context of the stream to prevent it being gc'd until the stream is closed
- stream_context_set_option($stream, 'swift','content', $objectContent);
-
- return $stream;
- }
-
- /**
- * @param string $urn Unified Resource Name
- * @return void
- * @throws Exception from openstack lib when something goes wrong
- */
- public function deleteObject($urn) {
- $this->init();
- // see https://github.com/rackspace/php-opencloud/issues/243#issuecomment-30032242
- $this->container->dataObject()->setName($urn)->delete();
- }
-
- public function deleteContainer($recursive = false) {
- $this->init();
- $this->container->delete($recursive);
- }
-
-}
diff --git a/lib/private/files/storage/common.php b/lib/private/files/storage/common.php
deleted file mode 100644
index 3a811b312c6..00000000000
--- a/lib/private/files/storage/common.php
+++ /dev/null
@@ -1,697 +0,0 @@
-<?php
-/**
- * @author Arthur Schiwon <blizzz@owncloud.com>
- * @author Bart Visscher <bartv@thisnet.nl>
- * @author Björn Schießle <schiessle@owncloud.com>
- * @author hkjolhede <hkjolhede@gmail.com>
- * @author Joas Schilling <nickvergessen@owncloud.com>
- * @author Jörn Friedrich Dreyer <jfd@butonic.de>
- * @author Lukas Reschke <lukas@owncloud.com>
- * @author Martin Mattel <martin.mattel@diemattels.at>
- * @author Michael Gapczynski <GapczynskiM@gmail.com>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <icewind@owncloud.com>
- * @author Robin McCorkell <robin@mccorkell.me.uk>
- * @author Sam Tuke <mail@samtuke.com>
- * @author scambra <sergio@entrecables.com>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- * @author Vincent Petry <pvince81@owncloud.com>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OC\Files\Storage;
-
-use OC\Files\Cache\Cache;
-use OC\Files\Cache\Propagator;
-use OC\Files\Cache\Scanner;
-use OC\Files\Cache\Updater;
-use OC\Files\Filesystem;
-use OC\Files\Cache\Watcher;
-use OCP\Files\FileNameTooLongException;
-use OCP\Files\InvalidCharacterInPathException;
-use OCP\Files\InvalidPathException;
-use OCP\Files\ReservedWordException;
-use OCP\Files\Storage\ILockingStorage;
-use OCP\Lock\ILockingProvider;
-
-/**
- * Storage backend class for providing common filesystem operation methods
- * which are not storage-backend specific.
- *
- * \OC\Files\Storage\Common is never used directly; it is extended by all other
- * storage backends, where its methods may be overridden, and additional
- * (backend-specific) methods are defined.
- *
- * Some \OC\Files\Storage\Common methods call functions which are first defined
- * in classes which extend it, e.g. $this->stat() .
- */
-abstract class Common implements Storage, ILockingStorage {
-
- use LocalTempFileTrait;
-
- protected $cache;
- protected $scanner;
- protected $watcher;
- protected $propagator;
- protected $storageCache;
- protected $updater;
-
- protected $mountOptions = [];
- protected $owner = null;
-
- public function __construct($parameters) {
- }
-
- /**
- * Remove a file or folder
- *
- * @param string $path
- * @return bool
- */
- protected function remove($path) {
- if ($this->is_dir($path)) {
- return $this->rmdir($path);
- } else if ($this->is_file($path)) {
- return $this->unlink($path);
- } else {
- return false;
- }
- }
-
- public function is_dir($path) {
- return $this->filetype($path) === 'dir';
- }
-
- public function is_file($path) {
- return $this->filetype($path) === 'file';
- }
-
- public function filesize($path) {
- if ($this->is_dir($path)) {
- return 0; //by definition
- } else {
- $stat = $this->stat($path);
- if (isset($stat['size'])) {
- return $stat['size'];
- } else {
- return 0;
- }
- }
- }
-
- public function isReadable($path) {
- // at least check whether it exists
- // subclasses might want to implement this more thoroughly
- return $this->file_exists($path);
- }
-
- public function isUpdatable($path) {
- // at least check whether it exists
- // subclasses might want to implement this more thoroughly
- // a non-existing file/folder isn't updatable
- return $this->file_exists($path);
- }
-
- public function isCreatable($path) {
- if ($this->is_dir($path) && $this->isUpdatable($path)) {
- return true;
- }
- return false;
- }
-
- public function isDeletable($path) {
- if ($path === '' || $path === '/') {
- return false;
- }
- $parent = dirname($path);
- return $this->isUpdatable($parent) && $this->isUpdatable($path);
- }
-
- public function isSharable($path) {
- return $this->isReadable($path);
- }
-
- public function getPermissions($path) {
- $permissions = 0;
- if ($this->isCreatable($path)) {
- $permissions |= \OCP\Constants::PERMISSION_CREATE;
- }
- if ($this->isReadable($path)) {
- $permissions |= \OCP\Constants::PERMISSION_READ;
- }
- if ($this->isUpdatable($path)) {
- $permissions |= \OCP\Constants::PERMISSION_UPDATE;
- }
- if ($this->isDeletable($path)) {
- $permissions |= \OCP\Constants::PERMISSION_DELETE;
- }
- if ($this->isSharable($path)) {
- $permissions |= \OCP\Constants::PERMISSION_SHARE;
- }
- return $permissions;
- }
-
- public function filemtime($path) {
- $stat = $this->stat($path);
- if (isset($stat['mtime']) && $stat['mtime'] > 0) {
- return $stat['mtime'];
- } else {
- return 0;
- }
- }
-
- public function file_get_contents($path) {
- $handle = $this->fopen($path, "r");
- if (!$handle) {
- return false;
- }
- $data = stream_get_contents($handle);
- fclose($handle);
- return $data;
- }
-
- public function file_put_contents($path, $data) {
- $handle = $this->fopen($path, "w");
- $this->removeCachedFile($path);
- $count = fwrite($handle, $data);
- fclose($handle);
- return $count;
- }
-
- public function rename($path1, $path2) {
- $this->remove($path2);
-
- $this->removeCachedFile($path1);
- return $this->copy($path1, $path2) and $this->remove($path1);
- }
-
- public function copy($path1, $path2) {
- if ($this->is_dir($path1)) {
- $this->remove($path2);
- $dir = $this->opendir($path1);
- $this->mkdir($path2);
- while ($file = readdir($dir)) {
- if (!Filesystem::isIgnoredDir($file)) {
- if (!$this->copy($path1 . '/' . $file, $path2 . '/' . $file)) {
- return false;
- }
- }
- }
- closedir($dir);
- return true;
- } else {
- $source = $this->fopen($path1, 'r');
- $target = $this->fopen($path2, 'w');
- list(, $result) = \OC_Helper::streamCopy($source, $target);
- $this->removeCachedFile($path2);
- return $result;
- }
- }
-
- public function getMimeType($path) {
- if ($this->is_dir($path)) {
- return 'httpd/unix-directory';
- } elseif ($this->file_exists($path)) {
- return \OC::$server->getMimeTypeDetector()->detectPath($path);
- } else {
- return false;
- }
- }
-
- public function hash($type, $path, $raw = false) {
- $fh = $this->fopen($path, 'rb');
- $ctx = hash_init($type);
- hash_update_stream($ctx, $fh);
- fclose($fh);
- return hash_final($ctx, $raw);
- }
-
- public function search($query) {
- return $this->searchInDir($query);
- }
-
- public function getLocalFile($path) {
- return $this->getCachedFile($path);
- }
-
- /**
- * @param string $path
- * @param string $target
- */
- private function addLocalFolder($path, $target) {
- $dh = $this->opendir($path);
- if (is_resource($dh)) {
- while (($file = readdir($dh)) !== false) {
- if (!\OC\Files\Filesystem::isIgnoredDir($file)) {
- if ($this->is_dir($path . '/' . $file)) {
- mkdir($target . '/' . $file);
- $this->addLocalFolder($path . '/' . $file, $target . '/' . $file);
- } else {
- $tmp = $this->toTmpFile($path . '/' . $file);
- rename($tmp, $target . '/' . $file);
- }
- }
- }
- }
- }
-
- /**
- * @param string $query
- * @param string $dir
- * @return array
- */
- protected function searchInDir($query, $dir = '') {
- $files = array();
- $dh = $this->opendir($dir);
- if (is_resource($dh)) {
- while (($item = readdir($dh)) !== false) {
- if (\OC\Files\Filesystem::isIgnoredDir($item)) continue;
- if (strstr(strtolower($item), strtolower($query)) !== false) {
- $files[] = $dir . '/' . $item;
- }
- if ($this->is_dir($dir . '/' . $item)) {
- $files = array_merge($files, $this->searchInDir($query, $dir . '/' . $item));
- }
- }
- }
- closedir($dh);
- return $files;
- }
-
- /**
- * check if a file or folder has been updated since $time
- *
- * The method is only used to check if the cache needs to be updated. Storage backends that don't support checking
- * the mtime should always return false here. As a result storage implementations that always return false expect
- * exclusive access to the backend and will not pick up files that have been added in a way that circumvents
- * ownClouds filesystem.
- *
- * @param string $path
- * @param int $time
- * @return bool
- */
- public function hasUpdated($path, $time) {
- return $this->filemtime($path) > $time;
- }
-
- public function getCache($path = '', $storage = null) {
- if (!$storage) {
- $storage = $this;
- }
- if (!isset($storage->cache)) {
- $storage->cache = new Cache($storage);
- }
- return $storage->cache;
- }
-
- public function getScanner($path = '', $storage = null) {
- if (!$storage) {
- $storage = $this;
- }
- if (!isset($storage->scanner)) {
- $storage->scanner = new Scanner($storage);
- }
- return $storage->scanner;
- }
-
- public function getWatcher($path = '', $storage = null) {
- if (!$storage) {
- $storage = $this;
- }
- if (!isset($this->watcher)) {
- $this->watcher = new Watcher($storage);
- $globalPolicy = \OC::$server->getConfig()->getSystemValue('filesystem_check_changes', Watcher::CHECK_NEVER);
- $this->watcher->setPolicy((int)$this->getMountOption('filesystem_check_changes', $globalPolicy));
- }
- return $this->watcher;
- }
-
- /**
- * get a propagator instance for the cache
- *
- * @param \OC\Files\Storage\Storage (optional) the storage to pass to the watcher
- * @return \OC\Files\Cache\Propagator
- */
- public function getPropagator($storage = null) {
- if (!$storage) {
- $storage = $this;
- }
- if (!isset($storage->propagator)) {
- $storage->propagator = new Propagator($storage);
- }
- return $storage->propagator;
- }
-
- public function getUpdater($storage = null) {
- if (!$storage) {
- $storage = $this;
- }
- if (!isset($storage->updater)) {
- $storage->updater = new Updater($storage);
- }
- return $storage->updater;
- }
-
- public function getStorageCache($storage = null) {
- if (!$storage) {
- $storage = $this;
- }
- if (!isset($this->storageCache)) {
- $this->storageCache = new \OC\Files\Cache\Storage($storage);
- }
- return $this->storageCache;
- }
-
- /**
- * get the owner of a path
- *
- * @param string $path The path to get the owner
- * @return string|false uid or false
- */
- public function getOwner($path) {
- if ($this->owner === null) {
- $this->owner = \OC_User::getUser();
- }
-
- return $this->owner;
- }
-
- /**
- * get the ETag for a file or folder
- *
- * @param string $path
- * @return string
- */
- public function getETag($path) {
- return uniqid();
- }
-
- /**
- * clean a path, i.e. remove all redundant '.' and '..'
- * making sure that it can't point to higher than '/'
- *
- * @param string $path The path to clean
- * @return string cleaned path
- */
- public function cleanPath($path) {
- if (strlen($path) == 0 or $path[0] != '/') {
- $path = '/' . $path;
- }
-
- $output = array();
- foreach (explode('/', $path) as $chunk) {
- if ($chunk == '..') {
- array_pop($output);
- } else if ($chunk == '.') {
- } else {
- $output[] = $chunk;
- }
- }
- return implode('/', $output);
- }
-
- /**
- * Test a storage for availability
- *
- * @return bool
- */
- public function test() {
- if ($this->stat('')) {
- return true;
- }
- return false;
- }
-
- /**
- * get the free space in the storage
- *
- * @param string $path
- * @return int|false
- */
- public function free_space($path) {
- return \OCP\Files\FileInfo::SPACE_UNKNOWN;
- }
-
- /**
- * {@inheritdoc}
- */
- public function isLocal() {
- // the common implementation returns a temporary file by
- // default, which is not local
- return false;
- }
-
- /**
- * Check if the storage is an instance of $class or is a wrapper for a storage that is an instance of $class
- *
- * @param string $class
- * @return bool
- */
- public function instanceOfStorage($class) {
- return is_a($this, $class);
- }
-
- /**
- * A custom storage implementation can return an url for direct download of a give file.
- *
- * For now the returned array can hold the parameter url - in future more attributes might follow.
- *
- * @param string $path
- * @return array|false
- */
- public function getDirectDownload($path) {
- return [];
- }
-
- /**
- * @inheritdoc
- */
- public function verifyPath($path, $fileName) {
- if (isset($fileName[255])) {
- throw new FileNameTooLongException();
- }
-
- // NOTE: $path will remain unverified for now
- if (\OC_Util::runningOnWindows()) {
- $this->verifyWindowsPath($fileName);
- } else {
- $this->verifyPosixPath($fileName);
- }
- }
-
- /**
- * https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247%28v=vs.85%29.aspx
- * @param string $fileName
- * @throws InvalidPathException
- */
- protected function verifyWindowsPath($fileName) {
- $fileName = trim($fileName);
- $this->scanForInvalidCharacters($fileName, "\\/<>:\"|?*");
- $reservedNames = ['CON', 'PRN', 'AUX', 'NUL', 'COM1', 'COM2', 'COM3', 'COM4', 'COM5', 'COM6', 'COM7', 'COM8', 'COM9', 'LPT1', 'LPT2', 'LPT3', 'LPT4', 'LPT5', 'LPT6', 'LPT7', 'LPT8', 'LPT9'];
- if (in_array(strtoupper($fileName), $reservedNames)) {
- throw new ReservedWordException();
- }
- }
-
- /**
- * @param string $fileName
- * @throws InvalidPathException
- */
- protected function verifyPosixPath($fileName) {
- $fileName = trim($fileName);
- $this->scanForInvalidCharacters($fileName, "\\/");
- $reservedNames = ['*'];
- if (in_array($fileName, $reservedNames)) {
- throw new ReservedWordException();
- }
- }
-
- /**
- * @param string $fileName
- * @param string $invalidChars
- * @throws InvalidPathException
- */
- private function scanForInvalidCharacters($fileName, $invalidChars) {
- foreach (str_split($invalidChars) as $char) {
- if (strpos($fileName, $char) !== false) {
- throw new InvalidCharacterInPathException();
- }
- }
-
- $sanitizedFileName = filter_var($fileName, FILTER_UNSAFE_RAW, FILTER_FLAG_STRIP_LOW);
- if ($sanitizedFileName !== $fileName) {
- throw new InvalidCharacterInPathException();
- }
- }
-
- /**
- * @param array $options
- */
- public function setMountOptions(array $options) {
- $this->mountOptions = $options;
- }
-
- /**
- * @param string $name
- * @param mixed $default
- * @return mixed
- */
- public function getMountOption($name, $default = null) {
- return isset($this->mountOptions[$name]) ? $this->mountOptions[$name] : $default;
- }
-
- /**
- * @param \OCP\Files\Storage $sourceStorage
- * @param string $sourceInternalPath
- * @param string $targetInternalPath
- * @param bool $preserveMtime
- * @return bool
- */
- public function copyFromStorage(\OCP\Files\Storage $sourceStorage, $sourceInternalPath, $targetInternalPath, $preserveMtime = false) {
- if ($sourceStorage === $this) {
- return $this->copy($sourceInternalPath, $targetInternalPath);
- }
-
- if ($sourceStorage->is_dir($sourceInternalPath)) {
- $dh = $sourceStorage->opendir($sourceInternalPath);
- $result = $this->mkdir($targetInternalPath);
- if (is_resource($dh)) {
- while ($result and ($file = readdir($dh)) !== false) {
- if (!Filesystem::isIgnoredDir($file)) {
- $result &= $this->copyFromStorage($sourceStorage, $sourceInternalPath . '/' . $file, $targetInternalPath . '/' . $file);
- }
- }
- }
- } else {
- $source = $sourceStorage->fopen($sourceInternalPath, 'r');
- // TODO: call fopen in a way that we execute again all storage wrappers
- // to avoid that we bypass storage wrappers which perform important actions
- // for this operation. Same is true for all other operations which
- // are not the same as the original one.Once this is fixed we also
- // need to adjust the encryption wrapper.
- $target = $this->fopen($targetInternalPath, 'w');
- list(, $result) = \OC_Helper::streamCopy($source, $target);
- if ($result and $preserveMtime) {
- $this->touch($targetInternalPath, $sourceStorage->filemtime($sourceInternalPath));
- }
- fclose($source);
- fclose($target);
-
- if (!$result) {
- // delete partially written target file
- $this->unlink($targetInternalPath);
- // delete cache entry that was created by fopen
- $this->getCache()->remove($targetInternalPath);
- }
- }
- return (bool)$result;
- }
-
- /**
- * @param \OCP\Files\Storage $sourceStorage
- * @param string $sourceInternalPath
- * @param string $targetInternalPath
- * @return bool
- */
- public function moveFromStorage(\OCP\Files\Storage $sourceStorage, $sourceInternalPath, $targetInternalPath) {
- if ($sourceStorage === $this) {
- return $this->rename($sourceInternalPath, $targetInternalPath);
- }
-
- if (!$sourceStorage->isDeletable($sourceInternalPath)) {
- return false;
- }
-
- $result = $this->copyFromStorage($sourceStorage, $sourceInternalPath, $targetInternalPath, true);
- if ($result) {
- if ($sourceStorage->is_dir($sourceInternalPath)) {
- $result &= $sourceStorage->rmdir($sourceInternalPath);
- } else {
- $result &= $sourceStorage->unlink($sourceInternalPath);
- }
- }
- return $result;
- }
-
- /**
- * @inheritdoc
- */
- public function getMetaData($path) {
- $permissions = $this->getPermissions($path);
- if (!$permissions & \OCP\Constants::PERMISSION_READ) {
- //can't read, nothing we can do
- return null;
- }
-
- $data = [];
- $data['mimetype'] = $this->getMimeType($path);
- $data['mtime'] = $this->filemtime($path);
- if ($data['mimetype'] == 'httpd/unix-directory') {
- $data['size'] = -1; //unknown
- } else {
- $data['size'] = $this->filesize($path);
- }
- $data['etag'] = $this->getETag($path);
- $data['storage_mtime'] = $data['mtime'];
- $data['permissions'] = $permissions;
-
- return $data;
- }
-
- /**
- * @param string $path
- * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
- * @param \OCP\Lock\ILockingProvider $provider
- * @throws \OCP\Lock\LockedException
- */
- public function acquireLock($path, $type, ILockingProvider $provider) {
- $provider->acquireLock('files/' . md5($this->getId() . '::' . trim($path, '/')), $type);
- }
-
- /**
- * @param string $path
- * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
- * @param \OCP\Lock\ILockingProvider $provider
- */
- public function releaseLock($path, $type, ILockingProvider $provider) {
- $provider->releaseLock('files/' . md5($this->getId() . '::' . trim($path, '/')), $type);
- }
-
- /**
- * @param string $path
- * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
- * @param \OCP\Lock\ILockingProvider $provider
- */
- public function changeLock($path, $type, ILockingProvider $provider) {
- $provider->changeLock('files/' . md5($this->getId() . '::' . trim($path, '/')), $type);
- }
-
- /**
- * @return array [ available, last_checked ]
- */
- public function getAvailability() {
- return $this->getStorageCache()->getAvailability();
- }
-
- /**
- * @param bool $isAvailable
- */
- public function setAvailability($isAvailable) {
- $this->getStorageCache()->setAvailability($isAvailable);
- }
-}
diff --git a/lib/private/files/storage/commontest.php b/lib/private/files/storage/commontest.php
deleted file mode 100644
index 0047a51169c..00000000000
--- a/lib/private/files/storage/commontest.php
+++ /dev/null
@@ -1,84 +0,0 @@
-<?php
-/**
- * @author Bart Visscher <bartv@thisnet.nl>
- * @author Christopher Schäpers <kondou@ts.unde.re>
- * @author Felix Moeller <mail@felixmoeller.de>
- * @author Michael Gapczynski <GapczynskiM@gmail.com>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <icewind@owncloud.com>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
- */
-
-/**
- * test implementation for \OC\Files\Storage\Common with \OC\Files\Storage\Local
- */
-
-namespace OC\Files\Storage;
-
-class CommonTest extends \OC\Files\Storage\Common{
- /**
- * underlying local storage used for missing functions
- * @var \OC\Files\Storage\Local
- */
- private $storage;
-
- public function __construct($params) {
- $this->storage=new \OC\Files\Storage\Local($params);
- }
-
- public function getId(){
- return 'test::'.$this->storage->getId();
- }
- public function mkdir($path) {
- return $this->storage->mkdir($path);
- }
- public function rmdir($path) {
- return $this->storage->rmdir($path);
- }
- public function opendir($path) {
- return $this->storage->opendir($path);
- }
- public function stat($path) {
- return $this->storage->stat($path);
- }
- public function filetype($path) {
- return @$this->storage->filetype($path);
- }
- public function isReadable($path) {
- return $this->storage->isReadable($path);
- }
- public function isUpdatable($path) {
- return $this->storage->isUpdatable($path);
- }
- public function file_exists($path) {
- return $this->storage->file_exists($path);
- }
- public function unlink($path) {
- return $this->storage->unlink($path);
- }
- public function fopen($path, $mode) {
- return $this->storage->fopen($path, $mode);
- }
- public function free_space($path) {
- return $this->storage->free_space($path);
- }
- public function touch($path, $mtime=null) {
- return $this->storage->touch($path, $mtime);
- }
-}
diff --git a/lib/private/files/storage/dav.php b/lib/private/files/storage/dav.php
deleted file mode 100644
index 8eebea1f3ba..00000000000
--- a/lib/private/files/storage/dav.php
+++ /dev/null
@@ -1,817 +0,0 @@
-<?php
-/**
- * @author Bart Visscher <bartv@thisnet.nl>
- * @author Björn Schießle <schiessle@owncloud.com>
- * @author Carlos Cerrillo <ccerrillo@gmail.com>
- * @author Felix Moeller <mail@felixmoeller.de>
- * @author Jörn Friedrich Dreyer <jfd@butonic.de>
- * @author Lukas Reschke <lukas@owncloud.com>
- * @author Michael Gapczynski <GapczynskiM@gmail.com>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Philipp Kapfer <philipp.kapfer@gmx.at>
- * @author Robin Appelman <icewind@owncloud.com>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- * @author Vincent Petry <pvince81@owncloud.com>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OC\Files\Storage;
-
-use Exception;
-use GuzzleHttp\Exception\RequestException;
-use GuzzleHttp\Message\ResponseInterface;
-use OC\Files\Filesystem;
-use OC\Files\Stream\Close;
-use Icewind\Streams\IteratorDirectory;
-use OC\MemCache\ArrayCache;
-use OCP\AppFramework\Http;
-use OCP\Constants;
-use OCP\Files;
-use OCP\Files\FileInfo;
-use OCP\Files\StorageInvalidException;
-use OCP\Files\StorageNotAvailableException;
-use OCP\Util;
-use Sabre\DAV\Client;
-use Sabre\DAV\Exception\NotFound;
-use Sabre\DAV\Xml\Property\ResourceType;
-use Sabre\HTTP\ClientException;
-use Sabre\HTTP\ClientHttpException;
-
-/**
- * Class DAV
- *
- * @package OC\Files\Storage
- */
-class DAV extends Common {
- /** @var string */
- protected $password;
- /** @var string */
- protected $user;
- /** @var string */
- protected $host;
- /** @var bool */
- protected $secure;
- /** @var string */
- protected $root;
- /** @var string */
- protected $certPath;
- /** @var bool */
- protected $ready;
- /** @var Client */
- private $client;
- /** @var ArrayCache */
- private $statCache;
- /** @var array */
- private static $tempFiles = [];
- /** @var \OCP\Http\Client\IClientService */
- private $httpClientService;
-
- /**
- * @param array $params
- * @throws \Exception
- */
- public function __construct($params) {
- $this->statCache = new ArrayCache();
- $this->httpClientService = \OC::$server->getHTTPClientService();
- if (isset($params['host']) && isset($params['user']) && isset($params['password'])) {
- $host = $params['host'];
- //remove leading http[s], will be generated in createBaseUri()
- if (substr($host, 0, 8) == "https://") $host = substr($host, 8);
- else if (substr($host, 0, 7) == "http://") $host = substr($host, 7);
- $this->host = $host;
- $this->user = $params['user'];
- $this->password = $params['password'];
- if (isset($params['secure'])) {
- if (is_string($params['secure'])) {
- $this->secure = ($params['secure'] === 'true');
- } else {
- $this->secure = (bool)$params['secure'];
- }
- } else {
- $this->secure = false;
- }
- if ($this->secure === true) {
- // inject mock for testing
- $certPath = \OC_User::getHome(\OC_User::getUser()) . '/files_external/rootcerts.crt';
- if (file_exists($certPath)) {
- $this->certPath = $certPath;
- }
- }
- $this->root = isset($params['root']) ? $params['root'] : '/';
- if (!$this->root || $this->root[0] != '/') {
- $this->root = '/' . $this->root;
- }
- if (substr($this->root, -1, 1) != '/') {
- $this->root .= '/';
- }
- } else {
- throw new \Exception('Invalid webdav storage configuration');
- }
- }
-
- private function init() {
- if ($this->ready) {
- return;
- }
- $this->ready = true;
-
- $settings = array(
- 'baseUri' => $this->createBaseUri(),
- 'userName' => $this->user,
- 'password' => $this->password,
- );
-
- $proxy = \OC::$server->getConfig()->getSystemValue('proxy', '');
- if($proxy !== '') {
- $settings['proxy'] = $proxy;
- }
-
- $this->client = new Client($settings);
- $this->client->setThrowExceptions(true);
- if ($this->secure === true && $this->certPath) {
- $this->client->addCurlSetting(CURLOPT_CAINFO, $this->certPath);
- }
- }
-
- /**
- * Clear the stat cache
- */
- public function clearStatCache() {
- $this->statCache->clear();
- }
-
- /** {@inheritdoc} */
- public function getId() {
- return 'webdav::' . $this->user . '@' . $this->host . '/' . $this->root;
- }
-
- /** {@inheritdoc} */
- public function createBaseUri() {
- $baseUri = 'http';
- if ($this->secure) {
- $baseUri .= 's';
- }
- $baseUri .= '://' . $this->host . $this->root;
- return $baseUri;
- }
-
- /** {@inheritdoc} */
- public function mkdir($path) {
- $this->init();
- $path = $this->cleanPath($path);
- $result = $this->simpleResponse('MKCOL', $path, null, 201);
- if ($result) {
- $this->statCache->set($path, true);
- }
- return $result;
- }
-
- /** {@inheritdoc} */
- public function rmdir($path) {
- $this->init();
- $path = $this->cleanPath($path);
- // FIXME: some WebDAV impl return 403 when trying to DELETE
- // a non-empty folder
- $result = $this->simpleResponse('DELETE', $path . '/', null, 204);
- $this->statCache->clear($path . '/');
- $this->statCache->remove($path);
- return $result;
- }
-
- /** {@inheritdoc} */
- public function opendir($path) {
- $this->init();
- $path = $this->cleanPath($path);
- try {
- $response = $this->client->propfind(
- $this->encodePath($path),
- array(),
- 1
- );
- $id = md5('webdav' . $this->root . $path);
- $content = array();
- $files = array_keys($response);
- array_shift($files); //the first entry is the current directory
-
- if (!$this->statCache->hasKey($path)) {
- $this->statCache->set($path, true);
- }
- foreach ($files as $file) {
- $file = urldecode($file);
- // do not store the real entry, we might not have all properties
- if (!$this->statCache->hasKey($path)) {
- $this->statCache->set($file, true);
- }
- $file = basename($file);
- $content[] = $file;
- }
- return IteratorDirectory::wrap($content);
- } catch (ClientHttpException $e) {
- if ($e->getHttpStatus() === 404) {
- $this->statCache->clear($path . '/');
- $this->statCache->set($path, false);
- return false;
- }
- $this->convertException($e, $path);
- } catch (\Exception $e) {
- $this->convertException($e, $path);
- }
- return false;
- }
-
- /**
- * Propfind call with cache handling.
- *
- * First checks if information is cached.
- * If not, request it from the server then store to cache.
- *
- * @param string $path path to propfind
- *
- * @return array propfind response
- *
- * @throws NotFound
- */
- protected function propfind($path) {
- $path = $this->cleanPath($path);
- $cachedResponse = $this->statCache->get($path);
- if ($cachedResponse === false) {
- // we know it didn't exist
- throw new NotFound();
- }
- // we either don't know it, or we know it exists but need more details
- if (is_null($cachedResponse) || $cachedResponse === true) {
- $this->init();
- try {
- $response = $this->client->propfind(
- $this->encodePath($path),
- array(
- '{DAV:}getlastmodified',
- '{DAV:}getcontentlength',
- '{DAV:}getcontenttype',
- '{http://owncloud.org/ns}permissions',
- '{http://open-collaboration-services.org/ns}share-permissions',
- '{DAV:}resourcetype',
- '{DAV:}getetag',
- )
- );
- $this->statCache->set($path, $response);
- } catch (NotFound $e) {
- // remember that this path did not exist
- $this->statCache->clear($path . '/');
- $this->statCache->set($path, false);
- throw $e;
- }
- } else {
- $response = $cachedResponse;
- }
- return $response;
- }
-
- /** {@inheritdoc} */
- public function filetype($path) {
- try {
- $response = $this->propfind($path);
- $responseType = array();
- if (isset($response["{DAV:}resourcetype"])) {
- /** @var ResourceType[] $response */
- $responseType = $response["{DAV:}resourcetype"]->getValue();
- }
- return (count($responseType) > 0 and $responseType[0] == "{DAV:}collection") ? 'dir' : 'file';
- } catch (ClientHttpException $e) {
- if ($e->getHttpStatus() === 404) {
- return false;
- }
- $this->convertException($e, $path);
- } catch (\Exception $e) {
- $this->convertException($e, $path);
- }
- return false;
- }
-
- /** {@inheritdoc} */
- public function file_exists($path) {
- try {
- $path = $this->cleanPath($path);
- $cachedState = $this->statCache->get($path);
- if ($cachedState === false) {
- // we know the file doesn't exist
- return false;
- } else if (!is_null($cachedState)) {
- return true;
- }
- // need to get from server
- $this->propfind($path);
- return true; //no 404 exception
- } catch (ClientHttpException $e) {
- if ($e->getHttpStatus() === 404) {
- return false;
- }
- $this->convertException($e, $path);
- } catch (\Exception $e) {
- $this->convertException($e, $path);
- }
- return false;
- }
-
- /** {@inheritdoc} */
- public function unlink($path) {
- $this->init();
- $path = $this->cleanPath($path);
- $result = $this->simpleResponse('DELETE', $path, null, 204);
- $this->statCache->clear($path . '/');
- $this->statCache->remove($path);
- return $result;
- }
-
- /** {@inheritdoc} */
- public function fopen($path, $mode) {
- $this->init();
- $path = $this->cleanPath($path);
- switch ($mode) {
- case 'r':
- case 'rb':
- try {
- $response = $this->httpClientService
- ->newClient()
- ->get($this->createBaseUri() . $this->encodePath($path), [
- 'auth' => [$this->user, $this->password],
- 'stream' => true
- ]);
- } catch (RequestException $e) {
- if ($e->getResponse() instanceof ResponseInterface
- && $e->getResponse()->getStatusCode() === 404) {
- return false;
- } else {
- throw $e;
- }
- }
-
- if ($response->getStatusCode() !== Http::STATUS_OK) {
- if ($response->getStatusCode() === Http::STATUS_LOCKED) {
- throw new \OCP\Lock\LockedException($path);
- } else {
- Util::writeLog("webdav client", 'Guzzle get returned status code ' . $response->getStatusCode(), Util::ERROR);
- }
- }
-
- return $response->getBody();
- case 'w':
- case 'wb':
- case 'a':
- case 'ab':
- case 'r+':
- case 'w+':
- case 'wb+':
- case 'a+':
- case 'x':
- case 'x+':
- case 'c':
- case 'c+':
- //emulate these
- $tempManager = \OC::$server->getTempManager();
- if (strrpos($path, '.') !== false) {
- $ext = substr($path, strrpos($path, '.'));
- } else {
- $ext = '';
- }
- if ($this->file_exists($path)) {
- if (!$this->isUpdatable($path)) {
- return false;
- }
- if ($mode === 'w' or $mode === 'w+') {
- $tmpFile = $tempManager->getTemporaryFile($ext);
- } else {
- $tmpFile = $this->getCachedFile($path);
- }
- } else {
- if (!$this->isCreatable(dirname($path))) {
- return false;
- }
- $tmpFile = $tempManager->getTemporaryFile($ext);
- }
- Close::registerCallback($tmpFile, array($this, 'writeBack'));
- self::$tempFiles[$tmpFile] = $path;
- return fopen('close://' . $tmpFile, $mode);
- }
- }
-
- /**
- * @param string $tmpFile
- */
- public function writeBack($tmpFile) {
- if (isset(self::$tempFiles[$tmpFile])) {
- $this->uploadFile($tmpFile, self::$tempFiles[$tmpFile]);
- unlink($tmpFile);
- }
- }
-
- /** {@inheritdoc} */
- public function free_space($path) {
- $this->init();
- $path = $this->cleanPath($path);
- try {
- // TODO: cacheable ?
- $response = $this->client->propfind($this->encodePath($path), array('{DAV:}quota-available-bytes'));
- if (isset($response['{DAV:}quota-available-bytes'])) {
- return (int)$response['{DAV:}quota-available-bytes'];
- } else {
- return FileInfo::SPACE_UNKNOWN;
- }
- } catch (\Exception $e) {
- return FileInfo::SPACE_UNKNOWN;
- }
- }
-
- /** {@inheritdoc} */
- public function touch($path, $mtime = null) {
- $this->init();
- if (is_null($mtime)) {
- $mtime = time();
- }
- $path = $this->cleanPath($path);
-
- // if file exists, update the mtime, else create a new empty file
- if ($this->file_exists($path)) {
- try {
- $this->statCache->remove($path);
- $this->client->proppatch($this->encodePath($path), array('{DAV:}lastmodified' => $mtime));
- } catch (ClientHttpException $e) {
- if ($e->getHttpStatus() === 501) {
- return false;
- }
- $this->convertException($e, $path);
- return false;
- } catch (\Exception $e) {
- $this->convertException($e, $path);
- return false;
- }
- } else {
- $this->file_put_contents($path, '');
- }
- return true;
- }
-
- /**
- * @param string $path
- * @param string $data
- * @return int
- */
- public function file_put_contents($path, $data) {
- $path = $this->cleanPath($path);
- $result = parent::file_put_contents($path, $data);
- $this->statCache->remove($path);
- return $result;
- }
-
- /**
- * @param string $path
- * @param string $target
- */
- protected function uploadFile($path, $target) {
- $this->init();
-
- // invalidate
- $target = $this->cleanPath($target);
- $this->statCache->remove($target);
- $source = fopen($path, 'r');
-
- $this->httpClientService
- ->newClient()
- ->put($this->createBaseUri() . $this->encodePath($target), [
- 'body' => $source,
- 'auth' => [$this->user, $this->password]
- ]);
-
- $this->removeCachedFile($target);
- }
-
- /** {@inheritdoc} */
- public function rename($path1, $path2) {
- $this->init();
- $path1 = $this->cleanPath($path1);
- $path2 = $this->cleanPath($path2);
- try {
- $this->client->request(
- 'MOVE',
- $this->encodePath($path1),
- null,
- array(
- 'Destination' => $this->createBaseUri() . $this->encodePath($path2)
- )
- );
- $this->statCache->clear($path1 . '/');
- $this->statCache->clear($path2 . '/');
- $this->statCache->set($path1, false);
- $this->statCache->set($path2, true);
- $this->removeCachedFile($path1);
- $this->removeCachedFile($path2);
- return true;
- } catch (\Exception $e) {
- $this->convertException($e);
- }
- return false;
- }
-
- /** {@inheritdoc} */
- public function copy($path1, $path2) {
- $this->init();
- $path1 = $this->encodePath($this->cleanPath($path1));
- $path2 = $this->createBaseUri() . $this->encodePath($this->cleanPath($path2));
- try {
- $this->client->request('COPY', $path1, null, array('Destination' => $path2));
- $this->statCache->clear($path2 . '/');
- $this->statCache->set($path2, true);
- $this->removeCachedFile($path2);
- return true;
- } catch (\Exception $e) {
- $this->convertException($e);
- }
- return false;
- }
-
- /** {@inheritdoc} */
- public function stat($path) {
- try {
- $response = $this->propfind($path);
- return array(
- 'mtime' => strtotime($response['{DAV:}getlastmodified']),
- 'size' => (int)isset($response['{DAV:}getcontentlength']) ? $response['{DAV:}getcontentlength'] : 0,
- );
- } catch (ClientHttpException $e) {
- if ($e->getHttpStatus() === 404) {
- return array();
- }
- $this->convertException($e, $path);
- } catch (\Exception $e) {
- $this->convertException($e, $path);
- }
- return array();
- }
-
- /** {@inheritdoc} */
- public function getMimeType($path) {
- try {
- $response = $this->propfind($path);
- $responseType = array();
- if (isset($response["{DAV:}resourcetype"])) {
- /** @var ResourceType[] $response */
- $responseType = $response["{DAV:}resourcetype"]->getValue();
- }
- $type = (count($responseType) > 0 and $responseType[0] == "{DAV:}collection") ? 'dir' : 'file';
- if ($type == 'dir') {
- return 'httpd/unix-directory';
- } elseif (isset($response['{DAV:}getcontenttype'])) {
- return $response['{DAV:}getcontenttype'];
- } else {
- return false;
- }
- } catch (ClientHttpException $e) {
- if ($e->getHttpStatus() === 404) {
- return false;
- }
- $this->convertException($e, $path);
- } catch (\Exception $e) {
- $this->convertException($e, $path);
- }
- return false;
- }
-
- /**
- * @param string $path
- * @return string
- */
- public function cleanPath($path) {
- if ($path === '') {
- return $path;
- }
- $path = Filesystem::normalizePath($path);
- // remove leading slash
- return substr($path, 1);
- }
-
- /**
- * URL encodes the given path but keeps the slashes
- *
- * @param string $path to encode
- * @return string encoded path
- */
- private function encodePath($path) {
- // slashes need to stay
- return str_replace('%2F', '/', rawurlencode($path));
- }
-
- /**
- * @param string $method
- * @param string $path
- * @param string|resource|null $body
- * @param int $expected
- * @return bool
- * @throws StorageInvalidException
- * @throws StorageNotAvailableException
- */
- private function simpleResponse($method, $path, $body, $expected) {
- $path = $this->cleanPath($path);
- try {
- $response = $this->client->request($method, $this->encodePath($path), $body);
- return $response['statusCode'] == $expected;
- } catch (ClientHttpException $e) {
- if ($e->getHttpStatus() === 404 && $method === 'DELETE') {
- $this->statCache->clear($path . '/');
- $this->statCache->set($path, false);
- return false;
- }
-
- $this->convertException($e, $path);
- } catch (\Exception $e) {
- $this->convertException($e, $path);
- }
- return false;
- }
-
- /**
- * check if curl is installed
- */
- public static function checkDependencies() {
- return true;
- }
-
- /** {@inheritdoc} */
- public function isUpdatable($path) {
- return (bool)($this->getPermissions($path) & Constants::PERMISSION_UPDATE);
- }
-
- /** {@inheritdoc} */
- public function isCreatable($path) {
- return (bool)($this->getPermissions($path) & Constants::PERMISSION_CREATE);
- }
-
- /** {@inheritdoc} */
- public function isSharable($path) {
- return (bool)($this->getPermissions($path) & Constants::PERMISSION_SHARE);
- }
-
- /** {@inheritdoc} */
- public function isDeletable($path) {
- return (bool)($this->getPermissions($path) & Constants::PERMISSION_DELETE);
- }
-
- /** {@inheritdoc} */
- public function getPermissions($path) {
- $this->init();
- $path = $this->cleanPath($path);
- $response = $this->propfind($path);
- if (isset($response['{http://owncloud.org/ns}permissions'])) {
- return $this->parsePermissions($response['{http://owncloud.org/ns}permissions']);
- } else if ($this->is_dir($path)) {
- return Constants::PERMISSION_ALL;
- } else if ($this->file_exists($path)) {
- return Constants::PERMISSION_ALL - Constants::PERMISSION_CREATE;
- } else {
- return 0;
- }
- }
-
- /** {@inheritdoc} */
- public function getETag($path) {
- $this->init();
- $path = $this->cleanPath($path);
- $response = $this->propfind($path);
- if (isset($response['{DAV:}getetag'])) {
- return trim($response['{DAV:}getetag'], '"');
- }
- return parent::getEtag($path);
- }
-
- /**
- * @param string $permissionsString
- * @return int
- */
- protected function parsePermissions($permissionsString) {
- $permissions = Constants::PERMISSION_READ;
- if (strpos($permissionsString, 'R') !== false) {
- $permissions |= Constants::PERMISSION_SHARE;
- }
- if (strpos($permissionsString, 'D') !== false) {
- $permissions |= Constants::PERMISSION_DELETE;
- }
- if (strpos($permissionsString, 'W') !== false) {
- $permissions |= Constants::PERMISSION_UPDATE;
- }
- if (strpos($permissionsString, 'CK') !== false) {
- $permissions |= Constants::PERMISSION_CREATE;
- $permissions |= Constants::PERMISSION_UPDATE;
- }
- return $permissions;
- }
-
- /**
- * check if a file or folder has been updated since $time
- *
- * @param string $path
- * @param int $time
- * @throws \OCP\Files\StorageNotAvailableException
- * @return bool
- */
- public function hasUpdated($path, $time) {
- $this->init();
- $path = $this->cleanPath($path);
- try {
- // force refresh for $path
- $this->statCache->remove($path);
- $response = $this->propfind($path);
- if (isset($response['{DAV:}getetag'])) {
- $cachedData = $this->getCache()->get($path);
- $etag = null;
- if (isset($response['{DAV:}getetag'])) {
- $etag = trim($response['{DAV:}getetag'], '"');
- }
- if (!empty($etag) && $cachedData['etag'] !== $etag) {
- return true;
- } else if (isset($response['{http://open-collaboration-services.org/ns}share-permissions'])) {
- $sharePermissions = (int)$response['{http://open-collaboration-services.org/ns}share-permissions'];
- return $sharePermissions !== $cachedData['permissions'];
- } else if (isset($response['{http://owncloud.org/ns}permissions'])) {
- $permissions = $this->parsePermissions($response['{http://owncloud.org/ns}permissions']);
- return $permissions !== $cachedData['permissions'];
- } else {
- return false;
- }
- } else {
- $remoteMtime = strtotime($response['{DAV:}getlastmodified']);
- return $remoteMtime > $time;
- }
- } catch (ClientHttpException $e) {
- if ($e->getHttpStatus() === 404 || $e->getHttpStatus() === 405) {
- if ($path === '') {
- // if root is gone it means the storage is not available
- throw new StorageNotAvailableException(get_class($e) . ': ' . $e->getMessage());
- }
- return false;
- }
- $this->convertException($e, $path);
- return false;
- } catch (\Exception $e) {
- $this->convertException($e, $path);
- return false;
- }
- }
-
- /**
- * Interpret the given exception and decide whether it is due to an
- * unavailable storage, invalid storage or other.
- * This will either throw StorageInvalidException, StorageNotAvailableException
- * or do nothing.
- *
- * @param Exception $e sabre exception
- * @param string $path optional path from the operation
- *
- * @throws StorageInvalidException if the storage is invalid, for example
- * when the authentication expired or is invalid
- * @throws StorageNotAvailableException if the storage is not available,
- * which might be temporary
- */
- private function convertException(Exception $e, $path = '') {
- Util::writeLog('files_external', $e->getMessage(), Util::ERROR);
- if ($e instanceof ClientHttpException) {
- if ($e->getHttpStatus() === 423) {
- throw new \OCP\Lock\LockedException($path);
- }
- if ($e->getHttpStatus() === 401) {
- // either password was changed or was invalid all along
- throw new StorageInvalidException(get_class($e) . ': ' . $e->getMessage());
- } else if ($e->getHttpStatus() === 405) {
- // ignore exception for MethodNotAllowed, false will be returned
- return;
- }
- throw new StorageNotAvailableException(get_class($e) . ': ' . $e->getMessage());
- } else if ($e instanceof ClientException) {
- // connection timeout or refused, server could be temporarily down
- throw new StorageNotAvailableException(get_class($e) . ': ' . $e->getMessage());
- } else if ($e instanceof \InvalidArgumentException) {
- // parse error because the server returned HTML instead of XML,
- // possibly temporarily down
- throw new StorageNotAvailableException(get_class($e) . ': ' . $e->getMessage());
- } else if (($e instanceof StorageNotAvailableException) || ($e instanceof StorageInvalidException)) {
- // rethrow
- throw $e;
- }
-
- // TODO: only log for now, but in the future need to wrap/rethrow exception
- }
-}
-
diff --git a/lib/private/files/storage/failedstorage.php b/lib/private/files/storage/failedstorage.php
deleted file mode 100644
index df7f76856d5..00000000000
--- a/lib/private/files/storage/failedstorage.php
+++ /dev/null
@@ -1,215 +0,0 @@
-<?php
-/**
- * @author Robin Appelman <icewind@owncloud.com>
- * @author Robin McCorkell <robin@mccorkell.me.uk>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OC\Files\Storage;
-
-use OC\Files\Cache\FailedCache;
-use \OCP\Lock\ILockingProvider;
-use \OCP\Files\StorageNotAvailableException;
-
-/**
- * Storage placeholder to represent a missing precondition, storage unavailable
- */
-class FailedStorage extends Common {
-
- /** @var \Exception */
- protected $e;
-
- /**
- * @param array $params ['exception' => \Exception]
- */
- public function __construct($params) {
- $this->e = $params['exception'];
- if (!$this->e) {
- throw new \InvalidArgumentException('Missing "exception" argument in FailedStorage constructor');
- }
- }
-
- public function getId() {
- // we can't return anything sane here
- return 'failedstorage';
- }
-
- public function mkdir($path) {
- throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
- }
-
- public function rmdir($path) {
- throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
- }
-
- public function opendir($path) {
- throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
- }
-
- public function is_dir($path) {
- throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
- }
-
- public function is_file($path) {
- throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
- }
-
- public function stat($path) {
- throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
- }
-
- public function filetype($path) {
- throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
- }
-
- public function filesize($path) {
- throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
- }
-
- public function isCreatable($path) {
- throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
- }
-
- public function isReadable($path) {
- throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
- }
-
- public function isUpdatable($path) {
- throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
- }
-
- public function isDeletable($path) {
- throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
- }
-
- public function isSharable($path) {
- throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
- }
-
- public function getPermissions($path) {
- throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
- }
-
- public function file_exists($path) {
- throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
- }
-
- public function filemtime($path) {
- throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
- }
-
- public function file_get_contents($path) {
- throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
- }
-
- public function file_put_contents($path, $data) {
- throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
- }
-
- public function unlink($path) {
- throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
- }
-
- public function rename($path1, $path2) {
- throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
- }
-
- public function copy($path1, $path2) {
- throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
- }
-
- public function fopen($path, $mode) {
- throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
- }
-
- public function getMimeType($path) {
- throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
- }
-
- public function hash($type, $path, $raw = false) {
- throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
- }
-
- public function free_space($path) {
- throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
- }
-
- public function search($query) {
- throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
- }
-
- public function touch($path, $mtime = null) {
- throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
- }
-
- public function getLocalFile($path) {
- throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
- }
-
- public function getLocalFolder($path) {
- throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
- }
-
- public function hasUpdated($path, $time) {
- throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
- }
-
- public function getETag($path) {
- throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
- }
-
- public function getDirectDownload($path) {
- throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
- }
-
- public function verifyPath($path, $fileName) {
- return true;
- }
-
- public function copyFromStorage(\OCP\Files\Storage $sourceStorage, $sourceInternalPath, $targetInternalPath) {
- throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
- }
-
- public function moveFromStorage(\OCP\Files\Storage $sourceStorage, $sourceInternalPath, $targetInternalPath) {
- throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
- }
-
- public function acquireLock($path, $type, ILockingProvider $provider) {
- throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
- }
-
- public function releaseLock($path, $type, ILockingProvider $provider) {
- throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
- }
-
- public function changeLock($path, $type, ILockingProvider $provider) {
- throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
- }
-
- public function getAvailability() {
- throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
- }
-
- public function setAvailability($isAvailable) {
- throw new StorageNotAvailableException($this->e->getMessage(), $this->e->getCode(), $this->e);
- }
-
- public function getCache($path = '', $storage = null) {
- return new FailedCache();
- }
-}
diff --git a/lib/private/files/storage/flysystem.php b/lib/private/files/storage/flysystem.php
deleted file mode 100644
index 608639b71a6..00000000000
--- a/lib/private/files/storage/flysystem.php
+++ /dev/null
@@ -1,256 +0,0 @@
-<?php
-/**
- * @author Robin Appelman <icewind@owncloud.com>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OC\Files\Storage;
-
-use Icewind\Streams\CallbackWrapper;
-use Icewind\Streams\IteratorDirectory;
-use League\Flysystem\AdapterInterface;
-use League\Flysystem\FileNotFoundException;
-use League\Flysystem\Filesystem;
-use League\Flysystem\Plugin\GetWithMetadata;
-
-/**
- * Generic adapter between flysystem adapters and owncloud's storage system
- *
- * To use: subclass and call $this->buildFlysystem with the flysystem adapter of choice
- */
-abstract class Flysystem extends Common {
- /**
- * @var Filesystem
- */
- protected $flysystem;
-
- /**
- * @var string
- */
- protected $root = '';
-
- /**
- * Initialize the storage backend with a flyssytem adapter
- *
- * @param \League\Flysystem\AdapterInterface $adapter
- */
- protected function buildFlySystem(AdapterInterface $adapter) {
- $this->flysystem = new Filesystem($adapter);
- $this->flysystem->addPlugin(new GetWithMetadata());
- }
-
- protected function buildPath($path) {
- $fullPath = \OC\Files\Filesystem::normalizePath($this->root . '/' . $path);
- return ltrim($fullPath, '/');
- }
-
- /**
- * {@inheritdoc}
- */
- public function file_get_contents($path) {
- return $this->flysystem->read($this->buildPath($path));
- }
-
- /**
- * {@inheritdoc}
- */
- public function file_put_contents($path, $data) {
- return $this->flysystem->put($this->buildPath($path), $data);
- }
-
- /**
- * {@inheritdoc}
- */
- public function file_exists($path) {
- return $this->flysystem->has($this->buildPath($path));
- }
-
- /**
- * {@inheritdoc}
- */
- public function unlink($path) {
- if ($this->is_dir($path)) {
- return $this->rmdir($path);
- }
- try {
- return $this->flysystem->delete($this->buildPath($path));
- } catch (FileNotFoundException $e) {
- return false;
- }
- }
-
- /**
- * {@inheritdoc}
- */
- public function rename($source, $target) {
- if ($this->file_exists($target)) {
- $this->unlink($target);
- }
- return $this->flysystem->rename($this->buildPath($source), $this->buildPath($target));
- }
-
- /**
- * {@inheritdoc}
- */
- public function copy($source, $target) {
- if ($this->file_exists($target)) {
- $this->unlink($target);
- }
- return $this->flysystem->copy($this->buildPath($source), $this->buildPath($target));
- }
-
- /**
- * {@inheritdoc}
- */
- public function filesize($path) {
- if ($this->is_dir($path)) {
- return 0;
- } else {
- return $this->flysystem->getSize($this->buildPath($path));
- }
- }
-
- /**
- * {@inheritdoc}
- */
- public function mkdir($path) {
- if ($this->file_exists($path)) {
- return false;
- }
- return $this->flysystem->createDir($this->buildPath($path));
- }
-
- /**
- * {@inheritdoc}
- */
- public function filemtime($path) {
- return $this->flysystem->getTimestamp($this->buildPath($path));
- }
-
- /**
- * {@inheritdoc}
- */
- public function rmdir($path) {
- try {
- return @$this->flysystem->deleteDir($this->buildPath($path));
- } catch (FileNotFoundException $e) {
- return false;
- }
- }
-
- /**
- * {@inheritdoc}
- */
- public function opendir($path) {
- try {
- $content = $this->flysystem->listContents($this->buildPath($path));
- } catch (FileNotFoundException $e) {
- return false;
- }
- $names = array_map(function ($object) {
- return $object['basename'];
- }, $content);
- return IteratorDirectory::wrap($names);
- }
-
- /**
- * {@inheritdoc}
- */
- public function fopen($path, $mode) {
- $fullPath = $this->buildPath($path);
- $useExisting = true;
- switch ($mode) {
- case 'r':
- case 'rb':
- try {
- return $this->flysystem->readStream($fullPath);
- } catch (FileNotFoundException $e) {
- return false;
- }
- case 'w':
- case 'w+':
- case 'wb':
- case 'wb+':
- $useExisting = false;
- case 'a':
- case 'ab':
- case 'r+':
- case 'a+':
- case 'x':
- case 'x+':
- case 'c':
- case 'c+':
- //emulate these
- if ($useExisting and $this->file_exists($path)) {
- if (!$this->isUpdatable($path)) {
- return false;
- }
- $tmpFile = $this->getCachedFile($path);
- } else {
- if (!$this->isCreatable(dirname($path))) {
- return false;
- }
- $tmpFile = \OCP\Files::tmpFile();
- }
- $source = fopen($tmpFile, $mode);
- return CallbackWrapper::wrap($source, null, null, function () use ($tmpFile, $fullPath) {
- $this->flysystem->putStream($fullPath, fopen($tmpFile, 'r'));
- unlink($tmpFile);
- });
- }
- return false;
- }
-
- /**
- * {@inheritdoc}
- */
- public function touch($path, $mtime = null) {
- if ($this->file_exists($path)) {
- return false;
- } else {
- $this->file_put_contents($path, '');
- return true;
- }
- }
-
- /**
- * {@inheritdoc}
- */
- public function stat($path) {
- $info = $this->flysystem->getWithMetadata($this->buildPath($path), ['timestamp', 'size']);
- return [
- 'mtime' => $info['timestamp'],
- 'size' => $info['size']
- ];
- }
-
- /**
- * {@inheritdoc}
- */
- public function filetype($path) {
- if ($path === '' or $path === '/' or $path === '.') {
- return 'dir';
- }
- try {
- $info = $this->flysystem->getMetadata($this->buildPath($path));
- } catch (FileNotFoundException $e) {
- return false;
- }
- return $info['type'];
- }
-}
diff --git a/lib/private/files/storage/home.php b/lib/private/files/storage/home.php
deleted file mode 100644
index 9b98f2f7e12..00000000000
--- a/lib/private/files/storage/home.php
+++ /dev/null
@@ -1,114 +0,0 @@
-<?php
-/**
- * @author Björn Schießle <schiessle@owncloud.com>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <icewind@owncloud.com>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- * @author Vincent Petry <pvince81@owncloud.com>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OC\Files\Storage;
-use OC\Files\Cache\HomePropagator;
-
-/**
- * Specialized version of Local storage for home directory usage
- */
-class Home extends Local implements \OCP\Files\IHomeStorage {
- /**
- * @var string
- */
- protected $id;
-
- /**
- * @var \OC\User\User $user
- */
- protected $user;
-
- /**
- * Construct a Home storage instance
- * @param array $arguments array with "user" containing the
- * storage owner and "legacy" containing "true" if the storage is
- * a legacy storage with "local::" URL instead of the new "home::" one.
- */
- public function __construct($arguments) {
- $this->user = $arguments['user'];
- $datadir = $this->user->getHome();
- if (isset($arguments['legacy']) && $arguments['legacy']) {
- // legacy home id (<= 5.0.12)
- $this->id = 'local::' . $datadir . '/';
- }
- else {
- $this->id = 'home::' . $this->user->getUID();
- }
-
- parent::__construct(array('datadir' => $datadir));
- }
-
- public function getId() {
- return $this->id;
- }
-
- /**
- * @return \OC\Files\Cache\HomeCache
- */
- public function getCache($path = '', $storage = null) {
- if (!$storage) {
- $storage = $this;
- }
- if (!isset($this->cache)) {
- $this->cache = new \OC\Files\Cache\HomeCache($storage);
- }
- return $this->cache;
- }
-
- /**
- * get a propagator instance for the cache
- *
- * @param \OC\Files\Storage\Storage (optional) the storage to pass to the watcher
- * @return \OC\Files\Cache\Propagator
- */
- public function getPropagator($storage = null) {
- if (!$storage) {
- $storage = $this;
- }
- if (!isset($this->propagator)) {
- $this->propagator = new HomePropagator($storage);
- }
- return $this->propagator;
- }
-
-
- /**
- * Returns the owner of this home storage
- * @return \OC\User\User owner of this home storage
- */
- public function getUser() {
- return $this->user;
- }
-
- /**
- * get the owner of a path
- *
- * @param string $path The path to get the owner
- * @return string uid or false
- */
- public function getOwner($path) {
- return $this->user->getUID();
- }
-}
diff --git a/lib/private/files/storage/local.php b/lib/private/files/storage/local.php
deleted file mode 100644
index 25b202af5f8..00000000000
--- a/lib/private/files/storage/local.php
+++ /dev/null
@@ -1,404 +0,0 @@
-<?php
-/**
- * @author Bart Visscher <bartv@thisnet.nl>
- * @author Brice Maron <brice@bmaron.net>
- * @author Jakob Sack <mail@jakobsack.de>
- * @author Joas Schilling <nickvergessen@owncloud.com>
- * @author Klaas Freitag <freitag@owncloud.com>
- * @author Martin Mattel <martin.mattel@diemattels.at>
- * @author Michael Gapczynski <GapczynskiM@gmail.com>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <icewind@owncloud.com>
- * @author Sjors van der Pluijm <sjors@desjors.nl>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- * @author Tigran Mkrtchyan <tigran.mkrtchyan@desy.de>
- * @author Vincent Petry <pvince81@owncloud.com>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OC\Files\Storage;
-/**
- * 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->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();
- }
- 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 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) {
- // file_get_contents() has a memory leak: https://bugs.php.net/bug.php?id=61961
- $fileName = $this->getSourcePath($path);
-
- $fileSize = filesize($fileName);
- if ($fileSize === 0) {
- return '';
- }
-
- $handle = fopen($fileName,'rb');
- $content = fread($handle, $fileSize);
- fclose($handle);
- return $content;
- }
-
- public function file_put_contents($path, $data) {
- return file_put_contents($this->getSourcePath($path), $data);
- }
-
- 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;
- }
-
- }
-
- public function rename($path1, $path2) {
- $srcParent = dirname($path1);
- $dstParent = dirname($path2);
-
- if (!$this->isUpdatable($srcParent)) {
- \OCP\Util::writeLog('core', 'unable to rename, source directory is not writable : ' . $srcParent, \OCP\Util::ERROR);
- return false;
- }
-
- if (!$this->isUpdatable($dstParent)) {
- \OCP\Util::writeLog('core', 'unable to rename, destination directory is not writable : ' . $dstParent, \OCP\Util::ERROR);
- return false;
- }
-
- if (!$this->file_exists($path1)) {
- \OCP\Util::writeLog('core', 'unable to rename, file does not exists : ' . $path1, \OCP\Util::ERROR);
- 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 can't 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 rename($this->getSourcePath($path1), $this->getSourcePath($path2));
- }
-
- 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 fopen($path, $mode) {
- return fopen($this->getSourcePath($path), $mode);
- }
-
- public function hash($type, $path, $raw = false) {
- return hash_file($type, $this->getSourcePath($path), $raw);
- }
-
- public function free_space($path) {
- $sourcePath = $this->getSourcePath($path);
- // using !is_dir because $sourcePath might be a part file or
- // non-existing file, so we'd still want to use the parent dir
- // in such cases
- if (!is_dir($sourcePath)) {
- // disk_free_space doesn't work on files
- $sourcePath = dirname($sourcePath);
- }
- $space = @disk_free_space($sourcePath);
- 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 (\OC\Files\Filesystem::isIgnoredDir($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;
- }
-
- /**
- * 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
- */
- 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 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/localtempfiletrait.php b/lib/private/files/storage/localtempfiletrait.php
deleted file mode 100644
index 88f11e4e752..00000000000
--- a/lib/private/files/storage/localtempfiletrait.php
+++ /dev/null
@@ -1,80 +0,0 @@
-<?php
-/**
- * @author Lukas Reschke <lukas@owncloud.com>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OC\Files\Storage;
-
-/**
- * Storage backend class for providing common filesystem operation methods
- * which are not storage-backend specific.
- *
- * \OC\Files\Storage\Common is never used directly; it is extended by all other
- * storage backends, where its methods may be overridden, and additional
- * (backend-specific) methods are defined.
- *
- * Some \OC\Files\Storage\Common methods call functions which are first defined
- * in classes which extend it, e.g. $this->stat() .
- */
-trait LocalTempFileTrait {
-
- /** @var string[] */
- protected $cachedFiles = [];
-
- /**
- * @param string $path
- * @return string
- */
- protected function getCachedFile($path) {
- if (!isset($this->cachedFiles[$path])) {
- $this->cachedFiles[$path] = $this->toTmpFile($path);
- }
- return $this->cachedFiles[$path];
- }
-
- /**
- * @param string $path
- */
- protected function removeCachedFile($path) {
- unset($this->cachedFiles[$path]);
- }
-
- /**
- * @param string $path
- * @return string
- */
- protected function toTmpFile($path) { //no longer in the storage api, still useful here
- $source = $this->fopen($path, 'r');
- if (!$source) {
- return false;
- }
- if ($pos = strrpos($path, '.')) {
- $extension = substr($path, $pos);
- } else {
- $extension = '';
- }
- $tmpFile = \OC::$server->getTempManager()->getTemporaryFile($extension);
- $target = fopen($tmpFile, 'w');
- \OC_Helper::streamCopy($source, $target);
- fclose($target);
- return $tmpFile;
- }
-}
diff --git a/lib/private/files/storage/polyfill/copydirectory.php b/lib/private/files/storage/polyfill/copydirectory.php
deleted file mode 100644
index d4cac117ade..00000000000
--- a/lib/private/files/storage/polyfill/copydirectory.php
+++ /dev/null
@@ -1,103 +0,0 @@
-<?php
-/**
- * @author Martin Mattel <martin.mattel@diemattels.at>
- * @author Robin Appelman <icewind@owncloud.com>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OC\Files\Storage\PolyFill;
-
-trait CopyDirectory {
- /**
- * Check if a path is a directory
- *
- * @param string $path
- * @return bool
- */
- abstract public function is_dir($path);
-
- /**
- * Check if a file or folder exists
- *
- * @param string $path
- * @return bool
- */
- abstract public function file_exists($path);
-
- /**
- * Delete a file or folder
- *
- * @param string $path
- * @return bool
- */
- abstract public function unlink($path);
-
- /**
- * Open a directory handle for a folder
- *
- * @param string $path
- * @return resource | bool
- */
- abstract public function opendir($path);
-
- /**
- * Create a new folder
- *
- * @param string $path
- * @return bool
- */
- abstract public function mkdir($path);
-
- public function copy($source, $target) {
- if ($this->is_dir($source)) {
- if ($this->file_exists($target)) {
- $this->unlink($target);
- }
- $this->mkdir($target);
- return $this->copyRecursive($source, $target);
- } else {
- return parent::copy($source, $target);
- }
- }
-
- /**
- * For adapters that don't support copying folders natively
- *
- * @param $source
- * @param $target
- * @return bool
- */
- protected function copyRecursive($source, $target) {
- $dh = $this->opendir($source);
- $result = true;
- while ($file = readdir($dh)) {
- if (!\OC\Files\Filesystem::isIgnoredDir($file)) {
- if ($this->is_dir($source . '/' . $file)) {
- $this->mkdir($target . '/' . $file);
- $result = $this->copyRecursive($source . '/' . $file, $target . '/' . $file);
- } else {
- $result = parent::copy($source . '/' . $file, $target . '/' . $file);
- }
- if (!$result) {
- break;
- }
- }
- }
- return $result;
- }
-}
diff --git a/lib/private/files/storage/storage.php b/lib/private/files/storage/storage.php
deleted file mode 100644
index c066336d4b8..00000000000
--- a/lib/private/files/storage/storage.php
+++ /dev/null
@@ -1,119 +0,0 @@
-<?php
-/**
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <icewind@owncloud.com>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OC\Files\Storage;
-use OCP\Lock\ILockingProvider;
-
-/**
- * Provide a common interface to all different storage options
- *
- * All paths passed to the storage are relative to the storage and should NOT have a leading slash.
- */
-interface Storage extends \OCP\Files\Storage {
-
- /**
- * get a cache instance for the storage
- *
- * @param string $path
- * @param \OC\Files\Storage\Storage (optional) the storage to pass to the cache
- * @return \OC\Files\Cache\Cache
- */
- public function getCache($path = '', $storage = null);
-
- /**
- * get a scanner instance for the storage
- *
- * @param string $path
- * @param \OC\Files\Storage\Storage (optional) the storage to pass to the scanner
- * @return \OC\Files\Cache\Scanner
- */
- public function getScanner($path = '', $storage = null);
-
-
- /**
- * get the user id of the owner of a file or folder
- *
- * @param string $path
- * @return string
- */
- public function getOwner($path);
-
- /**
- * get a watcher instance for the cache
- *
- * @param string $path
- * @param \OC\Files\Storage\Storage (optional) the storage to pass to the watcher
- * @return \OC\Files\Cache\Watcher
- */
- public function getWatcher($path = '', $storage = null);
-
- /**
- * get a propagator instance for the cache
- *
- * @param \OC\Files\Storage\Storage (optional) the storage to pass to the watcher
- * @return \OC\Files\Cache\Propagator
- */
- public function getPropagator($storage = null);
-
- /**
- * get a updater instance for the cache
- *
- * @param \OC\Files\Storage\Storage (optional) the storage to pass to the watcher
- * @return \OC\Files\Cache\Updater
- */
- public function getUpdater($storage = null);
-
- /**
- * @return \OC\Files\Cache\Storage
- */
- public function getStorageCache();
-
- /**
- * @param string $path
- * @return array
- */
- public function getMetaData($path);
-
- /**
- * @param string $path The path of the file to acquire the lock for
- * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
- * @param \OCP\Lock\ILockingProvider $provider
- * @throws \OCP\Lock\LockedException
- */
- public function acquireLock($path, $type, ILockingProvider $provider);
-
- /**
- * @param string $path The path of the file to release the lock for
- * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
- * @param \OCP\Lock\ILockingProvider $provider
- */
- public function releaseLock($path, $type, ILockingProvider $provider);
-
- /**
- * @param string $path The path of the file to change the lock for
- * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
- * @param \OCP\Lock\ILockingProvider $provider
- * @throws \OCP\Lock\LockedException
- */
- public function changeLock($path, $type, ILockingProvider $provider);
-}
diff --git a/lib/private/files/storage/storagefactory.php b/lib/private/files/storage/storagefactory.php
deleted file mode 100644
index 84362cabecc..00000000000
--- a/lib/private/files/storage/storagefactory.php
+++ /dev/null
@@ -1,107 +0,0 @@
-<?php
-/**
- * @author Jörn Friedrich Dreyer <jfd@butonic.de>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <icewind@owncloud.com>
- * @author Vincent Petry <pvince81@owncloud.com>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OC\Files\Storage;
-
-use OCP\Files\Mount\IMountPoint;
-use OCP\Files\Storage\IStorageFactory;
-
-class StorageFactory implements IStorageFactory {
- /**
- * @var array[] [$name=>['priority'=>$priority, 'wrapper'=>$callable] $storageWrappers
- */
- private $storageWrappers = [];
-
- /**
- * allow modifier storage behaviour by adding wrappers around storages
- *
- * $callback should be a function of type (string $mountPoint, Storage $storage) => Storage
- *
- * @param string $wrapperName name of the wrapper
- * @param callable $callback callback
- * @param int $priority wrappers with the lower priority are applied last (meaning they get called first)
- * @param \OCP\Files\Mount\IMountPoint[] $existingMounts existing mount points to apply the wrapper to
- * @return bool true if the wrapper was added, false if there was already a wrapper with this
- * name registered
- */
- public function addStorageWrapper($wrapperName, $callback, $priority = 50, $existingMounts = []) {
- if (isset($this->storageWrappers[$wrapperName])) {
- return false;
- }
-
- // apply to existing mounts before registering it to prevent applying it double in MountPoint::createStorage
- foreach ($existingMounts as $mount) {
- $mount->wrapStorage($callback);
- }
-
- $this->storageWrappers[$wrapperName] = ['wrapper' => $callback, 'priority' => $priority];
- return true;
- }
-
- /**
- * Remove a storage wrapper by name.
- * Note: internal method only to be used for cleanup
- *
- * @param string $wrapperName name of the wrapper
- * @internal
- */
- public function removeStorageWrapper($wrapperName) {
- unset($this->storageWrappers[$wrapperName]);
- }
-
- /**
- * Create an instance of a storage and apply the registered storage wrappers
- *
- * @param \OCP\Files\Mount\IMountPoint $mountPoint
- * @param string $class
- * @param array $arguments
- * @return \OCP\Files\Storage
- */
- public function getInstance(IMountPoint $mountPoint, $class, $arguments) {
- return $this->wrap($mountPoint, new $class($arguments));
- }
-
- /**
- * @param \OCP\Files\Mount\IMountPoint $mountPoint
- * @param \OCP\Files\Storage $storage
- * @return \OCP\Files\Storage
- */
- public function wrap(IMountPoint $mountPoint, $storage) {
- $wrappers = array_values($this->storageWrappers);
- usort($wrappers, function ($a, $b) {
- return $b['priority'] - $a['priority'];
- });
- /** @var callable[] $wrappers */
- $wrappers = array_map(function ($wrapper) {
- return $wrapper['wrapper'];
- }, $wrappers);
- foreach ($wrappers as $wrapper) {
- $storage = $wrapper($mountPoint->getMountPoint(), $storage, $mountPoint);
- if (!($storage instanceof \OCP\Files\Storage)) {
- throw new \Exception('Invalid result from storage wrapper');
- }
- }
- return $storage;
- }
-}
diff --git a/lib/private/files/storage/temporary.php b/lib/private/files/storage/temporary.php
deleted file mode 100644
index 2d8e84c2d52..00000000000
--- a/lib/private/files/storage/temporary.php
+++ /dev/null
@@ -1,47 +0,0 @@
-<?php
-/**
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <icewind@owncloud.com>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- * @author Vincent Petry <pvince81@owncloud.com>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OC\Files\Storage;
-
-/**
- * local storage backend in temporary folder for testing purpose
- */
-class Temporary extends Local{
- public function __construct($arguments = null) {
- parent::__construct(array('datadir' => \OC::$server->getTempManager()->getTemporaryFolder()));
- }
-
- public function cleanUp() {
- \OC_Helper::rmdirr($this->datadir);
- }
-
- public function __destruct() {
- parent::__destruct();
- $this->cleanUp();
- }
-
- public function getDataDir() {
- return $this->datadir;
- }
-}
diff --git a/lib/private/files/storage/wrapper/availability.php b/lib/private/files/storage/wrapper/availability.php
deleted file mode 100644
index 0ed31ba854a..00000000000
--- a/lib/private/files/storage/wrapper/availability.php
+++ /dev/null
@@ -1,461 +0,0 @@
-<?php
-/**
- * @author Robin Appelman <icewind@owncloud.com>
- * @author Robin McCorkell <robin@mccorkell.me.uk>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
- */
-namespace OC\Files\Storage\Wrapper;
-
-/**
- * Availability checker for storages
- *
- * Throws a StorageNotAvailableException for storages with known failures
- */
-class Availability extends Wrapper {
- const RECHECK_TTL_SEC = 600; // 10 minutes
-
- public static function shouldRecheck($availability) {
- if (!$availability['available']) {
- // trigger a recheck if TTL reached
- if ((time() - $availability['last_checked']) > self::RECHECK_TTL_SEC) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * @return bool
- */
- private function updateAvailability() {
- try {
- $result = $this->test();
- } catch (\Exception $e) {
- $result = false;
- }
- $this->setAvailability($result);
- return $result;
- }
-
- /**
- * @return bool
- */
- private function isAvailable() {
- $availability = $this->getAvailability();
- if (self::shouldRecheck($availability)) {
- return $this->updateAvailability();
- }
- return $availability['available'];
- }
-
- /**
- * @throws \OCP\Files\StorageNotAvailableException
- */
- private function checkAvailability() {
- if (!$this->isAvailable()) {
- throw new \OCP\Files\StorageNotAvailableException();
- }
- }
-
- /** {@inheritdoc} */
- public function mkdir($path) {
- $this->checkAvailability();
- try {
- return parent::mkdir($path);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- $this->setAvailability(false);
- throw $e;
- }
- }
-
- /** {@inheritdoc} */
- public function rmdir($path) {
- $this->checkAvailability();
- try {
- return parent::rmdir($path);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- $this->setAvailability(false);
- throw $e;
- }
- }
-
- /** {@inheritdoc} */
- public function opendir($path) {
- $this->checkAvailability();
- try {
- return parent::opendir($path);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- $this->setAvailability(false);
- throw $e;
- }
- }
-
- /** {@inheritdoc} */
- public function is_dir($path) {
- $this->checkAvailability();
- try {
- return parent::is_dir($path);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- $this->setAvailability(false);
- throw $e;
- }
- }
-
- /** {@inheritdoc} */
- public function is_file($path) {
- $this->checkAvailability();
- try {
- return parent::is_file($path);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- $this->setAvailability(false);
- throw $e;
- }
- }
-
- /** {@inheritdoc} */
- public function stat($path) {
- $this->checkAvailability();
- try {
- return parent::stat($path);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- $this->setAvailability(false);
- throw $e;
- }
- }
-
- /** {@inheritdoc} */
- public function filetype($path) {
- $this->checkAvailability();
- try {
- return parent::filetype($path);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- $this->setAvailability(false);
- throw $e;
- }
- }
-
- /** {@inheritdoc} */
- public function filesize($path) {
- $this->checkAvailability();
- try {
- return parent::filesize($path);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- $this->setAvailability(false);
- throw $e;
- }
- }
-
- /** {@inheritdoc} */
- public function isCreatable($path) {
- $this->checkAvailability();
- try {
- return parent::isCreatable($path);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- $this->setAvailability(false);
- throw $e;
- }
- }
-
- /** {@inheritdoc} */
- public function isReadable($path) {
- $this->checkAvailability();
- try {
- return parent::isReadable($path);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- $this->setAvailability(false);
- throw $e;
- }
- }
-
- /** {@inheritdoc} */
- public function isUpdatable($path) {
- $this->checkAvailability();
- try {
- return parent::isUpdatable($path);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- $this->setAvailability(false);
- throw $e;
- }
- }
-
- /** {@inheritdoc} */
- public function isDeletable($path) {
- $this->checkAvailability();
- try {
- return parent::isDeletable($path);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- $this->setAvailability(false);
- throw $e;
- }
- }
-
- /** {@inheritdoc} */
- public function isSharable($path) {
- $this->checkAvailability();
- try {
- return parent::isSharable($path);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- $this->setAvailability(false);
- throw $e;
- }
- }
-
- /** {@inheritdoc} */
- public function getPermissions($path) {
- $this->checkAvailability();
- try {
- return parent::getPermissions($path);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- $this->setAvailability(false);
- throw $e;
- }
- }
-
- /** {@inheritdoc} */
- public function file_exists($path) {
- if ($path === '') {
- return true;
- }
- $this->checkAvailability();
- try {
- return parent::file_exists($path);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- $this->setAvailability(false);
- throw $e;
- }
- }
-
- /** {@inheritdoc} */
- public function filemtime($path) {
- $this->checkAvailability();
- try {
- return parent::filemtime($path);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- $this->setAvailability(false);
- throw $e;
- }
- }
-
- /** {@inheritdoc} */
- public function file_get_contents($path) {
- $this->checkAvailability();
- try {
- return parent::file_get_contents($path);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- $this->setAvailability(false);
- throw $e;
- }
- }
-
- /** {@inheritdoc} */
- public function file_put_contents($path, $data) {
- $this->checkAvailability();
- try {
- return parent::file_put_contents($path, $data);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- $this->setAvailability(false);
- throw $e;
- }
- }
-
- /** {@inheritdoc} */
- public function unlink($path) {
- $this->checkAvailability();
- try {
- return parent::unlink($path);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- $this->setAvailability(false);
- throw $e;
- }
- }
-
- /** {@inheritdoc} */
- public function rename($path1, $path2) {
- $this->checkAvailability();
- try {
- return parent::rename($path1, $path2);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- $this->setAvailability(false);
- throw $e;
- }
- }
-
- /** {@inheritdoc} */
- public function copy($path1, $path2) {
- $this->checkAvailability();
- try {
- return parent::copy($path1, $path2);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- $this->setAvailability(false);
- throw $e;
- }
- }
-
- /** {@inheritdoc} */
- public function fopen($path, $mode) {
- $this->checkAvailability();
- try {
- return parent::fopen($path, $mode);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- $this->setAvailability(false);
- throw $e;
- }
- }
-
- /** {@inheritdoc} */
- public function getMimeType($path) {
- $this->checkAvailability();
- try {
- return parent::getMimeType($path);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- $this->setAvailability(false);
- throw $e;
- }
- }
-
- /** {@inheritdoc} */
- public function hash($type, $path, $raw = false) {
- $this->checkAvailability();
- try {
- return parent::hash($type, $path, $raw);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- $this->setAvailability(false);
- throw $e;
- }
- }
-
- /** {@inheritdoc} */
- public function free_space($path) {
- $this->checkAvailability();
- try {
- return parent::free_space($path);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- $this->setAvailability(false);
- throw $e;
- }
- }
-
- /** {@inheritdoc} */
- public function search($query) {
- $this->checkAvailability();
- try {
- return parent::search($query);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- $this->setAvailability(false);
- throw $e;
- }
- }
-
- /** {@inheritdoc} */
- public function touch($path, $mtime = null) {
- $this->checkAvailability();
- try {
- return parent::touch($path, $mtime);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- $this->setAvailability(false);
- throw $e;
- }
- }
-
- /** {@inheritdoc} */
- public function getLocalFile($path) {
- $this->checkAvailability();
- try {
- return parent::getLocalFile($path);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- $this->setAvailability(false);
- throw $e;
- }
- }
-
- /** {@inheritdoc} */
- public function hasUpdated($path, $time) {
- $this->checkAvailability();
- try {
- return parent::hasUpdated($path, $time);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- $this->setAvailability(false);
- throw $e;
- }
- }
-
- /** {@inheritdoc} */
- public function getOwner($path) {
- try {
- return parent::getOwner($path);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- $this->setAvailability(false);
- throw $e;
- }
- }
-
- /** {@inheritdoc} */
- public function getETag($path) {
- $this->checkAvailability();
- try {
- return parent::getETag($path);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- $this->setAvailability(false);
- throw $e;
- }
- }
-
- /** {@inheritdoc} */
- public function getDirectDownload($path) {
- $this->checkAvailability();
- try {
- return parent::getDirectDownload($path);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- $this->setAvailability(false);
- throw $e;
- }
- }
-
- /** {@inheritdoc} */
- public function copyFromStorage(\OCP\Files\Storage $sourceStorage, $sourceInternalPath, $targetInternalPath) {
- $this->checkAvailability();
- try {
- return parent::copyFromStorage($sourceStorage, $sourceInternalPath, $targetInternalPath);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- $this->setAvailability(false);
- throw $e;
- }
- }
-
- /** {@inheritdoc} */
- public function moveFromStorage(\OCP\Files\Storage $sourceStorage, $sourceInternalPath, $targetInternalPath) {
- $this->checkAvailability();
- try {
- return parent::moveFromStorage($sourceStorage, $sourceInternalPath, $targetInternalPath);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- $this->setAvailability(false);
- throw $e;
- }
- }
-
- /** {@inheritdoc} */
- public function getMetaData($path) {
- $this->checkAvailability();
- try {
- return parent::getMetaData($path);
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- $this->setAvailability(false);
- throw $e;
- }
- }
-}
diff --git a/lib/private/files/storage/wrapper/encryption.php b/lib/private/files/storage/wrapper/encryption.php
deleted file mode 100644
index 02da978a700..00000000000
--- a/lib/private/files/storage/wrapper/encryption.php
+++ /dev/null
@@ -1,993 +0,0 @@
-<?php
-/**
- * @author Björn Schießle <schiessle@owncloud.com>
- * @author Joas Schilling <nickvergessen@owncloud.com>
- * @author Lukas Reschke <lukas@owncloud.com>
- * @author Robin Appelman <icewind@owncloud.com>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- * @author Vincent Petry <pvince81@owncloud.com>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OC\Files\Storage\Wrapper;
-
-use OC\Encryption\Exceptions\ModuleDoesNotExistsException;
-use OC\Encryption\Update;
-use OC\Encryption\Util;
-use OC\Files\Cache\CacheEntry;
-use OC\Files\Filesystem;
-use OC\Files\Mount\Manager;
-use OC\Files\Storage\LocalTempFileTrait;
-use OC\Memcache\ArrayCache;
-use OCP\Encryption\Exceptions\GenericEncryptionException;
-use OCP\Encryption\IFile;
-use OCP\Encryption\IManager;
-use OCP\Encryption\Keys\IStorage;
-use OCP\Files\Mount\IMountPoint;
-use OCP\Files\Storage;
-use OCP\ILogger;
-use OCP\Files\Cache\ICacheEntry;
-
-class Encryption extends Wrapper {
-
- use LocalTempFileTrait;
-
- /** @var string */
- private $mountPoint;
-
- /** @var \OC\Encryption\Util */
- private $util;
-
- /** @var \OCP\Encryption\IManager */
- private $encryptionManager;
-
- /** @var \OCP\ILogger */
- private $logger;
-
- /** @var string */
- private $uid;
-
- /** @var array */
- protected $unencryptedSize;
-
- /** @var \OCP\Encryption\IFile */
- private $fileHelper;
-
- /** @var IMountPoint */
- private $mount;
-
- /** @var IStorage */
- private $keyStorage;
-
- /** @var Update */
- private $update;
-
- /** @var Manager */
- private $mountManager;
-
- /** @var array remember for which path we execute the repair step to avoid recursions */
- private $fixUnencryptedSizeOf = array();
-
- /** @var ArrayCache */
- private $arrayCache;
-
- /**
- * @param array $parameters
- * @param IManager $encryptionManager
- * @param Util $util
- * @param ILogger $logger
- * @param IFile $fileHelper
- * @param string $uid
- * @param IStorage $keyStorage
- * @param Update $update
- * @param Manager $mountManager
- * @param ArrayCache $arrayCache
- */
- public function __construct(
- $parameters,
- IManager $encryptionManager = null,
- Util $util = null,
- ILogger $logger = null,
- IFile $fileHelper = null,
- $uid = null,
- IStorage $keyStorage = null,
- Update $update = null,
- Manager $mountManager = null,
- ArrayCache $arrayCache = null
- ) {
-
- $this->mountPoint = $parameters['mountPoint'];
- $this->mount = $parameters['mount'];
- $this->encryptionManager = $encryptionManager;
- $this->util = $util;
- $this->logger = $logger;
- $this->uid = $uid;
- $this->fileHelper = $fileHelper;
- $this->keyStorage = $keyStorage;
- $this->unencryptedSize = array();
- $this->update = $update;
- $this->mountManager = $mountManager;
- $this->arrayCache = $arrayCache;
- parent::__construct($parameters);
- }
-
- /**
- * see http://php.net/manual/en/function.filesize.php
- * The result for filesize when called on a folder is required to be 0
- *
- * @param string $path
- * @return int
- */
- public function filesize($path) {
- $fullPath = $this->getFullPath($path);
-
- /** @var CacheEntry $info */
- $info = $this->getCache()->get($path);
- if (isset($this->unencryptedSize[$fullPath])) {
- $size = $this->unencryptedSize[$fullPath];
- // update file cache
- if ($info instanceof ICacheEntry) {
- $info = $info->getData();
- $info['encrypted'] = $info['encryptedVersion'];
- } else {
- if (!is_array($info)) {
- $info = [];
- }
- $info['encrypted'] = true;
- }
-
- $info['size'] = $size;
- $this->getCache()->put($path, $info);
-
- return $size;
- }
-
- if (isset($info['fileid']) && $info['encrypted']) {
- return $this->verifyUnencryptedSize($path, $info['size']);
- }
-
- return $this->storage->filesize($path);
- }
-
- /**
- * @param string $path
- * @return array
- */
- public function getMetaData($path) {
- $data = $this->storage->getMetaData($path);
- if (is_null($data)) {
- return null;
- }
- $fullPath = $this->getFullPath($path);
- $info = $this->getCache()->get($path);
-
- if (isset($this->unencryptedSize[$fullPath])) {
- $data['encrypted'] = true;
- $data['size'] = $this->unencryptedSize[$fullPath];
- } else {
- if (isset($info['fileid']) && $info['encrypted']) {
- $data['size'] = $this->verifyUnencryptedSize($path, $info['size']);
- $data['encrypted'] = true;
- }
- }
-
- if (isset($info['encryptedVersion']) && $info['encryptedVersion'] > 1) {
- $data['encryptedVersion'] = $info['encryptedVersion'];
- }
-
- return $data;
- }
-
- /**
- * see http://php.net/manual/en/function.file_get_contents.php
- *
- * @param string $path
- * @return string
- */
- public function file_get_contents($path) {
-
- $encryptionModule = $this->getEncryptionModule($path);
-
- if ($encryptionModule) {
- $handle = $this->fopen($path, "r");
- if (!$handle) {
- return false;
- }
- $data = stream_get_contents($handle);
- fclose($handle);
- return $data;
- }
- return $this->storage->file_get_contents($path);
- }
-
- /**
- * see http://php.net/manual/en/function.file_put_contents.php
- *
- * @param string $path
- * @param string $data
- * @return bool
- */
- public function file_put_contents($path, $data) {
- // file put content will always be translated to a stream write
- $handle = $this->fopen($path, 'w');
- if (is_resource($handle)) {
- $written = fwrite($handle, $data);
- fclose($handle);
- return $written;
- }
-
- return false;
- }
-
- /**
- * see http://php.net/manual/en/function.unlink.php
- *
- * @param string $path
- * @return bool
- */
- public function unlink($path) {
- $fullPath = $this->getFullPath($path);
- if ($this->util->isExcluded($fullPath)) {
- return $this->storage->unlink($path);
- }
-
- $encryptionModule = $this->getEncryptionModule($path);
- if ($encryptionModule) {
- $this->keyStorage->deleteAllFileKeys($this->getFullPath($path));
- }
-
- return $this->storage->unlink($path);
- }
-
- /**
- * see http://php.net/manual/en/function.rename.php
- *
- * @param string $path1
- * @param string $path2
- * @return bool
- */
- public function rename($path1, $path2) {
-
- $result = $this->storage->rename($path1, $path2);
-
- if ($result &&
- // versions always use the keys from the original file, so we can skip
- // this step for versions
- $this->isVersion($path2) === false &&
- $this->encryptionManager->isEnabled()) {
- $source = $this->getFullPath($path1);
- if (!$this->util->isExcluded($source)) {
- $target = $this->getFullPath($path2);
- if (isset($this->unencryptedSize[$source])) {
- $this->unencryptedSize[$target] = $this->unencryptedSize[$source];
- }
- $this->keyStorage->renameKeys($source, $target);
- $module = $this->getEncryptionModule($path2);
- if ($module) {
- $module->update($target, $this->uid, []);
- }
- }
- }
-
- return $result;
- }
-
- /**
- * see http://php.net/manual/en/function.rmdir.php
- *
- * @param string $path
- * @return bool
- */
- public function rmdir($path) {
- $result = $this->storage->rmdir($path);
- $fullPath = $this->getFullPath($path);
- if ($result &&
- $this->util->isExcluded($fullPath) === false &&
- $this->encryptionManager->isEnabled()
- ) {
- $this->keyStorage->deleteAllFileKeys($fullPath);
- }
-
- return $result;
- }
-
- /**
- * check if a file can be read
- *
- * @param string $path
- * @return bool
- */
- public function isReadable($path) {
-
- $isReadable = true;
-
- $metaData = $this->getMetaData($path);
- if (
- !$this->is_dir($path) &&
- isset($metaData['encrypted']) &&
- $metaData['encrypted'] === true
- ) {
- $fullPath = $this->getFullPath($path);
- $module = $this->getEncryptionModule($path);
- $isReadable = $module->isReadable($fullPath, $this->uid);
- }
-
- return $this->storage->isReadable($path) && $isReadable;
- }
-
- /**
- * see http://php.net/manual/en/function.copy.php
- *
- * @param string $path1
- * @param string $path2
- * @return bool
- */
- public function copy($path1, $path2) {
-
- $source = $this->getFullPath($path1);
-
- if ($this->util->isExcluded($source)) {
- return $this->storage->copy($path1, $path2);
- }
-
- // need to stream copy file by file in case we copy between a encrypted
- // and a unencrypted storage
- $this->unlink($path2);
- $result = $this->copyFromStorage($this, $path1, $path2);
-
- return $result;
- }
-
- /**
- * see http://php.net/manual/en/function.fopen.php
- *
- * @param string $path
- * @param string $mode
- * @return resource|bool
- * @throws GenericEncryptionException
- * @throws ModuleDoesNotExistsException
- */
- public function fopen($path, $mode) {
-
- // check if the file is stored in the array cache, this means that we
- // copy a file over to the versions folder, in this case we don't want to
- // decrypt it
- if ($this->arrayCache->hasKey('encryption_copy_version_' . $path)) {
- $this->arrayCache->remove('encryption_copy_version_' . $path);
- return $this->storage->fopen($path, $mode);
- }
-
- $encryptionEnabled = $this->encryptionManager->isEnabled();
- $shouldEncrypt = false;
- $encryptionModule = null;
- $header = $this->getHeader($path);
- $signed = (isset($header['signed']) && $header['signed'] === 'true') ? true : false;
- $fullPath = $this->getFullPath($path);
- $encryptionModuleId = $this->util->getEncryptionModuleId($header);
-
- if ($this->util->isExcluded($fullPath) === false) {
-
- $size = $unencryptedSize = 0;
- $realFile = $this->util->stripPartialFileExtension($path);
- $targetExists = $this->file_exists($realFile) || $this->file_exists($path);
- $targetIsEncrypted = false;
- if ($targetExists) {
- // in case the file exists we require the explicit module as
- // specified in the file header - otherwise we need to fail hard to
- // prevent data loss on client side
- if (!empty($encryptionModuleId)) {
- $targetIsEncrypted = true;
- $encryptionModule = $this->encryptionManager->getEncryptionModule($encryptionModuleId);
- }
-
- if ($this->file_exists($path)) {
- $size = $this->storage->filesize($path);
- $unencryptedSize = $this->filesize($path);
- } else {
- $size = $unencryptedSize = 0;
- }
- }
-
- try {
-
- if (
- $mode === 'w'
- || $mode === 'w+'
- || $mode === 'wb'
- || $mode === 'wb+'
- ) {
- // don't overwrite encrypted files if encryption is not enabled
- if ($targetIsEncrypted && $encryptionEnabled === false) {
- throw new GenericEncryptionException('Tried to access encrypted file but encryption is not enabled');
- }
- if ($encryptionEnabled) {
- // if $encryptionModuleId is empty, the default module will be used
- $encryptionModule = $this->encryptionManager->getEncryptionModule($encryptionModuleId);
- $shouldEncrypt = $encryptionModule->shouldEncrypt($fullPath);
- $signed = true;
- }
- } else {
- $info = $this->getCache()->get($path);
- // only get encryption module if we found one in the header
- // or if file should be encrypted according to the file cache
- if (!empty($encryptionModuleId)) {
- $encryptionModule = $this->encryptionManager->getEncryptionModule($encryptionModuleId);
- $shouldEncrypt = true;
- } else if (empty($encryptionModuleId) && $info['encrypted'] === true) {
- // we come from a old installation. No header and/or no module defined
- // but the file is encrypted. In this case we need to use the
- // OC_DEFAULT_MODULE to read the file
- $encryptionModule = $this->encryptionManager->getEncryptionModule('OC_DEFAULT_MODULE');
- $shouldEncrypt = true;
- $targetIsEncrypted = true;
- }
- }
- } catch (ModuleDoesNotExistsException $e) {
- $this->logger->warning('Encryption module "' . $encryptionModuleId .
- '" not found, file will be stored unencrypted (' . $e->getMessage() . ')');
- }
-
- // encryption disabled on write of new file and write to existing unencrypted file -> don't encrypt
- if (!$encryptionEnabled || !$this->mount->getOption('encrypt', true)) {
- if (!$targetExists || !$targetIsEncrypted) {
- $shouldEncrypt = false;
- }
- }
-
- if ($shouldEncrypt === true && $encryptionModule !== null) {
- $headerSize = $this->getHeaderSize($path);
- $source = $this->storage->fopen($path, $mode);
- if (!is_resource($source)) {
- return false;
- }
- $handle = \OC\Files\Stream\Encryption::wrap($source, $path, $fullPath, $header,
- $this->uid, $encryptionModule, $this->storage, $this, $this->util, $this->fileHelper, $mode,
- $size, $unencryptedSize, $headerSize, $signed);
- return $handle;
- }
-
- }
-
- return $this->storage->fopen($path, $mode);
- }
-
-
- /**
- * perform some plausibility checks if the the unencrypted size is correct.
- * If not, we calculate the correct unencrypted size and return it
- *
- * @param string $path internal path relative to the storage root
- * @param int $unencryptedSize size of the unencrypted file
- *
- * @return int unencrypted size
- */
- protected function verifyUnencryptedSize($path, $unencryptedSize) {
-
- $size = $this->storage->filesize($path);
- $result = $unencryptedSize;
-
- if ($unencryptedSize < 0 ||
- ($size > 0 && $unencryptedSize === $size)
- ) {
- // check if we already calculate the unencrypted size for the
- // given path to avoid recursions
- if (isset($this->fixUnencryptedSizeOf[$this->getFullPath($path)]) === false) {
- $this->fixUnencryptedSizeOf[$this->getFullPath($path)] = true;
- try {
- $result = $this->fixUnencryptedSize($path, $size, $unencryptedSize);
- } catch (\Exception $e) {
- $this->logger->error('Couldn\'t re-calculate unencrypted size for '. $path);
- $this->logger->logException($e);
- }
- unset($this->fixUnencryptedSizeOf[$this->getFullPath($path)]);
- }
- }
-
- return $result;
- }
-
- /**
- * calculate the unencrypted size
- *
- * @param string $path internal path relative to the storage root
- * @param int $size size of the physical file
- * @param int $unencryptedSize size of the unencrypted file
- *
- * @return int calculated unencrypted size
- */
- protected function fixUnencryptedSize($path, $size, $unencryptedSize) {
-
- $headerSize = $this->getHeaderSize($path);
- $header = $this->getHeader($path);
- $encryptionModule = $this->getEncryptionModule($path);
-
- $stream = $this->storage->fopen($path, 'r');
-
- // if we couldn't open the file we return the old unencrypted size
- if (!is_resource($stream)) {
- $this->logger->error('Could not open ' . $path . '. Recalculation of unencrypted size aborted.');
- return $unencryptedSize;
- }
-
- $newUnencryptedSize = 0;
- $size -= $headerSize;
- $blockSize = $this->util->getBlockSize();
-
- // if a header exists we skip it
- if ($headerSize > 0) {
- fread($stream, $headerSize);
- }
-
- // fast path, else the calculation for $lastChunkNr is bogus
- if ($size === 0) {
- return 0;
- }
-
- $signed = (isset($header['signed']) && $header['signed'] === 'true') ? true : false;
- $unencryptedBlockSize = $encryptionModule->getUnencryptedBlockSize($signed);
-
- // calculate last chunk nr
- // next highest is end of chunks, one subtracted is last one
- // we have to read the last chunk, we can't just calculate it (because of padding etc)
-
- $lastChunkNr = ceil($size/ $blockSize)-1;
- // calculate last chunk position
- $lastChunkPos = ($lastChunkNr * $blockSize);
- // try to fseek to the last chunk, if it fails we have to read the whole file
- if (@fseek($stream, $lastChunkPos, SEEK_CUR) === 0) {
- $newUnencryptedSize += $lastChunkNr * $unencryptedBlockSize;
- }
-
- $lastChunkContentEncrypted='';
- $count = $blockSize;
-
- while ($count > 0) {
- $data=fread($stream, $blockSize);
- $count=strlen($data);
- $lastChunkContentEncrypted .= $data;
- if(strlen($lastChunkContentEncrypted) > $blockSize) {
- $newUnencryptedSize += $unencryptedBlockSize;
- $lastChunkContentEncrypted=substr($lastChunkContentEncrypted, $blockSize);
- }
- }
-
- fclose($stream);
-
- // we have to decrypt the last chunk to get it actual size
- $encryptionModule->begin($this->getFullPath($path), $this->uid, 'r', $header, []);
- $decryptedLastChunk = $encryptionModule->decrypt($lastChunkContentEncrypted, $lastChunkNr . 'end');
- $decryptedLastChunk .= $encryptionModule->end($this->getFullPath($path), $lastChunkNr . 'end');
-
- // calc the real file size with the size of the last chunk
- $newUnencryptedSize += strlen($decryptedLastChunk);
-
- $this->updateUnencryptedSize($this->getFullPath($path), $newUnencryptedSize);
-
- // write to cache if applicable
- $cache = $this->storage->getCache();
- if ($cache) {
- $entry = $cache->get($path);
- $cache->update($entry['fileid'], ['size' => $newUnencryptedSize]);
- }
-
- return $newUnencryptedSize;
- }
-
- /**
- * @param Storage $sourceStorage
- * @param string $sourceInternalPath
- * @param string $targetInternalPath
- * @param bool $preserveMtime
- * @return bool
- */
- public function moveFromStorage(Storage $sourceStorage, $sourceInternalPath, $targetInternalPath, $preserveMtime = true) {
- if ($sourceStorage === $this) {
- return $this->rename($sourceInternalPath, $targetInternalPath);
- }
-
- // TODO clean this up once the underlying moveFromStorage in OC\Files\Storage\Wrapper\Common is fixed:
- // - call $this->storage->moveFromStorage() instead of $this->copyBetweenStorage
- // - copy the file cache update from $this->copyBetweenStorage to this method
- // - copy the copyKeys() call from $this->copyBetweenStorage to this method
- // - remove $this->copyBetweenStorage
-
- if (!$sourceStorage->isDeletable($sourceInternalPath)) {
- return false;
- }
-
- $result = $this->copyBetweenStorage($sourceStorage, $sourceInternalPath, $targetInternalPath, $preserveMtime, true);
- if ($result) {
- if ($sourceStorage->is_dir($sourceInternalPath)) {
- $result &= $sourceStorage->rmdir($sourceInternalPath);
- } else {
- $result &= $sourceStorage->unlink($sourceInternalPath);
- }
- }
- return $result;
- }
-
-
- /**
- * @param Storage $sourceStorage
- * @param string $sourceInternalPath
- * @param string $targetInternalPath
- * @param bool $preserveMtime
- * @param bool $isRename
- * @return bool
- */
- public function copyFromStorage(Storage $sourceStorage, $sourceInternalPath, $targetInternalPath, $preserveMtime = false, $isRename = false) {
-
- // TODO clean this up once the underlying moveFromStorage in OC\Files\Storage\Wrapper\Common is fixed:
- // - call $this->storage->copyFromStorage() instead of $this->copyBetweenStorage
- // - copy the file cache update from $this->copyBetweenStorage to this method
- // - copy the copyKeys() call from $this->copyBetweenStorage to this method
- // - remove $this->copyBetweenStorage
-
- return $this->copyBetweenStorage($sourceStorage, $sourceInternalPath, $targetInternalPath, $preserveMtime, $isRename);
- }
-
- /**
- * Update the encrypted cache version in the database
- *
- * @param Storage $sourceStorage
- * @param string $sourceInternalPath
- * @param string $targetInternalPath
- * @param bool $isRename
- */
- private function updateEncryptedVersion(Storage $sourceStorage, $sourceInternalPath, $targetInternalPath, $isRename) {
- $isEncrypted = $this->encryptionManager->isEnabled() && $this->mount->getOption('encrypt', true) ? 1 : 0;
- $cacheInformation = [
- 'encrypted' => (bool)$isEncrypted,
- ];
- if($isEncrypted === 1) {
- $encryptedVersion = $sourceStorage->getCache()->get($sourceInternalPath)['encryptedVersion'];
-
- // In case of a move operation from an unencrypted to an encrypted
- // storage the old encrypted version would stay with "0" while the
- // correct value would be "1". Thus we manually set the value to "1"
- // for those cases.
- // See also https://github.com/owncloud/core/issues/23078
- if($encryptedVersion === 0) {
- $encryptedVersion = 1;
- }
-
- $cacheInformation['encryptedVersion'] = $encryptedVersion;
- }
-
- // in case of a rename we need to manipulate the source cache because
- // this information will be kept for the new target
- if ($isRename) {
- $sourceStorage->getCache()->put($sourceInternalPath, $cacheInformation);
- } else {
- $this->getCache()->put($targetInternalPath, $cacheInformation);
- }
- }
-
- /**
- * copy file between two storages
- *
- * @param Storage $sourceStorage
- * @param string $sourceInternalPath
- * @param string $targetInternalPath
- * @param bool $preserveMtime
- * @param bool $isRename
- * @return bool
- * @throws \Exception
- */
- private function copyBetweenStorage(Storage $sourceStorage, $sourceInternalPath, $targetInternalPath, $preserveMtime, $isRename) {
-
- // for versions we have nothing to do, because versions should always use the
- // key from the original file. Just create a 1:1 copy and done
- if ($this->isVersion($targetInternalPath) ||
- $this->isVersion($sourceInternalPath)) {
- // remember that we try to create a version so that we can detect it during
- // fopen($sourceInternalPath) and by-pass the encryption in order to
- // create a 1:1 copy of the file
- $this->arrayCache->set('encryption_copy_version_' . $sourceInternalPath, true);
- $result = $this->storage->copyFromStorage($sourceStorage, $sourceInternalPath, $targetInternalPath);
- $this->arrayCache->remove('encryption_copy_version_' . $sourceInternalPath);
- if ($result) {
- $info = $this->getCache('', $sourceStorage)->get($sourceInternalPath);
- // make sure that we update the unencrypted size for the version
- if (isset($info['encrypted']) && $info['encrypted'] === true) {
- $this->updateUnencryptedSize(
- $this->getFullPath($targetInternalPath),
- $info['size']
- );
- }
- $this->updateEncryptedVersion($sourceStorage, $sourceInternalPath, $targetInternalPath, $isRename);
- }
- return $result;
- }
-
- // first copy the keys that we reuse the existing file key on the target location
- // and don't create a new one which would break versions for example.
- $mount = $this->mountManager->findByStorageId($sourceStorage->getId());
- if (count($mount) === 1) {
- $mountPoint = $mount[0]->getMountPoint();
- $source = $mountPoint . '/' . $sourceInternalPath;
- $target = $this->getFullPath($targetInternalPath);
- $this->copyKeys($source, $target);
- } else {
- $this->logger->error('Could not find mount point, can\'t keep encryption keys');
- }
-
- if ($sourceStorage->is_dir($sourceInternalPath)) {
- $dh = $sourceStorage->opendir($sourceInternalPath);
- $result = $this->mkdir($targetInternalPath);
- if (is_resource($dh)) {
- while ($result and ($file = readdir($dh)) !== false) {
- if (!Filesystem::isIgnoredDir($file)) {
- $result &= $this->copyFromStorage($sourceStorage, $sourceInternalPath . '/' . $file, $targetInternalPath . '/' . $file, false, $isRename);
- }
- }
- }
- } else {
- try {
- $source = $sourceStorage->fopen($sourceInternalPath, 'r');
- $target = $this->fopen($targetInternalPath, 'w');
- list(, $result) = \OC_Helper::streamCopy($source, $target);
- fclose($source);
- fclose($target);
- } catch (\Exception $e) {
- fclose($source);
- fclose($target);
- throw $e;
- }
- if($result) {
- if ($preserveMtime) {
- $this->touch($targetInternalPath, $sourceStorage->filemtime($sourceInternalPath));
- }
- $this->updateEncryptedVersion($sourceStorage, $sourceInternalPath, $targetInternalPath, $isRename);
- } else {
- // delete partially written target file
- $this->unlink($targetInternalPath);
- // delete cache entry that was created by fopen
- $this->getCache()->remove($targetInternalPath);
- }
- }
- return (bool)$result;
-
- }
-
- /**
- * get the path to a local version of the file.
- * The local version of the file can be temporary and doesn't have to be persistent across requests
- *
- * @param string $path
- * @return string
- */
- public function getLocalFile($path) {
- if ($this->encryptionManager->isEnabled()) {
- $cachedFile = $this->getCachedFile($path);
- if (is_string($cachedFile)) {
- return $cachedFile;
- }
- }
- return $this->storage->getLocalFile($path);
- }
-
- /**
- * Returns the wrapped storage's value for isLocal()
- *
- * @return bool wrapped storage's isLocal() value
- */
- public function isLocal() {
- if ($this->encryptionManager->isEnabled()) {
- return false;
- }
- return $this->storage->isLocal();
- }
-
- /**
- * see http://php.net/manual/en/function.stat.php
- * only the following keys are required in the result: size and mtime
- *
- * @param string $path
- * @return array
- */
- public function stat($path) {
- $stat = $this->storage->stat($path);
- $fileSize = $this->filesize($path);
- $stat['size'] = $fileSize;
- $stat[7] = $fileSize;
- return $stat;
- }
-
- /**
- * see http://php.net/manual/en/function.hash.php
- *
- * @param string $type
- * @param string $path
- * @param bool $raw
- * @return string
- */
- public function hash($type, $path, $raw = false) {
- $fh = $this->fopen($path, 'rb');
- $ctx = hash_init($type);
- hash_update_stream($ctx, $fh);
- fclose($fh);
- return hash_final($ctx, $raw);
- }
-
- /**
- * return full path, including mount point
- *
- * @param string $path relative to mount point
- * @return string full path including mount point
- */
- protected function getFullPath($path) {
- return Filesystem::normalizePath($this->mountPoint . '/' . $path);
- }
-
- /**
- * read first block of encrypted file, typically this will contain the
- * encryption header
- *
- * @param string $path
- * @return string
- */
- protected function readFirstBlock($path) {
- $firstBlock = '';
- if ($this->storage->file_exists($path)) {
- $handle = $this->storage->fopen($path, 'r');
- $firstBlock = fread($handle, $this->util->getHeaderSize());
- fclose($handle);
- }
- return $firstBlock;
- }
-
- /**
- * return header size of given file
- *
- * @param string $path
- * @return int
- */
- protected function getHeaderSize($path) {
- $headerSize = 0;
- $realFile = $this->util->stripPartialFileExtension($path);
- if ($this->storage->file_exists($realFile)) {
- $path = $realFile;
- }
- $firstBlock = $this->readFirstBlock($path);
-
- if (substr($firstBlock, 0, strlen(Util::HEADER_START)) === Util::HEADER_START) {
- $headerSize = $this->util->getHeaderSize();
- }
-
- return $headerSize;
- }
-
- /**
- * parse raw header to array
- *
- * @param string $rawHeader
- * @return array
- */
- protected function parseRawHeader($rawHeader) {
- $result = array();
- if (substr($rawHeader, 0, strlen(Util::HEADER_START)) === Util::HEADER_START) {
- $header = $rawHeader;
- $endAt = strpos($header, Util::HEADER_END);
- if ($endAt !== false) {
- $header = substr($header, 0, $endAt + strlen(Util::HEADER_END));
-
- // +1 to not start with an ':' which would result in empty element at the beginning
- $exploded = explode(':', substr($header, strlen(Util::HEADER_START)+1));
-
- $element = array_shift($exploded);
- while ($element !== Util::HEADER_END) {
- $result[$element] = array_shift($exploded);
- $element = array_shift($exploded);
- }
- }
- }
-
- return $result;
- }
-
- /**
- * read header from file
- *
- * @param string $path
- * @return array
- */
- protected function getHeader($path) {
- $realFile = $this->util->stripPartialFileExtension($path);
- if ($this->storage->file_exists($realFile)) {
- $path = $realFile;
- }
-
- $firstBlock = $this->readFirstBlock($path);
- $result = $this->parseRawHeader($firstBlock);
-
- // if the header doesn't contain a encryption module we check if it is a
- // legacy file. If true, we add the default encryption module
- if (!isset($result[Util::HEADER_ENCRYPTION_MODULE_KEY])) {
- if (!empty($result)) {
- $result[Util::HEADER_ENCRYPTION_MODULE_KEY] = 'OC_DEFAULT_MODULE';
- } else {
- // if the header was empty we have to check first if it is a encrypted file at all
- $info = $this->getCache()->get($path);
- if (isset($info['encrypted']) && $info['encrypted'] === true) {
- $result[Util::HEADER_ENCRYPTION_MODULE_KEY] = 'OC_DEFAULT_MODULE';
- }
- }
- }
-
- return $result;
- }
-
- /**
- * read encryption module needed to read/write the file located at $path
- *
- * @param string $path
- * @return null|\OCP\Encryption\IEncryptionModule
- * @throws ModuleDoesNotExistsException
- * @throws \Exception
- */
- protected function getEncryptionModule($path) {
- $encryptionModule = null;
- $header = $this->getHeader($path);
- $encryptionModuleId = $this->util->getEncryptionModuleId($header);
- if (!empty($encryptionModuleId)) {
- try {
- $encryptionModule = $this->encryptionManager->getEncryptionModule($encryptionModuleId);
- } catch (ModuleDoesNotExistsException $e) {
- $this->logger->critical('Encryption module defined in "' . $path . '" not loaded!');
- throw $e;
- }
- }
- return $encryptionModule;
- }
-
- /**
- * @param string $path
- * @param int $unencryptedSize
- */
- public function updateUnencryptedSize($path, $unencryptedSize) {
- $this->unencryptedSize[$path] = $unencryptedSize;
- }
-
- /**
- * copy keys to new location
- *
- * @param string $source path relative to data/
- * @param string $target path relative to data/
- * @return bool
- */
- protected function copyKeys($source, $target) {
- if (!$this->util->isExcluded($source)) {
- return $this->keyStorage->copyKeys($source, $target);
- }
-
- return false;
- }
-
- /**
- * check if path points to a files version
- *
- * @param $path
- * @return bool
- */
- protected function isVersion($path) {
- $normalized = Filesystem::normalizePath($path);
- return substr($normalized, 0, strlen('/files_versions/')) === '/files_versions/';
- }
-
-}
diff --git a/lib/private/files/storage/wrapper/jail.php b/lib/private/files/storage/wrapper/jail.php
deleted file mode 100644
index e8063f670c5..00000000000
--- a/lib/private/files/storage/wrapper/jail.php
+++ /dev/null
@@ -1,489 +0,0 @@
-<?php
-/**
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <icewind@owncloud.com>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OC\Files\Storage\Wrapper;
-
-use OC\Files\Cache\Wrapper\CacheJail;
-use OCP\Lock\ILockingProvider;
-
-/**
- * Jail to a subdirectory of the wrapped storage
- *
- * This restricts access to a subfolder of the wrapped storage with the subfolder becoming the root folder new storage
- */
-class Jail extends Wrapper {
- /**
- * @var string
- */
- protected $rootPath;
-
- /**
- * @param array $arguments ['storage' => $storage, 'mask' => $root]
- *
- * $storage: The storage that will be wrapper
- * $root: The folder in the wrapped storage that will become the root folder of the wrapped storage
- */
- public function __construct($arguments) {
- parent::__construct($arguments);
- $this->rootPath = $arguments['root'];
- }
-
- public function getSourcePath($path) {
- if ($path === '') {
- return $this->rootPath;
- } else {
- return $this->rootPath . '/' . $path;
- }
- }
-
- public function getId() {
- return 'link:' . parent::getId() . ':' . $this->rootPath;
- }
-
- /**
- * see http://php.net/manual/en/function.mkdir.php
- *
- * @param string $path
- * @return bool
- */
- public function mkdir($path) {
- return $this->storage->mkdir($this->getSourcePath($path));
- }
-
- /**
- * see http://php.net/manual/en/function.rmdir.php
- *
- * @param string $path
- * @return bool
- */
- public function rmdir($path) {
- return $this->storage->rmdir($this->getSourcePath($path));
- }
-
- /**
- * see http://php.net/manual/en/function.opendir.php
- *
- * @param string $path
- * @return resource
- */
- public function opendir($path) {
- return $this->storage->opendir($this->getSourcePath($path));
- }
-
- /**
- * see http://php.net/manual/en/function.is_dir.php
- *
- * @param string $path
- * @return bool
- */
- public function is_dir($path) {
- return $this->storage->is_dir($this->getSourcePath($path));
- }
-
- /**
- * see http://php.net/manual/en/function.is_file.php
- *
- * @param string $path
- * @return bool
- */
- public function is_file($path) {
- return $this->storage->is_file($this->getSourcePath($path));
- }
-
- /**
- * see http://php.net/manual/en/function.stat.php
- * only the following keys are required in the result: size and mtime
- *
- * @param string $path
- * @return array
- */
- public function stat($path) {
- return $this->storage->stat($this->getSourcePath($path));
- }
-
- /**
- * see http://php.net/manual/en/function.filetype.php
- *
- * @param string $path
- * @return bool
- */
- public function filetype($path) {
- return $this->storage->filetype($this->getSourcePath($path));
- }
-
- /**
- * see http://php.net/manual/en/function.filesize.php
- * The result for filesize when called on a folder is required to be 0
- *
- * @param string $path
- * @return int
- */
- public function filesize($path) {
- return $this->storage->filesize($this->getSourcePath($path));
- }
-
- /**
- * check if a file can be created in $path
- *
- * @param string $path
- * @return bool
- */
- public function isCreatable($path) {
- return $this->storage->isCreatable($this->getSourcePath($path));
- }
-
- /**
- * check if a file can be read
- *
- * @param string $path
- * @return bool
- */
- public function isReadable($path) {
- return $this->storage->isReadable($this->getSourcePath($path));
- }
-
- /**
- * check if a file can be written to
- *
- * @param string $path
- * @return bool
- */
- public function isUpdatable($path) {
- return $this->storage->isUpdatable($this->getSourcePath($path));
- }
-
- /**
- * check if a file can be deleted
- *
- * @param string $path
- * @return bool
- */
- public function isDeletable($path) {
- return $this->storage->isDeletable($this->getSourcePath($path));
- }
-
- /**
- * check if a file can be shared
- *
- * @param string $path
- * @return bool
- */
- public function isSharable($path) {
- return $this->storage->isSharable($this->getSourcePath($path));
- }
-
- /**
- * get the full permissions of a path.
- * Should return a combination of the PERMISSION_ constants defined in lib/public/constants.php
- *
- * @param string $path
- * @return int
- */
- public function getPermissions($path) {
- return $this->storage->getPermissions($this->getSourcePath($path));
- }
-
- /**
- * see http://php.net/manual/en/function.file_exists.php
- *
- * @param string $path
- * @return bool
- */
- public function file_exists($path) {
- return $this->storage->file_exists($this->getSourcePath($path));
- }
-
- /**
- * see http://php.net/manual/en/function.filemtime.php
- *
- * @param string $path
- * @return int
- */
- public function filemtime($path) {
- return $this->storage->filemtime($this->getSourcePath($path));
- }
-
- /**
- * see http://php.net/manual/en/function.file_get_contents.php
- *
- * @param string $path
- * @return string
- */
- public function file_get_contents($path) {
- return $this->storage->file_get_contents($this->getSourcePath($path));
- }
-
- /**
- * see http://php.net/manual/en/function.file_put_contents.php
- *
- * @param string $path
- * @param string $data
- * @return bool
- */
- public function file_put_contents($path, $data) {
- return $this->storage->file_put_contents($this->getSourcePath($path), $data);
- }
-
- /**
- * see http://php.net/manual/en/function.unlink.php
- *
- * @param string $path
- * @return bool
- */
- public function unlink($path) {
- return $this->storage->unlink($this->getSourcePath($path));
- }
-
- /**
- * see http://php.net/manual/en/function.rename.php
- *
- * @param string $path1
- * @param string $path2
- * @return bool
- */
- public function rename($path1, $path2) {
- return $this->storage->rename($this->getSourcePath($path1), $this->getSourcePath($path2));
- }
-
- /**
- * see http://php.net/manual/en/function.copy.php
- *
- * @param string $path1
- * @param string $path2
- * @return bool
- */
- public function copy($path1, $path2) {
- return $this->storage->copy($this->getSourcePath($path1), $this->getSourcePath($path2));
- }
-
- /**
- * see http://php.net/manual/en/function.fopen.php
- *
- * @param string $path
- * @param string $mode
- * @return resource
- */
- public function fopen($path, $mode) {
- return $this->storage->fopen($this->getSourcePath($path), $mode);
- }
-
- /**
- * get the mimetype for a file or folder
- * The mimetype for a folder is required to be "httpd/unix-directory"
- *
- * @param string $path
- * @return string
- */
- public function getMimeType($path) {
- return $this->storage->getMimeType($this->getSourcePath($path));
- }
-
- /**
- * see http://php.net/manual/en/function.hash.php
- *
- * @param string $type
- * @param string $path
- * @param bool $raw
- * @return string
- */
- public function hash($type, $path, $raw = false) {
- return $this->storage->hash($type, $this->getSourcePath($path), $raw);
- }
-
- /**
- * see http://php.net/manual/en/function.free_space.php
- *
- * @param string $path
- * @return int
- */
- public function free_space($path) {
- return $this->storage->free_space($this->getSourcePath($path));
- }
-
- /**
- * search for occurrences of $query in file names
- *
- * @param string $query
- * @return array
- */
- public function search($query) {
- return $this->storage->search($query);
- }
-
- /**
- * see http://php.net/manual/en/function.touch.php
- * If the backend does not support the operation, false should be returned
- *
- * @param string $path
- * @param int $mtime
- * @return bool
- */
- public function touch($path, $mtime = null) {
- return $this->storage->touch($this->getSourcePath($path), $mtime);
- }
-
- /**
- * get the path to a local version of the file.
- * The local version of the file can be temporary and doesn't have to be persistent across requests
- *
- * @param string $path
- * @return string
- */
- public function getLocalFile($path) {
- return $this->storage->getLocalFile($this->getSourcePath($path));
- }
-
- /**
- * check if a file or folder has been updated since $time
- *
- * @param string $path
- * @param int $time
- * @return bool
- *
- * hasUpdated for folders should return at least true if a file inside the folder is add, removed or renamed.
- * returning true for other changes in the folder is optional
- */
- public function hasUpdated($path, $time) {
- return $this->storage->hasUpdated($this->getSourcePath($path), $time);
- }
-
- /**
- * get a cache instance for the storage
- *
- * @param string $path
- * @param \OC\Files\Storage\Storage (optional) the storage to pass to the cache
- * @return \OC\Files\Cache\Cache
- */
- public function getCache($path = '', $storage = null) {
- if (!$storage) {
- $storage = $this;
- }
- $sourceCache = $this->storage->getCache($this->getSourcePath($path), $storage);
- return new CacheJail($sourceCache, $this->rootPath);
- }
-
- /**
- * get the user id of the owner of a file or folder
- *
- * @param string $path
- * @return string
- */
- public function getOwner($path) {
- return $this->storage->getOwner($this->getSourcePath($path));
- }
-
- /**
- * get a watcher instance for the cache
- *
- * @param string $path
- * @param \OC\Files\Storage\Storage (optional) the storage to pass to the watcher
- * @return \OC\Files\Cache\Watcher
- */
- public function getWatcher($path = '', $storage = null) {
- if (!$storage) {
- $storage = $this;
- }
- return $this->storage->getWatcher($this->getSourcePath($path), $storage);
- }
-
- /**
- * get the ETag for a file or folder
- *
- * @param string $path
- * @return string
- */
- public function getETag($path) {
- return $this->storage->getETag($this->getSourcePath($path));
- }
-
- /**
- * @param string $path
- * @return array
- */
- public function getMetaData($path) {
- return $this->storage->getMetaData($this->getSourcePath($path));
- }
-
- /**
- * @param string $path
- * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
- * @param \OCP\Lock\ILockingProvider $provider
- * @throws \OCP\Lock\LockedException
- */
- public function acquireLock($path, $type, ILockingProvider $provider) {
- $this->storage->acquireLock($this->getSourcePath($path), $type, $provider);
- }
-
- /**
- * @param string $path
- * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
- * @param \OCP\Lock\ILockingProvider $provider
- */
- public function releaseLock($path, $type, ILockingProvider $provider) {
- $this->storage->releaseLock($this->getSourcePath($path), $type, $provider);
- }
-
- /**
- * @param string $path
- * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
- * @param \OCP\Lock\ILockingProvider $provider
- */
- public function changeLock($path, $type, ILockingProvider $provider) {
- $this->storage->changeLock($this->getSourcePath($path), $type, $provider);
- }
-
- /**
- * Resolve the path for the source of the share
- *
- * @param string $path
- * @return array
- */
- public function resolvePath($path) {
- return [$this->storage, $this->getSourcePath($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 === $this) {
- return $this->copy($sourceInternalPath, $targetInternalPath);
- }
- return $this->storage->copyFromStorage($sourceStorage, $sourceInternalPath, $this->getSourcePath($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 === $this) {
- return $this->rename($sourceInternalPath, $targetInternalPath);
- }
- return $this->storage->moveFromStorage($sourceStorage, $sourceInternalPath, $this->getSourcePath($targetInternalPath));
- }
-}
diff --git a/lib/private/files/storage/wrapper/permissionsmask.php b/lib/private/files/storage/wrapper/permissionsmask.php
deleted file mode 100644
index 01dd78d418c..00000000000
--- a/lib/private/files/storage/wrapper/permissionsmask.php
+++ /dev/null
@@ -1,131 +0,0 @@
-<?php
-/**
- * @author Jörn Friedrich Dreyer <jfd@butonic.de>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <icewind@owncloud.com>
- * @author Robin McCorkell <robin@mccorkell.me.uk>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OC\Files\Storage\Wrapper;
-
-use OC\Files\Cache\Wrapper\CachePermissionsMask;
-use OCP\Constants;
-
-/**
- * Mask the permissions of a storage
- *
- * This can be used to restrict update, create, delete and/or share permissions of a storage
- *
- * Note that the read permissions can't be masked
- */
-class PermissionsMask extends Wrapper {
- /**
- * @var int the permissions bits we want to keep
- */
- private $mask;
-
- /**
- * @param array $arguments ['storage' => $storage, 'mask' => $mask]
- *
- * $storage: The storage the permissions mask should be applied on
- * $mask: The permission bits that should be kept, a combination of the \OCP\Constant::PERMISSION_ constants
- */
- public function __construct($arguments) {
- parent::__construct($arguments);
- $this->mask = $arguments['mask'];
- }
-
- private function checkMask($permissions) {
- return ($this->mask & $permissions) === $permissions;
- }
-
- public function isUpdatable($path) {
- return $this->checkMask(Constants::PERMISSION_UPDATE) and parent::isUpdatable($path);
- }
-
- public function isCreatable($path) {
- return $this->checkMask(Constants::PERMISSION_CREATE) and parent::isCreatable($path);
- }
-
- public function isDeletable($path) {
- return $this->checkMask(Constants::PERMISSION_DELETE) and parent::isDeletable($path);
- }
-
- public function isSharable($path) {
- return $this->checkMask(Constants::PERMISSION_SHARE) and parent::isSharable($path);
- }
-
- public function getPermissions($path) {
- return $this->storage->getPermissions($path) & $this->mask;
- }
-
- public function rename($path1, $path2) {
- return $this->checkMask(Constants::PERMISSION_UPDATE) and parent::rename($path1, $path2);
- }
-
- public function copy($path1, $path2) {
- return $this->checkMask(Constants::PERMISSION_CREATE) and parent::copy($path1, $path2);
- }
-
- public function touch($path, $mtime = null) {
- $permissions = $this->file_exists($path) ? Constants::PERMISSION_UPDATE : Constants::PERMISSION_CREATE;
- return $this->checkMask($permissions) and parent::touch($path, $mtime);
- }
-
- public function mkdir($path) {
- return $this->checkMask(Constants::PERMISSION_CREATE) and parent::mkdir($path);
- }
-
- public function rmdir($path) {
- return $this->checkMask(Constants::PERMISSION_DELETE) and parent::rmdir($path);
- }
-
- public function unlink($path) {
- return $this->checkMask(Constants::PERMISSION_DELETE) and parent::unlink($path);
- }
-
- public function file_put_contents($path, $data) {
- $permissions = $this->file_exists($path) ? Constants::PERMISSION_UPDATE : Constants::PERMISSION_CREATE;
- return $this->checkMask($permissions) and parent::file_put_contents($path, $data);
- }
-
- public function fopen($path, $mode) {
- if ($mode === 'r' or $mode === 'rb') {
- return parent::fopen($path, $mode);
- } else {
- $permissions = $this->file_exists($path) ? Constants::PERMISSION_UPDATE : Constants::PERMISSION_CREATE;
- return $this->checkMask($permissions) ? parent::fopen($path, $mode) : false;
- }
- }
-
- /**
- * get a cache instance for the storage
- *
- * @param string $path
- * @param \OC\Files\Storage\Storage (optional) the storage to pass to the cache
- * @return \OC\Files\Cache\Cache
- */
- public function getCache($path = '', $storage = null) {
- if (!$storage) {
- $storage = $this;
- }
- $sourceCache = parent::getCache($path, $storage);
- return new CachePermissionsMask($sourceCache, $this->mask);
- }
-}
diff --git a/lib/private/files/storage/wrapper/quota.php b/lib/private/files/storage/wrapper/quota.php
deleted file mode 100644
index 500677b092e..00000000000
--- a/lib/private/files/storage/wrapper/quota.php
+++ /dev/null
@@ -1,200 +0,0 @@
-<?php
-/**
- * @author Jörn Friedrich Dreyer <jfd@butonic.de>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <icewind@owncloud.com>
- * @author Robin McCorkell <robin@mccorkell.me.uk>
- * @author Vincent Petry <pvince81@owncloud.com>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OC\Files\Storage\Wrapper;
-
-use OCP\Files\Cache\ICacheEntry;
-
-class Quota extends Wrapper {
-
- /**
- * @var int $quota
- */
- protected $quota;
-
- /**
- * @var string $sizeRoot
- */
- protected $sizeRoot;
-
- /**
- * @param array $parameters
- */
- public function __construct($parameters) {
- $this->storage = $parameters['storage'];
- $this->quota = $parameters['quota'];
- $this->sizeRoot = isset($parameters['root']) ? $parameters['root'] : '';
- }
-
- /**
- * @return int quota value
- */
- public function getQuota() {
- return $this->quota;
- }
-
- /**
- * @param string $path
- * @param \OC\Files\Storage\Storage $storage
- */
- protected function getSize($path, $storage = null) {
- if (is_null($storage)) {
- $cache = $this->getCache();
- } else {
- $cache = $storage->getCache();
- }
- $data = $cache->get($path);
- if ($data instanceof ICacheEntry and isset($data['size'])) {
- return $data['size'];
- } else {
- return \OCP\Files\FileInfo::SPACE_NOT_COMPUTED;
- }
- }
-
- /**
- * Get free space as limited by the quota
- *
- * @param string $path
- * @return int
- */
- public function free_space($path) {
- if ($this->quota < 0) {
- return $this->storage->free_space($path);
- } else {
- $used = $this->getSize($this->sizeRoot);
- if ($used < 0) {
- return \OCP\Files\FileInfo::SPACE_NOT_COMPUTED;
- } else {
- $free = $this->storage->free_space($path);
- $quotaFree = max($this->quota - $used, 0);
- // if free space is known
- if ($free >= 0) {
- $free = min($free, $quotaFree);
- } else {
- $free = $quotaFree;
- }
- return $free;
- }
- }
- }
-
- /**
- * see http://php.net/manual/en/function.file_put_contents.php
- *
- * @param string $path
- * @param string $data
- * @return bool
- */
- public function file_put_contents($path, $data) {
- $free = $this->free_space('');
- if ($free < 0 or strlen($data) < $free) {
- return $this->storage->file_put_contents($path, $data);
- } else {
- return false;
- }
- }
-
- /**
- * see http://php.net/manual/en/function.copy.php
- *
- * @param string $source
- * @param string $target
- * @return bool
- */
- public function copy($source, $target) {
- $free = $this->free_space('');
- if ($free < 0 or $this->getSize($source) < $free) {
- return $this->storage->copy($source, $target);
- } else {
- return false;
- }
- }
-
- /**
- * see http://php.net/manual/en/function.fopen.php
- *
- * @param string $path
- * @param string $mode
- * @return resource
- */
- public function fopen($path, $mode) {
- $source = $this->storage->fopen($path, $mode);
-
- // don't apply quota for part files
- if (!$this->isPartFile($path)) {
- $free = $this->free_space('');
- if ($source && $free >= 0 && $mode !== 'r' && $mode !== 'rb') {
- // only apply quota for files, not metadata, trash or others
- if (strpos(ltrim($path, '/'), 'files/') === 0) {
- return \OC\Files\Stream\Quota::wrap($source, $free);
- }
- }
- }
- return $source;
- }
-
- /**
- * Checks whether the given path is a part file
- *
- * @param string $path Path that may identify a .part file
- * @return string File path without .part extension
- * @note this is needed for reusing keys
- */
- private function isPartFile($path) {
- $extension = pathinfo($path, PATHINFO_EXTENSION);
-
- return ($extension === 'part');
- }
-
- /**
- * @param \OCP\Files\Storage $sourceStorage
- * @param string $sourceInternalPath
- * @param string $targetInternalPath
- * @return bool
- */
- public function copyFromStorage(\OCP\Files\Storage $sourceStorage, $sourceInternalPath, $targetInternalPath) {
- $free = $this->free_space('');
- if ($free < 0 or $this->getSize($sourceInternalPath, $sourceStorage) < $free) {
- return $this->storage->copyFromStorage($sourceStorage, $sourceInternalPath, $targetInternalPath);
- } else {
- return false;
- }
- }
-
- /**
- * @param \OCP\Files\Storage $sourceStorage
- * @param string $sourceInternalPath
- * @param string $targetInternalPath
- * @return bool
- */
- public function moveFromStorage(\OCP\Files\Storage $sourceStorage, $sourceInternalPath, $targetInternalPath) {
- $free = $this->free_space('');
- if ($free < 0 or $this->getSize($sourceInternalPath, $sourceStorage) < $free) {
- return $this->storage->moveFromStorage($sourceStorage, $sourceInternalPath, $targetInternalPath);
- } else {
- return false;
- }
- }
-}
diff --git a/lib/private/files/storage/wrapper/wrapper.php b/lib/private/files/storage/wrapper/wrapper.php
deleted file mode 100644
index 21d7db1099b..00000000000
--- a/lib/private/files/storage/wrapper/wrapper.php
+++ /dev/null
@@ -1,608 +0,0 @@
-<?php
-/**
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <icewind@owncloud.com>
- * @author Robin McCorkell <robin@mccorkell.me.uk>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- * @author Vincent Petry <pvince81@owncloud.com>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OC\Files\Storage\Wrapper;
-
-use OCP\Files\InvalidPathException;
-use OCP\Files\Storage\ILockingStorage;
-use OCP\Lock\ILockingProvider;
-
-class Wrapper implements \OC\Files\Storage\Storage, ILockingStorage {
- /**
- * @var \OC\Files\Storage\Storage $storage
- */
- protected $storage;
-
- public $cache;
- public $scanner;
- public $watcher;
- public $propagator;
- public $updater;
-
- /**
- * @param array $parameters
- */
- public function __construct($parameters) {
- $this->storage = $parameters['storage'];
- }
-
- /**
- * @return \OC\Files\Storage\Storage
- */
- public function getWrapperStorage() {
- return $this->storage;
- }
-
- /**
- * Get the identifier for the storage,
- * the returned id should be the same for every storage object that is created with the same parameters
- * and two storage objects with the same id should refer to two storages that display the same files.
- *
- * @return string
- */
- public function getId() {
- return $this->storage->getId();
- }
-
- /**
- * see http://php.net/manual/en/function.mkdir.php
- *
- * @param string $path
- * @return bool
- */
- public function mkdir($path) {
- return $this->storage->mkdir($path);
- }
-
- /**
- * see http://php.net/manual/en/function.rmdir.php
- *
- * @param string $path
- * @return bool
- */
- public function rmdir($path) {
- return $this->storage->rmdir($path);
- }
-
- /**
- * see http://php.net/manual/en/function.opendir.php
- *
- * @param string $path
- * @return resource
- */
- public function opendir($path) {
- return $this->storage->opendir($path);
- }
-
- /**
- * see http://php.net/manual/en/function.is_dir.php
- *
- * @param string $path
- * @return bool
- */
- public function is_dir($path) {
- return $this->storage->is_dir($path);
- }
-
- /**
- * see http://php.net/manual/en/function.is_file.php
- *
- * @param string $path
- * @return bool
- */
- public function is_file($path) {
- return $this->storage->is_file($path);
- }
-
- /**
- * see http://php.net/manual/en/function.stat.php
- * only the following keys are required in the result: size and mtime
- *
- * @param string $path
- * @return array
- */
- public function stat($path) {
- return $this->storage->stat($path);
- }
-
- /**
- * see http://php.net/manual/en/function.filetype.php
- *
- * @param string $path
- * @return bool
- */
- public function filetype($path) {
- return $this->storage->filetype($path);
- }
-
- /**
- * see http://php.net/manual/en/function.filesize.php
- * The result for filesize when called on a folder is required to be 0
- *
- * @param string $path
- * @return int
- */
- public function filesize($path) {
- return $this->storage->filesize($path);
- }
-
- /**
- * check if a file can be created in $path
- *
- * @param string $path
- * @return bool
- */
- public function isCreatable($path) {
- return $this->storage->isCreatable($path);
- }
-
- /**
- * check if a file can be read
- *
- * @param string $path
- * @return bool
- */
- public function isReadable($path) {
- return $this->storage->isReadable($path);
- }
-
- /**
- * check if a file can be written to
- *
- * @param string $path
- * @return bool
- */
- public function isUpdatable($path) {
- return $this->storage->isUpdatable($path);
- }
-
- /**
- * check if a file can be deleted
- *
- * @param string $path
- * @return bool
- */
- public function isDeletable($path) {
- return $this->storage->isDeletable($path);
- }
-
- /**
- * check if a file can be shared
- *
- * @param string $path
- * @return bool
- */
- public function isSharable($path) {
- return $this->storage->isSharable($path);
- }
-
- /**
- * get the full permissions of a path.
- * Should return a combination of the PERMISSION_ constants defined in lib/public/constants.php
- *
- * @param string $path
- * @return int
- */
- public function getPermissions($path) {
- return $this->storage->getPermissions($path);
- }
-
- /**
- * see http://php.net/manual/en/function.file_exists.php
- *
- * @param string $path
- * @return bool
- */
- public function file_exists($path) {
- return $this->storage->file_exists($path);
- }
-
- /**
- * see http://php.net/manual/en/function.filemtime.php
- *
- * @param string $path
- * @return int
- */
- public function filemtime($path) {
- return $this->storage->filemtime($path);
- }
-
- /**
- * see http://php.net/manual/en/function.file_get_contents.php
- *
- * @param string $path
- * @return string
- */
- public function file_get_contents($path) {
- return $this->storage->file_get_contents($path);
- }
-
- /**
- * see http://php.net/manual/en/function.file_put_contents.php
- *
- * @param string $path
- * @param string $data
- * @return bool
- */
- public function file_put_contents($path, $data) {
- return $this->storage->file_put_contents($path, $data);
- }
-
- /**
- * see http://php.net/manual/en/function.unlink.php
- *
- * @param string $path
- * @return bool
- */
- public function unlink($path) {
- return $this->storage->unlink($path);
- }
-
- /**
- * see http://php.net/manual/en/function.rename.php
- *
- * @param string $path1
- * @param string $path2
- * @return bool
- */
- public function rename($path1, $path2) {
- return $this->storage->rename($path1, $path2);
- }
-
- /**
- * see http://php.net/manual/en/function.copy.php
- *
- * @param string $path1
- * @param string $path2
- * @return bool
- */
- public function copy($path1, $path2) {
- return $this->storage->copy($path1, $path2);
- }
-
- /**
- * see http://php.net/manual/en/function.fopen.php
- *
- * @param string $path
- * @param string $mode
- * @return resource
- */
- public function fopen($path, $mode) {
- return $this->storage->fopen($path, $mode);
- }
-
- /**
- * get the mimetype for a file or folder
- * The mimetype for a folder is required to be "httpd/unix-directory"
- *
- * @param string $path
- * @return string
- */
- public function getMimeType($path) {
- return $this->storage->getMimeType($path);
- }
-
- /**
- * see http://php.net/manual/en/function.hash.php
- *
- * @param string $type
- * @param string $path
- * @param bool $raw
- * @return string
- */
- public function hash($type, $path, $raw = false) {
- return $this->storage->hash($type, $path, $raw);
- }
-
- /**
- * see http://php.net/manual/en/function.free_space.php
- *
- * @param string $path
- * @return int
- */
- public function free_space($path) {
- return $this->storage->free_space($path);
- }
-
- /**
- * search for occurrences of $query in file names
- *
- * @param string $query
- * @return array
- */
- public function search($query) {
- return $this->storage->search($query);
- }
-
- /**
- * see http://php.net/manual/en/function.touch.php
- * If the backend does not support the operation, false should be returned
- *
- * @param string $path
- * @param int $mtime
- * @return bool
- */
- public function touch($path, $mtime = null) {
- return $this->storage->touch($path, $mtime);
- }
-
- /**
- * get the path to a local version of the file.
- * The local version of the file can be temporary and doesn't have to be persistent across requests
- *
- * @param string $path
- * @return string
- */
- public function getLocalFile($path) {
- return $this->storage->getLocalFile($path);
- }
-
- /**
- * check if a file or folder has been updated since $time
- *
- * @param string $path
- * @param int $time
- * @return bool
- *
- * hasUpdated for folders should return at least true if a file inside the folder is add, removed or renamed.
- * returning true for other changes in the folder is optional
- */
- public function hasUpdated($path, $time) {
- return $this->storage->hasUpdated($path, $time);
- }
-
- /**
- * get a cache instance for the storage
- *
- * @param string $path
- * @param \OC\Files\Storage\Storage (optional) the storage to pass to the cache
- * @return \OC\Files\Cache\Cache
- */
- public function getCache($path = '', $storage = null) {
- if (!$storage) {
- $storage = $this;
- }
- return $this->storage->getCache($path, $storage);
- }
-
- /**
- * get a scanner instance for the storage
- *
- * @param string $path
- * @param \OC\Files\Storage\Storage (optional) the storage to pass to the scanner
- * @return \OC\Files\Cache\Scanner
- */
- public function getScanner($path = '', $storage = null) {
- if (!$storage) {
- $storage = $this;
- }
- return $this->storage->getScanner($path, $storage);
- }
-
-
- /**
- * get the user id of the owner of a file or folder
- *
- * @param string $path
- * @return string
- */
- public function getOwner($path) {
- return $this->storage->getOwner($path);
- }
-
- /**
- * get a watcher instance for the cache
- *
- * @param string $path
- * @param \OC\Files\Storage\Storage (optional) the storage to pass to the watcher
- * @return \OC\Files\Cache\Watcher
- */
- public function getWatcher($path = '', $storage = null) {
- if (!$storage) {
- $storage = $this;
- }
- return $this->storage->getWatcher($path, $storage);
- }
-
- public function getPropagator($storage = null) {
- if (!$storage) {
- $storage = $this;
- }
- return $this->storage->getPropagator($storage);
- }
-
- public function getUpdater($storage = null) {
- if (!$storage) {
- $storage = $this;
- }
- return $this->storage->getUpdater($storage);
- }
-
- /**
- * @return \OC\Files\Cache\Storage
- */
- public function getStorageCache() {
- return $this->storage->getStorageCache();
- }
-
- /**
- * get the ETag for a file or folder
- *
- * @param string $path
- * @return string
- */
- public function getETag($path) {
- return $this->storage->getETag($path);
- }
-
- /**
- * Returns true
- *
- * @return true
- */
- public function test() {
- return $this->storage->test();
- }
-
- /**
- * Returns the wrapped storage's value for isLocal()
- *
- * @return bool wrapped storage's isLocal() value
- */
- public function isLocal() {
- return $this->storage->isLocal();
- }
-
- /**
- * Check if the storage is an instance of $class or is a wrapper for a storage that is an instance of $class
- *
- * @param string $class
- * @return bool
- */
- public function instanceOfStorage($class) {
- return is_a($this, $class) or $this->storage->instanceOfStorage($class);
- }
-
- /**
- * Pass any methods custom to specific storage implementations to the wrapped storage
- *
- * @param string $method
- * @param array $args
- * @return mixed
- */
- public function __call($method, $args) {
- return call_user_func_array(array($this->storage, $method), $args);
- }
-
- /**
- * A custom storage implementation can return an url for direct download of a give file.
- *
- * For now the returned array can hold the parameter url - in future more attributes might follow.
- *
- * @param string $path
- * @return array
- */
- public function getDirectDownload($path) {
- return $this->storage->getDirectDownload($path);
- }
-
- /**
- * Get availability of the storage
- *
- * @return array [ available, last_checked ]
- */
- public function getAvailability() {
- return $this->storage->getAvailability();
- }
-
- /**
- * Set availability of the storage
- *
- * @param bool $isAvailable
- */
- public function setAvailability($isAvailable) {
- $this->storage->setAvailability($isAvailable);
- }
-
- /**
- * @param string $path the path of the target folder
- * @param string $fileName the name of the file itself
- * @return void
- * @throws InvalidPathException
- */
- public function verifyPath($path, $fileName) {
- $this->storage->verifyPath($path, $fileName);
- }
-
- /**
- * @param \OCP\Files\Storage $sourceStorage
- * @param string $sourceInternalPath
- * @param string $targetInternalPath
- * @return bool
- */
- public function copyFromStorage(\OCP\Files\Storage $sourceStorage, $sourceInternalPath, $targetInternalPath) {
- if ($sourceStorage === $this) {
- return $this->copy($sourceInternalPath, $targetInternalPath);
- }
-
- return $this->storage->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 === $this) {
- return $this->rename($sourceInternalPath, $targetInternalPath);
- }
-
- return $this->storage->moveFromStorage($sourceStorage, $sourceInternalPath, $targetInternalPath);
- }
-
- /**
- * @param string $path
- * @return array
- */
- public function getMetaData($path) {
- return $this->storage->getMetaData($path);
- }
-
- /**
- * @param string $path
- * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
- * @param \OCP\Lock\ILockingProvider $provider
- * @throws \OCP\Lock\LockedException
- */
- public function acquireLock($path, $type, ILockingProvider $provider) {
- if ($this->storage->instanceOfStorage('\OCP\Files\Storage\ILockingStorage')) {
- $this->storage->acquireLock($path, $type, $provider);
- }
- }
-
- /**
- * @param string $path
- * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
- * @param \OCP\Lock\ILockingProvider $provider
- */
- public function releaseLock($path, $type, ILockingProvider $provider) {
- if ($this->storage->instanceOfStorage('\OCP\Files\Storage\ILockingStorage')) {
- $this->storage->releaseLock($path, $type, $provider);
- }
- }
-
- /**
- * @param string $path
- * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
- * @param \OCP\Lock\ILockingProvider $provider
- */
- public function changeLock($path, $type, ILockingProvider $provider) {
- if ($this->storage->instanceOfStorage('\OCP\Files\Storage\ILockingStorage')) {
- $this->storage->changeLock($path, $type, $provider);
- }
- }
-}
diff --git a/lib/private/files/stream/close.php b/lib/private/files/stream/close.php
deleted file mode 100644
index 1c9b30705dd..00000000000
--- a/lib/private/files/stream/close.php
+++ /dev/null
@@ -1,118 +0,0 @@
-<?php
-/**
- * @author Jörn Friedrich Dreyer <jfd@butonic.de>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <icewind@owncloud.com>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OC\Files\Stream;
-
-/**
- * stream wrapper that provides a callback on stream close
- */
-class Close {
- private static $callBacks = array();
- private $path = '';
- private $source;
- private static $open = array();
-
- public function stream_open($path, $mode, $options, &$opened_path) {
- $path = substr($path, strlen('close://'));
- $this->path = $path;
- $this->source = fopen($path, $mode);
- if (is_resource($this->source)) {
- $this->meta = stream_get_meta_data($this->source);
- }
- self::$open[] = $path;
- return is_resource($this->source);
- }
-
- public function stream_seek($offset, $whence = SEEK_SET) {
- return fseek($this->source, $offset, $whence) === 0;
- }
-
- public function stream_tell() {
- return ftell($this->source);
- }
-
- public function stream_read($count) {
- return fread($this->source, $count);
- }
-
- public function stream_write($data) {
- return fwrite($this->source, $data);
- }
-
- public function stream_set_option($option, $arg1, $arg2) {
- switch ($option) {
- case STREAM_OPTION_BLOCKING:
- stream_set_blocking($this->source, $arg1);
- break;
- case STREAM_OPTION_READ_TIMEOUT:
- stream_set_timeout($this->source, $arg1, $arg2);
- break;
- case STREAM_OPTION_WRITE_BUFFER:
- stream_set_write_buffer($this->source, $arg1, $arg2);
- }
- }
-
- public function stream_stat() {
- return fstat($this->source);
- }
-
- public function stream_lock($mode) {
- flock($this->source, $mode);
- }
-
- public function stream_flush() {
- return fflush($this->source);
- }
-
- public function stream_eof() {
- return feof($this->source);
- }
-
- public function url_stat($path) {
- $path = substr($path, strlen('close://'));
- if (file_exists($path)) {
- return stat($path);
- } else {
- return false;
- }
- }
-
- public function stream_close() {
- fclose($this->source);
- if (isset(self::$callBacks[$this->path])) {
- call_user_func(self::$callBacks[$this->path], $this->path);
- }
- }
-
- public function unlink($path) {
- $path = substr($path, strlen('close://'));
- return unlink($path);
- }
-
- /**
- * @param string $path
- */
- public static function registerCallback($path, $callback) {
- self::$callBacks[$path] = $callback;
- }
-}
diff --git a/lib/private/files/stream/dir.php b/lib/private/files/stream/dir.php
deleted file mode 100644
index 7489ee683a2..00000000000
--- a/lib/private/files/stream/dir.php
+++ /dev/null
@@ -1,66 +0,0 @@
-<?php
-/**
- * @author Jörn Friedrich Dreyer <jfd@butonic.de>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <icewind@owncloud.com>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OC\Files\Stream;
-
-class Dir {
- private static $dirs = array();
- private $name;
- private $index;
-
- public function dir_opendir($path, $options) {
- $this->name = substr($path, strlen('fakedir://'));
- $this->index = 0;
- if (!isset(self::$dirs[$this->name])) {
- self::$dirs[$this->name] = array();
- }
- return true;
- }
-
- public function dir_readdir() {
- if ($this->index >= count(self::$dirs[$this->name])) {
- return false;
- }
- $filename = self::$dirs[$this->name][$this->index];
- $this->index++;
- return $filename;
- }
-
- public function dir_closedir() {
- $this->name = '';
- return true;
- }
-
- public function dir_rewinddir() {
- $this->index = 0;
- return true;
- }
-
- /**
- * @param string $path
- * @param string[] $content
- */
- public static function register($path, $content) {
- self::$dirs[$path] = $content;
- }
-}
diff --git a/lib/private/files/stream/encryption.php b/lib/private/files/stream/encryption.php
deleted file mode 100644
index 772c9769bf7..00000000000
--- a/lib/private/files/stream/encryption.php
+++ /dev/null
@@ -1,500 +0,0 @@
-<?php
-/**
- * @author Björn Schießle <schiessle@owncloud.com>
- * @author jknockaert <jasper@knockaert.nl>
- * @author Lukas Reschke <lukas@owncloud.com>
- * @author Roeland Jago Douma <rullzer@owncloud.com>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- * @author Vincent Petry <pvince81@owncloud.com>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OC\Files\Stream;
-
-use Icewind\Streams\Wrapper;
-use OC\Encryption\Exceptions\EncryptionHeaderKeyExistsException;
-
-class Encryption extends Wrapper {
-
- /** @var \OC\Encryption\Util */
- protected $util;
-
- /** @var \OC\Encryption\File */
- protected $file;
-
- /** @var \OCP\Encryption\IEncryptionModule */
- protected $encryptionModule;
-
- /** @var \OC\Files\Storage\Storage */
- protected $storage;
-
- /** @var \OC\Files\Storage\Wrapper\Encryption */
- protected $encryptionStorage;
-
- /** @var string */
- protected $internalPath;
-
- /** @var string */
- protected $cache;
-
- /** @var integer */
- protected $size;
-
- /** @var integer */
- protected $position;
-
- /** @var integer */
- protected $unencryptedSize;
-
- /** @var integer */
- protected $headerSize;
-
- /** @var integer */
- protected $unencryptedBlockSize;
-
- /** @var array */
- protected $header;
-
- /** @var string */
- protected $fullPath;
-
- /** @var bool */
- protected $signed;
-
- /**
- * header data returned by the encryption module, will be written to the file
- * in case of a write operation
- *
- * @var array
- */
- protected $newHeader;
-
- /**
- * user who perform the read/write operation null for public access
- *
- * @var string
- */
- protected $uid;
-
- /** @var bool */
- protected $readOnly;
-
- /** @var bool */
- protected $writeFlag;
-
- /** @var array */
- protected $expectedContextProperties;
-
- public function __construct() {
- $this->expectedContextProperties = array(
- 'source',
- 'storage',
- 'internalPath',
- 'fullPath',
- 'encryptionModule',
- 'header',
- 'uid',
- 'file',
- 'util',
- 'size',
- 'unencryptedSize',
- 'encryptionStorage',
- 'headerSize',
- 'signed'
- );
- }
-
-
- /**
- * Wraps a stream with the provided callbacks
- *
- * @param resource $source
- * @param string $internalPath relative to mount point
- * @param string $fullPath relative to data/
- * @param array $header
- * @param string $uid
- * @param \OCP\Encryption\IEncryptionModule $encryptionModule
- * @param \OC\Files\Storage\Storage $storage
- * @param \OC\Files\Storage\Wrapper\Encryption $encStorage
- * @param \OC\Encryption\Util $util
- * @param \OC\Encryption\File $file
- * @param string $mode
- * @param int $size
- * @param int $unencryptedSize
- * @param int $headerSize
- * @param bool $signed
- * @param string $wrapper stream wrapper class
- * @return resource
- *
- * @throws \BadMethodCallException
- */
- public static function wrap($source, $internalPath, $fullPath, array $header,
- $uid,
- \OCP\Encryption\IEncryptionModule $encryptionModule,
- \OC\Files\Storage\Storage $storage,
- \OC\Files\Storage\Wrapper\Encryption $encStorage,
- \OC\Encryption\Util $util,
- \OC\Encryption\File $file,
- $mode,
- $size,
- $unencryptedSize,
- $headerSize,
- $signed,
- $wrapper = 'OC\Files\Stream\Encryption') {
-
- $context = stream_context_create(array(
- 'ocencryption' => array(
- 'source' => $source,
- 'storage' => $storage,
- 'internalPath' => $internalPath,
- 'fullPath' => $fullPath,
- 'encryptionModule' => $encryptionModule,
- 'header' => $header,
- 'uid' => $uid,
- 'util' => $util,
- 'file' => $file,
- 'size' => $size,
- 'unencryptedSize' => $unencryptedSize,
- 'encryptionStorage' => $encStorage,
- 'headerSize' => $headerSize,
- 'signed' => $signed
- )
- ));
-
- return self::wrapSource($source, $context, 'ocencryption', $wrapper, $mode);
- }
-
- /**
- * add stream wrapper
- *
- * @param resource $source
- * @param string $mode
- * @param resource $context
- * @param string $protocol
- * @param string $class
- * @return resource
- * @throws \BadMethodCallException
- */
- protected static function wrapSource($source, $context, $protocol, $class, $mode = 'r+') {
- try {
- stream_wrapper_register($protocol, $class);
- if (@rewinddir($source) === false) {
- $wrapped = fopen($protocol . '://', $mode, false, $context);
- } else {
- $wrapped = opendir($protocol . '://', $context);
- }
- } catch (\BadMethodCallException $e) {
- stream_wrapper_unregister($protocol);
- throw $e;
- }
- stream_wrapper_unregister($protocol);
- return $wrapped;
- }
-
- /**
- * Load the source from the stream context and return the context options
- *
- * @param string $name
- * @return array
- * @throws \BadMethodCallException
- */
- protected function loadContext($name) {
- $context = parent::loadContext($name);
-
- foreach ($this->expectedContextProperties as $property) {
- if (array_key_exists($property, $context)) {
- $this->{$property} = $context[$property];
- } else {
- throw new \BadMethodCallException('Invalid context, "' . $property . '" options not set');
- }
- }
- return $context;
-
- }
-
- public function stream_open($path, $mode, $options, &$opened_path) {
- $this->loadContext('ocencryption');
-
- $this->position = 0;
- $this->cache = '';
- $this->writeFlag = false;
- $this->unencryptedBlockSize = $this->encryptionModule->getUnencryptedBlockSize($this->signed);
-
- if (
- $mode === 'w'
- || $mode === 'w+'
- || $mode === 'wb'
- || $mode === 'wb+'
- || $mode === 'r+'
- || $mode === 'rb+'
- ) {
- $this->readOnly = false;
- } else {
- $this->readOnly = true;
- }
-
- $sharePath = $this->fullPath;
- if (!$this->storage->file_exists($this->internalPath)) {
- $sharePath = dirname($sharePath);
- }
-
- $accessList = $this->file->getAccessList($sharePath);
- $this->newHeader = $this->encryptionModule->begin($this->fullPath, $this->uid, $mode, $this->header, $accessList);
-
- if (
- $mode === 'w'
- || $mode === 'w+'
- || $mode === 'wb'
- || $mode === 'wb+'
- ) {
- // We're writing a new file so start write counter with 0 bytes
- $this->unencryptedSize = 0;
- $this->writeHeader();
- $this->headerSize = $this->util->getHeaderSize();
- $this->size = $this->headerSize;
- } else {
- $this->skipHeader();
- }
-
- return true;
-
- }
-
- public function stream_eof() {
- return $this->position >= $this->unencryptedSize;
- }
-
- public function stream_read($count) {
-
- $result = '';
-
- $count = min($count, $this->unencryptedSize - $this->position);
- while ($count > 0) {
- $remainingLength = $count;
- // update the cache of the current block
- $this->readCache();
- // determine the relative position in the current block
- $blockPosition = ($this->position % $this->unencryptedBlockSize);
- // if entire read inside current block then only position needs to be updated
- if ($remainingLength < ($this->unencryptedBlockSize - $blockPosition)) {
- $result .= substr($this->cache, $blockPosition, $remainingLength);
- $this->position += $remainingLength;
- $count = 0;
- // otherwise remainder of current block is fetched, the block is flushed and the position updated
- } else {
- $result .= substr($this->cache, $blockPosition);
- $this->flush();
- $this->position += ($this->unencryptedBlockSize - $blockPosition);
- $count -= ($this->unencryptedBlockSize - $blockPosition);
- }
- }
- return $result;
-
- }
-
- public function stream_write($data) {
-
- $length = 0;
- // loop over $data to fit it in 6126 sized unencrypted blocks
- while (isset($data[0])) {
- $remainingLength = strlen($data);
-
- // set the cache to the current 6126 block
- $this->readCache();
-
- // for seekable streams the pointer is moved back to the beginning of the encrypted block
- // flush will start writing there when the position moves to another block
- $positionInFile = (int)floor($this->position / $this->unencryptedBlockSize) *
- $this->util->getBlockSize() + $this->headerSize;
- $resultFseek = $this->parentStreamSeek($positionInFile);
-
- // only allow writes on seekable streams, or at the end of the encrypted stream
- if (!($this->readOnly) && ($resultFseek || $positionInFile === $this->size)) {
-
- // switch the writeFlag so flush() will write the block
- $this->writeFlag = true;
-
- // determine the relative position in the current block
- $blockPosition = ($this->position % $this->unencryptedBlockSize);
- // check if $data fits in current block
- // if so, overwrite existing data (if any)
- // update position and liberate $data
- if ($remainingLength < ($this->unencryptedBlockSize - $blockPosition)) {
- $this->cache = substr($this->cache, 0, $blockPosition)
- . $data . substr($this->cache, $blockPosition + $remainingLength);
- $this->position += $remainingLength;
- $length += $remainingLength;
- $data = '';
- // if $data doesn't fit the current block, the fill the current block and reiterate
- // after the block is filled, it is flushed and $data is updatedxxx
- } else {
- $this->cache = substr($this->cache, 0, $blockPosition) .
- substr($data, 0, $this->unencryptedBlockSize - $blockPosition);
- $this->flush();
- $this->position += ($this->unencryptedBlockSize - $blockPosition);
- $length += ($this->unencryptedBlockSize - $blockPosition);
- $data = substr($data, $this->unencryptedBlockSize - $blockPosition);
- }
- } else {
- $data = '';
- }
- $this->unencryptedSize = max($this->unencryptedSize, $this->position);
- }
- return $length;
- }
-
- public function stream_tell() {
- return $this->position;
- }
-
- public function stream_seek($offset, $whence = SEEK_SET) {
-
- $return = false;
-
- switch ($whence) {
- case SEEK_SET:
- $newPosition = $offset;
- break;
- case SEEK_CUR:
- $newPosition = $this->position + $offset;
- break;
- case SEEK_END:
- $newPosition = $this->unencryptedSize + $offset;
- break;
- default:
- return $return;
- }
-
- if ($newPosition > $this->unencryptedSize || $newPosition < 0) {
- return $return;
- }
-
- $newFilePosition = floor($newPosition / $this->unencryptedBlockSize)
- * $this->util->getBlockSize() + $this->headerSize;
-
- $oldFilePosition = parent::stream_tell();
- if ($this->parentStreamSeek($newFilePosition)) {
- $this->parentStreamSeek($oldFilePosition);
- $this->flush();
- $this->parentStreamSeek($newFilePosition);
- $this->position = $newPosition;
- $return = true;
- }
- return $return;
-
- }
-
- public function stream_close() {
- $this->flush('end');
- $position = (int)floor($this->position/$this->unencryptedBlockSize);
- $remainingData = $this->encryptionModule->end($this->fullPath, $position . 'end');
- if ($this->readOnly === false) {
- if(!empty($remainingData)) {
- parent::stream_write($remainingData);
- }
- $this->encryptionStorage->updateUnencryptedSize($this->fullPath, $this->unencryptedSize);
- }
- return parent::stream_close();
- }
-
- /**
- * write block to file
- * @param string $positionPrefix
- */
- protected function flush($positionPrefix = '') {
- // write to disk only when writeFlag was set to 1
- if ($this->writeFlag) {
- // Disable the file proxies so that encryption is not
- // automatically attempted when the file is written to disk -
- // we are handling that separately here and we don't want to
- // get into an infinite loop
- $position = (int)floor($this->position/$this->unencryptedBlockSize);
- $encrypted = $this->encryptionModule->encrypt($this->cache, $position . $positionPrefix);
- $bytesWritten = parent::stream_write($encrypted);
- $this->writeFlag = false;
- // Check whether the write concerns the last block
- // If so then update the encrypted filesize
- // Note that the unencrypted pointer and filesize are NOT yet updated when flush() is called
- // We recalculate the encrypted filesize as we do not know the context of calling flush()
- $completeBlocksInFile=(int)floor($this->unencryptedSize/$this->unencryptedBlockSize);
- if ($completeBlocksInFile === (int)floor($this->position/$this->unencryptedBlockSize)) {
- $this->size = $this->util->getBlockSize() * $completeBlocksInFile;
- $this->size += $bytesWritten;
- $this->size += $this->headerSize;
- }
- }
- // always empty the cache (otherwise readCache() will not fill it with the new block)
- $this->cache = '';
- }
-
- /**
- * read block to file
- */
- protected function readCache() {
- // cache should always be empty string when this function is called
- // don't try to fill the cache when trying to write at the end of the unencrypted file when it coincides with new block
- if ($this->cache === '' && !($this->position === $this->unencryptedSize && ($this->position % $this->unencryptedBlockSize) === 0)) {
- // Get the data from the file handle
- $data = parent::stream_read($this->util->getBlockSize());
- $position = (int)floor($this->position/$this->unencryptedBlockSize);
- $numberOfChunks = (int)($this->unencryptedSize / $this->unencryptedBlockSize);
- if($numberOfChunks === $position) {
- $position .= 'end';
- }
- $this->cache = $this->encryptionModule->decrypt($data, $position);
- }
- }
-
- /**
- * write header at beginning of encrypted file
- *
- * @return integer
- * @throws EncryptionHeaderKeyExistsException if header key is already in use
- */
- protected function writeHeader() {
- $header = $this->util->createHeader($this->newHeader, $this->encryptionModule);
- return parent::stream_write($header);
- }
-
- /**
- * read first block to skip the header
- */
- protected function skipHeader() {
- parent::stream_read($this->headerSize);
- }
-
- /**
- * call stream_seek() from parent class
- *
- * @param integer $position
- * @return bool
- */
- protected function parentStreamSeek($position) {
- return parent::stream_seek($position);
- }
-
- /**
- * @param string $path
- * @param array $options
- * @return bool
- */
- public function dir_opendir($path, $options) {
- return false;
- }
-
-}
diff --git a/lib/private/files/stream/oc.php b/lib/private/files/stream/oc.php
deleted file mode 100644
index 8439770e8fa..00000000000
--- a/lib/private/files/stream/oc.php
+++ /dev/null
@@ -1,153 +0,0 @@
-<?php
-/**
- * @author Jörn Friedrich Dreyer <jfd@butonic.de>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <icewind@owncloud.com>
- * @author Robin McCorkell <robin@mccorkell.me.uk>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OC\Files\Stream;
-
-/**
- * a stream wrappers for ownCloud's virtual filesystem
- */
-class OC {
- /**
- * @var \OC\Files\View
- */
- static private $rootView;
-
- private $path;
-
- /**
- * @var resource
- */
- private $dirSource;
-
- /**
- * @var resource
- */
- private $fileSource;
- private $meta;
-
- private function setup(){
- if (!self::$rootView) {
- self::$rootView = new \OC\Files\View('');
- }
- }
-
- public function stream_open($path, $mode, $options, &$opened_path) {
- $this->setup();
- $path = substr($path, strlen('oc://'));
- $this->path = $path;
- $this->fileSource = self::$rootView->fopen($path, $mode);
- if (is_resource($this->fileSource)) {
- $this->meta = stream_get_meta_data($this->fileSource);
- }
- return is_resource($this->fileSource);
- }
-
- public function stream_seek($offset, $whence = SEEK_SET) {
- return fseek($this->fileSource, $offset, $whence) === 0;
- }
-
- public function stream_tell() {
- return ftell($this->fileSource);
- }
-
- public function stream_read($count) {
- return fread($this->fileSource, $count);
- }
-
- public function stream_write($data) {
- return fwrite($this->fileSource, $data);
- }
-
- public function stream_set_option($option, $arg1, $arg2) {
- switch ($option) {
- case STREAM_OPTION_BLOCKING:
- stream_set_blocking($this->fileSource, $arg1);
- break;
- case STREAM_OPTION_READ_TIMEOUT:
- stream_set_timeout($this->fileSource, $arg1, $arg2);
- break;
- case STREAM_OPTION_WRITE_BUFFER:
- stream_set_write_buffer($this->fileSource, $arg1, $arg2);
- }
- }
-
- public function stream_stat() {
- return fstat($this->fileSource);
- }
-
- public function stream_lock($mode) {
- flock($this->fileSource, $mode);
- }
-
- public function stream_flush() {
- return fflush($this->fileSource);
- }
-
- public function stream_eof() {
- return feof($this->fileSource);
- }
-
- public function url_stat($path) {
- $this->setup();
- $path = substr($path, strlen('oc://'));
- if (self::$rootView->file_exists($path)) {
- return self::$rootView->stat($path);
- } else {
- return false;
- }
- }
-
- public function stream_close() {
- fclose($this->fileSource);
- }
-
- public function unlink($path) {
- $this->setup();
- $path = substr($path, strlen('oc://'));
- return self::$rootView->unlink($path);
- }
-
- public function dir_opendir($path, $options) {
- $this->setup();
- $path = substr($path, strlen('oc://'));
- $this->path = $path;
- $this->dirSource = self::$rootView->opendir($path);
- if (is_resource($this->dirSource)) {
- $this->meta = stream_get_meta_data($this->dirSource);
- }
- return is_resource($this->dirSource);
- }
-
- public function dir_readdir() {
- return readdir($this->dirSource);
- }
-
- public function dir_closedir() {
- closedir($this->dirSource);
- }
-
- public function dir_rewinddir() {
- rewinddir($this->dirSource);
- }
-}
diff --git a/lib/private/files/stream/quota.php b/lib/private/files/stream/quota.php
deleted file mode 100644
index 8d27575c568..00000000000
--- a/lib/private/files/stream/quota.php
+++ /dev/null
@@ -1,156 +0,0 @@
-<?php
-/**
- * @author Jörn Friedrich Dreyer <jfd@butonic.de>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <icewind@owncloud.com>
- * @author Vincent Petry <pvince81@owncloud.com>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OC\Files\Stream;
-
-/**
- * stream wrapper limits the amount of data that can be written to a stream
- *
- * usage: void \OC\Files\Stream\Quota::register($id, $stream, $limit)
- * or: resource \OC\Files\Stream\Quota::wrap($stream, $limit)
- */
-class Quota {
- private static $streams = array();
-
- /**
- * @var resource $source
- */
- private $source;
-
- /**
- * @var int $limit
- */
- private $limit;
-
- /**
- * @param string $id
- * @param resource $stream
- * @param int $limit
- */
- public static function register($id, $stream, $limit) {
- self::$streams[$id] = array($stream, $limit);
- }
-
- /**
- * remove all registered streams
- */
- public static function clear() {
- self::$streams = array();
- }
-
- /**
- * @param resource $stream
- * @param int $limit
- * @return resource
- */
- static public function wrap($stream, $limit) {
- $id = uniqid();
- self::register($id, $stream, $limit);
- $meta = stream_get_meta_data($stream);
- return fopen('quota://' . $id, $meta['mode']);
- }
-
- public function stream_open($path, $mode, $options, &$opened_path) {
- $id = substr($path, strlen('quota://'));
- if (isset(self::$streams[$id])) {
- list($this->source, $this->limit) = self::$streams[$id];
- return true;
- } else {
- return false;
- }
- }
-
- public function stream_seek($offset, $whence = SEEK_SET) {
- if ($whence === SEEK_END){
- // go to the end to find out last position's offset
- $oldOffset = $this->stream_tell();
- if (fseek($this->source, 0, $whence) !== 0){
- return false;
- }
- $whence = SEEK_SET;
- $offset = $this->stream_tell() + $offset;
- $this->limit += $oldOffset - $offset;
- }
- else if ($whence === SEEK_SET) {
- $this->limit += $this->stream_tell() - $offset;
- } else {
- $this->limit -= $offset;
- }
- // this wrapper needs to return "true" for success.
- // the fseek call itself returns 0 on succeess
- return fseek($this->source, $offset, $whence) === 0;
- }
-
- public function stream_tell() {
- return ftell($this->source);
- }
-
- public function stream_read($count) {
- $this->limit -= $count;
- return fread($this->source, $count);
- }
-
- public function stream_write($data) {
- $size = strlen($data);
- if ($size > $this->limit) {
- $data = substr($data, 0, $this->limit);
- $size = $this->limit;
- }
- $this->limit -= $size;
- return fwrite($this->source, $data);
- }
-
- public function stream_set_option($option, $arg1, $arg2) {
- switch ($option) {
- case STREAM_OPTION_BLOCKING:
- stream_set_blocking($this->source, $arg1);
- break;
- case STREAM_OPTION_READ_TIMEOUT:
- stream_set_timeout($this->source, $arg1, $arg2);
- break;
- case STREAM_OPTION_WRITE_BUFFER:
- stream_set_write_buffer($this->source, $arg1, $arg2);
- }
- }
-
- public function stream_stat() {
- return fstat($this->source);
- }
-
- public function stream_lock($mode) {
- return flock($this->source, $mode);
- }
-
- public function stream_flush() {
- return fflush($this->source);
- }
-
- public function stream_eof() {
- return feof($this->source);
- }
-
- public function stream_close() {
- fclose($this->source);
- }
-}
diff --git a/lib/private/files/stream/staticstream.php b/lib/private/files/stream/staticstream.php
deleted file mode 100644
index 7aacf7a9fe4..00000000000
--- a/lib/private/files/stream/staticstream.php
+++ /dev/null
@@ -1,170 +0,0 @@
-<?php
-/**
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <icewind@owncloud.com>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OC\Files\Stream;
-
-class StaticStream {
- const MODE_FILE = 0100000;
-
- public $context;
- protected static $data = array();
-
- protected $path = '';
- protected $pointer = 0;
- protected $writable = false;
-
- public function stream_close() {
- }
-
- public function stream_eof() {
- return $this->pointer >= strlen(self::$data[$this->path]);
- }
-
- public function stream_flush() {
- }
-
- public static function clear() {
- self::$data = array();
- }
-
- public function stream_open($path, $mode, $options, &$opened_path) {
- switch ($mode[0]) {
- case 'r':
- if (!isset(self::$data[$path])) return false;
- $this->path = $path;
- $this->writable = isset($mode[1]) && $mode[1] == '+';
- break;
- case 'w':
- self::$data[$path] = '';
- $this->path = $path;
- $this->writable = true;
- break;
- case 'a':
- if (!isset(self::$data[$path])) self::$data[$path] = '';
- $this->path = $path;
- $this->writable = true;
- $this->pointer = strlen(self::$data[$path]);
- break;
- case 'x':
- if (isset(self::$data[$path])) return false;
- $this->path = $path;
- $this->writable = true;
- break;
- case 'c':
- if (!isset(self::$data[$path])) self::$data[$path] = '';
- $this->path = $path;
- $this->writable = true;
- break;
- default:
- return false;
- }
- $opened_path = $this->path;
- return true;
- }
-
- public function stream_read($count) {
- $bytes = min(strlen(self::$data[$this->path]) - $this->pointer, $count);
- $data = substr(self::$data[$this->path], $this->pointer, $bytes);
- $this->pointer += $bytes;
- return $data;
- }
-
- public function stream_seek($offset, $whence = SEEK_SET) {
- $len = strlen(self::$data[$this->path]);
- switch ($whence) {
- case SEEK_SET:
- if ($offset <= $len) {
- $this->pointer = $offset;
- return true;
- }
- break;
- case SEEK_CUR:
- if ($this->pointer + $offset <= $len) {
- $this->pointer += $offset;
- return true;
- }
- break;
- case SEEK_END:
- if ($len + $offset <= $len) {
- $this->pointer = $len + $offset;
- return true;
- }
- break;
- }
- return false;
- }
-
- public function stream_stat() {
- return $this->url_stat($this->path);
- }
-
- public function stream_tell() {
- return $this->pointer;
- }
-
- public function stream_write($data) {
- if (!$this->writable) return 0;
- $size = strlen($data);
- if ($this->stream_eof()) {
- self::$data[$this->path] .= $data;
- } else {
- self::$data[$this->path] = substr_replace(
- self::$data[$this->path],
- $data,
- $this->pointer
- );
- }
- $this->pointer += $size;
- return $size;
- }
-
- public function unlink($path) {
- if (isset(self::$data[$path])) {
- unset(self::$data[$path]);
- }
- return true;
- }
-
- public function url_stat($path) {
- if (isset(self::$data[$path])) {
- $size = strlen(self::$data[$path]);
- $time = time();
- $data = array(
- 'dev' => 0,
- 'ino' => 0,
- 'mode' => self::MODE_FILE | 0777,
- 'nlink' => 1,
- 'uid' => 0,
- 'gid' => 0,
- 'rdev' => '',
- 'size' => $size,
- 'atime' => $time,
- 'mtime' => $time,
- 'ctime' => $time,
- 'blksize' => -1,
- 'blocks' => -1,
- );
- return array_values($data) + $data;
- }
- return false;
- }
-}
diff --git a/lib/private/files/type/detection.php b/lib/private/files/type/detection.php
deleted file mode 100644
index f106a98064f..00000000000
--- a/lib/private/files/type/detection.php
+++ /dev/null
@@ -1,318 +0,0 @@
-<?php
-/**
- * @author Andreas Fischer <bantu@owncloud.com>
- * @author Jens-Christian Fischer <jens-christian.fischer@switch.ch>
- * @author Lukas Reschke <lukas@owncloud.com>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <icewind@owncloud.com>
- * @author Robin McCorkell <robin@mccorkell.me.uk>
- * @author Roeland Jago Douma <rullzer@owncloud.com>
- * @author Thomas Tanghus <thomas@tanghus.net>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OC\Files\Type;
-
-use OCP\Files\IMimeTypeDetector;
-use OCP\IURLGenerator;
-
-/**
- * Class Detection
- *
- * Mimetype detection
- *
- * @package OC\Files\Type
- */
-class Detection implements IMimeTypeDetector {
- protected $mimetypes = [];
- protected $secureMimeTypes = [];
-
- protected $mimetypeIcons = [];
- /** @var string[] */
- protected $mimeTypeAlias = [];
-
- /** @var IURLGenerator */
- private $urlGenerator;
-
- /** @var string */
- private $customConfigDir;
-
- /** @var string */
- private $defaultConfigDir;
-
- /**
- * @param IURLGenerator $urlGenerator
- * @param string $customConfigDir
- * @param string $defaultConfigDir
- */
- public function __construct(IURLGenerator $urlGenerator,
- $customConfigDir,
- $defaultConfigDir) {
- $this->urlGenerator = $urlGenerator;
- $this->customConfigDir = $customConfigDir;
- $this->defaultConfigDir = $defaultConfigDir;
- }
-
- /**
- * Add an extension -> mimetype mapping
- *
- * $mimetype is the assumed correct mime type
- * The optional $secureMimeType is an alternative to send to send
- * to avoid potential XSS.
- *
- * @param string $extension
- * @param string $mimetype
- * @param string|null $secureMimeType
- */
- public function registerType($extension,
- $mimetype,
- $secureMimeType = null) {
- $this->mimetypes[$extension] = array($mimetype, $secureMimeType);
- $this->secureMimeTypes[$mimetype] = $secureMimeType ?: $mimetype;
- }
-
- /**
- * Add an array of extension -> mimetype mappings
- *
- * The mimetype value is in itself an array where the first index is
- * the assumed correct mimetype and the second is either a secure alternative
- * or null if the correct is considered secure.
- *
- * @param array $types
- */
- public function registerTypeArray($types) {
- $this->mimetypes = array_merge($this->mimetypes, $types);
-
- // Update the alternative mimetypes to avoid having to look them up each time.
- foreach ($this->mimetypes as $mimeType) {
- $this->secureMimeTypes[$mimeType[0]] = isset($mimeType[1]) ? $mimeType[1]: $mimeType[0];
- }
- }
-
- /**
- * Add the mimetype aliases if they are not yet present
- */
- private function loadAliases() {
- if (!empty($this->mimeTypeAlias)) {
- return;
- }
-
- $this->mimeTypeAlias = json_decode(file_get_contents($this->defaultConfigDir . '/mimetypealiases.dist.json'), true);
-
- if (file_exists($this->customConfigDir . '/mimetypealiases.json')) {
- $custom = json_decode(file_get_contents($this->customConfigDir . '/mimetypealiases.json'), true);
- $this->mimeTypeAlias = array_merge($this->mimeTypeAlias, $custom);
- }
- }
-
- /**
- * @return string[]
- */
- public function getAllAliases() {
- $this->loadAliases();
- return $this->mimeTypeAlias;
- }
-
- /**
- * Add mimetype mappings if they are not yet present
- */
- private function loadMappings() {
- if (!empty($this->mimetypes)) {
- return;
- }
-
- $mimetypeMapping = json_decode(file_get_contents($this->defaultConfigDir . '/mimetypemapping.dist.json'), true);
-
- //Check if need to load custom mappings
- if (file_exists($this->customConfigDir . '/mimetypemapping.json')) {
- $custom = json_decode(file_get_contents($this->customConfigDir . '/mimetypemapping.json'), true);
- $mimetypeMapping = array_merge($mimetypeMapping, $custom);
- }
-
- $this->registerTypeArray($mimetypeMapping);
- }
-
- /**
- * @return array
- */
- public function getAllMappings() {
- $this->loadMappings();
- return $this->mimetypes;
- }
-
- /**
- * detect mimetype only based on filename, content of file is not used
- *
- * @param string $path
- * @return string
- */
- public function detectPath($path) {
- $this->loadMappings();
-
- if (strpos($path, '.')) {
- //try to guess the type by the file extension
- $extension = strtolower(strrchr(basename($path), "."));
- $extension = substr($extension, 1); //remove leading .
- return (isset($this->mimetypes[$extension]) && isset($this->mimetypes[$extension][0]))
- ? $this->mimetypes[$extension][0]
- : 'application/octet-stream';
- } else {
- return 'application/octet-stream';
- }
- }
-
- /**
- * detect mimetype based on both filename and content
- *
- * @param string $path
- * @return string
- */
- public function detect($path) {
- $this->loadMappings();
-
- if (@is_dir($path)) {
- // directories are easy
- return "httpd/unix-directory";
- }
-
- $mimeType = $this->detectPath($path);
-
- if ($mimeType === 'application/octet-stream' and function_exists('finfo_open')
- and function_exists('finfo_file') and $finfo = finfo_open(FILEINFO_MIME)
- ) {
- $info = @strtolower(finfo_file($finfo, $path));
- finfo_close($finfo);
- if ($info) {
- $mimeType = substr($info, 0, strpos($info, ';'));
- return empty($mimeType) ? 'application/octet-stream' : $mimeType;
- }
-
- }
- $isWrapped = (strpos($path, '://') !== false) and (substr($path, 0, 7) === 'file://');
- if (!$isWrapped and $mimeType === 'application/octet-stream' && function_exists("mime_content_type")) {
- // use mime magic extension if available
- $mimeType = mime_content_type($path);
- }
- if (!$isWrapped and $mimeType === 'application/octet-stream' && \OC_Helper::canExecute("file")) {
- // it looks like we have a 'file' command,
- // lets see if it does have mime support
- $path = escapeshellarg($path);
- $fp = popen("file -b --mime-type $path 2>/dev/null", "r");
- $reply = fgets($fp);
- pclose($fp);
-
- //trim the newline
- $mimeType = trim($reply);
-
- if (empty($mimeType)) {
- $mimeType = 'application/octet-stream';
- }
-
- }
- return $mimeType;
- }
-
- /**
- * detect mimetype based on the content of a string
- *
- * @param string $data
- * @return string
- */
- public function detectString($data) {
- if (function_exists('finfo_open') and function_exists('finfo_file')) {
- $finfo = finfo_open(FILEINFO_MIME);
- return finfo_buffer($finfo, $data);
- } else {
- $tmpFile = \OC::$server->getTempManager()->getTemporaryFile();
- $fh = fopen($tmpFile, 'wb');
- fwrite($fh, $data, 8024);
- fclose($fh);
- $mime = $this->detect($tmpFile);
- unset($tmpFile);
- return $mime;
- }
- }
-
- /**
- * Get a secure mimetype that won't expose potential XSS.
- *
- * @param string $mimeType
- * @return string
- */
- public function getSecureMimeType($mimeType) {
- $this->loadMappings();
-
- return isset($this->secureMimeTypes[$mimeType])
- ? $this->secureMimeTypes[$mimeType]
- : 'application/octet-stream';
- }
-
- /**
- * Get path to the icon of a file type
- * @param string $mimetype the MIME type
- * @return string the url
- */
- public function mimeTypeIcon($mimetype) {
- $this->loadAliases();
-
- while (isset($this->mimeTypeAlias[$mimetype])) {
- $mimetype = $this->mimeTypeAlias[$mimetype];
- }
- if (isset($this->mimetypeIcons[$mimetype])) {
- return $this->mimetypeIcons[$mimetype];
- }
-
- // Replace slash and backslash with a minus
- $icon = str_replace('/', '-', $mimetype);
- $icon = str_replace('\\', '-', $icon);
-
- // Is it a dir?
- if ($mimetype === 'dir') {
- $this->mimetypeIcons[$mimetype] = $this->urlGenerator->imagePath('core', 'filetypes/folder.png');
- return $this->mimetypeIcons[$mimetype];
- }
- if ($mimetype === 'dir-shared') {
- $this->mimetypeIcons[$mimetype] = $this->urlGenerator->imagePath('core', 'filetypes/folder-shared.png');
- return $this->mimetypeIcons[$mimetype];
- }
- if ($mimetype === 'dir-external') {
- $this->mimetypeIcons[$mimetype] = $this->urlGenerator->imagePath('core', 'filetypes/folder-external.png');
- return $this->mimetypeIcons[$mimetype];
- }
-
- // Icon exists?
- try {
- $this->mimetypeIcons[$mimetype] = $this->urlGenerator->imagePath('core', 'filetypes/' . $icon . '.png');
- return $this->mimetypeIcons[$mimetype];
- } catch (\RuntimeException $e) {
- // Specified image not found
- }
-
- // Try only the first part of the filetype
- $mimePart = substr($icon, 0, strpos($icon, '-'));
- try {
- $this->mimetypeIcons[$mimetype] = $this->urlGenerator->imagePath('core', 'filetypes/' . $mimePart . '.png');
- return $this->mimetypeIcons[$mimetype];
- } catch (\RuntimeException $e) {
- // Image for the first part of the mimetype not found
- }
-
- $this->mimetypeIcons[$mimetype] = $this->urlGenerator->imagePath('core', 'filetypes/file.png');
- return $this->mimetypeIcons[$mimetype];
- }
-}
diff --git a/lib/private/files/type/loader.php b/lib/private/files/type/loader.php
deleted file mode 100644
index 95ba7597257..00000000000
--- a/lib/private/files/type/loader.php
+++ /dev/null
@@ -1,173 +0,0 @@
-<?php
-/**
- * @author Robin McCorkell <robin@mccorkell.me.uk>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OC\Files\Type;
-
-use OCP\Files\IMimeTypeLoader;
-use OCP\IDBConnection;
-
-use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
-
-/**
- * Mimetype database loader
- *
- * @package OC\Files\Type
- */
-class Loader implements IMimeTypeLoader {
-
- /** @var IDBConnection */
- private $dbConnection;
-
- /** @var array [id => mimetype] */
- protected $mimetypes;
-
- /** @var array [mimetype => id] */
- protected $mimetypeIds;
-
- /**
- * @param IDBConnection $dbConnection
- */
- public function __construct(IDBConnection $dbConnection) {
- $this->dbConnection = $dbConnection;
- $this->mimetypes = [];
- $this->mimetypeIds = [];
- }
-
- /**
- * Get a mimetype from its ID
- *
- * @param int $id
- * @return string|null
- */
- public function getMimetypeById($id) {
- if (!$this->mimetypes) {
- $this->loadMimetypes();
- }
- if (isset($this->mimetypes[$id])) {
- return $this->mimetypes[$id];
- }
- return null;
- }
-
- /**
- * Get a mimetype ID, adding the mimetype to the DB if it does not exist
- *
- * @param string $mimetype
- * @return int
- */
- public function getId($mimetype) {
- if (!$this->mimetypeIds) {
- $this->loadMimetypes();
- }
- if (isset($this->mimetypeIds[$mimetype])) {
- return $this->mimetypeIds[$mimetype];
- }
- return $this->store($mimetype);
- }
-
- /**
- * Test if a mimetype exists in the database
- *
- * @param string $mimetype
- * @return bool
- */
- public function exists($mimetype) {
- if (!$this->mimetypeIds) {
- $this->loadMimetypes();
- }
- return isset($this->mimetypeIds[$mimetype]);
- }
-
- /**
- * Clear all loaded mimetypes, allow for re-loading
- */
- public function reset() {
- $this->mimetypes = [];
- $this->mimetypeIds = [];
- }
-
- /**
- * Store a mimetype in the DB
- *
- * @param string $mimetype
- * @param int inserted ID
- */
- protected function store($mimetype) {
- try {
- $qb = $this->dbConnection->getQueryBuilder();
- $qb->insert('mimetypes')
- ->values([
- 'mimetype' => $qb->createNamedParameter($mimetype)
- ]);
- $qb->execute();
- } catch (UniqueConstraintViolationException $e) {
- // something inserted it before us
- }
-
- $fetch = $this->dbConnection->getQueryBuilder();
- $fetch->select('id')
- ->from('mimetypes')
- ->where(
- $fetch->expr()->eq('mimetype', $fetch->createNamedParameter($mimetype)
- ));
- $row = $fetch->execute()->fetch();
-
- $this->mimetypes[$row['id']] = $mimetype;
- $this->mimetypeIds[$mimetype] = $row['id'];
- return $row['id'];
- }
-
- /**
- * Load all mimetypes from DB
- */
- private function loadMimetypes() {
- $qb = $this->dbConnection->getQueryBuilder();
- $qb->select('id', 'mimetype')
- ->from('mimetypes');
- $results = $qb->execute()->fetchAll();
-
- foreach ($results as $row) {
- $this->mimetypes[$row['id']] = $row['mimetype'];
- $this->mimetypeIds[$row['mimetype']] = $row['id'];
- }
- }
-
- /**
- * Update filecache mimetype based on file extension
- *
- * @param string $ext file extension
- * @param int $mimetypeId
- * @return int number of changed rows
- */
- public function updateFilecache($ext, $mimetypeId) {
- $update = $this->dbConnection->getQueryBuilder();
- $update->update('filecache')
- ->set('mimetype', $update->createNamedParameter($mimetypeId))
- ->where($update->expr()->neq(
- 'mimetype', $update->createNamedParameter($mimetypeId)
- ))
- ->andWhere($update->expr()->like(
- $update->createFunction('LOWER(`name`)'), $update->createNamedParameter($ext)
- ));
- return $update->execute();
- }
-
-}
diff --git a/lib/private/files/type/templatemanager.php b/lib/private/files/type/templatemanager.php
deleted file mode 100644
index 363fb7a2a6c..00000000000
--- a/lib/private/files/type/templatemanager.php
+++ /dev/null
@@ -1,61 +0,0 @@
-<?php
-/**
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <icewind@owncloud.com>
- * @author Robin McCorkell <robin@mccorkell.me.uk>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OC\Files\Type;
-
-class TemplateManager {
- protected $templates = array();
-
- public function registerTemplate($mimetype, $path) {
- $this->templates[$mimetype] = $path;
- }
-
- /**
- * get the path of the template for a mimetype
- *
- * @param string $mimetype
- * @return string|null
- */
- public function getTemplatePath($mimetype) {
- if (isset($this->templates[$mimetype])) {
- return $this->templates[$mimetype];
- } else {
- return null;
- }
- }
-
- /**
- * get the template content for a mimetype
- *
- * @param string $mimetype
- * @return string
- */
- public function getTemplate($mimetype) {
- $path = $this->getTemplatePath($mimetype);
- if ($path) {
- return file_get_contents($path);
- } else {
- return '';
- }
- }
-}
diff --git a/lib/private/files/utils/scanner.php b/lib/private/files/utils/scanner.php
deleted file mode 100644
index 06526583899..00000000000
--- a/lib/private/files/utils/scanner.php
+++ /dev/null
@@ -1,172 +0,0 @@
-<?php
-/**
- * @author Jörn Friedrich Dreyer <jfd@butonic.de>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Olivier Paroz <github@oparoz.com>
- * @author Robin Appelman <icewind@owncloud.com>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
- */
-
-namespace OC\Files\Utils;
-
-use OC\Files\Filesystem;
-use OC\ForbiddenException;
-use OC\Hooks\PublicEmitter;
-use OC\Lock\DBLockingProvider;
-use OCP\Files\StorageNotAvailableException;
-use OCP\ILogger;
-
-/**
- * Class Scanner
- *
- * Hooks available in scope \OC\Utils\Scanner
- * - scanFile(string $absolutePath)
- * - scanFolder(string $absolutePath)
- *
- * @package OC\Files\Utils
- */
-class Scanner extends PublicEmitter {
- /**
- * @var string $user
- */
- private $user;
-
- /**
- * @var \OCP\IDBConnection
- */
- protected $db;
-
- /**
- * @var ILogger
- */
- protected $logger;
-
- /**
- * @param string $user
- * @param \OCP\IDBConnection $db
- * @param ILogger $logger
- */
- public function __construct($user, $db, ILogger $logger) {
- $this->logger = $logger;
- $this->user = $user;
- $this->db = $db;
- }
-
- /**
- * get all storages for $dir
- *
- * @param string $dir
- * @return \OC\Files\Mount\MountPoint[]
- */
- protected function getMounts($dir) {
- //TODO: move to the node based fileapi once that's done
- \OC_Util::tearDownFS();
- \OC_Util::setupFS($this->user);
-
- $mountManager = Filesystem::getMountManager();
- $mounts = $mountManager->findIn($dir);
- $mounts[] = $mountManager->find($dir);
- $mounts = array_reverse($mounts); //start with the mount of $dir
-
- return $mounts;
- }
-
- /**
- * attach listeners to the scanner
- *
- * @param \OC\Files\Mount\MountPoint $mount
- */
- protected function attachListener($mount) {
- $scanner = $mount->getStorage()->getScanner();
- $emitter = $this;
- $scanner->listen('\OC\Files\Cache\Scanner', 'scanFile', function ($path) use ($mount, $emitter) {
- $emitter->emit('\OC\Files\Utils\Scanner', 'scanFile', array($mount->getMountPoint() . $path));
- });
- $scanner->listen('\OC\Files\Cache\Scanner', 'scanFolder', function ($path) use ($mount, $emitter) {
- $emitter->emit('\OC\Files\Utils\Scanner', 'scanFolder', array($mount->getMountPoint() . $path));
- });
- $scanner->listen('\OC\Files\Cache\Scanner', 'postScanFile', function ($path) use ($mount, $emitter) {
- $emitter->emit('\OC\Files\Utils\Scanner', 'postScanFile', array($mount->getMountPoint() . $path));
- });
- $scanner->listen('\OC\Files\Cache\Scanner', 'postScanFolder', function ($path) use ($mount, $emitter) {
- $emitter->emit('\OC\Files\Utils\Scanner', 'postScanFolder', array($mount->getMountPoint() . $path));
- });
- }
-
- /**
- * @param string $dir
- */
- public function backgroundScan($dir) {
- $mounts = $this->getMounts($dir);
- foreach ($mounts as $mount) {
- if (is_null($mount->getStorage())) {
- continue;
- }
- // don't scan the root storage
- if ($mount->getStorage()->instanceOfStorage('\OC\Files\Storage\Local') && $mount->getMountPoint() === '/') {
- continue;
- }
- $scanner = $mount->getStorage()->getScanner();
- $this->attachListener($mount);
- $scanner->backgroundScan();
- }
- }
-
- /**
- * @param string $dir
- * @throws \OC\ForbiddenException
- */
- public function scan($dir = '') {
- if (!Filesystem::isValidPath($dir)) {
- throw new \InvalidArgumentException('Invalid path to scan');
- }
- $mounts = $this->getMounts($dir);
- foreach ($mounts as $mount) {
- if (is_null($mount->getStorage())) {
- continue;
- }
- $storage = $mount->getStorage();
- // if the home storage isn't writable then the scanner is run as the wrong user
- if ($storage->instanceOfStorage('\OC\Files\Storage\Home') and
- (!$storage->isCreatable('') or !$storage->isCreatable('files'))
- ) {
- throw new ForbiddenException();
- }
- $relativePath = $mount->getInternalPath($dir);
- $scanner = $storage->getScanner();
- $scanner->setUseTransactions(false);
- $this->attachListener($mount);
- $isDbLocking = \OC::$server->getLockingProvider() instanceof DBLockingProvider;
- if (!$isDbLocking) {
- $this->db->beginTransaction();
- }
- try {
- $scanner->scan($relativePath, \OC\Files\Cache\Scanner::SCAN_RECURSIVE, \OC\Files\Cache\Scanner::REUSE_ETAG | \OC\Files\Cache\Scanner::REUSE_SIZE);
- } catch (StorageNotAvailableException $e) {
- $this->logger->error('Storage ' . $storage->getId() . ' not available');
- $this->logger->logException($e);
- $this->emit('\OC\Files\Utils\Scanner', 'StorageNotAvailable', [$e]);
- }
- if (!$isDbLocking) {
- $this->db->commit();
- }
- }
- }
-}
-
diff --git a/lib/private/files/view.php b/lib/private/files/view.php
deleted file mode 100644
index aac33a4598c..00000000000
--- a/lib/private/files/view.php
+++ /dev/null
@@ -1,2058 +0,0 @@
-<?php
-/**
- * @author Arthur Schiwon <blizzz@owncloud.com>
- * @author Bart Visscher <bartv@thisnet.nl>
- * @author Björn Schießle <schiessle@owncloud.com>
- * @author cmeh <cmeh@users.noreply.github.com>
- * @author Florin Peter <github@florin-peter.de>
- * @author Jesús Macias <jmacias@solidgear.es>
- * @author Joas Schilling <nickvergessen@owncloud.com>
- * @author Jörn Friedrich Dreyer <jfd@butonic.de>
- * @author Klaas Freitag <freitag@owncloud.com>
- * @author Lukas Reschke <lukas@owncloud.com>
- * @author Luke Policinski <lpolicinski@gmail.com>
- * @author Martin Mattel <martin.mattel@diemattels.at>
- * @author Michael Gapczynski <GapczynskiM@gmail.com>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Robin Appelman <icewind@owncloud.com>
- * @author Robin McCorkell <robin@mccorkell.me.uk>
- * @author Roeland Jago Douma <rullzer@owncloud.com>
- * @author Sam Tuke <mail@samtuke.com>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- * @author Thomas Tanghus <thomas@tanghus.net>
- * @author Vincent Petry <pvince81@owncloud.com>
- *
- * @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 <http://www.gnu.org/licenses/>
- *
- */
-
-
-namespace OC\Files;
-
-use Icewind\Streams\CallbackWrapper;
-use OC\Files\Mount\MoveableMount;
-use OC\Files\Storage\Storage;
-use OC\User\User;
-use OCP\Constants;
-use OCP\Files\Cache\ICacheEntry;
-use OCP\Files\FileNameTooLongException;
-use OCP\Files\InvalidCharacterInPathException;
-use OCP\Files\InvalidPathException;
-use OCP\Files\NotFoundException;
-use OCP\Files\ReservedWordException;
-use OCP\Files\Storage\ILockingStorage;
-use OCP\IUser;
-use OCP\Lock\ILockingProvider;
-use OCP\Lock\LockedException;
-
-/**
- * Class to provide access to ownCloud filesystem via a "view", and methods for
- * working with files within that view (e.g. read, write, delete, etc.). Each
- * view is restricted to a set of directories via a virtual root. The default view
- * uses the currently logged in user's data directory as root (parts of
- * OC_Filesystem are merely a wrapper for OC\Files\View).
- *
- * Apps that need to access files outside of the user data folders (to modify files
- * belonging to a user other than the one currently logged in, for example) should
- * use this class directly rather than using OC_Filesystem, or making use of PHP's
- * built-in file manipulation functions. This will ensure all hooks and proxies
- * are triggered correctly.
- *
- * Filesystem functions are not called directly; they are passed to the correct
- * \OC\Files\Storage\Storage object
- */
-class View {
- /** @var string */
- private $fakeRoot = '';
-
- /**
- * @var \OCP\Lock\ILockingProvider
- */
- private $lockingProvider;
-
- private $lockingEnabled;
-
- private $updaterEnabled = true;
-
- private $userManager;
-
- /**
- * @param string $root
- * @throws \Exception If $root contains an invalid path
- */
- public function __construct($root = '') {
- if (is_null($root)) {
- throw new \InvalidArgumentException('Root can\'t be null');
- }
- if (!Filesystem::isValidPath($root)) {
- throw new \Exception();
- }
-
- $this->fakeRoot = $root;
- $this->lockingProvider = \OC::$server->getLockingProvider();
- $this->lockingEnabled = !($this->lockingProvider instanceof \OC\Lock\NoopLockingProvider);
- $this->userManager = \OC::$server->getUserManager();
- }
-
- public function getAbsolutePath($path = '/') {
- if ($path === null) {
- return null;
- }
- $this->assertPathLength($path);
- if ($path === '') {
- $path = '/';
- }
- if ($path[0] !== '/') {
- $path = '/' . $path;
- }
- return $this->fakeRoot . $path;
- }
-
- /**
- * change the root to a fake root
- *
- * @param string $fakeRoot
- * @return boolean|null
- */
- public function chroot($fakeRoot) {
- if (!$fakeRoot == '') {
- if ($fakeRoot[0] !== '/') {
- $fakeRoot = '/' . $fakeRoot;
- }
- }
- $this->fakeRoot = $fakeRoot;
- }
-
- /**
- * get the fake root
- *
- * @return string
- */
- public function getRoot() {
- return $this->fakeRoot;
- }
-
- /**
- * get path relative to the root of the view
- *
- * @param string $path
- * @return string
- */
- public function getRelativePath($path) {
- $this->assertPathLength($path);
- if ($this->fakeRoot == '') {
- return $path;
- }
-
- if (rtrim($path, '/') === rtrim($this->fakeRoot, '/')) {
- return '/';
- }
-
- // missing slashes can cause wrong matches!
- $root = rtrim($this->fakeRoot, '/') . '/';
-
- if (strpos($path, $root) !== 0) {
- return null;
- } else {
- $path = substr($path, strlen($this->fakeRoot));
- if (strlen($path) === 0) {
- return '/';
- } else {
- return $path;
- }
- }
- }
-
- /**
- * get the mountpoint of the storage object for a path
- * ( note: because a storage is not always mounted inside the fakeroot, the
- * returned mountpoint is relative to the absolute root of the filesystem
- * and does not take the chroot into account )
- *
- * @param string $path
- * @return string
- */
- public function getMountPoint($path) {
- return Filesystem::getMountPoint($this->getAbsolutePath($path));
- }
-
- /**
- * get the mountpoint of the storage object for a path
- * ( note: because a storage is not always mounted inside the fakeroot, the
- * returned mountpoint is relative to the absolute root of the filesystem
- * and does not take the chroot into account )
- *
- * @param string $path
- * @return \OCP\Files\Mount\IMountPoint
- */
- public function getMount($path) {
- return Filesystem::getMountManager()->find($this->getAbsolutePath($path));
- }
-
- /**
- * resolve a path to a storage and internal path
- *
- * @param string $path
- * @return array an array consisting of the storage and the internal path
- */
- public function resolvePath($path) {
- $a = $this->getAbsolutePath($path);
- $p = Filesystem::normalizePath($a);
- return Filesystem::resolvePath($p);
- }
-
- /**
- * return the path to a local version of the file
- * we need this because we can't know if a file is stored local or not from
- * outside the filestorage and for some purposes a local file is needed
- *
- * @param string $path
- * @return string
- */
- public function getLocalFile($path) {
- $parent = substr($path, 0, strrpos($path, '/'));
- $path = $this->getAbsolutePath($path);
- list($storage, $internalPath) = Filesystem::resolvePath($path);
- if (Filesystem::isValidPath($parent) and $storage) {
- return $storage->getLocalFile($internalPath);
- } else {
- return null;
- }
- }
-
- /**
- * @param string $path
- * @return string
- */
- public function getLocalFolder($path) {
- $parent = substr($path, 0, strrpos($path, '/'));
- $path = $this->getAbsolutePath($path);
- list($storage, $internalPath) = Filesystem::resolvePath($path);
- if (Filesystem::isValidPath($parent) and $storage) {
- return $storage->getLocalFolder($internalPath);
- } else {
- return null;
- }
- }
-
- /**
- * the following functions operate with arguments and return values identical
- * to those of their PHP built-in equivalents. Mostly they are merely wrappers
- * for \OC\Files\Storage\Storage via basicOperation().
- */
- public function mkdir($path) {
- return $this->basicOperation('mkdir', $path, array('create', 'write'));
- }
-
- /**
- * remove mount point
- *
- * @param \OC\Files\Mount\MoveableMount $mount
- * @param string $path relative to data/
- * @return boolean
- */
- protected function removeMount($mount, $path) {
- if ($mount instanceof MoveableMount) {
- // cut of /user/files to get the relative path to data/user/files
- $pathParts = explode('/', $path, 4);
- $relPath = '/' . $pathParts[3];
- $this->lockFile($relPath, ILockingProvider::LOCK_SHARED, true);
- \OC_Hook::emit(
- Filesystem::CLASSNAME, "umount",
- array(Filesystem::signal_param_path => $relPath)
- );
- $this->changeLock($relPath, ILockingProvider::LOCK_EXCLUSIVE, true);
- $result = $mount->removeMount();
- $this->changeLock($relPath, ILockingProvider::LOCK_SHARED, true);
- if ($result) {
- \OC_Hook::emit(
- Filesystem::CLASSNAME, "post_umount",
- array(Filesystem::signal_param_path => $relPath)
- );
- }
- $this->unlockFile($relPath, ILockingProvider::LOCK_SHARED, true);
- return $result;
- } else {
- // do not allow deleting the storage's root / the mount point
- // because for some storages it might delete the whole contents
- // but isn't supposed to work that way
- return false;
- }
- }
-
- public function disableCacheUpdate() {
- $this->updaterEnabled = false;
- }
-
- public function enableCacheUpdate() {
- $this->updaterEnabled = true;
- }
-
- protected function writeUpdate(Storage $storage, $internalPath, $time = null) {
- if ($this->updaterEnabled) {
- if (is_null($time)) {
- $time = time();
- }
- $storage->getUpdater()->update($internalPath, $time);
- }
- }
-
- protected function removeUpdate(Storage $storage, $internalPath) {
- if ($this->updaterEnabled) {
- $storage->getUpdater()->remove($internalPath);
- }
- }
-
- protected function renameUpdate(Storage $sourceStorage, Storage $targetStorage, $sourceInternalPath, $targetInternalPath) {
- if ($this->updaterEnabled) {
- $targetStorage->getUpdater()->renameFromStorage($sourceStorage, $sourceInternalPath, $targetInternalPath);
- }
- }
-
- /**
- * @param string $path
- * @return bool|mixed
- */
- public function rmdir($path) {
- $absolutePath = $this->getAbsolutePath($path);
- $mount = Filesystem::getMountManager()->find($absolutePath);
- if ($mount->getInternalPath($absolutePath) === '') {
- return $this->removeMount($mount, $absolutePath);
- }
- if ($this->is_dir($path)) {
- return $this->basicOperation('rmdir', $path, array('delete'));
- } else {
- return false;
- }
- }
-
- /**
- * @param string $path
- * @return resource
- */
- public function opendir($path) {
- return $this->basicOperation('opendir', $path, array('read'));
- }
-
- /**
- * @param $handle
- * @return mixed
- */
- public function readdir($handle) {
- $fsLocal = new Storage\Local(array('datadir' => '/'));
- return $fsLocal->readdir($handle);
- }
-
- /**
- * @param string $path
- * @return bool|mixed
- */
- public function is_dir($path) {
- if ($path == '/') {
- return true;
- }
- return $this->basicOperation('is_dir', $path);
- }
-
- /**
- * @param string $path
- * @return bool|mixed
- */
- public function is_file($path) {
- if ($path == '/') {
- return false;
- }
- return $this->basicOperation('is_file', $path);
- }
-
- /**
- * @param string $path
- * @return mixed
- */
- public function stat($path) {
- return $this->basicOperation('stat', $path);
- }
-
- /**
- * @param string $path
- * @return mixed
- */
- public function filetype($path) {
- return $this->basicOperation('filetype', $path);
- }
-
- /**
- * @param string $path
- * @return mixed
- */
- public function filesize($path) {
- return $this->basicOperation('filesize', $path);
- }
-
- /**
- * @param string $path
- * @return bool|mixed
- * @throws \OCP\Files\InvalidPathException
- */
- public function readfile($path) {
- $this->assertPathLength($path);
- @ob_end_clean();
- $handle = $this->fopen($path, 'rb');
- if ($handle) {
- $chunkSize = 8192; // 8 kB chunks
- while (!feof($handle)) {
- echo fread($handle, $chunkSize);
- flush();
- }
- $size = $this->filesize($path);
- return $size;
- }
- return false;
- }
-
- /**
- * @param string $path
- * @return mixed
- */
- public function isCreatable($path) {
- return $this->basicOperation('isCreatable', $path);
- }
-
- /**
- * @param string $path
- * @return mixed
- */
- public function isReadable($path) {
- return $this->basicOperation('isReadable', $path);
- }
-
- /**
- * @param string $path
- * @return mixed
- */
- public function isUpdatable($path) {
- return $this->basicOperation('isUpdatable', $path);
- }
-
- /**
- * @param string $path
- * @return bool|mixed
- */
- public function isDeletable($path) {
- $absolutePath = $this->getAbsolutePath($path);
- $mount = Filesystem::getMountManager()->find($absolutePath);
- if ($mount->getInternalPath($absolutePath) === '') {
- return $mount instanceof MoveableMount;
- }
- return $this->basicOperation('isDeletable', $path);
- }
-
- /**
- * @param string $path
- * @return mixed
- */
- public function isSharable($path) {
- return $this->basicOperation('isSharable', $path);
- }
-
- /**
- * @param string $path
- * @return bool|mixed
- */
- public function file_exists($path) {
- if ($path == '/') {
- return true;
- }
- return $this->basicOperation('file_exists', $path);
- }
-
- /**
- * @param string $path
- * @return mixed
- */
- public function filemtime($path) {
- return $this->basicOperation('filemtime', $path);
- }
-
- /**
- * @param string $path
- * @param int|string $mtime
- * @return bool
- */
- public function touch($path, $mtime = null) {
- if (!is_null($mtime) and !is_numeric($mtime)) {
- $mtime = strtotime($mtime);
- }
-
- $hooks = array('touch');
-
- if (!$this->file_exists($path)) {
- $hooks[] = 'create';
- $hooks[] = 'write';
- }
- $result = $this->basicOperation('touch', $path, $hooks, $mtime);
- if (!$result) {
- // If create file fails because of permissions on external storage like SMB folders,
- // check file exists and return false if not.
- if (!$this->file_exists($path)) {
- return false;
- }
- if (is_null($mtime)) {
- $mtime = time();
- }
- //if native touch fails, we emulate it by changing the mtime in the cache
- $this->putFileInfo($path, array('mtime' => $mtime));
- }
- return true;
- }
-
- /**
- * @param string $path
- * @return mixed
- */
- public function file_get_contents($path) {
- return $this->basicOperation('file_get_contents', $path, array('read'));
- }
-
- /**
- * @param bool $exists
- * @param string $path
- * @param bool $run
- */
- protected function emit_file_hooks_pre($exists, $path, &$run) {
- if (!$exists) {
- \OC_Hook::emit(Filesystem::CLASSNAME, Filesystem::signal_create, array(
- Filesystem::signal_param_path => $this->getHookPath($path),
- Filesystem::signal_param_run => &$run,
- ));
- } else {
- \OC_Hook::emit(Filesystem::CLASSNAME, Filesystem::signal_update, array(
- Filesystem::signal_param_path => $this->getHookPath($path),
- Filesystem::signal_param_run => &$run,
- ));
- }
- \OC_Hook::emit(Filesystem::CLASSNAME, Filesystem::signal_write, array(
- Filesystem::signal_param_path => $this->getHookPath($path),
- Filesystem::signal_param_run => &$run,
- ));
- }
-
- /**
- * @param bool $exists
- * @param string $path
- */
- protected function emit_file_hooks_post($exists, $path) {
- if (!$exists) {
- \OC_Hook::emit(Filesystem::CLASSNAME, Filesystem::signal_post_create, array(
- Filesystem::signal_param_path => $this->getHookPath($path),
- ));
- } else {
- \OC_Hook::emit(Filesystem::CLASSNAME, Filesystem::signal_post_update, array(
- Filesystem::signal_param_path => $this->getHookPath($path),
- ));
- }
- \OC_Hook::emit(Filesystem::CLASSNAME, Filesystem::signal_post_write, array(
- Filesystem::signal_param_path => $this->getHookPath($path),
- ));
- }
-
- /**
- * @param string $path
- * @param mixed $data
- * @return bool|mixed
- * @throws \Exception
- */
- public function file_put_contents($path, $data) {
- if (is_resource($data)) { //not having to deal with streams in file_put_contents makes life easier
- $absolutePath = Filesystem::normalizePath($this->getAbsolutePath($path));
- if (Filesystem::isValidPath($path)
- and !Filesystem::isFileBlacklisted($path)
- ) {
- $path = $this->getRelativePath($absolutePath);
-
- $this->lockFile($path, ILockingProvider::LOCK_SHARED);
-
- $exists = $this->file_exists($path);
- $run = true;
- if ($this->shouldEmitHooks($path)) {
- $this->emit_file_hooks_pre($exists, $path, $run);
- }
- if (!$run) {
- $this->unlockFile($path, ILockingProvider::LOCK_SHARED);
- return false;
- }
-
- $this->changeLock($path, ILockingProvider::LOCK_EXCLUSIVE);
-
- /** @var \OC\Files\Storage\Storage $storage */
- list($storage, $internalPath) = $this->resolvePath($path);
- $target = $storage->fopen($internalPath, 'w');
- if ($target) {
- list (, $result) = \OC_Helper::streamCopy($data, $target);
- fclose($target);
- fclose($data);
-
- $this->writeUpdate($storage, $internalPath);
-
- $this->changeLock($path, ILockingProvider::LOCK_SHARED);
-
- if ($this->shouldEmitHooks($path) && $result !== false) {
- $this->emit_file_hooks_post($exists, $path);
- }
- $this->unlockFile($path, ILockingProvider::LOCK_SHARED);
- return $result;
- } else {
- $this->unlockFile($path, ILockingProvider::LOCK_EXCLUSIVE);
- return false;
- }
- } else {
- return false;
- }
- } else {
- $hooks = ($this->file_exists($path)) ? array('update', 'write') : array('create', 'write');
- return $this->basicOperation('file_put_contents', $path, $hooks, $data);
- }
- }
-
- /**
- * @param string $path
- * @return bool|mixed
- */
- public function unlink($path) {
- if ($path === '' || $path === '/') {
- // do not allow deleting the root
- return false;
- }
- $postFix = (substr($path, -1, 1) === '/') ? '/' : '';
- $absolutePath = Filesystem::normalizePath($this->getAbsolutePath($path));
- $mount = Filesystem::getMountManager()->find($absolutePath . $postFix);
- if ($mount and $mount->getInternalPath($absolutePath) === '') {
- return $this->removeMount($mount, $absolutePath);
- }
- return $this->basicOperation('unlink', $path, array('delete'));
- }
-
- /**
- * @param string $directory
- * @return bool|mixed
- */
- public function deleteAll($directory) {
- return $this->rmdir($directory);
- }
-
- /**
- * Rename/move a file or folder from the source path to target path.
- *
- * @param string $path1 source path
- * @param string $path2 target path
- *
- * @return bool|mixed
- */
- public function rename($path1, $path2) {
- $absolutePath1 = Filesystem::normalizePath($this->getAbsolutePath($path1));
- $absolutePath2 = Filesystem::normalizePath($this->getAbsolutePath($path2));
- $result = false;
- if (
- Filesystem::isValidPath($path2)
- and Filesystem::isValidPath($path1)
- and !Filesystem::isFileBlacklisted($path2)
- ) {
- $path1 = $this->getRelativePath($absolutePath1);
- $path2 = $this->getRelativePath($absolutePath2);
- $exists = $this->file_exists($path2);
-
- if ($path1 == null or $path2 == null) {
- return false;
- }
-
- $this->lockFile($path1, ILockingProvider::LOCK_SHARED, true);
- try {
- $this->lockFile($path2, ILockingProvider::LOCK_SHARED, true);
- } catch (LockedException $e) {
- $this->unlockFile($path1, ILockingProvider::LOCK_SHARED);
- throw $e;
- }
-
- $run = true;
- if ($this->shouldEmitHooks($path1) && (Cache\Scanner::isPartialFile($path1) && !Cache\Scanner::isPartialFile($path2))) {
- // if it was a rename from a part file to a regular file it was a write and not a rename operation
- $this->emit_file_hooks_pre($exists, $path2, $run);
- } elseif ($this->shouldEmitHooks($path1)) {
- \OC_Hook::emit(
- Filesystem::CLASSNAME, Filesystem::signal_rename,
- array(
- Filesystem::signal_param_oldpath => $this->getHookPath($path1),
- Filesystem::signal_param_newpath => $this->getHookPath($path2),
- Filesystem::signal_param_run => &$run
- )
- );
- }
- if ($run) {
- $this->verifyPath(dirname($path2), basename($path2));
-
- $manager = Filesystem::getMountManager();
- $mount1 = $this->getMount($path1);
- $mount2 = $this->getMount($path2);
- $storage1 = $mount1->getStorage();
- $storage2 = $mount2->getStorage();
- $internalPath1 = $mount1->getInternalPath($absolutePath1);
- $internalPath2 = $mount2->getInternalPath($absolutePath2);
-
- $this->changeLock($path1, ILockingProvider::LOCK_EXCLUSIVE, true);
- $this->changeLock($path2, ILockingProvider::LOCK_EXCLUSIVE, true);
-
- if ($internalPath1 === '' and $mount1 instanceof MoveableMount) {
- if ($this->isTargetAllowed($absolutePath2)) {
- /**
- * @var \OC\Files\Mount\MountPoint | \OC\Files\Mount\MoveableMount $mount1
- */
- $sourceMountPoint = $mount1->getMountPoint();
- $result = $mount1->moveMount($absolutePath2);
- $manager->moveMount($sourceMountPoint, $mount1->getMountPoint());
- } else {
- $result = false;
- }
- // moving a file/folder within the same mount point
- } elseif ($storage1 == $storage2) {
- if ($storage1) {
- $result = $storage1->rename($internalPath1, $internalPath2);
- } else {
- $result = false;
- }
- // moving a file/folder between storages (from $storage1 to $storage2)
- } else {
- $result = $storage2->moveFromStorage($storage1, $internalPath1, $internalPath2);
- }
-
- if ((Cache\Scanner::isPartialFile($path1) && !Cache\Scanner::isPartialFile($path2)) && $result !== false) {
- // if it was a rename from a part file to a regular file it was a write and not a rename operation
-
- $this->writeUpdate($storage2, $internalPath2);
- } else if ($result) {
- if ($internalPath1 !== '') { // don't do a cache update for moved mounts
- $this->renameUpdate($storage1, $storage2, $internalPath1, $internalPath2);
- }
- }
-
- $this->changeLock($path1, ILockingProvider::LOCK_SHARED, true);
- $this->changeLock($path2, ILockingProvider::LOCK_SHARED, true);
-
- if ((Cache\Scanner::isPartialFile($path1) && !Cache\Scanner::isPartialFile($path2)) && $result !== false) {
- if ($this->shouldEmitHooks()) {
- $this->emit_file_hooks_post($exists, $path2);
- }
- } elseif ($result) {
- if ($this->shouldEmitHooks($path1) and $this->shouldEmitHooks($path2)) {
- \OC_Hook::emit(
- Filesystem::CLASSNAME,
- Filesystem::signal_post_rename,
- array(
- Filesystem::signal_param_oldpath => $this->getHookPath($path1),
- Filesystem::signal_param_newpath => $this->getHookPath($path2)
- )
- );
- }
- }
- }
- $this->unlockFile($path1, ILockingProvider::LOCK_SHARED, true);
- $this->unlockFile($path2, ILockingProvider::LOCK_SHARED, true);
- }
- return $result;
- }
-
- /**
- * Copy a file/folder from the source path to target path
- *
- * @param string $path1 source path
- * @param string $path2 target path
- * @param bool $preserveMtime whether to preserve mtime on the copy
- *
- * @return bool|mixed
- */
- public function copy($path1, $path2, $preserveMtime = false) {
- $absolutePath1 = Filesystem::normalizePath($this->getAbsolutePath($path1));
- $absolutePath2 = Filesystem::normalizePath($this->getAbsolutePath($path2));
- $result = false;
- if (
- Filesystem::isValidPath($path2)
- and Filesystem::isValidPath($path1)
- and !Filesystem::isFileBlacklisted($path2)
- ) {
- $path1 = $this->getRelativePath($absolutePath1);
- $path2 = $this->getRelativePath($absolutePath2);
-
- if ($path1 == null or $path2 == null) {
- return false;
- }
- $run = true;
-
- $this->lockFile($path2, ILockingProvider::LOCK_SHARED);
- $this->lockFile($path1, ILockingProvider::LOCK_SHARED);
- $lockTypePath1 = ILockingProvider::LOCK_SHARED;
- $lockTypePath2 = ILockingProvider::LOCK_SHARED;
-
- try {
-
- $exists = $this->file_exists($path2);
- if ($this->shouldEmitHooks()) {
- \OC_Hook::emit(
- Filesystem::CLASSNAME,
- Filesystem::signal_copy,
- array(
- Filesystem::signal_param_oldpath => $this->getHookPath($path1),
- Filesystem::signal_param_newpath => $this->getHookPath($path2),
- Filesystem::signal_param_run => &$run
- )
- );
- $this->emit_file_hooks_pre($exists, $path2, $run);
- }
- if ($run) {
- $mount1 = $this->getMount($path1);
- $mount2 = $this->getMount($path2);
- $storage1 = $mount1->getStorage();
- $internalPath1 = $mount1->getInternalPath($absolutePath1);
- $storage2 = $mount2->getStorage();
- $internalPath2 = $mount2->getInternalPath($absolutePath2);
-
- $this->changeLock($path2, ILockingProvider::LOCK_EXCLUSIVE);
- $lockTypePath2 = ILockingProvider::LOCK_EXCLUSIVE;
-
- if ($mount1->getMountPoint() == $mount2->getMountPoint()) {
- if ($storage1) {
- $result = $storage1->copy($internalPath1, $internalPath2);
- } else {
- $result = false;
- }
- } else {
- $result = $storage2->copyFromStorage($storage1, $internalPath1, $internalPath2);
- }
-
- $this->writeUpdate($storage2, $internalPath2);
-
- $this->changeLock($path2, ILockingProvider::LOCK_SHARED);
- $lockTypePath2 = ILockingProvider::LOCK_SHARED;
-
- if ($this->shouldEmitHooks() && $result !== false) {
- \OC_Hook::emit(
- Filesystem::CLASSNAME,
- Filesystem::signal_post_copy,
- array(
- Filesystem::signal_param_oldpath => $this->getHookPath($path1),
- Filesystem::signal_param_newpath => $this->getHookPath($path2)
- )
- );
- $this->emit_file_hooks_post($exists, $path2);
- }
-
- }
- } catch (\Exception $e) {
- $this->unlockFile($path2, $lockTypePath2);
- $this->unlockFile($path1, $lockTypePath1);
- throw $e;
- }
-
- $this->unlockFile($path2, $lockTypePath2);
- $this->unlockFile($path1, $lockTypePath1);
-
- }
- return $result;
- }
-
- /**
- * @param string $path
- * @param string $mode
- * @return resource
- */
- public function fopen($path, $mode) {
- $hooks = array();
- switch ($mode) {
- case 'r':
- case 'rb':
- $hooks[] = 'read';
- break;
- case 'r+':
- case 'rb+':
- case 'w+':
- case 'wb+':
- case 'x+':
- case 'xb+':
- case 'a+':
- case 'ab+':
- $hooks[] = 'read';
- $hooks[] = 'write';
- break;
- case 'w':
- case 'wb':
- case 'x':
- case 'xb':
- case 'a':
- case 'ab':
- $hooks[] = 'write';
- break;
- default:
- \OCP\Util::writeLog('core', 'invalid mode (' . $mode . ') for ' . $path, \OCP\Util::ERROR);
- }
-
- return $this->basicOperation('fopen', $path, $hooks, $mode);
- }
-
- /**
- * @param string $path
- * @return bool|string
- * @throws \OCP\Files\InvalidPathException
- */
- public function toTmpFile($path) {
- $this->assertPathLength($path);
- if (Filesystem::isValidPath($path)) {
- $source = $this->fopen($path, 'r');
- if ($source) {
- $extension = pathinfo($path, PATHINFO_EXTENSION);
- $tmpFile = \OC::$server->getTempManager()->getTemporaryFile($extension);
- file_put_contents($tmpFile, $source);
- return $tmpFile;
- } else {
- return false;
- }
- } else {
- return false;
- }
- }
-
- /**
- * @param string $tmpFile
- * @param string $path
- * @return bool|mixed
- * @throws \OCP\Files\InvalidPathException
- */
- public function fromTmpFile($tmpFile, $path) {
- $this->assertPathLength($path);
- if (Filesystem::isValidPath($path)) {
-
- // Get directory that the file is going into
- $filePath = dirname($path);
-
- // Create the directories if any
- if (!$this->file_exists($filePath)) {
- $this->mkdir($filePath);
- }
-
- $source = fopen($tmpFile, 'r');
- if ($source) {
- $result = $this->file_put_contents($path, $source);
- // $this->file_put_contents() might have already closed
- // the resource, so we check it, before trying to close it
- // to avoid messages in the error log.
- if (is_resource($source)) {
- fclose($source);
- }
- unlink($tmpFile);
- return $result;
- } else {
- return false;
- }
- } else {
- return false;
- }
- }
-
-
- /**
- * @param string $path
- * @return mixed
- * @throws \OCP\Files\InvalidPathException
- */
- public function getMimeType($path) {
- $this->assertPathLength($path);
- return $this->basicOperation('getMimeType', $path);
- }
-
- /**
- * @param string $type
- * @param string $path
- * @param bool $raw
- * @return bool|null|string
- */
- public function hash($type, $path, $raw = false) {
- $postFix = (substr($path, -1, 1) === '/') ? '/' : '';
- $absolutePath = Filesystem::normalizePath($this->getAbsolutePath($path));
- if (Filesystem::isValidPath($path)) {
- $path = $this->getRelativePath($absolutePath);
- if ($path == null) {
- return false;
- }
- if ($this->shouldEmitHooks($path)) {
- \OC_Hook::emit(
- Filesystem::CLASSNAME,
- Filesystem::signal_read,
- array(Filesystem::signal_param_path => $this->getHookPath($path))
- );
- }
- list($storage, $internalPath) = Filesystem::resolvePath($absolutePath . $postFix);
- if ($storage) {
- $result = $storage->hash($type, $internalPath, $raw);
- return $result;
- }
- }
- return null;
- }
-
- /**
- * @param string $path
- * @return mixed
- * @throws \OCP\Files\InvalidPathException
- */
- public function free_space($path = '/') {
- $this->assertPathLength($path);
- return $this->basicOperation('free_space', $path);
- }
-
- /**
- * abstraction layer for basic filesystem functions: wrapper for \OC\Files\Storage\Storage
- *
- * @param string $operation
- * @param string $path
- * @param array $hooks (optional)
- * @param mixed $extraParam (optional)
- * @return mixed
- * @throws \Exception
- *
- * This method takes requests for basic filesystem functions (e.g. reading & writing
- * files), processes hooks and proxies, sanitises paths, and finally passes them on to
- * \OC\Files\Storage\Storage for delegation to a storage backend for execution
- */
- private function basicOperation($operation, $path, $hooks = [], $extraParam = null) {
- $postFix = (substr($path, -1, 1) === '/') ? '/' : '';
- $absolutePath = Filesystem::normalizePath($this->getAbsolutePath($path));
- if (Filesystem::isValidPath($path)
- and !Filesystem::isFileBlacklisted($path)
- ) {
- $path = $this->getRelativePath($absolutePath);
- if ($path == null) {
- return false;
- }
-
- if (in_array('write', $hooks) || in_array('delete', $hooks) || in_array('read', $hooks)) {
- // always a shared lock during pre-hooks so the hook can read the file
- $this->lockFile($path, ILockingProvider::LOCK_SHARED);
- }
-
- $run = $this->runHooks($hooks, $path);
- /** @var \OC\Files\Storage\Storage $storage */
- list($storage, $internalPath) = Filesystem::resolvePath($absolutePath . $postFix);
- if ($run and $storage) {
- if (in_array('write', $hooks) || in_array('delete', $hooks)) {
- $this->changeLock($path, ILockingProvider::LOCK_EXCLUSIVE);
- }
- try {
- if (!is_null($extraParam)) {
- $result = $storage->$operation($internalPath, $extraParam);
- } else {
- $result = $storage->$operation($internalPath);
- }
- } catch (\Exception $e) {
- if (in_array('write', $hooks) || in_array('delete', $hooks)) {
- $this->unlockFile($path, ILockingProvider::LOCK_EXCLUSIVE);
- } else if (in_array('read', $hooks)) {
- $this->unlockFile($path, ILockingProvider::LOCK_SHARED);
- }
- throw $e;
- }
-
- if (in_array('delete', $hooks) and $result) {
- $this->removeUpdate($storage, $internalPath);
- }
- if (in_array('write', $hooks) and $operation !== 'fopen') {
- $this->writeUpdate($storage, $internalPath);
- }
- if (in_array('touch', $hooks)) {
- $this->writeUpdate($storage, $internalPath, $extraParam);
- }
-
- if ((in_array('write', $hooks) || in_array('delete', $hooks)) && ($operation !== 'fopen' || $result === false)) {
- $this->changeLock($path, ILockingProvider::LOCK_SHARED);
- }
-
- $unlockLater = false;
- if ($this->lockingEnabled && $operation === 'fopen' && is_resource($result)) {
- $unlockLater = true;
- $result = CallbackWrapper::wrap($result, null, null, function () use ($hooks, $path) {
- if (in_array('write', $hooks)) {
- $this->unlockFile($path, ILockingProvider::LOCK_EXCLUSIVE);
- } else if (in_array('read', $hooks)) {
- $this->unlockFile($path, ILockingProvider::LOCK_SHARED);
- }
- });
- }
-
- if ($this->shouldEmitHooks($path) && $result !== false) {
- if ($operation != 'fopen') { //no post hooks for fopen, the file stream is still open
- $this->runHooks($hooks, $path, true);
- }
- }
-
- if (!$unlockLater
- && (in_array('write', $hooks) || in_array('delete', $hooks) || in_array('read', $hooks))
- ) {
- $this->unlockFile($path, ILockingProvider::LOCK_SHARED);
- }
- return $result;
- } else {
- $this->unlockFile($path, ILockingProvider::LOCK_SHARED);
- }
- }
- return null;
- }
-
- /**
- * get the path relative to the default root for hook usage
- *
- * @param string $path
- * @return string
- */
- private function getHookPath($path) {
- if (!Filesystem::getView()) {
- return $path;
- }
- return Filesystem::getView()->getRelativePath($this->getAbsolutePath($path));
- }
-
- private function shouldEmitHooks($path = '') {
- if ($path && Cache\Scanner::isPartialFile($path)) {
- return false;
- }
- if (!Filesystem::$loaded) {
- return false;
- }
- $defaultRoot = Filesystem::getRoot();
- if ($defaultRoot === null) {
- return false;
- }
- if ($this->fakeRoot === $defaultRoot) {
- return true;
- }
- $fullPath = $this->getAbsolutePath($path);
-
- if ($fullPath === $defaultRoot) {
- return true;
- }
-
- return (strlen($fullPath) > strlen($defaultRoot)) && (substr($fullPath, 0, strlen($defaultRoot) + 1) === $defaultRoot . '/');
- }
-
- /**
- * @param string[] $hooks
- * @param string $path
- * @param bool $post
- * @return bool
- */
- private function runHooks($hooks, $path, $post = false) {
- $relativePath = $path;
- $path = $this->getHookPath($path);
- $prefix = ($post) ? 'post_' : '';
- $run = true;
- if ($this->shouldEmitHooks($relativePath)) {
- foreach ($hooks as $hook) {
- if ($hook != 'read') {
- \OC_Hook::emit(
- Filesystem::CLASSNAME,
- $prefix . $hook,
- array(
- Filesystem::signal_param_run => &$run,
- Filesystem::signal_param_path => $path
- )
- );
- } elseif (!$post) {
- \OC_Hook::emit(
- Filesystem::CLASSNAME,
- $prefix . $hook,
- array(
- Filesystem::signal_param_path => $path
- )
- );
- }
- }
- }
- return $run;
- }
-
- /**
- * 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->basicOperation('hasUpdated', $path, array(), $time);
- }
-
- /**
- * @param string $ownerId
- * @return \OC\User\User
- */
- private function getUserObjectForOwner($ownerId) {
- $owner = $this->userManager->get($ownerId);
- if ($owner instanceof IUser) {
- return $owner;
- } else {
- return new User($ownerId, null);
- }
- }
-
- /**
- * Get file info from cache
- *
- * If the file is not in cached it will be scanned
- * If the file has changed on storage the cache will be updated
- *
- * @param \OC\Files\Storage\Storage $storage
- * @param string $internalPath
- * @param string $relativePath
- * @return array|bool
- */
- private function getCacheEntry($storage, $internalPath, $relativePath) {
- $cache = $storage->getCache($internalPath);
- $data = $cache->get($internalPath);
- $watcher = $storage->getWatcher($internalPath);
-
- try {
- // if the file is not in the cache or needs to be updated, trigger the scanner and reload the data
- if (!$data || $data['size'] === -1) {
- $this->lockFile($relativePath, ILockingProvider::LOCK_SHARED);
- if (!$storage->file_exists($internalPath)) {
- $this->unlockFile($relativePath, ILockingProvider::LOCK_SHARED);
- return false;
- }
- $scanner = $storage->getScanner($internalPath);
- $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW);
- $data = $cache->get($internalPath);
- $this->unlockFile($relativePath, ILockingProvider::LOCK_SHARED);
- } else if (!Cache\Scanner::isPartialFile($internalPath) && $watcher->needsUpdate($internalPath, $data)) {
- $this->lockFile($relativePath, ILockingProvider::LOCK_SHARED);
- $watcher->update($internalPath, $data);
- $storage->getPropagator()->propagateChange($internalPath, time());
- $data = $cache->get($internalPath);
- $this->unlockFile($relativePath, ILockingProvider::LOCK_SHARED);
- }
- } catch (LockedException $e) {
- // if the file is locked we just use the old cache info
- }
-
- return $data;
- }
-
- /**
- * get the filesystem info
- *
- * @param string $path
- * @param boolean|string $includeMountPoints true to add mountpoint sizes,
- * 'ext' to add only ext storage mount point sizes. Defaults to true.
- * defaults to true
- * @return \OC\Files\FileInfo|false False if file does not exist
- */
- public function getFileInfo($path, $includeMountPoints = true) {
- $this->assertPathLength($path);
- if (!Filesystem::isValidPath($path)) {
- return false;
- }
- if (Cache\Scanner::isPartialFile($path)) {
- return $this->getPartFileInfo($path);
- }
- $relativePath = $path;
- $path = Filesystem::normalizePath($this->fakeRoot . '/' . $path);
-
- $mount = Filesystem::getMountManager()->find($path);
- $storage = $mount->getStorage();
- $internalPath = $mount->getInternalPath($path);
- if ($storage) {
- $data = $this->getCacheEntry($storage, $internalPath, $relativePath);
-
- if (!$data instanceof ICacheEntry) {
- return false;
- }
-
- if ($mount instanceof MoveableMount && $internalPath === '') {
- $data['permissions'] |= \OCP\Constants::PERMISSION_DELETE;
- }
-
- $owner = $this->getUserObjectForOwner($storage->getOwner($internalPath));
- $info = new FileInfo($path, $storage, $internalPath, $data, $mount, $owner);
-
- if ($data and isset($data['fileid'])) {
- if ($includeMountPoints and $data['mimetype'] === 'httpd/unix-directory') {
- //add the sizes of other mount points to the folder
- $extOnly = ($includeMountPoints === 'ext');
- $mounts = Filesystem::getMountManager()->findIn($path);
- foreach ($mounts as $mount) {
- $subStorage = $mount->getStorage();
- if ($subStorage) {
- // exclude shared storage ?
- if ($extOnly && $subStorage instanceof \OC\Files\Storage\Shared) {
- continue;
- }
- $subCache = $subStorage->getCache('');
- $rootEntry = $subCache->get('');
- $info->addSubEntry($rootEntry, $mount->getMountPoint());
- }
- }
- }
- }
-
- return $info;
- }
-
- return false;
- }
-
- /**
- * get the content of a directory
- *
- * @param string $directory path under datadirectory
- * @param string $mimetype_filter limit returned content to this mimetype or mimepart
- * @return FileInfo[]
- */
- public function getDirectoryContent($directory, $mimetype_filter = '') {
- $this->assertPathLength($directory);
- if (!Filesystem::isValidPath($directory)) {
- return [];
- }
- $path = $this->getAbsolutePath($directory);
- $path = Filesystem::normalizePath($path);
- $mount = $this->getMount($directory);
- $storage = $mount->getStorage();
- $internalPath = $mount->getInternalPath($path);
- if ($storage) {
- $cache = $storage->getCache($internalPath);
- $user = \OC_User::getUser();
-
- $data = $this->getCacheEntry($storage, $internalPath, $directory);
-
- if (!$data instanceof ICacheEntry || !isset($data['fileid']) || !($data->getPermissions() && Constants::PERMISSION_READ)) {
- return [];
- }
-
- $folderId = $data['fileid'];
- $contents = $cache->getFolderContentsById($folderId); //TODO: mimetype_filter
-
- $sharingDisabled = \OCP\Util::isSharingDisabledForUser();
- /**
- * @var \OC\Files\FileInfo[] $files
- */
- $files = array_map(function (ICacheEntry $content) use ($path, $storage, $mount, $sharingDisabled) {
- if ($sharingDisabled) {
- $content['permissions'] = $content['permissions'] & ~\OCP\Constants::PERMISSION_SHARE;
- }
- $owner = $this->getUserObjectForOwner($storage->getOwner($content['path']));
- return new FileInfo($path . '/' . $content['name'], $storage, $content['path'], $content, $mount, $owner);
- }, $contents);
-
- //add a folder for any mountpoint in this directory and add the sizes of other mountpoints to the folders
- $mounts = Filesystem::getMountManager()->findIn($path);
- $dirLength = strlen($path);
- foreach ($mounts as $mount) {
- $mountPoint = $mount->getMountPoint();
- $subStorage = $mount->getStorage();
- if ($subStorage) {
- $subCache = $subStorage->getCache('');
-
- $rootEntry = $subCache->get('');
- if (!$rootEntry) {
- $subScanner = $subStorage->getScanner('');
- try {
- $subScanner->scanFile('');
- } catch (\OCP\Files\StorageNotAvailableException $e) {
- continue;
- } catch (\OCP\Files\StorageInvalidException $e) {
- continue;
- } catch (\Exception $e) {
- // sometimes when the storage is not available it can be any exception
- \OCP\Util::writeLog(
- 'core',
- 'Exception while scanning storage "' . $subStorage->getId() . '": ' .
- get_class($e) . ': ' . $e->getMessage(),
- \OCP\Util::ERROR
- );
- continue;
- }
- $rootEntry = $subCache->get('');
- }
-
- if ($rootEntry && ($rootEntry->getPermissions() && Constants::PERMISSION_READ)) {
- $relativePath = trim(substr($mountPoint, $dirLength), '/');
- if ($pos = strpos($relativePath, '/')) {
- //mountpoint inside subfolder add size to the correct folder
- $entryName = substr($relativePath, 0, $pos);
- foreach ($files as &$entry) {
- if ($entry->getName() === $entryName) {
- $entry->addSubEntry($rootEntry, $mountPoint);
- }
- }
- } else { //mountpoint in this folder, add an entry for it
- $rootEntry['name'] = $relativePath;
- $rootEntry['type'] = $rootEntry['mimetype'] === 'httpd/unix-directory' ? 'dir' : 'file';
- $permissions = $rootEntry['permissions'];
- // do not allow renaming/deleting the mount point if they are not shared files/folders
- // for shared files/folders we use the permissions given by the owner
- if ($mount instanceof MoveableMount) {
- $rootEntry['permissions'] = $permissions | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE;
- } else {
- $rootEntry['permissions'] = $permissions & (\OCP\Constants::PERMISSION_ALL - (\OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE));
- }
-
- //remove any existing entry with the same name
- foreach ($files as $i => $file) {
- if ($file['name'] === $rootEntry['name']) {
- unset($files[$i]);
- break;
- }
- }
- $rootEntry['path'] = substr(Filesystem::normalizePath($path . '/' . $rootEntry['name']), strlen($user) + 2); // full path without /$user/
-
- // if sharing was disabled for the user we remove the share permissions
- if (\OCP\Util::isSharingDisabledForUser()) {
- $rootEntry['permissions'] = $rootEntry['permissions'] & ~\OCP\Constants::PERMISSION_SHARE;
- }
-
- $owner = $this->getUserObjectForOwner($subStorage->getOwner(''));
- $files[] = new FileInfo($path . '/' . $rootEntry['name'], $subStorage, '', $rootEntry, $mount, $owner);
- }
- }
- }
- }
-
- if ($mimetype_filter) {
- $files = array_filter($files, function (FileInfo $file) use ($mimetype_filter) {
- if (strpos($mimetype_filter, '/')) {
- return $file->getMimetype() === $mimetype_filter;
- } else {
- return $file->getMimePart() === $mimetype_filter;
- }
- });
- }
-
- return $files;
- } else {
- return [];
- }
- }
-
- /**
- * change file metadata
- *
- * @param string $path
- * @param array|\OCP\Files\FileInfo $data
- * @return int
- *
- * returns the fileid of the updated file
- */
- public function putFileInfo($path, $data) {
- $this->assertPathLength($path);
- if ($data instanceof FileInfo) {
- $data = $data->getData();
- }
- $path = Filesystem::normalizePath($this->fakeRoot . '/' . $path);
- /**
- * @var \OC\Files\Storage\Storage $storage
- * @var string $internalPath
- */
- list($storage, $internalPath) = Filesystem::resolvePath($path);
- if ($storage) {
- $cache = $storage->getCache($path);
-
- if (!$cache->inCache($internalPath)) {
- $scanner = $storage->getScanner($internalPath);
- $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW);
- }
-
- return $cache->put($internalPath, $data);
- } else {
- return -1;
- }
- }
-
- /**
- * search for files with the name matching $query
- *
- * @param string $query
- * @return FileInfo[]
- */
- public function search($query) {
- return $this->searchCommon('search', array('%' . $query . '%'));
- }
-
- /**
- * search for files with the name matching $query
- *
- * @param string $query
- * @return FileInfo[]
- */
- public function searchRaw($query) {
- return $this->searchCommon('search', array($query));
- }
-
- /**
- * search for files by mimetype
- *
- * @param string $mimetype
- * @return FileInfo[]
- */
- public function searchByMime($mimetype) {
- return $this->searchCommon('searchByMime', array($mimetype));
- }
-
- /**
- * search for files by tag
- *
- * @param string|int $tag name or tag id
- * @param string $userId owner of the tags
- * @return FileInfo[]
- */
- public function searchByTag($tag, $userId) {
- return $this->searchCommon('searchByTag', array($tag, $userId));
- }
-
- /**
- * @param string $method cache method
- * @param array $args
- * @return FileInfo[]
- */
- private function searchCommon($method, $args) {
- $files = array();
- $rootLength = strlen($this->fakeRoot);
-
- $mount = $this->getMount('');
- $mountPoint = $mount->getMountPoint();
- $storage = $mount->getStorage();
- if ($storage) {
- $cache = $storage->getCache('');
-
- $results = call_user_func_array(array($cache, $method), $args);
- foreach ($results as $result) {
- if (substr($mountPoint . $result['path'], 0, $rootLength + 1) === $this->fakeRoot . '/') {
- $internalPath = $result['path'];
- $path = $mountPoint . $result['path'];
- $result['path'] = substr($mountPoint . $result['path'], $rootLength);
- $owner = \OC::$server->getUserManager()->get($storage->getOwner($internalPath));
- $files[] = new FileInfo($path, $storage, $internalPath, $result, $mount, $owner);
- }
- }
-
- $mounts = Filesystem::getMountManager()->findIn($this->fakeRoot);
- foreach ($mounts as $mount) {
- $mountPoint = $mount->getMountPoint();
- $storage = $mount->getStorage();
- if ($storage) {
- $cache = $storage->getCache('');
-
- $relativeMountPoint = substr($mountPoint, $rootLength);
- $results = call_user_func_array(array($cache, $method), $args);
- if ($results) {
- foreach ($results as $result) {
- $internalPath = $result['path'];
- $result['path'] = rtrim($relativeMountPoint . $result['path'], '/');
- $path = rtrim($mountPoint . $internalPath, '/');
- $owner = \OC::$server->getUserManager()->get($storage->getOwner($internalPath));
- $files[] = new FileInfo($path, $storage, $internalPath, $result, $mount, $owner);
- }
- }
- }
- }
- }
- return $files;
- }
-
- /**
- * Get the owner for a file or folder
- *
- * @param string $path
- * @return string the user id of the owner
- * @throws NotFoundException
- */
- public function getOwner($path) {
- $info = $this->getFileInfo($path);
- if (!$info) {
- throw new NotFoundException($path . ' not found while trying to get owner');
- }
- return $info->getOwner()->getUID();
- }
-
- /**
- * get the ETag for a file or folder
- *
- * @param string $path
- * @return string
- */
- public function getETag($path) {
- /**
- * @var Storage\Storage $storage
- * @var string $internalPath
- */
- list($storage, $internalPath) = $this->resolvePath($path);
- if ($storage) {
- return $storage->getETag($internalPath);
- } else {
- return null;
- }
- }
-
- /**
- * Get the path of a file by id, relative to the view
- *
- * Note that the resulting path is not guarantied to be unique for the id, multiple paths can point to the same file
- *
- * @param int $id
- * @throws NotFoundException
- * @return string
- */
- public function getPath($id) {
- $id = (int)$id;
- $manager = Filesystem::getMountManager();
- $mounts = $manager->findIn($this->fakeRoot);
- $mounts[] = $manager->find($this->fakeRoot);
- // reverse the array so we start with the storage this view is in
- // which is the most likely to contain the file we're looking for
- $mounts = array_reverse($mounts);
- foreach ($mounts as $mount) {
- /**
- * @var \OC\Files\Mount\MountPoint $mount
- */
- if ($mount->getStorage()) {
- $cache = $mount->getStorage()->getCache();
- $internalPath = $cache->getPathById($id);
- if (is_string($internalPath)) {
- $fullPath = $mount->getMountPoint() . $internalPath;
- if (!is_null($path = $this->getRelativePath($fullPath))) {
- return $path;
- }
- }
- }
- }
- throw new NotFoundException(sprintf('File with id "%s" has not been found.', $id));
- }
-
- /**
- * @param string $path
- * @throws InvalidPathException
- */
- private function assertPathLength($path) {
- $maxLen = min(PHP_MAXPATHLEN, 4000);
- // Check for the string length - performed using isset() instead of strlen()
- // because isset() is about 5x-40x faster.
- if (isset($path[$maxLen])) {
- $pathLen = strlen($path);
- throw new \OCP\Files\InvalidPathException("Path length($pathLen) exceeds max path length($maxLen): $path");
- }
- }
-
- /**
- * check if it is allowed to move a mount point to a given target.
- * It is not allowed to move a mount point into a different mount point or
- * into an already shared folder
- *
- * @param string $target path
- * @return boolean
- */
- private function isTargetAllowed($target) {
-
- list($targetStorage, $targetInternalPath) = \OC\Files\Filesystem::resolvePath($target);
- if (!$targetStorage->instanceOfStorage('\OCP\Files\IHomeStorage')) {
- \OCP\Util::writeLog('files',
- 'It is not allowed to move one mount point into another one',
- \OCP\Util::DEBUG);
- return false;
- }
-
- // note: cannot use the view because the target is already locked
- $fileId = (int)$targetStorage->getCache()->getId($targetInternalPath);
- if ($fileId === -1) {
- // target might not exist, need to check parent instead
- $fileId = (int)$targetStorage->getCache()->getId(dirname($targetInternalPath));
- }
-
- // check if any of the parents were shared by the current owner (include collections)
- $shares = \OCP\Share::getItemShared(
- 'folder',
- $fileId,
- \OCP\Share::FORMAT_NONE,
- null,
- true
- );
-
- if (count($shares) > 0) {
- \OCP\Util::writeLog('files',
- 'It is not allowed to move one mount point into a shared folder',
- \OCP\Util::DEBUG);
- return false;
- }
-
- return true;
- }
-
- /**
- * Get a fileinfo object for files that are ignored in the cache (part files)
- *
- * @param string $path
- * @return \OCP\Files\FileInfo
- */
- private function getPartFileInfo($path) {
- $mount = $this->getMount($path);
- $storage = $mount->getStorage();
- $internalPath = $mount->getInternalPath($this->getAbsolutePath($path));
- $owner = \OC::$server->getUserManager()->get($storage->getOwner($internalPath));
- return new FileInfo(
- $this->getAbsolutePath($path),
- $storage,
- $internalPath,
- [
- 'fileid' => null,
- 'mimetype' => $storage->getMimeType($internalPath),
- 'name' => basename($path),
- 'etag' => null,
- 'size' => $storage->filesize($internalPath),
- 'mtime' => $storage->filemtime($internalPath),
- 'encrypted' => false,
- 'permissions' => \OCP\Constants::PERMISSION_ALL
- ],
- $mount,
- $owner
- );
- }
-
- /**
- * @param string $path
- * @param string $fileName
- * @throws InvalidPathException
- */
- public function verifyPath($path, $fileName) {
-
- $l10n = \OC::$server->getL10N('lib');
-
- // verify empty and dot files
- $trimmed = trim($fileName);
- if ($trimmed === '') {
- throw new InvalidPathException($l10n->t('Empty filename is not allowed'));
- }
- if (\OC\Files\Filesystem::isIgnoredDir($trimmed)) {
- throw new InvalidPathException($l10n->t('Dot files are not allowed'));
- }
-
- // verify database - e.g. mysql only 3-byte chars
- if (preg_match('%(?:
- \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3
- | [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15
- | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16
-)%xs', $fileName)) {
- throw new InvalidPathException($l10n->t('4-byte characters are not supported in file names'));
- }
-
- try {
- /** @type \OCP\Files\Storage $storage */
- list($storage, $internalPath) = $this->resolvePath($path);
- $storage->verifyPath($internalPath, $fileName);
- } catch (ReservedWordException $ex) {
- throw new InvalidPathException($l10n->t('File name is a reserved word'));
- } catch (InvalidCharacterInPathException $ex) {
- throw new InvalidPathException($l10n->t('File name contains at least one invalid character'));
- } catch (FileNameTooLongException $ex) {
- throw new InvalidPathException($l10n->t('File name is too long'));
- }
- }
-
- /**
- * get all parent folders of $path
- *
- * @param string $path
- * @return string[]
- */
- private function getParents($path) {
- $path = trim($path, '/');
- if (!$path) {
- return [];
- }
-
- $parts = explode('/', $path);
-
- // remove the single file
- array_pop($parts);
- $result = array('/');
- $resultPath = '';
- foreach ($parts as $part) {
- if ($part) {
- $resultPath .= '/' . $part;
- $result[] = $resultPath;
- }
- }
- return $result;
- }
-
- /**
- * Returns the mount point for which to lock
- *
- * @param string $absolutePath absolute path
- * @param bool $useParentMount true to return parent mount instead of whatever
- * is mounted directly on the given path, false otherwise
- * @return \OC\Files\Mount\MountPoint mount point for which to apply locks
- */
- private function getMountForLock($absolutePath, $useParentMount = false) {
- $results = [];
- $mount = Filesystem::getMountManager()->find($absolutePath);
- if (!$mount) {
- return $results;
- }
-
- if ($useParentMount) {
- // find out if something is mounted directly on the path
- $internalPath = $mount->getInternalPath($absolutePath);
- if ($internalPath === '') {
- // resolve the parent mount instead
- $mount = Filesystem::getMountManager()->find(dirname($absolutePath));
- }
- }
-
- return $mount;
- }
-
- /**
- * Lock the given path
- *
- * @param string $path the path of the file to lock, relative to the view
- * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
- * @param bool $lockMountPoint true to lock the mount point, false to lock the attached mount/storage
- *
- * @return bool False if the path is excluded from locking, true otherwise
- * @throws \OCP\Lock\LockedException if the path is already locked
- */
- private function lockPath($path, $type, $lockMountPoint = false) {
- $absolutePath = $this->getAbsolutePath($path);
- $absolutePath = Filesystem::normalizePath($absolutePath);
- if (!$this->shouldLockFile($absolutePath)) {
- return false;
- }
-
- $mount = $this->getMountForLock($absolutePath, $lockMountPoint);
- if ($mount) {
- try {
- $storage = $mount->getStorage();
- if ($storage->instanceOfStorage('\OCP\Files\Storage\ILockingStorage')) {
- $storage->acquireLock(
- $mount->getInternalPath($absolutePath),
- $type,
- $this->lockingProvider
- );
- }
- } catch (\OCP\Lock\LockedException $e) {
- // rethrow with the a human-readable path
- throw new \OCP\Lock\LockedException(
- $this->getPathRelativeToFiles($absolutePath),
- $e
- );
- }
- }
-
- return true;
- }
-
- /**
- * Change the lock type
- *
- * @param string $path the path of the file to lock, relative to the view
- * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
- * @param bool $lockMountPoint true to lock the mount point, false to lock the attached mount/storage
- *
- * @return bool False if the path is excluded from locking, true otherwise
- * @throws \OCP\Lock\LockedException if the path is already locked
- */
- public function changeLock($path, $type, $lockMountPoint = false) {
- $path = Filesystem::normalizePath($path);
- $absolutePath = $this->getAbsolutePath($path);
- $absolutePath = Filesystem::normalizePath($absolutePath);
- if (!$this->shouldLockFile($absolutePath)) {
- return false;
- }
-
- $mount = $this->getMountForLock($absolutePath, $lockMountPoint);
- if ($mount) {
- try {
- $storage = $mount->getStorage();
- if ($storage->instanceOfStorage('\OCP\Files\Storage\ILockingStorage')) {
- $storage->changeLock(
- $mount->getInternalPath($absolutePath),
- $type,
- $this->lockingProvider
- );
- }
- } catch (\OCP\Lock\LockedException $e) {
- // rethrow with the a human-readable path
- throw new \OCP\Lock\LockedException(
- $this->getPathRelativeToFiles($absolutePath),
- $e
- );
- }
- }
-
- return true;
- }
-
- /**
- * Unlock the given path
- *
- * @param string $path the path of the file to unlock, relative to the view
- * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
- * @param bool $lockMountPoint true to lock the mount point, false to lock the attached mount/storage
- *
- * @return bool False if the path is excluded from locking, true otherwise
- */
- private function unlockPath($path, $type, $lockMountPoint = false) {
- $absolutePath = $this->getAbsolutePath($path);
- $absolutePath = Filesystem::normalizePath($absolutePath);
- if (!$this->shouldLockFile($absolutePath)) {
- return false;
- }
-
- $mount = $this->getMountForLock($absolutePath, $lockMountPoint);
- if ($mount) {
- $storage = $mount->getStorage();
- if ($storage->instanceOfStorage('\OCP\Files\Storage\ILockingStorage')) {
- $storage->releaseLock(
- $mount->getInternalPath($absolutePath),
- $type,
- $this->lockingProvider
- );
- }
- }
-
- return true;
- }
-
- /**
- * Lock a path and all its parents up to the root of the view
- *
- * @param string $path the path of the file to lock relative to the view
- * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
- * @param bool $lockMountPoint true to lock the mount point, false to lock the attached mount/storage
- *
- * @return bool False if the path is excluded from locking, true otherwise
- */
- public function lockFile($path, $type, $lockMountPoint = false) {
- $absolutePath = $this->getAbsolutePath($path);
- $absolutePath = Filesystem::normalizePath($absolutePath);
- if (!$this->shouldLockFile($absolutePath)) {
- return false;
- }
-
- $this->lockPath($path, $type, $lockMountPoint);
-
- $parents = $this->getParents($path);
- foreach ($parents as $parent) {
- $this->lockPath($parent, ILockingProvider::LOCK_SHARED);
- }
-
- return true;
- }
-
- /**
- * Unlock a path and all its parents up to the root of the view
- *
- * @param string $path the path of the file to lock relative to the view
- * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
- * @param bool $lockMountPoint true to lock the mount point, false to lock the attached mount/storage
- *
- * @return bool False if the path is excluded from locking, true otherwise
- */
- public function unlockFile($path, $type, $lockMountPoint = false) {
- $absolutePath = $this->getAbsolutePath($path);
- $absolutePath = Filesystem::normalizePath($absolutePath);
- if (!$this->shouldLockFile($absolutePath)) {
- return false;
- }
-
- $this->unlockPath($path, $type, $lockMountPoint);
-
- $parents = $this->getParents($path);
- foreach ($parents as $parent) {
- $this->unlockPath($parent, ILockingProvider::LOCK_SHARED);
- }
-
- return true;
- }
-
- /**
- * Only lock files in data/user/files/
- *
- * @param string $path Absolute path to the file/folder we try to (un)lock
- * @return bool
- */
- protected function shouldLockFile($path) {
- $path = Filesystem::normalizePath($path);
-
- $pathSegments = explode('/', $path);
- if (isset($pathSegments[2])) {
- // E.g.: /username/files/path-to-file
- return ($pathSegments[2] === 'files') && (count($pathSegments) > 3);
- }
-
- return true;
- }
-
- /**
- * Shortens the given absolute path to be relative to
- * "$user/files".
- *
- * @param string $absolutePath absolute path which is under "files"
- *
- * @return string path relative to "files" with trimmed slashes or null
- * if the path was NOT relative to files
- *
- * @throws \InvalidArgumentException if the given path was not under "files"
- * @since 8.1.0
- */
- public function getPathRelativeToFiles($absolutePath) {
- $path = Filesystem::normalizePath($absolutePath);
- $parts = explode('/', trim($path, '/'), 3);
- // "$user", "files", "path/to/dir"
- if (!isset($parts[1]) || $parts[1] !== 'files') {
- throw new \InvalidArgumentException('$absolutePath must be relative to "files"');
- }
- if (isset($parts[2])) {
- return $parts[2];
- }
- return '';
- }
-
- /**
- * @param string $filename
- * @return array
- * @throws \OC\User\NoUserException
- * @throws NotFoundException
- */
- public function getUidAndFilename($filename) {
- $info = $this->getFileInfo($filename);
- if (!$info instanceof \OCP\Files\FileInfo) {
- throw new NotFoundException($this->getAbsolutePath($filename) . ' not found');
- }
- $uid = $info->getOwner()->getUID();
- if ($uid != \OCP\User::getUser()) {
- Filesystem::initMountPoints($uid);
- $ownerView = new View('/' . $uid . '/files');
- try {
- $filename = $ownerView->getPath($info['fileid']);
- } catch (NotFoundException $e) {
- throw new NotFoundException('File with id ' . $info['fileid'] . ' not found for user ' . $uid);
- }
- }
- return [$uid, $filename];
- }
-}