includes/common.php
changeset 1227 bdac73ed481e
parent 1206 50f6c144ec68
child 1251 d543689ed2eb
equal deleted inserted replaced
1226:de56132c008d 1227:bdac73ed481e
    20  */
    20  */
    21 
    21 
    22 // Make sure we don't have an attempt to inject globals (register_globals on)
    22 // Make sure we don't have an attempt to inject globals (register_globals on)
    23 if ( isset($_REQUEST['GLOBALS']) )
    23 if ( isset($_REQUEST['GLOBALS']) )
    24 {
    24 {
    25   ?>
    25 	?>
    26   <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"><html><head><title>Hacking Attempt</title><meta http-equiv="Content-type" content="text/html; charset=utf-8" /></head><style type="text/css">body{background-color:#000;color:#CCC;font-family:trebuchet ms,sans-serif;font-size:9pt;}a{color:#FFF;}</style><body><p>Hacking attempt using <a href="http://www.hardened-php.net/index.76.html">PHP $GLOBALS overwrite vulnerability</a> detected, reported to admin</p><p>You're worse than this guy! Unless you are this guy...</p><p id="billp"><img alt=" " src="about:blank" id="billi" /></p><script type="text/javascript">// <![CDATA[
    26 	<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"><html><head><title>Hacking Attempt</title><meta http-equiv="Content-type" content="text/html; charset=utf-8" /></head><style type="text/css">body{background-color:#000;color:#CCC;font-family:trebuchet ms,sans-serif;font-size:9pt;}a{color:#FFF;}</style><body><p>Hacking attempt using <a href="http://www.hardened-php.net/index.76.html">PHP $GLOBALS overwrite vulnerability</a> detected, reported to admin</p><p>You're worse than this guy! Unless you are this guy...</p><p id="billp"><img alt=" " src="about:blank" id="billi" /></p><script type="text/javascript">// <![CDATA[
    27   window.onload=function(){counter();setInterval('counter();', 1000);};var text=false;var cnt=10;function counter(){if(!text){text=document.createElement('span');text.id='billc';text.innerHTML=cnt;text.style.fontSize='96pt';text.style.color='#FF0000';p=document.getElementById('billp');p.appendChild(text);}else{if(cnt==1){document.getElementById('billi').src='http://upload.wikimedia.org/wikipedia/commons/7/7f/Bill_Gates_2004_cr.jpg';document.getElementById('billc').innerHTML='';return;}cnt--;document.getElementById('billc').innerHTML=cnt+' ';}}
    27 	window.onload=function(){counter();setInterval('counter();', 1000);};var text=false;var cnt=10;function counter(){if(!text){text=document.createElement('span');text.id='billc';text.innerHTML=cnt;text.style.fontSize='96pt';text.style.color='#FF0000';p=document.getElementById('billp');p.appendChild(text);}else{if(cnt==1){document.getElementById('billi').src='http://upload.wikimedia.org/wikipedia/commons/7/7f/Bill_Gates_2004_cr.jpg';document.getElementById('billc').innerHTML='';return;}cnt--;document.getElementById('billc').innerHTML=cnt+' ';}}
    28   // ]]>
    28 	// ]]>
    29   </script><p><span style="color:black;">You been f***ed by Enano | valid XHTML 1.1</span></p></body></html>
    29 	</script><p><span style="color:black;">You been f***ed by Enano | valid XHTML 1.1</span></p></body></html>
    30   <?php
    30 	<?php
    31   exit;
    31 	exit;
    32 }
    32 }
    33 
    33 
    34 // only do this if it hasn't been done yet
    34 // only do this if it hasn't been done yet
    35 if ( !defined('ENANO_COMMON_ROOT_LOADED') )
    35 if ( !defined('ENANO_COMMON_ROOT_LOADED') )
    36 {
    36 {
    52  */
    52  */
    53 
    53 
    54 // First check to see if something already declared this function.... it happens often.
    54 // First check to see if something already declared this function.... it happens often.
    55 if ( !function_exists('microtime_float') )
    55 if ( !function_exists('microtime_float') )
    56 {
    56 {
    57   function microtime_float()
    57 	function microtime_float()
    58   {
    58 	{
    59     list($usec, $sec) = explode(" ", microtime());
    59 		list($usec, $sec) = explode(" ", microtime());
    60     return ((float)$usec + (float)$sec);
    60 		return ((float)$usec + (float)$sec);
    61   }
    61 	}
    62 }
    62 }
    63 
    63 
    64 // Determine starting time
    64 // Determine starting time
    65 global $_starttime;
    65 global $_starttime;
    66 $_starttime = microtime_float();
    66 $_starttime = microtime_float();
    67 
    67 
    68 // Verbose error reporting
    68 // Verbose error reporting
    69 if ( defined('E_STRICT') )
    69 if ( defined('E_STRICT') )
    70 {
    70 {
    71   // PHP5, PHP6
    71 	// PHP5, PHP6
    72   error_reporting(E_ALL & ~E_STRICT);
    72 	error_reporting(E_ALL & ~E_STRICT);
    73 }
    73 }
    74 else
    74 else
    75 {
    75 {
    76   // PHP4
    76 	// PHP4
    77   error_reporting(E_ALL);
    77 	error_reporting(E_ALL);
    78 }
    78 }
    79 
    79 
    80 //
    80 //
    81 // Determine the location of Enano as an absolute path.
    81 // Determine the location of Enano as an absolute path.
    82 //
    82 //
    86 // using symlinks to reference the original files so as to segregate unique files from non-unique
    86 // using symlinks to reference the original files so as to segregate unique files from non-unique
    87 // and distribution-standard ones. Enano will pivot its root directory accordingly if the file
    87 // and distribution-standard ones. Enano will pivot its root directory accordingly if the file
    88 // .enanodev is found in the Enano root (not /repo/).
    88 // .enanodev is found in the Enano root (not /repo/).
    89 if ( strpos(__FILE__, '/repo/') && file_exists(dirname(__FILE__) . '/../../.enanodev') )
    89 if ( strpos(__FILE__, '/repo/') && file_exists(dirname(__FILE__) . '/../../.enanodev') )
    90 {
    90 {
    91   // We have a development directory. Remove /repo/ from the picture.
    91 	// We have a development directory. Remove /repo/ from the picture.
    92   $filename = str_replace('/repo/', '/', __FILE__);
    92 	$filename = str_replace('/repo/', '/', __FILE__);
    93 }
    93 }
    94 else
    94 else
    95 {
    95 {
    96   // Standard Enano installation
    96 	// Standard Enano installation
    97   $filename = __FILE__;
    97 	$filename = __FILE__;
    98 }
    98 }
    99 
    99 
   100 // ENANO_ROOT is sometimes defined by plugins like AjIM that need the constant before the Enano API is initialized
   100 // ENANO_ROOT is sometimes defined by plugins like AjIM that need the constant before the Enano API is initialized
   101 if ( !defined('ENANO_ROOT') )
   101 if ( !defined('ENANO_ROOT') )
   102   define('ENANO_ROOT', dirname(dirname($filename)));
   102 	define('ENANO_ROOT', dirname(dirname($filename)));
   103 
   103 
   104 // We deprecated debugConsole in 1.0.2 because it was never used and there were a lot of unneeded debugging points in the code.
   104 // We deprecated debugConsole in 1.0.2 because it was never used and there were a lot of unneeded debugging points in the code.
   105 
   105 
   106 // _nightly.php is used to tag non-Mercurial-generated nightly builds
   106 // _nightly.php is used to tag non-Mercurial-generated nightly builds
   107 if ( file_exists( ENANO_ROOT . '/_nightly.php') )
   107 if ( file_exists( ENANO_ROOT . '/_nightly.php') )
   108   require(ENANO_ROOT.'/_nightly.php');
   108 	require(ENANO_ROOT.'/_nightly.php');
   109 
   109 
   110 // List of scheduled tasks (don't change this manually, use register_cron_task())
   110 // List of scheduled tasks (don't change this manually, use register_cron_task())
   111 $cron_tasks = array();
   111 $cron_tasks = array();
   112 
   112 
   113 } // check for ENANO_COMMON_ROOT_LOADED
   113 } // check for ENANO_COMMON_ROOT_LOADED
   114 else
   114 else
   115 {
   115 {
   116   // loading a second time
   116 	// loading a second time
   117   if ( !defined('ENANO_COMMON_ROOT_LOADED_MULTI') )
   117 	if ( !defined('ENANO_COMMON_ROOT_LOADED_MULTI') )
   118   {
   118 	{
   119     define('ENANO_COMMON_ROOT_LOADED_MULTI', 1);
   119 		define('ENANO_COMMON_ROOT_LOADED_MULTI', 1);
   120   }
   120 	}
   121 }
   121 }
   122 
   122 
   123 // If all we really need is the root directory, just leave now
   123 // If all we really need is the root directory, just leave now
   124 // checking for ENANO_COMMON_ROOT_LOADED_MULTI here means that if common
   124 // checking for ENANO_COMMON_ROOT_LOADED_MULTI here means that if common
   125 // is included a second time, the rest of Enano will load.
   125 // is included a second time, the rest of Enano will load.
   126 if ( defined('ENANO_COMMON_ROOTONLY') && !defined('ENANO_COMMON_ROOT_LOADED_MULTI') )
   126 if ( defined('ENANO_COMMON_ROOTONLY') && !defined('ENANO_COMMON_ROOT_LOADED_MULTI') )
   127 {
   127 {
   128   return true;
   128 	return true;
   129 }
   129 }
   130 
   130 
   131 // Start including files. LOTS of files. Yeah!
   131 // Start including files. LOTS of files. Yeah!
   132 require_once(ENANO_ROOT.'/includes/constants.php');
   132 require_once(ENANO_ROOT.'/includes/constants.php');
   133 require_once(ENANO_ROOT.'/includes/functions.php');
   133 require_once(ENANO_ROOT.'/includes/functions.php');
   158 // All of these classes are singletons and are designed to carry as much data as possible within the object
   158 // All of these classes are singletons and are designed to carry as much data as possible within the object
   159 // to make data access and function calling easy.
   159 // to make data access and function calling easy.
   160 
   160 
   161 global $db, $session, $paths, $template, $plugins; // Common objects
   161 global $db, $session, $paths, $template, $plugins; // Common objects
   162 global $enano_config; // A global used to cache config information without making loads of queries ;-)
   162 global $enano_config; // A global used to cache config information without making loads of queries ;-)
   163                       // In addition, $enano_config is used to fetch config information if die_semicritical() is called.
   163 											// In addition, $enano_config is used to fetch config information if die_semicritical() is called.
   164 
   164 
   165 // Jim Tucek's e-mail encryption code                      
   165 // Jim Tucek's e-mail encryption code                      
   166 global $email;
   166 global $email;
   167 
   167 
   168 // Language object
   168 // Language object
   180 $is_https = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off';
   180 $is_https = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off';
   181 
   181 
   182 // Divert to CLI loader if running from CLI
   182 // Divert to CLI loader if running from CLI
   183 if ( defined('ENANO_CLI') || ( isset($argc) && isset($argv) ) )
   183 if ( defined('ENANO_CLI') || ( isset($argc) && isset($argv) ) )
   184 {
   184 {
   185   if ( defined('ENANO_CLI') || ( is_int($argc) && is_array($argv) && !isset($_SERVER['REQUEST_URI']) ) )
   185 	if ( defined('ENANO_CLI') || ( is_int($argc) && is_array($argv) && !isset($_SERVER['REQUEST_URI']) ) )
   186   {
   186 	{
   187     require(ENANO_ROOT . '/includes/common_cli.php');
   187 		require(ENANO_ROOT . '/includes/common_cli.php');
   188     return;
   188 		return;
   189   }
   189 	}
   190 }
   190 }
   191 
   191 
   192 // Because Enano sends out complete URLs in several occasions, we need to know what hostname the user is requesting the page from.
   192 // Because Enano sends out complete URLs in several occasions, we need to know what hostname the user is requesting the page from.
   193 // In future versions we may include a fallback "safety" host to use, but that's too much to worry about now
   193 // In future versions we may include a fallback "safety" host to use, but that's too much to worry about now
   194 if ( !isset($_SERVER['HTTP_HOST']) )
   194 if ( !isset($_SERVER['HTTP_HOST']) )
   195   grinding_halt('Cannot get hostname', '<p>Your web browser did not provide the HTTP Host: field. This site requires a modern browser that supports the HTTP 1.1 standard.</p>');
   195 	grinding_halt('Cannot get hostname', '<p>Your web browser did not provide the HTTP Host: field. This site requires a modern browser that supports the HTTP 1.1 standard.</p>');
   196 
   196 
   197 //
   197 //
   198 // END BACKGROUND AND ENVIRONMENT CHECKS
   198 // END BACKGROUND AND ENVIRONMENT CHECKS
   199 //
   199 //
   200 
   200 
   210 
   210 
   211 $config_file = ( defined('IN_ENANO_INSTALL') && !defined('IN_ENANO_UPGRADE') ) ? '/config.new.php' : '/config.php';
   211 $config_file = ( defined('IN_ENANO_INSTALL') && !defined('IN_ENANO_UPGRADE') ) ? '/config.new.php' : '/config.php';
   212 @include(ENANO_ROOT . $config_file);
   212 @include(ENANO_ROOT . $config_file);
   213 unset($dbuser, $dbpasswd);
   213 unset($dbuser, $dbpasswd);
   214 if ( !isset($dbdriver) )
   214 if ( !isset($dbdriver) )
   215   $dbdriver = 'mysql';
   215 	$dbdriver = 'mysql';
   216 
   216 
   217 $db = new $dbdriver();
   217 $db = new $dbdriver();
   218 $db->connect();
   218 $db->connect();
   219 
   219 
   220 profiler_log('Database connected');
   220 profiler_log('Database connected');
   227 unset($sep); // save 10 bytes of memory...
   227 unset($sep); // save 10 bytes of memory...
   228 
   228 
   229 // Build the list of system tables (this is mostly done in constants.php, but that's before table_prefix is known)
   229 // Build the list of system tables (this is mostly done in constants.php, but that's before table_prefix is known)
   230 if ( defined('table_prefix') && !defined('ENANO_TABLELIST_PREFIXED') )
   230 if ( defined('table_prefix') && !defined('ENANO_TABLELIST_PREFIXED') )
   231 {
   231 {
   232   define('ENANO_TABLELIST_PREFIXED', 1);
   232 	define('ENANO_TABLELIST_PREFIXED', 1);
   233   foreach ( $system_table_list as $i => $_ )
   233 	foreach ( $system_table_list as $i => $_ )
   234   {
   234 	{
   235     $system_table_list[$i] = table_prefix . $system_table_list[$i];
   235 		$system_table_list[$i] = table_prefix . $system_table_list[$i];
   236   }
   236 	}
   237 }
   237 }
   238 
   238 
   239 // Select and fetch the site configuration
   239 // Select and fetch the site configuration
   240 $e = $db->sql_query('SELECT config_name, config_value FROM '.table_prefix.'config;');
   240 $e = $db->sql_query('SELECT config_name, config_value FROM '.table_prefix.'config;');
   241 if ( !$e )
   241 if ( !$e )
   242 {
   242 {
   243   $db->_die('Some critical configuration information could not be selected.');
   243 	$db->_die('Some critical configuration information could not be selected.');
   244 }
   244 }
   245 // Used in die_semicritical to figure out whether to call getConfig() or not
   245 // Used in die_semicritical to figure out whether to call getConfig() or not
   246 define('ENANO_CONFIG_FETCHED', '');
   246 define('ENANO_CONFIG_FETCHED', '');
   247 
   247 
   248 // Initialize and fetch the site configuration array, which is used to cache the config
   248 // Initialize and fetch the site configuration array, which is used to cache the config
   249 $enano_config = Array();
   249 $enano_config = Array();
   250 while($r = $db->fetchrow())
   250 while($r = $db->fetchrow())
   251 {
   251 {
   252   $enano_config[$r['config_name']] = $r['config_value'];
   252 	$enano_config[$r['config_name']] = $r['config_value'];
   253 }
   253 }
   254 
   254 
   255 $db->free_result();
   255 $db->free_result();
   256 
   256 
   257 profiler_log('Config fetched');
   257 profiler_log('Config fetched');
   258 
   258 
   259 if ( defined('ENANO_EXIT_AFTER_CONFIG') )
   259 if ( defined('ENANO_EXIT_AFTER_CONFIG') )
   260 {
   260 {
   261   return true;
   261 	return true;
   262 }
   262 }
   263 
   263 
   264 // Now that we have the config, check the Enano version.
   264 // Now that we have the config, check the Enano version.
   265 if ( enano_version(false, true) != $version && !defined('IN_ENANO_UPGRADE') )
   265 if ( enano_version(false, true) != $version && !defined('IN_ENANO_UPGRADE') )
   266 {
   266 {
   267   grinding_halt('Version mismatch', '<p>It seems that the Enano release we\'re trying to run ('.$version.') is different from the version specified in your database ('.enano_version().'). Perhaps you need to <a href="'.scriptPath.'/install/index.php">upgrade</a>?</p>');
   267 	grinding_halt('Version mismatch', '<p>It seems that the Enano release we\'re trying to run ('.$version.') is different from the version specified in your database ('.enano_version().'). Perhaps you need to <a href="'.scriptPath.'/install/index.php">upgrade</a>?</p>');
   268 }
   268 }
   269 
   269 
   270 // Set our CDN path
   270 // Set our CDN path
   271 if ( !defined('cdnPath') )
   271 if ( !defined('cdnPath') )
   272 {
   272 {
   273   $cdnpath = getConfig('cdn_path', scriptPath);
   273 	$cdnpath = getConfig('cdn_path', scriptPath);
   274   if ( empty($cdnpath) )
   274 	if ( empty($cdnpath) )
   275     $cdnpath = scriptPath;
   275 		$cdnpath = scriptPath;
   276   define('cdnPath', $cdnpath);
   276 	define('cdnPath', $cdnpath);
   277 }
   277 }
   278 
   278 
   279 //
   279 //
   280 // Low level maintenance
   280 // Low level maintenance
   281 //
   281 //
   282 
   282 
   283 // If the AES key size has been changed, bail out and fast
   283 // If the AES key size has been changed, bail out and fast
   284 if ( !getConfig('aes_key_size') )
   284 if ( !getConfig('aes_key_size') )
   285 {
   285 {
   286   setConfig('aes_key_size', AES_BITS);
   286 	setConfig('aes_key_size', AES_BITS);
   287 }
   287 }
   288 else if ( $ks = getConfig('aes_key_size') )
   288 else if ( $ks = getConfig('aes_key_size') )
   289 {
   289 {
   290   if ( intval($ks) != AES_BITS )
   290 	if ( intval($ks) != AES_BITS )
   291   {
   291 	{
   292     grinding_halt('AES key size changed', '<p>Enano has detected that the AES key size in constants.php has been changed. This change cannot be performed after installation, otherwise the private key would have to be re-generated and all passwords would have to be re-encrypted.</p><p>Please change the key size back to ' . $ks . ' bits and reload this page.</p>');
   292 		grinding_halt('AES key size changed', '<p>Enano has detected that the AES key size in constants.php has been changed. This change cannot be performed after installation, otherwise the private key would have to be re-generated and all passwords would have to be re-encrypted.</p><p>Please change the key size back to ' . $ks . ' bits and reload this page.</p>');
   293   }
   293 	}
   294 }
   294 }
   295 
   295 
   296 // Same for AES block size
   296 // Same for AES block size
   297 if ( !getConfig('aes_block_size') )
   297 if ( !getConfig('aes_block_size') )
   298 {
   298 {
   299   setConfig('aes_block_size', AES_BLOCKSIZE);
   299 	setConfig('aes_block_size', AES_BLOCKSIZE);
   300 }
   300 }
   301 else if ( $ks = getConfig('aes_block_size') )
   301 else if ( $ks = getConfig('aes_block_size') )
   302 {
   302 {
   303   if ( intval($ks) != AES_BLOCKSIZE )
   303 	if ( intval($ks) != AES_BLOCKSIZE )
   304   {
   304 	{
   305     grinding_halt('AES block size changed', '<p>Enano has detected that the AES block size in constants.php has been changed. This change cannot be performed after installation, otherwise all passwords would have to be re-encrypted.</p><p>Please change the block size back to ' . $ks . ' bits and reload this page.</p>');
   305 		grinding_halt('AES block size changed', '<p>Enano has detected that the AES block size in constants.php has been changed. This change cannot be performed after installation, otherwise all passwords would have to be re-encrypted.</p><p>Please change the block size back to ' . $ks . ' bits and reload this page.</p>');
   306   }
   306 	}
   307 }
   307 }
   308 
   308 
   309 // Is there no default language?
   309 // Is there no default language?
   310 if ( getConfig('default_language') === false && !defined('IN_ENANO_MIGRATION') )
   310 if ( getConfig('default_language') === false && !defined('IN_ENANO_MIGRATION') )
   311 {
   311 {
   312   $q = $db->sql_query('SELECT lang_id FROM '.table_prefix.'language LIMIT 1;');
   312 	$q = $db->sql_query('SELECT lang_id FROM '.table_prefix.'language LIMIT 1;');
   313   if ( !$q )
   313 	if ( !$q )
   314     $db->_die('common.php - setting default language');
   314 		$db->_die('common.php - setting default language');
   315   if ( $db->numrows() < 1 && !defined('ENANO_ALLOW_LOAD_NOLANG') )
   315 	if ( $db->numrows() < 1 && !defined('ENANO_ALLOW_LOAD_NOLANG') )
   316   {
   316 	{
   317     grinding_halt('No languages', '<p>There are no languages installed on this site.</p>
   317 		grinding_halt('No languages', '<p>There are no languages installed on this site.</p>
   318         <p>If you are the website administrator, you may install a language by writing and executing a simple PHP script to install it:</p>
   318 				<p>If you are the website administrator, you may install a language by writing and executing a simple PHP script to install it:</p>
   319         <pre>
   319 				<pre>
   320 &lt;?php
   320 &lt;?php
   321 define("ENANO_ALLOW_LOAD_NOLANG", 1);
   321 define("ENANO_ALLOW_LOAD_NOLANG", 1);
   322 require("includes/common.php");
   322 require("includes/common.php");
   323 install_language("eng", "English", "English", ENANO_ROOT . "/language/english/enano.json");</pre>');
   323 install_language("eng", "English", "English", ENANO_ROOT . "/language/english/enano.json");</pre>');
   324   }
   324 	}
   325   $row = $db->fetchrow();
   325 	$row = $db->fetchrow();
   326   setConfig('default_language', $row['lang_id']);
   326 	setConfig('default_language', $row['lang_id']);
   327 }
   327 }
   328 
   328 
   329 profiler_log('Ran checks');
   329 profiler_log('Ran checks');
   330 
   330 
   331 // Init cache
   331 // Init cache
   346 global $plugins;
   346 global $plugins;
   347 
   347 
   348 // Load plugins from common because we can't give plugins full abilities in object context
   348 // Load plugins from common because we can't give plugins full abilities in object context
   349 foreach ( $plugins->load_list as $f )
   349 foreach ( $plugins->load_list as $f )
   350 {
   350 {
   351   if ( file_exists(ENANO_ROOT . '/plugins/' . $f) )
   351 	if ( file_exists(ENANO_ROOT . '/plugins/' . $f) )
   352     include_once ENANO_ROOT . '/plugins/' . $f;
   352 		include_once ENANO_ROOT . '/plugins/' . $f;
   353 }
   353 }
   354 
   354 
   355 profiler_log('Loaded plugins');
   355 profiler_log('Loaded plugins');
   356 
   356 
   357 // Three fifths of the Enano API gets the breath of life right here.
   357 // Three fifths of the Enano API gets the breath of life right here.
   369 // Once $paths->init() is called, we could be redirected to the main page, so we don't want
   369 // Once $paths->init() is called, we could be redirected to the main page, so we don't want
   370 // that if the installer's running. Don't just go and define IN_ENANO_INSTALL from your
   370 // that if the installer's running. Don't just go and define IN_ENANO_INSTALL from your
   371 // script though, because that will make the DBAL look in the wrong place for the config file.
   371 // script though, because that will make the DBAL look in the wrong place for the config file.
   372 if ( !defined('IN_ENANO_INSTALL') )
   372 if ( !defined('IN_ENANO_INSTALL') )
   373 {
   373 {
   374   // And here you have it, the de facto way to place a hook. Plugins can place hooks and hook
   374 	// And here you have it, the de facto way to place a hook. Plugins can place hooks and hook
   375   // into other plugins. You just never know.
   375 	// into other plugins. You just never know.
   376   $code = $plugins->setHook('base_classes_initted');
   376 	$code = $plugins->setHook('base_classes_initted');
   377   foreach ( $code as $cmd )
   377 	foreach ( $code as $cmd )
   378   {
   378 	{
   379     eval($cmd);
   379 		eval($cmd);
   380   }
   380 	}
   381   
   381 	
   382   profiler_log('Finished base_classes_initted hook');
   382 	profiler_log('Finished base_classes_initted hook');
   383   
   383 	
   384   // One quick security check...
   384 	// One quick security check...
   385   if ( !is_valid_ip($_SERVER['REMOTE_ADDR']) )
   385 	if ( !is_valid_ip($_SERVER['REMOTE_ADDR']) )
   386   {
   386 	{
   387     die('SECURITY: spoofed IP address: ' . htmlspecialchars($_SERVER['REMOTE_ADDR']));
   387 		die('SECURITY: spoofed IP address: ' . htmlspecialchars($_SERVER['REMOTE_ADDR']));
   388   }
   388 	}
   389   
   389 	
   390   // For special and administration pages, sometimes there is a "preloader" function that must be run
   390 	// For special and administration pages, sometimes there is a "preloader" function that must be run
   391   // before the session manager and/or path manager get the init signal. Call it here.
   391 	// before the session manager and/or path manager get the init signal. Call it here.
   392   $urlname = get_title(true);
   392 	$urlname = get_title(true);
   393   list($page_id, $namespace) = RenderMan::strToPageID($urlname);
   393 	list($page_id, $namespace) = RenderMan::strToPageID($urlname);
   394   list($page_id_top) = explode('/', $page_id);
   394 	list($page_id_top) = explode('/', $page_id);
   395   $fname = "page_{$namespace}_{$page_id_top}_preloader";
   395 	$fname = "page_{$namespace}_{$page_id_top}_preloader";
   396   if( ( $namespace == 'Admin' || $namespace == 'Special' ) && function_exists($fname))
   396 	if( ( $namespace == 'Admin' || $namespace == 'Special' ) && function_exists($fname))
   397   {
   397 	{
   398     call_user_func($fname);
   398 		call_user_func($fname);
   399   }
   399 	}
   400   
   400 	
   401   profiler_log('Checked for (and ran, if applicable) preloader');
   401 	profiler_log('Checked for (and ran, if applicable) preloader');
   402   
   402 	
   403   // Add all of our built in special pages
   403 	// Add all of our built in special pages
   404   foreach ( array('SpecialUserFuncs', 'SpecialPageFuncs', 'SpecialAdmin', 'SpecialCSS', 'SpecialUpDownload', 'SpecialSearch', 'PrivateMessages', 'SpecialGroups', 'SpecialLog') as $plugin )
   404 	foreach ( array('SpecialUserFuncs', 'SpecialPageFuncs', 'SpecialAdmin', 'SpecialCSS', 'SpecialUpDownload', 'SpecialSearch', 'PrivateMessages', 'SpecialGroups', 'SpecialLog') as $plugin )
   405   {
   405 	{
   406     $funcname = "{$plugin}_paths_init";
   406 		$funcname = "{$plugin}_paths_init";
   407     if ( function_exists($funcname) )
   407 		if ( function_exists($funcname) )
   408     {
   408 		{
   409       $funcname();
   409 			$funcname();
   410     }
   410 		}
   411   }
   411 	}
   412   profiler_log('Added special pages');
   412 	profiler_log('Added special pages');
   413   
   413 	
   414   // All checks passed! Start the main components up.  
   414 	// All checks passed! Start the main components up.  
   415   $session->start();
   415 	$session->start();
   416   
   416 	
   417   // This is where plugins will want to add pages from 1.1.x on out. You can still add
   417 	// This is where plugins will want to add pages from 1.1.x on out. You can still add
   418   // pages at base_classes_initted but the titles won't be localized. This is because
   418 	// pages at base_classes_initted but the titles won't be localized. This is because
   419   // the session manager has to be started before localization will work in the user's
   419 	// the session manager has to be started before localization will work in the user's
   420   // preferred language.
   420 	// preferred language.
   421   $code = $plugins->setHook('session_started');
   421 	$code = $plugins->setHook('session_started');
   422   foreach ( $code as $cmd )
   422 	foreach ( $code as $cmd )
   423   {
   423 	{
   424     eval($cmd);
   424 		eval($cmd);
   425   }
   425 	}
   426   
   426 	
   427   profiler_log('Ran session_started hook');
   427 	profiler_log('Ran session_started hook');
   428   
   428 	
   429   $paths->init($urlname);
   429 	$paths->init($urlname);
   430   
   430 	
   431   // setup output format
   431 	// setup output format
   432   if ( defined('ENANO_OUTPUT_FORMAT') )
   432 	if ( defined('ENANO_OUTPUT_FORMAT') )
   433     $class = 'Output_' . ENANO_OUTPUT_FORMAT;
   433 		$class = 'Output_' . ENANO_OUTPUT_FORMAT;
   434   else
   434 	else
   435     $class = ( isset($_GET['noheaders']) ) ? 'Output_Naked' : 'Output_HTML';
   435 		$class = ( isset($_GET['noheaders']) ) ? 'Output_Naked' : 'Output_HTML';
   436     
   436 		
   437   $output = new $class();
   437 	$output = new $class();
   438   
   438 	
   439   // Are we running from the API? If so, did the page set a title?
   439 	// Are we running from the API? If so, did the page set a title?
   440   if ( !defined('ENANO_INTERFACE_INDEX') && !defined('ENANO_INTERFACE_AJAX') && isset($title) )
   440 	if ( !defined('ENANO_INTERFACE_INDEX') && !defined('ENANO_INTERFACE_AJAX') && isset($title) )
   441   {
   441 	{
   442     $output->set_title($title);
   442 		$output->set_title($title);
   443   }
   443 	}
   444   
   444 	
   445   // We're ready for whatever life throws us now, at least from an API point of view.
   445 	// We're ready for whatever life throws us now, at least from an API point of view.
   446   define('ENANO_MAINSTREAM', '');
   446 	define('ENANO_MAINSTREAM', '');
   447   
   447 	
   448   // If the site is disabled, bail out, unless we're trying to log in or administer the site
   448 	// If the site is disabled, bail out, unless we're trying to log in or administer the site
   449   if(getConfig('site_disabled') == '1' && $session->user_level < USER_LEVEL_ADMIN)
   449 	if(getConfig('site_disabled') == '1' && $session->user_level < USER_LEVEL_ADMIN)
   450   {
   450 	{
   451     // is this one of the more critical special pages?
   451 		// is this one of the more critical special pages?
   452     if ( $paths->namespace == 'Admin' || ( $paths->namespace == 'Special' && ( $paths->page_id == 'CSS' || $paths->page_id == 'Administration' || $paths->page_id == 'Login' ) ) )
   452 		if ( $paths->namespace == 'Admin' || ( $paths->namespace == 'Special' && ( $paths->page_id == 'CSS' || $paths->page_id == 'Administration' || $paths->page_id == 'Login' ) ) )
   453     {
   453 		{
   454       // yeah, we need to keep this page available. do nothing; allow execution to continue
   454 			// yeah, we need to keep this page available. do nothing; allow execution to continue
   455     }
   455 		}
   456     else
   456 		else
   457     {
   457 		{
   458       if(!$n = getConfig('site_disabled_notice')) 
   458 			if(!$n = getConfig('site_disabled_notice')) 
   459       {
   459 			{
   460         $n = 'The administrator has disabled the site. Please check back later.';
   460 				$n = 'The administrator has disabled the site. Please check back later.';
   461       }
   461 			}
   462       
   462 			
   463       $text = RenderMan::render($n) . '
   463 			$text = RenderMan::render($n) . '
   464       <div class="info-box">
   464 			<div class="info-box">
   465         If you have an administrative account, you may <a href="'.makeUrlNS('Special', 'Login').'">log in</a> to the site.
   465 				If you have an administrative account, you may <a href="'.makeUrlNS('Special', 'Login').'">log in</a> to the site.
   466       </div>';
   466 			</div>';
   467       $paths->wiki_mode = 0;
   467 			$paths->wiki_mode = 0;
   468       die_semicritical('Site disabled', $text);
   468 			die_semicritical('Site disabled', $text);
   469     }
   469 		}
   470   }
   470 	}
   471   else if ( getConfig('site_disabled') == '1' && $session->user_level >= USER_LEVEL_ADMIN )
   471 	else if ( getConfig('site_disabled') == '1' && $session->user_level >= USER_LEVEL_ADMIN )
   472   {
   472 	{
   473     // If the site is disabled but the user has admin rights, allow browsing
   473 		// If the site is disabled but the user has admin rights, allow browsing
   474     // and stuff, but display the orange box notifying the admin.
   474 		// and stuff, but display the orange box notifying the admin.
   475     $template->site_disabled = true;
   475 		$template->site_disabled = true;
   476   }
   476 	}
   477   
   477 	
   478   // At this point all of Enano is fully initialized and running and you're ready to do whatever you want.
   478 	// At this point all of Enano is fully initialized and running and you're ready to do whatever you want.
   479   $code = $plugins->setHook('common_post');
   479 	$code = $plugins->setHook('common_post');
   480   foreach ( $code as $cmd )
   480 	foreach ( $code as $cmd )
   481   {
   481 	{
   482     eval($cmd);
   482 		eval($cmd);
   483   }
   483 	}
   484   
   484 	
   485   profiler_log('Ran disabled-site checks and common_post');
   485 	profiler_log('Ran disabled-site checks and common_post');
   486   
   486 	
   487   load_rank_data();
   487 	load_rank_data();
   488   
   488 	
   489   profiler_log('Loaded user rank data');
   489 	profiler_log('Loaded user rank data');
   490   
   490 	
   491   if ( isset($_GET['noheaders']) )
   491 	if ( isset($_GET['noheaders']) )
   492     $template->no_headers = true;
   492 		$template->no_headers = true;
   493 }
   493 }
   494 
   494 
   495 profiler_log('common finished');
   495 profiler_log('common finished');
   496 
   496 
   497 // That's the end. Enano should be loaded now :-)
   497 // That's the end. Enano should be loaded now :-)