local.php 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. <?php
  2. /**
  3. * Copyright (c) 2012 Robin Appelman <icewind@owncloud.com>
  4. * This file is licensed under the Affero General Public License version 3 or
  5. * later.
  6. * See the COPYING-README file.
  7. */
  8. namespace OC\Files\Storage;
  9. if (\OC_Util::runningOnWindows()) {
  10. class Local extends MappedLocal {
  11. }
  12. } else {
  13. /**
  14. * for local filestore, we only have to map the paths
  15. */
  16. class Local extends \OC\Files\Storage\Common {
  17. protected $datadir;
  18. public function __construct($arguments) {
  19. $this->datadir = $arguments['datadir'];
  20. if (substr($this->datadir, -1) !== '/') {
  21. $this->datadir .= '/';
  22. }
  23. }
  24. public function __destruct() {
  25. }
  26. public function getId() {
  27. return 'local::' . $this->datadir;
  28. }
  29. public function mkdir($path) {
  30. return @mkdir($this->datadir . $path);
  31. }
  32. public function rmdir($path) {
  33. try {
  34. $it = new \RecursiveIteratorIterator(
  35. new \RecursiveDirectoryIterator($this->datadir . $path),
  36. \RecursiveIteratorIterator::CHILD_FIRST
  37. );
  38. foreach ($it as $file) {
  39. /**
  40. * @var \SplFileInfo $file
  41. */
  42. if (in_array($file->getBasename(), array('.', '..'))) {
  43. continue;
  44. } elseif ($file->isDir()) {
  45. rmdir($file->getPathname());
  46. } elseif ($file->isFile() || $file->isLink()) {
  47. unlink($file->getPathname());
  48. }
  49. }
  50. return rmdir($this->datadir . $path);
  51. } catch (\UnexpectedValueException $e) {
  52. return false;
  53. }
  54. }
  55. public function opendir($path) {
  56. return opendir($this->datadir . $path);
  57. }
  58. public function is_dir($path) {
  59. if (substr($path, -1) == '/') {
  60. $path = substr($path, 0, -1);
  61. }
  62. return is_dir($this->datadir . $path);
  63. }
  64. public function is_file($path) {
  65. return is_file($this->datadir . $path);
  66. }
  67. public function stat($path) {
  68. $fullPath = $this->datadir . $path;
  69. $statResult = stat($fullPath);
  70. if ($statResult['size'] < 0) {
  71. $size = self::getFileSizeFromOS($fullPath);
  72. $statResult['size'] = $size;
  73. $statResult[7] = $size;
  74. }
  75. return $statResult;
  76. }
  77. public function filetype($path) {
  78. $filetype = filetype($this->datadir . $path);
  79. if ($filetype == 'link') {
  80. $filetype = filetype(realpath($this->datadir . $path));
  81. }
  82. return $filetype;
  83. }
  84. public function filesize($path) {
  85. if ($this->is_dir($path)) {
  86. return 0;
  87. } else {
  88. $fullPath = $this->datadir . $path;
  89. $fileSize = filesize($fullPath);
  90. if ($fileSize < 0) {
  91. return self::getFileSizeFromOS($fullPath);
  92. }
  93. return $fileSize;
  94. }
  95. }
  96. public function isReadable($path) {
  97. return is_readable($this->datadir . $path);
  98. }
  99. public function isUpdatable($path) {
  100. return is_writable($this->datadir . $path);
  101. }
  102. public function file_exists($path) {
  103. return file_exists($this->datadir . $path);
  104. }
  105. public function filemtime($path) {
  106. return filemtime($this->datadir . $path);
  107. }
  108. public function touch($path, $mtime = null) {
  109. // sets the modification time of the file to the given value.
  110. // If mtime is nil the current time is set.
  111. // note that the access time of the file always changes to the current time.
  112. if ($this->file_exists($path) and !$this->isUpdatable($path)) {
  113. return false;
  114. }
  115. if (!is_null($mtime)) {
  116. $result = touch($this->datadir . $path, $mtime);
  117. } else {
  118. $result = touch($this->datadir . $path);
  119. }
  120. if ($result) {
  121. clearstatcache(true, $this->datadir . $path);
  122. }
  123. return $result;
  124. }
  125. public function file_get_contents($path) {
  126. return file_get_contents($this->datadir . $path);
  127. }
  128. public function file_put_contents($path, $data) { //trigger_error("$path = ".var_export($path, 1));
  129. return file_put_contents($this->datadir . $path, $data);
  130. }
  131. public function unlink($path) {
  132. return $this->delTree($path);
  133. }
  134. public function rename($path1, $path2) {
  135. if (!$this->isUpdatable($path1)) {
  136. \OC_Log::write('core', 'unable to rename, file is not writable : ' . $path1, \OC_Log::ERROR);
  137. return false;
  138. }
  139. if (!$this->file_exists($path1)) {
  140. \OC_Log::write('core', 'unable to rename, file does not exists : ' . $path1, \OC_Log::ERROR);
  141. return false;
  142. }
  143. if ($return = rename($this->datadir . $path1, $this->datadir . $path2)) {
  144. }
  145. return $return;
  146. }
  147. public function copy($path1, $path2) {
  148. if ($this->is_dir($path2)) {
  149. if (!$this->file_exists($path2)) {
  150. $this->mkdir($path2);
  151. }
  152. $source = substr($path1, strrpos($path1, '/') + 1);
  153. $path2 .= $source;
  154. }
  155. return copy($this->datadir . $path1, $this->datadir . $path2);
  156. }
  157. public function fopen($path, $mode) {
  158. if ($return = fopen($this->datadir . $path, $mode)) {
  159. switch ($mode) {
  160. case 'r':
  161. break;
  162. case 'r+':
  163. case 'w+':
  164. case 'x+':
  165. case 'a+':
  166. break;
  167. case 'w':
  168. case 'x':
  169. case 'a':
  170. break;
  171. }
  172. }
  173. return $return;
  174. }
  175. public function getMimeType($path) {
  176. if ($this->isReadable($path)) {
  177. return \OC_Helper::getMimeType($this->datadir . $path);
  178. } else {
  179. return false;
  180. }
  181. }
  182. private function delTree($dir) {
  183. $dirRelative = $dir;
  184. $dir = $this->datadir . $dir;
  185. if (!file_exists($dir)) return true;
  186. if (!is_dir($dir) || is_link($dir)) return unlink($dir);
  187. foreach (scandir($dir) as $item) {
  188. if ($item == '.' || $item == '..') continue;
  189. if (is_file($dir . '/' . $item)) {
  190. if (unlink($dir . '/' . $item)) {
  191. }
  192. } elseif (is_dir($dir . '/' . $item)) {
  193. if (!$this->delTree($dirRelative . "/" . $item)) {
  194. return false;
  195. };
  196. }
  197. }
  198. if ($return = rmdir($dir)) {
  199. }
  200. return $return;
  201. }
  202. private static function getFileSizeFromOS($fullPath) {
  203. $name = strtolower(php_uname('s'));
  204. // Windows OS: we use COM to access the filesystem
  205. if (strpos($name, 'win') !== false) {
  206. if (class_exists('COM')) {
  207. $fsobj = new \COM("Scripting.FileSystemObject");
  208. $f = $fsobj->GetFile($fullPath);
  209. return $f->Size;
  210. }
  211. } else if (strpos($name, 'bsd') !== false) {
  212. if (\OC_Helper::is_function_enabled('exec')) {
  213. return (float)exec('stat -f %z ' . escapeshellarg($fullPath));
  214. }
  215. } else if (strpos($name, 'linux') !== false) {
  216. if (\OC_Helper::is_function_enabled('exec')) {
  217. return (float)exec('stat -c %s ' . escapeshellarg($fullPath));
  218. }
  219. } else {
  220. \OC_Log::write('core',
  221. 'Unable to determine file size of "' . $fullPath . '". Unknown OS: ' . $name,
  222. \OC_Log::ERROR);
  223. }
  224. return 0;
  225. }
  226. public function hash($path, $type, $raw = false) {
  227. return hash_file($type, $this->datadir . $path, $raw);
  228. }
  229. public function free_space($path) {
  230. $space = @disk_free_space($this->datadir . $path);
  231. if ($space === false) {
  232. return \OC\Files\SPACE_UNKNOWN;
  233. }
  234. return $space;
  235. }
  236. public function search($query) {
  237. return $this->searchInDir($query);
  238. }
  239. public function getLocalFile($path) {
  240. return $this->datadir . $path;
  241. }
  242. public function getLocalFolder($path) {
  243. return $this->datadir . $path;
  244. }
  245. protected function searchInDir($query, $dir = '') {
  246. $files = array();
  247. foreach (scandir($this->datadir . $dir) as $item) {
  248. if ($item == '.' || $item == '..') continue;
  249. if (strstr(strtolower($item), strtolower($query)) !== false) {
  250. $files[] = $dir . '/' . $item;
  251. }
  252. if (is_dir($this->datadir . $dir . '/' . $item)) {
  253. $files = array_merge($files, $this->searchInDir($query, $dir . '/' . $item));
  254. }
  255. }
  256. return $files;
  257. }
  258. /**
  259. * check if a file or folder has been updated since $time
  260. *
  261. * @param string $path
  262. * @param int $time
  263. * @return bool
  264. */
  265. public function hasUpdated($path, $time) {
  266. return $this->filemtime($path) > $time;
  267. }
  268. }
  269. }