#!/usr/bin/php -q
<?php
//    License for all code of this IssabelPBX module can be found in the license file inside the module directory
//    Copyright 2006-2014 Schmooze Com Inc.
//    Copyright 2022 Issabel Foundation
//
// ./install_amp --dbengine=$engine --dbuser=root --dbpass=mysqlrootpassword --adminuser=admin --adminpass=asteriskpass --installdb --dbfile /etc/asterisk/sqldata.db --scripted
chdir(__DIR__);

error_reporting(E_ALL & ~E_DEPRECATED);

date_default_timezone_set('America/Los_Angeles');
require_once ("libissabelpbx.install.php");
require_once(dirname(__FILE__) . '/amp_conf/htdocs/admin/libraries/php-upgrade.functions.php');
require_once(dirname(__FILE__) . '/amp_conf/htdocs/admin/libraries/sql.functions.php');
require_once(dirname(__FILE__) . '/amp_conf/htdocs/admin/libraries/utility.functions.php');

# constants
define("AMP_CONF",      "/etc/amportal.conf");
define("ASTERISK_CONF", "/etc/asterisk/asterisk.conf");
define("UPGRADE_DIR",   dirname(__FILE__)."/upgrades");
define("MODULE_DIR",    dirname(__FILE__)."/amp_conf/htdocs/admin/modules/");

# semi constants
$webroot       = "/var/www/html";
$ampsbin_dir   = "/usr/local/sbin";
$ampbin_dir    = "/var/lib/asterisk/bin";
$asterisk_user = "asteriskuser";
$manager_pass  = randomPass(10);
$database_pass = randomPass(10);

$final_restart = false;

/********************************************************************************************************************/

function showHelp() {
    out("Optional parameters:",false);
    out("  --help, -h, -?           Show this help",false);
    out("  --dbhost <ip address>    Use a remote database server",false);
    out("  --dbname databasename    Use database name specified, instead of 'asterisk'",false);
    out("  --dbengine engine        Use database engine specified, instead of 'mysqli'",false);
    out("  --dbfile <path>          Use file for sqlite engine","/etc/asterisk/sqldata.db");
    out("  --dbuser <user>          Use <user> to connect to db and write config",false);
    out("  --dbpass <pass>          Use <pass> to connect to db and write config",false);
    out("  --issabelpbxip <ip>      IssabelPBX web interface is accessed from <ip>",false);
    out("  --webroot <path>         Web root where IssabelPBX will be installed",false);
    out("  --cgibin <path>          Path where cgi-bin's lives",false);
    out("  --bin <path>             Path of asterisk binaries",false);
    out("  --sbin <path>            Path of system admin binaries",false);
    out("  --asteriskuser <user>    Asterisk Manager username",false);
    out("  --asteriskpass <pass>    Asterisk Manager password",false);
    out("  --asteriskip <ip>        Asterisk Manager IP address",false);
    out("  --debug                  Enable debug output",false);
    out("  --dry-run                Don't actually do anything",false);
    out("  --force-version <ver>    Force upgrade from version <ver>",false);
    out("  --skip-module-install    Don't run install scripts for packaged modules, the files are still loaded.",false);
    out("                           In a development environment you may not want the install scripts run.",false);
    out("  --no-files               Just run updates without installing files",false);
    out("  --force-overwrite        Don't ask if it is ok to overwrite modified files, assume yes for all.",false);
    out("  --install-moh            Install default music-on-hold files (normally doesn't, unless ",false);
    out("                           it's a new installation)",false);
    out("  --dev-links              Make links to files in the source directory instead of copying",false);
    out("                           (intended for developers only)",false);
    out("  --update-links           Update dev links without running through the whole install process (Bail before modules)", false);
    out("  --my-svn-is-correct      Ignore Asterisk version, assume it is correct",false);
    out("  --engine <name>          Use the specified PBX Engine ('asterisk')",false);
    out("  --uid <user>             Set ownership of files to user",false);
    out("  --gid <group>            Set ownership of files to group",false);
    out("  --scripted               Scripted install. Do not ask any questions.",false);
    out("                           (Intended for unattended installers only)",false);
    out("  --set-issabelpbx-settings   Force set the internal IssabelPBX DB Settings with install time parameters",false);
    out("  --installdb              Set up the IssabelPBX database",false);
    out("  --language <lang>        Set up the default GUI language",false);
    out("  --createinstalldb        Exports a newinstall.sql file from current system",false);
    out("  --cleaninstall           Like 'make clean' will clean up any previous settings or previous setup while installing a-new",false);
    out("  --uninstall              Completely Uninstall IssabelPBX",false);
}

function randomPass($length) {
    $bytes = openssl_random_pseudo_bytes(10);
    return bin2hex($bytes);
}

function install_parse_amportal_conf($filename) {
    $file = file($filename);
    foreach ($file as $line) {
        if (preg_match("/^\s*([^;#]*)\s*=\s*([^;\n]*)/",$line,$matches)) {
            trim($line);
            // TODO: force booleans into 0/1 this should be ok given the limited number of configuration values
            //
            switch (trim(strtolower($matches[2]))) {
            case 'false':
            case 'no':
            case 'off':
            case '0':
                $conf[$matches[1]] = '0';
                break;
            case 'true':
            case 'yes':
            case 'on':
            case '1':
                $conf[$matches[1]] = '1';
                break;
            default:
                $conf[$matches[1]] = $matches[2];
                break;
            }
        }
    }

    // use same defaults as function.inc.php
    if ( !isset($conf["AMPDBENGINE"]) || ($conf["AMPDBENGINE"] == "")) {
        $conf["AMPDBENGINE"] = "mysql";
    }

    if ( !isset($conf["AMPDBNAME"]) || ($conf["AMPDBNAME"] == "")) {
        $conf["AMPDBNAME"] = "asterisk";
    }

    if ( !isset($conf["AMPENGINE"]) || ($conf["AMPENGINE"] == "")) {
        $conf["AMPENGINE"] = "asterisk";
    }

    if ( !isset($conf["AMPDBHOST"]) || ($conf["AMPDBHOST"] == "")) {
        $conf["AMPDBHOST"] = "localhost";
    }

    out("parsed amp_conf variables from $filename:");
    foreach ($conf as $keyword => $value) {
        out("amp_conf [$keyword] => [$value]");
    }

    return $conf;
}

function install_parse_asterisk_conf($filename) {
    $file = file($filename);
    foreach ($file as $line) {
        if (preg_match("/^\s*([a-zA-Z0-9]+)\s* => \s*(.*)\s*([;#].*)?/",$line,$matches)) {
        $conf[ $matches[1] ] = $matches[2];
        }
    }
    // Now set defaults if not set (although asterisk should fail if not set but at least
    // it will get the setup somewhat right
    //
    if (!isset($asterisk_conf['astetcdir']))    { $asterisk_conf['astetcdir']    = "/etc/asterisk"; }
    if (!isset($asterisk_conf['astmoddir']))    { $asterisk_conf['astmoddir']    = "/usr/lib/asterisk/modules"; }
    if (!isset($asterisk_conf['astvarlibdir'])) { $asterisk_conf['astvarlibdir'] = "/var/lib/asterisk"; }
    if (!isset($asterisk_conf['astdatadir']))   { $asterisk_conf['astdatadir']   = "/var/lib/asterisk"; }
    if (!isset($asterisk_conf['astagidir']))    { $asterisk_conf['astagidir']    = "/var/lib/asterisk/agi-bin"; }
    if (!isset($asterisk_conf['astspooldir']))  { $asterisk_conf['astspooldir']  = "/var/spool/asterisk"; }
    if (!isset($asterisk_conf['astrundir']))    { $asterisk_conf['astrundir']    = "/var/run/asterisk"; }
    if (!isset($asterisk_conf['astlogdir']))    { $asterisk_conf['astlogdir']    = "/var/log/asterisk"; }

    return $conf;
}

function write_amportal_conf($filename, $conf) {
    $file = file($filename);
    // parse through the file
    foreach (array_keys($file) as $key) {
        if (preg_match("/^\s*([a-zA-Z0-9]+)\s*=\s*(.*)\s*([;#].*)?/",$file[$key],$matches)) {
        // this is an option=value line
        if (isset($conf[ $matches[1] ])) {
            // rewrite the line, if we have this in $conf
            $file[$key] = $matches[1]."=".$conf[ $matches[1] ]."\n";
            // unset it so we know what's new
            unset($conf[ $matches[1] ]);
        }
        }
    }

    // add new entries
    foreach ($conf as $key=>$val) {
        $file[] = $key."=".$val."\n";
    }

    // write the file
    if (!$fd = fopen($filename, "w")) {
        fatal("Could not open ".$filename." for writing");
    }
    fwrite($fd, implode("",$file));
    fclose($fd);
}

function ask_overwrite($file1, $file2) {
    global $check_md5s;
    do {
        out($file2." has been changed from the original version.");
        outn("Overwrite (y=yes/a=all/n=no/d=diff/s=shell/x=exit)? ");
        $key = fgets(STDIN,1024);
        switch (strtolower($key[0])) {
        case "y": return true;
        case "a": $check_md5s=false; return true;
        case "n": return false;
        case "d":
            out("");
            // w = ignore whitespace, u = unified
            passthru("diff -wu ".escapeshellarg($file2)." ".escapeshellarg($file1));
            break;
        case "s":
            if (function_exists("pcntl_fork")) {
                out("");
                $shell = (isset($_ENV["SHELL"]) ? $_ENV["SHELL"] : "/bin/bash");
                out("Dropping to shell. Type 'exit' to return");
                out("-> Original file:  ".$file2);
                out("-> New file:       ".$file1);

                $pid = pcntl_fork();
                if ($pid == -1) {
                    out("[ERROR] cannot fork");
                } else if ($pid) {
                    // parent
                    pcntl_waitpid($pid, $status);
                    // we wait till the child exits/dies/whatever
                } else {
                    pcntl_exec($shell, array(), $_ENV);
                }

                out("Returned from shell");
            } else {
                out("[ERROR] PHP not built with process control (--enable-pcntl) support: cannot spawn shell");
            }

            break;
        case "x":
            out("-> Original file:  ".$file2);
            out("-> New file:       ".$file1);
            out("Exiting install program.");
            exit(1);
            break;
        }
        out("");
    } while(1);
}

