From f4038a2160d55a7f519a3b42be1aa96e29e9a908 Mon Sep 17 00:00:00 2001
From: ftimme <ft@falkotimme.com>
Date: Wed, 27 Feb 2013 09:01:40 -0500
Subject: [PATCH] - Fixed "FUNCTION databasename.CONCAT does not exist" error for older MySQL versions.

---
 server/plugins-available/software_update_plugin.inc.php |  215 ++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 192 insertions(+), 23 deletions(-)

diff --git a/server/plugins-available/software_update_plugin.inc.php b/server/plugins-available/software_update_plugin.inc.php
index bf6aa56..a6b7162 100644
--- a/server/plugins-available/software_update_plugin.inc.php
+++ b/server/plugins-available/software_update_plugin.inc.php
@@ -1,7 +1,7 @@
 <?php
 
 /*
-Copyright (c) 2007, Till Brehm, projektfarm Gmbh
+Copyright (c) 2007-2012, Till Brehm, projektfarm Gmbh, Oliver Vogel www.muv.com
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without modification,
@@ -35,7 +35,7 @@
 	
 	//* This function is called during ispconfig installation to determine
 	//  if a symlink shall be created for this plugin.
-	function onInstall() {
+	public function onInstall() {
 		global $conf;
 		
 		return true;
@@ -47,84 +47,253 @@
 	 	This function is called when the plugin is loaded
 	*/
 	
