1
0

functions.dir.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441
  1. <?php
  2. /* $Id: functions.dir.php 3164 2007-07-23 09:58:35Z warion $ */
  3. /*******************************************************************************
  4. LICENSE
  5. This program is free software; you can redistribute it and/or
  6. modify it under the terms of the GNU General Public License (GPL)
  7. as published by the Free Software Foundation; either version 2
  8. of the License, or (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. To read the license please visit http://www.gnu.org/copyleft/gpl.html
  14. *******************************************************************************/
  15. /**
  16. * checks if $user has the $permission on $object
  17. *
  18. * @param $object
  19. * @param $user
  20. * @param $permission
  21. */
  22. function hasPermission($object, $user, $permission) {
  23. global $cfg;
  24. // if homedirs disabled return true
  25. if ($cfg["enable_home_dirs"] == 0)
  26. return true;
  27. // check permission
  28. switch ($permission) {
  29. case 'r':
  30. // public read enabled return true
  31. if ($cfg["dir_public_read"] == 1)
  32. return true;
  33. break;
  34. case 'w':
  35. // public write enabled return true
  36. if ($cfg["dir_public_write"] == 1)
  37. return true;
  38. break;
  39. default:
  40. return false;
  41. }
  42. // check if object in users home-dir
  43. if (preg_match("/^".$user."/", $object))
  44. return true;
  45. // only admin has right
  46. return $cfg['isAdmin'];
  47. }
  48. /**
  49. * inits restricted entries array.
  50. */
  51. function initRestrictedDirEntries() {
  52. global $cfg, $restrictedFileEntries;
  53. $restrictedFileEntries = ((isset($cfg["dir_restricted"])) && (strlen($cfg["dir_restricted"]) > 0))
  54. ? explode(":", trim($cfg["dir_restricted"]))
  55. : array();
  56. }
  57. /**
  58. * Checks for the location of the incoming directory
  59. * If it does not exist, then it creates it.
  60. */
  61. function checkIncomingPath() {
  62. global $cfg;
  63. switch ($cfg["enable_home_dirs"]) {
  64. case 1:
  65. default:
  66. // is there a user dir?
  67. checkDirectory($cfg["path"].$cfg["user"], 0777);
  68. break;
  69. case 0:
  70. // is there a incoming dir?
  71. checkDirectory($cfg["path"].$cfg["path_incoming"], 0777);
  72. break;
  73. }
  74. }
  75. /**
  76. * deletes a dir-entry. recursive process via avddelete
  77. *
  78. * @param $del entry to delete
  79. * @return string with current
  80. */
  81. function delDirEntry($del) {
  82. global $cfg;
  83. $current = "";
  84. if (tfb_isValidPath($del)) {
  85. avddelete($cfg["path"].$del);
  86. $arTemp = explode("/", $del);
  87. if (count($arTemp) > 1) {
  88. array_pop($arTemp);
  89. $current = implode("/", $arTemp);
  90. }
  91. AuditAction($cfg["constants"]["fm_delete"], $del);
  92. } else {
  93. AuditAction($cfg["constants"]["error"], "ILLEGAL DELETE: ".$cfg["user"]." tried to delete ".$del);
  94. }
  95. return $current;
  96. }
  97. /**
  98. * downloads a file.
  99. *
  100. * @param $down
  101. * @return string with current
  102. */
  103. function downloadFile($down) {
  104. global $cfg;
  105. $current = "";
  106. // we need to strip slashes twice in some circumstances
  107. // Ex. If we are trying to download test/tester's file/test.txt
  108. // $down will be "test/tester\\\'s file/test.txt"
  109. // one strip will give us "test/tester\'s file/test.txt
  110. // the second strip will give us the correct
  111. // "test/tester's file/test.txt"
  112. $down = stripslashes(stripslashes($down));
  113. if (tfb_isValidPath($down)) {
  114. $path = $cfg["path"].$down;
  115. $p = explode(".", $path);
  116. $pc = count($p);
  117. $f = explode("/", $path);
  118. $file = array_pop($f);
  119. $arTemp = explode("/", $down);
  120. if (count($arTemp) > 1) {
  121. array_pop($arTemp);
  122. $current = implode("/", $arTemp);
  123. }
  124. if (file_exists($path)) {
  125. // size
  126. $filesize = file_size($path);
  127. // filenames in IE containing dots will screw up the filename
  128. $headerName = (strstr($_SERVER['HTTP_USER_AGENT'], "MSIE"))
  129. ? preg_replace('/\./', '%2e', $file, substr_count($file, '.') - 1)
  130. : $file;
  131. // partial or full ?
  132. if (isset($_SERVER['HTTP_RANGE'])) {
  133. // Partial download
  134. $bufsize = 32768;
  135. if (preg_match("/^bytes=(\\d+)-(\\d*)$/D", $_SERVER['HTTP_RANGE'], $matches)) {
  136. $from = $matches[1];
  137. $to = $matches[2];
  138. if (empty($to))
  139. $to = $filesize - 1;
  140. $content_size = $to - $from + 1;
  141. @header("HTTP/1.1 206 Partial Content");
  142. @header("Content-Range: $from - $to / $filesize");
  143. @header("Content-Length: $content_size");
  144. @header("Content-Type: application/force-download");
  145. @header("Content-Disposition: attachment; filename=\"".$headerName."\"");
  146. @header("Content-Transfer-Encoding: binary");
  147. // write the session to close so you can continue to browse on the site.
  148. @session_write_close();
  149. $fh = fopen($path, "rb");
  150. fseek($fh, $from);
  151. $cur_pos = ftell($fh);
  152. while ($cur_pos !== FALSE && ftell($fh) + $bufsize < $to + 1) {
  153. $buffer = fread($fh, $bufsize);
  154. echo $buffer;
  155. $cur_pos = ftell($fh);
  156. }
  157. $buffer = fread($fh, $to + 1 - $cur_pos);
  158. echo $buffer;
  159. fclose($fh);
  160. } else {
  161. AuditAction($cfg["constants"]["error"], "Partial download : ".$cfg["user"]." tried to download ".$down);
  162. @header("HTTP/1.1 500 Internal Server Error");
  163. exit();
  164. }
  165. } else {
  166. // standard download
  167. @header("Content-type: application/octet-stream\n");
  168. @header("Content-disposition: attachment; filename=\"".$headerName."\"\n");
  169. @header("Content-transfer-encoding: binary\n");
  170. @header("Content-length: " . $filesize . "\n");
  171. // write the session to close so you can continue to browse on the site.
  172. @session_write_close();
  173. $fp = popen("cat ".tfb_shellencode($path), "r");
  174. fpassthru($fp);
  175. pclose($fp);
  176. }
  177. // log
  178. AuditAction($cfg["constants"]["fm_download"], $down);
  179. exit();
  180. } else {
  181. AuditAction($cfg["constants"]["error"], "File Not found for download: ".$cfg["user"]." tried to download ".$down);
  182. }
  183. } else {
  184. AuditAction($cfg["constants"]["error"], "ILLEGAL DOWNLOAD: ".$cfg["user"]." tried to download ".$down);
  185. }
  186. return $current;
  187. }
  188. /**
  189. * downloads as archive.
  190. *
  191. * @param $down
  192. * @return string with current
  193. */
  194. function downloadArchive($down) {
  195. global $cfg;
  196. $current = "";
  197. if (tfb_isValidPath($down)) {
  198. // This prevents the script from getting killed off when running lengthy tar jobs.
  199. @ini_set("max_execution_time", 3600);
  200. $down = $cfg["path"].$down;
  201. $arTemp = explode("/", $down);
  202. if (count($arTemp) > 1) {
  203. array_pop($arTemp);
  204. $current = implode("/", $arTemp);
  205. }
  206. // Find out if we're really trying to access a file within the
  207. // proper directory structure. Sadly, this way requires that $cfg["path"]
  208. // is a REAL path, not a symlinked one. Also check if $cfg["path"] is part
  209. // of the REAL path.
  210. if (is_dir($down)) {
  211. $sendname = basename($down);
  212. switch ($cfg["package_type"]) {
  213. Case "tar":
  214. $command = "tar cf - \"".addslashes($sendname)."\"";
  215. break;
  216. Case "zip":
  217. $command = "zip -0r - \"".addslashes($sendname)."\"";
  218. break;
  219. default:
  220. $cfg["package_type"] = "tar";
  221. $command = "tar cf - \"".addslashes($sendname)."\"";
  222. break;
  223. }
  224. // filenames in IE containing dots will screw up the filename
  225. $headerName = (strstr($_SERVER['HTTP_USER_AGENT'], "MSIE"))
  226. ? preg_replace('/\./', '%2e', $sendname, substr_count($sendname, '.') - 1)
  227. : $sendname;
  228. @header("Cache-Control: no-cache");
  229. @header("Pragma: no-cache");
  230. @header("Content-Description: File Transfer");
  231. @header("Content-Type: application/force-download");
  232. @header('Content-Disposition: attachment; filename="'.$headerName.'.'.$cfg["package_type"].'"');
  233. // write the session to close so you can continue to browse on the site.
  234. @session_write_close();
  235. // Make it a bit easier for tar/zip.
  236. chdir(dirname($down));
  237. passthru($command);
  238. AuditAction($cfg["constants"]["fm_download"], $sendname.".".$cfg["package_type"]);
  239. exit();
  240. } else {
  241. AuditAction($cfg["constants"]["error"], "Illegal download: ".$cfg["user"]." tried to download ".$down);
  242. }
  243. } else {
  244. AuditAction($cfg["constants"]["error"], "ILLEGAL TAR DOWNLOAD: ".$cfg["user"]." tried to download ".$down);
  245. }
  246. return $current;
  247. }
  248. /**
  249. * This function returns the extension of a given file.
  250. * Where the extension is the part after the last dot.
  251. * When no dot is found the noExtensionFile string is
  252. * returned. This should point to a 'unknown-type' image
  253. * time by default. This string is also returned when the
  254. * file starts with an dot.
  255. *
  256. * @param $fileName
  257. * @return
  258. */
  259. function getExtension($fileName) {
  260. $noExtensionFile="unknown"; // The return when no extension is found
  261. // Prepare the loop to find an extension
  262. $length = -1*(strlen($fileName)); // The maximum negative value for $i
  263. $i=-1; //The counter which counts back to $length
  264. // Find the last dot in an string
  265. while (substr($fileName,$i,1) != "." && $i > $length) {$i -= 1; }
  266. // Get the extension (with dot)
  267. $ext = substr($fileName,$i);
  268. // Decide what to return.
  269. $ext = (substr($ext,0,1)==".") ? substr($ext,((-1 * strlen($ext))+1)) : $noExtensionFile;
  270. // Return the extension
  271. return strtolower($ext);
  272. }
  273. /**
  274. * checks if file/dir is valid.
  275. *
  276. * @param $fileEntry
  277. * @return true/false
  278. */
  279. function isValidEntry($entry) {
  280. global $restrictedFileEntries;
  281. // is set
  282. if (!(isset($entry)))
  283. return false;
  284. // check if empty
  285. if ((strlen($entry)) < 1)
  286. return false;
  287. // check if dot-entry
  288. if (substr($entry, 0, 1) == ".")
  289. return false;
  290. if (strpos($entry, "/.") !== false)
  291. return false;
  292. // check if weirdo macos-entry
  293. if (substr($entry, 0, 1) == ":")
  294. return false;
  295. // check if in restricted array
  296. if (in_array($entry, $restrictedFileEntries))
  297. return false;
  298. // entry ok
  299. return true;
  300. }
  301. /**
  302. * checks if file is nfo.
  303. *
  304. * @param $entry
  305. * @return 0|1
  306. */
  307. function isNfo($entry) {
  308. $subst = strtolower(substr($entry, -4));
  309. if ($subst == ".nfo")
  310. return 1;
  311. if ($subst == ".txt")
  312. return 1;
  313. if ($subst == ".log")
  314. return 1;
  315. return 0;
  316. }
  317. /**
  318. * checks if file is rar.
  319. *
  320. * @param $entry
  321. * @return 0|1|2 ; 0 = no match, 1 = rar-file, 2 = zip-file
  322. */
  323. function isRar($entry) {
  324. if ((strpos($entry, '.rar') !== FALSE AND strpos($entry, '.Part') === FALSE) OR (strpos($entry, '.part01.rar') !== FALSE ) OR (strpos($entry, '.part1.rar') !== FALSE ))
  325. return 1;
  326. if (strpos($entry, '.zip') !== FALSE)
  327. return 2;
  328. return 0;
  329. }
  330. /**
  331. * SFV Check hack
  332. *
  333. * @param $dirName
  334. * @return
  335. */
  336. function findSFV($dirName) {
  337. $sfv = false;
  338. $d = dir($dirName);
  339. while (false !== ($entry = $d->read())) {
  340. if($entry != '.' && $entry != '..' && !empty($entry)) {
  341. if((isFile($dirName.'/'.$entry)) && (strtolower(substr($entry, -4, 4)) == '.sfv')) {
  342. $sfv['dir'] = $dirName;
  343. $sfv['sfv'] = $dirName.'/'.$entry;
  344. }
  345. }
  346. }
  347. $d->close();
  348. return $sfv;
  349. }
  350. /**
  351. * recursive chmod
  352. *
  353. * @param $path
  354. * @param $mode
  355. * @return boolean
  356. */
  357. function chmodRecursive($path, $mode = 0777) {
  358. if ((! @is_dir($path)) && (isValidEntry(basename($path))))
  359. return @chmod($path, $mode);
  360. $dirHandle = opendir($path);
  361. while ($file = readdir($dirHandle)) {
  362. if (isValidEntry(basename($file))) {
  363. $fullpath = $path.'/'.$file;
  364. if (!@is_dir($fullpath)) {
  365. if (!@chmod($fullpath, $mode))
  366. return false;
  367. } else {
  368. if (!chmodRecursive($fullpath, $mode))
  369. return false;
  370. }
  371. }
  372. }
  373. closedir($dirHandle);
  374. return ((isValidEntry(basename($path))) && (@chmod($path, $mode)));
  375. }
  376. /**
  377. * Encode a string for safe transport across GET transfers, adding
  378. * slashes if magic quoting is off
  379. *
  380. * @param string $input to apply encoding to
  381. * @return string $return string with encoded string
  382. */
  383. function UrlHTMLSlashesEncode($input){
  384. $return=htmlentities(rawurlencode($input), ENT_QUOTES);
  385. // Add slashes if magic quotes off:
  386. if(get_magic_quotes_gpc() === 0){
  387. $return=addslashes($return);
  388. }
  389. return($return);
  390. }
  391. /**
  392. * Decode a string encoded with UrlHTMLSlashesEncode()
  393. *
  394. * @param string $input string to decode
  395. * @return string $return string with decoded string
  396. */
  397. function UrlHTMLSlashesDecode($input){
  398. return(stripslashes(html_entity_decode(rawurldecode($input), ENT_QUOTES)));
  399. }
  400. /**
  401. * Get the size in bytes of a directory()
  402. *
  403. * @param string $path
  404. * @return string $size bytes
  405. */
  406. function dirsize($path)
  407. {
  408. if(!is_dir($path)) return -1;
  409. $size = shell_exec("du -sb ".tfb_shellencode($path));
  410. $size = (float) preg_replace("/(.+)[\t\s]*.*/","$1", $size);
  411. return $size;
  412. }
  413. ?>