/** Write AMP-generated configuration files
 */
function generate_configs() {
    global $amp_conf;
    global $dryrun;
    global $debug;
    global $runas_uid;

    out("Generating Configurations.conf, (if Asterisk is not running, you will get an error");
    out("In case of error, start Asterisk and hit the red bar in the GUI to generate the Configurations.conf files");
    if (!$dryrun)
        // added --run-install to make it work like it has been working since retrieve_conf changed to not run module install scripts by default

        //
        // TODO: Should check if Asterisk is running and/or try to start it.
        //
        passthru("sudo -u $runas_uid ".trim($amp_conf["AMPBIN"])."/retrieve_conf --run-install --skip-registry-checks ".($debug ? ' --debug' : ''));
}


/** Collect AMP settings
 */
function collect_settings($filename, $dbhost = '', $dbuser = '', $dbpass = '', $dbname = 'asterisk', $dbengine = 'mysqli') {
    global $webroot;
    global $ampsbin_dir;
    global $ampbin_dir;
    global $asterisk_user;
    global $admin_user;
    global $manager_pass;
    global $database_pass;
    global $scripted;
    global $issabelpbxip;
    global $asteriskip;
    global $runas_uid;
    global $runas_gid;
    global $dbfile;

    if($dbhost=='') $dbhost='localhost';

    out("Creating new $filename");

    if ($scripted == true) {
        # Scripted install. Everything should have been set for us, don't ask questions.
        out("Scripted install. Accepting command line params.");
        $amp_conf["AMPDBUSER"] = $asterisk_user;
        $amp_conf["AMPDBPASS"] = $database_pass;
        $amp_conf["AMPDBHOST"] = $dbhost;
        $amp_conf["AMPDBNAME"] = $dbname;
        $amp_conf["AMPMGRUSER"] ='admin';
        $amp_conf["AMPMGRPASS"] = $manager_pass;
        $amp_conf["AMPWEBROOT"] = $webroot;
        $amp_conf["AMPWEBADDRESS"] = $issabelpbxip;
        $amp_conf["ASTMANAGERHOST"] = $asteriskip;
        $amp_conf["AMPEXTENSIONS"] = "extensions";
        $amp_conf["AMPBIN"] = $ampbin_dir;
        $amp_conf["AMPSBIN"] = "$ampsbin_dir";
        $amp_conf["AMPASTERISKWEBUSER"] = $runas_uid;
        $amp_conf["AMPASTERISKWEBGROUP"] = $runas_gid;
        $amp_conf["AMPASTERISKUSER"] = $runas_uid;
        $amp_conf["AMPASTERISKGROUP"] = $runas_gid;
        $amp_conf["AMPDEVUSER"] = $runas_uid;
        $amp_conf["AMPDEVGROUP"] = $runas_gid;
        write_amportal_conf($filename, $amp_conf);
        out(AMP_CONF." written");
        return;
    }

    outn("Enter your USERNAME to connect to the '$dbname' database:\n [".$asterisk_user. "] ");
    $key = trim(fgets(STDIN,1024));
    if (preg_match('/^$/',$key))
        $amp_conf["AMPDBUSER"] = $asterisk_user;
    else
        $amp_conf["AMPDBUSER"] = $key;

    outn("Enter your PASSWORD to connect to the '$dbname' database:\n [".$database_pass."] ");
    $key = trim(fgets(STDIN,1024));
    if (preg_match('/^$/',$key))
        $amp_conf["AMPDBPASS"] = $database_pass;
    else
        $amp_conf["AMPDBPASS"] = $key;

    outn("Enter the hostname of the '$dbname' database:\n [".($dbhost ? $dbhost : "localhost")."] ");
    $key = trim(fgets(STDIN,1024));
    if (preg_match('/^$/',$key))
        $amp_conf["AMPDBHOST"] = ($dbhost ? $dbhost : "localhost");
    else
        $amp_conf["AMPDBHOST"] = $key;

    outn("Enter a USERNAME to connect to the Asterisk Manager interface:\n [admin] ");
    $key = trim(fgets(STDIN,1024));
    if (preg_match('/^$/',$key)) $amp_conf["AMPMGRUSER"] = "admin";
    else $amp_conf["AMPMGRUSER"] = $key;

    $rs = substr(md5(rand()), 0, 5);
    outn("Enter a PASSWORD to connect to the Asterisk Manager interface:\n [amp111] ");
    $key = trim(fgets(STDIN,1024));
    if (preg_match('/^$/',$key)) $amp_conf["AMPMGRPASS"] = 'amp111';
    else $amp_conf["AMPMGRPASS"] = $key;

    do {
        out("Enter the path to use for your AMP web root:\n [$webroot] ");
        $key = trim(fgets(STDIN,1024));
        if (preg_match('/^$/',$key))
            $amp_conf["AMPWEBROOT"] = "$webroot";
        else
            $amp_conf["AMPWEBROOT"] = rtrim($key,'/');

        $webroot = $amp_conf["AMPWEBROOT"];

        if (is_dir($amp_conf["AMPWEBROOT"])) {
            break;
        } else if (amp_mkdir($amp_conf["AMPWEBROOT"],"0755",true)){
            out("Created ".$amp_conf["AMPWEBROOT"]);
            break;
        } else {
            fatal("Cannot create ".$amp_conf["AMPWEBROOT"]."!");
        }
    } while(1);

    /*
    outn("Enter the IP ADDRESS or hostname used to access the AMP web-admin:\n [$issabelpbxip] ");
    $key = trim(fgets(STDIN,1024));
    if (preg_match('/^$/',$key)) $amp_conf["AMPWEBADDRESS"] = $issabelpbxip;
    else $amp_conf["AMPWEBADDRESS"] = $key;
     */

    outn("Use simple Extensions [extensions] admin or separate Devices and Users [deviceanduser]?\n [extensions] ");
    $key = trim(fgets(STDIN,1024));
    if (preg_match('/^$/',$key)) $amp_conf["AMPEXTENSIONS"] = "extensions";
    else $amp_conf["AMPEXTENSIONS"] = $key;

    do {
        out("Enter directory in which to store AMP executable scripts:\n [$ampbin_dir] ");
        $key = trim(fgets(STDIN,1024));
        if (preg_match('/^$/',$key))
            $amp_conf["AMPBIN"] = $ampbin_dir;
        else
            $amp_conf["AMPBIN"] = rtrim($key,'/');

        if (is_dir($amp_conf["AMPBIN"])) {
            break;
        } else if (amp_mkdir($amp_conf["AMPBIN"],"0755",true)){
            out("Created ".$amp_conf["AMPBIN"]);
            break;
        } else {
            fatal("Cannot create ".$amp_conf["AMPBIN"]."!");
        }
    } while(1);

    do {
        out("Enter directory in which to store super-user scripts:\n [$ampsbin_dir] ");
        $key = trim(fgets(STDIN,1024));
        if (preg_match('/^$/',$key))
            $amp_conf["AMPSBIN"] = "$ampsbin_dir";
        else
            $amp_conf["AMPSBIN"] = rtrim($key,'/');

        if (is_dir($amp_conf["AMPSBIN"])) {
            break;
        } else if (amp_mkdir($amp_conf["AMPSBIN"],"0755",true)){
            out("Created ".$amp_conf["AMPSBIN"]);
            break;
        } else {
            fatal("Cannot create ".$amp_conf["AMPSBIN"]."!");
        }
    } while(1);

    // write amportal.conf
    write_amportal_conf($filename, $amp_conf);
    outn(AMP_CONF." written");
}

/** Set base of packaged modules to the versions packaged in the tarball since they are
 *  getting overwritten with the tarball from anything that may have been updated online.
 *
 */
function set_base_version() {
    global $dryrun;

    // read modules list from MODULE_DIR
    //
    $included_modules = array();
    $dir = opendir(MODULE_DIR);
    while ($file = readdir($dir)) {
        if ($file[0] != "." && $file[0] != "_" && is_dir(MODULE_DIR."/".$file)) {
            $included_modules[] = $file;
        }
    }
    closedir($dir);

    foreach ($included_modules as $up_module) {
        outn("Checking $up_module.. ");
        if (!$dryrun) {
            out(set_module_version($up_module));
        } else {
            out("Dry Run Not Updated");
        }
    }
}

function compile_gettext() {
    outn("Compiling gettext language files");
    system('find /var/www/html/admin -name "*.po" -exec sh -c \'POFILE="$1"; MOFILE="${POFILE%.po}.mo"; sudo -u asterisk msgfmt "$POFILE" -o "$MOFILE" || :\' sh {} \;');
    out("..OK");
}

/** Install all modules packaged with the install. We use the force flag because the
 *  the assumption is that the dependencies are met and the package is able to have
 *  the modules installed.
 */
