changes to implement retrieve_conf as an include file
authordrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Wed, 12 Mar 2008 04:20:20 +0000 (04:20 +0000)
committerdrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Wed, 12 Mar 2008 04:20:20 +0000 (04:20 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@13 01035d8c-6547-0410-b346-abe4f91aad63

freepbx-sandbox/Makefile
freepbx-sandbox/files/do_reload.php [new file with mode: 0644]
freepbx-sandbox/files/retrieve_conf.inc.php [new file with mode: 0644]
freepbx-sandbox/patch/freepbx.patch

index fa5b41eb0b01b309d91098419481eb585ed614ab..1ef667decfd47bb95acbf215c774a246f0ae56bd 100644 (file)
@@ -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 (file)
index 0000000..5e2d677
--- /dev/null
@@ -0,0 +1,121 @@
+<?php 
+
+// do_reload.php
+// David Rowe March 11 2008
+// non-function version that executes in same php-cgi as config.php to
+// save run-time memory      
+
+//Copyright (C) 2004 Coalescent Systems Inc. (info@coalescentsystems.ca)
+//
+//This program is free software; you can redistribute it and/or
+//modify it under the terms of the GNU General Public License
+//as published by the Free Software Foundation; either version 2
+//of the License, or (at your option) any later version.
+//
+//This program is distributed in the hope that it will be useful,
+//but WITHOUT ANY WARRANTY; without even the implied warranty of
+//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//GNU General Public License for more details.
+
+# this file runs inside special window that makes it hard to log
+# messages using regular HTML.  So we use a log file instead.
+
+function reload_dbg($msg) {
+       $myFile = "/tmp/log.txt";
+       $fh = fopen($myFile, 'a') or die("can't open file");
+       fwrite($fh, $msg);
+       fclose($fh);
+}
+
+# This is more or less the code copied from do_reload() in
+# admin/functions.inc.php
+
+       $notify =& notifications::create($db);
+       
+       $return = array('num_errors'=>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 (file)
index 0000000..d47bde2
--- /dev/null
@@ -0,0 +1,766 @@
+<?php
+
+/* fairly similar to retrieve_conf, have just commented out a bunch of
+   code we don't need when used as an include file from do_update.php
+   rather than a stand alone exec. */ 
+
+if (! function_exists("_")) {
+       function _($str) {
+               return $str;
+       }
+}
+
+ini_set('error_reporting', E_ALL & ~E_NOTICE);
+
+define("AMP_CONF", "/home/david/freepbx-sandbox/root/etc/amportal.conf");
+$amportalconf = AMP_CONF;
+
+//define("ASTERISK_CONF", "/etc/asterisk/asterisk.conf");
+define("WARNING_BANNER", "; "._("do not edit this file, this is an auto-generated file by freepbx\n")."; "._("all modifications must be done from the web gui")."\n\n\n");
+
+// Emulate gettext extension functions if gettext is not available
+if (!function_exists('_')) {
+       function _($str) {
+               return $str;
+       }
+}
+
+function out($text) {
+       global $rc_output;
+       $rc_output = $rc_output . $text. "\n";
+}
+
+function outn($text) {
+       global $rc_output;
+       $rc_output = $rc_output . $text;
+}
+
+function error($text) {
+       global $rc_output;
+       $rc_output = $rc_output . "[ERROR] ".$text."\n";
+}
+
+function fatal($text, $extended_text="", $type="FATAL") {
+       global $db;
+
+       echo "[$type] ".$text." ".$extended_text."\n";
+
+       if(!DB::isError($db)) {
+               $nt = notifications::create($db);
+               $nt->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:<br />";
+                               $count++;
+                       }
+                       $str .= sprintf("%8s: %s<br />",$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."<br />";
+                       $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;
+?>
index b2fb51c671738eabf5ec29a072356fccff145013..35b61d3e1c82f7c0642feed8929d5b653da60a29 100644 (file)
@@ -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;
  }
    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);
                
                
 --- 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`
  --
        `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");
  
  
  // 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);
  
  
  ?>
 --- 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);
  //
  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
  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;