PageRenderTime 46ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/components/com_jfusionplugins/dokuwiki/auth/io.class.php

http://jfusion.googlecode.com/
PHP | 280 lines | 188 code | 3 blank | 89 comment | 45 complexity | d31c31955e05baf18d3356b9fb81bd43 MD5 | raw file
Possible License(s): Apache-2.0
  1. <?php
  2. /**
  3. * @package JFusion_dokuwiki
  4. * @author Andreas Gohr <andi@splitbrain.org>
  5. * @author Ben Coburn <btcoburn@silicodon.net>
  6. * @author JFusion development team
  7. * @copyright Copyright (C) 2008 JFusion. All rights reserved.
  8. * @license http://www.gnu.org/copyleft/gpl.html GNU/GPL
  9. */
  10. // no direct access
  11. defined('_JEXEC') or die('Restricted access');
  12. /**
  13. * Class for dokuwiki file access
  14. * @package JFusion_dokuwiki
  15. */
  16. class JFusionDokuwiki_Io {
  17. var $jname = null;
  18. function JFusionDokuwiki_Io($jname) {
  19. $this->jname = $jname;
  20. }
  21. /**
  22. * Saves $content to $file.
  23. *
  24. * If the third parameter is set to true the given content
  25. * will be appended.
  26. *
  27. * Uses gzip if extension is .gz
  28. * and bz2 if extension is .bz2
  29. *
  30. * @author Andreas Gohr <andi@splitbrain.org>
  31. * @return bool true on success
  32. */
  33. function saveFile($file, $content, $append = false) {
  34. $share = Dokuwiki::getInstance($this->jname);
  35. $conf = $share->getConf();
  36. $mode = ($append) ? 'ab' : 'wb';
  37. $fileexists = @file_exists($file);
  38. $this->makefiledir($file);
  39. $this->lock($file);
  40. if (substr($file, -3) == '.gz') {
  41. $fh = @gzopen($file, $mode . '9');
  42. if (!$fh) {
  43. JError::raiseWarning(500, "Writing $file failed");
  44. $this->unlock($file);
  45. return false;
  46. }
  47. gzwrite($fh, $content);
  48. gzclose($fh);
  49. } else if (substr($file, -4) == '.bz2') {
  50. $fh = @bzopen($file, $mode{0});
  51. if (!$fh) {
  52. JError::raiseWarning(500, "Writing $file failed");
  53. $this->unlock($file);
  54. return false;
  55. }
  56. bzwrite($fh, $content);
  57. bzclose($fh);
  58. } else {
  59. $fh = @fopen($file, $mode);
  60. if ($fh === false) {
  61. JError::raiseWarning(500, "Writing $file failed");
  62. $this->unlock($file);
  63. return false;
  64. }
  65. fwrite($fh, $content);
  66. fclose($fh);
  67. }
  68. if (!$fileexists and !empty($conf['fperm'])) chmod($file, $conf['fperm']);
  69. $this->unlock($file);
  70. return true;
  71. }
  72. /**
  73. * Delete exact linematch for $badline from $file.
  74. *
  75. * Be sure to include the trailing newline in $badline
  76. *
  77. * Uses gzip if extension is .gz
  78. *
  79. * 2005-10-14 : added regex option -- Christopher Smith <chris@jalakai.co.uk>
  80. *
  81. * @author Steven Danz <steven-danz@kc.rr.com>
  82. * @return bool true on success
  83. */
  84. function deleteFromFile($file, $badline, $regex = false) {
  85. if (!@file_exists($file)) return true;
  86. $this->lock($file);
  87. // load into array
  88. if (substr($file, -3) == '.gz') {
  89. $lines = gzfile($file);
  90. } else {
  91. $lines = file($file);
  92. }
  93. // remove all matching lines
  94. if ($regex) {
  95. $lines = preg_grep($badline, $lines, PREG_GREP_INVERT);
  96. } else {
  97. $pos = array_search($badline, $lines); //return null or false if not found
  98. while (is_int($pos)) {
  99. unset($lines[$pos]);
  100. $pos = array_search($badline, $lines);
  101. }
  102. }
  103. if (count($lines)) {
  104. $content = join('', $lines);
  105. if (substr($file, -3) == '.gz') {
  106. $fh = @gzopen($file, 'wb9');
  107. if (!$fh) {
  108. JError::raiseWarning(500, "Removing content from $file failed");
  109. $this->unlock($file);
  110. return false;
  111. }
  112. gzwrite($fh, $content);
  113. gzclose($fh);
  114. } else {
  115. $fh = @fopen($file, 'wb');
  116. if (!$fh) {
  117. JError::raiseWarning(500, "Removing content from $file failed");
  118. $this->unlock($file);
  119. return false;
  120. }
  121. fwrite($fh, $content);
  122. fclose($fh);
  123. }
  124. } else {
  125. @unlink($file);
  126. }
  127. $this->unlock($file);
  128. return true;
  129. }
  130. /**
  131. * Tries to lock a file
  132. *
  133. * Locking is only done for io_savefile and uses directories
  134. * inside $conf['lockdir']
  135. *
  136. * It waits maximal 3 seconds for the lock, after this time
  137. * the lock is assumed to be stale and the function goes on
  138. *
  139. * @author Andreas Gohr <andi@splitbrain.org>
  140. */
  141. function lock($file) {
  142. $share = Dokuwiki::getInstance($this->jname);
  143. $conf = $share->getConf();
  144. // no locking if safemode hack
  145. if (@$conf['safemodehack']) return;
  146. $lockDir = @$conf['lockdir'] . '/' . md5($file);
  147. @ignore_user_abort(1);
  148. $timeStart = time();
  149. do {
  150. //waited longer than 3 seconds? -> stale lock
  151. if ((time() - $timeStart) > 3) break;
  152. $locked = @mkdir($lockDir, @$conf['dmode']);
  153. if ($locked) {
  154. if (!empty($conf['dperm'])) chmod($lockDir, $conf['dperm']);
  155. break;
  156. }
  157. usleep(50);
  158. }
  159. while ($locked === false);
  160. }
  161. /**
  162. * JFusionDokuwiki_Io::unlocks a file
  163. *
  164. * @author Andreas Gohr <andi@splitbrain.org>
  165. */
  166. function unlock($file) {
  167. $share = Dokuwiki::getInstance($this->jname);
  168. $conf = $share->getConf();;
  169. // no locking if safemode hack
  170. if (@$conf['safemodehack']) return;
  171. $lockDir = @$conf['lockdir'] . '/' . md5($file);
  172. @rmdir($lockDir);
  173. @ignore_user_abort(0);
  174. }
  175. /**
  176. * Create the directory needed for the given file
  177. *
  178. * @author Andreas Gohr <andi@splitbrain.org>
  179. */
  180. function makeFileDir($file) {
  181. $dir = dirname($file);
  182. if (!@is_dir($dir)) {
  183. $this->mkdir_p($dir) || JError::raiseWarning(500, "Creating directory $dir failed");
  184. }
  185. }
  186. /**
  187. * Creates a directory hierachy.
  188. *
  189. * @link http://www.php.net/manual/en/function.mkdir.php
  190. * @author <saint@corenova.com>
  191. * @author Andreas Gohr <andi@splitbrain.org>
  192. */
  193. function mkdir_p($target) {
  194. $share = Dokuwiki::getInstance($this->jname);
  195. $conf = $share->getConf();
  196. if (@is_dir($target) || empty($target)) return 1; // best case check first
  197. if (@file_exists($target) && !is_dir($target)) return 0;
  198. //recursion
  199. if ($this->mkdir_p(substr($target, 0, strrpos($target, '/')))) {
  200. if ($conf['safemodehack']) {
  201. $dir = preg_replace('/^' . preg_quote($this->fullpath($conf['ftp']['root']), '/') . '/', '', $target);
  202. return $this->mkdir_ftp($dir);
  203. } else {
  204. $ret = @mkdir($target, $conf['dmode']); // crawl back up & create dir tree
  205. if ($ret && $conf['dperm']) chmod($target, $conf['dperm']);
  206. return $ret;
  207. }
  208. }
  209. return 0;
  210. }
  211. /**
  212. * Creates a directory using FTP
  213. *
  214. * This is used when the safemode workaround is enabled
  215. *
  216. * @author <andi@splitbrain.org>
  217. */
  218. function mkdir_ftp($dir) {
  219. $share = Dokuwiki::getInstance($this->jname);
  220. $conf = $share->getConf();
  221. if (!function_exists('ftp_connect')) {
  222. JError::raiseWarning(500, "FTP support not found - safemode workaround not usable");
  223. return false;
  224. }
  225. $conn = @ftp_connect($conf['ftp']['host'], $conf['ftp']['port'], 10);
  226. if (!$conn) {
  227. JError::raiseWarning(500, "FTP connection failed");
  228. return false;
  229. }
  230. if (!@ftp_login($conn, $conf['ftp']['user'], $conf['ftp']['pass'])) {
  231. JError::raiseWarning(500, "FTP login failed");
  232. return false;
  233. }
  234. //create directory
  235. $ok = @ftp_mkdir($conn, $dir);
  236. //set permissions
  237. @ftp_site($conn, sprintf("CHMOD %04o %s", $conf['dmode'], $dir));
  238. @ftp_close($conn);
  239. return $ok;
  240. }
  241. /**
  242. * A realpath() replacement
  243. *
  244. * This function behaves similar to PHP's realpath() but does not resolve
  245. * symlinks or accesses upper directories
  246. *
  247. * @author <richpageau at yahoo dot co dot uk>
  248. * @link http://de3.php.net/manual/en/function.realpath.php#75992
  249. */
  250. function fullpath($path) {
  251. $iswin = (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN');
  252. if ($iswin) $path = str_replace('\\', '/', $path); // windows compatibility
  253. // check if path begins with "/" or "c:" ie. is absolute
  254. // if it isnt concat with script path
  255. if ((!$iswin && $path{0} !== '/') || ($iswin && $path{1} !== ':')) {
  256. $base = dirname($_SERVER['SCRIPT_FILENAME']);
  257. $path = $base . "/" . $path;
  258. }
  259. // canonicalize
  260. $path = explode('/', $path);
  261. $newpath = array();
  262. foreach ($path as $p) {
  263. if ($p === '' || $p === '.') continue;
  264. if ($p === '..') {
  265. array_pop($newpath);
  266. continue;
  267. }
  268. array_push($newpath, $p);
  269. }
  270. $finalpath = implode('/', $newpath);
  271. if (!$iswin) $finalpath = '/' . $finalpath;
  272. // check then return valid path or filename
  273. if (file_exists($finalpath)) {
  274. return ($finalpath);
  275. } else return false;
  276. }
  277. }