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