aboutsummaryrefslogtreecommitdiffstats
path: root/lib/private/Files
diff options
context:
space:
mode:
authorRobin Appelman <robin@icewind.nl>2023-10-16 17:39:23 +0200
committerRobin Appelman <robin@icewind.nl>2023-10-20 15:03:11 +0200
commit8418fcfedf8524d3e00263d9028dab5651cf9c00 (patch)
tree28ee7d0d1fb3d117f70c5e6b891581600cae0916 /lib/private/Files
parentc932c94fdd18a0799c522e4e25cca197724d9f2f (diff)
downloadnextcloud-server-8418fcfedf8524d3e00263d9028dab5651cf9c00.tar.gz
nextcloud-server-8418fcfedf8524d3e00263d9028dab5651cf9c00.zip
add some support for rename on case insensitive local filesystems
Signed-off-by: Robin Appelman <robin@icewind.nl>
Diffstat (limited to 'lib/private/Files')
-rw-r--r--lib/private/Files/Storage/Local.php27
1 files changed, 26 insertions, 1 deletions
diff --git a/lib/private/Files/Storage/Local.php b/lib/private/Files/Storage/Local.php
index eeb9e11b24e..0fca853da59 100644
--- a/lib/private/Files/Storage/Local.php
+++ b/lib/private/Files/Storage/Local.php
@@ -74,6 +74,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');
@@ -93,6 +95,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);
@@ -162,6 +165,9 @@ class Local extends \OC\Files\Storage\Common {
}
public function is_dir($path) {
+ if ($this->caseInsensitive && !$this->file_exists($path)) {
+ return false;
+ }
if (str_ends_with($path, '/')) {
$path = substr($path, 0, -1);
}
@@ -169,6 +175,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));
}
@@ -271,7 +280,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) {
@@ -372,6 +387,11 @@ class Local extends \OC\Files\Storage\Common {
}
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;
}
@@ -388,6 +408,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;
}
}