function install_modules() {
    global $dryrun;
    global $amp_conf;
    global $runas_uid;
    global $runas_gid;

    $directories = glob($amp_conf['AMPWEBROOT'].'/admin/modules/*', GLOB_ONLYDIR);
    $numDirectories = count($directories);

    // Check if its an upgrade
    $installed_modules = array();
    if(is_dir($amp_conf['AMPWEBROOT'].'/admin/modules/framework') && $numDirectories>10) {
        out($amp_conf['AMPWEBROOT']."/admin/modules/framework exists with many other modules, assume upgrading instead of installing, number of directories $numDirectories");
        $dir = opendir($amp_conf['AMPWEBROOT'].'/admin/modules/');
        while ($file = readdir($dir)) {
            if ($file[0] != "." && $file[0] != "_" && is_dir($amp_conf['AMPWEBROOT'].'/admin/modules/'.$file)) {
                $installed_modules[] = $file;
            }
        }
        closedir($dir);

        // Use particular order to reinstall existing modules
        $elementsToRemove = array('framework', 'core', 'recordings', 'timeconditions', 'announcement');
        $filteredArray = array_diff($installed_modules, $elementsToRemove);
        $base_modules = array_merge($elementsToRemove, $filteredArray);
        out(print_r($base_modules,1));

    } else {
        // Or a new installation

        $base_modules = array('framework','core','recordings','timeconditions','announcement','asterisk-cli','asteriskinfo','blacklist','callback','callforward','callrecording','callwaiting','cdr','cidlookup','conferences','customappsreg','customcontexts','dashboard','daynight','disa','donotdisturb','dynamicfeatures','dynroute','extensionsettings','featurecodeadmin','findmefollow','iaxsettings','ivr','languages','logfiles','manager','managersettings','miscapps','miscdests','music','outroutemsg','paging','parking','pinsets','queueprio','queues','ringgroups','setcid','sipsettings','tts','voicemail','weakpasswords','writequeuelog','printextensions','extensionsettings','trunkbalance','dialplaninjection','vmblast','hotelwakeup','bosssecretary','phonebook','speeddial','infoservices');
    }

    $SOURCEDIR = dirname(__FILE__)."/../";

    foreach($base_modules as $module) {
        if(is_dir($SOURCEDIR.$module)) {
            out("installing $module module...");
            if(!is_dir($amp_conf['AMPWEBROOT'].'/admin/modules/'.$module)) {
                mkdir($amp_conf['AMPWEBROOT'].'/admin/modules/'.$module);
            }
            $md5sum = array();
            recursive_copy($SOURCEDIR.$module, $amp_conf['AMPWEBROOT'].'/admin/modules/'.$module, $md5sum); 
            chown($amp_conf['AMPWEBROOT'].'/admin/modules/'.$module, $runas_uid);
            chgrp($amp_conf['AMPWEBROOT'].'/admin/modules/'.$module, $runas_gid);
            $output=array();
            exec($amp_conf['AMPBIN']."/module_admin install $module",$output,$retval);
            if($retval) {
                out("problem installing $module module");
                print_r($output);
            }
        }
    }

    // read modules list from MODULE_DIR
    //
    $included_modules = array();
    $dir = opendir(MODULE_DIR);
    while ($file = readdir($dir)) {
        if ($file[0] != "." && $file[0] != "_" && is_dir(MODULE_DIR."/".$file)) {
            $included_modules[] = $file;
        }
    }
    closedir($dir);

    $output = array();
    $keep_checking = true;
    $num_modules = false;
    while ($keep_checking && count($included_modules)) {
        if ($num_modules === count($included_modules)) {
            $keep_checking = false;
        } else {
            $num_modules = count($included_modules);
        }
        foreach ($included_modules as $id => $up_module) {
            outn("Checking $up_module.. ");
            if (!$dryrun) {
                // if $keep_checking then check dependencies first and skip if not met
                // otherwise we will install anyhow even if some dependencies are not met
                // since it is included. (TODO: should we not?)
                //
                if ($keep_checking) {
                    exec($amp_conf['AMPBIN']."/module_admin --no-warnings checkdepends $up_module",$output,$retval);
                    unset($output);
                    if ($retval) {
                        out("dependencies pending");
                        continue;
                    }
                }
                // Framework modules cannot be enabled, only installed.
                //
                switch ($up_module) {
                case 'framework':
                case 'fw_ari':
                    system($amp_conf['AMPBIN']."/module_admin --no-warnings -f install $up_module");
                    out("installed");
                    break;
                default:
                    system($amp_conf['AMPBIN']."/module_admin --no-warnings -f install $up_module");
                    system($amp_conf['AMPBIN']."/module_admin --no-warnings -f enable $up_module");
                    out("installed");
                }
                unset($included_modules[$id]);
            } else {
                out("Dry Run Not Installed");
            }
        }
    }
}

/** Set the module version number to the packaged version and enable
 *  module must require not install.php or install.sql script
 *  this is primarily to package core and framework with IssabelPBX tarballs
 *
 */
function set_module_version($module) {
    global $db;

    $module_dir = MODULE_DIR;
    $file_path = $module_dir.$module."/module.xml";
    if (file_exists($file_path)) {
        // TODO: this is bad, there are other version tags (depends on) but this
        //       is equivalnet to what publish.pl does, so it expects this to be
        //       at the top.
        //
        $module_xml = file_get_contents($file_path);
        if (preg_match('/<version>(.+)<\/version>/', $module_xml, $matches)) {
            $version = $matches[1];
        } else {
            fatal("ERROR: $file_path found but no version information");
        }
    } else {
        return  "not packaged, no updating needed";
    }

    // If we didn't return above, then we found the package as part of the install
    // tarball and want to update the version info since this might be overwriting
    // an existing install that has a newer version.
    //
    $sql = "SELECT version FROM modules WHERE modulename = '$module'";
    $result = $db->getCol($sql);
    if(DB::IsError($result)) {
        fatal("error accessing version table: ".$result->getMessage());
    }
    $sql = "";
    if (count($result) == 0) {
        // insert but disable as we have to first run install scripts which come later
        $sql = "INSERT INTO modules (modulename, version, enabled) VALUES ('$module', '$version', 0)";
    } else if ($result[0] != $version) {
        if (version_compare_issabel($version, $result[0], "gt")) {
            // if new version is greater than old, then we disable the module and it will get enabled next when installed
            //
            $sql = "UPDATE modules SET version = '$version', enabled = 0 WHERE modulename = '$module'";
        } else {
            // if new version is equal to or less than old, then we leave it in the enable/disable state it was in but just
            // reset the version number.
            //
            $sql = "UPDATE modules SET version = '$version' WHERE modulename = '$module'";
        }
    }
    if ($sql) {
        debug($sql);
        $result = $db->query($sql);
        if(DB::IsError($result)) {
            fatal("error writing to version table: ".$result->getMessage());
        }
        return "updated to $version";
    } else {
        return "already at $version";
    }
}

function installampimport_mysql_dump($file,$db=NULL) {
    if(!isset($db)) {
        global $db;
    }

    $dir = dirname(__FILE__);
    if(file_exists($dir.'/SQL/'.$file)) {
        // Temporary variable, used to store current query
        $templine = '';
        // Read in entire file
        $lines = file($dir.'/SQL/'.$file);
        // Loop through each line
        foreach ($lines as $line)
        {
            // Skip it if it's a comment
            if (substr($line, 0, 2) == '--' || $line == '')
                continue;

            // Add this line to the current segment
            $templine .= $line;
            // If it has a semicolon at the end, it's the end of the query
            if (substr(trim($line), -1, 1) == ';')
            {
                // Perform the query
                $result = $db->query($templine);
                if(DB::IsError($result)) {
                    fatal("Error performing query: ". $templine . " Message:".$result->getMessage());
                }
                // Reset temp variable to empty
                $templine = '';
            }
        }
    }
}

function change_ami_password($sNewPassword) {

    $content = file("/etc/asterisk/manager.conf");
    $bAdmin = FALSE;
    for ($i = 0; $i < count($content); $i++) {
        $regs = NULL;
        if (preg_match('/^\[(\w+)\]/', $content[$i], $regs)) {
            $bAdmin = ($regs[1] == 'admin');
        } elseif ($bAdmin && preg_match('/^secret\s*=\s*/', $content[$i])) {
            $content[$i] = "secret = $sNewPassword\n";
        }
    }
    file_put_contents("/etc/asterisk/manager.conf",implode("",$content));
    outn("manager.conf admin password set");
}

function insert_admin_user($user,$pass) {
    global $db;
    $query = "INSERT INTO ampusers (username,password_sha1,extension_low,extension_high,deptname,sections) VALUES (?,?,'','','','*')";
    $params = array($user,sha1($pass));
    $db->query($query,$params);
}

function grant_mysql() {
    global $db;
    global $asterisk_user;
    global $database_pass;
    global $dbengine;

    if($dbengine!="mysql" && $dbengine!="mysqli") { return; }
    out("Granting MySQL permissions to asteriskuser");
    $query = "GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES ON `asteriskcdrdb`.* TO 'asteriskuser'@'localhost' IDENTIFIED BY '$database_pass'";
    $res = $db->query($query);

    if(DB::IsError($res)) {
        out("FAILED");
        echo 'Standard Message: ' . $db->getMessage() . "\n";
        echo 'Standard Code: ' . $db->getCode() . "\n";
        echo 'DBMS/User Message: ' . $db->getUserInfo() . "\n";
        echo 'DBMS/Debug Message: ' . $db->getDebugInfo() . "\n";
        fatal("Cannot connect to database");
    }

    $query = "GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES ON `asterisk`.* TO 'asteriskuser'@'localhost' IDENTIFIED BY '$database_pass'";
    $res = $db->query($query);
    if(DB::IsError($res)) {
        out("FAILED");
        echo 'Standard Message: ' . $db->getMessage() . "\n";
        echo 'Standard Code: ' . $db->getCode() . "\n";
        echo 'DBMS/User Message: ' . $db->getUserInfo() . "\n";
        echo 'DBMS/Debug Message: ' . $db->getDebugInfo() . "\n";
        fatal("Cannot connect to database");
    }

    out("Permissions granted!");

}

