@@ -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