1<?php 2/** 3 * Initialize some defaults needed for DokuWiki 4 */ 5 6 // start timing Dokuwiki execution 7 function delta_time($start=0) { 8 list($usec, $sec) = explode(" ", microtime()); 9 return ((float)$usec+(float)$sec)-((float)$start); 10 } 11 define('DOKU_START_TIME', delta_time()); 12 13 global $config_cascade; 14 $config_cascade = ''; 15 16 // if available load a preload config file 17 $preload = fullpath(dirname(__FILE__)).'/preload.php'; 18 if (@file_exists($preload)) include($preload); 19 20 // define the include path 21 if(!defined('DOKU_INC')) define('DOKU_INC',fullpath(dirname(__FILE__).'/../').'/'); 22 23 // define config path (packagers may want to change this to /etc/dokuwiki/) 24 if(!defined('DOKU_CONF')) define('DOKU_CONF',DOKU_INC.'conf/'); 25 26 // check for error reporting override or set error reporting to sane values 27 if (!defined('DOKU_E_LEVEL') && @file_exists(DOKU_CONF.'report_e_all')) { 28 define('DOKU_E_LEVEL', E_ALL); 29 } 30 if (!defined('DOKU_E_LEVEL')) { 31 if(defined('E_DEPRECATED')){ // since php 5.3 32 error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED); 33 }else{ 34 error_reporting(E_ALL ^ E_NOTICE); 35 } 36 } else { 37 error_reporting(DOKU_E_LEVEL); 38 } 39 40 // init memory caches 41 global $cache_revinfo; $cache_revinfo = array(); 42 global $cache_wikifn; $cache_wikifn = array(); 43 global $cache_cleanid; $cache_cleanid = array(); 44 global $cache_authname; $cache_authname = array(); 45 global $cache_metadata; $cache_metadata = array(); 46 47 //set the configuration cascade - but only if its not already been set in preload.php 48 if (empty($config_cascade)) { 49 $config_cascade = array( 50 'main' => array( 51 'default' => array(DOKU_CONF.'dokuwiki.php'), 52 'local' => array(DOKU_CONF.'local.php'), 53 'protected' => array(DOKU_CONF.'local.protected.php'), 54 ), 55 'acronyms' => array( 56 'default' => array(DOKU_CONF.'acronyms.conf'), 57 'local' => array(DOKU_CONF.'acronyms.local.conf'), 58 ), 59 'entities' => array( 60 'default' => array(DOKU_CONF.'entities.conf'), 61 'local' => array(DOKU_CONF.'entities.local.conf'), 62 ), 63 'interwiki' => array( 64 'default' => array(DOKU_CONF.'interwiki.conf'), 65 'local' => array(DOKU_CONF.'interwiki.local.conf'), 66 ), 67 'license' => array( 68 'default' => array(DOKU_CONF.'license.php'), 69 'local' => array(DOKU_CONF.'license.local.php'), 70 ), 71 'mediameta' => array( 72 'default' => array(DOKU_CONF.'mediameta.php'), 73 'local' => array(DOKU_CONF.'mediameta.local.php'), 74 ), 75 'mime' => array( 76 'default' => array(DOKU_CONF.'mime.conf'), 77 'local' => array(DOKU_CONF.'mime.local.conf'), 78 ), 79 'scheme' => array( 80 'default' => array(DOKU_CONF.'scheme.conf'), 81 'local' => array(DOKU_CONF.'scheme.local.conf'), 82 ), 83 'smileys' => array( 84 'default' => array(DOKU_CONF.'smileys.conf'), 85 'local' => array(DOKU_CONF.'smileys.local.conf'), 86 ), 87 'wordblock' => array( 88 'default' => array(DOKU_CONF.'wordblock.conf'), 89 'local' => array(DOKU_CONF.'wordblock.local.conf'), 90 ), 91 ); 92 } 93 94 //prepare config array() 95 global $conf; 96 $conf = array(); 97 98 // load the global config file(s) 99 foreach (array('default','local','protected') as $config_group) { 100 if (empty($config_cascade['main'][$config_group])) continue; 101 foreach ($config_cascade['main'][$config_group] as $config_file) { 102 if (@file_exists($config_file)) { 103 include($config_file); 104 } 105 } 106 } 107 108 //prepare language array 109 global $lang; 110 $lang = array(); 111 112 //load the language files 113 require_once(DOKU_INC.'inc/lang/en/lang.php'); 114 if ( $conf['lang'] && $conf['lang'] != 'en' ) { 115 require_once(DOKU_INC.'inc/lang/'.$conf['lang'].'/lang.php'); 116 } 117 118 //prepare license array() 119 global $license; 120 $license = array(); 121 122 // load the license file(s) 123 foreach (array('default','local') as $config_group) { 124 if (empty($config_cascade['license'][$config_group])) continue; 125 foreach ($config_cascade['license'][$config_group] as $config_file) { 126 if(@file_exists($config_file)){ 127 include($config_file); 128 } 129 } 130 } 131 132 // define baseURL 133 if(!defined('DOKU_REL')) define('DOKU_REL',getBaseURL(false)); 134 if(!defined('DOKU_URL')) define('DOKU_URL',getBaseURL(true)); 135 if(!defined('DOKU_BASE')){ 136 if($conf['canonical']){ 137 define('DOKU_BASE',DOKU_URL); 138 }else{ 139 define('DOKU_BASE',DOKU_REL); 140 } 141 } 142 143 // define whitespace 144 if(!defined('DOKU_LF')) define ('DOKU_LF',"\n"); 145 if(!defined('DOKU_TAB')) define ('DOKU_TAB',"\t"); 146 147 // define cookie and session id, append server port when securecookie is configured FS#1664 148 if (!defined('DOKU_COOKIE')) define('DOKU_COOKIE', 'DW'.md5(DOKU_REL.(($conf['securecookie'])?$_SERVER['SERVER_PORT']:''))); 149 150 // define Plugin dir 151 if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); 152 153 // define main script 154 if(!defined('DOKU_SCRIPT')) define('DOKU_SCRIPT','doku.php'); 155 156 // define Template baseURL 157 if(!defined('DOKU_TPL')) define('DOKU_TPL', 158 DOKU_BASE.'lib/tpl/'.$conf['template'].'/'); 159 160 // define real Template directory 161 if(!defined('DOKU_TPLINC')) define('DOKU_TPLINC', 162 DOKU_INC.'lib/tpl/'.$conf['template'].'/'); 163 164 // make session rewrites XHTML compliant 165 @ini_set('arg_separator.output', '&'); 166 167 // make sure global zlib does not interfere FS#1132 168 @ini_set('zlib.output_compression', 'off'); 169 170 // increase PCRE backtrack limit 171 @ini_set('pcre.backtrack_limit', '20971520'); 172 173 // enable gzip compression if supported 174 $conf['gzip_output'] &= (strpos($_SERVER['HTTP_ACCEPT_ENCODING'],'gzip') !== false); 175 if ($conf['gzip_output'] && 176 !defined('DOKU_DISABLE_GZIP_OUTPUT') && 177 function_exists('ob_gzhandler')) { 178 ob_start('ob_gzhandler'); 179 } 180 181 // init session 182 if (!headers_sent() && !defined('NOSESSION')){ 183 session_name("DokuWiki"); 184 if (version_compare(PHP_VERSION, '5.2.0', '>')) { 185 session_set_cookie_params(0,DOKU_REL,'',($conf['securecookie'] && is_ssl()),true); 186 }else{ 187 session_set_cookie_params(0,DOKU_REL,'',($conf['securecookie'] && is_ssl())); 188 } 189 session_start(); 190 191 // load left over messages 192 if(isset($_SESSION[DOKU_COOKIE]['msg'])){ 193 $MSG = $_SESSION[DOKU_COOKIE]['msg']; 194 unset($_SESSION[DOKU_COOKIE]['msg']); 195 } 196 } 197 198 // kill magic quotes 199 if (get_magic_quotes_gpc() && !defined('MAGIC_QUOTES_STRIPPED')) { 200 if (!empty($_GET)) remove_magic_quotes($_GET); 201 if (!empty($_POST)) remove_magic_quotes($_POST); 202 if (!empty($_COOKIE)) remove_magic_quotes($_COOKIE); 203 if (!empty($_REQUEST)) remove_magic_quotes($_REQUEST); 204 @ini_set('magic_quotes_gpc', 0); 205 define('MAGIC_QUOTES_STRIPPED',1); 206 } 207 @set_magic_quotes_runtime(0); 208 @ini_set('magic_quotes_sybase',0); 209 210 // don't let cookies ever interfere with request vars 211 $_REQUEST = array_merge($_GET,$_POST); 212 213 // we don't want a purge URL to be digged 214 if($_REQUEST['purge'] && $_SERVER['HTTP_REFERER']) unset($_REQUEST['purge']); 215 216 // disable gzip if not available 217 if($conf['compression'] == 'bz2' && !function_exists('bzopen')){ 218 $conf['compression'] = 'gz'; 219 } 220 if($conf['compression'] == 'gz' && !function_exists('gzopen')){ 221 $conf['compression'] = 0; 222 } 223 224 // fix dateformat for upgraders 225 if(strpos($conf['dformat'],'%') === false){ 226 $conf['dformat'] = '%Y/%m/%d %H:%M'; 227 } 228 229 // precalculate file creation modes 230 init_creationmodes(); 231 232 // make real paths and check them 233 init_paths(); 234 init_files(); 235 236 // automatic upgrade to script versions of certain files 237 scriptify(DOKU_CONF.'users.auth'); 238 scriptify(DOKU_CONF.'acl.auth'); 239 240 241/** 242 * Checks paths from config file 243 */ 244function init_paths(){ 245 global $conf; 246 247 $paths = array('datadir' => 'pages', 248 'olddir' => 'attic', 249 'mediadir' => 'media', 250 'metadir' => 'meta', 251 'cachedir' => 'cache', 252 'indexdir' => 'index', 253 'lockdir' => 'locks', 254 'tmpdir' => 'tmp'); 255 256 foreach($paths as $c => $p){ 257 if(empty($conf[$c])) $conf[$c] = $conf['savedir'].'/'.$p; 258 $conf[$c] = init_path($conf[$c]); 259 if(empty($conf[$c])) nice_die("The $c ('$p') does not exist, isn't accessible or writable. 260 You should check your config and permission settings. 261 Or maybe you want to <a href=\"install.php\">run the 262 installer</a>?"); 263 } 264 265 // path to old changelog only needed for upgrading 266 $conf['changelog_old'] = init_path((isset($conf['changelog']))?($conf['changelog']):($conf['savedir'].'/changes.log')); 267 if ($conf['changelog_old']=='') { unset($conf['changelog_old']); } 268 // hardcoded changelog because it is now a cache that lives in meta 269 $conf['changelog'] = $conf['metadir'].'/_dokuwiki.changes'; 270 $conf['media_changelog'] = $conf['metadir'].'/_media.changes'; 271} 272 273/** 274 * Checks the existance of certain files and creates them if missing. 275 */ 276function init_files(){ 277 global $conf; 278 279 $files = array( $conf['indexdir'].'/page.idx'); 280 281 foreach($files as $file){ 282 if(!@file_exists($file)){ 283 $fh = @fopen($file,'a'); 284 if($fh){ 285 fclose($fh); 286 if($conf['fperm']) chmod($file, $conf['fperm']); 287 }else{ 288 nice_die("$file is not writable. Check your permissions settings!"); 289 } 290 } 291 } 292} 293 294/** 295 * Returns absolute path 296 * 297 * This tries the given path first, then checks in DOKU_INC. 298 * Check for accessability on directories as well. 299 * 300 * @author Andreas Gohr <andi@splitbrain.org> 301 */ 302function init_path($path){ 303 // check existance 304 $p = fullpath($path); 305 if(!@file_exists($p)){ 306 $p = fullpath(DOKU_INC.$path); 307 if(!@file_exists($p)){ 308 return ''; 309 } 310 } 311 312 // check writability 313 if(!@is_writable($p)){ 314 return ''; 315 } 316 317 // check accessability (execute bit) for directories 318 if(@is_dir($p) && !@file_exists("$p/.")){ 319 return ''; 320 } 321 322 return $p; 323} 324 325/** 326 * Sets the internal config values fperm and dperm which, when set, 327 * will be used to change the permission of a newly created dir or 328 * file with chmod. Considers the influence of the system's umask 329 * setting the values only if needed. 330 */ 331function init_creationmodes(){ 332 global $conf; 333 334 // Legacy support for old umask/dmask scheme 335 unset($conf['dmask']); 336 unset($conf['fmask']); 337 unset($conf['umask']); 338 unset($conf['fperm']); 339 unset($conf['dperm']); 340 341 // get system umask, fallback to 0 if none available 342 $umask = @umask(); 343 if(!$umask) $umask = 0000; 344 345 // check what is set automatically by the system on file creation 346 // and set the fperm param if it's not what we want 347 $auto_fmode = 0666 & ~$umask; 348 if($auto_fmode != $conf['fmode']) $conf['fperm'] = $conf['fmode']; 349 350 // check what is set automatically by the system on file creation 351 // and set the dperm param if it's not what we want 352 $auto_dmode = $conf['dmode'] & ~$umask; 353 if($auto_dmode != $conf['dmode']) $conf['dperm'] = $conf['dmode']; 354} 355 356/** 357 * remove magic quotes recursivly 358 * 359 * @author Andreas Gohr <andi@splitbrain.org> 360 */ 361function remove_magic_quotes(&$array) { 362 foreach (array_keys($array) as $key) { 363 // handle magic quotes in keynames (breaks order) 364 $sk = stripslashes($key); 365 if($sk != $key){ 366 $array[$sk] = $array[$key]; 367 unset($array[$key]); 368 $key = $sk; 369 } 370 371 // do recursion if needed 372 if (is_array($array[$key])) { 373 remove_magic_quotes($array[$key]); 374 }else { 375 $array[$key] = stripslashes($array[$key]); 376 } 377 } 378} 379 380/** 381 * Returns the full absolute URL to the directory where 382 * DokuWiki is installed in (includes a trailing slash) 383 * 384 * @author Andreas Gohr <andi@splitbrain.org> 385 */ 386function getBaseURL($abs=null){ 387 global $conf; 388 //if canonical url enabled always return absolute 389 if(is_null($abs)) $abs = $conf['canonical']; 390 391 if($conf['basedir']){ 392 $dir = $conf['basedir']; 393 }elseif(substr($_SERVER['SCRIPT_NAME'],-4) == '.php'){ 394 $dir = dirname($_SERVER['SCRIPT_NAME']); 395 }elseif(substr($_SERVER['PHP_SELF'],-4) == '.php'){ 396 $dir = dirname($_SERVER['PHP_SELF']); 397 }elseif($_SERVER['DOCUMENT_ROOT'] && $_SERVER['SCRIPT_FILENAME']){ 398 $dir = preg_replace ('/^'.preg_quote($_SERVER['DOCUMENT_ROOT'],'/').'/','', 399 $_SERVER['SCRIPT_FILENAME']); 400 $dir = dirname('/'.$dir); 401 }else{ 402 $dir = '.'; //probably wrong 403 } 404 405 $dir = str_replace('\\','/',$dir); // bugfix for weird WIN behaviour 406 $dir = preg_replace('#//+#','/',"/$dir/"); // ensure leading and trailing slashes 407 408 //handle script in lib/exe dir 409 $dir = preg_replace('!lib/exe/$!','',$dir); 410 411 //handle script in lib/plugins dir 412 $dir = preg_replace('!lib/plugins/.*$!','',$dir); 413 414 //finish here for relative URLs 415 if(!$abs) return $dir; 416 417 //use config option if available, trim any slash from end of baseurl to avoid multiple consecutive slashes in the path 418 if($conf['baseurl']) return rtrim($conf['baseurl'],'/').$dir; 419 420 //split hostheader into host and port 421 list($host,$port) = explode(':',$_SERVER['HTTP_HOST']); 422 if(!$port) $port = $_SERVER['SERVER_PORT']; 423 if(!$port) $port = 80; 424 425 if(!is_ssl()){ 426 $proto = 'http://'; 427 if ($port == '80') { 428 $port=''; 429 } 430 }else{ 431 $proto = 'https://'; 432 if ($port == '443') { 433 $port=''; 434 } 435 } 436 437 if($port) $port = ':'.$port; 438 439 return $proto.$host.$port.$dir; 440} 441 442/** 443 * Check if accessed via HTTPS 444 * 445 * Apache leaves ,$_SERVER['HTTPS'] empty when not available, IIS sets it to 'off'. 446 * 'false' and 'disabled' are just guessing 447 * 448 * @returns bool true when SSL is active 449 */ 450function is_ssl(){ 451 if (preg_match('/^(|off|false|disabled)$/i',$_SERVER['HTTPS'])){ 452 return false; 453 }else{ 454 return true; 455 } 456} 457 458/** 459 * Append a PHP extension to a given file and adds an exit call 460 * 461 * This is used to migrate some old configfiles. An added PHP extension 462 * ensures the contents are not shown to webusers even if .htaccess files 463 * do not work 464 * 465 * @author Jan Decaluwe <jan@jandecaluwe.com> 466 */ 467function scriptify($file) { 468 // checks 469 if (!is_readable($file)) { 470 return; 471 } 472 $fn = $file.'.php'; 473 if (@file_exists($fn)) { 474 return; 475 } 476 $fh = fopen($fn, 'w'); 477 if (!$fh) { 478 nice_die($fn.' is not writable. Check your permission settings!'); 479 } 480 // write php exit hack first 481 fwrite($fh, "# $fn\n"); 482 fwrite($fh, '# <?php exit()?>'."\n"); 483 fwrite($fh, "# Don't modify the lines above\n"); 484 fwrite($fh, "#\n"); 485 // copy existing lines 486 $lines = file($file); 487 foreach ($lines as $line){ 488 fwrite($fh, $line); 489 } 490 fclose($fh); 491 //try to rename the old file 492 io_rename($file,"$file.old"); 493} 494 495/** 496 * print a nice message even if no styles are loaded yet. 497 */ 498function nice_die($msg){ 499 echo<<<EOT 500 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 501 "http://www.w3.org/TR/html4/loose.dtd"> 502 <html> 503 <head><title>DokuWiki Setup Error</title></head> 504 <body style="font-family: Arial, sans-serif"> 505 <div style="width:60%; margin: auto; background-color: #fcc; 506 border: 1px solid #faa; padding: 0.5em 1em;"> 507 <h1 style="font-size: 120%">DokuWiki Setup Error</h1> 508 <p>$msg</p> 509 </div> 510 </body> 511 </html> 512EOT; 513 exit; 514} 515 516 517/** 518 * A realpath() replacement 519 * 520 * This function behaves similar to PHP's realpath() but does not resolve 521 * symlinks or accesses upper directories 522 * 523 * @author Andreas Gohr <andi@splitbrain.org> 524 * @author <richpageau at yahoo dot co dot uk> 525 * @link http://de3.php.net/manual/en/function.realpath.php#75992 526 */ 527function fullpath($path,$exists=false){ 528 static $run = 0; 529 $root = ''; 530 $iswin = (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN' || @$GLOBALS['DOKU_UNITTEST_ASSUME_WINDOWS']); 531 532 // find the (indestructable) root of the path - keeps windows stuff intact 533 if($path{0} == '/'){ 534 $root = '/'; 535 }elseif($iswin){ 536 // match drive letter and UNC paths 537 if(preg_match('!^([a-zA-z]:)(.*)!',$path,$match)){ 538 $root = $match[1].'/'; 539 $path = $match[2]; 540 }else if(preg_match('!^(\\\\\\\\[^\\\\/]+\\\\[^\\\\/]+[\\\\/])(.*)!',$path,$match)){ 541 $root = $match[1]; 542 $path = $match[2]; 543 } 544 } 545 $path = str_replace('\\','/',$path); 546 547 // if the given path wasn't absolute already, prepend the script path and retry 548 if(!$root){ 549 $base = dirname($_SERVER['SCRIPT_FILENAME']); 550 $path = $base.'/'.$path; 551 if($run == 0){ // avoid endless recursion when base isn't absolute for some reason 552 $run++; 553 return fullpath($path,$exists); 554 } 555 } 556 $run = 0; 557 558 // canonicalize 559 $path=explode('/', $path); 560 $newpath=array(); 561 foreach($path as $p) { 562 if ($p === '' || $p === '.') continue; 563 if ($p==='..') { 564 array_pop($newpath); 565 continue; 566 } 567 array_push($newpath, $p); 568 } 569 $finalpath = $root.implode('/', $newpath); 570 571 // check for existance when needed (except when unit testing) 572 if($exists && !defined('DOKU_UNITTEST') && !@file_exists($finalpath)) { 573 return false; 574 } 575 return $finalpath; 576} 577 578 579 580//Setup VIM: ex: et ts=2 enc=utf-8 : 581