/********************************************************************************************************************/

//
// TODO: will this work, basically using bootstrap once installed if using to upgrade, etc?
/*
$bootstrap_settings['skip_astman']) = true;
$bootstrap_settings['issabelpbx_auth'] = false;
$restrict_mods = true;
if (@include_once(getenv('ISSABELPBX_CONF') ? getenv('ISSABELPBX_CONF') : '/etc/issabelpbx.conf')) {
  out(_("IssabelPBX already installed, bootstrapping"));
} else if (@include_once('/etc/asterisk/issabelpbx.conf')) {
  out(_("IssabelPBX already installed, bootstrapping"));
} else {
  // all the initialization here instead
}
 */

// **** 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 must be installed (requires DB.php). Include path: ".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 must be installed (requires Console/Getopt.php). Include path: ".ini_get("include_path"));
}
out("OK");

// **** Parse out command-line options
$shortopts = "h?u:p:";
$longopts = array(
    "asteriskip=",
    "adminpass=",
    "adminuser=",
    "bin=",
    "cgibin=",
    "cleaninstall",
    "dbhost=",
    "dbname=",
    "dbengine=",
    "dbfile=",
    "debug",
    "dev-links",
    "dry-run",
    "engine=",
    "fopwebroot=",
    "force-overwrite",
    "force-version=",
    "issabelpbxip=",
    "gid=",
    "help",
    "install-fop",
    "install-moh",
    "installdb",
    'language=',
    "createinstalldb",
    "make-links-devel",
    "my-svn-is-correct",
    "no-files",
    "dbpass=",
    "sbin=",
    "scripted",
    "set-issabelpbx-settings",
    "skip-module-install",
    "uid=",
    "uninstall",
    "update-links",
    "dbuser=",
    "webroot=",
    "compile-gettext"
);

$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;
$install_files = true;
$override_astvers = false;
$scripted = false;

$install_moh = false;
$make_links = false;
$update_links = false;
$compile_gettext = false;
$module_install = true;
$set_issabelpbx_settings = false;

$installamp_clean = false;
$uninstallamp = false;
$installdb = false;
$createinstalldb = false;
$language = "";

//initialize variables to avoid php notices
$dbhost = null;
$dbname = 'asterisk';
$dbengine = 'mysqli';
$dbfile = '/etc/asterisk/sqldata.db';
$new_username = null;
$new_password = null;

$runas_uid = "asterisk";
$runas_gid = "asterisk";
$issabelpbxip = "";
$asteriskip = "localhost";
$admin_user = 'admin';
$admin_pass = 'admin';

foreach ($args[0] as $arg) {
    switch ($arg[0]) {
    case "--help": case "h": case "?":
        showHelp();
        exit(10);
        break;
    case "--dry-run":
        out("Dry-run only, nothing will be changed");
        $dryrun = true;
        break;
    case "--debug":
        $debug = true;
        debug("Debug mode enabled");
        break;
    case "--dbuser": case "u":
        out("Using username: ".$arg[1]);
        $new_username = $arg[1];
        break;
    case "--dbpass": case "p":
        out("Using password: ".str_repeat("*",strlen($arg[1])));
        $new_password = $arg[1];
        break;
    case "--force-version":
        $version = $arg[1];
        out("Forcing upgrade from version ".$version);
        break;
    case "--dbhost":
        $dbhost = $arg[1];
        out("Using remote database server at ".$dbhost);
        break;
    case "--dbname":
        $dbname = $arg[1];
        out("Using database ".$dbname);
        break;
    case "--dbengine":
        $dbengine = $arg[1];
        out("Using database engine ".$dbengine);
        break;
    case "--dbfile":
        $dbfile = $arg[1];
        out("Using sqlite database file ".$dbengine);
        break;
    case "--no-files":
        $install_files = false;
        out("Running upgrade only, without installing files.");
        break;
    case "--force-overwrite":
        $check_md5s = false;
        out("Overwriting all files including modified ones.");
        break;
    case "--my-svn-is-correct":
        $override_astvers = true;
        break;
    case "--engine":
        if ($arg[1] != 'asterisk') {
            fatal('Currently only "asterisk" is supported as a PBX engine');
        }
        $pbx_engine = $arg[1];
        break;
    case "--install-moh":
        $install_moh = true;
        break;
    case "--set-issabelpbx-settings":
        $set_issabelpbx_settings = true;
        break;
    case "--fopwebroot":
    case "--install-fop":
        out("install-fop: depricated setting, does nothing.");
        break;
    case "--compile-gettext":
        $compile_gettext = true;
        break;
    case "--update-links":
        $update_links = true;
    case "--make-links-devel":
    case "--dev-links":
        $make_links = true;
        break;
    case "--skip-module-install":
        $module_install = false;
        break;
    case "--webroot":
        $webroot = $arg[1];
        out("Using Webroot at ".$webroot);
        break;
    case "--cgibin":
        $cgibin = $arg[1];
        out("Using CGI-BIN at ".$cgibin);
        break;
    case "--bin":
        $ampbin_dir = $arg[1];
        out("Using bin at ".$ampbin_dir);
        break;
    case "--sbin":
        $ampsbin_dir = $arg[1];
        out("Using sbin at ".$ampsbin_dir);
        break;
    case "--adminuser":
        $admin_user = $arg[1];
        out("Using Admin user ".$admin_user);
        break;
    case "--adminpass":
        $admin_pass = $arg[1];
        out("Using Admin pass ".str_repeat("*",strlen($arg[1])));
        break;
    case "--uid":
        $runas_uid = $arg[1];
        out("Setting ownership (user) to ".$runas_uid);
        break;
    case "--gid":
        $runas_gid = $arg[1];
        out("Setting ownership (group) to ".$runas_gid);
        break;
    case "--scripted":
        $scripted = true;
        out("Unattended installation. No questions will be asked");
        break;
    case "--issabelpbxip":
        $issabelpbxip = $arg[1];
        out("Setting IP address of web interface to $issabelpbxip");
        break;
    case "--asteriskip":
        $asteriskip = $arg[1];
        out("Setting IP address of asterisk to $asteriskip");
        break;
    case "--cleaninstall":
        $installamp_clean = true;
        break;
    case "--uninstall":
        $uninstallamp = true;
        break;
    case "--installdb":
        $installdb = true;
        break;
    case "--language":
        $language = $arg[1];
        break;
    case "--createinstalldb":
        $createinstalldb = true;
        break;
    }
}

if($compile_gettext) {
    compile_gettext();
    exit;
}
if($new_username=='') $new_username='root';

