3 * con.php: Generic setup file.
5 * Contains user authentication, database connection and other exciting stuff.
6 * Everything else depends on this file. Don't touch it unless you know what
7 * you're doing, all the config is done in other places.
9 * @author Anthony Parsons (irc://specialops.ath.cx/whitefyre)
10 * @license file:COPYING
15 * Source revision displayed in the page footer.
16 * AFAIK there's no way to get the overall value both accurately and quickly,
17 * so the revision for just this file will have to do.
19 define('SO2VER', '$Rev$');
22 // Check for PHP version. SO2 won't run (sanely) on anything less than PHP 5.
23 if ( version_compare(PHP_VERSION
, '5.0', '<') ) {
24 header('HTTP/1.1 500 Internal Server Error');
25 die('Fatal Server Error: PHP 5.0 or higher is required.');
28 // Use verbose errors. They won't be shown to the general public anyway.
29 error_reporting(E_ALL|E_STRICT
);
33 * Start that timer at the bottom of each page.
35 define('CLOCK', microtime(1));
38 /* Empty exception classes.
39 These allow for more specific catch{} blocks. */
40 class InvalidInputException
extends Exception
{}
41 class DatabaseException
extends Exception
{}
42 class RateLimitException
extends Exception
{}
45 /* SPL exception classes:
46 These classes are defined in the Standard PHP Library in PHP 5.1 and above.
47 If you only run the code on a 5.0 server, you can delete the if...{ and } lines.
48 If you only run it on a 5.1 server, you can delete the lines inbetween too. */
49 if ( version_compare(PHP_VERSION
, '5.1', '<') ) {
50 class OutOfBoundsException
extends Exception
{}
51 class RuntimeException
extends Exception
{}
52 class LengthException
extends Exception
{}
59 function __autoload($classname)
61 require 'lib/class.'.$classname.'.php';
66 if ( !isset($_SERVER['REMOTE_ADDR']) ||
$_SERVER['REMOTE_ADDR'] === $_SERVER['SERVER_ADDR'] )
68 * If the "DEVELOPER" constant is defined a bunch of stuff works differently.
70 define('DEVELOPER', 1);
73 // Create page object. The earlier this is done the better, because it contains the error handler stuff.
77 /* Set up the exception handler bit.
78 If dev mode is on you'll get a traceback when something fucks up.
79 If not, you'll get a patronizing/"user-friendly" error message. */
80 if ( defined('DEVELOPER') ) {
81 /* Using the output buffer lets us switch off XHTML mode later if something buggers up.
82 Fixing PHP errors is a lot less stressful when they're not hidden behind XML ones. */
85 function e_handler($exception)
87 header('HTTP/1.1 500 Internal Server Error');
88 header('Content-Type: text/html; charset=UTF-8');
89 echo '<pre class="error">',$exception->__toString(),'</pre>';
93 function e_handler($exception)
95 if ( !headers_sent() ) {
96 header('HTTP/1.1 500 Internal Server Error');
97 header('Content-Type: text/html; charset=UTF-8');
99 $page->errorfooter('runtime');
102 set_exception_handler('e_handler');
105 /* Database thingers.
106 Refer to res/mysql_ident.example for how this file should look. */
107 require 'mysql_ident.php';
110 /* Open database connection here. This is where it gets more interesting.
111 lib/class.debugmysqli.php has a bunch of debug stuff you might want to mess with. */
112 if ( defined('DEVELOPER') ) {
113 /* Turns on Really Fucking Verbose Modeā¢.
114 This line is disabled because it persists across threads.
115 Don't use it unless you're masochistic. */
116 //mysqli_report(MYSQLI_REPORT_ALL);
118 $DB = new debugmysqli($DB['host'], $DB['user'], $DB['pass'], DATABASE_NAME
);
120 $DB = new mysqli($DB['host'], $DB['user'], $DB['pass'], DATABASE_NAME
);
122 // Check for a DB connection error. Shit happens.
123 if ( mysqli_connect_errno() ) {
124 header('HTTP/1.1 500 Internal Server Error');
125 die('Server error connecting to DB');
128 // Check MySQL server version. See the comment about PHP versions at the top of the file.
129 if ( version_compare($DB->server_info
, '5.0', '<') ) {
130 header('HTTP/1.1 500 Internal Server Error');
131 die('Server error: MySQL 5.0 not found');
134 /* Login cookie setting hack.
135 This bit could be avoided by using $_SESSION everywhere I used $_COOKIE, but sessions are crap. */
136 if ( isset($_POST['login'], $_POST['u'], $_POST['p']) )
137 list($_COOKIE['u'], $_COOKIE['p']) = array($_POST['u'], $_POST['p']);
140 // The rest of the file is stuff to decide whether you're logged in or not:
141 if ( isset($_POST['logout']) ) {
142 setcookie('u', null, 1);
143 setcookie('p', null, 1);
145 $user = new anonuser
;
146 } elseif ( isset($_COOKIE['u'], $_COOKIE['p']) ) {
147 /* Try to get the user ID from the DB.
148 Also tells the DB to remember your user ID, saves fucking around with PHP globals all the time. */
149 $q = $DB->query('SELECT @userid := `userid` FROM `users`
150 WHERE `alias` = \''.$DB->escape_string($_COOKIE['u']).'\'
151 AND (`password` = AES_ENCRYPT(\''.$DB->escape_string($_COOKIE['p']).'\', `reg_ip`)
152 OR `password` IS NULL)');
154 // If there's a matching row in the DB then they're authenticated
155 if ( 1 === $q->num_rows
) {
156 // Keep people logged in for 24 hours after their last page view
157 setcookie('u', $_COOKIE['u'], time()+
86400);
158 setcookie('p', $_COOKIE['p'], time()+
86400);
160 $user = new authuser(isset($prefetch) ?
$prefetch : null);
162 /* This block of code gets executed if they fail a login attempt.
163 The relevant insults are in lib/class.page.php */
164 setcookie('u', null, 1);
165 setcookie('p', null, 1);
167 $user = new anonuser
;
170 $user = new anonuser
;