<?php

	/*
	*	Gekko - Open Source Web Development Framework
	*	------------------------------------------------------------------------
	*	Copyright (C) 2004-2005, J. Carlos Nieto <xiam@users.sourceforge.net>
	*	This program is Free Software.
	*
	*	@package	Gekko
	*	@license	http://www.gnu.org/copyleft/gpl.html GNU/GPL License 2.0
	*	@author		J. Carlos Nieto <xiam@users.sf.net>
	*	@version	CVS: $Id:$
	*	@link		http://www.gekkoware.org
	*/

	if (!defined("IN-GEKKO")) die("Get a life!");

	/* BEGIN CORE CONFIGURATION */

	// the gekko main source path
	define("GEKKO_ROOT", dirname(__FILE__)."/");

	// this directory must be writable for gekko and should not be visible
	// for web clients... (check temp/.htaccess)
	define("GEKKO_TMPDIR", GEKKO_ROOT."temp/");

	// enable this for showing gekko detailed errors (useful when you're
	// developing modules or the core)
	define("GEKKO_ENABLE_DEBUG", true);

	// current version of gekko (as distribution)
	define("GEKKO_VERSION", "0.5.12");

	// default language files to load
	define("GEKKO_DEFAULT_LANG", "es");

	// seconds that a nasty user must be banned when trying to perform
	// common attacks such as d.o.s. against gekko engine
	define("GEKKO_BAN_TIME", 600);

	// use 'real ip' (not 'real' since it can be faked) instead of the
	// proxy ip
	define("GEKKO_REAL_IP", false);

	// enables gekko demo mode (all action requests are denied)
	define("GEKKO_DEMO_MODE", false);

	// set this as 'true' when you're having 'connection timeout' problems
	// or if you know your host is not allowing secure http (shttp)
	// connections.
	define("GEKKO_NO_SSL", false);

	/* END CORE CONFIGURATION */

	// works better when register globals if off.
	ini_set("register_globals", false);

	if (GEKKO_ENABLE_DEBUG) {
		error_reporting(E_ALL);
		ini_set("display_errors", true);
	}

	/*
	*	getmicrotime();
	*	Returns current time fraction.
	*/
	function getmicrotime() {
		$mtime = explode(" ",microtime());
		return ((float)$mtime[0] + (float)$mtime[1]);
	}

	define ("GEKKO_START_TIME", getmicrotime());

	/*
	*	getIP(); (Borrowed from php.net)
	*	Returns current user's IP.
	*	This needs to be checked since X-Forwarded-For headed can be easily changed...
	*/
	function getIP() {
		$ip = false;
		$ips = array();
		if (!empty($_SERVER["HTTP_CLIENT_IP"])) {
			$ip = $_SERVER["HTTP_CLIENT_IP"];
		}
		if (!empty($_SERVER["HTTP_X_FORWARDED_FOR"])) {
			$ips = explode(", ", $_SERVER["HTTP_X_FORWARDED_FOR"]);
			if ($ip) { array_unshift($ips, $ip); $ip = false; }
		}
		for ($i = 0; $i < count($ips); $i++) {
			if (!eregi("^(10|172\.16|192\.168)\.", $ips[$i])) {
				$ip = $ips[$i];
				break;
			}
		}
		return (($ip && GEKKO_REAL_IP == true) ? $ip : $_SERVER["REMOTE_ADDR"]);
	}

	define ("USER_IP", getIP());

	// this hack solves some problems with PHP 5 and "pretty urls"
	if (isset($_SERVER["ORIG_PATH_INFO"]) && $_SERVER["ORIG_PATH_INFO"]) $_SERVER["PATH_INFO"] = $_SERVER["ORIG_PATH_INFO"];
	if (isset($_ENV["ORIG_PATH_INFO"]) && $_ENV["ORIG_PATH_INFO"]) $_SERVER["PATH_INFO"] = $_ENV["ORIG_PATH_INFO"];
	if (isset($_ENV["PATH_INFO"]) && $_ENV["PATH_INFO"]) $_SERVER["PATH_INFO"] = $_ENV["PATH_INFO"];

	/*
		MAGIC BLACKLIST

		Some lonely and spheric dudes thinks that is very funny to
		do a lot of automated requests for overloading our database
		and see what happens. If you ask me, I think it's very lame.
		So, when some stupid kid is trying to do such a thing we warning
		him about the risks on being stupid and, if he doesn't care,
		we add his stupid IP to our stupid blacklist. We ban his
		access for about 10 minutes (by default) until he leaves to
		do such stupid requests.

		Please check lib/auth.inc.php, there you will find the
		complementary part of this script
	*/

	/* contains a (serialized) list of banned ips */
	define("GEKKO_BLACKLIST", GEKKO_TMPDIR."ip.banned");

	$banlist = Array();
	$is_banned = false;
	$ban_reason = "";

	// setting file handler for banlist (if exists)
	if (file_exists(GEKKO_BLACKLIST) && (($banfh = fopen(GEKKO_BLACKLIST, "r+")) !== false)) {

		// loading serialized banned ip list
		$banlist = unserialize(fread($banfh, filesize(GEKKO_BLACKLIST)));

		// checking & updating entries in the ban list
		foreach ($banlist as $ip => $time) {
			// personalized error message and bantime
			if (is_array($time))
				list($time, $bantime, $banmsg) = $time;

			if (($time+(isset($bantime) ? $bantime : GEKKO_BAN_TIME)) < time()) {
				// this user has fulfilled his punishment, removing from ban list
				unset($banlist[$ip]);
			} else {
				if ($ip == USER_IP) {
					$is_banned = true;
					$ban_reason = isset($banmsg) ? $banmsg : "";
				}
			}
		}
		// saving our updated banlist
		fwrite($banfh, serialize($banlist));
		// closing file handler (this was opened in conf.php)
		fclose($banfh);
	}

	if ($is_banned) {
		// aborting by showing a `you're so annoying` message.
		header("HTTP/1.1 403 Forbidden");
		echo "
		<h1>Forbidden</h1>
		".($ban_reason ? $ban_reason : "You've been a bad, bad girl! I though I told you not to bother me!")."
		<hr /><address>This site is powered by <a href=\"http://www.gekkoware.org\">Gekko</a></address>
		";
		die;
	}
	// NOTE: updated banlist array is not saved, and $ban_fh (banlist file handler)
	// is still open, the list will be saved in auth.inc.php

	// END MAGIC BLACKLIST

	$_cache = array();

	require_once("lib/core.lib.php");

	if (!defined("IN-INSTALL")) {

		db_init();

		// stored user language preferences
		$test_lang = isset($_GET["lang"]) ? $_GET["lang"] : ((($cookie = rcookie("lang")) != false) ? $cookie : conf::getkey("core", "site.lang"));
		$test_lang = preg_replace("/[^a-zA-Z\-]/", "", $test_lang);

		if ($test_lang && isset($_GET["lang"])) {
			// how to store language preferences?
			// http://www.example.org/index.php?lang=es
			gcookie("lang", $test_lang);
		}

		define ("GEKKO_LANG", $test_lang);

		$Lang = new Lang();

		// access table is very useful! isn't it?
		$AccessTable = new AccessControl();

		// loading core configuration variables
		$Conf = new Conf();
		$Conf->Load("core");

		// note that we're requesting both 'core' and 'lang' modules, when 'lang' module
		// is specified, it's key and value will overwrite the default definition.
		$db->query("
		SELECT
			Module, KeyName, KeyValue
		FROM ".db_table("conf")."
		WHERE Module = 'core' OR Module = 'lang'
		", __FILE__, __LINE__);

		while ($row = $db->fetch_row()) {
			// configuration values are accesible by the form:
			// 		C_CONF.KEY
			$prefix = "C";
			switch ($row["Module"]) {
				case "lang":
					$prefix = "L";
				break;
			}
			_l($prefix."_".strtoupper($row["KeyName"]), $row["KeyValue"]);
		}

		/* stylesheet */
		if (isset($_GET["style"]) || rcookie("style")) {
			// overwriting style preferences
			$style = isset($_GET["style"]) ? $_GET["style"] : rcookie("style");

			$style = preg_replace("/[^a-zA-Z0-9\-_]/", "", $style);
			if (file_exists(GEKKO_ROOT."templates/{$L["C_SITE.TEMPLATE"]}/$style.css")) {
				_l("C_SITE.STYLESHEET", $style);
				gcookie("style", $style);
			}
		}

		if (!file_exists(GEKKO_ROOT."templates/{$L["C_SITE.TEMPLATE"]}/"._l("C_SITE.STYLESHEET").".css"))
			_l("C_SITE.STYLESHEET", "default");
	}

	_l("C_SITE.LANG", GEKKO_LANG);

	_l("C_SITE.REQUEST_PATH", preg_replace("/\?(.*)/", "", $_SERVER["REQUEST_URI"]));

	// SETTING UP DINAMIC CONSTANTS
	_l("C_SITE_ROOT", rtrim(dirname($_SERVER["SCRIPT_NAME"]), "/"));

	// guessing relative path
	_l("C_SITE.REL_URL", rtrim(str_repeat("../", substr_count(substr($_SERVER["REQUEST_URI"], strlen($_SERVER["SCRIPT_NAME"])), "/")), "/"));
	if ($L["C_SITE.REL_URL"]) $L["C_SITE.REL_URL"] .= "/";

	if (!isset($L["C_SITE.ICONTHEME"])) $L["C_SITE.ICONTHEME"] = "default";
	if (!isset($L["C_SITE.TEMPLATE"])) $L["C_SITE.TEMPLATE"] = "default";

	_l("C_TEMPLATEDIR", "{$L["C_SITE.REL_URL"]}templates/{$L["C_SITE.TEMPLATE"]}/");
	_l("C_ICONDIR", "{$L["C_SITE.REL_URL"]}media/icons/{$L["C_SITE.ICONTHEME"]}/");
	_l("C_GEKKO_VERSION", GEKKO_VERSION);

	// main script url
	$gekko_uri = "http://{$_SERVER["SERVER_NAME"]}".(($_SERVER["SERVER_PORT"] != 80) ? ":{$_SERVER["SERVER_PORT"]}":"").dirname($_SERVER["SCRIPT_NAME"]);
	if (ereg("/modules/", $gekko_uri)) {

		// guessing invoked module when a form is submitted
		$match = Array();
		preg_match("'(.*)\/modules\/([^\/]*)'", $gekko_uri, $match);
		$gekko_uri = $match[1];
		$modinvoke = $match[2];

		define("ACTION_MODULE", $modinvoke);

		// autoloading language for the invoked module
		$Lang->load($modinvoke);
	}
	$gekko_uri = rtrim($gekko_uri, "/")."/";

	_l("C_SITE.URL", $gekko_uri);

	_l("C_USER_IP", USER_IP);
?>
