root/freepbx/trunk/amp_conf/bin/retrieve_conf

Revision 7110, 26.7 kB (checked in by mbrevda, 5 years ago)

#3319, run cron_scheduler on submit

  • Property svn:mime-type set to text/html
  • 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
3 <?php
4
5 if (! function_exists("_")) {
6   function _($str) {
7     return $str;
8   }
9 }
10
11 ini_set('error_reporting', E_ALL & ~E_NOTICE);
12
13 define("AMP_CONF", "/etc/amportal.conf");
14 $amportalconf = AMP_CONF;
15
16 //define("ASTERISK_CONF", "/etc/asterisk/asterisk.conf");
17 define("WARNING_BANNER", _(";--------------------------------------------------------------------------------;\n; Do NOT edit this file as it is auto-generated by FreePBX. All modifications to ;\n; this file must be done via the web gui. There are alternative files to make    ;\n; custom modifications, details at: http://freepbx.org/configuration_files       ;\n;--------------------------------------------------------------------------------;\n;\n\n"));
18
19 // Emulate gettext extension functions if gettext is not available
20 if (!function_exists('_')) {
21   function _($str) {
22     return $str;
23   }
24 }
25
26 function out($text) {
27   echo $text."\n";
28 }
29
30 function outn($text) {
31   echo $text;
32 }
33
34 function error($text) {
35   echo "[ERROR] ".$text."\n";
36 }
37
38 function fatal($text, $extended_text="", $type="FATAL") {
39   global $db;
40
41   echo "[$type] ".$text." ".$extended_text."\n";
42
43   if(!DB::isError($db)) {
44     $nt = notifications::create($db);
45     $nt->add_critical('retrieve_conf', $type, $text, $extended_text);
46   }
47
48   exit(1);
49 }
50
51 function debug($text) {
52   global $debug;
53  
54   if ($debug) echo "[DEBUG-preDB] ".$text."\n";
55 }
56
57 function showHelp() {
58   out(_("Optional parameters:"));
59   out(_("  --help, -h, -?           Show this help"));
60   out(_("  --debug                  Enable debug output"));
61   out(_("  --dry-run                Don't actually do anything"));
62 }
63
64
65 // bootstrap retrieve_conf by getting the AMPWEBROOT since that is currently where the necessary
66 // functions.inc.php resides, and then use that parser to properly parse the file and get all
67 // the defaults as needed.
68 //
69 function parse_amportal_conf_bootstrap($filename) {
70   $file = file($filename);
71   foreach ($file as $line) {
72     if (preg_match("/^\s*([\w]+)\s*=\s*\"?([\w\/\:\.\*\%-]*)\"?\s*([;#].*)?/",$line,$matches)) {
73       $conf[ $matches[1] ] = $matches[2];
74     }
75   }
76   if ( !isset($conf["AMPWEBROOT"]) || ($conf["AMPWEBROOT"] == "")) {
77     $conf["AMPWEBROOT"] = "/var/www/html";
78   } else {
79     $conf["AMPWEBROOT"] = rtrim($conf["AMPWEBROOT"],'/');
80   }
81
82   return $conf;
83 }
84
85 /** Adds a trailing slash to a directory, if it doesn't already have one
86  */
87 function addslash($dir) {
88   return (($dir[ strlen($dir)-1 ] == '/') ? $dir : $dir.'/');
89 }
90
91
92 /********************************************************************************************************************/
93
94 // **** Make sure we have STDIN etc
95
96 // from  ben-php dot net at efros dot com   at  php.net/install.unix.commandline
97 if (version_compare(phpversion(),'4.3.0','<') || !defined("STDIN")) {
98   define('STDIN',fopen("php://stdin","r"));
99   define('STDOUT',fopen("php://stdout","r"));
100   define('STDERR',fopen("php://stderr","r"));
101   register_shutdown_function( create_function( '' , 'fclose(STDIN); fclose(STDOUT); fclose(STDERR); return true;' ) );
102 }
103   
104 // **** Make sure we have PEAR's DB.php, and include it
105
106 outn(_("Checking for PEAR DB.."));
107 if (! @ include('DB.php')) {
108   out(_("FAILED"));
109   fatal(_("PEAR Missing"),sprintf(_("PEAR must be installed (requires DB.php). Include path: %s "), ini_get("include_path")));
110 }
111 out(_("OK"));
112
113
114 // **** Make sure we have PEAR's GetOpts.php, and include it
115
116 outn(_("Checking for PEAR Console::Getopt.."));
117 if (! @ include("Console/Getopt.php")) {
118   out(_("FAILED"));
119   fatal(_("PEAR Getopt.php Missing"),sprintf(_("PEAR must be installed (requires Console/Getopt.php). Include path: %s"), ini_get("include_path")));
120 }
121 out(_("OK"));
122
123
124 // **** Parse out command-line options
125
126 $shortopts = "h?u:p:";
127 $longopts = array("help","debug","dry-run","run-install","amportalconf=");
128
129 $args = Console_Getopt::getopt(Console_Getopt::readPHPArgv(), $shortopts, $longopts);
130 if (is_object($args)) {
131   // assume it's PEAR_ERROR
132   out($args->message);
133   exit(255);
134 }
135
136 $debug = false;
137 $dryrun = false;
138 $run_install = false;
139
140 foreach ($args[0] as $arg) {
141   switch ($arg[0]) {
142     case "--help": case "h": case "?":
143       showHelp();
144       exit(10);
145     break;
146     case "--dry-run":
147       out(_("Dry-run only, no files will be written"));
148       $dryrun = true;
149     break;
150     case "--debug":
151       $debug = true;
152       debug(_("Debug mode enabled"));
153     break;
154     case "--run-install":
155       $run_install = true;
156       out(_("Running module install.php and install.sql scripts"));
157     break;
158     case "--amportalconf":
159       $amportalconf = $arg[1];
160       out(sprintf(_("Using %s configuration file"), $amportalconf));
161     break;
162   }
163 }
164
165 // **** Check for amportal.conf
166
167 outn(sprintf(_("Checking for %s "), $amportalconf)._(".."));
168 if (!file_exists($amportalconf)) {
169   fatal(_("amportal.conf access problem: "),sprintf(_("The %s file does not exist, or is inaccessible"), $amportalconf));
170 }
171 out(_("OK"));
172
173 // **** read amportal.conf
174
175 outn(sprintf(_("Bootstrapping %s .."), $amportalconf));
176 $amp_conf = parse_amportal_conf_bootstrap($amportalconf);
177 if (count($amp_conf) == 0) {
178   fatal(_("amportal.conf parsing failure"),sprintf(_("no entries found in %s"), $amportalconf));
179 }
180 out(_("OK"));
181
182 outn(sprintf(_("Parsing %s .."), $amportalconf));
183 require_once($amp_conf['AMPWEBROOT']."/admin/functions.inc.php");
184 $amp_conf = parse_amportal_conf($amportalconf);
185 if (count($amp_conf) == 0) {
186   fatal(_("amportal.conf parsing failure"),sprintf(_("no entries found in %s"), $amportalconf));
187 }
188 out(_("OK"));
189
190 $asterisk_conf_file = $amp_conf["ASTETCDIR"]."/asterisk.conf";
191 outn(sprintf(_("Parsing %s .."), $asterisk_conf_file));
192 $asterisk_conf = parse_asterisk_conf($asterisk_conf_file);
193 if (count($asterisk_conf) == 0) {
194   fatal(_("asterisk.conf parsing failure"),sprintf(_("no entries found in %s"), $asterisk_conf_file));
195 }
196 out(_("OK"));
197
198 // **** Connect to database
199
200 outn(_("Connecting to database.."));
201
202 # the engine to be used for the SQL queries,
203 # if none supplied, backfall to mysql
204 $db_engine = "mysql";
205 if (isset($amp_conf["AMPDBENGINE"])){
206   $db_engine = $amp_conf["AMPDBENGINE"];
207 }
208
209 // **** Create symlinks array
210 $symlink_dirs = array();
211 $symlink_dirs['sounds'] = $amp_conf['ASTVARLIBDIR'].'/sounds';
212 $symlink_dirs['bin']    = $amp_conf['AMPBIN'];
213 $symlink_dirs['etc']    = $amp_conf['ASTETCDIR'];
214 $symlink_dirs['images'] = $amp_conf['AMPWEBROOT']."/admin/images";
215
216 $cp_errors = "";
217 $cp_dirs = array();
218 $cp_dirs['agi-bin'] = $amp_conf['ASTAGIDIR'];
219
220 switch ($db_engine)
221 {
222   case "pgsql":
223   case "mysql":
224     /* datasource in in this style:
225     dbengine://username:password@host/database */
226  
227     $db_user = $amp_conf["AMPDBUSER"];
228     $db_pass = $amp_conf["AMPDBPASS"];
229     $db_host = $amp_conf["AMPDBHOST"];
230     $db_name = $amp_conf["AMPDBNAME"];
231  
232     $datasource = $db_engine.'://'.$db_user.':'.$db_pass.'@'.$db_host.'/'.$db_name;
233     $db = DB::connect($datasource); // attempt connection
234     break;
235  
236   case "sqlite":
237     die_freepbx("SQLite2 support is deprecated. Please use sqlite3 only.");
238     break;
239  
240   case "sqlite3":
241     if (!isset($amp_conf["AMPDBFILE"]))
242       fatal("You must setup properly AMPDBFILE in $amportalconf");
243       
244     if (isset($amp_conf["AMPDBFILE"]) == "")
245       fatal("AMPDBFILE in $amportalconf cannot be blank");
246
247     /* on centos this extension is not loaded by default */
248     if (! extension_loaded('sqlite3.so')  && ! extension_loaded('SQLITE3'))
249       dl('sqlite3.so');
250
251     if (! @require_once('DB/sqlite3.php') )
252     {
253       die_freepbx("Your PHP installation has no PEAR/SQLite3 support. Please install php-sqlite3 and php-pear.");
254     }
255
256     require_once('DB/sqlite3.php');
257     $datasource = "sqlite3:///" . $amp_conf["AMPDBFILE"] . "?mode=0666";
258     $db = DB::connect($datasource);
259     break;
260
261   default:
262     fatal( "Unknown SQL engine: [$db_engine]");
263 }
264
265 if(DB::isError($db)) {
266   out(_("FAILED"));
267   debug($db->userinfo);
268   fatal(_("database connection failure"),("failed trying to connect to the configured database"));
269  
270 }
271 out(_("OK"));
272
273 // Define the notification class for logging to the dashboard
274 //
275 $nt = notifications::create($db);
276
277 /*
278 */
279 // Check and increase php memory_limit if needed and if allowed on the system
280 //
281 $current_memory_limit = rtrim(ini_get('memory_limit'),'M');
282 $proper_memory_limit = '100';
283 if ($current_memory_limit < $proper_memory_limit) {
284   if (ini_set('memory_limit',$proper_memory_limit.'M') !== false) {
285     $nt->add_notice('core', 'MEMLIMIT', _("Memory Limit Changed"), sprintf(_("Your memory_limit, %sM, is set too low and has been increased to %sM. You may want to change this in you php.ini config file"),$current_memory_limit,$proper_memory_limit));
286   } else {
287     $nt->add_warning('core', 'MEMERR', _("Low Memory Limit"), sprintf(_("Your memory_limit, %sM, is set too low and may cause problems. FreePBX is not able to change this on your system. You should increase this to %sM in you php.ini config file"),$current_memory_limit,$proper_memory_limit));
288   }
289 } else {
290   $nt->delete('core', 'MEMLIMIT');
291 }
292
293 //TODO : make this engine-neutral
294 outn(_("Connecting to Asterisk manager interface.."));
295 // connect to asterisk manager
296 require_once($amp_conf['AMPWEBROOT'].'/admin/common/php-asmanager.php');
297 $astman = new AGI_AsteriskManager();
298 if (! $res = $astman->connect("127.0.0.1:".$amp_conf["ASTMANAGERPORT"], $amp_conf["AMPMGRUSER"] , $amp_conf["AMPMGRPASS"])) {
299   out(_("FAILED"));
300   fatal(_("Asterisk Manager Connection Failure"),sprintf(_("Failed to connect to the Asterisk manager through port: %s"), $amp_conf['ASTMANAGERPORT']));
301 }
302 out(_("OK"));
303
304 //include common functions
305 require_once($amp_conf['AMPWEBROOT']."/admin/extensions.class.php");
306 freepbx_log("retrieve_conf", "devel-debug", "Started retrieve_conf, DB Connection OK");
307
308 // query for our modules
309 // var_dump( $db );
310 $modules = module_getinfo();
311
312 //Putting the core module last, to move outbound-allroutes
313 // last in from-internals-additional
314 if (array_key_exists('core', $modules)) {
315         $core_tmp = $modules['core'];
316         unset($modules['core']);
317         $modules['core'] = $core_tmp;
318 }
319
320 // include any module global functions
321 if(is_array($modules)){
322   foreach($modules as $key => $module) {
323     //only use this module if it's enabled (status=2)
324     if (isset($module['status']) && $module['status'] == MODULE_STATUS_ENABLED) {
325       // Make sure the module is installed and up to date
326       if ($run_install) module_install($key);
327       // active_modules array used in genConf function
328       $active_modules[] = $key;
329       //include module functions
330       if (is_file($amp_conf['AMPWEBROOT']."/admin/modules/{$key}/functions.inc.php")) {
331         freepbx_log('retrieve_conf', 'devel-debug', 'Including '.$amp_conf['AMPWEBROOT']."/admin/modules/{$key}/functions.inc.php");
332         include_once($amp_conf['AMPWEBROOT']."/admin/modules/{$key}/functions.inc.php");
333         freepbx_log('retrieve_conf', 'devel-debug', $amp_conf['AMPWEBROOT']."/admin/modules/{$key}/functions.inc.php processed OK");
334       }
335
336       // create symlinks for files in appropriate sub directories
337       // don't symlink framework files, it is a special case module that happens to have
338       // some conflicting names
339       //
340       if ($key != 'framework') {
341         symlink_subdirs( $amp_conf['AMPWEBROOT'].'/admin/modules/'.$key );
342         cp_subdirs( $amp_conf['AMPWEBROOT'].'/admin/modules/'.$key );
343       }
344     }
345   }
346 }
347 // Now also make sure to symlink the CDR images which is not a proper module
348 //
349 symlink_subdirs( $amp_conf['AMPWEBROOT'].'/admin/cdr/');
350
351 // create an object of the extensions class
352 require_once($amp_conf['AMPWEBROOT']."/admin/extensions.class.php");
353 $ext = new extensions;
354
355 // create objects for any module classes
356 // currently only 1 class can be declared per module, not sure if that will be an issue
357 if(isset($active_modules) && is_array($active_modules)){
358   foreach($active_modules as $active_module) {
359     freepbx_log('retrieve_conf', 'devel-debug', "Creating ".$active_module."_conf class");
360     $classname = $active_module."_conf";
361     if(class_exists($classname)) {
362       ${$classname} = new $classname;
363     }
364   }
365 }
366
367 $engineinfo = engine_getinfo();
368 if($engineinfo['version'] == 0){
369   freepbx_log('retrieve_conf', 'fatal', "Failed to get engine information (engine_getinfo: {$engineinfo['engine']})");
370   fatal(_("Failed to get engine_info"),_("retreive_conf failed to get engine information and cannot configure up a softwitch with out it. Error: {$engineinfo['engine']}"));
371 }
372 // was setting these variables before, assume we still need them
373 $engine = $engineinfo['engine'];
374 $version = $engineinfo['version'];
375 $chan_dahdi = ast_with_dahdi();
376
377 // Check for and report any extension conflicts
378 //
379
380 $extens_ok = true;
381 $dests_ok = true;
382
383 $nt = notifications::create($db);
384
385 $my_hash = array_flip($active_modules);
386 $my_prob_extens = framework_list_extension_conflicts($my_hash);
387
388 if (empty($my_prob_extens)) {
389   $nt->delete('retrieve_conf', 'XTNCONFLICT');
390 } else {
391   $previous = null;
392   $str = null;
393   $count = 0;
394   foreach ($my_prob_extens as $extens) {
395     foreach ($extens as $exten => $details) {
396       if ($exten != $previous) {
397         $str .=  "Extension: $exten:<br />";
398         $count++;
399       }
400       $str .= sprintf("%8s: %s<br />",$details['status'], $details['description']);
401       $previous = $exten;
402     }
403   }
404   $nt->add_error('retrieve_conf', 'XTNCONFLICT', sprintf(_("There are %s conflicting extensions"),$count), $str);
405   $extens_ok = false;
406 }
407
408 // Check for and report any bogus destinations
409 //
410 $my_probs = framework_list_problem_destinations($my_hash, !$amp_conf['CUSTOMASERROR']);
411
412 if (empty($my_probs)) {
413   $nt->delete('retrieve_conf', 'BADDEST');
414 } else {
415   $results = array();
416   $count = 0;
417   $str = null;
418   foreach ($my_probs as $problem) {
419     //print_r($problem);
420     $results[$problem['status']][] = $problem['description'];
421     $count++;
422   }
423   foreach ($results as $status => $subjects) {
424     $str .= sprintf(_("DEST STATUS: %s%s"),$status,"\n");
425     foreach ($subjects as $subject) {
426       //$str .= $subject."<br />";
427       $str .= "   ".$subject."\n";
428     }
429   }
430   $nt->add_error('retrieve_conf', 'BADDEST', sprintf(_("There are %s bad destinations"),$count), $str);
431   $dests_ok = false;
432 }
433
434 if ((!$exten_ok && $amp_conf['XTNCONFLICTABORT']) || (!$dest_ok && $amp_conf['BADDESTABORT'])) {
435   out(_("Aborting reload because extension conflicts or bad destinations"));
436   exit(20);
437 }
438
439 // run all of the *_get_config and _hookGet_config functions, which will populate the appropriate objects
440 if(isset($active_modules) && is_array($active_modules)){
441   foreach($active_modules as $module) {
442     $funcname = $module."_get_config";
443     if (function_exists($funcname)) {
444       freepbx_log('retrieve_conf', 'devel-debug', 'Calling '.$funcname.'()');
445       $funcname($engine);
446     }
447   }
448   foreach($active_modules as $module) {
449     $funcname = $module."_hookGet_config";
450     if (function_exists($funcname)) {
451       freepbx_log('retrieve_conf', 'devel-debug', 'Calling '.$funcname.'()');
452       $funcname($engine);
453     }
454   }
455 }
456
457 // extensions_additional.conf
458 // create the from-internal-additional context so other can add to it
459 $ext->add('from-internal-additional', 'h', '', new ext_hangup(''));
460 //echo $ext->get_filename();
461 //echo $ext->generateConf();
462 write_file($ext->get_filename(),$ext->generateConf());
463
464 // now we write out our conf files for modules
465 // check for any objects for each of the active modules
466 // ** conferences is an example of a module that write a conf
467 if(isset($active_modules) && is_array($active_modules)){
468   foreach($active_modules as $active_module) {
469     $classname = $active_module."_conf";
470     if(class_exists($classname) && get_class(${$classname}) !== false) {
471       //echo ${$classname}->get_filename();
472       //echo ${$classname}->generateConf();
473       
474       // if the module returns an array, it wants to write multiple files
475       // ** pinsets is an example of a module that does this
476       if (is_array(${$classname}->get_filename())) {
477         foreach(${$classname}->get_filename() as $modconf) {
478           freepbx_log('retrieve_conf', 'devel-debug', 'generateConf from '.$classname.'->'.$modconf.'');
479           if (isset(${$classname}->use_warning_banner)) {
480             write_file($modconf,${$classname}->generateConf($modconf),${$classname}->use_warning_banner);
481           } else {
482             write_file($modconf,${$classname}->generateConf($modconf));
483           }
484         }
485       } else {
486         freepbx_log('retrieve_conf', 'devel-debug', 'generateConf from '.$classname);
487         if (isset(${$classname}->use_warning_banner)) {
488           write_file(${$classname}->get_filename(),${$classname}->generateConf(),${$classname}->use_warning_banner);
489         } else {
490           write_file(${$classname}->get_filename(),${$classname}->generateConf());
491         }
492       }
493     }
494   }
495 }
496
497
498 function write_file($filename,$contents,$use_warning_banner=true) {
499   global $asterisk_conf;
500   freepbx_log('retrieve_conf', 'devel-debug', 'Writing '.$filename);
501   if (isset($filename) && !empty($filename)) {
502     if ($fd = fopen(addslash($asterisk_conf['astetcdir']).$filename, "w")) {
503       if ($use_warning_banner) {
504         fwrite($fd, WARNING_BANNER );
505       }
506       fwrite($fd, $contents);
507       fclose($fd);
508     }
509   }
510 }
511
512 /* file_exists_wrapper()
513  * wrapper for file_exists() with the following additonal functionality.
514  * if the file is a symlink, it will check if the link exists and if not
515  * it will try to remove this file. It returns a false (file does not exists)
516  * if the file is successfully removed, true if not. If not a symlink, just
517  * returns file_exists()
518  */
519 function file_exists_wrapper($string) {
520   if (is_link($string)) {
521     $linkinfo = readlink($string);
522     if ($linkinfo === false) {
523       //TODO: throw error?
524       return !unlink($string);
525     } else {
526       if (file_exists($linkinfo)) {
527         return true;
528       } else {
529         return !unlink($string);
530       }
531     }
532   } else {
533     return file_exists($string);
534   }
535 }
536
537 function symlink_subdirs($moduledir) {
538   global $symlink_dirs;
539   $symlink_errors = false;
540
541   $nt = notifications::create($db);
542
543   $error_modules = '';
544   foreach ($symlink_dirs as $subdir => $targetdir) {
545     $dir = addslash($moduledir).$subdir;
546     if (is_dir($dir)) {
547       $d = opendir($dir);
548       while ($file = readdir($d)) {
549         if ($file[0] != '.') {
550           $src = addslash($dir).$file;
551           $dest = addslash($targetdir).$file;
552           if (file_exists_wrapper($dest)) {
553             if (!is_link($dest)) {
554               freepbx_log('retrieve-conf', 'error', $dest.' already exists, and is not a symlink!');
555               $error_modules .= "<br />&nbsp;&nbsp;&nbsp;".$dest;
556               $symlink_errors = true;
557             } else if (readlink($dest) != $src) {
558               // TODO : is this the proper handling? should we just overwrite..?
559               freepbx_log('retrieve-conf', 'error', $dest.' already exists, and is linked to something else!');
560               $error_modules .= "<br />&nbsp;&nbsp;&nbsp;".$dest;
561               $symlink_errors = true;
562             } else {
563               freepbx_log('retrieve-conf', 'devel-debug', $dest.' already points to '.$src.' - OK');
564             }
565           } else {
566 //            // symlink, unlike copy, doesn't overwrite - have to delete first
567 //            if (is_link($dest) || file_exists($dest)) {
568 //              unlink($dest);
569 //            }
570             if (symlink($src, $dest)) {
571               freepbx_log('retrieve-conf', 'devel-debug', 'Symlinked '.$src.' to '.$dest);
572             } else {
573               freepbx_log('retreive-conf', 'devel-debug', 'Cannot symlink '.$src.' to '.$dest.'. Check Permissions?');
574             }
575           }
576         }
577       }
578       closedir($d);
579     }
580   }
581   if ($error_modules) {
582     $nt->add_error('retrieve_conf', 'SYMLINK', _("Symlink from modules failed"), sprintf(_("retrieve_conf failed to sym link: %s<br \>This can result in FATAL failures to your PBX. If the target file exists, the symlink will not occur and you should rename the target file to allow the automatic sym link to occur and remove this error, unless this is an intentional customization."),$error_modules));
583   } else {
584     $nt->delete('retrieve_conf', 'SYMLINK');
585   }
586 }
587
588 // wrap copy with error handler
589 //
590 function err_copy($source, $dest) {
591   $ret = false;
592   set_error_handler("report_errors");
593   if (copy($source, $dest)) {
594     $ret = chmod($dest,0754);
595   }
596   restore_error_handler();
597   return $ret;
598 }
599
600 // wrap unlink with error handler
601 //
602 function err_unlink($dest) {
603   set_error_handler("report_errors");
604   $ret = unlink($dest);
605   restore_error_handler();
606   return $ret;
607 }
608
609 function cp_subdirs($moduledir) {
610   global $cp_errors;
611   global $cp_dirs;
612
613   $cp_errors = "";
614   foreach ($cp_dirs as $subdir => $targetdir) {
615     $dir = addslash($moduledir).$subdir;
616     if (is_dir($dir)) {
617       $d = opendir($dir);
618       while ($file = readdir($d)) {
619         if ($file[0] != '.') {
620           $sourcefile = addslash($dir).$file;
621           $targetfile = addslash($targetdir).$file;
622
623           if (file_exists_wrapper($targetfile)) {
624             if (is_link($targetfile)) {
625               if (err_unlink($targetfile)) {
626                 freepbx_log('retrieve-conf', 'devel-debug', "$targetfile was symbolic link, unlink successful");
627               } else {
628                 freepbx_log('retrieve-conf', 'error', "$targetfile is a symblolic link, failed to unlink!");
629                 break;
630               }
631             }
632           }
633           // OK, now either the file is a regular file or isn't there, so proceed
634           //
635           if (err_copy($sourcefile,$targetfile)) {
636             freepbx_log('retrieve-conf', 'devel-debug', "$targetfile successfully copied");
637             // copy was successful, make sure it has execute permissions
638             chmod($targetfile,0754);
639           } else {
640             freepbx_log('retrieve-conf', 'error', "$targetfile failed to copy from module directory");
641           }
642         }
643       }
644       closedir($d);
645     }
646   }
647   $nt = notifications::create($db);
648   if ($cp_errors) {
649     $nt->add_error('retrieve_conf', 'CPAGIBIN', _("Failed to copy from module agi-bin"), sprintf(_("Retrieve conf failed to copy file(s) from a module's agi-bin dir: %s"),$cp_errors));
650   } else {
651     $nt->delete('retrieve_conf', 'CPAGIBIN');
652   }
653 }
654
655 function report_errors($errno, $errstr, $errfile, $errline) {
656   global $cp_errors;
657   switch($db_engine) {
658     case "sqlite3":
659       $escaped_string = sqlite_real_escape($errstr);
660       break;
661     case "mysql":
662       $escaped_string = mysql_real_escape_string($errstr);
663       break;
664     case "pgsql":
665       $escaped_string = pgsql_escape_string($errstr);
666       break;
667   }
668   freepbx_log('retrieve-conf', 'error', "php reported: '$escaped_string' after copy or unlink attempt!");
669   $cp_errors .= $errstr."\n";
670 }
671
672 /** Check if there is a job running, if one is found then all is good, if one is not found, it will be added and a
673  *  notification will be sent.
674  */
675 function install_cron_scheduler() {
676   global $amp_conf;
677   global $nt;
678
679   // crontab appears to return an error when no entries, os only fail if error returned AND a list of entries.
680   // Don't know if this will ever happen, but a failure and a list could indicate something wrong.
681   //
682   exec("/usr/bin/crontab -l", $outlines, $ret);
683   if ($ret && count($outlines)) {
684     $nt->add_error('retrieve_conf', 'CRONMGR', _("Failed to check crontab for cron manager"), sprintf(_("crontab returned %s error code when checking for crontab entries to start freepbx-cron-scheduler.php crontab manager"),$ret));
685   } else {
686     $nt->delete('retrieve_conf', 'CRONMGR');
687     $outlines2 = preg_grep("/freepbx-cron-scheduler.php/",$outlines);
688     $cnt = count($outlines2);
689     switch ($cnt) {
690       case 0:
691         /** grab any other cronjobs that are running as asterisk and NOT associated with backups
692         *  this code was taken from the backup module for the most part. But seems to work...
693         */
694         $outlines = array();
695         exec("/usr/bin/crontab -l | grep -v ^#\ DO\ NOT | grep -v ^#\ \( |  grep -v freepbx-cron-scheduler.php", $outlines, $ret);
696         $crontab_entry = "";
697         foreach ($outlines as $line) {
698           $crontab_entry .= $line."\n";
699         }
700         // schedule to run hourly, at a random time. The random time is explicit to accomodate things like module_admin online update checking
701         // since we will want a random access to the server. In the case of module_admin, that will also be scheduled randomly within the hour
702         // that it is to run
703         //
704         $crontab_entry .= rand(0,59)." * * * * ".$amp_conf['AMPBIN']."/freepbx-cron-scheduler.php";
705         system("/bin/echo '$crontab_entry' | /usr/bin/crontab -");
706         break;
707       case 1:
708         // already running, nothing to do
709         break;
710       default:
711         // error, there should never be more than one running
712         echo "TODO: deal with error here\n";
713         $nt->add_error('retrieve_conf', 'CRONMGR', _("Multiple freepbx-cron-scheduler.php running"), sprintf(_("There were %s freepbx-cron-scheduler.php instances running. There should be only 1."),$cnt));
714     }
715   }
716 }
717
718 include("libfreepbx.confgen.php");
719
720 // script to write op_server.cfg file from mysql
721 //
722 if(!$amp_conf['FOPDISABLE'])  {
723   $script = $amp_conf['AMPBIN'].'/retrieve_op_conf_from_mysql.pl';
724   if (is_executable($script)) {
725     $script .= ' '.$amportalconf.' '.rtrim($asterisk_conf['astetcdir'],DIRECTORY_SEPARATOR);
726     exec($script, $output, $ret);
727     if ($ret) {
728       error(sprintf(_("retrieve_op_conf_from_mysql.pl returned with an error code %s"),$ret));
729     }
730   } else {
731     error(_("retrieve_op_conf_from_mysql.pl does not exist or is not executable"));
732   }
733 }
734 // generate configuration files
735 //
736 // Leave the legacy scripts in for a little while to help with odd-ball upgrade scenarios if they haven't gotten
737 // a module upgraded yet. In particular Queues
738 //
739 if (!isset($core_conf) || !is_a($core_conf, "core_conf")) {
740   generate_configurations_sip($version);
741   generate_configurations_iax($version);
742   generate_configurations_zap($version);
743 }
744 if (!isset($queues_conf) || !is_a($queues_conf, "queues_conf")) {
745   generate_configurations_queues($version);
746 }
747  
748 // Check and install the freepbx-cron-scheduler.php manager
749 //
750 install_cron_scheduler();
751
752 // check for and run backup_retrieve_backup_cron()
753 if (function_exists('backup_retrieve_backup_cron')) {
754  backup_retrieve_backup_cron();
755 }
756
757 // run retrieve_conf_post_custom
758 // If the following file exists, it will be run. This allows customization to be run automatically after the normal
759 // processing. Caution should be taken using this as it is only deisgned for expert usage. Errors in the code will
760 // have bad consequences and can cripple the system.
761 //
762 if (isset($amp_conf['AMPLOCALBIN'])) {
763 $post_custom = $amp_conf['AMPLOCALBIN'].'/retrieve_conf_post_custom';
764   if (file_exists($post_custom)) {
765     outn(sprintf(_("Found script %s, executing.."), $post_custom));
766     include($post_custom);
767     out(_("OK"));
768   }
769 }
770
771 /* As of Asterisk 1.4.16 or there abouts, a missing #include file will make the reload fail. So
772    we need to make sure that we have such for everything that is in our configs. We will simply
773    look for the #include statements and touch the files vs. trying to inventory everything we may
774    need and then forgetting something.
775 */
776
777 exec("grep '#include' ".$amp_conf['ASTETCDIR']."/*.conf | sed 's/;.*//; s/#include//'",$output,$retcode);
778 if ($retcode != 0) {
779   error("Error code $retcode: trying to search for missing #include files");
780 }
781
782 foreach($output as $file) {
783   if (trim($file) == '') {
784     continue;
785   }
786   $parse1 = explode(':',$file);
787   $parse2 = explode(';',$parse1[1]);
788   $rawfile = trim($parse2[0]);
789   if ($rawfile == '') {
790     continue;
791   }
792
793   $target = ($rawfile[0] == '/') ? $rawfile : $amp_conf['ASTETCDIR']."/$rawfile";
794
795   if (!file_exists($target)) {
796     exec("touch $target", $output, $retcode);
797     if ($retcode != 0) {
798       error("Error code $retcode: trying to create empty file $target");
799     }
800   }
801 }
802
803
804 // **** Set reload flag for AMP admin
805 needreload();
806 if (isset($amp_conf["AMPWEBADDRESS"]) && $amp_conf["AMPWEBADDRESS"])
807 {
808   out(sprintf(_("Please update your modules and reload Asterisk by visiting %s"), "http://".$amp_conf["AMPWEBADDRESS"]."/admin"));
809 }
810 else
811 {
812   out(_("Please update your modules and reload Asterisk by browsing to your server."));
813 }
814   $nt->delete('retrieve_conf', 'FATAL');
815 ?>
Note: See TracBrowser for help on using the browser.