Skip to content

Commit 9147bc1

Browse files
authored
Merge pull request #41505 from nextcloud/backport/40935/stable26
[stable26] add some support for rename on case insensitive local filesystems
2 parents bba6080 + 0fb0314 commit 9147bc1

1 file changed

Lines changed: 31 additions & 2 deletions

File tree

lib/private/Files/Storage/Local.php

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ class Local extends \OC\Files\Storage\Common {
7373

7474
protected bool $unlinkOnTruncate;
7575

76+
protected bool $caseInsensitive = false;
77+
7678
public function __construct($arguments) {
7779
if (!isset($arguments['datadir']) || !is_string($arguments['datadir'])) {
7880
throw new \InvalidArgumentException('No data directory set for local storage');
@@ -92,6 +94,7 @@ public function __construct($arguments) {
9294
$this->config = \OC::$server->get(IConfig::class);
9395
$this->mimeTypeDetector = \OC::$server->get(IMimeTypeDetector::class);
9496
$this->defUMask = $this->config->getSystemValue('localstorage.umask', 0022);
97+
$this->caseInsensitive = $this->config->getSystemValueBool('localstorage.case_insensitive', false);
9598

9699
// support Write-Once-Read-Many file systems
97100
$this->unlinkOnTruncate = $this->config->getSystemValue('localstorage.unlink_on_truncate', false);
@@ -155,13 +158,19 @@ public function opendir($path) {
155158
}
156159

157160
public function is_dir($path) {
161+
if ($this->caseInsensitive && !$this->file_exists($path)) {
162+
return false;
163+
}
158164
if (substr($path, -1) == '/') {
159165
$path = substr($path, 0, -1);
160166
}
161167
return is_dir($this->getSourcePath($path));
162168
}
163169

164170
public function is_file($path) {
171+
if ($this->caseInsensitive && !$this->file_exists($path)) {
172+
return false;
173+
}
165174
return is_file($this->getSourcePath($path));
166175
}
167176

@@ -264,7 +273,13 @@ public function isUpdatable($path) {
264273
}
265274

266275
public function file_exists($path) {
267-
return file_exists($this->getSourcePath($path));
276+
if ($this->caseInsensitive) {
277+
$fullPath = $this->getSourcePath($path);
278+
$content = scandir(dirname($fullPath), SCANDIR_SORT_NONE);
279+
return is_array($content) && array_search(basename($fullPath), $content) !== false;
280+
} else {
281+
return file_exists($this->getSourcePath($path));
282+
}
268283
}
269284

270285
public function filemtime($path) {
@@ -375,7 +390,16 @@ public function rename($source, $target) {
375390
$this->checkTreeForForbiddenItems($this->getSourcePath($source));
376391
}
377392

378-
return rename($this->getSourcePath($source), $this->getSourcePath($target));
393+
if (rename($this->getSourcePath($source), $this->getSourcePath($target))) {
394+
if ($this->caseInsensitive) {
395+
if (mb_strtolower($target) === mb_strtolower($source) && !$this->file_exists($target)) {
396+
return false;
397+
}
398+
}
399+
return true;
400+
}
401+
402+
return false;
379403
}
380404

381405
public function copy($source, $target) {
@@ -388,6 +412,11 @@ public function copy($source, $target) {
388412
}
389413
$result = copy($this->getSourcePath($source), $this->getSourcePath($target));
390414
umask($oldMask);
415+
if ($this->caseInsensitive) {
416+
if (mb_strtolower($target) === mb_strtolower($source) && !$this->file_exists($target)) {
417+
return false;
418+
}
419+
}
391420
return $result;
392421
}
393422
}

0 commit comments

Comments
 (0)