diff --git a/doc/rpm-build/rpm_post_install.php b/doc/rpm-build/rpm_post_install.php new file mode 100755 index 0000000000..81307df5b2 --- /dev/null +++ b/doc/rpm-build/rpm_post_install.php @@ -0,0 +1,245 @@ +#!/usr/bin/php +rpm_post_install.php must NOT be called as web-page --> exiting !!!'); +} +$verbose = false; +$config = array( + 'php' => '/usr/bin/php', + 'source_dir' => '/usr/share/egroupware', + 'data_dir' => '/var/lib/egroupware', + 'header' => '/var/lib/egroupware/header.inc.php', // symlinked to source_dir by rpm + 'setup-cli' => '/usr/share/egroupware/setup/setup-cli.php', + 'domain' => 'default', + 'config_user' => 'admin', + 'config_passwd' => randomstring(), + 'db_type' => 'mysql', + 'db_host' => 'localhost', + 'db_port' => 3306, + 'db_name' => 'egroupware', + 'db_user' => 'egroupware', + 'db_pass' => randomstring(), + 'db_grant_host' => 'localhost', + 'db_root' => 'root', // mysql root user/pw to create database + 'db_root_pw' => '', + 'backup' => '', + 'admin_user' => 'sysop', + 'admin_passwd'=> randomstring(), + 'lang' => 'en', // languages for admin user and extra lang to install + 'charset' => 'utf-8', + 'start_db' => '/etc/init.d/mysqld', + 'autostart_db' => '/sbin/chkconfig --level 3 mysqld on', + 'start_webserver' => '/etc/init.d/httpd', + 'autostart_webserver' => '/sbin/chkconfig --level 3 httpd on', +); +// read language from LANG enviroment variable +if (($lang = $_ENV['LANG'])) +{ + list($lang,$nat) = split('[_.]',$lang); + if (in_array($lang.'-'.strtolower($nat),array('es-es','pt-br','zh-tw'))) + { + $lang .= '-'.strtolower($nat); + } + $config['lang'] = $lang; +} +// read config from command line +$argv = $_SERVER['argv']; +$prog = array_shift($argv); + +while(($arg = array_shift($argv))) +{ + if ($arg == '-v' || $arg == '--verbose') + { + $verbose = true; + } + elseif($arg == '-h' || $arg == '--help') + { + usage(); + } + elseif(substr($arg,0,2) == '--' && isset($config[$name=substr($arg,2)])) + { + $config[$name] = array_shift($argv); + } + else + { + usage("Unknown argument '$arg'!"); + } +} +// basic config checks +foreach(array('php','source_dir','data_dir','setup-cli') as $name) +{ + if (!file_exists($config[$name])) bail_out(1,$config[$name].' not found!'); +} +$setup_cli = $config['php'].' '.$config['setup-cli']; + +if (!file_exists($config['header']) || filesize($config['header']) < 200) // default header redirecting to setup is 147 bytes +{ + // --> new install + + // create header + @unlink($config['header']); // remove redirect header, setup-cli stalls otherwise + $setup_header = $setup_cli.' --create-header '.escapeshellarg($config['config_passwd'].','.$config['config_user']). + ' --domain '.escapeshellarg($config['domain'].','.$config['db_name'].','.$config['db_user'].','.$config['db_pass']. + ','.$config['db_type'].','.$config['db_host'].','.$config['db_port']); + run_cmd($setup_header); + + // check for localhost if database server is started and start it (permanent) if not + if ($config['db_host'] == 'localhost' && file_exists($config['start_db'])) + { + if (exec($config['start_db'].' status',$dummy,$ret) && $ret) + { + system($config['start_db'].' start'); + system($config['autostart_db']); + } + } + // create database + $setup_db = $setup_cli.' --setup-cmd-database sub_command=create_db'; + foreach(array('domain','db_type','db_host','db_port','db_name','db_user','db_pass','db_root','db_root_pw','db_grant_host') as $name) + { + $setup_db .= ' '.escapeshellarg($name.'='.$config[$name]); + } + run_cmd($setup_db); + + // install egroupware + $setup_install = $setup_cli.' --install '.escapeshellarg($config['domain'].','.$config['config_user'].','.$config['config_passwd'].','.$config['backup'].','.$config['charset'].','.$config['lang']); + run_cmd($setup_install); + + if ($config['data_dir'] != '/var/lib/egroupware') + { + // set files dir different from default + $setup_config = $setup_cli.' --config '.escapeshellarg($config['domain'].','.$config['config_user'].','.$config['config_passwd']). + ' --files-dir '.escapeshellarg($config['data_dir'].'/files').' --backup-dir '.escapeshellarg($config['data_dir'].'/backup'); + run_cmd($setup_config); + } + + // create first user + $setup_admin = $setup_cli.' --admin '.escapeshellarg($config['domain'].','.$config['config_user'].','.$config['config_passwd'].','. + $config['admin_user'].','.$config['admin_passwd'].',,,,'.$config['lang']); + run_cmd($setup_admin); + + // check if webserver is started and start it (permanent) if not + if (file_exists($config['start_webserver'])) + { + if (exec($config['start_webserver'].' status',$dummy,$ret) && $ret) + { + system($config['start_webserver'].' start'); + system($config['autostart_webserver']); + } + } + echo "\n"; + echo "EGroupware successful installed\n"; + echo "===============================\n"; + echo "\n"; + echo "Please note the following user names and passwords:\n"; + echo "\n"; + echo "Setup username: $config[config_user]\n"; + echo " password: $config[config_passwd]\n"; + echo "\n"; + echo "EGroupware username: $config[admin_user]\n"; + echo " password: $config[admin_passwd]\n"; + echo "\n"; + echo "You can log into EGroupware by pointing your browser to http://localhost/egroupware/\n"; + echo "Please replace localhost with the appropriate hostname, if you connect remote.\n\n"; + + if (empty($config['db_root_pw'])) + { + echo "*** Database has no root password set, please fix that immediatly: mysqladmin -u root password NEWPASSWORD\n\n"; + } +} +else +{ + // --> existing install --> update + + // get user from header and replace password, as we dont know it + $header = file_get_contents($config['header']); + if (!preg_match('/'.preg_quote("\$GLOBALS['egw_info']['server']['header_admin_user'] = '")."([^']+)';/m",$header,$matches)) + { + bail_out(1,$config['header']." is no regular EGroupware header.inc.php!"); + } + $tmp_header= preg_replace('/'.preg_quote("\$GLOBALS['egw_info']['server']['header_admin_password'] = '")."([^']+)';/m", + "\$GLOBALS['egw_info']['server']['header_admin_password'] = '".$config['config_passwd']."';",$header); + file_put_contents($config['header'],$tmp_header); + + // update egroupware + $setup_update = $setup_cli.' --update '.escapeshellarg('all,'.$config['config_user'].','.$config['config_passwd']); + run_cmd($setup_update); + + // restore original header + file_put_contents($config['header'],$header); + + echo "EGroupware successful updated\n"; +} + +function run_cmd($cmd,array &$output=null) +{ + global $verbose; + + if ($verbose) + { + echo $cmd."\n"; + system($cmd,$ret); + } + else + { + $output[] = $cmd; + exec($cmd,$output,$ret); + } + if ($ret) bail_out($ret,$verbose?null:$output); +} + +function bail_out($ret=1,$output=null) +{ + if ($output) echo implode("\n",(array)$output); + echo "\n\nInstallation failed --> exiting!\n\n"; + exit($ret); +} + +/** + * Return a rand string, eg. to generate passwords + * + * @param int $len=16 + * @return string + */ +function randomstring($len=16) +{ + static $usedchars = array( + '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f', + 'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v', + 'w','x','y','z','A','B','C','D','E','F','G','H','I','J','K','L', + 'M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z', + '@','!','$','%','&','/','(',')','=','?',';',':','#','_','-','<', + '>','|','{','[',']','}', // dont add \,'" as we have problems dealing with them + ); + + $str = ''; + for($i=0; $i < $len; $i++) + { + $str .= $usedchars[mt_rand(0,count($usedchars)-1)]; + } + return $str; +} + +function usage($error=null) +{ + global $prog,$config; + + echo "Usage: $prog [-h|--help] [-v|--verbose] [options, ...]\n\n"; + echo "options and their defaults:\n"; + foreach($config as $name => $default) + { + if (in_array($name,array('config_passwd','db_pass','admin_passwd'))) $default = '<16 char random string>'; + echo '--'.str_pad($name,20).$default."\n"; + } + if ($error) echo "$error\n\n"; + exit(1); +} diff --git a/phpgwapi/inc/class.egw.inc.php b/phpgwapi/inc/class.egw.inc.php index cd4a637ae4..8c2e3fa349 100644 --- a/phpgwapi/inc/class.egw.inc.php +++ b/phpgwapi/inc/class.egw.inc.php @@ -555,7 +555,7 @@ class egw_minimal if (!isset(self::$sub_objects[$name]) && !class_exists($name)) { - error_log(__METHOD__.": There's NO $name object! ".function_backtrace()); + if ($name != 'ADOdb') error_log(__METHOD__.": There's NO $name object! ".function_backtrace()); return null; } switch($name) diff --git a/phpgwapi/inc/class.egw_cache.inc.php b/phpgwapi/inc/class.egw_cache.inc.php index b71ff4bd46..8d4b77e49e 100644 --- a/phpgwapi/inc/class.egw_cache.inc.php +++ b/phpgwapi/inc/class.egw_cache.inc.php @@ -444,9 +444,10 @@ class egw_cache * Get a system configuration, even if in setup and it's not read * * @param string $name - * @return mixed + * @param boolean $throw=true throw an exception, if we can't retriev the value + * @return string|boolean string with config or false if not found and !$throw */ - static protected function get_system_config($name) + static protected function get_system_config($name,$throw=true) { if(!isset($GLOBALS['egw_info']['server'][$name])) { @@ -457,7 +458,7 @@ class egw_cache 'config_name' => $name, ),__LINE__,__FILE__)->fetchColumn(); } - if (!$GLOBALS['egw_info']['server'][$name]) + if (!$GLOBALS['egw_info']['server'][$name] && $throw) { throw new Exception (__METHOD__."($name) \$GLOBALS['egw_info']['server']['$name'] is NOT set!"); } @@ -484,7 +485,7 @@ class egw_cache case self::TREE: $bases[$level] = $level.'-'.str_replace(array(':','/','\\'),'-',EGW_SERVER_ROOT); // add charset to key, if not utf-8 (as everything we store depends on charset!) - if (($charset = self::get_system_config('system_charset')) && $charset != 'utf-8') + if (($charset = self::get_system_config('system_charset',false)) && $charset != 'utf-8') { $bases[$level] .= '-'.$charset; } diff --git a/phpgwapi/inc/common_functions.inc.php b/phpgwapi/inc/common_functions.inc.php index 3d49d1c346..547103584e 100755 --- a/phpgwapi/inc/common_functions.inc.php +++ b/phpgwapi/inc/common_functions.inc.php @@ -1441,21 +1441,24 @@ function egw_exception_handler(Exception $e) { $headline = try_lang('An error happend'); } + // exception handler for cli (command line interface) clients, no html, no logging + if(!isset($_SERVER['HTTP_HOST']) || $GLOBALS['egw_info']['flags']['no_exception_handler'] == 'cli') + { + echo ($headline ? $headline.': ' : '').$e->getMessage()."\n"; + if ($GLOBALS['egw_info']['server']['exception_show_trace']) + { + echo $e->getTraceAsString()."\n"; + } + exit($e->getCode() ? $e->getCode() : 9999); // allways give a non-zero exit code + } // logging all exceptions to the error_log error_log($headline.': '.$e->getMessage()); foreach(explode("\n",$e->getTraceAsString()) as $line) error_log($line); error_log('# Instance='.$GLOBALS['egw_info']['user']['domain'].', User='.$GLOBALS['egw_info']['user']['account_lid'].', URL='. ($_SERVER['HTTPS']?'https://':'http://').$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']); - // exception handler for cli (command line interface) clients, no html - if(!isset($_SERVER['HTTP_HOST']) || $GLOBALS['egw_info']['flags']['no_exception_handler'] == 'cli') - { - echo ($headline ? $headline.': ' : '').$e->getMessage()."\n"; - if (!($e instanceof egw_exception_wrong_userinput)) echo $e->getTraceAsString()."\n"; - exit($e->getCode() ? $e->getCode() : 9999); // allways give a non-zero exit code - } // regular GUI exception - elseif (!isset($GLOBALS['egw_info']['flags']['no_exception_handler'])) + if (!isset($GLOBALS['egw_info']['flags']['no_exception_handler'])) { $message = '

