Source for file configtest.php

Documentation is available at configtest.php

  1. <?php
  2.  
  3. /**
  4.  * SquirrelMail configtest script
  5.  *
  6.  * @copyright 2003-2014 The SquirrelMail Project Team
  7.  * @license http://opensource.org/licenses/gpl-license.php GNU Public License
  8.  * @version $Id: configtest.php 14420 2014-01-01 20:33:20Z pdontthink $
  9.  * @package squirrelmail
  10.  * @subpackage config
  11.  */
  12.  
  13. /************************************************************
  14.  * NOTE: you do not need to change this script!             *
  15.  * If it throws errors you need to adjust your config.      *
  16.  ************************************************************/
  17.  
  18. /** This is the configtest page */
  19. define('PAGE_NAME''configtest');
  20.  
  21. // This script could really use some restructuring as it has grown quite rapidly
  22. // but is not very 'clean'. Feel free to get some structure into this thing.
  23.  
  24. // force verbose error reporting and turn on display of errors, but not before
  25. // getting their original values
  26. $php_display_errors_original_value ini_get('display_errors');
  27. $php_error_reporting_original_value ini_get('error_reporting');
  28. ini_set('display_errors',1);
  29.  
  30. /** Blockcopy from init.php. Cleans globals. */
  31. if ((bool) ini_get('register_globals'&&
  32.     strtolower(ini_get('register_globals'))!='off'{
  33.     /**
  34.      * Remove all globals that are not reserved by PHP
  35.      * 'value' and 'key' are used by foreach. Don't unset them inside foreach.
  36.      */
  37.     foreach ($GLOBALS as $key => $value{
  38.         switch($key{
  39.         case 'HTTP_POST_VARS':
  40.         case '_POST':
  41.         case 'HTTP_GET_VARS':
  42.         case '_GET':
  43.         case 'HTTP_COOKIE_VARS':
  44.         case '_COOKIE':
  45.         case 'HTTP_SERVER_VARS':
  46.         case '_SERVER':
  47.         case 'HTTP_ENV_VARS':
  48.         case '_ENV':
  49.         case 'HTTP_POST_FILES':
  50.         case '_FILES':
  51.         case '_REQUEST':
  52.         case 'HTTP_SESSION_VARS':
  53.         case '_SESSION':
  54.         case 'GLOBALS':
  55.         case 'key':
  56.         case 'value':
  57.             break;
  58.         default:
  59.             unset($GLOBALS[$key]);
  60.         }
  61.     }
  62.     // Unset variables used in foreach
  63.     unset($GLOBALS['key']);
  64.     unset($GLOBALS['value']);
  65. }
  66.  
  67.  
  68. /**
  69.  * Displays error messages and warnings
  70.  * @param string $str message
  71.  * @param boolean $fatal fatal error or only warning
  72.  */
  73. function do_err($str$fatal TRUE{
  74.     global $IND$warnings;
  75.     $level $fatal 'FATAL ERROR:' 'WARNING:';
  76.     echo '<p>'.$IND.'<font color="red"><b>' $level '</b></font> ' .$str"</p>\n";
  77.     if($fatal{
  78.         echo '</body></html>';
  79.         exit;
  80.     else {
  81.         $warnings++;
  82.     }
  83. }
  84.  
  85. /** @ignore */
  86. define('SM_PATH''../');
  87. /** load minimal function set */
  88. require(SM_PATH 'include/constants.php');
  89. require(SM_PATH 'functions/global.php');
  90. require(SM_PATH 'functions/strings.php');
  91. require(SM_PATH 'functions/files.php');
  92. $SQM_INTERNAL_VERSION explode('.'SM_VERSION3);
  93. $SQM_INTERNAL_VERSION[2intval($SQM_INTERNAL_VERSION[2]);
  94.  
  95. /** set default value in order to block remote access */
  96. $allow_remote_configtest=false;
  97.  
  98. /** Load all configuration files before output begins */
  99.  
  100. /* load default configuration */
  101. require(SM_PATH 'config/config_default.php');
  102. /* reset arrays in default configuration */
  103. $ldap_server array();
  104. $plugins array();
  105. $fontsets array();
  106. $theme array();
  107. $theme[0]['PATH'SM_PATH 'themes/default_theme.php';
  108. $theme[0]['NAME''Default';
  109. $aTemplateSet array();
  110. $aTemplateSet[0]['ID''default';
  111. $aTemplateSet[0]['NAME''Default';
  112. /* load site configuration */
  113. if (file_exists(SM_PATH 'config/config.php')) {
  114.     require(SM_PATH 'config/config.php');
  115. }
  116. /* load local configuration overrides */
  117. if (file_exists(SM_PATH 'config/config_local.php')) {
  118.     require(SM_PATH 'config/config_local.php');
  119. }
  120.  
  121. /**
  122.  * Include Compatibility plugin if available.
  123.  */
  124. if (!$disable_plugins && file_exists(SM_PATH 'plugins/compatibility/functions.php'))
  125.     include_once(SM_PATH 'plugins/compatibility/functions.php');
  126.  
  127. /** Load plugins */
  128. global $disable_plugins;
  129. $squirrelmail_plugin_hooks array();
  130. if (!$disable_plugins && file_exists(SM_PATH 'config/plugin_hooks.php')) {
  131.     require(SM_PATH 'config/plugin_hooks.php');
  132. }
  133.  
  134. /** Warning counter */
  135. $warnings 0;
  136.  
  137. /** indent */
  138. $IND str_repeat('&nbsp;',4);
  139.  
  140. /**
  141.  * get_location starts session and must be run before output is started.
  142.  */
  143. $test_location get_location();
  144.  
  145. ?><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
  146.   "http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd">
  147. <html>
  148. <head>
  149.   <meta name="robots" content="noindex,nofollow">
  150.   <title>SquirrelMail configtest</title>
  151. </head>
  152. <body>
  153. <h1>SquirrelMail configtest</h1>
  154.  
  155. <p>This script will try to check some aspects of your SquirrelMail configuration
  156. and point you to errors whereever it can find them. You need to go run <tt>conf.pl</tt>
  157. in the <tt>config/</tt> directory first before you run this script.</p>
  158.  
  159. <?php
  160.  
  161. $included array_map('basename'get_included_files() );
  162. if(!in_array('config.php'$included)) {
  163.     if(!file_exists(SM_PATH 'config/config.php')) {
  164.         do_err('Config file '.SM_PATH 'config/config.php does not exist!<br />'.
  165.                 'You need to run <tt>conf.pl</tt> first.');
  166.     }
  167.     do_err('Could not read '.SM_PATH.'config/config.php! Check file permissions.');
  168. }
  169. if(!in_array('strings.php'$included)) {
  170.     do_err('Could not include '.SM_PATH.'functions/strings.php!<br />'.
  171.             'Check permissions on that file.');
  172. }
  173.  
  174. /* Block remote use of script */
  175. if ($allow_remote_configtest{
  176.     sqGetGlobalVar('REMOTE_ADDR',$client_ip,SQ_SERVER);
  177.     sqGetGlobalVar('SERVER_ADDR',$server_ip,SQ_SERVER);
  178.  
  179.     if ((isset($client_ip|| $client_ip!='127.0.0.1'&&
  180.             (isset($client_ip|| isset($server_ip|| $client_ip!=$server_ip)) {
  181.         do_err('Enable "Allow remote configtest" option in squirrelmail configuration in order to use this script.');
  182.     }
  183. }
  184.  
  185. echo "<p><table>\n<tr><td>SquirrelMail version:</td><td><b>" SM_VERSION "</b></td></tr>\n" .
  186.     '<tr><td>Config file version:</td><td><b>' $config_version "</b></td></tr>\n" .
  187.     '<tr><td>Config file last modified:</td><td><b>' .
  188.     date ('d F Y H:i:s'filemtime(SM_PATH 'config/config.php')) .
  189.     "</b></td></tr>\n</table>\n</p>\n\n";
  190.  
  191. /* check $config_version */
  192. if ($config_version!='1.5.0'{
  193.     do_err('Configuration file version does not match required version. Please update your configuration file.');
  194. }
  195.  
  196.  
  197. /* checking PHP specs */
  198.  
  199. echo "Checking PHP configuration...<br />\n";
  200.  
  201. if(!check_php_version(4,1,0)) {
  202.     do_err('Insufficient PHP version: 'PHP_VERSION '! Minimum required: 4.1.0');
  203. }
  204.  
  205. echo $IND 'PHP version ' PHP_VERSION ' OK. (You have: ' phpversion(". Minimum: 4.1.0)<br />\n";
  206.  
  207. // try to determine information about the user and group the web server is running as
  208. //
  209. $webOwnerID 'N/A';
  210. $webOwnerInfo array('name' => 'N/A');
  211. if (function_exists('posix_getuid'))
  212.     $webOwnerID posix_getuid();
  213. if ($webOwnerID === FALSE)
  214.     $webOwnerID 'N/A';
  215. if ($webOwnerID !== 'N/A' && function_exists('posix_getpwuid'))
  216.     $webOwnerInfo posix_getpwuid($webOwnerID);
  217. if (!$webOwnerInfo)
  218.     $webOwnerInfo array('name' => 'N/A');
  219. $webGroupID 'N/A';
  220. $webGroupInfo array('name' => 'N/A');
  221. if (function_exists('posix_getgid'))
  222.     $webGroupID posix_getgid();
  223. if ($webGroupID === FALSE)
  224.     $webGroupID 'N/A';
  225. if ($webGroupID !== 'N/A' && function_exists('posix_getgrgid'))
  226.     $webGroupInfo posix_getgrgid($webGroupID);
  227. if (!$webGroupInfo)
  228.     $webGroupInfo array('name' => 'N/A');
  229.  
  230. echo $IND 'Running as ' $webOwnerInfo['name''(' $webOwnerID
  231.           . ') / ' $webGroupInfo['name''(' $webGroupID ")<br />\n";
  232.  
  233. echo $IND 'display_errors: ' $php_display_errors_original_value " (overridden with 1 for this page only)<br />\n";
  234.  
  235. echo $IND 'error_reporting: ' $php_error_reporting_original_value " (overridden with " E_ALL " for this page only)<br />\n";
  236.  
  237. $safe_mode ini_get('safe_mode');
  238. if ($safe_mode{
  239.     //FIXME: should show that safe_mode is off when it is (this only shows the safe_mode setting when it's on) (also might be generally helpful to show things like open_basedir, too or even add phpinfo() output or a link to another script that has phpinfo()
  240.     echo $IND 'safe_mode: ' $safe_mode;
  241.     if (empty($prefs_dsn|| empty($addrbook_dsn))
  242.         echo ' (<font color="red">double check data and attachment directory ownership, etc!</font>)';
  243.     if (!empty($addrbook_dsn|| !empty($prefs_dsn|| !empty($addrbook_global_dsn))
  244.         echo ' (<font color="red">does PHP have access to database interface?</font>)';
  245.     echo "<br />\n";
  246.     $safe_mode_exec_dir ini_get('safe_mode_exec_dir');
  247.     echo $IND 'safe_mode_exec_dir: ' $safe_mode_exec_dir "<br />\n";
  248. }
  249.  
  250. /* register_globals check: test for boolean false and any string that is not equal to 'off' */
  251.  
  252. if ((bool) ini_get('register_globals'&&
  253.     strtolower(ini_get('register_globals'))!='off'{
  254.     do_err('You have register_globals turned on. This is not an error, but it CAN be a security hazard. Consider turning register_globals off.'false);
  255. }
  256.  
  257.  
  258. /* variables_order check */
  259.  
  260. // FIXME(?): Hmm, how do we distinguish between when an ini setting is not available (ini_set() returns empty string) and when the administrator set the value to an empty string? The latter is sure to be highly rare, so for now, just assume that empty value means the setting isn't even available (could also check PHP version when this setting was implemented) although, we'll also warn the user if it is empty, with a non-fatal error
  261. $variables_order strtoupper(ini_get('variables_order'));
  262. if (empty($variables_order))
  263.     do_err('Your variables_order setting seems to be empty. Make sure it is undefined in any PHP ini files, .htaccess files, etc. and not specifically set to an empty value or SquirrelMail may not function correctly'false);
  264. else if (strpos($variables_order'G'=== FALSE
  265.  || strpos($variables_order'P'=== FALSE
  266.  || strpos($variables_order'C'=== FALSE
  267.  || strpos($variables_order'S'=== FALSE{
  268.     do_err('Your variables_order setting is insufficient for SquirrelMail to function. It needs at least "GPCS", but you have it set to "' sm_encode_html_special_chars($variables_order'"'true);
  269. else {
  270.     echo $IND "variables_order OK: $variables_order.<br />\n";
  271. }
  272.  
  273.  
  274. /* gpc_order check (removed from PHP as of v5.0) */
  275.  
  276. if (!check_php_version(5)) {
  277.     // FIXME(?): Hmm, how do we distinguish between when an ini setting is not available (ini_set() returns empty string) and when the administrator set the value to an empty string? The latter is sure to be highly rare, so for now, just assume that empty value means the setting isn't even available (could also check PHP version when this setting was implemented) although, we'll also warn the user if it is empty, with a non-fatal error
  278.     $gpc_order strtoupper(ini_get('gpc_order'));
  279.     if (empty($gpc_order))
  280.         do_err('Your gpc_order setting seems to be empty. Make sure it is undefined in any PHP ini files, .htaccess files, etc. and not specifically set to an empty value or SquirrelMail may not function correctly'false);
  281.     else if (strpos($gpc_order'G'=== FALSE
  282.      || strpos($gpc_order'P'=== FALSE
  283.      || strpos($gpc_order'C'=== FALSE{
  284.         do_err('Your gpc_order setting is insufficient for SquirrelMail to function. It needs to be set to "GPC", but you have it set to "' sm_encode_html_special_chars($gpc_order'"'true);
  285.     else {
  286.         echo $IND "gpc_order OK: $gpc_order.<br />\n";
  287.     }
  288. }
  289.  
  290.  
  291. /* check PHP extensions */
  292.  
  293. $php_exts array('session','pcre');
  294. $diff array_diff($php_extsget_loaded_extensions());
  295. if(count($diff)) {
  296.     do_err('Required PHP extensions missing: '.implode(', ',$diff) );
  297. }
  298.  
  299. echo $IND "PHP extensions OK. Dynamic loading is ";
  300.  
  301. if (!(bool)ini_get('enable_dl'|| (bool)ini_get('safe_mode')) {
  302.     echo "disabled.<br />\n";
  303. else {
  304.     echo "enabled.<br />\n";
  305. }
  306.  
  307.  
  308. /* dangerous php settings */
  309. /**
  310.  * mbstring.func_overload allows to replace original string and regexp functions
  311.  * with their equivalents from php mbstring extension. It causes problems when
  312.  * scripts analyze 8bit strings byte after byte or use 8bit strings in regexp tests.
  313.  * Setting can be controlled in php.ini (php 4.2.0), webserver config (php 4.2.0)
  314.  * and .htaccess files (php 4.3.5).
  315.  */
  316. if (function_exists('mb_internal_encoding'&&
  317.     check_php_version(4,2,0&&
  318.     (int)ini_get('mbstring.func_overload')!=0{
  319.     $mb_error='You have enabled mbstring overloading.'
  320.         .' It can cause problems with SquirrelMail scripts that rely on single byte string functions.';
  321.     do_err($mb_error);
  322. }
  323.  
  324. /**
  325.  * Do not use SquirrelMail with magic_quotes_* on.
  326.  */
  327. if ( (function_exists('get_magic_quotes_runtime'&&  @get_magic_quotes_runtime()) ||
  328.      (function_exists('get_magic_quotes_gpc'&& @get_magic_quotes_gpc()) ||
  329.     (bool) ini_get('magic_quotes_sybase'&& ini_get('magic_quotes_sybase'!= 'off' )
  330.     {
  331.     $magic_quotes_warning='You have enabled any one of <tt>magic_quotes_runtime</tt>, '
  332.         .'<tt>magic_quotes_gpc</tt> or <tt>magic_quotes_sybase</tt> in your PHP '
  333.         .'configuration. We recommend all those settings to be off. SquirrelMail '
  334.         .'may work with them on, but when experiencing stray backslashes in your mail '
  335.         .'or other strange behaviour, it may be advisable to turn them off.';
  336.     do_err($magic_quotes_warning,false);
  337. }
  338.  
  339. if (ini_get('short_open_tag'== 0{
  340.     $short_open_tag_warning 'You have configured PHP not to allow short tags '
  341.         . '(<tt>short_open_tag=off</tt>). This shouldn\'t be a problem with '
  342.         . 'SquirrelMail or any plugin coded coded according to the '
  343.         . 'SquirrelMail Coding Guidelines, but if you experience problems with '
  344.         . 'PHP code being displayed in some of the pages and changing setting '
  345.         . 'to "on" solves the problem, please file a bug report against the '
  346.         . 'failing plugin. The correct contact information is most likely '
  347.         . 'to be found in the plugin documentation.';
  348.     do_err($short_open_tag_warningfalse);
  349. }
  350.  
  351.  
  352. /* check who the web server is running as if possible */
  353.  
  354. if ($process_info get_process_owner_info()) {
  355.     echo $IND 'Web server is running as user: ' $process_info['name'' (' $process_info['uid'")<br />\n";
  356.     //echo $IND . 'Web server is running as effective user: ' . $process_info['ename'] . ' (' . $process_info['euid'] . ")<br />\n";
  357.     echo $IND 'Web server is running as group: ' $process_info['group'' (' $process_info['gid'")<br />\n";
  358.     //echo $IND . 'Web server is running as effective group: ' . $process_info['egroup'] . ' (' . $process_info['egid'] . ")<br />\n";
  359. }
  360.  
  361.  
  362. /* checking paths */
  363.  
  364. echo "Checking paths...<br />\n";
  365.  
  366. if(!file_exists($data_dir)) {
  367.     // data_dir is not that important in db_setups.
  368.     if (!empty($prefs_dsn)) {
  369.         $data_dir_error "Data dir ($data_dir) does not exist!\n";
  370.         echo $IND .'<font color="red"><b>ERROR:</b></font> ' $data_dir_error;
  371.     else {
  372.         do_err("Data dir ($data_dir) does not exist!");
  373.     }
  374. }
  375. // don't check if errors
  376. if(!isset($data_dir_error&& !is_dir($data_dir)) {
  377.     if (!empty($prefs_dsn)) {
  378.         $data_dir_error "Data dir ($data_dir) is not a directory!\n";
  379.         echo $IND '<font color="red"><b>ERROR:</b></font> ' $data_dir_error;
  380.     else {
  381.         do_err("Data dir ($data_dir) is not a directory!");
  382.     }
  383. }
  384. // datadir should be executable - but no clean way to test on that
  385. if(!isset($data_dir_error&& !sq_is_writable($data_dir)) {
  386.     if (!empty($prefs_dsn)) {
  387.         $data_dir_error "Data dir ($data_dir) is not writable!\n";
  388.         echo $IND '<font color="red"><b>ERROR:</b></font> ' $data_dir_error;
  389.     else {
  390.         do_err("Data dir ($data_dir) is not writable!");
  391.     }
  392. }
  393.  
  394. if (isset($data_dir_error)) {
  395.     echo " Some plugins might need access to data directory.<br />\n";
  396. else {
  397.     // todo_ornot: actually write something and read it back.
  398.     echo $IND "Data dir OK.<br />\n";
  399. }
  400.  
  401. if($data_dir == $attachment_dir{
  402.     echo $IND "Attachment dir is the same as data dir.<br />\n";
  403.     if (isset($data_dir_error)) {
  404.         do_err($data_dir_error);
  405.     }
  406. else {
  407.     if(!file_exists($attachment_dir)) {
  408.         do_err("Attachment dir ($attachment_dir) does not exist!");
  409.     }
  410.     if (!is_dir($attachment_dir)) {
  411.         do_err("Attachment dir ($attachment_dir) is not a directory!");
  412.     }
  413.     if (!sq_is_writable($attachment_dir)) {
  414.         do_err("I cannot write to attachment dir ($attachment_dir)!");
  415.     }
  416.     echo $IND "Attachment dir OK.<br />\n";
  417. }
  418.  
  419.  
  420. echo "Checking plugins...<br />\n";
  421.  
  422. /* check plugins and themes */
  423. //FIXME: check requirements given in plugin _info() function, such as required PHP extensions, Pear packages, other plugins, SM version, etc see development docs for list of returned info from that function
  424. //FIXME: update this list with most recent contents of the Obsolete category - I think it has changed recently
  425. $bad_plugins array(
  426.         'attachment_common',      // Integrated into SquirrelMail 1.2 core
  427.         'auto_prune_sent',        // Obsolete: See Proon Automatic Folder Pruning plugin
  428.         'compose_new_window',     // Integrated into SquirrelMail 1.4 core
  429.         'delete_move_next',       // Integrated into SquirrelMail 1.5 core
  430.         'disk_quota',             // Obsolete: See Check Quota plugin
  431.         'email_priority',         // Integrated into SquirrelMail 1.2 core
  432.         'emoticons',              // Obsolete: See HTML Mail plugin
  433.         'focus_change',           // Integrated into SquirrelMail 1.2 core
  434.         'folder_settings',        // Integrated into SquirrelMail 1.5.1 core
  435.         'global_sql_addressbook'// Integrated into SquirrelMail 1.4 core
  436.         'hancock',                // Not Working: See Random Signature Taglines plugin
  437.         'msg_flags',              // Integrated into SquirrelMail 1.5.1 core
  438.         'message_source',         // Added to SquirrelMail 1.4 Core Plugins (message_details)
  439.         'motd',                   // Integrated into SquirrelMail 1.2 core
  440.         'paginator',              // Integrated into SquirrelMail 1.2 core
  441.         'printer_friendly',       // Integrated into SquirrelMail 1.2 core
  442.         'procfilter',             // Obsolete: See Server Side Filter plugin
  443.         'redhat_php_cgi_fix',     // Integrated into SquirrelMail 1.1.1 core
  444.         'send_to_semicolon',      // Integrated into SquirrelMail 1.4.1 core
  445.         'spamassassin',           // Not working beyond SquirrelMail 1.2.7: See Spamassassin SpamFilter (Frontend) v2 plugin
  446.         'sqcalendar',             // Added to SquirrelMail 1.2 Core Plugins (calendar)
  447.         'sqclock',                // Integrated into SquirrelMail 1.2 core
  448.         'sql_squirrel_logger',    // Obsolete: See Squirrel Logger plugin
  449.         'tmda',                   // Obsolete: See TMDA Tools plugin
  450.         'vacation',               // Obsolete: See Vacation Local plugin
  451.         'view_as_html',           // Integrated into SquirrelMail 1.5.1 core
  452.         'xmailer'                 // Integrated into SquirrelMail 1.2 core
  453.         );
  454.  
  455. if (isset($plugins[0])) {
  456.     foreach($plugins as $plugin{
  457.         if(!file_exists(SM_PATH .'plugins/'.$plugin)) {
  458.             do_err('You have enabled the <i>'.$plugin.'</i> plugin, but I cannot find it.'FALSE);
  459.         elseif (!is_readable(SM_PATH .'plugins/'.$plugin.'/setup.php')) {
  460.             do_err('You have enabled the <i>'.$plugin.'</i> plugin, but I cannot locate or read its setup.php file.'FALSE);
  461.         elseif (in_array($plugin$bad_plugins)) {
  462.             do_err('You have enabled the <i>'.$plugin.'</i> plugin, which causes problems with this version of SquirrelMail. Please check the ReleaseNotes or other documentation for more information.'false);
  463.         }
  464.     }
  465.  
  466.  
  467.     // load plugin functions
  468.     include_once(SM_PATH 'functions/plugin.php');
  469.  
  470.     // turn on output buffering in order to prevent output of new lines
  471.     ob_start();
  472.     foreach ($plugins as $name{
  473.         use_plugin($name);
  474.  
  475.         // get output and remove whitespace
  476.         $output trim(ob_get_contents());
  477.  
  478.         // if plugin outputs more than newlines and spacing, stop script execution.
  479.         if (!empty($output)) {
  480.             $plugin_load_error 'Some output was produced when plugin <i>' $name '</i> was loaded.  Usually this means there is an error in the plugin\'s setup or configuration file.  The output was: '.sm_encode_html_special_chars($output);
  481.             do_err($plugin_load_error);
  482.         }
  483.     }
  484.     ob_end_clean();
  485.  
  486.  
  487.     /**
  488.      * Check the contents of the static plugin hooks array file against
  489.      * the plugin setup file, which may have changed in an upgrade, etc.
  490.      * This helps remind admins to re-run the configuration utility when
  491.      * a plugin has been changed or upgraded.
  492.      */
  493.     $static_squirrelmail_plugin_hooks $squirrelmail_plugin_hooks;
  494.     $squirrelmail_plugin_hooks array();
  495.     foreach ($plugins as $name{
  496.         $function "squirrelmail_plugin_init_$name";
  497.         if (function_exists($function)) {
  498.             $function();
  499.  
  500.             // now iterate through each hook and make sure the
  501.             // plugin is registered on the correct ones in the
  502.             // static plugin configuration file
  503.             //
  504.             foreach ($squirrelmail_plugin_hooks as $hook_name => $hooked_plugins)
  505.                 foreach ($hooked_plugins as $hooked_plugin => $hooked_function)
  506.                     if ($hooked_plugin == $name
  507.                      && (empty($static_squirrelmail_plugin_hooks[$hook_name][$hooked_plugin])
  508.                       || $static_squirrelmail_plugin_hooks[$hook_name][$hooked_plugin!= $hooked_function))
  509.                         do_err('The plugin <i>' $name '</i> is supposed to be registered on the <i>' $hook_name '</i> hook, but it is not.  You need to re-run the configuration utility and re-save your configuration file.'FALSE);
  510.         }
  511.     }
  512.     $squirrelmail_plugin_hooks $static_squirrelmail_plugin_hooks;
  513.  
  514.  
  515.     /**
  516.      * Print plugin versions
  517.      */
  518.     echo $IND "Plugin versions...<br />\n";
  519.     foreach ($plugins as $name{
  520.         $plugin_version get_plugin_version($name);
  521.         $english_name get_plugin_requirement($name'english_name');
  522.         echo $IND $IND (empty($english_name$name ' ' $english_name ' (' $name ') '(empty($plugin_version'??' $plugin_version"<br />\n";
  523.  
  524.         // check if this plugin has any other plugin
  525.         // dependencies and if they are satisfied
  526.         //
  527.         $failed_dependencies check_plugin_dependencies($name);
  528.         if ($failed_dependencies === SQ_INCOMPATIBLE{
  529.             do_err($name ' is NOT COMPATIBLE with this version of SquirrelMail'FALSE);
  530.         }
  531.         else if (is_array($failed_dependencies)) {
  532.             $missing_plugins '';
  533.             $incompatible_plugins '';
  534.             foreach ($failed_dependencies as $depend_name => $depend_requirements{
  535.                 if ($depend_requirements['version'== SQ_INCOMPATIBLE)
  536.                     $incompatible_plugins .= ', ' $depend_name;
  537.                 else
  538.                     $missing_plugins .= ', ' $depend_name ' (version ' $depend_requirements['version'', ' ($depend_requirements['activate''must be activated' 'need not be activated'')';
  539.             }
  540.             $error_string (!empty($incompatible_plugins$name ' cannot be activated at the same time as the following plugins: ' trim($incompatible_plugins', ''')
  541.                           . (!empty($missing_plugins(!empty($incompatible_plugins'.  ' $name ' is also ' $name ' is ''missing some dependencies: ' trim($missing_plugins', ''');
  542.             do_err($error_stringFALSE);
  543.         }
  544.  
  545.     }
  546.  
  547.  
  548.     /**
  549.      * This hook was added in 1.5.2 and 1.4.10. Each plugins should print an error
  550.      * message and return TRUE if there are any errors in its setup/configuration.
  551.      */
  552.     $plugin_err boolean_hook_function('configtest'$null1);
  553.     if($plugin_err{
  554.         do_err('Some plugin tests failed.');
  555.     else {
  556.         echo $IND "Plugins OK.<br />\n";
  557.     }
  558. else {
  559.     echo $IND "Plugins are not enabled in config.<br />\n";
  560. }
  561. foreach($theme as $thm{
  562.     if(!file_exists($thm['PATH'])) {
  563.         do_err('You have enabled the <i>'.$thm['NAME'].'</i> theme but I cannot find it ('.$thm['PATH'].').'FALSE);
  564.     elseif(!is_readable($thm['PATH'])) {
  565.         do_err('You have enabled the <i>'.$thm['NAME'].'</i> theme but I cannot read it ('.$thm['PATH'].').'FALSE);
  566.     }
  567. }
  568.  
  569. echo $IND "Themes OK.<br />\n";
  570.  
  571. if $squirrelmail_default_language != 'en_US' {
  572.     $loc_path SM_PATH .'locale/'.$squirrelmail_default_language.'/LC_MESSAGES/squirrelmail.mo';
  573.     iffile_exists$loc_path ) ) {
  574.         do_err('You have set <i>' $squirrelmail_default_language .
  575.                 '</i> as your default language, but I cannot find this translation (should be '.
  576.                 'in <tt>' $loc_path '</tt>). Please note that you have to download translations '.
  577.                 'separately from the main SquirrelMail package.'FALSE);
  578.     elseif is_readable$loc_path ) ) {
  579.         do_err('You have set <i>' $squirrelmail_default_language .
  580.                 '</i> as your default language, but I cannot read this translation (file '.
  581.                 'in <tt>' $loc_path '</tt> unreadable).'FALSE);
  582.     else {
  583.         echo $IND "Default language OK.<br />\n";
  584.     }
  585. else {
  586.     echo $IND "Default language OK.<br />\n";
  587. }
  588.  
  589. echo $IND "Base URL detected as: <tt>" sm_encode_html_special_chars($test_location.
  590.     "</tt> (location base " (empty($config_location_base'autodetected' 'set to <tt>' .
  591.     sm_encode_html_special_chars($config_location_base)."</tt>"")<br />\n";
  592.  
  593. /* check minimal requirements for other security options */
  594.  
  595. /* imaps or ssmtp */
  596. if($use_smtp_tls == || $use_imap_tls == 1{
  597.     if(!check_php_version(4,3,0)) {
  598.         do_err('You need at least PHP 4.3.0 for SMTP/IMAP TLS!');
  599.     }
  600.     if(!extension_loaded('openssl')) {
  601.         do_err('You need the openssl PHP extension to use SMTP/IMAP TLS!');
  602.     }
  603. }
  604. /* starttls extensions */
  605. if($use_smtp_tls === || $use_imap_tls === 2{
  606.     if (function_exists('stream_socket_enable_crypto')) {
  607.         do_err('If you want to use STARTTLS extension, you need stream_socket_enable_crypto() function from PHP 5.1.0 and newer.');
  608.     }
  609. }
  610. /* digest-md5 */
  611. if ($smtp_auth_mech=='digest-md5' || $imap_auth_mech =='digest-md5'{
  612.     if (!extension_loaded('xml')) {
  613.         do_err('You need the PHP XML extension to use Digest-MD5 authentication!');
  614.     }
  615. }
  616.  
  617. /* check outgoing mail */
  618.  
  619. echo "Checking outgoing mail service....<br />\n";
  620.  
  621. if($useSendmail{
  622.     // is_executable also checks for existance, but we want to be as precise as possible with the errors
  623.     if(!file_exists($sendmail_path)) {
  624.         do_err("Location of sendmail program incorrect ($sendmail_path)!");
  625.     }
  626.     if(!is_executable($sendmail_path)) {
  627.         do_err("I cannot execute the sendmail program ($sendmail_path)!");
  628.     }
  629.  
  630.     echo $IND "sendmail OK<br />\n";
  631. else {
  632.     $stream fsockopen( ($use_smtp_tls==1?'tls://':'').$smtpServerAddress$smtpPort,
  633.             $errorNumber$errorString);
  634.     if(!$stream{
  635.         do_err("Error connecting to SMTP server \"$smtpServerAddress:$smtpPort\".".
  636.                 "Server error: ($errorNumber".sm_encode_html_special_chars($errorString));
  637.     }
  638.  
  639.     // check for SMTP code; should be 2xx to allow us access
  640.     $smtpline fgets($stream1024);
  641.     if(((int) $smtpline{0}3{
  642.         do_err("Error connecting to SMTP server. Server error: ".
  643.                 sm_encode_html_special_chars($smtpline));
  644.     }
  645.  
  646.     /* smtp starttls checks */
  647.     if ($use_smtp_tls===2{
  648.         // if something breaks, script should close smtp connection on exit.
  649.  
  650.  
  651.         // format EHLO argument correctly if needed
  652.         //
  653.         if (preg_match('/^\d+\.\d+\.\d+\.\d+$/'$client_ip))
  654.             $helohost '[' $client_ip ']';
  655.         else // some day might add IPv6 here
  656.             $helohost $client_ip;
  657.  
  658.  
  659.         // say helo
  660.         fwrite($stream,"EHLO $helohost\r\n");
  661.  
  662.         $ehlo=array();
  663.         $ehlo_error false;
  664.         while ($line=fgets($stream1024)){
  665.             if (preg_match("/^250(-|\s)(\S*)\s+(\S.*)/",$line,$match)||
  666.                     preg_match("/^250(-|\s)(\S*)\s+/",$line,$match)) {
  667.                 if (!isset($match[3])) {
  668.                     // simple one word extension
  669.                     $ehlo[strtoupper($match[2])]='';
  670.                 else {
  671.                     // ehlo-keyword + ehlo-param
  672.                     $ehlo[strtoupper($match[2])]=trim($match[3]);
  673.                 }
  674.                 if ($match[1]==' '{
  675.                     $ret $line;
  676.                     break;
  677.                 }
  678.             else {
  679.                 //
  680.                 $ehlo_error true;
  681.                 $ehlo[]=$line;
  682.                 break;
  683.             }
  684.         }
  685.         if ($ehlo_error{
  686.             do_err('SMTP EHLO failed. You need ESMTP support for SMTP STARTTLS');
  687.         elseif (!array_key_exists('STARTTLS',$ehlo)) {
  688.             do_err('STARTTLS support is not declared by SMTP server.');
  689.         }
  690.  
  691.         fwrite($stream,"STARTTLS\r\n");
  692.         $starttls_response=fgets($stream1024);
  693.         if ($starttls_response[0]!=2{
  694.             $starttls_cmd_err 'SMTP STARTTLS failed. Server replied: '
  695.                 .sm_encode_html_special_chars($starttls_response);
  696.             do_err($starttls_cmd_err);
  697.         elseif(stream_socket_enable_crypto($stream,true,STREAM_CRYPTO_METHOD_TLS_CLIENT)) {
  698.             do_err('Failed to enable encryption on SMTP STARTTLS connection.');
  699.         else {
  700.             echo $IND "SMTP STARTTLS extension looks OK.<br />\n";
  701.         }
  702.         // According to RFC we should second ehlo call here.
  703.     }
  704.  
  705.     fputs($stream'QUIT');
  706.     fclose($stream);
  707.     echo $IND 'SMTP server OK (<tt><small>'.
  708.             trim(sm_encode_html_special_chars($smtpline))."</small></tt>)<br />\n";
  709.  
  710.     /* POP before SMTP */
  711.     if($pop_before_smtp{
  712.         if (empty($pop_before_smtp_host)) $pop_before_smtp_host $smtpServerAddress;
  713.         $stream fsockopen($pop_before_smtp_host110$err_no$err_str);
  714.         if (!$stream{
  715.             do_err("Error connecting to POP Server ($pop_before_smtp_host:110) "
  716.                 . $err_no ' : ' sm_encode_html_special_chars($err_str));
  717.         }
  718.  
  719.         $tmp fgets($stream1024);
  720.         if (substr($tmp03!= '+OK'{
  721.             do_err("Error connecting to POP Server ($pop_before_smtp_host:110)"
  722.                 . ' '.sm_encode_html_special_chars($tmp));
  723.         }
  724.         fputs($stream'QUIT');
  725.         fclose($stream);
  726.         echo $IND "POP-before-SMTP OK.<br />\n";
  727.     }
  728. }
  729.  
  730. /**
  731.  * Check the IMAP server
  732.  */
  733. echo "Checking IMAP service....<br />\n";
  734.  
  735. /** Can we open a connection? */
  736. $stream fsockopen( ($use_imap_tls==1?'tls://':'').$imapServerAddress$imapPort,
  737.         $errorNumber$errorString);
  738. if(!$stream{
  739.     do_err("Error connecting to IMAP server \"$imapServerAddress:$imapPort\".".
  740.             "Server error: ($errorNumber".
  741.             sm_encode_html_special_chars($errorString));
  742. }
  743.  
  744. /** Is the first response 'OK'? */
  745. $imapline fgets($stream1024);
  746. if(substr($imapline0,4!= '* OK'{
  747.     do_err('Error connecting to IMAP server. Server error: '.
  748.             sm_encode_html_special_chars($imapline));
  749. }
  750.  
  751. echo $IND 'IMAP server ready (<tt><small>'.
  752.     sm_encode_html_special_chars(trim($imapline))."</small></tt>)<br />\n";
  753.  
  754. /** Check capabilities */
  755. fputs($stream"A001 CAPABILITY\r\n");
  756. $capline '';
  757. while ($line=fgets($stream1024)){
  758.     if (preg_match("/A001.*/",$line)) {
  759.         break;
  760.     else {
  761.         $capline.=$line;
  762.     }
  763. }
  764.  
  765. /* don't display capabilities before STARTTLS */
  766. if ($use_imap_tls===&& stristr($capline'STARTTLS'=== false{
  767.     do_err('Your server doesn\'t support STARTTLS.');
  768. elseif($use_imap_tls===2{
  769.     /* try starting starttls */
  770.     fwrite($stream,"A002 STARTTLS\r\n");
  771.     $starttls_line=fgets($stream1024);
  772.     if (preg_match("/^A002 OK.*/i",$starttls_line)) {
  773.         $imap_starttls_err 'IMAP STARTTLS failed. Server replied: '
  774.             .sm_encode_html_special_chars($starttls_line);
  775.         do_err($imap_starttls_err);
  776.     elseif (stream_socket_enable_crypto($stream,true,STREAM_CRYPTO_METHOD_TLS_CLIENT)) {
  777.         do_err('Failed to enable encryption on IMAP connection.');
  778.     else {
  779.         echo $IND "IMAP STARTTLS extension looks OK.<br />\n";
  780.     }
  781.  
  782.     // get new capability line
  783.     fwrite($stream,"A003 CAPABILITY\r\n");
  784.     $capline='';
  785.     while ($line=fgets($stream1024)){
  786.         if (preg_match("/A003.*/",$line)) {
  787.             break;
  788.         else {
  789.             $capline.=$line;
  790.         }
  791.     }
  792. }
  793.  
  794. echo $IND 'Capabilities: <tt>'.sm_encode_html_special_chars($capline)."</tt><br />\n";
  795.  
  796. if($imap_auth_mech == 'login' && stristr($capline'LOGINDISABLED'!== FALSE{
  797.     do_err('Your server doesn\'t allow plaintext logins. '.
  798.             'Try enabling another authentication mechanism like CRAM-MD5, DIGEST-MD5 or TLS-encryption '.
  799.             'in the SquirrelMail configuration.'FALSE);
  800. }
  801.  
  802. if (stristr($capline'XMAGICTRASH'!== false{
  803.     $magic_trash 'It looks like IMAP_MOVE_EXPUNGE_TO_TRASH option is turned on '
  804.         .'in your Courier IMAP configuration. Courier does not provide tools that '
  805.         .'allow to detect folder used for Trash or commands are not documented. '
  806.         .'SquirrelMail can\'t detect special trash folder. SquirrelMail manages '
  807.         .'all message deletion or move operations internally and '
  808.         .'IMAP_MOVE_EXPUNGE_TO_TRASH option can cause errors in message and '
  809.         .'folder management operations. Please turn off IMAP_MOVE_EXPUNGE_TO_TRASH '
  810.         .'option in Courier imapd configuration.';
  811.     do_err($magic_trash,false);
  812. }
  813.  
  814. /* add warning about IMAP delivery */
  815. if (stristr($capline'XCOURIEROUTBOX'!== false{
  816.     $courier_outbox 'OUTBOX setting is enabled in your Courier imapd '
  817.         .'configuration. SquirrelMail uses standard SMTP protocol or sendmail '
  818.         .'binary to send emails. Courier IMAP delivery method is not supported'
  819.         .' and can create duplicate email messages.';
  820.     do_err($courier_outbox,false);
  821. }
  822.  
  823. /** OK, close connection */
  824. fputs($stream"A004 LOGOUT\r\n");
  825. fclose($stream);
  826.  
  827. echo "Checking internationalization (i18n) settings...<br />\n";
  828. echo "$IND gettext - ";
  829. if (function_exists('gettext')) {
  830.     echo 'Gettext functions are available.'
  831.         .' On some systems you must have appropriate system locales compiled.'
  832.         ."<br />\n";
  833.  
  834.     /* optional setlocale() tests. Should work only on glibc systems. */
  835.     if (sqgetGlobalVar('testlocales',$testlocales,SQ_GET)) {
  836.         include_once(SM_PATH 'include/languages.php');
  837.         echo $IND $IND 'Testing translations:<br>';
  838.         foreach ($languages as $lang_code => $lang_data{
  839.             /* don't test aliases */
  840.             if (isset($lang_data['NAME'])) {
  841.                 /* locale can be $lang_code or $lang_data['LOCALE'] */
  842.                 if (isset($lang_data['LOCALE'])) {
  843.                     $setlocale $lang_data['LOCALE'];
  844.                 else {
  845.                     $setlocale $lang_code;
  846.                 }
  847.                 /* prepare information about tested locales */
  848.                 if (is_array($setlocale)) {
  849.                     $display_locale implode(', ',$setlocale);
  850.                     $locale_count count($setlocale);
  851.                 else {
  852.                     $display_locale $setlocale;
  853.                     $locale_count 1;
  854.                 }
  855.                 $tested_locales_msg 'Tested '.sm_encode_html_special_chars($display_locale).' '
  856.                     .($locale_count>'locales':'locale')'.';
  857.  
  858.                 echo $IND $IND .$IND $lang_data['NAME'].' (' .$lang_code') - ';
  859.                 $retlocale sq_setlocale(LC_ALL,$setlocale);
  860.                 if (is_bool($retlocale)) {
  861.                     echo '<font color="red">unsupported</font>. ';
  862.                     echo $tested_locales_msg;
  863.                 else {
  864.                     echo 'supported. '
  865.                         .$tested_locales_msg
  866.                         .' setlocale() returned "'.sm_encode_html_special_chars($retlocale).'"';
  867.                 }
  868.                 echo "<br />\n";
  869.             }
  870.         }
  871.         echo $IND $IND '<a href="configtest.php">Don\'t test translations</a>';
  872.     else {
  873.         echo $IND $IND '<a href="configtest.php?testlocales=1">Test translations</a>. '
  874.             .'This test is not accurate and might work only on some systems.'
  875.             ."\n";
  876.     }
  877.     echo "<br />\n";
  878.     /* end of translation tests */
  879. else {
  880.     echo 'Gettext functions are unavailable.'
  881.         .' SquirrelMail will use slower internal gettext functions.'
  882.         ."<br />\n";
  883. }
  884. echo "$IND mbstring - ";
  885. if (function_exists('mb_detect_encoding')) {
  886.     echo "Mbstring functions are available.<br />\n";
  887. else {
  888.     echo 'Mbstring functions are unavailable.'
  889.         ." Japanese translation won't work.<br />\n";
  890. }
  891. echo "$IND recode - ";
  892. if (function_exists('recode')) {
  893.     echo "Recode functions are available.<br />\n";
  894. elseif (isset($use_php_recode&& $use_php_recode{
  895.     echo "Recode functions are unavailable.<br />\n";
  896.     do_err('Your configuration requires recode support, but recode support is missing.');
  897. else {
  898.     echo "Recode functions are unavailable.<br />\n";
  899. }
  900. echo "$IND iconv - ";
  901. if (function_exists('iconv')) {
  902.     echo "Iconv functions are available.<br />\n";
  903. elseif (isset($use_php_iconv&& $use_php_iconv{
  904.     echo "Iconv functions are unavailable.<br />\n";
  905.     do_err('Your configuration requires iconv support, but iconv support is missing.');
  906. else {
  907.     echo "Iconv functions are unavailable.<br />\n";
  908. }
  909. // same test as in include/init.php + date_default_timezone_set check
  910. echo "$IND timezone - ";
  911. if ( (!ini_get('safe_mode')) || function_exists('date_default_timezone_set'||
  912.         !strcmp(ini_get('safe_mode_allowed_env_vars'),''||
  913.         preg_match('/^([\w_]+,)*TZ/'ini_get('safe_mode_allowed_env_vars')) ) {
  914.     echo "Webmail users can change their time zone settings. \n";
  915. else {
  916.     echo "Webmail users can't change their time zone settings. \n";
  917. }
  918. if (isset($_ENV['TZ'])) {
  919.     echo 'Default time zone is '.sm_encode_html_special_chars($_ENV['TZ']);
  920. else {
  921.     echo 'Current time zone is '.date('T');
  922. }
  923. echo ".<br />\n";
  924.  
  925. // Pear DB tests
  926. echo "Checking database functions...<br />\n";
  927. if($addrbook_dsn || $prefs_dsn || $addrbook_global_dsn{
  928.     @include_once('DB.php');
  929.     if (class_exists('DB')) {
  930.         echo "$IND PHP Pear DB support is present.<br />\n";
  931.         $db_functions=array(
  932.                 'dbase' => 'dbase_open',
  933.                 'fbsql' => 'fbsql_connect',
  934.                 'interbase' => 'ibase_connect',
  935.                 'informix' => 'ifx_connect',
  936.                 'msql' => 'msql_connect',
  937.                 'mssql' => 'mssql_connect',
  938.                 'mysql' => 'mysql_connect',
  939.                 'mysqli' => 'mysqli_connect',
  940.                 'oci8' => 'ocilogon',
  941.                 'odbc' => 'odbc_connect',
  942.                 'pgsql' => 'pg_connect',
  943.                 'sqlite' => 'sqlite_open',
  944.                 'sybase' => 'sybase_connect'
  945.                 );
  946.  
  947.         $dsns array();
  948.         if($prefs_dsn{
  949.             $dsns['preferences'$prefs_dsn;
  950.         }
  951.         if($addrbook_dsn{
  952.             $dsns['addressbook'$addrbook_dsn;
  953.         }
  954.         if($addrbook_global_dsn{
  955.             $dsns['global addressbook'$addrbook_global_dsn;
  956.         }
  957.  
  958.         foreach($dsns as $type => $dsn{
  959.             $aDsn explode(':'$dsn);
  960.             $dbtype array_shift($aDsn);
  961.  
  962.             if(isset($db_functions[$dbtype]&& function_exists($db_functions[$dbtype])) {
  963.                 echo "$IND$dbtype database support present.<br />\n";
  964.             elseif(!(bool)ini_get('enable_dl'|| (bool)ini_get('safe_mode')) {
  965.                 do_err($dbtype.' database support not present!');
  966.             else {
  967.                 // Non-fatal error
  968.                 do_err($dbtype.' database support not present or not configured!
  969.                     Trying to dynamically load '.$dbtype.' extension.
  970.                     Please note that it is advisable to not rely on dynamic loading of extensions.'FALSE);
  971.             }
  972.  
  973.  
  974.             // now, test this interface:
  975.  
  976.             $dbh DB::connect($dsntrue);
  977.             if (DB::isError($dbh)) {
  978.                 do_err('Database error: 'sm_encode_html_special_chars(DB::errorMessage($dbh)) .
  979.                         ' in ' .$type .' DSN.');
  980.             }
  981.             $dbh->disconnect();
  982.             echo "$IND$type database connect successful.<br />\n";
  983.         }
  984.     else {
  985.         $db_error='Required PHP PEAR DB support is not available.'
  986.             .' Is PEAR installed and is the include path set correctly to find <tt>DB.php</tt>?'
  987.             .' The include path is now: "<tt>' ini_get('include_path''</tt>".';
  988.         do_err($db_error);
  989.     }
  990. else {
  991.     echo $IND."not using database functionality.<br />\n";
  992. }
  993.  
  994. // LDAP DB tests
  995. echo "Checking LDAP functions...<br />\n";
  996. ifempty($ldap_server) ) {
  997.     echo $IND."not using LDAP functionality.<br />\n";
  998. else {
  999.     if !function_exists('ldap_connect') ) {
  1000.         do_err('Required LDAP support is not available.');
  1001.     else {
  1002.         echo "$IND LDAP support present.<br />\n";
  1003.         foreach $ldap_server as $param {
  1004.  
  1005.             $linkid @ldap_connect($param['host'](empty($param['port']389 $param['port']) );
  1006.  
  1007.             if $linkid {
  1008.                 echo "$IND LDAP connect to ".$param['host']." successful: ".$linkid."<br />\n";
  1009.  
  1010.                 if !empty($param['protocol']&&
  1011.                         !ldap_set_option($linkidLDAP_OPT_PROTOCOL_VERSION$param['protocol']) ) {
  1012.                     do_err('Unable to set LDAP protocol');
  1013.                 }
  1014.  
  1015.                 if empty($param['binddn']) ) {
  1016.                     $bind @ldap_bind($linkid);
  1017.                 else {
  1018.                     $bind @ldap_bind($linkid$param['binddn']$param['bindpw']);
  1019.                 }
  1020.  
  1021.                 if $bind {
  1022.                     echo "$IND LDAP Bind Successful <br />";
  1023.                 else {
  1024.                     do_err('Unable to Bind to LDAP Server');
  1025.                 }
  1026.  
  1027.                 @ldap_close($linkid);
  1028.             else {
  1029.                 do_err('Connection to LDAP failed');
  1030.             }
  1031.         }
  1032.     }
  1033. }
  1034.  
  1035. echo '<hr width="75%" align="center">';
  1036. echo '<h2 align="center">Summary</h2>';
  1037. $footer '<hr width="75%" align="center">';
  1038. if ($warnings{
  1039.     echo '<p>No fatal errors were found, but there was at least 1 warning. Please check the flagged issue(s) carefully, as correcting them may prevent erratic, undefined, or incorrect behavior (or flat out breakage).</p>';
  1040.     echo $footer;
  1041. else {
  1042.     print <<< EOF
  1043. <p>Congratulations, your SquirrelMail setup looks fine to me!</p>
  1044.  
  1045. <p><a href="login.php">Login now</a></p>
  1046.  
  1047. </body>
  1048. </html>
  1049. EOF;
  1050.     echo $footer;
  1051. }

Documentation generated on Sun, 21 Dec 2014 04:17:29 +0100 by phpDocumentor 1.4.3