668 lines
23 KiB
PHP
668 lines
23 KiB
PHP
<?php
|
|
// File name: init.inc.php
|
|
// Description: PHP subroutines to initial the environment
|
|
// Date: 2002-04-12
|
|
// Author: imacat <imacat@pristine.com.tw>
|
|
// Copyright: Copyright (C) 2002-2011 Pristine Communications
|
|
|
|
// Set the include path
|
|
if (!defined("INCPATH_SET")) {
|
|
require_once dirname(__FILE__) . "/incpath.inc.php";
|
|
}
|
|
// Referenced subroutines
|
|
require_once "monica/altlang.inc.php";
|
|
require_once "monica/cgiemu.inc.php";
|
|
require_once "monica/chkpriv.inc.php";
|
|
require_once "monica/curtime.inc.php";
|
|
require_once "monica/decform.inc.php";
|
|
require_once "monica/errhndl.inc.php";
|
|
require_once "monica/formfunc.inc.php";
|
|
require_once "monica/getlang.inc.php";
|
|
require_once "monica/gettext.inc.php";
|
|
require_once "monica/hires.inc.php";
|
|
require_once "monica/http.inc.php";
|
|
require_once "monica/https.inc.php";
|
|
require_once "monica/lastmodf.inc.php";
|
|
require_once "monica/listpref.inc.php";
|
|
require_once "monica/lninfo.inc.php";
|
|
require_once "monica/login.inc.php";
|
|
require_once "monica/logout.inc.php";
|
|
require_once "monica/page2rel.inc.php";
|
|
require_once "monica/pagefunc.inc.php";
|
|
require_once "monica/rel2abs.inc.php";
|
|
require_once "monica/requri.inc.php";
|
|
require_once "monica/scptpriv.inc.php";
|
|
require_once "monica/sql.inc.php";
|
|
require_once "monica/sqlconst.inc.php";
|
|
require_once "monica/unauth.inc.php";
|
|
require_once "monica/unicode.inc.php";
|
|
require_once "monica/upload.inc.php";
|
|
require_once "monica/xhtml.inc.php";
|
|
require_once "monica/xfileio.inc.php";
|
|
|
|
// Settings
|
|
if (!defined("FIELD_HARD_LIMIT")) {
|
|
define("FIELD_HARD_LIMIT", 307200);
|
|
}
|
|
if (!defined("FORM_HARD_LIMIT")) {
|
|
define("FORM_HARD_LIMIT", 512000);
|
|
}
|
|
|
|
// initenv: Initialize the script environment
|
|
// Input:
|
|
// $args: An associative array of arguments, where
|
|
// $args["allowed"]: The allowed request methods
|
|
// $args["restricted"]: Whether restricted to those permitted here
|
|
// $args["session"]: Whether to start a session (boolean)
|
|
// $args["sql"]: Which SQL (SQL_NONE, SQL_POSTGRESQL, SQL_MYSQL)
|
|
// $args["sql_lock"]: The SQL tables to lock in advance
|
|
function initenv($args)
|
|
{
|
|
// The submitted data
|
|
$FORM =& get_or_post();
|
|
|
|
// Parse the arguments
|
|
$session = true;
|
|
if (array_key_exists("session", $args)) {
|
|
$session = $args["session"];
|
|
} elseif (defined("START_SESSION")) {
|
|
$session = START_SESSION;
|
|
}
|
|
settype($session, "boolean");
|
|
$sql = SQL_POSTGRESQL;
|
|
if ( array_key_exists("sql", $args)
|
|
&& in_array($args["sql"], $GLOBALS["VALID_SQLS"])) {
|
|
$sql = $args["sql"];
|
|
} elseif (defined("START_SQL")
|
|
&& in_array(START_SQL, $GLOBALS["VALID_SQLS"])) {
|
|
$sql = START_SQL;
|
|
}
|
|
$GLOBALS["SQL_DBTYPE"] = $sql;
|
|
$restricted = false;
|
|
if (array_key_exists("restricted", $args)) {
|
|
$restricted = $args["restricted"];
|
|
}
|
|
$lastmod = false;
|
|
if (array_key_exists("lastmod", $args)) {
|
|
$lastmod = $args["lastmod"];
|
|
}
|
|
settype($lastmod, "boolean");
|
|
$logtime = false;
|
|
if (array_key_exists("logtime", $args)) {
|
|
$logtime = $args["logtime"];
|
|
}
|
|
settype($logtime, "boolean");
|
|
define("LOGTIME", $logtime);
|
|
|
|
// Set the custom error handler: http_500(): Standard error handler for Monica
|
|
set_error_handler("http500_error_handler");
|
|
// Secure the script environment
|
|
secure_env();
|
|
// Set the multi-byte environment
|
|
mb_internal_encoding("UTF-8");
|
|
// Initial the gettext locale
|
|
_init_initgettext();
|
|
// Check the last output buffering level
|
|
define("LAST_OB_LEVEL", (ini_get("output_buffering") == "" || !IS_CGI)? 0: 1);
|
|
// Start output buffering (till one level more than LAST_OB_LEVEL)
|
|
ob_start();
|
|
|
|
// Block FunWebProduct
|
|
// See http://www.networkworld.com/newsletters/web/2003/1208web2.html
|
|
if ( array_key_exists("HTTP_USER_AGENT", $_SERVER)
|
|
&& strpos($_SERVER["HTTP_USER_AGENT"], "FunWebProduct") !== false) {
|
|
http_403(N_("Sorry, browsers with FunWebProduct plugin (Smiley, PopSwatter, Spin4Dough, My Mail Signature, My Mail Stationery, My Mail Stamp, Cursor Mania, etc.) are are not welcome. It duplicates your request and produces high load and even crashes to our server. Please remove it first before you visit us."));
|
|
}
|
|
// Block bad-behaved e-mail crawlers
|
|
// Some bad-behaved e-mail crawlers cannot deal with the parent
|
|
// directory ".." and ampersands, and attach them to the URI infinitely
|
|
if (strstr(REQUEST_PATH, "/..") !== false || strstr(REQUEST_URI, "&") !== false) {
|
|
http_400(false);
|
|
}
|
|
// Limit the request methods, default to GET, HEAD and POST
|
|
// Set to null for no check. Useful for testing and debugging
|
|
$allowed = array_key_exists("allowed", $args)?
|
|
$args["allowed"]: array("GET", "HEAD", "POST");
|
|
if (!is_null($allowed) && !in_array($_SERVER["REQUEST_METHOD"], $allowed)) {
|
|
http_405($allowed);
|
|
}
|
|
// Block bad robots
|
|
_init_block_bad_robots();
|
|
|
|
// Initialize the session
|
|
if ($session) {
|
|
// Form processed with HTTPs
|
|
$https = false;
|
|
if (array_key_exists("https", $FORM)) {
|
|
$https = $FORM["https"]? true: false;
|
|
}
|
|
// We are HTTPS, processing a form that came from
|
|
// another non-HTTPS virtual host.
|
|
// Overriding the session ID. to keep the original session.
|
|
if ($https && is_https()) {
|
|
// Use the provided session ID
|
|
if (array_key_exists(session_name(), $FORM)) {
|
|
session_id($FORM[session_name()]);
|
|
}
|
|
}
|
|
// Avoid bad robots producing bad session ID.
|
|
$GLOBALS["php_errormsg"] = null;
|
|
set_error_handler("null_error_handler");
|
|
session_start();
|
|
if (!is_null($GLOBALS["php_errormsg"])) {
|
|
http_400($GLOBALS["php_errormsg"]);
|
|
}
|
|
restore_error_handler();
|
|
}
|
|
// Prevent huge sized request
|
|
check_request_size();
|
|
|
|
// If client has not logged in on restricted area, we can
|
|
// bypass SQL connection to save our work
|
|
if (IS_CGI && is_null(get_login_sn()) && $restricted !== false) {
|
|
unauth();
|
|
}
|
|
|
|
// Initialize the SQL connection
|
|
if ($sql) {
|
|
if (defined("NODATABASE") && NODATABASE) {
|
|
http_503("Database shut down for maintainance.");
|
|
}
|
|
sql_connect();
|
|
}
|
|
|
|
// Only available on systems with membership turned on
|
|
if ($sql && use_users() && $session) {
|
|
// Update the log-in infomation
|
|
upd_login_info();
|
|
// Check the client permission
|
|
if ($restricted !== false && !is_script_permitted($restricted)) {
|
|
unauth();
|
|
}
|
|
// Check if this site is closed for policy
|
|
_init_check_nologin();
|
|
}
|
|
|
|
// Prepare the SQL tables to lock
|
|
if ($sql && array_key_exists("sql_lock", $args)) {
|
|
// Read-only on non-POSTed forms
|
|
if ($_SERVER["REQUEST_METHOD"] != "POST") {
|
|
foreach (array_keys($args["sql_lock"]) as $table) {
|
|
$args["sql_lock"][$table] = LOCK_SH;
|
|
}
|
|
// Add mtime to POSTed forms
|
|
} else {
|
|
if (in_array("mtime", sql_tables())) {
|
|
$args["sql_lock"]["mtime"] = LOCK_EX;
|
|
}
|
|
}
|
|
// Supply the default locks
|
|
if (use_users()) {
|
|
$default_locks = array("users", "groups", "scptpriv", "userpref",
|
|
"users AS createdby", "users AS updatedby");
|
|
foreach ($default_locks as $table) {
|
|
if (!array_key_exists($table, $args["sql_lock"])) {
|
|
$args["sql_lock"][$table] = LOCK_SH;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Check the last modified
|
|
if ($lastmod) {
|
|
// Set the database tables to check
|
|
$tables = array();
|
|
if (array_key_exists("lmtables", $args)) {
|
|
$tables = array_merge($tables, $args["lmtables"]);
|
|
}
|
|
// Add the locked tables automatically
|
|
if (array_key_exists("sql_lock", $args)) {
|
|
$tables = array_merge($tables, array_keys($args["sql_lock"]));
|
|
}
|
|
// Set the files to check
|
|
$files = array();
|
|
if (array_key_exists("lmfiles", $args)) {
|
|
$files = array_merge($files, $args["lmfiles"]);
|
|
}
|
|
$callers = debug_backtrace();
|
|
if (not_modified($tables, $files,
|
|
basename($callers[count($callers)-1]["file"]))) {
|
|
http_304();
|
|
}
|
|
}
|
|
|
|
// Lock the SQL tables
|
|
if ($sql && array_key_exists("sql_lock", $args)) {
|
|
sql_lock($args["sql_lock"]);
|
|
}
|
|
|
|
// Fetch the current data
|
|
if (function_exists("fetch_current")) {
|
|
fetch_current();
|
|
}
|
|
|
|
// Decode user input FORMs to UTF-8
|
|
decode_forms();
|
|
|
|
// Process the list preference form
|
|
if (form_type() == "listpref") {
|
|
if ( array_key_exists("domain", $_POST)
|
|
&& class_exists($_POST["domain"])) {
|
|
$LIST = new $_POST["domain"];
|
|
$LIST->set_listpref();
|
|
} else {
|
|
$handler = new ListPreference($_POST);
|
|
$handler->main();
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
// restenv: Restore the script environment
|
|
function restenv()
|
|
{
|
|
// Disconnect SQL
|
|
if ($GLOBALS["SQL_DBTYPE"] != SQL_NONE) {
|
|
sql_close();
|
|
}
|
|
|
|
// Print the page and end the output buffering, if it exists
|
|
if (ob_get_level() > LAST_OB_LEVEL) {
|
|
// Return from the innermost level to level 1
|
|
while (ob_get_level() > LAST_OB_LEVEL + 1) {
|
|
ob_end_flush();
|
|
}
|
|
// Obtain the final content
|
|
$html = ob_get_contents();
|
|
ob_end_clean();
|
|
// No content -- HTTP 204
|
|
if ($html == "") {
|
|
http_204();
|
|
}
|
|
|
|
// The content type
|
|
$type = array_key_exists("CONTENT_TYPE", $GLOBALS)?
|
|
$GLOBALS["CONTENT_TYPE"]: xhtml_content_type();
|
|
$is_html = preg_match("/^(?:text\/html|application\/xhtml\+xml)\b/", $type)? true: false;
|
|
$is_rss = $type == "application/rss+xml";
|
|
// application/rss+xml is not supported yet
|
|
if ($is_rss) {
|
|
$type = "application/xml";
|
|
}
|
|
$is_text = preg_match("/^(?:text\/plain)\b/", $type)? true: false;
|
|
$is_csv = preg_match("/^(?:text\/csv)\b/", $type)? true: false;
|
|
$is_js = preg_match("/^(?:text\/javascript)\b/", $type)? true: false;
|
|
$is_attach = array_key_exists("CONTENT_DISPOSITION", $GLOBALS) &&
|
|
preg_match("/^attachment\b/", $GLOBALS["CONTENT_DISPOSITION"]);
|
|
|
|
// Do the run-time replacements
|
|
if (($is_html || $is_rss || $is_text || $is_js) && function_exists("page_replacements")) {
|
|
$rep = page_replacements();
|
|
foreach (array_keys($rep) as $key) {
|
|
$html = str_replace("<!--monica:$key-->", $rep[$key]["content"], $html);
|
|
}
|
|
}
|
|
|
|
// Fix the HTML output
|
|
if ($is_html) {
|
|
if (preg_match("/; charset=([^ ;]+)/", $type, $m)) {
|
|
$charset = $m[1];
|
|
} else {
|
|
$charset = getlang(LN_CHARSET);
|
|
$type .= "; charset=$charset";
|
|
}
|
|
// Convert the URLs to relative
|
|
if ($is_attach) {
|
|
$html = page2abs($html, REQUEST_PATH);
|
|
} else {
|
|
$html = page2rel($html, REQUEST_PATH);
|
|
}
|
|
// Mung the e-mail at-signs (@)
|
|
$html = str_replace("@", "@", $html);
|
|
// Decode the e-mail at-signs (@) of spamtrap
|
|
$html = str_replace("spamtrap@", "spamtrap@", $html);
|
|
// Convert to the desired character set
|
|
$html = page_encode($html, $charset);
|
|
|
|
// Fix the RSS output
|
|
} elseif ($is_rss) {
|
|
if (preg_match("/; charset=([^ ;]+)/", $type, $m)) {
|
|
$charset = $m[1];
|
|
} else {
|
|
$charset = getlang(LN_CHARSET);
|
|
$type .= "; charset=$charset";
|
|
}
|
|
// Mung the e-mail at-signs (@)
|
|
$html = str_replace("@", "@", $html);
|
|
// Decode the e-mail at-signs (@) of spamtrap
|
|
$html = str_replace("spamtrap@", "spamtrap@", $html);
|
|
// Convert to the desired character set
|
|
$html = page_encode($html, $charset);
|
|
|
|
// Fix the plain text output
|
|
} elseif ($is_text) {
|
|
if (preg_match("/; charset=([^ ;]+)/", $type, $m)) {
|
|
$charset = $m[1];
|
|
} else {
|
|
$charset = "UTF-8";
|
|
$type .= "; charset=$charset";
|
|
}
|
|
// Mung the e-mail at-signs (@)
|
|
$html = str_replace("@", "-at-", $html);
|
|
// Decode the e-mail at-signs (@) of spamtrap
|
|
$html = str_replace("spamtrap-at-", "spamtrap@", $html);
|
|
// Convert to the desired character set
|
|
$html = h_encode($html, $charset);
|
|
|
|
// Fix the comma-seperated values output
|
|
} elseif ($is_csv) {
|
|
if (preg_match("/; charset=([^ ;]+)/", $type, $m)) {
|
|
$charset = $m[1];
|
|
} else {
|
|
$charset = "UTF-8";
|
|
$type .= "; charset=$charset";
|
|
}
|
|
// Convert to the desired character set
|
|
$html = h_encode($html, $charset);
|
|
|
|
// Fix the javascript output
|
|
} elseif ($is_js) {
|
|
if (preg_match("/; charset=([^ ;]+)/", $type, $m)) {
|
|
$charset = $m[1];
|
|
} else {
|
|
$charset = getlang(LN_CHARSET);
|
|
$type .= "; charset=$charset";
|
|
}
|
|
// Convert to the desired character set
|
|
$html = h_encode($html, $charset);
|
|
}
|
|
|
|
header("Content-Type: $type");
|
|
header("Content-Length: " . strlen($html));
|
|
if (array_key_exists("CONTENT_DISPOSITION", $GLOBALS)) {
|
|
header("Content-Disposition: " . $GLOBALS["CONTENT_DISPOSITION"]);
|
|
}
|
|
header("Accept-Ranges: none");
|
|
if ( substr($type, 0, 5) == "text/"
|
|
|| $is_html
|
|
|| substr($type, 0, 15) == "application/pdf") {
|
|
header("Content-Language: " . getlang(LN_NAME));
|
|
}
|
|
// Client cache
|
|
if (array_key_exists("LAST_MODIFIED", $GLOBALS)) {
|
|
if (!is_null(get_login_sn())) {
|
|
header("Cache-Control: private");
|
|
} else {
|
|
header("Cache-Control: public");
|
|
}
|
|
header("Last-Modified: " . date("r", $GLOBALS["LAST_MODIFIED"]));
|
|
} else {
|
|
header("Cache-Control: no-cache");
|
|
}
|
|
// Content negotiation, see HTTP/1.1 section 13.6
|
|
if ( count($GLOBALS["ALL_LINGUAS"]) > 1
|
|
&& $_SERVER["REQUEST_METHOD"] != "POST"
|
|
&& $_SERVER["REQUEST_METHOD"] != "PUT"
|
|
&& !array_key_exists("lang", $_GET)) {
|
|
header("Content-Location: " . rel2abs(altlang(getlang(), page_param())));
|
|
header("Vary: negotiate,accept,accept-language,cookie");
|
|
}
|
|
|
|
// Print the page body
|
|
if ($_SERVER["REQUEST_METHOD"] != "HEAD") {
|
|
echo $html;
|
|
}
|
|
}
|
|
|
|
// Purge the file cache
|
|
if (isset($_SESSION) && array_key_exists("savefile", $_SESSION)) {
|
|
$FILES =& file_deposit();
|
|
$total = 0;
|
|
foreach (array_keys($FILES) as $sn) {
|
|
// Not a normal record
|
|
if ( !is_array($FILES[$sn])
|
|
|| !array_key_exists("size", $FILES[$sn])) {
|
|
continue;
|
|
}
|
|
$total += $FILES[$sn]["size"];
|
|
// Too larged
|
|
if ($total > UPLOAD_DEPOSIT_MAX) {
|
|
clear_file_deposit();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Print the processing time for debugging purpose
|
|
if (defined("LOGTIME") && LOGTIME) {
|
|
error_log("Process time: " . (time_hires() - T_START) . " sec.");
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
// secure_env: Secure the script environment
|
|
function secure_env()
|
|
{
|
|
$ENVLIST = array("PATH", "USER", "MAIL", "HOME", "USERNAME",
|
|
"LOGNAME", "PWD", "ENV", "KDEDIR");
|
|
foreach ($ENVLIST as $env) {
|
|
if (getenv($env) !== false) {
|
|
putenv("$env=");
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
// check_request_size: Prevent huge sized request
|
|
function check_request_size()
|
|
{
|
|
$len = _init_check_array_size($_GET);
|
|
if ($len === false) http_413();
|
|
if ($len > FORM_HARD_LIMIT) http_413();
|
|
$len = _init_check_array_size($_POST);
|
|
if ($len === false) http_413();
|
|
if ($len > FORM_HARD_LIMIT) http_413();
|
|
$len = _init_check_array_size($_COOKIE);
|
|
if ($len === false) http_413();
|
|
if ($len > FORM_HARD_LIMIT) http_413();
|
|
$len = _init_check_array_size($_SERVER);
|
|
if ($len === false) http_413();
|
|
if ($len > FORM_HARD_LIMIT) http_413();
|
|
return;
|
|
}
|
|
// _init_check_array_size: Recursively check the size of an array
|
|
function _init_check_array_size(&$a)
|
|
{
|
|
// Check the array size
|
|
if (gettype($a) != "array") {
|
|
$len = strlen($a);
|
|
if ($len > FIELD_HARD_LIMIT) {
|
|
return false;
|
|
}
|
|
return $len;
|
|
}
|
|
// Check the array size
|
|
$len = 0;
|
|
foreach (array_keys($a) as $k) {
|
|
$len += strlen($k);
|
|
if (gettype($a[$k]) == "array") {
|
|
$len0 = _init_check_array_size($a[$k]);
|
|
if ($len0 === false) {
|
|
return false;
|
|
}
|
|
$len += $len0;
|
|
} else {
|
|
$len0 = strlen($a[$k]);
|
|
if ($len0 > FIELD_HARD_LIMIT) {
|
|
return false;
|
|
}
|
|
$len += $len0;
|
|
}
|
|
}
|
|
return $len;
|
|
}
|
|
|
|
// _init_check_nologin: If this site is closed for policy
|
|
function _init_check_nologin()
|
|
{
|
|
// Not logged in - no checks needed
|
|
if (is_null(get_login_sn())) {
|
|
return;
|
|
}
|
|
// NOLOGIN: Only super-users can log in now
|
|
if (defined("NOLOGIN") && NOLOGIN) {
|
|
// Only super-users can log into no-log-in websites
|
|
if (is_su()) {
|
|
return;
|
|
}
|
|
logout();
|
|
// Deny access to the development site
|
|
ob_end_clean();
|
|
ob_start();
|
|
html_header(_("Log-In Closed"));
|
|
html_title(_("Log-In Closed"));
|
|
html_message(_("Log-in is temporarily closed for maintainance now. Please come again later. Sorry for the inconvienence."));
|
|
html_footer();
|
|
$html = ob_get_contents();
|
|
ob_end_clean();
|
|
if ($_SERVER["REQUEST_METHOD"] != "HEAD") {
|
|
echo $html;
|
|
}
|
|
// No need to return
|
|
exit;
|
|
|
|
// CLOSEDEV: Only developers can log in now
|
|
} elseif (defined("CLOSEDEV") && CLOSEDEV) {
|
|
if (is_group("dev")) {
|
|
return;
|
|
}
|
|
logout();
|
|
// Deny access to the development site
|
|
ob_end_clean();
|
|
ob_start();
|
|
html_header(_("Development Site Closed"));
|
|
html_title(_("Development Site Closed"));
|
|
html_message(_("Development site is closed. Please work on the live site."));
|
|
html_footer();
|
|
$html = ob_get_contents();
|
|
ob_end_clean();
|
|
if ($_SERVER["REQUEST_METHOD"] != "HEAD") {
|
|
echo $html;
|
|
}
|
|
// No need to return
|
|
exit;
|
|
}
|
|
|
|
}
|
|
|
|
// _init_block_bad_robots: Block bad robots
|
|
function _init_block_bad_robots()
|
|
{
|
|
// User-Agent: was sent
|
|
if (array_key_exists("HTTP_USER_AGENT", $_SERVER)) {
|
|
// Check MSIE 6 and unbalanced brackets
|
|
if ($_SERVER["HTTP_USER_AGENT"] == "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1") {
|
|
http_403();
|
|
}
|
|
// Check User-Agent in user-agent identification
|
|
if (substr($_SERVER["HTTP_USER_AGENT"], 0, 11) == "User-Agent:") {
|
|
http_403();
|
|
}
|
|
// Check User-Agent in user-agent identification
|
|
if (strpos($_SERVER["HTTP_USER_AGENT"], "DTS Agent") !== false) {
|
|
http_403(false);
|
|
}
|
|
// MSIE 6 must be HTTP/1.1
|
|
// -- disabled 2006-07-07. Lots of innocent set this way (why?)
|
|
// Opera pretends to be MSIE 6, and uses HTTP/1.0 (why?)
|
|
//if ( preg_match("/\bMSIE [456]/", $_SERVER["HTTP_USER_AGENT"])
|
|
// && strstr($_SERVER["HTTP_USER_AGENT"], "Opera") === false
|
|
// && $_SERVER["SERVER_PROTOCOL"] != "HTTP/1.1") {
|
|
// http_403();
|
|
//}
|
|
}
|
|
// Check huge amount of requests from a same host in a short time
|
|
if (IS_CGI) {
|
|
$file = ini_get("session.save_path") . "/ipacct.txt";
|
|
$count = 0;
|
|
$newrecs = array();
|
|
$lastseen = null;
|
|
// Check the current records
|
|
if (file_exists($file)) {
|
|
$fp = fopen($file, "r+");
|
|
flock($fp, LOCK_EX);
|
|
$size = filesize($file);
|
|
// fread() does not allow reading of 0 bytes now
|
|
if ($size == 0) {
|
|
$content = "";
|
|
} else {
|
|
$content = fread($fp, $size);
|
|
}
|
|
$currecs = explode("\n", $content);
|
|
foreach ($currecs as $record) {
|
|
// Drop invalid
|
|
if (!preg_match("/^(\d+) (\d+\.\d+\.\d+\.\d+) /", $record, $m)) {
|
|
continue;
|
|
}
|
|
// We only keep 30 minutes
|
|
if (NOW - $m[1] >= 1800) {
|
|
continue;
|
|
}
|
|
$newrecs[] = "$record\n";
|
|
if ($m[2] == $_SERVER["REMOTE_ADDR"]) {
|
|
if (is_null($lastseen) || $lastseen > $m[1]) {
|
|
$lastseen = $m[1];
|
|
}
|
|
$count++;
|
|
}
|
|
}
|
|
fseek($fp, 0, SEEK_SET);
|
|
ftruncate($fp, 0);
|
|
// No current records yet
|
|
} else {
|
|
$fp = fopen($file, "w");
|
|
flock($fp, LOCK_EX);
|
|
}
|
|
// Add this record
|
|
if (is_null($lastseen)) {
|
|
$lastseen = NOW;
|
|
}
|
|
$newrecs[] = sprintf("%d %s %s\n", NOW, $_SERVER["REMOTE_ADDR"],
|
|
date("Y-m-d H:i:s", NOW));
|
|
$count++;
|
|
// Update the accounting
|
|
fwrite($fp, implode("", $newrecs));
|
|
flock($fp, LOCK_UN);
|
|
fclose($fp);
|
|
/* Debug
|
|
if (array_key_exists("debug_reqid", $_GET)) {
|
|
error_log(sprintf("req=%s NOW=%d lastseen=%d count=%d avg=%.2f block=%s",
|
|
$_GET["debug_reqid"], NOW, $lastseen, $count,
|
|
$count / ((NOW == $lastseen)? 1: NOW - $lastseen),
|
|
($count / ((NOW == $lastseen)? 1: NOW - $lastseen) > 2? "yes": "no")));
|
|
} */
|
|
// Averagely 2 script requests in 1 second from a same host - that is too much.
|
|
if ($count / ((NOW == $lastseen)? 1: NOW - $lastseen) > 2) {
|
|
http_503("Request too fast.");
|
|
}
|
|
}
|
|
}
|
|
|
|
// _init_initgettext: Initialize the gettext locale
|
|
function _init_initgettext()
|
|
{
|
|
putenv("LANG=" . getlang(LN_LOCALE));
|
|
putenv("LANGUAGE=" . getlang(LN_LOCALE));
|
|
putenv("LC_ALL=" . getlang(LN_LOCALE));
|
|
setlocale(LC_ALL, "");
|
|
bindtextdomain(COMMONDOMAIN, COMMONLOCALEDIR);
|
|
if (defined("PACKAGE")) {
|
|
bindtextdomain(PACKAGE, LOCALEDIR);
|
|
textdomain(PACKAGE);
|
|
}
|
|
}
|
|
|
|
?>
|