updated on Tue Jan 10 12:02:00 UTC 2012
[aur-mirror.git] / freepbx / install_amp
blob89234b5faa2609c01fc4fa42b6c8d48269b84025
1 #!/usr/bin/php -q
2 <?php
4 ini_set ("open_basedir", "/");
5 require_once ("libfreepbx.install.php");
7 # constants
8 define("AMP_CONF", "/etc/amportal.conf");
9 define("ASTERISK_CONF", "/etc/asterisk/asterisk.conf");
10 define("UPGRADE_DIR", dirname(__FILE__)."/upgrades");
11 define("MODULE_DIR", dirname(__FILE__)."/amp_conf/htdocs/admin/modules/");
13 # semi constants
14 $webroot = "/srv/http";
15 $fopwebroot = ""; // if blank, will use $webroot/panel
16 $ampsbin_dir = "/usr/sbin"; // default if not set
17 $ampbin_dir = "/usr/bin";
18 $asterisk_user = "asterisk";
19 $asterisk_pass = "amp109";
23 freepbx versions
24 '1.10.005',
25 '1.10.006',
26 '1.10.007beta1',
27 '1.10.007beta2',
28 '1.10.007',
29 '1.10.007a',
30 '1.10.008beta1',
31 '1.10.008beta2',
32 '1.10.008beta3',
33 '1.10.008',
34 '1.10.009beta1',
35 '1.10.009beta2',
36 '1.10.009',
37 '1.10.010beta1',
38 '1.10.010',
39 '2.0beta1',
40 '2.0beta2',
41 '2.0beta3',
42 '2.0beta4',
43 '2.0beta5',
44 '2.0.0',
45 '2.0.1',
46 '2.1beta1',
47 '2.1beta2',
48 '2.1beta3',
49 '2.1.0',
50 '2.1.1',
51 '2.1.2',
52 '2.1.3',
53 '2.2.0beta1',
54 '2.2.0beta2',
55 '2.2.0beta3',
56 '2.2.0rc1',
57 '2.2.0rc2',
58 '2.2.0rc3',
59 '2.2.0',
60 '2.2.1',
61 '2.2.2',
62 '2.2.3',
63 '2.3.0beta1',
66 /********************************************************************************************************************/
68 function out($text) {
69 echo $text."\n";
72 function outn($text) {
73 echo $text;
76 function error($text) {
77 echo "[ERROR] ".$text."\n";
80 function fatal($text) {
81 echo "[FATAL] ".$text."\n";
82 exit(1);
85 function debug($text) {
86 global $debug;
88 if ($debug) echo "[DEBUG-preDB] ".$text."\n";
91 if (!function_exists('version_compare_freepbx')) {
92 /* verison_compare that works with freePBX version numbers
94 function version_compare_freepbx($version1, $version2, $op = null) {
95 $version1 = str_replace("rc","RC", strtolower($version1));
96 $version2 = str_replace("rc","RC", strtolower($version2));
97 if (!is_null($op)) {
98 return version_compare($version1, $version2, $op);
99 } else {
100 return version_compare($version1, $version2);
105 function showHelp() {
106 out("Optional parameters:");
107 out(" --help, -h, -? Show this help");
108 out(" --dbhost <ip address> Use a remote database server");
109 out(" --dbname databasename Use database name specified, instead of 'asterisk'");
110 out(" --username <user> Use <user> to connect to db and write config");
111 out(" --password <pass> Use <pass> to connect to db and write config");
112 out(" --fopwebroot <path> Web path where fop will be installed");
113 out(" --webroot <path> Web root where freepbx will be installed");
114 out(" --cgibin <path> Path where cgi-bin's lives");
115 out(" --bin <path> Path of asterisk binaries");
116 out(" --sbin <path> Path of system admin binaries");
117 out(" --asteriskuser <user> Asterisk Manager username");
118 out(" --asteriskpass <pass> Asterisk Manager password");
119 out(" --systemconfig <path> System config files");
120 out(" --debug Enable debug output");
121 out(" --dry-run Don't actually do anything");
122 out(" --force-version <ver> Force upgrade from version <ver>");
123 out(" --skip-module-install Don't run install scripts for packaged modules, the files are still loaded.");
124 out(" In a development environment you may not want the install scripts run.");
125 out(" --no-files Just run updates without installing files");
126 out(" --install-moh Install default music-on-hold files (normally doesn't, unless ");
127 out(" it's a new installation)");
128 out(" --install-fop=false Don't install FOP and don't display it anywhere on the interface");
129 //out(" --make-links-devel Make links to files in the source directory instead of copying");
130 //out(" (intended for developers only)");
131 out(" --my-svn-is-correct Ignore Asterisk version, assume it is correct");
132 out(" --engine <name> Use the specified PBX Engine ('asterisk', 'asterisk14' or 'openpbx')");
135 function install_parse_amportal_conf($filename) {
136 $file = file($filename);
137 foreach ($file as $line) {
138 if (preg_match("/^\s*([a-zA-Z0-9]+)\s*=\s*(.*)\s*([;#].*)?/",$line,$matches)) {
139 $conf[ $matches[1] ] = $matches[2];
143 // use same defaults as function.inc.php
144 if ( !isset($conf["AMPDBENGINE"]) || ($conf["AMPDBENGINE"] == "")) {
145 $conf["AMPDBENGINE"] = "mysql";
148 if ( !isset($conf["AMPDBNAME"]) || ($conf["AMPDBNAME"] == "")) {
149 $conf["AMPDBNAME"] = "asterisk";
152 if ( !isset($conf["AMPENGINE"]) || ($conf["AMPENGINE"] == "")) {
153 $conf["AMPENGINE"] = "asterisk";
156 return $conf;
159 function install_parse_asterisk_conf($filename) {
160 $file = file($filename);
161 foreach ($file as $line) {
162 if (preg_match("/^\s*([a-zA-Z0-9]+)\s* => \s*(.*)\s*([;#].*)?/",$line,$matches)) {
163 $conf[ $matches[1] ] = $matches[2];
166 // Now set defaults if not set (although asterisk should fail if not set but at least
167 // it will get the setup somewhat right
169 if (!isset($asterisk_conf['astetcdir'])) { $asterisk_conf['astetcdir'] = "/etc/asterisk"; }
170 if (!isset($asterisk_conf['astmoddir'])) { $asterisk_conf['astmoddir'] = "/usr/lib/asterisk/modules"; }
171 if (!isset($asterisk_conf['astvarlibdir'])) { $asterisk_conf['astvarlibdir'] = "/var/lib/asterisk"; }
172 if (!isset($asterisk_conf['astagidir'])) { $asterisk_conf['astagidir'] = "/var/lib/asterisk/agi-bin"; }
173 if (!isset($asterisk_conf['astspooldir'])) { $asterisk_conf['astspooldir'] = "/var/spool/asterisk"; }
174 if (!isset($asterisk_conf['astrundir'])) { $asterisk_conf['astrundir'] = "/var/run/asterisk"; }
175 if (!isset($asterisk_conf['astlogdir'])) { $asterisk_conf['astlogdir'] = "/var/log/asterisk"; }
177 return $conf;
180 function write_amportal_conf($filename, $conf) {
181 $file = file($filename);
182 // parse through the file
183 foreach (array_keys($file) as $key) {
184 if (preg_match("/^\s*([a-zA-Z0-9]+)\s*=\s*(.*)\s*([;#].*)?/",$file[$key],$matches)) {
185 // this is an option=value line
186 if (isset($conf[ $matches[1] ])) {
187 // rewrite the line, if we have this in $conf
188 $file[$key] = $matches[1]."=".$conf[ $matches[1] ]."\n";
189 // unset it so we know what's new
190 unset($conf[ $matches[1] ]);
195 // add new entries
196 foreach ($conf as $key=>$val) {
197 $file[] = $key."=".$val."\n";
200 // write the file
201 if (!$fd = fopen($filename, "w")) {
202 fatal("Could not open ".$filename." for writing");
204 fwrite($fd, implode("",$file));
205 fclose($fd);
208 function ask_overwrite($file1, $file2) {
209 global $check_md5s;
210 do {
211 out($file2." has been changed from the original version.");
212 outn("Overwrite (y=yes/a=all/n=no/d=diff/s=shell/x=exit)? ");
213 $key = fgets(STDIN,1024);
214 switch (strtolower($key[0])) {
215 case "y": return true;
216 case "a": $check_md5s=false; return true;
217 case "n": return false;
218 case "d":
219 out("");
220 // w = ignore whitespace, u = unified
221 passthru("diff -wu ".escapeshellarg($file2)." ".escapeshellarg($file1));
222 break;
223 case "s":
224 if (function_exists("pcntl_fork")) {
225 out("");
226 $shell = (isset($_ENV["SHELL"]) ? $_ENV["SHELL"] : "/bin/bash");
227 out("Dropping to shell. Type 'exit' to return");
228 out("-> Original file: ".$file2);
229 out("-> New file: ".$file1);
231 $pid = pcntl_fork();
232 if ($pid == -1) {
233 out("[ERROR] cannot fork");
234 } else if ($pid) {
235 // parent
236 pcntl_waitpid($pid, $status);
237 // we wait till the child exits/dies/whatever
238 } else {
239 pcntl_exec($shell, array(), $_ENV);
242 out("Returned from shell");
243 } else {
244 out("[ERROR] PHP not built with process control (--enable-pcntl) support: cannot spawn shell");
247 break;
248 case "x":
249 out("-> Original file: ".$file2);
250 out("-> New file: ".$file1);
251 out("Exiting install program.");
252 exit(1);
253 break;
255 out("");
256 } while(1);
259 /** Write AMP-generated configuration files
261 function generate_configs() {
262 global $amp_conf;
263 global $dryrun;
264 global $debug;
266 out("Generating Configurations.conf, (if Asterisk is not running, you will get an error");
267 out("In case of error, start Asterisk and hit the red bar in the GUI to generate the Configuraions.conf files");
268 if (!$dryrun)
269 // added --run-install to make it work like it has been working since retrieve_conf changed to not run module install scripts by default
272 // TODO: Should check if Asterisk is running and/or try to start it.
274 passthru("su - asterisk -c \"".trim($amp_conf["AMPBIN"])."/retrieve_conf --run-install ".($debug ? ' --debug' : '').'"');
278 /** Set reload flag for AMP admin
280 function install_needreload() {
281 global $db;
282 $sql = "UPDATE admin SET value = 'true' WHERE variable = 'need_reload'";
283 $result = $db->query($sql);
284 if(DB::IsError($result)) {
285 die($result->getMessage());
290 /** Collect AMP settings
292 function collect_settings($filename, $dbhost = '', $dbuser = '', $dbpass = '', $dbname = 'asterisk') {
293 global $webroot;
294 global $fopwebroot;
295 global $ampsbin_dir;
296 global $ampbin_dir;
297 global $asterisk_user;
298 global $asterisk_pass;
300 out("Creating new $filename");
302 outn("Enter your USERNAME to connect to the '$dbname' database:\n [".($dbuser ? $dbuser : $asterisk_user) . "] ");
303 $key = trim(fgets(STDIN,1024));
304 if (preg_match('/^$/',$key))
305 $amp_conf["AMPDBUSER"] = ($dbuser ? $dbuser : $asterisk_user);
306 else
307 $amp_conf["AMPDBUSER"] = $key;
309 outn("Enter your PASSWORD to connect to the '$dbname' database:\n [".($dbpass ? $dbpass : $asterisk_pass)."] ");
310 $key = trim(fgets(STDIN,1024));
311 if (preg_match('/^$/',$key))
312 $amp_conf["AMPDBPASS"] = ($dbpass ? $dbpass : $asterisk_pass);
313 else
314 $amp_conf["AMPDBPASS"] = $key;
316 outn("Enter the hostname of the '$dbname' database:\n [".($dbhost ? $dbhost : "localhost")."] ");
317 $key = trim(fgets(STDIN,1024));
318 if (preg_match('/^$/',$key))
319 $amp_conf["AMPDBHOST"] = ($dbhost ? $dbhost : "localhost");
320 else
321 $amp_conf["AMPDBHOST"] = $key;
323 outn("Enter a USERNAME to connect to the Asterisk Manager interface:\n [admin] ");
324 $key = trim(fgets(STDIN,1024));
325 if (preg_match('/^$/',$key)) $amp_conf["AMPMGRUSER"] = "admin";
326 else $amp_conf["AMPMGRUSER"] = $key;
328 outn("Enter a PASSWORD to connect to the Asterisk Manager interface:\n [amp111] ");
329 $key = trim(fgets(STDIN,1024));
330 if (preg_match('/^$/',$key)) $amp_conf["AMPMGRPASS"] = "amp111";
331 else $amp_conf["AMPMGRPASS"] = $key;
333 do {
334 out("Enter the path to use for your AMP web root:\n [$webroot] ");
335 $key = trim(fgets(STDIN,1024));
336 if (preg_match('/^$/',$key))
337 $amp_conf["AMPWEBROOT"] = "$webroot";
338 else
339 $amp_conf["AMPWEBROOT"] = rtrim($key,'/');
341 if (is_dir($amp_conf["AMPWEBROOT"])) {
342 break;
343 } else if (amp_mkdir($amp_conf["AMPWEBROOT"],"0755",true)){
344 out("Created ".$amp_conf["AMPWEBROOT"]);
345 break;
346 } else {
347 fatal("Cannot create ".$amp_conf["AMPWEBROOT"]."!");
349 } while(1);
351 // Really no need to ask, is there.
352 if (empty($fopwebroot))
353 $amp_conf["FOPWEBROOT"] = $amp_conf["AMPWEBROOT"]."/panel";
354 else
355 $amp_conf["FOPWEBROOT"] = $fopwebroot;
357 outn("Enter the IP ADDRESS or hostname used to access the AMP web-admin:\n [xx.xx.xx.xx] ");
358 $key = trim(fgets(STDIN,1024));
359 if (preg_match('/^$/',$key)) $amp_conf["AMPWEBADDRESS"] = "xx.xx.xx.xx";
360 else $amp_conf["AMPWEBADDRESS"] = $key;
362 outn("Enter a PASSWORD to perform call transfers with the Flash Operator Panel:\n [passw0rd] ");
363 $key = trim(fgets(STDIN,1024));
364 if (preg_match('/^$/',$key)) $amp_conf["FOPPASSWORD"] = "passw0rd";
365 else $amp_conf["FOPPASSWORD"] = $key;
367 outn("Use simple Extensions [extensions] admin or separate Devices and Users [deviceanduser]?\n [extensions] ");
368 $key = trim(fgets(STDIN,1024));
369 if (preg_match('/^$/',$key)) $amp_conf["AMPEXTENSIONS"] = "extensions";
370 else $amp_conf["AMPEXTENSIONS"] = $key;
372 do {
373 out("Enter directory in which to store AMP executable scripts:\n [$ampbin_dir] ");
374 $key = trim(fgets(STDIN,1024));
375 if (preg_match('/^$/',$key))
376 $amp_conf["AMPBIN"] = $ampbin_dir;
377 else
378 $amp_conf["AMPBIN"] = rtrim($key,'/');
380 if (is_dir($amp_conf["AMPBIN"])) {
381 break;
382 } else if (amp_mkdir($amp_conf["AMPBIN"],"0755",true)){
383 out("Created ".$amp_conf["AMPBIN"]);
384 break;
385 } else {
386 fatal("Cannot create ".$amp_conf["AMPBIN"]."!");
388 } while(1);
390 do {
391 out("Enter directory in which to store super-user scripts:\n [$ampsbin_dir] ");
392 $key = trim(fgets(STDIN,1024));
393 if (preg_match('/^$/',$key))
394 $amp_conf["AMPSBIN"] = "$ampsbin_dir";
395 else
396 $amp_conf["AMPSBIN"] = rtrim($key,'/');
398 if (is_dir($amp_conf["AMPSBIN"])) {
399 break;
400 } else if (amp_mkdir($amp_conf["AMPSBIN"],"0755",true)){
401 out("Created ".$amp_conf["AMPSBIN"]);
402 break;
403 } else {
404 fatal("Cannot create ".$amp_conf["AMPSBIN"]."!");
406 } while(1);
408 // write amportal.conf
409 write_amportal_conf($filename, $amp_conf);
410 outn(AMP_CONF." written");
413 /** Set base of packaged modules to the versions packaged in the tarball since they are
414 * getting overwritten with the tarball from anything that may have been updated online.
417 function set_base_version() {
418 global $dryrun;
420 // read modules list from MODULE_DIR
422 $included_modules = array();
423 $dir = opendir(MODULE_DIR);
424 while ($file = readdir($dir)) {
425 if ($file[0] != "." && $file[0] != "_" && is_dir(MODULE_DIR."/".$file)) {
426 $included_modules[] = $file;
429 closedir($dir);
431 foreach ($included_modules as $up_module) {
432 outn("Checking $up_module.. ");
433 if (!$dryrun) {
434 out(set_module_version($up_module));
435 } else {
436 out("Dry Run Not Updated");
441 /** Install all modules packaged with the install. We use the force flag because the
442 * the assumption is that the dependencies are met and the package is able to have
443 * the modules installed.
445 function install_modules() {
446 global $dryrun;
447 global $amp_conf;
449 // read modules list from MODULE_DIR
451 $included_modules = array();
452 $dir = opendir(MODULE_DIR);
453 while ($file = readdir($dir)) {
454 if ($file[0] != "." && $file[0] != "_" && is_dir(MODULE_DIR."/".$file)) {
455 $included_modules[] = $file;
458 closedir($dir);
460 foreach ($included_modules as $up_module) {
461 outn("Checking $up_module.. ");
462 if (!$dryrun) {
463 // special case framework, it should not be installed just enabled.
465 if ($up_module != 'framework') {
466 system($amp_conf['AMPBIN']."/module_admin --no-warnings -f install $up_module");
467 system($amp_conf['AMPBIN']."/module_admin --no-warnings -f enable $up_module");
468 out("installed");
469 } else {
470 system($amp_conf['AMPBIN']."/module_admin --no-warnings -f enable $up_module");
471 out("enabled");
473 } else {
474 out("Dry Run Not Installed");
479 /** Set the module version number to the packaged version and enable
480 * module must require not install.php or install.sql script
481 * this is primarily to package core and framework with freepbx tarballs
484 function set_module_version($module) {
485 global $db;
487 $module_dir = MODULE_DIR;
488 $file_path = $module_dir.$module."/module.xml";
489 if (file_exists($file_path)) {
490 // TODO: this is bad, there are other version tags (depends on) but this
491 // is equivalnet to what publish.pl does, so it expects this to be
492 // at the top.
494 $module_xml = file_get_contents($file_path);
495 if (preg_match('/<version>(.+)<\/version>/', $module_xml, $matches)) {
496 $version = $matches[1];
497 } else {
498 fatal("ERROR: $file_path found but no verison information");
500 } else {
501 return "not packaged, no updating needed";
504 // If we didn't return above, then we found the package as part of the install
505 // tarball and want to update the version info since this might be overwriting
506 // an existing install that has a newever version.
508 $sql = "SELECT version FROM modules WHERE modulename = '$module'";
509 $result = $db->getCol($sql);
510 if(DB::IsError($result)) {
511 fatal("error accessing version table: ".$result->getMessage());
513 $sql = "";
514 if (count($result) == 0) {
515 // insert but disable as we have to first run install scripts which come later
516 $sql = "INSERT INTO modules (modulename, version, enabled) VALUES ('$module', '$version', 0)";
517 } else if ($result[0] != $version) {
518 if (version_compare_freepbx($version, $result[0], "gt")) {
519 // if new verison is greater than old, then we disable the module and it will get enabled next when installed
521 $sql = "UPDATE modules SET version = '$version', enabled = 0 WHERE modulename = '$module'";
522 } else {
523 // if new version is equal to or less than old, then we leave it in the enable/disable state it was in but just
524 // reset the version number.
526 $sql = "UPDATE modules SET version = '$version' WHERE modulename = '$module'";
529 if ($sql) {
530 debug($sql);
531 $result = $db->query($sql);
532 if(DB::IsError($result)) {
533 fatal("error writing to version table: ".$result->getMessage());
535 return "updated to $version";
536 } else {
537 return "already at $version";
541 /********************************************************************************************************************/
543 // **** Make sure we have STDIN etc
545 // from ben-php dot net at efros dot com at php.net/install.unix.commandline
546 if (version_compare(phpversion(),'4.3.0','<') || !defined("STDIN")) {
547 define('STDIN',fopen("php://stdin","r"));
548 define('STDOUT',fopen("php://stdout","r"));
549 define('STDERR',fopen("php://stderr","r"));
550 register_shutdown_function( create_function( '' , 'fclose(STDIN); fclose(STDOUT); fclose(STDERR); return true;' ) );
553 // **** Make sure we have PEAR's DB.php, and include it
555 outn("Checking for PEAR DB..");
556 if (! @ include('DB.php')) {
557 out("FAILED");
558 fatal("PEAR must be installed (requires DB.php). Include path: ".ini_get("include_path"));
560 out("OK");
562 // **** Make sure we have PEAR's GetOpts.php, and include it
564 outn("Checking for PEAR Console::Getopt..");
565 if (! @ include("Console/Getopt.php")) {
566 out("FAILED");
567 fatal("PEAR must be installed (requires Console/Getopt.php). Include path: ".ini_get("include_path"));
569 out("OK");
571 // **** Parse out command-line options
572 $shortopts = "h?u:p:";
573 $longopts = array("help","debug","dry-run","username=","password=","force-version=","dbhost=","no-files","dbname=","my-svn-is-correct","engine=","webroot=","install-moh","install-fop","make-links-devel","skip-module-install");
575 $args = Console_Getopt::getopt(Console_Getopt::readPHPArgv(), $shortopts, $longopts);
576 if (is_object($args)) {
577 // assume it's PEAR_ERROR
578 out($args->message);
579 exit(255);
582 $debug = false;
583 $dryrun = false;
584 $install_files = true;
585 $override_astvers = false;
587 $install_moh = false;
588 $install_fop = true;
589 $make_links = false;
590 $module_install = true;
592 //initialize variables to avoid php notices
593 $dbhost = null;
594 $dbname = null;
595 $new_username = null;
596 $new_password = null;
598 foreach ($args[0] as $arg) {
599 switch ($arg[0]) {
600 case "--help": case "h": case "?":
601 showHelp();
602 exit(10);
603 break;
604 case "--dry-run":
605 out("Dry-run only, nothing will be changed");
606 $dryrun = true;
607 break;
608 case "--debug":
609 $debug = true;
610 debug("Debug mode enabled");
611 break;
612 case "--username": case "u":
613 out("Using username: ".$arg[1]);
614 $new_username = $arg[1];
615 break;
616 case "--password": case "p":
617 out("Using password: ".str_repeat("*",strlen($arg[1])));
618 $new_password = $arg[1];
619 break;
620 case "--force-version":
621 $version = $arg[1];
622 out("Forcing upgrade from version ".$version);
623 break;
624 case "--dbhost":
625 $dbhost = $arg[1];
626 out("Using remote database server at ".$dbhost);
627 break;
628 case "--dbname":
629 $dbname = $arg[1];
630 out("Using database ".$dbname);
631 break;
632 case "--no-files":
633 $install_files = false;
634 out("Running upgrade only, without installing files.");
635 break;
636 case "--my-svn-is-correct":
637 $override_astvers = true;
638 break;
639 case "--engine":
640 if ($arg[1] != 'asterisk' && $arg[1] != 'asterisk14' && $arg[1] != 'openpbx') {
641 fatal('Currently only "asterisk", "asterisk14" or "openpbx" are supported as a PBX engine');
643 $pbx_engine = $arg[1];
644 break;
645 case "--install-moh":
646 $install_moh = true;
647 break;
648 case "--install-fop":
649 if($arg[1] != "false") {
650 $install_fop = true;
651 out("FOP will be installed and activated.");
653 else {
654 out("FOP will be deactivated in the interface. Set FOPDISABLE=false in amportal.conf to change later.");
658 break;
659 case "--make-links-devel":
660 $make_links = true;
661 break;
662 case "--skip-module-install":
663 $module_install = false;
664 break;
665 case "--fopwebroot":
666 $fopwebroot = $arg[1];
667 out("Using fop at ".$fopwebroot);
668 break;
669 case "--webroot":
670 $webroot = $arg[1];
671 out("Using Webroot at ".$webroot);
672 break;
673 case "--cgibin":
674 $cgibin = $arg[1];
675 out("Using CGI-BIN at ".$cgibin);
676 break;
677 case "--bin":
678 $ampbin_dir = $arg[1];
679 out("Using bin at ".$ampbin_dir);
680 break;
681 case "--sbin":
682 $ampsbin_dir = $arg[1];
683 out("Using sbin ar ".$ampsbin_dir);
684 break;
685 case "--asteriskuser":
686 $asterisk_user = $arg[1];
687 out("Using Asterisk user ".$asterisk_user);
688 break;
689 case "--asteriskpass":
690 $asterisk_pass = $arg[1];
691 out("Using asteriskpass ".str_repeat("*",strlen($arg[1])));
692 break;
694 /* do we need this ?
695 case "--systemconfig":
696 $systemconfig = $arg[1];
697 out("Using system config at ". $systemconfig);
698 break;
705 // **** Look for user = root
707 outn("Checking user..");
708 //$current_user=(isset($_ENV["USER"]) ? $_ENV["USER"] : exec('whoami',$output));
709 $euid = (posix_getpwuid(posix_geteuid()));
710 $current_user = $euid['name'];
711 if ($current_user != "root"){
712 out("FAILED");
713 fatal($argv[0]." must be run as root");
715 out("OK");
718 outn("Checking if Asterisk is running..");
719 exec("pidof asterisk", $pid_val, $ret);
720 if ($ret) {
721 out("FAILED");
722 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'");
724 out("running with PID: ".$pid_val[0]."..OK");
726 // **** Check for amportal.conf, create if necessary
728 outn("Checking for ".AMP_CONF."..");
729 if (!file_exists(AMP_CONF)) {
730 out(AMP_CONF." does not exist, copying default");
731 copy("amportal.conf", AMP_CONF);
733 // this file contains password and should not be a+r
734 // this addresses http://freepbx.org/trac/ticket/1878
735 chown(AMP_CONF, "asterisk");
736 chgrp(AMP_CONF, "asterisk");
737 chmod(AMP_CONF, 0640);
739 collect_settings(AMP_CONF, $dbhost, $new_username, $new_password, 'asterisk');
741 out("Assuming new install, --install-moh added to command line");
742 $install_moh = true;
744 out("OK");
746 // **** read amportal.conf
748 outn("Reading ".AMP_CONF."..");
749 $amp_conf = install_parse_amportal_conf(AMP_CONF);
750 if (count($amp_conf) == 0) {
751 fatal("FAILED");
753 out("OK");
755 // Ensure our "critical" variables are set. We absolutely need these to copy in files.
757 if (!array_key_exists("AMPWEBROOT",$amp_conf)) {
758 out("Adding AMPWEBROOT option to amportal.conf - using AMP default");
759 $amp_conf["AMPWEBROOT"] = "/var/www/html";
762 if (!array_key_exists("FOPWEBROOT",$amp_conf)) {
763 out("Adding FOPWEBROOT option to amportal.conf - using AMP default");
764 $amp_conf["FOPWEBROOT"] = $amp_conf["AMPWEBROOT"]."/panel";
767 if (!array_key_exists("AMPBIN",$amp_conf)) {
768 out("Adding AMPBIN option to amportal.conf - using AMP default");
769 $amp_conf["AMPBIN"] = "/var/lib/asterisk/bin";
772 if (!array_key_exists("AMPSBIN",$amp_conf)) {
773 out("Adding AMPSBIN option to amportal.conf - using AMP default");
774 $amp_conf["AMPSBIN"] = "/usr/sbin";
777 if (!array_key_exists("AMPDBENGINE",$amp_conf)) {
778 out("Adding AMPDBENGINE option to amportal.conf - using AMP default");
779 $amp_conf["AMPDBENGINE"] = "mysql";
781 if (!array_key_exists("AMPDBNAME",$amp_conf)) {
782 out("Adding AMPDBNAME option to amportal.conf - using AMP default");
783 $amp_conf["AMPDBNAME"] = "asterisk";
786 if (isset($new_username)) {
787 $amp_conf["AMPDBUSER"] = $new_username;
790 if (isset($new_password)) {
791 $amp_conf["AMPDBPASS"] = $new_password;
794 if (isset($dbhost)) {
795 $amp_conf["AMPDBHOST"] = $dbhost;
798 if (isset($dbname)) {
799 $amp_conf["AMPDBNAME"] = $dbname;
801 if(!$install_fop) { // Set from --install-fop parameter; Add it to amportal.conf
802 out("Adding FOPDISABLE option to amportal.conf");
803 $amp_conf["FOPDISABLE"] = "true";
805 // If they pre-set this in their amportal.conf or this is an upgrade, we should honor it as well
807 if (isset($amp_conf['FOPDISABLE']) && (strtolower(trim($amp_conf['FOPDISABLE'])) == 'true' || strtolower(trim($amp_conf['FOPDISABLE'])) == 'yes' || strtolower(trim($amp_conf['FOPDISABLE'])) == 'y') ) {
808 $install_fop = false;
810 // write amportal.conf
811 write_amportal_conf(AMP_CONF, $amp_conf);
813 // **** Check for amportal.conf, create if necessary
815 outn("Checking for ".ASTERISK_CONF."..");
816 if (!file_exists(ASTERISK_CONF)) {
817 out(ASTERISK_CONF." does not exist, copying default");
818 copy("asterisk.conf", ASTERISK_CONF);
820 out("OK");
822 // **** read asterisk.conf
824 outn("Reading ".ASTERISK_CONF."..");
825 $asterisk_conf = install_parse_asterisk_conf(ASTERISK_CONF);
826 if (count($asterisk_conf) == 0) {
827 fatal("FAILED. Have you installed Asterisk?");
829 out("OK");
831 /* deprecated on freepbx 2.2, from now pages need to read this information
832 from $asterik_conf and not $amp_conf.
834 this code will stay in 2.2, but in 2.3 it will be gone. developers - please
835 update your code
837 if (isset($asterisk_conf['astetcdir'])) { $amp_conf['ASTETCDIR'] = $asterisk_conf['astetcdir']; }
838 if (isset($asterisk_conf['astmoddir'])) { $amp_conf['ASTMODDIR'] = $asterisk_conf['astmoddir']; }
839 if (isset($asterisk_conf['astvarlibdir'])) { $amp_conf['ASTVARLIBDIR'] = $asterisk_conf['astvarlibdir']; }
840 if (isset($asterisk_conf['astagidir'])) { $amp_conf['ASTAGIDIR'] = $asterisk_conf['astagidir']; }
841 if (isset($asterisk_conf['astspooldir'])) { $amp_conf['ASTSPOOLDIR'] = $asterisk_conf['astspooldir']; }
842 if (isset($asterisk_conf['astrundir'])) { $amp_conf['ASTRUNDIR'] = $asterisk_conf['astrundir']; }
843 if (isset($asterisk_conf['astlogdir'])) { $amp_conf['ASTLOGDIR'] = $asterisk_conf['astlogdir']; }
845 if (!isset($pbx_engine)) { $pbx_engine='asterisk'; }
846 out("Using $pbx_engine as PBX Engine");
847 $amp_conf["AMPENGINE"]=$pbx_engine;
849 write_amportal_conf(AMP_CONF, $amp_conf);
852 // **** Write asterisk version to ASTETCDIR/version
854 $tmpoutput = '';
855 $tmpout = exec("asterisk -V", $tmpoutput, $exitcode);
856 if ($exitcode != 0) {
857 fatal("Error executing asterisk: be sure Asterisk is installed and in the path");
859 if (!$fd = fopen($amp_conf['ASTETCDIR'].'/version','w')) {
860 fatal('Cannot open '.$amp_conf['ASTETCDIR'].'/version for writing');
862 fwrite($fd, $tmpout);
863 fclose($fd);
864 // change to read-only
865 chmod($amp_conf['ASTETCDIR'].'/version',0444);
868 // normally this would be the contents of ASTETCDIR/version, but this is for simplicity, as we just read it above
869 $verinfo = $tmpout;
871 // **** Check asterisk verison
872 // Set the 'engine' to be 'asterisk14' if using asterisk 1.4, otherwise
873 // 'asterisk'
874 outn("Checking for Asterisk version..");
875 if ((preg_match('/^Asterisk (\d+(\.\d+)*)(-?(.*))$/', $verinfo, $matches)) ||
876 (preg_match('/^Asterisk SVN-(\d+(\.\d+)*)(-?(.*))$/', $verinfo, $matches))) {
878 if ((version_compare($matches[1], "1.2") < 0)) {
879 fatal("Asterisk 1.2, 1.4, or 1.6 is required for this version of FreePBX. Detected version is: ".$matches[1]);
881 if (version_compare($matches[1], "1.7", "ge")) {
882 fatal("Asterisk 1.2, 1.4, or 1.6 is required for this version of FreePBX. Detected version is: ".$matches[1]);
884 out("{$matches[1]}");
886 } elseif (preg_match('/^Asterisk ([ABC]\.\d+(\.\d+)*)(-?(.*))$/', $verinfo, $matches)) {
887 if (substr($matches[1], 0, 1) == "A") {
888 fatal("Asterisk Business Edition B or C is required for this version of FreePBX. Detected version is: ".$matches[1]);
890 out("{$matches[1]}");
892 } elseif (preg_match('/^Asterisk SVN.+/', $verinfo)) {
893 out("FAIL");
894 out("*** WARNING ***");
895 out("You are not using a released version of Asterisk. We are unable to verify");
896 out("that your Asterisk version is compatible with FreePBX. Whilst this probably");
897 out("won't cause any problems, YOU NEED TO BE CERTAIN that it is compatible");
898 out("with at least the released Asterisk version 1.2" );
899 if ($override_astvers==false) {
900 out("If you are SURE that this is compatible, you can re-run ".$argv[0]." with");
901 out("the parameter --my-svn-is-correct");
902 exit;
903 } else {
904 out("--my-svn-is-correct specified, continuing");
906 } else {
907 fatal("Could not determine asterisk version (got: \"".$verinfo."\" please report this)");
910 // **** Make sure selinux isn't enabled
912 outn("Checking for selinux..");
913 $tmpoutput;
914 $tmpout = exec("getenforce", $tmpoutput, $sereturn);
915 if (strtolower($tmpoutput[0]) === "enabled") {
916 // this method seems better because disabled and premissive are the same
917 // if a user installs and realizes selinux is running the other method
918 // requires a reboot to get selinuxenabled to work after editing the selinux config
919 // this will allow you to use setenforce 0 which turns selinux into premissive mode which
920 // doesnt enforce, it just warns.
921 fatal("selinux is ENABLED. This is not supported. Please disable selinux before using FreePBX");
923 out("OK");
925 // **** Connect to database
927 outn("Connecting to database..");
929 $db_engine = $amp_conf["AMPDBENGINE"];
930 if ($db_engine != "sqlite3") {
931 $db_user = $amp_conf["AMPDBUSER"];
932 $db_pass = $amp_conf["AMPDBPASS"];
933 $db_host = $amp_conf["AMPDBHOST"];
935 $db_name = $amp_conf["AMPDBNAME"];
937 // we still support older configurations, and fall back
938 // into mysql when no other engine is defined
939 if ($db_engine == "")
941 $db_engine = "mysql";
944 switch ($db_engine)
946 case "pgsql":
947 case "mysql":
948 // datasource in in this style: dbengine://username:password@host/database
949 if (!function_exists($db_engine.'_connect')) {
950 out("FAILED");
951 fatal($db_engine." PHP libraries not installed");
954 $datasource = $db_engine.'://'.$db_user.':'.$db_pass.'@'.$db_host.'/'.$db_name;
955 $db = DB::connect($datasource); // attempt connection
956 break;
958 case "sqlite":
959 die_freepbx("SQLite2 support is deprecated. Please use sqlite3 only.");
960 break;
962 case "sqlite3":
963 if (!isset($amp_conf["AMPDBFILE"]))
964 die("You must setup properly AMPDBFILE in /etc/amportal.conf");
966 if (isset($amp_conf["AMPDBFILE"]) == "")
967 die("AMPDBFILE in /etc/amportal.conf cannot be blank");
969 /* on centos this extension is not loaded by default */
970 if (! extension_loaded('sqlite3.so') && ! extension_loaded('SQLITE3'))
971 dl('sqlite3.so');
973 if (! @require_once('DB/sqlite3.php') )
975 out("FAILED");
976 fatal( "Your PHP installation has no PEAR/SQLite3 support. Please install php-sqlite3 and php-pear.");
979 $datasource = "sqlite3:///" . $amp_conf["AMPDBFILE"] . "?mode=0666";
980 $db = DB::connect($datasource);
981 break;
983 default:
984 die( "Unknown SQL engine: [$db_engine]");
987 if(DB::isError($db)) {
988 out("FAILED");
989 debug($db->userinfo);
990 out("Try running ".$argv[0]." --username=user --password=pass (using your own user and pass)");
991 fatal("Cannot connect to database");
994 out("OK");
997 // **** Read DB for version info
999 if (!isset($version)) {
1000 outn("Checking current version of AMP..");
1001 $version = install_getversion();
1002 if (!$version) {
1003 out("no version information");
1004 out("Assuming new installation");
1005 } else {
1006 out($version);
1011 // **** Copy files
1013 if ($install_files)
1015 outn("Installing new FreePBX files..");
1016 $check_md5s=true;
1017 $md5sums = read_md5_file(UPGRADE_DIR."/".$version.".md5");
1018 list($num_files, $num_copied) = recursive_copy("amp_conf", "", $md5sums);
1019 if (!is_file("/etc/asterisk/voicemail.conf")) copy("/etc/asterisk/voicemail.conf.template","/etc/asterisk/voicemail.conf");
1020 if (!is_dir("/var/spool/asterisk/voicemail/device")) amp_mkdir("/var/spool/asterisk/voicemail/device", "0755", true);
1021 out("OK (".$num_copied." files copied, ".($num_files-$num_copied)." skipped)");
1024 // **** Apply amportal.conf configuration to files
1025 debug("Running ".dirname(__FILE__)."/apply_conf.sh");
1026 outn("Configuring install for your environment..");
1027 if (!$dryrun) {
1028 if (file_exists($amp_conf["AMPSBIN"]."/amportal")) {
1029 exec("chmod u+x ".$amp_conf["AMPSBIN"]."/amportal");
1030 outn("amportal..");
1031 } else {
1032 outn("no amportal..");
1034 if (file_exists($amp_conf["AMPBIN"]."/freepbx_engine")) {
1035 exec("chmod u+x ".$amp_conf["AMPBIN"]."/freepbx_engine");
1036 outn("freepbx_engine..");
1037 } else {
1038 outn("no freepbx_engine..");
1040 out("done");
1041 // edit conf file passwords and then
1042 // reload manager in asterisk if it is running:
1044 outn("apply username/password changes to conf files..");
1045 exec(dirname(__FILE__)."/apply_conf.sh");
1046 out("done");
1048 /* As of Asterisk 1.4.16 or there abouts, a missing #include file will make the reload fail. So
1049 we need to make sure that we have such for everything that is in our configs. We will simply
1050 look for the #include statements and touch the files vs. trying to inventory everything we may
1051 need and then forgetting something.
1054 outn("creating missing #include files..");
1055 $include_err = false;
1056 exec("grep '#include' ".$amp_conf['ASTETCDIR']."/*.conf | sed 's/;.*//; s/#include//'",$output,$retcode);
1057 if ($retcode != 0) {
1058 out("Error code $retcode: trying to search for missing #include files");
1059 $include_err = true;
1062 foreach($output as $file) {
1063 if (trim($file) == '') {
1064 continue;
1066 $parse1 = explode(':',$file);
1067 $parse2 = explode(';',$parse1[1]);
1068 $rawfile = trim($parse2[0]);
1069 if ($rawfile == '') {
1070 continue;
1073 $target = ($rawfile[0] == '/') ? $rawfile : $amp_conf['ASTETCDIR']."/$rawfile";
1075 if (!file_exists($target)) {
1076 exec("touch $target", $output, $retcode);
1077 if ($retcode != 0) {
1078 out("Error code $retcode: trying to create empty file $target");
1079 $include_err = true;
1083 if (! $include_err) {
1084 out("OK");
1086 // reload manager in asterisk if it was running:
1087 // Execute the 1.4+ syntax and the 1.2 syntax, it will reload twice on 1.4 and in the other cases
1088 // it will simply ignore the command since it has been removed. (not worth trying to figure out what
1089 // version they have...
1091 system("asterisk -rx 'module reload manager'");
1092 system("asterisk -rx 'reload manager'");
1094 out("OK");
1096 // **** Create spool directories for monitor and fax
1097 if (!is_dir($asterisk_conf["astspooldir"]."/monitor"))
1098 amp_mkdir($asterisk_conf["astspooldir"]."/monitor","0766",true);
1099 if (!is_dir($asterisk_conf["astspooldir"]."/fax"))
1100 amp_mkdir($asterisk_conf["astspooldir"]."/fax","0766",true);
1103 // **** Set permissions all files
1105 if ($install_files)
1107 outn("Setting permissions on files..");
1108 if (!$dryrun) {
1109 exec($amp_conf["AMPSBIN"]."/amportal chown");
1111 out("OK");
1114 // Run through all the upgrade scripts starting at the specified version
1116 upgrade_all($version);
1118 // **** Generate AMP configs
1119 out("Generating AMP configs..");
1120 generate_configs();
1121 out("Generating AMP configs..OK");
1123 $version = install_getversion();
1125 if($install_fop && $amp_conf["FOPRUN"]) {
1126 // **** Bounce FOP
1127 outn("Restarting Flash Operator Panel..");
1128 exec('su - asterisk -c "'.$amp_conf["AMPBIN"].'/bounce_op.sh"');
1129 out("OK");
1132 // Now force an install for all modules that are packaged with the tarball
1133 // directory.
1135 if ($module_install) {
1136 install_modules();
1137 } else {
1138 out("bypassing packaged module installation because --skip-module-install flag");
1142 // **** Set reload flag for AMP admin
1143 install_needreload();
1145 if ($amp_conf["AMPWEBADDRESS"])
1147 out("Please update your modules and reload Asterisk by visiting http://".$amp_conf["AMPWEBADDRESS"]."/admin");
1149 else
1151 out("Please update your modules and reload Asterisk by browsing to your server.");
1154 out("");
1155 out("*************************************************************************");
1156 out("* Note: It's possible that if you click the red 'Update Now' bar BEFORE *");
1157 out("* updating your modules, your machine will start dropping calls. Ensure *");
1158 out("* that all modules are up to date BEFORE YOU CLICK THE RED BAR. As long *");
1159 out("* as this is observed, your machine will be fully functional whilst the *");
1160 out("* upgrade is in progress. *");
1161 out("*************************************************************************");