root/freepbx/branches/2.5/install_amp

Revision 7552, 36.3 kB (checked in by mickecarlsson, 3 years ago)

Added GPL license text to various files

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