summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorRobin Appelman <robin@icewind.nl>2023-10-16 17:39:23 +0200
committerBenjamin Gaussorgues <benjamin.gaussorgues@nextcloud.com>2023-11-15 15:21:14 +0100
commit482deca3543ecfed3041bdf8516c89094309794e (patch)
tree88c5245481657a35dae4d860a3813fddeeae1f3b /lib
parent11764ffec1113f14fe15a22e6db90ec633d1bb8e (diff)
downloadnextcloud-server-482deca3543ecfed3041bdf8516c89094309794e.tar.gz
nextcloud-server-482deca3543ecfed3041bdf8516c89094309794e.zip
add some support for rename on case insensitive local filesystems
Signed-off-by: Robin Appelman <robin@icewind.nl>
Diffstat (limited to 'lib')
-rw-r--r--lib/private/Files/Storage/Local.php33
1 files changed, 31 insertions, 2 deletions
diff --git a/lib/private/Files/Storage/Local.php b/lib/private/Files/Storage/Local.php
index 3b292506578..813e5aa09d7 100644
--- a/lib/private/Files/Storage/Local.php
+++ b/lib/private/Files/Storage/Local.php
@@ -73,6 +73,8 @@ class Local extends \OC\Files\Storage\Common {
protected bool $unlinkOnTruncate;
+ protected bool $caseInsensitive = false;
+
public function __construct($arguments) {
if (!isset($arguments['datadir']) || !is_string($arguments['datadir'])) {
throw new \InvalidArgumentException('No data directory set for local storage');
@@ -92,6 +94,7 @@ class Local extends \OC\Files\Storage\Common {
$this->config = \OC::$server->get(IConfig::class);
$this->mimeTypeDetector = \OC::$server->get(IMimeTypeDetector::class);
$this->defUMask = $this->config->getSystemValue('localstorage.umask', 0022);
+ $this->caseInsensitive = $this->config->getSystemValueBool('localstorage.case_insensitive', false);
// support Write-Once-Read-Many file systems
$this->unlinkOnTruncate = $this->config->getSystemValueBool('localstorage.unlink_on_truncate', false);
@@ -155,6 +158,9 @@ class Local extends \OC\Files\Storage\Common {
}
public function is_dir($path) {
+ if ($this->caseInsensitive && !$this->file_exists($path)) {
+ return false;
+ }
if (substr($path, -1) == '/') {
$path = substr($path, 0, -1);
}
@@ -162,6 +168,9 @@ class Local extends \OC\Files\Storage\Common {
}
public function is_file($path) {
+ if ($this->caseInsensitive && !$this->file_exists($path)) {
+ return false;
+ }
return is_file($this->getSourcePath($path));
}
@@ -264,7 +273,13 @@ class Local extends \OC\Files\Storage\Common {
}
public function file_exists($path) {
- return file_exists($this->getSourcePath($path));
+ if ($this->caseInsensitive) {
+ $fullPath = $this->getSourcePath($path);
+ $content = scandir(dirname($fullPath), SCANDIR_SORT_NONE);
+ return is_array($content) && array_search(basename($fullPath), $content) !== false;
+ } else {
+ return file_exists($this->getSourcePath($path));
+ }
}
public function filemtime($path) {
@@ -375,7 +390,16 @@ class Local extends \OC\Files\Storage\Common {
$this->checkTreeForForbiddenItems($this->getSourcePath($source));
}
- return rename($this->getSourcePath($source), $this->getSourcePath($target));
+ if (rename($this->getSourcePath($source), $this->getSourcePath($target))) {
+ if ($this->caseInsensitive) {
+ if (mb_strtolower($target) === mb_strtolower($source) && !$this->file_exists($target)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ return false;
}
public function copy($source, $target) {
@@ -388,6 +412,11 @@ class Local extends \OC\Files\Storage\Common {
}
$result = copy($this->getSourcePath($source), $this->getSourcePath($target));
umask($oldMask);
+ if ($this->caseInsensitive) {
+ if (mb_strtolower($target) === mb_strtolower($source) && !$this->file_exists($target)) {
+ return false;
+ }
+ }
return $result;
}
}