&1 ", "r"); if(!$fd) { log_error("Warning, could not execute command {$command}"); return 0; } while(!feof($fd)) { $tmp .= fread($fd,49); } fclose($fd); if($tmp == "") return false; else return true; } /****f* pfsense-utils/find_number_of_created_carp_interfaces * NAME * find_number_of_created_carp_interfaces - Return the number of CARP interfaces. * RESULT * $tmp - Number of currently created CARP interfaces. ******/ function find_number_of_created_carp_interfaces() { $command = "/sbin/ifconfig | /usr/bin/grep \"carp*:\" | /usr/bin/wc -l"; $fd = popen($command . " 2>&1 ", "r"); if(!$fd) { log_error("Warning, could not execute command {$command}"); return 0; } while(!feof($fd)) { $tmp .= fread($fd,49); } fclose($fd); $tmp = intval($tmp); return $tmp; } /****f* pfsense-utils/link_ip_to_carp_interface * NAME * link_ip_to_carp_interface - Find where a CARP interface links to. * INPUTS * $ip * RESULT * $carp_ints ******/ function link_ip_to_carp_interface($ip) { global $config; if($ip == "") return; $i = 0; $ifdescrs = array('wan', 'lan'); for ($j = 1; isset($config['interfaces']['opt' . $j]); $j++) { $ifdescrs['opt' . $j] = "opt" . $j; } $ft = split("\.", $ip); $ft_ip = $ft[0] . "." . $ft[1] . "." . $ft[2] . "."; $carp_ints = ""; $num_carp_ints = find_number_of_created_carp_interfaces(); foreach ($ifdescrs as $ifdescr => $ifname) { for($x=0; $x<$num_carp_ints; $x++) { $carp_int = "carp{$x}"; $carp_ip = find_interface_ip($carp_int); $carp_ft = split("\.", $carp_ip); $carp_ft_ip = $carp_ft[0] . "." . $carp_ft[1] . "." . $carp_ft[2] . "."; $result = does_interface_exist($carp_int); if($result <> true) break; $interface = filter_opt_interface_to_real($ifname); if($ft_ip == $carp_ft_ip) if(stristr($carp_ints,$carp_int) == false) $carp_ints .= " " . $carp_int; } } return $carp_ints; } /****f* pfsense-utils/exec_command * NAME * exec_command - Execute a command and return a string of the result. * INPUTS * $command - String of the command to be executed. * RESULT * String containing the command's result. * NOTES * This function returns the command's stdout and stderr. ******/ function exec_command($command) { $output = array(); exec($command . ' 2>&1 ', $output); return(implode("\n", $output)); } /* * does_interface_exist($interface): return true or false if a interface is detected. */ function does_interface_exist($interface) { $ints = exec_command("/sbin/ifconfig -l"); if(stristr($ints, $interface) !== false) return true; else return false; } /* * convert_ip_to_network_format($ip, $subnet): converts an ip address to network form */ function convert_ip_to_network_format($ip, $subnet) { $ipsplit = split('[.]', $ip); $string = $ipsplit[0] . "." . $ipsplit[1] . "." . $ipsplit[2] . ".0/" . $subnet; return $string; } /* * find_interface_ip($interface): return the interface ip (first found) */ function find_interface_ip($interface) { if(does_interface_exist($interface) == false) return; $ip = exec_command("/sbin/ifconfig {$interface} | /usr/bin/grep -w \"inet\" | /usr/bin/cut -d\" \" -f 2"); $ip = str_replace("\n","",$ip); return $ip; } function guess_interface_from_ip($ipaddress) { $ints = `/sbin/ifconfig -l`; $ints_split = split(" ", $ints); $ip_subnet_split = split("\.", $ipaddress); $ip_subnet = $ip_subnet_split[0] . "." . $ip_subnet_split[1] . "." . $ip_subnet_split[2] . "."; foreach($ints_split as $int) { $ip = find_interface_ip($int); $ip_split = split("\.", $ip); $ip_tocheck = $ip_split[0] . "." . $ip_split[1] . "." . $ip_split[2] . "."; if(stristr($ip_tocheck, $ip_subnet) != false) return $int; } } function filter_opt_interface_to_real($opt) { global $config; return $config['interfaces'][$opt]['if']; } function filter_get_opt_interface_descr($opt) { global $config; return $config['interfaces'][$opt]['descr']; } function get_friendly_interface_list_as_array() { global $config; $ints = array(); $i = 0; $ifdescrs = array('wan', 'lan'); for ($j = 1; isset($config['interfaces']['opt' . $j]); $j++) { $ifdescrs['opt' . $j] = "opt" . $j; } $ifdescrs = get_interface_list(); foreach ($ifdescrs as $ifdescr => $ifname) { array_push($ints,$ifdescr); } return $ints; } /* * find_ip_interface($ip): return the interface where an ip is defined */ function find_ip_interface($ip) { global $config; $i = 0; $ifdescrs = array('wan', 'lan'); for ($j = 1; isset($config['interfaces']['opt' . $j]); $j++) { $ifdescrs['opt' . $j] = "opt" . $j; } foreach ($ifdescrs as $ifdescr => $ifname) { $int = filter_translate_type_to_real_interface($ifname); $ifconfig = exec_command("/sbin/ifconfig {$int}"); if(stristr($ifconfig,$ip) <> false) return $int; } return false; } /* * filter_translate_type_to_real_interface($interface): returns the real interface name * for a friendly interface. ie: wan */ function filter_translate_type_to_real_interface($interface) { global $config; return $config['interfaces'][$interface]['if']; } /* * get_carp_interface_status($carpinterface): returns the status of a carp ip */ function get_carp_interface_status($carpinterface) { /* basically cache the contents of ifconfig statement to speed up this routine */ global $carp_query; if($carp_query == "") $carp_query = split("\n", `/sbin/ifconfig | /usr/bin/grep carp`); $found_interface = 0; foreach($carp_query as $int) { if($found_interface == 1) { if(stristr($int, "MASTER") == true) return "MASTER"; if(stristr($int, "BACKUP") == true) return "BACKUP"; if(stristr($int, "INIT") == true) return "INIT"; return false; } if(stristr($int, $carpinterface) == true) $found_interface=1; } return $status; } /* * get_pfsync_interface_status($pfsyncinterface): returns the status of a pfsync */ function get_pfsync_interface_status($pfsyncinterface) { $result = does_interface_exist($pfsyncinterface); if($result <> true) return; $status = exec_command("/sbin/ifconfig {$pfsyncinterface} | /usr/bin/grep \"pfsync:\" | /usr/bin/cut -d\" \" -f5"); return $status; } /* * find_carp_interface($ip): return the carp interface where an ip is defined */ function find_carp_interface($ip) { global $find_carp_ifconfig; if($find_carp_ifconfig == "") { $find_carp_ifconfig = array(); $num_carp_ints = find_number_of_created_carp_interfaces(); for($x=0; $x<$num_carp_ints; $x++) { $find_carp_ifconfig[$x] = exec_command("/sbin/ifconfig carp{$x}"); } } $carps = 0; foreach($find_carp_ifconfig as $fci) { if(stristr($fci, $ip) == true) return "carp{$carps}"; $carps++; } } /* * add_rule_to_anchor($anchor, $rule): adds the specified rule to an anchor */ function add_rule_to_anchor($anchor, $rule, $label) { mwexec("echo " . $rule . " | /sbin/pfctl -a " . $anchor . ":" . $label . " -f -"); } /* * remove_text_from_file * remove $text from file $file */ function remove_text_from_file($file, $text) { global $fd_log; fwrite($fd_log, "Adding needed text items:\n"); $filecontents = exec_command_and_return_text("cat " . $file); $textTMP = str_replace($text, "", $filecontents); $text .= $textTMP; fwrite($fd_log, $text . "\n"); $fd = fopen($file, "w"); fwrite($fd, $text); fclose($fd); } /* * is_package_installed($packagename): returns 1 if a package is installed, 0 otherwise. */ function is_package_installed($packagename) { global $config; if($config['installedpackages']['package'] <> "") foreach ($config['installedpackages']['package'] as $pkg) { if($pkg['name'] == $packagename) return 1; } return 0; } /* * lookup pkg array id# */ function get_pkg_id($pkg_name) { global $config; global $pkg_config; if(is_array($config['installedpackages']['package'])) { $i = 0; foreach ($config['installedpackages']['package'] as $pkg) { if($pkg['name'] == $pkg_name) return $i; $i++; } return $i; } return -1; } /* * get_latest_package_version($pkgname): Get current version of a package. Returns latest package version or false * if package isn't defined in the currently used pkg_config.xml. */ function get_latest_package_version($pkg_name) { global $g; fetch_latest_pkg_config(); $pkg_config = parse_xml_config_pkg("{$g['tmp_path']}/pkg_config.xml", "pfsensepkgs"); foreach($pkg_config['packages']['package'] as $pkg) { if($pkg['name'] == $pkg_name) { return $pkg['version']; } } return false; } /* * Lookup pkg_id in pkg_config.xml */ function get_available_pkg_id($pkg_name) { global $pkg_config, $g; if(!is_array($pkg_config)) { fetch_latest_pkg_config(); } $pkg_config = parse_xml_config_pkg("{$g['tmp_path']}/pkg_config.xml", "pfsensepkgs"); $id = 0; foreach($pkg_config['packages']['package'] as $pkg) { if($pkg['name'] == $pkg_name) { return $id; } $id++; } return; } /* * fetch_latest_pkg_config: download the latest pkg_config.xml to /tmp/ directory */ function fetch_latest_pkg_config() { global $g; global $config; if(!file_exists("{$g['tmp_path']}/pkg_config.xml")) { $pkg_config_location = $g['pkg_config_location']; $pkg_config_base_url = $g['pkg_config_base_url']; if(isset($config['system']['alt_pkgconfig_url']['enabled'])) { $pkg_config_location = $config['system']['alt_pkgconfig_url']['pkgconfig_base_url'] . $config['system']['alt_pkgconfig_url']['pkgconfig_filename']; $pkg_config_base_url = $config['system']['alt_pkgconfig_url']['pkgconfig_base_url']; } mwexec("/usr/bin/fetch -o {$g['tmp_path']}/pkg_config.xml {$pkg_config_location}"); if(!file_exists("{$g['tmp_path']}/pkg_config.xml")) { print_info_box_np("Could not download pkg_config.xml from " . $pkg_config_base_url . ". Check your DNS settings."); die; } } return; } /* * add_text_to_file($file, $text): adds $text to $file. * replaces the text if it already exists. */ function add_text_to_file($file, $text) { global $fd_log; fwrite($fd_log, "Adding needed text items:\n"); $filecontents = exec_command_and_return_text("cat " . $file); $filecontents = str_replace($text, "", $filecontents); $text = $filecontents . $text; fwrite($fd_log, $text . "\n"); $fd = fopen($file, "w"); fwrite($fd, $text . "\n"); fclose($fd); } /* * get_filename_from_url($url): converts a url to its filename. */ function get_filename_from_url($url) { $filenamesplit = split("/", $url); foreach($filenamesplit as $fn) $filename = $fn; return $filename; } /* * update_output_window: update bottom textarea dynamically. */ function update_output_window($text) { $log = ereg_replace("\n", "\\n", $text); echo "\n"; } /* * get_dir: return an array of $dir */ function get_dir($dir) { $dir_array = array(); $d = dir($dir); while (false !== ($entry = $d->read())) { array_push($dir_array, $entry); } $d->close(); return $dir_array; } /* * update_output_window: update top textarea dynamically. */ function update_status($status) { echo "\n"; } /* * exec_command_and_return_text_array: execute command and return output */ function exec_command_and_return_text_array($command) { $counter = 0; $fd = popen($command . " 2>&1 ", "r"); while(!feof($fd)) { $tmp .= fread($fd,49); } fclose($fd); $temp_array = split("\n", $tmp); return $tmp_array; } /* * exec_command_and_return_text: execute command and return output */ function exec_command_and_return_text($command) { return exec_command($command); } /* * exec_command_and_return_text: execute command and update output window dynamically */ function execute_command_return_output($command) { global $fd_log; $fd = popen($command . " 2>&1 ", "r"); echo "\n"; $counter = 0; $counter2 = 0; while(!feof($fd)) { $tmp = fread($fd, 50); $tmp1 = ereg_replace("\n","\\n", $tmp); $text = ereg_replace("\"","'", $tmp1); if($lasttext == "..") { $text = ""; $lasttext = ""; $counter=$counter-2; } else { $lasttext .= $text; } if($counter > 51) { $counter = 0; $extrabreak = "\\n"; } else { $extrabreak = ""; $counter++; } if($counter2 > 600) { echo "\n"; $counter2 = 0; } else $counter2++; echo "\n"; } fclose($fd); } /* * convert_friendly_interface_to_real_interface_name($interface): convert WAN to FXP0 */ function convert_friendly_interface_to_real_interface_name($interface) { global $config; $lc_interface = strtolower($interface); if($lc_interface == "lan") return $config['interfaces']['lan']['if']; if($lc_interface == "wan") return $config['interfaces']['wan']['if']; $i = 0; $ifdescrs = array(); for ($j = 1; isset($config['interfaces']['opt' . $j]); $j++) $ifdescrs['opt' . $j] = "opt" . $j; foreach ($ifdescrs as $ifdescr => $ifname) { if(strtolower($ifname) == $lc_interface) return $config['interfaces'][$ifname]['if']; if(strtolower($config['interfaces'][$ifname]['descr']) == $lc_interface) return $config['interfaces'][$ifname]['if']; } return $interface; } /* * convert_real_interface_to_friendly_interface_name($interface): convert fxp0 -> wan, etc. */ function convert_real_interface_to_friendly_interface_name($interface) { global $config; $i = 0; $ifdescrs = array('wan', 'lan'); for ($j = 1; isset($config['interfaces']['opt' . $j]); $j++) $ifdescrs['opt' . $j] = "opt" . $j; foreach ($ifdescrs as $ifdescr => $ifname) { $int = filter_translate_type_to_real_interface($ifname); if($ifname == $interface) return $ifname; if($int == $interface) return $ifname; } return $interface; } /* * update_progress_bar($percent): updates the javascript driven progress bar. */ function update_progress_bar($percent) { if($percent > 100) $percent = 1; echo "\n"; } /* * resync_all_package_configs() Force packages to setup their configuration and rc.d files. * This function may also print output to the terminal indicating progress. */ function resync_all_package_configs($show_message = false) { global $config; $i = 0; log_error("Resyncing configuration for all packages."); if(!$config['installedpackages']['package']) return; if($show_message == true) print "Syncing packages:"; foreach($config['installedpackages']['package'] as $package) { if($show_message == true) print " " . $package['name']; sync_package($i, true, true); $i++; } if($show_message == true) print ".\n"; } /* * sweep_package_processes(): Periodically kill a package's unnecessary processes * that may still be running (a server that does not automatically timeout, for example) */ function sweep_package_processes() { global $config; if(!$config['installedpackages']['package']) return; foreach($config['installedpackages']['package'] as $package) { $pkg_config = parse_xml_config_pkg("/usr/local/pkg/" . $package['configurationfile'], "packagegui"); if($pkg_config['swept_processes'] <> "") { mwexec("/usr/bin/killall " . $pkg_config['swept_processes']); log_error("Killed " . $package['name'] . "'s unnecessary processes."); } } } /* * gather_altq_queue_stats(): gather alq queue stats and return an array that * is queuename|qlength|measured_packets * NOTE: this command takes 5 seconds to run */ function gather_altq_queue_stats($dont_return_root_queues) { mwexec("/usr/bin/killall -9 pfctl"); $stats = `/sbin/pfctl -vvsq & /bin/sleep 5;/usr/bin/killall pfctl 2>/dev/null`; $stats_array = split("\n", $stats); $queue_stats = array(); foreach ($stats_array as $stats_line) { if (preg_match_all("/queue\s+(\w+)\s+/",$stats_line,$match_array)) $queue_name = $match_array[1][0]; if (preg_match_all("/measured:\s+.*packets\/s\,\s(.*)\s+\]/",$stats_line,$match_array)) $speed = $match_array[1][0]; if (preg_match_all("/borrows:\s+(.*)/",$stats_line,$match_array)) $borrows = $match_array[1][0]; if (preg_match_all("/suspends:\s+(.*)/",$stats_line,$match_array)) $suspends = $match_array[1][0]; if (preg_match_all("/dropped pkts:\s+(.*)/",$stats_line,$match_array)) $drops = $match_array[1][0]; if (preg_match_all("/measured:\s+(.*)packets/",$stats_line,$match_array)) { $measured = $match_array[1][0]; if($dont_return_root_queues == true) if(stristr($queue_name,"root_") == false) array_push($queue_stats, "{$queue_name}|{$speed}|{$measured}|{$borrows}|{$suspends}|{$drops}"); } } return $queue_stats; } /* * reverse_strrchr($haystack, $needle): Return everything in $haystack up to the *last* instance of $needle. * Useful for finding paths and stripping file extensions. */ function reverse_strrchr($haystack, $needle) { return strrpos($haystack, $needle) ? substr($haystack, 0, strrpos($haystack, $needle) +1 ) : false; } /* * get_pkg_depends($pkg_name, $filetype = ".xml", $format = "files", return_nosync = 1): Return a package's dependencies. * * $filetype = "all" || ".xml", ".tgz", etc. * $format = "files" (full filenames) || "names" (stripped / parsed depend names) * $return_nosync = 1 (return depends that have nosync set) | 0 (ignore packages with nosync) * */ function get_pkg_depends($pkg_name, $filetype = ".xml", $format = "files", $return_nosync = 1) { global $config; if(!is_numeric($pkg_name)) { $pkg_name = get_pkg_id($pkg_name); if($pkg_id == -1) return -1; // This package doesn't really exist - exit the function. } else { if(!isset($config['installedpackages']['package'][$pkg_id])) return; // No package belongs to the pkg_id passed to this function. } $package = $config['installedpackages']['package'][$pkg_id]; print '$package done.'; if(!file_exists("/usr/local/pkg/" . $package['configurationfile'])) { // If the package's config file doesn't exist, log an error and fetch it. log_error("Fetching missing configuration XML for " . $package['name']); mwexec("/usr/bin/fetch -o /usr/local/pkg/" . $package['configurationfile'] . " http://www.pfsense.com/packages/config/" . $package['configurationfile']); } $pkg_xml = parse_xml_config_pkg("/usr/local/pkg/" . $package['configurationfile'], "packagegui"); if($pkg_xml['additional_files_needed'] != "") { foreach($pkg_xml['additional_files_needed'] as $item) { if (($return_nosync == 0) && (isset($item['nosync']))) continue; // Do not return depends with nosync set if not required. $depend_file = substr(strrchr($item['item']['0'], '/'),1); // Strip URLs down to filenames. $depend_name = substr(substr($depend_file,0,strpos($depend_file,".")+1),0,-1); // Strip filename down to dependency name. if (($filetype != "all") && (!preg_match("/${filetype}/i", $depend_file))) continue; if ($item['prefix'] != "") { $prefix = $item['prefix']; } else { $prefix = "/usr/local/pkg/"; } if(!file_exists($prefix . $pkg_name)) { log_error("Fetching missing dependency (" . $depend_name . ") for " . $pkg_name); mwexec("/usr/local/bin/fetch -o " . $prefix . $depend_file . " " . $item['name']['0']); if($item['chmod'] != "") chmod($prefix . $depend_file, $item['chmod']); // Handle chmods. } switch ($format) { case "files": $depends[] = $depend_file; break; case "names": switch ($filetype) { case "all": if(preg_match("/\.xml/i", $depend_file)) { $depend_xml = parse_xml_config_pkg("/usr/local/pkg/" . $depend_file, "packagegui"); $depends[] = $depend_xml['name']; break; } else { $depends[] = $depend_name; // If this dependency isn't package XML, use the stripped filename. break; } case ".xml": $depend_xml = parse_xml_config_pkg("/usr/local/pkg/" . $depend_file, "packagegui"); $depends[] = $depend_xml['name']; break; default: $depends[] = $depend_name; // If we aren't looking for XML, use the stripped filename (it's all we have). break; } } } return $depends; } } /* * is_service_running($service_name): checks to see if a service is running. * if the service is running returns 1. */ function is_service_running($service_name) { $status = `/bin/ps ax | grep {$service_name} | grep -v grep`; $status_split = split("\n", $service_name); $counter = 0; foreach ($status_split as $ss) $counter++; if($counter > 0) return 1; return 0; } /* * backup_config_section($section): returns as an xml file string of * the configuration section */ function backup_config_section($section) { global $config; $new_section = &$config[$section]; /* generate configuration XML */ $xmlconfig = dump_xml_config($new_section, $section); $xmlconfig = str_replace("", "", $xmlconfig); return $xmlconfig; } /* * restore_config_section($section, new_contents): restore a configuration section, * and write the configuration out * to disk/cf. */ function restore_config_section($section, $new_contents) { global $config; $fout = fopen("{$g['tmp_path']}/tmpxml","w"); fwrite($fout, $new_contents); fclose($fout); $section_xml = parse_xml_config_pkg($g['tmp_path'] . "/tmpxml", $section); $config[$section] = &$section_xml; unlink($g['tmp_path'] . "/tmpxml"); write_config("Restored {$section} of config file (maybe from CARP partner)"); return; } /* * http_post($server, $port, $url, $vars): does an http post to a web server * posting the vars array. * written by nf@bigpond.net.au */ function http_post($server, $port, $url, $vars) { $user_agent = "Mozilla/4.0 (compatible; MSIE 5.5; Windows 98)"; $urlencoded = ""; while (list($key,$value) = each($vars)) $urlencoded.= urlencode($key) . "=" . urlencode($value) . "&"; $urlencoded = substr($urlencoded,0,-1); $content_length = strlen($urlencoded); $headers = "POST $url HTTP/1.1 Accept: */* Accept-Language: en-au Content-Type: application/x-www-form-urlencoded User-Agent: $user_agent Host: $server Connection: Keep-Alive Cache-Control: no-cache Content-Length: $content_length "; $fp = fsockopen($server, $port, $errno, $errstr); if (!$fp) { return false; } fputs($fp, $headers); fputs($fp, $urlencoded); $ret = ""; while (!feof($fp)) $ret.= fgets($fp, 1024); fclose($fp); return $ret; } /* * php_check_syntax($code_tocheck, $errormessage): checks $code_to_check for errors */ if (!function_exists('php_check_syntax')){ function php_check_syntax($code_to_check, &$errormessage){ return false; $fout = fopen("/tmp/codetocheck.php","w"); $code = $_POST['content']; $code = str_replace("", "", $code); fwrite($fout, "\n"); fclose($fout); $command = "/usr/local/bin/php -l /tmp/codetocheck.php"; $output = exec_command($command); if (stristr($output, "Errors parsing") == false) { echo "false\n"; $errormessage = ''; return(false); } else { $errormessage = $output; return(true); } } } /* * php_check_filename_syntax($filename, $errormessage): checks the file $filename for errors */ if (!function_exists('php_check_syntax')){ function php_check_syntax($code_to_check, &$errormessage){ return false; $command = "/usr/local/bin/php -l " . $code_to_check; $output = exec_command($command); if (stristr($output, "Errors parsing") == false) { echo "false\n"; $errormessage = ''; return(false); } else { $errormessage = $output; return(true); } } } /* * sync_package($pkg_name, $sync_depends = true, $show_message = false) Force a package to setup its configuration and rc.d files. */ function sync_package($pkg_name, $sync_depends = true, $show_message = false) { global $config; if(!file_exists("/usr/local/pkg")) mwexec("/bin/mkdir -p /usr/local/pkg/pf"); if(!$config['installedpackages']['package']) return; if(!is_numeric($pkg_name)) { $pkg_id = get_pkg_id($pkg_name); if($pkg_id == -1) return -1; // This package doesn't really exist - exit the function. } else { $pkg_id = $pkg_name; if(!isset($config['installedpackages']['package'][$pkg_id])) return; // No package belongs to the pkg_id passed to this function. } $package = $config['installedpackages']['package'][$pkg_id]; if(!file_exists("/usr/local/pkg/" . $package['configurationfile'])) { //if($show_message == true) print "(f)"; Don't mess with this until the package system has settled. log_error("Fetching missing configuration XML for " . $package['name']); mwexec("/usr/bin/fetch -o /usr/local/pkg/" . $package['configurationfile'] . " http://www.pfsense.com/packages/config/" . $package['configurationfile']); } $pkg_config = parse_xml_config_pkg("/usr/local/pkg/" . $package['configurationfile'], "packagegui"); if(isset($pkg_config['nosync'])) continue; //if($show_message == true) print "Syncing " . $pkg_name; if($pkg['custom_php_global_functions'] <> "") eval($pkg['custom_php_global_functions']); if($pkg_config['custom_php_command_before_form'] <> "") eval($pkg_config['custom_php_command_before_form']); if($pkg_config['custom_php_resync_config_command'] <> "") eval($pkg_config['custom_php_resync_config_command']); if($sync_depends == true) { $depends = get_pkg_depends($pkg_name, ".xml", "files", 1); // Call dependency handler and do a little more error checking. if(is_array($depends)) { foreach($depends as $item) { $item_config = parse_xml_config_pkg("/usr/local/pkg/" . $item, "packagegui"); if(isset($item_config['nosync'])) continue; if($item_config['custom_php_command_before_form'] <> "") { eval($item_config['custom_php_command_before_form']); print "Evaled dependency."; } if($item_config['custom_php_resync_config_command'] <> "") { eval($item_config['custom_php_resync_config_command']); print "Evaled dependency."; } if($show_message == true) print " " . $item_config['name']; } } } // if($show_message == true) print "."; } /* * rmdir_recursive($path,$follow_links=false) * Recursively remove a directory tree (rm -rf path) * This is for directories _only_ */ function rmdir_recursive($path,$follow_links=false) { $to_do = glob($path); if(!is_array($to_do)) { if(file_exists($to_do)) { $dir = opendir($path); while ($entry = readdir($dir)) { if (is_file("$path/$entry") || ((!$follow_links) && is_link("$path/$entry"))) unlink("$path/$entry"); elseif (is_dir("$path/$entry") && $entry!='.' && $entry!='..') rmdir_recursive("$path/$entry"); } closedir($dir); rmdir($path); return; } } else { foreach($to_do as $workingdir) { // Handle wildcards by foreaching. if(file_exists($workingdir)) { $dir = opendir($workingdir); while ($entry = readdir($dir)) { if (is_file("$workingdir/$entry") || ((!$follow_links) && is_link("$workingdir/$entry"))) unlink("$workingdir/$entry"); elseif (is_dir("$workingdir/$entry") && $entry!='.' && $entry!='..') rmdir_recursive("$workingdir/$entry"); } closedir($dir); rmdir($workingdir); } } return; } return; } /* * safe_mkdir($path, $mode = 0755) * create directory if it doesn't already exist and isn't a file! */ function safe_mkdir($path, $mode=0755) { if (!is_file($path) && !is_dir($path)) return mkdir($path, $mode); else return false; } /* * make_dirs($path, $mode = 0755) * create directory tree recursively (mkdir -p) */ function make_dirs($path, $mode = 0755) { return is_dir($path) || (make_dirs(dirname($path), $mode) && safe_mkdir($path, $mode)); } /****f* pfsense-utils/auto_upgrade * NAME * auto_upgrade - pfSense autoupdate handler. * FUNCTION * Begin the pfSense autoupdate process. This function calls check_firmware_version to get * a list of current versions and then loops through them, applying binary diffs etc. * RESULT * null * BUGS * This function needs to have logic in place to automatically switch over to full updates * if a certain amount of binary diffs do not apply successfully. * SEE ALSO * pfsense.utils/check_firmware_version ******/ function auto_upgrade() { global $config, $g; if (isset($config['system']['alt_firmware_url']['enabled'])) { $firmwareurl=$config['system']['alt_firmware_url']['firmware_base_url']; $firmwarepath=$config['system']['alt_firmware_url']['firmware_filename']; } else { $firmwareurl=$g['firmwarebaseurl']; $firmwarepath=$g['firmwarefilename']; } if($config['system']['proxy_auth_username'] <> "") $http_auth_username = $config['system']['proxy_auth_username']; if($config['system']['proxy_auth_password'] <> "") $http_auth_password = $config['system']['proxy_auth_password']; if (isset($config['system']['alt_firmware_url']['enabled'])) { $firmwareurl=$config['system']['alt_firmware_url']['firmware_base_url']; $firmwarename=$config['system']['alt_firmware_url']['firmware_filename']; } else { $firmwareurl=$g['firmwarebaseurl']; $firmwarename=$g['firmwarefilename']; } exec_rc_script_async("/etc/rc.firmware_auto {$firmwareurl} {$firmwarename} {$http_auth_username} {$http_auth_password}"); return; } /* * check_firmware_version(): Check whether the current firmware installed is the most recently released. */ function check_firmware_version($tocheck = "all", $return_php = true) { global $g; $versioncheck_base_url = $g['versioncheckbaseurl']; $versioncheck_path = $g['versioncheckpath']; if(isset($config['system']['alt_firmware_url']['enabled']) and isset($config['system']['alt_firmware_url']['versioncheck_base_url'])) { $versioncheck_base_url = $config['system']['alt_firmware_url']['versioncheck_base_url']; } $rawparams = array("firmware" => array("version" => trim(file_get_contents('/etc/version'))), "kernel" => array("version" => trim(file_get_contents('/etc/version_kernel'))), "base" => array("version" => trim(file_get_contents('/etc/version_base'))), "platform" => trim(file_get_contents('/etc/platform')) ); if($tocheck = "all") { $params = $rawparams; } else { foreach($tocheck as $check) { $params['check'] = $rawparams['check']; $params['platform'] = $rawparams['platform']; } } if(isset($config['system']['firmwarebranch'])) { $params['branch'] = $config['system']['firmwarebranch']; } $xmlparams = php_value_to_xmlrpc($params); $msg = new XML_RPC_Message('pfsense.get_firmware_version', array($xmlparams)); $cli = new XML_RPC_Client($versioncheck_path, $versioncheck_base_url); $resp = $cli->send($msg, 10); if(!$resp or $resp->faultCode()) { $raw_versions = false; } else { $raw_versions = xmlrpc_value_to_php($resp->value()); $raw_versions["current"] = $params; } return $raw_versions; } function pkg_fetch_recursive($pkgname, $filename, $dependlevel = 0, $base_url = 'http://ftp2.freebsd.org/pub/FreeBSD/ports/i386/packages-5.4-release/Latest') { global $pkgent, $static_status, $static_output, $g, $fd_log; $pkg_extension = strrchr($filename, '.'); $static_output .= "\n" . str_repeat(" ", $dependlevel * 2) . $pkgname . " "; $fetchto = "/tmp/apkg_" . $pkgname . $pkg_extension; download_file_with_progress_bar($base_url . "/" . $filename, $fetchto); // update_output_window($static_output . "\n\n" . $pkg_progress); exec("/usr/bin/bzcat {$fetchto} | /usr/bin/tar -O -f - -x +CONTENTS", $slaveout); $workingdir = preg_grep("/instmp/", $slaveout); $workingdir = $workingdir[0]; $raw_depends_list = array_values(preg_grep("/\@pkgdep/", $slaveout)); if($raw_depends_list != "") { if($pkgent['exclude_dependency'] != "") $raw_depends_list = array_values(preg_grep($pkent['exclude_dependency'], PREG_GREP_INVERT)); foreach($raw_depends_list as $adepend) { $working_depend = explode(" ", $adepend); //$working_depend = explode("-", $working_depend[1]); $depend_filename = $working_depend[1] . $pkg_extension; exec("ls /var/db/pkg", $is_installed); $pkg_installed = false; foreach($is_installed as $is_inst) { if($is_inst == $working_depend[1]) { $pkg_installed = true; break; } } // $is_installed = array_values(preg_grep("/\b{$working_depend[0]}\b/i", $is_installed)); if($pkg_installed === false) { pkg_fetch_recursive($working_depend[1], $depend_filename, $dependlevel + 1, $base_url); } else { $dependlevel++; $static_output .= "\n" . str_repeat(" ", $dependlevel * 2) . $working_depend[1] . " "; fwrite($fd_log, $working_depend[1] . "\n"); } } } exec("cat {$g['tmp_path']}/y | /usr/sbin/pkg_add -fv {$fetchto} 2>&1", $pkgaddout); fwrite($fd_log, $pkgname . " " . print_r($pkgaddout, true) . "\n"); return true; } function download_file_with_progress_bar($url_file, $destination_file) { global $ch, $fout, $file_size, $downloaded, $counter; $file_size = 1; $downloaded = 1; /* open destination file */ $fout = fopen($destination_file, "wb"); /* Originally by Author: Keyvan Minoukadeh Modified by Scott Ullrich to return Content-Length size */ $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url_file); curl_setopt($ch, CURLOPT_HEADERFUNCTION, 'read_header'); curl_setopt($ch, CURLOPT_WRITEFUNCTION, 'read_body'); curl_setopt($ch, CURLOPT_NOPROGRESS, '1'); curl_exec($ch); fclose($fout); curl_close($ch); return 1; } function read_header($ch, $string) { global $file_size, $ch, $fout; $length = strlen($string); ereg("(Content-Length:) (.*)", $string, $regs); if($regs[2] <> "") { $file_size = intval($regs[2]); } return $length; } function read_body($ch, $string) { global $fout, $file_size, $downloaded, $counter, $sendto, $static_output, $lastseen; $length = strlen($string); $downloaded += intval($length); $downloadProgress = round(100 * (1 - $downloaded / $file_size), 0); $downloadProgress = 100 - $downloadProgress; /* lastseen is used to prevent from spamming firefox with hundreds of unnecessary javascript update messages which sends the clients firefox utilization to 100% */ if($lastseen <> $downloadProgress and $downloadProgress < 101) { if($sendto == "status") { $tostatus = $static_status . $downloadProgress . "%"; update_status($tostatus); } else { $tooutput = $static_output . $downloadProgress . "%"; update_output_window($tooutput); } update_progress_bar($downloadProgress); $lastseen = $downloadProgress; } fwrite($fout, $string); return $length; } ?>