files.php 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. <?php
  2. /**
  3. * ownCloud
  4. *
  5. * @author Frank Karlitschek
  6. * @copyright 2010 Frank Karlitschek karlitschek@kde.org
  7. *
  8. * This library is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
  10. * License as published by the Free Software Foundation; either
  11. * version 3 of the License, or any later version.
  12. *
  13. * This library is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
  17. *
  18. * You should have received a copy of the GNU Affero General Public
  19. * License along with this library. If not, see <http://www.gnu.org/licenses/>.
  20. *
  21. */
  22. /**
  23. * Class for fileserver access
  24. *
  25. */
  26. class OC_Files {
  27. static $tmpFiles=array();
  28. /**
  29. * get the content of a directory
  30. * @param dir $directory
  31. */
  32. public static function getDirectoryContent($directory){
  33. if(strpos($directory,OC::$CONFIG_DATADIRECTORY)===0){
  34. $directory=substr($directory,strlen(OC::$CONFIG_DATADIRECTORY));
  35. }
  36. $files=OC_FileCache::getFolderContent($directory);
  37. foreach($files as &$file){
  38. $file['directory']=$directory;
  39. $file['type']=($file['mimetype']=='httpd/unix-directory')?'dir':'file';
  40. }
  41. usort($files, "fileCmp");//TODO: remove this once ajax is merged
  42. return $files;
  43. }
  44. /**
  45. * return the content of a file or return a zip file containning multiply files
  46. *
  47. * @param dir $dir
  48. * @param file $file ; seperated list of files to download
  49. */
  50. public static function get($dir,$files){
  51. if(strpos($files,';')){
  52. $files=explode(';',$files);
  53. }
  54. if(is_array($files)){
  55. $zip = new ZipArchive();
  56. $filename = get_temp_dir()."/ownCloud.zip";
  57. if ($zip->open($filename, ZIPARCHIVE::CREATE)!==TRUE) {
  58. exit("cannot open <$filename>\n");
  59. }
  60. foreach($files as $file){
  61. $file=$dir.'/'.$file;
  62. if(OC_Filesystem::is_file($file)){
  63. $tmpFile=OC_Filesystem::toTmpFile($file);
  64. self::$tmpFiles[]=$tmpFile;
  65. $zip->addFile($tmpFile,basename($file));
  66. }elseif(OC_Filesystem::is_dir($file)){
  67. self::zipAddDir($file,$zip);
  68. }
  69. }
  70. $zip->close();
  71. }elseif(OC_Filesystem::is_dir($dir.'/'.$files)){
  72. $zip = new ZipArchive();
  73. $filename = get_temp_dir()."/ownCloud.zip";
  74. if ($zip->open($filename, ZIPARCHIVE::CREATE)!==TRUE) {
  75. exit("cannot open <$filename>\n");
  76. }
  77. $file=$dir.'/'.$files;
  78. self::zipAddDir($file,$zip);
  79. $zip->close();
  80. }else{
  81. $zip=false;
  82. $filename=$dir.'/'.$files;
  83. }
  84. if($zip or OC_Filesystem::is_readable($filename)){
  85. header('Content-Disposition: attachment; filename="'.basename($filename).'"');
  86. header('Content-Transfer-Encoding: binary');
  87. header('Expires: 0');
  88. header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
  89. header('Pragma: public');
  90. if($zip){
  91. header('Content-Type: application/zip');
  92. header('Content-Length: ' . filesize($filename));
  93. }else{
  94. header('Content-Type: ' . OC_Filesystem::getMimeType($filename));
  95. header('Content-Length: ' . OC_Filesystem::filesize($filename));
  96. }
  97. }elseif($zip or !OC_Filesystem::file_exists($filename)){
  98. header("HTTP/1.0 404 Not Found");
  99. $tmpl = new OC_Template( '', '404', 'guest' );
  100. $tmpl->assign('file',$filename);
  101. $tmpl->printPage();
  102. // die('404 Not Found');
  103. }else{
  104. header("HTTP/1.0 403 Forbidden");
  105. die('403 Forbidden');
  106. }
  107. @ob_end_clean();
  108. if($zip){
  109. readfile($filename);
  110. unlink($filename);
  111. }else{
  112. OC_Filesystem::readfile($filename);
  113. }
  114. foreach(self::$tmpFiles as $tmpFile){
  115. if(file_exists($tmpFile) and is_file($tmpFile)){
  116. unlink($tmpFile);
  117. }
  118. }
  119. }
  120. public static function zipAddDir($dir,$zip,$internalDir=''){
  121. $dirname=basename($dir);
  122. $zip->addEmptyDir($internalDir.$dirname);
  123. $internalDir.=$dirname.='/';
  124. $files=OC_Files::getdirectorycontent($dir);
  125. foreach($files as $file){
  126. $filename=$file['name'];
  127. $file=$dir.'/'.$filename;
  128. if(OC_Filesystem::is_file($file)){
  129. $tmpFile=OC_Filesystem::toTmpFile($file);
  130. OC_Files::$tmpFiles[]=$tmpFile;
  131. $zip->addFile($tmpFile,$internalDir.$filename);
  132. }elseif(OC_Filesystem::is_dir($file)){
  133. self::zipAddDir($file,$zip,$internalDir);
  134. }
  135. }
  136. }
  137. /**
  138. * move a file or folder
  139. *
  140. * @param dir $sourceDir
  141. * @param file $source
  142. * @param dir $targetDir
  143. * @param file $target
  144. */
  145. public static function move($sourceDir,$source,$targetDir,$target){
  146. if(OC_User::isLoggedIn()){
  147. $targetFile=self::normalizePath($targetDir.'/'.$target);
  148. $sourceFile=self::normalizePath($sourceDir.'/'.$source);
  149. return OC_Filesystem::rename($sourceFile,$targetFile);
  150. }
  151. }
  152. /**
  153. * copy a file or folder
  154. *
  155. * @param dir $sourceDir
  156. * @param file $source
  157. * @param dir $targetDir
  158. * @param file $target
  159. */
  160. public static function copy($sourceDir,$source,$targetDir,$target){
  161. if(OC_User::isLoggedIn()){
  162. $targetFile=$targetDir.'/'.$target;
  163. $sourceFile=$sourceDir.'/'.$source;
  164. return OC_Filesystem::copy($sourceFile,$targetFile);
  165. }
  166. }
  167. /**
  168. * create a new file or folder
  169. *
  170. * @param dir $dir
  171. * @param file $name
  172. * @param type $type
  173. */
  174. public static function newFile($dir,$name,$type){
  175. if(OC_User::isLoggedIn()){
  176. $file=$dir.'/'.$name;
  177. if($type=='dir'){
  178. return OC_Filesystem::mkdir($file);
  179. }elseif($type=='file'){
  180. $fileHandle=OC_Filesystem::fopen($file, 'w');
  181. if($fileHandle){
  182. fclose($fileHandle);
  183. return true;
  184. }else{
  185. return false;
  186. }
  187. }
  188. }
  189. }
  190. /**
  191. * deletes a file or folder
  192. *
  193. * @param dir $dir
  194. * @param file $name
  195. */
  196. public static function delete($dir,$file){
  197. if(OC_User::isLoggedIn()){
  198. $file=$dir.'/'.$file;
  199. return OC_Filesystem::unlink($file);
  200. }
  201. }
  202. /**
  203. * try to detect the mime type of a file
  204. *
  205. * @param string path
  206. * @return string guessed mime type
  207. */
  208. static function getMimeType($path){
  209. return OC_Filesystem::getMimeType($path);
  210. }
  211. /**
  212. * get a file tree
  213. *
  214. * @param string path
  215. * @return array
  216. */
  217. static function getTree($path){
  218. return OC_Filesystem::getTree($path);
  219. }
  220. /**
  221. * pull a file from a remote server
  222. * @param string source
  223. * @param string token
  224. * @param string dir
  225. * @param string file
  226. * @return string guessed mime type
  227. */
  228. static function pull($source,$token,$dir,$file){
  229. $tmpfile=tempnam(get_temp_dir(),'remoteCloudFile');
  230. $fp=fopen($tmpfile,'w+');
  231. $url=$source.="/files/pull.php?token=$token";
  232. $ch=curl_init();
  233. curl_setopt($ch,CURLOPT_URL,$url);
  234. curl_setopt($ch, CURLOPT_FILE, $fp);
  235. curl_exec($ch);
  236. fclose($fp);
  237. $info=curl_getinfo($ch);
  238. $httpCode=$info['http_code'];
  239. curl_close($ch);
  240. if($httpCode==200 or $httpCode==0){
  241. OC_Filesystem::fromTmpFile($tmpfile,$dir.'/'.$file);
  242. return true;
  243. }else{
  244. return false;
  245. }
  246. }
  247. /**
  248. * set the maximum upload size limit for apache hosts using .htaccess
  249. * @param int size filesisze in bytes
  250. */
  251. static function setUploadLimit($size){
  252. $size=OC_Helper::humanFileSize($size);
  253. $size=substr($size,0,-1);//strip the B
  254. $size=str_replace(' ','',$size); //remove the space between the size and the postfix
  255. $content = "ErrorDocument 404 /".OC::$WEBROOT."/core/templates/404.php\n";//custom 404 error page
  256. $content.= "php_value upload_max_filesize $size\n";//upload limit
  257. $content.= "php_value post_max_size $size\n";
  258. $content.= "SetEnv htaccessWorking true\n";
  259. $content.= "Options -Indexes\n";
  260. @file_put_contents(OC::$SERVERROOT.'/.htaccess', $content); //supress errors in case we don't have permissions for it
  261. }
  262. /**
  263. * normalize a path, removing any double, add leading /, etc
  264. * @param string $path
  265. * @return string
  266. */
  267. static public function normalizePath($path){
  268. $path='/'.$path;
  269. $old='';
  270. while($old!=$path){//replace any multiplicity of slashes with a single one
  271. $old=$path;
  272. $path=str_replace('//','/',$path);
  273. }
  274. return $path;
  275. }
  276. }
  277. function fileCmp($a,$b){
  278. if($a['type']=='dir' and $b['type']!='dir'){
  279. return -1;
  280. }elseif($a['type']!='dir' and $b['type']=='dir'){
  281. return 1;
  282. }else{
  283. return strnatcasecmp($a['name'],$b['name']);
  284. }
  285. }