if($installamp_clean || $uninstallamp) {
    global $webroot;
    global $asterisk_user;

    $oldampconf = array();
    if(file_exists('/etc/amportal.conf')) {
        $amportalconf = file_get_contents('/etc/amportal.conf');
        if(preg_match('/AMPWEBROOT=(.*)/',$amportalconf,$matches)) {
            $oldampconf['AMPWEBROOT'] = $matches[1];
        }
        if(preg_match('/AMPDBENGINE=(.*)/',$amportalconf,$matches)) {
            $oldampconf['AMPDBENGINE'] = $matches[1];
        }
        if(preg_match('/AMPDBUSER=(.*)/',$amportalconf,$matches)) {
            $oldampconf['AMPDBUSER'] = $matches[1];
        }
        if(preg_match('/AMPDBPASS=(.*)/',$amportalconf,$matches)) {
            $oldampconf['AMPDBPASS'] = $matches[1];
        }
        if(preg_match('/AMPDBNAME=(.*)/',$amportalconf,$matches)) {
            $oldampconf['AMPDBNAME'] = $matches[1];
        }
        if(preg_match('/AMPDBHOST=(.*)/',$amportalconf,$matches)) {
            $oldampconf['AMPDBHOST'] = $matches[1];
        }
        if(preg_match('/AMPBIN=(.*)/',$amportalconf,$matches)) {
            $oldampconf['AMPBIN'] = $matches[1];
        }
        outn("Remove /etc/amportal.conf?:\n [y] ");
        $key = trim(fgets(STDIN,1024));
        switch($key) {
        case "n":
        case "no":
            break;
        case "y":
        case "yes":
        default:
        outn("Removing /etc/amportal.conf.....");
        unlink('/etc/amportal.conf');
        out("Done!");
        break;
        }
    }
    if(file_exists('/etc/issabelpbx.conf')) {
        outn("Remove /etc/issabelpbx.conf?:\n [y] ");
        $key = trim(fgets(STDIN,1024));
        switch($key) {
        case "n":
        case "no":
            break;
        case "y":
        case "yes":
        default:
        outn("Removing /etc/issabelpbx.conf.....");
        unlink('/etc/issabelpbx.conf');
        out("Done!");
        break;
        }
    }
    if(file_exists('/usr/local/sbin/amportal')) {
        outn("Remove /usr/local/sbin/amportal?:\n [y] ");
        $key = trim(fgets(STDIN,1024));
        switch($key) {
        case "n":
        case "no":
            break;
        case "y":
        case "yes":
        default:
        outn("Removing /usr/local/sbin/amportal.....");
        unlink('/usr/local/sbin/amportal');
        out("Done!");
        break;
        }
    }
    if(!empty($oldampconf['AMPBIN']) && file_exists($oldampconf['AMPBIN'])) {
        outn("Remove All IssabelPBX Tools in ".$oldampconf['AMPBIN']."?:\n [y] ");
        $key = trim(fgets(STDIN,1024));
        $files = array("archive_recordings","issabelpbx_engine", "gen_amp_conf.php", "libissabelpbx.confgen.php", "retrieve_conf", "issabelpbx-cron-scheduler.php", "issabelpbx_setting", "generate_hints.php", "module_admin", "retrieve_parse_amportal_conf.pl");
        foreach (glob($oldampconf['AMPBIN']."/*") as $filename) {
            if(is_link($filename)) {
                if(preg_match('/'.preg_quote($oldampconf['AMPWEBROOT'],'/').'/i',readlink($filename))) {
                    $files[] = basename($filename);
                }
            }
        }
        switch($key) {
        case "n":
        case "no":
            break;
        case "y":
        case "yes":
        default:
        foreach($files as $file) {
            if(file_exists($oldampconf['AMPBIN'].'/'.$file)) {
                outn("Removing ".$oldampconf['AMPBIN']."/".$file.".....");
                unlink($oldampconf['AMPBIN'].'/'.$file);
                out("Done!");
            }
        }
        break;
        }
    }
    if(!empty($oldampconf) && isset($oldampconf['AMPWEBROOT']) && file_exists($oldampconf['AMPWEBROOT'].'/admin')) {
        outn("Remove ".$oldampconf['AMPWEBROOT']."/admin ?:\n [y] ");
        $key = trim(fgets(STDIN,1024));
        switch($key) {
        case "n":
        case "no":
            break;
        case "y":
        case "yes":
        default:
        outn("Removing ".$oldampconf['AMPWEBROOT']."/admin......");
        exec('rm -Rf '.$oldampconf['AMPWEBROOT'].'/admin');
        out("Done!");
        break;
        }
    }
    if(!$uninstallamp && !empty($oldampconf) && $oldampconf['AMPDBENGINE'] == 'mysql') {
        outn("Reinitalize & Reinstall IssabelPBX's Asterisk Database?:\n [y] ");
        $key = trim(fgets(STDIN,1024));
        switch($key) {
        case "n":
        case "no":
            break;
        case "y":
        case "yes":
        default:
        outn("Erasing Database...");
        $datasource = 'mysqli://'.$oldampconf["AMPDBUSER"].':'.$oldampconf["AMPDBPASS"].'@'.$oldampconf["AMPDBHOST"].'/'.$oldampconf["AMPDBNAME"];
        $cleandb = DB::connect($datasource); // attempt connection

        if(DB::IsError($cleandb)) {
            out("FAILED");
            fatal("Try not selecting 'y' on Reinitalize & Reinstall IssabelPBX's Asterisk Database");
        } else {
            $sql = "SHOW TABLES FROM ".$oldampconf['AMPDBNAME'];
            $tables = $cleandb->getAll($sql);
            foreach($tables as $list) {
                $sql = "DROP TABLE ".$oldampconf['AMPDBNAME'].".".$list[0];
                $cleandb->query($sql);
            }
            out("Done");
            outn("Reinstalling DB Structure...");
            installampimport_mysql_dump('newinstall.sql',$cleandb);
            out("Done");
        }
        break;
        }
    }
    if($uninstallamp && (!empty($oldampconf) || !empty($new_username))) {
        outn("Uninstall IssabelPBX's Asterisk Database?:\n [y] ");
        $u_username = !empty($oldampconf["AMPDBUSER"]) ? $oldampconf["AMPDBUSER"] : $new_username;
        $u_password = !empty($oldampconf["AMPDBPASS"]) ? $oldampconf["AMPDBPASS"] : (!empty($new_password) ? $new_password : '');
        $u_host = !empty($oldampconf["AMPDBHOST"]) ? $oldampconf["AMPDBHOST"] : (!empty($dbhost) ? $dbhost : 'localhost');
        $u_database = !empty($oldampconf["AMPDBNAME"]) ? $oldampconf["AMPDBNAME"] : (!empty($dbname) ? $dbname : 'asterisk');
        $key = trim(fgets(STDIN,1024));
        switch($key) {
        case "n":
        case "no":
            break;
        case "y":
        case "yes":
        default:
        outn("Erasing Database...");
        $datasource = 'mysqli://'.$u_username.':'.$u_password.'@'.$u_host;
        $cleandb = DB::connect($datasource); // attempt connection

        if(DB::IsError($cleandb)) {
            out("FAILED");
            fatal("Could Not Connect to Database (Probably already deleted)");
        } else {
            $sql = "DROP DATABASE asterisk";
            $cleandb->query($sql);
            $sql = "DROP DATABASE asteriskcdrdb";
            $cleandb->query($sql);
            //$sql = "SHOW TABLES FROM ".$u_database;
            //$tables = $cleandb->getAll($sql);
            //foreach($tables as $list) {
            //            $sql = "DROP TABLE ".$u_database.".".$list[0];
            //              $cleandb->query($sql);
            //         }
            out("Done");
        }
        break;
        }
    }
    if($uninstallamp) {
        die("Successfully Uninstalled IssabelPBX\n");
    }
}

// **** Look for user = root

// TODO: if we bootstrap, do this first before even trying. Also, is their a problem boostraping as user root???
//
outn("Checking user..");
//$current_user=(isset($_ENV["USER"]) ? $_ENV["USER"] : exec('whoami',$output));
$euid = (posix_getpwuid(posix_geteuid()));
$current_user = $euid['name'];
if ($current_user != "root"){
    out("FAILED");
    fatal($argv[0]." must be run as root");
}
out("OK");


// TODO: if we bootstrap, do this first before even trying.
//
outn("Checking if Asterisk is running..");
exec("pidof asterisk", $pid_val, $ret);
if ($ret) {
    out("FAILED");
    fatal($argv[0]."\n\tAsterisk must be running. If this is a first time install, you should start\n\tAsterisk by typing './start_asterisk start'\n\tFor upgrading, you should run 'amportal start'");
}
out("running with PID: ".$pid_val[0]."..OK");

// **** Check for amportal.conf, create if necessary

// TODO: Check if issabelpbx_settings has been setup, if so then we don't even want to mess with amportal.conf, that
//       should only be first time install.
//
out("Checking for ".AMP_CONF."..");

if (!file_exists(AMP_CONF)) {
    out(AMP_CONF." does not exist, copying default");
    copy("amportal.conf", AMP_CONF);

    chown(AMP_CONF, $runas_uid);
    chgrp(AMP_CONF, $runas_gid);
    chmod(AMP_CONF, 0640);

    collect_settings(AMP_CONF, $dbhost, $new_username, $new_password, $dbname, $dbengine);

    out("Assuming new install, --install-moh added to command line");
    $install_moh = true;

    $amp_conf = install_parse_amportal_conf(AMP_CONF);
    if (count($amp_conf) == 0) {
        fatal("FAILED parsing/reading ".AMP_CONF);
    }

} else {

    $amp_conf = install_parse_amportal_conf(AMP_CONF);
    if (count($amp_conf) == 0) {
        fatal("FAILED parsing/reading ".AMP_CONF);
    }
    $manager_pass= $amp_conf['AMPMGRPASS'];
    $database_pass= $amp_conf['AMPDBPASS'];
}

// TODO: if we boostrapped I think we can count on ALL of these being set but maybe it's
//       fine to do a sanity check?
//
// Ensure our "critical" variables are set.  We absolutely need these to copy in files.

if (!array_key_exists("AMPWEBROOT",$amp_conf)) {
    out("Adding AMPWEBROOT option to amportal.conf - using AMP default");
    $amp_conf["AMPWEBROOT"] = "/var/www/html";
}
if (!array_key_exists("AMPBIN",$amp_conf)) {
    out("Adding AMPBIN option to amportal.conf - using AMP default");
    $amp_conf["AMPBIN"] = "/var/lib/asterisk/bin";
}
if (!array_key_exists("AMPSBIN",$amp_conf)) {
    out("Adding AMPSBIN option to amportal.conf - using AMP default");
    $amp_conf["AMPSBIN"] = "/usr/sbin";
}
if (!array_key_exists("AMPDBENGINE",$amp_conf)) {
    out("Adding AMPDBENGINE option to amportal.conf - using AMP default");
    $amp_conf["AMPDBENGINE"] = "mysql";
}
if (!array_key_exists("AMPDBNAME",$amp_conf)) {
    out("Adding AMPDBNAME option to amportal.conf - using AMP default");
    $amp_conf["AMPDBNAME"] = "asterisk";
}

// TODO: if we boostrapped do we ignore these? (Can they even be set?)
//

if (isset($dbhost)) {
    $amp_conf["AMPDBHOST"] = $dbhost;
}
if (isset($dbname)) {
    $amp_conf["AMPDBNAME"] = $dbname;
}
if (isset($dbengine)) {
    $amp_conf["AMPDBENGINE"] = $dbengine;
}

if(isset($dbfile)) {
    $amp_conf["AMPDBFILE"] = $dbfile;
}

// If they pre-set this in their amportal.conf or this is an upgrade, we should honor it as well
//
// TODO: if we boostrap, then this value could be normalized (1/0 I think?)
//
// write amportal.conf
// TODO: if we boostrapped we don't want to write amportal.conf, or do we? e.g. if we are running out of the file vs. the
//       database then we probably want to write, though there should be a issabelpbx_conf class to use that does that and knows
//       how to make that decsion as well as what to write?
//
write_amportal_conf(AMP_CONF, $amp_conf);

