diff options
author | Robin Appelman <robin@icewind.nl> | 2024-04-08 14:55:49 +0200 |
---|---|---|
committer | Robin Appelman <robin@icewind.nl> | 2024-04-08 14:55:49 +0200 |
commit | 77cd7560a5392a28f6a496fc1a2a360eda256af1 (patch) | |
tree | 98431cd7e3e91d053ca5ccd6f96db91d56c1a489 | |
parent | e10853450e4f327d146c2874f175d2a9102a959a (diff) | |
download | nextcloud-server-path-available.tar.gz nextcloud-server-path-available.zip |
add a seperate storage method to distinguish between 'path exists' and 'path is available'path-available
Signed-off-by: Robin Appelman <robin@icewind.nl>
-rw-r--r-- | lib/private/Files/Storage/Common.php | 4 | ||||
-rw-r--r-- | lib/private/Files/Storage/Local.php | 9 | ||||
-rw-r--r-- | lib/private/Files/Storage/Storage.php | 12 |
3 files changed, 24 insertions, 1 deletions
diff --git a/lib/private/Files/Storage/Common.php b/lib/private/Files/Storage/Common.php index c236541390f..7ffcd25ac0a 100644 --- a/lib/private/Files/Storage/Common.php +++ b/lib/private/Files/Storage/Common.php @@ -919,4 +919,8 @@ abstract class Common implements Storage, ILockingStorage, IWriteStreamStorage { } } } + + public function pathAvailable(string $path): bool { + return !$this->file_exists($path); + } } diff --git a/lib/private/Files/Storage/Local.php b/lib/private/Files/Storage/Local.php index 909b124ff64..3d06ac0e206 100644 --- a/lib/private/Files/Storage/Local.php +++ b/lib/private/Files/Storage/Local.php @@ -95,7 +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); + $this->caseInsensitive = $arguments['case_insensitive'] ?? $this->config->getSystemValueBool('localstorage.case_insensitive', false); // support Write-Once-Read-Many file systems $this->unlinkOnTruncate = $this->config->getSystemValueBool('localstorage.unlink_on_truncate', false); @@ -281,6 +281,8 @@ class Local extends \OC\Files\Storage\Common { public function file_exists($path) { if ($this->caseInsensitive) { + // if the underlying filesystem is case-insensitive, we do our own case-sensitive + // comparison to ensure our `file_exists` implementation is always case-sensitive $fullPath = $this->getSourcePath($path); $parentPath = dirname($fullPath); if (!is_dir($parentPath)) { @@ -293,6 +295,11 @@ class Local extends \OC\Files\Storage\Common { } } + public function pathAvailable(string $path): bool { + // use the native file-exists even for case-insensitive filesystems + return !file_exists($this->getSourcePath($path)); + } + public function filemtime($path) { $fullPath = $this->getSourcePath($path); clearstatcache(true, $fullPath); diff --git a/lib/private/Files/Storage/Storage.php b/lib/private/Files/Storage/Storage.php index 0a2511de164..040de66afe2 100644 --- a/lib/private/Files/Storage/Storage.php +++ b/lib/private/Files/Storage/Storage.php @@ -136,4 +136,16 @@ interface Storage extends \OCP\Files\Storage { * - permissions */ public function getDirectoryContent($directory): \Traversable; + + /** + * Check if a filepath is available/unused + * + * This is usually the inverse of `file_exists` but some filesystems might have additional restrictions for + * which file names are available. + * For example with case-insensitive filesystems where names that only differ by case would conflict. + * + * @param string $path + * @return bool + */ + public function pathAvailable(string $path): bool; } |