summaryrefslogtreecommitdiffstats
path: root/lib/files
diff options
context:
space:
mode:
authorGeorg Ehrke <developer@georgehrke.com>2013-08-19 17:30:56 +0200
committerGeorg Ehrke <developer@georgehrke.com>2013-08-19 17:30:56 +0200
commitcbeccb2fcd3d3d445726c9e0cd5b8e6c8285a1ea (patch)
treea262c1ad4511a04922519a868a7733a7b1794f3a /lib/files
parentc5402f457530577999d1adc1715c76e742ad8aa9 (diff)
parent95e1b62940444eb2a7467d994a7b4366f6e7f2fc (diff)
downloadnextcloud-server-cbeccb2fcd3d3d445726c9e0cd5b8e6c8285a1ea.tar.gz
nextcloud-server-cbeccb2fcd3d3d445726c9e0cd5b8e6c8285a1ea.zip
Merge branch 'master' into readdir-strict-equals
Diffstat (limited to 'lib/files')
-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.php2
-rw-r--r--lib/files/storage/local.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
8 files changed, 264 insertions, 5 deletions
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 1a273240eeb..01560f34fde 100644
--- a/lib/files/storage/common.php
+++ b/lib/files/storage/common.php
@@ -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/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);
+ }
+}