private function parseSysLog() { /* * For parsing the syslog looking for sensord entries * POTENTIALLY BUGGY -- only tested on debian/ubuntu flavored syslogs * Also slow as balls as it parses the entire syslog instead of * using something like tail */ $file = '/var/log/syslog'; if (!is_file($file) || !is_readable($file)) { return array(); } $devices = array(); foreach (Common::getLines($file) as $line) { if (preg_match('/\\w+\\s*\\d+ \\d{2}:\\d{2}:\\d{2} \\w+ sensord:\\s*(.+):\\s*(.+)/i', trim($line), $match) == 1) { // Replace current record of dev with updated temp $devices[$match[1]] = $match[2]; } } $return = array(); foreach ($devices as $dev => $stat) { $return[] = array('path' => 'N/A', 'name' => $dev, 'temp' => $stat, 'unit' => ''); } return $return; }
/** * Do the job. */ public function work() { $t = new Timer('dnsmasq leases extension'); foreach (Common::getLines($this->_leases_file) as $line) { if (!preg_match('/^(\\d+) ([a-z0-9:]+) (\\S+) (\\S+)/', $line, $m)) { continue; } $this->_leases[] = array_combine(array('lease_end', 'mac', 'ip', 'hostname'), array_slice($m, 1)); } }
private function _call() { $this->_res = array(); foreach ($this->_servers as $name => $path) { $lines = Common::getLines($path); if (count($lines) == 0) { continue; } $info = self::readgamestat($lines); $this->_res[] = array('name' => $name, 'info' => $info); } }
public function indexAction() { try { $settings = Common::getVarFromFile($this->linfoHome . 'sample.config.inc.php', 'settings'); $settings["compress_content"] = false; $linfo = new Linfo($settings); $linfo->scan(); $output = new \Linfo\Output\Html($linfo); $output->output(); } catch (FatalException $e) { echo $e->getMessage() . "\n"; exit(1); } $this->removeViewRenderer(); }
private function _call() { // Time this $t = new Timer('CUPS extension'); // Deal with calling it try { $result = $this->_CallExt->exec('lpstat', '-p -o -l'); } catch (Exception $e) { // messed up somehow $this->_LinfoError->add('CUPS Extension', $e->getMessage()); $this->_res = false; // Don't bother going any further return false; } // Split it into lines $lines = explode("\n", $result); // Hold temporarily values here $printers = array(); $queue = array(); $begin_queue_list = false; // Go through it line by line for ($i = 0, $num = count($lines); $i < $num; ++$i) { // So regexes don't break on endlines $lines[$i] = trim($lines[$i]); // If there are no entries, don't waste time and end here if ($lines[$i] == 'no entries') { break; } elseif (preg_match('/^printer (.+) is idle\\. (.+)$/', $lines[$i], $printers_match) == 1) { $printers[] = array('name' => str_replace('_', ' ', $printers_match[1]), 'status' => $printers_match[2]); } elseif (preg_match('/^(.+)+ is (ready|ready and printing|not ready)$/', $lines[$i], $printers_match) == 1) { $printers[] = array('name' => str_replace('_', ' ', $printers_match[1]), 'status' => $printers_match[2]); } elseif (preg_match('/^Rank\\s+Owner\\s+Job\\s+File\\(s\\)\\s+Total Size$/', $lines[$i])) { $begin_queue_list = true; } elseif ($begin_queue_list && preg_match('/^([a-z0-9]+)\\s+(\\S+)\\s+(\\d+)\\s+(.+)\\s+(\\d+) bytes$/', $lines[$i], $queue_match)) { $queue[] = array('rank' => $queue_match[1], 'owner' => $queue_match[2], 'job' => $queue_match[3], 'files' => $queue_match[4], 'size' => Common::byteConvert($queue_match[5])); } } // Save result lset $this->_res = array('printers' => $printers, 'queue' => $queue); // Apparent success return true; }
public function output() { // Gain access to translations $lang = $this->linfo->getLang(); // And info $this->linfo->scan(); $info = $this->linfo->getInfo(); // Say we're called more than once. Kill previous remnants if (count($this->_windows) > 0) { $this->_kill_windows(); } // Get dimensions and give lovely header text $fullscreen = ncurses_newwin(0, 0, 0, 0); ncurses_wrefresh($fullscreen); ncurses_getmaxyx($fullscreen, $x, $y); ncurses_mvwaddstr($fullscreen, 0, 0, 'Generated by ' . $this->linfo->getAppName() . ' (' . $this->linfo->getVersion() . ') (ncurses) on ' . date('m/d/Y @ h:i:s A (T)')); ncurses_wrefresh($fullscreen); $this->_max_dims = array($x, $y); // Some important windows $core_wins = array(array('name' => $lang['core'], 'content' => array(array($lang['os'], $info['OS']), array_key_exists('Distro', $info) ? array($lang['distro'], $info['Distro']['name'] . ($info['Distro']['version'] ? ' ' . $info['Distro']['version'] : '')) : false, array($lang['kernel'], $info['Kernel']), array_key_exists('Model', $info) && !empty($info['Model']) ? array($lang['model'], $info['Model']) : false, array($lang['uptime'], str_ireplace(array(' ', 'days', 'minutes', 'hours', 'seconds'), array('', 'd', 'm', 'h', 's'), $info['UpTime']['text'])), array($lang['hostname'], $info['HostName']), array_key_exists('CPUArchitecture', $info) ? array($lang['cpu_arch'], $info['CPUArchitecture']) : false, array($lang['load'], implode(' ', (array) $info['Load'])))), array('name' => $lang['memory'], 'content' => array(array($lang['size'], Common::byteConvert($info['RAM']['total'])), array($lang['used'], Common::byteConvert($info['RAM']['total'] - $info['RAM']['free'])), array($lang['free'], Common::byteConvert($info['RAM']['free']))))); // Show them $h = 1; foreach ($core_wins as $win) { list($width, $height) = $this->_window_with_lines($win['name'], $win['content'], $h, 0); $h += $height + 1; } // Makeshift event loop while (true) { // Die on input $getch = ncurses_getch(); if ($getch > 0 && $getch == 113) { $this->__destruct(); echo "\nEnding at your request.\n"; // exit(0); } // Stop temporariy ncurses_napms(1000); // Call ourselves $this->output(); } }
public function ensureFQDN($hostname) { $parts = explode('.', $hostname); $num_parts = count($parts); // Already FQDN, like a boss.. if ($num_parts >= 2) { return $hostname; } // Don't bother trying to expand on .local if ($num_parts > 0 && $parts[$num_parts - 1] == '.local') { return $hostname; } // This relies on reading /etc/hosts. if (!($contents = Common::getContents('/etc/hosts', false))) { return $hostname; } preg_match_all('/^[^\\s#]+\\s+(.+)/m', $contents, $matches, PREG_SET_ORDER); // Lets see if we can do some magic with /etc/hosts.. foreach ($matches as $match) { if (!preg_match_all('/(\\S+)/', $match[1], $hosts, PREG_SET_ORDER)) { continue; } foreach ($hosts as $host) { // I don't want to expand on localhost as it's pointlesss if (strpos('localhost', $host[1]) !== false) { continue; } $entry_parts = explode('.', $host[1]); if (count($entry_parts) > 1 && $entry_parts[0] == $hostname) { return $host[1]; } } } // Couldn't make it better :/ return $hostname; }
protected function loadSettings($settings = array()) { // Running unit tests? if (defined('LINFO_TESTING')) { $this->settings = Common::getVarFromFile($this->linfo_testdir . '/test_settings.php', 'settings'); if (!is_array($this->settings)) { throw new FatalException('Failed getting test-specific settings'); } return; } // Don't just blindly assume we have the ob_* functions... if (!function_exists('ob_start')) { $settings['compress_content'] = false; } if (!isset($settings['hide'])) { $settings['hide'] = array('filesystems' => array(), 'storage_devices' => array()); } // Make sure these are arrays $settings['hide']['filesystems'] = is_array($settings['hide']['filesystems']) ? $settings['hide']['filesystems'] : array(); $settings['hide']['storage_devices'] = is_array($settings['hide']['storage_devices']) ? $settings['hide']['storage_devices'] : array(); // Make sure these are always hidden $settings['hide']['filesystems'][] = 'rootfs'; $settings['hide']['filesystems'][] = 'binfmt_misc'; // Default timeformat $settings['dates'] = array_key_exists('dates', $settings) ? $settings['dates'] : 'm/d/y h:i A (T)'; // Default to english translation if garbage is passed if (empty($settings['language']) || !preg_match('/^[a-z]{2}$/', $settings['language'])) { $settings['language'] = 'en'; } // If it can't be found default to english if (!is_file($this->linfo_localdir . 'src/Linfo/Lang/' . $settings['language'] . '.php')) { $settings['language'] = 'en'; } $this->settings = $settings; }
public function getUpTime() { // Time? if (!empty($this->settings['timer'])) { $t = new Timer('Uptime'); } // Use sysctl $booted = strtotime($this->sysctl['kern.boottime']); // Give it return array('text' => Common::secondsConvert(time() - $booted), 'bootedTimestamp' => $booted); }
public function result() { if (!$this->res) { return false; } $rows[] = array('type' => 'header', 'columns' => array('Torrent/hash' . ($this->hideName ? ' (names hidden)' : ''), 'Size', 'Progress', 'Status', 'Seeds', 'Peers', 'Downloaded', 'Uploaded', 'Ratio', 'Speeds')); foreach ($this->torrents as $name => $info) { $rows[] = array('type' => 'values', 'columns' => array(($this->hideName ? '' : $info['TORRENT_NAME'] . '<br />') . '<span style="font-size: 80%; font-family: monaco, monospace, courier;">' . $info['TORRENT_HASH'] . '</span>', Common::byteConvert($info['TORRENT_SIZE']), Html::generateBarChart($info['TORRENT_PROGRESS'] / 10), $info['TORRENT_STATUS_MESSAGE'], $info['TORRENT_SEEDS_CONNECTED'] . '/' . $info['TORRENT_SEEDS_SWARM'], $info['TORRENT_SEEDS_CONNECTED'] . '/' . $info['TORRENT_PEERS_SWARM'], Common::byteConvert($info['TORRENT_DOWNLOADED']), Common::byteConvert($info['TORRENT_UPLOADED']), $info['TORRENT_RATIO'] > 0 ? round($info['TORRENT_RATIO'] / 1000, 2) ?: '0.0' : '0.0', Common::byteConvert($info['TORRENT_DOWNSPEED']) . '/s ↓ ' . Common::byteConvert($info['TORRENT_UPSPEED']) . '/s ↑ ')); } // Give it off return array('root_title' => 'µTorrent <span style="font-size: 80%;">(' . Common::byteConvert($this->stats['downloaded']) . ' ↓ ' . Common::byteConvert($this->stats['uploaded']) . ' ↑ ' . round($this->stats['uploaded'] / $this->stats['downloaded'], 2) . ' ratio)</span>', 'rows' => $rows); }
public static function tearDownAfterClass() { self::$linfo = null; Common::unconfig(); }
public function output() { $lang = $this->linfo->getLang(); $settings = $this->linfo->getSettings(); $info = $this->linfo->getInfo(); try { // Start it up $xml = new SimpleXMLElement('<?xml version="1.0"?><linfo></linfo>'); // Deal with core stuff $core_elem = $xml->addChild('core'); $core = array(); if (!empty($settings['show']['os'])) { $core[] = array('os', $info['OS']); } if (!empty($settings['show']['distro']) && isset($info['Distro']) && is_array($info['Distro'])) { $core[] = array('distro', $info['Distro']['name'] . ($info['Distro']['version'] ? ' - ' . $info['Distro']['version'] : '')); } if (!empty($settings['show']['kernel'])) { $core[] = array('kernel', $info['Kernel']); } if (!empty($settings['show']['webservice'])) { $core[] = array('webservice', $info['webService']); } if (!empty($settings['show']['phpversion'])) { $core[] = array('phpversion', $info['phpVersion']); } if (!isset($settings['show']['ip']) || !empty($settings['show']['ip'])) { $core[] = array('accessed_ip', isset($_SERVER['SERVER_ADDR']) ? $_SERVER['SERVER_ADDR'] : 'Unknown'); } if (!empty($settings['show']['uptime'])) { $core[] = array('uptime', $info['UpTime']['text']); } if (!empty($settings['show']['hostname'])) { $core[] = array('hostname', $info['HostName']); } if (!empty($settings['show']['cpu'])) { $cpus = ''; foreach ((array) $info['CPU'] as $cpu) { $cpus .= (array_key_exists('Vendor', $cpu) && empty($cpu['Vendor']) ? $cpu['Vendor'] . ' - ' : '') . $cpu['Model'] . (array_key_exists('MHz', $cpu) ? $cpu['MHz'] < 1000 ? ' (' . $cpu['MHz'] . ' MHz)' : ' (' . round($cpu['MHz'] / 1000, 3) . ' GHz)' : '') . '<br />'; } $core[] = array('cpus', $cpus); } if (!empty($settings['show']['model']) && array_key_exists('Model', $info) && !empty($info['Model'])) { $core[] = array('model', $info['Model']); } if (!empty($settings['show']['process_stats']) && $info['processStats']['exists']) { $proc_stats = array(); if (array_key_exists('totals', $info['processStats']) && is_array($info['processStats']['totals'])) { foreach ($info['processStats']['totals'] as $k => $v) { $proc_stats[] = $k . ': ' . number_format($v); } } $proc_stats[] = 'total: ' . number_format($info['processStats']['proc_total']); $core[] = array('processes', implode('; ', $proc_stats)); if ($info['processStats']['threads'] !== false) { $core[] = array('threads', number_format($info['processStats']['threads'])); } } if (!empty($settings['show']['load'])) { $core[] = array('load', implode(' ', (array) $info['Load'])); } // Adding each core stuff for ($i = 0, $core_num = count($core); $i < $core_num; ++$i) { $core_elem->addChild($core[$i][0], $core[$i][1]); } // RAM if (!empty($settings['show']['ram'])) { $mem = $xml->addChild('memory'); $core_mem = $mem->addChild($info['RAM']['type']); $core_mem->addChild('free', $info['RAM']['free']); $core_mem->addChild('total', $info['RAM']['total']); $core_mem->addChild('used', $info['RAM']['total'] - $info['RAM']['free']); if (isset($info['RAM']['swapFree']) || isset($info['RAM']['swapTotal'])) { $swap = $mem->addChild('swap'); $swap_core = $swap->addChild('core'); $swap_core->addChild('free', $info['RAM']['swapFree']); $swap_core->addChild('total', $info['RAM']['swapTotal']); $swap_core->addChild('used', $info['RAM']['swapTotal'] - $info['RAM']['swapFree']); if (is_array($info['RAM']['swapInfo']) && count($info['RAM']['swapInfo']) > 0) { $swap_devices = $swap->addChild('devices'); foreach ($info['RAM']['swapInfo'] as $swap_dev) { $swap_dev_elem = $swap_devices->addChild('device'); $swap_dev_elem->addAttribute('device', $swap_dev['device']); $swap_dev_elem->addAttribute('type', $swap_dev['type']); $swap_dev_elem->addAttribute('size', $swap_dev['size']); $swap_dev_elem->addAttribute('used', $swap_dev['used']); } } } } // NET if (!empty($settings['show']['network']) && isset($info['Network Devices']) && is_array($info['Network Devices'])) { $net = $xml->addChild('net'); foreach ($info['Network Devices'] as $device => $stats) { $nic = $net->addChild('interface'); $nic->addAttribute('device', $device); $nic->addAttribute('type', $stats['type']); $nic->addAttribute('sent', $stats['sent']['bytes']); $nic->addAttribute('recieved', $stats['recieved']['bytes']); } } // TEMPS if (!empty($settings['show']['temps']) && isset($info['Temps']) && count($info['Temps']) > 0) { $temps = $xml->addChild('temps'); foreach ($info['Temps'] as $stat) { $temp = $temps->addChild('temp'); $temp->addAttribute('path', $stat['path']); $temp->addAttribute('name', $stat['name']); $temp->addAttribute('temp', $stat['temp'] . ' ' . $stat['unit']); } } // Batteries if (!empty($settings['show']['battery']) && isset($info['Battery']) && count($info['Battery']) > 0) { $bats = $xml->addChild('batteries'); foreach ($info['Battery'] as $bat) { $bat = $bats->addChild('battery'); $bat->addAttribute('device', $bat['device']); $bat->addAttribute('state', $bat['state']); $bat->addAttribute('percentage', $bat['percentage']); } } // SERVICES if (!empty($settings['show']['services']) && isset($info['services']) && count($info['services']) > 0) { $services = $xml->addChild('services'); foreach ($info['services'] as $service => $state) { $state_parts = explode(' ', $state['state'], 2); $service_elem = $services->addChild('service'); $service_elem->addAttribute('name', $service); $service_elem->addAttribute('state', $state_parts[0] . (array_key_exists(1, $state_parts) ? ' ' . $state_parts[1] : '')); $service_elem->addAttribute('pid', $state['pid']); $service_elem->addAttribute('threads', $state['threads'] ? $state['threads'] : '?'); $service_elem->addAttribute('mem_usage', $state['memory_usage'] ? $state['memory_usage'] : '?'); } } // DEVICES if (!empty($settings['show']['devices']) && isset($info['Devices'])) { $show_vendor = array_key_exists('hw_vendor', $info['contains']) ? $info['contains']['hw_vendor'] === false ? false : true : true; $devices = $xml->addChild('devices'); for ($i = 0, $num_devs = count($info['Devices']); $i < $num_devs; ++$i) { $device = $devices->addChild('device'); $device->addAttribute('type', $info['Devices'][$i]['type']); if ($show_vendor) { $device->addAttribute('vendor', $info['Devices'][$i]['vendor']); } $device->addAttribute('name', $info['Devices'][$i]['device']); } } // DRIVES if (!empty($settings['show']['hd']) && isset($info['HD']) && is_array($info['HD'])) { $show_stats = array_key_exists('drives_rw_stats', $info['contains']) ? $info['contains']['drives_rw_stats'] === false ? false : true : true; $drives = $xml->addChild('drives'); foreach ($info['HD'] as $drive) { $drive_elem = $drives->addChild('drive'); $drive_elem->addAttribute('device', $drive['device']); $drive_elem->addAttribute('vendor', $drive['vendor'] ? $drive['vendor'] : $lang['unknown']); $drive_elem->addAttribute('name', $drive['name']); if ($show_stats) { $drive_elem->addAttribute('reads', $drive['reads'] ? $drive['reads'] : 'unknown'); $drive_elem->addAttribute('writes', $drive['writes'] ? $drive['writes'] : 'unknown'); } $drive_elem->addAttribute('size', $drive['size'] ? $drive['size'] : 'unknown'); if (is_array($drive['partitions']) && count($drive['partitions']) > 0) { $partitions = $drive_elem->addChild('partitions'); foreach ($drive['partitions'] as $partition) { $partition_elem = $partitions->addChild('partition'); $partition_elem->addAttribute('name', isset($partition['number']) ? $drive['device'] . $partition['number'] : $partition['name']); $partition_elem->addAttribute('size', $partition['size']); } } } } // Sound cards? lol if (!empty($settings['show']['sound']) && isset($info['SoundCards']) && count($info['SoundCards']) > 0) { $cards = $xml->addChild('soundcards'); foreach ($info['SoundCards'] as $card) { $card_elem = $cards->addChild('card'); $card_elem->addAttribute('number', $card['number']); $card_elem->addAttribute('vendor', empty($card['vendor']) ? 'unknown' : $card['vendor']); $card_elem->addAttribute('card', $card['card']); } } // File system mounts if (!empty($settings['show']['mounts'])) { $has_devices = false; $has_labels = false; $has_types = false; foreach ($info['Mounts'] as $mount) { if (!empty($mount['device'])) { $has_devices = true; } if (!empty($mount['label'])) { $has_labels = true; } if (!empty($mount['devtype'])) { $has_types = true; } } $mounts = $xml->addChild('mounts'); foreach ($info['Mounts'] as $mount) { $mount_elem = $mounts->addChild('mount'); if (preg_match('/^.+:$/', $mount['device']) == 1) { $mount['device'] .= DIRECTORY_SEPARATOR; } if ($has_types) { $mount_elem->addAttribute('type', $mount['devtype']); } if ($has_devices) { $mount_elem->addAttribute('device', $mount['device']); } $mount_elem->addAttribute('mountpoint', $mount['mount']); if ($has_labels) { $mount_elem->addAttribute('label', $mount['label']); } $mount_elem->addAttribute('fstype', $mount['type']); if ($settings['show']['mounts_options'] && !empty($mount['options'])) { $mount_elem->addAttribute('options', implode(',', $mount['options'])); } $mount_elem->addAttribute('size', $mount['size']); $mount_elem->addAttribute('used', $mount['used']); $mount_elem->addAttribute('free', $mount['free']); } } // RAID arrays if (!empty($settings['show']['raid']) && isset($info['Raid']) && count($info['Raid']) > 0) { $raid_elem = $xml->addChild('raid'); foreach ($info['Raid'] as $raid) { $array = $raid_elem->addChild('array'); $active = explode('/', $raid['count']); $array->addAttribute('device', $raid['device']); $array->addAttribute('level', $raid['level']); $array->addAttribute('status', $raid['status']); $array->addAttribute('size', $raid['size']); $array->addAttribute('active', $active[1] . '/' . $active[0]); $drives = $array->addChild('drives'); foreach ($raid['drives'] as $drive) { $drive_elem = $drives->addChild('drive'); $drive_elem->addAttribute('drive', $drive['drive']); $drive_elem->addAttribute('state', $drive['state']); } } } // Timestamp $xml->addChild('timestamp', $info['timestamp']); // Extensions if (count($info['extensions']) > 0) { $extensions = $xml->addChild('extensions'); foreach ($info['extensions'] as $ext) { $header = false; if (is_array($ext) && count($ext) > 0) { $this_ext = $extensions->addChild(Common::xmlStringSanitize($ext['root_title'])); foreach ((array) $ext['rows'] as $i => $row) { if ($row['type'] == 'header') { $header = $i; } elseif ($row['type'] == 'values') { $this_row = $this_ext->addChild('row'); if ($header !== false && array_key_exists($header, $ext['rows'])) { foreach ($ext['rows'][$header]['columns'] as $ri => $rc) { $this_row->addChild(Common::xmlStringSanitize($rc), $ext['rows'][$i]['columns'][$ri]); } } } } } } } // Out it if (!headers_sent()) { header('Content-type: text/xml'); } echo $xml->asXML(); // Comment which has stats and generator echo '<!-- Generated in ' . round(microtime(true) - $this->linfo->getTimeStart(), 2) . ' seconds by ' . $this->linfo->getAppName() . ' (' . $this->linfo->getVersion() . ')-->'; } catch (Exception $e) { throw new FatalException('Creation of XML error: ' . $e->getMessage()); } }
/** * getUpTime. * * @return string uptime */ public function getUpTime() { // Time? if (!empty($this->settings['timer'])) { $t = new Timer('Uptime'); } $booted_str = ''; foreach ($this->wmi->ExecQuery('SELECT LastBootUpTime FROM Win32_OperatingSystem') as $os) { $booted_str = $os->LastBootUpTime; break; } $booted = array('year' => substr($booted_str, 0, 4), 'month' => substr($booted_str, 4, 2), 'day' => substr($booted_str, 6, 2), 'hour' => substr($booted_str, 8, 2), 'minute' => substr($booted_str, 10, 2), 'second' => substr($booted_str, 12, 2)); $booted_ts = mktime($booted['hour'], $booted['minute'], $booted['second'], $booted['month'], $booted['day'], $booted['year']); return array('text' => Common::secondsConvert(time() - $booted_ts), 'bootedTimestamp' => $booted_ts); }
public function getUpTime() { // Time? if (!empty($this->settings['timer'])) { $t = new Timer('Uptime'); } // Extract boot part of it if (preg_match('/^\\{ sec \\= (\\d+).+$/', $this->sysctl['kern.boottime'], $m) == 0) { return ''; } return array('text' => Common::secondsConvert(time() - $m[1]), 'bootedTimestamp' => $m[1]); }
private function _call() { // Time this $t = new Timer('apcaccess Extension'); // Deal with calling it try { $result = $this->_CallExt->exec('apcaccess'); } catch (Exception $e) { // messed up somehow Errors::add('apcaccess Extension', $e->getMessage()); $this->_res = false; // Don't bother going any further return false; } // Store them here $this->_res = array(); // Get name if (preg_match('/^UPSNAME\\s+:\\s+(.+)$/m', $result, $m)) { $this->_res['name'] = $m[1]; } // Get model if (preg_match('/^MODEL\\s+:\\s+(.+)$/m', $result, $m)) { $this->_res['model'] = $m[1]; } // Get battery voltage if (preg_match('/^BATTV\\s+:\\s+(\\d+\\.\\d+)/m', $result, $m)) { $this->_res['volts'] = $m[1]; } // Get charge percentage, and get it cool if (preg_match('/^BCHARGE\\s+:\\s+(\\d+(?:\\.\\d+)?)/m', $result, $m)) { $charge = (int) $m[1]; $this->_res['charge'] = ' <div class="bar_chart"> <div class="bar_inner" style="width: ' . (int) $charge . '%;"> <div class="bar_text"> ' . ($charge ? $charge . '%' : '?') . ' </div> </div> </div> '; } // Get time remaning if (preg_match('/^TIMELEFT\\s+:\\s+([\\d\\.]+)/m', $result, $m)) { $this->_res['time_left'] = Common::secondsConvert($m[1] * 60); } // Get status if (preg_match('/^STATUS\\s+:\\s+([A-Z]+)/m', $result, $m)) { $this->_res['status'] = $m[1] == 'ONBATT' ? 'On Battery' : ucfirst(strtolower($m[1])); } // Load percentage looking cool if (preg_match('/^LOADPCT\\s+:\\s+(\\d+\\.\\d+)/m', $result, $m)) { $load = (int) $m[1]; $this->_res['load'] = ' <div class="bar_chart"> <div class="bar_inner" style="width: ' . (int) $load . '%;"> <div class="bar_text"> ' . ($load ? $load . '%' : '?') . ' </div> </div> </div> '; } // Attempt getting wattage if (isset($load) && preg_match('/^NOMPOWER\\s+:\\s+(\\d+)/m', $result, $m)) { $watts = (int) $m['1']; $this->_res['watts_used'] = $load * round($watts / 100); } else { $this->_res['watts_used'] = false; } // Apparent success return true; }
/** * Get brand/name of motherboard/server through /sys' interface to dmidecode. */ public function getModel() { $info = array(); $vendor = Common::getContents('/sys/devices/virtual/dmi/id/board_vendor', false); $name = Common::getContents('/sys/devices/virtual/dmi/id/board_name', false); $product = Common::getContents('/sys/devices/virtual/dmi/id/product_name', false); if (!$name) { return false; } // Don't add vendor to the mix if the name starts with it if ($vendor && strpos($name, $vendor) !== 0) { $info[] = $vendor; } $info[] = $name; $infostr = implode(' ', $info); // product name is usually bullshit, but *occasionally* it's a useful name of the computer, such as // dell latitude e6500 or hp z260 if ($product && strpos($name, $product) === false && strpos($product, 'Filled') === false) { return $product . ' (' . $infostr . ')'; } else { return $infostr; } }
public function getUpTime() { $booted = $this->kstat['unix:0:system_misc:boot_time']; return array('text' => Common::secondsConvert(time() - $booted), 'bootedTimestamp' => $booted); }
/** * Deal with it. */ private function _call() { // Time this $t = new Timer('dhcpd3 leases extension'); // We couldn't find leases file? if ($this->_leases_file === false) { Errors::add('dhcpd3 leases extension', 'couldn\'t find leases file'); $this->_res = false; return; } // Get contents $contents = Common::getContents($this->_leases_file, false); // Couldn't? if ($contents === false) { Errors::add('dhcpd3 leases extension', 'Error getting contents of leases file'); $this->_res = false; return; } // All dates in the file are in UTC format. Attempt finding out local time zone to convert UTC to local. // This prevents confusing the hell out of people. $do_date_conversion = false; $local_timezone = false; // Make sure we have what we need. Stuff this requires doesn't exist on certain php installations if (function_exists('date_default_timezone_get') && class_exists('DateTime') && class_exists('DateTimeZone')) { // I only want this called once, hence value stored here. It also might fail $local_timezone = @date_default_timezone_get(); // Make sure it didn't fail if ($local_timezone !== false && is_string($local_timezone)) { $do_date_conversion = true; } // Say we'll allow conversion later on } // Get it into lines $lines = explode("\n", $contents); // Store temp entries here $curr = false; // Parse each line, while ignoring certain useless'ish values // I'd do a single preg_match_all() using multiline regex, but the values in each lease block are inconsistent. :-/ for ($i = 0, $num_lines = count($lines); $i < $num_lines; ++$i) { // Kill padding whitespace $lines[$i] = trim($lines[$i]); // Last line in entry if ($lines[$i] == '}') { // Have we a current entry to save? if (is_array($curr)) { $this->_leases[] = $curr; } // Make it empty for next time $curr = false; } elseif (preg_match('/^lease (\\d+\\.\\d+\\.\\d+\\.\\d+) \\{$/', $lines[$i], $m)) { $curr = array('ip' => $m[1]); } elseif ($curr && preg_match('/^starts \\d+ (\\d+\\/\\d+\\/\\d+ \\d+:\\d+:\\d+);$/', $lines[$i], $m)) { // Get it in unix time stamp for prettier formatting later and easier tz offset conversion $curr['lease_start'] = strtotime($m[1]); // Handle offset conversion if ($do_date_conversion) { // This handy class helps out with timezone offsets. Pass it original date, not unix timestamp $d = new DateTime($m[1], new DateTimeZone($local_timezone)); $offset = $d->getOffset(); // If ofset looks good, deal with it if (is_numeric($offset) && $offset != 0) { $curr['lease_start'] += $offset; } } } elseif ($curr && preg_match('/^ends \\d+ (\\d+\\/\\d+\\/\\d+ \\d+:\\d+:\\d+);$/', $lines[$i], $m)) { // Get it in unix time stamp for prettier formatting later and easier tz offset conversion $curr['lease_end'] = strtotime($m[1]); // Handle offset conversion if ($do_date_conversion) { // This handy class helps out with timezone offsets. Pass it original date, not unix timestamp $d = new DateTime($m[1], new DateTimeZone($local_timezone)); $offset = $d->getOffset(); // If ofset looks good, deal with it if (is_numeric($offset) && $offset != 0) { $curr['lease_end'] += $offset; } } // Is this old? // The file seems to contain all leases since the dhcpd server was started for the first time if (time() > $curr['lease_end']) { // Kill current entry and ignore any following parts of this lease $curr = false; // Jump out right now continue; } } elseif (!$this->_hide_mac && $curr && preg_match('/^hardware ethernet (\\w+:\\w+:\\w+:\\w+:\\w+:\\w+);$/', $lines[$i], $m)) { $curr['mac'] = $m[1]; } elseif ($curr && preg_match('/^client\\-hostname "([^"]+)";$/', $lines[$i], $m)) { $curr['hostname'] = $m[1]; } } }
/** * @test */ public function getLines() { $lines = array("lineone\n", "linetwo\n", "line3\n"); $file = LINFO_TESTDIR . '/files/lines.txt'; $this->assertEquals($lines, Common::getLines($file)); }
/** * Return result. * * @return false on failure|array of the torrents */ public function result() { // Don't bother if it didn't go well if ($this->_res === false) { return false; } // it did; continue // Store rows here $rows = array(); // Start showing connections $rows[] = array('type' => 'header', 'columns' => array('Torrent', array(1, 'Done', '10%'), 'State', 'Have', 'Uploaded', 'Time Left', 'Ratio', 'Up', 'Down')); // No torrents? if (count($this->_torrents) == 0) { $rows[] = array('type' => 'none', 'columns' => array(array(9, 'None found'))); } else { // Store a total amount of certain torrents here: $status_tally = array(); // As well as uploaded/downloaded $status_tally['Downloaded'] = 0; $status_tally['Uploaded'] = 0; $status_tally['Ratio'] = ''; // Go through each torrent foreach ($this->_torrents as $torrent) { // Status count tally $status_tally[$torrent['state']] = !array_key_exists($torrent['state'], $status_tally) ? 1 : $status_tally[$torrent['state']] + 1; // Make some sense of the have so we can get it into bytes, which we can then have fun with $have_bytes = false; if ($torrent['have'] != 'None') { $have_parts = explode(' ', $torrent['have'], 2); if (is_numeric($have_parts[0]) && $have_parts[0] > 0) { switch ($have_parts[1]) { case 'TiB': $have_bytes = (double) $have_parts[0] * 1099511627776.0; break; case 'GiB': $have_bytes = (double) $have_parts[0] * 1073741824; break; case 'MiB': $have_bytes = (double) $have_parts[0] * 1048576; break; case 'KiB': $have_bytes = (double) $have_parts[0] * 1024; break; } } } // Try getting amount uploaded, based upon ratio and exact amount downloaded above $uploaded_bytes = false; if (is_numeric($have_bytes) && $have_bytes > 0 && is_numeric($torrent['ratio']) && $torrent['ratio'] > 0) { $uploaded_bytes = $torrent['ratio'] * $have_bytes; } // Save amount uploaded/downloaded tally if (is_numeric($have_bytes) && $have_bytes > 0 && is_numeric($uploaded_bytes) && $uploaded_bytes > 0) { $status_tally['Downloaded'] += $have_bytes; $status_tally['Uploaded'] += $uploaded_bytes; } // Save result $rows[] = array('type' => 'values', 'columns' => array(wordwrap(htmlspecialchars($torrent['torrent']), 50, ' ', true), '<div class="bar_chart"> <div class="bar_inner" style="width: ' . (int) $torrent['done'] . '%;"> <div class="bar_text"> ' . ($torrent['done'] ? $torrent['done'] . '%' : '0%') . ' </div> </div> </div> ', $torrent['state'], $have_bytes !== false ? Common::byteConvert($have_bytes) : $torrent['have'], $uploaded_bytes !== false ? Common::byteConvert($uploaded_bytes) : 'None', $torrent['eta'], $torrent['ratio'], Common::byteConvert($torrent['up']) . '/s', Common::byteConvert($torrent['down']) . '/s')); } // Finish the size totals $status_tally['Ratio'] = $status_tally['Downloaded'] > 0 && $status_tally['Uploaded'] > 0 ? round($status_tally['Uploaded'] / $status_tally['Downloaded'], 2) : 'N/A'; $status_tally['Downloaded'] = $status_tally['Downloaded'] > 0 ? Common::byteConvert($status_tally['Downloaded']) : 'None'; $status_tally['Uploaded'] = $status_tally['Uploaded'] > 0 ? Common::byteConvert($status_tally['Uploaded']) : 'None'; // Create a row for the tally of statuses if (count($status_tally) > 0) { // Store list of k: v'ish values here $tally_contents = array(); // Populate that foreach ($status_tally as $state => $tally) { $tally_contents[] = "{$state}: {$tally}"; } // Save this final row $rows[] = array('type' => 'values', 'columns' => array(array(9, implode(', ', $tally_contents)))); } } // Handle stats which might not exist if (is_array($this->_stats) && array_key_exists('downloaded-bytes', $this->_stats) && array_key_exists('uploaded-bytes', $this->_stats) && array_key_exists('seconds-active', $this->_stats)) { $extra_vals = array('title' => 'Transmission Stats', 'values' => array(array('Total Downloaded', Common::byteConvert($this->_stats['downloaded-bytes'])), array('Total Uploaded', Common::byteConvert($this->_stats['uploaded-bytes'])), $this->_stats['uploaded-bytes'] > 0 && $this->_stats['downloaded-bytes'] > 0 ? array('Total Ratio', round($this->_stats['uploaded-bytes'] / $this->_stats['downloaded-bytes'], 3)) : false, array('Duration', Common::secondsConvert($this->_stats['seconds-active'])))); } else { $extra_vals = false; } // Give it off return array('root_title' => 'Transmission Torrents', 'rows' => $rows, 'extra_type' => 'k->v', 'extra_vals' => $extra_vals); }
public function output() { $lang = $this->linfo->getLang(); $settings = $this->linfo->getSettings(); $info = $this->linfo->getInfo(); $appName = $this->linfo->getAppName(); $version = $this->linfo->getVersion(); // Fun icons $show_icons = array_key_exists('icons', $settings) ? !empty($settings['icons']) : true; $os_icon = $info['OS'] == 'Windows' ? 'windows' : strtolower(str_replace(' ', '', current(explode('(', $info['OS'])))); $distro_icon = $info['OS'] == 'Linux' && is_array($info['Distro']) && $info['Distro']['name'] ? strtolower(str_replace(' ', '', $info['Distro']['name'])) : false; // Start compressed output buffering. Try to not do this if we've had errors or otherwise already outputted stuff if ((!function_exists('error_get_last') || !error_get_last()) && (!isset($settings['compress_content']) || $settings['compress_content'])) { ob_start(function_exists('ob_gzhandler') ? 'ob_gzhandler' : null); } // See if we have a specific theme file installed if (isset($settings['theme']) && strpos($settings['theme'], '..') === false && file_exists('layout/theme_' . $settings['theme'] . '.css')) { $theme_css = 'theme_' . $settings['theme'] . '.css'; } elseif (($settings['theme'] = 'default') && file_exists('layout/theme_' . $settings['theme'] . '.css')) { $theme_css = 'theme_' . $settings['theme'] . '.css'; } else { $theme_css = 'styles.css'; } // Proceed to letting it all out echo '<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>' . $appName . ' - ' . $info['HostName'] . '</title> <link href="./layout/favicon.ico" type="image/x-icon" rel="shortcut icon"> <link href="./layout/' . $theme_css . '" rel="stylesheet">' . ($show_icons ? ' <link href="./layout/icons.css" rel="stylesheet">' : '') . ' <script src="./layout/scripts.min.js"></script> <meta name="generator" content="' . $appName . ' (' . $version . ')"> <meta name="author" content="Joseph Gillotti & friends"> <!--[if lt IE 8]> <link href="./layout/old_ie.css" type="text/css" rel="stylesheet"> <![endif]--> <link rel="stylesheet" type="text/css" href="./layout/mobile.css" media="screen and (max-width: 640px)"> </head> <body id="info"> <div id="header"> <h1>' . $info['HostName'] . '</h1> <div class="subtitle">' . $lang['header'] . '</div> </div> <div class="col2"> <div class="col"> <div class="infoTable"> <h2>' . $lang['core'] . '</h2> <table>'; // Linfo Core. Decide what to show. $core = array(); // OS? (with icon, if we have it) if (!empty($settings['show']['os'])) { $core[] = array($lang['os'], ($show_icons && (file_exists($this->linfo->getLocalDir() . 'layout/icons/os_' . $os_icon . '.gif') || file_exists($this->linfo->getLocalDir() . 'layout/icons/os_' . $os_icon . '.png')) ? '<span class="icon icon_os_' . $os_icon . '"></span>' : '') . $info['OS']); } // Distribution? (with icon, if we have it) if (!empty($settings['show']['distro']) && array_key_exists('Distro', $info) && is_array($info['Distro'])) { $core[] = array($lang['distro'], ($show_icons && $distro_icon && (file_exists($this->linfo->getLocalDir() . 'layout/icons/distro_' . $distro_icon . '.gif') || file_exists($this->linfo->getLocalDir() . 'layout/icons/distro_' . $distro_icon . '.png')) ? '<span class="icon icon_distro_' . $distro_icon . '"></span>' : '') . $info['Distro']['name'] . ($info['Distro']['version'] ? ' - ' . $info['Distro']['version'] : '')); } // Virtualization if (!empty($settings['show']['virtualization']) && isset($info['virtualization']) && !empty($info['virtualization'])) { $vmval = false; if ($info['virtualization']['type'] == 'guest') { $vmval = '<span class="icon icon_vm_' . str_replace('/', '_', strtolower($info['virtualization']['method'])) . '"></span>' . $info['virtualization']['method'] . ' ' . $lang['guest']; } elseif ($info['virtualization']['type'] == 'host') { $vmval = '<span class="icon icon_vm_' . str_replace('/', '_', strtolower($info['virtualization']['method'])) . '"></span>' . $info['virtualization']['method'] . ' ' . $lang['host']; } if ($vmval) { $core[] = array($lang['virtualization'], $vmval); } } // Kernel if (!empty($settings['show']['kernel'])) { $core[] = array($lang['kernel'], $info['Kernel']); } // Model? if (!empty($settings['show']['model']) && array_key_exists('Model', $info) && !empty($info['Model'])) { $core[] = array($lang['model'], $info['Model']); } // IP if (!isset($settings['show']['ip']) || !empty($settings['show']['ip'])) { $core[] = array($lang['accessed_ip'], $info['AccessedIP']); } // Uptime if (!empty($settings['show']['uptime']) && $info['UpTime']) { $core[] = array($lang['uptime'], $info['UpTime']['text'] . (isset($info['UpTime']['bootedTimestamp']) && $info['UpTime']['bootedTimestamp'] ? '; booted ' . date($settings['dates'], $info['UpTime']['bootedTimestamp']) : '')); } // Hostname if (!empty($settings['show']['hostname'])) { $core[] = array($lang['hostname'], $info['HostName']); } //Web server if (!empty($settings['show']['webservice'])) { $core[] = array($lang['webservice'], $info['webService']); } //Php version if (!empty($settings['show']['phpversion'])) { $core[] = array($lang['phpversion'], $info['phpVersion']); } // The CPUs if (!empty($settings['show']['cpu'])) { $cpus = array(); foreach ((array) $info['CPU'] as $cpu) { $cpu_html = (array_key_exists('Vendor', $cpu) && !empty($cpu['Vendor']) ? $cpu['Vendor'] . ' - ' : '') . $cpu['Model'] . (array_key_exists('MHz', $cpu) ? $cpu['MHz'] < 1000 ? ' (' . $cpu['MHz'] . ' MHz)' : ' (' . round($cpu['MHz'] / 1000, 3) . ' GHz)' : '') . (array_key_exists('usage_percentage', $cpu) ? ' (' . $cpu['usage_percentage'] . '%)' : ''); if (array_key_exists('usage_percentage', $cpu)) { $cpu_html = '<div class="new_bar_left" style="margin-top: 3px; margin-bottom: 3px;">' . self::generateBarChart($cpu['usage_percentage'], $cpu_html) . '</div>'; } else { $cpu_html .= '<br>'; } $cpus[] = $cpu_html; } $core[] = array('CPUs (' . count($info['CPU']) . ')', implode('', $cpus)); } // CPU Usage? if (!empty($settings['cpu_usage']) && isset($info['cpuUsage']) && $info['cpuUsage'] !== false) { $core[] = array($lang['cpu_usage'], self::generateBarChart($info['cpuUsage'])); } // System Load if (!empty($settings['show']['load'])) { $core[] = array($lang['load'], implode(' ', (array) $info['Load'])); } // CPU architecture. Permissions goes hand in hand with normal CPU if (!empty($settings['show']['cpu']) && array_key_exists('CPUArchitecture', $info)) { $core[] = array($lang['cpu_arch'], $info['CPUArchitecture']); } // We very well may not have process stats if (!empty($settings['show']['process_stats']) && $info['processStats']['exists']) { // Different os' have different keys of info $proc_stats = array(); // Load the keys if (array_key_exists('totals', $info['processStats']) && is_array($info['processStats']['totals'])) { foreach ($info['processStats']['totals'] as $k => $v) { $proc_stats[] = $k . ': ' . number_format($v); } } // Total as well $proc_stats[] = 'total: ' . number_format($info['processStats']['proc_total']); // Show them $core[] = array($lang['processes'], implode('; ', $proc_stats)); // We might not have threads if ($info['processStats']['threads'] !== false) { $core[] = array($lang['threads'], number_format($info['processStats']['threads'])); } } // Users with active shells if (!empty($settings['show']['numLoggedIn']) && array_key_exists('numLoggedIn', $info) && $info['numLoggedIn']) { $core[] = array($lang['numLoggedIn'], $info['numLoggedIn']); } // Show foreach ($core as $val) { echo ' <tr> <th>' . $val[0] . '</th> <td>' . $val[1] . '</td> </tr> '; } echo ' </table> </div>'; // Show memory? if (!empty($settings['show']['ram'])) { echo ' <div class="infoTable"> <h2>' . $lang['memory'] . '</h2> <table> <colgroup> <col style="width: 12%;" /> <col style="width: 23%;" /> <col style="width: 23%;" /> <col style="width: 23%;" /> <col style="width: 23%;" /> </colgroup> <tr> <th>' . $lang['type'] . '</th> <th>' . $lang['size'] . '</th> <th>' . $lang['used'] . '</th> <th>' . $lang['free'] . '</th> <th>' . $lang['percent_used'] . '</th> </tr> <tr> <td>' . $info['RAM']['type'] . '</td> <td>' . Common::byteConvert($info['RAM']['total']) . '</td> <td>' . Common::byteConvert($info['RAM']['total'] - $info['RAM']['free']) . '</td> <td>' . Common::byteConvert($info['RAM']['free']) . '</td> <td>' . self::generateBarChart(round(($info['RAM']['total'] - $info['RAM']['free']) * 100 / $info['RAM']['total'])) . '</td> </tr>'; $have_swap = isset($info['RAM']['swapFree']) || isset($info['RAM']['swapTotal']); if ($have_swap && !empty($info['RAM']['swapTotal'])) { // Show detailed swap info? $show_detailed_swap = is_array($info['RAM']['swapInfo']) && count($info['RAM']['swapInfo']) > 0; echo ' <tr> <td' . ($show_detailed_swap ? ' rowspan="2"' : '') . '>Swap</td> <td>' . Common::byteConvert(@$info['RAM']['swapTotal']) . '</td> <td>' . Common::byteConvert(@$info['RAM']['swapTotal'] - $info['RAM']['swapFree']) . '</td> <td>' . Common::byteConvert(@$info['RAM']['swapFree']) . '</td> <td>' . self::generateBarChart(round(($info['RAM']['swapTotal'] - $info['RAM']['swapFree']) * 100 / $info['RAM']['swapTotal'])) . '</td> </tr>'; // As in we have at least one swap device present. Show them. if ($show_detailed_swap) { echo ' <tr> <td colspan="4"> <table class="mini center"> <colgroup> <col style="width: 25%;" /> <col style="width: 25%;" /> <col style="width: 25%;" /> <col style="width: 25%;" /> </colgroup> <tr> <th>' . $lang['device'] . '</th> <th>' . $lang['type'] . '</th> <th>' . $lang['size'] . '</th> <th>' . $lang['used'] . '</th> </tr>'; foreach ($info['RAM']['swapInfo'] as $swap) { echo ' <tr> <td>' . $swap['device'] . '</td> <td>' . ucfirst($swap['type']) . '</td> <td>' . Common::byteConvert($swap['size']) . '</td> <td>' . Common::byteConvert($swap['used']) . '</td> </tr> '; } echo ' </table> </td> </tr>'; } } echo ' </table> </div>'; } // Network Devices? if (!empty($settings['show']['network'])) { $show_type = array_key_exists('nic_type', $info['contains']) ? $info['contains']['nic_type'] : true; $show_speed = array_key_exists('nic_port_speed', $info['contains']) ? $info['contains']['nic_port_speed'] : true; echo ' <div class="infoTable network_devices"> <h2>' . $lang['network_devices'] . '</h2> <table> <tr> <th>' . $lang['device_name'] . '</th>' . ($show_type ? ' <th>' . $lang['type'] . '</th>' : '') . ($show_speed ? ' <th>' . $lang['port_speed'] . '</th>' : '') . ' <th>' . $lang['amount_sent'] . '</th> <th>' . $lang['amount_received'] . '</th> <th>' . $lang['state'] . '</th> </tr>'; if (count($info['Network Devices']) > 0) { foreach ($info['Network Devices'] as $device => $stats) { echo ' <tr> <td>' . $device . '</td>' . ($show_type ? ' <td>' . $stats['type'] . '</td>' : '') . ($show_speed ? ' <td>' . (isset($stats['port_speed']) && $stats['port_speed'] !== false ? $stats['port_speed'] . 'Mb/s' : '') . '</td>' : '') . ' <td>' . Common::byteConvert($stats['sent']['bytes']) . '</td> <td>' . Common::byteConvert($stats['recieved']['bytes']) . '</td> <td class="net_' . $stats['state'] . '">' . ucfirst($stats['state']) . '</td> </tr>'; } } else { echo '<tr><td colspan="5" class="none">' . $lang['none_found'] . '</td></tr>'; } echo ' </table> </div>'; } // Show temps? if (!empty($settings['show']['temps']) && count($info['Temps']) > 0) { echo ' <div class="infoTable"> <h2>' . $lang['temps_voltages'] . '</h2> <table> <tr><th>' . $lang['path'] . '</th><th>' . $lang['device'] . '</th><th>' . $lang['value'] . '</th></tr> '; if (count($info['Temps']) > 0) { foreach ($info['Temps'] as $stat) { echo ' <tr> <td>' . $stat['path'] . '</td> <td>' . $stat['name'] . '</td> <td>' . (array_key_exists('bar', $stat) && $stat['bar'] && $stat['unit'] == '%' ? '<div class="bar_chart"> <div class="bar_inner" style="width: ' . $stat['temp'] . '%;"> <div class="bar_text"> ' . ($stat['temp'] > -1 ? $stat['temp'] : '?') . '% </div> </div> </div> ' : $stat['temp'] . ' ' . $stat['unit']) . '</td> </tr> '; } } else { echo '<tr><td colspan="3" class="none">' . $lang['none_found'] . '</td></tr>'; } echo ' </table> </div>'; } // Show battery? if (!empty($settings['show']['battery']) && count($info['Battery']) > 0) { echo ' <div class="infoTable"> <h2>' . $lang['batteries'] . '</h2> <table> <tr> <th>' . $lang['device'] . '</th> <th>' . $lang['state'] . '</th> <th>' . $lang['charge'] . ' %</th> </tr> '; foreach ($info['Battery'] as $bat) { echo ' <tr> <td>' . $bat['device'] . '</td> <td>' . $bat['state'] . '</td> <td>' . self::generateBarChart((int) $bat['percentage'], $bat['percentage'] > -1 ? $bat['percentage'] . '%' : 'N/A') . '</td> </tr> '; } echo ' </table> </div>'; } // Show services? if (!empty($settings['show']['services']) && count($info['services']) > 0) { echo ' <div class="infoTable"> <h2>' . $lang['services'] . '</h2> <table> <tr> <th>' . $lang['service'] . '</th> <th>' . $lang['state'] . '</th> <th>' . $lang['pid'] . '</th> <th>Threads</th> <th>' . $lang['memory_usage'] . '</th> </tr> '; // Show them foreach ($info['services'] as $service => $state) { $state_parts = explode(' ', $state['state'], 2); echo ' <tr> <td>' . $service . '</td> <td> <span class="service_' . strtolower($state_parts[0]) . '">' . $state_parts[0] . '</span> ' . (array_key_exists(1, $state_parts) ? self::fadedText($state_parts[1]) . '</span>' : '') . '</td> <td>' . $state['pid'] . '</td> <td>', $state['threads'] ? $state['threads'] : '?', '</td> <td>', $state['memory_usage'] ? Common::byteConvert($state['memory_usage']) : '?', '</td> </tr> '; } echo ' </table> </div>'; } echo ' </div> <div class="col">'; // Show hardware? if (!empty($settings['show']['devices'])) { // Don't show vendor? $show_vendor = array_key_exists('hw_vendor', $info['contains']) ? $info['contains']['hw_vendor'] === false ? false : true : true; echo ' <div class="infoTable"> <h2>' . $lang['hardware'] . '</h2> <table> <tr> <th>' . $lang['type'] . '</th> ', $show_vendor ? '<th>' . $lang['vendor'] . '</th>' : '', ' <th>' . $lang['device'] . '</th> </tr> '; $num_devs = count($info['Devices']); if ($num_devs > 0) { for ($i = 0; $i < $num_devs; ++$i) { echo ' <tr> <td class="center">' . $info['Devices'][$i]['type'] . '</td> ', $show_vendor ? '<td>' . ($info['Devices'][$i]['vendor'] ? $info['Devices'][$i]['vendor'] : 'Unknown') . '</td>' : '', ' <td>' . $info['Devices'][$i]['device'] . '</td> </tr>'; } } else { echo '<tr><td colspan="3" class="none">' . $lang['none_found'] . '</td></tr>'; } echo ' </table> </div>'; } // Show drives? if (!empty($settings['show']['hd'])) { // Should we not show the Reads and Writes columns? $show_stats = array_key_exists('drives_rw_stats', $info['contains']) ? $info['contains']['drives_rw_stats'] === false ? false : true : true; // Or vendor columns? $show_vendor = array_key_exists('drives_vendor', $info['contains']) ? $info['contains']['drives_vendor'] === false ? false : true : true; echo ' <div class="infoTable"> <h2>' . $lang['drives'] . '</h2> <table> <tr> <th>' . $lang['path'] . '</th> ', $show_vendor ? '<th>' . $lang['vendor'] : '', '</th> <th>' . $lang['name'] . '</th> ', $show_stats ? '<th>' . $lang['reads'] . '</th> <th>' . $lang['writes'] . '</th>' : '', ' <th>' . $lang['size'] . '</th> </tr>'; if (count($info['HD']) > 0) { foreach ($info['HD'] as $drive) { echo ' <tr> <td>' . $drive['device'] . '</td> ', $show_vendor ? '<td>' . ($drive['vendor'] ? $drive['vendor'] : $lang['unknown']) . '</td>' : '', ' <td>', $drive['name'] ? $drive['name'] : $lang['unknown'], '</td> ', $show_stats ? '<td>' . ($drive['reads'] !== false ? number_format($drive['reads']) : $lang['unknown']) . '</td> <td>' . ($drive['writes'] !== false ? number_format($drive['writes']) : $lang['unknown']) . '</td>' : '', ' <td>', $drive['size'] ? Common::byteConvert($drive['size']) : $lang['unknown'], '</td> </tr>'; // If we've got partitions for this drive, show them too if (array_key_exists('partitions', $drive) && is_array($drive['partitions']) && count($drive['partitions']) > 0) { echo ' <tr> <td colspan="6">'; // Each foreach ($drive['partitions'] as $partition) { echo ' └ ' . (isset($partition['number']) ? $drive['device'] . $partition['number'] : $partition['name']) . ' - ' . Common::byteConvert($partition['size']) . '<br />'; } echo ' </td> </tr> '; } } } else { echo '<tr><td colspan="6" class="none">' . $lang['none_found'] . '</td></tr>'; } echo ' </table> </div>'; } // Show sound card stuff? if (!empty($settings['show']['sound']) && count($info['SoundCards']) > 0) { echo ' <div class="infoTable"> <h2>' . $lang['sound_cards'] . '</h2> <table> <tr> <th>' . $lang['number'] . '</th> <th>' . $lang['vendor'] . '</th> <th>' . $lang['card'] . '</th> </tr>'; foreach ($info['SoundCards'] as $card) { if (empty($card['vendor'])) { $card['vendor'] = 'Unknown'; } echo ' <tr> <td>' . $card['number'] . '</td> <td>' . $card['vendor'] . '</td> <td>' . $card['card'] . '</td> </tr>'; } echo ' </table> </div> '; } echo ' </div> </div>'; // Show file system mounts? if (!empty($settings['show']['mounts'])) { $has_devices = false; $has_labels = false; $has_types = false; foreach ($info['Mounts'] as $mount) { if (!empty($mount['device'])) { $has_devices = true; } if (!empty($mount['label'])) { $has_labels = true; } if (!empty($mount['devtype'])) { $has_types = true; } } $addcolumns = 0; if ($settings['show']['mounts_options']) { $addcolumns++; } if ($has_devices) { $addcolumns++; } if ($has_labels) { $addcolumns++; } if ($has_types) { $addcolumns++; } echo ' <div class="infoTable filesystem_mounts"> <h2>' . $lang['filesystem_mounts'] . '</h2> <table> <tr>'; if ($has_types) { echo '<th>' . $lang['type'] . '</th>'; } if ($has_devices) { echo '<th>' . $lang['device'] . '</th>'; } echo '<th>' . $lang['mount_point'] . '</th>'; if ($has_labels) { echo '<th>' . $lang['label'] . '</th>'; } echo ' <th>' . $lang['filesystem'] . '</th>', $settings['show']['mounts_options'] ? ' <th>' . $lang['mount_options'] . '</th>' : '', ' <th>' . $lang['size'] . '</th> <th>' . $lang['used'] . '</th> <th>' . $lang['free'] . '</th> <th style="width: 12%;">' . $lang['percent_used'] . '</th> </tr> '; // Calc totals $total_size = 0; $total_used = 0; $total_free = 0; // Don't add totals for duplicates. (same filesystem mount twice in different places) $done_devices = array(); // Are there any? if (count($info['Mounts']) > 0) { // Go through each foreach ($info['Mounts'] as $mount) { // Only add totals for this device if we haven't already if (!in_array($mount['device'], $done_devices)) { $total_size += $mount['size']; $total_used += $mount['used']; $total_free += $mount['free']; if (!empty($mount['device'])) { $done_devices[] = $mount['device']; } } elseif (array_key_exists('duplicate_mounts', $settings['show']) && empty($settings['show']['duplicate_mounts'])) { continue; } // If it's an NFS mount it's likely in the form of server:path (without a trailing slash), // but if the path is just / it likely just shows up as server:, // which is vague. If there isn't a /, add one if (preg_match('/^.+:$/', $mount['device']) == 1) { $mount['device'] .= DIRECTORY_SEPARATOR; } echo '<tr>'; if ($has_types) { echo '<td>' . $mount['devtype'] . '</td>'; } if ($has_devices) { echo '<td>' . $mount['device'] . '</td>'; } echo '<td>' . $mount['mount'] . '</td>'; if ($has_labels) { echo '<td>' . $mount['label'] . '</td>'; } echo ' <td>' . $mount['type'] . '</td>', $settings['show']['mounts_options'] ? ' <td>' . (empty($mount['options']) ? '<em>unknown</em>' : '<ul><li>' . implode('</li><li>', $mount['options']) . '</li></ul>') . '</td>' : '', ' <td>' . Common::byteConvert($mount['size']) . '</td> <td>' . Common::byteConvert($mount['used']) . ($mount['used_percent'] !== false ? ' <span class="perc">(' . $mount['used_percent'] . '%)</span>' : '') . '</td> <td>' . Common::byteConvert($mount['free']) . ($mount['free_percent'] !== false ? ' <span class="perc">(' . $mount['free_percent'] . '%)</span>' : '') . '</td> <td> ' . self::generateBarChart((int) $mount['used_percent'], $mount['used_percent'] ? $mount['used_percent'] . '%' : 'N/A') . ' </td> </tr>'; } } else { echo '<tr><td colspan="', 6 + $addcolumns, '" class="none">None found</td></tr>'; } // Show totals and finish table $total_used_perc = $total_size > 0 && $total_used > 0 ? round($total_used / $total_size, 2) * 100 : 0; echo ' <tr class="alt"> <td colspan="', 2 + $addcolumns, '">Totals: </td> <td>' . Common::byteConvert($total_size) . '</td> <td>' . Common::byteConvert($total_used) . '</td> <td>' . Common::byteConvert($total_free) . '</td> <td> ' . self::generateBarChart($total_used_perc, $total_used_perc . '%') . ' </td> </tr> </table> </div>'; } // Show RAID Arrays? if (!empty($settings['show']['raid']) && count($info['Raid']) > 0) { echo ' <div class="infoTable drives"> <h2>' . $lang['raid_arrays'] . '</h2> <table> <colgroup> <col style="width: 10%;" /> <col style="width: 30%;" /> <col style="width: 10%;" /> <col style="width: 10%;" /> <col style="width: 30%;" /> <col style="width: 10%;" /> </colgroup> <tr> <th>' . $lang['name'] . '</th> <th>' . $lang['level'] . '</th> <th>' . $lang['status'] . '</th> <th>' . $lang['size'] . '</th> <th>' . $lang['devices'] . '</th> <th>' . $lang['active'] . '</th> </tr> '; if (count($info['Raid']) > 0) { foreach ($info['Raid'] as $raid) { $active = explode('/', $raid['count']); // http://en.wikipedia.org/wiki/Standard_RAID_levels switch ($raid['level']) { case 0: $type = 'Stripe'; break; case 1: $type = 'Mirror'; break; case 10: $type = 'Mirrored Stripe'; break; case 5: case 6: $type = 'Distributed Parity Block-Level Striping'; break; default: $type = false; break; } echo ' <tr> <td>' . $raid['device'] . '</td> <td>' . $raid['level'] . ($type ? ' <span class="caption">(' . $type . ')</span>' : '') . '</td> <td>' . ucfirst($raid['status']) . '</td> <td>' . $raid['size'] . '</td> <td><table class="mini center margin_auto"><tr><th>' . $lang['device'] . '</th><th>' . $lang['state'] . '</th></tr>'; foreach ($raid['drives'] as $drive) { echo '<tr><td>' . $drive['drive'] . '</td><td class="raid_' . $drive['state'] . '">' . ucfirst($drive['state']) . '</td></tr>'; } echo '</table></td> <td>' . $active[1] . '/' . $active[0] . '</td> </tr> '; } } else { echo '<tr><td colspan="6" class="none">' . $lang['none_found'] . '</td></tr>'; } echo ' </table> </div>'; } // Feel like showing errors? Are there any even? if (!empty($settings['show_errors']) && Errors::Singleton()->num() > 0) { echo ' <div id="errorList" class="infoTable"> <h2>' . $lang['error_head'] . '</h2> <table> <tr> <th>' . $lang['from_where'] . '</th> <th>' . $lang['message'] . '</th> </tr>'; foreach (Errors::Singleton()->show() as $error) { echo ' <tr> <td>' . $error[0] . '</td> <td>' . $error[1] . '</td> </tr> '; } echo ' </table> </div> '; } // Additional extensions if (count($info['extensions']) > 0) { foreach ($info['extensions'] as $ext) { if (is_array($ext) && count($ext) > 0) { // Decide how to show something extra switch (array_key_exists('extra_type', $ext) && !empty($ext['extra_vals']) ? $ext['extra_type'] : false) { // Table with a key->value table to the right of it // Useful for stats or other stuff pertaining to // the main info to the left case 'k->v': echo ' <div class="col2_side"> <div class="col2_side_left"> ' . self::createTable($ext) . ' </div> <div class="col2_side_right"> <div class="infoTable"> <h2>' . $ext['extra_vals']['title'] . '</h2> <table>'; // Give each value foreach (array_filter($ext['extra_vals']['values']) as $v) { echo ' <tr> <th>' . $v[0] . '</th> <td>' . $v[1] . '</td> </tr>'; } echo ' </table> </div> </div> </div> '; break; // Nothing extra; just the table // Nothing extra; just the table default: echo self::createTable($ext); break; } } } } // Feel like showing timed results? if (!empty($settings['timer'])) { echo ' <div id="timerList" class="infoTable"> <h2>' . $lang['timer'] . '</h2> <table> <tr> <th>' . $lang['area'] . '</th> <th>' . $lang['time_taken'] . '</th> </tr>'; foreach (Timer::getResults() as $result) { echo ' <tr> <td>' . $result['id'] . '</td> <td>' . round($result['duration'], 3) . ' ' . $lang['seconds'] . '</td> </tr> '; } echo ' </table> </div> '; } echo ' <div id="foot"> ' . sprintf($lang['footer_app'], '<a href="https://github.com/jrgp/linfo"><em>' . $appName . '</em></a> (' . $version . ')', round(microtime(true) - $this->linfo->getTimeStart(), 2)) . '<br> <em>' . $appName . '</em> © 2010 – ' . (date('Y') > 2011 ? date('Y') : 2011) . ' Joseph Gillotti ' . (date('m/d') == '06/03' ? ' (who turns ' . (date('Y') - 1993) . ' today!)' : '') . '& friends. Source code licensed under GPL. </div> <div id="foot_time"> <br /> Generated on ' . date($settings['dates']) . ' </div> <script>Linfo.init()</script> </body> </html>'; }
protected function loadDmesg() { $this->dmesg = Common::getContents('/var/run/dmesg.boot'); }
require_once __DIR__ . '/standalone_autoload.php'; use Linfo\Exceptions\FatalException; use Linfo\Linfo; use Linfo\Common; try { // Load settings file.. // Support legacy config files define('IN_LINFO', 'true'); define('IN_INFO', 'true'); if (!is_file(__DIR__ . '/config.inc.php') && is_file(__DIR__ . '/sample.config.inc.php')) { throw new FatalException('Make changes to sample.config.inc.php then rename as config.inc.php'); } elseif (!is_file(__DIR__ . '/config.inc.php')) { throw new FatalException('Config file not found.'); } $settings = Common::getVarFromFile(__DIR__ . '/config.inc.php', 'settings'); $linfo = new Linfo($settings); $linfo->scan(); if (isset($_SERVER['LINFO_NCURSES']) && php_sapi_name() == 'cli') { $output = new \Linfo\Output\Ncurses($linfo); } else { switch (array_key_exists('out', $_GET) ? strtolower($_GET['out']) : 'html') { default: case 'html': $output = new \Linfo\Output\Html($linfo); break; case 'json': case 'jsonp': // To use JSON-P, pass the GET arg - callback=function_name $output = new \Linfo\Output\Json($linfo, array_key_exists('callback', $_GET) ? $_GET['callback'] : null); break;
public function getUpTime() { // Time? if (!empty($this->settings['timer'])) { $t = new Timer('Uptime'); } // Use sysctl to get unix timestamp of boot. Very elegant! if (preg_match('/^\\{ sec \\= (\\d+).+$/', $this->sysctl['kern.boottime'], $m) == 0) { return ''; } // Boot unix timestamp $booted = $m[1]; // Give it return array('text' => Common::secondsConvert(time() - $booted), 'bootedTimestamp' => $booted); }
public function result() { if (!$this->res) { return false; } $rows[] = array('type' => 'header', 'columns' => array('VM Name', 'Status', 'RAM Allocation', 'CPUs', 'CPU Time', 'Autostart', 'Block Storage', 'Network Devices')); $running = 0; $allram = 0; foreach ($this->VMs as $name => $info) { $disks = array(); foreach ($info['storage'] as $disk) { $disks[] = $disk['device'] . (isset($disk['file']) && isset($disk['capacity']) ? ': ' . $disk['file'] . ' (' . Common::byteConvert($disk['capacity'], 2) . ')' : ''); } $rows[] = array('type' => 'values', 'columns' => array($name, $info['state'] == 1 ? '<span style="color: green;">On</span>' : '<span style="color: maroon;">Off</span>', Common::byteConvert($info['memory'] * 1024, 2), $info['nrVirtCpu'], $info['cpuUsed'] ? $info['cpuUsed'] : 'N/A', $info['autostart'], $disks ? implode('<br />', $disks) : 'None', $info['nets'] ? implode('<br />', $info['nets']) : 'None')); if ($info['state'] == 1) { $running++; } $allram += $info['memory']; } // Give it off return array('root_title' => 'libvirt Virtual Machines <span style="font-size: 80%;">(' . $running . ' running - using ' . Common::byteConvert($allram * 1024, 2) . ' RAM)</span>', 'rows' => $rows); }
/** * Get the PCI ids from /sys. */ private function _fetchPciIdsLinux() { foreach ((array) @glob('/sys/bus/pci/devices/*', GLOB_NOSORT) as $path) { // See if we can use simple vendor/device files and avoid taking time with regex if (($f_device = Common::getContents($path . '/device', '')) && ($f_vend = Common::getContents($path . '/vendor', '')) && $f_device != '' && $f_vend != '') { list(, $v_id) = explode('x', $f_vend, 2); list(, $d_id) = explode('x', $f_device, 2); $this->_pci_entries[$v_id][$d_id] = 1; } elseif (is_readable($path . '/uevent') && preg_match('/pci\\_(?:subsys_)?id=(\\w+):(\\w+)/', strtolower(Common::getContents($path . '/uevent')), $match)) { $this->_pci_entries[$match[1]][$match[2]] = 1; } elseif (is_readable($path . '/modalias') && preg_match('/^pci:v0{4}([0-9A-Z]{4})d0{4}([0-9A-Z]{4})/', Common::getContents($path . '/modalias'), $match)) { $this->_pci_entries[strtolower($match[1])][strtolower($match[2])] = 1; } } }
public function getUpTime() { // Time? if (!empty($this->settings['timer'])) { $t = new Timer('Uptime'); } // Short and sweet $booted = $this->sysctl['kern.boottime']; if ($booted == false) { return 'Unknown'; } // Is it not a timestamp? if (!is_numeric($booted)) { $booted = strtotime($booted); } // Give it return array('text' => Common::secondsConvert(time() - $booted), 'bootedTimestamp' => $booted); }
public function output() { $lang = $this->linfo->getLang(); $settings = $this->linfo->getSettings(); $info = $this->linfo->getInfo(); $appName = $this->linfo->getAppName(); $version = $this->linfo->getVersion(); // Fun icons $show_icons = array_key_exists('icons', $settings) ? !empty($settings['icons']) : true; $os_icon = $info['OS'] == 'Windows' ? 'windows' : strtolower(str_replace(' ', '', current(explode('(', $info['OS'])))); $distro_icon = $info['OS'] == 'Linux' && is_array($info['Distro']) && $info['Distro']['name'] ? strtolower(str_replace(' ', '', $info['Distro']['name'])) : false; // Start compressed output buffering. Try to not do this if we've had errors or otherwise already outputted stuff if ((!function_exists('error_get_last') || !error_get_last()) && (!isset($settings['compress_content']) || $settings['compress_content'])) { ob_start(function_exists('ob_gzhandler') ? 'ob_gzhandler' : null); } // See if we have a specific theme file installed if (isset($settings['theme']) && strpos($settings['theme'], '..') === false && file_exists('layout/theme_' . $settings['theme'] . '.css')) { $theme_css = 'theme_' . $settings['theme'] . '.css'; } elseif (($settings['theme'] = 'default') && file_exists('layout/theme_' . $settings['theme'] . '.css')) { $theme_css = 'theme_' . $settings['theme'] . '.css'; } else { $theme_css = 'styles.css'; } // Proceed to letting it all out echo '<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>' . $appName . ' - ' . $info['HostName'] . '</title> <meta name="generator" content="' . $appName . ' (' . $version . ')"> <meta name="author" content="Joseph Gillotti & friends"> <style> body{font-family:arial,sans-serif;background-color:#fff;color:#000;font-size:12px}a{color:#666}a:hover{color:#000}table{border-collapse:collapse;width:100%}table th{font-weight:normal;color:#444}table th,table td{border-right:1px solid #c3c3c3;border-left:1px solid #c3c3c3;border-bottom:1px solid #c3c3c3;padding:4px;background-color:#eee}table tr th,table tr.alt td{background-color:#ddd}.infoTable{margin:10px 5px 10px 5px;clear:both;box-shadow:none}.infoTable h2{margin:0;padding:5px;color:#fff;text-shadow:#2665a7 1px 1px 1px;border:1px solid #4a8fd6;background-color:#5c9ada}.infoTable,.infoTable h2{border-top-left-radius:3px;border-top-right-radius:3px;-moz-border-radius-topleft:3px;-moz-border-radius-topright:3px}.infoTable.collapsed{border-bottom-left-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-bottomleft:4px;-moz-border-radius-bottomright:4px}.collapsed h2{border-bottom-left-radius:3px;border-bottom-right-radius:3px;-moz-border-radius-bottomleft:3px;-moz-border-radius-bottomright:3px}.collapsed table{display:none}#foot{margin:15px 0px 20px 15px;color:#444;float:left}#foot_time{margin:15px 15px 20px 0px;color:#444;float:right;vertical-align:bottom}h1{font-size:1.6em;margin:0;padding:0}h2{font-size:1.2em;margin:0}.col2{overflow:hidden}.col2 .col{float:left;width:50%}#info .center{text-align:center}td.none{text-align:center;font-size:12px;padding:10px;color:#666}span.perc,span.faded{color:#666}span.caption{font-size:90%}td ul{margin:0;padding:0}td ul li{list-style-type:square;padding:0;margin-left:15px;margin-top:0;margin-bottom:0;margin-right:0}.raid_normal{color:green}.raid_spare{color:blue}.raid_failed{color:red}.raid_unknown{color:purple}.margin_auto{margin:auto}table.mini{padding:0;font-size:90%;border-collapse:collapse}table.mini th,table.mini td{margin:0;padding:0;border:none}table.mini th{background-color:inherit;color:#444}.net_up{color:green}.net_down{color:red}.net_unknown{color:purple}#errorList,#timerList{font-size:75%;margin-top:15px;margin-bottom:15px}.bar_chart{position:relative;margin:auto}.smaller_bar_chart{padding-bottom:2px}.smaller_bar_chart .bar_text{text-align:left !important}.bar_inner{border-radius:2px;-moz-border-radius:2px;min-height:18px;background-color:#b7cce2}.bar_text{position:absolute;line-height:18px;font-size:12px;text-indent:2px;text-align:center;width:100%}.new_bar_outer{position:relative;margin:auto;background-color:inherit}.new_bar_text{z-index:2;position:relative;padding:2px;text-align:center;color:#000}.new_bar_bg{border-radius:2px;-moz-border-radius:2px;z-index:1;height:100%;position:absolute;display:block;background-color:#b7cce2}.new_bar_left .new_bar_text{text-align:left}.alt .bar_inner,.alt .new_bar_bg{background-color:#96b4d5}.service_up{color:green}.service_down{color:maroon}.service_zombie{color:orange}span.toggler{line-height:24px;color:#8abdf2;float:right;font-family:"Courier New";cursor:pointer;font-weight:bold;font-size:1.4em;padding-top:0.2em;padding-right:0.4em}.infoTable span.toggler:hover{color:#fff}#header{padding:5px 0px 5px 5px}#header:before{float:left;content:url("icons/logo.png");display:inline-block;margin-right:10px}.subtitle{color:#999;font-size:12px}.time{padding:5px 15px 0px 0px;color:#999;float:right;text-align:right}.col2_side{overflow:hidden}.col2_side_left{float:left;width:80%}.col2_side_right{float:left;width:20%} @media only screen and (max-width: 640px) { .col2 .col{width:100%}.infoTable{margin:0px 0px 5px 0px}#header{padding:0px 0px 5px 2px}.filesystem_mounts table th:nth-child(2),.filesystem_mounts table td:nth-child(2),.filesystem_mounts table th:nth-child(3),.filesystem_mounts table td:nth-child(3),.filesystem_mounts table th:nth-child(4),.filesystem_mounts table td:nth-child(4),.network_devices table th:nth-child(2),.network_devices table td:nth-child(2),.drives table th:nth-child(2),.drives table td:nth-child(2),.drives table th:nth-child(3),.drives table td:nth-child(3){display:none}#foot_time{margin:0}#foot{margin:5px 5px 0px 5px} } </style> </head> <body id="info"> <div id="header"> <h1>' . $info['HostName'] . '</h1> <div class="subtitle">' . $lang['header'] . '</div> </div> <div class="col2"> <div class="col"> <div class="infoTable"> <h2>' . $lang['core'] . '</h2> <table>'; // Linfo Core. Decide what to show. $core = array(); // OS? (with icon, if we have it) if (!empty($settings['show']['os'])) { $core[] = array($lang['os'], ($show_icons && (file_exists($this->linfo->getLocalDir() . 'layout/icons/os_' . $os_icon . '.gif') || file_exists($this->linfo->getLocalDir() . 'layout/icons/os_' . $os_icon . '.png')) ? '<span class="icon icon_os_' . $os_icon . '"></span>' : '') . $info['OS']); } // Distribution? (with icon, if we have it) if (!empty($settings['show']['distro']) && array_key_exists('Distro', $info) && is_array($info['Distro'])) { $core[] = array($lang['distro'], ($show_icons && $distro_icon && (file_exists($this->linfo->getLocalDir() . 'layout/icons/distro_' . $distro_icon . '.gif') || file_exists($this->linfo->getLocalDir() . 'layout/icons/distro_' . $distro_icon . '.png')) ? '<span class="icon icon_distro_' . $distro_icon . '"></span>' : '') . $info['Distro']['name'] . ($info['Distro']['version'] ? ' - ' . $info['Distro']['version'] : '')); } // Virtualization if (!empty($settings['show']['virtualization']) && isset($info['virtualization']) && !empty($info['virtualization'])) { $vmval = false; if ($info['virtualization']['type'] == 'guest') { $vmval = '<span class="icon icon_vm_' . str_replace('/', '_', strtolower($info['virtualization']['method'])) . '"></span>' . $info['virtualization']['method'] . ' ' . $lang['guest']; } elseif ($info['virtualization']['type'] == 'host') { $vmval = '<span class="icon icon_vm_' . str_replace('/', '_', strtolower($info['virtualization']['method'])) . '"></span>' . $info['virtualization']['method'] . ' ' . $lang['host']; } if ($vmval) { $core[] = array($lang['virtualization'], $vmval); } } // Kernel if (!empty($settings['show']['kernel'])) { $core[] = array($lang['kernel'], $info['Kernel']); } // Model? if (!empty($settings['show']['model']) && array_key_exists('Model', $info) && !empty($info['Model'])) { $core[] = array($lang['model'], $info['Model']); } // IP if (!isset($settings['show']['ip']) || !empty($settings['show']['ip'])) { $core[] = array($lang['accessed_ip'], $info['AccessedIP']); } // Uptime if (!empty($settings['show']['uptime']) && $info['UpTime']) { $core[] = array($lang['uptime'], $info['UpTime']['text'] . (isset($info['UpTime']['bootedTimestamp']) && $info['UpTime']['bootedTimestamp'] ? '; booted ' . date($settings['dates'], $info['UpTime']['bootedTimestamp']) : '')); } // Hostname if (!empty($settings['show']['hostname'])) { $core[] = array($lang['hostname'], $info['HostName']); } //Web server if (!empty($settings['show']['webservice'])) { $core[] = array($lang['webservice'], $info['webService']); } //Php version if (!empty($settings['show']['phpversion'])) { $core[] = array($lang['phpversion'], $info['phpVersion']); } // The CPUs if (!empty($settings['show']['cpu'])) { $cpus = array(); foreach ((array) $info['CPU'] as $cpu) { $cpu_html = (array_key_exists('Vendor', $cpu) && !empty($cpu['Vendor']) ? $cpu['Vendor'] . ' - ' : '') . $cpu['Model'] . (array_key_exists('MHz', $cpu) ? $cpu['MHz'] < 1000 ? ' (' . $cpu['MHz'] . ' MHz)' : ' (' . round($cpu['MHz'] / 1000, 3) . ' GHz)' : '') . (array_key_exists('usage_percentage', $cpu) ? ' (' . $cpu['usage_percentage'] . '%)' : ''); if (array_key_exists('usage_percentage', $cpu)) { $cpu_html = '<div class="new_bar_left" style="margin-top: 3px; margin-bottom: 3px;">' . self::generateBarChart($cpu['usage_percentage'], $cpu_html) . '</div>'; } else { $cpu_html .= '<br>'; } $cpus[] = $cpu_html; } $core[] = array('CPUs (' . count($info['CPU']) . ')', implode('', $cpus)); } // CPU Usage? if (!empty($settings['cpu_usage']) && isset($info['cpuUsage']) && $info['cpuUsage'] !== false) { $core[] = array($lang['cpu_usage'], self::generateBarChart($info['cpuUsage'])); } // System Load if (!empty($settings['show']['load'])) { $core[] = array($lang['load'], implode(' ', (array) $info['Load'])); } // CPU architecture. Permissions goes hand in hand with normal CPU if (!empty($settings['show']['cpu']) && array_key_exists('CPUArchitecture', $info)) { $core[] = array($lang['cpu_arch'], $info['CPUArchitecture']); } // We very well may not have process stats if (!empty($settings['show']['process_stats']) && $info['processStats']['exists']) { // Different os' have different keys of info $proc_stats = array(); // Load the keys if (array_key_exists('totals', $info['processStats']) && is_array($info['processStats']['totals'])) { foreach ($info['processStats']['totals'] as $k => $v) { $proc_stats[] = $k . ': ' . number_format($v); } } // Total as well $proc_stats[] = 'total: ' . number_format($info['processStats']['proc_total']); // Show them $core[] = array($lang['processes'], implode('; ', $proc_stats)); // We might not have threads if ($info['processStats']['threads'] !== false) { $core[] = array($lang['threads'], number_format($info['processStats']['threads'])); } } // Users with active shells if (!empty($settings['show']['numLoggedIn']) && array_key_exists('numLoggedIn', $info) && $info['numLoggedIn']) { $core[] = array($lang['numLoggedIn'], $info['numLoggedIn']); } // Show foreach ($core as $val) { echo ' <tr> <th>' . $val[0] . '</th> <td>' . $val[1] . '</td> </tr> '; } echo ' </table> </div>'; // Show memory? if (!empty($settings['show']['ram'])) { echo ' <div class="infoTable"> <h2>' . $lang['memory'] . '</h2> <table> <colgroup> <col style="width: 12%;" /> <col style="width: 23%;" /> <col style="width: 23%;" /> <col style="width: 23%;" /> <col style="width: 23%;" /> </colgroup> <tr> <th>' . $lang['type'] . '</th> <th>' . $lang['size'] . '</th> <th>' . $lang['used'] . '</th> <th>' . $lang['free'] . '</th> <th>' . $lang['percent_used'] . '</th> </tr> <tr> <td>' . $info['RAM']['type'] . '</td> <td>' . Common::byteConvert($info['RAM']['total']) . '</td> <td>' . Common::byteConvert($info['RAM']['total'] - $info['RAM']['free']) . '</td> <td>' . Common::byteConvert($info['RAM']['free']) . '</td> <td>' . self::generateBarChart(round(($info['RAM']['total'] - $info['RAM']['free']) * 100 / $info['RAM']['total'])) . '</td> </tr>'; $have_swap = isset($info['RAM']['swapFree']) || isset($info['RAM']['swapTotal']); if ($have_swap && !empty($info['RAM']['swapTotal'])) { // Show detailed swap info? $show_detailed_swap = is_array($info['RAM']['swapInfo']) && count($info['RAM']['swapInfo']) > 0; echo ' <tr> <td' . ($show_detailed_swap ? ' rowspan="2"' : '') . '>Swap</td> <td>' . Common::byteConvert(@$info['RAM']['swapTotal']) . '</td> <td>' . Common::byteConvert(@$info['RAM']['swapTotal'] - $info['RAM']['swapFree']) . '</td> <td>' . Common::byteConvert(@$info['RAM']['swapFree']) . '</td> <td>' . self::generateBarChart(round(($info['RAM']['swapTotal'] - $info['RAM']['swapFree']) * 100 / $info['RAM']['swapTotal'])) . '</td> </tr>'; // As in we have at least one swap device present. Show them. if ($show_detailed_swap) { echo ' <tr> <td colspan="4"> <table class="mini center"> <colgroup> <col style="width: 25%;" /> <col style="width: 25%;" /> <col style="width: 25%;" /> <col style="width: 25%;" /> </colgroup> <tr> <th>' . $lang['device'] . '</th> <th>' . $lang['type'] . '</th> <th>' . $lang['size'] . '</th> <th>' . $lang['used'] . '</th> </tr>'; foreach ($info['RAM']['swapInfo'] as $swap) { echo ' <tr> <td>' . $swap['device'] . '</td> <td>' . ucfirst($swap['type']) . '</td> <td>' . Common::byteConvert($swap['size']) . '</td> <td>' . Common::byteConvert($swap['used']) . '</td> </tr> '; } echo ' </table> </td> </tr>'; } } echo ' </table> </div>'; } // Network Devices? if (!empty($settings['show']['network'])) { $show_type = array_key_exists('nic_type', $info['contains']) ? $info['contains']['nic_type'] : true; $show_speed = array_key_exists('nic_port_speed', $info['contains']) ? $info['contains']['nic_port_speed'] : true; echo ' <div class="infoTable network_devices"> <h2>' . $lang['network_devices'] . '</h2> <table> <tr> <th>' . $lang['device_name'] . '</th>' . ($show_type ? ' <th>' . $lang['type'] . '</th>' : '') . ($show_speed ? ' <th>' . $lang['port_speed'] . '</th>' : '') . ' <th>' . $lang['amount_sent'] . '</th> <th>' . $lang['amount_received'] . '</th> <th>' . $lang['state'] . '</th> </tr>'; if (count($info['Network Devices']) > 0) { foreach ($info['Network Devices'] as $device => $stats) { echo ' <tr> <td>' . $device . '</td>' . ($show_type ? ' <td>' . $stats['type'] . '</td>' : '') . ($show_speed ? ' <td>' . (isset($stats['port_speed']) && $stats['port_speed'] !== false ? $stats['port_speed'] . 'Mb/s' : '') . '</td>' : '') . ' <td>' . Common::byteConvert($stats['sent']['bytes']) . '</td> <td>' . Common::byteConvert($stats['recieved']['bytes']) . '</td> <td class="net_' . $stats['state'] . '">' . ucfirst($stats['state']) . '</td> </tr>'; } } else { echo '<tr><td colspan="5" class="none">' . $lang['none_found'] . '</td></tr>'; } echo ' </table> </div>'; } // Show temps? if (!empty($settings['show']['temps']) && count($info['Temps']) > 0) { echo ' <div class="infoTable"> <h2>' . $lang['temps_voltages'] . '</h2> <table> <tr><th>' . $lang['path'] . '</th><th>' . $lang['device'] . '</th><th>' . $lang['value'] . '</th></tr> '; if (count($info['Temps']) > 0) { foreach ($info['Temps'] as $stat) { echo ' <tr> <td>' . $stat['path'] . '</td> <td>' . $stat['name'] . '</td> <td>' . (array_key_exists('bar', $stat) && $stat['bar'] && $stat['unit'] == '%' ? '<div class="bar_chart"> <div class="bar_inner" style="width: ' . $stat['temp'] . '%;"> <div class="bar_text"> ' . ($stat['temp'] > -1 ? $stat['temp'] : '?') . '% </div> </div> </div> ' : $stat['temp'] . ' ' . $stat['unit']) . '</td> </tr> '; } } else { echo '<tr><td colspan="3" class="none">' . $lang['none_found'] . '</td></tr>'; } echo ' </table> </div>'; } // Show battery? if (!empty($settings['show']['battery']) && count($info['Battery']) > 0) { echo ' <div class="infoTable"> <h2>' . $lang['batteries'] . '</h2> <table> <tr> <th>' . $lang['device'] . '</th> <th>' . $lang['state'] . '</th> <th>' . $lang['charge'] . ' %</th> </tr> '; foreach ($info['Battery'] as $bat) { echo ' <tr> <td>' . $bat['device'] . '</td> <td>' . $bat['state'] . '</td> <td>' . self::generateBarChart((int) $bat['percentage'], $bat['percentage'] > -1 ? $bat['percentage'] . '%' : 'N/A') . '</td> </tr> '; } echo ' </table> </div>'; } // Show services? if (!empty($settings['show']['services']) && count($info['services']) > 0) { echo ' <div class="infoTable"> <h2>' . $lang['services'] . '</h2> <table> <tr> <th>' . $lang['service'] . '</th> <th>' . $lang['state'] . '</th> <th>' . $lang['pid'] . '</th> <th>Threads</th> <th>' . $lang['memory_usage'] . '</th> </tr> '; // Show them foreach ($info['services'] as $service => $state) { $state_parts = explode(' ', $state['state'], 2); echo ' <tr> <td>' . $service . '</td> <td> <span class="service_' . strtolower($state_parts[0]) . '">' . $state_parts[0] . '</span> ' . (array_key_exists(1, $state_parts) ? self::fadedText($state_parts[1]) . '</span>' : '') . '</td> <td>' . $state['pid'] . '</td> <td>', $state['threads'] ? $state['threads'] : '?', '</td> <td>', $state['memory_usage'] ? Common::byteConvert($state['memory_usage']) : '?', '</td> </tr> '; } echo ' </table> </div>'; } echo ' </div> <div class="col">'; // Show hardware? if (!empty($settings['show']['devices'])) { // Don't show vendor? $show_vendor = array_key_exists('hw_vendor', $info['contains']) ? $info['contains']['hw_vendor'] === false ? false : true : true; echo ' <div class="infoTable"> <h2>' . $lang['hardware'] . '</h2> <table> <tr> <th>' . $lang['type'] . '</th> ', $show_vendor ? '<th>' . $lang['vendor'] . '</th>' : '', ' <th>' . $lang['device'] . '</th> </tr> '; $num_devs = count($info['Devices']); if ($num_devs > 0) { for ($i = 0; $i < $num_devs; ++$i) { echo ' <tr> <td class="center">' . $info['Devices'][$i]['type'] . '</td> ', $show_vendor ? '<td>' . ($info['Devices'][$i]['vendor'] ? $info['Devices'][$i]['vendor'] : 'Unknown') . '</td>' : '', ' <td>' . $info['Devices'][$i]['device'] . '</td> </tr>'; } } else { echo '<tr><td colspan="3" class="none">' . $lang['none_found'] . '</td></tr>'; } echo ' </table> </div>'; } // Show drives? if (!empty($settings['show']['hd'])) { // Should we not show the Reads and Writes columns? $show_stats = array_key_exists('drives_rw_stats', $info['contains']) ? $info['contains']['drives_rw_stats'] === false ? false : true : true; // Or vendor columns? $show_vendor = array_key_exists('drives_vendor', $info['contains']) ? $info['contains']['drives_vendor'] === false ? false : true : true; echo ' <div class="infoTable"> <h2>' . $lang['drives'] . '</h2> <table> <tr> <th>' . $lang['path'] . '</th> ', $show_vendor ? '<th>' . $lang['vendor'] : '', '</th> <th>' . $lang['name'] . '</th> ', $show_stats ? '<th>' . $lang['reads'] . '</th> <th>' . $lang['writes'] . '</th>' : '', ' <th>' . $lang['size'] . '</th> </tr>'; if (count($info['HD']) > 0) { foreach ($info['HD'] as $drive) { echo ' <tr> <td>' . $drive['device'] . '</td> ', $show_vendor ? '<td>' . ($drive['vendor'] ? $drive['vendor'] : $lang['unknown']) . '</td>' : '', ' <td>', $drive['name'] ? $drive['name'] : $lang['unknown'], '</td> ', $show_stats ? '<td>' . ($drive['reads'] !== false ? number_format($drive['reads']) : $lang['unknown']) . '</td> <td>' . ($drive['writes'] !== false ? number_format($drive['writes']) : $lang['unknown']) . '</td>' : '', ' <td>', $drive['size'] ? Common::byteConvert($drive['size']) : $lang['unknown'], '</td> </tr>'; // If we've got partitions for this drive, show them too if (array_key_exists('partitions', $drive) && is_array($drive['partitions']) && count($drive['partitions']) > 0) { echo ' <tr> <td colspan="6">'; // Each foreach ($drive['partitions'] as $partition) { echo ' └ ' . (isset($partition['number']) ? $drive['device'] . $partition['number'] : $partition['name']) . ' - ' . Common::byteConvert($partition['size']) . '<br />'; } echo ' </td> </tr> '; } } } else { echo '<tr><td colspan="6" class="none">' . $lang['none_found'] . '</td></tr>'; } echo ' </table> </div>'; } // Show sound card stuff? if (!empty($settings['show']['sound']) && count($info['SoundCards']) > 0) { echo ' <div class="infoTable"> <h2>' . $lang['sound_cards'] . '</h2> <table> <tr> <th>' . $lang['number'] . '</th> <th>' . $lang['vendor'] . '</th> <th>' . $lang['card'] . '</th> </tr>'; foreach ($info['SoundCards'] as $card) { if (empty($card['vendor'])) { $card['vendor'] = 'Unknown'; } echo ' <tr> <td>' . $card['number'] . '</td> <td>' . $card['vendor'] . '</td> <td>' . $card['card'] . '</td> </tr>'; } echo ' </table> </div> '; } echo ' </div> </div>'; // Show file system mounts? if (!empty($settings['show']['mounts'])) { $has_devices = false; $has_labels = false; $has_types = false; foreach ($info['Mounts'] as $mount) { if (!empty($mount['device'])) { $has_devices = true; } if (!empty($mount['label'])) { $has_labels = true; } if (!empty($mount['devtype'])) { $has_types = true; } } $addcolumns = 0; if ($settings['show']['mounts_options']) { $addcolumns++; } if ($has_devices) { $addcolumns++; } if ($has_labels) { $addcolumns++; } if ($has_types) { $addcolumns++; } echo ' <div class="infoTable filesystem_mounts"> <h2>' . $lang['filesystem_mounts'] . '</h2> <table> <tr>'; if ($has_types) { echo '<th>' . $lang['type'] . '</th>'; } if ($has_devices) { echo '<th>' . $lang['device'] . '</th>'; } echo '<th>' . $lang['mount_point'] . '</th>'; if ($has_labels) { echo '<th>' . $lang['label'] . '</th>'; } echo ' <th>' . $lang['filesystem'] . '</th>', $settings['show']['mounts_options'] ? ' <th>' . $lang['mount_options'] . '</th>' : '', ' <th>' . $lang['size'] . '</th> <th>' . $lang['used'] . '</th> <th>' . $lang['free'] . '</th> <th style="width: 12%;">' . $lang['percent_used'] . '</th> </tr> '; // Calc totals $total_size = 0; $total_used = 0; $total_free = 0; // Don't add totals for duplicates. (same filesystem mount twice in different places) $done_devices = array(); // Are there any? if (count($info['Mounts']) > 0) { // Go through each foreach ($info['Mounts'] as $mount) { // Only add totals for this device if we haven't already if (!in_array($mount['device'], $done_devices)) { $total_size += $mount['size']; $total_used += $mount['used']; $total_free += $mount['free']; if (!empty($mount['device'])) { $done_devices[] = $mount['device']; } } elseif (array_key_exists('duplicate_mounts', $settings['show']) && empty($settings['show']['duplicate_mounts'])) { continue; } // If it's an NFS mount it's likely in the form of server:path (without a trailing slash), // but if the path is just / it likely just shows up as server:, // which is vague. If there isn't a /, add one if (preg_match('/^.+:$/', $mount['device']) == 1) { $mount['device'] .= DIRECTORY_SEPARATOR; } echo '<tr>'; if ($has_types) { echo '<td>' . $mount['devtype'] . '</td>'; } if ($has_devices) { echo '<td>' . $mount['device'] . '</td>'; } echo '<td>' . $mount['mount'] . '</td>'; if ($has_labels) { echo '<td>' . $mount['label'] . '</td>'; } echo ' <td>' . $mount['type'] . '</td>', $settings['show']['mounts_options'] ? ' <td>' . (empty($mount['options']) ? '<em>unknown</em>' : '<ul><li>' . implode('</li><li>', $mount['options']) . '</li></ul>') . '</td>' : '', ' <td>' . Common::byteConvert($mount['size']) . '</td> <td>' . Common::byteConvert($mount['used']) . ($mount['used_percent'] !== false ? ' <span class="perc">(' . $mount['used_percent'] . '%)</span>' : '') . '</td> <td>' . Common::byteConvert($mount['free']) . ($mount['free_percent'] !== false ? ' <span class="perc">(' . $mount['free_percent'] . '%)</span>' : '') . '</td> <td> ' . self::generateBarChart((int) $mount['used_percent'], $mount['used_percent'] ? $mount['used_percent'] . '%' : 'N/A') . ' </td> </tr>'; } } else { echo '<tr><td colspan="', 6 + $addcolumns, '" class="none">None found</td></tr>'; } // Show totals and finish table $total_used_perc = $total_size > 0 && $total_used > 0 ? round($total_used / $total_size, 2) * 100 : 0; echo ' <tr class="alt"> <td colspan="', 2 + $addcolumns, '">Totals: </td> <td>' . Common::byteConvert($total_size) . '</td> <td>' . Common::byteConvert($total_used) . '</td> <td>' . Common::byteConvert($total_free) . '</td> <td> ' . self::generateBarChart($total_used_perc, $total_used_perc . '%') . ' </td> </tr> </table> </div>'; } // Show RAID Arrays? if (!empty($settings['show']['raid']) && count($info['Raid']) > 0) { echo ' <div class="infoTable drives"> <h2>' . $lang['raid_arrays'] . '</h2> <table> <colgroup> <col style="width: 10%;" /> <col style="width: 30%;" /> <col style="width: 10%;" /> <col style="width: 10%;" /> <col style="width: 30%;" /> <col style="width: 10%;" /> </colgroup> <tr> <th>' . $lang['name'] . '</th> <th>' . $lang['level'] . '</th> <th>' . $lang['status'] . '</th> <th>' . $lang['size'] . '</th> <th>' . $lang['devices'] . '</th> <th>' . $lang['active'] . '</th> </tr> '; if (count($info['Raid']) > 0) { foreach ($info['Raid'] as $raid) { $active = explode('/', $raid['count']); // http://en.wikipedia.org/wiki/Standard_RAID_levels switch ($raid['level']) { case 0: $type = 'Stripe'; break; case 1: $type = 'Mirror'; break; case 10: $type = 'Mirrored Stripe'; break; case 5: case 6: $type = 'Distributed Parity Block-Level Striping'; break; default: $type = false; break; } echo ' <tr> <td>' . $raid['device'] . '</td> <td>' . $raid['level'] . ($type ? ' <span class="caption">(' . $type . ')</span>' : '') . '</td> <td>' . ucfirst($raid['status']) . '</td> <td>' . $raid['size'] . '</td> <td><table class="mini center margin_auto"><tr><th>' . $lang['device'] . '</th><th>' . $lang['state'] . '</th></tr>'; foreach ($raid['drives'] as $drive) { echo '<tr><td>' . $drive['drive'] . '</td><td class="raid_' . $drive['state'] . '">' . ucfirst($drive['state']) . '</td></tr>'; } echo '</table></td> <td>' . $active[1] . '/' . $active[0] . '</td> </tr> '; } } else { echo '<tr><td colspan="6" class="none">' . $lang['none_found'] . '</td></tr>'; } echo ' </table> </div>'; } // Feel like showing errors? Are there any even? if (!empty($settings['show_errors']) && Errors::num() > 0) { echo ' <div id="errorList" class="infoTable"> <h2>' . $lang['error_head'] . '</h2> <table> <tr> <th>' . $lang['from_where'] . '</th> <th>' . $lang['message'] . '</th> </tr>'; foreach (Errors::show() as $error) { echo ' <tr> <td>' . $error[0] . '</td> <td>' . $error[1] . '</td> </tr> '; } echo ' </table> </div> '; } // Additional extensions if (count($info['extensions']) > 0) { foreach ($info['extensions'] as $ext) { if (is_array($ext) && count($ext) > 0) { // Decide how to show something extra switch (array_key_exists('extra_type', $ext) && !empty($ext['extra_vals']) ? $ext['extra_type'] : false) { // Table with a key->value table to the right of it // Useful for stats or other stuff pertaining to // the main info to the left case 'k->v': echo ' <div class="col2_side"> <div class="col2_side_left"> ' . self::createTable($ext) . ' </div> <div class="col2_side_right"> <div class="infoTable"> <h2>' . $ext['extra_vals']['title'] . '</h2> <table>'; // Give each value foreach (array_filter($ext['extra_vals']['values']) as $v) { echo ' <tr> <th>' . $v[0] . '</th> <td>' . $v[1] . '</td> </tr>'; } echo ' </table> </div> </div> </div> '; break; // Nothing extra; just the table // Nothing extra; just the table default: echo self::createTable($ext); break; } } } } // Feel like showing timed results? if (!empty($settings['timer'])) { echo ' <div id="timerList" class="infoTable"> <h2>' . $lang['timer'] . '</h2> <table> <tr> <th>' . $lang['area'] . '</th> <th>' . $lang['time_taken'] . '</th> </tr>'; foreach (Timer::getResults() as $result) { echo ' <tr> <td>' . $result['id'] . '</td> <td>' . round($result['duration'], 3) . ' ' . $lang['seconds'] . '</td> </tr> '; } echo ' </table> </div> '; } echo ' <div id="foot"> ' . sprintf($lang['footer_app'], '<a href="https://github.com/jrgp/linfo"><em>' . $appName . '</em></a> (' . $version . ')', round(microtime(true) - $this->linfo->getTimeStart(), 2)) . '<br> <em>' . $appName . '</em> © 2010 – ' . (date('Y') > 2011 ? date('Y') : 2011) . ' Joseph Gillotti ' . (date('m/d') == '06/03' ? ' (who turns ' . (date('Y') - 1993) . ' today!)' : '') . '& friends. Source code licensed under GPL. </div> <div id="foot_time"> <br /> Generated on ' . date($settings['dates']) . ' </div> </body> </html>'; }
public static function tearDownAfterClass() { self::$parser = null; Common::unconfig(); Common::$path_prefix = false; }
/** * Run a command and cache its output for later. * * @throws Exception * * @param string $name name of executable to call * @param string $switches command arguments */ public function exec($name, $switches = '') { // Sometimes it is necessary to call a program with sudo $attempt_sudo = array_key_exists('sudo_apps', self::$settings) && in_array($name, self::$settings['sudo_apps']); // Have we gotten it before? if (array_key_exists($name . $switches, $this->cliCache)) { return $this->cliCache[$name . $switches]; } // Try finding the exec foreach ($this->searchPaths as $path) { // Found it; run it if (is_file($path . $name) && is_executable($path . $name)) { // Complete command, path switches and all $command = "{$path}{$name} {$switches}"; // Sudoing? $command = $attempt_sudo ? Common::locateActualPath(Common::arrayAppendString($this->searchPaths, 'sudo', '%2s%1s')) . ' ' . $command : $command; // Result of command $result = `{$command}`; // Increment call count ++self::$callCount; // Cache that $this->cliCache[$name . $switches] = $result; // Give result return $result; } } // Never got it throw new Exception('Exec `' . $name . '\' not found'); }