// **** Check for amportal.conf, create if necessary

outn("Checking for ".ASTERISK_CONF."..");
if (!file_exists(ASTERISK_CONF)) {
    out(ASTERISK_CONF." does not exist, copying default");
    copy("asterisk.conf", ASTERISK_CONF);
}
out("OK");

// **** read asterisk.conf

// TODO: if we boostrapped don't do this
//
outn("Reading ".ASTERISK_CONF."..");
$asterisk_conf = install_parse_asterisk_conf(ASTERISK_CONF);
if (count($asterisk_conf) == 0) {
    fatal("FAILED. Have you installed Asterisk?");
}
out("OK");

/* TODO: if we boostrapped this should have been done but doesn't hurt?
 */
if (isset($asterisk_conf['astetcdir']))    { $amp_conf['ASTETCDIR']    = $asterisk_conf['astetcdir']; }
if (isset($asterisk_conf['astmoddir']))    { $amp_conf['ASTMODDIR']    = $asterisk_conf['astmoddir']; }
if (isset($asterisk_conf['astvarlibdir'])) { $amp_conf['ASTVARLIBDIR'] = $asterisk_conf['astvarlibdir']; }
if (isset($asterisk_conf['astdatadir']))   { $amp_conf['ASTDATADIR']   = $asterisk_conf['astdatadir']; }
if (isset($asterisk_conf['astagidir']))    { $amp_conf['ASTAGIDIR']    = $asterisk_conf['astagidir']; }
if (isset($asterisk_conf['astspooldir']))  { $amp_conf['ASTSPOOLDIR']  = $asterisk_conf['astspooldir']; }
if (isset($asterisk_conf['astrundir']))    { $amp_conf['ASTRUNDIR']    = $asterisk_conf['astrundir']; }
if (isset($asterisk_conf['astlogdir']))    { $amp_conf['ASTLOGDIR']    = $asterisk_conf['astlogdir']; }

if (!isset($pbx_engine)) { $pbx_engine='asterisk'; }
out("Using $pbx_engine as PBX Engine");
$amp_conf["AMPENGINE"]=$pbx_engine;

// TODO: I guess we have new variables set, of course see note above if we boostrapped. Probably
//       this one stays?
//
write_amportal_conf(AMP_CONF, $amp_conf);


// **** Write asterisk version to ASTETCDIR/version

// TODO: does anything use this? What's the point? (other than we need the version for below)
//
$tmpoutput = '';
$tmpout = exec("asterisk -V", $tmpoutput, $exitcode);
if ($exitcode != 0) {
    fatal("Error executing asterisk: be sure Asterisk is installed and in the path");
}
if (!$fd = fopen($amp_conf['ASTETCDIR'].'/version','w')) {
    fatal('Cannot open '.$amp_conf['ASTETCDIR'].'/version for writing');
}
fwrite($fd, $tmpout);
fclose($fd);
// change to read-only
chmod($amp_conf['ASTETCDIR'].'/version',0444);


// normally this would be the contents of ASTETCDIR/version, but this is for simplicity, as we just read it above
$verinfo = $tmpout;

// **** Check asterisk version
//  Set the 'engine' to be 'asterisk14' if using asterisk 1.4, otherwise
//  'asterisk'
outn("Checking for Asterisk version..");
if ((preg_match('/^Asterisk (\d+(\.\d+)*)(-?(.*))$/', $verinfo, $matches)) ||
    (preg_match('/^Asterisk SVN-(\d+(\.\d+)*)(-?(.*))$/', $verinfo, $matches)) ||
    (preg_match('/^Asterisk certified\/(\d+(\.\d+)*)(-?(.*))$/', $verinfo, $matches))) {
    if ((version_compare($matches[1], "1.6") < 0)) {
        fatal("Asterisk 1.6, 1.8 or 10 is required for this version of IssabelPBX. Detected version is: ".$matches[1]);
    }
    if (version_compare($matches[1], "23", "ge")) {
        fatal("Asterisk 1.6, 1.8, 10, 11, 12, 13, 16, 18, 20, 21 or 22 is required for this version of IssabelPBX. Detected version is: ".$matches[1]);
    }
    out("{$matches[1]}");
    $asterisk_version = $matches[1];

} elseif (preg_match('/^Asterisk ([ABC]\.\d+(\.\d+)*)(-?(.*))$/', $verinfo, $matches)) {
    if (substr($matches[1], 0, 1) == "A") {
        fatal("Asterisk Business Edition B or C is required for this version of IssabelPBX. Detected version is: ".$matches[1]);
    }
    out("{$matches[1]}");
    $asterisk_version = '1.4'; //Not really, but this makes sure that proper execution occurs later on reload commands, etc.

} elseif ($asterisk_version = preg_match('/^Asterisk SVN.+/', $verinfo)) {
    out("FAIL");
    out("*** WARNING ***");
    out("You are not using a released version of Asterisk. We are unable to verify");
    out("that your Asterisk version is compatible with IssabelPBX. Whilst this probably");
    out("won't cause any problems, YOU NEED TO BE CERTAIN that it is compatible");
    out("with at least the released Asterisk version 1.2" );
    if ($override_astvers==false) {
        out("If you are SURE that this is compatible, you can re-run ".$argv[0]." with");
        out("the parameter --my-svn-is-correct");
        exit;
    } else {
        out("--my-svn-is-correct specified, continuing");
    }
} else {
    fatal("Could not determine asterisk version (got: \"".$verinfo."\" please report this)");
}

// **** Make sure selinux isn't enabled

outn("Checking for selinux..");
$tmpoutput = array();
$tmpout = exec("getenforce 2>/dev/null", $tmpoutput, $sereturn);
if (isset($tmpoutput[0]) && strtolower($tmpoutput[0]) === "enabled") {
    // this method seems better because disabled and permissive are the same
    // if a user installs and realizes selinux is running the other method
    // requires a reboot to get selinuxenabled to work after editing the  selinux config
    // this will allow you to use setenforce 0 which turns selinux into permissive mode which
    // doesnt enforce, it just warns.
    fatal("selinux is ENABLED. This is not supported. Please disable selinux before using IssabelPBX");
}
out("OK");

// **** Connect to database

// TODO: if we bootstrapped, we are already connected and this can all be skipped
//
outn("Connecting to database..");

$dbengine = $amp_conf["AMPDBENGINE"];
echo "engine $dbengine\n";
if ($dbengine != "sqlite3" && $dbengine != "rqlite") {
    $db_user = $amp_conf["AMPDBUSER"];
    $db_pass = $amp_conf["AMPDBPASS"];
    $db_host = $amp_conf["AMPDBHOST"];
}
$db_name = $amp_conf["AMPDBNAME"];

// we still support older configurations,  and fall back
// into mysql when no other engine is defined
if ($dbengine == "")
{
    $dbengine = "mysql";
}

if($dbengine=="mysql") $dbengine="mysqli";

switch ($dbengine)
{
case "pgsql":
case "mysqli":
case "mysql":
    // datasource in in this style: dbengine://username:password@host/database
    if (!function_exists($dbengine.'_connect')) {
        out("FAILED");
        fatal($dbengine." PHP libraries not installed");
    }
    $datasource = $dbengine.'://'.$new_username.':'.$new_password.'@'.$db_host;

    out("Connecting as: $datasource");

    $db = DB::connect($datasource); // attempt connection
    if (DB::isError($db)) {
        fatal("Could not connect to database with supplied credentials (user: $new_username, pass: $new_password)");
    }

    $query = "SHOW DATABASES LIKE 'asterisk'";
    $q = $db->query($query);
    if (DB::iserror($q)) { die($q->getMessage( )); }
    if($q->numRows()==0) {
        $res = $db->query("CREATE DATABASE asterisk");
        $res = $db->query("CREATE DATABASE asteriskcdrdb");

        out("Databases created!");

        grant_mysql();

    } else {
        out("Database asterisk already exists");
    }

    $db->disconnect();

    $dbcdr = DB::connect($datasource."/asteriskcdrdb"); 

    $datasource = $dbengine.'://'.$db_user.':'.$db_pass.'@'.$db_host.'/'.$db_name;

    out("Reconnecting as $datasource with asterisk user ");

    $db = DB::connect($datasource); // attempt connection
    $db->query('SET NAMES utf8mb4');
    break;

case "rqlite":
    $datasource = "rqlite:///localhost:4001";
    $db = DB::connect($datasource);
    break;
case "sqlite":
case "sqlite3":
    if (!isset($amp_conf["AMPDBFILE"]))
        die("You must setup properly AMPDBFILE in /etc/amportal.conf");

    if (isset($amp_conf["AMPDBFILE"]) == "")
        die("AMPDBFILE in /etc/amportal.conf cannot be blank");

    /* on centos this extension is not loaded by default */
    if (! extension_loaded('sqlite3.so')  && ! extension_loaded('SQLITE3'))
        dl('sqlite3.so');


    /*
    if (! @require_once('DB/sqlite3.php') )
    {
        out("FAILED");
        fatal( "Your PHP installation has no PEAR/SQLite3 support. Please install php-sqlite3 and php-pear.");
    }
     */

    $datasource = "sqlite3:///" . $amp_conf["AMPDBFILE"] . "?mode=0666";
    $db = DB::connect($datasource);
    break;

default:
    die( "Unknown SQL engine: [$dbengine]");
}

if(DB::IsError($db)) {
    out("FAILED");
    echo 'Standard Message: ' . $db->getMessage() . "\n";
    echo 'Standard Code: ' . $db->getCode() . "\n";
    echo 'DBMS/User Message: ' . $db->getUserInfo() . "\n";
    echo 'DBMS/Debug Message: ' . $db->getDebugInfo() . "\n";
    out("Try running ".$argv[0]." --username=user --password=pass  (using your own user and pass)");
    fatal("Cannot connect to database");
}