'.$headline."

\n". '
'.$e->getMessage()."\n\n";
diff --git a/setup/inc/class.setup_cmd.inc.php b/setup/inc/class.setup_cmd.inc.php
index 0b68a14a65..82d2bfe0db 100644
--- a/setup/inc/class.setup_cmd.inc.php
+++ b/setup/inc/class.setup_cmd.inc.php
@@ -25,7 +25,7 @@ abstract class setup_cmd extends admin_cmd
 	/**
 	 * Should be called by every command usually requiring header admin rights
 	 *
-	 * @throws Exception(lang('Wrong credentials to access the header.inc.php file!'),2);
+	 * @throws egw_exception_no_permission(lang('Wrong credentials to access the header.inc.php file!'),2);
 	 */
 	protected function _check_header_access()
 	{
@@ -41,7 +41,7 @@ abstract class setup_cmd extends admin_cmd
 		if ($this->header_secret != $secret)
 		{
 			//echo "_check_header_access: header_secret='$this->header_secret' != '$secret'=_calc_header_secret({$GLOBALS['egw_info']['server']['header_admin_user']},{$GLOBALS['egw_info']['server']['header_admin_password']})\n";
-			throw new Exception (lang('Wrong credentials to access the header.inc.php file!'),2);
+			throw new egw_exception_no_permission(lang('Wrong credentials to access the header.inc.php file!'),2);
 		}
 
 	}