-	function onLoad() {
+	public function onLoad() {
 		global $app;
 		
 		/*
 		Register for the events
 		*/
 		
-		//* Mailboxes
 		$app->plugins->registerEvent('software_update_inst_insert',$this->plugin_name,'process');
 		//$app->plugins->registerEvent('software_update_inst_update',$this->plugin_name,'process');
 		//$app->plugins->registerEvent('software_update_inst_delete',$this->plugin_name,'process');
 		
+		//* Register for actions
+		$app->plugins->registerAction('os_update',$this->plugin_name,'os_update');
+		
 		
 	}
 	
-	
-	function process($event_name,$data) {
+	private function set_install_status($inst_id, $status) {
+        global $app;
+        
+        $app->db->query("UPDATE software_update_inst SET status = '{$status}' WHERE software_update_inst_id = '{$inst_id}'");
+        $app->dbmaster->query("UPDATE software_update_inst SET status = '{$status}' WHERE software_update_inst_id = '{$inst_id}'");
+    }
+    
+	public function process($event_name,$data) {
 		global $app, $conf;
-		
-		if(!$conf['software_updates_enabled'] == true) {
-			$app->log('Software Updates not enabled on this server. To enable updates, set $conf["software_updates_enabled"] = true; in config.inc.php',LOGLEVEL_ERROR);
-			return false;
-		}
 		
 		//* Get the info of the package:
 		$software_update_id = intval($data["new"]["software_update_id"]);
 		$software_update = $app->db->queryOneRecord("SELECT * FROM software_update WHERE software_update_id = '$software_update_id'");
+		$software_package = $app->db->queryOneRecord("SELECT * FROM software_package WHERE package_name = '".$app->db->quote($software_update['package_name'])."'");
+		
+		if($software_package['package_type'] == 'ispconfig' && !$conf['software_updates_enabled'] == true) {
+			$app->log('Software Updates not enabled on this server. To enable updates, set $conf["software_updates_enabled"] = true; in config.inc.php',LOGLEVEL_WARN);
+            $this->set_install_status($data["new"]["software_update_inst_id"], "failed");
+			return false;
+		}
+		
+		$installuser = '';
+		if($software_package['package_type'] == 'ispconfig') {
+			$installuser = '';
+		} elseif ($software_package['package_type'] == 'app') {
+			$installuser = 'ispapps';
+		} else {
+			$app->log('package_type not supported',LOGLEVEL_WARN);
+            $this->set_install_status($data["new"]["software_update_inst_id"], "failed");
+			return false;
+		}
 		
 		$temp_dir = '/tmp/'.md5 (uniqid (rand()));
 		$app->log("The temp dir is $temp_dir",LOGLEVEL_DEBUG);
 		mkdir($temp_dir);
+		if($installuser != '') chown($temp_dir, $installuser);
+		
 		if(!is_dir($temp_dir)) {
-			$app->log("Unable to create temp directory.",LOGLEVEL_ERROR);
+			$app->log("Unable to create temp directory.",LOGLEVEL_WARN);
+            $this->set_install_status($data["new"]["software_update_inst_id"], "failed");
 			return false;
 		}
 		
-		exec("cd $temp_dir && wget ".$software_update["update_url"]);
+		//* Replace placeholders in download URL
+		$software_update["update_url"] = str_replace('{key}',$software_package['package_key'],$software_update["update_url"]);
+		
+		//* Download the update package
+		$cmd = "cd $temp_dir && wget ".$software_update["update_url"];
+		if($installuser == '') {
+			exec($cmd);
+		} else {
+			exec("su -c ".escapeshellarg($cmd)." $installuser");
+		}
 		$app->log("Downloading the update file from: ".$software_update["update_url"],LOGLEVEL_DEBUG);
 		
-		$url_parts = parse_url($software_update["update_url"]);
-		$update_filename = basename($url_parts["path"]);
+		//$url_parts = parse_url($software_update["update_url"]);
+		//$update_filename = basename($url_parts["path"]);
+		//* Find the name of the zip file which contains the app.
+		$tmp_dir_handle = dir($temp_dir);
+		$update_filename = '';
+		while (false !== ($t = $tmp_dir_handle->read())) {
+			if($t != '.' && $t != '..' && is_file($temp_dir.'/'.$t) && substr($t,-4) == '.zip') {
+				$update_filename = $t;
+			}
+		}
+		$tmp_dir_handle->close();
+		unset($tmp_dir_handle);
+		unset($t);
+		
+		if($update_filename == '') {
+			$app->log("No package file found. Download failed? Installation aborted.",LOGLEVEL_WARN);
+			exec("rm -rf $temp_dir");
+			$app->log("Deleting the temp directory $temp_dir",LOGLEVEL_DEBUG);
+			$this->set_install_status($data["new"]["software_update_inst_id"], "failed");
+			return false;
+		}
+
 		$app->log("The update filename is $update_filename",LOGLEVEL_DEBUG);
 		
 		if(is_file($temp_dir.'/'.$update_filename)) {
 			
 			//* Checking the md5sum
 			if(md5_file($temp_dir.'/'.$update_filename) != $software_update["update_md5"]) {
-				$app->log("The md5 sum of the downloaded file is incorrect. Update aborted.",LOGLEVEL_ERROR);
+				$app->log("The md5 sum of the downloaded file is incorrect. Update aborted.",LOGLEVEL_WARN);
 				exec("rm -rf $temp_dir");
 				$app->log("Deleting the temp directory $temp_dir",LOGLEVEL_DEBUG);
+				$this->set_install_status($data["new"]["software_update_inst_id"], "failed");
 				return false;
 			} else {
-				$app->log("md5sum of the downloaded file is verified.",LOGLEVEL_DEBUG);
+				$app->log("MD5 checksum of the downloaded file verified.",LOGLEVEL_DEBUG);
 			}
 			
 			
 			//* unpacking the update
-			exec("cd $temp_dir && unzip $update_filename");
+			$cmd = "cd $temp_dir && unzip $update_filename";
+			if($installuser == '') {
+				exec($cmd);
+			} else {
+				exec("su -c ".escapeshellarg($cmd)." $installuser");
+			}
+			
+			//* Create a database, if the package requires one
+			if($software_package['package_type'] == 'app' && $software_package['package_requires_db'] == 'mysql') {
+				
+				$app->uses('ini_parser');
+				$package_config = $app->ini_parser->parse_ini_string(stripslashes($software_package['package_config']));
+				
+				$this->create_app_db($package_config['mysql']);
+				$app->log("Creating the app DB.",LOGLEVEL_DEBUG);
+				
+				//* Load the sql dump into the database
+				if(is_file($temp_dir.'/setup.sql')) {
+					$db_config = $package_config['mysql'];
+					if(	$db_config['database_user'] != '' &&
+						$db_config['database_password'] != '' &&
+						$db_config['database_name'] != '' &&
+						$db_config['database_host'] != '') {
+						system("mysql --default-character-set=utf8 --force -h '".$db_config['database_host']."' -u '".$db_config['database_user']."' ".$db_config['database_name']." < ".escapeshellcmd($temp_dir.'/setup.sql'));
+						$app->log("Loading setup.sql dump into the app db.",LOGLEVEL_DEBUG);
+					}
+				}
+				
+			}
+			
+			//* Save the package config file as app.ini
+			if($software_package['package_config'] != '') {
+				file_put_contents($temp_dir.'/app.ini',$software_package['package_config']);
+				$app->log("Writing ".$temp_dir.'/app.ini',LOGLEVEL_DEBUG);
+			}
 			
 			if(is_file($temp_dir.'/setup.sh')) {
 				// Execute the setup script
 				exec('chmod +x '.$temp_dir.'/setup.sh');
 				$app->log("Executing setup.sh file in directory $temp_dir",LOGLEVEL_DEBUG);
-				exec('cd '.$temp_dir.' && ./setup.sh');
-				$app->db->query("UPDATE software_update_inst SET status = 'installed' WHERE software_update_inst_id = ".$data["new"]["software_update_inst_id"]);
+				$cmd = 'cd '.$temp_dir.' && ./setup.sh > package_install.log';
+				if($installuser == '') {
+					exec($cmd);
+				} else {
+					exec("su -c ".escapeshellarg($cmd)." $installuser");
+				}
+                
+                $log_data = @file_get_contents("{$temp_dir}/package_install.log");
+                if(preg_match("'.*\[OK\]\s*$'is", $log_data)) {
+                    $app->log("Installation successful",LOGLEVEL_DEBUG);
+                    $app->log($log_data,LOGLEVEL_DEBUG);
+                    $this->set_install_status($data["new"]["software_update_inst_id"], "installed");
+                } else {
+                    $app->log("Installation failed:\n\n" . $log_data,LOGLEVEL_WARN);
+                    $this->set_install_status($data["new"]["software_update_inst_id"], "failed");
+                }
 			} else {
 				$app->log("setup.sh file not found",LOGLEVEL_ERROR);
+                $this->set_install_status($data["new"]["software_update_inst_id"], "failed");
 			}
 		} else {
-			$app->log("Download of the update file failed",LOGLEVEL_ERROR);
+			$app->log("Download of the update file failed",LOGLEVEL_WARN);
+            $this->set_install_status($data["new"]["software_update_inst_id"], "failed");
 		}
 		
-		exec("rm -rf $temp_dir");
+		if($temp_dir != '' && $temp_dir != '/') exec("rm -rf $temp_dir");
 		$app->log("Deleting the temp directory $temp_dir",LOGLEVEL_DEBUG);
+	}
+	
+	private function create_app_db($db_config) {
+		global $app, $conf;
+		
+		if(	$db_config['database_user'] != '' &&
+			$db_config['database_password'] != '' &&
+			$db_config['database_name'] != '' &&
+			$db_config['database_host'] != '') {
+			
+			if(!include(ISPC_LIB_PATH.'/mysql_clientdb.conf')) {
+				$app->log('Unable to open'.ISPC_LIB_PATH.'/mysql_clientdb.conf',LOGLEVEL_ERROR);
+				return;
+			}
+			
+			if($db_config['database_user'] == 'root') {
+				$app->log('User root not allowed for App databases',LOGLEVEL_WARNING);
+				return;
+			}
+		
+			//* Connect to the database
+			$link = mysql_connect($clientdb_host, $clientdb_user, $clientdb_password);
+			if (!$link) {
+				$app->log('Unable to connect to the database'.mysql_error($link),LOGLEVEL_ERROR);
+				return;
+			}
+
+			$query_charset_table = '';
+
+			//* Create the new database
+			if (mysql_query('CREATE DATABASE '.mysql_real_escape_string($db_config['database_name']).$query_charset_table,$link)) {
+				$app->log('Created MySQL database: '.$db_config['database_name'],LOGLEVEL_DEBUG);
+			} else {
+				$app->log('Unable to connect to the database'.mysql_error($link),LOGLEVEL_ERROR);
+			}
+			
+			if(mysql_query("GRANT ALL ON ".mysql_real_escape_string($db_config['database_name'],$link).".* TO '".mysql_real_escape_string($db_config['database_user'],$link)."'@'".$db_config['database_host']."' IDENTIFIED BY '".mysql_real_escape_string($db_config['database_password'],$link)."';",$link)) {
+			$app->log('Created MySQL user: '.$db_config['database_user'],LOGLEVEL_DEBUG);
+			} else {
+				$app->log('Unable to create database user'.$db_config['database_user'].' '.mysql_error($link),LOGLEVEL_ERROR);
+			}
+
+			mysql_query("FLUSH PRIVILEGES;",$link);
+			mysql_close($link);
+			
+		}
 		
 	}
 	
+	//* Operating system update
+	public function os_update($action_name,$data) {
+		global $app;
+		 
+		//** Debian and compatible Linux distributions
+		if(file_exists('/etc/debian_version')) {
+			exec("aptitude update");
+			exec("aptitude safe-upgrade -y");
+			$app->log('Execeuted Debian / Ubuntu update',LOGLEVEL_DEBUG);
+		}
+
+		//** Gentoo Linux
+		if(file_exists('/etc/gentoo-release')) {
+			exec("glsa-check -f --nocolor affected");
+			$app->log('Execeuted Gentoo update',LOGLEVEL_DEBUG);
+		}
+		
+		return 'ok';
+	}
 
 } // end class
 
-?>
\ No newline at end of file
+?>

--
Gitblit v1.9.1