out("OK");

function escapeDouble($val) {
    return preg_replace('/"/','\"',$val);
}
if($createinstalldb) {
    $final_output= "";
    $tables = array('admin', 'ampusers', 'cronmanager', 'dahdi', 'devices', 'extensions', 'featurecodes', 'issabelpbx_log', 'issabelpbx_settings', 'globals', 'iax', 'incoming', 'module_xml', 'modules', 'notifications', 'outbound_route_patterns', 'outbound_route_sequence', 'outbound_route_trunks', 'outbound_routes', 'sip', 'trunk_dialpatterns', 'users', 'dahdichandids', 'pjsipsettings');
    out("Creating newinstall.sql file");
    foreach($tables as $table) {

        $datarow = $db->tableInfo($table);
        $fields=array();
        $count_primary_fields=array();
        foreach($datarow as $idx=>$data) {
            if(preg_match("/primary/",$data['flags'])) {
                $count_primary_fields[]=$data['name'];
            }
        }
        foreach($datarow as $idx=>$data) {
            array_shift($data);

            $field_name = array_shift($data);
            $field_type = array_shift($data);
            $field_length = array_shift($data);
            $field_length = $field_length/4;  //  utf8mbr4
            $field_flags = array_shift($data);

            if($field_type=='int') { $field_type='INTEGER'; $field_length=''; }
            if($field_type=='blob') { $field_type='TEXT'; $field_length=''; }
            if($field_type=='datetime') { $field_type='datetime'; $field_length=''; }
            $field_create = "`$field_name` $field_type";
            if($field_length<>'') {
                $field_create.="($field_length) ";
            }
            if(preg_match("/primary/",$field_flags)) {
                if(count($count_primary_fields)<=1) {
                    $field_create.=" PRIMARY KEY ";
                }
            }
            if(preg_match("/increment/",$field_flags)) {
                $field_create.=" AUTO_INCREMENT ";
            }
            if(preg_match("/not_null/",$field_flags)) {
                $field_create.=" NOT NULL";
            }
            $field_create = preg_replace("/  /"," ",$field_create);
            $fields[]=$field_create;

        }
        $final_output.="CREATE TABLE `$table` (\n".implode($fields,",\n");
        if(count($count_primary_fields)>1) {
            $final_output.=",\nPRIMARY KEY (`".implode($count_primary_fields,"`,`")."`)";
        }
        $final_output.="\n);\n\n";

        if($table!='issabelpbx_settings' && !preg_match("/module/",$table) && $table!='notifications' && $table!="ampusers") {
            $data = $db->getAll("SELECT * FROM $table");
            foreach($data as $idx=>$row) {
                $fields = count($row);
                $escaped = array_map('escapeDouble',$row);
                $final_output.="INSERT INTO `$table` VALUES(\"".implode($escaped,"\",\"")."\");\n";
            }
            if(count($data)>0) { $final_output.="\n";}
        }
    }
    file_put_contents("SQL/newinstall.sql",$final_output);
    die();
}

if($installdb) {
    outn("Checking state of IssabelPBX DB...");
    if(!is_array($db->tableInfo('notifications'))) {
        outn("IssabelPBX DB is empty, inserting standard rows...");
        installampimport_mysql_dump('newinstall.sql');
        installampimport_mysql_dump('cdr_mysql_table.sql',$dbcdr);
        installampimport_mysql_dump('cel_table.sql',$dbcdr);
        out("Done!");
        $final_restart = true;
    } else {
        out("IssabelPBX DB is already populated skipping");
    }
}

// **** Read DB for version info

if (!isset($version)) {
    outn("Checking current version of AMP..");
    $version = install_getversion();
    if (!$version) {
        out("no version information");
        outn("Checking version for new installation..");
        $curdir = dirname(__FILE__);
        $contents = file("$curdir/../core/module.xml");
        foreach($contents as $linea) {
            if(preg_match("/<version>(.*)<\/version>/",$linea,$matches)) {
                $version=$matches[1];
                break;
            }
        }
        out($version);
    } else {
        out($version);
    }
}

// Check if issabelpbx_settings is there and has been initialized
// if it has anything less than about 5 settings in it (and that
// is probably quite low) then something is wrong so assume it
// is not there.
//
$sql = "SELECT count(*) FROM issabelpbx_settings";
$num_settings = $db->getOne($sql);
$force_amportal_conf = DB::IsError($num_settings) || $num_settings < 5;

// **** Copy files

if ($install_files)
{
    $asteriskuser = isset($amp_conf['AMPASTERISKUSER']) && $amp_conf['AMPASTERISKUSER'] ? $amp_conf['AMPASTERISKUSER'] : 'asterisk';
    outn("Installing new IssabelPBX files..");
    $check_md5s=true;
    $md5sums = read_md5_file(UPGRADE_DIR."/".$version.".md5");
    list($num_files, $num_copied) = recursive_copy("amp_conf", "", $md5sums);
    if(!file_exists(dirname(__FILE__).'/amp_conf/htdocs/admin/modules/_cache')) {
        mkdir(dirname(__FILE__).'/amp_conf/htdocs/admin/modules/_cache',0777,true);
        chown(dirname(__FILE__).'/amp_conf/htdocs/admin/modules',$asteriskuser);
        if(!file_exists(dirname(__FILE__).'/amp_conf/htdocs/admin/modules')) {
            die("We were not able to create the local modules directory, which is important\n");
        }
    }
    if(!file_exists($amp_conf['AMPWEBROOT'].'/admin/modules/_cache')) {
        mkdir($amp_conf['AMPWEBROOT'].'/admin/modules/_cache',0777,true);
        chown($amp_conf['AMPWEBROOT'].'/admin/modules',$asteriskuser);
        if(!file_exists($amp_conf['AMPWEBROOT'].'/admin/modules')) {
            die("We were not able to create the web modules directory, which is important\n");
        }
    }
    if (!is_file("/etc/asterisk/voicemail.conf")) {  
        copy("/etc/asterisk/voicemail.conf.template","/etc/asterisk/voicemail.conf"); 
    } else {  
        exec("grep vm_email /etc/asterisk/voicemail.conf", $output, $return);
        if($return==1) {
            if(is_file("/etc/asterisk/voicemail.conf.template")) {
                unlink("/etc/asterisk/voicemail.conf");
                copy("/etc/asterisk/voicemail.conf.template","/etc/asterisk/voicemail.conf"); 
            }
        }
    }
    if (!is_dir("/var/spool/asterisk/voicemail/device")) amp_mkdir("/var/spool/asterisk/voicemail/device", "0755", true);
    out("OK (".$num_copied." files copied, ".($num_files-$num_copied)." skipped)");

}