diff --git a/setup/inc/class.setup_cmd_header.inc.php b/setup/inc/class.setup_cmd_header.inc.php
index 03de2cf75c..a934fa4c2c 100644
--- a/setup/inc/class.setup_cmd_header.inc.php
+++ b/setup/inc/class.setup_cmd_header.inc.php
@@ -48,9 +48,8 @@ class setup_cmd_header extends setup_cmd
 		//echo __CLASS__.'::__construct()'; _debug_array($domain);
 		admin_cmd::__construct($sub_command);
 
-		// header is 2 levels lower then this command in setup/inc
-		$this->header_path = realpath(dirname(__FILE__).'/../../header.inc.php');
-
+		// header is 3 levels lower then this command in setup/inc
+		$this->header_path = dirname(dirname(dirname(__FILE__))).'/header.inc.php';
 		$this->setup_header =& new setup_header();
 	}
 
@@ -68,7 +67,7 @@ class setup_cmd_header extends setup_cmd
 		{
 			return true;	// can only check locally
 		}
-		if (!file_exists($this->header_path))
+		if (!file_exists($this->header_path) || filesize($this->header_path) < 200)	// redirect header in rpms is ~150 byte
 		{
 			if ($this->sub_command != 'create')
 			{
@@ -126,10 +125,11 @@ class setup_cmd_header extends setup_cmd
 		{
 			echo $header;	// for cli, we echo the header
 		}
-		if (file_exists($this->header_path) && is_writable($this->header_path) || is_writable(dirname($this->header_path)))
+		if (file_exists($this->header_path) && is_writable($this->header_path) || is_writable(dirname($this->header_path)) ||
+			function_exists('posix_getuid') && !posix_getuid())	// root has all rights
 		{
 			if (is_writable(dirname($this->header_path)) && file_exists($this->header_path)) unlink($this->header_path);
-			if (($f = fopen($this->header_path,'wb')) && fwrite($f,$header))
+			if (($f = fopen($this->header_path,'wb')) && ($w=fwrite($f,$header)))
 			{
 				fclose($f);
 				return lang('header.inc.php successful written.');
diff --git a/setup/inc/class.setup_process.inc.php b/setup/inc/class.setup_process.inc.php
index 5f0fb3b1ef..def3150ff8 100755
--- a/setup/inc/class.setup_process.inc.php
+++ b/setup/inc/class.setup_process.inc.php
@@ -207,16 +207,24 @@ class setup_process
 		$is_windows = strtoupper(substr(PHP_OS,0,3)) == 'WIN';
 
 		$current_config['site_title'] = 'eGroupWare';
-		$current_config['hostname']  = $_SERVER['HTTP_HOST'] ? $_SERVER['HTTP_HOST'] : 'localhost';
+		$current_config['hostname']  = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : 'localhost';
 
 		// guessing the eGW url
-		$parts = explode('/',$_SERVER['PHP_SELF']);
-		array_pop($parts);	// remove config.php
-		array_pop($parts);	// remove setup
-		$current_config['webserver_url'] = implode('/',$parts);
-		$egroupwareDirName = end($parts);
-
-		if(!$is_windows) {
+		if (isset($_SERVER['HTTP_HOST']))
+		{
+			$parts = explode('/',$_SERVER['PHP_SELF']);
+			array_pop($parts);	// remove config.php
+			array_pop($parts);	// remove setup
+			$current_config['webserver_url'] = implode('/',$parts);
+			$egroupwareDirName = end($parts);
+		}
+		else	// eg. cli install --> use defaults
+		{
+			$current_config['webserver_url'] = '/egroupware';
+			$egroupwareDirName = 'egroupware';
+		}
+		if(!$is_windows) 
+		{
 			if(@is_dir('/tmp'))
 			{
 				$current_config['temp_dir'] = '/tmp';
diff --git a/setup/setup-cli.php b/setup/setup-cli.php
index 6cb1b1e017..a84705b9d2 100755
--- a/setup/setup-cli.php
+++ b/setup/setup-cli.php
@@ -22,7 +22,7 @@ elseif ($_SERVER['argc'] > 1)
 	$arguments = $_SERVER['argv'];
 	array_shift($arguments);
 	$action = array_shift($arguments);
-	list($_POST['FormDomain']) = explode(',',$arguments[0]);	// header include needs that to detects the right domain
+	if (isset($arguments[0])) list($_POST['FormDomain']) = explode(',',$arguments[0]);	// header include needs that to detects the right domain
 }
 else
 {