@@ -74,6 +74,8 @@ class Local extends \OC\Files\Storage\Common {
7474
7575 protected bool $ unlinkOnTruncate ;
7676
77+ protected bool $ caseInsensitive = false ;
78+
7779 public function __construct ($ arguments ) {
7880 if (!isset ($ arguments ['datadir ' ]) || !is_string ($ arguments ['datadir ' ])) {
7981 throw new \InvalidArgumentException ('No data directory set for local storage ' );
@@ -93,6 +95,7 @@ public function __construct($arguments) {
9395 $ this ->config = \OC ::$ server ->get (IConfig::class);
9496 $ this ->mimeTypeDetector = \OC ::$ server ->get (IMimeTypeDetector::class);
9597 $ this ->defUMask = $ this ->config ->getSystemValue ('localstorage.umask ' , 0022 );
98+ $ this ->caseInsensitive = $ this ->config ->getSystemValueBool ('localstorage.case_insensitive ' , false );
9699
97100 // support Write-Once-Read-Many file systems
98101 $ this ->unlinkOnTruncate = $ this ->config ->getSystemValueBool ('localstorage.unlink_on_truncate ' , false );
@@ -162,13 +165,19 @@ public function opendir($path) {
162165 }
163166
164167 public function is_dir ($ path ) {
168+ if ($ this ->caseInsensitive && !$ this ->file_exists ($ path )) {
169+ return false ;
170+ }
165171 if (str_ends_with ($ path , '/ ' )) {
166172 $ path = substr ($ path , 0 , -1 );
167173 }
168174 return is_dir ($ this ->getSourcePath ($ path ));
169175 }
170176
171177 public function is_file ($ path ) {
178+ if ($ this ->caseInsensitive && !$ this ->file_exists ($ path )) {
179+ return false ;
180+ }
172181 return is_file ($ this ->getSourcePath ($ path ));
173182 }
174183
@@ -271,7 +280,13 @@ public function isUpdatable($path) {
271280 }
272281
273282 public function file_exists ($ path ) {
274- return file_exists ($ this ->getSourcePath ($ path ));
283+ if ($ this ->caseInsensitive ) {
284+ $ fullPath = $ this ->getSourcePath ($ path );
285+ $ content = scandir (dirname ($ fullPath ), SCANDIR_SORT_NONE );
286+ return is_array ($ content ) && array_search (basename ($ fullPath ), $ content ) !== false ;
287+ } else {
288+ return file_exists ($ this ->getSourcePath ($ path ));
289+ }
275290 }
276291
277292 public function filemtime ($ path ) {
@@ -372,6 +387,11 @@ public function rename($source, $target): bool {
372387 }
373388
374389 if (@rename ($ this ->getSourcePath ($ source ), $ this ->getSourcePath ($ target ))) {
390+ if ($ this ->caseInsensitive ) {
391+ if (mb_strtolower ($ target ) === mb_strtolower ($ source ) && !$ this ->file_exists ($ target )) {
392+ return false ;
393+ }
394+ }
375395 return true ;
376396 }
377397
@@ -388,6 +408,11 @@ public function copy($source, $target) {
388408 }
389409 $ result = copy ($ this ->getSourcePath ($ source ), $ this ->getSourcePath ($ target ));
390410 umask ($ oldMask );
411+ if ($ this ->caseInsensitive ) {
412+ if (mb_strtolower ($ target ) === mb_strtolower ($ source ) && !$ this ->file_exists ($ target )) {
413+ return false ;
414+ }
415+ }
391416 return $ result ;
392417 }
393418 }
0 commit comments