aboutsummaryrefslogtreecommitdiffstats
path: root/lib/files
diff options
context:
space:
mode:
Diffstat (limited to 'lib/files')
-rw-r--r--lib/files/cache/scanner.php2
-rw-r--r--lib/files/filesystem.php17
-rw-r--r--lib/files/mount/manager.php7
-rw-r--r--lib/files/mount/mount.php7
-rw-r--r--lib/files/storage/common.php8
-rw-r--r--lib/files/storage/local.php2
-rw-r--r--lib/files/storage/mappedlocal.php2
-rw-r--r--lib/files/storage/wrapper/quota.php104
-rw-r--r--lib/files/storage/wrapper/wrapper.php2
-rw-r--r--lib/files/stream/quota.php128
-rw-r--r--lib/files/view.php2
11 files changed, 270 insertions, 11 deletions
diff --git a/lib/files/cache/scanner.php b/lib/files/cache/scanner.php
index 597eabecf54..87fa7c1365a 100644
--- a/lib/files/cache/scanner.php
+++ b/lib/files/cache/scanner.php
@@ -159,7 +159,7 @@ class Scanner extends BasicEmitter {
$newChildren = array();
if ($this->storage->is_dir($path) && ($dh = $this->storage->opendir($path))) {
\OC_DB::beginTransaction();
- while ($file = readdir($dh)) {
+ while (($file = readdir($dh)) !== false) {
$child = ($path) ? $path . '/' . $file : $file;
if (!Filesystem::isIgnoredDir($file)) {
$newChildren[] = $file;
diff --git a/lib/files/filesystem.php b/lib/files/filesystem.php
index d6ebe7d629a..10ec5c41d11 100644
--- a/lib/files/filesystem.php
+++ b/lib/files/filesystem.php
@@ -31,8 +31,9 @@
namespace OC\Files;
use OC\Files\Storage\Loader;
-const FREE_SPACE_UNKNOWN = -2;
-const FREE_SPACE_UNLIMITED = -3;
+const SPACE_NOT_COMPUTED = -1;
+const SPACE_UNKNOWN = -2;
+const SPACE_UNLIMITED = -3;
class Filesystem {
/**
@@ -148,6 +149,18 @@ class Filesystem {
*/
private static $loader;
+ /**
+ * @param callable $wrapper
+ */
+ public static function addStorageWrapper($wrapper) {
+ self::getLoader()->addStorageWrapper($wrapper);
+
+ $mounts = self::getMountManager()->getAll();
+ foreach ($mounts as $mount) {
+ $mount->wrapStorage($wrapper);
+ }
+ }
+
public static function getLoader() {
if (!self::$loader) {
self::$loader = new Loader();
diff --git a/lib/files/mount/manager.php b/lib/files/mount/manager.php
index 25a5fe241cc..4c432dcf724 100644
--- a/lib/files/mount/manager.php
+++ b/lib/files/mount/manager.php
@@ -96,6 +96,13 @@ class Manager {
}
/**
+ * @return Mount[]
+ */
+ public function getAll() {
+ return $this->mounts;
+ }
+
+ /**
* Find mounts by numeric storage id
*
* @param string $id
diff --git a/lib/files/mount/mount.php b/lib/files/mount/mount.php
index 17b0055ee84..0ce2f5975c7 100644
--- a/lib/files/mount/mount.php
+++ b/lib/files/mount/mount.php
@@ -138,4 +138,11 @@ class Mount {
}
return $path;
}
+
+ /**
+ * @param callable $wrapper
+ */
+ public function wrapStorage($wrapper) {
+ $this->storage = $wrapper($this->mountPoint, $this->storage);
+ }
}
diff --git a/lib/files/storage/common.php b/lib/files/storage/common.php
index 3da13ac4df0..01560f34fde 100644
--- a/lib/files/storage/common.php
+++ b/lib/files/storage/common.php
@@ -142,7 +142,7 @@ abstract class Common implements \OC\Files\Storage\Storage {
return false;
} else {
$directoryHandle = $this->opendir($directory);
- while ($contents = readdir($directoryHandle)) {
+ while (($contents = readdir($directoryHandle)) !== false) {
if (!\OC\Files\Filesystem::isIgnoredDir($contents)) {
$path = $directory . '/' . $contents;
if ($this->is_dir($path)) {
@@ -225,7 +225,7 @@ abstract class Common implements \OC\Files\Storage\Storage {
private function addLocalFolder($path, $target) {
if ($dh = $this->opendir($path)) {
- while ($file = readdir($dh)) {
+ while (($file = readdir($dh)) !== false) {
if ($file !== '.' and $file !== '..') {
if ($this->is_dir($path . '/' . $file)) {
mkdir($target . '/' . $file);
@@ -243,7 +243,7 @@ abstract class Common implements \OC\Files\Storage\Storage {
$files = array();
$dh = $this->opendir($dir);
if ($dh) {
- while ($item = readdir($dh)) {
+ while (($item = readdir($dh)) !== false) {
if ($item == '.' || $item == '..') continue;
if (strstr(strtolower($item), strtolower($query)) !== false) {
$files[] = $dir . '/' . $item;
@@ -366,6 +366,6 @@ abstract class Common implements \OC\Files\Storage\Storage {
* @return int
*/
public function free_space($path) {
- return \OC\Files\FREE_SPACE_UNKNOWN;
+ return \OC\Files\SPACE_UNKNOWN;
}
}
diff --git a/lib/files/storage/local.php b/lib/files/storage/local.php
index b08fd73ce19..5209fabc30a 100644
--- a/lib/files/storage/local.php
+++ b/lib/files/storage/local.php
@@ -265,7 +265,7 @@ if (\OC_Util::runningOnWindows()) {
public function free_space($path) {
$space = @disk_free_space($this->datadir . $path);
if ($space === false) {
- return \OC\Files\FREE_SPACE_UNKNOWN;
+ return \OC\Files\SPACE_UNKNOWN;
}
return $space;
}
diff --git a/lib/files/storage/mappedlocal.php b/lib/files/storage/mappedlocal.php
index cf5d9b3ef4f..fbf1b4ebf96 100644
--- a/lib/files/storage/mappedlocal.php
+++ b/lib/files/storage/mappedlocal.php
@@ -65,7 +65,7 @@ class MappedLocal extends \OC\Files\Storage\Common{
$logicalPath = $this->mapper->physicalToLogic($physicalPath);
$dh = opendir($physicalPath);
- while ($file = readdir($dh)) {
+ while (($file = readdir($dh)) !== false) {
if ($file === '.' or $file === '..') {
continue;
}
diff --git a/lib/files/storage/wrapper/quota.php b/lib/files/storage/wrapper/quota.php
new file mode 100644
index 00000000000..e2da8cf2e05
--- /dev/null
+++ b/lib/files/storage/wrapper/quota.php
@@ -0,0 +1,104 @@
+<?php
+/**
+ * Copyright (c) 2013 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OC\Files\Storage\Wrapper;
+
+class Quota extends Wrapper {
+
+ /**
+ * @var int $quota
+ */
+ protected $quota;
+
+ /**
+ * @param array $parameters
+ */
+ public function __construct($parameters) {
+ $this->storage = $parameters['storage'];
+ $this->quota = $parameters['quota'];
+ }
+
+ protected function getSize($path) {
+ $cache = $this->getCache();
+ $data = $cache->get($path);
+ if (is_array($data) and isset($data['size'])) {
+ return $data['size'];
+ } else {
+ return \OC\Files\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('');
+ if ($used < 0) {
+ return \OC\Files\SPACE_NOT_COMPUTED;
+ } else {
+ $free = $this->storage->free_space($path);
+ return min($free, (max($this->quota - $used, 0)));
+ }
+ }
+ }
+
+ /**
+ * 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);
+ $free = $this->free_space('');
+ if ($free >= 0) {
+ return \OC\Files\Stream\Quota::wrap($source, $free);
+ } else {
+ return $source;
+ }
+ }
+}
diff --git a/lib/files/storage/wrapper/wrapper.php b/lib/files/storage/wrapper/wrapper.php
index 4feb0520f12..0336c27efa1 100644
--- a/lib/files/storage/wrapper/wrapper.php
+++ b/lib/files/storage/wrapper/wrapper.php
@@ -395,7 +395,7 @@ class Wrapper implements \OC\Files\Storage\Storage {
* @return \OC\Files\Cache\Permissions
*/
public function getPermissionsCache($path = '') {
- return $this->storage->getPermissions($path);
+ return $this->storage->getPermissionsCache($path);
}
/**
diff --git a/lib/files/stream/quota.php b/lib/files/stream/quota.php
new file mode 100644
index 00000000000..53d8a03d30f
--- /dev/null
+++ b/lib/files/stream/quota.php
@@ -0,0 +1,128 @@
+<?php
+/**
+ * Copyright (c) 2013 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+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_SET) {
+ $this->limit += $this->stream_tell() - $offset;
+ } else {
+ $this->limit -= $offset;
+ }
+ fseek($this->source, $offset, $whence);
+ }
+
+ 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) {
+ 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/files/view.php b/lib/files/view.php
index c9727fe4984..bb737f19ef8 100644
--- a/lib/files/view.php
+++ b/lib/files/view.php
@@ -499,7 +499,7 @@ class View {
} else {
if ($this->is_dir($path1) && ($dh = $this->opendir($path1))) {
$result = $this->mkdir($path2);
- while ($file = readdir($dh)) {
+ while (($file = readdir($dh)) !== false) {
if (!Filesystem::isIgnoredDir($file)) {
$result = $this->copy($path1 . '/' . $file, $path2 . '/' . $file);
}