public static function cpu_model()
 {
     // Returns the processor name / frequency information
     $info = null;
     if (isset(phodevi::$vfs->cpuinfo)) {
         $physical_cpu_ids = phodevi_linux_parser::read_cpuinfo('physical id');
         $physical_cpu_count = count(array_unique($physical_cpu_ids));
         $cpu_strings = phodevi_linux_parser::read_cpuinfo(array('model name', 'Processor', 'cpu', 'cpu model'));
         $cpu_strings_unique = array_unique($cpu_strings);
         if ($physical_cpu_count == 1 || empty($physical_cpu_count)) {
             // Just one processor
             if (isset($cpu_strings[0]) && ($cut = strpos($cpu_strings[0], ' (')) !== false) {
                 $cpu_strings[0] = substr($cpu_strings[0], 0, $cut);
             }
             $info = isset($cpu_strings[0]) ? $cpu_strings[0] : null;
             if (strpos($info, 'ARM') !== false) {
                 if (is_dir('/sys/devices/system/exynos-core/') && stripos($info, 'Exynos') === false) {
                     $info = 'Exynos ' . $info;
                 }
             }
         } else {
             if ($physical_cpu_count > 1 && count($cpu_strings_unique) == 1) {
                 // Multiple processors, same model
                 $info = $physical_cpu_count . ' x ' . $cpu_strings[0];
             } else {
                 if ($physical_cpu_count > 1 && count($cpu_strings_unique) > 1) {
                     // Multiple processors, different models
                     $current_id = -1;
                     $current_string = $cpu_strings[0];
                     $current_count = 0;
                     $cpus = array();
                     for ($i = 0; $i < count($physical_cpu_ids); $i++) {
                         if ($current_string != $cpu_strings[$i] || $i == count($physical_cpu_ids) - 1) {
                             array_push($cpus, $current_count . ' x ' . $current_string);
                             $current_string = $cpu_strings[$i];
                             $current_count = 0;
                         }
                         if ($physical_cpu_ids[$i] != $current_id) {
                             $current_count++;
                             $current_id = $physical_cpu_ids[$i];
                         }
                     }
                     $info = implode(', ', $cpus);
                 }
             }
         }
     } else {
         if (phodevi::is_solaris()) {
             $dmi_cpu = phodevi_solaris_parser::read_sun_ddu_dmi_info('CPUType', '-C');
             if (count($dmi_cpu) == 0) {
                 $dmi_cpu = phodevi_solaris_parser::read_sun_ddu_dmi_info('ProcessorName');
             }
             if (count($dmi_cpu) > 0) {
                 $info = $dmi_cpu[0];
             } else {
                 $info = trim(shell_exec('dmesg 2>&1 | grep cpu0'));
                 $info = trim(substr($info, strrpos($info, 'cpu0:') + 6));
                 if (empty($info)) {
                     $info = array_pop(phodevi_solaris_parser::read_sun_ddu_dmi_info('ProcessorManufacturer'));
                 }
             }
             //TODO: Add in proper support for reading multiple CPUs, similar to the code from above
             $physical_cpu_count = count(phodevi_solaris_parser::read_sun_ddu_dmi_info('ProcessorSocketType'));
             if ($physical_cpu_count > 1 && !empty($info)) {
                 // TODO: For now assuming when multiple CPUs are installed, that they are of the same type
                 $info = $physical_cpu_count . ' x ' . $info;
             }
         } else {
             if (phodevi::is_bsd()) {
                 $info = phodevi_bsd_parser::read_sysctl('hw.model');
             } else {
                 if (phodevi::is_macosx()) {
                     $info = phodevi_osx_parser::read_osx_system_profiler('SPHardwareDataType', 'ProcessorName');
                 } else {
                     if (phodevi::is_windows()) {
                         $info = phodevi_windows_parser::read_cpuz('Processor 1', 'Name');
                         if (!$info) {
                             $info = getenv('PROCESSOR_IDENTIFIER');
                         }
                     }
                 }
             }
         }
     }
     if (empty($info)) {
         $info = 'Unknown';
     } else {
         if (($strip_point = strpos($info, '@')) > 0) {
             $info = trim(substr($info, 0, $strip_point));
             // stripping out the reported freq, since the CPU could be overclocked, etc
         }
         $info = pts_strings::strip_string($info);
         // It seems Intel doesn't report its name when reporting Pentium hardware
         if (strpos($info, 'Pentium') !== false && strpos($info, 'Intel') === false) {
             $info = 'Intel ' . $info;
         }
         if (substr($info, 0, 5) == 'Intel') {
             $cpu_words = explode(' ', $info);
             $cpu_words_count = count($cpu_words);
             // Convert strings like 'Intel Core i7 M 620' -> 'Intel Core i7 620M' and 'Intel Core i7 X 990' -> 'Intel Core i7 990X' to better reflect Intel product marketing names
             if ($cpu_words_count > 4 && is_numeric($cpu_words[$cpu_words_count - 1]) && strlen($cpu_words[$cpu_words_count - 2]) == 1 && strlen($cpu_words[$cpu_words_count - 3]) == 2) {
                 $cpu_words[$cpu_words_count - 1] .= $cpu_words[$cpu_words_count - 2];
                 unset($cpu_words[$cpu_words_count - 2]);
                 $info = implode(' ', $cpu_words);
             }
         }
     }
     return $info;
 }
 public static function read_pci($desc, $clean_string = true)
 {
     // Read PCI bus information
     static $pci_info = null;
     $info = false;
     $desc = pts_arrays::to_array($desc);
     if ($pci_info == null) {
         if (!is_executable('/usr/bin/lspci') && is_executable('/sbin/lspci')) {
             $lspci_cmd = '/sbin/lspci';
         } else {
             if ($lspci = pts_client::executable_in_path('lspci')) {
                 $lspci_cmd = $lspci;
             } else {
                 return false;
             }
         }
         $pci_info = shell_exec($lspci_cmd . ' 2> /dev/null');
     }
     for ($i = 0; $i < count($desc) && empty($info); $i++) {
         if (substr($desc[$i], -1) != ':') {
             $desc[$i] .= ':';
         }
         if (($pos = strpos($pci_info, $desc[$i])) !== false) {
             $sub_pci_info = str_replace(array('[AMD]', '[AMD/ATI]'), null, substr($pci_info, $pos + strlen($desc[$i])));
             $EOL = strpos($sub_pci_info, "\n");
             if ($clean_string) {
                 if (($temp = strpos($sub_pci_info, '/')) < $EOL && $temp > 0) {
                     if (($temp = strpos($sub_pci_info, ' ', $temp + 2)) < $EOL && $temp > 0) {
                         $EOL = $temp;
                     }
                 }
                 if (($temp = strpos($sub_pci_info, '(')) < $EOL && $temp > 0) {
                     $EOL = $temp;
                 }
                 if (($temp = strpos($sub_pci_info, '[')) < $EOL && $temp > 0) {
                     $EOL = $temp;
                 }
             }
             $sub_pci_info = trim(substr($sub_pci_info, 0, $EOL));
             if (($strlen = strlen($sub_pci_info)) >= 6 && $strlen < 128) {
                 $info = pts_strings::strip_string($sub_pci_info);
             }
         }
     }
     return $info;
 }
 public static function read_property($device, $read_property)
 {
     $value = false;
     if (method_exists('phodevi_' . $device, 'read_property')) {
         $property = call_user_func(array('phodevi_' . $device, 'read_property'), $read_property);
         if (!$property instanceof phodevi_device_property) {
             return false;
         }
         $cache_code = $property->cache_code();
         if ($cache_code != phodevi::no_caching && phodevi::$allow_phodevi_caching && isset(self::$device_cache[$device][$read_property])) {
             $value = self::$device_cache[$device][$read_property];
         } else {
             $dev_function_r = pts_arrays::to_array($property->get_device_function());
             $dev_function = $dev_function_r[0];
             $function_pass = array();
             for ($i = 1; $i < count($dev_function_r); $i++) {
                 array_push($function_pass, $dev_function_r[$i]);
             }
             if (method_exists('phodevi_' . $device, $dev_function)) {
                 $value = call_user_func_array(array('phodevi_' . $device, $dev_function), $function_pass);
                 if (!is_array($value) && $value != null) {
                     $value = pts_strings::strip_string($value);
                     if (function_exists('preg_replace')) {
                         $value = preg_replace('/[^(\\x20-\\x7F)]*/', '', $value);
                     }
                 }
                 if ($cache_code != phodevi::no_caching) {
                     self::$device_cache[$device][$read_property] = $value;
                     if ($cache_code == phodevi::smart_caching) {
                         // TODO: For now just copy the smart cache to other var, but come up with better yet efficient way
                         self::$smart_cache[$device][$read_property] = $value;
                     }
                 }
             }
         }
     }
     return $value;
 }
 public static function parse_pci_device_data(&$lspci, &$dmesg, $ignore_external_pci_devices = false)
 {
     $pci_devices = explode(PHP_EOL . PHP_EOL, $lspci);
     $sanitized_devices = array();
     foreach ($pci_devices as &$device) {
         $device .= PHP_EOL;
         $location = substr($device, 0, strpos($device, ' '));
         if (!strpos($location, ':') || !strpos($location, '.')) {
             // If it's not a valid PCI bus location (i.e. XX:YY.Z), it's probably not formatted well or wrong
             continue;
         }
         $class = substr($device, $s = strpos($device, '[') + 1, strpos($device, ']', $s) - $s);
         if (!(isset($class[3]) && !isset($class[4]))) {
             // class must be 4 characters: 2 for class, 2 for sub-class
             continue;
         }
         // 0300 is GPUs
         if ($ignore_external_pci_devices && in_array($class, array('0300'))) {
             // Don't report external PCI devices
             continue;
         }
         $device_class = substr($class, 0, 2);
         $sub_class = substr($class, 2, 2);
         $device_name = substr($device, $l = strpos($device, ']:') + 3, ($s = strpos($device, ':', $l)) - $l);
         $device_name = substr($device_name, 0, strrpos($device_name, ' ['));
         $device_name = str_replace('/', '-', str_replace(array('[AMD]', '[SiS]'), null, $device_name));
         $device_name = pts_strings::strip_string($device_name);
         if ($device_name == null || strpos($device_name, ' ') === false) {
             // it must be junk not worth reporting
             continue;
         }
         $temp = substr($device, $s - 5);
         if ($temp[0] != '[' || $temp[10] != ']') {
             continue;
         }
         $vendor_id = substr($temp, 1, 4);
         $device_id = substr($temp, 6, 4);
         $drivers = array();
         if (($s = strpos($device, 'Kernel driver in use:')) !== false) {
             $temp = substr($device, $s = $s + 22, strpos($device, PHP_EOL, $s) - $s);
             if ($temp != null) {
                 array_push($drivers, $temp);
             }
         }
         if (($s = strpos($device, 'Kernel modules:')) !== false) {
             $temp = substr($device, $s = $s + 16, strpos($device, PHP_EOL, $s) - $s);
             if ($temp != null) {
                 foreach (explode(' ', trim($temp)) as $temp) {
                     $temp = str_replace(',', null, $temp);
                     if ($temp != null && !in_array($temp, $drivers)) {
                         array_push($drivers, $temp);
                     }
                 }
             }
         }
         if (empty($drivers)) {
             // If there's no drivers, nothing to report
             continue;
         }
         if (!in_array($vendor_id . ':' . $device_id, array_keys($sanitized_devices))) {
             $dmesg_example = array();
             if ($dmesg != null) {
                 foreach ($drivers as $driver) {
                     $offset = 1;
                     while ($offset != false && ($offset = strpos($dmesg, $driver, $offset)) !== false) {
                         $line = substr($dmesg, 0, strpos($dmesg, "\n", $offset));
                         $line = substr($line, strrpos($line, "\n"));
                         $line = trim(substr($line, strpos($line, '] ') + 2));
                         if ($line != null && !isset($line[128])) {
                             array_push($dmesg_example, $line);
                         }
                         $offset = strpos($dmesg, "\n", $offset + 1);
                     }
                 }
             }
             $sanitized_devices[$vendor_id . ':' . $device_id] = array($vendor_id, $device_id, $device_name, $device_class, $sub_class, $drivers, trim($device), implode(PHP_EOL, $dmesg_example));
         }
     }
     return $sanitized_devices;
 }
 protected function generate_processor_data(&$result_file, $system_identifier)
 {
     $this->rows[] = $system_identifier;
     $rows_index = count($this->rows) - 1;
     foreach ($this->columns as $i => $cpuinfo_item) {
         switch ($cpuinfo_item) {
             case 'Features':
                 $line = phodevi_cpu::instruction_set_extensions();
                 break;
             case 'Core Count':
                 $line = phodevi_cpu::cpuinfo_core_count();
                 break;
             case 'Thread Count':
                 $line = phodevi_cpu::cpuinfo_thread_count();
                 break;
             case 'L2 Cache':
                 $line = phodevi_cpu::lscpu_l2_cache();
                 break;
             case 'Virtualization':
                 $line = phodevi_cpu::virtualization_technology();
                 break;
             default:
                 $line = phodevi_cpu::read_cpuinfo_line(strtolower($cpuinfo_item), false);
                 break;
         }
         if ($line) {
             $line = pts_strings::strip_string($line);
         }
         $this->table_data[$i][$rows_index] = $line;
     }
 }