Separate E_STRICT reporting from E_ALL in internal debug mode (E_STRICT is included...
[squirrelmail.git] / include / init.php
1 <?php
2
3 /**
4 * init.php -- initialisation file
5 *
6 * File should be loaded in every file in src/ or plugins that occupate an entire frame
7 *
8 * @copyright 2006-2012 The SquirrelMail Project Team
9 * @license http://opensource.org/licenses/gpl-license.php GNU Public License
10 * @version $Id$
11 * @package squirrelmail
12 */
13
14 /**
15 * This is a development version so in order to track programmer mistakes we
16 * set the error reporting to E_ALL
17 FIXME: disabling this for now, because we now have $sm_debug_mode, but the problem with that is that we don't know what it will be until we have loaded the config file, a good 175 lines below after several important files have been included, etc. For now, we'll trust that developers have turned on E_ALL in php.ini anyway, but this can be uncommented if not.
18 */
19 //error_reporting(E_ALL);
20
21
22 /**
23 * Make sure we have a page name
24 *
25 */
26 if ( !defined('PAGE_NAME') ) define('PAGE_NAME', NULL);
27
28
29 /**
30 * If register_globals are on, unregister globals.
31 * Second test covers boolean set as string (php_value register_globals off).
32 */
33 if ((bool) ini_get('register_globals') &&
34 strtolower(ini_get('register_globals'))!='off') {
35 /**
36 * Remove all globals that are not reserved by PHP
37 * 'value' and 'key' are used by foreach. Don't unset them inside foreach.
38 */
39 foreach ($GLOBALS as $key => $value) {
40 switch($key) {
41 case 'HTTP_POST_VARS':
42 case '_POST':
43 case 'HTTP_GET_VARS':
44 case '_GET':
45 case 'HTTP_COOKIE_VARS':
46 case '_COOKIE':
47 case 'HTTP_SERVER_VARS':
48 case '_SERVER':
49 case 'HTTP_ENV_VARS':
50 case '_ENV':
51 case 'HTTP_POST_FILES':
52 case '_FILES':
53 case '_REQUEST':
54 case 'HTTP_SESSION_VARS':
55 case '_SESSION':
56 case 'GLOBALS':
57 case 'key':
58 case 'value':
59 break;
60 default:
61 unset($GLOBALS[$key]);
62 }
63 }
64 // Unset variables used in foreach
65 unset($GLOBALS['key']);
66 unset($GLOBALS['value']);
67 }
68
69 /**
70 * Used as a dummy value, e.g., for passing as an empty
71 * hook argument (where the value is passed by reference,
72 * and therefore NULL itself is not acceptable).
73 */
74 global $null;
75 $null = NULL;
76
77 /**
78 * The global $server_os variable will be "windows" if
79 * we are working in a Windows environment or "*nix"
80 * otherwise.
81 */
82 global $server_os;
83 if (DIRECTORY_SEPARATOR == '\\') $server_os = 'windows'; else $server_os = '*nix';
84
85 /**
86 * [#1518885] session.use_cookies = off breaks SquirrelMail
87 *
88 * When session cookies are not used, all http redirects, meta refreshes,
89 * src/download.php and javascript URLs are broken. Setting must be set
90 * before session is started.
91 */
92 if (!(bool)ini_get('session.use_cookies') ||
93 ini_get('session.use_cookies') == 'off') {
94 ini_set('session.use_cookies','1');
95 }
96
97 /**
98 * Initialize seed of random number generator.
99 * We use a number of things to randomize input: current time in ms,
100 * info about the remote client, info about the current process, the
101 * randomness of uniqid and stat of the current file.
102 *
103 * We seed this here only once per init, not only to save cycles
104 * but also to make the result of mt_rand more random (it now also
105 * depends on the number of times mt_rand was called before in this
106 * execution.
107 */
108 $seed = microtime() . $_SERVER['REMOTE_PORT'] . $_SERVER['REMOTE_ADDR'] . getmypid();
109
110 if (function_exists('getrusage')) {
111 /* Avoid warnings with Win32 */
112 $dat = @getrusage();
113 if (isset($dat) && is_array($dat)) { $seed .= implode('', $dat); }
114 }
115
116 if(!empty($_SERVER['UNIQUE_ID'])) {
117 $seed .= $_SERVER['UNIQUE_ID'];
118 }
119
120 $seed .= uniqid(mt_rand(),TRUE);
121 $seed .= implode('', stat( __FILE__));
122
123 // mt_srand() uses an integer to seed, so we need to distill our
124 // very large seed to something useful (without taking a sub-string,
125 // the integer conversion of such a large number is always 0 on
126 // many systems, but strangely, 9 hex numbers - even if larger
127 // than a signed 32 bit integer - seem to be an acceptable "integer"
128 // seed (perhaps it is used as unsigned?)...
129 // we may want to revisit this and always force it to be less than
130 // 2,147,483,647
131 //
132 $seed = hexdec(substr(md5($seed), 0, 9));
133
134 // PHP 4.2 and up don't require seeding, but their used seed algorithm
135 // is of questionable quality, so we keep doing it ourselves. */
136 mt_srand($seed);
137
138 /**
139 * calculate SM_PATH and calculate the base_uri
140 * assumptions made: init.php is only called from plugins or from the src dir.
141 * files in the plugin directory may not be part of a subdirectory called "src"
142 *
143 */
144 if (isset($_SERVER['SCRIPT_NAME'])) {
145 $a = explode('/', $_SERVER['SCRIPT_NAME']);
146 } elseif (isset($HTTP_SERVER_VARS['SCRIPT_NAME'])) {
147 $a = explode('/', $HTTP_SERVER_VARS['SCRIPT_NAME']);
148 } else {
149 $error = 'Unable to detect script environment. Please test your PHP '
150 . 'settings and send your PHP core configuration, $_SERVER and '
151 . '$HTTP_SERVER_VARS contents to the SquirrelMail developers.';
152 die($error);
153 }
154 $sSM_PATH = '';
155 for($i = count($a) -2; $i > -1; --$i) {
156 $sSM_PATH .= '../';
157 if ($a[$i] === 'src' || $a[$i] === 'plugins') {
158 break;
159 }
160 }
161
162 $base_uri = implode('/', array_slice($a, 0, $i)). '/';
163
164 define('SM_PATH',$sSM_PATH);
165 define('SM_BASE_URI', $base_uri);
166
167
168 /**
169 * global var $bInit is used to check if initialisation took place.
170 * At this moment it's a workarounf for the include of addrbook_search_html
171 * inside compose.php. If we found a better way then remove this. Do only use
172 * this var if you know for sure a page can be called stand alone and be included
173 * in another file.
174 */
175 $bInit = true;
176
177 /**
178 * This theme as a failsafe if no themes were found, or if we error
179 * out before anything could be initialised.
180 */
181 $color = array();
182 $color[0] = '#DCDCDC'; /* light gray TitleBar */
183 $color[1] = '#800000'; /* red */
184 $color[2] = '#CC0000'; /* light red Warning/Error Messages */
185 $color[3] = '#A0B8C8'; /* green-blue Left Bar Background */
186 $color[4] = '#FFFFFF'; /* white Normal Background */
187 $color[5] = '#FFFFCC'; /* light yellow Table Headers */
188 $color[6] = '#000000'; /* black Text on left bar */
189 $color[7] = '#0000CC'; /* blue Links */
190 $color[8] = '#000000'; /* black Normal text */
191 $color[9] = '#ABABAB'; /* mid-gray Darker version of #0 */
192 $color[10] = '#666666'; /* dark gray Darker version of #9 */
193 $color[11] = '#770000'; /* dark red Special Folders color */
194 $color[12] = '#EDEDED';
195 $color[13] = '#800000'; /* (dark red) Color for quoted text -- > 1 quote */
196 $color[14] = '#ff0000'; /* (red) Color for quoted text -- >> 2 or more */
197 $color[15] = '#002266'; /* (dark blue) Unselectable folders */
198 $color[16] = '#ff9933'; /* (orange) Highlight color */
199
200 require(SM_PATH . 'include/constants.php');
201 require(SM_PATH . 'functions/global.php');
202 require(SM_PATH . 'functions/strings.php');
203 require(SM_PATH . 'functions/arrays.php');
204 require(SM_PATH . 'functions/files.php');
205
206 /* load default configuration */
207 require(SM_PATH . 'config/config_default.php');
208 /* reset arrays in default configuration */
209 $ldap_server = array();
210 $plugins = array();
211 $fontsets = array();
212 $aTemplateSet = array();
213 $aTemplateSet[0]['ID'] = 'default';
214 $aTemplateSet[0]['NAME'] = 'Default';
215
216 /* load site configuration */
217 require(SM_PATH . 'config/config.php');
218 /* load local configuration overrides */
219 if (file_exists(SM_PATH . 'config/config_local.php')) {
220 require(SM_PATH . 'config/config_local.php');
221 }
222
223
224 /**
225 * Set PHP error reporting level based on the SquirrelMail debug mode
226 * E_STRICT = 2048
227 * E_DEPRECATED = 8192
228 */
229 $error_level = 0;
230 if ($sm_debug_mode & SM_DEBUG_MODE_SIMPLE)
231 $error_level |= E_ERROR;
232 if ($sm_debug_mode & SM_DEBUG_MODE_MODERATE
233 || $sm_debug_mode & SM_DEBUG_MODE_ADVANCED)
234 $error_level = ($error_level | E_ALL) & ~2048 & ~8192;
235 if ($sm_debug_mode & SM_DEBUG_MODE_STRICT)
236 $error_level |= 2048 | 8192;
237 error_reporting($error_level);
238
239
240 /**
241 * Detect SSL connections
242 */
243 $is_secure_connection = is_ssl_secured_connection();
244
245
246 require(SM_PATH . 'functions/plugin.php');
247 require(SM_PATH . 'include/languages.php');
248 require(SM_PATH . 'class/template/Template.class.php');
249 require(SM_PATH . 'class/error.class.php');
250
251 /**
252 * If magic_quotes_runtime is on, SquirrelMail breaks in new and creative ways.
253 * Force magic_quotes_runtime off.
254 * tassium@squirrelmail.org - I put it here in the hopes that all SM code includes this.
255 * If there's a better place, please let me know.
256 */
257 ini_set('magic_quotes_runtime','0');
258
259
260 /* if running with magic_quotes_gpc then strip the slashes
261 from POST and GET global arrays */
262 if (function_exists('get_magic_quotes_gpc') && @get_magic_quotes_gpc()) {
263 sqstripslashes($_GET);
264 sqstripslashes($_POST);
265 }
266
267
268 /**
269 * Strip any tags added to the url from PHP_SELF.
270 * This fixes hand crafted url XXS expoits for any
271 * page that uses PHP_SELF as the FORM action
272 * Update: strip_tags() won't catch something like
273 * src/right_main.php?sort=0&startMessage=1&mailbox=INBOX&xxx="><script>window.open("http://example.com")</script>
274 * or
275 * contrib/decrypt_headers.php/%22%20onmouseover=%22alert(%27hello%20world%27)%22%3E
276 * because it doesn't bother with broken tags.
277 * htmlspecialchars() is the preferred method.
278 * QUERY_STRING also needs the same treatment since it is
279 * used in php_self().
280 * Update again: the encoding of ampersands that occurs
281 * using htmlspecialchars() corrupts the query strings
282 * in normal URIs, so we have to let those through.
283 FIXME: will the de-sanitizing of ampersands create any security/XSS problems?
284 */
285 if (isset($_SERVER['REQUEST_URI']))
286 $_SERVER['REQUEST_URI'] = str_replace('&amp;', '&', htmlspecialchars($_SERVER['REQUEST_URI']));
287 if (isset($_SERVER['PHP_SELF']))
288 $_SERVER['PHP_SELF'] = str_replace('&amp;', '&', htmlspecialchars($_SERVER['PHP_SELF']));
289 if (isset($_SERVER['QUERY_STRING']))
290 $_SERVER['QUERY_STRING'] = str_replace('&amp;', '&', htmlspecialchars($_SERVER['QUERY_STRING']));
291
292 $PHP_SELF = php_self();
293
294 /**
295 * Initialize the session
296 */
297
298 /** set the name of the session cookie */
299 if (!isset($session_name) || !$session_name) {
300 $session_name = 'SQMSESSID';
301 }
302
303 /**
304 * When session.auto_start is On we want to destroy/close the session
305 */
306 $sSessionAutostartName = session_name();
307 $sSessionAutostartID = session_id();
308 if (!empty($sSessionAutostartID) && $sSessionAutostartName !== $session_name) {
309 $sCookiePath = ini_get('session.cookie_path');
310 $sCookieDomain = ini_get('session.cookie_domain');
311 // reset the cookie
312 sqsetcookie($sSessionAutostartName,'',1,$sCookiePath,$sCookieDomain);
313 @session_destroy();
314 session_write_close();
315 }
316
317 /**
318 * includes from classes stored in the session
319 */
320 require(SM_PATH . 'class/mime.class.php');
321
322 ini_set('session.name' , $session_name);
323 session_set_cookie_params (0, $base_uri);
324 sqsession_is_active();
325
326 /**
327 * When on login page, have to reset the user session, making
328 * sure to save session restore data first
329 */
330 if (PAGE_NAME == 'login') {
331 if (!sqGetGlobalVar('session_expired_post', $sep, SQ_SESSION))
332 $sep = '';
333 if (!sqGetGlobalVar('session_expired_location', $sel, SQ_SESSION))
334 $sel = '';
335 sqsession_destroy();
336 session_write_close();
337
338 /**
339 * in some rare instances, the session seems to stick
340 * around even after destroying it (!!), so if it does,
341 * we'll manually flatten the $_SESSION data
342 */
343 if (!empty($_SESSION))
344 $_SESSION = array();
345
346 /**
347 * Allow administrators to define custom session handlers
348 * for SquirrelMail without needing to change anything in
349 * php.ini (application-level).
350 *
351 * In config_local.php, admin needs to put:
352 *
353 * $custom_session_handlers = array(
354 * 'my_open_handler',
355 * 'my_close_handler',
356 * 'my_read_handler',
357 * 'my_write_handler',
358 * 'my_destroy_handler',
359 * 'my_gc_handler',
360 * );
361 * session_module_name('user');
362 * session_set_save_handler(
363 * $custom_session_handlers[0],
364 * $custom_session_handlers[1],
365 * $custom_session_handlers[2],
366 * $custom_session_handlers[3],
367 * $custom_session_handlers[4],
368 * $custom_session_handlers[5]
369 * );
370 *
371 * We need to replicate that code once here because PHP has
372 * long had a bug that resets the session handler mechanism
373 * when the session data is also destroyed. Because of this
374 * bug, even administrators who define custom session handlers
375 * via a PHP pre-load defined in php.ini (auto_prepend_file)
376 * will still need to define the $custom_session_handlers array
377 * in config_local.php.
378 */
379 global $custom_session_handlers;
380 if (!empty($custom_session_handlers)) {
381 $open = $custom_session_handlers[0];
382 $close = $custom_session_handlers[1];
383 $read = $custom_session_handlers[2];
384 $write = $custom_session_handlers[3];
385 $destroy = $custom_session_handlers[4];
386 $gc = $custom_session_handlers[5];
387 session_module_name('user');
388 session_set_save_handler($open, $close, $read, $write, $destroy, $gc);
389 }
390
391 sqsession_is_active();
392 session_regenerate_id();
393
394 // put session restore data back into session if necessary
395 if (!empty($sel)) {
396 sqsession_register($sel, 'session_expired_location');
397 if (!empty($sep))
398 sqsession_register($sep, 'session_expired_post');
399 }
400 }
401
402 /**
403 * SquirrelMail internal version number -- DO NOT CHANGE
404 * $sm_internal_version = array (release, major, minor)
405 */
406 $SQM_INTERNAL_VERSION = explode('.', SM_VERSION, 3);
407 $SQM_INTERNAL_VERSION[2] = intval($SQM_INTERNAL_VERSION[2]);
408
409
410 /* load prefs system; even when user not logged in, should be OK to do this here */
411 require(SM_PATH . 'functions/prefs.php');
412
413
414 /* if plugins are disabled only for one user and
415 * the current user is NOT that user, turn them
416 * back on
417 */
418 sqgetGlobalVar('username', $username, SQ_SESSION);
419 if ($disable_plugins && !empty($disable_plugins_user)
420 && $username != $disable_plugins_user) {
421 $disable_plugins = false;
422 }
423
424
425 /* remove all plugins if they are disabled */
426 if ($disable_plugins) {
427 $plugins = array();
428 }
429
430
431 /**
432 * Include Compatibility plugin if available.
433 */
434 if (!$disable_plugins && file_exists(SM_PATH . 'plugins/compatibility/functions.php'))
435 include_once(SM_PATH . 'plugins/compatibility/functions.php');
436
437
438 /**
439 * MAIN PLUGIN LOADING CODE HERE
440 * On init, we no longer need to load all plugin setup files.
441 * Now, we load the statically generated hook registrations here
442 * and let the hook calls include only the plugins needed.
443 */
444 $squirrelmail_plugin_hooks = array();
445 if (!$disable_plugins && file_exists(SM_PATH . 'config/plugin_hooks.php')) {
446 //FIXME: if we keep the plugin hooks array static like this, it seems like we should also keep the template files list in a static file too (when a new user session is started or the template set is changed, the code will dynamically iterate through the directory heirarchy of the template directory and catalog all the template files therein (and store the "catalog" in PHP session) -- instead, we could do that once at config-time and keep that static so SM can just include the file just like the line below)
447 require(SM_PATH . 'config/plugin_hooks.php');
448 }
449
450
451 /**
452 * Plugin authors note that the "config_override" hook used to be
453 * executed here, but please adapt your plugin to use this "prefs_backend"
454 * hook instead, making sure that it does NOT return anything, since
455 * doing so will interfere with proper prefs system functionality.
456 * Of course, otherwise, this hook may be used to do any configuration
457 * overrides as needed, as well as set up a custom preferences backend.
458 */
459 $prefs_backend = do_hook('prefs_backend', $null);
460 if (isset($prefs_backend) && !empty($prefs_backend) && file_exists(SM_PATH . $prefs_backend)) {
461 require(SM_PATH . $prefs_backend);
462 } elseif (isset($prefs_dsn) && !empty($prefs_dsn)) {
463 require(SM_PATH . 'functions/db_prefs.php');
464 } else {
465 require(SM_PATH . 'functions/file_prefs.php');
466 }
467
468
469
470 /**
471 * DISABLED.
472 * Remove globalized session data in rg=on setups
473 *
474 * Code can be utilized when session is started, but data is not loaded.
475 * We have already loaded configuration and other important vars. Can't
476 * clean session globals here, beside, the cleanout of globals at the
477 * top of this file will have removed anything this code would find anyway.
478 if ((bool) @ini_get('register_globals') &&
479 strtolower(ini_get('register_globals'))!='off') {
480 foreach ($_SESSION as $key => $value) {
481 unset($GLOBALS[$key]);
482 }
483 }
484 */
485
486 sqsession_register(SM_BASE_URI,'base_uri');
487
488 /**
489 * Retrieve the language cookie
490 */
491 if (! sqgetGlobalVar('squirrelmail_language',$squirrelmail_language,SQ_COOKIE)) {
492 $squirrelmail_language = '';
493 }
494
495
496 /**
497 * In some cases, buffering all output allows more complex functionality,
498 * especially for plugins that want to add headers on hooks that are beyond
499 * the point of output having been sent to the browser otherwise.
500 *
501 * Note that we don't turn this on any earlier since we want to allow plugins
502 * to turn it on themselves via a configuration override on the prefs_backend
503 * hook.
504 *
505 */
506 if ($buffer_output) ob_start(!empty($buffered_output_handler) ? $buffered_output_handler : NULL);
507
508
509 /**
510 * Do something special for some pages. This is based on the PAGE_NAME constant
511 * set at the top of every page.
512 */
513 $set_up_langage_after_template_setup = FALSE;
514 switch (PAGE_NAME) {
515 case 'style':
516
517 // need to get the right template set up
518 //
519 sqGetGlobalVar('templateid', $templateid, SQ_GET);
520
521 // sanitize just in case...
522 //
523 $templateid = preg_replace('/(\.\.\/){1,}/', '', $templateid);
524
525 // make sure given template actually is available
526 //
527 $found_templateset = false;
528 for ($i = 0; $i < count($aTemplateSet); ++$i) {
529 if ($aTemplateSet[$i]['ID'] == $templateid) {
530 $found_templateset = true;
531 break;
532 }
533 }
534
535 // FIXME: do we need/want to check here for actual (physical) presence of template sets?
536 // selected template not available, fall back to default template
537 //
538 if (!$found_templateset) {
539 $sTemplateID = Template::get_default_template_set();
540 } else {
541 $sTemplateID = $templateid;
542 }
543
544 session_write_close();
545 break;
546
547 case 'mailto':
548 // nothing to do
549 break;
550
551 case 'redirect':
552 require(SM_PATH . 'functions/auth.php');
553 //nobreak;
554
555 case 'login':
556 require(SM_PATH . 'functions/display_messages.php' );
557 require(SM_PATH . 'functions/page_header.php');
558 require(SM_PATH . 'functions/html.php');
559
560 // reset template file cache
561 //
562 $sTemplateID = Template::get_default_template_set();
563 Template::cache_template_file_hierarchy($sTemplateID, TRUE);
564
565 /**
566 * Make sure icon variables are setup for the login page.
567 */
568 $icon_theme = $icon_themes[$icon_theme_def]['PATH'];
569 /*
570 * NOTE: The $icon_theme_path var should contain the path to the icon
571 * theme to use. If the admin has disabled icons, or the user has
572 * set the icon theme to "None," no icons will be used.
573 */
574 $icon_theme_path = (!$use_icons || $icon_theme=='none') ? NULL : ($icon_theme == 'template' ? SM_PATH . Template::calculate_template_images_directory($sTemplateID) : $icon_theme);
575
576 break;
577 default:
578 require(SM_PATH . 'functions/display_messages.php' );
579 require(SM_PATH . 'functions/page_header.php');
580 require(SM_PATH . 'functions/html.php');
581
582
583 /**
584 * Check if we are logged in and does optional referrer check
585 */
586 require(SM_PATH . 'functions/auth.php');
587
588 global $check_referrer, $domain;
589 if (!sqgetGlobalVar('HTTP_REFERER', $referrer, SQ_SERVER)) $referrer = '';
590 if ($check_referrer == '###DOMAIN###') $check_referrer = $domain;
591 if (!empty($check_referrer)) {
592 $ssl_check_referrer = 'https://' . $check_referrer;
593 $check_referrer = 'http://' . $check_referrer;
594 }
595 if (!sqsession_is_registered('user_is_logged_in')
596 || ($check_referrer && !empty($referrer)
597 && strpos(strtolower($referrer), strtolower($check_referrer)) !== 0
598 && strpos(strtolower($referrer), strtolower($ssl_check_referrer)) !== 0)) {
599
600 // use $message to indicate what logout text the user
601 // will see... if 0, typical "You must be logged in"
602 // if 1, information that the user session was saved
603 // and will be resumed after (re)login, if 2, there
604 // seems to have been a XSS or phishing attack (bad
605 // referrer)
606 //
607 $message = 0;
608
609 // First we store some information in the new session to prevent
610 // information-loss.
611 //
612 $session_expired_post = $_POST;
613 $session_expired_location = PAGE_NAME;
614 if (!sqsession_is_registered('session_expired_post')) {
615 sqsession_register($session_expired_post,'session_expired_post');
616 }
617 if (!sqsession_is_registered('session_expired_location')) {
618 sqsession_register($session_expired_location,'session_expired_location');
619 if ($session_expired_location == 'compose')
620 $message = 1;
621 }
622
623 // was bad referrer the reason we were rejected?
624 //
625 if (sqsession_is_registered('user_is_logged_in')
626 && $check_referrer && !empty($referrer))
627 $message = 2;
628
629 // signout page will deal with users who aren't logged
630 // in on its own; don't show error here
631 //
632 if ( PAGE_NAME == 'signout' ) {
633 return;
634 }
635
636 /**
637 * Initialize the template object (logout_error uses it)
638 */
639 /*
640 * $sTemplateID is not initialized when a user is not logged in, so we
641 * will use the config file defaults here. If the neccesary variables
642 * are not set, force a default value.
643 */
644 if (PAGE_NAME == 'squirrelmail_rpc') {
645 $sTemplateID = Template::get_rpc_template_set();
646 } else {
647 $sTemplateID = Template::get_default_template_set();
648 }
649 $oTemplate = Template::construct_template($sTemplateID);
650
651 set_up_language($squirrelmail_language, true);
652 if (!$message)
653 logout_error( _("You must be logged in to access this page.") );
654 else if ($message == 1)
655 logout_error( _("Your session has expired, but will be resumed after logging in again.") );
656 else if ($message == 2)
657 logout_error( _("The current page request appears to have originated from an unrecognized source.") );
658 exit;
659 }
660
661 sqgetGlobalVar('authz',$authz,SQ_SESSION);
662
663 /**
664 * Setting the prefs backend
665 */
666 sqgetGlobalVar('prefs_cache', $prefs_cache, SQ_SESSION );
667 sqgetGlobalVar('prefs_are_cached', $prefs_are_cached, SQ_SESSION );
668
669 if ( !sqsession_is_registered('prefs_are_cached') ||
670 !isset( $prefs_cache) ||
671 !is_array( $prefs_cache)) {
672 $prefs_are_cached = false;
673 $prefs_cache = false; //array();
674 }
675
676 /**
677 * initializing user settings
678 */
679 require(SM_PATH . 'include/load_prefs.php');
680
681 /**
682 * We'll need this to later have a noframes version
683 *
684 * Check if the user has a language preference, but no cookie.
685 * Send him a cookie with his language preference, if there is
686 * such discrepancy.
687 */
688 $my_language = getPref($data_dir, $username, 'language');
689 if ($my_language != $squirrelmail_language) {
690 sqsetcookie('squirrelmail_language', $my_language, time()+2592000, $base_uri);
691 }
692
693 $set_up_langage_after_template_setup = TRUE;
694
695 $timeZone = getPref($data_dir, $username, 'timezone');
696
697 /* Check to see if we are allowed to set the TZ environment variable.
698 * We are able to do this if ...
699 * safe_mode is disabled OR
700 * safe_mode_allowed_env_vars is empty (you are allowed to set any) OR
701 * safe_mode_allowed_env_vars contains TZ
702 */
703 $tzChangeAllowed = (!ini_get('safe_mode')) ||
704 !strcmp(ini_get('safe_mode_allowed_env_vars'),'') ||
705 preg_match('/^([\w_]+,)*TZ/', ini_get('safe_mode_allowed_env_vars'));
706
707 if ( $timeZone != SMPREF_NONE && ($timeZone != "")
708 && $tzChangeAllowed ) {
709
710 // get time zone key, if strict or custom strict timezones are used
711 if (isset($time_zone_type) &&
712 ($time_zone_type == 1 || $time_zone_type == 3)) {
713 /* load time zone functions */
714 require(SM_PATH . 'include/timezones.php');
715 $realTimeZone = sq_get_tz_key($timeZone);
716 } else {
717 $realTimeZone = $timeZone;
718 }
719
720 // set time zone
721 if ($realTimeZone) {
722 putenv("TZ=".$realTimeZone);
723 }
724 }
725
726 /**
727 * php 5.1.0 added time zone functions. Set time zone with them in order
728 * to prevent E_STRICT notices and allow time zone modifications in safe_mode.
729 */
730 if (function_exists('date_default_timezone_set')) {
731 if ($timeZone != SMPREF_NONE && $timeZone != "") {
732 date_default_timezone_set($timeZone);
733 } else {
734 // interface runs on server's time zone. Remove php E_STRICT complains
735 $default_timezone = @date_default_timezone_get();
736 date_default_timezone_set($default_timezone);
737 }
738 }
739 break;
740 }
741
742 /*
743 * $sTemplateID is not initialized when a user is not logged in, so we
744 * will use the config file defaults here. If the neccesary variables
745 * are not set, force a default value.
746 *
747 * If the user is logged in, $sTemplateID will be set in load_prefs.php,
748 * so we shouldn't change it here.
749 */
750 if (!isset($sTemplateID)) {
751 if (PAGE_NAME == 'squirrelmail_rpc') {
752 $sTemplateID = Template::get_rpc_template_set();
753 } else {
754 $sTemplateID = Template::get_default_template_set();
755 }
756 $icon_theme_path = !$use_icons ? NULL : Template::calculate_template_images_directory($sTemplateID);
757 }
758
759 // template object may have already been constructed in load_prefs.php
760 //
761 if (empty($oTemplate)) {
762 $oTemplate = Template::construct_template($sTemplateID);
763 }
764
765 // We want some variables to always be available to the template
766 //
767 $oTemplate->assign('javascript_on',
768 (sqGetGlobalVar('user_is_logged_in', $user_is_logged_in, SQ_SESSION)
769 ? checkForJavascript() : 0));
770 $oTemplate->assign('base_uri', sqm_baseuri());
771 $always_include = array('sTemplateID', 'icon_theme_path');
772 foreach ($always_include as $var) {
773 $oTemplate->assign($var, (isset($$var) ? $$var : NULL));
774 }
775
776 // A few output elements are used often, so just get them once here
777 //
778 $nbsp = $oTemplate->fetch('non_breaking_space.tpl');
779 $br = $oTemplate->fetch('line_break.tpl');
780
781
782 /**
783 * Set up the language.
784 *
785 * This code block corresponds to the *default* block of the switch
786 * statement above, but the language cannot be set up until after the
787 * template is instantiated, so we set $set_up_langage_after_template_setup
788 * above and do the linguistic stuff now.
789 */
790 if ($set_up_langage_after_template_setup) {
791 $err=set_up_language(getPref($data_dir, $username, 'language'));
792
793 // Japanese translation used without mbstring support
794 if ($err==2) {
795 $sError = "<p>Your administrator needs to have PHP installed with the multibyte string extension enabled (using configure option --enable-mbstring).</p>\n"
796 . "<p>This system has assumed that you accidently switched to Japanese and has reverted your language preference to English.</p>\n"
797 . "<p>Please refresh this page in order to continue using your webmail.</p>\n";
798 error_box($sError);
799 }
800 }
801
802
803 /**
804 * Initialize our custom error handler object
805 */
806 $oErrorHandler = new ErrorHandler($oTemplate,'error_message.tpl');
807
808
809 /**
810 * Activate custom error handling
811 */
812 if (version_compare(PHP_VERSION, "4.3.0", ">=")) {
813 $oldErrorHandler = set_error_handler(array($oErrorHandler, 'SquirrelMailErrorhandler'));
814 } else {
815 $oldErrorHandler = set_error_handler('SquirrelMailErrorhandler');
816 }
817
818
819 // ============================================================================
820 // ================= End of Live Code, Beginning of Functions =================
821 // ============================================================================
822
823
824 /**
825 * Javascript support detection function
826 * @param boolean $reset recheck javascript support if set to true.
827 * @return integer SMPREF_JS_ON or SMPREF_JS_OFF ({@see include/constants.php})
828 * @since 1.5.1
829 */
830 function checkForJavascript($reset = FALSE) {
831 global $data_dir, $username, $javascript_on, $javascript_setting;
832
833 if ( !$reset && sqGetGlobalVar('javascript_on', $javascript_on, SQ_SESSION) )
834 return $javascript_on;
835
836 //FIXME: this isn't used anywhere else in this function; can we remove it? why is it here?
837 $user_is_logged_in = FALSE;
838 if ( $reset || !isset($javascript_setting) )
839 $javascript_setting = getPref($data_dir, $username, 'javascript_setting', SMPREF_JS_AUTODETECT);
840
841 if ( !sqGetGlobalVar('new_js_autodetect_results', $js_autodetect_results) &&
842 !sqGetGlobalVar('js_autodetect_results', $js_autodetect_results) )
843 $js_autodetect_results = SMPREF_JS_OFF;
844
845 if ( $javascript_setting == SMPREF_JS_AUTODETECT )
846 $javascript_on = $js_autodetect_results;
847 else
848 $javascript_on = $javascript_setting;
849
850 sqsession_register($javascript_on, 'javascript_on');
851 return $javascript_on;
852 }
853
854 function sqm_baseuri() {
855 global $base_uri;
856 return $base_uri;
857 }