3 * General functions library
5 * @author Roland Haeder <webmaster@ship-simu.org>
7 * @copyright Copyright (c) 2009 - 2011 Cracker Tracker Team
8 * @license GNU GPL 3.0 or any newer version
9 * @link http://www.ship-simu.org
11 * This program is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation, either version 3 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program. If not, see <http://www.gnu.org/licenses/>.
25 if (!function_exists('implode_r')) {
26 // Implode recursive a multi-dimension array, taken from www.php.net
27 function implode_r ($glue, $array, $array_name = NULL) {
29 while(list($key,$value) = @each($array)) {
30 if(is_array($value)) {
31 // Is an array again, so call recursive
32 $return[] = implode_r($glue, $value, (string) $key);
34 if($array_name != NULL) {
35 $return[] = $array_name . '[' . (string) $key . ']=' . $value . "\n";
37 $return[] = $key . '=' . $value."\n";
42 // Return resulting array
43 return(implode($glue, $return));
47 if (!function_exists('implode_secure')) {
48 // Implode a simple array with a 'call-back' to our escaper function
49 function implode_secure ($array) {
54 foreach ($array as $entry) {
56 if (in_array($entry, array('NOW()'))) {
57 // Add it with non-string glue
58 $return .= $entry . ',';
59 } elseif (empty($entry)) {
60 // Empty strings need no escaping
63 // Secure this string and add it
64 $return .= '"' . crackerTrackerEscapeString($entry) . '",';
69 $return = substr($return, 0, -1);
76 // Getter for ctracker_debug_enabled
77 function isCrackerTrackerDebug () {
79 return ((isset($GLOBALS['ctracker_debug_enabled'])) && ($GLOBALS['ctracker_debug_enabled'] === true));
82 // Determines the real remote address
83 function determineCrackerTrackerRealRemoteAddress () {
88 if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
90 $address = $_SERVER['HTTP_X_FORWARDED_FOR'];
91 } elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {
93 $address = $_SERVER['HTTP_CLIENT_IP'];
94 } elseif (isset($_SERVER['REMOTE_ADDR'])) {
95 // The regular address when no proxy was used
96 $address = $_SERVER['REMOTE_ADDR'];
99 // This strips out the real address from proxy output
100 if (strstr($address, ',')) {
101 $addressArray = explode(',', $address);
102 $address = $addressArray[0];
109 // Determine if a proxy was used
110 function isCrackerTrackerProxyUsed () {
111 // Check if specific entries are set
112 $proxyUsed = ((isset($_SERVER['HTTP_X_FORWARDED_FOR'])) || (isset($_SERVER['HTTP_CLIENT_IP'])));
118 // Detects the user-agent string
119 function crackerTrackerUserAgent () {
120 // Default is 'unknown'
123 // Is the entry there?
124 if (isset($_SERVER['HTTP_USER_AGENT'])) {
125 // Then use it securely
126 $ua = crackerTrackerSecureString($_SERVER['HTTP_USER_AGENT']);
133 // Detects the script name
134 function crackerTrackerScriptName () {
136 if (!isset($_SERVER['SCRIPT_NAME'])) {
141 // Should always be there!
142 return crackerTrackerSecureString($_SERVER['SCRIPT_NAME']);
145 // Detects the query string
146 function crackerTrackerQueryString () {
148 if (!isset($_SERVER['QUERY_STRING'])) {
153 // Should always be there!
154 return crackerTrackerEscapeString($_SERVER['QUERY_STRING']);
157 // Detects the server's name
158 function crackerTrackerServerName () {
160 if (!isset($_SERVER['SERVER_NAME'])) {
165 // Should always be there!
166 return crackerTrackerSecureString($_SERVER['SERVER_NAME']);
169 // Detects the referer
170 function crackerTrackerReferer () {
175 if (isset($_SERVER['HTTP_REFERER'])) {
176 // Then use it securely
177 $referer = crackerTrackerSecureString($_SERVER['HTTP_REFERER']);
184 // Detects the scripts path
185 function crackerTrackerScriptPath () {
186 // Should always be there!
187 $path = dirname(crackerTrackerScriptName()) . '/';
189 // Return detected path
193 // Detects wether we have SSL
194 function crackerTrackerSecured () {
196 $ssl = ((isset($_SERVER['HTTPS'])) && ($_SERVER['HTTPS'] != 'off'));
202 // Secures a string by escaping it and passing it through strip_tags,htmlentities-chain
203 function crackerTrackerSecureString ($str) {
205 $str = crackerTrackerEscapeString($str);
207 // Then pass it through the functions
208 $str = htmlentities(strip_tags($str), ENT_QUOTES);
214 // Is the file there and readable?
215 function isCrackerTrackerFileFound ($FQFN) {
217 return ((file_exists($FQFN)) && (is_readable($FQFN)));
220 // Loads a given "template" (this is more an include file)
221 function crackerTrackerLoadTemplate ($template) {
222 // Create the full-qualified filename (FQFN)
223 $FQFN = sprintf("%s/templates/%s.tpl.php",
228 // Is this template found?
229 if (isCrackerTrackerFileFound($FQFN)) {
231 crackerTrackerLanguage();
236 // Not found, so die here
241 // Loads a given "template" (this is more an include file)
242 function crackerTrackerLoadLocalizedTemplate ($template) {
243 // Create the full-qualified filename (FQFN)
244 $FQFN = sprintf("%s/templates/%s/%s.tpl.php",
246 getCrackerTrackerLanguage(),
250 // Is this template found?
251 if (isCrackerTrackerFileFound($FQFN)) {
255 // Not found, so die here
260 // Detects the browser's language file and tries to load it, fall-back on english!
261 function crackerTrackerLanguage () {
262 // Default is English
263 $GLOBALS['ctracker_language'] = 'en';
266 // Is the language string there?
267 if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
269 foreach (explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']) as $lang) {
270 // Split it again for q=x.x value
271 $langArray = explode(';', $lang);
273 // If there is an entry, we have a weight
274 if ((isset($langArray[1])) && ($langArray[1] > $weight)) {
275 // Use this language/weight instead
276 $GLOBALS['ctracker_language'] = $langArray[0];
277 $weight = $langArray[1];
283 $FQFN = sprintf("%s/language/%s.php",
285 getCrackerTrackerLanguage()
288 // Is it not there, switch to "en"
289 if ((getCrackerTrackerLanguage() != 'en') && (!isCrackerTrackerFileFound($FQFN))) {
290 // English is default!
291 $GLOBALS['ctracker_language'] = 'en';
293 // Construct FQFN again
294 $FQFN = sprintf("%s/language/en.php",
299 // Load the language file
303 // Loads a given email template and passes through $content
304 function crackerTrackerLoadEmailTemplate ($template, array $content = array(), $language = null) {
306 crackerTrackerLanguage();
309 $FQFN = sprintf("%s/mails/%s/%s.tpl",
311 getCrackerTrackerLanguage($language),
315 // So is the file there?
316 if (isCrackerTrackerFileFound($FQFN)) {
318 $result = 'No result from template ' . $template . '. Please report this at http://forum.ship-simu.org Thank you.';
321 eval('$result = "' . crackerTrackerCompileCode(file_get_contents($FQFN)) . '";');
331 // Getter for message
332 function getCrackerTrackerLocalized ($message) {
334 $output = '!' . $message . '!';
336 // Is the language string there?
337 if (isset($GLOBALS['ctracker_localized'][$message])) {
339 $output = $GLOBALS['ctracker_localized'][$message];
346 // Tries to find a message and outputs it
347 function crackerTrackerOutputLocalized ($message) {
349 print getCrackerTrackerLocalized($message);
352 // Compiles the given code
353 function crackerTrackerCompileCode ($code) {
354 // Find all $content[foo]
355 preg_match_all('/\$(content|GLOBALS)((\[([a-zA-Z0-9-_]+)\])*)/', $code, $matches);
357 // Replace " with {QUOTE}
358 $code = str_replace('"', '{QUOTE}', $code);
361 foreach ($matches[0] as $key=>$match) {
363 if (substr($match, 0, 8) == '$GLOBALS') {
365 $code = str_replace($match, "\" . \$GLOBALS['" . $matches[4][$key] . "'] . \"", $code);
366 } elseif (substr($match, 0, 8) == '$content') {
368 $code = str_replace($match, "\" . \$content['" . $matches[4][$key] . "'] . \"", $code);
376 // "Getter" for language
377 function getCrackerTrackerLanguage ($lang = null) {
378 // Default is from browser
379 $language = $GLOBALS['ctracker_language'];
382 if (!is_null($lang)) {
383 // Then use this instead
391 // "Getter" for ticket id
392 function getCrackerTrackerTicketId () {
397 if (isset($GLOBALS['ctracker_last_ticket']['ctracker_ticket'])) {
399 $id = $GLOBALS['ctracker_last_ticket']['ctracker_ticket'];
406 // Sends a cookie to the user that he would not see this security warning again
407 function sendCrackerTrackerCookie () {
409 // @TODO Why can't domain be set to value from crackerTrackerServerName() ?
410 setcookie('ctracker_ticket', getCrackerTrackerTicketId(), (time() + 60*60*24), '/', '', crackerTrackerSecured(), true);
411 $_COOKIE['ctracker_ticket'] = getCrackerTrackerTicketId();
414 // Is the cookie set?
415 function ifCrackerTrackerCookieIsSet () {
416 // Is it set and valid?
417 return ((isset($_COOKIE['ctracker_ticket'])) && ($_COOKIE['ctracker_ticket'] > 0));
420 // Redirects to the same URL
421 function crackerTrackerRedirectSameUrl () {
423 $url = '://' . crackerTrackerServerName() . crackerTrackerScriptName() . '?' . crackerTrackerQueryString();
426 if (crackerTrackerSecured()) {
428 $url = 'https' . $url;
431 $url = 'http' . $url;
435 crackerTrackerSendRawRedirect($url);
439 * Send a HTTP redirect to the browser. This function was taken from DokuWiki
440 * (GNU GPL 2; http://www.dokuwiki.org) and modified to fit into this script.
442 * Works arround Microsoft IIS cookie sending bug. Does exit the script.
444 * @link http://support.microsoft.com/kb/q176113/
445 * @author Andreas Gohr <andi@splitbrain.org>
448 function crackerTrackerSendRawRedirect ($url) {
449 // Better remove any data by ctracker
452 // always close the session
453 session_write_close();
455 // Revert entity &
456 $url = str_replace('&', '&', $url);
458 // check if running on IIS < 6 with CGI-PHP
459 if ((isset($_SERVER['SERVER_SOFTWARE'])) && (isset($_SERVER['GATEWAY_INTERFACE'])) &&
460 (strpos($_SERVER['GATEWAY_INTERFACE'],'CGI') !== false) &&
461 (preg_match('|^Microsoft-IIS/(\d)\.\d$|', trim($_SERVER['SERVER_SOFTWARE']), $matches)) &&
463 // Send the IIS header
464 header('Refresh: 0;url=' . $url);
466 // Send generic header
467 header('Location: ' . $url);
472 // Removes all ctracker-related data from global space
473 function unsetCtrackerData () {
480 'ctracker_debug_enabled',
482 'ctracker_whitelist',
483 'ctracker_get_blacklist',
484 'ctracker_post_blacklist',
486 'ctracker_post_track',
487 'ctracker_checkworm',
488 'ctracker_check_post',
490 'ctracker_last_result',
494 'ctracker_localized',
498 unset($GLOBALS[$key]);