if (!$dryrun) {
    $asteriskuser = isset($amp_conf['AMPASTERISKUSER']) && $amp_conf['AMPASTERISKUSER'] ? $amp_conf['AMPASTERISKUSER'] : 'asterisk';

    if (file_exists($amp_conf["AMPSBIN"]."/amportal")) {
        exec("chmod 755 ".$amp_conf["AMPSBIN"]."/amportal");
        outn("amportal..");
    } else {
        outn("no amportal..");
    }
    if (file_exists($amp_conf["AMPSBIN"]."/fpbx")) {
        exec("chmod 755 ".$amp_conf["AMPSBIN"]."/fpbx");
        outn("fpbx..");
    } else {
        outn("no fpbx..");
    }
    if (file_exists($amp_conf["AMPBIN"]."/issabelpbx_engine")) {
        exec("chmod 755 ".$amp_conf["AMPBIN"]."/issabelpbx_engine");
        outn("issabelpbx_engine..");
    } else {
        outn("no issabelpbx_engine..");
    }
    if (file_exists($amp_conf["AMPBIN"]."/issabelpbx_setting")) {
        exec("chmod 755 ".$amp_conf["AMPBIN"]."/issabelpbx_setting");
        outn("issabelpbx_setting..");
    } else {
        outn("no issabelpbx_setting..");
    }
    if (file_exists($amp_conf["AMPBIN"]."/gen_amp_conf.php")) {
        exec("chmod 755 ".$amp_conf["AMPBIN"]."/gen_amp_conf.php");
        outn("gen_amp_conf.php..");
    } else {
        outn("no gen_amp_conf..");
    }
    if (file_exists($amp_conf["AMPBIN"]."/retrieve_conf")) {
        exec("chmod 755 ".$amp_conf["AMPBIN"]."/retrieve_conf");
        outn("retrieve_conf.php..");
    } else {
        outn("no retrieve_conf..");
    }
    if (file_exists($amp_conf["AMPBIN"]."/module_admin")) {
        exec("chmod 755 ".$amp_conf["AMPBIN"]."/module_admin");
        outn("module_admin.php..");
    } else {
        outn("no module_admin..");
    }

    out("done");

    // Ensure UIDs are set correctly before any chowns happen
    // Note - issabelpbx_engine must be used the first time to ensure that issabelpbx.conf exists.
    exec($amp_conf["AMPBIN"]."/issabelpbx_engine admin issabelpbx_setting AMPASTERISKWEBGROUP $runas_gid");
    exec($amp_conf["AMPBIN"]."/issabelpbx_setting AMPASTERISKWEBUSER $runas_uid");
    exec($amp_conf["AMPBIN"]."/issabelpbx_setting AMPASTERISKGROUP $runas_gid");
    exec($amp_conf["AMPBIN"]."/issabelpbx_setting AMPASTERISKUSER $runas_uid");
    exec($amp_conf["AMPBIN"]."/issabelpbx_setting AMPDEVGROUP $runas_gid");
    exec($amp_conf["AMPBIN"]."/issabelpbx_setting AMPDEVUSER $runas_uid");
    exec($amp_conf["AMPBIN"]."/issabelpbx_setting ASTMANAGERHOST $asteriskip");
    // edit conf file passwords and then
    // reload manager in asterisk if it is running:
    //
    if (file_exists(dirname(__FILE__)."/apply_conf.sh")) {
        out("apply username/password changes to conf files:");
        debug("Running ".dirname(__FILE__)."/apply_conf.sh");
        $apply_conf_out = array();
        if ($force_amportal_conf) {
            out("running apply_conf.sh from " . AMP_CONF);
            putenv('FORCE_AMPORTAL_CONF=1');
            exec(dirname(__FILE__)."/apply_conf.sh ".AMP_CONF, $apply_conf_out);
            putenv('FORCE_AMPORTAL_CONF=');
        } else {
            out("running apply_conf.sh from issabelpbx_settings");
            exec(dirname(__FILE__)."/apply_conf.sh", $apply_conf_out);
        }
        foreach ($apply_conf_out as $line) {
            out($line);
        }
        unset($apply_conf_out);
        out("done with apply_conf.sh");
    }

    /* As of Asterisk 1.4.16 or there about, 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.
     */

    outn("creating missing #include files..");
    $include_err = false;
    exec("grep '#include' ".$amp_conf['ASTETCDIR']."/*.conf | sed 's/;.*//; s/#include//'",$output,$retcode);
    if ($retcode != 0) {
        out("Error code $retcode: trying to search for missing #include files");
        $include_err = true;
    }

    foreach($output as $file) {
        if (trim($file) == '') {
            continue;
        }
        $parse1 = explode(':',$file);
        if(!isset($parse1[1])) { continue; }
        $parse2 = explode(';',$parse1[1]);
        $rawfile = trim($parse2[0]);
        if(substr($rawfile,0,1)=='"' && substr($rawfile,-1)=='"') { $rawfile=substr($rawfile,1,-1); }
        if ($rawfile == '') {
            continue;
        }
        $target = ($rawfile[0] == '/') ? $rawfile : $amp_conf['ASTETCDIR']."/$rawfile";
        if(preg_match("/\*/",$target)) { continue; }

        if (!file_exists($target)) {
            exec("sudo -u $asteriskuser touch $target", $output, $retcode);
            if ($retcode != 0) {
                out("Error code $retcode: trying to create empty file $target");
                $include_err = true;
            }
        }
    }
    if (! $include_err) {
        out("OK");
    }

    change_ami_password($manager_pass);
    insert_admin_user($admin_user,$admin_pass);

    // reload manager in asterisk if it was running:
    //
    if (version_compare($asterisk_version,'1.4','ge')) {
        system("asterisk -rx 'module reload manager'");
    } else {
        system("asterisk -rx 'reload manager'"); //1.2 syntax
    }
}
out("OK");

// **** Create spool directories for monitor and fax
if (!is_dir($amp_conf["ASTSPOOLDIR"]."/monitor"))
    amp_mkdir($amp_conf["ASTSPOOLDIR"]."/monitor","0766",true);
if (!is_dir($amp_conf["ASTSPOOLDIR"]."/fax"))
    amp_mkdir($amp_conf["ASTSPOOLDIR"]."/fax","0766",true);

//Check to make sure database is installed
$sql = "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = '".$amp_conf["AMPDBNAME"]."'";
if(!$db->getOne($sql)) {
    fatal('The '. $amp_conf["AMPDBNAME"] . ' ' . $amp_conf["AMPDBENGINE"] . ' database appears empty, try running with the "--cleaninstall --installdb" commands or install the database manually');
}
// **** Set permissions all files

// tell amportal/issabelpbx_engine to use amportal.conf and not bootstrap
// if issabelpbx_settings has not been setup yet or you will get an error.
//
if ($install_files)
{
    outn("Setting permissions on files..");
    if (!$dryrun) {
        if ($force_amportal_conf) {
            putenv('FORCE_AMPORTAL_CONF=1');
        }
        exec($amp_conf["AMPSBIN"]."/amportal chown");
        if ($force_amportal_conf) {
            putenv('FORCE_AMPORTAL_CONF=');
        }
    }
    out("OK");
}

// Run through all the upgrade scripts starting at the specified version
//
upgrade_all($version);

// Save $amp_conf variables so we can set the configured values
if (($set_issabelpbx_settings && $force_amportal_conf) || (!file_exists('/etc/redhat-release')))  {
    $amp_conf_file = $amp_conf;
}
outn("Creating or updating issabelpbx_conf settings..");
issabelpbx_settings_init(true);
out("..OK");

outn("Setting manager password..");
exec($amp_conf["AMPBIN"]."/issabelpbx_setting AMPMGRPASS $manager_pass");
out("..OK");


$valid_langs = array("es_ES", "pt_BR", "bg_BG", "zh_CN", "de_DE", "fr_FR", "he_IL", "hu_HU", "it_IT", "pt_PT", "ru_RU", "sv_SE", "ja_JP");
$langs = array('ipbxLang'=>'en');
if(file_exists("/tmp/ipbx.lang")) {
    $langs=parse_ini_file("/tmp/ipbx.lang");
    $language = $langs['ipbxLang'];
}

if($language!="") {
    if(in_array($language,$valid_langs)) {
        outn("Setting language to $language...");
        $issabelpbx_conf =& issabelpbx_conf::create();
        if ($issabelpbx_conf->conf_setting_exists('LANGUAGE')) {
            $issabelpbx_conf->set_conf_values(array('LANGUAGE' => $language),true,true);
            out("..OK");
        }
    }
}

// TODO: if file is $force_amportal_conf let's go set any settings in issabelpbx_settings,
//       question is, should we do this further up???
//
if (($set_issabelpbx_settings && $force_amportal_conf) || (!file_exists('/etc/redhat-release'))) {
    out("Setting issabelpbx settings from " . AMP_CONF);
    $issabelpbx_conf =& issabelpbx_conf::create();
    foreach ($amp_conf_file as $keyword => $value) {
        if ($issabelpbx_conf->conf_setting_exists($keyword)) {
            $issabelpbx_conf->set_conf_values(array($keyword => $value),true,true);
            out("issabelpbx setting [$keyword] set to [$value]");
        } else {
            out("issabelpbx setting [$keyword] DOES NOT EXIST, can't set to [$value]");
        }
    }
} else {
    //We are here mainly because of bug #6159
    //Meaning they are installing this on CentOS manually so the above checks fail
    global $webroot;
    if(isset($webroot) && !empty($webroot) && ($webroot != $amp_conf['AMPWEBROOT'])) {
        $issabelpbx_conf =& issabelpbx_conf::create();
        outn("Noticed Irregular AMPWEBROOT setting....");
        if ($issabelpbx_conf->conf_setting_exists('AMPWEBROOT')) {
            $issabelpbx_conf->set_conf_values(array('AMPWEBROOT' => $webroot),true,true);
        }
        $amportalconf = file_get_contents('/etc/amportal.conf');
        $amportalconf = preg_replace('/AMPWEBROOT=.*/', 'AMPWEBROOT='.$webroot, $amportalconf);
        file_put_contents('/etc/amportal.conf',$amportalconf);
        out("Fixed");
    }
}

// **** Generate AMP configs
out("Generating AMP configs..");
generate_configs();
out("Generating AMP configs..OK");

$version = install_getversion();

// Now force an install for all modules that are packaged with the tarball
// directory.
//
if ($module_install && !$update_links) {
    install_modules();
    compile_gettext();
} else {
    out("bypassing packaged module installation because --skip-module-install or --update-links flag");
}

if($update_links) {
    //copy framework into installed folder if it doesnt already exist
    if(!file_exists($amp_conf['AMPWEBROOT'].'/admin/modules/framework')) {
        mkdir($amp_conf['AMPWEBROOT'].'/admin/modules/framework');
    }
    copy(__DIR__.'/module.xml',$amp_conf['AMPWEBROOT'].'/admin/modules/framework/module.xml');
}

if($install_moh) {
    $md5=array();
    out("installing music on hold files");
    $dirfrom = dirname(__DIR__)."/tgzassets/moh";
    $dirto="/moh";
    recursive_copy($dirfrom,$dirto,$md5);
    exec($amp_conf["AMPSBIN"]."/amportal chown");
}

// **** Set reload flag for AMP admin
needreload();

if ($amp_conf["AMPWEBADDRESS"])
{
    out("Please update your modules and reload Asterisk by visiting http://".$amp_conf["AMPWEBADDRESS"]."/admin",false);
}
else
{
    out("Please update your modules and reload Asterisk by browsing to your server.",false);
}

out("",false);
if($final_restart) {
    exec($amp_conf["AMPSBIN"]."/amportal a r");
    out("Install complete!",false);
} else {
    out("*************************************************************************",false);
    out("* Note: It's possible that if you click the red 'Update Now' bar BEFORE *",false);
    out("* updating your modules, your machine will start dropping calls. Ensure *",false);
    out("* that all modules are up to date BEFORE YOU CLICK THE BUTTON. As long  *",false);
    out("* as this is observed, your machine will be fully functional whilst the *",false);
    out("* upgrade is in progress.                                               *",false);
    out("*************************************************************************",false);
}

// vim: set ts=4 sw=4 : //
// Ensure you 'set modeline' in your ~/.vimrc to activate this //
?>
