PageRenderTime 53ms CodeModel.GetById 25ms RepoModel.GetById 1ms app.codeStats 0ms

/wiki/inc/infoutils.php

https://github.com/godber/PHXdata-Website
PHP | 386 lines | 267 code | 42 blank | 77 comment | 61 complexity | 99fa883db0821fc18336f07f7aa8451f MD5 | raw file
  1. <?php
  2. /**
  3. * Information and debugging functions
  4. *
  5. * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
  6. * @author Andreas Gohr <andi@splitbrain.org>
  7. */
  8. if(!defined('DOKU_INC')) die('meh.');
  9. if(!defined('DOKU_MESSAGEURL')) define('DOKU_MESSAGEURL','http://update.dokuwiki.org/check/');
  10. /**
  11. * Check for new messages from upstream
  12. *
  13. * @author Andreas Gohr <andi@splitbrain.org>
  14. */
  15. function checkUpdateMessages(){
  16. global $conf;
  17. global $INFO;
  18. global $updateVersion;
  19. if(!$conf['updatecheck']) return;
  20. if($conf['useacl'] && !$INFO['ismanager']) return;
  21. $cf = $conf['cachedir'].'/messages.txt';
  22. $lm = @filemtime($cf);
  23. // check if new messages needs to be fetched
  24. if($lm < time()-(60*60*24) || $lm < @filemtime(DOKU_INC.'doku.php')){
  25. $http = new DokuHTTPClient();
  26. $http->timeout = 8;
  27. $data = $http->get(DOKU_MESSAGEURL.$updateVersion);
  28. io_saveFile($cf,$data);
  29. }else{
  30. $data = io_readFile($cf);
  31. }
  32. // show messages through the usual message mechanism
  33. $msgs = explode("\n%\n",$data);
  34. foreach($msgs as $msg){
  35. if($msg) msg($msg,2);
  36. }
  37. }
  38. /**
  39. * Return DokuWiki's version (split up in date and type)
  40. *
  41. * @author Andreas Gohr <andi@splitbrain.org>
  42. */
  43. function getVersionData(){
  44. $version = array();
  45. //import version string
  46. if(@file_exists(DOKU_INC.'VERSION')){
  47. //official release
  48. $version['date'] = trim(io_readfile(DOKU_INC.'VERSION'));
  49. $version['type'] = 'Release';
  50. }elseif(is_dir(DOKU_INC.'.git')){
  51. $version['type'] = 'Git';
  52. $version['date'] = 'unknown';
  53. $inventory = DOKU_INC.'.git/logs/HEAD';
  54. if(is_file($inventory)){
  55. $sz = filesize($inventory);
  56. $seek = max(0,$sz-2000); // read from back of the file
  57. $fh = fopen($inventory,'rb');
  58. fseek($fh,$seek);
  59. $chunk = fread($fh,2000);
  60. fclose($fh);
  61. $chunk = trim($chunk);
  62. $chunk = array_pop(explode("\n",$chunk)); //last log line
  63. $chunk = array_shift(explode("\t",$chunk)); //strip commit msg
  64. $chunk = explode(" ",$chunk);
  65. array_pop($chunk); //strip timezone
  66. $date = date('Y-m-d',array_pop($chunk));
  67. if($date) $version['date'] = $date;
  68. }
  69. }else{
  70. $version['date'] = 'unknown';
  71. $version['type'] = 'snapshot?';
  72. }
  73. return $version;
  74. }
  75. /**
  76. * Return DokuWiki's version (as a string)
  77. *
  78. * @author Anika Henke <anika@selfthinker.org>
  79. */
  80. function getVersion(){
  81. $version = getVersionData();
  82. return $version['type'].' '.$version['date'];
  83. }
  84. /**
  85. * Run a few sanity checks
  86. *
  87. * @author Andreas Gohr <andi@splitbrain.org>
  88. */
  89. function check(){
  90. global $conf;
  91. global $INFO;
  92. if ($INFO['isadmin'] || $INFO['ismanager']){
  93. msg('DokuWiki version: '.getVersion(),1);
  94. }
  95. if(version_compare(phpversion(),'5.1.2','<')){
  96. msg('Your PHP version is too old ('.phpversion().' vs. 5.1.2+ needed)',-1);
  97. }else{
  98. msg('PHP version '.phpversion(),1);
  99. }
  100. $mem = (int) php_to_byte(ini_get('memory_limit'));
  101. if($mem){
  102. if($mem < 16777216){
  103. msg('PHP is limited to less than 16MB RAM ('.$mem.' bytes). Increase memory_limit in php.ini',-1);
  104. }elseif($mem < 20971520){
  105. msg('PHP is limited to less than 20MB RAM ('.$mem.' bytes), you might encounter problems with bigger pages. Increase memory_limit in php.ini',-1);
  106. }elseif($mem < 33554432){
  107. msg('PHP is limited to less than 32MB RAM ('.$mem.' bytes), but that should be enough in most cases. If not, increase memory_limit in php.ini',0);
  108. }else{
  109. msg('More than 32MB RAM ('.$mem.' bytes) available.',1);
  110. }
  111. }
  112. if(is_writable($conf['changelog'])){
  113. msg('Changelog is writable',1);
  114. }else{
  115. if (@file_exists($conf['changelog'])) {
  116. msg('Changelog is not writable',-1);
  117. }
  118. }
  119. if (isset($conf['changelog_old']) && @file_exists($conf['changelog_old'])) {
  120. msg('Old changelog exists', 0);
  121. }
  122. if (@file_exists($conf['changelog'].'_failed')) {
  123. msg('Importing old changelog failed', -1);
  124. } else if (@file_exists($conf['changelog'].'_importing')) {
  125. msg('Importing old changelog now.', 0);
  126. } else if (@file_exists($conf['changelog'].'_import_ok')) {
  127. msg('Old changelog imported', 1);
  128. if (!plugin_isdisabled('importoldchangelog')) {
  129. msg('Importoldchangelog plugin not disabled after import', -1);
  130. }
  131. }
  132. if(is_writable($conf['datadir'])){
  133. msg('Datadir is writable',1);
  134. }else{
  135. msg('Datadir is not writable',-1);
  136. }
  137. if(is_writable($conf['olddir'])){
  138. msg('Attic is writable',1);
  139. }else{
  140. msg('Attic is not writable',-1);
  141. }
  142. if(is_writable($conf['mediadir'])){
  143. msg('Mediadir is writable',1);
  144. }else{
  145. msg('Mediadir is not writable',-1);
  146. }
  147. if(is_writable($conf['cachedir'])){
  148. msg('Cachedir is writable',1);
  149. }else{
  150. msg('Cachedir is not writable',-1);
  151. }
  152. if(is_writable($conf['lockdir'])){
  153. msg('Lockdir is writable',1);
  154. }else{
  155. msg('Lockdir is not writable',-1);
  156. }
  157. if($conf['authtype'] == 'plain'){
  158. if(is_writable(DOKU_CONF.'users.auth.php')){
  159. msg('conf/users.auth.php is writable',1);
  160. }else{
  161. msg('conf/users.auth.php is not writable',0);
  162. }
  163. }
  164. if(function_exists('mb_strpos')){
  165. if(defined('UTF8_NOMBSTRING')){
  166. msg('mb_string extension is available but will not be used',0);
  167. }else{
  168. msg('mb_string extension is available and will be used',1);
  169. if(ini_get('mbstring.func_overload') != 0){
  170. msg('mb_string function overloading is enabled, this will cause problems and should be disabled',-1);
  171. }
  172. }
  173. }else{
  174. msg('mb_string extension not available - PHP only replacements will be used',0);
  175. }
  176. if($conf['allowdebug']){
  177. msg('Debugging support is enabled. If you don\'t need it you should set $conf[\'allowdebug\'] = 0',-1);
  178. }else{
  179. msg('Debugging support is disabled',1);
  180. }
  181. if($INFO['userinfo']['name']){
  182. msg('You are currently logged in as '.$_SERVER['REMOTE_USER'].' ('.$INFO['userinfo']['name'].')',0);
  183. msg('You are part of the groups '.join($INFO['userinfo']['grps'],', '),0);
  184. }else{
  185. msg('You are currently not logged in',0);
  186. }
  187. msg('Your current permission for this page is '.$INFO['perm'],0);
  188. if(is_writable($INFO['filepath'])){
  189. msg('The current page is writable by the webserver',0);
  190. }else{
  191. msg('The current page is not writable by the webserver',0);
  192. }
  193. if($INFO['writable']){
  194. msg('The current page is writable by you',0);
  195. }else{
  196. msg('The current page is not writable by you',0);
  197. }
  198. $check = wl('','',true).'data/_dummy';
  199. $http = new DokuHTTPClient();
  200. $http->timeout = 6;
  201. $res = $http->get($check);
  202. if(strpos($res,'data directory') !== false){
  203. msg('It seems like the data directory is accessible from the web.
  204. Make sure this directory is properly protected
  205. (See <a href="http://www.dokuwiki.org/security">security</a>)',-1);
  206. }elseif($http->status == 404 || $http->status == 403){
  207. msg('The data directory seems to be properly protected',1);
  208. }else{
  209. msg('Failed to check if the data directory is accessible from the web.
  210. Make sure this directory is properly protected
  211. (See <a href="http://www.dokuwiki.org/security">security</a>)',-1);
  212. }
  213. }
  214. /**
  215. * print a message
  216. *
  217. * If HTTP headers were not sent yet the message is added
  218. * to the global message array else it's printed directly
  219. * using html_msgarea()
  220. *
  221. *
  222. * Levels can be:
  223. *
  224. * -1 error
  225. * 0 info
  226. * 1 success
  227. *
  228. * @author Andreas Gohr <andi@splitbrain.org>
  229. * @see html_msgarea
  230. */
  231. function msg($message,$lvl=0,$line='',$file=''){
  232. global $MSG;
  233. $errors[-1] = 'error';
  234. $errors[0] = 'info';
  235. $errors[1] = 'success';
  236. $errors[2] = 'notify';
  237. if($line || $file) $message.=' ['.basename($file).':'.$line.']';
  238. if(!isset($MSG)) $MSG = array();
  239. $MSG[]=array('lvl' => $errors[$lvl], 'msg' => $message);
  240. if(headers_sent()){
  241. if(function_exists('html_msgarea')){
  242. html_msgarea();
  243. }else{
  244. print "ERROR($lvl) $message";
  245. }
  246. unset($GLOBALS['MSG']);
  247. }
  248. }
  249. /**
  250. * print debug messages
  251. *
  252. * little function to print the content of a var
  253. *
  254. * @author Andreas Gohr <andi@splitbrain.org>
  255. */
  256. function dbg($msg,$hidden=false){
  257. if($hidden){
  258. echo "<!--\n";
  259. print_r($msg);
  260. echo "\n-->";
  261. }else{
  262. echo '<pre class="dbg">';
  263. echo hsc(print_r($msg,true));
  264. echo '</pre>';
  265. }
  266. }
  267. /**
  268. * Print info to a log file
  269. *
  270. * @author Andreas Gohr <andi@splitbrain.org>
  271. */
  272. function dbglog($msg,$header=''){
  273. global $conf;
  274. // The debug log isn't automatically cleaned thus only write it when
  275. // debugging has been enabled by the user.
  276. if($conf['allowdebug'] !== 1) return;
  277. if(is_object($msg) || is_array($msg)){
  278. $msg = print_r($msg,true);
  279. }
  280. if($header) $msg = "$header\n$msg";
  281. $file = $conf['cachedir'].'/debug.log';
  282. $fh = fopen($file,'a');
  283. if($fh){
  284. fwrite($fh,date('H:i:s ').$_SERVER['REMOTE_ADDR'].': '.$msg."\n");
  285. fclose($fh);
  286. }
  287. }
  288. /**
  289. * Print a reversed, prettyprinted backtrace
  290. *
  291. * @author Gary Owen <gary_owen@bigfoot.com>
  292. */
  293. function dbg_backtrace(){
  294. // Get backtrace
  295. $backtrace = debug_backtrace();
  296. // Unset call to debug_print_backtrace
  297. array_shift($backtrace);
  298. // Iterate backtrace
  299. $calls = array();
  300. $depth = count($backtrace) - 1;
  301. foreach ($backtrace as $i => $call) {
  302. $location = $call['file'] . ':' . $call['line'];
  303. $function = (isset($call['class'])) ?
  304. $call['class'] . $call['type'] . $call['function'] : $call['function'];
  305. $params = array();
  306. if (isset($call['args'])){
  307. foreach($call['args'] as $arg){
  308. if(is_object($arg)){
  309. $params[] = '[Object '.get_class($arg).']';
  310. }elseif(is_array($arg)){
  311. $params[] = '[Array]';
  312. }elseif(is_null($arg)){
  313. $param[] = '[NULL]';
  314. }else{
  315. $params[] = (string) '"'.$arg.'"';
  316. }
  317. }
  318. }
  319. $params = implode(', ',$params);
  320. $calls[$depth - $i] = sprintf('%s(%s) called at %s',
  321. $function,
  322. str_replace("\n", '\n', $params),
  323. $location);
  324. }
  325. ksort($calls);
  326. return implode("\n", $calls);
  327. }
  328. /**
  329. * Remove all data from an array where the key seems to point to sensitive data
  330. *
  331. * This is used to remove passwords, mail addresses and similar data from the
  332. * debug output
  333. *
  334. * @author Andreas Gohr <andi@splitbrain.org>
  335. */
  336. function debug_guard(&$data){
  337. foreach($data as $key => $value){
  338. if(preg_match('/(notify|pass|auth|secret|ftp|userinfo|token|buid|mail|proxy)/i',$key)){
  339. $data[$key] = '***';
  340. continue;
  341. }
  342. if(is_array($value)) debug_guard($data[$key]);
  343. }
  344. }