diff options
author | Georg Ehrke <developer@georgehrke.com> | 2013-08-19 17:30:56 +0200 |
---|---|---|
committer | Georg Ehrke <developer@georgehrke.com> | 2013-08-19 17:30:56 +0200 |
commit | cbeccb2fcd3d3d445726c9e0cd5b8e6c8285a1ea (patch) | |
tree | a262c1ad4511a04922519a868a7733a7b1794f3a /lib/files | |
parent | c5402f457530577999d1adc1715c76e742ad8aa9 (diff) | |
parent | 95e1b62940444eb2a7467d994a7b4366f6e7f2fc (diff) | |
download | nextcloud-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.php | 17 | ||||
-rw-r--r-- | lib/files/mount/manager.php | 7 | ||||
-rw-r--r-- | lib/files/mount/mount.php | 7 | ||||
-rw-r--r-- | lib/files/storage/common.php | 2 | ||||
-rw-r--r-- | lib/files/storage/local.php | 2 | ||||
-rw-r--r-- | lib/files/storage/wrapper/quota.php | 104 | ||||
-rw-r--r-- | lib/files/storage/wrapper/wrapper.php | 2 | ||||
-rw-r--r-- | lib/files/stream/quota.php | 128 |
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); + } +} |