| | Anya Tarnyavsky | +----------------------------------------------------------------------+ */ error_reporting (E_ALL); include_once ('basic_install.inc'); include_once("gaugebox.inc"); include_once ('license_downloader.inc'); if(defined('SERIAL_NUMBER')){ include_once("forms.inc"); } if (!defined ('LOG_FILE')) { define ('LOG_FILE', getcwd()."/install.log"); } class Install extends BasicInstall { var $forms; /* forms for displaying more complex dialogs */ function Install ($product, $version="") { set_time_limit(0); error_reporting(E_ALL ^ E_NOTICE); print ("Please, wait ...\n"); parent::BasicInstall(); global $_SERVER; # Parse command line arguments: $argc = count ($_SERVER["argv"]); $argv = $_SERVER["argv"]; $this->cmdline_arg = array(); $this->cmdline_arg["__options"] = array(); for ($i=1; $i < $argc; $i++) { if (preg_match ('/^\-\-?(.*)$/', $argv[$i], $match)) { if (isset ($argv[$i+1]) && !preg_match ('/^\-\-?/', $argv[$i+1])) { $this->cmdline_arg[strtolower($match[1])] = $argv[$i+1]; $argc++; } else { $this->cmdline_arg[strtolower($match[1])] = true; } } else { $this->cmdline_arg["__options"][] = $argv[$i]; } } $this->cmdline_args = array ( "help" => "Show this help", "answers-file 'file'" => "Read installation configuration from file", "save-answers 'file'" => "Save installation configuration to file" ); // the following overriddes logger and error handler from the basic class $this->logger = new InstallLogger (LOG_FILE); $this->error_handler = new InstallErrorHandler ($this); $this->conf['product'] = $product; //$this->conf['version'] = $version; //$this->conf['title'] = "$product $version"; $this->conf['backtitle'] = "$product Installation"; $this->conf['install_guide'] = 1; // by default, there is Installation Guide $this->conf['backup_suffix'] = "-". strtolower(preg_replace("/[\s\/]+/", "_", $product)).".bak"; $this->conf['progress_bar_started'] = false; $this->conf['wrap_size'] = 75; $this->conf['php_ini_opened'] = false; $this->logger->log ("Starting installation of $product $version ..."); // define system information // $uname = posix_uname(); $this->conf['uname'] = $this->my_uname(); if(empty($this->conf['uname']['nodename'])){ $this->conf['uname']['nodename'] = "localhost"; } $this->logger->log ('System: ' . $this->conf['uname']['sysname'] . ' ' . $this->conf['uname']['release'] . ' ' . $this->conf['uname']['machine']); $this->logger->log ('Hostname: ' . $this->conf['uname']['nodename']); $this->conf['nl'] = "\n"; $this->conf['zend_ext_directive'] = "zend_extension"; if ($this->conf['uname']['sysname'] == "HP-UX") { $this->conf['so_ext'] = ".sl"; } else { $this->conf['so_ext'] = ".so"; } // determine temporary directory $this->conf['tmp_dir'] = getenv("ZEND_TMPDIR"); unset ($_ENV["ZEND_TMPDIR"]); if(empty($this->conf['tmp_dir'])){ $this->conf['tmp_dir'] = "/tmp".$this->conf['slash']."zend_install.". getmypid(); } $this->logger->log ('Setting TEMP=' . $this->conf['tmp_dir']); // and create it $this->my_delete($this->conf['tmp_dir']); $this->my_mkdir($this->conf['tmp_dir']); chmod($this->conf['tmp_dir'],0700); $this->conf['interactive'] = true; # Read default config values $answers_file = null; if (isset ($this->cmdline_arg["answers-file"])) { $answers_file = $this->cmdline_arg["answers-file"]; if (!$this->my_file_exists ($answers_file)) { $file = $this->search_file(array("../", "../data"), array($answers_file)); if (!empty ($file)) { $answers_file = $file; } else { $this->on_error ("{${answers_file}}: file doesn't exist!"); } } } else { $config_file = strtolower(preg_replace("/\s+/", "_", $product)).".conf"; $answers_file = $this->search_file(array("../", "../data"), array($config_file)); } if(!empty ($answers_file)) { $default_config = parse_ini_file($answers_file); foreach ($default_config as $name => $val) { $this->conf[$name] = $val; } $this->conf['interactive'] = false; } $this->conf['webserver'] = "Web server"; $this->conf['comp_dirs_arr'] = array( /* possible directories where to get install components */ 1 => "../data", 2 => "../install", 3 => "../", 4 => "/" ); // initialize components array $this->conf['components'] = array(); $this->conf['webserver_docroot_arr'] = array(); // initialize file permissions if($this->my_file_exists("permissions")){ $file_perms = file("permissions"); foreach ($file_perms as $num => $line){ if(preg_match("/^\s*\#/", $line) || preg_match("/^\s*$/", $line)){ continue; } list($file, $mode, $owner, $group) = preg_split("/\s+/", $line); // file mode owner group $this->conf['file_perms'][$num] = array($file, $mode, $owner, $group); } } else{ $this->conf['file_perms'] = array(); } $this->conf['build_info'] = array(); $inventory_file = $this->search_file(array("../", "../data"), array("Inventory.xml")); if($this->my_file_exists($inventory_file)) { $inventory = $this->file2str ($inventory_file); if(preg_match ("/\/iU", $inventory, $match)) { //$this->conf['build_info']['package.version'] = rtrim(preg_replace("/RC.*$/", "", $this->tag2version ($match[1])), '_'); $this->conf['build_info']['package.version'] = $this->tag2version ($match[1]); } if(preg_match_all ("/\]+)\>/iU", $inventory, $match)) { for ($i=0; $iconf['build_info']["${name}.version"] = $this->tag2version ($ver_match[1], $name); } } } } // if version is specified as argument to ctor, take it, otherwise rely // on one automatically determined from Inventory.xml $this->conf['version'] = (empty ($version) ? $this->conf['build_info']['package.version'] : $version); $this->conf['title'] = "$product " . $this->conf['version']; // compose version, as should be submitted for license download mechanism if (empty ($this->conf['release'])) { // $this->on_error("Undefined release name"); $this->conf['release'] = 'release'; $release = '0'; } elseif (preg_match ("/^beta(.)$/", $this->conf['release'], $arr)) { $release = $arr[1]; } else { $release = '99'; // invalid build_id } // this thingy is needed for license download; probably we should // catch it later, somewhere in get_license() or in license_downloader.inc; // otherwise (like for zend core) it is just not needed /* if(empty($this->conf['product_id'])){ $this->on_error("Undefined product ID"); } */ $this->conf['version_for_license'] = $this->conf['version'] . '-' . $release; // get the basename of the calling script $basename = basename(getenv("CALLING_SCRIPT")); unset ($_ENV["CALLING_SCRIPT"]); if ($basename == "install-tty" || !$this->conf['interactive']) { unset($this->conf['dialog']); } else { $dialog = "./dialog"; if(!$this->my_file_exists($dialog)){ $this->on_error ("File: $dialog does not exist!"); } if(!is_executable($dialog)){ chmod($dialog, 0555); } $this->conf['dialog'] = $dialog; } if(defined('SERIAL_NUMBER')){ $this->forms =& new Forms($this, !empty($this->conf['dialog'])); } if(!empty($this->conf['dialog'])){ // set common dialog setup $this->conf['dialog'] .= sprintf(" --clear --backtitle %s --title %s", escapeshellarg ($this->conf['backtitle']), escapeshellarg ($this->conf['title']) ); $this->conf['max_x'] = 78; // default size $this->conf['max_y'] = 24; $this->conf['dialog_tmp'] = $this->conf['tmp_dir'] . "/dialog.tmpfile"; $this->conf['dialog_error'] = "Error while executing the dialog utility.\n". "Probable reason - wrong terminal settings.\n". "Please use install-tty instead."; } $this->conf['php_ini_backup_msg'] = ""; $this->conf['lic_error_file'] = "error.txt"; $this->conf['license_installed'] = false; $this->restore_config(); foreach ($this->conf['saved_config'] as $key => $val) { $this->conf[$key] = $val; } $this->conf['min_space_size'] = $this->my_du("../data"); $this->conf['installer_dir'] = dirname(getcwd()); $this->conf['installer_path'] = $this->conf['installer_dir'].":".$this->make_path($this->conf['installer_dir'], "data").":".$this->make_path($this->conf['installer_dir'], "zui_files"); // needed for searching zendid in path putenv ('PATH=' . $this->conf['installer_path'] . ':' . getenv ('PATH')); } // end of ctor // =================================== // Command line arguments functions // =================================== function add_cmdline_args ($options) { $this->cmdline_args = array_merge ($this->cmdline_args, $options); $this->check_bad_arguments(); if ($this->get_cmdline_arg ("help") || $this->get_cmdline_arg ("h")) { $this->help_and_die(); } } function help_and_die ($err=null) { $prog = getenv("CALLING_SCRIPT"); if ($err) { $err = "ERROR: {$err}\n"; } $help = <<cmdline_args as $opt => $descr) { if (strlen ($opt) > $space) { $space = strlen ($opt); } } $space += 12; foreach ($this->cmdline_args as $opt => $descr) { $help .= "--{$opt}".str_repeat (" ", $space-strlen($opt)).$descr."\n"; } $this->msgbox ($help); $this->cleanup(); die(-1); } function get_cmdline_arg($name) { return (isset($this->cmdline_arg[$name]) ? $this->cmdline_arg[$name] : null); } function check_bad_arguments() { $args = array(); foreach ($this->cmdline_args as $arg => $descr) { $args[preg_replace ('/\s.*/', '', $arg)] = true; } foreach ($this->cmdline_arg as $arg => $val) { if ($arg == "__options") continue; if (!isset ($args[$arg])) { $this->help_and_die ("Bad option: --{$arg}"); } } } // ------------------ // SYSTEM FUNCTIONS // ================== // parms: 0 - tag (like OPTIMIZER_2_6_2_RC4_20060104) // 1 - (optional) component name (like 'optimizer') // returns: version (like 2.6.2) function tag2version ($tag, $name=null) { if (isset ($name)) { // don't take into account '-ts' suffix in name, if any $name = preg_replace ('/-ts$/', '', $name); // strip the component name from the beginning of the tag, if any $tag = preg_replace ("/^$name/i", '', $tag); } if (preg_match ('/\w?_(\d+)_(\d+)_(\d+[a-z]?|[a-zA-Z0-9]+?)_?((ALPHA|BETA)\d*?)?_?RC(\d+)_/', $tag, $match)) { $version = "{$match[1]}.{$match[2]}.{$match[3]}"; } else { $version = $tag; } // it still could be something like 2.1.2RC7, so stripping out RC part return (preg_replace ('/RC.*$/', '', $version)); //$version = preg_replace ('/_/', '.', $version); //return ($version); } // end of tag2version() function my_uname() { $uname = array(); $uname["sysname"] = $this->cmd2str("uname -s 2>/dev/null"); $uname["machine"] = ($uname["sysname"] == "Linux" ? $this->cmd2str("uname -m 2>/dev/null") : $this->cmd2str("uname -p 2>/dev/null")); $uname["release"] = $this->cmd2str("uname -r 2>/dev/null"); $uname["nodename"] = $this->cmd2str("uname -n 2>/dev/null"); if ($uname["sysname"]=="AIX") { $major = $this->cmd2str("uname -v 2>/dev/null"); $uname["release"] = $major.'.'.$uname["release"]; } foreach ($uname as $name => $val) { if($val == "") { $uname[$name] = "unknown"; } } return $uname; } // GUESS_DOMAINNAME function guess_domainname() { $cmd = $this->search_cmd_in_path ("domainname", true); if ($cmd) { return str_replace ("(none)", "", $this->cmd2str ("{$cmd} 2>/dev/null")); } return ""; } // GUESS_GLIBC_VERSION function guess_glibc_version() { $glibc_ver = ""; if($this->conf['uname']['sysname'] == "Linux") { $glibc_path = $this->cmd2str ('/bin/ls /lib{,64}/{libc,ld}-?.?.* 2>/dev/null'); if(@preg_match("/(\d)\.(\d)/", $glibc_path, $match)) { $glibc_ver = "$match[1].$match[2]"; $this->logger->log ("Detected GLIBC version: $glibc_ver"); } } return $glibc_ver; } // GET_RELEASE_VERSION function get_release_version() { $release = $this->conf['uname']['release']; if(preg_match("/^(\d+\.\d+)/", $this->conf['uname']['release'], $match)) { $release = $match[1]; } $this->logger->log ("Detected release version: $release"); return $release; } // CHECK_SYSTEM_SUPPORTED function check_system_supported() { if(!isset($this->conf['supported_systems'][$this->conf['uname']['sysname']])) { $error = "OS type: ".$this->conf['uname']['sysname']; } else { $sysconf = $this->conf['supported_systems'][$this->conf['uname']['sysname']]; if(count($sysconf) > 0) { if(isset($sysconf["glibc"])) { $glibc_arr = $sysconf["glibc"]; $glibc_OK = true; foreach($glibc_arr as $glibc) { $glibc_OK = false; if(preg_match("/^([\>\<]?)(.*)$/", $glibc, $match)) { $installed_glibc = $this->guess_glibc_version(); if(($match[1] == ">" && version_compare($installed_glibc, $match[2]) >= 0) || ($match[1] == "<" && version_compare($installed_glibc, $match[2]) <= 0) || $this->ver_equal($installed_glibc, $glibc)) { // Glibc version is OK $glibc_OK = true; break; } } } if(!$glibc_OK) { $error = "GLIBC version: $installed_glibc"; } } if(!isset($error) && isset($sysconf["release"])) { $release_arr = $sysconf["release"]; $release_OK = true; foreach($release_arr as $release) { $release_OK = false; if(preg_match("/^([\>\<]?)(.*)$/", $release, $match)) { $installed_release = $this->get_release_version(); if( ($match[1] == ">" && version_compare($installed_release, $match[2]) >= 0) || ($match[1] == "<" && version_compare($installed_release, $match[2]) <= 0) || $this->ver_equal($installed_release, $release)) { // Release is OK $release_OK = true; break; } } } if(!$release_OK) { $error = "OS release: $installed_release"; } } if(!isset($error) && isset($sysconf["machine"])) { $machine_arr = $sysconf["machine"]; $machine_OK = true; foreach($machine_arr as $machine) { $machine_OK = false; if($machine == $this->conf['uname']['machine']) { // Processor type is OK $machine_OK = true; break; } } if(!$machine_OK) { $error = "processor type: ".$this->conf['uname']['machine']; } } } } if(isset($error)) { $this->yesnobox("The installation detected that this package is not compatible with your\nsystem configuration.\n". "It seems that you have an unsupported $error\n". "Do you still wish to continue the installation?\n". "For list of supported configurations, please refer to the Zend Product\ncompatibility table.", true, true); } } // ------------------ // BASIC FUNCTIONS // ================== // CLRSCR function clrscr() { $this->run_command("clear"); } // WELCOME_BOX function welcome_box($msg="", $addtext="") { if(!isset($this->conf['dialog'])) { // Clear screen before showing the "welcome" message $this->clrscr(); } if($msg == ""){ $msg = "Welcome to the ".$this->conf['product']." ".$this->conf['version']." Installation!\n\n"; // by default, we assume there is Installation Guide if ($this->conf['install_guide'] == 1) { $msg .= "For more information regarding this procedure, please see the\n"; $msg .= $this->conf['product']." Installation Guide.\n"; } if(!empty($addtext)){ $msg .= "\n$addtext"; } } $this->msgbox($msg); } // BYE_BYE function bye_bye($url="", $msg="", $need_restart=true, $know_port=false) { $this->save_answers_file(); $this->clrscr(); print "\n\n\n\n\n\n\n"; print "******************************************************************************\n"; print "\n"; if(!empty($msg)){ print "{$msg}\n"; } if(!$this->conf['license_installed']){ print " You must INSTALL the license files from ". "Zend.com to your installation directory\n"; print "\n"; } if($need_restart){ if(isset($this->conf['php_type']) && $this->conf['php_type'] == "fastcgi"){ print " You must RESTART your FastCGI for the ". "modifications to take effect\n"; print "\n"; } else{ print " You must RESTART your ".$this->conf['webserver']." for the ". "modifications to take effect\n"; print "\n"; } } if(!empty($url)) { print " You can access the ".$this->conf['product']."'s User Interface using the URL:\n"; print " $url\n"; print "\n"; if(!$know_port && !preg_match("@:\d+/@", $url)){ $url_with_port = preg_replace("@://([^/]*)/@", "://\\1:/", $url); print " If your Web server is running on port different from the default\n"; print " port 80, you should access the ".$this->conf['product']." as\n"; print " $url_with_port\n"; print "\n"; } } print "\n"; print "******************************************************************************\n\n\n\n\n\n"; $this->logger->log ('Bye bye ... :)'); } // RUN_COMMAND function run_command($cmd, $err_msg="", $need_logging=true) { $tmpfile = tempnam ($this->conf['tmp_dir'], "cmd"); if ($tmpfile) { $fp = popen("$cmd 2> {$tmpfile}", "w"); } else { $fp = popen("$cmd 2> /dev/null", "w"); } if(empty($fp)){ $this->on_error ("Can't execute command: $cmd" . (strlen($err_msg) > 0 ? "\nERROR: $err_msg" : '')); } $status = $this->safe_pclose($fp); if ($need_logging) { $this->logger->log ("Executing: \"$cmd\" (status: $status)"); if ($status != 0 && $tmpfile) { $error = @trim($this->file2str ($tmpfile)); if (@strlen ($error) > 0) { $this->logger->log ("Error was: {$error}"); } @unlink ($tmpfile); } } return $status; } // NICE_PATH function nice_path($path) /* removes all multiple slashes */ { /* remove multiple slashes from the path */ $path = preg_replace("/\/\/\/*/", "/", $path); /* multiple '/' */ $path = preg_replace("/^\.\//", "", $path); /* first './' from the path */ $path = preg_replace("/\/\.\//", "/", $path); /* '/./' from the path */ $path = preg_replace("/^[^\/]+\/\.\.\/?/", "", $path); /* dir/.. from the beginning */ $path = preg_replace("/\/[^\/]+\/\.\.\/?/", "/", $path); /* /dir/.. from the path */ $path = preg_replace("/([^\/])\/+$/", "\\1", $path); /* last / from the end of path */ return $path; } // ADD_DASHES function add_dashes($msg) { $dashes_len = 0; /* define dashes line under the menu title */ $tmp_len = 0; for($i=0; $i $dashes_len){ $dashes_len = $tmp_len; $tmp_len = 0; } } else{ $tmp_len ++; } } if($dashes_len == 0){ $dashes_len = $tmp_len; } if($dashes_len > $this->conf['wrap_size']){ $dashes_len = $this->conf['wrap_size']; } $dashes = str_repeat("-", $dashes_len); return "$msg\n$dashes"; } // MY_DU function my_du($filename) { $total_size = 0; if($this->my_dir_exists($filename)) { $dir = $this->my_opendir($filename); while($file = readdir($dir)){ if($file == "." || $file == ".."){ continue; } $total_size += $this->my_du($this->make_path($filename, $file)); } closedir($dir); } else if($this->my_file_exists($filename)) { $total_size = filesize($filename); } return $total_size; } // SIZE_HUMAN function size_human($size) { if($size > 1048576) { return round($size/1048576, 1)."MB"; } else if($size > 1024) { return round($size/1024, 1)."KB"; } else return round($size, 1)." bytes"; } // EXPAND_TILDE function expand_tilde($path) /* converts tilde to a real path */ { if(preg_match("/^~(.*)$/", $path, $match1)) { if(preg_match("/^([\w]+)(.*)$/", $match1[1], $match2)) { $pwd = $this->run_silently("posix_getpwnam", $match2[1]); if(!empty($pwd)) { $path = $this->make_path($pwd["dir"], $match2[2]); } } else { $path = $this->make_path(getenv("HOME"), $match1[1]); } } return $path; } // IS_EMAIL_VALID function is_email_valid($email) { return preg_match("/^(.+)\@(.+)\.(.+)$/", $email); } // IS_IP_VALID function is_ip_valid($ip) { if (preg_match ('/^\d+\.\d+\.\d+\.\d+$/', $ip) && @ip2long ($ip) !== -1) { return true; } return false; } // GET_BUILD_INFO function get_build_info() { return $this->conf['build_info']; } // INI_ARRAY_REBUILD function ini_array_rebuild($ini_arr,$translation_arr) { if (!is_array($ini_arr) or !is_array($translation_arr)) return array(); if (empty($ini_arr) or empty($translation_arr)) return array(); $result=array(); foreach ($ini_arr as $directive=>$value) { foreach ($translation_arr as $prefix=>$translated_prefix) { $prefix_length=strlen($prefix); if (strncmp($prefix,$directive,$prefix_length)==0) { $translated_directive=$translated_prefix.substr($directive,$prefix_length); $result[$translated_directive]=$value; } } } return $result; } // VER_EQUAL function ver_equal($version1, $version2, $from=0) { $ver_arr1 = preg_split("/[\.\_]/", $version1); $ver_arr2 = preg_split("/[\.\_]/", $version2); if(count($ver_arr1) != count($ver_arr2)){ return false; } for($i = 0; $i < count($ver_arr1); $i++){ if(($ver_arr1[$i]!=$ver_arr2[$i]) && ($ver_arr1[$i]!='x') && ($ver_arr2[$i]!='x')){ return false; } if(($ver_arr1[$i]!=$ver_arr2[$i]) && ($ver_arr1[$i]=='x') && ($from != 0) && ($ver_arr2[$i] < $from)){ return false; } } return true; } // ARRAY2STRING function array2string($array, $index=-1) { $str = ""; foreach ($array as $num => $data){ if($index==-1){ $str .= $data.$this->conf['nl']; } else{ $str .= $data[$index].$this->conf['nl']; } } return $str; } // ARRAY2PHP_SUPPORT_STRING function array2php_support_string($array, $index=-1, $from_index=-1) { $str = ""; foreach ($array as $num => $data){ if($index==-1){ $str .= $data.$this->conf['nl']; } else{ if($from_index != -1 && $data[$from_index] != 0){ $sub_str=substr($data[$index],0 ,(strlen($data[$index])-1) ); $str .= $sub_str.$data[$from_index]." and above".$this->conf['nl']; }else{ $str .= $data[$index].$this->conf['nl']; } } } return $str; } // WARN function warn($msg) { $this->infobox($msg); } // ON_ABORT function on_abort($msg = "", $dont_ask=false) /* die with error message */ { if(!$this->conf['interactive']) { $dont_ask = true; } if(!$dont_ask && !$this->yesnobox("Do you really wish to abort the installation?", true)) { return; } $this->logger->log ("ABORT: $msg"); $this->save_config(); $this->php_ini_restore(); if(strlen($msg) > 0) { $msg = "\n$msg"; } $this->msgbox($this->conf['product']." installation was aborted.$msg"); $this->cleanup(); die(-1); } // DEFAULT_ABORT function default_abort() { $this->on_abort("The installation was NOT completed successfully.", true); } // CLEANUP function cleanup() { $this->logger->log ('Cleaning up ...'); /* Save installation log */ if (isset($this->conf['prefix'])) { $this->my_mkdir_long ($this->conf['prefix'].'/logs'); //$this->logger->store ($this->conf['prefix'].'/logs'); $this->my_copy ($this->logger->logfile_name, $this->conf['prefix'] . '/logs'); } $this->my_delete($this->conf['tmp_dir']); } // SAVE_ANSWERS_FILE function save_answers_file() { $answers_file = $this->get_cmdline_arg("save-answers"); $save_file = ''; if ($answers_file) { foreach ($this->conf as $key => $val) { if (is_numeric ($val) || is_string ($val) && strlen ($val) < 20) { $save_file .= "{$key}={$val}\n"; } } $this->str2file ($save_file, $answers_file); } } // SAVE_CONFIG function save_config() { if(!empty($this->conf['saved_config'])) { $this->str2file(serialize($this->conf['saved_config']), "install.sav"); } } // RESTORE_CONFIG function restore_config() { if($this->my_file_exists("install.sav")) { $this->conf['saved_config'] = unserialize($this->file2str("install.sav")); } else $this->conf['saved_config'] = array(); } // SEARCH_DIR function search_dir($dirs_array) { foreach ($dirs_array as $dir){ /* searches for an existent directory in an array of paths */ if($this->my_dir_exists($dir)){ return $dir; } } return ""; } // SEARCH_FILE function search_file($dirs_array, $files_arr) { foreach ($dirs_array as $dir){ /* searches for an existent directory and file in an array of paths */ if($this->my_dir_exists($dir)){ foreach($files_arr as $file){ if($this->my_file_exists($this->make_path($dir, $file))){ return $this->make_path($dir, $file); } } } } return ""; } // SELECT_DIR function select_dir($msg, $default="", $create=false) { while(true){ $dir = $this->choose_dir($msg, $default); $dir = $this->nice_path($dir); if(!$this->my_dir_exists($dir)){ if($this->my_file_exists($dir)){ $this->msgbox("\"$dir\" must be a directory!"); } else{ if ($create) { if ($this->yesnobox ("Directory: \"$dir\" doesn't exist!\nWould you like this directory to be created?")) { $this->my_mkdir_long ($dir); break; } } else $this->msgbox("Directory: \"$dir\" doesn't exist!"); } } else{ break; } } return $dir; } // SELECT_FILE_NOSTRIP function select_file_nostrip($msg, $default="", $accept_empty=false) { while(true) { $file = $this->inputbox($msg, $default, $accept_empty); if ((empty($file) || $file == -1) && $accept_empty) { return null; } $file = $this->nice_path($file); if(!$this->my_file_exists($file)){ if($this->my_dir_exists($file)){ $this->msgbox("\"$file\" must be a file!"); } else{ $this->msgbox("File: \"$file\" doesn't exist!"); } } else{ break; } } return $file; } // SELECT_FILE function select_file($msg, $default="", $accept_empty=false) { return $this->strip_symlink ($this->select_file_nostrip($msg, $default, $accept_empty)); } // CHOOSE_DIR function choose_dir($msg, $default, $min_space_size=0, $illegal_chars=" \;\$\#\'\"") { while(true){ $dir = $this->inputbox($msg, $default); $dir = $this->expand_tilde($dir); if(file_exists($dir)) { $dir = $this->strip_symlink($dir); } if(!preg_match("/^\//", $dir)){ $this->msgbox("The path must be absolute!"); } else if($illegal_chars && preg_match("/[".$illegal_chars."]/", $dir)) { $chars_str = implode(",", preg_split("//", trim(stripslashes($illegal_chars)), -1, PREG_SPLIT_NO_EMPTY)); if($chars_str != "") { $chars_str = ": $chars_str and"; } $chars_str .= " the whitespace character"; $this->msgbox("The path contains illegal characters!\n" ."It must not contain".addslashes($chars_str)."."); } else{ $dir = $this->nice_path($dir); if($min_space_size != 0) { $install_target = $dir; while(strlen($install_target) > 1 && !$this->my_dir_exists($install_target)) { $install_target = $this->my_dirname($install_target); } $actual_free_space = disk_free_space($install_target); if($actual_free_space < $min_space_size) { $this->logger->log ("Directory $dir has a free disk space: " . $this->size_human ($actual_free_space) . ' , but at least ' . $this->size_human ($min_space_size) . ' is needed'); $this->msgbox("The directory must have at least ".$this->size_human($min_space_size). " of free disk space.\nPlease provide another directory."); continue; } } break; } } return $dir; } // FSELECT function fselect ($path="/", $msg=null) { $this->progress_bar_stop(); if (isset ($this->conf['dialog'])) { $file = $this->rundialog ('fselect', $path); } else { $file = $this->select_file ($msg, $file); } return $file; } // CHOOSE_PREFIX function choose_prefix($what, $default, $min_space_size=0, $illegal_chars=" \;\$\#\'\"") { return $this->choose_dir("Please specify the location for installing $what:\n", $default, $min_space_size, $illegal_chars); } // CHOOSE_INSTALL_PREFIX function choose_install_prefix($default) { if(isset($this->conf['default_prefix'])) { if(!$this->conf['interactive']) { return; } $default = $this->conf['default_prefix']; } $this->logger->log ('Choosing install prefix ...'); $this->conf['prefix'] = $this->choose_prefix($this->conf['product'], $default, isset($this->conf['min_space_size']) ? $this->conf['min_space_size'] : 0); $this->conf['saved_config']['default_prefix'] = $this->conf['prefix']; } // USER2UID function user2uid($user) { $pw = posix_getpwnam($user); return $pw["uid"]; } // UID2USER function uid2user ($uid) { $userinfo = @posix_getpwuid($uid); if($userinfo !== false) { return $userinfo["name"]; } return false; } // LINK_STARTUP_DAEMON /* program must understand 'start' and 'stop' arguments */ function link_startup_daemon($script, $name=null, $descr=null) { if (!$name) { $name = basename($script); $name = preg_replace ('@\..*$@', '', $name); } if (!$descr) { $descr = $name; } $err = null; if (@file_exists ('/etc/gentoo-release')) { $init_script = <<str2file ($init_script, $target_script); $this->set_permissions ($target_script, "0755"); $cmd = "rc-update add {$name}.Zend default"; if ($this->run_command ("{$cmd} 1>/dev/null") != 0) { $err = "Cannot run: {$cmd}"; } } else if (PHP_OS == "Linux" || PHP_OS == "SunOS") { // Detect default init level to determine the RC directory where to install the script if(preg_match ('/(\d+):initdefault/', $this->file2str('/etc/inittab'), $match)) { $rc_dir = '/etc/rc'.$match[1].'.d'; if (!$this->my_dir_exists ($rc_dir)) { $rc_dir = '/etc/init.d/rc'.$match[1].'.d'; } if (!$this->my_dir_exists ($rc_dir)) { $rc_dir = '/etc/rc.d/rc'.$match[1].'.d'; } } if (isset ($rc_dir)) { $target_script = $rc_dir.'/S'.$name.".Zend"; if (!$this->my_symlink ($script, $target_script)) { $err = "Cannot symlink {$target_script} to {$script}"; } } else { $err = "Cannot find init scripts directory"; } } else if (PHP_OS == "FreeBSD") { $rc_dir = '/usr/local/etc/rc.d'; $target_script = $rc_dir.'/S'.$name.".Zend.sh"; if (!$this->my_symlink ($script, $target_script)) { $err = "Cannot symlink {$target_script} to {$script}"; } } else if (PHP_OS == "Darwin") { $rc_dir = '/Library/StartupItems/Zend'.$name; if(!$this->my_mkdir_long ($rc_dir)) { $err = "Cannot create directory {$rc_dir}"; } $this->my_copy ($script, '/Library/StartupItems/Zend'.$name.'/'.basename($script)); $this->str2file ( "{\n". " Description = \"$descr\";\n". " Provides = (\"$script\");\n". " Requires = (\"Network\");\n". " OrderPreference = \"None\";\n". " Messages =\n". " {\n". " start = \"Starting $name\";\n". " stop = \"Stopping $name\";\n". " };\n". "}", '/Library/StartupItems/Zend'.$name.'/StartupParameters.plist'); } else{ $err = "Automatic loading is not supported for this platform"; } if ($err !== null) { $this->msgbox ( "Cannot register $script to start automatically when the system boots\n\n". "ERROR: {$err}\n\n". "You will have to fix this problem after the installation is complete" ); } } // CONSTRUCT_CRONTAB_LINE function construct_crontab_line($min_frequency, $args) { if($min_frequency <= 0 || $min_frequency > 60){ $this->on_error ('Frequency must be in range between 1 and 60'); } $crontab_line = ""; for($i=0; $i<60; $i += $min_frequency){ $crontab_line .= "$i"; if($i < 60-$min_frequency){ $crontab_line .= ","; } } $crontab_line .= " * * * * $args"; $this->logger->log ("Constructing a crontab line: $crontab_line"); return $crontab_line; } // -------------------------- // FILE FUNCTIONS // ========================== // MY_MOVE function my_move($oldname, $newname, $delete=false) { if($delete){ /* delete destination before moving */ $this->my_delete($newname); } $this->my_mkdir_long (dirname($newname)); if($this->my_file_exists($this->strip_symlink($oldname))){ $this->logger->log ("Moving: $oldname to: $newname"); return @rename($oldname, $newname); } else if($this->my_dir_exists($oldname)){ $this->my_dir_move($oldname, $newname); } else{ $this->on_error ("Cannot rename file: \"$oldname\" (it's neither a file nor a directory)."); } } // MY_DIR_MOVE function my_dir_move($oldname, $newname) { if(!$this->my_dir_exists($oldname)){ $this->on_error ("File: $oldname should be a directory."); } $this->run_command("mv $oldname $newname"); } // MY_TOUCH function my_touch($file) { $dir = dirname($file); if(!$this->my_dir_exists($dir)){ $this->my_mkdir_long($dir); } if(!$this->my_file_exists($file)){ $this->logger->log ("Creating file: $file"); if(!$this->run_silently("touch", $file)){ $this->on_error ("Cannot create file: $file"); } } } // MY_COPY function my_copy ($oldname, $newname, $follow_symlinks=true, $overrite=true) { if($this->my_dir_exists($newname)){ $newname = $newname.$this->conf['slash'].basename($oldname); } if ($this->my_file_exists ($newname)) { if (! $overrite) { $this->logger->log ("Not overriting $newname with $oldname"); return; } $this->my_rename ($newname, "$newname.old", false); $this->my_unlink ("$newname.old", false); // Unlink the old file } else { $this->my_delete ($newname); } $this->my_mkdir_long (dirname($newname)); if (!$follow_symlinks && $this->my_link_exists($oldname)) { $dest = readlink ($oldname); if ($dest !== false) { $this->my_symlink ($dest, $newname); } } else if($this->my_file_exists($this->strip_symlink($oldname))){ $perms = fileperms($oldname); $owner = fileowner($oldname); $group = filegroup($oldname); if(!$this->my_is_writable($newname)){ $this->infobox("Cannot overwrite: $newname"); } else{ if (!$this->run_silently("copy", $oldname, $newname)) { $this->infobox("Cannot copy: $oldname to: $newname"); } else{ $this->logger->log ("Copying: $oldname to: $newname"); $this->set_permissions($newname, decoct($perms), $owner, $group); } } } else if($this->my_dir_exists($oldname)){ $this->my_dir_copy($oldname, $newname, $follow_symlinks); } else{ $this->on_error ("Cannot copy file: \"$oldname\" (it's neither a file nor a directory)."); } } // MY_DIR_COPY function my_dir_copy($oldname, $newname, $follow_symlinks=true) { $this->my_mkdir($newname); $dir = $this->my_opendir($oldname); while($file = readdir($dir)){ if($file == "." || $file == ".."){ continue; } if($this->my_dir_exists($oldname.$this->conf['slash'].$file) && $this->my_dir_exists($newname.$this->conf['slash'].$file)) { $this->my_dir_copy($oldname.$this->conf['slash'].$file, $newname.$this->conf['slash'].$file, $follow_symlinks); } else $this->my_copy($oldname.$this->conf['slash'].$file, $newname.$this->conf['slash'].$file, $follow_symlinks); } closedir($dir); } // MY_IS_WRITABLE function my_is_writable($file) { if(!$this->my_file_exists($file)){ return true; } $fp = $this->run_silently("fopen", $file, "w"); if($fp == false){ return false; } else{ fclose($fp); return true; } } // MY_SYMLINK function my_symlink($from, $to) { $this->my_unlink($to); $this->logger->log ("Symlinking $to -> $from"); return $this->run_silently("symlink", $from, $to); } // MY_DELETE function my_delete($file) /* recursive deletion of directories and files */ { if($this->my_file_exists($file) || $this->my_link_exists($file)){ $this->logger->log ("Deleting: $file"); $this->my_unlink($file); } else if($this->my_dir_exists($file)){ $this->logger->log ("Removing directory: $file"); $this->run_command("rm -rf $file"); } } // MY_MKDIR_SILENTLY function my_mkdir_silently($dir) { return $this->my_mkdir_long($dir, true); } // MY_MKDIR_LONG function my_mkdir_long($dir, $silent = false) { if(!$this->my_dir_exists($dir)){ if ($this->is_broken_link ($dir)) { $this->my_unlink ($dir); } $this->run_command("mkdir -p '$dir'", "Cannot create directory: $dir"); } return true; } // MY_MKDIR function my_mkdir($dir, $silent = false) { if(!$this->my_dir_exists($dir)){ $this->logger->log ("Creating directory: $dir"); if(!$this->run_silently("mkdir", $dir)){ if(!$silent){ $this->on_error ("Cannot create directory: $dir"); } return false; } } return true; } // IS_BROKEN_LINK function is_broken_link($file) { return ($this->strip_symlink($file) == ""); } // MY_LIST_DIR function my_list_dir($path, $pattern) { if(function_exists('glob')) { return glob($this->make_path($path, $pattern)); } $files_list = array(); $dir = $this->my_opendir($path); while($file = readdir($dir)){ if($file == "." || $file == ".."){ continue; } if($this->my_fnmatch($pattern, $file)){ array_push($files_list, $this->nice_path("$path/$file")); } } closedir($dir); return $files_list; } // MY_BACKUP function my_backup($file, $backup_link_dest=false) { if($this->my_link_exists($file)){ /* don't backup links */ if($backup_link_dest){ $dest = $this->strip_symlink($file); if(empty($dest)){ $this->my_unlink($file); } else{ $this->logger->log ("Backing-up link destination: $dest"); $this->my_copy($dest, $dest.$this->conf['backup_suffix']); $new_file = $dest.$this->conf['backup_suffix']; } } else{ $this->logger->log ("Not backing-up a link: $file"); } } elseif($this->my_file_exists($file)){ $this->logger->log ("Backing-up file: $file"); $this->my_copy($file, $file.$this->conf['backup_suffix']); $new_file = $file.$this->conf['backup_suffix']; } elseif($this->my_dir_exists($file)){ $this->logger->log ("Backing-up directory: $file"); $this->my_move($file, $file.$this->conf['backup_suffix'], true); $new_file = $file.$this->conf['backup_suffix']; } return isset($new_file) ? $new_file : null; } // MY_FNMATCH function my_fnmatch($pattern, $file) { if(function_exists('fnmatch')) { return fnmatch ($pattern, $file); } $lenpattern = strlen($pattern); $lenfile = strlen($file); for($i=0 ; $i<$lenpattern ; $i++) { if($pattern[$i] == "*") { for($c=$i ; $cmy_fnmatch(substr($pattern, $i+1), substr($file, $c))) return true; } return false; } if($pattern[$i] == "[") { $letter_set = array(); for($c=$i+1 ; $c<$lenpattern ; $c++) { if($pattern[$c] != "]") array_push($letter_set, $pattern[$c]); else break; } foreach($letter_set as $letter) { if($this->my_fnmatch($letter.substr($pattern, $c+1), substr($file, $i))) return true; } return false; } if($pattern[$i] == "?") continue; if($pattern[$i] != $file[$i]) return false; } if(($lenpattern != $lenfile) && ($pattern[$i - 1] == "?")) return false; return true; } // MY_SCANDIR function my_scandir($dir) { $files = array(); if($this->my_dir_exists ($dir)) { $fh = opendir($dir); while (false !== ($filename = readdir($fh))) { array_push($files, $filename); } closedir($fh); } return $files; } // FIND_FILE function find_file($dir, $pattern, $ret_arr=null) { $num_files = 0; if($this->my_dir_exists ($dir)) { $files = preg_grep ("/^\.+$/", $this->my_scandir ($dir), PREG_GREP_INVERT);; foreach ($files as $file) { $num_files += $this->find_file ($this->make_path($dir, $file), $pattern, $ret_arr); } } else if($this->my_file_exists ($dir)) { if($this->my_fnmatch($pattern, basename($dir))) { if(is_array($ret_arr)) { array_push ($ret_arr, $dir); } return 1; } } return $num_files; } // FILECMP function filecmp($file1, $file2) { return strcmp(file2str($file1), file2str($file2)); } // STR2FILE function str2file($str , $file) { $fp = $this->my_fopen($file, "w"); $ret = fwrite($fp, $str); fclose($fp); return $ret; } // FILE_WORD_WRAP function file_word_wrap($file) { $this->logger->log ("Wrapping text from file: $file"); $tmp_file = $this->conf['tmp_dir'].$this->conf['slash'].basename($file).".wrapped"; $this->str2file(wordwrap($this->file2str($file), $this->conf['wrap_size']), $tmp_file); return $tmp_file; } // MY_OPENDIR function my_opendir($path) { if(!$this->my_dir_exists($path)){ $this->on_error("No such directory: $path"); } $dir = $this->run_silently("opendir", $path); if(empty($dir)){ $this->on_error("Cannot open directory: $path for reading"); } return $dir; } // PUSHD function pushd($dir) { $cwd = getcwd(); if(empty($cwd)){ $this->on_error("Unable to store the current working directory."); } if(!isset($this->conf['cwd'])) { $this->conf['cwd'] = array(); } array_push($this->conf['cwd'], $cwd); $this->my_chdir($dir); } // POPD function popd() { if(!isset($this->conf['cwd'])) { $error = "Current directory is not stored"; } $cwd = array_pop($this->conf['cwd']); if(!chdir($cwd)){ $error = "Can't change directory to: $cwd"; } if(isset($error)) { $this->on_error("Unable to restore the current working directory.\n$error"); } } // MY_CHDIR function my_chdir($dir, $log=false) { if ($log) { $this->logger->log ("Changing directory to: $dir"); } if(!chdir($dir)){ $this->on_error("Unable to change directory to: $dir"); } } // GET_FILE_TREE function get_file_tree($dir, &$file_tree) { $totalsize = 0; $file_tree = array(); $this->get_file_tree_a($dir, $file_tree, $totalsize); return $totalsize; } function get_file_tree_a($path, &$file_tree, &$totalsize) /* returns number of files */ { $dir = $this->my_opendir($path); $num_files = 0; while($file = readdir($dir)){ if($file != "." && $file != ".."){ if($this->my_file_exists("$path/$file")){ $size = filesize($path.$this->conf['slash'].$file); $file_tree[$path.$this->conf['slash'].$file] = $size; $totalsize += $size; } elseif($this->my_dir_exists($path.$this->conf['slash'].$file)){ if($this->get_file_tree_a($path.$this->conf['slash'].$file, $file_tree, $totalsize)==0){ $file_tree[$path.$this->conf['slash'].$file] = 0; /* if directory is empty put it into components array */ } } $num_files ++; } } closedir($dir); return $num_files; } // ------------------------------ // DIALOG FUNCTIONS // ============================== // MY_READLINE function my_readline($msg = "[To continue, press Enter]") { print($msg); flush(); if($this->conf['interactive']) { exec("read OUTPUT\necho \$OUTPUT", $output); } print ("\n"); return isset($output[0]) ? $output[0] : ""; } // RUNDIALOG function rundialog($mode, $msg, $extra_args=null) { $this->progress_bar_stop(); $command = $this->conf['dialog']; # Strip not always displayable HTML and PHP tags: $msg = strip_tags ($msg); # remove ascii escape sequences(not suitable for dialog) $msg = preg_replace('/\\033[0-9;\[]*m/', '', $msg); # If message is empty escapeshellarg() returns empty string, instead of expected '' $msg = strlen($msg) ? $msg : " "; switch($mode) { case 'fselect': case 'msgbox': case 'inputbox': case 'passwordbox': case 'noyes': if($mode == "noyes") { $command .= " --defaultno "; $mode = "yesno"; } case 'yesno': case 'infobox': if ($mode == "infobox") $command .= " --sleep 1 "; case 'menu': case 'checklist': $command .= sprintf(" --%s %s 0 0", $mode, escapeshellarg("{$msg}\n")); break; case 'textbox': $command .= sprintf(" --%s %s 0 0", $mode, escapeshellarg($msg)); break; default: print("Unsupported dialog option\n"); return(''); } if (is_array ($extra_args)) { foreach ($extra_args as $arg) { $arg = strlen($arg) ? $arg : " "; $command .= " ".escapeshellarg ($arg); } } else if ($extra_args !== null) { $extra_args = strlen($extra_args) ? $extra_args : " "; $command .= " ".escapeshellarg ($extra_args); } $rc = $this->dialog_execute($command); if((($mode == 'passwordbox') || ($mode == 'inputbox')) && ($rc>0)) { // Cancel pressed. return -1; } $dialog_output = $this->dialog_get_output(); if(preg_match ('/Error opening terminal/', $dialog_output)) { unset($this->conf['dialog']); $this->on_error($this->conf['dialog_error']); } return($mode == 'yesno' ? 1 - $rc : $dialog_output); } function floating_box($msg) { } // MSGBOX function msgbox($msg) { $this->progress_bar_stop(); $this->logger->log ("MSGBOX: \n\"$msg\""); if(!empty($this->conf['dialog'])){ $this->rundialog("msgbox", "\n{$msg}"); } else{ print("\n$msg\n"); $this->my_readline(); } } // INPUTBOX function inputbox($msg, $init="", $accept_empty=false, $show_empty_msg=true) { $this->progress_bar_stop(); $this->logger->log ("ASK: $msg"); do { if(!empty($this->conf['dialog'])){ while(true) { if ($show_empty_msg && $accept_empty && $init == "") { $msg .= "\n\nPress OK to leave empty."; } $input = $this->rundialog("inputbox", "\n{$msg}", $init); if(!$accept_empty && $input == -1) { $this->on_abort(); continue; } break; } } else{ // replace last ':' if it exits and trim : $msg = preg_replace("/\:\s*$/", "", $msg); if($show_empty_msg && $accept_empty && $init == ""){ $init = "Press ENTER to leave empty"; } $prompt = "{$msg}: "; if (!empty ($init)) { if (preg_match ('/\n$/', $msg)) { $prompt = "{$msg}[{$init}]: "; } else { $prompt = "{$msg} [{$init}]: "; } } $input = $this->my_readline ($prompt); if($input == "" && $init != "Press ENTER to leave empty") { $input = $init; } } $this->logger->log ("INPUTBOX: $input"); } while((empty($input) || preg_match("/^\s*$/", $input)) && !$accept_empty); $input = trim($input); /* trim the line */ $input = addslashes($input); /* add the back slashes to illegal characters */ return $input; } // INPUTBOX_BOUNDED function inputbox_bounded($msg, $what, $min_chars, $max_chars, $init="", $accept_empty=false) { while(true) { $output = $this->inputbox($msg, $init, $accept_empty); if(strlen($output) < $min_chars) { $this->msgbox("A $what should contain at least $min_chars characters. Please try again."); continue; } if(strlen($output) > $max_chars) { $this->msgbox("A $what should contain at most $max_chars characters. Please try again."); continue; } break; } return $output; } // YESNOBOX function yesnobox($msg, $defaultno=false, $abort_on_no=false) { $this->progress_bar_stop(); $this->logger->log ("YESNO: $msg"); $answer = false; $default = ($defaultno ? "NO" : "YES"); while(true) { if(!empty($this->conf['dialog'])){ if($defaultno) { $answer = $this->rundialog("noyes", "\n{$msg}"); } else { $answer = $this->rundialog("yesno", "\n{$msg}"); } } else{ print("\n$msg\n"); do{ $output = $this->my_readline("Answer (yes or no) [$default]: "); if(preg_match("/^\s*$/", $output)){ $output = $default; } if(strcasecmp($output, "yes") == 0 || strcasecmp($output, "y") == 0){ $answer = true; break; } if(strcasecmp($output, "no") == 0 || strcasecmp($output, "n") == 0){ $answer = false; break; } }while(true); } if($abort_on_no && !$answer) { $this->on_abort(); continue; } print("\n"); break; } $result = $answer ? "YES" : "NO"; $this->logger->log ("User choose: $result"); return $answer; } // INFOBOX function infobox($msg) { $this->progress_bar_stop(); $this->logger->log ("INFOBOX: \n\"$msg\""); if(!empty($this->conf['dialog'])){ $this->rundialog("infobox", "\n{$msg}"); } else{ print("\n$msg\n\n"); } } // PASSWDBOX function passwdbox($msg, $accept_cancel=false) { $this->progress_bar_stop(); do{ if(!empty($this->conf['dialog'])){ while(true) { $passwd = $this->rundialog("passwordbox", $msg); if($passwd == -1 && !$accept_cancel) { $this->on_abort(); continue; } break; } }else{ print("\n$msg"); exec("stty -echo"); $passwd = $this->my_readline(""); exec("stty echo"); //print("\n"); } } while(empty($passwd) || preg_match("/^\s*$/", $passwd)); $this->logger->log ("PASSWDBOX: " . preg_replace ("/\w/", "X", $passwd)); return($passwd); } // PASSWORD_CHECK function password_check($passwd, $num_chars=4) { if(strlen($passwd) < $num_chars){ $this->msgbox("A password should contain at least $num_chars characters. Please try again."); return false; } if(0 && (urlencode($passwd) != $passwd) or (strpos($passwd, "_") !== false)){ $this->msgbox("Illegal password. The password may contain only:\n\n" ."a) The alphanumeric characters 'a' through 'z',\n 'A' through 'Z' and '0' through '9'\n" ."b) The special characters '.' and '-'\n\n" ."Please try again.\n"); return false; } return true; } // PASSWORD_GET function password_get($msg="", $num_chars=4, $accept_cancel=false) { while(true) { $passwd = $this->passwdbox("$msg\n\nPassword: ", $accept_cancel); if($passwd != -1 && !$this->password_check($passwd, $num_chars)) { continue; } break; } return $passwd; } // PASSWORD_CHOOSE function password_choose($msg="", $num_chars=4, $accept_cancel=false) { while(true){ $passwd = $this->password_get($msg, $num_chars, $accept_cancel); if($passwd == -1) { return $passwd; } $checkpasswd = $this->passwdbox("Verify the password: "); if(strcmp($passwd, $checkpasswd) == 0){ printf ("\n"); break; } $this->msgbox("Passwords did not match, please try again."); } return $passwd; } // MENUBOX function menubox($msg, $menu_arr_orig, $allow_blank=false, $abort_msg="", $default=null) { $this->progress_bar_stop(); $this->logger->log ("MENU: $msg\n:" . var_export ($menu_arr_orig, true)); $temp_hash = array(); $menu_arr = array(); $index = 1; foreach($menu_arr_orig as $key=>$val){ if($default !== null && $default == $key) { $default_index = $index; } $temp_hash[$index] = $key; $menu_arr[$index] = $val; $index ++; } $default = isset($default_index)?$default_index:null; if(!empty($this->conf['dialog'])) { $menu_params = array ('0'); $item_len = 0; foreach ($menu_arr as $tag => $menu_item){ $menu_params[] = $tag; $menu_params[] = $menu_item; if(strlen($menu_item) > $item_len){ $item_len = strlen($menu_item); } } if($item_len > strlen($msg)-6){ /* message must be longer than items */ $len_add = $item_len - strlen($msg); $len_add = (strlen($msg)+10 > $this->conf['wrap_size'])? $this->conf['wrap_size'] - strlen($msg) : $len_add + 10; $msg .= str_repeat(" ", $len_add); } $msg = wordwrap($msg, $this->conf['wrap_size']); while(true) { $choice = $this->rundialog("menu", "\n{$msg}", $menu_params); if(!$choice) { if($allow_blank) { $choice = ""; } else { $this->on_abort($abort_msg); continue; } } else { $choice = $temp_hash[$choice]; } break; } } else { $msg = $this->add_dashes($msg); $count_lines = 0; $str = "\n$msg\n\n"; foreach ($menu_arr as $tag => $menu_item){ $str .= "[$tag] $menu_item\n"; $count_lines ++; } do { if($count_lines > 20){ $tmp_file = $this->make_path($this->conf['tmp_dir'], "tmp.scroll"); $this->str2file($str, $tmp_file); $this->show_file($tmp_file, false); } else{ print($str); } while(true){ $quest = "\nPlease select "; if ($default !== null) { $quest .= "[$default]"; } else if ($allow_blank) { if($count_lines > 20){ $quest .= "[S - show again, ENTER - leave empty]"; } else { $quest .= "[Press ENTER to leave empty]"; } } else if ($count_lines > 20) { $quest .= "[S - show again]"; } $quest .= ": "; $output = $this->my_readline($quest); if($output == "S" || $output == "s") { break; } if(empty($output) && $default !== null) { $output = $default; } if(empty($output) && $allow_blank){ /* if ENTER was pressed */ $choice = ""; break; } if(isset($menu_arr[$output])){ /* if this value exists */ $choice = $temp_hash[$output]; break; } else { if(!empty($output)) { $this->infobox("Illegal input: $output"); } } } } while(!isset($choice)); print("\n"); } $this->logger->log ("User's choice: $choice"); return $choice; } // CHECKLIST /* * @param string Text to display in the checklist box * @param array choices (key => choice) * @param array fired choices (choice => 1) * @return array fired choices (choice => 1) */ function checklist ($text, $choices, $default_choices=null) { if ($default_choices === null || !is_array($default_choices)) { $default_choices = array(); } $retval = array(); // Use integer counter for defining keys: $new_key = 1; $new_default_choices = array(); foreach ($choices as $orig_key => $choice) { $new_choices[$new_key] = $choice; $keys_f[$new_key] = $orig_key; if (isset($default_choices [$orig_key])) { $new_default_choices [$new_key] = 1; } $new_key ++; } $default_choices = $new_default_choices; $choices = $new_choices; if (empty($this->conf["dialog"])) { // Display text: print "\n{$text}\n\n"; // Until a legal option will be choosen do { // Display choices: $line = ""; foreach ($choices as $key => $choice) { if (isset($default_choices [$key])) { $line .= sprintf ("[X] %d. %s\n", $key, $choice); } else $line .= sprintf ("[ ] %d. %s\n", $key, $choice); } print "{$line}\n"; // Read the answer: $res = $this->my_readline ("[Change setting or press ENTER to continue]: "); // On empty answer - finish setting values if ($res === "") { foreach ($default_choices as $key => $value) { $retval [$keys_f[$key]] = $value; } break; } if (isset($keys_f[$res])) { if(isset($default_choices[$res])) { unset ($default_choices[$res]); } else $default_choices[$res] = 1; continue; } print "Illegal input: $res\n"; } while (true); } else { $checklist_params = array('0'); $item_len = 0; foreach ($choices as $key => $choice) { $checklist_params[] = $key; $checklist_params[] = $choice; $checklist_params[] = isset($default_choices [$key]) ? "On" : "Off"; if(strlen($choice) > $item_len){ $item_len = strlen($choice); } } if($item_len > strlen($text)-8){ /* message must be longer than the longer of items */ $len_add = $item_len - strlen($text); $len_add = (strlen($text)+10 > $this->conf['wrap_size'])? $this->conf['wrap_size'] - strlen($text) : $len_add + 10; $text .= str_repeat(" ", $len_add); } $text = wordwrap($text, $this->conf['wrap_size']); while(true) { $res = $this->rundialog("checklist", "\n{$text}", $checklist_params); if(!$res) { return array(); } else { $res = trim ($res, "\" \t "); foreach (array_flip (explode ("\" \"", $res)) as $key => $val) { $key = trim ($key, "\" \t "); $retval[$keys_f[$key]] = 1; } } break; } } return $retval; } // SHOW_FILE function show_file($file, $clean=true) { $this->progress_bar_stop(); if(!$this->conf['interactive']) { return; } $file = $this->file_word_wrap($file); if(!empty($this->conf['dialog'])){ $this->rundialog("textbox", $file); } else{ $this->clrscr(); popen("cat $file | more", "w"); if($clean){ $this->clrscr(); } } } // PROGRESS_BAR_START /* start external process with dialog progress bar */ function progress_bar_start($seconds, $message, $message_tty=null) { $message = "\n\n".$message; if(!$message_tty){ $message_tty = $message; } $pb_proc_env = array(); $pb_proc_env["TIME"] = $seconds; /* set progress bar timeout */ $pb_proc_env["MESSAGE"] = $message; $pb_proc_env["MESSAGE_TTY"] = $message_tty; $pb_proc_env["TITLE"] = $this->conf['title']; if(!empty($this->conf['dialog'])){ $pb_proc_env["DIALOG"] = $this->conf['dialog']; /* set path to dialog */ } $this->conf['progress_pid_file'] = $this->conf['tmp_dir'].$this->conf['slash']."progress_bar.pid"; $this->conf['progress_fatal_file'] = $this->conf['tmp_dir'].$this->conf['slash']."kill_progress_bar"; if (@file_exists ($this->conf['progress_fatal_file'])) { @unlink ($this->conf['progress_fatal_file']); } $pb_proc_env["PID_FILE"] = $this->conf['progress_pid_file']; $pb_proc_env["FATAL_FILE"] = $this->conf['progress_fatal_file']; $dspec = array( 0 => array("pipe", "r"), 2 => array("pipe", "w") ); $proc_env = ""; foreach ($pb_proc_env as $key => $val) { $val = strlen($val) ? $val : " "; $proc_env .= "{$key}=".escapeshellarg($val)." "; } if (isset($this->conf['php_run_cmd'])) { $php_cmd = $this->conf['php_run_cmd']; } else { $php_cmd = "./php -c ./php-install.ini"; } touch ($this->conf['progress_pid_file']); $this->conf['progress_fp'] = proc_open ("{$proc_env} {$php_cmd} -q ".dirname(__FILE__)."/progress_bar.php", $dspec, $pipes); $this->conf['progress_bar_started'] = true; } // PROGRESS_BAR_STOP function progress_bar_stop() /* stop the progress bar by killing it */ { if (!$this->conf['progress_bar_started']) { return; } while(!file_exists($this->conf['progress_pid_file'])); // Wait for process to create a file sleep(1); @touch($this->conf['progress_fatal_file']); @proc_close($this->conf['progress_fp']); if(empty($this->conf['dialog'])){ print("\n"); } $this->conf['progress_bar_started'] = false; sleep(1); } // DIALOG_CALC_MAX_SIZE function dialog_calc_max_size() { if(empty($this->conf['dialog'])){ return -1; } $this->dialog_execute($this->conf['dialog']." --print-maxsize"); $out = $this->dialog_get_output(); if(preg_match("/.*:\s(.*),\s(.*)$/m", $out, $match)){ $this->conf['max_y'] = $match[1]; $this->conf['max_x'] = $match[2]; } } // DIALOG_EXECUTE function dialog_execute($dialog_cmd) { if(empty($this->conf['dialog'])){ $this->logger->log ('Tried to run a dialog utility, while it doesn\'t exist!'); return -1; } $this->logger->log ($dialog_cmd); $fd = $this->my_popen("$dialog_cmd 2>". $this->conf['dialog_tmp'], "w", false); if(empty($fd)){ $this->on_error($this->conf['dialog_error']); } $status = $this->safe_pclose($fd); return $status; } // DIALOG_GET_OUTPUT function dialog_get_output() { if(!empty($this->conf['dialog'])){ return $this->file2str($this->conf['dialog_tmp']); } return false; } // ----------------------------- // WEBSERVER FUNCTIONS // ============================= // WEBSERVER_SUPPORTED_CHECK function webserver_supported_check($name) { if(empty($this->conf['supported_webservers'])){ return true; } else{ return array_search($name, $this->conf['supported_webservers']); } } // WEBSERVER_CHOOSE function webserver_choose($errmsg="") { if($this->conf['webserver'] != "Web server") { return true; } if(empty($this->conf['supported_webservers'])){ return false; } if(count($this->conf['supported_webservers']) == 1){ if($this->yesnobox("Are you using ".$this->conf['supported_webservers'][1]." Web server?")){ $this->conf['webserver'] = $this->conf['supported_webservers'][1]; } else{ if(empty($errmsg)){ $errmsg = "For now ".$this->conf['product']." supports only ". $this->conf['supported_webservers'][1]. " on ". $this->conf['uname']['sysname']; } $this->on_abort($errmsg, true); } } else{ $rc = $this->menubox("Choose one of supported Web servers:", $this->conf['supported_webservers'], false, $errmsg); $this->conf['webserver'] = $this->conf['supported_webservers'][$rc]; } } // WEBSERVER_ROOT_GUESS function webserver_root_guess() { if(empty($this->conf['webserver_root_dir'])){ $webserver_root = ""; if($this->conf['webserver'] == "Apache"){ $webserver_root = $this->apache_root_guess(); } else if($this->conf['webserver'] == "Zeus" && $this->my_dir_exists("/usr/local/zeus")) { $webserver_root = "/usr/local/zeus"; } else if($this->conf['webserver'] == "SunONE" && $this->my_dir_exists("/opt/SUNWwbsvr")) { $webserver_root = "/opt/SUNWwbsvr"; } $word = empty($webserver_root) ? "enter" : "confirm"; $this->conf['webserver_root_dir'] = $this->select_dir("Please $word your ".$this->conf['webserver']. " root directory", $webserver_root); if($this->conf['webserver'] == "Zeus"){ $this->conf['zeus_root'] = $this->conf['webserver_root_dir']; } else if($this->conf['webserver'] == "SunONE") { $this->conf['sunone_root'] = $this->conf['webserver_root_dir']; } } return $this->conf['webserver_root_dir']; } // WEBSERVER_DOCROOT_GUESS function webserver_docroot_guess() { if(isset($this->conf['webserver_doc_root']) && $this->my_dir_exists($this->conf['webserver_doc_root'])){ return $this->conf['webserver_doc_root']; } $this->logger->log ('Trying to guess ' . $this->conf['webserver'] . ' docroot ...'); $default = ""; if($this->conf['webserver'] == "Apache"){ $default = $this->apache_docroot_guess(); } elseif($this->conf['webserver'] == "Zeus"){ $default = $this->zeus_docroot_guess(); } elseif($this->conf['webserver'] == "SunONE"){ $default = $this->sunone_docroot_guess(); } else{ $default = "/var/www/html"; } $manually_set = false; if(!isset($this->conf['webserver_doc_root'])) { $manually_set = true; } else if(!$this->my_dir_exists($this->conf['webserver_doc_root'])) { $this->msgbox("Directory:\n".$this->conf['webserver_doc_root']."\ndoesn't exist!"); $manually_set = true; } if($manually_set) { $word = empty($default) ? "enter" : "confirm"; $this->conf['webserver_doc_root'] = $this->select_dir( "Please $word the location of your ".$this->conf['webserver']." document root directory.\n". "This is the location where your web documents are stored", $default); } $this->logger->log ('Guessed: ' . $this->conf['webserver_doc_root']); return $this->conf['webserver_doc_root']; } function webserver_docroot_set ($docroot) { $this->conf['webserver_doc_root'] = $docroot; } // WEBSERVER_GET_USER function webserver_get_user($msg="") { $this->logger->log ('Trying to guess ' . $this->conf['webserver'] . '\'s UID'); $user = ""; if($this->conf['webserver'] == "Apache"){ $user = $this->apache_user_guess(); } else if($this->conf['webserver'] == "Zeus"){ $user = $this->zeus_user_guess(); } else if($this->conf['webserver'] == "SunONE"){ $user = $this->sunone_user_guess(); } $word = empty($user) ? "enter" : "confirm"; if(empty($msg)){ $msg = "\nPlease $word the username that your PHP scripts run as under ".$this->conf['webserver']; } $default = $user; while(true){ $user = $this->inputbox($msg, $default); // Verify whether such user really exists: if (posix_getpwnam($user) !== false) { break; } if(!$this->yesnobox("Cannot find user: '$user'\nDo you want to try again?")){ $this->on_error("The installation cannot continue."); } } if($this->conf['webserver'] == "Apache"){ $this->conf['apache_user'] = $user; } return $user; } // WATCH_CONFIG_FILES function watch_config_files () { $config_files = func_get_args(); foreach ($config_files as $config) { $this->conf['config_files'][$config] = @filemtime ($config); } } // WEBSERVER_NEEDS_RESTART function webserver_needs_restart() { $needs_restart = false; if (@isset ($this->conf['config_files'])) { foreach ($this->conf['config_files'] as $config => $atime) { if ($atime != @filemtime ($config)) { $needs_restart = true; break; } } } return $needs_restart; } // WEBSERVER_RESTART function webserver_restart($silent=false) { $this->logger->log ('Trying to restart ' . $this->conf['webserver'] . ' ...'); $restarted=false; if($this->conf['webserver'] == "Apache"){ $restarted = $this->apache_restart($silent); } elseif($this->conf['webserver'] == "Zeus"){ $restarted = $this->zeus_restart($silent); } elseif($this->conf['webserver'] == "SunONE"){ $restarted = $this->sunone_restart($silent); } else{ $this->warn("Don't know how to restart ". $this->conf['webserver']); } if($restarted){ if (@isset ($this->conf['config_files'])) { foreach ($this->conf['config_files'] as $config => $atime) { $this->conf['config_files'][$config] = @filemtime ($config); } } if (!$silent) { $this->msgbox($this->conf['webserver']." has restarted successfully."); } return true; } $this->msgbox("Installation failed to restart your Web server,\nplease restart it manually."); return false; } // WEBSERVER_VERIFY_RUNNING function webserver_verify_running($abort_on_cancel=false) { $running = false; if($this->conf['webserver'] == "Apache") { $running = $this->apache_is_running(); } elseif ($this->conf['webserver'] == "Zeus") { $running = $this->zeus_is_running(); } if(!$running) { $this->yesnobox ( "The installation has detected that your ".$this->conf['webserver']." Web server\n". "is currently not running. In order to continue with the installation,\n". "it must be started. Do you want to start it now?", false, $abort_on_cancel); $running = false; if($this->conf['webserver'] == "Apache") { $running = $this->apache_start(); } elseif ($this->conf['webserver'] == "Zeus") { $running = $this->zeus_start(); } if(!$running) { $button = empty ($this->conf['dialog']) ? "ENTER" : "OK"; $this->msgbox ("The installation could not start your ".$this->conf['webserver']." Web server.\n". "Please do it manually, then press {$button}"); $this->webserver_verify_running($abort_on_cancel); } } } // PHP_VERSION_DETECT_FROM_WEBSERVER function php_version_detect_from_webserver($silent = false) { $this->logger->log ('Detecting PHP version ...'); if($this->is_using_apache($silent)) { $this->php_version_detect_from_apache($silent); } elseif ($this->conf['webserver'] == "Zeus") { $this->php_version_detect_from_zeus($silent); } else { return false; } if(isset($this->conf['php_version'])){ if($silent) { if(!$this->php_version_substitute($silent)) { $this->conf['php_version'] = "unsupported"; return false; } else return true; } return $this->php_version_confirm(); } return false; } // WEBSERVER_GET_VIRTUAL_HOST_URL function webserver_get_virtual_host_url ($default=null, $use_default_host=false) { if($this->conf['webserver'] == "Apache") { return $this->apache_get_virtual_host ($default, $use_default_host); } elseif ($this->conf['webserver'] == "Zeus") { return $this->zeus_get_virtual_host_url ($default); } else return false; } // ----------------------------- // APACHE FUNCTIONS // ============================= // APACHE_ROOT_SET function apache_root_set($apache_root) { $this->conf['apache_root_dir'] = $apache_root; $this->conf['webserver_root_dir'] = $apache_root; } // APACHE_CONF_SET function apache_conf_set($apache_conf) { $this->conf['apache_conf_dir'] = $apache_conf; $this->conf['apache_conf_file'] = $this->make_path($apache_conf, "httpd.conf"); } // APACHE_EXEC_SET function apache_exec_set($apache_exec) { $this->conf['apache_exec_dir'] = $apache_exec; $this->conf['apache_exec_file'] = $this->make_path($apache_exec, "httpd"); } // APACHE_LIBEXEC_SET function apache_libexec_set($apache_libexec) { $this->conf['apache_libexec_dir'] = $apache_libexec; } // APACHE_CONF_OPEN function apache_conf_open() { $this->apache_conf_guess(); if(!empty($this->conf['apache_conf_cont'])) { return $this->conf['apache_conf_cont']; } if(empty($this->conf['apache_conf_cont']) && $this->my_file_exists ($this->conf['apache_conf_file'])) { $this->conf['apache_conf_cont'] = ""; $this->logger->log ('Opening Apache configuration file.'); $apache_cont = $this->file2str($this->conf['apache_conf_file']); foreach(explode("\n", $apache_cont) as $line) { if(preg_match("@^\s*Include\s+\"?([^\s\"]+)\"?@", $line, $match)) { /* insert include file */ $include_path = $match[1]; /* Guess Apache root directory */ if(preg_match("#^\s*ServerRoot\s+\"?([^\s\"]+)\"?#m", $apache_cont, $match)){ $this->conf['apache_root_dir'] = $match[1]; } if(empty($this->conf['apache_root_dir'])) { $this->apache_guess_from_binary(); } $include_path = $this->make_full_path($include_path, isset($this->conf['apache_root_dir']) ? $this->conf['apache_root_dir'] : ""); $include_files_arr = array(); if(preg_match("@\*@", $include_path)) { $include_files_arr = $this->my_list_dir($this->my_dirname($include_path), basename($include_path)); } else if($this->my_dir_exists($include_path)) { $include_files_arr = $this->my_list_dir($include_path, "*"); } else { $include_files_arr[0] = $include_path; } if(is_array ($include_files_arr)) { foreach ($include_files_arr as $include_file) { $this->logger->log ('Found "Include" directive in ' . $this->conf['apache_conf_file'] . ": $include_file"); if($this->my_file_exists($include_file)) { $this->conf['apache_conf_cont'] .= "# zend_open<$include_file>\n"; $this->conf['apache_conf_cont'] .= $this->file2str($include_file); $this->conf['apache_conf_cont'] .= "# zend_close<$include_file>\n"; } else { $this->logger->log ("File: $include_file doesn't exist"); } } } } $this->conf['apache_conf_cont'] .= "$line\n"; } } else { $this->conf['apache_conf_cont']=""; } $this->conf['apache_conf_modified'] = false; return $this->conf['apache_conf_cont']; } // APACHE_CONF_CLOSE function apache_conf_close() { if(empty($this->conf['apache_conf_cont'])){ return false; } // Save only modified httpd.conf if($this->conf['apache_conf_modified']) { // Backup the old configuration $this->logger->log ('Closing Apache configuration file.'); /* backup httpd.conf */ $apache_conf_backup = $this->my_backup($this->conf['apache_conf_file'], true); if(isset($apache_conf_backup)) { $this->msgbox("Backed up Apache configuration file to:\n$apache_conf_backup"); } if(preg_match_all("@# zend_open<(.*)>\n(.*)# zend_close<\\1>\n@Us", $this->conf['apache_conf_cont'], $match)) { for($i=0; $ifile2str($match[1][$i])) != 0) { /* If changed this file - backup the original */ $this->my_backup($match[1][$i], true); } $this->str2file($match[2][$i], $match[1][$i]); /* Write all includes to their destinations */ } } $this->conf['apache_conf_cont'] = preg_replace("@# zend_open<(.*)>\n.*# zend_close<\\1>\n@Us", "", $this->conf['apache_conf_cont']); $this->str2file($this->conf['apache_conf_cont'], $this->conf['apache_conf_file']); } } // IS_USING_APACHE function is_using_apache($silent = false) { if($this->conf['webserver'] == "Apache"){ return true; } if($this->conf['webserver'] != "Web server"){ return false; } if(isset($this->conf['using_apache'])){ return ($this->conf['using_apache'] == "YES") ? true: false; } if($silent) { return false; } if($this->yesnobox("Are you using Apache Web server?")){ $this->conf['using_apache'] = "YES"; $this->conf['webserver'] = "Apache"; return true; } $this->conf['using_apache'] = "NO"; return false; } // APACHE_CONF_GUESS function apache_conf_guess($silent = false) /* guess configuration file */ { if(!$this->is_using_apache($silent)){ return false; } $this->apache_exec_guess(); if(!empty($this->conf['apache_conf_file'])){ return $this->conf['apache_conf_file']; } $this->logger->log ('Trying to guess Apache configuration file ...'); $possible_configs = array( "httpd.conf", /* Regular */ "httpsd.conf", /* For Apache compiled with SSL support */ "httpd2.conf", /* Some systems (like Mandrake 9.1) called so to Apache 2 configuration file */ "apache.conf", /* Some systems (like Mandrake 9.1)*/ "apache2.conf" /* Some systems (like Mandrake 9.1)*/ ); $apache_conf_default = array( /* default paths to config dir */ "/usr/local/apache/conf", "/usr/local/apache2/conf", "/etc/httpd/conf", "/usr/local/apache/etc/", "/usr/local/apache2/etc/", "/usr/local/etc/apache/", "/etc/apache", "/etc/httpd" ); if(@file_exists($this->conf['apache_conf_dir'])) { array_unshift ($apache_conf_default, $this->conf['apache_conf_dir']); } if(isset($this->conf['apache_root_dir'])) { array_unshift ($apache_conf_default, $this->make_path($this->conf['apache_root_dir'], "conf")); } $conf_default = $this->search_file($apache_conf_default, $possible_configs); if(isset($this->conf['default_apache_conf_file'])) { $conf_default = $this->conf['default_apache_conf_file']; } if(!$silent) { $this->conf['apache_conf_file'] = $this->select_file("Please specify the full path to the Apache configuration file (httpd.conf)", $conf_default); } else { $this->conf['apache_conf_file'] = $conf_default; } if(@file_exists($this->conf['apache_conf_file'])) { $this->apache_guess_from_conf(); $this->conf['apache_conf_dir'] = dirname($this->conf['apache_conf_file']); $this->conf['saved_config']['default_apache_conf_file'] = $this->conf['apache_conf_file']; $this->logger->log ('Found: ' . $this->conf['apache_conf_file']); } return $this->conf['apache_conf_file']; } // APACHE_EXEC_GUESS function apache_exec_guess($silent = false) /* guess exec. dir */ { if(!$this->is_using_apache($silent)){ return false; } if(!empty($this->conf['apache_exec_file'])){ return $this->conf['apache_exec_file']; } $this->logger->log ('Trying to guess Apache executable file ...'); $apachectls = array("apachectl", "httpdctl", "httpsdctl", "apache2ctl", "apache-sslctl"); $apache_dirs = array( /* default paths to bin dir */ 1 => "/usr/local/apache/bin", 2 => "/usr/local/apache2/bin", 3 => "/usr/sbin", 4 => "/usr/bin", 5 => "/usr/local/sbin", 6 => "/usr/local/bin" ); if(!empty($this->conf['apache_exec_dir'])) { array_unshift ($apache_dirs, $this->conf['apache_exec_dir']); } if(!empty($this->conf['apache_root_dir'])) { array_unshift ($apache_dirs, $this->make_path($this->conf['apache_root_dir'], "bin")); } $apachectl_def = $this->search_file($apache_dirs, $apachectls); do { $this->conf['apachectl_path'] = $this->select_file("Specify the full path to the Apache control utility (apachectl)", $apachectl_def); $file_type = $this->file_mime_type ($this->conf['apachectl_path']); $err = null; if(($file_type !== false && !strstr($file_type, "application/x-sh")) || ($file_type === false && !strstr($this->file2str ($this->conf['apachectl_path']), '#!/bin/sh'))) { $err = "Apache control utility should be a shell script"; } if(!@is_executable($this->conf['apachectl_path'])) { $err = "Apache control utility should be an executable shell script"; } if (!$err || $this->yesnobox ("{$err}!\nDo you still wish to use this path?")) { break; } } while (true); $this->logger->log ('Found apachectl: ' . $this->conf['apachectl_path']); $apachectl_cont = $this->file2str ($this->conf['apachectl_path']); if(preg_match ("@^\s*HTTPD\s*\=(.*)$@m", $apachectl_cont, $match)) { $arr = preg_split('@\s+@', trim($match[1], " \t\'\"")); if (isset($arr[0]) && $this->my_file_exists ($arr[0])) { $this->conf['apache_exec_file'] = $arr[0]; } } if(preg_match ("@^\s*PIDFILE\s*\=(.*)$@m", $apachectl_cont, $match)) { $this->conf['apache_pid_file'] = trim($match[1], " \t\'\""); $this->logger->log ('Found Apache PID file: ' . $this->conf['apache_pid_file']); } if(!isset($this->conf['apache_exec_file']) || !$this->my_file_exists($this->conf['apache_exec_file'])) { $this->conf['apache_exec_file'] = $this->select_file("Installation couldn't detect the location of Apache executable.\nPlease specify the full path to the Apache binary (httpd)", isset($this->conf['apache_exec_file']) ? $this->conf['apache_exec_file'] : ""); } $this->logger->log ('Found httpd: ' . $this->conf['apache_exec_file']); $this->conf['apache_exec_dir'] = dirname($this->conf['apache_exec_file']); $this->apache_guess_from_binary(); return $this->conf['apache_exec_file']; } // APACHE_GET_VIRTUAL_HOST function apache_get_virtual_host($default_host=null, $use_default_host=false) { $this->apache_guess_from_conf(); $host = $this->conf['uname']['nodename']; if($default_host) { $host = $default_host; } $docroot = $this->webserver_docroot_guess(); if(@is_array($this->conf['apache_vhosts'])) { foreach ($this->conf['apache_vhosts'] as $key => $arr) { if($arr['docroot'] == $docroot && $arr['port'] != "443") { $found_key = $key; break; } } } if(isset($found_key)) { if(!$use_default_host) { if(isset($this->conf['apache_vhosts'][$found_key]["server"])) { $host = $this->conf['apache_vhosts'][$found_key]["server"]; } else if(isset($this->conf['apache_vhosts'][$found_key]["ip"]) && preg_match("/^[\d+\.]+$/", $this->conf['apache_vhosts'][$found_key]["ip"])) { $host = $this->conf['apache_vhosts'][$found_key]["ip"]; } } if(!preg_match("/\:\d+$/", $host)) { $host .= ":".$this->conf['apache_vhosts'][$found_key]["port"]; } if($this->conf['apache_vhosts'][$found_key]['ssl']) { $host = "https://{$host}"; } else { $host = "http://{$host}"; } } return $host; } // APACHE_LIBEXEC_GUESS function apache_libexec_guess() { if(!$this->is_using_apache()){ return false; } if(!empty($this->conf['apache_libexec_dir'])){ return $this->conf['apache_libexec_dir']; } $this->apache_guess_from_conf(); $this->conf['apache_libexec_dir'] = $this->select_dir( "Please specify the location of your Apache modules\n(usually: HTTPD_ROOT/libexec):", $this->make_path($this->conf['apache_root_dir'], ($this->apache_get_version() == "2" ? "modules" : "libexec"))); $this->logger->log ('Found Apache libexec directory at: ' . $this->conf['apache_libexec_dir']); } // APACHE_ROOT_GUESS function apache_root_guess() { if(!$this->is_using_apache()){ return false; } if(!empty($this->conf['apache_root_dir'])){ return $this->conf['apache_root_dir']; } $this->apache_guess_from_conf(); if(empty($this->conf['apache_root_dir'])){ $this->apache_guess_from_binary(); } if(empty($this->conf['apache_root_dir'])){ /* set default apache root directory */ $this->conf['apache_root_dir'] = $this->nice_path($this->conf['apache_conf_dir']."../"); } return $this->conf['apache_root_dir']; } // APACHE_DOCROOT_GUESS function apache_docroot_guess() { if(!$this->is_using_apache()){ return false; } if(!empty($this->conf['webserver_doc_root'])){ return $this->conf['webserver_doc_root']; } $default = ""; $this->apache_guess_from_conf(); if(count($this->conf['webserver_docroot_arr']) == 0) { $possible_dirs = array( 1 => '/usr/local/apache/htdocs', 2 => '/usr/local/apache2/htdocs', 3 => '/var/www/html', 4 => '/var/lib/apache/htdocs', 5 => '/var/lib/apache2/htdocs', 6 => '/usr/local/httpd/htdoc', 7 => '/home/httpd/html' ); if(isset($this->conf['apache_root_dir'])) { array_unshift($possible_dirs, $this->make_path($this->conf['apache_root_dir'], "htdocs")); } $default = $this->search_dir($possible_dirs); } else if(count($this->conf['webserver_docroot_arr']) >1 && count($this->conf['webserver_docroot_arr']) <5) { array_push($this->conf['webserver_docroot_arr'], "other"); while(true) { $num = $this->menubox("Please select the location of your Apache document root directory.\n". "This is the location where your web documents are stored.", $this->conf['webserver_docroot_arr']); if($this->conf['webserver_docroot_arr'][$num] == "other") { break; } else if($this->my_dir_exists($this->conf['webserver_docroot_arr'][$num])) { $this->conf['webserver_doc_root'] = $this->conf['webserver_docroot_arr'][$num]; break; } $this->msgbox("Broken Apache configuration!\n". "Document root: \"".$this->conf['webserver_docroot_arr'][$num]."\" doesn't exist"); } } else { $default = array_pop($this->conf['webserver_docroot_arr']); } return $default; } // APACHE_USER_GUESS function apache_user_guess() { if(!$this->is_using_apache()){ return false; } if(!empty($this->conf['apache_user'])){ return $this->conf['apache_user']; } $this->logger->log ('Trying to guess a User ID apache runs with ...'); $this->apache_guess_from_conf(); return empty($this->conf['apache_user'])? null : $this->conf['apache_user']; } // APACHE_ERRORLOG_GUESS function apache_errorlog_guess() { if(!empty($this->conf['apache_error_log'])){ return $this->conf['apache_error_log']; } $this->apache_guess_from_conf(); if(empty($this->conf['apache_error_log'])){ $this->apache_guess_from_binary(); } } // APACHE_GUESS_FROM_BINARY function apache_guess_from_binary() { if(!$this->is_using_apache()){ return false; } $this->apache_exec_guess(); $msg = "Guessed from Apache executable:"; $httpd_res = $this->cmd2str($this->conf['apache_exec_file']. " -V 2>/dev/null"); // Apache root if(empty($this->conf['apache_root_dir']) && preg_match("#HTTPD_ROOT=\"?([^\s\"]+)\"?\s*$#m", $httpd_res, $match)){ $this->conf['apache_root_dir'] = $match[1]; $this->logger->log ("$msg HTTPD_ROOT=" . $this->conf['apache_root_dir']); } // Apache version if(empty($this->conf['apache_version']) && preg_match("#^\s*Server version\:\s+Apache\/(\d+)#m", $httpd_res, $match)){ $this->conf['apache_version'] = $match[1]; $this->logger->log ("$msg APACHE_VERSION=" . $this->conf['apache_version']); } // Apache error log if(empty($this->conf['apache_error_log']) && preg_match("#DEFAULT_ERRORLOG=\"?([^\s\"]+)\"?\s*$#m", $httpd_res, $match)){ $this->conf['apache_error_log'] = $this->make_full_path($match[1], $this->conf['apache_root_dir']); $this->logger->log ("$msg ERROR_LOG=" . $this->conf['apache_error_log']); } // Apache config file if(empty($this->conf['apache_conf_file']) && preg_match("#SERVER_CONFIG_FILE=\"?([^\s\"]+)\"?\s*$#m", $httpd_res, $match)){ $this->conf['apache_conf_file'] = $this->make_full_path($match[1], $this->conf['apache_root_dir']); $this->conf['apache_conf_dir'] = dirname($this->conf['apache_conf_file']); $this->logger->log ("$msg APACHE_CONFIG=" . $this->conf['apache_conf_file']); } // Apache PID file if(empty($this->conf['apache_pid_file']) && preg_match("#DEFAULT_PIDLOG=\"?([^\s\"]+)\"?\s*$#m", $httpd_res, $match)){ $this->conf['apache_pid_file'] = $this->make_full_path($match[1], $this->conf['apache_root_dir']); $this->logger->log ("$msg DEFAULT_PIDLOG=".$this->conf['apache_pid_file']); } // guess Apache2 worker $httpd_l_res = $this->cmd2str($this->conf['apache_exec_file']. " -l 2>/dev/null"); if(empty($this->conf['apache2_worker']) && preg_match("#^\s*worker\.c#m",$httpd_l_res,$match)){ $this->conf['apache2_worker'] = "yes"; $this->install_log("$msg APACHE2 worker=".$this->conf['apache2_worker']); } else { $this->conf['apache2_worker'] = "no"; } return true; } // APACHE_GUESS_FROM_CONF function apache_guess_from_conf() { if(!$this->is_using_apache()){ return false; } if (@isset($this->conf['apache_guessed_from_conf'])) { return true; } $this->conf['apache_guessed_from_conf'] = true; if(!@isset($this->conf['apache_root_dir'])){ $this->conf['apache_root_dir']=""; } $this->apache_conf_open(); $msg = "Guessed from Apache httpd.conf:"; // Apache root if(empty($this->conf['apache_root_dir']) && preg_match("#^\s*ServerRoot\s+\"?([^\s\"]+)\"?#m", $this->conf['apache_conf_cont'], $match)){ $this->conf['apache_root_dir'] = $match[1]; $this->install_log("$msg HTTPD_ROOT=".$this->conf['apache_root_dir']); } // Error log if(empty($this->conf['apache_error_log']) && preg_match("#^\s*ErrorLog\s+\"?([^\s\"]+)\"?#m", $this->conf['apache_conf_cont'], $match)){ $this->conf['apache_error_log'] = $this->make_full_path($match[1], $this->conf['apache_root_dir']); $this->install_log("$msg ERROR_LOG=".$this->conf['apache_error_log']); } // User if(empty($this->conf['apache_user']) && preg_match("#^\s*User\s+([^\s]*)\s*$#m", $this->conf['apache_conf_cont'], $match)){ $this->conf['apache_user'] = $match[1]; $this->install_log("$msg USER=".$this->conf['apache_user']); } // Port if(empty($this->conf['apache_port'])){ if(preg_match("#^\s*Port\s+([\d]+)\s*$#m", $this->conf['apache_conf_cont'], $match)){ $port = $match[1]; } else if(preg_match("#^\s*Listen\s+([\d]+)\s*$#m", $this->conf['apache_conf_cont'], $match)){ $port = $match[1]; } if(isset($port)){ $this->conf['apache_port'] = $port; $this->install_log("$msg PORT=".$this->conf['apache_port']); } } // Group if(empty($this->conf['apache_group']) && preg_match("#^\s*Group\s+([^\s]*)\s*$#m", $this->conf['apache_conf_cont'], $match)){ $this->conf['apache_group'] = $match[1]; $this->install_log("$msg GROUP=".$this->conf['apache_group']); } // MaxClients if(empty($this->conf['max_clients']) && preg_match("@^\s*MaxClients\s+([\d]+)\s*$@m", $this->conf['apache_conf_cont'], $match)) { $this->conf['max_clients'] = $match[1]; $this->install_log("$msg MaxClients=".$this->conf['max_clients']); } // PidFile if(preg_match("@^\s*PidFile\s+(.*)$@m", $this->conf['apache_conf_cont'], $match)) { $this->conf['apache_pid_file'] = $this->make_full_path(trim($match[1], " \t\"\'"), $this->conf['apache_root_dir']); $this->install_log("$msg PidFile=".$this->conf['apache_pid_file']); } // Server Name if(empty($this->conf['server_name']) && preg_match("@^\s*ServerName\s+([^\s]*).*]+>.*@sU", $this->conf['apache_conf_cont'], $match)) { } // Virtual hosts if(empty($this->conf['apache_vhosts']) && preg_match_all("@^\s*]+)>(.*)@msU", $this->conf['apache_conf_cont'], $match)) { for($i=0; $imy_dir_exists($vhost_docroot) && isset($vhost_ip) && isset($vhost_servername) && !preg_match("/\\\$/",$vhost_ip) && !preg_match("/\\\$/",$vhost_servername) ) { $vhost_docroot = $this->nice_path($vhost_docroot); $this->conf['apache_vhosts'][$vhost_docroot.":".$vhost_ip] = array( 'ip' => $vhost_ip, 'port' => $vhost_port, 'server' => $vhost_servername, 'docroot'=> $vhost_docroot, 'ssl' => $is_ssl ); $this->install_log("$msg VHOST=$vhost_ip:$vhost_port ($vhost_servername) => $vhost_docroot"); } } } } // Document root if(empty($this->conf['webserver_docroot_arr']) && preg_match_all("#^\s*DocumentRoot\s+\"?([^\s\"]+)\"?#m", $this->conf['apache_conf_cont'], $match)){ $multiples = array(); for($i=0, $c=1; $imake_full_path($match[1][$i], $this->conf['apache_root_dir']); if(!strstr($docroot,'$') && $this->my_dir_exists($docroot)) { $docroot = $this->nice_path($docroot); if(!isset($multiples[$docroot])) { $this->conf['webserver_docroot_arr'][$c] = $docroot; $this->install_log ("$msg DOCUMENT_ROOT=$docroot"); $multiples[$docroot] = true; $c++; } } } } // Global document root if (empty ($this->conf['webserver_global_docroot'])) { $global_http_conf = preg_replace ('@^\s*]+)>(.*)@msU', '', $this->conf['apache_conf_cont']); if (preg_match ('@^\s*DocumentRoot\s+([^\#]+)@m', $global_http_conf, $match)) { $this->conf['webserver_global_docroot'] = trim ($match[1], "\t \r\n\"\'"); $this->install_log ("{$msg} GLOBAL_DOCUMENT_ROOT={$this->conf['webserver_global_docroot']}"); } } // Libexec if(empty($this->conf['apache_libexec_dir']) && preg_match("#^\s*LoadModule\s+[^\s]+\s+\"?([^\s\"]+)\"?#m", $this->conf['apache_conf_cont'], $match)) { $path = $this->make_full_path(dirname($match[1]), $this->conf['apache_root_dir']); if($this->my_dir_exists($path)) { $this->conf['apache_libexec_dir'] = $path; $this->install_log("$msg APACHE_LIBEXEC=".$this->conf['apache_libexec_dir']); } } // PHP (module or executable) path if(empty($this->conf['php_path'])){ // Script aliases preg_match_all("#^\s*ScriptAlias\s+\"?([^\s\"]+)\"?\s+\"?([^\s\"]+)\"?#m", $this->conf['apache_conf_cont'], $match); array_shift($match); $script_aliases = array(); for($i=0; $iconf['apache_conf_cont'], $match)){ $this->conf['php_type'] = "module"; $this->conf['php_path'] = $match[1]; } elseif(preg_match("#^\s*Action\s+application\/x-httpd-php\s+\"?([^\s\"]+)\"?\s*$#m", $this->conf['apache_conf_cont'], $match)){ $this->conf['php_type'] = "executable"; $this->conf['php_path'] = $match[1]; } if(!empty($this->conf['php_path'])){ foreach($script_aliases as $alias => $path){ $this->conf['php_path'] = preg_replace("#^$alias#", $path, $this->conf['php_path'], 1); } $this->conf['php_path'] = $this->make_full_path($this->conf['php_path'], $this->conf['apache_root_dir']); $this->install_log("$msg PHP_PATH=".$this->conf['php_path']); $this->install_log("$msg PHP_TYPE=".$this->conf['php_type']); } } return true; } function apache_pidfile_detect() { if (!isset($this->conf['apache_pid_file'])) { $this->apache_guess_from_binary(); } $this->apache_guess_from_conf(); return (@isset($this->conf['apache_pid_file']) ? $this->conf['apache_pid_file'] : null); } // APACHE_HAS_MODULE function apache_has_module($mod_name) { $this->apache_exec_guess(); if(preg_match("/$mod_name/", $this->cmd2str($this->conf['apache_exec_file']." -l"))) { return true; } return false; } // APACHE_GET_VERSION function apache_get_version() { if(!$this->is_using_apache()){ return false; } if(!empty($this->conf['apache_version'])){ return $this->conf['apache_version']; } $this->apache_guess_from_binary(); if(empty($this->conf['apache_version'])){ $version = $this->menubox( "The installation has failed to detect the version of Apache you use.". "Please choose the correct version.", array(1 => 'Apache 1.x.x', 2 => 'Apache 2.x.x') ); $this->conf['apache_version'] = preg_replace("/Apache\s+(\d).*/", "\\1", $version); } return $this->conf['apache_version']; } // APACHE_CONFIGURE_INSTALL function apache_configure_install() { $apache_install_dir=dirname($this->conf['apache_root_dir']); if(empty($apache_install_dir) or $apache_install_dir == "/") { $this->on_error("Cannot install Apache into / (not permitted)"); } if(!$this->my_dir_exists($apache_install_dir)){ $this->on_error("Cannot install Apache into ".$apache_install_dir." (not a directory)"); } $this->infobox("Configuring Apache installation ..."); // Fix apachectl $this->conf['apachectl_path'] = $this->conf['apache_exec_dir']."/apachectl"; $this->conf['apache_conf_file'] = $this->conf['apache_conf_dir']."/httpd.conf"; $new_apachectl = preg_replace( "@(\s*HTTPD=).*$@m", "\\1\"".$this->conf['apache_exec_dir']."/httpd -f ".$this->conf['apache_conf_file']."\"", $this->file2str($this->conf['apachectl_path'])); $new_apachectl = preg_replace( "@(\s*PIDFILE=).*$@m", "\\1".$this->conf['apache_root_dir']."/logs/httpd.pid", $new_apachectl); $this->my_fwrite($this->conf['apachectl_path'], "w", $new_apachectl); # Configure httpd.conf $this->apache_conf_open(); // Fix httpd.conf $this->conf['apache_conf_cont'] = preg_replace( "@/usr/local/apache@m", $this->conf['apache_root_dir'], $this->conf['apache_conf_cont']); // fix "Group" directive $group_is_set = false; foreach (array('nobody', 'nogroup') as $grp) { if (posix_getgrnam($grp) !== false) { $this->conf['apache_conf_cont'] = preg_replace ("@^\s*Group\s+.*@m", "Group {$grp}", $this->conf['apache_conf_cont']); $group_is_set = true; break; } } if(!$group_is_set){ $this->conf['apache_conf_cont'] = preg_replace ("@(^\s*Group\s+.*)@m", "#\\1", $this->conf['apache_conf_cont']); } $this->link_startup_daemon($this->conf['apachectl_path']); $this->conf['apache_conf_modified'] = true; return true; } // APACHE_CONFIGURE_PHP_INSTALL function apache_configure_php_install($php_version) { $this->apache_conf_guess(); $this->infobox("Configuring Apache for PHP installation..."); $this->apache_libexec_guess(); if(!$this->my_dir_exists($this->conf['apache_libexec_dir'])) { $this->on_error("Broken Apache configuration: The needed directory:\n". $this->conf['apache_libexec_dir']."\nwhere Apache modules should be placed could not be found.\n". "The installation cannot proceed.\n"); } $apache_libphp_so_path = $this->conf['apache_libexec_dir']."/libphp".$php_version.".so"; if($this->my_file_exists($apache_libphp_so_path)){ $this->my_backup($apache_libphp_so_path); } if(!$this->my_symlink($this->conf['prefix'].'/lib/libphp'.$php_version.'.so', $apache_libphp_so_path)){ $this->on_error("Can't place a link to PHP library in your Apache ". "libexec directory at: ".$apache_libphp_so_path); } # Configure httpd.conf: $this->apache_conf_open(); // install AddType entries if(!preg_match("@^\s*(AddType\s+application.*php)@m", $this->conf['apache_conf_cont'])) { $this->conf['apache_conf_cont'] .= "\n". "\n". " AddType application/x-httpd-php .php\n". " AddType application/x-httpd-php-source .phps\n". "\n\n"; } // Install LoadModule entry $load_module_new_entry = "\nLoadModule php".$php_version."_module $apache_libphp_so_path\n"; if(preg_match("@^\s*LoadModule\s+php\d_module\s+@m", $this->conf['apache_conf_cont'])) { $this->conf['apache_conf_cont'] = preg_replace( "@^\s*(LoadModule\s+php\d_module\s.*)$@m", "#Zend# \\1$load_module_new_entry", $this->conf['apache_conf_cont']); } elseif (preg_match("@^\s*Action\s+application/x-httpd-php@m", $this->conf['apache_conf_cont'])) { $this->conf['apache_conf_cont'] = preg_replace( "@^\s*(Action\s+application/x-httpd-php.*)$@m", "#Zend# \\1$load_module_new_entry", $this->conf['apache_conf_cont']); } else { $this->conf['apache_conf_cont'] .= $load_module_new_entry; } $this->conf['apache_conf_modified'] = true; } // APACHE_DO_CONFIG function apache_check_php_config() { $this->apache_conf_open(); $config_exists = preg_match("/^\s*AddType\s+application.*php/m", $this->conf['apache_conf_cont']); if(!$config_exists){ $this->msgbox("No existing PHP configuration found in your ".$this->conf['apache_conf_file']."!\n". "Your Apache must be configured to enable PHP scripts running on it,\n". "otherwise this product is useless!"); } } // APACHE_STOP function apache_stop() { if(!$this->is_using_apache()){ return false; } $this->apache_exec_guess(); $this->progress_bar_start(20, "Stopping Apache ...\n". "Please wait... (this may take a few seconds)", "Stopping ..."); $status = $this->run_command($this->conf['apachectl_path']." stop 1>/dev/null"); sleep(4); $this->progress_bar_stop(); if($status==0){ return true; } return false; } // APACHE_START function apache_start() { if(!$this->is_using_apache()){ return false; } $this->apache_exec_guess(); $apache_ssl = false; if (strstr($this->file2str($this->conf['apachectl_path']), "startssl")) { $cmd = $this->inputbox ("Please confirm your Apache Web server startup command", $this->conf['apachectl_path']." startssl"); if (strstr($cmd, "startssl")) { $apache_ssl = true; } } else { $cmd = $this->conf['apachectl_path']." start"; } if ($apache_ssl) { $status = $this->run_command($cmd); } else { $this->progress_bar_start(20, "Starting Apache ...\n". "Please wait... (this may take a few seconds)", "Starting ..."); $status = $this->run_command("{$cmd} 1>/dev/null"); } sleep(4); if(!$this->apache_is_running()) { if ($apache_ssl) { $status = $this->run_command($cmd); } else { $status = $this->run_command("{$cmd} 1>/dev/null"); } sleep(4); } if (!$apache_ssl) { $this->progress_bar_stop(); } if(!$this->apache_is_running()) { $status = -1; } return ($status == 0); } // APACHE_RESTART function apache_restart($silent=false) { if(!$this->is_using_apache()){ return false; } $this->apache_exec_guess(); $stop_cmd = "stop"; $start_cmd = "start"; if (!$silent) { $this->progress_bar_start(20, "Restarting Apache ...\n". "Please wait... (this may take a few seconds)", "Restarting ..."); } if(strstr($this->file2str($this->conf['apachectl_path']), "startssl")) { $status = $this->run_command($this->conf['apachectl_path']." graceful 1>/dev/null"); sleep(4); } else { $this->run_command($this->conf['apachectl_path']." $stop_cmd 1>/dev/null"); sleep(4); $status = $this->run_command($this->conf['apachectl_path']." $start_cmd 1>/dev/null"); sleep(4); if(!$this->apache_is_running()) { $status = $this->run_command($this->conf['apachectl_path']." $start_cmd 1>/dev/null"); sleep(4); } } if (!$silent) { $this->progress_bar_stop(); } if(!$this->apache_is_running()) { $status = -1; } if($status==0){ return true; } return false; } // APACHE_IS_RUNNING function apache_is_running() { if(!$this->is_using_apache()){ return false; } $pidfile = $this->apache_pidfile_detect(); if($pidfile) { if ($this->my_file_exists($pidfile) && $this->run_command ("kill -0 ".$this->file2str($pidfile)." 1>/dev/null") == 0) { return true; } /* PID file doesn't exists - it means Apache Web server is not running */ return false; } # Else try to find PID by name of the Apache executable $pids = $this->pidof (basename($this->conf['apache_exec_file'])); if(count($pids) == 0) { return false; } return true; } // ---------------------- // ZEUS FUNCTIONS // ====================== // ZEUS_RESTART function zeus_restart($silent=false) { $this->webserver_root_guess(); if (!$silent) { $this->infobox("Restarting Zeus ..."); } if($this->my_file_exists($this->conf['zeus_root']."/restart-zeus")){ $status = $this->run_command($this->conf['zeus_root']."/restart-zeus 2>&1 1>/dev/null"); if($status == 0){ return true; } } return false; } // ZEUS_START function zeus_start() { $this->webserver_root_guess(); $this->infobox("Starting Zeus ..."); if($this->my_file_exists($this->conf['zeus_root']."/start-zeus")){ $status = $this->run_command($this->conf['zeus_root']."/start-zeus 2>&1 1>/dev/null"); if($status == 0){ return true; } } return false; } // ZEUS_CHOOSE_VIRTUAL_HOST function zeus_choose_virtual_host() { $this->webserver_root_guess(); if(!isset($this->conf['zeus_vhost'])) { $conf_dir = $this->conf['zeus_root']."/webadmin/conf/virtual_servers/sites"; $vhosts = array(); if($this->my_dir_exists($conf_dir)) { foreach ($this->my_list_dir($conf_dir, "*") as $file) { $file = basename($file); if (!preg_match ("/^(_default|_skel.*)$/", $file)) { array_push ($vhosts, basename($file)); } } } if(count($vhosts) > 0) { $i = $this->menubox("Please select the name of the virtual host,\n" ."where you wish to setup the product", $vhosts); $vhost = $vhosts[$i]; } elseif ($this->my_dir_exists($conf_dir)) { do { $vhost = $this->inputbox ("Please enter the name of the virtual host,\n" ."where you wish to setup the product"); if(!$this->my_file_exists ("$conf_dir/$vhost")) { $this->msgbox ("Virtual host: $vhost doesn't exist in the Zeus configuration!\nPlease try again!"); continue; } } while (false); } else return false; /* Guess everything from the virtual host */ $this->conf['zeus_vhost'] = $vhost; $cont = $this->file2str ("$conf_dir/$vhost"); if(preg_match ("/^\s*docroot\s+(\S.+)$/m", $cont, $match)) { $this->conf['webserver_doc_root'] = trim ($match[1], "\t \'\""); $this->install_log ("Guessed Zeus document root: ".$this->conf['webserver_doc_root']); } if(preg_match ("/^\s*ip_name\s+(\S.+)$/m", $cont, $match)) { $this->conf['zeus_ip_name'] = trim ($match[1], "\t \'\""); $this->install_log ("Guessed Zeus hostname: ".$this->conf['zeus_ip_name']); } if(preg_match ("/^\s*port\s+(\d+)$/m", $cont, $match)) { $this->conf['zeus_port'] = trim ($match[1], "\t \'\""); $this->install_log ("Guessed Zeus port: ".$this->conf['zeus_port']); } if(preg_match ("/zeus-php-handler\!filepath\s+(\S.+)$/m", $cont, $match)) { $this->conf['php_path'] = str_replace("%zeushome%", $this->conf['zeus_root'], trim ($match[1], "\t \'\"")); $this->install_log ("Guessed Zeus PHP path: ".$this->conf['php_path']); } if(preg_match ("/zeus-php-handler\!type\s+(\S.+)$/m", $cont, $match)) { $this->conf['php_type'] = trim ($match[1], "\t \'\""); if($this->conf['php_type'] != 'fastcgi') { $this->conf['php_type'] = 'unknown'; } $this->install_log ("Guessed Zeus PHP type: ".$this->conf['php_type']); } if(preg_match ("/fastcgi!uid\s+(\d+)$/m", $cont, $match)) { $user = $this->uid2user(trim ($match[1], "\t \'\"")); if($user !== false) { $this->conf['zeus_user'] = $user; $this->install_log ("Guessed Zeus user: ".$this->conf['zeus_user']); } } if(preg_match ("/fastcgi!gid\s+(\d+)$/m", $cont, $match)) { $groupinfo = posix_getgrgid(trim ($match[1], "\t \'\"")); if($groupinfo !== false) { $this->conf['zeus_group'] = $groupinfo['name']; $this->install_log ("Guessed Zeus group: ".$this->conf['zeus_group']); } } } return true; } // ZEUS_DOCROOT_GUESS function zeus_docroot_guess() { $this->zeus_choose_virtual_host(); if(!empty($this->conf['webserver_doc_root'])){ return $this->conf['webserver_doc_root']; } $this->webserver_root_guess(); $multiples = array(); $c = 1; if(!empty($this->conf['zeus_root'])){ if($this->my_dir_exists($this->conf['zeus_root']."/webadmin/conf/virtual_servers/sites")) { foreach ($this->my_list_dir($this->conf['zeus_root']."/webadmin/conf/virtual_servers/sites", "*") as $file) { if(preg_match("/^docroot\s+(.*)$/m", $this->file2str($file), $match)) { if($this->my_dir_exists($match[1]) && !isset($multiples[$match[1]])) { $this->conf['webserver_docroot_arr'][$c] = $match[1]; $c++; } } } } } $default = ""; if(count($this->conf['webserver_docroot_arr']) == 0) { $default = $this->search_dir(array( 1 => "/usr/local/zeus/web/docroot", 2 => "/var/www/html" )); } else if(count($this->conf['webserver_docroot_arr']) > 1) { array_push($this->conf['webserver_docroot_arr'], "other"); while(true) { $num = $this->menubox("Please select the location of your document root directory.\n". "This is the location where your web documents are stored.", $this->conf['webserver_docroot_arr']); if($this->conf['webserver_docroot_arr'][$num] == "other") { break; } else if($this->my_dir_exists($this->conf['webserver_docroot_arr'][$num])) { $this->conf['webserver_doc_root'] = $this->conf['webserver_docroot_arr'][$num]; break; } $this->msgbox("Broken Zeus configuration!\n". "Document root: \"".$this->conf['webserver_docroot_arr'][$num]."\" doesn't exist"); } } else { $default = array_pop($this->conf['webserver_docroot_arr']); } return $default; } // ZEUS_USER_GUESS function zeus_user_guess() { $this->zeus_choose_virtual_host(); if(isset($this->conf['zeus_user'])) { return $this->conf['zeus_user']; } $this->webserver_root_guess(); if(!empty($this->conf['zeus_root'])){ if($this->my_file_exists($this->conf['zeus_root']."/web/global.cfg")) { if(preg_match("/^uid\s+(.*)$/m", $this->file2str($this->conf['zeus_root']."/web/global.cfg"), $match)) { $this->conf['zeus_user'] = $match[1]; } } } return isset($this->conf['zeus_user']) ? $this->conf['zeus_user'] : null; } // ZEUS_IS_RUNNING function zeus_is_running() { $pids = $this->pidof ("zeus"); if(count($pids) == 0) { return false; } return true; } // PHP_VERSION_DETECT_FROM_ZEUS function php_version_detect_from_zeus($silent = false) { $this->zeus_choose_virtual_host(); $this->webserver_root_guess(); $this->php_type_guess (); if($this->conf['php_type'] == "fastcgi" && file_exists ($this->conf['zeus_root']."/php/php.fcgi")) { $this->php_version_search_in($this->conf['zeus_root']."/php/php.fcgi"); } } // ZEUS_GET_VIRTUAL_HOST_URL function zeus_get_virtual_host_url($default = null) { $this->zeus_choose_virtual_host(); $host = $this->conf['uname']['nodename']; if(isset($this->conf['zeus_ip_name'])) { $host = $this->conf['zeus_ip_name']; if(isset($this->conf['zeus_port'])) { $host .= ":".$this->conf['zeus_port']; } } elseif ($default) { $host = $default; } return $host; } // ---------------------- // SUNONE FUNCTIONS // ====================== // SUNONE_RESTART function sunone_restart($silent=false) { $this->sunone_root_guess(); if (!$silent) { $this->infobox("Restarting SunONE ..."); } if($this->my_file_exists($this->conf['sunone_root']."/restart")){ $status = $this->run_command($this->conf['sunone_root']."/restart"); if($status == 0){ return true; } } return false; } // SUNONE_ROOT_GUESS function sunone_root_guess() { if(!empty($this->conf['sunone_root'])) { return $this->conf['sunone_root']; } $this->webserver_root_guess(); $c = 1; $servers = array(); foreach ($this->my_list_dir($this->conf['sunone_root'], "https-*") as $dir) { $server_id = substr($dir, strrpos($dir, "-")+1); if($server_id == "admserv") { continue; } $servers[$c++] = $server_id; } if(count($servers) > 1) { $i = $this->menubox("Please select the server instance you wish to use.", $servers); $server_id = $servers[$i]; } else $server_id = $servers[1]; $this->conf['sunone_root'] = $this->make_path($this->conf['sunone_root'], "https-".$server_id); } // SUNONE_GUESS_FROM_CONF function sunone_guess_from_conf() { $this->sunone_root_guess(); $sunone_conf = $this->conf['sunone_root']."/config/server.xml"; if(!$this->my_file_exists($sunone_conf)) { $this->install_log("Can't find SunONE configuration file: $sunone_conf"); return false; } $sunone_conf_cont = $this->file2str($sunone_conf); $msg = "Guessed from SunONE configuration:"; // User if(empty($this->conf['sunone_user']) && preg_match("#PROPERTY\s+name=\"user\"\s+value=\"([^\"]*)\"#mi", $sunone_conf_cont, $match)){ $this->conf['sunone_user'] = $match[1]; $this->install_log("$msg USER=".$this->conf['sunone_user']); } // Port if(empty($this->conf['sunone_port']) && preg_match("#port=\"(\d+)\"#mi", $sunone_conf_cont, $match)){ $this->conf['sunone_port'] = $match[1]; $this->install_log("$msg PORT=".$this->conf['sunone_port']); } // Group if(empty($this->conf['sunone_group']) && preg_match("#PROPERTY\s+name=\"group\"\s+value=\"([^\"]*)\"#mi", $sunone_conf_cont, $match)){ $this->conf['sunone_group'] = $match[1]; $this->install_log("$msg GROUP=".$this->conf['sunone_group']); } // Server Name if(empty($this->conf['server_name']) && preg_match("#servername=\"[^\"]*\"#mi", $sunone_conf_cont, $match)){ } // Document root if(empty($this->conf['webserver_docroot_arr']) && preg_match_all("#PROPERTY\s+name=\"docroot\"\s+value=\"([^\"]*)\"#mi", $sunone_conf_cont, $match)){ $multiples = array(); for($i=0, $c=1; $imy_dir_exists($docroot) && !isset($multiples[$docroot])) { $this->conf['webserver_docroot_arr'][$c] = $docroot; $this->install_log("$msg DOCUMENT_ROOT=$docroot"); $multiples[$docroot] = true; $c++; } } } return true; } // SUNONE_DOCROOT_GUESS function sunone_docroot_guess() { if(!empty($this->conf['webserver_doc_root'])){ return $this->conf['webserver_doc_root']; } $this->sunone_guess_from_conf(); if(count($this->conf['webserver_docroot_arr']) > 1) { array_push($this->conf['webserver_docroot_arr'], "other"); while(true) { $num = $this->menubox("Please select the location of your document root directory.\n". "This is the location where your web documents are stored.", $this->conf['webserver_docroot_arr']); if($this->conf['webserver_docroot_arr'][$num] == "other") { break; } else if($this->my_dir_exists($this->conf['webserver_docroot_arr'][$num])) { $this->conf['webserver_doc_root'] = $this->conf['webserver_docroot_arr'][$num]; break; } $this->msgbox("Broken SunONE configuration!\n". "Document root: \"".$this->conf['webserver_docroot_arr'][$num]."\" doesn't exist"); } } else { $default = array_pop($this->conf['webserver_docroot_arr']); } return $default; } // SUNONE_USER_GUESS function sunone_user_guess() { if(!empty($this->conf['sunone_user'])) { return $this->conf['sunone_user']; } $this->sunone_guess_from_conf(); if(!empty($this->conf['sunone_root'])) { $conf_file = $this->conf['sunone_root']."/config/magnus.conf"; if($this->my_file_exists($conf_file)) { if(preg_match("/^\s*User\s+(.*)$/m", $this->file2str($conf_file), $match)) { $this->conf['sunone_user'] = $match[1]; } } } return (isset($this->conf['sunone_user']) ? $this->conf['sunone_user'] : null); } // ---------------------- // PHP FUNCTIONS // ====================== // DONT_HAVE_PHP function dont_have_php() { if (@isset($this->conf['compatibility_page'])) { $compatibility_info = <<conf['product']} system requirements page at: {$this->conf['compatibility_page']} EOF; } $this->on_error( <<conf['product']} you must have supported PHP installed on your computer. Please install a valid PHP, then restart the installation. {$compatibility_info} EOF ); } // PHP_VERSION_DETECT function php_version_detect($silent = false, $warn_unsupported_php = false) { if(!$this->php_version_detect_from_webserver($silent)){ if(!$silent) { if(!$this->php_version_ask()){ $this->php_version_select_manually(); } } } if(isset($this->conf['php_version'])) { $this->install_log("Detected PHP version: ".$this->conf['php_version']); if($this->conf['php_version'] == "unsupported" && $warn_unsupported_php) { $this->msgbox( "Installation has detected PHP version ".$this->conf['detected_unsupported_php_version'].".\n". "This version is not compatible with the ".$this->conf['product']." ".$this->conf['version'].".\n". "The installation process will continue but in order for the ".$this->conf['product']."\n". "to load you must switch to a compatible PHP version.\n\n". "For a detailed compatibility table please refer to\n". (isset($this->conf['compatibility_page']) ? $this->conf['compatibility_page'] : "http://www.zend.com/store/products/product_compatibility.php")); } } } // PHP_VERSION_DETECT_FROM_APACHE function php_version_detect_from_apache($silent = false) { if($this->is_using_apache($silent)){ $this->apache_conf_guess($silent); $this->php_path_guess($silent); if(isset($this->conf['php_type'])) { if($this->conf['php_type'] == "unknown"){ $this->apache_exec_guess($silent); if($this->php_version_search_in($this->conf['apache_exec_file'])){ $this->conf['php_type'] = "builtin"; } } elseif($this->conf['php_type'] == "executable" && isset($this->conf['php_path'])){ if(preg_match("/(\d+\.\d+\.\d+)/", $this->cmd2str($this->conf['php_path']. " -v 2>/dev/null"), $match)){ $this->conf['php_version'] = $match[1]; } } elseif(($this->conf['php_type'] == "module" || $this->conf['php_type'] == "fastcgi") && isset($this->conf['php_path'])){ $this->php_version_search_in($this->conf['php_path']); } } } } // PHP_VERSION_ASK function php_version_ask($msg=null, $type=null) { $this->php_versions_array_init(); if(!$this->conf['interactive']) { return false; } if($msg == null){ $msg = "Setup has failed to determine your PHP version."; } $menu = array( 1 => "Detection of PHP version from a binary.", 2 => "Manually select my PHP version." ); $choice = $this->menubox($msg, $menu); if($choice == 1){ return $this->php_version_detect_from_binary(); } elseif($choice == 2){ $this->php_version_select_manually(); return true; } } // PHP_VERSION_DETECT_FROM_BINARY function php_version_detect_from_binary() { $this->php_versions_array_init(); $this->php_type_guess(); $confirm_msg = "Setup will attempt to determine your PHP version from a binary.\n"; if($this->conf['php_type'] == "module") // detect PHP version from a PHP module { $default = empty($this->conf['php_path'])? "" : $this->conf['php_path']; $this->conf['php_path'] = $this->select_file( $confirm_msg."Please enter the full path to your PHP module", $default); $this->php_version_search_in($this->conf['php_path']); } elseif($this->conf['php_type'] == "executable") // detect from a PHP binary { $default = empty($this->conf['php_path'])? "" : $this->conf['php_path']; $this->conf['php_path'] = $this->select_file( $confirm_msg."Please enter the full path to your PHP executable file", $default); if(preg_match("/(\d+\.\d+\.\d+)/", $this->cmd2str($this->conf['php_path']. " -v 2>/dev/null"), $match)){ $this->conf['php_version'] = $match[1]; } } elseif($this->conf['php_type'] == "builtin") // detect from an Apache executable { $default = empty($this->conf['apache_exec_file'])? "": $this->conf['apache_exec_file']; $php_search_path = $this->select_file( $confirm_msg."Please enter the full path to your ".$this->conf['webserver'], $default); $this->php_version_search_in($php_search_path); } elseif($this->conf['php_type'] == "fastcgi") // detect from a PHP FastCGI SAPI executable { $php_search_path = $this->select_file( $confirm_msg."Please enter the full path to your FastCGI PHP application", ""); $this->php_version_search_in($php_search_path); } if(empty($this->conf['php_version'])){ $this->msgbox("The installation still fails to determine your PHP version."); return false; } return $this->php_version_confirm(); } // PHP_VERSION_SELECT_MANUALLY function php_version_select_manually($msg="") { $this->php_versions_array_init(); if(!$this->conf['interactive']) { return false; } foreach ($this->conf['php_versions_array'] as $num => $php_arr){ if($php_arr[2] != 0){ $sub_str=substr($php_arr[0],0 ,(strlen($php_arr[0])-1) ); $php_ver_arr[$num]= $php_arr[0]." (".$sub_str.$php_arr[2]." and later)"; }else{ $php_ver_arr[$num]= $php_arr[0]; } $last_i = $num+1; } $msg = "$msg\nIn order to install the correct version of the Zend Modules\n". "you must specify which PHP version you are using."; $php_ver_arr[$last_i] = "Other PHP version"; $php_ver_arr[$last_i+1] = "I don't have PHP"; $choice = $this->menubox($msg , $php_ver_arr); if($choice == $last_i || $choice == $last_i+1) { if(isset($this->conf['doesnt_need_php'])) { $this->conf['php_version'] = "donthave"; } else $this->dont_have_php(); } else $this->conf['php_version'] = $this->conf['php_versions_array'][$choice][1]; return true; } // PHP_TYPES_SET function php_types_set($php_types_arr) { $this->install_log("PHP types was set to: ". var_export($php_types_arr, true)); $this->conf['php_types_supported'] = $php_types_arr; } // PHP_TYPE_ADD function php_type_add($new_php_type) // PHP type is an array that consists of two elements: // 1) PHP type description // 2) PHP type internal use name { $this->install_log("Added new PHP type: ". $new_php_type[0]); array_push($this->conf['php_types_supported'], $new_php_type); } // PHP_TYPE_EXISTS function php_type_exists($php_type) { $this->php_types_array_init(); if(!empty($this->conf['php_types_supported'])){ foreach($this->conf['php_types_supported'] as $php_type_arr){ if($php_type_arr[1] == $php_type){ return true; } } } return false; } // PHP_TYPE_GUESS function php_type_guess() { $this->install_log("Trying to guess PHP type ..."); $this->php_types_array_init(); $this->apache_guess_from_conf(); if(!empty($this->conf['php_type']) && $this->conf['php_type'] != "unknown"){ $this->php_type_supported_check(); return true; } else { if($this->is_using_apache() && $this->apache_has_module("mod_php")) { $this->conf['php_type'] = "builtin"; $this->php_type_supported_check(); return true; } } $old_php_type = isset($this->conf['php_type'])? $this->conf['php_type'] : "unknown"; $this->install_log("Old PHP type was: $old_php_type"); while(1) { if(count($this->conf['php_types_supported'])==1){ if($this->yesnobox("Are you using ".$this->conf['php_types_supported'][1][0]."?")){ $this->conf['php_type'] = $this->conf['php_types_supported'][1][1]; } else{ $this->on_abort("For now ".$this->conf['product']." supports only ". $this->conf['php_types_supported'][1][0]." with ".$this->conf['webserver'], true); } } else { foreach($this->conf['php_types_supported'] as $num => $data){ $php_types[$num] = $data[0]; $last_i = $num+1; } $php_types[$last_i] = "I don't have PHP"; $choice = $this->menubox("Please choose the type of PHP you use", $php_types, false, "The ".$this->conf['product']." supports the following PHP configurations:\n\n". $this->array2string($this->conf['php_types_supported'], 0)); if($choice == $last_i) { if(isset($this->conf['doesnt_need_php'])) { $this->conf['php_type'] = "donthave"; } else $this->dont_have_php(); } else $this->conf['php_type'] = $this->conf['php_types_supported'][$choice][1]; } if($this->conf['php_type'] != "executable") { /* Dummy check */ if(isset($this->conf['php_path'])) { if(preg_match("/^([\d+\.]+)$/", $this->get_binary_strings($this->conf['php_path']))) { $this->msgbox("You have specified that you are using PHP ".$this->conf['php_type']."\n". "But the installation detected usage of PHP CGI.\nPlease don't try to cheat the installation."); continue; } } } break; } $this->install_log("Guessed PHP type: ".$this->conf['php_type']); if($this->conf['php_type'] != $old_php_type){ unset($this->conf['php_path']); } return true; } // PHP_TYPE_SUPPORTED_CHECK function php_type_supported_check() { $this->install_log("Checking eigther PHP type (".$this->conf['php_type'].") is supported."); $this->php_types_array_init(); if(empty($this->conf['php_type']) || $this->conf['php_type'] == "unknown") { $this->php_type_guess(); } if(!$this->php_type_exists($this->conf['php_type'])) { $this->on_abort("ERROR: Unsupported PHP configuration.\n". "The ".$this->conf['product']." supports the following PHP configurations:\n\n". $this->array2string($this->conf['php_types_supported'], 0), true); } } // PHP_VERSIONS_ARRAY_INIT function php_versions_array_init() { if(@isset($this->conf['php_versions_array_initialized'])){ return; } /* $this->conf['php_versions_array'] = array( 1 => array("PHP 4.0.5/6", "4.0.6", 0), 2 => array("PHP 4.1.x", "4.1.x", 0), 3 => array("PHP 4.2.0", "4.2.0", 0), 4 => array("PHP 4.2.x (other than 4.2.0)", "4.2.x", 0), 5 => array("PHP 4.3.x", "4.3.x", 0), 6 => array("PHP 5.0.x", "5.0.x", 0) ); */ $this->conf['php_versions_array'] = array(); $this->conf['php_ts_versions_array'] = array(); $php_vers = glob("../data/*_comp"); if (is_array($php_vers)) { foreach ($php_vers as $php_ver) { $ts = file_exists ("{$php_ver}/TS"); $php_ver = basename ($php_ver); $php_ver = str_replace ("_comp", "", $php_ver); $php_ver = str_replace ("_", ".", $php_ver); if ($php_ver == "4.0.6") { $ver = array("PHP 4.0.5/6", "4.0.6", 0); } else if ($php_ver == "4.2.x") { $ver = array("PHP 4.2.x (other than 4.2.0)", "4.2.x", 0); } else { $ver = array("PHP {$php_ver}", $php_ver, 0); } $this->conf['php_versions_array'][] = $ver; if ($ts) { $this->conf['php_ts_versions_array'][] = $ver; } } } $this->conf['php_versions_array_initialized'] = true; } // PHP_TYPES_ARRAY_INIT function php_types_array_init() { if(!empty($this->conf['php_types_supported'])){ return; } $this->conf['php_types_supported'] = array( 1 => array("PHP module (e.g libphp4.so)", "module"), 2 => array("PHP executable (also called CGI)", "executable"), 3 => array("PHP compiled into ". $this->conf['webserver'], "builtin"), 4 => array("Other", "unknown") ); } // PHP_VERSION_SUBSTITUTE function php_version_substitute($silent = false) { $this->php_versions_array_init(); if(!isset($this->conf['php_version'])){ if($silent) { return false; } $this->php_version_select_manually(); } foreach ($this->conf['php_versions_array'] as $num => $php_arr){ /* look for an exact match */ if($php_arr[1] == $this->conf['php_version']){ return true; } elseif (($php_arr[1] == "4.0.6" ) && ("4.0.5" == $this->conf['php_version'])){ $this->conf['php_version'] = $php_arr[1]; return true; } } foreach ($this->conf['php_versions_array'] as $num => $php_arr){ if($this->ver_equal($php_arr[1], $this->conf['php_version'], $php_arr[2])){ /* look for a corresponding match */ $this->conf['php_version'] = $php_arr[1]; return true; } } $this->conf['detected_unsupported_php_version'] = $this->conf['php_version']; return false; } // PHP_VERSION_CONFIRM function php_version_confirm() { $this->php_versions_array_init(); $this->php_type_supported_check(); if($this->yesnobox("Please confirm the PHP version you use: ".$this->conf['php_version'])){ if($this->php_version_substitute()){ $this->install_log("Confirmed PHP version: ".$this->conf['php_version']); return true; } if(count($this->conf['php_versions_array']) != 1) { $vers_msg = "on of the following versions of PHP:\n\n" .$this->array2php_support_string($this->conf['php_versions_array'], 0, 2); } else { $vers_msg = $this->array2php_support_string($this->conf['php_versions_array'], 0, 2); } $this->on_error($this->conf['product']." does not support PHP ".$this->conf['php_version']. "\nIn order to install ".$this->conf['product']." on ".$this->conf['uname']['sysname']."\n". "you must have $vers_msg"); } unset($this->conf['php_version']); return false; } // PHP_VERSIONS_GET_ARRAY function php_versions_get_array($ts=false) { $this->php_versions_array_init(); $key = $ts ? 'php_ts_versions_array' : 'php_versions_array'; $php_vers_array = array(); foreach($this->conf[$key] as $php_ver) { array_push($php_vers_array, $php_ver[1]); } return $php_vers_array; } // PHP_VERSION_ADD function php_version_add($descr, $ver, $from=0) /* description of version , PHP version */ { $this->php_versions_array_init(); $descr = trim($descr); $ver = trim($ver); $found = false; foreach($this->conf['php_versions_array'] as $num => $php_arr) { if($php_arr[1] == $ver) { $found = true; $this->conf['php_versions_array'][$num] = array($descr, $ver, $from); break; } } if(!$found) { if(count($this->conf['php_versions_array']) == 0) { // Always begin the index from 1 $this->conf['php_versions_array'][1] = array($descr, $ver, $from); } else array_push($this->conf['php_versions_array'], array($descr, $ver, $from)); } $this->install_log("Added $ver ($descr) from version $from to the array of PHP versions"); } // PHP_VERSION_REMOVE function php_version_remove($ver) { $this->php_versions_array_init(); $new_array = array(); $index = 1; foreach($this->conf['php_versions_array'] as $num => $php_arr){ if($php_arr[1] != $ver){ $new_array[$index++] = $php_arr; } else{ $this->install_log("Removed $ver from array of PHP versions"); } } $this->conf['php_versions_array'] = $new_array; } // PHP_VERSIONS_SET function php_versions_set($php_arr) { $this->install_log("PHP versions set as: ". var_export($php_arr, true)); $this->conf['php_versions_array'] = $php_arr; } // PHP_VERSION_SEARCH_IN function php_version_search_in($file) { $this->progress_bar_start(100, "Trying to determine the version of PHP.\n". "Please wait... (this may take a few seconds)", "Detecting ..."); $ret = false; if(!$this->my_file_exists($file)){ $this->install_log("Path to PHP: $file is broken"); } else if($this->is_broken_link($file)) { $this->warn("Link: $file is broken"); } else { $file_cont = $this->get_binary_strings($file); if(preg_match("/PHP\/(\d+\.\d+\.\d+)/", $file_cont, $match)){ $this->conf['php_version'] = $match[1]; $ret = $match[1]; } } $this->progress_bar_stop(); return $ret; } // PHP_PATH_GUESS function php_path_guess() { if(empty($this->conf['php_type'])){ $this->conf['php_type'] = "unknown"; } if(!empty($this->conf['apache_conf_file'])){ $this->apache_guess_from_conf(); } } // PHP_INI_FILE_PARSE_ERROR_CB function php_ini_file_parse_error_cb ($errno, $errstr, $errfile, $errline, $errcontext) { $this->conf['php_ini_parse_error'] = $errstr; } // PHP_INI_FILE_TEST function php_ini_file_test ($php_ini) { unset ($this->conf['php_ini_parse_error']); $old_err_handler = set_error_handler (array(&$this, "php_ini_file_parse_error_cb")); parse_ini_file ($php_ini); restore_error_handler(); } // PHP_INI_LOCATION_GUESS function php_ini_location_guess() { if(isset($this->conf['php_ini_path'])) { return $this->conf['php_ini_path']; } $this->install_log("Trying to guess PHP.ini location ..."); $default = array ( "/usr/local/lib", "/usr/local/Zend/etc", "/usr/local/etc", "/etc", "/etc/php", "/etc/php4/apache", "/etc/php/apache1-php4", "/etc/php/apache1-php5", "/etc/php/apache2-php4", "/etc/php/apache2-php5" ); if(isset($this->conf['prefix'])) { array_push ($default, $this->conf['prefix']."/etc"); } foreach ($default as $path){ if($this->my_file_exists($this->strip_symlink("$path/php.ini"))) { $this->install_log("Found php.ini in: $path"); $php_ini_dir = $path; break; } } if(empty($php_ini_dir)){ $php_ini_dir = ""; } if(isset($this->conf['default_php_ini_path']) && @file_exists ($this->conf['default_php_ini_path'])) { $php_ini_dir = $this->conf['default_php_ini_path']; } while(true){ $default_path = $php_ini_dir; $word = ($default_path == "") ? "Enter" : "Confirm"; $php_ini_dir = $this->select_dir("$word the location of your php.ini file", $default_path); if(!$this->my_file_exists($this->strip_symlink("$php_ini_dir/php.ini"))) { if(!$this->yesnobox ("php.ini was not found in $php_ini_dir.\n". "Do you wish that an empty php.ini will be created in that location?")) { continue; } else { $this->my_unlink ("$php_ini_dir/php.ini"); $this->my_touch ("$php_ini_dir/php.ini"); } } $php_ini_path = "$php_ini_dir/php.ini"; $this->php_ini_file_test ($php_ini_path); if (@isset ($this->conf['php_ini_parse_error'])) { $this->msgbox ( "PHP configuration file: {$php_ini_path} is corrupted:\n". $this->conf['php_ini_parse_error']. "\nPlease try again!" ); continue; } $this->conf['php_ini_path'] = $php_ini_path; $this->strip_symlink($this->conf['php_ini_path']); break; } $this->conf['saved_config']['default_php_ini_path'] = $php_ini_dir; $this->install_log("Confirmed the location of php.ini at: $php_ini_dir"); } // PHP_INI_FIX function php_ini_fix() { $this->php_ini_open(); if($this->php_ini_replace_entry("\' at MYSQL_PORT", "; at MYSQL_PORT")) { $this->install_log("PHP.ini fixed"); } } // GUESS_CONFLICT function guess_conflict() { $this->install_log("Trying to guess a conflict in PHP.ini ..."); $not_asked=TRUE; foreach ($this->conf['php_ini_cont'] as $num => $line){ $line = chop($line); if(preg_match("#^\s*zend_extension(?:_ts)?=.*ZendAccelerator.*#", $line) || preg_match("#^\s*zend_extension(?:_ts)?=.*ZendPerformanceSuite.*#", $line)){ if($not_asked){ $not_asked=FALSE; $config_choose = $this->menubox( << "Disable ZPS and continue", 2 => "Abort installation") ); } if($config_choose == 1){ $this->conf['php_ini_cont'][$num] = preg_replace( "@^\s*(.*)@", ";Zend; \\1", $this->conf['php_ini_cont'][$num]); $this->install_log("Commenting PHP.ini entry: $line"); }else{ $this->default_abort(); } } } $this->install_log("PHP.ini checked for a conflict"); } // PHP_INI_GUESS_BAD_DIRECTIVES function php_ini_guess_bad_directives ($bad_directives, $add_msg="") { $existing_bad_directives = array(); foreach ($bad_directives as $entry => $pattern) { $value = $this->php_ini_get_entry ($entry, $pattern); if (!empty ($value)) { $existing_bad_directives[] = "{$entry} = {$value}"; } } if (count($existing_bad_directives) > 0) { $this->on_abort( "\nThe installation has detected one or more PHP configuration directives that\n". "will conflict with {$this->conf['product']}. These directive(s) are located in the\n". "server's php.ini file.\n\n". "The conflicting directive(s) are:\n\n". implode ("\n", $existing_bad_directives)."\n\n". "To resolve this problem, you can comment the above directive(s), restart\n". "your Web server, and re-run the {$this->conf['product']} installation.\n\n$add_msg" , true ); } } // PHP_INI_REORDER function php_ini_reorder() { $this->php_ini_open(); $zend_ext_order_table = array( "ZendExtensionManager" => "", "ZendExtensionManager_TS" => "", "ZendOptimizer" => "", "ZendOptimizer_TS" => "", "ZendAccelerator" => "", "ZendDebugger" => "", "ZendDebugger_TS" => "" ); foreach($this->conf['php_ini_cont'] as $line_num => $line){ $line = chop($line); if(preg_match("/^\s*zend_extension(?:_ts)?=([a-zA-Z0-9_\/\"-\.]*Zend[a-zA-Z0-9_]+\.[a-z]+)/", $line, $match)){ $zend_module = basename($match[1]); $zend_module = preg_replace("/\.[^\.]+$/", "", $zend_module); $zend_ext_order_table[$zend_module] = $line; $this->conf['php_ini_cont'][$line_num] = ""; } } foreach($zend_ext_order_table as $module => $line){ if(strlen($line) > 0) { array_push($this->conf['php_ini_cont'], "$line\n"); } } $this->install_log("PHP.ini re-ordered"); } // PHP_INI_REMOVE_ENTRY function php_ini_remove_entry($value, $just_comment=true) { $this->php_ini_open(); reset($this->conf['php_ini_cont']); foreach ($this->conf['php_ini_cont'] as $num => $line){ if(!preg_match("/^\s*;/", $line) && preg_match("#$value#", $line)){ if ($just_comment) { $this->conf['php_ini_cont'][$num] = preg_replace("@^\s*(.*$value)@m", ";Zend; \\1", $this->conf['php_ini_cont'][$num]); $this->install_log("Commenting PHP.ini entry: $line"); } else { unset($this->conf['php_ini_cont'][$num]); $this->install_log("Removing PHP.ini entry: $line"); } } } } // IN_PHP_INI function in_php_ini($key) { $this->php_ini_open(); reset($this->conf['php_ini_cont']); foreach ($this->conf['php_ini_cont'] as $num => $line){ $line = preg_replace("/;.*$/", "", $line); if(preg_match("/^\s*$key\s*=/", $line)){ return true; } } return false; } // PHP_INI_GET_ENTRY function php_ini_get_entry($key, $pattern="") { $this->php_ini_open(); reset($this->conf['php_ini_cont']); foreach ($this->conf['php_ini_cont'] as $num => $line){ $line = preg_replace("/;.*$/", "", $line); if(preg_match("@^\s*$key\s*=(.*".addcslashes($pattern, '@').".*)@", $line, $match)){ return trim($match[1], "\"\' \t "); } } if ($key != "zend_ini_file" && !strstr($this->conf['product'], 'ZendCore')) { # Try to search for value in zend.ini: if (!isset($this->conf['zend_ini_file_parsed'])) { $zend_ini_file = $this->php_ini_get_entry ("zend_ini_file"); if (@file_exists ($zend_ini_file)) { include_once ('Config.inc'); $this->zend_ini_config_cache =& new Config ($zend_ini_file, CONFIG_INI); } $this->conf['zend_ini_file_parsed'] = true; } if (isset($this->zend_ini_config_cache)) { $val = $this->zend_ini_config_cache->get ($key, null, $pattern); if ($val !== null) { return $val; } } } return ""; } // PHP_INI_MOVE_ENRY_TO_ZEND_INI function php_ini_move_entry_to_zend_ini ($entry, &$zend_ini_conf) { if ($this->in_php_ini ($entry)) { $value = $this->php_ini_get_entry ($entry); $zend_ini_conf->set ($entry, $value); $this->php_ini_remove_entry ($entry, false); } } // PHP_INI_ADD_ENTRY function php_ini_add_entry($key, $value, $replace_old_entries=true, $commented=false) { $this->php_ini_open(); $new_line = "$key=$value". $this->conf['nl']; if($commented){ $new_line = ";$new_line"; } reset($this->conf['php_ini_cont']); $replaced = false; foreach ($this->conf['php_ini_cont'] as $num => $line){ $line = preg_replace("/;.*$/", "", $line); if(preg_match("/^\s*$key\s*=/", $line)){ $replaced = true; if($replace_old_entries) { $this->conf['php_ini_cont'][$num] = $new_line; $this->install_log("Replaced line: ".$this->conf['php_ini_cont'][$num]." by: $new_line in php.ini"); } } } if (!$replaced) { array_push($this->conf['php_ini_cont'], $new_line); $this->install_log("Added new line to php.ini: $new_line"); } } // PHP_INI_UNCOMMENT_ENTRY function php_ini_uncomment_entry ($key) { $this->php_ini_open(); foreach ($this->conf['php_ini_cont'] as $num => $line){ if(preg_match("/^\s*\;\s*($key\s*=.*)$/", $line, $match)){ $this->conf['php_ini_cont'][$num] = $match[1].$this->conf['nl']; $this->install_log("Uncommented entry: {$key} in php.ini"); } } } // PHP_INI_ADD_PATH function php_ini_add_path($entry_name, $value) { $this->php_ini_open(); $sep = ":"; $old_value = $this->php_ini_get_entry($entry_name); $path_arr = explode($sep, $old_value); array_unshift ($path_arr, $value); $this->php_ini_add_entry ($entry_name, trim(implode($sep, array_unique ($path_arr)), " \t:")); } // PHP_INI_REPLACE_ENTRY function php_ini_replace_entry($old, $new) { $this->php_ini_open(); $replaced = false; reset($this->conf['php_ini_cont']); foreach ($this->conf['php_ini_cont'] as $num => $line){ if(preg_match("#$old#", $line)){ $this->conf['php_ini_cont'][$num] = preg_replace("#$old#", $new, $line); $replaced = true; } } return $replaced; } // PHP_INI_ADD_EXTENSION function php_ini_add_extension($path, $directive, $commented=false) { $this->php_ini_open(); $ext = basename($path); reset($this->conf['php_ini_cont']); $new_line = "$directive=$path". $this->conf['nl']; if($commented){ $new_line = ";$new_line"; } $found = false; foreach ($this->conf['php_ini_cont'] as $num => $line){ if(preg_match("/^\s*;\s*$directive\s*=.*$ext/", $line)){ $found = true; $this->conf['php_ini_cont'][$num] = $new_line; break; } $line = preg_replace("/;.*$/", "", $line); if(preg_match("/^\s*$directive\s*=.*$ext/", $line)){ $found = true; $this->conf['php_ini_cont'][$num] = $new_line; break; } } if(!$found){ array_push($this->conf['php_ini_cont'], $new_line); } $this->install_log("Added new extension to php.ini: $new_line"); } // PHP_INI_ADD_PHP_EXTENSION function php_ini_add_php_extension($path, $commented=false) { $this->php_ini_open(); $extension_dir = $this->php_ini_get_entry ("extension_dir"); if (empty($extension_dir) || !preg_match("/^\//", $extension_dir)) { $extension_dir = dirname($path); $this->php_ini_add_entry ("extension_dir", $extension_dir); $this->msgbox ( "Directive extension_dir in your PHP.ini was empty or wasn't set\n". "to absolute path. This directive has been changed to:\n$extension_dir\n\n". "If you intend to change this directive in the future,\n". "please copy all PHP extensions from:\n". "$extension_dir\nto the new location.\n" ); } $this->php_ini_add_extension (basename($path), "extension", $commented); if ($this->nice_path ($extension_dir) != $this->nice_path (dirname($path))) { $this->my_symlink ($path, $this->make_path ($extension_dir, basename($path))); } } // PHP_INI_ADD_ZEND_EXTENSION function php_ini_add_zend_extension($path, $directive="", $commented=false) { $this->php_ini_open(); if($directive == ""){ $directive = $this->conf['zend_ext_directive']; } $this->php_ini_add_extension($path, $directive, $commented); } // PHP_INI_ADD_ZEND_SECTION function php_ini_add_zend_section() { $this->php_ini_open(); $found = false; foreach ($this->conf['php_ini_cont'] as $num => $line){ $line = preg_replace("/;.*$/", "", $line); if(preg_match("/^\s*\[Zend\]\s*/", $line)){ $found = true; } } if(!$found){ array_push($this->conf['php_ini_cont'], str_repeat($this->conf['nl'], 2)."[Zend]".$this->conf['nl']); }else{ array_push($this->conf['php_ini_cont'], $this->conf['nl']); } } // PHP_INI_OPEN function php_ini_open() { if(!isset($this->conf['php_ini_cont'])){ $this->install_log("Reading PHP.ini: ".$this->conf['php_ini_path']); if($this->my_file_exists($this->conf['php_ini_path'])) { $this->conf['php_ini_cont'] = file($this->conf['php_ini_path']); } else { $this->install_log("Opened new (empty) PHP.ini"); $this->conf['php_ini_cont'] = array(); } $this->php_ini_set_unmodified(); $this->conf['php_ini_opened'] = true; $this->conf['php_ini_saved_file'] = $this->make_path( $this->conf['tmp_dir'], "saved", strtr($this->conf['php_ini_path'], "/\\: ", "____")); $this->my_mkdir (dirname($this->conf['php_ini_saved_file'])); $this->str2file (join("", $this->conf['php_ini_cont']), $this->conf['php_ini_saved_file']); $this->watch_config_files ($this->conf['php_ini_path']); } } // PHP_INI_RESTORE function php_ini_restore() { if(isset($this->conf['php_ini_saved_file'])) { if(@filesize($this->conf['php_ini_path']) < @filesize($this->conf['php_ini_saved_file'])) { $this->my_unlink ($this->conf['php_ini_path']); $this->my_move ($this->conf['php_ini_saved_file'], $this->conf['php_ini_path']); } } unset ($this->conf['php_ini_saved_file']); } // PHP_INI_CLOSE function php_ini_close($nobackup=false) { $this->php_ini_save($nobackup); unset($this->conf['php_ini_cont']); $this->conf['php_ini_opened'] = false; } // PHP_INI_MODIFIED function php_ini_modified() { if(isset($this->conf['php_ini_cont']) && isset($this->conf['php_ini_md5'])) { return (md5(implode("", $this->conf['php_ini_cont'])) != $this->conf['php_ini_md5']); } return false; } // PHP_INI_SET_UNMODIFIED function php_ini_set_unmodified() { if(isset($this->conf['php_ini_cont'])) { $this->conf['php_ini_md5'] = md5(implode("", $this->conf['php_ini_cont'])); } } // PHP_INI_SAVE function php_ini_save($nobackup=false) { if(isset($this->conf['php_ini_cont'])) { if(!$nobackup && $this->php_ini_modified()) { $this->php_ini_backup(); $this->install_log ("Saving PHP.ini file: ".$this->conf['php_ini_path']); $this->my_fwrite($this->conf['php_ini_path'], "w", join("", $this->conf['php_ini_cont'])); $this->php_ini_set_unmodified(); } } if (isset($this->conf['moved_pack_ini'])) { @unlink ($this->conf['moved_pack_ini']); unset ($this->conf['moved_pack_ini']); } } // PHP_INI_BACKUP function php_ini_backup() { if(!isset($this->conf['php_ini_backed_up'])) { $php_ini_backup = $this->my_backup($this->conf['php_ini_path'], true); if(isset($php_ini_backup)) { $this->conf['php_ini_backup_msg'] = "The original php.ini was backed up to\n $php_ini_backup"; } $this->conf['php_ini_backed_up'] = true; } } // PHP_INI_RELOCATE function php_ini_relocate() { $new_ini_path = $this->conf['prefix']."/etc/php.ini"; $this->my_mkdir($this->my_dirname($new_ini_path)); $old_ini_path = $this->strip_symlink($this->conf['php_ini_path']); $msg = "The following configuration changes have been made:\n\n"; if(realpath($old_ini_path) != realpath($new_ini_path)) { $this->install_log("Relocating php.ini from: $old_ini_path to: $new_ini_path"); $this->my_move($old_ini_path, $new_ini_path); $this->my_unlink($this->conf['php_ini_path']); $this->my_symlink($new_ini_path, $this->conf['php_ini_path']); $msg.= "- The php.ini file has been relocated from ".dirname($old_ini_path)." to ".dirname($new_ini_path)."\n\n". "- A symbolic link for the php.ini file has been created in ".dirname($this->conf['php_ini_path']).".\n"; $added_message = true; } if(!empty($this->conf['php_ini_backup_msg'])) { $msg .= "\n- ".$this->conf['php_ini_backup_msg']."\n"; $added_message = true; } if(!isset($added_message)) { return; } if(!preg_match("/^\s*$/s", $msg)) { $this->msgbox($msg); } } // PHP_INI_GET_PRODUCT_VERSION /* $product_suffix - product name suffix in Zend Extension Manager PHP.ini entry */ function php_ini_get_product_version($product_suffix) { $this->php_ini_open(); $product_path = $this->php_ini_get_entry ("zend_extension_manager.$product_suffix"); if(@file_exists ($product_path)) { return substr ($product_path, strrpos($product_path, "-")+1); } return false; } // ------------------ // INSTALL FUNCTIONS // ================== // GET_COMPONENT_VERSION function get_component_version($name) { $name .= ".version"; if(!isset($this->conf['build_info'][$name])) { $this->on_error("Cannot find version of $name in the package."); } return $this->conf['build_info'][$name]; } // ADD_PACKAGE_INFO function add_package_info() { $this->move_pack_ini_to_php_ini(); $this->php_ini_add_entry (strtolower(str_replace(" ", "_", $this->conf['product'])).".version", $this->get_component_version("package")); } // MOVE_PACK_INI_TO_PHP_INI function move_pack_ini_to_php_ini ($pack_ini=null) { if (@file_exists ($pack_ini)) { $pack_conf = @parse_ini_file($pack_ini); foreach ($pack_conf as $name => $val) { $this->php_ini_add_entry ($name, $val); } $this->conf['moved_pack_ini'] = $pack_ini; } } // ADD_COMPONENT function add_component($name, $destination, $make_backup) { if (!isset ($this->conf['components'][$name])) { $this->conf['components'][$name] = array($destination, $make_backup); } } // GET_COMPONENT_DEST function get_component_dest ($name) { foreach ($this->conf['components'] as $comp_name => $data) { if(count ($data) == 2 && $comp_name == $name || count ($data) == 4 && $data[2] == $name) { return $data[0]; } } return null; } // SET_COMPONENTS function set_components($new_components) { $this->conf['components'] = $new_components; } // REMOVE_COMPONENT function remove_component($name) { unset($this->conf['components'][$name]); } // COMPONENT_EXISTS function component_exists($name) { return isset($this->conf['components'][$name]); } // SET_VAR_COMPONENT function set_var_component($pattern, $value) /* substitute undefined variables in components destinations */ { foreach($this->conf['components'] as $name => $data){ $this->conf['components'][$name][0] = preg_replace("#$pattern#", $value, $data[0]); } } // START_INSTALL function start_install ($stop_webserver=true, $progress_delay=0) { ini_set("max_execution_time", 100000000); /* give reasonable execution time */ if(false && $this->is_using_apache()) { # If there are old copies of files in the installation prefix # try to stop the Web server before overwritting them foreach (array_keys($this->conf['components']) as $file) { if(preg_match("/\.so$/", $file)) { if($this->find_file ($this->conf['prefix'], basename($file)) > 0) { $msg = "The installation has found installation of Zend product in ". $this->conf['prefix']."\n\n". "Its recommended to stop your Web server before proceeding with copying\n". "new files onto your system. Your Web server will be started automatically\n". "by the installation after it finishes to copy files.\n\n". "Do you want to stop your Web server now?"; if($this->yesnobox($msg)) { $webserver_stopped = $this->apache_stop (); } break; } } } } $percent = 0; $size_done = 0; $backup_dirs = array(); // array of the directories to backup $total_size = $this->gather_components_info($backup_dirs); if($total_size == 0) { $total_size = 100; } //$this->dialog_calc_max_size(); $gb = new Gaugebox( empty ($this->conf['dialog']) ? null: $this->conf['dialog'], isset ($this->conf['max_x']) ? $this->conf['max_x'] : null, isset ($this->conf['max_y']) ? $this->conf['max_y'] : null, null, 0, $this->conf['title'] ); foreach($backup_dirs as $dir){ $this->my_backup($dir); } foreach($this->conf['components'] as $what => $data){ $where = $data[0]; // path where to install $make_backup = $data[1]; // either make a backup or not $comp_name = $data[2]; // name of the component $file_size = $data[3]; // file size of the component $size_done += $file_size; $percent = (int)(($size_done/$total_size)*100); $gb->update("Installing $comp_name", $percent); if($make_backup){ $this->my_backup("$where/".basename($comp_name)); } if(!$this->my_dir_exists($where)){ /* create the destination directory */ $this->my_mkdir_long ($where); } $this->my_copy($what, $where, false /* dont follow symbolic links */ ); /* perform copy */ if ($progress_delay > 0) { usleep ($progress_delay); } } $gb->close(); if (empty($this->conf['dialog'])) { print ("\n"); } if(isset($webserver_stopped)) { $this->apache_start(); } } // GATHER_COMPONENTS_INFO function gather_components_info(&$backup_dirs) { $this->install_log("Gathering components info ..."); $total_size = 0; foreach($this->conf['components'] as $what => $data){ $where = $data[0]; $backup = $data[1]; $comp_found = false; foreach ($this->conf['comp_dirs_arr'] as $dir){ $comp = $this->nice_path("$dir/$what"); if($this->my_file_exists($comp)){ $file_size = filesize($comp); $total_size += $file_size; $new_comp_arr[$comp] = array($where, $backup, $what, $file_size); $comp_found = true; break; } elseif($this->my_dir_exists($comp)){ $this->pushd($comp); $this->get_file_tree(".", $files_arr); if($backup){ array_push($backup_dirs, $where); } foreach($files_arr as $file => $file_size){ $total_size += $file_size; $dir_dest = $this->nice_path("$where/".$this->my_dirname($file)); $new_comp_arr[$this->nice_path("$comp/$file")] = array($dir_dest, false, $what, $file_size); } $this->popd(); $comp_found = true; break; } } if(!$comp_found) { $this->on_error("Installation component: '$what' was not found."); } } $this->conf['components'] = $new_comp_arr; return $total_size; } // ADD_GROUP /** * @param string group name * @param int suggested group ID */ function add_group($group, $gid=null) { $err = null; // First check whether such group already exists: if (posix_getgrnam($group) !== false) { return true; } if ($this->conf['uname']['sysname'] == "AIX") { if ($this->run_command ("mkgroup {$group}") == 0) { if ($gid !== null) { $this->run_command ("chgroup id={$gid} {$group}"); } } else $err = "Bad exit status from command: \"mkgroup {$group}\""; } else if ($this->conf['uname']['sysname'] == "Darwin") { if ($this->run_command ("nicl . -create /groups/{$group}") == 0) { if ($gid !== null) { // Try to change the group ID: $this->run_command ("nicl . -createprop /groups/{$group} gid {$gid}"); $this->run_command ("nicl . -createprop /groups/{$group} passwd '*'"); } $err = null; } else $err = "Bad exit status from command: \"nicl . -read /groups/{$group}\""; } else { $cmd = $this->search_cmd_in_path ("pw", true); if ($cmd) { if ($this->run_command ("{$cmd} groupadd {$group}") == 0) { if ($gid !== null) { // Try to change the group ID: $this->run_command ("{$cmd} groupmod {$group} -g {$gid}"); } $err = null; } else $err = "Bad exit status from command: \"{$cmd} groupadd {$group}\""; } else { foreach (array ('groupadd', 'addgroup') as $cmd) { $cmd = $this->search_cmd_in_path ($cmd, true); if ($cmd) break; } if ($cmd) { if ($this->run_command ("{$cmd} {$group}") == 0) { if ($gid !== null) { // Try to change the group ID: $modcmd = $this->search_cmd_in_path ("groupmod", true); if ($modcmd) { $this->run_command ("{$modcmd} -g {$gid} {$group}"); } } $err = null; } else $err = "Bad exit status from command: \"{$cmd} {$group}\""; } else $err = "Couldn't find program utility for adding new group to this system"; } } if ($err) { $this->msgbox("The group {$group} couldn't be added! The error was:\n\n{$err}\n\nPlease add the group {$group} manually."); return false; } return true; } // REMOVE_GROUP /** * @param string group name */ function remove_group($group) { $err = null; if (posix_getgrnam($group) === false) { return; } if ($this->conf['uname']['sysname'] == "Darwin") { if ($this->run_command ("nicl . -delete /groups/{$group}") != 0) { $err = "Bad exit status from command: \"nicl . -delete /groups/{$group}\""; } } else { $cmd = $this->search_cmd_in_path ("pw", true); if ($cmd) { if ($this->run_command ("{$cmd} groupdel {$group}") != 0) { $err = "Bad exit status from command: \"{$cmd} groupdel {$group}\""; } } else { foreach (array ('groupdel', 'delgroup', 'rmgroup') as $cmd) { $cmd = $this->search_cmd_in_path ($cmd, true); if ($cmd) break; } if ($cmd) { if ($this->run_command ("{$cmd} {$group}") != 0) { $err = "Bad exit status from command: \"{$cmd} {$group}\""; } } else $err = "Couldn't find program utility for deleting a group from this system"; } } if ($err) { $this->msgbox("The group {$group} couldn't be deleted! The error was:\n\n{$err}\n\nPlease delete the group {$group} manually."); } } // ADD_USER /** * @param string user name * @param string home directory path * @param string shell (default: /bin/false) * @param int suggested user ID (optional) */ function add_user($user, $home_dir, $uid=null) { $err = null; // First check whether such user already exists: if (posix_getpwnam($user) !== false) { return true; } if ($this->conf['uname']['sysname'] == "AIX") { if ($this->run_command ("mkuser home={$home_dir} {$user}") == 0) { if ($uid !== null) { $this->run_command ("chuser id={$uid} {$user}"); } } else $err = "Bad exit status from command: \"mkuser {$user}\""; } else if ($this->conf['uname']['sysname'] == "Darwin") { if ($this->run_command ("nicl . -create /users/{$user}") == 0) { if ($uid !== null) { // Try to change the user ID: $this->run_command ("nicl . -createprop /users/{$user} uid {$uid}"); $this->run_command ("nicl . -createprop /users/{$user} passwd '*'"); $this->run_command ("nicl . -createprop /users/{$user} home {$home_dir}"); } $err = null; } else $err = "Bad exit status from command: \"nicl . -read /users/{$user}\""; } else { $cmd = $this->search_cmd_in_path ("pw", true); if ($cmd) { if ($this->run_command ("{$cmd} useradd {$user} -d {$home_dir}") == 0) { if ($uid !== null) { // Try to change the user ID: $this->run_command ("{$cmd} usermod {$user} -g {$uid}"); } $err = null; } else $err = "Bad exit status from command: \"{$cmd} useradd {$user}\""; } else { foreach (array ('useradd', 'adduser') as $cmd) { $cmd = $this->search_cmd_in_path ($cmd, true); if ($cmd) break; } if ($cmd) { if ($this->run_command ("{$cmd} -d {$home_dir} {$user}") == 0) { if ($uid !== null) { // Try to change the user ID: $modcmd = $this->search_cmd_in_path ("usermod", true); if ($modcmd) { $this->run_command ("{$modcmd} -g {$uid} {$user}"); } } $err = null; } else $err = "Bad exit status from command: \"{$cmd} {$user}\""; } else $err = "Couldn't find program utility for adding new user to this system"; } } if ($err) { $this->msgbox("The user {$user} couldn't be added! The error was:\n\n{$err}\n\nPlease add the user {$user} manually."); return false; } return true; } // REMOVE_USER /** * @param string user name */ function remove_user($user) { $err = null; if (posix_getpwnam($user) === false) { return; } if ($this->conf['uname']['sysname'] == "Darwin") { if ($this->run_command ("nicl . -delete /users/{$user}") != 0) { $err = "Bad exit status from command: \"nicl . -delete /users/{$user}\""; } } else { $cmd = $this->search_cmd_in_path ("pw", true); if ($cmd) { if ($this->run_command ("{$cmd} userdel {$user}") != 0) { $err = "Bad exit status from command: \"{$cmd} userdel {$user}\""; } } else { foreach (array ('userdel', 'deluser', 'rmuser') as $cmd) { $cmd = $this->search_cmd_in_path ($cmd, true); if ($cmd) break; } if ($cmd) { if ($this->run_command ("{$cmd} {$user}") != 0) { $err = "Bad exit status from command: \"{$cmd} {$user}\""; } } else $err = "Couldn't find program utility for deleting a user from this system"; } } if ($err) { $this->msgbox("The user {$user} couldn't be deleted! The error was:\n\n{$err}\n\nPlease delete the user {$user} manually."); } } // SET_PERMISSIONS function set_permissions($file, $mode, $owner="", $group="") { $this->install_log("Setting permissions on $file: mode=$mode". (empty($owner) ? "":", owner=$owner").(empty($group) ? "":", group=$group")); if(!$this->my_file_exists($file) && !$this->my_dir_exists($file)){ $this->on_error("File: $file does not exist."); } if(!empty($owner)){ if(!chown($file, $owner)){ $this->on_error("Cannot set ownership for: $file"); } } if(!empty($group)){ if($group == "zendtech"){ $this->add_group($group, 200); } if(!@chgrp($file, $group)){ $this->warn("Cannot set group $group for file $file"); } } if(!empty($mode)){ if(!chmod($file, octdec($mode))){ $this->on_error("Cannot set permissions for: $file"); } } } // ADD_PERMISSIONS function add_permissions($file, $mode, $owner="", $group="") { array_push($this->conf['file_perms'], array($file, $mode, $owner, $group)); } // SET_FILE_PERMISSIONS function set_file_permissions() { foreach ($this->conf['file_perms'] as $perms){ if(isset($this->conf['prefix'])) { $file = $this->make_full_path($perms[0], $this->conf['prefix']); } $this->set_permissions ($file, $perms[1], $perms[2], $perms[3]); } } // FILE_TYPE function file_mime_type($filename) { if(!function_exists('mime_content_type')) { $file_cmd = $this->search_cmd_in_path ("file"); if($file_cmd) { $mime_type = trim($this->cmd2str("$file_cmd -bi $filename 2>/dev/null")); if(preg_match("/(\w+\/[^\s\(\)\<\>\@\,\;\:\\\"\/\[\]\?\=]+)/", $mime_type, $match)) { return $match[1]; } return false; } } else return mime_content_type($filename); return false; } // CRONTAB_ERROR function crontab_error($cron_err) { $answer = $this->yesnobox("WARNING!\n\n$cron_err\n\nWould you like to continue setup anyway?", true); if(!$answer) { $this->default_abort(); } } // ADD_TO_CRONTAB function add_to_crontab( $cron_msg, $user, $line, $cron_warn, $cron_err, $ident = "Zend crontab entry") { if (!$line) { $this->install_log("Removing {$ident} from the $user's crontab file."); } else { $this->install_log("Trying to add the line: $line to the $user's crontab file."); } $cron_deny_files = array( "/usr/lib/cron/cron.deny", /* IRIX 5.3 */ "/etc/cron.d/cron.deny", /* SunOS 5.X */ "/var/spool/cron/cron.deny", /* SunOS 4.X */ "/etc/cron.deny", /* Linux */ "/var/adm/cron/cron.deny" /* HP-UX */ ); foreach ($cron_deny_files as $file) { if($this->my_file_exists($file)) { if(preg_match("/^$user$/m", $this->file2str($file))) { $this->crontab_error($cron_err); return; } } } $crontab_opt = $this->cmd2str("crontab -H 2>&1"); // get crontab options (guess type) if(preg_match("@-u\s+user@", $crontab_opt)){ $crontab_type = 2; } else if(preg_match("@user@", $crontab_opt)){ $crontab_type = 1; } if(isset($crontab_type)){ if($crontab_type == 1){ $crontab_cont = $this->cmd2str("crontab -l $user 2>/dev/null"); } else{ $crontab_cont = $this->cmd2str("EDITOR=cat VISUAL=cat crontab -u $user -e 2>/dev/null"); } $error = "Failed to execute command: "; // remove the old settings $crontab_cont = preg_replace("@[\r\n]*# ".$ident.":.*# End of ".$ident."[\r\n]*@s", "\n", $crontab_cont); if ($line) { // add the new line $crontab_cont .= "\n# $ident:\n$line\n# End of $ident\n"; while(true) { if(!$this->yesnobox( "$cron_msg\n\nWe are going to add scheduled execution to the crontab of user $user:\n\n". wordwrap($line, $this->conf['wrap_size'])."\n\nDo you accept?")) { if($this->yesnobox($cron_warn)) { $this->default_abort(); } continue; } break; } } $fp = $this->my_fopen($this->conf['tmp_dir']."/crontab", "w"); fwrite($fp, $crontab_cont); fclose($fp); if($crontab_type == 1){ // First type of crontab $proc_env = "EDITOR=\"cat ". $this->conf['tmp_dir'] ."/crontab >\" "; $proc_env .= "VISUAL=\"cat ". $this->conf['tmp_dir'] ."/crontab >\""; if($this->run_command($proc_env." crontab -e $user")==0){ unset($error); } else { $error .= "crontab -e $user"; } } else { // Second type if($this->run_command("crontab -u $user ". $this->conf['tmp_dir'] ."/crontab")==0){ unset($error); } else { $error .= "crontab -u $user ". $this->conf['tmp_dir'] ."/crontab"; } } } else { $error = "Failed to execute crontab."; } if(isset($error)){ //$this->warn("Couldn't add a crontab scheduled execution.\n$error"); $this->crontab_error($cron_err); } } // -------------------------- // LICENSE FUNCTIONS // ========================== // SHOW_LICENSE function show_license($file, $message="\n") { while(true) { $this->show_file($file); if(!$this->yesnobox($message."Do you accept the terms of this license?")) { if($this->yesnobox("In order to install ".$this->conf['product']." you must accept this agreement!\n". "Do you really want to cancel the installation?", true)) { $this->on_abort("", true); } } else { break; } } } // LICENSE_AGMNT_BOX function license_agmnt_box() { $license_agr_file = $this->search_file(array("../", "../data"), array("LICENSE")); if(!@file_exists ($license_agr_file)) { $this->on_error("Can't find file LICENSE in the package."); } $this->install_log("Showing license: {$license_agr_file}"); $license = "IMPORTANT:\n". "BY SELECTING THE 'YES' OPTION BELOW, DOWNLOADING, INSTALLING, OR\n". "OTHERWISE USING THIS SOFTWARE, YOU ACKNOWLEDGE THAT YOU HAVE READ THE\n". "LICENSE AGREEMENT, AND THAT YOU AGREE TO BE BOUND BY ITS TERMS AND\n". "CONDITIONS.\n". "IF YOU DO NOT AGREE TO ALL OF THE TERMS AND CONDITIONS OF SUCH AGREEMENT,\n". "YOU ARE NOT AN AUTHORIZED USER OF THE SOFTWARE AND IT IS YOUR\n". "RESPONSIBILITY TO EXIT THIS DOWNLOADING/INSTALLATION PROCESS WITHOUT\n". "DOWNLOADING OR INSTALLING THE SOFTWARE BY SELECTING THE 'NO' OPTION BELOW,\n". "AND TO DELETE THE SOFTWARE FROM YOUR COMPUTER.\n\n\n"; $this->show_license ($license_agr_file, $license); } // VERIFY_KEY function verify_key($user, $key) { $rc = $this->run_command("./verifykey \"$user\" $key"); if($rc == 0){ $this->on_error("Wrong parameters passed to verifykey."); } if($rc == 127){ $this->on_error("Could not execute verifykey."); } return $rc; } // DLG_VERIFY_LICENSE_KEY function dlg_verify_license_key(&$user, &$key) { if(isset($this->conf['license_user'])) { $user = $this->conf['license_user']; } if(isset($this->conf['license_key'])) { $key = $this->conf['license_key']; } $rc = 0; do{ switch($rc){ case 0: $error = ""; break; case 255: $error = "The name and/or key you have entered are incorrect !\n\n"; break; case 254: $error = "The key you have entered has expired !\n\n"; break; default : $error = "Unrecognized return value from verifykey !\n\n"; } $user = $this->inputbox( $error."Please enter the Registration Name you received for the ".$this->conf['product'], $user); while(true){ $key = $this->inputbox("Please enter the License Key you received for the ".$this->conf['product'], $key); if(!preg_match("/^[A-Za-z0-9]+$/", $key)){ $this->msgbox("The key you entered contains invalid characters. Please try again!"); } else{ $key = preg_replace("/^LK/i", "", trim($key)); if(!preg_match("/^[A-Za-z0-9]+$/", $key)){ $this->msgbox("Invalid key. Please try again!"); }else{ break; } } } } while(($rc = $this->verify_key($user, $key)) != 1); } // GET_LMUTIL_HOST_ID /* function get_lmutil_host_id() { $line = $this->cmd2str("../lmutil lmhostid"); if(!preg_match("/^.+\"(.+)\"/m", $line, $hostid)){ $this->on_error("Can't determine host ID."); } return $hostid[1]; } */ function generate_trial_license($install_trial_utility = true) { // generate trial license with special secret utility $this->infobox ('Generating trial license...'); preg_match ('/(M:[A-Z0-9\-]+)/', $this->get_host_id(), $matches); $m_host_id = $matches[1]; $trial_utility = $this->generate_trial_utility(); $license_file = (isset($this->conf['trial_license_file']) ? $this->conf['trial_license_file'] : $this->conf['license_file']); $rc = $this->run_command ($trial_utility . ' ../data/' . $license_file . " $m_host_id"); if ($rc != 0) { $msg = ''; switch ($rc) { case 1: $msg = 'Utility not installed'; break; case 2: $msg = 'Utility expired'; break; case 3: case 31: case 32: case 33: $msg = 'Utility broken'; break; case 4: $msg = 'Invalid host id'; break; case 5: $msg = 'Signature failed'; break; case 7: $msg = 'Random geberator failed'; break; case 8: $msg = 'Utility expired'; break; } $this->msgbox ("Error generating trial license: ${msg}."); return (-1); } if ($install_trial_utility) { $this->add_component ($trial_utility, $this->conf['prefix']."/sbin", false); } } function get_license(&$passwd, &$uid, $license_file = "") { if($license_file == ""){ $license_file = $this->conf['license_file']; } // check for license in package if($this->my_file_exists("../data/$license_file")){ return 0; } $args = array(); static $save_args; //if(extension_loaded("curl") && $this->conf['interactive']) { if ($this->conf['interactive']) { //$m1 = 'Download a license file from ' . $license_downloader->conf['license_host']; $m1 = 'Get a license from Zend'; $m2 = "Search for a license file on my disk"; $menu = array(1 => $m1, 2 => $m2); $msg_add = isset($this->conf['accept_licenses']) ? "" : " The license file is called: \"{$license_file}\"."; $msg = "In order to proceed, setup needs a valid license file.{$msg_add} If you don't have a valid license file, select \"{$m1}\". Otherwise select \n\"{$m2}\".\n\nThe license file can also be downloaded manually from:\nhttp://www.zend.com/store/pickup.php\n\n"; $msg = wordwrap ($msg, $this->conf['wrap_size']); $rc = $this->menubox($msg, $menu); } else { $rc = 2; } if($rc == 2){ $this->find_license_on_disk($license_file); } elseif($rc == 1){ if(defined('SERIAL_NUMBER')) { // pasha nov 28 2005: as of now, it is possible to download from zend.com // a commerical license only $trial_commerc = "c"; if ($trial_commerc == "c"){ $serial = $this->dlg_ask_serial_number(); // It's impossible, that user won't be registered on the site, // if he has a commercial license: list ($username, $passwd) = $this->dlg_username_password(); // download license from zend.com $this->progress_bar_start (300, "Downloading license. Please wait...\n(this may take a few minutes)", 'Downloading ...'); $license_downloader = new LicenseDownloader ($this->logger, $this->error_handler); list ($ret_value, $license, $error_msg) = $license_downloader->download ($username, md5 ($passwd), $this->conf['product_id'], $this->conf['version_for_license'], $serial); $this->progress_bar_stop(); // write license to a file if( ! $this->my_fwrite ($license_file, "w", $license)) { $this->error_handler->on_error ('Could not write license file.'); } $new_license_file = $license_file; if (preg_match ('@^\s*Product-Name\s*=(.*)$@m', $this->file2str($license_file), $match)) { $new_license_file = str_replace (' ', '_', strtolower (trim ($match[1], " \t\r\n"))) . '.zl'; } if ($license_file != $new_license_file) { $this->my_rename ($license_file, $new_license_file); $license_file = $new_license_file; } if (($ret_value == -1) && (! empty ($error_msg))) { $this->license_errmsg ($error_msg); } if ($ret_value != -1) { // license file needs to end up in 'data' for install_license() $this->my_copy($license_file, "../data/$license_file"); $this->conf['license_file'] = $license_file; } if ($ret_value == -1) { $passwd = ''; $uid = ''; } if (! defined('SERIAL_NUMBER')) { if (isset ($ret_value) && ($ret_value != -1) && preg_match("/^\s*\d+$/", $ret_value)) { $this->msgbox ('Successfully downloaded a ' . trim ($ret_value). '-day trial license!'); } else { $this->msgbox ('Successfully downloaded license file!'); } } if(defined('SERIAL_NUMBER') && ($ret_value!=-1)) { if(defined('TRIAL')) { $this->msgbox ('Successfully downloaded a ' . trim($ret_value) . '-day trial license.'); } else { $this->msgbox ("Successfully downloaded license file.\n". "In case you may wish to download your license information in the future,\n". "you may do so by accessing http://www.zend.com/store/pickup.php"); } return (0); } return ($ret_value); // end of license download } else { $this->generate_trial_license(); } } else { // TODO: I don't know when this supposed to be executed, // bring it in a sync with the fact that only commercial license // could be downloaded from zend.com list ($username, $passwd) = $this->dlg_username_password ("(If you don't have a Zend username,\nplease register at www.zend.com/add_user.php)\n\n"); } } return 0; } // end of get_license() // REGISTER_USER function register_user(&$args) { do { $this->forms->reg_page1($args); } while(!$this->forms->reg_page2($args)); } // returns: serial number //function dlg_ask_serial_number(&$args) function dlg_ask_serial_number() { if(isset($this->conf['serial_number'])) { $serial = $this->conf['serial_number']; } else { do { $serial = $this->inputbox("Please enter your serial number. The serial number can be found at\n". "http://www.zend.com/store/pickup.php or in the purchase confirmation E-mail"); if(strlen($serial) < 8){ $this->msgbox("Serial number must contain 8 or more characters"); } elseif(!preg_match ("/^SN/i",$serial)){ $this->msgbox("Serial number should start with SN"); } else break; } while(true); } //$args["serial"] = $serial; return ($serial); } // DLG_TRIAL_COMMERCIAL function dlg_trial_commercial(&$args) { if(!$this->conf['interactive']) { return "c"; } if(defined('TRIAL')){ /* return immidiately, if the product is for trial usage */ return "t"; } $m = array( "t" => "Get Trial License", "c" => "Get Commercial License" ); $r = $this->menubox("Is the product for trial or commercial use?", $m, false, "", "c"); return $r; } // DLG_EXISTING_USER_ASK function dlg_existing_user_ask() { if(!isset($this->conf['existing_zend_com_account'])) { $this->conf['existing_zend_com_account'] = $this->yesnobox("Do you have a Zend.com account?\n". "You will be asked for your Zend.com username\nand password during installation."); } return $this->conf['existing_zend_com_account']; } // returns: 2-element array (username, password) //function dlg_username_password(&$args, $msg="") function dlg_username_password ($msg="") { $username_def = ""; if(isset($this->conf['zend_username'])) { $username_def = $this->conf['zend_username']; } $password_def = ""; if(isset($this->conf['zend_password'])) { $password_def = $this->conf['zend_password']; } $this->conf['zend_username'] = $this->inputbox($msg."Please enter your Zend.com username", $username_def); $this->conf['zend_password'] = $this->password_get("Please enter your Zend.com password: "); if(empty($this->conf['dialog'])){ print("\n"); } /* $args["uid"] = $this->conf['zend_username']; $args["pass"] = $this->conf['zend_password']; */ return (array ($this->conf['zend_username'], $this->conf['zend_password'])); } // FIND_LICENSE_ON_DISK function find_license_on_disk($license_file="", $product="", $license_def_dir="") { if(empty($license_file)){ $license_file = $this->conf['license_file']; } // check for license in package if($this->my_file_exists("../data/$license_file")){ return 0; } if (!$this->conf['interactive']) { $this->on_error ("Please put your license file into: ". $this->make_path ($this->conf['installer_dir'], "data")); } // look for a license in current directory if($this->my_file_exists("./$license_file")){ $this->my_move($license_file, "../data/$license_file"); return 0; } if(empty($product)){ $product = $this->conf['product']; } $license_dir=""; if(isset($this->conf['accept_licenses'])) { while (true) { $lf = $this->select_file("Please enter full path to the license file\n". "(it's called: ".join(" or ", $this->conf['accept_licenses']).")", $license_def_dir); if(in_array(basename($lf), $this->conf['accept_licenses'])) { $license_file = basename($lf); $license_dir = dirname($lf); break; } $this->msgbox("License file should be called: ".join(" or ", $this->conf['accept_licenses']). "\nPlease try again!"); } } else { while(true){ $license_dir = $this->choose_dir( "Specify a path to a $product license file\n(it's called: $license_file)", $license_def_dir); if(basename ($license_dir) == $license_file) { if(!$this->my_file_exists($license_dir)) { $this->msgbox ("License file: {$license_dir}\ndoes not exist. Please try again."); } else { $license_dir = dirname($license_dir); break; } } else if($this->my_dir_exists ($license_dir)) { if(!$this->my_file_exists($this->make_path($license_dir, $license_file))) { $this->msgbox ("License file: ". $this->make_path($license_dir, $license_file)."\ndoes not exist. Please try again."); } else break; } else { $this->msgbox ("No such file or directory: $license_dir"); } } } if($this->nice_path($license_dir."/".$license_file) != $this->nice_path("../data/$license_file")) { $this->my_copy($license_dir."/".$license_file, "../data/$license_file"); } $this->conf['license_file'] = $license_file; return $license_dir; } // LICENSE_ERRMSG function license_errmsg($msg) { $this->msgbox( "There was a problem downloading the license file:\n\n$msg\n" . "If you still can't download a license file, you can download it from\n". "http://www.zend.com/store/pickup.php, or email the Zend sales team at\n". "sales@zend.com." ); return -1; } // INSTALL_LICENSE function install_license($license=null, $prefix=null) { if(!$prefix){ $prefix = $this->conf['prefix']; } if(!$license){ $license = $this->conf['license_file']; } if(!$this->my_file_exists("../data/$license")){ $this->on_error("License file: $license does not exist"); } $this->my_mkdir_long($prefix); #$this->infobox("Installing license $license ..."); // don't overrite existing license $this->my_copy("../data/$license", $prefix, true, false); $this->conf['license_installed'] = true; } // DETECT_IP_ADDRESS function detect_ip_address ($default_ip = null) { $ext_ip = null; # First try to determine IP via external interface $def_route_line = shell_exec("netstat -r 2>/dev/null"); $this->install_log ("\"netstat -r\" returned: $def_route_line"); if(preg_match("/^\s*default.*\s([^\s]+)\s*$/m", $def_route_line, $match)) { $ext_int = $match[1]; } else $this->install_log ("Couldn't detect the default network interface"); if(isset($ext_int)) { $ifconfig_out = shell_exec("/sbin/ifconfig $ext_int 2>/dev/null"); $this->install_log ("\"/sbin/ifconfig $ext_int\" returned: $ifconfig_out"); if(preg_match("/inet\s[^\d]*([\d\.]+)/", $ifconfig_out, $match)) { $ext_ip = $match[1]; } else $this->install_log ("Couldn't parse the output from the /sbin/ifconfig"); } if(!$ext_ip) { # Try to reverse hostname: $hostname = $this->conf['uname']['nodename']; $ext_ip = @gethostbyname ($hostname); } if(!$this->is_ip_valid($ext_ip) || strncmp($ext_ip, "127.", 4) == 0) { $ext_ip = null; } if(!$ext_ip) { if ($default_ip) { $ext_ip = $default_ip; } else { $msg = "The installation has failed to detect the external IP address of your machine."; while (true) { $ext_ip = $this->inputbox ("{$msg}\nPlease enter the external IP address of your machine"); if (!$this->is_ip_valid ($ext_ip) || strncmp($ext_ip, "127.", 4) == 0) { $msg = "The IP address you entered is invalid or irresolvable from outside."; continue; } break; } } } return $ext_ip; } // PIDOF function pidof($process) { $ps = $this->search_cmd_in_path ("ps"); $pids = array(); if($ps) { $out = $this->cmd2str("$ps aux 2>/dev/null"); if(empty($out)) { $out = $this->cmd2str("$ps -ef 2>/dev/null"); } $this->install_log ("Trying to find PID of $process..."); if(preg_match_all("/^[^\d]*(\d+)\s.*".addcslashes($process, "/")."/m", $out, $match)) { for($i=0; $i 10) { # To eliminate any possible error and not to kill the all array_push ($pids, $match[1][$i]); } } } } return $pids; } // RUNAS2STR function runas2str($cmd, $user, $need_logging = true) { $runas = $this->search_cmd_in_path("runas"); if(!@file_exists($runas)) { $this->on_error ("Cannot find utility: runas"); } $uid = $this->user2uid($user); return $this->run_command ("$runas $uid \"$cmd\"", $need_logging); } // RUNAS function runas($cmd, $user) { $runas = $this->search_cmd_in_path("runas"); if(!@file_exists($runas)) { $this->on_error ("Cannot find utility: runas"); } $uid = $this->user2uid($user); return $this->run_command ("$runas $uid \"$cmd\""); } // DIR_IS_WRITABLE_BY_USER function dir_is_writable_by_user($dir, $user, $msg=true) { if(!$this->my_dir_exists ($dir)) { return false; } $grid = posix_getgrgid(filegroup($dir)); if($grid["name"] == $user) { return true; } $test_file = "$dir/.test_file_create.".getmypid(); if($this->runas("touch $test_file", $user) == 0) { $this->my_delete($test_file); return true; } if ($msg) { $this->msgbox ("Directory: $dir is not writable by user '$user'!\n". "Please check, that '$user' can write to that directory,\n". "otherwise ".$this->conf['product']." may not work properly!"); } return false; } // KILL_PROCESS function kill_process ($name, $signal="KILL") { $status = 1; # Try to lookup PID's for the process and use simple kill utility $kill = $this->search_cmd_in_path ("kill"); $killall = $this->search_cmd_in_path ("killall"); $pids = $this->pidof($name); if($kill && count($pids) > 0) { $status = $this->run_command ("{$kill} -{$signal} ".join(" ", $pids)." 1>/dev/null"); $pids = $this->pidof($name); if(count($pids) > 0) $status = 1; else $status = 0; } else if(PHP_OS != "SunOS" && PHP_OS != "AIX" && $killall) { $status = $this->run_command ("{$killall} -{$signal} {$name} 1>/dev/null"); } if($status == 0) $this->install_log ("Killed process: $name with signal: $signal"); else $this->install_log ("Failed to kill process: $name"); return $status; } // WRITE_VHOSTS_FILE function write_vhosts_file($vhosts_file) { if($this->my_file_exists($vhosts_file)) { $vhosts_arr = @file($vhosts_file); } else $vhosts_arr = array(); //create vhosts.ini for configuration vr_hosts : //host:ip;document_root foreach ($vhosts_arr as $num => $line) { if(strncmp($line, "http://", 7)==0 || strncmp($line,"https://", 8)==0) { continue; } $proto = "http"; if(preg_match("/:(\d+)/", $line, $match)) { if($match[1] == "443"){ $proto = "https"; } } $vhosts_arr[$num] = "$proto://$line"; } if(isset($this->conf['apache_vhosts'])) { foreach ($this->conf['apache_vhosts'] as $vhost_key => $vhost_docroot_array) { $vhost_ip=$vhost_docroot_array['ip']; $vhost_port=$vhost_docroot_array['port']; $vhost_servername=$vhost_docroot_array['server']; $vhost_docroot = $vhost_docroot_array['docroot']; $is_ssl = $vhost_docroot_array['ssl']; if($vhost_port == "443" || $is_ssl) { $proto = "https"; } else $proto = "http"; if($vhost_port == "80") { $vhost_port = ""; } else $vhost_port = ":$vhost_port"; if (preg_match("/\d+\.\d+\.\d+\.\d+/",$vhost_ip)) { $vhost_servername = $vhost_ip; } array_push($vhosts_arr, "$proto://$vhost_servername$vhost_port;$vhost_docroot\n"); } } $this->my_fwrite($vhosts_file, "w", implode("", array_unique($vhosts_arr))); } // CURL_GET function curl_get($url, $timeout=300, $silent=true) { if(!extension_loaded("curl")){ $this->on_error("Your PHP must be loaded with cURL extension."); } $url_arr = $this->my_parse_url($url); $this->install_log ("Trying to access page: $url (timeout: $timeout)"); $ch = curl_init(); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); $proxy = @getenv("HTTP_PROXY").@getenv("http_proxy").@getenv("FTP_PROXY").@getenv("ftp_proxy"); if(isset($proxy)) { curl_setopt($ch, CURLOPT_PROXY, ""); } $buf = curl_exec($ch); $curl_errno = curl_errno($ch); if((!@is_numeric($buf) && !$buf) || $curl_errno != CURLE_OK) { switch($curl_errno) { case CURLE_COULDNT_CONNECT: $curl_error = "Connection failure"; break; case CURLE_OPERATION_TIMEOUTED: $curl_error = "Connection timeout"; break; case CURLE_COULDNT_RESOLVE_HOST: $curl_error = "Cannot resolve host"; break; default: $curl_error = curl_error($ch); } $curl_error = "Couldn't access page: $url\nError was: $curl_error"; $this->install_log ("ERROR: $curl_error"); if(!$silent) { $this->msgbox($curl_error); } $buf = null; } curl_close($ch); return $buf; } // EXEC_STR_THROUGH_WEBSERVER function exec_str_through_webserver($str, $ext = "php", $docroot=null, $url=null) { if (!$docroot) { $docroot = $this->webserver_docroot_guess(); } if (!$url) { $url = $this->webserver_get_virtual_host_url("127.0.0.1", true); } $test_file = "zend_install_".rand().".".$ext; $test_file_full = $this->make_path($docroot, $test_file); $this->str2file($str, $test_file_full); $this->install_log("Executing: {$str} via URL: {$url}, document root: {$docroot}"); $cont = $this->curl_get ("{$url}/$test_file"); $this->my_unlink($test_file_full); $this->install_log("Webserver returned: {$cont}"); return $cont; } // CHECK_URL_CORRESPONDS_TO_DOCROOT function check_url_corresponds_to_docroot ($url, $docroot) { $test_file = "zend_install_".rand().".html"; $test_file_full = $this->make_path($docroot, $test_file); $this->str2file("CORRESPONDS", $test_file_full); $cont = $this->curl_get ("{$url}/{$test_file}"); $this->my_unlink($test_file_full); return strstr ($cont, "CORRESPONDS"); } // CHECK_PHP_IS_LOADED function check_php_is_loaded($docroot=null, $url=null) { $test_str = ""; return strstr($this->exec_str_through_webserver($test_str, "php", $docroot, $url), "PHP_IS_LOADED"); } // CHECK_WEBSERVER_IS_LOADED function check_webserver_is_loaded($docroot=null, $url=null) { $test_str = "WEBSERVER_IS_LOADED"; return strstr($this->exec_str_through_webserver($test_str, "html", $docroot, $url), "WEBSERVER_IS_LOADED"); } // CHECK_LOADED_EXTENSIONS function check_loaded_extensions($docroot=null, $url=null) { $test_str = ""; $cont = $this->exec_str_through_webserver($test_str, "php", $docroot, $url); return split("\n", strtolower($cont)); } // POSTINSTALL_TEST function postinstall_test($test_extensions, $add_info=array(), $docroot=null, $url=null) { $this->progress_bar_start(100, "Running post installation tests\n(this may take a few seconds)...", "Testing ..."); $res = true; if(!$this->check_webserver_is_loaded($docroot, $url)) { $this->progress_bar_stop(); $this->msgbox( "Setup was unable to communicate with the Web server. It is possible that\n". "the Web server failed to start. Try to start the Web server manually." ); $res = false; } else { if(!$this->check_php_is_loaded($docroot, $url)) { $this->progress_bar_stop(); $this->msgbox("Setup was unable to detect working PHP on your Web server."); $res = false; } else { if(@count($test_extensions) + @count($add_info) > 0) { $extensions = $this->check_loaded_extensions($docroot, $url); $post_summary = $this->conf['product']." Post Installation Summary:\n\n"; foreach ($test_extensions as $ext => $ext_name) { $success = in_array(strtolower($ext), $extensions); $post_summary .= "{$ext_name} (".($success ? "Success" : "Failure").")\n"; $res = $res && $success; } foreach ($add_info as $ext_name => $success) { $post_summary .= "$ext_name (".($success ? "Success" : "Failure").")\n"; $res = $res && $success; } } $this->progress_bar_stop(); } } if(isset($post_summary)) { $this->msgbox($post_summary); } return $res; } function substitute_vars_in_script($script, $vars) { $this->install_log ("Updating $script ..."); $text = $this->file2str($script); foreach ($vars as $name=>$var) { $text = str_replace ("%%$name%%", $var, $text); } $this->str2file ($text, $script); } function get_php_cmd ($php_path=null, $php_ini_path=null, $php_script=null, $php_args=array()) { $php_cmd = ($php_path ? $php_path : $this->make_path($this->conf['prefix'], 'sbin', 'php')); // Unset dangerous PHP.ini entries (if using unknown PHP.ini): if ($php_ini_path === null) { $php_cmd .= " -d safe_mode=Off -d open_basedir='' -d auto_prepend_file='' -d auto_append_file=''"; } $php_cmd .= ' -c '.($php_ini_path ? $php_ini_path : $this->conf['php_ini_path']); if($php_script) { $php_cmd .= ' '.$php_script; foreach ($php_args as $arg) { $php_cmd .= " '".addcslashes($arg, "'")."'"; } } return $php_cmd; } // parms: $filename - filename of shell script to be created // $script - filename of php script to be wrapped // $php_path - filename of php executable // $php_ini_path - filename of php.ini // $args_arr (optional) - array of additional arguments // returns: nothing function create_php_script_wrapper($filename, $script, $php_path, $php_ini_path, $args_arr=array()) { $this->install_log ("Installing shell wrapper for $script ..."); $php_cmd = $this->get_php_cmd ($php_path, $php_ini_path, $script, $args_arr); $this->str2file ("#!/bin/sh\n$php_cmd \"\$@\"\n", $filename); $this->set_permissions ($filename, "0755"); } function openssl_test() { $openssl = $this->search_cmd_in_path("openssl"); if(!@file_exists($openssl)) { $this->on_error ("Cannot find utility: openssl"); } if(preg_match("/PRNG is not seeded/", $this->cmd2str("$openssl rand 32 -out /dev/null"))) { $this->on_error ("The installation has detected, that \"randomness device\"\n". "is not working properly on your system. For more information, refer to:\n". "http://www.openssl.org/support/faq.html#USER1"); } } function get_binary_strings($binary) { if (!file_exists ($binary)) { return false; } $strings = $this->search_cmd_in_path ("strings"); if($strings) { $all_strings = $this->cmd2str ("$strings $binary"); } else { $all_strings = @file_get_contents ($binary); } return $all_strings; } function grep_binary_file($pattern, $binary, &$match) { return preg_match ($pattern, $this->get_binary_strings($binary), $match); } function zend_module_get_version($filename) { $zem_path = $this->php_ini_get_entry ("zend_extension", $filename); if($this->my_file_exists ($zem_path)) { if($this->grep_binary_file ("/VERSION=(\w+)/", $zem_path, $match)) { return $match[1]; } } return false; } function ask_keep_existing_component ($comp, $comp_ver, $package_ver) { return $this->yesnobox ("$comp already installed, and it's version ($comp_ver) is greater,\n" ."than the one in the package ($package_ver).\n" ."Do you wish to keep the existing component (recommended) ?"); } function set_known_versions ($known_versions) { $this->conf['known_versions'] = $known_versions; } function my_version_compare ($ver1, $ver2) { $ver1 = preg_replace ("/\s/", "", $ver1); $ver2 = preg_replace ("/\s/", "", $ver2); if (@isset($this->conf['known_versions'])) { foreach ($this->conf['known_versions'] as $main_ver => $arr) { if (preg_match ("/".preg_quote($main_ver, '/')."/", $ver1)) { foreach ($arr as $ver) { if (preg_match ("/".preg_quote($ver, '/')."/", $ver2)) { $ver1_is_greater = 1; break; } } } if (preg_match ("/".preg_quote($main_ver, '/')."/", $ver2)) { foreach ($arr as $ver) { if (preg_match ("/".preg_quote($ver, '/')."/", $ver1)) { $ver1_is_greater = -1; break; } } } } } if (!isset($ver1_is_greater)) { $ver1_is_greater = version_compare($ver1, $ver2); } return $ver1_is_greater; } function check_installed_components ($comps) { $keep_existing = array(); foreach ($comps as $comp) { unset ($comp_ver); if(isset($comp["zemname"])) { $comp_ver = $this->php_ini_get_product_version ($comp["zemname"]); } else { $comp_ver = $this->zend_module_get_version ($comp["filename"]); } if($comp_ver !== false) { $package_ver = $this->get_component_version($comp["compname"]); if ($this->my_version_compare ($comp_ver, $package_ver) > 0) { if($this->ask_keep_existing_component ($comp["nicename"], $comp_ver, $package_ver)) { $keep_existing[$comp["compname"]] = $comp_ver; } } } } return $keep_existing; } function file_encoded($php_file) { $fp = @fopen($php_file, "r"); if(!$fp) { $this->on_error ("Can't open file for reading: $php_file!"); } $str = fgets ($fp); fclose ($fp); return strstr($str, "Zend"); } function is_evaluation_license($license) { $license_cont = $this->file2str ($license); if (preg_match ('@Expires\s*=\s*Never@', $license_cont)) { return false; } return true; } function my_parse_url($url) { if (preg_match('@^[^:]+://.*$@', $url)) { return @parse_url($url); } $url = 'http://'.$url; $url_arr = @parse_url($url); unset ($url_arr['scheme']); return $url_arr; } // ------------------ // MYSQL FUNCTIONS // ================== // MYSQL_INSTALL_CONFIGURE function mysql_install_configure ($basedir, $user="mysql") { if(!$this->add_user ($user, $basedir)) { return false; } # Enter to the MySQL basedir (installation prefix) $this->pushd ($basedir); $datadir = "{$basedir}/var"; if (!$this->my_dir_exists ($datadir)) { $this->my_mkdir ($datadir); $this->set_permissions ($datadir, "0755", $user); } $mysqld_install_cmd = "{$basedir}/bin/mysqld --defaults-file={$basedir}/etc/my.cnf --language={$basedir}/share/mysql/english --bootstrap --skip-grant-tables --basedir={$basedir} --datadir={$datadir} --skip-innodb --skip-bdb --skip-ndbcluster --max_allowed_packet=8M --net_buffer_length=16K --user={$user}"; if($this->run_command ("$mysqld_install_cmd < {$basedir}/share/mysql/init_db.sql") != 0) { $this->on_error ("Cannot initialize MySQL database!"); } $this->popd(); $this->link_startup_daemon ("{$basedir}/bin/mysql.sh", "MySQL", "MySQL Server"); } // MYSQL_UPDATE_STARTUP_SCRIPT function mysql_update_startup_script ($basedir, $user="mysql") { $datadir = "{$basedir}/var"; # Update MySQL startup script: $mysqlrc_cont = $this->file2str ("{$basedir}/bin/mysql.sh"); $mysqlrc_cont = preg_replace ('/^s*BASEDIR\s*=.*$/m', "BASEDIR={$basedir}", $mysqlrc_cont); $mysqlrc_cont = preg_replace ('/^s*USER\s*=.*$/m', "USER={$user}", $mysqlrc_cont); $mysqlrc_cont = preg_replace ('/^s*TEMP\s*=.*$/m', "TEMP={$datadir}", $mysqlrc_cont); $this->str2file ($mysqlrc_cont, "{$basedir}/bin/mysql.sh"); } // MYSQL_START function mysql_start ($basedir) { if ($this->run_command ("{$basedir}/bin/mysql.sh start 1>/dev/null") !== 0) { $this->warn ("Failed to start the MySQL server!"); } sleep (3); } // MYSQL_STOP function mysql_stop ($basedir) { $this->run_command ("{$basedir}/bin/mysql.sh stop 1>/dev/null"); sleep (3); } // MYSQL_DELETE_OLD_LOGFILES function mysql_delete_old_logfiles ($basedir) { $this->run_command ("rm -f {$basedir}/var/ib_logfile*"); } // MYSQL_DELETE_DATABASE function mysql_delete_database ($basedir, $database, $check_exit_status=false) { if ($this->run_command ("echo 'DROP DATABASE {$database};' | {$basedir}/bin/mysql --defaults-file={$basedir}/etc/my.cnf --socket={$basedir}/var/mysql.sock") != 0) { if ($check_exit_status) { $this->on_error ("Cannot delete MySQL database: {$database}!"); } } } // MYSQL_CREATE_DATABASE function mysql_create_database ($basedir, $database) { if ($this->run_command ("echo 'CREATE DATABASE {$database};' | {$basedir}/bin/mysql --defaults-file={$basedir}/etc/my.cnf --socket={$basedir}/var/mysql.sock") != 0) { $this->on_error ("Cannot initialize MySQL database!"); } } // MYSQL_RUN_SQL_SCRIPT function mysql_run_sql_script ($basedir, $sql_script, $database="mysql") { if ($this->run_command ("{$basedir}/bin/mysql --defaults-file={$basedir}/etc/my.cnf --socket={$basedir}/var/mysql.sock {$database} < {$sql_script}") != 0) { $this->on_error ("Cannot initialize MySQL database!"); } } // MYSQL_RUN_SQL_QUERY function mysql_run_sql_query ($basedir, $sql_query, $database="mysql") { $sql_query .= ";"; $sql_query = escapeshellarg ($sql_query); if ($this->run_command ("echo {$sql_query} | {$basedir}/bin/mysql --defaults-file={$basedir}/etc/my.cnf --socket={$basedir}/var/mysql.sock {$database}") != 0) { $this->on_error ("Cannot run MySQL query: {$sql_query}!"); } } /** FIND_JAVA * @param string component, that requires Java * @param string the least version of Java * @param boolean does component require Sun JRE? (default: false) * @param boolean whether we can skip this question (default: true) */ function find_java ($component, $least_version=null, $sun_java=false, $accept_empty=true) { $java_path = $this->search_cmd_in_path("java"); do { $msg = "Please ".($java_path ? "submit" : "enter")." the full path to the Java binary, ". "that will be used\nfor running the {$component}. You can leave the field empty, or\n". "click CANCEL in order to disable the {$component}."; if ($sun_java || $least_version !== null) { $requires = "requires"; if ($sun_java) { $requires .= " Sun's"; } $requires .= " JRE"; if ($least_version !== null) { $requires .= " {$least_version} or later"; } $msg .= "\n\nPlease note that the {$component} {$requires}!\n"; } $java_path = $this->select_file_nostrip ($msg, $java_path, $accept_empty); if ($java_path === null) { if ($this->yesnobox ("Do you wish to disable {$component}?")) { return null; } continue; } if ($this->is_broken_link ($java_path) || !@is_executable($java_path)) { $this->msgbox ("Java binary: {$java_path} is not executable or broken link!\n\nPlease try again!"); $java_path = null; continue; } $verstr = $this->cmd2str ("{$java_path} -version 2>&1"); // Check whether this Java meets our needs: $compatible = true; if (!preg_match ('/java\s+version/', $verstr)) { // Empty result: $compatible = false; } else { if ($sun_java && preg_match("/gij/", $verstr)) { $compatible = false; } if ($least_version != null && preg_match ("/java\s+version\s+\"([^\"]+)\"/", $verstr, $match)) { if (version_compare ($least_version, $match[1]) > 0) { $compatible = false; } } } if ($compatible || $this->yesnobox ( "WARNING: An incompatible version of the Java Runtime Environment (JRE) has been detected.\n". "The {$component} {$requires}! Do you still wish to use this JRE?", true)) { return $java_path; } $java_path = ""; } while (true); } //=-=-=-=-=-=-=-=-=-= // SELinux functions //=-=-=-=-=-=-=-=-=-= function selinux_enabled() { $selinuxenabled = $this->search_cmd_in_path ("selinuxenabled", true); if ($selinuxenabled) { return ($this->run_command ($selinuxenabled) == 0); } } function selinux_disable_httpd_protection() { $setsebool = $this->search_cmd_in_path ("setsebool", true); if ($setsebool) { /* You need to restart the Web server after running this command: */ return ($this->run_command ("$setsebool -P httpd_disable_trans 1") == 0); } return false; } function selinux_enabled_for_apache() { if (!$this->selinux_enabled()) { return false; } $getsebool = $this->search_cmd_in_path ("getsebool", true); if ($getsebool) { return (preg_match ('/(0|inactive)/', $this->cmd2str("$getsebool httpd_disable_trans 2>/dev/null"))); } $getfilecon = $this->search_cmd_in_path ("getfilecon", true); if ($getfilecon) { $httpd_exec = $this->apache_exec_guess(); $out = $this->cmd2str ("$getfilecon $httpd_exec 2>/dev/null"); if (preg_match('/^\s*[^ \t]*\s+.*http.*/sx', $out)) { true; } } return false; } function detect_processors_num() { if (@file_exists ('/proc/cpuinfo')) { if (preg_match_all ('/^processor\s*:\s*\d/mi', $this->file2str("/proc/cpuinfo"), $match)) { return count($match[0]); } } $psrinfo = $this->search_cmd_in_path ("psrinfo", true); if ($psrinfo) { if (preg_match_all ('/^\d+\s$/m', $this->cmd2str ($psrinfo), $match)) { return count($match[0]); } } $sysctl = $this->search_cmd_in_path ("sysctl", true); if ($sysctl) { if (preg_match ('/^(\d+)$/', trim($this->cmd2str ("{$sysctl} -n hw.ncpu")), $match)) { if ($match[1] > 0) { return $match[1]; } } } return 1; // We surely have at least one processor } /* Convert IP range to list of IP's and write it to file */ function expand_ip_range ($ip_range, $file) { list ($ip, $mask) = explode("/", $ip_range); if (!$this->is_ip_valid ($ip) || !is_numeric($mask) || $mask > 31 || $mask < 0) { return false; } $ip_start = ip2long($ip); $ip_end = $ip_start + pow (2, 32 - $mask) - 1; $fp = fopen ($file, "w"); if (!is_resource ($fp)) { $this->on_error ("Can't write to file: {$file}!"); } while ($ip_start < $ip_end) { fwrite ($fp, long2ip ($ip_start++)); fwrite ($fp, "\n"); } fclose ($fp); return true; } // PARSE_HOST function parse_host ($host) { $arr = split ("\.",$host); for ($i=count($arr); $i<4; $i++) { $arr[$i] = "*"; } if (count($arr) != 4) return false; $mask=32; for ($i=3; $i>=0; $i--) { if ($arr[$i]!="*") { break; } $mask-=8; $arr[$i]=0; } for (/*$i is already initialized*/; $i>=0; $i--) { $tmp=(integer)($arr[$i]); if ($arr[$i]!="$tmp" or $tmp>255 or $tmp<0) { // parse error; return false; } $arr[$i]=$tmp; } return join(".",$arr)."/".$mask; } // BINARY_GET_PRECISION function binary_get_precision ($path) { $file_cmd = $this->search_cmd_in_path ("file"); if ($file_cmd) { $precision = $this->cmd2str("{$file_cmd} {$path} 2>/dev/null"); if(preg_match("/(\d+)\-bit/i", $precision, $match)) { return $match[1]; } } return false; } // install (new) license utility // return: path to install utility function generate_trial_utility ($destination=null) { if (! isset ($this->conf['generated_trial'])) // do that only once { // $destination = $this->conf['prefix'] . '/sbin/trial'; if (!$destination) { $destination = $this->conf['tmp_dir']."/trial"; } $failure = 0; // the 3rd parm SHOULD be false in final release (no logging), this is for debugging! if ($this->run_command ("../data/trial $destination", '', true) == 0) { if ($this->my_file_exists ($destination)) { $this->conf['generated_trial'] = $destination; } else { $failure = 1; } } else { $failure = 1; } if ($failure == 1) { $this->error_handler->on_error ('Unable to install trial license utility.'); } } return ($this->conf['generated_trial']); } // the following two are for backward compatability, deprecated function install_log ($msg) { $this->logger->log ($msg); } function on_error ($msg) { $this->error_handler->on_error ($msg); } } // end of class Install /* function error_handler($errno, $errstr, $errfile, $errline) { global $INSTALL; $INSTALL->error_handler($errno, $errstr, $errfile, $errline); } */ class InstallLogger { var $logfile_name; function InstallLogger ($logfile_name) // ctor { $this->logfile_name = $logfile_name; @unlink ($this->logfile_name); } function log ($msg) { $msg = preg_replace("/[\r\n]+/", " ", $msg); $msg = preg_replace("/\s+/", " ", $msg); error_log (sprintf("%s %s\n", date('[M d H:i:s]'), $msg), 3, $this->logfile_name); } /* function store ($path) { $this->my_copy ($this->logfile_name, $path); } */ } // end of class InstallLogger class InstallErrorHandler { var $install; function InstallErrorHandler (&$install) // ctor { $this->install = &$install; // by this we create a bloody circular reference // but hopefuly nobody would notice } function on_error($msg = "") /* die with error message */ { static $in_error; $this->install->logger->log ("ERROR: $msg"); $msg = "\n{$msg}\n"; if ( $this->install->conf['interactive'] && @file_exists ($this->install->conf['prefix'] . '/bin/support_tool.sh') && @file_exists ($this->install->conf['prefix'] . '/lib/tools/conf.db') && (! isset ($in_error)) ) { $in_error = true; if ($this->install->yesnobox ( <<install->conf['product']} installation was NOT completed successfully. {$msg} Do you wish to run the Support Tool for gathering your system configuration information, that will help to investigate this problem? EOF )) { $this->install->run_command ($this->install->conf['prefix'] . '/bin/support_tool.sh' . (empty ($this->install->conf['dialog']) ? ' --text-mode' : '')); } } else { $this->install->msgbox ( <<install->conf['product']} installation was NOT completed successfully. {$msg} For further assistance, please contact Zend Support at https://www.zend.com/support/ EOF ); } $this->install->cleanup(); die(-1); } // end of on_error() } // end of class InstallErrorHandler ?>