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