4 * SquirrelMail configtest script
6 * Copyright (c) 2003-2005 The SquirrelMail Project Team
7 * Licensed under the GNU GPL. For full terms see the file COPYING.
10 * @package squirrelmail
14 /************************************************************
15 * NOTE: you do not need to change this script! *
16 * If it throws errors you need to adjust your config. *
17 ************************************************************/
19 // This script could really use some restructuring as it has grown quite rapidly
20 // but is not very 'clean'. Feel free to get some structure into this thing.
22 function do_err($str, $exit = TRUE) {
24 echo '<p>'.$IND.'<font color="red"><b>ERROR:</b></font> ' .$str. "</p>\n";
26 echo '</body></html>';
31 $IND = str_repeat(' ',4);
35 define('SM_PATH', '../');
38 * Load config before output begins. functions/strings.php depends on
39 * functions/globals.php. functions/global.php needs to be run before
40 * any html output starts. If config.php is missing, error will be displayed
43 if (file_exists(SM_PATH
. 'config/config.php')) {
44 include(SM_PATH
. 'config/config.php');
45 include(SM_PATH
. 'functions/strings.php');
47 ?
><!DOCTYPE HTML
PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
50 <title
>SquirrelMail configtest
</title
>
53 <h1
>SquirrelMail configtest
</h1
>
55 <p
>This script will
try to check some aspects of your SquirrelMail configuration
56 and point you to errors whereever it can find them
. You need to go run
<tt
>conf
.pl
</tt
>
57 in the
<tt
>config
/</tt
> directory first before you run this script
.</p
>
62 $included = array_map('basename', get_included_files() );
63 if(!in_array('config.php', $included)) {
64 if(!file_exists(SM_PATH
. 'config/config.php')) {
65 do_err('Config file '.SM_PATH
. 'config/config.php does not exist!<br />'.
66 'You need to run <tt>conf.pl</tt> first.');
68 do_err('Could not read '.SM_PATH
.'config/config.php! Check file permissions.');
70 if(!in_array('strings.php', $included)) {
71 do_err('Could not include '.SM_PATH
.'functions/strings.php!<br />'.
72 'Check permissions on that file.');
75 /* checking PHP specs */
77 echo "<p><table>\n<tr><td>SquirrelMail version:</td><td><b>" . $version . "</b></td></tr>\n" .
78 '<tr><td>Config file version:</td><td><b>' . $config_version . "</b></td></tr>\n" .
79 '<tr><td>Config file last modified:</td><td><b>' .
80 date ('d F Y H:i:s', filemtime(SM_PATH
. 'config/config.php')) .
81 "</b></td></tr>\n</table>\n</p>\n\n";
83 echo "Checking PHP configuration...<br />\n";
85 if(!check_php_version(4,1,0)) {
86 do_err('Insufficient PHP version: '. PHP_VERSION
. '! Minimum required: 4.1.0');
89 echo $IND . 'PHP version ' . PHP_VERSION
. " OK.<br />\n";
91 $php_exts = array('session','pcre');
92 $diff = array_diff($php_exts, get_loaded_extensions());
94 do_err('Required PHP extensions missing: '.implode(', ',$diff) );
97 echo $IND . "PHP extensions OK.<br />\n";
99 /* dangerous php settings */
101 * mbstring.func_overload allows to replace original string and regexp functions
102 * with their equivalents from php mbstring extension. It causes problems when
103 * scripts analyse 8bit strings byte after byte or use 8bit strings in regexp tests.
104 * Setting can be controlled in php.ini (php 4.2.0), webserver config (php 4.2.0)
105 * and .htaccess files (php 4.3.5).
107 if (function_exists('mb_internal_encoding') &&
108 check_php_version(4,2,0) &&
109 (int)ini_get('mbstring.func_overload')!=0) {
110 $mb_error='You have enabled mbstring overloading.'
111 .' It can cause problems with SquirrelMail scripts that rely on single byte string functions.';
117 echo "Checking paths...<br />\n";
119 if(!file_exists($data_dir)) {
120 do_err("Data dir ($data_dir) does not exist!");
122 if(!is_dir($data_dir)) {
123 do_err("Data dir ($data_dir) is not a directory!");
125 if(!is_readable($data_dir)) {
126 do_err("I cannot read from data dir ($data_dir)!");
128 if(!is_writable($data_dir)) {
129 do_err("I cannot write to data dir ($data_dir)!");
132 // todo_ornot: actually write something and read it back.
133 echo $IND . "Data dir OK.<br />\n";
136 if($data_dir == $attachment_dir) {
137 echo $IND . "Attachment dir is the same as data dir.<br />\n";
139 if(!file_exists($attachment_dir)) {
140 do_err("Attachment dir ($attachment_dir) does not exist!");
142 if (!is_dir($attachment_dir)) {
143 do_err("Attachment dir ($attachment_dir) is not a directory!");
145 if (!is_writable($attachment_dir)) {
146 do_err("I cannot write to attachment dir ($attachment_dir)!");
148 echo $IND . "Attachment dir OK.<br />\n";
152 /* check plugins and themes */
153 if (isset($plugins[0])) {
154 foreach($plugins as $plugin) {
155 if(!file_exists(SM_PATH
.'plugins/'.$plugin)) {
156 do_err('You have enabled the <i>'.$plugin.'</i> plugin but I cannot find it.', FALSE);
157 } elseif (!is_readable(SM_PATH
.'plugins/'.$plugin.'/setup.php')) {
158 do_err('You have enabled the <i>'.$plugin.'</i> plugin but I cannot read its setup.php file.', FALSE);
161 echo $IND . "Plugins OK.<br />\n";
163 echo $IND . "Plugins are not enabled in config.<br />\n";
165 foreach($theme as $thm) {
166 if(!file_exists($thm['PATH'])) {
167 do_err('You have enabled the <i>'.$thm['NAME'].'</i> theme but I cannot find it ('.$thm['PATH'].').', FALSE);
168 } elseif(!is_readable($thm['PATH'])) {
169 do_err('You have enabled the <i>'.$thm['NAME'].'</i> theme but I cannot read it ('.$thm['PATH'].').', FALSE);
173 echo $IND . "Themes OK.<br />\n";
175 if ( $squirrelmail_default_language != 'en_US' ) {
176 $loc_path = SM_PATH
.'locale/'.$squirrelmail_default_language.'/LC_MESSAGES/squirrelmail.mo';
177 if( ! file_exists( $loc_path ) ) {
178 do_err('You have set <i>' . $squirrelmail_default_language .
179 '</i> as your default language, but I cannot find this translation (should be '.
180 'in <tt>' . $loc_path . '</tt>). Please note that you have to download translations '.
181 'separately from the main SquirrelMail package.', FALSE);
182 } elseif ( ! is_readable( $loc_path ) ) {
183 do_err('You have set <i>' . $squirrelmail_default_language .
184 '</i> as your default language, but I cannot read this translation (file '.
185 'in <tt>' . $loc_path . '</tt> unreadable).', FALSE);
187 echo $IND . "Default language OK.<br />\n";
190 echo $IND . "Default language OK.<br />\n";
193 echo $IND . "Base URL detected as: <tt>" . htmlspecialchars(get_location()) . "</tt><br />\n";
196 /* check outgoing mail */
198 if($use_smtp_tls ||
$use_imap_tls) {
199 if(!check_php_version(4,3,0)) {
200 do_err('You need at least PHP 4.3.0 for SMTP/IMAP TLS!');
202 if(!extension_loaded('openssl')) {
203 do_err('You need the openssl PHP extension to use SMTP/IMAP TLS!');
207 echo "Checking outgoing mail service....<br />\n";
210 // is_executable also checks for existance, but we want to be as precise as possible with the errors
211 if(!file_exists($sendmail_path)) {
212 do_err("Location of sendmail program incorrect ($sendmail_path)!");
214 if(!is_executable($sendmail_path)) {
215 do_err("I cannot execute the sendmail program ($sendmail_path)!");
218 echo $IND . "sendmail OK<br />\n";
220 $stream = fsockopen( ($use_smtp_tls?
'tls://':'').$smtpServerAddress, $smtpPort,
221 $errorNumber, $errorString);
223 do_err("Error connecting to SMTP server \"$smtpServerAddress:$smtpPort\".".
224 "Server error: ($errorNumber) ".htmlspecialchars($errorString));
227 // check for SMTP code; should be 2xx to allow us access
228 $smtpline = fgets($stream, 1024);
229 if(((int) $smtpline{0}) > 3) {
230 do_err("Error connecting to SMTP server. Server error: ".
231 htmlspecialchars($smtpline));
234 fputs($stream, 'QUIT');
236 echo $IND . 'SMTP server OK (<tt><small>'.
237 trim(htmlspecialchars($smtpline))."</small></tt>)<br />\n";
239 /* POP before SMTP */
240 if($pop_before_smtp) {
241 $stream = fsockopen($smtpServerAddress, 110, $err_no, $err_str);
243 do_err("Error connecting to POP Server ($smtpServerAddress:110) "
244 . $err_no . ' : ' . htmlspecialchars($err_str));
247 $tmp = fgets($stream, 1024);
248 if (substr($tmp, 0, 3) != '+OK') {
249 do_err("Error connecting to POP Server ($smtpServerAddress:110)"
250 . ' '.htmlspecialchars($tmp));
252 fputs($stream, 'QUIT');
254 echo $IND . "POP-before-SMTP OK.<br />\n";
259 * Check the IMAP server
261 echo "Checking IMAP service....<br />\n";
263 /** Can we open a connection? */
264 $stream = fsockopen( ($use_imap_tls?
'tls://':'').$imapServerAddress, $imapPort,
265 $errorNumber, $errorString);
267 do_err("Error connecting to IMAP server \"$imapServerAddress:$imapPort\".".
268 "Server error: ($errorNumber) ".
269 htmlspecialchars($errorString));
272 /** Is the first response 'OK'? */
273 $imapline = fgets($stream, 1024);
274 if(substr($imapline, 0,4) != '* OK') {
275 do_err('Error connecting to IMAP server. Server error: '.
276 htmlspecialchars($imapline));
279 echo $IND . 'IMAP server ready (<tt><small>'.
280 htmlspecialchars(trim($imapline))."</small></tt>)<br />\n";
282 /** Check capabilities */
283 fputs($stream, "A001 CAPABILITY\r\n");
284 $capline = fgets($stream, 1024);
286 echo $IND . 'Capabilities: <tt>'.htmlspecialchars($capline)."</tt><br />\n";
288 if($imap_auth_mech == 'login' && stristr($capline, 'LOGINDISABLED') !== FALSE) {
289 do_err('Your server doesn\'t allow plaintext logins. '.
290 'Try enabling another authentication mechanism like CRAM-MD5, DIGEST-MD5 or TLS-encryption '.
291 'in the SquirrelMail configuration.', FALSE);
293 if($use_imap_tls && stristr($capline, 'STARTTLS') === FALSE) {
294 do_err('You have enabled TLS encryption in the config, but the server does not '.
295 'report STARTTLS capability. TLS is probably not supported.', FALSE);
298 /** OK, close connection */
299 fputs($stream, "A002 LOGOUT\r\n");
302 echo "Checking internationalization (i18n) settings...<br />\n";
303 echo "$IND gettext - ";
304 if (function_exists('gettext')) {
305 echo 'Gettext functions are available.'
306 .' On some systems you must have appropriate system locales compiled.'
309 echo 'Gettext functions are unavailable.'
310 .' SquirrelMail will use slower internal gettext functions.'
313 echo "$IND mbstring - ";
314 if (function_exists('mb_detect_encoding')) {
315 echo "Mbstring functions are available.<br />\n";
317 echo 'Mbstring functions are unavailable.'
318 ." Japanese translation won't work.<br />\n";
320 echo "$IND recode - ";
321 if (function_exists('recode')) {
322 echo "Recode functions are available.<br />\n";
323 } elseif ($use_php_recode) {
324 echo "Recode functions are unavailable.<br />\n";
325 do_err('Your configuration requires recode support, but recode support is missing.');
327 echo "Recode functions are unavailable.<br />\n";
329 echo "$IND iconv - ";
330 if (function_exists('iconv')) {
331 echo "Iconv functions are available.<br />\n";
332 } elseif ($use_php_iconv) {
333 echo "Iconv functions are unavailable.<br />\n";
334 do_err('Your configuration requires iconv support, but iconv support is missing.');
336 echo "Iconv functions are unavailable.<br />\n";
338 // same test as in include/validate.php
339 echo "$IND timezone - ";
340 if ( (!ini_get('safe_mode')) ||
341 !strcmp(ini_get('safe_mode_allowed_env_vars'),'') ||
342 preg_match('/^([\w_]+,)*TZ/', ini_get('safe_mode_allowed_env_vars')) ) {
343 echo "Webmail users can change their time zone settings.<br />\n";
345 echo "Webmail users can't change their time zone settings.<br />\n";
350 echo "Checking database functions...<br />\n";
351 if($addrbook_dsn ||
$prefs_dsn ||
$addrbook_global_dsn) {
352 @include_once
('DB.php');
353 if (class_exists('DB')) {
354 echo "$IND PHP Pear DB support is present.<br />\n";
356 'dbase' => 'dbase_open',
357 'fbsql' => 'fbsql_connect',
358 'interbase' => 'ibase_connect',
359 'informix' => 'ifx_connect',
360 'msql' => 'msql_connect',
361 'mssql' => 'mssql_connect',
362 'mysql' => 'mysql_connect',
363 'mysqli' => 'mysqli_connect',
364 'oci8' => 'ocilogon',
365 'odbc' => 'odbc_connect',
366 'pgsql' => 'pgsql_connect',
367 'sqlite' => 'sqlite_open',
368 'sybase' => 'sybase_connect'
373 $dsns['preferences'] = $prefs_dsn;
376 $dsns['addressbook'] = $addrbook_dsn;
378 if($addrbook_global_dsn) {
379 $dsns['global addressbook'] = $addrbook_global_dsn;
382 foreach($dsns as $type => $dsn) {
383 $dbtype = array_shift(explode(':', $dsn));
384 if(isset($db_functions[$dbtype]) && function_exists($db_functions[$dbtype])) {
385 echo "$IND$dbtype database support present.<br />\n";
387 // now, test this interface:
389 $dbh = DB
::connect($dsn, true);
390 if (DB
::isError($dbh)) {
391 do_err('Database error: '. htmlspecialchars(DB
::errorMessage($dbh)) .
392 ' in ' .$type .' DSN.');
395 echo "$IND$type database connect successful.<br />\n";
398 do_err($db.' database support not present!');
402 $db_error='Required PHP PEAR DB support is not available.'
403 .' Is PEAR installed and is the include path set correctly to find <tt>DB.php</tt>?'
404 .' The include path is now:<tt>' . ini_get('include_path') . '</tt>.';
408 echo $IND."not using database functionality.<br />\n";
412 echo "Checking LDAP functions...<br />\n";
413 if( empty($ldap_server) ) {
414 echo $IND."not using LDAP functionality.<br />\n";
416 if ( !function_exists(ldap_connect
) ) {
417 do_err('Required LDAP support is not available.');
419 echo "$IND LDAP support present.<br />\n";
420 foreach ( $ldap_server as $param ) {
422 $linkid = ldap_connect($param['host'], (empty($param['port']) ?
389 : $param['port']) );
425 echo "$IND LDAP connect to ".$param['host']." successful: ".$linkid."<br />\n";
427 if ( !empty($param['protocol']) &&
428 !ldap_set_option($linkid, LDAP_OPT_PROTOCOL_VERSION
, $param['protocol']) ) {
429 do_err('Unable to set LDAP protocol');
432 if ( empty($param['binddn']) ) {
433 $bind = ldap_bind($linkid);
435 $bind = ldap_bind($param['binddn'], $param['bindpw']);
439 echo "$IND LDAP Bind Successful <br />";
441 do_err('Unable to Bind to LDAP Server');
446 do_err('Connection to LDAP failed');
453 <p
>Congratulations
, your SquirrelMail setup looks fine to me
!</p
>
455 <p
><a href
="login.php">Login now
</a
></p
>