aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobin Appelman <robin@icewind.nl>2024-04-08 14:55:49 +0200
committerRobin Appelman <robin@icewind.nl>2024-04-08 14:55:49 +0200
commit77cd7560a5392a28f6a496fc1a2a360eda256af1 (patch)
tree98431cd7e3e91d053ca5ccd6f96db91d56c1a489
parente10853450e4f327d146c2874f175d2a9102a959a (diff)
downloadnextcloud-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.php4
-rw-r--r--lib/private/Files/Storage/Local.php9
-rw-r--r--lib/private/Files/Storage/Storage.php12
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;
}