2002-03-03 22:47:30 +01:00
< ? php
/************************************************************************** \
2004-05-05 14:06:13 +02:00
* eGroupWare - Setup *
* http :// www . egroupware . org *
2003-10-22 13:28:17 +02:00
* -------------------------------------------- *
* This file written by Joseph Engo < jengo @ phpgroupware . org > *
* and Dan Kuykendall < seek3r @ phpgroupware . org > *
* and Mark Peters < skeeter @ phpgroupware . org > *
2004-05-05 14:06:13 +02:00
* and Miles Lott < milosch @ groupwhere . org > *
2003-10-22 13:28:17 +02:00
* -------------------------------------------- *
2002-03-03 22:47:30 +01:00
* This program is free software ; you can redistribute it and / or modify it *
* under the terms of the GNU General Public License as published by the *
* Free Software Foundation ; either version 2 of the License , or ( at your *
2003-10-22 13:28:17 +02:00
* option ) any later version . *
2002-03-03 22:47:30 +01:00
\ **************************************************************************/
/* $Id$ */
2005-07-20 14:46:59 +02:00
class egw_dummy {
var $db ;
var $common ;
var $accounts ;
2005-07-27 12:59:30 +02:00
function invalidate_session_cache () { }
2005-07-20 14:46:59 +02:00
}
2002-03-03 22:47:30 +01:00
class setup
{
var $db ;
2004-09-18 16:55:02 +02:00
var $config_table = 'phpgw_config' ;
var $applications_table = 'phpgw_applications' ;
2002-03-04 05:49:42 +01:00
var $oProc ;
2002-03-03 22:47:30 +01:00
var $detection = '' ;
var $process = '' ;
var $lang = '' ;
var $html = '' ;
2003-10-22 13:28:17 +02:00
/* table name vars */
2003-10-05 04:06:11 +02:00
var $tbl_apps ;
var $tbl_config ;
var $tbl_hooks ;
2002-03-03 22:47:30 +01:00
function setup ( $html = False , $translation = False )
{
2005-03-24 14:15:12 +01:00
$this -> detection =& CreateObject ( 'setup.setup_detection' );
$this -> process =& CreateObject ( 'setup.setup_process' );
2002-03-03 22:47:30 +01:00
/* The setup application needs these */
2005-03-04 13:40:28 +01:00
$this -> html = $html ? CreateObject ( 'setup.setup_html' ) : '' ;
$this -> translation = $translation ? CreateObject ( 'setup.setup_translation' ) : '' ;
2003-10-05 04:06:11 +02:00
// $this->tbl_apps = $this->get_apps_table_name();
// $this->tbl_config = $this->get_config_table_name();
$this -> tbl_hooks = $this -> get_hooks_table_name ();
2002-03-03 22:47:30 +01:00
}
2005-03-24 14:15:12 +01:00
/**
* include api db class for the ConfigDomain and connect to the db
*/
2004-11-21 10:44:02 +01:00
function loaddb ( $connect_and_setcharset = true )
2002-03-03 22:47:30 +01:00
{
2004-01-06 14:38:45 +01:00
if ( ! isset ( $this -> ConfigDomain ) || empty ( $this -> ConfigDomain ))
{
$this -> ConfigDomain = get_var ( 'ConfigDomain' , array ( 'COOKIE' , 'POST' ), $_POST [ 'FormDomain' ]);
}
2002-03-03 22:47:30 +01:00
2005-03-04 13:40:28 +01:00
$GLOBALS [ 'egw_info' ][ 'server' ][ 'db_type' ] = $GLOBALS [ 'egw_domain' ][ $this -> ConfigDomain ][ 'db_type' ];
2002-03-03 22:47:30 +01:00
2005-03-04 13:40:28 +01:00
if ( $GLOBALS [ 'egw_info' ][ 'server' ][ 'db_type' ] == 'pgsql' )
2004-06-28 11:29:44 +02:00
{
2005-03-04 13:40:28 +01:00
$GLOBALS [ 'egw_info' ][ 'server' ][ 'db_persistent' ] = False ;
2004-06-28 11:29:44 +02:00
}
2005-06-19 14:43:00 +02:00
$this -> db =& CreateObject ( 'phpgwapi.egw_db' );
2005-03-04 13:40:28 +01:00
$this -> db -> Host = $GLOBALS [ 'egw_domain' ][ $this -> ConfigDomain ][ 'db_host' ];
$this -> db -> Port = $GLOBALS [ 'egw_domain' ][ $this -> ConfigDomain ][ 'db_port' ];
$this -> db -> Type = $GLOBALS [ 'egw_domain' ][ $this -> ConfigDomain ][ 'db_type' ];
$this -> db -> Database = $GLOBALS [ 'egw_domain' ][ $this -> ConfigDomain ][ 'db_name' ];
$this -> db -> User = $GLOBALS [ 'egw_domain' ][ $this -> ConfigDomain ][ 'db_user' ];
$this -> db -> Password = $GLOBALS [ 'egw_domain' ][ $this -> ConfigDomain ][ 'db_pass' ];
2004-09-18 16:55:02 +02:00
$this -> db -> set_app ( 'phpgwapi' );
2004-11-21 10:44:02 +01:00
if ( $connect_and_setcharset )
{
2005-05-19 08:32:42 +02:00
$this -> db -> Halt_On_Error = 'no' ; // table might not be created at that stage
2004-11-21 10:44:02 +01:00
// Set the DB's client charset if a system-charset is set
$this -> db -> query ( " select config_value from phpgw_config WHERE config_app='phpgwapi' and config_name='system_charset' " , __LINE__ , __FILE__ );
if ( $this -> db -> next_record () && $this -> db -> f ( 0 ))
{
$this -> db -> Link_ID -> SetCharSet ( $this -> db -> f ( 0 ));
}
$this -> db -> Halt_On_Error = 'yes' ; // setting the default again
}
2004-01-06 14:38:45 +01:00
}
/**
* Set the domain used for cookies
*
* @ return string domain
*/
function set_cookiedomain ()
{
2004-05-01 11:58:38 +02:00
$this -> cookie_domain = $_SERVER [ 'HTTP_HOST' ];
// remove port from HTTP_HOST
if ( preg_match ( " /^(.*):(.*) $ / " , $this -> cookie_domain , $arr ))
2004-01-06 14:38:45 +01:00
{
2004-05-01 11:58:38 +02:00
$this -> cookie_domain = $arr [ 1 ];
2004-01-06 14:38:45 +01:00
}
2004-05-01 11:58:38 +02:00
if ( count ( explode ( '.' , $this -> cookie_domain )) <= 1 )
2004-01-06 14:38:45 +01:00
{
2004-05-01 11:58:38 +02:00
// setcookie dont likes domains without dots, leaving it empty, gets setcookie to fill the domain in
2004-01-06 14:38:45 +01:00
$this -> cookie_domain = '' ;
}
}
/**
* Set a cookie
*
* @ param string $cookiename name of cookie to be set
* @ param string $cookievalue value to be used , if unset cookie is cleared ( optional )
* @ param int $cookietime when cookie should expire , 0 for session only ( optional )
*/
function set_cookie ( $cookiename , $cookievalue = '' , $cookietime = 0 )
{
2004-03-09 22:05:28 +01:00
if ( ! isset ( $this -> cookie_domain ) || ! $this -> cookie_domain )
2004-01-06 14:38:45 +01:00
{
$this -> set_cookiedomain ();
}
2004-05-25 00:33:48 +02:00
setcookie ( $cookiename , $cookievalue , $cookietime , '/' , $this -> cookie_domain );
2002-03-03 22:47:30 +01:00
}
2005-03-24 14:15:12 +01:00
/**
* authenticate the setup user
*
* @ param $auth_type ? ? ?
*/
2002-03-06 03:47:47 +01:00
function auth ( $auth_type = 'Config' )
2002-03-03 22:47:30 +01:00
{
2003-09-28 17:45:07 +02:00
#phpinfo();
2004-01-18 22:03:56 +01:00
$FormLogout = get_var ( 'FormLogout' , array ( 'GET' , 'POST' ));
2004-01-06 14:38:45 +01:00
if ( ! $FormLogout )
2002-05-11 21:30:10 +02:00
{
2004-01-06 14:38:45 +01:00
$ConfigLogin = get_var ( 'ConfigLogin' , array ( 'POST' ));
$HeaderLogin = get_var ( 'HeaderLogin' , array ( 'POST' ));
$FormDomain = get_var ( 'FormDomain' , array ( 'POST' ));
2004-01-18 22:03:56 +01:00
$FormUser = get_var ( 'FormUser' , array ( 'POST' ));
2004-01-06 14:38:45 +01:00
$FormPW = get_var ( 'FormPW' , array ( 'POST' ));
2002-05-11 21:30:10 +02:00
2004-01-06 14:38:45 +01:00
$this -> ConfigDomain = get_var ( 'ConfigDomain' , array ( 'POST' , 'COOKIE' ));
2004-01-18 22:03:56 +01:00
$ConfigUser = get_var ( 'ConfigUser' , array ( 'POST' , 'COOKIE' ));
2004-01-06 14:38:45 +01:00
$ConfigPW = get_var ( 'ConfigPW' , array ( 'POST' , 'COOKIE' ));
2004-01-18 22:03:56 +01:00
$HeaderUser = get_var ( 'HeaderUser' , array ( 'POST' , 'COOKIE' ));
2004-01-06 14:38:45 +01:00
$HeaderPW = get_var ( 'HeaderPW' , array ( 'POST' , 'COOKIE' ));
$ConfigLang = get_var ( 'ConfigLang' , array ( 'POST' , 'COOKIE' ));
2004-01-18 22:03:56 +01:00
/* Setup defaults to aid in header upgrade to version 1.26 .
* This was the first version to include the following values .
*/
2005-03-04 13:40:28 +01:00
if ( !@ isset ( $GLOBALS [ 'egw_domain' ][ $FormDomain ][ 'config_user' ]) && isset ( $GLOBALS [ 'egw_domain' ][ $FormDomain ]))
2004-01-18 22:03:56 +01:00
{
2005-03-04 13:40:28 +01:00
@ $GLOBALS [ 'egw_domain' ][ $FormDomain ][ 'config_user' ] = 'admin' ;
2004-01-18 22:03:56 +01:00
}
2005-03-04 13:40:28 +01:00
if ( !@ isset ( $GLOBALS [ 'egw_info' ][ 'server' ][ 'header_admin_user' ]))
2004-01-18 22:03:56 +01:00
{
2005-03-04 13:40:28 +01:00
@ $GLOBALS [ 'egw_info' ][ 'server' ][ 'header_admin_user' ] = 'admin' ;
2004-01-18 22:03:56 +01:00
}
2004-01-06 14:38:45 +01:00
}
2002-03-04 03:55:53 +01:00
2004-05-04 11:08:28 +02:00
$remoteip = $_SERVER [ 'REMOTE_ADDR' ];
if ( ! empty ( $remoteip ) && ! $this -> checkip ( $remoteip )) { return False ; }
2002-03-06 03:40:30 +01:00
2004-01-06 14:38:45 +01:00
/* If FormLogout is set, simply invalidate the cookies (LOGOUT) */
switch ( strtolower ( $FormLogout ))
2002-03-03 22:47:30 +01:00
{
2004-01-06 14:38:45 +01:00
case 'config' :
2002-03-04 03:55:53 +01:00
/* config logout */
2004-01-06 14:38:45 +01:00
$expire = time () - 86400 ;
2004-01-18 22:03:56 +01:00
$this -> set_cookie ( 'ConfigUser' , '' , $expire , '/' );
2004-01-06 14:38:45 +01:00
$this -> set_cookie ( 'ConfigPW' , '' , $expire , '/' );
$this -> set_cookie ( 'ConfigDomain' , '' , $expire , '/' );
$this -> set_cookie ( 'ConfigLang' , '' , $expire , '/' );
2005-03-04 13:40:28 +01:00
$GLOBALS [ 'egw_info' ][ 'setup' ][ 'LastDomain' ] = $_COOKIE [ 'ConfigDomain' ];
$GLOBALS [ 'egw_info' ][ 'setup' ][ 'ConfigLoginMSG' ] = lang ( 'You have successfully logged out' );
$GLOBALS [ 'egw_info' ][ 'setup' ][ 'HeaderLoginMSG' ] = '' ;
2002-03-03 22:47:30 +01:00
return False ;
2004-01-06 14:38:45 +01:00
case 'header' :
2002-03-04 03:55:53 +01:00
/* header admin logout */
2004-01-06 14:38:45 +01:00
$expire = time () - 86400 ;
2004-01-18 22:03:56 +01:00
$this -> set_cookie ( 'HeaderUser' , '' , $expire , '/' );
2004-01-06 14:38:45 +01:00
$this -> set_cookie ( 'HeaderPW' , '' , $expire , '/' );
$this -> set_cookie ( 'ConfigLang' , '' , $expire , '/' );
2005-03-04 13:40:28 +01:00
$GLOBALS [ 'egw_info' ][ 'setup' ][ 'HeaderLoginMSG' ] = lang ( 'You have successfully logged out' );
$GLOBALS [ 'egw_info' ][ 'setup' ][ 'ConfigLoginMSG' ] = '' ;
2002-03-04 03:55:53 +01:00
return False ;
2002-03-03 22:47:30 +01:00
}
2004-01-06 14:38:45 +01:00
/* We get here if FormLogout is not set (LOGIN or subsequent pages) */
/* Expire login if idle for 20 minutes. The cookies are updated on every page load. */
$expire = ( int )( time () + ( 1200 * 9 ));
switch ( strtolower ( $auth_type ))
2002-03-03 22:47:30 +01:00
{
2004-01-06 14:38:45 +01:00
case 'header' :
if ( ! empty ( $HeaderLogin ))
{
/* header admin login */
2004-01-18 22:03:56 +01:00
/* New test is md5, cleartext version is for header < 1.26 */
2005-03-04 13:40:28 +01:00
if ( $this -> check_auth ( $FormUser , $FormPW , $GLOBALS [ 'egw_info' ][ 'server' ][ 'header_admin_user' ],
$GLOBALS [ 'egw_info' ][ 'server' ][ 'header_admin_password' ]))
2004-01-06 14:38:45 +01:00
{
2005-05-19 08:32:42 +02:00
$this -> set_cookie ( 'HeaderUser' , $FormUser , $expire , '/' );
$this -> set_cookie ( 'HeaderPW' , md5 ( $FormPW ), $expire , '/' );
$this -> set_cookie ( 'ConfigLang' , $ConfigLang , $expire , '/' );
2004-01-06 14:38:45 +01:00
return True ;
}
else
{
2005-03-04 13:40:28 +01:00
$GLOBALS [ 'egw_info' ][ 'setup' ][ 'HeaderLoginMSG' ] = lang ( 'Invalid password' );
$GLOBALS [ 'egw_info' ][ 'setup' ][ 'ConfigLoginMSG' ] = '' ;
2004-01-06 14:38:45 +01:00
return False ;
}
}
elseif ( ! empty ( $HeaderPW ) && $auth_type == 'Header' )
{
// Returning after login to header admin
2004-01-18 22:03:56 +01:00
/* New test is md5, cleartext version is for header < 1.26 */
2005-03-04 13:40:28 +01:00
if ( $this -> check_auth ( $HeaderUser , $HeaderPW , $GLOBALS [ 'egw_info' ][ 'server' ][ 'header_admin_user' ],
$GLOBALS [ 'egw_info' ][ 'server' ][ 'header_admin_password' ]))
2004-01-06 14:38:45 +01:00
{
2005-05-19 08:32:42 +02:00
$this -> set_cookie ( 'HeaderUser' , $HeaderUser , $expire , '/' );
$this -> set_cookie ( 'HeaderPW' , $HeaderPW , $expire , '/' );
$this -> set_cookie ( 'ConfigLang' , $ConfigLang , $expire , '/' );
2004-01-06 14:38:45 +01:00
return True ;
}
else
{
2005-03-04 13:40:28 +01:00
$GLOBALS [ 'egw_info' ][ 'setup' ][ 'HeaderLoginMSG' ] = lang ( 'Invalid password' );
$GLOBALS [ 'egw_info' ][ 'setup' ][ 'ConfigLoginMSG' ] = '' ;
2004-01-06 14:38:45 +01:00
return False ;
}
}
break ;
case 'config' :
if ( ! empty ( $ConfigLogin ))
{
/* config login */
2004-01-18 22:03:56 +01:00
/* New test is md5, cleartext version is for header < 1.26 */
2005-03-04 13:40:28 +01:00
if ( isset ( $GLOBALS [ 'egw_domain' ][ $FormDomain ]) &&
$this -> check_auth ( $FormUser , $FormPW , @ $GLOBALS [ 'egw_domain' ][ $FormDomain ][ 'config_user' ],
@ $GLOBALS [ 'egw_domain' ][ $FormDomain ][ 'config_passwd' ]))
2004-01-06 14:38:45 +01:00
{
2005-05-19 08:32:42 +02:00
$this -> set_cookie ( 'ConfigUser' , $FormUser , $expire , '/' );
$this -> set_cookie ( 'ConfigPW' , md5 ( $FormPW ), $expire , '/' );
$this -> set_cookie ( 'ConfigDomain' , $FormDomain , $expire , '/' );
2004-01-06 14:38:45 +01:00
/* Set this now since the cookie will not be available until the next page load */
2005-05-19 08:32:42 +02:00
$this -> ConfigDomain = $FormDomain ;
$this -> set_cookie ( 'ConfigLang' , $ConfigLang , $expire , '/' );
2004-01-06 14:38:45 +01:00
return True ;
}
else
{
2005-03-04 13:40:28 +01:00
$GLOBALS [ 'egw_info' ][ 'setup' ][ 'ConfigLoginMSG' ] = lang ( 'Invalid password' );
$GLOBALS [ 'egw_info' ][ 'setup' ][ 'HeaderLoginMSG' ] = '' ;
2004-01-06 14:38:45 +01:00
return False ;
}
}
elseif ( ! empty ( $ConfigPW ))
{
// Returning after login to config
2004-01-18 22:03:56 +01:00
/* New test is md5, cleartext version is for header < 1.26 */
2005-03-04 13:40:28 +01:00
if ( $this -> check_auth ( $ConfigUser , $ConfigPW , @ $GLOBALS [ 'egw_domain' ][ $this -> ConfigDomain ][ 'config_user' ],
@ $GLOBALS [ 'egw_domain' ][ $this -> ConfigDomain ][ 'config_passwd' ]))
2004-01-06 14:38:45 +01:00
{
2005-05-19 08:32:42 +02:00
$this -> set_cookie ( 'ConfigUser' , $ConfigUser , $expire , '/' );
$this -> set_cookie ( 'ConfigPW' , $ConfigPW , $expire , '/' );
2004-01-06 14:38:45 +01:00
$this -> set_cookie ( 'ConfigDomain' , $this -> ConfigDomain , $expire , '/' );
2005-05-19 08:32:42 +02:00
$this -> set_cookie ( 'ConfigLang' , $ConfigLang , $expire , '/' );
2004-01-06 14:38:45 +01:00
return True ;
}
else
{
2005-03-04 13:40:28 +01:00
$GLOBALS [ 'egw_info' ][ 'setup' ][ 'ConfigLoginMSG' ] = lang ( 'Invalid password' );
$GLOBALS [ 'egw_info' ][ 'setup' ][ 'HeaderLoginMSG' ] = '' ;
2004-01-06 14:38:45 +01:00
return False ;
}
}
break ;
2002-03-03 22:47:30 +01:00
}
2004-01-06 14:38:45 +01:00
return False ;
2002-03-03 22:47:30 +01:00
}
2005-05-29 10:03:01 +02:00
/**
* check if username and password is valid
*
* this function compares the supplied and stored username and password
* as any of the passwords can be clear text or md5 we convert them to md5
* internal and compare always the md5 hashs
*
* @ param string $user the user supplied username
* @ param string $pw the user supplied password
* @ param string $conf_user the configured username
* @ param string $conf_pw the configured password
* @ returns bool
*/
2004-02-23 11:07:55 +01:00
function check_auth ( $user , $pw , $conf_user , $conf_pw )
{
2005-05-29 10:03:01 +02:00
#echo "<p>setup::check_auth('$user','$pw','$conf_user','$conf_pw')</p>\n";exit;
2004-02-23 11:07:55 +01:00
if ( $user != $conf_user )
{
return False ; // wrong username
}
2005-05-29 10:03:01 +02:00
// Verify that $pw is not already encoded as md5
if ( ! preg_match ( '/^[0-9a-f]{32}$/' , $conf_pw ))
2004-02-23 11:07:55 +01:00
{
2005-05-29 10:03:01 +02:00
$conf_pw = md5 ( $conf_pw );
2004-02-23 11:07:55 +01:00
}
2005-05-29 10:03:01 +02:00
2005-05-16 02:42:05 +02:00
2005-05-29 10:03:01 +02:00
// Verify that $pw is not already encoded as md5
if ( ! preg_match ( '/^[0-9a-f]{32}$/' , $pw ))
{
$pw = md5 ( $pw );
}
2004-02-23 11:07:55 +01:00
return $pw == $conf_pw ;
2005-05-29 10:03:01 +02:00
2004-02-23 11:07:55 +01:00
}
2002-05-11 21:30:10 +02:00
function checkip ( $remoteip = '' )
{
2005-03-04 13:40:28 +01:00
//echo "<p>setup::checkip($remoteip) against setup_acl='".$GLOBALS['egw_info']['server']['setup_acl']."'</p>\n";
$allowed_ips = explode ( ',' , @ $GLOBALS [ 'egw_info' ][ 'server' ][ 'setup_acl' ]);
if ( empty ( $GLOBALS [ 'egw_info' ][ 'server' ][ 'setup_acl' ]) || ! is_array ( $allowed_ips ))
2002-05-11 21:30:10 +02:00
{
2004-05-04 11:51:17 +02:00
return True ; // no test
}
$remotes = explode ( '.' , $remoteip );
foreach ( $allowed_ips as $value )
{
if ( ! preg_match ( '/^[0-9.]+$/' , $value ))
2002-05-11 21:30:10 +02:00
{
2004-05-04 11:51:17 +02:00
$value = gethostbyname ( $was = $value ); // resolve domain-name, eg. a dyndns account
//echo "resolving '$was' to '$value'<br>\n";
}
$values = explode ( '.' , $value );
for ( $i = 0 ; $i < count ( $values ); ++ $i )
{
if (( int ) $values [ $i ] != ( int ) $remotes [ $i ])
2002-05-11 21:30:10 +02:00
{
2004-05-04 11:51:17 +02:00
break ;
2002-05-11 21:30:10 +02:00
}
}
2004-05-04 11:51:17 +02:00
if ( $i == count ( $values ))
2002-05-11 21:30:10 +02:00
{
2004-05-04 11:51:17 +02:00
return True ; // match
2002-05-11 21:30:10 +02:00
}
}
2005-03-04 13:40:28 +01:00
$GLOBALS [ 'egw_info' ][ 'setup' ][ 'HeaderLoginMSG' ] = '' ;
$GLOBALS [ 'egw_info' ][ 'setup' ][ 'ConfigLoginMSG' ] = lang ( 'Invalid IP address' );
2004-05-04 11:51:17 +02:00
return False ;
2002-05-11 21:30:10 +02:00
}
2005-03-24 14:15:12 +01:00
/**
* Return X . X . X major version from X . X . X . X versionstring
*
* @ param $
*/
2002-03-03 22:47:30 +01:00
function get_major ( $versionstring )
{
if ( ! $versionstring )
{
return False ;
}
2004-05-04 11:51:17 +02:00
2003-08-28 16:31:11 +02:00
$version = str_replace ( 'pre' , '.' , $versionstring );
2002-03-03 22:47:30 +01:00
$varray = explode ( '.' , $version );
$major = implode ( '.' , array ( $varray [ 0 ], $varray [ 1 ], $varray [ 2 ]));
return $major ;
}
2005-03-24 14:15:12 +01:00
/**
* Clear system / user level cache so as to have it rebuilt with the next access
*/
2002-03-03 22:47:30 +01:00
function clear_session_cache ()
{
2002-04-10 01:48:36 +02:00
$tables = Array ();
2002-04-17 13:58:09 +02:00
$tablenames = $this -> db -> table_names ();
2003-08-28 16:31:11 +02:00
foreach ( $tablenames as $key => $val )
2002-03-03 22:47:30 +01:00
{
$tables [] = $val [ 'table_name' ];
}
if ( in_array ( 'phpgw_app_sessions' , $tables ))
{
$this -> db -> lock ( array ( 'phpgw_app_sessions' ));
@ $this -> db -> query ( " DELETE FROM phpgw_app_sessions WHERE sessionid = '0' and loginid = '0' and app = 'phpgwapi' and location = 'config' " , __LINE__ , __FILE__ );
@ $this -> db -> query ( " DELETE FROM phpgw_app_sessions WHERE app = 'phpgwapi' and location = 'phpgw_info_cache' " , __LINE__ , __FILE__ );
$this -> db -> unlock ();
}
}
2005-03-24 14:15:12 +01:00
/**
* Add an application to the phpgw_applications table
*
* @ param $appname Application 'name' with a matching $setup_info [ $appname ] array slice
* @ param $enable * optional , set to True / False to override setup . inc . php setting
*/
2002-03-03 22:47:30 +01:00
function register_app ( $appname , $enable = 99 )
{
$setup_info = $GLOBALS [ 'setup_info' ];
if ( ! $appname )
{
return False ;
}
if ( $enable == 99 )
{
$enable = $setup_info [ $appname ][ 'enable' ];
}
2003-11-04 15:14:57 +01:00
$enable = ( int ) $enable ;
2002-03-03 22:47:30 +01:00
/*
2003-08-28 16:31:11 +02:00
Use old applications table if the currentver is less than 0.9 . 10 pre8 ,
but not if the currentver = '' , which probably means new install .
2002-03-03 22:47:30 +01:00
*/
if ( $this -> alessthanb ( $setup_info [ 'phpgwapi' ][ 'currentver' ], '0.9.10pre8' ) && ( $setup_info [ 'phpgwapi' ][ 'currentver' ] != '' ))
{
2004-09-18 16:55:02 +02:00
$this -> applications_table = 'applications' ;
2002-03-03 22:47:30 +01:00
}
if ( $GLOBALS [ 'DEBUG' ])
{
echo '<br>register_app(): ' . $appname . ', version: ' . $setup_info [ $appname ][ 'version' ] . ', table: ' . $appstbl . '<br>' ;
// _debug_array($setup_info[$appname]);
}
if ( $setup_info [ $appname ][ 'version' ])
{
if ( $setup_info [ $appname ][ 'tables' ])
{
$tables = implode ( ',' , $setup_info [ $appname ][ 'tables' ]);
}
2003-08-28 16:31:11 +02:00
if ( $setup_info [ $appname ][ 'tables_use_prefix' ] == True )
{
2004-09-18 16:55:02 +02:00
if ( $GLOBALS [ 'DEBUG' ])
{
echo " <br> $appname uses tables_use_prefix, storing " . $setup_info [ $appname ][ 'tables_prefix' ] . " as prefix for tables \n " ;
}
$this -> db -> insert ( $this -> config_table , array (
'config_app' => $appname ,
'config_name' => $appname . '_tables_prefix' ,
'config_value' => $setup_info [ $appname ][ 'tables_prefix' ],
), False , __LINE__ , __FILE__ );
2003-08-28 16:31:11 +02:00
}
2004-09-18 16:55:02 +02:00
$this -> db -> insert ( $this -> applications_table , array (
'app_name' => $appname ,
'app_enabled' => $enable ,
'app_order' => $setup_info [ $appname ][ 'app_order' ],
'app_tables' => $tables ,
'app_version' => $setup_info [ $appname ][ 'version' ],
), False , __LINE__ , __FILE__ );
2002-03-03 22:47:30 +01:00
$this -> clear_session_cache ();
}
}
2005-03-24 14:15:12 +01:00
/**
* Check if an application has info in the db
*
* @ param $appname Application 'name' with a matching $setup_info [ $appname ] array slice
* @ param $enabled optional , set to False to not enable this app
*/
2002-03-03 22:47:30 +01:00
function app_registered ( $appname )
{
$setup_info = $GLOBALS [ 'setup_info' ];
if ( ! $appname )
{
return False ;
}
if ( $this -> alessthanb ( $setup_info [ 'phpgwapi' ][ 'currentver' ], '0.9.10pre8' ) && ( $setup_info [ 'phpgwapi' ][ 'currentver' ] != '' ))
{
2004-09-18 16:55:02 +02:00
$this -> applications_table = 'applications' ;
2002-03-03 22:47:30 +01:00
}
if ( @ $GLOBALS [ 'DEBUG' ])
{
2004-09-18 16:55:02 +02:00
echo '<br>app_registered(): checking ' . $appname . ', table: ' . $this -> applications_table ;
2002-03-03 22:47:30 +01:00
// _debug_array($setup_info[$appname]);
}
2004-09-18 16:55:02 +02:00
$this -> db -> select ( $this -> applications_table , 'COUNT(*)' , array ( 'app_name' => $appname ), __LINE__ , __FILE__ );
2002-03-03 22:47:30 +01:00
$this -> db -> next_record ();
if ( $this -> db -> f ( 0 ))
{
if ( @ $GLOBALS [ 'DEBUG' ])
{
echo '... app previously registered.' ;
}
return True ;
}
if ( @ $GLOBALS [ 'DEBUG' ])
{
echo '... app not registered' ;
}
return False ;
}
2005-03-24 14:15:12 +01:00
/**
* Update application info in the db
*
* @ param $appname Application 'name' with a matching $setup_info [ $appname ] array slice
* @ param $enabled optional , set to False to not enable this app
*/
2002-03-03 22:47:30 +01:00
function update_app ( $appname )
{
$setup_info = $GLOBALS [ 'setup_info' ];
if ( ! $appname )
{
return False ;
}
if ( $this -> alessthanb ( $setup_info [ 'phpgwapi' ][ 'currentver' ], '0.9.10pre8' ) && ( $setup_info [ 'phpgwapi' ][ 'currentver' ] != '' ))
{
2004-09-18 16:55:02 +02:00
$this -> applications_table = 'applications' ;
2002-03-03 22:47:30 +01:00
}
if ( $GLOBALS [ 'DEBUG' ])
{
2004-09-18 16:55:02 +02:00
echo '<br>update_app(): ' . $appname . ', version: ' . $setup_info [ $appname ][ 'currentver' ] . ', table: ' . $this -> applications_table . '<br>' ;
2002-03-03 22:47:30 +01:00
// _debug_array($setup_info[$appname]);
}
2004-09-18 16:55:02 +02:00
if ( ! $this -> app_registered ( $appname ))
2002-03-03 22:47:30 +01:00
{
return False ;
}
if ( $setup_info [ $appname ][ 'version' ])
{
//echo '<br>' . $setup_info[$appname]['version'];
if ( $setup_info [ $appname ][ 'tables' ])
{
$tables = implode ( ',' , $setup_info [ $appname ][ 'tables' ]);
}
2004-09-18 16:55:02 +02:00
$this -> db -> update ( $this -> applications_table , array (
'app_enabled' => $setup_info [ $appname ][ 'enable' ],
'app_order' => $setup_info [ $appname ][ 'app_order' ],
'app_tables' => $tables ,
'app_version' => $setup_info [ $appname ][ 'version' ],
), array ( 'app_name' => $appname ), __LINE__ , __FILE__ );
2002-03-03 22:47:30 +01:00
}
}
2005-03-24 14:15:12 +01:00
/**
* Update application version in applications table , post upgrade
*
* @ param $setup_info * Array of application information ( multiple apps or single )
* @ param $appname * Application 'name' with a matching $setup_info [ $appname ] array slice
* @ param $tableschanged ? ? ?
*/
2002-03-03 22:47:30 +01:00
function update_app_version ( $setup_info , $appname , $tableschanged = True )
{
if ( ! $appname )
{
return False ;
}
if ( $this -> alessthanb ( $setup_info [ 'phpgwapi' ][ 'currentver' ], '0.9.10pre8' ) && ( $setup_info [ 'phpgwapi' ][ 'currentver' ] != '' ))
{
2004-09-18 16:55:02 +02:00
$this -> applications_table = 'applications' ;
2002-03-03 22:47:30 +01:00
}
if ( $tableschanged == True )
{
2005-03-04 13:40:28 +01:00
$GLOBALS [ 'egw_info' ][ 'setup' ][ 'tableschanged' ] = True ;
2002-03-03 22:47:30 +01:00
}
if ( $setup_info [ $appname ][ 'currentver' ])
{
2004-09-18 16:55:02 +02:00
$this -> db -> update ( $this -> applications_table , array (
'app_version' => $setup_info [ $appname ][ 'currentver' ],
), array ( 'app_name' => $appname ), __LINE__ , __FILE__ );
2002-03-03 22:47:30 +01:00
}
return $setup_info ;
}
2005-03-24 14:15:12 +01:00
/**
* de - Register an application
*
* @ param $appname Application 'name' with a matching $setup_info [ $appname ] array slice
*/
2002-03-03 22:47:30 +01:00
function deregister_app ( $appname )
{
if ( ! $appname )
{
return False ;
}
$setup_info = $GLOBALS [ 'setup_info' ];
if ( $this -> alessthanb ( $setup_info [ 'phpgwapi' ][ 'currentver' ], '0.9.10pre8' ) && ( $setup_info [ 'phpgwapi' ][ 'currentver' ] != '' ))
{
2004-09-18 16:55:02 +02:00
$this -> applications_table = 'applications' ;
2002-03-03 22:47:30 +01:00
}
//echo 'DELETING application: ' . $appname;
2004-09-18 16:55:02 +02:00
$this -> db -> delete ( $this -> applications_table , array ( 'app_name' => $appname ), __LINE__ , __FILE__ );
2002-03-03 22:47:30 +01:00
$this -> clear_session_cache ();
}
2005-03-24 14:15:12 +01:00
/**
* Register an application ' s hooks
*
* @ param $appname Application 'name' with a matching $setup_info [ $appname ] array slice
*/
2002-03-03 22:47:30 +01:00
function register_hooks ( $appname )
{
$setup_info = $GLOBALS [ 'setup_info' ];
if ( ! $appname )
{
return False ;
}
if ( $this -> alessthanb ( $setup_info [ 'phpgwapi' ][ 'currentver' ], '0.9.8pre5' ) && ( $setup_info [ 'phpgwapi' ][ 'currentver' ] != '' ))
{
/* No phpgw_hooks table yet. */
return False ;
}
2003-04-28 00:26:04 +02:00
if ( ! is_object ( $this -> hooks ))
2002-03-03 22:47:30 +01:00
{
2005-03-24 14:15:12 +01:00
$this -> hooks =& CreateObject ( 'phpgwapi.hooks' , $this -> db );
2002-03-03 22:47:30 +01:00
}
2003-04-28 00:26:04 +02:00
$this -> hooks -> register_hooks ( $appname , $setup_info [ $appname ][ 'hooks' ]);
2002-03-03 22:47:30 +01:00
}
2005-03-24 14:15:12 +01:00
/**
* Update an application ' s hooks
*
* @ param $appname Application 'name' with a matching $setup_info [ $appname ] array slice
*/
2002-03-03 22:47:30 +01:00
function update_hooks ( $appname )
{
2003-04-28 00:26:04 +02:00
$this -> register_hooks ( $appname );
2002-03-03 22:47:30 +01:00
}
2005-03-24 14:15:12 +01:00
/**
* de - Register an application ' s hooks
*
* @ param $appname Application 'name' with a matching $setup_info [ $appname ] array slice
*/
2002-03-03 22:47:30 +01:00
function deregister_hooks ( $appname )
{
if ( $this -> alessthanb ( $setup_info [ 'phpgwapi' ][ 'currentver' ], '0.9.8pre5' ))
{
/* No phpgw_hooks table yet. */
return False ;
}
if ( ! $appname )
{
return False ;
}
2003-04-28 00:26:04 +02:00
2002-03-03 22:47:30 +01:00
//echo "DELETING hooks for: " . $setup_info[$appname]['name'];
2003-04-28 00:26:04 +02:00
if ( ! is_object ( $this -> hooks ))
{
2005-03-24 14:15:12 +01:00
$this -> hooks =& CreateObject ( 'phpgwapi.hooks' , $this -> db );
2003-04-28 00:26:04 +02:00
}
$this -> hooks -> register_hooks ( $appname );
2002-03-03 22:47:30 +01:00
}
2005-03-24 14:15:12 +01:00
/**
* call the hooks for a single application
*
* @ param $location hook location - required
* @ param $appname application name - optional
*/
2002-03-03 22:47:30 +01:00
function hook ( $location , $appname = '' )
{
2003-04-28 00:26:04 +02:00
if ( ! is_object ( $this -> hooks ))
2002-03-03 22:47:30 +01:00
{
2005-03-24 14:15:12 +01:00
$this -> hooks =& CreateObject ( 'phpgwapi.hooks' , $this -> db );
2002-03-03 22:47:30 +01:00
}
2003-04-28 10:25:59 +02:00
return $this -> hooks -> single ( $location , $appname , True , True );
2002-03-03 22:47:30 +01:00
}
2005-03-24 14:15:12 +01:00
/**
* egw version checking , is param 1 < param 2 in phpgw versionspeak ?
* @ param $a phpgw version number to check if less than $b
* @ param $b phpgw version number to check $a against
* @ return True if $a < $b
*/
2002-03-03 22:47:30 +01:00
function alessthanb ( $a , $b , $DEBUG = False )
{
$num = array ( '1st' , '2nd' , '3rd' , '4th' );
if ( $DEBUG )
{
echo '<br>Input values: '
. 'A="' . $a . '", B="' . $b . '"' ;
}
2003-11-04 15:14:57 +01:00
$newa = str_replace ( 'pre' , '.' , $a );
$newb = str_replace ( 'pre' , '.' , $b );
2002-03-03 22:47:30 +01:00
$testa = explode ( '.' , $newa );
if ( @ $testa [ 1 ] == '' )
{
$testa [ 1 ] = 0 ;
}
2004-07-10 12:56:09 +02:00
2002-03-03 22:47:30 +01:00
$testb = explode ( '.' , $newb );
if ( @ $testb [ 1 ] == '' )
{
$testb [ 1 ] = 0 ;
}
if ( @ $testb [ 3 ] == '' )
{
$testb [ 3 ] = 0 ;
}
$less = 0 ;
for ( $i = 0 ; $i < count ( $testa ); $i ++ )
{
2003-11-04 15:14:57 +01:00
if ( $DEBUG ) { echo '<br>Checking if ' . ( int ) $testa [ $i ] . ' is less than ' . ( int ) $testb [ $i ] . ' ...' ; }
if (( int ) $testa [ $i ] < ( int ) $testb [ $i ])
2002-03-03 22:47:30 +01:00
{
if ( $DEBUG ) { echo ' yes.' ; }
$less ++ ;
if ( $i < 3 )
{
/* Ensure that this is definitely smaller */
if ( $DEBUG ) { echo " This is the $num[$i] octet, so A is definitely less than B. " ; }
$less = 5 ;
break ;
}
}
2003-11-04 15:14:57 +01:00
elseif (( int ) $testa [ $i ] > ( int ) $testb [ $i ])
2002-03-03 22:47:30 +01:00
{
if ( $DEBUG ) { echo ' no.' ; }
$less -- ;
if ( $i < 2 )
{
/* Ensure that this is definitely greater */
if ( $DEBUG ) { echo " This is the $num[$i] octet, so A is definitely greater than B. " ; }
$less = - 5 ;
break ;
}
}
else
{
2004-07-10 12:56:09 +02:00
if ( $DEBUG ) { echo ' no, they are equal or of different length.' ; }
// makes sure eg. '1.0.0' is counted less the '1.0.0.xxx' !
$less = count ( $testa ) < count ( $testb ) ? 1 : 0 ;
2002-03-03 22:47:30 +01:00
}
}
if ( $DEBUG ) { echo '<br>Check value is: "' . $less . '"' ; }
if ( $less > 0 )
{
if ( $DEBUG ) { echo '<br>A is less than B' ; }
return True ;
}
elseif ( $less < 0 )
{
if ( $DEBUG ) { echo '<br>A is greater than B' ; }
return False ;
}
else
{
if ( $DEBUG ) { echo '<br>A is equal to B' ; }
return False ;
}
}
2005-03-24 14:15:12 +01:00
/**
* egw version checking , is param 1 > param 2 in phpgw versionspeak ?
*
* @ param $a phpgw version number to check if more than $b
* @ param $b phpgw version number to check $a against
* @ return True if $a < $b
*/
2002-03-03 22:47:30 +01:00
function amorethanb ( $a , $b , $DEBUG = False )
{
$num = array ( '1st' , '2nd' , '3rd' , '4th' );
if ( $DEBUG )
{
echo '<br>Input values: '
. 'A="' . $a . '", B="' . $b . '"' ;
}
2003-11-04 15:14:57 +01:00
$newa = str_replace ( 'pre' , '.' , $a );
$newb = str_replace ( 'pre' , '.' , $b );
2002-03-03 22:47:30 +01:00
$testa = explode ( '.' , $newa );
if ( $testa [ 3 ] == '' )
{
$testa [ 3 ] = 0 ;
}
$testb = explode ( '.' , $newb );
if ( $testb [ 3 ] == '' )
{
$testb [ 3 ] = 0 ;
}
$less = 0 ;
for ( $i = 0 ; $i < count ( $testa ); $i ++ )
{
2003-11-04 15:14:57 +01:00
if ( $DEBUG ) { echo '<br>Checking if ' . ( int ) $testa [ $i ] . ' is more than ' . ( int ) $testb [ $i ] . ' ...' ; }
if (( int ) $testa [ $i ] > ( int ) $testb [ $i ])
2002-03-03 22:47:30 +01:00
{
if ( $DEBUG ) { echo ' yes.' ; }
$less ++ ;
if ( $i < 3 )
{
/* Ensure that this is definitely greater */
if ( $DEBUG ) { echo " This is the $num[$i] octet, so A is definitely greater than B. " ; }
$less = 5 ;
break ;
}
}
2003-11-04 15:14:57 +01:00
elseif (( int ) $testa [ $i ] < ( int ) $testb [ $i ])
2002-03-03 22:47:30 +01:00
{
if ( $DEBUG ) { echo ' no.' ; }
$less -- ;
if ( $i < 2 )
{
/* Ensure that this is definitely smaller */
if ( $DEBUG ) { echo " This is the $num[$i] octet, so A is definitely less than B. " ; }
$less = - 5 ;
break ;
}
}
else
{
if ( $DEBUG ) { echo ' no, they are equal.' ; }
$less = 0 ;
}
}
if ( $DEBUG ) { echo '<br>Check value is: "' . $less . '"' ; }
if ( $less > 0 )
{
if ( $DEBUG ) { echo '<br>A is greater than B' ; }
return True ;
}
elseif ( $less < 0 )
{
if ( $DEBUG ) { echo '<br>A is less than B' ; }
return False ;
}
else
{
if ( $DEBUG ) { echo '<br>A is equal to B' ; }
return False ;
}
}
2003-09-11 20:13:49 +02:00
function get_hooks_table_name ()
{
2003-11-04 15:14:57 +01:00
if ( @ $this -> alessthanb ( $GLOBALS [ 'setup_info' ][ 'phpgwapi' ][ 'currentver' ], '0.9.8pre5' ) &&
@ $GLOBALS [ 'setup_info' ][ 'phpgwapi' ][ 'currentver' ] != '' )
2003-08-28 16:31:11 +02:00
{
/* No phpgw_hooks table yet. */
return False ;
}
2003-09-11 20:13:49 +02:00
return 'phpgw_hooks' ;
}
2003-12-29 22:05:06 +01:00
function setup_account_object ()
{
2005-03-04 13:40:28 +01:00
if ( ! is_object ( $GLOBALS [ 'egw' ] -> accounts ))
2003-12-29 22:05:06 +01:00
{
if ( ! is_object ( $this -> db ))
{
$this -> loaddb ();
}
/* Load up some configured values */
2004-02-05 02:35:53 +01:00
$this -> db -> query ( " SELECT config_name,config_value FROM phpgw_config "
. " WHERE config_name LIKE 'ldap%' OR config_name LIKE 'account_%' OR config_name LIKE '%encryption%' " , __LINE__ , __FILE__ );
while ( $this -> db -> next_record ())
2003-12-29 22:05:06 +01:00
{
2005-03-04 13:40:28 +01:00
$GLOBALS [ 'egw_info' ][ 'server' ][ $this -> db -> f ( 'config_name' )] = $this -> db -> f ( 'config_value' );
2003-12-29 22:05:06 +01:00
}
2005-07-20 14:46:59 +02:00
//if (!is_object($GLOBALS['egw']))
2003-12-29 22:05:06 +01:00
{
2005-07-20 14:46:59 +02:00
$GLOBALS [ 'egw' ] =& new egw_dummy ();
2005-03-24 14:15:12 +01:00
$GLOBALS [ 'phpgw' ] =& $GLOBALS [ 'egw' ];
2003-12-29 22:05:06 +01:00
}
2005-03-24 14:15:12 +01:00
$GLOBALS [ 'egw' ] -> db = clone ( $this -> db );
$GLOBALS [ 'egw' ] -> common =& CreateObject ( 'phpgwapi.common' );
$GLOBALS [ 'egw' ] -> accounts =& CreateObject ( 'phpgwapi.accounts' );
2003-12-29 22:05:06 +01:00
2005-03-04 13:40:28 +01:00
if (( $GLOBALS [ 'egw_info' ][ 'server' ][ 'account_repository' ] == 'ldap' ) &&
! $GLOBALS [ 'egw' ] -> accounts -> ds )
2003-12-29 22:05:06 +01:00
{
2005-03-04 13:40:28 +01:00
printf ( " <b>Error: Error connecting to LDAP server %s!</b><br> " , $GLOBALS [ 'egw_info' ][ 'server' ][ 'ldap_host' ]);
2003-12-29 22:05:06 +01:00
exit ;
}
}
}
2005-03-24 14:15:12 +01:00
/**
* add an user account or a user group
*
* if the $username already exists , only the id is returned , no new user / group gets created
*
* @ param username string alphanumerical username or groupname ( account_lid )
* @ param first , last string first / last name
* @ param $passwd string cleartext pw
* @ param $group string / boolean Groupname for users primary group or False for a group , default 'Default'
* @ param $changepw boolean user has right to change pw , default False
* @ return the numerical user - id
*/
2003-12-29 22:05:06 +01:00
function add_account ( $username , $first , $last , $passwd , $group = 'default' , $changepw = False )
{
$this -> setup_account_object ();
2005-03-04 13:40:28 +01:00
$groupid = $group ? $GLOBALS [ 'egw' ] -> accounts -> name2id ( $group ) : False ;
2003-12-29 22:05:06 +01:00
2005-03-04 13:40:28 +01:00
if ( ! ( $accountid = $GLOBALS [ 'egw' ] -> accounts -> name2id ( $username )))
2003-12-29 22:05:06 +01:00
{
2005-03-04 13:40:28 +01:00
$accountid = $accountid ? $accountid : $GLOBALS [ 'egw' ] -> accounts -> create ( array (
2003-12-29 22:05:06 +01:00
'account_type' => $group ? 'u' : 'g' ,
'account_lid' => $username ,
'account_passwd' => $passwd ,
'account_firstname' => $first ,
'account_lastname' => $last ,
'account_status' => 'A' ,
'account_primary_group' => $groupid ,
'account_expires' => - 1
));
}
2004-01-26 10:21:47 +01:00
$accountid = ( int ) $accountid ;
2004-01-26 04:26:11 +01:00
if ( $groupid )
2003-12-29 22:05:06 +01:00
{
2004-01-26 10:21:47 +01:00
$this -> add_acl ( 'phpgw_group' ,( int ) $groupid , $accountid );
2003-12-29 22:05:06 +01:00
}
2004-01-26 10:21:47 +01:00
$this -> add_acl ( 'preferences' , 'changepassword' , $accountid ,( int ) $changepw );
2003-12-29 22:05:06 +01:00
return $accountid ;
}
2005-03-24 14:15:12 +01:00
/**
* Add ACL rights
*
* @ param $app string / array with app - names
* @ param $locations string eg . run
* @ param $account int / string accountid or account_lid
* @ param $rights int rights to set , default 1
*/
2003-12-29 22:05:06 +01:00
function add_acl ( $apps , $location , $account , $rights = 1 )
{
if ( ! is_int ( $account ))
{
$this -> setup_account_object ();
2005-03-04 13:40:28 +01:00
$account = $GLOBALS [ 'egw' ] -> accounts -> name2id ( $account );
2003-12-29 22:05:06 +01:00
}
2004-01-26 09:56:11 +01:00
$rights = ( int ) $rights ;
2004-02-05 02:35:53 +01:00
if ( ! is_object ( $this -> db ))
{
$this -> loaddb ();
}
2003-12-29 22:05:06 +01:00
2004-02-05 02:35:53 +01:00
if ( ! is_array ( $apps ))
{
$apps = array ( $apps );
}
2003-12-29 22:05:06 +01:00
foreach ( $apps as $app )
{
2004-04-03 15:01:28 +02:00
$this -> db -> query ( " DELETE FROM phpgw_acl WHERE acl_appname=' $app ' AND acl_location=' $location ' AND acl_account= $account " );
2004-02-23 14:22:59 +01:00
if ( $rights )
{
$this -> db -> query ( " INSERT INTO phpgw_acl(acl_appname,acl_location,acl_account,acl_rights) VALUES(' $app ',' $location ', $account , $rights ) " );
}
2003-12-29 22:05:06 +01:00
}
}
2002-03-03 22:47:30 +01:00
}
?>