aboutsummaryrefslogtreecommitdiffstats
path: root/lib/files
diff options
context:
space:
mode:
authorRobin Appelman <icewind@owncloud.com>2013-06-07 17:12:16 +0200
committerRobin Appelman <icewind@owncloud.com>2013-06-07 17:12:16 +0200
commitf35578ec54b5ce4133e668625d6a7a34bfc6b1e9 (patch)
tree6a603a3e0f2c5637529f64c90750d78e9e3e9c4f /lib/files
parentbd675124096707a925faac2774516975ec7049c1 (diff)
parent81b6cab94fcaa5c3bc76a92d38997cd7928cb37d (diff)
downloadnextcloud-server-f35578ec54b5ce4133e668625d6a7a34bfc6b1e9.tar.gz
nextcloud-server-f35578ec54b5ce4133e668625d6a7a34bfc6b1e9.zip
merge master into storage-wrapper
Diffstat (limited to 'lib/files')
-rw-r--r--lib/files/cache/backgroundwatcher.php4
-rw-r--r--lib/files/cache/cache.php83
-rw-r--r--lib/files/cache/permissions.php20
-rw-r--r--lib/files/cache/scanner.php44
-rw-r--r--lib/files/cache/updater.php9
-rw-r--r--lib/files/cache/watcher.php2
-rw-r--r--lib/files/filesystem.php52
-rw-r--r--lib/files/storage/common.php18
-rw-r--r--lib/files/view.php74
9 files changed, 227 insertions, 79 deletions
diff --git a/lib/files/cache/backgroundwatcher.php b/lib/files/cache/backgroundwatcher.php
index 7549745e7d7..8933101577d 100644
--- a/lib/files/cache/backgroundwatcher.php
+++ b/lib/files/cache/backgroundwatcher.php
@@ -30,7 +30,7 @@ class BackgroundWatcher {
return;
}
list($storageId, $internalPath) = $cacheItem;
- $mounts = Mount::findByStorageId($storageId);
+ $mounts = Filesystem::getMountByStorageId($storageId);
if (count($mounts) === 0) {
//if the storage we need isn't mounted on default, try to find a user that has access to the storage
@@ -40,7 +40,7 @@ class BackgroundWatcher {
return;
}
Filesystem::initMountPoints($users[0]);
- $mounts = Mount::findByStorageId($storageId);
+ $mounts = Filesystem::getMountByStorageId($storageId);
if (count($mounts) === 0) {
return;
}
diff --git a/lib/files/cache/cache.php b/lib/files/cache/cache.php
index 8f5c9643bef..cae2e63e4dc 100644
--- a/lib/files/cache/cache.php
+++ b/lib/files/cache/cache.php
@@ -100,6 +100,9 @@ class 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
@@ -107,7 +110,7 @@ class Cache {
$params = array($file);
}
$query = \OC_DB::prepare(
- 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted`, `etag`
+ 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `storage_mtime`, `encrypted`, `unencrypted_size`, `etag`
FROM `*PREFIX*filecache` ' . $where);
$result = $query->execute($params);
$data = $result->fetchRow();
@@ -123,9 +126,13 @@ class Cache {
$data['size'] = (int)$data['size'];
$data['mtime'] = (int)$data['mtime'];
$data['encrypted'] = (bool)$data['encrypted'];
+ $data['unencrypted_size'] = (int)$data['unencrypted_size'];
$data['storage'] = $this->storageId;
$data['mimetype'] = $this->getMimetype($data['mimetype']);
$data['mimepart'] = $this->getMimetype($data['mimepart']);
+ if ($data['storage_mtime'] == 0) {
+ $data['storage_mtime'] = $data['mtime'];
+ }
}
return $data;
@@ -141,13 +148,20 @@ class Cache {
$fileId = $this->getId($folder);
if ($fileId > -1) {
$query = \OC_DB::prepare(
- 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted`, `etag`
- FROM `*PREFIX*filecache` WHERE parent = ? ORDER BY `name` ASC');
+ 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `storage_mtime`, `encrypted`, `unencrypted_size`, `etag`
+ FROM `*PREFIX*filecache` WHERE `parent` = ? ORDER BY `name` ASC');
+
$result = $query->execute(array($fileId));
+ if (\OC_DB::isError($result)) {
+ \OCP\Util::writeLog('cache', 'getFolderContents failed: ' . $result->getMessage(), \OCP\Util::ERROR);
+ }
$files = $result->fetchAll();
foreach ($files as &$file) {
$file['mimetype'] = $this->getMimetype($file['mimetype']);
$file['mimepart'] = $this->getMimetype($file['mimepart']);
+ if ($file['storage_mtime'] == 0) {
+ $file['storage_mtime'] = $file['mtime'];
+ }
}
return $files;
} else {
@@ -168,6 +182,9 @@ class Cache {
$this->update($id, $data);
return $id;
} else {
+ // 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]);
@@ -195,7 +212,7 @@ class Cache {
. ' VALUES(' . implode(', ', $valuesPlaceholder) . ')');
$result = $query->execute($params);
if (\OC_DB::isError($result)) {
- \OCP\Util::writeLog('cache', 'Insert to cache failed: ' . $result, \OCP\Util::ERROR);
+ \OCP\Util::writeLog('cache', 'Insert to cache failed: ' . $result->getMessage(), \OCP\Util::ERROR);
}
return (int)\OC_DB::insertid('*PREFIX*filecache');
@@ -209,6 +226,17 @@ class Cache {
* @param array $data
*/
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);
$params[] = $id;
@@ -224,7 +252,7 @@ class Cache {
* @return array
*/
function buildParts(array $data) {
- $fields = array('path', 'parent', 'name', 'mimetype', 'size', 'mtime', 'encrypted', 'etag');
+ $fields = array('path', 'parent', 'name', 'mimetype', 'size', 'mtime', 'storage_mtime', 'encrypted', 'unencrypted_size', 'etag');
$params = array();
$queryParts = array();
foreach ($data as $name => $value) {
@@ -236,6 +264,11 @@ class Cache {
$params[] = $this->getMimetypeId(substr($value, 0, strpos($value, '/')));
$queryParts[] = '`mimepart`';
$value = $this->getMimetypeId($value);
+ } elseif ($name === 'storage_mtime') {
+ if (!isset($data['mtime'])) {
+ $params[] = $value;
+ $queryParts[] = '`mtime`';
+ }
}
$params[] = $value;
$queryParts[] = '`' . $name . '`';
@@ -251,6 +284,9 @@ class Cache {
* @return int
*/
public function getId($file) {
+ // normalize file
+ $file = $this->normalize($file);
+
$pathHash = md5($file);
$query = \OC_DB::prepare('SELECT `fileid` FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path_hash` = ?');
@@ -318,14 +354,18 @@ class Cache {
* @param string $target
*/
public function move($source, $target) {
+ // normalize source and target
+ $source = $this->normalize($source);
+ $target = $this->normalize($target);
+
$sourceData = $this->get($source);
$sourceId = $sourceData['fileid'];
$newParentId = $this->getParentId($target);
if ($sourceData['mimetype'] === 'httpd/unix-directory') {
//find all child entries
- $query = \OC_DB::prepare('SELECT `path`, `fileid` FROM `*PREFIX*filecache` WHERE `path` LIKE ?');
- $result = $query->execute(array($source . '/%'));
+ $query = \OC_DB::prepare('SELECT `path`, `fileid` FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path` LIKE ?');
+ $result = $query->execute(array($this->getNumericStorageId(), $source . '/%'));
$childEntries = $result->fetchAll();
$sourceLength = strlen($source);
$query = \OC_DB::prepare('UPDATE `*PREFIX*filecache` SET `path` = ?, `path_hash` = ? WHERE `fileid` = ?');
@@ -358,9 +398,15 @@ class Cache {
* @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);
$query = \OC_DB::prepare('SELECT `size` FROM `*PREFIX*filecache` WHERE `storage` = ? AND `path_hash` = ?');
$result = $query->execute(array($this->getNumericStorageId(), $pathHash));
+ if( \OC_DB::isError($result)) {
+ \OCP\Util::writeLog('cache', 'get status failed: ' . $result->getMessage(), \OCP\Util::ERROR);
+ }
if ($row = $result->fetchRow()) {
if ((int)$row['size'] === -1) {
return self::SHALLOW;
@@ -383,8 +429,12 @@ class Cache {
* @return array of file data
*/
public function search($pattern) {
+
+ // normalize pattern
+ $pattern = $this->normalize($pattern);
+
$query = \OC_DB::prepare('
- SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted`, `etag`
+ SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted`, `unencrypted_size`, `etag`
FROM `*PREFIX*filecache` WHERE `name` LIKE ? AND `storage` = ?'
);
$result = $query->execute(array($pattern, $this->getNumericStorageId()));
@@ -410,7 +460,7 @@ class Cache {
$where = '`mimepart` = ?';
}
$query = \OC_DB::prepare('
- SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted`, `etag`
+ SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted`, `unencrypted_size`, `etag`
FROM `*PREFIX*filecache` WHERE ' . $where . ' AND `storage` = ?'
);
$mimetype = $this->getMimetypeId($mimetype);
@@ -498,8 +548,11 @@ class Cache {
*/
public function getIncomplete() {
$query = \OC_DB::prepare('SELECT `path` FROM `*PREFIX*filecache`'
- . ' WHERE `storage` = ? AND `size` = -1 ORDER BY `fileid` DESC LIMIT 1');
+ . ' WHERE `storage` = ? AND `size` = -1 ORDER BY `fileid` DESC',1);
$result = $query->execute(array($this->getNumericStorageId()));
+ if (\OC_DB::isError($result)) {
+ \OCP\Util::writeLog('cache', 'getIncomplete failed: ' . $result->getMessage(), \OCP\Util::ERROR);
+ }
if ($row = $result->fetchRow()) {
return $row['path'];
} else {
@@ -529,4 +582,14 @@ class Cache {
return null;
}
}
+
+ /**
+ * normalize the given path
+ * @param $path
+ * @return string
+ */
+ public function normalize($path) {
+
+ return \OC_Util::normalizeUnicode($path);
+ }
}
diff --git a/lib/files/cache/permissions.php b/lib/files/cache/permissions.php
index faa5ff5eacc..29c30b0f36c 100644
--- a/lib/files/cache/permissions.php
+++ b/lib/files/cache/permissions.php
@@ -86,6 +86,26 @@ class Permissions {
}
/**
+ * get the permissions for all files in a folder
+ *
+ * @param int $parentId
+ * @param string $user
+ * @return int[]
+ */
+ public function getDirectoryPermissions($parentId, $user) {
+ $query = \OC_DB::prepare('SELECT `*PREFIX*permissions`.`fileid`, `permissions`
+ FROM `*PREFIX*permissions` INNER JOIN `*PREFIX*filecache` ON `*PREFIX*permissions`.`fileid` = `*PREFIX*filecache`.`fileid`
+ WHERE `*PREFIX*filecache`.`parent` = ? AND `*PREFIX*permissions`.`user` = ?');
+
+ $result = $query->execute(array($parentId, $user));
+ $filePermissions = array();
+ while ($row = $result->fetchRow()) {
+ $filePermissions[$row['fileid']] = $row['permissions'];
+ }
+ return $filePermissions;
+ }
+
+ /**
* remove the permissions for a file
*
* @param int $fileId
diff --git a/lib/files/cache/scanner.php b/lib/files/cache/scanner.php
index 5241acec1ee..8f9a7921956 100644
--- a/lib/files/cache/scanner.php
+++ b/lib/files/cache/scanner.php
@@ -51,6 +51,7 @@ class Scanner {
$data['size'] = $this->storage->filesize($path);
}
$data['etag'] = $this->storage->getETag($path);
+ $data['storage_mtime'] = $data['mtime'];
return $data;
}
@@ -62,7 +63,9 @@ class Scanner {
* @return array with metadata of the scanned file
*/
public function scanFile($file, $checkExisting = false) {
- if (!self::isIgnoredFile($file)) {
+ if ( ! self::isPartialFile($file)
+ and ! \OC\Files\Filesystem::isFileBlacklisted($file)
+ ) {
\OC_Hook::emit('\OC\Files\Cache\Scanner', 'scan_file', array('path' => $file, 'storage' => $this->storageId));
$data = $this->getData($file);
if ($data) {
@@ -75,18 +78,21 @@ class Scanner {
$this->scanFile($parent);
}
}
- if($cacheData = $this->cache->get($file)) {
+ $newData = $data;
+ if ($cacheData = $this->cache->get($file)) {
+ if ($checkExisting && $data['size'] === -1) {
+ $data['size'] = $cacheData['size'];
+ }
if ($data['mtime'] === $cacheData['mtime'] &&
$data['size'] === $cacheData['size']) {
$data['etag'] = $cacheData['etag'];
}
+ // Only update metadata that has changed
+ $newData = array_diff($data, $cacheData);
}
- if ($checkExisting and $cacheData) {
- if ($data['size'] === -1) {
- $data['size'] = $cacheData['size'];
- }
+ if (!empty($newData)) {
+ $this->cache->put($file, $newData);
}
- $this->cache->put($file, $data);
}
return $data;
}
@@ -113,7 +119,7 @@ class Scanner {
\OC_DB::beginTransaction();
while ($file = readdir($dh)) {
$child = ($path) ? $path . '/' . $file : $file;
- if (!$this->isIgnoredDir($file)) {
+ if (!\OC\Files\Filesystem::isIgnoredDir($file)) {
$data = $this->scanFile($child, $recursive === self::SCAN_SHALLOW);
if ($data) {
if ($data['size'] === -1) {
@@ -148,28 +154,14 @@ class Scanner {
}
/**
- * @brief check if the directory should be ignored when scanning
- * NOTE: the special directories . and .. would cause never ending recursion
- * @param String $dir
- * @return boolean
- */
- private function isIgnoredDir($dir) {
- if ($dir === '.' || $dir === '..') {
- return true;
- }
- return false;
- }
- /**
* @brief 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 isIgnoredFile($file) {
- if (pathinfo($file, PATHINFO_EXTENSION) === 'part'
- || \OC\Files\Filesystem::isFileBlacklisted($file)
- ) {
+ public static function isPartialFile($file) {
+ if (pathinfo($file, PATHINFO_EXTENSION) === 'part') {
return true;
}
return false;
@@ -179,9 +171,11 @@ class Scanner {
* walk over any folders that are not fully scanned yet and scan them
*/
public function backgroundScan() {
- while (($path = $this->cache->getIncomplete()) !== false) {
+ $lastPath = null;
+ while (($path = $this->cache->getIncomplete()) !== false && $path !== $lastPath) {
$this->scan($path);
$this->cache->correctFolderSize($path);
+ $lastPath = $path;
}
}
}
diff --git a/lib/files/cache/updater.php b/lib/files/cache/updater.php
index 92a16d9d9b6..417a47f3830 100644
--- a/lib/files/cache/updater.php
+++ b/lib/files/cache/updater.php
@@ -132,7 +132,14 @@ class Updater {
* @param array $params
*/
static public function touchHook($params) {
- self::writeUpdate($params['path']);
+ $path = $params['path'];
+ list($storage, $internalPath) = self::resolvePath($path);
+ $cache = $storage->getCache();
+ $id = $cache->getId($internalPath);
+ if ($id !== -1) {
+ $cache->update($id, array('etag' => $storage->getETag($internalPath)));
+ }
+ self::writeUpdate($path);
}
/**
diff --git a/lib/files/cache/watcher.php b/lib/files/cache/watcher.php
index 31059ec7f56..8bfd4602f3a 100644
--- a/lib/files/cache/watcher.php
+++ b/lib/files/cache/watcher.php
@@ -43,7 +43,7 @@ class Watcher {
*/
public function checkUpdate($path) {
$cachedEntry = $this->cache->get($path);
- if ($this->storage->hasUpdated($path, $cachedEntry['mtime'])) {
+ if ($this->storage->hasUpdated($path, $cachedEntry['storage_mtime'])) {
if ($this->storage->is_dir($path)) {
$this->scanner->scan($path, Scanner::SCAN_SHALLOW);
} else {
diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php
index ce89c5c23ff..0daa863e79d 100644
--- a/lib/files/filesystem.php
+++ b/lib/files/filesystem.php
@@ -158,6 +158,9 @@ class Filesystem {
* @return string
*/
static public function getMountPoint($path) {
+ if (!self::$mounts) {
+ \OC_Util::setupFS();
+ }
$mount = self::$mounts->find($path);
if ($mount) {
return $mount->getMountPoint();
@@ -173,6 +176,9 @@ class Filesystem {
* @return string[]
*/
static public function getMountPoints($path) {
+ if (!self::$mounts) {
+ \OC_Util::setupFS();
+ }
$result = array();
$mounts = self::$mounts->findIn($path);
foreach ($mounts as $mount) {
@@ -188,6 +194,9 @@ class Filesystem {
* @return \OC\Files\Storage\Storage
*/
public static function getStorage($mountPoint) {
+ if (!self::$mounts) {
+ \OC_Util::setupFS();
+ }
$mount = self::$mounts->find($mountPoint);
return $mount->getStorage();
}
@@ -197,6 +206,9 @@ class Filesystem {
* @return Mount\Mount[]
*/
public static function getMountByStorageId($id) {
+ if (!self::$mounts) {
+ \OC_Util::setupFS();
+ }
return self::$mounts->findByStorageId($id);
}
@@ -205,6 +217,9 @@ class Filesystem {
* @return Mount\Mount[]
*/
public static function getMountByNumericId($id) {
+ if (!self::$mounts) {
+ \OC_Util::setupFS();
+ }
return self::$mounts->findByNumericId($id);
}
@@ -215,6 +230,9 @@ class Filesystem {
* @return 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(), $mount->getInternalPath($path));
@@ -229,7 +247,10 @@ class Filesystem {
}
self::$loader = new Loader();
self::$defaultInstance = new View($root);
- self::$mounts = new Mount\Manager();
+
+ if (!self::$mounts) {
+ self::$mounts = new Mount\Manager();
+ }
//load custom mount config
self::initMountPoints($user);
@@ -240,7 +261,9 @@ class Filesystem {
}
static public function initMounts() {
- self::$mounts = new Mount\Manager();
+ if (!self::$mounts) {
+ self::$mounts = new Mount\Manager();
+ }
}
/**
@@ -361,7 +384,9 @@ class Filesystem {
* clear all mounts and storage backends
*/
public static function clearMounts() {
- self::$mounts->clear();
+ if (self::$mounts) {
+ self::$mounts->clear();
+ }
}
/**
@@ -372,6 +397,9 @@ class Filesystem {
* @param string $mountpoint
*/
static public function mount($class, $arguments, $mountpoint) {
+ if (!self::$mounts) {
+ \OC_Util::setupFS();
+ }
$mount = new Mount\Mount($class, $mountpoint, $arguments, self::$loader);
self::$mounts->addMount($mount);
}
@@ -458,6 +486,19 @@ class Filesystem {
}
/**
+ * @brief 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) {
@@ -620,9 +661,8 @@ class Filesystem {
$path = substr($path, 0, -1);
}
//normalize unicode if possible
- if (class_exists('Normalizer')) {
- $path = \Normalizer::normalize($path);
- }
+ $path = \OC_Util::normalizeUnicode($path);
+
return $path;
}
diff --git a/lib/files/storage/common.php b/lib/files/storage/common.php
index e87fe3b5239..3da13ac4df0 100644
--- a/lib/files/storage/common.php
+++ b/lib/files/storage/common.php
@@ -138,27 +138,21 @@ abstract class Common implements \OC\Files\Storage\Storage {
*/
public function deleteAll($directory, $empty = false) {
$directory = trim($directory, '/');
-
- if (!$this->file_exists(\OCP\USER::getUser() . '/' . $directory)
- || !$this->is_dir(\OCP\USER::getUser() . '/' . $directory)
- ) {
- return false;
- } elseif (!$this->isReadable(\OCP\USER::getUser() . '/' . $directory)) {
+ if (!$this->is_dir($directory) || !$this->isReadable($directory)) {
return false;
} else {
- $directoryHandle = $this->opendir(\OCP\USER::getUser() . '/' . $directory);
+ $directoryHandle = $this->opendir($directory);
while ($contents = readdir($directoryHandle)) {
- if ($contents != '.' && $contents != '..') {
- $path = $directory . "/" . $contents;
+ if (!\OC\Files\Filesystem::isIgnoredDir($contents)) {
+ $path = $directory . '/' . $contents;
if ($this->is_dir($path)) {
$this->deleteAll($path);
} else {
- $this->unlink(\OCP\USER::getUser() . '/' . $path); // TODO: make unlink use same system path as is_dir
+ $this->unlink($path);
}
}
}
- //$this->closedir( $directoryHandle ); // TODO: implement closedir in OC_FSV
- if ($empty == false) {
+ if ($empty === false) {
if (!$this->rmdir($directory)) {
return false;
}
diff --git a/lib/files/view.php b/lib/files/view.php
index f89b7f66ffd..ecb0f30400a 100644
--- a/lib/files/view.php
+++ b/lib/files/view.php
@@ -251,8 +251,11 @@ class View {
if (!$this->file_exists($path)) {
$hooks[] = 'write';
}
-
- return $this->basicOperation('touch', $path, $hooks, $mtime);
+ $result = $this->basicOperation('touch', $path, $hooks, $mtime);
+ if (!$result) { //if native touch fails, we emulate it by changing the mtime in the cache
+ $this->putFileInfo($path, array('mtime' => $mtime));
+ }
+ return true;
}
public function file_get_contents($path) {
@@ -263,12 +266,13 @@ class View {
if (is_resource($data)) { //not having to deal with streams in file_put_contents makes life easier
$absolutePath = Filesystem::normalizePath($this->getAbsolutePath($path));
if (\OC_FileProxy::runPreProxies('file_put_contents', $absolutePath, $data)
- && Filesystem::isValidPath($path)
+ and Filesystem::isValidPath($path)
+ and !Filesystem::isFileBlacklisted($path)
) {
$path = $this->getRelativePath($absolutePath);
$exists = $this->file_exists($path);
$run = true;
- if ($this->fakeRoot == Filesystem::getRoot() && !Cache\Scanner::isIgnoredFile($path)) {
+ if ($this->fakeRoot == Filesystem::getRoot() && !Cache\Scanner::isPartialFile($path)) {
if (!$exists) {
\OC_Hook::emit(
Filesystem::CLASSNAME,
@@ -296,7 +300,7 @@ class View {
list ($count, $result) = \OC_Helper::streamCopy($data, $target);
fclose($target);
fclose($data);
- if ($this->fakeRoot == Filesystem::getRoot() && !Cache\Scanner::isIgnoredFile($path)) {
+ if ($this->fakeRoot == Filesystem::getRoot() && !Cache\Scanner::isPartialFile($path)) {
if (!$exists) {
\OC_Hook::emit(
Filesystem::CLASSNAME,
@@ -340,6 +344,7 @@ class View {
\OC_FileProxy::runPreProxies('rename', $absolutePath1, $absolutePath2)
and Filesystem::isValidPath($path2)
and Filesystem::isValidPath($path1)
+ and !Filesystem::isFileBlacklisted($path2)
) {
$path1 = $this->getRelativePath($absolutePath1);
$path2 = $this->getRelativePath($absolutePath2);
@@ -348,7 +353,7 @@ class View {
return false;
}
$run = true;
- if ($this->fakeRoot == Filesystem::getRoot()) {
+ if ($this->fakeRoot == Filesystem::getRoot() && !Cache\Scanner::isPartialFile($path1)) {
\OC_Hook::emit(
Filesystem::CLASSNAME, Filesystem::signal_rename,
array(
@@ -366,17 +371,26 @@ class View {
list(, $internalPath2) = Filesystem::resolvePath($absolutePath2 . $postFix2);
if ($storage) {
$result = $storage->rename($internalPath1, $internalPath2);
+ \OC_FileProxy::runPostProxies('rename', $absolutePath1, $absolutePath2);
} else {
$result = false;
}
} else {
- $source = $this->fopen($path1 . $postFix1, 'r');
- $target = $this->fopen($path2 . $postFix2, 'w');
- list($count, $result) = \OC_Helper::streamCopy($source, $target);
- list($storage1, $internalPath1) = Filesystem::resolvePath($absolutePath1 . $postFix1);
- $storage1->unlink($internalPath1);
+ if ($this->is_dir($path1)) {
+ $result = $this->copy($path1, $path2);
+ if ($result === true) {
+ list($storage1, $internalPath1) = Filesystem::resolvePath($absolutePath1 . $postFix1);
+ $result = $storage1->deleteAll($internalPath1);
+ }
+ } else {
+ $source = $this->fopen($path1 . $postFix1, 'r');
+ $target = $this->fopen($path2 . $postFix2, 'w');
+ list($count, $result) = \OC_Helper::streamCopy($source, $target);
+ list($storage1, $internalPath1) = Filesystem::resolvePath($absolutePath1 . $postFix1);
+ $storage1->unlink($internalPath1);
+ }
}
- if ($this->fakeRoot == Filesystem::getRoot()) {
+ if ($this->fakeRoot == Filesystem::getRoot() && !Cache\Scanner::isPartialFile($path1)) {
\OC_Hook::emit(
Filesystem::CLASSNAME,
Filesystem::signal_post_rename,
@@ -404,6 +418,7 @@ class View {
\OC_FileProxy::runPreProxies('copy', $absolutePath1, $absolutePath2)
and Filesystem::isValidPath($path2)
and Filesystem::isValidPath($path1)
+ and !Filesystem::isFileBlacklisted($path2)
) {
$path1 = $this->getRelativePath($absolutePath1);
$path2 = $this->getRelativePath($absolutePath2);
@@ -456,9 +471,18 @@ class View {
$result = false;
}
} else {
- $source = $this->fopen($path1 . $postFix1, 'r');
- $target = $this->fopen($path2 . $postFix2, 'w');
- list($count, $result) = \OC_Helper::streamCopy($source, $target);
+ if ($this->is_dir($path1) && ($dh = $this->opendir($path1))) {
+ $result = $this->mkdir($path2);
+ while ($file = readdir($dh)) {
+ if (!Filesystem::isIgnoredDir($file)) {
+ $result = $this->copy($path1 . '/' . $file, $path2 . '/' . $file);
+ }
+ }
+ } else {
+ $source = $this->fopen($path1 . $postFix1, 'r');
+ $target = $this->fopen($path2 . $postFix2, 'w');
+ list($count, $result) = \OC_Helper::streamCopy($source, $target);
+ }
}
if ($this->fakeRoot == Filesystem::getRoot()) {
\OC_Hook::emit(
@@ -606,7 +630,10 @@ class View {
private function basicOperation($operation, $path, $hooks = array(), $extraParam = null) {
$postFix = (substr($path, -1, 1) === '/') ? '/' : '';
$absolutePath = Filesystem::normalizePath($this->getAbsolutePath($path));
- if (\OC_FileProxy::runPreProxies($operation, $absolutePath, $extraParam) and Filesystem::isValidPath($path)) {
+ if (\OC_FileProxy::runPreProxies($operation, $absolutePath, $extraParam)
+ and Filesystem::isValidPath($path)
+ and !Filesystem::isFileBlacklisted($path)
+ ) {
$path = $this->getRelativePath($absolutePath);
if ($path == null) {
return false;
@@ -635,7 +662,7 @@ class View {
private function runHooks($hooks, $path, $post = false) {
$prefix = ($post) ? 'post_' : '';
$run = true;
- if (Filesystem::$loaded and $this->fakeRoot == Filesystem::getRoot() && !Cache\Scanner::isIgnoredFile($path)) {
+ if (Filesystem::$loaded and $this->fakeRoot == Filesystem::getRoot()) {
foreach ($hooks as $hook) {
if ($hook != 'read') {
\OC_Hook::emit(
@@ -732,6 +759,9 @@ class View {
$data['permissions'] = $permissions;
}
}
+
+ $data = \OC_FileProxy::runPostProxies('getFileInfo', $path, $data);
+
return $data;
}
@@ -767,18 +797,18 @@ class View {
}
$files = $cache->getFolderContents($internalPath); //TODO: mimetype_filter
+ $permissions = $permissionsCache->getDirectoryPermissions($cache->getId($internalPath), $user);
$ids = array();
foreach ($files as $i => $file) {
$files[$i]['type'] = $file['mimetype'] === 'httpd/unix-directory' ? 'dir' : 'file';
$ids[] = $file['fileid'];
- $permissions = $permissionsCache->get($file['fileid'], $user);
- if ($permissions === -1) {
- $permissions = $storage->getPermissions($file['path']);
- $permissionsCache->set($file['fileid'], $user, $permissions);
+ if (!isset($permissions[$file['fileid']])) {
+ $permissions[$file['fileid']] = $storage->getPermissions($file['path']);
+ $permissionsCache->set($file['fileid'], $user, $permissions[$file['fileid']]);
}
- $files[$i]['permissions'] = $permissions;
+ $files[$i]['permissions'] = $permissions[$file['fileid']];
}
//add a folder for any mountpoint in this directory and add the sizes of other mountpoints to the folders