Completed
Push — master ( 333060...2a9e00 )
by Morris
14:18
created
lib/private/Files/Storage/Local.php 3 patches
Braces   +3 added lines, -2 removed lines patch added patch discarded remove patch
@@ -317,8 +317,9 @@
 block discarded – undo
317 317
 		$files = array();
318 318
 		$physicalDir = $this->getSourcePath($dir);
319 319
 		foreach (scandir($physicalDir) as $item) {
320
-			if (\OC\Files\Filesystem::isIgnoredDir($item))
321
-				continue;
320
+			if (\OC\Files\Filesystem::isIgnoredDir($item)) {
321
+							continue;
322
+			}
322 323
 			$physicalItem = $physicalDir . '/' . $item;
323 324
 
324 325
 			if (strstr(strtolower($item), strtolower($query)) !== false) {
Please login to merge, or discard this patch.
Indentation   +414 added lines, -414 removed lines patch added patch discarded remove patch
@@ -48,418 +48,418 @@
 block discarded – undo
48 48
  * for local filestore, we only have to map the paths
49 49
  */
50 50
 class Local extends \OC\Files\Storage\Common {
51
-	protected $datadir;
52
-
53
-	protected $dataDirLength;
54
-
55
-	protected $allowSymlinks = false;
56
-
57
-	protected $realDataDir;
58
-
59
-	public function __construct($arguments) {
60
-		if (!isset($arguments['datadir']) || !is_string($arguments['datadir'])) {
61
-			throw new \InvalidArgumentException('No data directory set for local storage');
62
-		}
63
-		$this->datadir = str_replace('//', '/', $arguments['datadir']);
64
-		// some crazy code uses a local storage on root...
65
-		if ($this->datadir === '/') {
66
-			$this->realDataDir = $this->datadir;
67
-		} else {
68
-			$realPath = realpath($this->datadir) ?: $this->datadir;
69
-			$this->realDataDir = rtrim($realPath, '/') . '/';
70
-		}
71
-		if (substr($this->datadir, -1) !== '/') {
72
-			$this->datadir .= '/';
73
-		}
74
-		$this->dataDirLength = strlen($this->realDataDir);
75
-	}
76
-
77
-	public function __destruct() {
78
-	}
79
-
80
-	public function getId() {
81
-		return 'local::' . $this->datadir;
82
-	}
83
-
84
-	public function mkdir($path) {
85
-		return @mkdir($this->getSourcePath($path), 0777, true);
86
-	}
87
-
88
-	public function rmdir($path) {
89
-		if (!$this->isDeletable($path)) {
90
-			return false;
91
-		}
92
-		try {
93
-			$it = new \RecursiveIteratorIterator(
94
-				new \RecursiveDirectoryIterator($this->getSourcePath($path)),
95
-				\RecursiveIteratorIterator::CHILD_FIRST
96
-			);
97
-			/**
98
-			 * RecursiveDirectoryIterator on an NFS path isn't iterable with foreach
99
-			 * This bug is fixed in PHP 5.5.9 or before
100
-			 * See #8376
101
-			 */
102
-			$it->rewind();
103
-			while ($it->valid()) {
104
-				/**
105
-				 * @var \SplFileInfo $file
106
-				 */
107
-				$file = $it->current();
108
-				if (in_array($file->getBasename(), array('.', '..'))) {
109
-					$it->next();
110
-					continue;
111
-				} elseif ($file->isDir()) {
112
-					rmdir($file->getPathname());
113
-				} elseif ($file->isFile() || $file->isLink()) {
114
-					unlink($file->getPathname());
115
-				}
116
-				$it->next();
117
-			}
118
-			return rmdir($this->getSourcePath($path));
119
-		} catch (\UnexpectedValueException $e) {
120
-			return false;
121
-		}
122
-	}
123
-
124
-	public function opendir($path) {
125
-		return opendir($this->getSourcePath($path));
126
-	}
127
-
128
-	public function is_dir($path) {
129
-		if (substr($path, -1) == '/') {
130
-			$path = substr($path, 0, -1);
131
-		}
132
-		return is_dir($this->getSourcePath($path));
133
-	}
134
-
135
-	public function is_file($path) {
136
-		return is_file($this->getSourcePath($path));
137
-	}
138
-
139
-	public function stat($path) {
140
-		clearstatcache();
141
-		$fullPath = $this->getSourcePath($path);
142
-		$statResult = stat($fullPath);
143
-		if (PHP_INT_SIZE === 4 && !$this->is_dir($path)) {
144
-			$filesize = $this->filesize($path);
145
-			$statResult['size'] = $filesize;
146
-			$statResult[7] = $filesize;
147
-		}
148
-		return $statResult;
149
-	}
150
-
151
-	public function filetype($path) {
152
-		$filetype = filetype($this->getSourcePath($path));
153
-		if ($filetype == 'link') {
154
-			$filetype = filetype(realpath($this->getSourcePath($path)));
155
-		}
156
-		return $filetype;
157
-	}
158
-
159
-	public function filesize($path) {
160
-		if ($this->is_dir($path)) {
161
-			return 0;
162
-		}
163
-		$fullPath = $this->getSourcePath($path);
164
-		if (PHP_INT_SIZE === 4) {
165
-			$helper = new \OC\LargeFileHelper;
166
-			return $helper->getFileSize($fullPath);
167
-		}
168
-		return filesize($fullPath);
169
-	}
170
-
171
-	public function isReadable($path) {
172
-		return is_readable($this->getSourcePath($path));
173
-	}
174
-
175
-	public function isUpdatable($path) {
176
-		return is_writable($this->getSourcePath($path));
177
-	}
178
-
179
-	public function file_exists($path) {
180
-		return file_exists($this->getSourcePath($path));
181
-	}
182
-
183
-	public function filemtime($path) {
184
-		$fullPath = $this->getSourcePath($path);
185
-		clearstatcache(true, $fullPath);
186
-		if (!$this->file_exists($path)) {
187
-			return false;
188
-		}
189
-		if (PHP_INT_SIZE === 4) {
190
-			$helper = new \OC\LargeFileHelper();
191
-			return $helper->getFileMtime($fullPath);
192
-		}
193
-		return filemtime($fullPath);
194
-	}
195
-
196
-	public function touch($path, $mtime = null) {
197
-		// sets the modification time of the file to the given value.
198
-		// If mtime is nil the current time is set.
199
-		// note that the access time of the file always changes to the current time.
200
-		if ($this->file_exists($path) and !$this->isUpdatable($path)) {
201
-			return false;
202
-		}
203
-		if (!is_null($mtime)) {
204
-			$result = touch($this->getSourcePath($path), $mtime);
205
-		} else {
206
-			$result = touch($this->getSourcePath($path));
207
-		}
208
-		if ($result) {
209
-			clearstatcache(true, $this->getSourcePath($path));
210
-		}
211
-
212
-		return $result;
213
-	}
214
-
215
-	public function file_get_contents($path) {
216
-		return file_get_contents($this->getSourcePath($path));
217
-	}
218
-
219
-	public function file_put_contents($path, $data) {
220
-		return file_put_contents($this->getSourcePath($path), $data);
221
-	}
222
-
223
-	public function unlink($path) {
224
-		if ($this->is_dir($path)) {
225
-			return $this->rmdir($path);
226
-		} else if ($this->is_file($path)) {
227
-			return unlink($this->getSourcePath($path));
228
-		} else {
229
-			return false;
230
-		}
231
-
232
-	}
233
-
234
-	public function rename($path1, $path2) {
235
-		$srcParent = dirname($path1);
236
-		$dstParent = dirname($path2);
237
-
238
-		if (!$this->isUpdatable($srcParent)) {
239
-			\OCP\Util::writeLog('core', 'unable to rename, source directory is not writable : ' . $srcParent, ILogger::ERROR);
240
-			return false;
241
-		}
242
-
243
-		if (!$this->isUpdatable($dstParent)) {
244
-			\OCP\Util::writeLog('core', 'unable to rename, destination directory is not writable : ' . $dstParent, ILogger::ERROR);
245
-			return false;
246
-		}
247
-
248
-		if (!$this->file_exists($path1)) {
249
-			\OCP\Util::writeLog('core', 'unable to rename, file does not exists : ' . $path1, ILogger::ERROR);
250
-			return false;
251
-		}
252
-
253
-		if ($this->is_dir($path2)) {
254
-			$this->rmdir($path2);
255
-		} else if ($this->is_file($path2)) {
256
-			$this->unlink($path2);
257
-		}
258
-
259
-		if ($this->is_dir($path1)) {
260
-			// we can't move folders across devices, use copy instead
261
-			$stat1 = stat(dirname($this->getSourcePath($path1)));
262
-			$stat2 = stat(dirname($this->getSourcePath($path2)));
263
-			if ($stat1['dev'] !== $stat2['dev']) {
264
-				$result = $this->copy($path1, $path2);
265
-				if ($result) {
266
-					$result &= $this->rmdir($path1);
267
-				}
268
-				return $result;
269
-			}
270
-		}
271
-
272
-		return rename($this->getSourcePath($path1), $this->getSourcePath($path2));
273
-	}
274
-
275
-	public function copy($path1, $path2) {
276
-		if ($this->is_dir($path1)) {
277
-			return parent::copy($path1, $path2);
278
-		} else {
279
-			return copy($this->getSourcePath($path1), $this->getSourcePath($path2));
280
-		}
281
-	}
282
-
283
-	public function fopen($path, $mode) {
284
-		return fopen($this->getSourcePath($path), $mode);
285
-	}
286
-
287
-	public function hash($type, $path, $raw = false) {
288
-		return hash_file($type, $this->getSourcePath($path), $raw);
289
-	}
290
-
291
-	public function free_space($path) {
292
-		$sourcePath = $this->getSourcePath($path);
293
-		// using !is_dir because $sourcePath might be a part file or
294
-		// non-existing file, so we'd still want to use the parent dir
295
-		// in such cases
296
-		if (!is_dir($sourcePath)) {
297
-			// disk_free_space doesn't work on files
298
-			$sourcePath = dirname($sourcePath);
299
-		}
300
-		$space = @disk_free_space($sourcePath);
301
-		if ($space === false || is_null($space)) {
302
-			return \OCP\Files\FileInfo::SPACE_UNKNOWN;
303
-		}
304
-		return $space;
305
-	}
306
-
307
-	public function search($query) {
308
-		return $this->searchInDir($query);
309
-	}
310
-
311
-	public function getLocalFile($path) {
312
-		return $this->getSourcePath($path);
313
-	}
314
-
315
-	public function getLocalFolder($path) {
316
-		return $this->getSourcePath($path);
317
-	}
318
-
319
-	/**
320
-	 * @param string $query
321
-	 * @param string $dir
322
-	 * @return array
323
-	 */
324
-	protected function searchInDir($query, $dir = '') {
325
-		$files = array();
326
-		$physicalDir = $this->getSourcePath($dir);
327
-		foreach (scandir($physicalDir) as $item) {
328
-			if (\OC\Files\Filesystem::isIgnoredDir($item))
329
-				continue;
330
-			$physicalItem = $physicalDir . '/' . $item;
331
-
332
-			if (strstr(strtolower($item), strtolower($query)) !== false) {
333
-				$files[] = $dir . '/' . $item;
334
-			}
335
-			if (is_dir($physicalItem)) {
336
-				$files = array_merge($files, $this->searchInDir($query, $dir . '/' . $item));
337
-			}
338
-		}
339
-		return $files;
340
-	}
341
-
342
-	/**
343
-	 * check if a file or folder has been updated since $time
344
-	 *
345
-	 * @param string $path
346
-	 * @param int $time
347
-	 * @return bool
348
-	 */
349
-	public function hasUpdated($path, $time) {
350
-		if ($this->file_exists($path)) {
351
-			return $this->filemtime($path) > $time;
352
-		} else {
353
-			return true;
354
-		}
355
-	}
356
-
357
-	/**
358
-	 * Get the source path (on disk) of a given path
359
-	 *
360
-	 * @param string $path
361
-	 * @return string
362
-	 * @throws ForbiddenException
363
-	 */
364
-	public function getSourcePath($path) {
365
-		$fullPath = $this->datadir . $path;
366
-		$currentPath = $path;
367
-		if ($this->allowSymlinks || $currentPath === '') {
368
-			return $fullPath;
369
-		}
370
-		$pathToResolve = $fullPath;
371
-		$realPath = realpath($pathToResolve);
372
-		while ($realPath === false) { // for non existing files check the parent directory
373
-			$currentPath = dirname($currentPath);
374
-			if ($currentPath === '' || $currentPath === '.') {
375
-				return $fullPath;
376
-			}
377
-			$realPath = realpath($this->datadir . $currentPath);
378
-		}
379
-		if ($realPath) {
380
-			$realPath = $realPath . '/';
381
-		}
382
-		if (substr($realPath, 0, $this->dataDirLength) === $this->realDataDir) {
383
-			return $fullPath;
384
-		}
385
-
386
-		\OCP\Util::writeLog('core', "Following symlinks is not allowed ('$fullPath' -> '$realPath' not inside '{$this->realDataDir}')", ILogger::ERROR);
387
-		throw new ForbiddenException('Following symlinks is not allowed', false);
388
-	}
389
-
390
-	/**
391
-	 * {@inheritdoc}
392
-	 */
393
-	public function isLocal() {
394
-		return true;
395
-	}
396
-
397
-	/**
398
-	 * get the ETag for a file or folder
399
-	 *
400
-	 * @param string $path
401
-	 * @return string
402
-	 */
403
-	public function getETag($path) {
404
-		if ($this->is_file($path)) {
405
-			$stat = $this->stat($path);
406
-			return md5(
407
-				$stat['mtime'] .
408
-				$stat['ino'] .
409
-				$stat['dev'] .
410
-				$stat['size']
411
-			);
412
-		} else {
413
-			return parent::getETag($path);
414
-		}
415
-	}
416
-
417
-	/**
418
-	 * @param IStorage $sourceStorage
419
-	 * @param string $sourceInternalPath
420
-	 * @param string $targetInternalPath
421
-	 * @param bool $preserveMtime
422
-	 * @return bool
423
-	 */
424
-	public function copyFromStorage(IStorage $sourceStorage, $sourceInternalPath, $targetInternalPath, $preserveMtime = false) {
425
-		if ($sourceStorage->instanceOfStorage(Local::class)) {
426
-			if ($sourceStorage->instanceOfStorage(Jail::class)) {
427
-				/**
428
-				 * @var \OC\Files\Storage\Wrapper\Jail $sourceStorage
429
-				 */
430
-				$sourceInternalPath = $sourceStorage->getUnjailedPath($sourceInternalPath);
431
-			}
432
-			/**
433
-			 * @var \OC\Files\Storage\Local $sourceStorage
434
-			 */
435
-			$rootStorage = new Local(['datadir' => '/']);
436
-			return $rootStorage->copy($sourceStorage->getSourcePath($sourceInternalPath), $this->getSourcePath($targetInternalPath));
437
-		} else {
438
-			return parent::copyFromStorage($sourceStorage, $sourceInternalPath, $targetInternalPath);
439
-		}
440
-	}
441
-
442
-	/**
443
-	 * @param IStorage $sourceStorage
444
-	 * @param string $sourceInternalPath
445
-	 * @param string $targetInternalPath
446
-	 * @return bool
447
-	 */
448
-	public function moveFromStorage(IStorage $sourceStorage, $sourceInternalPath, $targetInternalPath) {
449
-		if ($sourceStorage->instanceOfStorage(Local::class)) {
450
-			if ($sourceStorage->instanceOfStorage(Jail::class)) {
451
-				/**
452
-				 * @var \OC\Files\Storage\Wrapper\Jail $sourceStorage
453
-				 */
454
-				$sourceInternalPath = $sourceStorage->getUnjailedPath($sourceInternalPath);
455
-			}
456
-			/**
457
-			 * @var \OC\Files\Storage\Local $sourceStorage
458
-			 */
459
-			$rootStorage = new Local(['datadir' => '/']);
460
-			return $rootStorage->rename($sourceStorage->getSourcePath($sourceInternalPath), $this->getSourcePath($targetInternalPath));
461
-		} else {
462
-			return parent::moveFromStorage($sourceStorage, $sourceInternalPath, $targetInternalPath);
463
-		}
464
-	}
51
+    protected $datadir;
52
+
53
+    protected $dataDirLength;
54
+
55
+    protected $allowSymlinks = false;
56
+
57
+    protected $realDataDir;
58
+
59
+    public function __construct($arguments) {
60
+        if (!isset($arguments['datadir']) || !is_string($arguments['datadir'])) {
61
+            throw new \InvalidArgumentException('No data directory set for local storage');
62
+        }
63
+        $this->datadir = str_replace('//', '/', $arguments['datadir']);
64
+        // some crazy code uses a local storage on root...
65
+        if ($this->datadir === '/') {
66
+            $this->realDataDir = $this->datadir;
67
+        } else {
68
+            $realPath = realpath($this->datadir) ?: $this->datadir;
69
+            $this->realDataDir = rtrim($realPath, '/') . '/';
70
+        }
71
+        if (substr($this->datadir, -1) !== '/') {
72
+            $this->datadir .= '/';
73
+        }
74
+        $this->dataDirLength = strlen($this->realDataDir);
75
+    }
76
+
77
+    public function __destruct() {
78
+    }
79
+
80
+    public function getId() {
81
+        return 'local::' . $this->datadir;
82
+    }
83
+
84
+    public function mkdir($path) {
85
+        return @mkdir($this->getSourcePath($path), 0777, true);
86
+    }
87
+
88
+    public function rmdir($path) {
89
+        if (!$this->isDeletable($path)) {
90
+            return false;
91
+        }
92
+        try {
93
+            $it = new \RecursiveIteratorIterator(
94
+                new \RecursiveDirectoryIterator($this->getSourcePath($path)),
95
+                \RecursiveIteratorIterator::CHILD_FIRST
96
+            );
97
+            /**
98
+             * RecursiveDirectoryIterator on an NFS path isn't iterable with foreach
99
+             * This bug is fixed in PHP 5.5.9 or before
100
+             * See #8376
101
+             */
102
+            $it->rewind();
103
+            while ($it->valid()) {
104
+                /**
105
+                 * @var \SplFileInfo $file
106
+                 */
107
+                $file = $it->current();
108
+                if (in_array($file->getBasename(), array('.', '..'))) {
109
+                    $it->next();
110
+                    continue;
111
+                } elseif ($file->isDir()) {
112
+                    rmdir($file->getPathname());
113
+                } elseif ($file->isFile() || $file->isLink()) {
114
+                    unlink($file->getPathname());
115
+                }
116
+                $it->next();
117
+            }
118
+            return rmdir($this->getSourcePath($path));
119
+        } catch (\UnexpectedValueException $e) {
120
+            return false;
121
+        }
122
+    }
123
+
124
+    public function opendir($path) {
125
+        return opendir($this->getSourcePath($path));
126
+    }
127
+
128
+    public function is_dir($path) {
129
+        if (substr($path, -1) == '/') {
130
+            $path = substr($path, 0, -1);
131
+        }
132
+        return is_dir($this->getSourcePath($path));
133
+    }
134
+
135
+    public function is_file($path) {
136
+        return is_file($this->getSourcePath($path));
137
+    }
138
+
139
+    public function stat($path) {
140
+        clearstatcache();
141
+        $fullPath = $this->getSourcePath($path);
142
+        $statResult = stat($fullPath);
143
+        if (PHP_INT_SIZE === 4 && !$this->is_dir($path)) {
144
+            $filesize = $this->filesize($path);
145
+            $statResult['size'] = $filesize;
146
+            $statResult[7] = $filesize;
147
+        }
148
+        return $statResult;
149
+    }
150
+
151
+    public function filetype($path) {
152
+        $filetype = filetype($this->getSourcePath($path));
153
+        if ($filetype == 'link') {
154
+            $filetype = filetype(realpath($this->getSourcePath($path)));
155
+        }
156
+        return $filetype;
157
+    }
158
+
159
+    public function filesize($path) {
160
+        if ($this->is_dir($path)) {
161
+            return 0;
162
+        }
163
+        $fullPath = $this->getSourcePath($path);
164
+        if (PHP_INT_SIZE === 4) {
165
+            $helper = new \OC\LargeFileHelper;
166
+            return $helper->getFileSize($fullPath);
167
+        }
168
+        return filesize($fullPath);
169
+    }
170
+
171
+    public function isReadable($path) {
172
+        return is_readable($this->getSourcePath($path));
173
+    }
174
+
175
+    public function isUpdatable($path) {
176
+        return is_writable($this->getSourcePath($path));
177
+    }
178
+
179
+    public function file_exists($path) {
180
+        return file_exists($this->getSourcePath($path));
181
+    }
182
+
183
+    public function filemtime($path) {
184
+        $fullPath = $this->getSourcePath($path);
185
+        clearstatcache(true, $fullPath);
186
+        if (!$this->file_exists($path)) {
187
+            return false;
188
+        }
189
+        if (PHP_INT_SIZE === 4) {
190
+            $helper = new \OC\LargeFileHelper();
191
+            return $helper->getFileMtime($fullPath);
192
+        }
193
+        return filemtime($fullPath);
194
+    }
195
+
196
+    public function touch($path, $mtime = null) {
197
+        // sets the modification time of the file to the given value.
198
+        // If mtime is nil the current time is set.
199
+        // note that the access time of the file always changes to the current time.
200
+        if ($this->file_exists($path) and !$this->isUpdatable($path)) {
201
+            return false;
202
+        }
203
+        if (!is_null($mtime)) {
204
+            $result = touch($this->getSourcePath($path), $mtime);
205
+        } else {
206
+            $result = touch($this->getSourcePath($path));
207
+        }
208
+        if ($result) {
209
+            clearstatcache(true, $this->getSourcePath($path));
210
+        }
211
+
212
+        return $result;
213
+    }
214
+
215
+    public function file_get_contents($path) {
216
+        return file_get_contents($this->getSourcePath($path));
217
+    }
218
+
219
+    public function file_put_contents($path, $data) {
220
+        return file_put_contents($this->getSourcePath($path), $data);
221
+    }
222
+
223
+    public function unlink($path) {
224
+        if ($this->is_dir($path)) {
225
+            return $this->rmdir($path);
226
+        } else if ($this->is_file($path)) {
227
+            return unlink($this->getSourcePath($path));
228
+        } else {
229
+            return false;
230
+        }
231
+
232
+    }
233
+
234
+    public function rename($path1, $path2) {
235
+        $srcParent = dirname($path1);
236
+        $dstParent = dirname($path2);
237
+
238
+        if (!$this->isUpdatable($srcParent)) {
239
+            \OCP\Util::writeLog('core', 'unable to rename, source directory is not writable : ' . $srcParent, ILogger::ERROR);
240
+            return false;
241
+        }
242
+
243
+        if (!$this->isUpdatable($dstParent)) {
244
+            \OCP\Util::writeLog('core', 'unable to rename, destination directory is not writable : ' . $dstParent, ILogger::ERROR);
245
+            return false;
246
+        }
247
+
248
+        if (!$this->file_exists($path1)) {
249
+            \OCP\Util::writeLog('core', 'unable to rename, file does not exists : ' . $path1, ILogger::ERROR);
250
+            return false;
251
+        }
252
+
253
+        if ($this->is_dir($path2)) {
254
+            $this->rmdir($path2);
255
+        } else if ($this->is_file($path2)) {
256
+            $this->unlink($path2);
257
+        }
258
+
259
+        if ($this->is_dir($path1)) {
260
+            // we can't move folders across devices, use copy instead
261
+            $stat1 = stat(dirname($this->getSourcePath($path1)));
262
+            $stat2 = stat(dirname($this->getSourcePath($path2)));
263
+            if ($stat1['dev'] !== $stat2['dev']) {
264
+                $result = $this->copy($path1, $path2);
265
+                if ($result) {
266
+                    $result &= $this->rmdir($path1);
267
+                }
268
+                return $result;
269
+            }
270
+        }
271
+
272
+        return rename($this->getSourcePath($path1), $this->getSourcePath($path2));
273
+    }
274
+
275
+    public function copy($path1, $path2) {
276
+        if ($this->is_dir($path1)) {
277
+            return parent::copy($path1, $path2);
278
+        } else {
279
+            return copy($this->getSourcePath($path1), $this->getSourcePath($path2));
280
+        }
281
+    }
282
+
283
+    public function fopen($path, $mode) {
284
+        return fopen($this->getSourcePath($path), $mode);
285
+    }
286
+
287
+    public function hash($type, $path, $raw = false) {
288
+        return hash_file($type, $this->getSourcePath($path), $raw);
289
+    }
290
+
291
+    public function free_space($path) {
292
+        $sourcePath = $this->getSourcePath($path);
293
+        // using !is_dir because $sourcePath might be a part file or
294
+        // non-existing file, so we'd still want to use the parent dir
295
+        // in such cases
296
+        if (!is_dir($sourcePath)) {
297
+            // disk_free_space doesn't work on files
298
+            $sourcePath = dirname($sourcePath);
299
+        }
300
+        $space = @disk_free_space($sourcePath);
301
+        if ($space === false || is_null($space)) {
302
+            return \OCP\Files\FileInfo::SPACE_UNKNOWN;
303
+        }
304
+        return $space;
305
+    }
306
+
307
+    public function search($query) {
308
+        return $this->searchInDir($query);
309
+    }
310
+
311
+    public function getLocalFile($path) {
312
+        return $this->getSourcePath($path);
313
+    }
314
+
315
+    public function getLocalFolder($path) {
316
+        return $this->getSourcePath($path);
317
+    }
318
+
319
+    /**
320
+     * @param string $query
321
+     * @param string $dir
322
+     * @return array
323
+     */
324
+    protected function searchInDir($query, $dir = '') {
325
+        $files = array();
326
+        $physicalDir = $this->getSourcePath($dir);
327
+        foreach (scandir($physicalDir) as $item) {
328
+            if (\OC\Files\Filesystem::isIgnoredDir($item))
329
+                continue;
330
+            $physicalItem = $physicalDir . '/' . $item;
331
+
332
+            if (strstr(strtolower($item), strtolower($query)) !== false) {
333
+                $files[] = $dir . '/' . $item;
334
+            }
335
+            if (is_dir($physicalItem)) {
336
+                $files = array_merge($files, $this->searchInDir($query, $dir . '/' . $item));
337
+            }
338
+        }
339
+        return $files;
340
+    }
341
+
342
+    /**
343
+     * check if a file or folder has been updated since $time
344
+     *
345
+     * @param string $path
346
+     * @param int $time
347
+     * @return bool
348
+     */
349
+    public function hasUpdated($path, $time) {
350
+        if ($this->file_exists($path)) {
351
+            return $this->filemtime($path) > $time;
352
+        } else {
353
+            return true;
354
+        }
355
+    }
356
+
357
+    /**
358
+     * Get the source path (on disk) of a given path
359
+     *
360
+     * @param string $path
361
+     * @return string
362
+     * @throws ForbiddenException
363
+     */
364
+    public function getSourcePath($path) {
365
+        $fullPath = $this->datadir . $path;
366
+        $currentPath = $path;
367
+        if ($this->allowSymlinks || $currentPath === '') {
368
+            return $fullPath;
369
+        }
370
+        $pathToResolve = $fullPath;
371
+        $realPath = realpath($pathToResolve);
372
+        while ($realPath === false) { // for non existing files check the parent directory
373
+            $currentPath = dirname($currentPath);
374
+            if ($currentPath === '' || $currentPath === '.') {
375
+                return $fullPath;
376
+            }
377
+            $realPath = realpath($this->datadir . $currentPath);
378
+        }
379
+        if ($realPath) {
380
+            $realPath = $realPath . '/';
381
+        }
382
+        if (substr($realPath, 0, $this->dataDirLength) === $this->realDataDir) {
383
+            return $fullPath;
384
+        }
385
+
386
+        \OCP\Util::writeLog('core', "Following symlinks is not allowed ('$fullPath' -> '$realPath' not inside '{$this->realDataDir}')", ILogger::ERROR);
387
+        throw new ForbiddenException('Following symlinks is not allowed', false);
388
+    }
389
+
390
+    /**
391
+     * {@inheritdoc}
392
+     */
393
+    public function isLocal() {
394
+        return true;
395
+    }
396
+
397
+    /**
398
+     * get the ETag for a file or folder
399
+     *
400
+     * @param string $path
401
+     * @return string
402
+     */
403
+    public function getETag($path) {
404
+        if ($this->is_file($path)) {
405
+            $stat = $this->stat($path);
406
+            return md5(
407
+                $stat['mtime'] .
408
+                $stat['ino'] .
409
+                $stat['dev'] .
410
+                $stat['size']
411
+            );
412
+        } else {
413
+            return parent::getETag($path);
414
+        }
415
+    }
416
+
417
+    /**
418
+     * @param IStorage $sourceStorage
419
+     * @param string $sourceInternalPath
420
+     * @param string $targetInternalPath
421
+     * @param bool $preserveMtime
422
+     * @return bool
423
+     */
424
+    public function copyFromStorage(IStorage $sourceStorage, $sourceInternalPath, $targetInternalPath, $preserveMtime = false) {
425
+        if ($sourceStorage->instanceOfStorage(Local::class)) {
426
+            if ($sourceStorage->instanceOfStorage(Jail::class)) {
427
+                /**
428
+                 * @var \OC\Files\Storage\Wrapper\Jail $sourceStorage
429
+                 */
430
+                $sourceInternalPath = $sourceStorage->getUnjailedPath($sourceInternalPath);
431
+            }
432
+            /**
433
+             * @var \OC\Files\Storage\Local $sourceStorage
434
+             */
435
+            $rootStorage = new Local(['datadir' => '/']);
436
+            return $rootStorage->copy($sourceStorage->getSourcePath($sourceInternalPath), $this->getSourcePath($targetInternalPath));
437
+        } else {
438
+            return parent::copyFromStorage($sourceStorage, $sourceInternalPath, $targetInternalPath);
439
+        }
440
+    }
441
+
442
+    /**
443
+     * @param IStorage $sourceStorage
444
+     * @param string $sourceInternalPath
445
+     * @param string $targetInternalPath
446
+     * @return bool
447
+     */
448
+    public function moveFromStorage(IStorage $sourceStorage, $sourceInternalPath, $targetInternalPath) {
449
+        if ($sourceStorage->instanceOfStorage(Local::class)) {
450
+            if ($sourceStorage->instanceOfStorage(Jail::class)) {
451
+                /**
452
+                 * @var \OC\Files\Storage\Wrapper\Jail $sourceStorage
453
+                 */
454
+                $sourceInternalPath = $sourceStorage->getUnjailedPath($sourceInternalPath);
455
+            }
456
+            /**
457
+             * @var \OC\Files\Storage\Local $sourceStorage
458
+             */
459
+            $rootStorage = new Local(['datadir' => '/']);
460
+            return $rootStorage->rename($sourceStorage->getSourcePath($sourceInternalPath), $this->getSourcePath($targetInternalPath));
461
+        } else {
462
+            return parent::moveFromStorage($sourceStorage, $sourceInternalPath, $targetInternalPath);
463
+        }
464
+    }
465 465
 }
Please login to merge, or discard this patch.
Spacing   +14 added lines, -14 removed lines patch added patch discarded remove patch
@@ -66,7 +66,7 @@  discard block
 block discarded – undo
66 66
 			$this->realDataDir = $this->datadir;
67 67
 		} else {
68 68
 			$realPath = realpath($this->datadir) ?: $this->datadir;
69
-			$this->realDataDir = rtrim($realPath, '/') . '/';
69
+			$this->realDataDir = rtrim($realPath, '/').'/';
70 70
 		}
71 71
 		if (substr($this->datadir, -1) !== '/') {
72 72
 			$this->datadir .= '/';
@@ -78,7 +78,7 @@  discard block
 block discarded – undo
78 78
 	}
79 79
 
80 80
 	public function getId() {
81
-		return 'local::' . $this->datadir;
81
+		return 'local::'.$this->datadir;
82 82
 	}
83 83
 
84 84
 	public function mkdir($path) {
@@ -236,17 +236,17 @@  discard block
 block discarded – undo
236 236
 		$dstParent = dirname($path2);
237 237
 
238 238
 		if (!$this->isUpdatable($srcParent)) {
239
-			\OCP\Util::writeLog('core', 'unable to rename, source directory is not writable : ' . $srcParent, ILogger::ERROR);
239
+			\OCP\Util::writeLog('core', 'unable to rename, source directory is not writable : '.$srcParent, ILogger::ERROR);
240 240
 			return false;
241 241
 		}
242 242
 
243 243
 		if (!$this->isUpdatable($dstParent)) {
244
-			\OCP\Util::writeLog('core', 'unable to rename, destination directory is not writable : ' . $dstParent, ILogger::ERROR);
244
+			\OCP\Util::writeLog('core', 'unable to rename, destination directory is not writable : '.$dstParent, ILogger::ERROR);
245 245
 			return false;
246 246
 		}
247 247
 
248 248
 		if (!$this->file_exists($path1)) {
249
-			\OCP\Util::writeLog('core', 'unable to rename, file does not exists : ' . $path1, ILogger::ERROR);
249
+			\OCP\Util::writeLog('core', 'unable to rename, file does not exists : '.$path1, ILogger::ERROR);
250 250
 			return false;
251 251
 		}
252 252
 
@@ -327,13 +327,13 @@  discard block
 block discarded – undo
327 327
 		foreach (scandir($physicalDir) as $item) {
328 328
 			if (\OC\Files\Filesystem::isIgnoredDir($item))
329 329
 				continue;
330
-			$physicalItem = $physicalDir . '/' . $item;
330
+			$physicalItem = $physicalDir.'/'.$item;
331 331
 
332 332
 			if (strstr(strtolower($item), strtolower($query)) !== false) {
333
-				$files[] = $dir . '/' . $item;
333
+				$files[] = $dir.'/'.$item;
334 334
 			}
335 335
 			if (is_dir($physicalItem)) {
336
-				$files = array_merge($files, $this->searchInDir($query, $dir . '/' . $item));
336
+				$files = array_merge($files, $this->searchInDir($query, $dir.'/'.$item));
337 337
 			}
338 338
 		}
339 339
 		return $files;
@@ -362,7 +362,7 @@  discard block
 block discarded – undo
362 362
 	 * @throws ForbiddenException
363 363
 	 */
364 364
 	public function getSourcePath($path) {
365
-		$fullPath = $this->datadir . $path;
365
+		$fullPath = $this->datadir.$path;
366 366
 		$currentPath = $path;
367 367
 		if ($this->allowSymlinks || $currentPath === '') {
368 368
 			return $fullPath;
@@ -374,10 +374,10 @@  discard block
 block discarded – undo
374 374
 			if ($currentPath === '' || $currentPath === '.') {
375 375
 				return $fullPath;
376 376
 			}
377
-			$realPath = realpath($this->datadir . $currentPath);
377
+			$realPath = realpath($this->datadir.$currentPath);
378 378
 		}
379 379
 		if ($realPath) {
380
-			$realPath = $realPath . '/';
380
+			$realPath = $realPath.'/';
381 381
 		}
382 382
 		if (substr($realPath, 0, $this->dataDirLength) === $this->realDataDir) {
383 383
 			return $fullPath;
@@ -404,9 +404,9 @@  discard block
 block discarded – undo
404 404
 		if ($this->is_file($path)) {
405 405
 			$stat = $this->stat($path);
406 406
 			return md5(
407
-				$stat['mtime'] .
408
-				$stat['ino'] .
409
-				$stat['dev'] .
407
+				$stat['mtime'].
408
+				$stat['ino'].
409
+				$stat['dev'].
410 410
 				$stat['size']
411 411
 			);
412 412
 		} else {
Please login to merge, or discard this patch.
lib/private/Files/Storage/LocalTempFileTrait.php 1 patch
Indentation   +38 added lines, -38 removed lines patch added patch discarded remove patch
@@ -37,45 +37,45 @@
 block discarded – undo
37 37
  */
38 38
 trait LocalTempFileTrait {
39 39
 
40
-	/** @var string[] */
41
-	protected $cachedFiles = [];
40
+    /** @var string[] */
41
+    protected $cachedFiles = [];
42 42
 
43
-	/**
44
-	 * @param string $path
45
-	 * @return string
46
-	 */
47
-	protected function getCachedFile($path) {
48
-		if (!isset($this->cachedFiles[$path])) {
49
-			$this->cachedFiles[$path] = $this->toTmpFile($path);
50
-		}
51
-		return $this->cachedFiles[$path];
52
-	}
43
+    /**
44
+     * @param string $path
45
+     * @return string
46
+     */
47
+    protected function getCachedFile($path) {
48
+        if (!isset($this->cachedFiles[$path])) {
49
+            $this->cachedFiles[$path] = $this->toTmpFile($path);
50
+        }
51
+        return $this->cachedFiles[$path];
52
+    }
53 53
 
54
-	/**
55
-	 * @param string $path
56
-	 */
57
-	protected function removeCachedFile($path) {
58
-		unset($this->cachedFiles[$path]);
59
-	}
54
+    /**
55
+     * @param string $path
56
+     */
57
+    protected function removeCachedFile($path) {
58
+        unset($this->cachedFiles[$path]);
59
+    }
60 60
 
61
-	/**
62
-	 * @param string $path
63
-	 * @return string
64
-	 */
65
-	protected function toTmpFile($path) { //no longer in the storage api, still useful here
66
-		$source = $this->fopen($path, 'r');
67
-		if (!$source) {
68
-			return false;
69
-		}
70
-		if ($pos = strrpos($path, '.')) {
71
-			$extension = substr($path, $pos);
72
-		} else {
73
-			$extension = '';
74
-		}
75
-		$tmpFile = \OC::$server->getTempManager()->getTemporaryFile($extension);
76
-		$target = fopen($tmpFile, 'w');
77
-		\OC_Helper::streamCopy($source, $target);
78
-		fclose($target);
79
-		return $tmpFile;
80
-	}
61
+    /**
62
+     * @param string $path
63
+     * @return string
64
+     */
65
+    protected function toTmpFile($path) { //no longer in the storage api, still useful here
66
+        $source = $this->fopen($path, 'r');
67
+        if (!$source) {
68
+            return false;
69
+        }
70
+        if ($pos = strrpos($path, '.')) {
71
+            $extension = substr($path, $pos);
72
+        } else {
73
+            $extension = '';
74
+        }
75
+        $tmpFile = \OC::$server->getTempManager()->getTemporaryFile($extension);
76
+        $target = fopen($tmpFile, 'w');
77
+        \OC_Helper::streamCopy($source, $target);
78
+        fclose($target);
79
+        return $tmpFile;
80
+    }
81 81
 }
Please login to merge, or discard this patch.
lib/private/Files/Storage/Common.php 3 patches
Braces   +3 added lines, -1 removed lines patch added patch discarded remove patch
@@ -289,7 +289,9 @@
 block discarded – undo
289 289
 		$dh = $this->opendir($dir);
290 290
 		if (is_resource($dh)) {
291 291
 			while (($item = readdir($dh)) !== false) {
292
-				if (\OC\Files\Filesystem::isIgnoredDir($item)) continue;
292
+				if (\OC\Files\Filesystem::isIgnoredDir($item)) {
293
+				    continue;
294
+				}
293 295
 				if (strstr(strtolower($item), strtolower($query)) !== false) {
294 296
 					$files[] = $dir . '/' . $item;
295 297
 				}
Please login to merge, or discard this patch.
Indentation   +734 added lines, -734 removed lines patch added patch discarded remove patch
@@ -71,742 +71,742 @@
 block discarded – undo
71 71
  */
72 72
 abstract class Common implements Storage, ILockingStorage {
73 73
 
74
-	use LocalTempFileTrait;
75
-
76
-	protected $cache;
77
-	protected $scanner;
78
-	protected $watcher;
79
-	protected $propagator;
80
-	protected $storageCache;
81
-	protected $updater;
82
-
83
-	protected $mountOptions = [];
84
-	protected $owner = null;
85
-
86
-	private $shouldLogLocks = null;
87
-	private $logger;
88
-
89
-	public function __construct($parameters) {
90
-	}
91
-
92
-	/**
93
-	 * Remove a file or folder
94
-	 *
95
-	 * @param string $path
96
-	 * @return bool
97
-	 */
98
-	protected function remove($path) {
99
-		if ($this->is_dir($path)) {
100
-			return $this->rmdir($path);
101
-		} else if ($this->is_file($path)) {
102
-			return $this->unlink($path);
103
-		} else {
104
-			return false;
105
-		}
106
-	}
107
-
108
-	public function is_dir($path) {
109
-		return $this->filetype($path) === 'dir';
110
-	}
111
-
112
-	public function is_file($path) {
113
-		return $this->filetype($path) === 'file';
114
-	}
115
-
116
-	public function filesize($path) {
117
-		if ($this->is_dir($path)) {
118
-			return 0; //by definition
119
-		} else {
120
-			$stat = $this->stat($path);
121
-			if (isset($stat['size'])) {
122
-				return $stat['size'];
123
-			} else {
124
-				return 0;
125
-			}
126
-		}
127
-	}
128
-
129
-	public function isReadable($path) {
130
-		// at least check whether it exists
131
-		// subclasses might want to implement this more thoroughly
132
-		return $this->file_exists($path);
133
-	}
134
-
135
-	public function isUpdatable($path) {
136
-		// at least check whether it exists
137
-		// subclasses might want to implement this more thoroughly
138
-		// a non-existing file/folder isn't updatable
139
-		return $this->file_exists($path);
140
-	}
141
-
142
-	public function isCreatable($path) {
143
-		if ($this->is_dir($path) && $this->isUpdatable($path)) {
144
-			return true;
145
-		}
146
-		return false;
147
-	}
148
-
149
-	public function isDeletable($path) {
150
-		if ($path === '' || $path === '/') {
151
-			return false;
152
-		}
153
-		$parent = dirname($path);
154
-		return $this->isUpdatable($parent) && $this->isUpdatable($path);
155
-	}
156
-
157
-	public function isSharable($path) {
158
-		return $this->isReadable($path);
159
-	}
160
-
161
-	public function getPermissions($path) {
162
-		$permissions = 0;
163
-		if ($this->isCreatable($path)) {
164
-			$permissions |= \OCP\Constants::PERMISSION_CREATE;
165
-		}
166
-		if ($this->isReadable($path)) {
167
-			$permissions |= \OCP\Constants::PERMISSION_READ;
168
-		}
169
-		if ($this->isUpdatable($path)) {
170
-			$permissions |= \OCP\Constants::PERMISSION_UPDATE;
171
-		}
172
-		if ($this->isDeletable($path)) {
173
-			$permissions |= \OCP\Constants::PERMISSION_DELETE;
174
-		}
175
-		if ($this->isSharable($path)) {
176
-			$permissions |= \OCP\Constants::PERMISSION_SHARE;
177
-		}
178
-		return $permissions;
179
-	}
180
-
181
-	public function filemtime($path) {
182
-		$stat = $this->stat($path);
183
-		if (isset($stat['mtime']) && $stat['mtime'] > 0) {
184
-			return $stat['mtime'];
185
-		} else {
186
-			return 0;
187
-		}
188
-	}
189
-
190
-	public function file_get_contents($path) {
191
-		$handle = $this->fopen($path, "r");
192
-		if (!$handle) {
193
-			return false;
194
-		}
195
-		$data = stream_get_contents($handle);
196
-		fclose($handle);
197
-		return $data;
198
-	}
199
-
200
-	public function file_put_contents($path, $data) {
201
-		$handle = $this->fopen($path, "w");
202
-		$this->removeCachedFile($path);
203
-		$count = fwrite($handle, $data);
204
-		fclose($handle);
205
-		return $count;
206
-	}
207
-
208
-	public function rename($path1, $path2) {
209
-		$this->remove($path2);
210
-
211
-		$this->removeCachedFile($path1);
212
-		return $this->copy($path1, $path2) and $this->remove($path1);
213
-	}
214
-
215
-	public function copy($path1, $path2) {
216
-		if ($this->is_dir($path1)) {
217
-			$this->remove($path2);
218
-			$dir = $this->opendir($path1);
219
-			$this->mkdir($path2);
220
-			while ($file = readdir($dir)) {
221
-				if (!Filesystem::isIgnoredDir($file)) {
222
-					if (!$this->copy($path1 . '/' . $file, $path2 . '/' . $file)) {
223
-						return false;
224
-					}
225
-				}
226
-			}
227
-			closedir($dir);
228
-			return true;
229
-		} else {
230
-			$source = $this->fopen($path1, 'r');
231
-			$target = $this->fopen($path2, 'w');
232
-			list(, $result) = \OC_Helper::streamCopy($source, $target);
233
-			if (!$result) {
234
-				\OC::$server->getLogger()->warning("Failed to write data while copying $path1 to $path2");
235
-			}
236
-			$this->removeCachedFile($path2);
237
-			return $result;
238
-		}
239
-	}
240
-
241
-	public function getMimeType($path) {
242
-		if ($this->is_dir($path)) {
243
-			return 'httpd/unix-directory';
244
-		} elseif ($this->file_exists($path)) {
245
-			return \OC::$server->getMimeTypeDetector()->detectPath($path);
246
-		} else {
247
-			return false;
248
-		}
249
-	}
250
-
251
-	public function hash($type, $path, $raw = false) {
252
-		$fh = $this->fopen($path, 'rb');
253
-		$ctx = hash_init($type);
254
-		hash_update_stream($ctx, $fh);
255
-		fclose($fh);
256
-		return hash_final($ctx, $raw);
257
-	}
258
-
259
-	public function search($query) {
260
-		return $this->searchInDir($query);
261
-	}
262
-
263
-	public function getLocalFile($path) {
264
-		return $this->getCachedFile($path);
265
-	}
266
-
267
-	/**
268
-	 * @param string $path
269
-	 * @param string $target
270
-	 */
271
-	private function addLocalFolder($path, $target) {
272
-		$dh = $this->opendir($path);
273
-		if (is_resource($dh)) {
274
-			while (($file = readdir($dh)) !== false) {
275
-				if (!\OC\Files\Filesystem::isIgnoredDir($file)) {
276
-					if ($this->is_dir($path . '/' . $file)) {
277
-						mkdir($target . '/' . $file);
278
-						$this->addLocalFolder($path . '/' . $file, $target . '/' . $file);
279
-					} else {
280
-						$tmp = $this->toTmpFile($path . '/' . $file);
281
-						rename($tmp, $target . '/' . $file);
282
-					}
283
-				}
284
-			}
285
-		}
286
-	}
287
-
288
-	/**
289
-	 * @param string $query
290
-	 * @param string $dir
291
-	 * @return array
292
-	 */
293
-	protected function searchInDir($query, $dir = '') {
294
-		$files = array();
295
-		$dh = $this->opendir($dir);
296
-		if (is_resource($dh)) {
297
-			while (($item = readdir($dh)) !== false) {
298
-				if (\OC\Files\Filesystem::isIgnoredDir($item)) continue;
299
-				if (strstr(strtolower($item), strtolower($query)) !== false) {
300
-					$files[] = $dir . '/' . $item;
301
-				}
302
-				if ($this->is_dir($dir . '/' . $item)) {
303
-					$files = array_merge($files, $this->searchInDir($query, $dir . '/' . $item));
304
-				}
305
-			}
306
-		}
307
-		closedir($dh);
308
-		return $files;
309
-	}
310
-
311
-	/**
312
-	 * check if a file or folder has been updated since $time
313
-	 *
314
-	 * The method is only used to check if the cache needs to be updated. Storage backends that don't support checking
315
-	 * the mtime should always return false here. As a result storage implementations that always return false expect
316
-	 * exclusive access to the backend and will not pick up files that have been added in a way that circumvents
317
-	 * ownClouds filesystem.
318
-	 *
319
-	 * @param string $path
320
-	 * @param int $time
321
-	 * @return bool
322
-	 */
323
-	public function hasUpdated($path, $time) {
324
-		return $this->filemtime($path) > $time;
325
-	}
326
-
327
-	public function getCache($path = '', $storage = null) {
328
-		if (!$storage) {
329
-			$storage = $this;
330
-		}
331
-		if (!isset($storage->cache)) {
332
-			$storage->cache = new Cache($storage);
333
-		}
334
-		return $storage->cache;
335
-	}
336
-
337
-	public function getScanner($path = '', $storage = null) {
338
-		if (!$storage) {
339
-			$storage = $this;
340
-		}
341
-		if (!isset($storage->scanner)) {
342
-			$storage->scanner = new Scanner($storage);
343
-		}
344
-		return $storage->scanner;
345
-	}
346
-
347
-	public function getWatcher($path = '', $storage = null) {
348
-		if (!$storage) {
349
-			$storage = $this;
350
-		}
351
-		if (!isset($this->watcher)) {
352
-			$this->watcher = new Watcher($storage);
353
-			$globalPolicy = \OC::$server->getConfig()->getSystemValue('filesystem_check_changes', Watcher::CHECK_NEVER);
354
-			$this->watcher->setPolicy((int)$this->getMountOption('filesystem_check_changes', $globalPolicy));
355
-		}
356
-		return $this->watcher;
357
-	}
358
-
359
-	/**
360
-	 * get a propagator instance for the cache
361
-	 *
362
-	 * @param \OC\Files\Storage\Storage (optional) the storage to pass to the watcher
363
-	 * @return \OC\Files\Cache\Propagator
364
-	 */
365
-	public function getPropagator($storage = null) {
366
-		if (!$storage) {
367
-			$storage = $this;
368
-		}
369
-		if (!isset($storage->propagator)) {
370
-			$storage->propagator = new Propagator($storage, \OC::$server->getDatabaseConnection());
371
-		}
372
-		return $storage->propagator;
373
-	}
374
-
375
-	public function getUpdater($storage = null) {
376
-		if (!$storage) {
377
-			$storage = $this;
378
-		}
379
-		if (!isset($storage->updater)) {
380
-			$storage->updater = new Updater($storage);
381
-		}
382
-		return $storage->updater;
383
-	}
384
-
385
-	public function getStorageCache($storage = null) {
386
-		if (!$storage) {
387
-			$storage = $this;
388
-		}
389
-		if (!isset($this->storageCache)) {
390
-			$this->storageCache = new \OC\Files\Cache\Storage($storage);
391
-		}
392
-		return $this->storageCache;
393
-	}
394
-
395
-	/**
396
-	 * get the owner of a path
397
-	 *
398
-	 * @param string $path The path to get the owner
399
-	 * @return string|false uid or false
400
-	 */
401
-	public function getOwner($path) {
402
-		if ($this->owner === null) {
403
-			$this->owner = \OC_User::getUser();
404
-		}
405
-
406
-		return $this->owner;
407
-	}
408
-
409
-	/**
410
-	 * get the ETag for a file or folder
411
-	 *
412
-	 * @param string $path
413
-	 * @return string
414
-	 */
415
-	public function getETag($path) {
416
-		return uniqid();
417
-	}
418
-
419
-	/**
420
-	 * clean a path, i.e. remove all redundant '.' and '..'
421
-	 * making sure that it can't point to higher than '/'
422
-	 *
423
-	 * @param string $path The path to clean
424
-	 * @return string cleaned path
425
-	 */
426
-	public function cleanPath($path) {
427
-		if (strlen($path) == 0 or $path[0] != '/') {
428
-			$path = '/' . $path;
429
-		}
430
-
431
-		$output = array();
432
-		foreach (explode('/', $path) as $chunk) {
433
-			if ($chunk == '..') {
434
-				array_pop($output);
435
-			} else if ($chunk == '.') {
436
-			} else {
437
-				$output[] = $chunk;
438
-			}
439
-		}
440
-		return implode('/', $output);
441
-	}
442
-
443
-	/**
444
-	 * Test a storage for availability
445
-	 *
446
-	 * @return bool
447
-	 */
448
-	public function test() {
449
-		try {
450
-			if ($this->stat('')) {
451
-				return true;
452
-			}
453
-			\OC::$server->getLogger()->info("External storage not available: stat() failed");
454
-			return false;
455
-		} catch (\Exception $e) {
456
-			\OC::$server->getLogger()->info("External storage not available: " . $e->getMessage());
457
-			\OC::$server->getLogger()->logException($e, ['level' => ILogger::DEBUG]);
458
-			return false;
459
-		}
460
-	}
461
-
462
-	/**
463
-	 * get the free space in the storage
464
-	 *
465
-	 * @param string $path
466
-	 * @return int|false
467
-	 */
468
-	public function free_space($path) {
469
-		return \OCP\Files\FileInfo::SPACE_UNKNOWN;
470
-	}
471
-
472
-	/**
473
-	 * {@inheritdoc}
474
-	 */
475
-	public function isLocal() {
476
-		// the common implementation returns a temporary file by
477
-		// default, which is not local
478
-		return false;
479
-	}
480
-
481
-	/**
482
-	 * Check if the storage is an instance of $class or is a wrapper for a storage that is an instance of $class
483
-	 *
484
-	 * @param string $class
485
-	 * @return bool
486
-	 */
487
-	public function instanceOfStorage($class) {
488
-		if (ltrim($class, '\\') === 'OC\Files\Storage\Shared') {
489
-			// FIXME Temporary fix to keep existing checks working
490
-			$class = '\OCA\Files_Sharing\SharedStorage';
491
-		}
492
-		return is_a($this, $class);
493
-	}
494
-
495
-	/**
496
-	 * A custom storage implementation can return an url for direct download of a give file.
497
-	 *
498
-	 * For now the returned array can hold the parameter url - in future more attributes might follow.
499
-	 *
500
-	 * @param string $path
501
-	 * @return array|false
502
-	 */
503
-	public function getDirectDownload($path) {
504
-		return [];
505
-	}
506
-
507
-	/**
508
-	 * @inheritdoc
509
-	 * @throws InvalidPathException
510
-	 */
511
-	public function verifyPath($path, $fileName) {
512
-
513
-		// verify empty and dot files
514
-		$trimmed = trim($fileName);
515
-		if ($trimmed === '') {
516
-			throw new EmptyFileNameException();
517
-		}
518
-
519
-		if (\OC\Files\Filesystem::isIgnoredDir($trimmed)) {
520
-			throw new InvalidDirectoryException();
521
-		}
522
-
523
-		if (!\OC::$server->getDatabaseConnection()->supports4ByteText()) {
524
-			// verify database - e.g. mysql only 3-byte chars
525
-			if (preg_match('%(?:
74
+    use LocalTempFileTrait;
75
+
76
+    protected $cache;
77
+    protected $scanner;
78
+    protected $watcher;
79
+    protected $propagator;
80
+    protected $storageCache;
81
+    protected $updater;
82
+
83
+    protected $mountOptions = [];
84
+    protected $owner = null;
85
+
86
+    private $shouldLogLocks = null;
87
+    private $logger;
88
+
89
+    public function __construct($parameters) {
90
+    }
91
+
92
+    /**
93
+     * Remove a file or folder
94
+     *
95
+     * @param string $path
96
+     * @return bool
97
+     */
98
+    protected function remove($path) {
99
+        if ($this->is_dir($path)) {
100
+            return $this->rmdir($path);
101
+        } else if ($this->is_file($path)) {
102
+            return $this->unlink($path);
103
+        } else {
104
+            return false;
105
+        }
106
+    }
107
+
108
+    public function is_dir($path) {
109
+        return $this->filetype($path) === 'dir';
110
+    }
111
+
112
+    public function is_file($path) {
113
+        return $this->filetype($path) === 'file';
114
+    }
115
+
116
+    public function filesize($path) {
117
+        if ($this->is_dir($path)) {
118
+            return 0; //by definition
119
+        } else {
120
+            $stat = $this->stat($path);
121
+            if (isset($stat['size'])) {
122
+                return $stat['size'];
123
+            } else {
124
+                return 0;
125
+            }
126
+        }
127
+    }
128
+
129
+    public function isReadable($path) {
130
+        // at least check whether it exists
131
+        // subclasses might want to implement this more thoroughly
132
+        return $this->file_exists($path);
133
+    }
134
+
135
+    public function isUpdatable($path) {
136
+        // at least check whether it exists
137
+        // subclasses might want to implement this more thoroughly
138
+        // a non-existing file/folder isn't updatable
139
+        return $this->file_exists($path);
140
+    }
141
+
142
+    public function isCreatable($path) {
143
+        if ($this->is_dir($path) && $this->isUpdatable($path)) {
144
+            return true;
145
+        }
146
+        return false;
147
+    }
148
+
149
+    public function isDeletable($path) {
150
+        if ($path === '' || $path === '/') {
151
+            return false;
152
+        }
153
+        $parent = dirname($path);
154
+        return $this->isUpdatable($parent) && $this->isUpdatable($path);
155
+    }
156
+
157
+    public function isSharable($path) {
158
+        return $this->isReadable($path);
159
+    }
160
+
161
+    public function getPermissions($path) {
162
+        $permissions = 0;
163
+        if ($this->isCreatable($path)) {
164
+            $permissions |= \OCP\Constants::PERMISSION_CREATE;
165
+        }
166
+        if ($this->isReadable($path)) {
167
+            $permissions |= \OCP\Constants::PERMISSION_READ;
168
+        }
169
+        if ($this->isUpdatable($path)) {
170
+            $permissions |= \OCP\Constants::PERMISSION_UPDATE;
171
+        }
172
+        if ($this->isDeletable($path)) {
173
+            $permissions |= \OCP\Constants::PERMISSION_DELETE;
174
+        }
175
+        if ($this->isSharable($path)) {
176
+            $permissions |= \OCP\Constants::PERMISSION_SHARE;
177
+        }
178
+        return $permissions;
179
+    }
180
+
181
+    public function filemtime($path) {
182
+        $stat = $this->stat($path);
183
+        if (isset($stat['mtime']) && $stat['mtime'] > 0) {
184
+            return $stat['mtime'];
185
+        } else {
186
+            return 0;
187
+        }
188
+    }
189
+
190
+    public function file_get_contents($path) {
191
+        $handle = $this->fopen($path, "r");
192
+        if (!$handle) {
193
+            return false;
194
+        }
195
+        $data = stream_get_contents($handle);
196
+        fclose($handle);
197
+        return $data;
198
+    }
199
+
200
+    public function file_put_contents($path, $data) {
201
+        $handle = $this->fopen($path, "w");
202
+        $this->removeCachedFile($path);
203
+        $count = fwrite($handle, $data);
204
+        fclose($handle);
205
+        return $count;
206
+    }
207
+
208
+    public function rename($path1, $path2) {
209
+        $this->remove($path2);
210
+
211
+        $this->removeCachedFile($path1);
212
+        return $this->copy($path1, $path2) and $this->remove($path1);
213
+    }
214
+
215
+    public function copy($path1, $path2) {
216
+        if ($this->is_dir($path1)) {
217
+            $this->remove($path2);
218
+            $dir = $this->opendir($path1);
219
+            $this->mkdir($path2);
220
+            while ($file = readdir($dir)) {
221
+                if (!Filesystem::isIgnoredDir($file)) {
222
+                    if (!$this->copy($path1 . '/' . $file, $path2 . '/' . $file)) {
223
+                        return false;
224
+                    }
225
+                }
226
+            }
227
+            closedir($dir);
228
+            return true;
229
+        } else {
230
+            $source = $this->fopen($path1, 'r');
231
+            $target = $this->fopen($path2, 'w');
232
+            list(, $result) = \OC_Helper::streamCopy($source, $target);
233
+            if (!$result) {
234
+                \OC::$server->getLogger()->warning("Failed to write data while copying $path1 to $path2");
235
+            }
236
+            $this->removeCachedFile($path2);
237
+            return $result;
238
+        }
239
+    }
240
+
241
+    public function getMimeType($path) {
242
+        if ($this->is_dir($path)) {
243
+            return 'httpd/unix-directory';
244
+        } elseif ($this->file_exists($path)) {
245
+            return \OC::$server->getMimeTypeDetector()->detectPath($path);
246
+        } else {
247
+            return false;
248
+        }
249
+    }
250
+
251
+    public function hash($type, $path, $raw = false) {
252
+        $fh = $this->fopen($path, 'rb');
253
+        $ctx = hash_init($type);
254
+        hash_update_stream($ctx, $fh);
255
+        fclose($fh);
256
+        return hash_final($ctx, $raw);
257
+    }
258
+
259
+    public function search($query) {
260
+        return $this->searchInDir($query);
261
+    }
262
+
263
+    public function getLocalFile($path) {
264
+        return $this->getCachedFile($path);
265
+    }
266
+
267
+    /**
268
+     * @param string $path
269
+     * @param string $target
270
+     */
271
+    private function addLocalFolder($path, $target) {
272
+        $dh = $this->opendir($path);
273
+        if (is_resource($dh)) {
274
+            while (($file = readdir($dh)) !== false) {
275
+                if (!\OC\Files\Filesystem::isIgnoredDir($file)) {
276
+                    if ($this->is_dir($path . '/' . $file)) {
277
+                        mkdir($target . '/' . $file);
278
+                        $this->addLocalFolder($path . '/' . $file, $target . '/' . $file);
279
+                    } else {
280
+                        $tmp = $this->toTmpFile($path . '/' . $file);
281
+                        rename($tmp, $target . '/' . $file);
282
+                    }
283
+                }
284
+            }
285
+        }
286
+    }
287
+
288
+    /**
289
+     * @param string $query
290
+     * @param string $dir
291
+     * @return array
292
+     */
293
+    protected function searchInDir($query, $dir = '') {
294
+        $files = array();
295
+        $dh = $this->opendir($dir);
296
+        if (is_resource($dh)) {
297
+            while (($item = readdir($dh)) !== false) {
298
+                if (\OC\Files\Filesystem::isIgnoredDir($item)) continue;
299
+                if (strstr(strtolower($item), strtolower($query)) !== false) {
300
+                    $files[] = $dir . '/' . $item;
301
+                }
302
+                if ($this->is_dir($dir . '/' . $item)) {
303
+                    $files = array_merge($files, $this->searchInDir($query, $dir . '/' . $item));
304
+                }
305
+            }
306
+        }
307
+        closedir($dh);
308
+        return $files;
309
+    }
310
+
311
+    /**
312
+     * check if a file or folder has been updated since $time
313
+     *
314
+     * The method is only used to check if the cache needs to be updated. Storage backends that don't support checking
315
+     * the mtime should always return false here. As a result storage implementations that always return false expect
316
+     * exclusive access to the backend and will not pick up files that have been added in a way that circumvents
317
+     * ownClouds filesystem.
318
+     *
319
+     * @param string $path
320
+     * @param int $time
321
+     * @return bool
322
+     */
323
+    public function hasUpdated($path, $time) {
324
+        return $this->filemtime($path) > $time;
325
+    }
326
+
327
+    public function getCache($path = '', $storage = null) {
328
+        if (!$storage) {
329
+            $storage = $this;
330
+        }
331
+        if (!isset($storage->cache)) {
332
+            $storage->cache = new Cache($storage);
333
+        }
334
+        return $storage->cache;
335
+    }
336
+
337
+    public function getScanner($path = '', $storage = null) {
338
+        if (!$storage) {
339
+            $storage = $this;
340
+        }
341
+        if (!isset($storage->scanner)) {
342
+            $storage->scanner = new Scanner($storage);
343
+        }
344
+        return $storage->scanner;
345
+    }
346
+
347
+    public function getWatcher($path = '', $storage = null) {
348
+        if (!$storage) {
349
+            $storage = $this;
350
+        }
351
+        if (!isset($this->watcher)) {
352
+            $this->watcher = new Watcher($storage);
353
+            $globalPolicy = \OC::$server->getConfig()->getSystemValue('filesystem_check_changes', Watcher::CHECK_NEVER);
354
+            $this->watcher->setPolicy((int)$this->getMountOption('filesystem_check_changes', $globalPolicy));
355
+        }
356
+        return $this->watcher;
357
+    }
358
+
359
+    /**
360
+     * get a propagator instance for the cache
361
+     *
362
+     * @param \OC\Files\Storage\Storage (optional) the storage to pass to the watcher
363
+     * @return \OC\Files\Cache\Propagator
364
+     */
365
+    public function getPropagator($storage = null) {
366
+        if (!$storage) {
367
+            $storage = $this;
368
+        }
369
+        if (!isset($storage->propagator)) {
370
+            $storage->propagator = new Propagator($storage, \OC::$server->getDatabaseConnection());
371
+        }
372
+        return $storage->propagator;
373
+    }
374
+
375
+    public function getUpdater($storage = null) {
376
+        if (!$storage) {
377
+            $storage = $this;
378
+        }
379
+        if (!isset($storage->updater)) {
380
+            $storage->updater = new Updater($storage);
381
+        }
382
+        return $storage->updater;
383
+    }
384
+
385
+    public function getStorageCache($storage = null) {
386
+        if (!$storage) {
387
+            $storage = $this;
388
+        }
389
+        if (!isset($this->storageCache)) {
390
+            $this->storageCache = new \OC\Files\Cache\Storage($storage);
391
+        }
392
+        return $this->storageCache;
393
+    }
394
+
395
+    /**
396
+     * get the owner of a path
397
+     *
398
+     * @param string $path The path to get the owner
399
+     * @return string|false uid or false
400
+     */
401
+    public function getOwner($path) {
402
+        if ($this->owner === null) {
403
+            $this->owner = \OC_User::getUser();
404
+        }
405
+
406
+        return $this->owner;
407
+    }
408
+
409
+    /**
410
+     * get the ETag for a file or folder
411
+     *
412
+     * @param string $path
413
+     * @return string
414
+     */
415
+    public function getETag($path) {
416
+        return uniqid();
417
+    }
418
+
419
+    /**
420
+     * clean a path, i.e. remove all redundant '.' and '..'
421
+     * making sure that it can't point to higher than '/'
422
+     *
423
+     * @param string $path The path to clean
424
+     * @return string cleaned path
425
+     */
426
+    public function cleanPath($path) {
427
+        if (strlen($path) == 0 or $path[0] != '/') {
428
+            $path = '/' . $path;
429
+        }
430
+
431
+        $output = array();
432
+        foreach (explode('/', $path) as $chunk) {
433
+            if ($chunk == '..') {
434
+                array_pop($output);
435
+            } else if ($chunk == '.') {
436
+            } else {
437
+                $output[] = $chunk;
438
+            }
439
+        }
440
+        return implode('/', $output);
441
+    }
442
+
443
+    /**
444
+     * Test a storage for availability
445
+     *
446
+     * @return bool
447
+     */
448
+    public function test() {
449
+        try {
450
+            if ($this->stat('')) {
451
+                return true;
452
+            }
453
+            \OC::$server->getLogger()->info("External storage not available: stat() failed");
454
+            return false;
455
+        } catch (\Exception $e) {
456
+            \OC::$server->getLogger()->info("External storage not available: " . $e->getMessage());
457
+            \OC::$server->getLogger()->logException($e, ['level' => ILogger::DEBUG]);
458
+            return false;
459
+        }
460
+    }
461
+
462
+    /**
463
+     * get the free space in the storage
464
+     *
465
+     * @param string $path
466
+     * @return int|false
467
+     */
468
+    public function free_space($path) {
469
+        return \OCP\Files\FileInfo::SPACE_UNKNOWN;
470
+    }
471
+
472
+    /**
473
+     * {@inheritdoc}
474
+     */
475
+    public function isLocal() {
476
+        // the common implementation returns a temporary file by
477
+        // default, which is not local
478
+        return false;
479
+    }
480
+
481
+    /**
482
+     * Check if the storage is an instance of $class or is a wrapper for a storage that is an instance of $class
483
+     *
484
+     * @param string $class
485
+     * @return bool
486
+     */
487
+    public function instanceOfStorage($class) {
488
+        if (ltrim($class, '\\') === 'OC\Files\Storage\Shared') {
489
+            // FIXME Temporary fix to keep existing checks working
490
+            $class = '\OCA\Files_Sharing\SharedStorage';
491
+        }
492
+        return is_a($this, $class);
493
+    }
494
+
495
+    /**
496
+     * A custom storage implementation can return an url for direct download of a give file.
497
+     *
498
+     * For now the returned array can hold the parameter url - in future more attributes might follow.
499
+     *
500
+     * @param string $path
501
+     * @return array|false
502
+     */
503
+    public function getDirectDownload($path) {
504
+        return [];
505
+    }
506
+
507
+    /**
508
+     * @inheritdoc
509
+     * @throws InvalidPathException
510
+     */
511
+    public function verifyPath($path, $fileName) {
512
+
513
+        // verify empty and dot files
514
+        $trimmed = trim($fileName);
515
+        if ($trimmed === '') {
516
+            throw new EmptyFileNameException();
517
+        }
518
+
519
+        if (\OC\Files\Filesystem::isIgnoredDir($trimmed)) {
520
+            throw new InvalidDirectoryException();
521
+        }
522
+
523
+        if (!\OC::$server->getDatabaseConnection()->supports4ByteText()) {
524
+            // verify database - e.g. mysql only 3-byte chars
525
+            if (preg_match('%(?:
526 526
       \xF0[\x90-\xBF][\x80-\xBF]{2}      # planes 1-3
527 527
     | [\xF1-\xF3][\x80-\xBF]{3}          # planes 4-15
528 528
     | \xF4[\x80-\x8F][\x80-\xBF]{2}      # plane 16
529 529
 )%xs', $fileName)) {
530
-				throw new InvalidCharacterInPathException();
531
-			}
532
-		}
533
-
534
-		if (isset($fileName[255])) {
535
-			throw new FileNameTooLongException();
536
-		}
537
-
538
-		// NOTE: $path will remain unverified for now
539
-		$this->verifyPosixPath($fileName);
540
-	}
541
-
542
-	/**
543
-	 * @param string $fileName
544
-	 * @throws InvalidPathException
545
-	 */
546
-	protected function verifyPosixPath($fileName) {
547
-		$fileName = trim($fileName);
548
-		$this->scanForInvalidCharacters($fileName, "\\/");
549
-		$reservedNames = ['*'];
550
-		if (in_array($fileName, $reservedNames)) {
551
-			throw new ReservedWordException();
552
-		}
553
-	}
554
-
555
-	/**
556
-	 * @param string $fileName
557
-	 * @param string $invalidChars
558
-	 * @throws InvalidPathException
559
-	 */
560
-	private function scanForInvalidCharacters($fileName, $invalidChars) {
561
-		foreach (str_split($invalidChars) as $char) {
562
-			if (strpos($fileName, $char) !== false) {
563
-				throw new InvalidCharacterInPathException();
564
-			}
565
-		}
566
-
567
-		$sanitizedFileName = filter_var($fileName, FILTER_UNSAFE_RAW, FILTER_FLAG_STRIP_LOW);
568
-		if ($sanitizedFileName !== $fileName) {
569
-			throw new InvalidCharacterInPathException();
570
-		}
571
-	}
572
-
573
-	/**
574
-	 * @param array $options
575
-	 */
576
-	public function setMountOptions(array $options) {
577
-		$this->mountOptions = $options;
578
-	}
579
-
580
-	/**
581
-	 * @param string $name
582
-	 * @param mixed $default
583
-	 * @return mixed
584
-	 */
585
-	public function getMountOption($name, $default = null) {
586
-		return isset($this->mountOptions[$name]) ? $this->mountOptions[$name] : $default;
587
-	}
588
-
589
-	/**
590
-	 * @param IStorage $sourceStorage
591
-	 * @param string $sourceInternalPath
592
-	 * @param string $targetInternalPath
593
-	 * @param bool $preserveMtime
594
-	 * @return bool
595
-	 */
596
-	public function copyFromStorage(IStorage $sourceStorage, $sourceInternalPath, $targetInternalPath, $preserveMtime = false) {
597
-		if ($sourceStorage === $this) {
598
-			return $this->copy($sourceInternalPath, $targetInternalPath);
599
-		}
600
-
601
-		if ($sourceStorage->is_dir($sourceInternalPath)) {
602
-			$dh = $sourceStorage->opendir($sourceInternalPath);
603
-			$result = $this->mkdir($targetInternalPath);
604
-			if (is_resource($dh)) {
605
-				while ($result and ($file = readdir($dh)) !== false) {
606
-					if (!Filesystem::isIgnoredDir($file)) {
607
-						$result &= $this->copyFromStorage($sourceStorage, $sourceInternalPath . '/' . $file, $targetInternalPath . '/' . $file);
608
-					}
609
-				}
610
-			}
611
-		} else {
612
-			$source = $sourceStorage->fopen($sourceInternalPath, 'r');
613
-			// TODO: call fopen in a way that we execute again all storage wrappers
614
-			// to avoid that we bypass storage wrappers which perform important actions
615
-			// for this operation. Same is true for all other operations which
616
-			// are not the same as the original one.Once this is fixed we also
617
-			// need to adjust the encryption wrapper.
618
-			$target = $this->fopen($targetInternalPath, 'w');
619
-			list(, $result) = \OC_Helper::streamCopy($source, $target);
620
-			if ($result and $preserveMtime) {
621
-				$this->touch($targetInternalPath, $sourceStorage->filemtime($sourceInternalPath));
622
-			}
623
-			fclose($source);
624
-			fclose($target);
625
-
626
-			if (!$result) {
627
-				// delete partially written target file
628
-				$this->unlink($targetInternalPath);
629
-				// delete cache entry that was created by fopen
630
-				$this->getCache()->remove($targetInternalPath);
631
-			}
632
-		}
633
-		return (bool)$result;
634
-	}
635
-
636
-	/**
637
-	 * @param IStorage $sourceStorage
638
-	 * @param string $sourceInternalPath
639
-	 * @param string $targetInternalPath
640
-	 * @return bool
641
-	 */
642
-	public function moveFromStorage(IStorage $sourceStorage, $sourceInternalPath, $targetInternalPath) {
643
-		if ($sourceStorage === $this) {
644
-			return $this->rename($sourceInternalPath, $targetInternalPath);
645
-		}
646
-
647
-		if (!$sourceStorage->isDeletable($sourceInternalPath)) {
648
-			return false;
649
-		}
650
-
651
-		$result = $this->copyFromStorage($sourceStorage, $sourceInternalPath, $targetInternalPath, true);
652
-		if ($result) {
653
-			if ($sourceStorage->is_dir($sourceInternalPath)) {
654
-				$result &= $sourceStorage->rmdir($sourceInternalPath);
655
-			} else {
656
-				$result &= $sourceStorage->unlink($sourceInternalPath);
657
-			}
658
-		}
659
-		return $result;
660
-	}
661
-
662
-	/**
663
-	 * @inheritdoc
664
-	 */
665
-	public function getMetaData($path) {
666
-		$permissions = $this->getPermissions($path);
667
-		if (!$permissions & \OCP\Constants::PERMISSION_READ) {
668
-			//can't read, nothing we can do
669
-			return null;
670
-		}
671
-
672
-		$data = [];
673
-		$data['mimetype'] = $this->getMimeType($path);
674
-		$data['mtime'] = $this->filemtime($path);
675
-		if ($data['mtime'] === false) {
676
-			$data['mtime'] = time();
677
-		}
678
-		if ($data['mimetype'] == 'httpd/unix-directory') {
679
-			$data['size'] = -1; //unknown
680
-		} else {
681
-			$data['size'] = $this->filesize($path);
682
-		}
683
-		$data['etag'] = $this->getETag($path);
684
-		$data['storage_mtime'] = $data['mtime'];
685
-		$data['permissions'] = $permissions;
686
-
687
-		return $data;
688
-	}
689
-
690
-	/**
691
-	 * @param string $path
692
-	 * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
693
-	 * @param \OCP\Lock\ILockingProvider $provider
694
-	 * @throws \OCP\Lock\LockedException
695
-	 */
696
-	public function acquireLock($path, $type, ILockingProvider $provider) {
697
-		$logger = $this->getLockLogger();
698
-		if ($logger) {
699
-			$typeString = ($type === ILockingProvider::LOCK_SHARED) ? 'shared' : 'exclusive';
700
-			$logger->info(
701
-				sprintf(
702
-					'acquire %s lock on "%s" on storage "%s"',
703
-					$typeString,
704
-					$path,
705
-					$this->getId()
706
-				),
707
-				[
708
-					'app' => 'locking',
709
-				]
710
-			);
711
-		}
712
-		try {
713
-			$provider->acquireLock('files/' . md5($this->getId() . '::' . trim($path, '/')), $type);
714
-		} catch (LockedException $e) {
715
-			if ($logger) {
716
-				$logger->logException($e);
717
-			}
718
-			throw $e;
719
-		}
720
-	}
721
-
722
-	/**
723
-	 * @param string $path
724
-	 * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
725
-	 * @param \OCP\Lock\ILockingProvider $provider
726
-	 * @throws \OCP\Lock\LockedException
727
-	 */
728
-	public function releaseLock($path, $type, ILockingProvider $provider) {
729
-		$logger = $this->getLockLogger();
730
-		if ($logger) {
731
-			$typeString = ($type === ILockingProvider::LOCK_SHARED) ? 'shared' : 'exclusive';
732
-			$logger->info(
733
-				sprintf(
734
-					'release %s lock on "%s" on storage "%s"',
735
-					$typeString,
736
-					$path,
737
-					$this->getId()
738
-				),
739
-				[
740
-					'app' => 'locking',
741
-				]
742
-			);
743
-		}
744
-		try {
745
-			$provider->releaseLock('files/' . md5($this->getId() . '::' . trim($path, '/')), $type);
746
-		} catch (LockedException $e) {
747
-			if ($logger) {
748
-				$logger->logException($e);
749
-			}
750
-			throw $e;
751
-		}
752
-	}
753
-
754
-	/**
755
-	 * @param string $path
756
-	 * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
757
-	 * @param \OCP\Lock\ILockingProvider $provider
758
-	 * @throws \OCP\Lock\LockedException
759
-	 */
760
-	public function changeLock($path, $type, ILockingProvider $provider) {
761
-		$logger = $this->getLockLogger();
762
-		if ($logger) {
763
-			$typeString = ($type === ILockingProvider::LOCK_SHARED) ? 'shared' : 'exclusive';
764
-			$logger->info(
765
-				sprintf(
766
-					'change lock on "%s" to %s on storage "%s"',
767
-					$path,
768
-					$typeString,
769
-					$this->getId()
770
-				),
771
-				[
772
-					'app' => 'locking',
773
-				]
774
-			);
775
-		}
776
-		try {
777
-			$provider->changeLock('files/' . md5($this->getId() . '::' . trim($path, '/')), $type);
778
-		} catch (LockedException $e) {
779
-			\OC::$server->getLogger()->logException($e);
780
-			throw $e;
781
-		}
782
-	}
783
-
784
-	private function getLockLogger() {
785
-		if (is_null($this->shouldLogLocks)) {
786
-			$this->shouldLogLocks = \OC::$server->getConfig()->getSystemValue('filelocking.debug', false);
787
-			$this->logger = $this->shouldLogLocks ? \OC::$server->getLogger() : null;
788
-		}
789
-		return $this->logger;
790
-	}
791
-
792
-	/**
793
-	 * @return array [ available, last_checked ]
794
-	 */
795
-	public function getAvailability() {
796
-		return $this->getStorageCache()->getAvailability();
797
-	}
798
-
799
-	/**
800
-	 * @param bool $isAvailable
801
-	 */
802
-	public function setAvailability($isAvailable) {
803
-		$this->getStorageCache()->setAvailability($isAvailable);
804
-	}
805
-
806
-	/**
807
-	 * @return bool
808
-	 */
809
-	public function needsPartFile() {
810
-		return true;
811
-	}
530
+                throw new InvalidCharacterInPathException();
531
+            }
532
+        }
533
+
534
+        if (isset($fileName[255])) {
535
+            throw new FileNameTooLongException();
536
+        }
537
+
538
+        // NOTE: $path will remain unverified for now
539
+        $this->verifyPosixPath($fileName);
540
+    }
541
+
542
+    /**
543
+     * @param string $fileName
544
+     * @throws InvalidPathException
545
+     */
546
+    protected function verifyPosixPath($fileName) {
547
+        $fileName = trim($fileName);
548
+        $this->scanForInvalidCharacters($fileName, "\\/");
549
+        $reservedNames = ['*'];
550
+        if (in_array($fileName, $reservedNames)) {
551
+            throw new ReservedWordException();
552
+        }
553
+    }
554
+
555
+    /**
556
+     * @param string $fileName
557
+     * @param string $invalidChars
558
+     * @throws InvalidPathException
559
+     */
560
+    private function scanForInvalidCharacters($fileName, $invalidChars) {
561
+        foreach (str_split($invalidChars) as $char) {
562
+            if (strpos($fileName, $char) !== false) {
563
+                throw new InvalidCharacterInPathException();
564
+            }
565
+        }
566
+
567
+        $sanitizedFileName = filter_var($fileName, FILTER_UNSAFE_RAW, FILTER_FLAG_STRIP_LOW);
568
+        if ($sanitizedFileName !== $fileName) {
569
+            throw new InvalidCharacterInPathException();
570
+        }
571
+    }
572
+
573
+    /**
574
+     * @param array $options
575
+     */
576
+    public function setMountOptions(array $options) {
577
+        $this->mountOptions = $options;
578
+    }
579
+
580
+    /**
581
+     * @param string $name
582
+     * @param mixed $default
583
+     * @return mixed
584
+     */
585
+    public function getMountOption($name, $default = null) {
586
+        return isset($this->mountOptions[$name]) ? $this->mountOptions[$name] : $default;
587
+    }
588
+
589
+    /**
590
+     * @param IStorage $sourceStorage
591
+     * @param string $sourceInternalPath
592
+     * @param string $targetInternalPath
593
+     * @param bool $preserveMtime
594
+     * @return bool
595
+     */
596
+    public function copyFromStorage(IStorage $sourceStorage, $sourceInternalPath, $targetInternalPath, $preserveMtime = false) {
597
+        if ($sourceStorage === $this) {
598
+            return $this->copy($sourceInternalPath, $targetInternalPath);
599
+        }
600
+
601
+        if ($sourceStorage->is_dir($sourceInternalPath)) {
602
+            $dh = $sourceStorage->opendir($sourceInternalPath);
603
+            $result = $this->mkdir($targetInternalPath);
604
+            if (is_resource($dh)) {
605
+                while ($result and ($file = readdir($dh)) !== false) {
606
+                    if (!Filesystem::isIgnoredDir($file)) {
607
+                        $result &= $this->copyFromStorage($sourceStorage, $sourceInternalPath . '/' . $file, $targetInternalPath . '/' . $file);
608
+                    }
609
+                }
610
+            }
611
+        } else {
612
+            $source = $sourceStorage->fopen($sourceInternalPath, 'r');
613
+            // TODO: call fopen in a way that we execute again all storage wrappers
614
+            // to avoid that we bypass storage wrappers which perform important actions
615
+            // for this operation. Same is true for all other operations which
616
+            // are not the same as the original one.Once this is fixed we also
617
+            // need to adjust the encryption wrapper.
618
+            $target = $this->fopen($targetInternalPath, 'w');
619
+            list(, $result) = \OC_Helper::streamCopy($source, $target);
620
+            if ($result and $preserveMtime) {
621
+                $this->touch($targetInternalPath, $sourceStorage->filemtime($sourceInternalPath));
622
+            }
623
+            fclose($source);
624
+            fclose($target);
625
+
626
+            if (!$result) {
627
+                // delete partially written target file
628
+                $this->unlink($targetInternalPath);
629
+                // delete cache entry that was created by fopen
630
+                $this->getCache()->remove($targetInternalPath);
631
+            }
632
+        }
633
+        return (bool)$result;
634
+    }
635
+
636
+    /**
637
+     * @param IStorage $sourceStorage
638
+     * @param string $sourceInternalPath
639
+     * @param string $targetInternalPath
640
+     * @return bool
641
+     */
642
+    public function moveFromStorage(IStorage $sourceStorage, $sourceInternalPath, $targetInternalPath) {
643
+        if ($sourceStorage === $this) {
644
+            return $this->rename($sourceInternalPath, $targetInternalPath);
645
+        }
646
+
647
+        if (!$sourceStorage->isDeletable($sourceInternalPath)) {
648
+            return false;
649
+        }
650
+
651
+        $result = $this->copyFromStorage($sourceStorage, $sourceInternalPath, $targetInternalPath, true);
652
+        if ($result) {
653
+            if ($sourceStorage->is_dir($sourceInternalPath)) {
654
+                $result &= $sourceStorage->rmdir($sourceInternalPath);
655
+            } else {
656
+                $result &= $sourceStorage->unlink($sourceInternalPath);
657
+            }
658
+        }
659
+        return $result;
660
+    }
661
+
662
+    /**
663
+     * @inheritdoc
664
+     */
665
+    public function getMetaData($path) {
666
+        $permissions = $this->getPermissions($path);
667
+        if (!$permissions & \OCP\Constants::PERMISSION_READ) {
668
+            //can't read, nothing we can do
669
+            return null;
670
+        }
671
+
672
+        $data = [];
673
+        $data['mimetype'] = $this->getMimeType($path);
674
+        $data['mtime'] = $this->filemtime($path);
675
+        if ($data['mtime'] === false) {
676
+            $data['mtime'] = time();
677
+        }
678
+        if ($data['mimetype'] == 'httpd/unix-directory') {
679
+            $data['size'] = -1; //unknown
680
+        } else {
681
+            $data['size'] = $this->filesize($path);
682
+        }
683
+        $data['etag'] = $this->getETag($path);
684
+        $data['storage_mtime'] = $data['mtime'];
685
+        $data['permissions'] = $permissions;
686
+
687
+        return $data;
688
+    }
689
+
690
+    /**
691
+     * @param string $path
692
+     * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
693
+     * @param \OCP\Lock\ILockingProvider $provider
694
+     * @throws \OCP\Lock\LockedException
695
+     */
696
+    public function acquireLock($path, $type, ILockingProvider $provider) {
697
+        $logger = $this->getLockLogger();
698
+        if ($logger) {
699
+            $typeString = ($type === ILockingProvider::LOCK_SHARED) ? 'shared' : 'exclusive';
700
+            $logger->info(
701
+                sprintf(
702
+                    'acquire %s lock on "%s" on storage "%s"',
703
+                    $typeString,
704
+                    $path,
705
+                    $this->getId()
706
+                ),
707
+                [
708
+                    'app' => 'locking',
709
+                ]
710
+            );
711
+        }
712
+        try {
713
+            $provider->acquireLock('files/' . md5($this->getId() . '::' . trim($path, '/')), $type);
714
+        } catch (LockedException $e) {
715
+            if ($logger) {
716
+                $logger->logException($e);
717
+            }
718
+            throw $e;
719
+        }
720
+    }
721
+
722
+    /**
723
+     * @param string $path
724
+     * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
725
+     * @param \OCP\Lock\ILockingProvider $provider
726
+     * @throws \OCP\Lock\LockedException
727
+     */
728
+    public function releaseLock($path, $type, ILockingProvider $provider) {
729
+        $logger = $this->getLockLogger();
730
+        if ($logger) {
731
+            $typeString = ($type === ILockingProvider::LOCK_SHARED) ? 'shared' : 'exclusive';
732
+            $logger->info(
733
+                sprintf(
734
+                    'release %s lock on "%s" on storage "%s"',
735
+                    $typeString,
736
+                    $path,
737
+                    $this->getId()
738
+                ),
739
+                [
740
+                    'app' => 'locking',
741
+                ]
742
+            );
743
+        }
744
+        try {
745
+            $provider->releaseLock('files/' . md5($this->getId() . '::' . trim($path, '/')), $type);
746
+        } catch (LockedException $e) {
747
+            if ($logger) {
748
+                $logger->logException($e);
749
+            }
750
+            throw $e;
751
+        }
752
+    }
753
+
754
+    /**
755
+     * @param string $path
756
+     * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
757
+     * @param \OCP\Lock\ILockingProvider $provider
758
+     * @throws \OCP\Lock\LockedException
759
+     */
760
+    public function changeLock($path, $type, ILockingProvider $provider) {
761
+        $logger = $this->getLockLogger();
762
+        if ($logger) {
763
+            $typeString = ($type === ILockingProvider::LOCK_SHARED) ? 'shared' : 'exclusive';
764
+            $logger->info(
765
+                sprintf(
766
+                    'change lock on "%s" to %s on storage "%s"',
767
+                    $path,
768
+                    $typeString,
769
+                    $this->getId()
770
+                ),
771
+                [
772
+                    'app' => 'locking',
773
+                ]
774
+            );
775
+        }
776
+        try {
777
+            $provider->changeLock('files/' . md5($this->getId() . '::' . trim($path, '/')), $type);
778
+        } catch (LockedException $e) {
779
+            \OC::$server->getLogger()->logException($e);
780
+            throw $e;
781
+        }
782
+    }
783
+
784
+    private function getLockLogger() {
785
+        if (is_null($this->shouldLogLocks)) {
786
+            $this->shouldLogLocks = \OC::$server->getConfig()->getSystemValue('filelocking.debug', false);
787
+            $this->logger = $this->shouldLogLocks ? \OC::$server->getLogger() : null;
788
+        }
789
+        return $this->logger;
790
+    }
791
+
792
+    /**
793
+     * @return array [ available, last_checked ]
794
+     */
795
+    public function getAvailability() {
796
+        return $this->getStorageCache()->getAvailability();
797
+    }
798
+
799
+    /**
800
+     * @param bool $isAvailable
801
+     */
802
+    public function setAvailability($isAvailable) {
803
+        $this->getStorageCache()->setAvailability($isAvailable);
804
+    }
805
+
806
+    /**
807
+     * @return bool
808
+     */
809
+    public function needsPartFile() {
810
+        return true;
811
+    }
812 812
 }
Please login to merge, or discard this patch.
Spacing   +17 added lines, -17 removed lines patch added patch discarded remove patch
@@ -219,7 +219,7 @@  discard block
 block discarded – undo
219 219
 			$this->mkdir($path2);
220 220
 			while ($file = readdir($dir)) {
221 221
 				if (!Filesystem::isIgnoredDir($file)) {
222
-					if (!$this->copy($path1 . '/' . $file, $path2 . '/' . $file)) {
222
+					if (!$this->copy($path1.'/'.$file, $path2.'/'.$file)) {
223 223
 						return false;
224 224
 					}
225 225
 				}
@@ -273,12 +273,12 @@  discard block
 block discarded – undo
273 273
 		if (is_resource($dh)) {
274 274
 			while (($file = readdir($dh)) !== false) {
275 275
 				if (!\OC\Files\Filesystem::isIgnoredDir($file)) {
276
-					if ($this->is_dir($path . '/' . $file)) {
277
-						mkdir($target . '/' . $file);
278
-						$this->addLocalFolder($path . '/' . $file, $target . '/' . $file);
276
+					if ($this->is_dir($path.'/'.$file)) {
277
+						mkdir($target.'/'.$file);
278
+						$this->addLocalFolder($path.'/'.$file, $target.'/'.$file);
279 279
 					} else {
280
-						$tmp = $this->toTmpFile($path . '/' . $file);
281
-						rename($tmp, $target . '/' . $file);
280
+						$tmp = $this->toTmpFile($path.'/'.$file);
281
+						rename($tmp, $target.'/'.$file);
282 282
 					}
283 283
 				}
284 284
 			}
@@ -297,10 +297,10 @@  discard block
 block discarded – undo
297 297
 			while (($item = readdir($dh)) !== false) {
298 298
 				if (\OC\Files\Filesystem::isIgnoredDir($item)) continue;
299 299
 				if (strstr(strtolower($item), strtolower($query)) !== false) {
300
-					$files[] = $dir . '/' . $item;
300
+					$files[] = $dir.'/'.$item;
301 301
 				}
302
-				if ($this->is_dir($dir . '/' . $item)) {
303
-					$files = array_merge($files, $this->searchInDir($query, $dir . '/' . $item));
302
+				if ($this->is_dir($dir.'/'.$item)) {
303
+					$files = array_merge($files, $this->searchInDir($query, $dir.'/'.$item));
304 304
 				}
305 305
 			}
306 306
 		}
@@ -351,7 +351,7 @@  discard block
 block discarded – undo
351 351
 		if (!isset($this->watcher)) {
352 352
 			$this->watcher = new Watcher($storage);
353 353
 			$globalPolicy = \OC::$server->getConfig()->getSystemValue('filesystem_check_changes', Watcher::CHECK_NEVER);
354
-			$this->watcher->setPolicy((int)$this->getMountOption('filesystem_check_changes', $globalPolicy));
354
+			$this->watcher->setPolicy((int) $this->getMountOption('filesystem_check_changes', $globalPolicy));
355 355
 		}
356 356
 		return $this->watcher;
357 357
 	}
@@ -425,7 +425,7 @@  discard block
 block discarded – undo
425 425
 	 */
426 426
 	public function cleanPath($path) {
427 427
 		if (strlen($path) == 0 or $path[0] != '/') {
428
-			$path = '/' . $path;
428
+			$path = '/'.$path;
429 429
 		}
430 430
 
431 431
 		$output = array();
@@ -453,7 +453,7 @@  discard block
 block discarded – undo
453 453
 			\OC::$server->getLogger()->info("External storage not available: stat() failed");
454 454
 			return false;
455 455
 		} catch (\Exception $e) {
456
-			\OC::$server->getLogger()->info("External storage not available: " . $e->getMessage());
456
+			\OC::$server->getLogger()->info("External storage not available: ".$e->getMessage());
457 457
 			\OC::$server->getLogger()->logException($e, ['level' => ILogger::DEBUG]);
458 458
 			return false;
459 459
 		}
@@ -604,7 +604,7 @@  discard block
 block discarded – undo
604 604
 			if (is_resource($dh)) {
605 605
 				while ($result and ($file = readdir($dh)) !== false) {
606 606
 					if (!Filesystem::isIgnoredDir($file)) {
607
-						$result &= $this->copyFromStorage($sourceStorage, $sourceInternalPath . '/' . $file, $targetInternalPath . '/' . $file);
607
+						$result &= $this->copyFromStorage($sourceStorage, $sourceInternalPath.'/'.$file, $targetInternalPath.'/'.$file);
608 608
 					}
609 609
 				}
610 610
 			}
@@ -630,7 +630,7 @@  discard block
 block discarded – undo
630 630
 				$this->getCache()->remove($targetInternalPath);
631 631
 			}
632 632
 		}
633
-		return (bool)$result;
633
+		return (bool) $result;
634 634
 	}
635 635
 
636 636
 	/**
@@ -710,7 +710,7 @@  discard block
 block discarded – undo
710 710
 			);
711 711
 		}
712 712
 		try {
713
-			$provider->acquireLock('files/' . md5($this->getId() . '::' . trim($path, '/')), $type);
713
+			$provider->acquireLock('files/'.md5($this->getId().'::'.trim($path, '/')), $type);
714 714
 		} catch (LockedException $e) {
715 715
 			if ($logger) {
716 716
 				$logger->logException($e);
@@ -742,7 +742,7 @@  discard block
 block discarded – undo
742 742
 			);
743 743
 		}
744 744
 		try {
745
-			$provider->releaseLock('files/' . md5($this->getId() . '::' . trim($path, '/')), $type);
745
+			$provider->releaseLock('files/'.md5($this->getId().'::'.trim($path, '/')), $type);
746 746
 		} catch (LockedException $e) {
747 747
 			if ($logger) {
748 748
 				$logger->logException($e);
@@ -774,7 +774,7 @@  discard block
 block discarded – undo
774 774
 			);
775 775
 		}
776 776
 		try {
777
-			$provider->changeLock('files/' . md5($this->getId() . '::' . trim($path, '/')), $type);
777
+			$provider->changeLock('files/'.md5($this->getId().'::'.trim($path, '/')), $type);
778 778
 		} catch (LockedException $e) {
779 779
 			\OC::$server->getLogger()->logException($e);
780 780
 			throw $e;
Please login to merge, or discard this patch.
lib/private/Files/Storage/StorageFactory.php 2 patches
Indentation   +70 added lines, -70 removed lines patch added patch discarded remove patch
@@ -29,80 +29,80 @@
 block discarded – undo
29 29
 use OCP\Files\Storage\IStorageFactory;
30 30
 
31 31
 class StorageFactory implements IStorageFactory {
32
-	/**
33
-	 * @var array[] [$name=>['priority'=>$priority, 'wrapper'=>$callable] $storageWrappers
34
-	 */
35
-	private $storageWrappers = [];
32
+    /**
33
+     * @var array[] [$name=>['priority'=>$priority, 'wrapper'=>$callable] $storageWrappers
34
+     */
35
+    private $storageWrappers = [];
36 36
 
37
-	/**
38
-	 * allow modifier storage behaviour by adding wrappers around storages
39
-	 *
40
-	 * $callback should be a function of type (string $mountPoint, Storage $storage) => Storage
41
-	 *
42
-	 * @param string $wrapperName name of the wrapper
43
-	 * @param callable $callback callback
44
-	 * @param int $priority wrappers with the lower priority are applied last (meaning they get called first)
45
-	 * @param \OCP\Files\Mount\IMountPoint[] $existingMounts existing mount points to apply the wrapper to
46
-	 * @return bool true if the wrapper was added, false if there was already a wrapper with this
47
-	 * name registered
48
-	 */
49
-	public function addStorageWrapper($wrapperName, $callback, $priority = 50, $existingMounts = []) {
50
-		if (isset($this->storageWrappers[$wrapperName])) {
51
-			return false;
52
-		}
37
+    /**
38
+     * allow modifier storage behaviour by adding wrappers around storages
39
+     *
40
+     * $callback should be a function of type (string $mountPoint, Storage $storage) => Storage
41
+     *
42
+     * @param string $wrapperName name of the wrapper
43
+     * @param callable $callback callback
44
+     * @param int $priority wrappers with the lower priority are applied last (meaning they get called first)
45
+     * @param \OCP\Files\Mount\IMountPoint[] $existingMounts existing mount points to apply the wrapper to
46
+     * @return bool true if the wrapper was added, false if there was already a wrapper with this
47
+     * name registered
48
+     */
49
+    public function addStorageWrapper($wrapperName, $callback, $priority = 50, $existingMounts = []) {
50
+        if (isset($this->storageWrappers[$wrapperName])) {
51
+            return false;
52
+        }
53 53
 
54
-		// apply to existing mounts before registering it to prevent applying it double in MountPoint::createStorage
55
-		foreach ($existingMounts as $mount) {
56
-			$mount->wrapStorage($callback);
57
-		}
54
+        // apply to existing mounts before registering it to prevent applying it double in MountPoint::createStorage
55
+        foreach ($existingMounts as $mount) {
56
+            $mount->wrapStorage($callback);
57
+        }
58 58
 
59
-		$this->storageWrappers[$wrapperName] = ['wrapper' => $callback, 'priority' => $priority];
60
-		return true;
61
-	}
59
+        $this->storageWrappers[$wrapperName] = ['wrapper' => $callback, 'priority' => $priority];
60
+        return true;
61
+    }
62 62
 
63
-	/**
64
-	 * Remove a storage wrapper by name.
65
-	 * Note: internal method only to be used for cleanup
66
-	 *
67
-	 * @param string $wrapperName name of the wrapper
68
-	 * @internal
69
-	 */
70
-	public function removeStorageWrapper($wrapperName) {
71
-		unset($this->storageWrappers[$wrapperName]);
72
-	}
63
+    /**
64
+     * Remove a storage wrapper by name.
65
+     * Note: internal method only to be used for cleanup
66
+     *
67
+     * @param string $wrapperName name of the wrapper
68
+     * @internal
69
+     */
70
+    public function removeStorageWrapper($wrapperName) {
71
+        unset($this->storageWrappers[$wrapperName]);
72
+    }
73 73
 
74
-	/**
75
-	 * Create an instance of a storage and apply the registered storage wrappers
76
-	 *
77
-	 * @param \OCP\Files\Mount\IMountPoint $mountPoint
78
-	 * @param string $class
79
-	 * @param array $arguments
80
-	 * @return \OCP\Files\Storage
81
-	 */
82
-	public function getInstance(IMountPoint $mountPoint, $class, $arguments) {
83
-		return $this->wrap($mountPoint, new $class($arguments));
84
-	}
74
+    /**
75
+     * Create an instance of a storage and apply the registered storage wrappers
76
+     *
77
+     * @param \OCP\Files\Mount\IMountPoint $mountPoint
78
+     * @param string $class
79
+     * @param array $arguments
80
+     * @return \OCP\Files\Storage
81
+     */
82
+    public function getInstance(IMountPoint $mountPoint, $class, $arguments) {
83
+        return $this->wrap($mountPoint, new $class($arguments));
84
+    }
85 85
 
86
-	/**
87
-	 * @param \OCP\Files\Mount\IMountPoint $mountPoint
88
-	 * @param \OCP\Files\Storage $storage
89
-	 * @return \OCP\Files\Storage
90
-	 */
91
-	public function wrap(IMountPoint $mountPoint, $storage) {
92
-		$wrappers = array_values($this->storageWrappers);
93
-		usort($wrappers, function ($a, $b) {
94
-			return $b['priority'] - $a['priority'];
95
-		});
96
-		/** @var callable[] $wrappers */
97
-		$wrappers = array_map(function ($wrapper) {
98
-			return $wrapper['wrapper'];
99
-		}, $wrappers);
100
-		foreach ($wrappers as $wrapper) {
101
-			$storage = $wrapper($mountPoint->getMountPoint(), $storage, $mountPoint);
102
-			if (!($storage instanceof \OCP\Files\Storage)) {
103
-				throw new \Exception('Invalid result from storage wrapper');
104
-			}
105
-		}
106
-		return $storage;
107
-	}
86
+    /**
87
+     * @param \OCP\Files\Mount\IMountPoint $mountPoint
88
+     * @param \OCP\Files\Storage $storage
89
+     * @return \OCP\Files\Storage
90
+     */
91
+    public function wrap(IMountPoint $mountPoint, $storage) {
92
+        $wrappers = array_values($this->storageWrappers);
93
+        usort($wrappers, function ($a, $b) {
94
+            return $b['priority'] - $a['priority'];
95
+        });
96
+        /** @var callable[] $wrappers */
97
+        $wrappers = array_map(function ($wrapper) {
98
+            return $wrapper['wrapper'];
99
+        }, $wrappers);
100
+        foreach ($wrappers as $wrapper) {
101
+            $storage = $wrapper($mountPoint->getMountPoint(), $storage, $mountPoint);
102
+            if (!($storage instanceof \OCP\Files\Storage)) {
103
+                throw new \Exception('Invalid result from storage wrapper');
104
+            }
105
+        }
106
+        return $storage;
107
+    }
108 108
 }
Please login to merge, or discard this patch.
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -90,11 +90,11 @@
 block discarded – undo
90 90
 	 */
91 91
 	public function wrap(IMountPoint $mountPoint, $storage) {
92 92
 		$wrappers = array_values($this->storageWrappers);
93
-		usort($wrappers, function ($a, $b) {
93
+		usort($wrappers, function($a, $b) {
94 94
 			return $b['priority'] - $a['priority'];
95 95
 		});
96 96
 		/** @var callable[] $wrappers */
97
-		$wrappers = array_map(function ($wrapper) {
97
+		$wrappers = array_map(function($wrapper) {
98 98
 			return $wrapper['wrapper'];
99 99
 		}, $wrappers);
100 100
 		foreach ($wrappers as $wrapper) {
Please login to merge, or discard this patch.
lib/private/Files/Storage/PolyFill/CopyDirectory.php 2 patches
Indentation   +71 added lines, -71 removed lines patch added patch discarded remove patch
@@ -25,81 +25,81 @@
 block discarded – undo
25 25
 namespace OC\Files\Storage\PolyFill;
26 26
 
27 27
 trait CopyDirectory {
28
-	/**
29
-	 * Check if a path is a directory
30
-	 *
31
-	 * @param string $path
32
-	 * @return bool
33
-	 */
34
-	abstract public function is_dir($path);
28
+    /**
29
+     * Check if a path is a directory
30
+     *
31
+     * @param string $path
32
+     * @return bool
33
+     */
34
+    abstract public function is_dir($path);
35 35
 
36
-	/**
37
-	 * Check if a file or folder exists
38
-	 *
39
-	 * @param string $path
40
-	 * @return bool
41
-	 */
42
-	abstract public function file_exists($path);
36
+    /**
37
+     * Check if a file or folder exists
38
+     *
39
+     * @param string $path
40
+     * @return bool
41
+     */
42
+    abstract public function file_exists($path);
43 43
 
44
-	/**
45
-	 * Delete a file or folder
46
-	 *
47
-	 * @param string $path
48
-	 * @return bool
49
-	 */
50
-	abstract public function unlink($path);
44
+    /**
45
+     * Delete a file or folder
46
+     *
47
+     * @param string $path
48
+     * @return bool
49
+     */
50
+    abstract public function unlink($path);
51 51
 
52
-	/**
53
-	 * Open a directory handle for a folder
54
-	 *
55
-	 * @param string $path
56
-	 * @return resource | bool
57
-	 */
58
-	abstract public function opendir($path);
52
+    /**
53
+     * Open a directory handle for a folder
54
+     *
55
+     * @param string $path
56
+     * @return resource | bool
57
+     */
58
+    abstract public function opendir($path);
59 59
 
60
-	/**
61
-	 * Create a new folder
62
-	 *
63
-	 * @param string $path
64
-	 * @return bool
65
-	 */
66
-	abstract public function mkdir($path);
60
+    /**
61
+     * Create a new folder
62
+     *
63
+     * @param string $path
64
+     * @return bool
65
+     */
66
+    abstract public function mkdir($path);
67 67
 
68
-	public function copy($source, $target) {
69
-		if ($this->is_dir($source)) {
70
-			if ($this->file_exists($target)) {
71
-				$this->unlink($target);
72
-			}
73
-			$this->mkdir($target);
74
-			return $this->copyRecursive($source, $target);
75
-		} else {
76
-			return parent::copy($source, $target);
77
-		}
78
-	}
68
+    public function copy($source, $target) {
69
+        if ($this->is_dir($source)) {
70
+            if ($this->file_exists($target)) {
71
+                $this->unlink($target);
72
+            }
73
+            $this->mkdir($target);
74
+            return $this->copyRecursive($source, $target);
75
+        } else {
76
+            return parent::copy($source, $target);
77
+        }
78
+    }
79 79
 
80
-	/**
81
-	 * For adapters that don't support copying folders natively
82
-	 *
83
-	 * @param $source
84
-	 * @param $target
85
-	 * @return bool
86
-	 */
87
-	protected function copyRecursive($source, $target) {
88
-		$dh = $this->opendir($source);
89
-		$result = true;
90
-		while ($file = readdir($dh)) {
91
-			if (!\OC\Files\Filesystem::isIgnoredDir($file)) {
92
-				if ($this->is_dir($source . '/' . $file)) {
93
-					$this->mkdir($target . '/' . $file);
94
-					$result = $this->copyRecursive($source . '/' . $file, $target . '/' . $file);
95
-				} else {
96
-					$result = parent::copy($source . '/' . $file, $target . '/' . $file);
97
-				}
98
-				if (!$result) {
99
-					break;
100
-				}
101
-			}
102
-		}
103
-		return $result;
104
-	}
80
+    /**
81
+     * For adapters that don't support copying folders natively
82
+     *
83
+     * @param $source
84
+     * @param $target
85
+     * @return bool
86
+     */
87
+    protected function copyRecursive($source, $target) {
88
+        $dh = $this->opendir($source);
89
+        $result = true;
90
+        while ($file = readdir($dh)) {
91
+            if (!\OC\Files\Filesystem::isIgnoredDir($file)) {
92
+                if ($this->is_dir($source . '/' . $file)) {
93
+                    $this->mkdir($target . '/' . $file);
94
+                    $result = $this->copyRecursive($source . '/' . $file, $target . '/' . $file);
95
+                } else {
96
+                    $result = parent::copy($source . '/' . $file, $target . '/' . $file);
97
+                }
98
+                if (!$result) {
99
+                    break;
100
+                }
101
+            }
102
+        }
103
+        return $result;
104
+    }
105 105
 }
Please login to merge, or discard this patch.
Spacing   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -89,11 +89,11 @@
 block discarded – undo
89 89
 		$result = true;
90 90
 		while ($file = readdir($dh)) {
91 91
 			if (!\OC\Files\Filesystem::isIgnoredDir($file)) {
92
-				if ($this->is_dir($source . '/' . $file)) {
93
-					$this->mkdir($target . '/' . $file);
94
-					$result = $this->copyRecursive($source . '/' . $file, $target . '/' . $file);
92
+				if ($this->is_dir($source.'/'.$file)) {
93
+					$this->mkdir($target.'/'.$file);
94
+					$result = $this->copyRecursive($source.'/'.$file, $target.'/'.$file);
95 95
 				} else {
96
-					$result = parent::copy($source . '/' . $file, $target . '/' . $file);
96
+					$result = parent::copy($source.'/'.$file, $target.'/'.$file);
97 97
 				}
98 98
 				if (!$result) {
99 99
 					break;
Please login to merge, or discard this patch.
lib/private/Files/Storage/CommonTest.php 2 patches
Indentation   +47 added lines, -47 removed lines patch added patch discarded remove patch
@@ -33,53 +33,53 @@
 block discarded – undo
33 33
 namespace OC\Files\Storage;
34 34
 
35 35
 class CommonTest extends \OC\Files\Storage\Common{
36
-	/**
37
-	 * underlying local storage used for missing functions
38
-	 * @var \OC\Files\Storage\Local
39
-	 */
40
-	private $storage;
36
+    /**
37
+     * underlying local storage used for missing functions
38
+     * @var \OC\Files\Storage\Local
39
+     */
40
+    private $storage;
41 41
 
42
-	public function __construct($params) {
43
-		$this->storage=new \OC\Files\Storage\Local($params);
44
-	}
42
+    public function __construct($params) {
43
+        $this->storage=new \OC\Files\Storage\Local($params);
44
+    }
45 45
 
46
-	public function getId(){
47
-		return 'test::'.$this->storage->getId();
48
-	}
49
-	public function mkdir($path) {
50
-		return $this->storage->mkdir($path);
51
-	}
52
-	public function rmdir($path) {
53
-		return $this->storage->rmdir($path);
54
-	}
55
-	public function opendir($path) {
56
-		return $this->storage->opendir($path);
57
-	}
58
-	public function stat($path) {
59
-		return $this->storage->stat($path);
60
-	}
61
-	public function filetype($path) {
62
-		return @$this->storage->filetype($path);
63
-	}
64
-	public function isReadable($path) {
65
-		return $this->storage->isReadable($path);
66
-	}
67
-	public function isUpdatable($path) {
68
-		return $this->storage->isUpdatable($path);
69
-	}
70
-	public function file_exists($path) {
71
-		return $this->storage->file_exists($path);
72
-	}
73
-	public function unlink($path) {
74
-		return $this->storage->unlink($path);
75
-	}
76
-	public function fopen($path, $mode) {
77
-		return $this->storage->fopen($path, $mode);
78
-	}
79
-	public function free_space($path) {
80
-		return $this->storage->free_space($path);
81
-	}
82
-	public function touch($path, $mtime=null) {
83
-		return $this->storage->touch($path, $mtime);
84
-	}
46
+    public function getId(){
47
+        return 'test::'.$this->storage->getId();
48
+    }
49
+    public function mkdir($path) {
50
+        return $this->storage->mkdir($path);
51
+    }
52
+    public function rmdir($path) {
53
+        return $this->storage->rmdir($path);
54
+    }
55
+    public function opendir($path) {
56
+        return $this->storage->opendir($path);
57
+    }
58
+    public function stat($path) {
59
+        return $this->storage->stat($path);
60
+    }
61
+    public function filetype($path) {
62
+        return @$this->storage->filetype($path);
63
+    }
64
+    public function isReadable($path) {
65
+        return $this->storage->isReadable($path);
66
+    }
67
+    public function isUpdatable($path) {
68
+        return $this->storage->isUpdatable($path);
69
+    }
70
+    public function file_exists($path) {
71
+        return $this->storage->file_exists($path);
72
+    }
73
+    public function unlink($path) {
74
+        return $this->storage->unlink($path);
75
+    }
76
+    public function fopen($path, $mode) {
77
+        return $this->storage->fopen($path, $mode);
78
+    }
79
+    public function free_space($path) {
80
+        return $this->storage->free_space($path);
81
+    }
82
+    public function touch($path, $mtime=null) {
83
+        return $this->storage->touch($path, $mtime);
84
+    }
85 85
 }
Please login to merge, or discard this patch.
Spacing   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -32,7 +32,7 @@  discard block
 block discarded – undo
32 32
 
33 33
 namespace OC\Files\Storage;
34 34
 
35
-class CommonTest extends \OC\Files\Storage\Common{
35
+class CommonTest extends \OC\Files\Storage\Common {
36 36
 	/**
37 37
 	 * underlying local storage used for missing functions
38 38
 	 * @var \OC\Files\Storage\Local
@@ -40,10 +40,10 @@  discard block
 block discarded – undo
40 40
 	private $storage;
41 41
 
42 42
 	public function __construct($params) {
43
-		$this->storage=new \OC\Files\Storage\Local($params);
43
+		$this->storage = new \OC\Files\Storage\Local($params);
44 44
 	}
45 45
 
46
-	public function getId(){
46
+	public function getId() {
47 47
 		return 'test::'.$this->storage->getId();
48 48
 	}
49 49
 	public function mkdir($path) {
@@ -79,7 +79,7 @@  discard block
 block discarded – undo
79 79
 	public function free_space($path) {
80 80
 		return $this->storage->free_space($path);
81 81
 	}
82
-	public function touch($path, $mtime=null) {
82
+	public function touch($path, $mtime = null) {
83 83
 		return $this->storage->touch($path, $mtime);
84 84
 	}
85 85
 }
Please login to merge, or discard this patch.
lib/private/Files/Notify/RenameChange.php 1 patch
Indentation   +21 added lines, -21 removed lines patch added patch discarded remove patch
@@ -26,27 +26,27 @@
 block discarded – undo
26 26
 use OCP\Files\Notify\IRenameChange;
27 27
 
28 28
 class RenameChange extends Change implements IRenameChange {
29
-	/** @var string */
30
-	private $targetPath;
29
+    /** @var string */
30
+    private $targetPath;
31 31
 
32
-	/**
33
-	 * Change constructor.
34
-	 *
35
-	 * @param int $type
36
-	 * @param string $path
37
-	 * @param string $targetPath
38
-	 */
39
-	public function __construct($type, $path, $targetPath) {
40
-		parent::__construct($type, $path);
41
-		$this->targetPath = $targetPath;
42
-	}
32
+    /**
33
+     * Change constructor.
34
+     *
35
+     * @param int $type
36
+     * @param string $path
37
+     * @param string $targetPath
38
+     */
39
+    public function __construct($type, $path, $targetPath) {
40
+        parent::__construct($type, $path);
41
+        $this->targetPath = $targetPath;
42
+    }
43 43
 
44
-	/**
45
-	 * Get the new path of the renamed file relative to the storage root
46
-	 *
47
-	 * @return string
48
-	 */
49
-	public function getTargetPath() {
50
-		return $this->targetPath;
51
-	}
44
+    /**
45
+     * Get the new path of the renamed file relative to the storage root
46
+     *
47
+     * @return string
48
+     */
49
+    public function getTargetPath() {
50
+        return $this->targetPath;
51
+    }
52 52
 }
Please login to merge, or discard this patch.
lib/private/Files/Notify/Change.php 1 patch
Indentation   +32 added lines, -32 removed lines patch added patch discarded remove patch
@@ -26,40 +26,40 @@
 block discarded – undo
26 26
 use OCP\Files\Notify\IChange;
27 27
 
28 28
 class Change implements IChange {
29
-	/** @var int */
30
-	private $type;
29
+    /** @var int */
30
+    private $type;
31 31
 
32
-	/** @var string */
33
-	private $path;
32
+    /** @var string */
33
+    private $path;
34 34
 
35
-	/**
36
-	 * Change constructor.
37
-	 *
38
-	 * @param int $type
39
-	 * @param string $path
40
-	 */
41
-	public function __construct($type, $path) {
42
-		$this->type = $type;
43
-		$this->path = $path;
44
-	}
35
+    /**
36
+     * Change constructor.
37
+     *
38
+     * @param int $type
39
+     * @param string $path
40
+     */
41
+    public function __construct($type, $path) {
42
+        $this->type = $type;
43
+        $this->path = $path;
44
+    }
45 45
 
46
-	/**
47
-	 * Get the type of the change
48
-	 *
49
-	 * @return int IChange::ADDED, IChange::REMOVED, IChange::MODIFIED or IChange::RENAMED
50
-	 */
51
-	public function getType() {
52
-		return $this->type;
53
-	}
46
+    /**
47
+     * Get the type of the change
48
+     *
49
+     * @return int IChange::ADDED, IChange::REMOVED, IChange::MODIFIED or IChange::RENAMED
50
+     */
51
+    public function getType() {
52
+        return $this->type;
53
+    }
54 54
 
55
-	/**
56
-	 * Get the path of the file that was changed relative to the root of the storage
57
-	 *
58
-	 * Note, for rename changes this path is the old path for the file
59
-	 *
60
-	 * @return mixed
61
-	 */
62
-	public function getPath() {
63
-		return $this->path;
64
-	}
55
+    /**
56
+     * Get the path of the file that was changed relative to the root of the storage
57
+     *
58
+     * Note, for rename changes this path is the old path for the file
59
+     *
60
+     * @return mixed
61
+     */
62
+    public function getPath() {
63
+        return $this->path;
64
+    }
65 65
 }
Please login to merge, or discard this patch.
lib/private/Files/Cache/HomePropagator.php 1 patch
Indentation   +21 added lines, -21 removed lines patch added patch discarded remove patch
@@ -25,28 +25,28 @@
 block discarded – undo
25 25
 use OCP\IDBConnection;
26 26
 
27 27
 class HomePropagator extends Propagator {
28
-	private $ignoredBaseFolders;
28
+    private $ignoredBaseFolders;
29 29
 
30
-	/**
31
-	 * @param \OC\Files\Storage\Storage $storage
32
-	 */
33
-	public function __construct(\OC\Files\Storage\Storage $storage, IDBConnection $connection) {
34
-		parent::__construct($storage, $connection);
35
-		$this->ignoredBaseFolders = ['files_encryption'];
36
-	}
30
+    /**
31
+     * @param \OC\Files\Storage\Storage $storage
32
+     */
33
+    public function __construct(\OC\Files\Storage\Storage $storage, IDBConnection $connection) {
34
+        parent::__construct($storage, $connection);
35
+        $this->ignoredBaseFolders = ['files_encryption'];
36
+    }
37 37
 
38 38
 
39
-	/**
40
-	 * @param string $internalPath
41
-	 * @param int $time
42
-	 * @param int $sizeDifference number of bytes the file has grown
43
-	 */
44
-	public function propagateChange($internalPath, $time, $sizeDifference = 0) {
45
-		list($baseFolder) = explode('/', $internalPath, 2);
46
-		if (in_array($baseFolder, $this->ignoredBaseFolders)) {
47
-			return [];
48
-		} else {
49
-			parent::propagateChange($internalPath, $time, $sizeDifference);
50
-		}
51
-	}
39
+    /**
40
+     * @param string $internalPath
41
+     * @param int $time
42
+     * @param int $sizeDifference number of bytes the file has grown
43
+     */
44
+    public function propagateChange($internalPath, $time, $sizeDifference = 0) {
45
+        list($baseFolder) = explode('/', $internalPath, 2);
46
+        if (in_array($baseFolder, $this->ignoredBaseFolders)) {
47
+            return [];
48
+        } else {
49
+            parent::propagateChange($internalPath, $time, $sizeDifference);
50
+        }
51
+    }
52 52
 }
Please login to merge, or discard this patch.