From e6f33695764d562a0c46eb6d421b9644f916a5c9 Mon Sep 17 00:00:00 2001 From: drowe67 Date: Wed, 12 Mar 2008 04:20:20 +0000 Subject: [PATCH] changes to implement retrieve_conf as an include file git-svn-id: https://svn.code.sf.net/p/freetel/code@13 01035d8c-6547-0410-b346-abe4f91aad63 --- freepbx-sandbox/Makefile | 17 +- freepbx-sandbox/files/do_reload.php | 121 ++++ freepbx-sandbox/files/retrieve_conf.inc.php | 766 ++++++++++++++++++++ freepbx-sandbox/patch/freepbx.patch | 33 +- 4 files changed, 926 insertions(+), 11 deletions(-) create mode 100644 freepbx-sandbox/files/do_reload.php create mode 100644 freepbx-sandbox/files/retrieve_conf.inc.php diff --git a/freepbx-sandbox/Makefile b/freepbx-sandbox/Makefile index fa5b41eb..1ef667de 100644 --- a/freepbx-sandbox/Makefile +++ b/freepbx-sandbox/Makefile @@ -24,7 +24,7 @@ PHP_SOURCE=php-$(PHP_VERSION).tar.bz2 PHP_CONFIGURE_OPTS=--disable-all --with-pcre-regex --enable-force-cgi-redirect \ --with-config-file-path=$(ROOT)/etc --prefix=$(ROOT) \ --with-pear --enable-xml --enable-libxml --enable-session \ - --with-gettext + --with-gettext --enable-debug $(DL_DIR)/$(PHP_SOURCE): mkdir -p dl @@ -233,6 +233,11 @@ $(DL_DIR)/$(FREEPBX_SOURCE): $(FREEPBX_DIR)/.unpacked: $(DL_DIR)/$(FREEPBX_SOURCE) zcat $(DL_DIR)/$(FREEPBX_SOURCE) | tar -C $(BUILD_DIR) -xf - patch -d $(FREEPBX_DIR) -p1 < patch/freepbx.patch + + # additional files to implement retrieve_conf as include + + cp files/retrieve_conf.inc.php files/do_reload.php $(FREEPBX_DIR)/amp_conf/admin + touch $(FREEPBX_DIR)/.unpacked $(FREEPBX_DIR)/.installed: $(FREEPBX_DIR)/.unpacked @@ -411,11 +416,21 @@ freepbx-make-patch: $(A)/amp_conf/bin/retrieve_conf \ >> patch/freepbx.patch + # set up default AMP user and password + -diff -uN \ $(AO)/amp_conf/astetc/manager.conf \ $(A)/amp_conf/astetc/manager.conf \ >> patch/freepbx.patch + # make retrieve_conf an include from config.php rather + # than exec to save about 15M + + -diff -uN \ + $(AO)/amp_conf/htdocs/admin/config.php \ + $(AROOT)/admin/config.php \ + >> patch/freepbx.patch + # NOTE: common.patch was generated manually from command line # undo sandbox path (messy! Must be a better way....) diff --git a/freepbx-sandbox/files/do_reload.php b/freepbx-sandbox/files/do_reload.php new file mode 100644 index 00000000..5e2d677c --- /dev/null +++ b/freepbx-sandbox/files/do_reload.php @@ -0,0 +1,121 @@ +0,'test'=>'abc'); + $exit_val = null; + + if (isset($amp_conf["PRE_RELOAD"]) && !empty($amp_conf['PRE_RELOAD'])) { + exec( $amp_conf["PRE_RELOAD"], $output, $exit_val ); + + if ($exit_val != 0) { + $desc = sprintf(_("Exit code was %s and output was: %s"), $exit_val, "\n\n".implode("\n",$output)); + $notify->add_error('freepbx','reload_pre_script', sprintf(_('Could not run %s script.'), $amp_conf['PRE_RELOAD']), $desc); + + $return['num_errors']++; + } else { + $notify->delete('freepbx', 'reload_pre_script'); + } + } + + // use include file in current php-cgi, avoid repeating a lot + // of the code + + require_once('retrieve_conf.inc.php'); + $return['retrieve_conf'] = $rc_output; + + // retrive_conf html output + if ($exit_val != 0) { + $return['status'] = false; + $return['message'] = sprintf(_('Reload failed because retrieve_conf encountered an error: %s'),$exit_val); + $return['num_errors']++; + $notify->add_critical('freepbx','RCONFFAIL', _("retrieve_conf failed, config not applied"), $return['message']); + return $return; + } + + if (!isset($astman) || !$astman) { + $return['status'] = false; + $return['message'] = _('Reload failed because FreePBX could not connect to the asterisk manager interface.'); + $return['num_errors']++; + $notify->add_critical('freepbx','RCONFFAIL', _("retrieve_conf failed, config not applied"), $return['message']); + return $return; + } + $notify->delete('freepbx', 'RCONFFAIL'); + + //reload MOH to get around 'reload' not actually doing that. + $astman->send_request('Command', array('Command'=>'moh reload')); + + //reload asterisk + $astman->send_request('Command', array('Command'=>'reload')); + + $return['status'] = true; + $return['message'] = _('Successfully reloaded'); + + if ($amp_conf['FOPRUN']) { + //bounce op_server.pl + $wOpBounce = $amp_conf['AMPBIN'].'/bounce_op.sh'; + exec($wOpBounce.' &>'.$asterisk_conf['astlogdir'].'/freepbx-bounce_op.log', $output, $exit_val); + + if ($exit_val != 0) { + $desc = _('Could not reload the FOP operator panel server using the bounce_op.sh script. Configuration changes may not be reflected in the panel display.'); + $notify->add_error('freepbx','reload_fop', _('Could not reload FOP server'), $desc); + + $return['num_errors']++; + } else { + $notify->delete('freepbx','reload_fop'); + } + } + + //store asterisk reloaded status + $sql = "UPDATE admin SET value = 'false' WHERE variable = 'need_reload'"; + $result = $db->query($sql); + if(DB::IsError($result)) { + $return['message'] = _('Successful reload, but could not clear reload flag due to a database error: ').$db->getMessage(); + $return['num_errors']++; + } + + if (isset($amp_conf["POST_RELOAD"]) && !empty($amp_conf['POST_RELOAD'])) { + exec( $amp_conf["POST_RELOAD"], $output, $exit_val ); + + if ($exit_val != 0) { + $desc = sprintf(_("Exit code was %s and output was: %s"), $exit_val, "\n\n".implode("\n",$output)); + $notify->add_error('freepbx','reload_post_script', sprintf(_('Could not run %s script.'), 'POST_RELOAD'), $desc); + + $return['num_errors']++; + } else { + $notify->delete('freepbx', 'reload_post_script'); + } + } + $response = $return; + +?> diff --git a/freepbx-sandbox/files/retrieve_conf.inc.php b/freepbx-sandbox/files/retrieve_conf.inc.php new file mode 100644 index 00000000..d47bde2b --- /dev/null +++ b/freepbx-sandbox/files/retrieve_conf.inc.php @@ -0,0 +1,766 @@ +add_critical('retrieve_conf', $type, $text, $extended_text); + } + + exit(1); +} + +function debug($text) { + global $debug; + + if ($debug) echo "[DEBUG-preDB] ".$text."\n"; +} + +function showHelp() { + out(_("Optional parameters:")); + out(_(" --help, -h, -? Show this help")); + out(_(" --debug Enable debug output")); + out(_(" --dry-run Don't actually do anything")); +} + + +// bootstrap retrieve_conf by getting the AMPWEBROOT since that is currently where the necessary +// functions.inc.php resides, and then use that parser to properly parse the file and get all +// the defaults as needed. +// +function parse_amportal_conf_bootstrap($filename) { + $file = file($filename); + foreach ($file as $line) { + if (preg_match("/^\s*([\w]+)\s*=\s*\"?([\w\/\:\.\*\%-]*)\"?\s*([;#].*)?/",$line,$matches)) { + $conf[ $matches[1] ] = $matches[2]; + } + } + if ( !isset($conf["AMPWEBROOT"]) || ($conf["AMPWEBROOT"] == "")) { + $conf["AMPWEBROOT"] = "/var/www/html"; + } else { + $conf["AMPWEBROOT"] = rtrim($conf["AMPWEBROOT"],'/'); + } + + return $conf; +} + +/** Adds a trailing slash to a directory, if it doesn't already have one + */ +function addslash($dir) { + return (($dir[ strlen($dir)-1 ] == '/') ? $dir : $dir.'/'); +} + + +/********************************************************************************************************************/ +/* DR +// **** Make sure we have STDIN etc + +// from ben-php dot net at efros dot com at php.net/install.unix.commandline +if (version_compare(phpversion(),'4.3.0','<') || !defined("STDIN")) { + define('STDIN',fopen("php://stdin","r")); + define('STDOUT',fopen("php://stdout","r")); + define('STDERR',fopen("php://stderr","r")); + register_shutdown_function( create_function( '' , 'fclose(STDIN); fclose(STDOUT); fclose(STDERR); return true;' ) ); +} + +// **** Make sure we have PEAR's DB.php, and include it + +outn(_("Checking for PEAR DB..")); +if (! @ include('DB.php')) { + out(_("FAILED")); + fatal(_("PEAR Missing"),sprintf(_("PEAR must be installed (requires DB.php). Include path: %s "), ini_get("include_path"))); +} +out(_("OK")); + + +// **** Make sure we have PEAR's GetOpts.php, and include it + +outn(_("Checking for PEAR Console::Getopt..")); +if (! @ include("Console/Getopt.php")) { + out(_("FAILED")); + fatal(_("PEAR Getopt.php Missing"),sprintf(_("PEAR must be installed (requires Console/Getopt.php). Include path: %s"), ini_get("include_path"))); +} +out(_("OK")); + + +// **** Parse out command-line options + +$shortopts = "h?u:p:"; +$longopts = array("help","debug","dry-run","run-install","amportalconf="); + +$args = Console_Getopt::getopt(Console_Getopt::readPHPArgv(), $shortopts, $longopts); +if (is_object($args)) { + // assume it's PEAR_ERROR + out($args->message); + exit(255); +} +*/ +$debug = false; +$dryrun = false; +$run_install = false; + +/* +foreach ($args[0] as $arg) { + switch ($arg[0]) { + case "--help": case "h": case "?": + showHelp(); + exit(10); + break; + case "--dry-run": + out(_("Dry-run only, no files will be written")); + $dryrun = true; + break; + case "--debug": + $debug = true; + debug(_("Debug mode enabled")); + break; + case "--run-install": + $run_install = true; + out(_("Running module install.php and install.sql scripts")); + break; + case "--amportalconf": + $amportalconf = $arg[1]; + out(sprintf(_("Using %s configuration file"), $amportalconf)); + break; + } +} + +// **** Check for amportal.conf + +outn(sprintf(_("Checking for %s "), $amportalconf)._("..")); +if (!file_exists($amportalconf)) { + fatal(_("amportal.conf access problem: "),sprintf(_("The %s file does not exist, or is inaccessible"), $amportalconf)); +} +out(_("OK")); + +// **** read amportal.conf + +outn(sprintf(_("Bootstrapping %s .."), $amportalconf)); +$amp_conf = parse_amportal_conf_bootstrap($amportalconf); +if (count($amp_conf) == 0) { + fatal(_("amportal.conf parsing failure"),sprintf(_("no entries found in %s"), $amportalconf)); +} +out(_("OK")); + +outn(sprintf(_("Parsing %s .."), $amportalconf)); +require_once($amp_conf['AMPWEBROOT']."/admin/functions.inc.php"); +$amp_conf = parse_amportal_conf($amportalconf); +if (count($amp_conf) == 0) { + fatal(_("amportal.conf parsing failure"),sprintf(_("no entries found in %s"), $amportalconf)); +} +out(_("OK")); + +$asterisk_conf_file = $amp_conf["ASTETCDIR"]."/asterisk.conf"; +outn(sprintf(_("Parsing %s .."), $asterisk_conf_file)); +$asterisk_conf = parse_asterisk_conf($asterisk_conf_file); +if (count($asterisk_conf) == 0) { + fatal(_("asterisk.conf parsing failure"),sprintf(_("no entries found in %s"), $asterisk_conf_file)); +} +out(_("OK")); + +// **** Connect to database + +outn(_("Connecting to database..")); + +# the engine to be used for the SQL queries, +# if none supplied, backfall to mysql +$db_engine = "mysql"; +if (isset($amp_conf["AMPDBENGINE"])){ + $db_engine = $amp_conf["AMPDBENGINE"]; +} +*/ + +// Define the notification class for logging to the dashboard +// +$nt = notifications::create($db); + +// **** Create symlinks array +$symlink_dirs = array(); +$symlink_dirs['sounds'] = $amp_conf['ASTVARLIBDIR'].'/sounds'; +$symlink_dirs['bin'] = $amp_conf['AMPBIN']; +$symlink_dirs['etc'] = $amp_conf['ASTETCDIR']; +$symlink_dirs['images'] = $amp_conf['AMPWEBROOT']."/admin/images"; + +/* +switch ($db_engine) +{ + case "pgsql": + case "mysql": + // datasource in in this style: + // dbengine://username:password@host/database + + $db_user = $amp_conf["AMPDBUSER"]; + $db_pass = $amp_conf["AMPDBPASS"]; + $db_host = $amp_conf["AMPDBHOST"]; + $db_name = $amp_conf["AMPDBNAME"]; + + $datasource = $db_engine.'://'.$db_user.':'.$db_pass.'@'.$db_host.'/'.$db_name; + $db = DB::connect($datasource); // attempt connection + break; + + case "sqlite": + die_freepbx("SQLite2 support is deprecated. Please use sqlite3 only."); + break; + + case "sqlite3": + if (!isset($amp_conf["AMPDBFILE"])) + fatal("You must setup properly AMPDBFILE in $amportalconf"); + + if (isset($amp_conf["AMPDBFILE"]) == "") + fatal("AMPDBFILE in $amportalconf cannot be blank"); + + // on centos this extension is not loaded by default + if (! extension_loaded('sqlite3.so') ) + dl('sqlite3.so'); + + if (! @require_once('DB/sqlite3.php') ) + { + die_freepbx("Your PHP installation has no PEAR/SQLite3 support. Please install php-sqlite3 and php-pear."); + } + + require_once('DB/sqlite3.php'); + $datasource = "sqlite3:///" . $amp_conf["AMPDBFILE"] . "?mode=0666"; + $db = DB::connect($datasource); + break; + + default: + fatal( "Unknown SQL engine: [$db_engine]"); +} + +if(DB::isError($db)) { + out(_("FAILED")); + debug($db->userinfo); + fatal(_("database connection failure"),("failed trying to connect to the configured database")); + +} + +//TODO : make this engine-neutral +outn(_("Connecting to Asterisk manager interface..")); +// connect to asterisk manager +require_once($amp_conf['AMPWEBROOT'].'/admin/common/php-asmanager.php'); +$astman = new AGI_AsteriskManager(); +if (! $res = $astman->connect("127.0.0.1:".$amp_conf["ASTMANAGERPORT"], $amp_conf["AMPMGRUSER"] , $amp_conf["AMPMGRPASS"])) { + out(_("FAILED")); + fatal(_("Asterisk Manager Connection Failure"),sprintf(_("Failed to connect to the Asterisk manager through port: %s"), $amp_conf['ASTMANAGERPORT'])); +} +*/ + +//include common functions +require_once($amp_conf['AMPWEBROOT']."/admin/extensions.class.php"); +freepbx_log("retrieve_conf", "devel-debug", "Started retrieve_conf, DB Connection OK"); + +// query for our modules +// var_dump( $db ); +$modules = module_getinfo(); + +//Putting the core module last, to move outbound-allroutes +// last in from-internals-additional +if (array_key_exists('core', $modules)) { + $core_tmp = $modules['core']; + unset($modules['core']); + $modules['core'] = $core_tmp; +} + +// include any module global functions +if(is_array($modules)){ + foreach($modules as $key => $module) { + $return['retrieve_conf'] = $return['retrieve_conf'] . $key . "\n"; + //only use this module if it's enabled (status=2) + if (isset($module['status']) && $module['status'] == MODULE_STATUS_ENABLED) { + // Make sure the module is installed and up to date + if ($run_install) module_install($key); + // active_modules array used in genConf function + $active_modules[] = $key; + //include module functions + if (is_file($amp_conf['AMPWEBROOT']."/admin/modules/{$key}/functions.inc.php")) { + freepbx_log('retrieve_conf', 'devel-debug', 'Including '.$amp_conf['AMPWEBROOT']."/admin/modules/{$key}/functions.inc.php"); + include_once($amp_conf['AMPWEBROOT']."/admin/modules/{$key}/functions.inc.php"); + freepbx_log('retrieve_conf', 'devel-debug', $amp_conf['AMPWEBROOT']."/admin/modules/{$key}/functions.inc.php processed OK"); + } + + // create symlinks for files in appropriate sub directories + symlink_subdirs( $amp_conf['AMPWEBROOT'].'/admin/modules/'.$key ); + cp_subdirs( $amp_conf['AMPWEBROOT'].'/admin/modules/'.$key ); + } + } +} +$return['retrieve_conf'] = $return['retrieve_conf'] . $amp_conf['AMPWEBROOT']; + +// create an object of the extensions class +require_once($amp_conf['AMPWEBROOT']."/admin/extensions.class.php"); +$ext = new extensions; + +// create objects for any module classes +// currently only 1 class can be declared per module, not sure if that will be an issue +if(isset($active_modules) && is_array($active_modules)){ + foreach($active_modules as $active_module) { + freepbx_log('retrieve_conf', 'devel-debug', "Creating ".$active_module."_conf class"); + $classname = $active_module."_conf"; + if(class_exists($classname)) { + ${$classname} = new $classname; + } + } +} + +$engineinfo = engine_getinfo(); +if($engineinfo['version'] == 0){ + freepbx_log('retrieve_conf', 'fatal', "Failed to get engine information (engine_getinfo: {$engineinfo['engine']})"); + fatal(_("Failed to get engine_info"),_("retreive_conf failed to get engine information and cannot configure up a softwitch with out it. Error: {$engineinfo['engine']}")); +} +// was setting these variables before, assume we still need them +$engine = $engineinfo['engine']; +$version = $engineinfo['version']; + +// Check for and report any extension conflicts +// + +$extens_ok = true; +$dests_ok = true; + +$nt = notifications::create($db); + +$my_hash = array_flip($active_modules); +$my_prob_extens = framework_list_extension_conflicts($my_hash); + +if (empty($my_prob_extens)) { + $nt->delete('retrieve_conf', 'XTNCONFLICT'); +} else { + $previous = null; + $str = null; + $count = 0; + foreach ($my_prob_extens as $extens) { + foreach ($extens as $exten => $details) { + if ($exten != $previous) { + $str .= "Extension: $exten:
"; + $count++; + } + $str .= sprintf("%8s: %s
",$details['status'], $details['description']); + $previous = $exten; + } + } + $nt->add_error('retrieve_conf', 'XTNCONFLICT', sprintf(_("There are %s conflicting extensions"),$count), $str); + $extens_ok = false; +} + +// Check for and report any bogus destinations +// +$my_probs = framework_list_problem_destinations($my_hash, !$amp_conf['CUSTOMASERROR']); + +if (empty($my_probs)) { + $nt->delete('retrieve_conf', 'BADDEST'); +} else { + $results = array(); + $count = 0; + $str = null; + foreach ($my_probs as $problem) { + //print_r($problem); + $results[$problem['status']][] = $problem['description']; + $count++; + } + foreach ($results as $status => $subjects) { + $str .= sprintf(_("DEST STATUS: %s%s"),$status,"\n"); + foreach ($subjects as $subject) { + //$str .= $subject."
"; + $str .= " ".$subject."\n"; + } + } + $nt->add_error('retrieve_conf', 'BADDEST', sprintf(_("There are %s bad destinations"),$count), $str); + $dests_ok = false; +} + +if ((!$exten_ok && $amp_conf['XTNCONFLICTABORT']) || (!$dest_ok && $amp_conf['BADDESTABORT'])) { + out(_("Aborting reload because extension conflicts or bad destinations")); + exit(20); +} +//$return['retrieve_conf'] = $return['retrieve_conf'] . "\n"; + +// run all of the *_get_config and _hookGet_config functions, which will populate the appropriate objects +if(isset($active_modules) && is_array($active_modules)){ + foreach($active_modules as $module) { + $funcname = $module."_get_config"; + if (function_exists($funcname)) { + freepbx_log('retrieve_conf', 'devel-debug', 'Calling '.$funcname.'()'); + $return['retrieve_conf'] = $return['retrieve_conf'] . $funcname . "\n"; + $funcname($engine); + } + } + foreach($active_modules as $module) { + $funcname = $module."_hookGet_config"; + if (function_exists($funcname)) { + freepbx_log('retrieve_conf', 'devel-debug', 'Calling '.$funcname.'()'); + $return['retrieve_conf'] = $return['retrieve_conf'] . $funcname . "\n"; + $funcname($engine); + } + } +} + +// extensions_additional.conf +// create the from-internal-additional context so other can add to it +$ext->add('from-internal-additional', 'h', '', new ext_hangup('')); +//echo $ext->get_filename(); +//echo $ext->generateConf(); +write_file($ext->get_filename(),$ext->generateConf()); + +// now we write out our conf files for modules +// check for any objects for each of the active modules +// ** conferences is an example of a module that write a conf +if(isset($active_modules) && is_array($active_modules)){ + foreach($active_modules as $active_module) { + $classname = $active_module."_conf"; + if(class_exists($classname) && get_class(${$classname}) !== false) { + //echo ${$classname}->get_filename(); + //echo ${$classname}->generateConf(); + + // if the module returns an array, it wants to write multiple files + // ** pinsets is an example of a module that does this + if (is_array(${$classname}->get_filename())) { + foreach(${$classname}->get_filename() as $modconf) { + freepbx_log('retrieve_conf', 'devel-debug', 'generateConf from '.$classname.'->'.$modconf.''); + write_file($modconf,${$classname}->generateConf($modconf)); + } + } else { + freepbx_log('retrieve_conf', 'devel-debug', 'generateConf from '.$classname); + write_file(${$classname}->get_filename(),${$classname}->generateConf()); + } + } + } +} + + +function write_file($filename,$contents) { + global $asterisk_conf; + freepbx_log('retrieve_conf', 'devel-debug', 'Writing '.$filename); + if (isset($filename) && !empty($filename)) { + if ($fd = fopen(addslash($asterisk_conf['astetcdir']).$filename, "w")) { + fwrite($fd, WARNING_BANNER ); + fwrite($fd, $contents); + fclose($fd); + } + } +} + +/* file_exists_wrapper() + * wrapper for file_exists() with the following additonal functionality. + * if the file is a symlink, it will check if the link exists and if not + * it will try to remove this file. It returns a false (file does not exists) + * if the file is successfully removed, true if not. If not a symlink, just + * returns file_exists() + */ +function file_exists_wrapper($string) { + if (is_link($string)) { + $linkinfo = readlink($string); + if ($linkinfo === false) { + //TODO: throw error? + return !unlink($string); + } else { + if (file_exists($linkinfo)) { + return true; + } else { + return !unlink($string); + } + } + } else { + return file_exists($string); + } +} + +function symlink_subdirs($moduledir) { +global $amp_conf; +$symlink_dirs = array(); +$symlink_dirs['sounds'] = $amp_conf['ASTVARLIBDIR'].'/sounds'; +$symlink_dirs['bin'] = $amp_conf['AMPBIN']; +$symlink_dirs['etc'] = $amp_conf['ASTETCDIR']; +$symlink_dirs['images'] = $amp_conf['AMPWEBROOT']."/admin/images"; + +// global $symlink_dirs; + $symlink_errors = false; + + $nt = notifications::create($db); + + foreach ($symlink_dirs as $subdir => $targetdir) { + $dir = addslash($moduledir).$subdir; + if (is_dir($dir)) { + $d = opendir($dir); + while ($file = readdir($d)) { + if ($file[0] != '.') { + $src = addslash($dir).$file; + $dest = addslash($targetdir).$file; + if (file_exists_wrapper($dest)) { + if (!is_link($dest)) { + freepbx_log('retrieve-conf', 'error', $dest.' already exists, and is not a symlink!'); + $nt->add_error('retrieve_conf', 'SYMLINK', _("symlink from modules failed"), sprintf(_("retrieve_conf failed to sym link the %s file from modules"),$dest)); + $symlink_errors = true; + } else if (readlink($dest) != $src) { + // TODO : is this the proper handling? should we just overwrite..? + freepbx_log('retrieve-conf', 'error', $dest.' already exists, and is linked to something else!'); + $nt->add_error('retrieve_conf', 'SYMLINK', _("symlink from modules failed"), sprintf(_("retrieve_conf failed to sym link the %s file from modules"),$dest)); + $symlink_errors = true; + } else { + freepbx_log('retrieve-conf', 'devel-debug', $dest.' already points to '.$src.' - OK'); + } + } else { +// // symlink, unlike copy, doesn't overwrite - have to delete first +// if (is_link($dest) || file_exists($dest)) { +// unlink($dest); +// } + if (symlink($src, $dest)) { + freepbx_log('retrieve-conf', 'devel-debug', 'Symlinked '.$src.' to '.$dest); + } else { + freepbx_log('retreive-conf', 'devel-debug', 'Cannot symlink '.$src.' to '.$dest.'. Check Permissions?'); + } + } + } + } + closedir($d); + } + } + if (!$symlink_errors) { + $nt->delete('retrieve_conf', 'SYMLINK'); + } +} + +// wrap copy with error handler +// +function err_copy($source, $dest) { + $ret = false; + set_error_handler("report_errors"); + if (copy($source, $dest)) { + $ret = chmod($dest,'0754'); + } + restore_error_handler(); + return $ret; +} + +// wrap unlink with error handler +// +function err_unlink($dest) { + set_error_handler("report_errors"); + $ret = unlink($dest); + restore_error_handler(); + return $ret; +} + +function cp_subdirs($moduledir) { + global $cp_errors; +global $amp_conf; +$cp_dirs = array(); +$cp_dirs['agi-bin'] = $amp_conf['ASTAGIDIR']; +// global $cp_dirs; + + $cp_errors = ""; + foreach ($cp_dirs as $subdir => $targetdir) { + $dir = addslash($moduledir).$subdir; + if (is_dir($dir)) { + $d = opendir($dir); + while ($file = readdir($d)) { + if ($file[0] != '.') { + $sourcefile = addslash($dir).$file; + $targetfile = addslash($targetdir).$file; + + if (file_exists_wrapper($targetfile)) { + if (is_link($targetfile)) { + if (err_unlink($targetfile)) { + freepbx_log('retrieve-conf', 'devel-debug', "$targetfile was symbolic link, unlink successful"); + } else { + freepbx_log('retrieve-conf', 'error', "$targetfile is a symblolic link, failed to unlink!"); + break; + } + } + } + // OK, now either the file is a regular file or isn't there, so proceed + // + if (err_copy($sourcefile,$targetfile)) { + freepbx_log('retrieve-conf', 'devel-debug', "$targetfile successfully copied"); + // copy was successful, make sure it has execute permissions + chmod($targetfile,0754); + } else { + freepbx_log('retrieve-conf', 'error', "$targetfile failed to copy from module directory"); + } + } + } + closedir($d); + } + } + $nt = notifications::create($db); + if ($cp_errors) { + $nt->add_error('retrieve_conf', 'CPAGIBIN', _("Failed to copy from module agi-bin"), sprintf(_("Retrieve conf failed to copy file(s) from a module's agi-bin dir: %s"),$cp_errors)); + } else { + $nt->delete('retrieve_conf', 'CPAGIBIN'); + } +} + +function report_errors($errno, $errstr, $errfile, $errline) { + global $cp_errors; + freepbx_log('retrieve-conf', 'error', "php reported: '".mysql_real_escape_string($errstr)."' after copy or unlink attempt!"); + $cp_errors .= $errstr."\n"; +} + +/** Check if there is a job running, if one is found then all is good, if one is not found, it will be added and a + * notification will be sent. + */ +function install_cron_scheduler() { + global $amp_conf; + global $nt; + + // crontab appears to return an error when no entries, os only fail if error returned AND a list of entries. + // Don't know if this will ever happen, but a failure and a list could indicate something wrong. + // + exec("/usr/bin/crontab -l", $outlines, $ret); + if ($ret && count($outlines)) { + $nt->add_error('retrieve_conf', 'CRONMGR', _("Failed to check crontab for cron manager"), sprintf(_("crontab returned %s error code when checking for crontab entries to start freepbx-cron-scheduler.php crontab manager"),$ret)); + } else { + $nt->delete('retrieve_conf', 'CRONMGR'); + $outlines2 = preg_grep("/freepbx-cron-scheduler.php/",$outlines); + $cnt = count($outlines2); + switch ($cnt) { + case 0: + /** grab any other cronjobs that are running as asterisk and NOT associated with backups + * this code was taken from the backup module for the most part. But seems to work... + */ + $outlines = array(); + exec("/usr/bin/crontab -l | grep -v ^#\ DO\ NOT | grep -v ^#\ \( | grep -v freepbx-cron-scheduler.php", $outlines, $ret); + $crontab_entry = ""; + foreach ($outlines as $line) { + $crontab_entry .= $line."\n"; + } + // schedule to run hourly, at a random time. The random time is explicit to accomodate things like module_admin online update checking + // since we will want a random access to the server. In the case of module_admin, that will also be scheduled randomly within the hour + // that it is to run + // + $crontab_entry .= rand(0,59)." * * * * ".$amp_conf['AMPBIN']."/freepbx-cron-scheduler.php"; + system("/bin/echo '$crontab_entry' | /usr/bin/crontab -"); + break; + case 1: + // already running, nothing to do + break; + default: + // error, there should never be more than one running + echo "TODO: deal with error here\n"; + $nt->add_error('retrieve_conf', 'CRONMGR', _("Multiple freepbx-cron-scheduler.php running"), sprintf(_("There were %s freepbx-cron-scheduler.php instances running. There should be only 1."),$cnt)); + } + } +} +include($amp_conf['AMPBIN']."/libfreepbx.confgen.php"); +// script to write op_server.cfg file from mysql +// +if ($amp_conf["AMPDBENGINE"] != 'sqlite3') { + // sqlite3 not supported just yet + $script = $amp_conf['AMPBIN'].'/retrieve_op_conf_from_mysql.pl '.$amportalconf.' '.rtrim($asterisk_conf['astetcdir'],DIRECTORY_SEPARATOR); + exec($script); +} + +// generate configuration files +// +// Leave the legacy scripts in for a little while to help with odd-ball upgrade scenarios if they haven't gotten +// a module upgraded yet. In particular Queues +// +if (!isset($core_conf) || !is_a($core_conf, "core_conf")) { + generate_configurations_sip($version); + generate_configurations_iax($version); + generate_configurations_zap($version); +} + +// Check and install the freepbx-cron-scheduler.php manager +// +install_cron_scheduler(); +// run retrieve_conf_post_custom +// If the following file exists, it will be run. This allows customization to be run automatically after the normal +// processing. Caution should be taken using this as it is only deisgned for expert usage. Errors in the code will +// have bad consequences and can cripple the system. +// +if (isset($amp_conf['AMPLOCALBIN'])) { +$post_custom = $amp_conf['AMPLOCALBIN'].'/retrieve_conf_post_custom'; + if (file_exists($post_custom)) { + outn(sprintf(_("Found script %s, executing.."), $post_custom)); + include($post_custom); + out(_("OK")); + } +} + +out("after post"); +/* As of Asterisk 1.4.16 or there abouts, a missing #include file will make the reload fail. So + we need to make sure that we have such for everything that is in our configs. We will simply + look for the #include statements and touch the files vs. trying to inventory everything we may + need and then forgetting something. +*/ + +exec("grep '#include' ".$amp_conf['ASTETCDIR']."/*.conf | sed 's/;.*//; s/#include//'",$output,$retcode); +if ($retcode != 0) { + error("Error code $retcode: trying to search for missing #include files"); +} +foreach($output as $file) { + if (trim($file) == '') { + continue; + } + $parse1 = explode(':',$file); + $parse2 = explode(';',$parse1[1]); + $rawfile = trim($parse2[0]); + if ($rawfile == '') { + continue; + } + + $target = ($rawfile[0] == '/') ? $rawfile : $amp_conf['ASTETCDIR']."/$rawfile"; + + if (!file_exists($target)) { + exec("touch $target", $output, $retcode); + error("Error code $retcode: trying to create empty file $target"); + } +} + +// **** Set reload flag for AMP admin +needreload(); +if (isset($amp_conf["AMPWEBADDRESS"]) && $amp_conf["AMPWEBADDRESS"]) +{ + out(sprintf(_("Please update your modules and reload Asterisk by visiting %s"), "http://".$amp_conf["AMPWEBADDRESS"]."/admin")); +} +else +{ + out(_("Please update your modules and reload Asterisk by browsing to your server.")); +} + $nt->delete('retrieve_conf', 'FATAL'); +out("end\n"); +$exit_val = 0; +?> diff --git a/freepbx-sandbox/patch/freepbx.patch b/freepbx-sandbox/patch/freepbx.patch index b2fb51c6..35b61d3e 100644 --- a/freepbx-sandbox/patch/freepbx.patch +++ b/freepbx-sandbox/patch/freepbx.patch @@ -1,5 +1,5 @@ --- freepbx-2.4.0-orig//amp_conf/htdocs/admin/modules/core/functions.inc.php 2008-02-10 05:16:02.000000000 +1030 -+++ root/www/admin/modules/core/functions.inc.php 2008-03-07 14:20:23.000000000 +1030 ++++ root/www/admin/modules/core/functions.inc.php 2008-03-11 11:31:52.000000000 +1030 @@ -2886,6 +2886,7 @@ // TODO: sqlite work arround - diego // TODO: WILL NOT WORK, need to remove the usage of SUBSTRING @@ -22,7 +22,7 @@ else { --- freepbx-2.4.0-orig//amp_conf/htdocs/admin/common/db_connect.php 2007-09-09 20:41:11.000000000 +0930 -+++ root/www/admin/common/db_connect.php 2008-03-07 14:20:23.000000000 +1030 ++++ root/www/admin/common/db_connect.php 2008-03-11 11:31:52.000000000 +1030 @@ -52,7 +52,11 @@ } @@ -45,7 +45,7 @@ } else { $nt->delete('core', 'AMPDBPASS'); --- freepbx-2.4.0-orig//amp_conf/htdocs/recordings/includes/database.php 2006-05-01 01:05:45.000000000 +0930 -+++ root/www/recordings/includes/database.php 2008-03-07 14:20:23.000000000 +1030 ++++ root/www/recordings/includes/database.php 2008-03-11 11:31:52.000000000 +1030 @@ -43,18 +43,25 @@ // connect string if ($dbfile) { @@ -80,7 +80,7 @@ // attempt connection $dbh = DB::connect($datasource,$options); --- freepbx-2.4.0-orig//amp_conf/htdocs/admin/cdr/lib/defines.php 2006-09-26 20:48:51.000000000 +0930 -+++ root/www/admin/cdr/lib/defines.php 2008-03-07 14:20:23.000000000 +1030 ++++ root/www/admin/cdr/lib/defines.php 2008-03-11 11:31:52.000000000 +1030 @@ -12,7 +12,7 @@ return $conf; } @@ -146,7 +146,7 @@ if(DB::isError($db)) { --- freepbx-2.4.0-orig//amp_conf/htdocs/admin/cdr/lib/Class.Table.php 2006-09-26 20:48:51.000000000 +0930 -+++ root/www/admin/cdr/lib/Class.Table.php 2008-03-07 14:20:23.000000000 +1030 ++++ root/www/admin/cdr/lib/Class.Table.php 2008-03-11 11:31:52.000000000 +1030 @@ -80,8 +80,11 @@ //$res=DbExec($link, $QUERY); @@ -161,7 +161,7 @@ --- freepbx-2.4.0-orig//SQL/newinstall.sqlite3.sql 2008-02-11 14:27:53.000000000 +1030 -+++ freepbx-2.4.0//SQL/newinstall.sqlite3.sql 2008-03-02 20:20:33.000000000 +1030 ++++ freepbx-2.4.0//SQL/newinstall.sqlite3.sql 2008-03-08 10:05:24.000000000 +1030 @@ -323,7 +323,7 @@ -- Dumping data for table `modules` -- @@ -172,7 +172,7 @@ `id` varchar(20) NOT NULL default 'xml', `time` int(11) NOT NULL default '0', --- freepbx-2.4.0-orig//install_amp 2008-01-28 04:22:58.000000000 +1030 -+++ freepbx-2.4.0//install_amp 2008-03-08 10:05:14.000000000 +1030 ++++ freepbx-2.4.0//install_amp 2008-03-08 10:05:29.000000000 +1030 @@ -4,7 +4,7 @@ require_once ("libfreepbx.install.php"); @@ -222,7 +222,7 @@ // we still support older configurations, and fall back --- freepbx-2.4.0-orig//amp_conf/htdocs/admin/modules/recordings/install.php 2007-08-08 14:34:58.000000000 +0930 -+++ freepbx-2.4.0//amp_conf/htdocs/admin/modules/recordings/install.php 2008-03-02 20:20:33.000000000 +1030 ++++ freepbx-2.4.0//amp_conf/htdocs/admin/modules/recordings/install.php 2008-03-08 10:05:24.000000000 +1030 @@ -22,7 +22,14 @@ unset($fcc); @@ -274,7 +274,7 @@ ?> --- freepbx-2.4.0-orig//amp_conf/bin/retrieve_conf 2007-12-15 08:18:39.000000000 +1030 -+++ freepbx-2.4.0//amp_conf/bin/retrieve_conf 2008-03-07 20:39:45.000000000 +1030 ++++ freepbx-2.4.0//amp_conf/bin/retrieve_conf 2008-03-08 10:05:28.000000000 +1030 @@ -10,7 +10,7 @@ ini_set('error_reporting', E_ALL & ~E_NOTICE); @@ -337,7 +337,7 @@ // install_cron_scheduler(); --- freepbx-2.4.0-orig//amp_conf/astetc/manager.conf 2006-05-01 11:39:24.000000000 +0930 -+++ freepbx-2.4.0//amp_conf/astetc/manager.conf 2008-03-07 13:41:16.000000000 +1030 ++++ freepbx-2.4.0//amp_conf/astetc/manager.conf 2008-03-08 10:05:24.000000000 +1030 @@ -6,8 +6,8 @@ port = 5038 bindaddr = 0.0.0.0 @@ -349,3 +349,16 @@ deny=0.0.0.0/0.0.0.0 permit=127.0.0.1/255.255.255.0 read = system,call,log,verbose,command,agent,user +--- freepbx-2.4.0-orig//amp_conf/htdocs/admin/config.php 2007-12-02 18:06:31.000000000 +1030 ++++ root/www/admin/config.php 2008-03-11 13:22:34.000000000 +1030 +@@ -39,7 +39,9 @@ + /** AJAX handler for reload event + */ + include_once('common/json.inc.php'); +- $response = do_reload(); ++ // DR: include as global code ++ include_once('do_reload.php'); ++ //$response = do_reload(); + $json = new Services_JSON(); + echo $json->encode($response); + break; -- 2.25.1