2024-09-07 20:53:46 +10:00
< ? php
/**
* Linux System Class
*
* PHP version 5
*
* @ category PHP
* @ package PSI Linux OS class
* @ author Michael Cramer < BigMichi1 @ users . sourceforge . net >
* @ copyright 2009 phpSysInfo
2025-05-14 16:14:01 +01:00
* @ license http :// opensource . org / licenses / gpl - 2.0 . php GNU General Public License version 2 , or ( at your option ) any later version
2024-09-07 20:53:46 +10:00
* @ version SVN : $Id : class . Linux . inc . php 712 2012 - 12 - 05 14 : 09 : 18 Z namiltd $
* @ link http :// phpsysinfo . sourceforge . net
*/
/**
* Linux sysinfo class
* get all the required information from Linux system
*
* @ category PHP
* @ package PSI Linux OS class
* @ author Michael Cramer < BigMichi1 @ users . sourceforge . net >
* @ copyright 2009 phpSysInfo
2025-05-14 16:14:01 +01:00
* @ license http :// opensource . org / licenses / gpl - 2.0 . php GNU General Public License version 2 , or ( at your option ) any later version
2024-09-07 20:53:46 +10:00
* @ version Release : 3.0
* @ link http :// phpsysinfo . sourceforge . net
*/
class Linux extends OS
{
2025-05-14 16:14:01 +01:00
/**
* Uptime command result .
*/
private $_uptime = null ;
2024-09-07 20:53:46 +10:00
/**
* Assoc array of all CPUs loads .
*/
2025-05-14 16:14:01 +01:00
protected $_cpu_loads = null ;
/**
* Version string .
*/
private $_kernel_string = null ;
2024-09-07 20:53:46 +10:00
/**
2025-05-14 16:14:01 +01:00
* Array of info from Bios .
2024-09-07 20:53:46 +10:00
*/
2025-05-14 16:14:01 +01:00
private $_machine_info = null ;
/**
* Content of dmesg file .
*/
private $_dmesg_f = null ;
/**
* Result of executing dmesg command .
*/
private $_dmesg_c = null ;
/**
* Result of systemd - detect - virt .
*/
private $system_detect_virt = null ;
/**
* Read contents of the dmesg file .
*
* @ return string
*/
private function _get_dmesg_f ()
{
if ( $this -> _dmesg_f === null ) {
$this -> _dmesg_f = " " ;
if ( CommonFunctions :: rfts ( '/var/log/dmesg' , $result , 0 , 4096 , false )) {
$this -> _dmesg_f = trim ( $result );
}
}
return $this -> _dmesg_f ;
}
/**
* Save output of the dmesg command .
*
* @ return string
*/
private function _get_dmesg_c ()
2024-09-07 20:53:46 +10:00
{
2025-05-14 16:14:01 +01:00
if ( $this -> _dmesg_c === null ) {
$this -> _dmesg_c = " " ;
if ( CommonFunctions :: executeProgram ( 'dmesg' , '' , $result , false )) {
$this -> _dmesg_c = trim ( $result );
}
}
return $this -> _dmesg_c ;
2024-09-07 20:53:46 +10:00
}
/**
2025-05-14 16:14:01 +01:00
* Get machine info
2024-09-07 20:53:46 +10:00
*
2025-05-14 16:14:01 +01:00
* @ return string
2024-09-07 20:53:46 +10:00
*/
2025-05-14 16:14:01 +01:00
private function _get_machine_info ()
2024-09-07 20:53:46 +10:00
{
2025-05-14 16:14:01 +01:00
if ( $this -> _machine_info === null ) {
$this -> _machine_info = array ();
if ( defined ( 'PSI_SHOW_VIRTUALIZER_INFO' ) && PSI_SHOW_VIRTUALIZER_INFO ) {
if ( CommonFunctions :: executeProgram ( 'systemd-detect-virt' , '-v' , $resultv , false )) {
$this -> system_detect_virt = $resultv ;
}
2024-09-07 20:53:46 +10:00
}
2025-05-14 16:14:01 +01:00
$vendor_array = array ();
if (((( $dmesg = $this -> _get_dmesg_f ()) !== null ) && preg_match ( '/^[\s\[\]\.\d]*DMI:\s*(.+)/m' , $dmesg , $ar_buf )) ||
((( $dmesg = $this -> _get_dmesg_c ()) !== null ) && preg_match ( '/^[\s\[\]\.\d]*DMI:\s*(.+)/m' , $dmesg , $ar_buf ))) {
$this -> _machine_info [ 'machine' ] = trim ( $ar_buf [ 1 ]);
if ( defined ( 'PSI_SHOW_VIRTUALIZER_INFO' ) && PSI_SHOW_VIRTUALIZER_INFO && ( $this -> system_detect_virt === null )) {
/* Test this before sys_vendor to detect KVM over QEMU */
if ( CommonFunctions :: rfts ( '/sys/devices/virtual/dmi/id/product_name' , $buf , 1 , 4096 , false ) && ( trim ( $buf ) != " " )) {
$vendor_array [] = $product_name = trim ( $buf );
} else {
$product_name = '' ;
}
if ( CommonFunctions :: rfts ( '/sys/devices/virtual/dmi/id/sys_vendor' , $buf , 1 , 4096 , false ) && ( trim ( $buf ) != " " )) {
$vendor_array [] = trim ( $buf );
}
if ( CommonFunctions :: rfts ( '/sys/devices/virtual/dmi/id/board_vendor' , $buf , 1 , 4096 , false ) && ( trim ( $buf ) != " " )) {
if ( $product_name != " " ) {
$vendor_array [] = trim ( $buf ) . " " . $product_name ;
} else {
$vendor_array [] = trim ( $buf );
}
} else {
$vendor_array [] = $this -> _machine_info [ 'machine' ];
}
if ( CommonFunctions :: rfts ( '/sys/devices/virtual/dmi/id/bios_vendor' , $buf , 1 , 4096 , false ) && ( trim ( $buf ) != " " )) {
$vendor_array [] = trim ( $buf );
}
if ( CommonFunctions :: rfts ( '/sys/devices/virtual/dmi/id/product_version' , $buf , 1 , 4096 , false ) && ( trim ( $buf ) != " " )) {
$vendor_array [] = trim ( $buf );
}
}
} else { // 'machine' data from /sys/devices/virtual/dmi/id/
$bios = " " ;
if ( defined ( 'PSI_SHOW_VIRTUALIZER_INFO' ) && PSI_SHOW_VIRTUALIZER_INFO && ( $this -> system_detect_virt === null )) {
// Test this before sys_vendor to detect KVM over QEMU
if ( CommonFunctions :: rfts ( '/sys/devices/virtual/dmi/id/product_name' , $buf , 1 , 4096 , false ) && ( trim ( $buf ) != " " )) {
$vendor_array [] = $product_name = trim ( $buf );
} else {
$product_name = '' ;
}
if ( CommonFunctions :: rfts ( '/sys/devices/virtual/dmi/id/sys_vendor' , $buf , 1 , 4096 , false ) && ( trim ( $buf ) != " " )) {
$vendor_array [] = trim ( $buf );
}
if ( CommonFunctions :: rfts ( '/sys/devices/virtual/dmi/id/board_vendor' , $buf , 1 , 4096 , false ) && ( trim ( $buf ) != " " )) {
if ( $product_name != " " ) {
$this -> _machine_info [ 'machine' ] = trim ( $buf ) . " " . $product_name ;
} else {
$this -> _machine_info [ 'machine' ] = trim ( $buf );
}
$vendor_array [] = $this -> _machine_info [ " machine " ];
} elseif ( $product_name != " " ) {
$this -> _machine_info [ 'machine' ] = $product_name ;
}
if ( CommonFunctions :: rfts ( '/sys/devices/virtual/dmi/id/bios_vendor' , $buf , 1 , 4096 , false ) && ( trim ( $buf ) != " " )) {
$vendor_array [] = trim ( $buf );
}
if ( CommonFunctions :: rfts ( '/sys/devices/virtual/dmi/id/product_version' , $buf , 1 , 4096 , false ) && ( trim ( $buf ) != " " )) {
$vendor_array [] = trim ( $buf );
}
} else {
if ( CommonFunctions :: rfts ( '/sys/devices/virtual/dmi/id/board_vendor' , $buf , 1 , 4096 , false ) && ( trim ( $buf ) != " " )) {
$this -> _machine_info [ 'machine' ] = trim ( $buf );
}
if ( CommonFunctions :: rfts ( '/sys/devices/virtual/dmi/id/product_name' , $buf , 1 , 4096 , false ) && ( trim ( $buf ) != " " )) {
if ( isset ( $this -> _machine_info [ 'machine' ])) {
$this -> _machine_info [ 'machine' ] .= " " . trim ( $buf );
} else {
$this -> _machine_info [ 'machine' ] = trim ( $buf );
}
}
}
if ( CommonFunctions :: rfts ( '/sys/devices/virtual/dmi/id/board_name' , $buf , 1 , 4096 , false ) && ( trim ( $buf ) != " " )) {
if ( isset ( $this -> _machine_info [ 'machine' ])) {
$this -> _machine_info [ 'machine' ] .= " / " . trim ( $buf );
} else {
$this -> _machine_info [ 'machine' ] = trim ( $buf );
}
}
if ( CommonFunctions :: rfts ( '/sys/devices/virtual/dmi/id/bios_version' , $buf , 1 , 4096 , false ) && ( trim ( $buf ) != " " )) {
$bios = trim ( $buf );
}
if ( CommonFunctions :: rfts ( '/sys/devices/virtual/dmi/id/bios_date' , $buf , 1 , 4096 , false ) && ( trim ( $buf ) != " " )) {
$bios = trim ( $bios . " " . trim ( $buf ));
}
if ( $bios != " " ) {
if ( isset ( $this -> _machine_info [ 'machine' ])) {
$this -> _machine_info [ 'machine' ] .= " , BIOS " . $bios ;
} else {
$this -> _machine_info [ 'machine' ] = " BIOS " . $bios ;
}
}
2024-09-07 20:53:46 +10:00
}
2025-05-14 16:14:01 +01:00
if ( isset ( $this -> _machine_info [ 'machine' ])) {
$this -> _machine_info [ 'machine' ] = trim ( preg_replace ( " /^ \ /,?/ " , " " , preg_replace ( " / ?(To be filled by O \ .E \ .M \ .|System manufacturer|System Product Name|Not Specified|Default string) ?/i " , " " , $this -> _machine_info [ 'machine' ])));
2024-09-07 20:53:46 +10:00
}
2025-05-14 16:14:01 +01:00
if ( defined ( 'PSI_SHOW_VIRTUALIZER_INFO' ) && PSI_SHOW_VIRTUALIZER_INFO && ( $this -> system_detect_virt === null ) && count ( $vendor_array ) > 0 ) {
$virt = CommonFunctions :: decodevirtualizer ( $vendor_array );
if ( $virt !== null ) {
$this -> _machine_info [ 'hypervisor' ] = $virt ;
}
2024-09-07 20:53:46 +10:00
}
2025-05-14 16:14:01 +01:00
}
return $this -> _machine_info ;
}
/**
* Get kernel string
*
* @ return string
*/
private function _get_kernel_string ()
{
if ( $this -> _kernel_string === null ) {
$this -> _kernel_string = " " ;
if ( $this -> sys -> getOS () !== 'SSH' ) {
if (( CommonFunctions :: executeProgram ( $uname = " uptrack-uname " , '-r' , $strBuf , false ) && ( $strBuf !== '' )) || // show effective kernel if ksplice uptrack is installed
( CommonFunctions :: executeProgram ( $uname = " uname " , '-r' , $strBuf , PSI_DEBUG ) && ( $strBuf !== '' ))) {
$this -> _kernel_string = $strBuf ;
if ( CommonFunctions :: executeProgram ( $uname , '-v' , $strBuf , PSI_DEBUG ) && ( $strBuf !== '' )) {
if ( preg_match ( '/ SMP /' , $strBuf )) {
$this -> _kernel_string .= ' (SMP)' ;
}
}
if ( CommonFunctions :: executeProgram ( $uname , '-m' , $strBuf , PSI_DEBUG ) && ( $strBuf !== '' )) {
$this -> _kernel_string .= ' ' . $strBuf ;
}
} elseif ( CommonFunctions :: rfts ( '/proc/version' , $strBuf , 1 )) {
if ( preg_match ( '/\/Hurd-([^\)]+)/' , $strBuf , $ar_buf )) {
$this -> _kernel_string = $ar_buf [ 1 ];
} elseif ( preg_match ( '/version\s+(\S+)/' , $strBuf , $ar_buf )) {
$this -> _kernel_string = $ar_buf [ 1 ];
if ( preg_match ( '/ SMP /' , $strBuf )) {
$this -> _kernel_string .= ' (SMP)' ;
}
}
}
2024-09-07 20:53:46 +10:00
}
2025-05-14 16:14:01 +01:00
}
return $this -> _kernel_string ;
}
/**
* check OS type
*/
public function __construct ( $blockname = false )
{
parent :: __construct ( $blockname );
if (( $this -> sys -> getOS () == 'SSH' ) && CommonFunctions :: executeProgram ( 'uname' , '-s' , $strBuf , false ) && ( $strBuf !== '' )) {
$this -> sys -> setOS ( $strBuf );
}
}
/**
* Machine
*
* @ return void
*/
protected function _machine ()
{
$machine_info = $this -> _get_machine_info ();
if ( isset ( $machine_info [ 'machine' ])) {
$machine = $machine_info [ 'machine' ];
} else {
$machine = " " ;
}
2024-09-07 20:53:46 +10:00
2025-05-14 16:14:01 +01:00
if ( CommonFunctions :: fileexists ( $filename = " /etc/config/uLinux.conf " ) // QNAP detection
&& CommonFunctions :: rfts ( $filename , $buf , 0 , 4096 , false )
&& preg_match ( " /^Rsync \ sModel \ s*= \ s*QNAP/m " , $buf )
&& CommonFunctions :: fileexists ( $filename = " /etc/platform.conf " ) // Platform detection
&& CommonFunctions :: rfts ( $filename , $buf , 0 , 4096 , false )
&& preg_match ( " /^DISPLAY_NAME \ s*= \ s*( \ S+)/m " , $buf , $mach_buf ) && ( $mach_buf [ 1 ] !== " " )) {
if ( $machine !== " " ) {
$machine = " QNAP " . $mach_buf [ 1 ] . ' - ' . $machine ;
} else {
$machine = " QNAP " . $mach_buf [ 1 ];
2024-09-07 20:53:46 +10:00
}
}
2025-05-14 16:14:01 +01:00
if ( $machine !== " " ) {
$this -> sys -> setMachine ( $machine );
}
2024-09-07 20:53:46 +10:00
}
/**
* Hostname
*
* @ return void
*/
protected function _hostname ()
{
2025-05-14 16:14:01 +01:00
if ( PSI_USE_VHOST && ! defined ( 'PSI_EMU_PORT' )) {
if ( CommonFunctions :: readenv ( 'SERVER_NAME' , $hnm )) $this -> sys -> setHostname ( $hnm );
2024-09-07 20:53:46 +10:00
} else {
2025-05-14 16:14:01 +01:00
if ( CommonFunctions :: rfts ( '/proc/sys/kernel/hostname' , $result , 1 , 4096 , PSI_DEBUG && ( PSI_OS != 'Android' ))) {
2024-09-07 20:53:46 +10:00
$result = trim ( $result );
$ip = gethostbyname ( $result );
if ( $ip != $result ) {
2025-05-14 16:14:01 +01:00
$this -> sys -> setHostname ( trim ( gethostbyaddr ( $ip ), " . " ));
2024-09-07 20:53:46 +10:00
}
2025-05-14 16:14:01 +01:00
} elseif ( CommonFunctions :: executeProgram ( 'hostname' , '' , $ret , false )) {
$this -> sys -> setHostname ( $ret );
} elseif ( CommonFunctions :: executeProgram ( 'uname' , '-n' , $ret , false )) {
$this -> sys -> setHostname ( $ret );
2024-09-07 20:53:46 +10:00
}
2025-05-14 16:14:01 +01:00
2024-09-07 20:53:46 +10:00
}
}
/**
2025-05-14 16:14:01 +01:00
* Kernel Version
2024-09-07 20:53:46 +10:00
*
* @ return void
*/
2025-05-14 16:14:01 +01:00
protected function _kernel ()
2024-09-07 20:53:46 +10:00
{
2025-05-14 16:14:01 +01:00
if (( $verBuf = $this -> _get_kernel_string ()) != " " ) {
$this -> sys -> setKernel ( $verBuf );
2024-09-07 20:53:46 +10:00
}
}
/**
2025-05-14 16:14:01 +01:00
* Virtualizer info
2024-09-07 20:53:46 +10:00
*
* @ return void
*/
2025-05-14 16:14:01 +01:00
protected function _virtualizer ()
2024-09-07 20:53:46 +10:00
{
2025-05-14 16:14:01 +01:00
if ( ! defined ( 'PSI_SHOW_VIRTUALIZER_INFO' ) || ! PSI_SHOW_VIRTUALIZER_INFO ) {
return ;
}
if ( $this -> system_detect_virt !== null ) {
if (( $this -> system_detect_virt !== " " ) && ( $this -> system_detect_virt !== " none " )) {
$this -> sys -> setVirtualizer ( $this -> system_detect_virt );
}
if (( $verBuf = $this -> _get_kernel_string ()) !== " " ) {
if ( preg_match ( '/^[\d\.-]+-microsoft-standard/' , $verBuf )) {
$this -> sys -> setVirtualizer ( 'wsl2' , 'wsl' ); // Windows Subsystem for Linux 2
2024-09-07 20:53:46 +10:00
}
}
2025-05-14 16:14:01 +01:00
if ( CommonFunctions :: executeProgram ( 'systemd-detect-virt' , '-c' , $resultc , false ) && ( $resultc !== " " ) && ( $resultc !== " none " )) {
$this -> sys -> setVirtualizer ( $resultc );
2024-09-07 20:53:46 +10:00
}
2025-05-14 16:14:01 +01:00
} else {
$cpuvirt = $this -> sys -> getVirtualizer (); // previous info from _cpuinfo()
$novm = true ;
// code based on src/basic/virt.c from systemd-detect-virt source code (https://github.com/systemd/systemd)
// First, try to detect Oracle Virtualbox, Amazon EC2 Nitro and Parallels, even if they use KVM,
// as well as Xen even if it cloaks as Microsoft Hyper-V. Attempt to detect uml at this stage also
// since it runs as a user-process nested inside other VMs. Also check for Xen now, because Xen PV
// mode does not override CPUID when nested inside another hypervisor.
$machine_info = $this -> _get_machine_info ();
if ( isset ( $machine_info [ 'hypervisor' ])) {
$hypervisor = $machine_info [ 'hypervisor' ];
if (( $hypervisor === 'oracle' ) || ( $hypervisor === 'amazon' ) || ( $hypervisor === 'xen' ) || ( $hypervisor === 'parallels' )) {
$this -> sys -> setVirtualizer ( $hypervisor );
$novm = false ;
}
2024-09-07 20:53:46 +10:00
}
2025-05-14 16:14:01 +01:00
// Detect UML
if ( $novm ) {
if ( isset ( $cpuvirt [ " cpuid:UserModeLinux " ])) {
$this -> sys -> setVirtualizer ( 'uml' ); // User-mode Linux
$novm = false ;
}
}
// Detect Xen
if ( $novm && is_dir ( '/proc/xen' )) {
// xen Dom0 is detected as XEN in hypervisor and maybe others.
// In order to detect the Dom0 as not virtualization we need to
// double-check it
if ( CommonFunctions :: rfts ( '/sys/hypervisor/properties/features' , $features , 1 , 4096 , false )) {
if (( hexdec ( $features ) & 2048 ) == 0 ) { // XENFEAT_dom0 is not set
$this -> sys -> setVirtualizer ( 'xen' ); // Xen hypervisor (only domU, not dom0)
$novm = false ;
}
} elseif ( CommonFunctions :: rfts ( '/proc/xen/capabilities' , $capabilities , 1 , 4096 , false ) && ! preg_match ( '/control_d/' , $capabilities )) { // control_d not in capabilities
$this -> sys -> setVirtualizer ( 'xen' ); // Xen hypervisor (only domU, not dom0)
$novm = false ;
}
}
// Second, try to detect from CPUID, this will report KVM for whatever software is used even if info in DMI is overwritten.
// Since the vendor_id in /proc/cpuinfo is overwritten on virtualization we use values from msr-cpuid.
if ( $novm && CommonFunctions :: executeProgram ( 'msr-cpuid' , '' , $bufr , false )
&& ( preg_match ( '/^40000000 00000000: [0-9a-f]{8} \S{4} [0-9a-f]{8} ([A-Za-z0-9\.]{4}) [0-9a-f]{8} ([A-Za-z0-9\.]{4}) [0-9a-f]{8} ([A-Za-z0-9\.]{4})/m' , $bufr , $cpuid ))) {
$virt = CommonFunctions :: decodevirtualizer ( $cpuid [ 1 ] . $cpuid [ 2 ] . $cpuid [ 3 ]);
if ( $virt !== null ) {
$this -> sys -> setVirtualizer ( $virt );
}
}
// Third, try to detect from DMI.
if ( $novm && isset ( $hypervisor )) {
$this -> sys -> setVirtualizer ( $hypervisor );
$novm = false ;
}
// Check high-level hypervisor sysfs file
if ( $novm && CommonFunctions :: rfts ( '/sys/hypervisor/type' , $type , 1 , 4096 , false ) && ( $type === " xen " )) {
$this -> sys -> setVirtualizer ( 'xen' ); // Xen hypervisor
$novm = false ;
}
if ( $novm ) {
if ( CommonFunctions :: rfts ( '/proc/device-tree/hypervisor/compatible' , $compatible , 1 , 4096 , false )) {
switch ( $compatible ) {
case 'linux,kvm' :
$this -> sys -> setVirtualizer ( 'kvm' ); // KVM
$novm = false ;
break ;
case 'vmware' :
$this -> sys -> setVirtualizer ( 'vmware' ); // VMware
$novm = false ;
break ;
case 'xen' :
$this -> sys -> setVirtualizer ( 'xen' ); // Xen hypervisor
$novm = false ;
}
} else {
if ( CommonFunctions :: fileexists ( '/proc/device-tree/ibm,partition-name' )
&& CommonFunctions :: fileexists ( '/proc/device-tree/hmc-managed?' )
&& CommonFunctions :: fileexists ( '/proc/device-tree/chosen/qemu,graphic-width' )) {
$this -> sys -> setVirtualizer ( 'powervm' ); // IBM PowerVM hypervisor
$novm = false ;
} else {
$names = CommonFunctions :: findglob ( '/proc/device-tree' , GLOB_NOSORT );
if ( is_array ( $names ) && (( $total = count ( $names )) > 0 )) {
for ( $i = 0 ; $i < $total ; $i ++ ) {
if ( preg_match ( '/fw-cfg/' , $names [ $i ])) {
$this -> sys -> setVirtualizer ( 'qemu' ); // QEMU
$novm = false ;
break ;
}
}
}
if ( CommonFunctions :: rfts ( '/proc/device-tree/compatible' , $compatible , 1 , 4096 , false ) && ( $compatible === " qemu,pseries " )) {
$this -> sys -> setVirtualizer ( 'qemu' ); // QEMU
$novm = false ;
}
}
}
}
if ( $novm && CommonFunctions :: rfts ( '/proc/sysinfo' , $sysinfo , 0 , 4096 , false ) && preg_match ( '//VM00 Control Program:\s*(\S+)/m' , $sysinfo , $vcp )) {
if ( $vcp [ 1 ] === 'z/VM' ) {
$this -> sys -> setVirtualizer ( 'zvm' ); // s390 z/VM
} else {
$this -> sys -> setVirtualizer ( 'kvm' ); // KVM
}
$novm = false ;
}
// Additional tests outside of the systemd-detect-virt source code
if ( $novm && (
((( $dmesg = $this -> _get_dmesg_f ()) !== null ) && preg_match ( '/^[\s\[\]\.\d]*Hypervisor detected:\s*(.+)/m' , $dmesg , $ar_buf )) ||
((( $dmesg = $this -> _get_dmesg_c ()) !== null ) && preg_match ( '/^[\s\[\]\.\d]*Hypervisor detected:\s*(.+)/m' , $dmesg , $ar_buf )))) {
switch ( trim ( $ar_buf [ 1 ])) {
case 'VMware' :
$this -> sys -> setVirtualizer ( 'vmware' ); // VMware
$novm = false ;
break ;
case 'KVM' :
$this -> sys -> setVirtualizer ( 'kvm' ); // KVM
$novm = false ;
break ;
case 'Microsoft HyperV' :
case 'Microsoft Hyper-V' :
$this -> sys -> setVirtualizer ( 'microsoft' ); // Hyper-V
$novm = false ;
break ;
case 'ACRN' :
$this -> sys -> setVirtualizer ( 'acrn' ); // ACRN hypervisor
$novm = false ;
break ;
case 'Jailhouse' :
$this -> sys -> setVirtualizer ( 'jailhouse' ); // Jailhouse
$novm = false ;
break ;
case 'Xen' :
case 'Xen PV' :
case 'Xen HVM' :
// xen Dom0 is detected as XEN in hypervisor and maybe others.
// In order to detect the Dom0 as not virtualization we need to
// double-check it
if ( CommonFunctions :: rfts ( '/sys/hypervisor/properties/features' , $features , 1 , 4096 , false )) {
if (( hexdec ( $features ) & 2048 ) == 0 ) { // XENFEAT_dom0 is not set
$this -> sys -> setVirtualizer ( 'xen' ); // Xen hypervisor (only domU, not dom0)
$novm = false ;
}
} elseif ( CommonFunctions :: rfts ( '/proc/xen/capabilities' , $capabilities , 1 , 4096 , false ) && ! preg_match ( '/control_d/' , $capabilities )) { // control_d not in capabilities
$this -> sys -> setVirtualizer ( 'xen' ); // Xen hypervisor (only domU, not dom0)
$novm = false ;
}
}
}
// Detect QEMU cpu
if ( $novm && isset ( $cpuvirt [ " cpuid:QEMU " ])) {
$this -> sys -> setVirtualizer ( 'qemu' ); // QEMU
$novm = false ;
}
if ( $novm && isset ( $cpuvirt [ " hypervisor " ])) {
$this -> sys -> setVirtualizer ( 'unknown' );
}
if (( count ( CommonFunctions :: gdc ( '/proc/vz' , false )) == 0 ) && ( count ( CommonFunctions :: gdc ( '/proc/bc' , false )) > 0 )) {
$this -> sys -> setVirtualizer ( 'openvz' ); // OpenVZ/Virtuozzo
}
if (( $verBuf = $this -> _get_kernel_string ()) !== " " ) {
if ( preg_match ( '/^[\d\.-]+-Microsoft/' , $verBuf )) {
$this -> sys -> setVirtualizer ( 'wsl' ); // Windows Subsystem for Linux
} elseif ( preg_match ( '/^[\d\.-]+-microsoft-standard/' , $verBuf )) {
$this -> sys -> setVirtualizer ( 'wsl2' ); // Windows Subsystem for Linux 2
}
}
2024-09-07 20:53:46 +10:00
if ( CommonFunctions :: rfts ( '/proc/self/cgroup' , $strBuf2 , 0 , 4096 , false )) {
2025-05-14 16:14:01 +01:00
if ( preg_match ( '/:\/lxc\//m' , $strBuf2 )) {
$this -> sys -> setVirtualizer ( 'lxc' ); // Linux container
2024-09-07 20:53:46 +10:00
} elseif ( preg_match ( '/:\/docker\//m' , $strBuf2 )) {
2025-05-14 16:14:01 +01:00
$this -> sys -> setVirtualizer ( 'docker' ); // Docker
2024-09-07 20:53:46 +10:00
} elseif ( preg_match ( '/:\/system\.slice\/docker\-/m' , $strBuf2 )) {
2025-05-14 16:14:01 +01:00
$this -> sys -> setVirtualizer ( 'docker' ); // Docker
2024-09-07 20:53:46 +10:00
}
}
}
}
/**
* UpTime
* time the system is running
*
* @ return void
*/
2025-05-14 16:14:01 +01:00
protected function _uptime ( $bufu = null )
2024-09-07 20:53:46 +10:00
{
2025-05-14 16:14:01 +01:00
if ( CommonFunctions :: rfts ( '/proc/uptime' , $buf , 1 , 4096 , PSI_OS != 'Android' )) {
$ar_buf = preg_split ( '/ /' , $buf );
$this -> sys -> setUptime ( trim ( $ar_buf [ 0 ]));
} elseif (( $this -> _uptime !== null ) || ( $bufu !== null ) || CommonFunctions :: executeProgram ( 'uptime' , '' , $bufu )) {
if (( $this -> _uptime === null ) && ( $bufu !== null )) {
$this -> _uptime = $bufu ;
}
if ( preg_match ( " /up ( \ d+) day[s]?,[ ]+( \ d+):( \ d+),/ " , $this -> _uptime , $ar_buf )) {
$min = $ar_buf [ 3 ];
$hours = $ar_buf [ 2 ];
$days = $ar_buf [ 1 ];
$this -> sys -> setUptime ( $days * 86400 + $hours * 3600 + $min * 60 );
} elseif ( preg_match ( " /up ( \ d+) day[s]?,[ ]+( \ d+) min,/ " , $this -> _uptime , $ar_buf )) {
$min = $ar_buf [ 2 ];
$days = $ar_buf [ 1 ];
$this -> sys -> setUptime ( $days * 86400 + $min * 60 );
} elseif ( preg_match ( " /up[ ]+( \ d+):( \ d+),/ " , $this -> _uptime , $ar_buf )) {
$min = $ar_buf [ 2 ];
$hours = $ar_buf [ 1 ];
$this -> sys -> setUptime ( $hours * 3600 + $min * 60 );
} elseif ( preg_match ( " /up[ ]+( \ d+):( \ d+):( \ d+)/ " , $this -> _uptime , $ar_buf )) {
$sec = $ar_buf [ 3 ];
$min = $ar_buf [ 2 ];
$hours = $ar_buf [ 1 ];
$this -> sys -> setUptime ( $hours * 3600 + $min * 60 + $sec );
} elseif ( preg_match ( " /up[ ]+( \ d+) min,/ " , $this -> _uptime , $ar_buf )) {
$min = $ar_buf [ 1 ];
$this -> sys -> setUptime ( $min * 60 );
} elseif ( preg_match ( " /up[ ]+( \ d+) day[s]?,[ ]+( \ d+) hour[s]?,[ ]+( \ d+) minute[s]?/ " , $this -> _uptime , $ar_buf )) {
$min = $ar_buf [ 3 ];
$hours = $ar_buf [ 2 ];
$days = $ar_buf [ 1 ];
$this -> sys -> setUptime ( $days * 86400 + $hours * 3600 + $min * 60 );
2024-09-07 20:53:46 +10:00
}
}
}
/**
* Processor Load
* optionally create a loadbar
*
* @ return void
*/
2025-05-14 16:14:01 +01:00
protected function _loadavg ( $buf = null )
2024-09-07 20:53:46 +10:00
{
2025-05-14 16:14:01 +01:00
if ((( $buf !== null ) || CommonFunctions :: rfts ( '/proc/loadavg' , $buf , 1 , 4096 , PSI_OS != 'Android' )) && preg_match ( " /^ \ d/ " , trim ( $buf ))) {
2024-09-07 20:53:46 +10:00
$result = preg_split ( " / \ s/ " , $buf , 4 );
// don't need the extra values, only first three
unset ( $result [ 3 ]);
$this -> sys -> setLoad ( implode ( ' ' , $result ));
2025-05-14 16:14:01 +01:00
} elseif (( $buf === null ) && ((( $this -> _uptime !== null ) || CommonFunctions :: executeProgram ( 'uptime' , '' , $this -> _uptime )) && preg_match ( " /load average: (.*), (.*), (.*) $ / " , $this -> _uptime , $ar_buf ))) {
$this -> sys -> setLoad ( $ar_buf [ 1 ] . ' ' . $ar_buf [ 2 ] . ' ' . $ar_buf [ 3 ]);
2024-09-07 20:53:46 +10:00
}
if ( PSI_LOAD_BAR ) {
$this -> sys -> setLoadPercent ( $this -> _parseProcStat ( 'cpu' ));
}
}
/**
* fill the load for a individual cpu , through parsing / proc / stat for the specified cpu
*
* @ param String $cpuline cpu for which load should be meassured
*
2025-05-14 16:14:01 +01:00
* @ return int
2024-09-07 20:53:46 +10:00
*/
protected function _parseProcStat ( $cpuline )
{
2025-05-14 16:14:01 +01:00
if ( $this -> _cpu_loads === null ) {
2024-09-07 20:53:46 +10:00
$this -> _cpu_loads = array ();
2025-05-14 16:14:01 +01:00
$cpu_tmp = array ();
if ( CommonFunctions :: rfts ( '/proc/stat' , $buf , 0 , 4096 , PSI_DEBUG && ( PSI_OS != 'Android' ))) {
2024-09-07 20:53:46 +10:00
if ( preg_match_all ( '/^(cpu[0-9]*) (.*)/m' , $buf , $matches , PREG_SET_ORDER )) {
foreach ( $matches as $line ) {
$cpu = $line [ 1 ];
$buf2 = $line [ 2 ];
2025-05-14 16:14:01 +01:00
$cpu_tmp [ $cpu ] = array ();
2024-09-07 20:53:46 +10:00
$ab = 0 ;
$ac = 0 ;
$ad = 0 ;
$ae = 0 ;
sscanf ( $buf2 , " %Ld %Ld %Ld %Ld " , $ab , $ac , $ad , $ae );
2025-05-14 16:14:01 +01:00
$cpu_tmp [ $cpu ][ 'load' ] = $ab + $ac + $ad ; // cpu.user + cpu.sys
$cpu_tmp [ $cpu ][ 'total' ] = $ab + $ac + $ad + $ae ; // cpu.total
2024-09-07 20:53:46 +10:00
}
}
2025-05-14 16:14:01 +01:00
// we need a second value, wait 1 second befor getting (< 1 second no good value will occour)
2024-09-07 20:53:46 +10:00
sleep ( 1 );
2025-05-14 16:14:01 +01:00
if ( CommonFunctions :: rfts ( '/proc/stat' , $buf , 0 , 4096 , PSI_DEBUG )) {
if ( preg_match_all ( '/^(cpu[0-9]*) (.*)/m' , $buf , $matches , PREG_SET_ORDER )) {
foreach ( $matches as $line ) {
$cpu = $line [ 1 ];
if ( isset ( $cpu_tmp [ $cpu ])) {
$buf2 = $line [ 2 ];
$ab = 0 ;
$ac = 0 ;
$ad = 0 ;
$ae = 0 ;
sscanf ( $buf2 , " %Ld %Ld %Ld %Ld " , $ab , $ac , $ad , $ae );
$load2 = $ab + $ac + $ad ; // cpu.user + cpu.sys
$total2 = $ab + $ac + $ad + $ae ; // cpu.total
$total = $cpu_tmp [ $cpu ][ 'total' ];
$load = $cpu_tmp [ $cpu ][ 'load' ];
$this -> _cpu_loads [ $cpu ] = 0 ;
if ( $total > 0 && $total2 > 0 && $load > 0 && $load2 > 0 && $total2 != $total && $load2 != $load ) {
$this -> _cpu_loads [ $cpu ] = ( 100 * ( $load2 - $load )) / ( $total2 - $total );
}
}
2024-09-07 20:53:46 +10:00
}
}
}
}
}
if ( isset ( $this -> _cpu_loads [ $cpuline ])) {
return $this -> _cpu_loads [ $cpuline ];
2025-05-14 16:14:01 +01:00
} else {
return null ;
2024-09-07 20:53:46 +10:00
}
}
/**
* CPU information
* All of the tags here are highly architecture dependant .
*
* @ return void
*/
2025-05-14 16:14:01 +01:00
protected function _cpuinfo ( $bufr = null )
2024-09-07 20:53:46 +10:00
{
2025-05-14 16:14:01 +01:00
if (( $bufr !== null ) || CommonFunctions :: rfts ( '/proc/cpuinfo' , $bufr )) {
$cpulist = null ;
$raslist = null ;
// sparc
if ( preg_match ( '/\nCpu(\d+)Bogo\s*:/i' , $bufr )) {
$bufr = preg_replace ( '/\nCpu(\d+)ClkTck\s*:/i' , " \n Cpu0ClkTck: " , preg_replace ( '/\nCpu(\d+)Bogo\s*:/i' , " \n \n processor: $ 1 \n Cpu0Bogo: " , $bufr ));
} else {
$bufr = preg_replace ( '/\nCpu(\d+)ClkTck\s*:/i' , " \n \n processor: $ 1 \n Cpu0ClkTck: " , $bufr );
}
if ( preg_match ( '/\nprocessor\s*:\s*\d+\r?\nprocessor\s*:\s*\d+/' , $bufr )) {
$bufr = preg_replace ( '/^(processor\s*:\s*\d+)\r?$/m' , " $ 1 \n " , $bufr );
}
// IBM/S390
$bufr = preg_replace ( '/\ncpu number\s*:\s*(\d+)\r?\ncpu MHz dynamic\s*:\s*(\d+)/m' , " \n processor: $ 1 \n clock: $ 2 " , $bufr );
// machine
$bufr = preg_replace ( '/(\nmachine\s*:\s*[^\r\n]+)/m' , " $ 1 \n " , $bufr );
2024-09-07 20:53:46 +10:00
$processors = preg_split ( '/\s?\n\s?\n/' , trim ( $bufr ));
2025-05-14 16:14:01 +01:00
//first stage
$_arch = null ;
$_impl = null ;
$_part = null ;
$_vari = null ;
$_hard = null ;
$_revi = null ;
$_cpus = null ;
$_buss = null ;
$_bogo = null ;
$_vend = null ;
$_system = null ;
2024-09-07 20:53:46 +10:00
$procname = null ;
2025-05-14 16:14:01 +01:00
foreach ( $processors as $processor ) if ( ! preg_match ( '/^\s*processor\s*:/mi' , $processor )) {
$details = preg_split ( " / \n / " , $processor , - 1 , PREG_SPLIT_NO_EMPTY );
foreach ( $details as $detail ) {
if ( preg_match ( '/^([^:]+):(.+)$/' , trim ( $detail ) , $arrBuff ) && (( $arrBuff2 = trim ( $arrBuff [ 2 ])) !== '' )) {
switch ( strtolower ( trim ( $arrBuff [ 1 ]))) {
case 'cpu architecture' :
$_arch = $arrBuff2 ;
break ;
case 'cpu implementer' :
$_impl = $arrBuff2 ;
break ;
case 'cpu part' :
$_part = $arrBuff2 ;
break ;
case 'cpu variant' :
$_vari = $arrBuff2 ;
break ;
case 'system type' :
$_system = $arrBuff2 ;
break ;
case 'machine' :
case 'hardware' :
$_hard = $arrBuff2 ;
break ;
case 'revision' :
$_revi = $arrBuff2 ;
break ;
case 'cpu frequency' :
if ( preg_match ( '/^(\d+)\s+Hz/i' , $arrBuff2 , $bufr2 )) {
$_cpus = round ( $bufr2 [ 1 ] / 1000000 );
} elseif ( preg_match ( '/^(\d+)\s+MHz/i' , $arrBuff2 , $bufr2 )) {
$_cpus = $bufr2 [ 1 ];
}
break ;
case 'system bus frequency' :
if ( preg_match ( '/^(\d+)\s+Hz/i' , $arrBuff2 , $bufr2 )) {
$_buss = round ( $bufr2 [ 1 ] / 1000000 );
} elseif ( preg_match ( '/^(\d+)\s+MHz/i' , $arrBuff2 , $bufr2 )) {
$_buss = $bufr2 [ 1 ];
}
break ;
case 'bogomips per cpu' :
$_bogo = round ( $arrBuff2 );
break ;
case 'vendor_id' :
$_vend = $arrBuff2 ;
break ;
case 'cpu' :
$procname = $arrBuff2 ;
}
}
}
}
//second stage
$cpucount = 0 ;
$speedset = false ;
foreach ( $processors as $processor ) if ( preg_match ( '/^\s*processor\s*:/mi' , $processor )) {
2024-09-07 20:53:46 +10:00
$proc = null ;
$arch = null ;
2025-05-14 16:14:01 +01:00
$impl = null ;
$part = null ;
$vari = null ;
2024-09-07 20:53:46 +10:00
$dev = new CpuDevice ();
$details = preg_split ( " / \n / " , $processor , - 1 , PREG_SPLIT_NO_EMPTY );
foreach ( $details as $detail ) {
2025-05-14 16:14:01 +01:00
if ( preg_match ( '/^([^:]+):(.+)$/' , trim ( $detail ) , $arrBuff ) && (( $arrBuff2 = trim ( $arrBuff [ 2 ])) !== '' )) {
switch ( strtolower ( trim ( $arrBuff [ 1 ]))) {
2024-09-07 20:53:46 +10:00
case 'processor' :
2025-05-14 16:14:01 +01:00
$proc = $arrBuff2 ;
2024-09-07 20:53:46 +10:00
if ( is_numeric ( $proc )) {
2025-05-14 16:14:01 +01:00
if (( $procname !== null ) && ( strlen ( $procname ) > 0 )) {
2024-09-07 20:53:46 +10:00
$dev -> setModel ( $procname );
}
} else {
$procname = $proc ;
$dev -> setModel ( $procname );
}
break ;
case 'model name' :
case 'cpu model' :
case 'cpu type' :
case 'cpu' :
2025-05-14 16:14:01 +01:00
$dev -> setModel ( $arrBuff2 );
break ;
case 'cpu frequency' :
if ( preg_match ( '/^(\d+)\s+Hz/i' , $arrBuff2 , $bufr2 )) {
if (( $tmpsp = round ( $bufr2 [ 1 ] / 1000000 )) > 0 ) {
$dev -> setCpuSpeed ( $tmpsp );
$speedset = true ;
}
} elseif ( preg_match ( '/^(\d+)\s+MHz/i' , $arrBuff2 , $bufr2 )) {
if ( $bufr2 [ 1 ] > 0 ) {
$dev -> setCpuSpeed ( $bufr2 [ 1 ]);
$speedset = true ;
}
}
2024-09-07 20:53:46 +10:00
break ;
case 'cpu mhz' :
case 'clock' :
2025-05-14 16:14:01 +01:00
if ( $arrBuff2 > 0 ) {
$dev -> setCpuSpeed ( $arrBuff2 );
$speedset = true ;
2024-09-07 20:53:46 +10:00
}
break ;
2025-05-14 16:14:01 +01:00
case 'cpu mhz static' :
$dev -> setCpuSpeedMax ( $arrBuff2 );
break ;
2024-09-07 20:53:46 +10:00
case 'cycle frequency [hz]' :
2025-05-14 16:14:01 +01:00
if (( $tmpsp = round ( $arrBuff2 / 1000000 )) > 0 ) {
$dev -> setCpuSpeed ( $tmpsp );
$speedset = true ;
}
2024-09-07 20:53:46 +10:00
break ;
2025-05-14 16:14:01 +01:00
case 'cpu0clktck' : // Linux sparc64
if (( $tmpsp = round ( hexdec ( $arrBuff2 ) / 1000000 )) > 0 ) {
$dev -> setCpuSpeed ( $tmpsp );
$speedset = true ;
}
2024-09-07 20:53:46 +10:00
break ;
2025-05-14 16:14:01 +01:00
case 'l3 cache' :
2024-09-07 20:53:46 +10:00
case 'cache size' :
2025-05-14 16:14:01 +01:00
$dev -> setCache ( trim ( preg_replace ( " /[a-zA-Z]/ " , " " , $arrBuff2 )) * 1024 );
2024-09-07 20:53:46 +10:00
break ;
case 'initial bogomips' :
case 'bogomips' :
case 'cpu0bogo' :
2025-05-14 16:14:01 +01:00
$dev -> setBogomips ( round ( $arrBuff2 ));
2024-09-07 20:53:46 +10:00
break ;
case 'flags' :
2025-05-14 16:14:01 +01:00
if ( preg_match ( " / vmx/ " , $arrBuff2 )) {
2024-09-07 20:53:46 +10:00
$dev -> setVirt ( " vmx " );
2025-05-14 16:14:01 +01:00
} elseif ( preg_match ( " / svm/ " , $arrBuff2 )) {
2024-09-07 20:53:46 +10:00
$dev -> setVirt ( " svm " );
2025-05-14 16:14:01 +01:00
}
if ( preg_match ( " / hypervisor/ " , $arrBuff2 )) {
if ( $dev -> getVirt () === null ) {
$dev -> setVirt ( " hypervisor " );
}
if ( defined ( 'PSI_SHOW_VIRTUALIZER_INFO' ) && PSI_SHOW_VIRTUALIZER_INFO && ( $this -> system_detect_virt === null )) {
$this -> sys -> setVirtualizer ( " hypervisor " , false );
}
2024-09-07 20:53:46 +10:00
}
break ;
case 'i size' :
case 'd size' :
if ( $dev -> getCache () === null ) {
2025-05-14 16:14:01 +01:00
$dev -> setCache ( $arrBuff2 * 1024 );
2024-09-07 20:53:46 +10:00
} else {
2025-05-14 16:14:01 +01:00
$dev -> setCache ( $dev -> getCache () + ( $arrBuff2 * 1024 ));
2024-09-07 20:53:46 +10:00
}
break ;
case 'cpu architecture' :
2025-05-14 16:14:01 +01:00
$arch = $arrBuff2 ;
break ;
case 'cpu implementer' :
$impl = $arrBuff2 ;
break ;
case 'cpu part' :
$part = $arrBuff2 ;
2024-09-07 20:53:46 +10:00
break ;
2025-05-14 16:14:01 +01:00
case 'cpu variant' :
$vari = $arrBuff2 ;
break ;
case 'vendor_id' :
$dev -> setVendorId ( $arrBuff2 );
if ( defined ( 'PSI_SHOW_VIRTUALIZER_INFO' ) && PSI_SHOW_VIRTUALIZER_INFO && preg_match ( '/^User Mode Linux/' , $arrBuff2 )) {
$this -> sys -> setVirtualizer ( " cpuid:UserModeLinux " , false );
}
2024-09-07 20:53:46 +10:00
}
}
}
2025-05-14 16:14:01 +01:00
if ( $arch === null ) $arch = $_arch ;
if ( $impl === null ) $impl = $_impl ;
if ( $part === null ) $part = $_part ;
if ( $vari === null ) $vari = $_vari ;
2024-09-07 20:53:46 +10:00
// sparc64 specific code follows
// This adds the ability to display the cache that a CPU has
// Originally made by Sven Blumenstein <bazik@gentoo.org> in 2004
// Modified by Tom Weustink <freshy98@gmx.net> in 2004
$sparclist = array ( 'SUNW,UltraSPARC@0,0' , 'SUNW,UltraSPARC-II@0,0' , 'SUNW,UltraSPARC@1c,0' , 'SUNW,UltraSPARC-IIi@1c,0' , 'SUNW,UltraSPARC-II@1c,0' , 'SUNW,UltraSPARC-IIe@0,0' );
foreach ( $sparclist as $name ) {
if ( CommonFunctions :: rfts ( '/proc/openprom/' . $name . '/ecache-size' , $buf , 1 , 32 , false )) {
2025-05-14 16:14:01 +01:00
$dev -> setCache ( base_convert ( trim ( $buf ), 16 , 10 ));
2024-09-07 20:53:46 +10:00
}
}
// sparc64 specific code ends
// XScale detection code
2025-05-14 16:14:01 +01:00
if (( $arch === " 5TE " ) && (( $bogo = $dev -> getBogomips ()) !== null ) && ( $bogo > 0 )) {
$dev -> setCpuSpeed ( $bogo ); // BogoMIPS are not BogoMIPS on this CPU, it's the speed
$speedset = true ;
2024-09-07 20:53:46 +10:00
$dev -> setBogomips ( null ); // no BogoMIPS available, unset previously set BogoMIPS
}
2025-05-14 16:14:01 +01:00
if (( $dev -> getBusSpeed () == 0 ) && ( $_buss !== null )) {
$dev -> setBusSpeed ( $_buss );
}
if (( $dev -> getCpuSpeed () == 0 ) && ( $_cpus !== null ) && ( $_cpus > 0 )) {
$dev -> setCpuSpeed ( $_cpus );
$speedset = true ;
}
if (( $dev -> getBogomips () == 0 ) && ( $_bogo !== null )) {
$dev -> setBogomips ( $_bogo );
}
if (( $dev -> getVendorId () === null ) && ( $_vend !== null )) {
$dev -> setVendorId ( $_vend );
if ( defined ( 'PSI_SHOW_VIRTUALIZER_INFO' ) && PSI_SHOW_VIRTUALIZER_INFO && preg_match ( '/^User Mode Linux/' , $_vend )) {
$this -> sys -> setVirtualizer ( " cpuid:UserModeLinux " , false );
}
}
if ( $proc !== null ) {
2024-09-07 20:53:46 +10:00
if ( ! is_numeric ( $proc )) {
$proc = 0 ;
}
// variable speed processors specific code follows
2025-05-14 16:14:01 +01:00
if ( CommonFunctions :: rfts ( '/sys/devices/system/cpu/cpu' . $proc . '/cpufreq/cpuinfo_cur_freq' , $buf , 1 , 4096 , false )
|| CommonFunctions :: rfts ( '/sys/devices/system/cpu/cpu' . $proc . '/cpufreq/scaling_cur_freq' , $buf , 1 , 4096 , false )) {
if ( round ( trim ( $buf ) / 1000 ) > 0 ) {
$dev -> setCpuSpeed ( round ( trim ( $buf ) / 1000 ));
$speedset = true ;
}
2024-09-07 20:53:46 +10:00
}
2025-05-14 16:14:01 +01:00
if ( CommonFunctions :: rfts ( '/sys/devices/system/cpu/cpu' . $proc . '/cpufreq/cpuinfo_max_freq' , $buf , 1 , 4096 , false )
|| CommonFunctions :: rfts ( '/sys/devices/system/cpu/cpu' . $proc . '/cpufreq/scaling_max_freq' , $buf , 1 , 4096 , false )) {
$dev -> setCpuSpeedMax ( round ( trim ( $buf ) / 1000 ));
2024-09-07 20:53:46 +10:00
}
2025-05-14 16:14:01 +01:00
if ( CommonFunctions :: rfts ( '/sys/devices/system/cpu/cpu' . $proc . '/cpufreq/cpuinfo_min_freq' , $buf , 1 , 4096 , false )
|| CommonFunctions :: rfts ( '/sys/devices/system/cpu/cpu' . $proc . '/cpufreq/scaling_min_freq' , $buf , 1 , 4096 , false )) {
$dev -> setCpuSpeedMin ( round ( trim ( $buf ) / 1000 ));
2024-09-07 20:53:46 +10:00
}
// variable speed processors specific code ends
if ( PSI_LOAD_BAR ) {
$dev -> setLoad ( $this -> _parseProcStat ( 'cpu' . $proc ));
}
2025-05-14 16:14:01 +01:00
/*
if ( CommonFunctions :: rfts ( '/proc/acpi/thermal_zone/THRM/temperature' , $buf , 1 , 4096 , false )
&& preg_match ( " /( \ S+) \ sC $ / " , $buf , $value )) {
$dev -> setTemp ( value [ 1 ]);
}
*/
if (( $arch !== null ) && ( $impl !== null ) && ( $part !== null )) {
if (( $impl === '0x41' )
&& (( $_hard === 'BCM2708' ) || ( $_hard === 'BCM2709' ) || ( $_hard === 'BCM2710' ) || ( $_hard === 'BCM2711' ) || ( $_hard === 'BCM2712' ) || ( $_hard === 'BCM2835' ) || ( $_hard === 'BCM2836' ) || ( $_hard === 'BCM2837' ) || ( $_hard === 'BCM2838' ))
&& ( $_revi !== null )) { // Raspberry Pi detection (instead of 'cat /proc/device-tree/model')
if ( $raslist === null ) $raslist = @ parse_ini_file ( PSI_APP_ROOT . " /data/raspberry.ini " , true );
$oldmach = $this -> sys -> getMachine ();
if (( $oldmach !== '' ) && preg_match ( " /^raspberrypi rpi(,.+)/ " , $oldmach , $machbuf )) {
$oldmachend = $machbuf [ 1 ];
} else {
$oldmachend = '' ;
}
if ( $raslist && ! preg_match ( '/[^0-9a-f]/' , $_revi )) {
if (( $revidec = hexdec ( $_revi )) & 0x800000 ) {
if (( $oldmach === '' ) || ( $oldmachend !== '' )) {
$manufacturer = ( $revidec >> 16 ) & 15 ;
if ( isset ( $raslist [ 'manufacturer' ][ $manufacturer ])) {
$manuf = ' ' . $raslist [ 'manufacturer' ][ $manufacturer ];
} else {
$manuf = '' ;
}
$model = ( $revidec >> 4 ) & 255 ;
if ( isset ( $raslist [ 'model' ][ $model ])) {
$this -> sys -> setMachine ( 'Raspberry Pi ' . $raslist [ 'model' ][ $model ] . ' (PCB 1.' . ( $revidec & 15 ) . $manuf . ')' . $oldmachend );
} else {
$this -> sys -> setMachine ( 'Raspberry Pi (PCB 1.' . ( $revidec & 15 ) . $manuf . ')' . $oldmachend );
}
}
} else {
if (( $oldmach === '' ) || ( $oldmachend !== '' )) {
if ( isset ( $raslist [ 'old' ][ $revidec & 0x7fffff ])) {
$this -> sys -> setMachine ( 'Raspberry Pi ' . $raslist [ 'old' ][ $revidec & 0x7fffff ] . $oldmachend );
} else {
$this -> sys -> setMachine ( 'Raspberry Pi' . $oldmachend );
}
}
}
}
} elseif ( $this -> sys -> getMachine () === '' ) { // other ARM hardware
if ( $_hard !== null ) {
if ( $_system !== null ) {
$this -> sys -> setMachine ( $_hard . " - " . $_system );
} else {
$this -> sys -> setMachine ( $_hard );
}
} elseif ( $_system !== null ) {
$this -> sys -> setMachine ( $_system );
}
}
if ( $cpulist === null ) $cpulist = @ parse_ini_file ( PSI_APP_ROOT . " /data/cpus.ini " , true );
if ( $cpulist && (((( $vari !== null ) && isset ( $cpulist [ 'cpu' ][ $cpufromlist = strtolower ( $impl . ',' . $part . ',' . $vari )]))
|| isset ( $cpulist [ 'cpu' ][ $cpufromlist = strtolower ( $impl . ',' . $part )])))) {
if (( $cpumodel = $dev -> getModel ()) !== '' ) {
$dev -> setModel ( $cpumodel . ' - ' . $cpulist [ 'cpu' ][ $cpufromlist ]);
} else {
$dev -> setModel ( $cpulist [ 'cpu' ][ $cpufromlist ]);
}
}
} elseif ( $this -> sys -> getMachine () === '' ) { // other hardware
if ( $_hard !== null ) {
if ( $_system !== null ) {
$this -> sys -> setMachine ( $_hard . " - " . $_system );
} else {
$this -> sys -> setMachine ( $_hard );
}
} elseif ( $_system !== null ) {
$this -> sys -> setMachine ( $_system );
}
}
2024-09-07 20:53:46 +10:00
2025-05-14 16:14:01 +01:00
$cpumodel = $dev -> getModel ();
if ( defined ( 'PSI_SHOW_VIRTUALIZER_INFO' ) && PSI_SHOW_VIRTUALIZER_INFO && ( $this -> system_detect_virt === null ) && preg_match ( '/^QEMU Virtual CPU version /' , $cpumodel )) {
$this -> sys -> setVirtualizer ( " cpuid:QEMU " , false );
2024-09-07 20:53:46 +10:00
}
2025-05-14 16:14:01 +01:00
if ( $cpumodel === " " ) {
if (( $vendid = $dev -> getVendorId ()) !== " " ) {
$dev -> setModel ( $vendid );
} else {
$dev -> setModel ( " unknown " );
}
}
$cpucount ++ ;
$this -> sys -> setCpus ( $dev );
}
}
$cpudevices = CommonFunctions :: findglob ( '/sys/devices/system/cpu/cpu[0-9]*/uevent' , GLOB_NOSORT );
if ( is_array ( $cpudevices ) && (( $cpustopped = count ( $cpudevices ) - $cpucount ) > 0 )) {
for (; $cpustopped > 0 ; $cpustopped -- ) {
$dev = new CpuDevice ();
$dev -> setModel ( " stopped " );
if ( $speedset ) {
$dev -> setCpuSpeed ( - 1 );
2024-09-07 20:53:46 +10:00
}
$this -> sys -> setCpus ( $dev );
}
}
}
}
/**
* PCI devices
*
* @ return void
*/
private function _pci ()
{
2025-05-14 16:14:01 +01:00
if ( $arrResults = Parser :: lspci ()) {
foreach ( $arrResults as $dev ) {
$this -> sys -> setPciDevices ( $dev );
}
} elseif ( CommonFunctions :: rfts ( '/proc/pci' , $strBuf , 0 , 4096 , false )) {
$booDevice = false ;
$arrBuf = preg_split ( " / \n / " , $strBuf , - 1 , PREG_SPLIT_NO_EMPTY );
foreach ( $arrBuf as $strLine ) {
if ( preg_match ( '/^\s*Bus\s/' , $strLine )) {
$booDevice = true ;
continue ;
}
if ( $booDevice ) {
$dev = new HWDevice ();
$dev -> setName ( preg_replace ( '/\(rev\s[^\)]+\)\.$/' , '' , trim ( $strLine )));
$this -> sys -> setPciDevices ( $dev );
/*
list ( $strKey , $strValue ) = preg_split ( '/: /' , $strLine , 2 );
if ( ! preg_match ( '/bridge/i' , $strKey ) && ! preg_match ( '/USB/i ' , $strKey )) {
$dev = new HWDevice ();
$dev -> setName ( preg_replace ( '/\(rev\s[^\)]+\)\.$/' , '' , trim ( $strValue )));
$this -> sys -> setPciDevices ( $dev );
2024-09-07 20:53:46 +10:00
}
2025-05-14 16:14:01 +01:00
*/
$booDevice = false ;
2024-09-07 20:53:46 +10:00
}
}
} else {
2025-05-14 16:14:01 +01:00
$pcidevices = CommonFunctions :: findglob ( '/sys/bus/pci/devices/*/uevent' , GLOB_NOSORT );
if ( is_array ( $pcidevices ) && (( $total = count ( $pcidevices )) > 0 )) {
$buf = " " ;
for ( $i = 0 ; $i < $total ; $i ++ ) {
if ( CommonFunctions :: rfts ( $pcidevices [ $i ], $buf , 0 , 4096 , false ) && ( trim ( $buf ) != " " )) {
$pcibuf = " " ;
if ( preg_match ( " /^PCI_CLASS=( \ S+)/m " , trim ( $buf ), $subbuf )) {
$pcibuf = " Class " . $subbuf [ 1 ] . " : " ;
}
if ( preg_match ( " /^PCI_ID=( \ S+)/m " , trim ( $buf ), $subbuf )) {
$pcibuf .= " Device " . $subbuf [ 1 ];
}
if ( preg_match ( " /^DRIVER=( \ S+)/m " , trim ( $buf ), $subbuf )) {
$pcibuf .= " Driver " . $subbuf [ 1 ];
}
$dev = new HWDevice ();
if ( trim ( $pcibuf ) != " " ) {
$dev -> setName ( trim ( $pcibuf ));
} else {
$dev -> setName ( " unknown " );
}
$this -> sys -> setPciDevices ( $dev );
}
}
} elseif (( $dmesg = $this -> _get_dmesg_c ()) !== null ) {
$arrBuf = preg_split ( " / \n / " , $dmesg , - 1 , PREG_SPLIT_NO_EMPTY );
foreach ( $arrBuf as $strLine ) {
if ( preg_match ( '/^[\s\[\]\.\d]*pci\s+\d\d\d\d:\d\d:\d\d.\d: (\[[^\]]+\].*)/' , $strLine , $ar_buf )) {
$dev = new HWDevice ();
$dev -> setName ( trim ( $ar_buf [ 1 ]));
$this -> sys -> setPciDevices ( $dev );
}
}
2024-09-07 20:53:46 +10:00
}
}
}
/**
* IDE devices
*
* @ return void
*/
private function _ide ()
{
$bufd = CommonFunctions :: gdc ( '/proc/ide' , false );
foreach ( $bufd as $file ) {
if ( preg_match ( '/^hd/' , $file )) {
$dev = new HWDevice ();
$dev -> setName ( trim ( $file ));
2025-05-14 16:14:01 +01:00
if ( defined ( 'PSI_SHOW_DEVICES_INFOS' ) && PSI_SHOW_DEVICES_INFOS && CommonFunctions :: rfts ( " /proc/ide/ " . $file . " /media " , $buf , 1 )) {
2024-09-07 20:53:46 +10:00
if ( trim ( $buf ) == 'disk' ) {
if ( CommonFunctions :: rfts ( " /proc/ide/ " . $file . " /capacity " , $buf , 1 , 4096 , false ) || CommonFunctions :: rfts ( " /sys/block/ " . $file . " /size " , $buf , 1 , 4096 , false )) {
2025-05-14 16:14:01 +01:00
$dev -> setCapacity ( trim ( $buf ) * 512 );
2024-09-07 20:53:46 +10:00
}
}
}
if ( CommonFunctions :: rfts ( " /proc/ide/ " . $file . " /model " , $buf , 1 )) {
$dev -> setName ( $dev -> getName () . " : " . trim ( $buf ));
}
$this -> sys -> setIdeDevices ( $dev );
}
}
}
/**
* SCSI devices
*
* @ return void
*/
private function _scsi ()
{
2025-05-14 16:14:01 +01:00
$getline = 0 ;
2024-09-07 20:53:46 +10:00
$device = null ;
2025-05-14 16:14:01 +01:00
$scsiid = null ;
2024-09-07 20:53:46 +10:00
if ( CommonFunctions :: executeProgram ( 'lsscsi' , '-c' , $bufr , PSI_DEBUG ) || CommonFunctions :: rfts ( '/proc/scsi/scsi' , $bufr , 0 , 4096 , PSI_DEBUG )) {
$bufe = preg_split ( " / \n / " , $bufr , - 1 , PREG_SPLIT_NO_EMPTY );
foreach ( $bufe as $buf ) {
2025-05-14 16:14:01 +01:00
if ( preg_match ( '/Host: scsi(\d+) Channel: (\d+) Target: (\d+) Lun: (\d+)/i' , $buf , $scsiids )
|| preg_match ( '/Host: scsi(\d+) Channel: (\d+) Id: (\d+) Lun: (\d+)/i' , $buf , $scsiids )) {
$scsiid = $scsiids ;
$getline = 1 ;
continue ;
}
if ( $getline == 1 ) {
preg_match ( '/Vendor: (.*) Model: (.*) Rev: (.*)/i' , $buf , $devices );
$getline = 2 ;
2024-09-07 20:53:46 +10:00
$device = $devices ;
continue ;
}
2025-05-14 16:14:01 +01:00
if ( $getline == 2 ) {
2024-09-07 20:53:46 +10:00
preg_match ( '/Type:\s+(\S+)/i' , $buf , $dev_type );
2025-05-14 16:14:01 +01:00
2024-09-07 20:53:46 +10:00
$dev = new HWDevice ();
$dev -> setName ( $device [ 1 ] . ' ' . $device [ 2 ] . ' (' . $dev_type [ 1 ] . ')' );
2025-05-14 16:14:01 +01:00
if ( defined ( 'PSI_SHOW_DEVICES_INFOS' ) && PSI_SHOW_DEVICES_INFOS
&& ( $dev_type [ 1 ] === 'Direct-Access' )) {
$sizelist = CommonFunctions :: findglob ( '/sys/bus/scsi/devices/' . intval ( $scsiid [ 1 ]) . ':' . intval ( $scsiid [ 2 ]) . ':' . intval ( $scsiid [ 3 ]) . ':' . intval ( $scsiid [ 4 ]) . '/*/*/size' , GLOB_NOSORT );
if ( is_array ( $sizelist ) && (( $total = count ( $sizelist )) > 0 )) {
$buf = " " ;
for ( $i = 0 ; $i < $total ; $i ++ ) {
if ( CommonFunctions :: rfts ( $sizelist [ $i ], $buf , 1 , 4096 , false ) && (( $buf = trim ( $buf )) != " " ) && ( $buf > 0 )) {
$dev -> setCapacity ( $buf * 512 );
break ;
}
}
}
}
2024-09-07 20:53:46 +10:00
$this -> sys -> setScsiDevices ( $dev );
2025-05-14 16:14:01 +01:00
$getline = 0 ;
2024-09-07 20:53:46 +10:00
}
}
}
}
/**
* USB devices
*
2025-05-14 16:14:01 +01:00
* @ return void
2024-09-07 20:53:46 +10:00
*/
2025-05-14 16:14:01 +01:00
protected function _usb ( $bufu = null )
2024-09-07 20:53:46 +10:00
{
2025-05-14 16:14:01 +01:00
$usbarray = array ();
if ( $nobufu = ( $bufu === null )) {
if ( CommonFunctions :: executeProgram ( 'lsusb' , ( PSI_OS != 'Android' ) ? '' : '2>/dev/null' , $bufr , PSI_DEBUG && ( PSI_OS != 'Android' ), 5 ) && ( $bufr !== " " )) {
2024-09-07 20:53:46 +10:00
$bufe = preg_split ( " / \n / " , $bufr , - 1 , PREG_SPLIT_NO_EMPTY );
foreach ( $bufe as $buf ) {
2025-05-14 16:14:01 +01:00
$device = preg_split ( " / / " , $buf , 7 );
if ((( isset ( $device [ 6 ]) && trim ( $device [ 6 ]) != " " )) ||
(( isset ( $device [ 5 ]) && trim ( $device [ 5 ]) != " " ))) {
$usbid = intval ( $device [ 1 ]) . '-' . intval ( trim ( $device [ 3 ], ':' )) . ' ' . $device [ 5 ];
if (( isset ( $device [ 6 ]) && trim ( $device [ 6 ]) != " " )) {
$usbarray [ $usbid ][ 'name' ] = trim ( $device [ 6 ]);
} else {
$usbarray [ $usbid ][ 'name' ] = 'unknown' ;
2024-09-07 20:53:46 +10:00
}
}
}
2025-05-14 16:14:01 +01:00
}
$usbdevices = CommonFunctions :: findglob ( '/sys/bus/usb/devices/*/idProduct' , GLOB_NOSORT );
if ( is_array ( $usbdevices ) && (( $total = count ( $usbdevices )) > 0 )) {
for ( $i = 0 ; $i < $total ; $i ++ ) {
if ( CommonFunctions :: rfts ( $usbdevices [ $i ], $idproduct , 1 , 4096 , false ) && (( $idproduct = trim ( $idproduct )) != " " )) { // is readable
$busnum = CommonFunctions :: rolv ( $usbdevices [ $i ], '/\/idProduct$/' , '/busnum' );
$devnum = CommonFunctions :: rolv ( $usbdevices [ $i ], '/\/idProduct$/' , '/devnum' );
$idvendor = CommonFunctions :: rolv ( $usbdevices [ $i ], '/\/idProduct$/' , '/idVendor' );
if (( $busnum !== null ) && ( $devnum !== null ) && ( $idvendor !== null )) {
$usbid = intval ( $busnum ) . '-' . intval ( $devnum ) . ' ' . $idvendor . ':' . $idproduct ;
$manufacturer = CommonFunctions :: rolv ( $usbdevices [ $i ], '/\/idProduct$/' , '/manufacturer' );
if ( $manufacturer !== null ) {
$usbarray [ $usbid ][ 'manufacturer' ] = $manufacturer ;
}
$product = CommonFunctions :: rolv ( $usbdevices [ $i ], '/\/idProduct$/' , '/product' );
if ( $product !== null ) {
$usbarray [ $usbid ][ 'product' ] = $product ;
}
$speed = CommonFunctions :: rolv ( $usbdevices [ $i ], '/\/idProduct$/' , '/speed' );
if ( $product !== null ) {
$usbarray [ $usbid ][ 'speed' ] = $speed ;
}
if ( defined ( 'PSI_SHOW_DEVICES_INFOS' ) && PSI_SHOW_DEVICES_INFOS
&& defined ( 'PSI_SHOW_DEVICES_SERIAL' ) && PSI_SHOW_DEVICES_SERIAL ) {
$serial = CommonFunctions :: rolv ( $usbdevices [ $i ], '/\/idProduct$/' , '/serial' );
if (( $serial !== null ) && ! preg_match ( '/\W/' , $serial )) {
$usbarray [ $usbid ][ 'serial' ] = $serial ;
}
}
}
}
2024-09-07 20:53:46 +10:00
}
}
2025-05-14 16:14:01 +01:00
}
if ( ! $nobufu || (( count ( $usbarray ) == 0 ) && CommonFunctions :: rfts ( '/proc/bus/usb/devices' , $bufu , 0 , 4096 , false ))) { // usb-devices
$devnum = - 1 ;
$bufe = preg_split ( " / \n / " , $bufu , - 1 , PREG_SPLIT_NO_EMPTY );
foreach ( $bufe as $buf ) {
if ( preg_match ( '/^T/' , $buf )) {
$devnum ++ ;
if ( preg_match ( '/\sSpd=([\d\.]+)/' , $buf , $bufr )
&& isset ( $bufr [ 1 ]) && ( $bufr [ 1 ] !== " " )) {
$usbarray [ $devnum ][ 'speed' ] = $bufr [ 1 ];
}
} elseif ( preg_match ( '/^S:/' , $buf )) {
list ( $key , $value ) = preg_split ( '/: /' , $buf , 2 );
list ( $key , $value2 ) = preg_split ( '/=/' , $value , 2 );
switch ( trim ( $key )) {
case 'Manufacturer' :
$usbarray [ $devnum ][ 'manufacturer' ] = trim ( $value2 );
break ;
case 'Product' :
$usbarray [ $devnum ][ 'product' ] = trim ( $value2 );
break ;
case 'SerialNumber' :
if ( defined ( 'PSI_SHOW_DEVICES_INFOS' ) && PSI_SHOW_DEVICES_INFOS
&& defined ( 'PSI_SHOW_DEVICES_SERIAL' ) && PSI_SHOW_DEVICES_SERIAL
&& ! preg_match ( '/\W/' , trim ( $value2 ))) {
$usbarray [ $devnum ][ 'serial' ] = trim ( $value2 );
}
}
}
}
}
if ( $nobufu && ( count ( $usbarray ) == 0 ) && CommonFunctions :: rfts ( '/proc/bus/input/devices' , $bufr , 0 , 4096 , false )) {
$devnam = " unknown " ;
2024-09-07 20:53:46 +10:00
$bufe = preg_split ( " / \n / " , $bufr , - 1 , PREG_SPLIT_NO_EMPTY );
foreach ( $bufe as $buf ) {
2025-05-14 16:14:01 +01:00
if ( preg_match ( '/^I:\s+(.+)/' , $buf , $bufr )
&& isset ( $bufr [ 1 ]) && ( trim ( $bufr [ 1 ]) !== " " )) {
$devnam = trim ( $bufr [ 1 ]);
$usbarray [ $devnam ][ 'phys' ] = 'unknown' ;
} elseif ( preg_match ( '/^N:\s+Name="([^"]+)"/' , $buf , $bufr2 )
&& isset ( $bufr2 [ 1 ]) && ( trim ( $bufr2 [ 1 ]) !== " " )) {
$usbarray [ $devnam ][ 'name' ] = trim ( $bufr2 [ 1 ]);
} elseif ( preg_match ( '/^P:\s+Phys=(.*)/' , $buf , $bufr2 )
&& isset ( $bufr2 [ 1 ]) && ( trim ( $bufr2 [ 1 ]) !== " " )) {
$usbarray [ $devnam ][ 'phys' ] = trim ( $bufr2 [ 1 ]);
} elseif ( defined ( 'PSI_SHOW_DEVICES_INFOS' ) && PSI_SHOW_DEVICES_INFOS
&& defined ( 'PSI_SHOW_DEVICES_SERIAL' ) && PSI_SHOW_DEVICES_SERIAL
&& preg_match ( '/^U:\s+Uniq=(.+)/' , $buf , $bufr2 )
&& isset ( $bufr2 [ 1 ]) && ( trim ( $bufr2 [ 1 ]) !== " " )) {
$usbarray [ $devnam ][ 'serial' ] = trim ( $bufr2 [ 1 ]);
}
}
}
foreach ( $usbarray as $usbdev ) if ( ! isset ( $usbdev [ 'phys' ]) || preg_match ( '/^usb-/' , $usbdev [ 'phys' ])) {
$dev = new HWDevice ();
if ( isset ( $usbdev [ 'manufacturer' ]) && (( $manufacturer = $usbdev [ 'manufacturer' ]) !== 'no manufacturer' )) {
if ( preg_match ( " /^linux \ s/i " , $manufacturer )) {
$manufacturer = 'Linux Foundation' ;
}
if ( defined ( 'PSI_SHOW_DEVICES_INFOS' ) && PSI_SHOW_DEVICES_INFOS ) {
$dev -> setManufacturer ( $manufacturer );
}
} else {
$manufacturer = '' ;
}
if ( isset ( $usbdev [ 'product' ])) {
$product = $usbdev [ 'product' ];
if ( defined ( 'PSI_SHOW_DEVICES_INFOS' ) && PSI_SHOW_DEVICES_INFOS ) {
$dev -> setProduct ( $product );
}
} else {
$product = '' ;
}
if ( defined ( 'PSI_SHOW_DEVICES_INFOS' ) && PSI_SHOW_DEVICES_INFOS ) {
if ( isset ( $usbdev [ 'speed' ])) {
$dev -> setSpeed ( $usbdev [ 'speed' ]);
}
if ( defined ( 'PSI_SHOW_DEVICES_SERIAL' ) && PSI_SHOW_DEVICES_SERIAL
&& isset ( $usbdev [ 'serial' ])) {
$dev -> setSerial ( $usbdev [ 'serial' ]);
}
}
if ( isset ( $usbdev [ 'name' ]) && (( $name = $usbdev [ 'name' ]) !== 'unknown' )) {
$dev -> setName ( $name );
} else {
if (( $newname = trim ( $manufacturer . ' ' . $product )) !== '' ) {
$dev -> setName ( $newname );
} else {
$dev -> setName ( 'unknown' );
2024-09-07 20:53:46 +10:00
}
}
2025-05-14 16:14:01 +01:00
$this -> sys -> setUsbDevices ( $dev );
2024-09-07 20:53:46 +10:00
}
}
/**
* I2C devices
*
* @ return void
*/
protected function _i2c ()
{
2025-05-14 16:14:01 +01:00
$i2cdevices = CommonFunctions :: findglob ( '/sys/bus/i2c/devices/*/name' , GLOB_NOSORT );
if ( is_array ( $i2cdevices ) && (( $total = count ( $i2cdevices )) > 0 )) {
2024-09-07 20:53:46 +10:00
$buf = " " ;
for ( $i = 0 ; $i < $total ; $i ++ ) {
2025-05-14 16:14:01 +01:00
if ( CommonFunctions :: rfts ( $i2cdevices [ $i ], $buf , 1 , 4096 , false ) && ( trim ( $buf ) != " " )) {
$dev = new HWDevice ();
$dev -> setName ( trim ( $buf , " : \n \r \t \ v \x00 " ));
$this -> sys -> setI2cDevices ( $dev );
}
}
}
}
/**
* NVMe devices
*
* @ return void
*/
protected function _nvme ()
{
if ( CommonFunctions :: executeProgram ( 'nvme' , 'list' , $bufr , PSI_DEBUG ) && ( $bufr != " " )) {
$bufe = preg_split ( " / \n / " , $bufr , - 1 , PREG_SPLIT_NO_EMPTY );
$count = 0 ;
$nlocate = array ();
$nsize = array ();
foreach ( $bufe as $buf ) {
if ( $count == 1 ) {
$locid = 0 ;
$nlocate [ 0 ] = 0 ;
$total = strlen ( $buf );
$begin = true ;
for ( $i = 0 ; $i < $total ; $i ++ ) {
if ( $begin ) {
if ( $buf [ $i ] !== '-' ) {
$nsize [ $locid ] = $i - $nlocate [ $locid ];
$locid ++ ;
$begin = false ;
}
} else {
if ( $buf [ $i ] === '-' ) {
$nlocate [ $locid ] = $i ;
$begin = true ;
}
}
}
if ( $begin ) {
$nsize [ $locid ] = $i - $nlocate [ $locid ];
}
} elseif ( $count > 1 ) {
if ( isset ( $nlocate [ 2 ]) && isset ( $nsize [ 2 ]) && (( $nvname = trim ( substr ( $buf , $nlocate [ 2 ], $nsize [ 2 ]))) !== '' )) {
2024-09-07 20:53:46 +10:00
$dev = new HWDevice ();
2025-05-14 16:14:01 +01:00
$dev -> setName ( $nvname );
if ( defined ( 'PSI_SHOW_DEVICES_INFOS' ) && ( PSI_SHOW_DEVICES_INFOS )) {
if ( isset ( $nlocate [ 4 ]) && isset ( $nsize [ 4 ])) {
if ( preg_match ( '/\/\s*([0-9\.]+)\s*(B|KB|MB|GB|TB|PB)$/' , str_replace ( ',' , '.' , trim ( substr ( $buf , $nlocate [ 4 ], $nsize [ 4 ]))), $tmpbuf )) {
switch ( $tmpbuf [ 2 ]) {
case 'B' :
$dev -> setCapacity ( $tmpbuf [ 1 ]);
break ;
case 'KB' :
$dev -> setCapacity ( 1000 * $tmpbuf [ 1 ]);
break ;
case 'MB' :
$dev -> setCapacity ( 1000 * 1000 * $tmpbuf [ 1 ]);
break ;
case 'GB' :
$dev -> setCapacity ( 1000 * 1000 * 1000 * $tmpbuf [ 1 ]);
break ;
case 'TB' :
$dev -> setCapacity ( 1000 * 1000 * 1000 * 1000 * $tmpbuf [ 1 ]);
break ;
case 'PB' :
$dev -> setCapacity ( 1000 * 1000 * 1000 * 1000 * 1000 * $tmpbuf [ 1 ]);
}
}
}
if ( defined ( 'PSI_SHOW_DEVICES_SERIAL' ) && PSI_SHOW_DEVICES_SERIAL ) {
if ( isset ( $nlocate [ 1 ]) && isset ( $nsize [ 1 ])) {
$dev -> setSerial ( trim ( substr ( $buf , $nlocate [ 1 ], $nsize [ 1 ])));
}
}
}
$this -> sys -> setNvmeDevices ( $dev );
2024-09-07 20:53:46 +10:00
}
}
2025-05-14 16:14:01 +01:00
$count ++ ;
2024-09-07 20:53:46 +10:00
}
}
}
/**
* Network devices
* includes also rx / tx bytes
*
* @ return void
*/
2025-05-14 16:14:01 +01:00
protected function _network ( $bufr = null )
2024-09-07 20:53:46 +10:00
{
2025-05-14 16:14:01 +01:00
if (( $bufr === null ) && CommonFunctions :: rfts ( '/proc/net/dev' , $bufr , 0 , 4096 , PSI_DEBUG )) {
2024-09-07 20:53:46 +10:00
$bufe = preg_split ( " / \n / " , $bufr , - 1 , PREG_SPLIT_NO_EMPTY );
foreach ( $bufe as $buf ) {
if ( preg_match ( '/:/' , $buf )) {
list ( $dev_name , $stats_list ) = preg_split ( '/:/' , $buf , 2 );
$stats = preg_split ( '/\s+/' , trim ( $stats_list ));
$dev = new NetDevice ();
$dev -> setName ( trim ( $dev_name ));
$dev -> setRxBytes ( $stats [ 0 ]);
$dev -> setTxBytes ( $stats [ 8 ]);
$dev -> setErrors ( $stats [ 2 ] + $stats [ 10 ]);
$dev -> setDrops ( $stats [ 3 ] + $stats [ 11 ]);
2025-05-14 16:14:01 +01:00
if ((( defined ( 'PSI_SHOW_NETWORK_INFOS' ) && ( PSI_SHOW_NETWORK_INFOS )) || ( defined ( 'PSI_SHOW_NETWORK_BRIDGE' ) && PSI_SHOW_NETWORK_BRIDGE ))
&& CommonFunctions :: executeProgram ( 'ip' , 'addr show ' . trim ( $dev_name ), $bufr2 , PSI_DEBUG ) && ( trim ( $bufr2 ) != " " )) {
if ( defined ( 'PSI_SHOW_NETWORK_BRIDGE' ) && PSI_SHOW_NETWORK_BRIDGE && preg_match ( " /^ \ d+: \ s+([^ \ s:@]+).+ \ s+master \ s+( \ S+)/ " , $bufr2 , $brbufr )) {
$dev -> setBridge ( $brbufr [ 2 ]);
}
} else {
$bufr2 = " " ;
}
if ( defined ( 'PSI_SHOW_NETWORK_INFOS' ) && ( PSI_SHOW_NETWORK_INFOS )) {
$macaddr = " " ;
if (( $bufr2 != " " ) || CommonFunctions :: executeProgram ( 'ifconfig' , trim ( $dev_name ) . ' 2>/dev/null' , $bufr2 , PSI_DEBUG )) {
$bufe2 = preg_split ( " / \n / " , $bufr2 , - 1 , PREG_SPLIT_NO_EMPTY );
foreach ( $bufe2 as $buf2 ) {
// if (preg_match('/^'.trim($dev_name).'\s+Link\sencap:Ethernet\s+HWaddr\s(\S+)/i', $buf2, $ar_buf2)
if ( preg_match ( '/\s+encap:Ethernet\s+HWaddr\s(\S+)/i' , $buf2 , $ar_buf2 )
|| preg_match ( '/\s+encap:UNSPEC\s+HWaddr\s(\S+)-00-00-00-00-00-00-00-00-00-00\s*$/i' , $buf2 , $ar_buf2 )
|| preg_match ( '/^\s+ether\s+(\S+)\s+txqueuelen/i' , $buf2 , $ar_buf2 )
|| preg_match ( '/^\s+link\/\S+\s+(\S+)\s+brd/i' , $buf2 , $ar_buf2 )
|| preg_match ( '/^\s+link\/\S+\s+(\S+)$/i' , $buf2 , $ar_buf2 )) {
if ( ! defined ( 'PSI_HIDE_NETWORK_MACADDR' ) || ! PSI_HIDE_NETWORK_MACADDR ) {
$macaddr = preg_replace ( '/:/' , '-' , strtoupper ( $ar_buf2 [ 1 ]));
if (( $macaddr === '00-00-00-00-00-00' ) || ( $macaddr === '00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00' ) || ( $macaddr === '--' ) || ( $macaddr === '0.0.0.0' )) { // empty
$macaddr = " " ;
}
}
} elseif ( preg_match ( '/^\s+inet\saddr:(\S+)\s+P-t-P:(\S+)/i' , $buf2 , $ar_buf2 )
|| preg_match ( '/^\s+inet\s+(\S+)\s+netmask.+destination\s+(\S+)/i' , $buf2 , $ar_buf2 )
|| preg_match ( '/^\s+inet\s+([^\/\s]+).*peer\s+([^\/\s]+).*\s+scope\s((global)|(host))/i' , $buf2 , $ar_buf2 )
/*|| preg_match('/^\s+link\/sit\s+([^\/\s]+).*peer\s+([^\/\s]+)/i', $buf2, $ar_buf2)*/ ) {
2024-09-07 20:53:46 +10:00
if ( $ar_buf2 [ 1 ] != $ar_buf2 [ 2 ]) {
2025-05-14 16:14:01 +01:00
$dev -> setInfo (( $dev -> getInfo () ? $dev -> getInfo () . ';' : '' ) . $ar_buf2 [ 1 ] . " ;: " . $ar_buf2 [ 2 ]);
2024-09-07 20:53:46 +10:00
} else {
2025-05-14 16:14:01 +01:00
$dev -> setInfo (( $dev -> getInfo () ? $dev -> getInfo () . ';' : '' ) . $ar_buf2 [ 1 ]);
2024-09-07 20:53:46 +10:00
}
2025-05-14 16:14:01 +01:00
} elseif (( preg_match ( '/^\s+inet\saddr:(\S+)/i' , $buf2 , $ar_buf2 )
|| preg_match ( '/^\s+inet\s+(\S+)\s+netmask/i' , $buf2 , $ar_buf2 )
|| preg_match ( '/^' . trim ( $dev_name ) . ':\s+ip\s+(\S+)\s+mask/i' , $buf2 , $ar_buf2 )
|| preg_match ( '/^\s+inet6\saddr:\s([^\/\s]+)(.+)\s+Scope:[GH]/i' , $buf2 , $ar_buf2 )
|| preg_match ( '/^\s+inet6\s+(\S+)\s+prefixlen(.+)((<global>)|(<host>))/i' , $buf2 , $ar_buf2 )
|| preg_match ( '/^\s+inet6?\s+([^\/\s]+).*\s+scope\s((global)|(host))/i' , $buf2 , $ar_buf2 )
|| preg_match ( '/^\s+inet\saddr6:\s+(\S+)\s+prefixlen(.+)/i' , $buf2 , $ar_buf2 ))
&& ( $ar_buf2 [ 1 ] != " :: " ) && ! preg_match ( '/^fe80::/i' , $ar_buf2 [ 1 ])) {
$dev -> setInfo (( $dev -> getInfo () ? $dev -> getInfo () . ';' : '' ) . strtolower ( $ar_buf2 [ 1 ]));
}
}
}
if ( $macaddr != " " ) {
$dev -> setInfo ( $macaddr . ( $dev -> getInfo () ? ';' . $dev -> getInfo () : '' ));
}
if (( ! CommonFunctions :: rfts ( '/sys/class/net/' . trim ( $dev_name ) . '/operstate' , $buf , 1 , 4096 , false ) || (( $down = strtolower ( trim ( $buf ))) == " " ) || ( $down !== " down " )) &&
( CommonFunctions :: rfts ( '/sys/class/net/' . trim ( $dev_name ) . '/speed' , $buf , 1 , 4096 , false ) && (( $speed = trim ( $buf )) != " " ) && ( $buf > 0 ) && ( $buf < 65535 ))) {
if ( $speed > 1000 ) {
$speed = $speed / 1000 ;
$unit = " G " ;
} else {
$unit = " M " ;
}
if ( CommonFunctions :: rfts ( '/sys/class/net/' . trim ( $dev_name ) . '/duplex' , $buf , 1 , 4096 , false ) && (( $duplex = strtolower ( trim ( $buf ))) != " " ) && ( $duplex != 'unknown' )) {
$dev -> setInfo (( $dev -> getInfo () ? $dev -> getInfo () . ';' : '' ) . $speed . $unit . 'b/s ' . $duplex );
} else {
$dev -> setInfo (( $dev -> getInfo () ? $dev -> getInfo () . ';' : '' ) . $speed . $unit . 'b/s' );
}
2024-09-07 20:53:46 +10:00
}
}
$this -> sys -> setNetDevices ( $dev );
}
}
2025-05-14 16:14:01 +01:00
} elseif (( $bufr === null ) && CommonFunctions :: executeProgram ( 'ip' , 'addr show' , $bufr , PSI_DEBUG ) && ( $bufr != " " )) {
$lines = preg_split ( " / \n / " , $bufr , - 1 , PREG_SPLIT_NO_EMPTY );
$was = false ;
$macaddr = " " ;
$speedinfo = " " ;
$dev = null ;
foreach ( $lines as $line ) {
if ( preg_match ( " /^ \ d+: \ s+([^ \ s:@]+)(.*)/ " , $line , $ar_buf )) {
if ( $was ) {
if ( $macaddr != " " ) {
$dev -> setInfo ( $macaddr . ( $dev -> getInfo () ? ';' . $dev -> getInfo () : '' ));
}
if ( $speedinfo != " " ) {
$dev -> setInfo (( $dev -> getInfo () ? $dev -> getInfo () . ';' : '' ) . $speedinfo );
}
$this -> sys -> setNetDevices ( $dev );
}
$speedinfo = " " ;
$macaddr = " " ;
$dev = new NetDevice ();
$dev -> setName ( $ar_buf [ 1 ]);
if ( defined ( 'PSI_SHOW_NETWORK_BRIDGE' ) && PSI_SHOW_NETWORK_BRIDGE
&& isset ( $ar_buf [ 2 ]) && (( $ar_buf [ 2 ] = trim ( $ar_buf [ 2 ])) !== " " ) && preg_match ( " / \ s+master \ s+( \ S+)/ " , $ar_buf [ 2 ], $bufr2 )) {
$dev -> setBridge ( $bufr2 [ 1 ]);
}
if ( CommonFunctions :: executeProgram ( 'ip' , '-s link show ' . $ar_buf [ 1 ], $bufr2 , false ) && ( $bufr2 != " " )
&& preg_match ( " / \n \ s+RX: \ s[^ \n ]+ \n \ s+( \ d+) \ s+ \ d+ \ s+( \ d+) \ s+( \ d+)[^ \n ]+ \n \ s+TX: \ s[^ \n ]+ \n \ s+( \ d+) \ s+ \ d+ \ s+( \ d+) \ s+( \ d+)/m " , $bufr2 , $ar_buf2 )) {
$dev -> setRxBytes ( $ar_buf2 [ 1 ]);
$dev -> setTxBytes ( $ar_buf2 [ 4 ]);
$dev -> setErrors ( $ar_buf2 [ 2 ] + $ar_buf2 [ 5 ]);
$dev -> setDrops ( $ar_buf2 [ 3 ] + $ar_buf2 [ 6 ]);
} elseif ( CommonFunctions :: executeProgram ( 'ifconfig' , $ar_buf [ 1 ], $bufr2 , false ) && ( $bufr2 != " " )) {
if ( preg_match ( '/\sRX bytes:(\d+)\s/im' , $bufr2 , $ar_buf2 )) {
$dev -> setRxBytes ( $ar_buf2 [ 1 ]);
}
if ( preg_match ( '/\sTX bytes:(\d+)\s/im' , $bufr2 , $ar_buf2 )) {
$dev -> setTxBytes ( $ar_buf2 [ 1 ]);
}
$errors = 0 ;
$drops = 0 ;
if ( preg_match ( '/\sRX packets:\d+\serrors:(\d+)\sdropped:(\d+)/im' , $bufr2 , $ar_buf2 )) {
$errors += $ar_buf2 [ 1 ];
$drops += $ar_buf2 [ 2 ];
}
if ( preg_match ( '/\sTX packets:\d+\serrors:(\d+)\sdropped:(\d+)/im' , $bufr2 , $ar_buf2 )) {
$errors += $ar_buf2 [ 1 ];
$drops += $ar_buf2 [ 2 ];
}
$dev -> setErrors ( $errors );
$dev -> setDrops ( $drops );
}
$was = true ;
if ( defined ( 'PSI_SHOW_NETWORK_INFOS' ) && ( PSI_SHOW_NETWORK_INFOS )) {
if (( ! CommonFunctions :: rfts ( '/sys/class/net/' . $ar_buf [ 1 ] . '/operstate' , $buf , 1 , 4096 , false ) || (( $down = strtolower ( trim ( $buf ))) == " " ) || ( $down !== " down " )) &&
( CommonFunctions :: rfts ( '/sys/class/net/' . $ar_buf [ 1 ] . '/speed' , $buf , 1 , 4096 , false ) && (( $speed = trim ( $buf )) != " " ) && ( $buf > 0 ) && ( $buf < 65535 ))) {
if ( $speed > 1000 ) {
$speed = $speed / 1000 ;
$unit = " G " ;
} else {
$unit = " M " ;
}
if ( CommonFunctions :: rfts ( '/sys/class/net/' . $ar_buf [ 1 ] . '/duplex' , $buf , 1 , 4096 , false ) && (( $duplex = strtolower ( trim ( $buf ))) != " " ) && ( $duplex != 'unknown' )) {
$speedinfo = $speed . $unit . 'b/s ' . $duplex ;
} else {
$speedinfo = $speed . $unit . 'b/s' ;
}
}
}
} else {
if ( $was ) {
if ( defined ( 'PSI_SHOW_NETWORK_INFOS' ) && ( PSI_SHOW_NETWORK_INFOS )) {
if ( preg_match ( '/^\s+link\/\S+\s+(\S+)\s+brd/i' , $line , $ar_buf2 )
|| preg_match ( '/^\s+link\/\S+\s+(\S+)$/i' , $line , $ar_buf2 )) {
if ( ! defined ( 'PSI_HIDE_NETWORK_MACADDR' ) || ! PSI_HIDE_NETWORK_MACADDR ) {
$macaddr = preg_replace ( '/:/' , '-' , strtoupper ( $ar_buf2 [ 1 ]));
if (( $macaddr === '00-00-00-00-00-00' ) || ( $macaddr === '00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00' ) || ( $macaddr === '--' ) || ( $macaddr === '0.0.0.0' )) { // empty
$macaddr = " " ;
}
}
} elseif ( preg_match ( '/^\s+inet\s+([^\/\s]+).*peer\s+([^\/\s]+).*\s+scope\s((global)|(host))/i' , $line , $ar_buf2 )
/*|| preg_match('/^\s+link\/sit\s+([^\/\s]+).*peer\s+([^\/\s]+)/i', $line, $ar_buf2)*/ ) {
if ( $ar_buf2 [ 1 ] != $ar_buf2 [ 2 ]) {
$dev -> setInfo (( $dev -> getInfo () ? $dev -> getInfo () . ';' : '' ) . $ar_buf2 [ 1 ] . " ;: " . $ar_buf2 [ 2 ]);
} else {
$dev -> setInfo (( $dev -> getInfo () ? $dev -> getInfo () . ';' : '' ) . $ar_buf2 [ 1 ]);
}
} elseif ( preg_match ( '/^\s+inet6?\s+([^\/\s]+).*\s+scope\s((global)|(host))/i' , $line , $ar_buf2 )
&& ( $ar_buf2 [ 1 ] != " :: " ) && ! preg_match ( '/^fe80::/i' , $ar_buf2 [ 1 ])) {
$dev -> setInfo (( $dev -> getInfo () ? $dev -> getInfo () . ';' : '' ) . strtolower ( $ar_buf2 [ 1 ]));
}
}
}
}
}
if ( $was ) {
if ( $macaddr != " " ) {
$dev -> setInfo ( $macaddr . ( $dev -> getInfo () ? ';' . $dev -> getInfo () : '' ));
}
if ( $speedinfo != " " ) {
$dev -> setInfo (( $dev -> getInfo () ? $dev -> getInfo () . ';' : '' ) . $speedinfo );
}
$this -> sys -> setNetDevices ( $dev );
}
} elseif (( $bufr !== null ) || CommonFunctions :: executeProgram ( 'ifconfig' , '-a' , $bufr , PSI_DEBUG )) {
2024-09-07 20:53:46 +10:00
$lines = preg_split ( " / \n / " , $bufr , - 1 , PREG_SPLIT_NO_EMPTY );
2025-05-14 16:14:01 +01:00
$was = false ;
$errors = 0 ;
$drops = 0 ;
$macaddr = " " ;
$speedinfo = " " ;
$dev = null ;
2024-09-07 20:53:46 +10:00
foreach ( $lines as $line ) {
if ( preg_match ( " /^([^ \ s:]+)/ " , $line , $ar_buf )) {
2025-05-14 16:14:01 +01:00
if ( $was ) {
2024-09-07 20:53:46 +10:00
$dev -> setErrors ( $errors );
$dev -> setDrops ( $drops );
2025-05-14 16:14:01 +01:00
if ( $macaddr != " " ) {
$dev -> setInfo ( $macaddr . ( $dev -> getInfo () ? ';' . $dev -> getInfo () : '' ));
}
if ( $speedinfo != " " ) {
$dev -> setInfo (( $dev -> getInfo () ? $dev -> getInfo () . ';' : '' ) . $speedinfo );
}
2024-09-07 20:53:46 +10:00
$this -> sys -> setNetDevices ( $dev );
}
$errors = 0 ;
$drops = 0 ;
2025-05-14 16:14:01 +01:00
$speedinfo = " " ;
$macaddr = " " ;
2024-09-07 20:53:46 +10:00
$dev = new NetDevice ();
$dev -> setName ( $ar_buf [ 1 ]);
2025-05-14 16:14:01 +01:00
$was = true ;
2024-09-07 20:53:46 +10:00
if ( defined ( 'PSI_SHOW_NETWORK_INFOS' ) && ( PSI_SHOW_NETWORK_INFOS )) {
2025-05-14 16:14:01 +01:00
if (( ! CommonFunctions :: rfts ( '/sys/class/net/' . $ar_buf [ 1 ] . '/operstate' , $buf , 1 , 4096 , false ) || (( $down = strtolower ( trim ( $buf ))) == " " ) || ( $down !== " down " )) &&
( CommonFunctions :: rfts ( '/sys/class/net/' . $ar_buf [ 1 ] . '/speed' , $buf , 1 , 4096 , false ) && (( $speed = trim ( $buf )) != " " ) && ( $buf > 0 ) && ( $buf < 65535 ))) {
if ( $speed > 1000 ) {
$speed = $speed / 1000 ;
$unit = " G " ;
} else {
$unit = " M " ;
}
if ( CommonFunctions :: rfts ( '/sys/class/net/' . $ar_buf [ 1 ] . '/duplex' , $buf , 1 , 4096 , false ) && (( $duplex = strtolower ( trim ( $buf ))) != " " ) && ( $duplex != 'unknown' )) {
$speedinfo = $speed . $unit . 'b/s ' . $duplex ;
} else {
$speedinfo = $speed . $unit . 'b/s' ;
}
}
if ( preg_match ( '/^' . $ar_buf [ 1 ] . '\s+Link\sencap:Ethernet\s+HWaddr\s(\S+)/i' , $line , $ar_buf2 )
|| preg_match ( '/^' . $ar_buf [ 1 ] . '\s+Link\s+encap:UNSPEC\s+HWaddr\s(\S+)-00-00-00-00-00-00-00-00-00-00\s*$/i' , $line , $ar_buf2 )) {
if ( ! defined ( 'PSI_HIDE_NETWORK_MACADDR' ) || ! PSI_HIDE_NETWORK_MACADDR ) {
$macaddr = preg_replace ( '/:/' , '-' , strtoupper ( $ar_buf2 [ 1 ]));
if ( $macaddr === '00-00-00-00-00-00' ) { // empty
$macaddr = " " ;
}
}
} elseif ( preg_match ( '/^' . $ar_buf [ 1 ] . ':\s+ip\s+(\S+)\s+mask/i' , $line , $ar_buf2 ))
2024-09-07 20:53:46 +10:00
$dev -> setInfo (( $dev -> getInfo () ? $dev -> getInfo () . ';' : '' ) . $ar_buf2 [ 1 ]);
}
} else {
2025-05-14 16:14:01 +01:00
if ( $was ) {
2024-09-07 20:53:46 +10:00
if ( preg_match ( '/\sRX bytes:(\d+)\s/i' , $line , $ar_buf2 )) {
$dev -> setRxBytes ( $ar_buf2 [ 1 ]);
}
if ( preg_match ( '/\sTX bytes:(\d+)\s/i' , $line , $ar_buf2 )) {
$dev -> setTxBytes ( $ar_buf2 [ 1 ]);
}
if ( preg_match ( '/\sRX packets:\d+\serrors:(\d+)\sdropped:(\d+)/i' , $line , $ar_buf2 )) {
$errors += $ar_buf2 [ 1 ];
$drops += $ar_buf2 [ 2 ];
} elseif ( preg_match ( '/\sTX packets:\d+\serrors:(\d+)\sdropped:(\d+)/i' , $line , $ar_buf2 )) {
$errors += $ar_buf2 [ 1 ];
$drops += $ar_buf2 [ 2 ];
}
if ( defined ( 'PSI_SHOW_NETWORK_INFOS' ) && ( PSI_SHOW_NETWORK_INFOS )) {
if ( preg_match ( '/\s+encap:Ethernet\s+HWaddr\s(\S+)/i' , $line , $ar_buf2 )
2025-05-14 16:14:01 +01:00
|| preg_match ( '/\s+encap:UNSPEC\s+HWaddr\s(\S+)-00-00-00-00-00-00-00-00-00-00\s*$/i' , $line , $ar_buf2 )
|| preg_match ( '/^\s+ether\s+(\S+)\s+txqueuelen/i' , $line , $ar_buf2 )) {
if ( ! defined ( 'PSI_HIDE_NETWORK_MACADDR' ) || ! PSI_HIDE_NETWORK_MACADDR ) {
$macaddr = preg_replace ( '/:/' , '-' , strtoupper ( $ar_buf2 [ 1 ]));
if ( $macaddr === '00-00-00-00-00-00' ) { // empty
$macaddr = " " ;
2024-09-07 20:53:46 +10:00
}
2025-05-14 16:14:01 +01:00
}
} elseif ( preg_match ( '/^\s+inet\saddr:(\S+)\s+P-t-P:(\S+)/i' , $line , $ar_buf2 )
|| preg_match ( '/^\s+inet\s+(\S+)\s+netmask.+destination\s+(\S+)/i' , $line , $ar_buf2 )) {
if ( $ar_buf2 [ 1 ] != $ar_buf2 [ 2 ]) {
$dev -> setInfo (( $dev -> getInfo () ? $dev -> getInfo () . ';' : '' ) . $ar_buf2 [ 1 ] . " ;: " . $ar_buf2 [ 2 ]);
} else {
$dev -> setInfo (( $dev -> getInfo () ? $dev -> getInfo () . ';' : '' ) . $ar_buf2 [ 1 ]);
}
} elseif (( preg_match ( '/^\s+inet\saddr:(\S+)/i' , $line , $ar_buf2 )
2024-09-07 20:53:46 +10:00
|| preg_match ( '/^\s+inet\s+(\S+)\s+netmask/i' , $line , $ar_buf2 )
2025-05-14 16:14:01 +01:00
|| preg_match ( '/^\s+inet6\saddr:\s([^\/\s]+)(.+)\s+Scope:[GH]/i' , $line , $ar_buf2 )
|| preg_match ( '/^\s+inet6\s+(\S+)\s+prefixlen(.+)((<global>)|(<host>))/i' , $line , $ar_buf2 )
|| preg_match ( '/^\s+inet\saddr6:\s+(\S+)\s+prefixlen(.+)/i' , $line , $ar_buf2 ))
&& ( $ar_buf2 [ 1 ] != " :: " ) && ! preg_match ( '/^fe80::/i' , $ar_buf2 [ 1 ])) {
$dev -> setInfo (( $dev -> getInfo () ? $dev -> getInfo () . ';' : '' ) . strtolower ( $ar_buf2 [ 1 ]));
}
2024-09-07 20:53:46 +10:00
}
}
}
}
2025-05-14 16:14:01 +01:00
if ( $was ) {
2024-09-07 20:53:46 +10:00
$dev -> setErrors ( $errors );
$dev -> setDrops ( $drops );
2025-05-14 16:14:01 +01:00
if ( $macaddr != " " ) {
$dev -> setInfo ( $macaddr . ( $dev -> getInfo () ? ';' . $dev -> getInfo () : '' ));
}
if ( $speedinfo != " " ) {
$dev -> setInfo (( $dev -> getInfo () ? $dev -> getInfo () . ';' : '' ) . $speedinfo );
}
2024-09-07 20:53:46 +10:00
$this -> sys -> setNetDevices ( $dev );
}
}
}
/**
* Physical memory information and Swap Space information
*
* @ return void
*/
2025-05-14 16:14:01 +01:00
protected function _memory ( $mbuf = null , $sbuf = null )
2024-09-07 20:53:46 +10:00
{
2025-05-14 16:14:01 +01:00
if (( $mbuf !== null ) || CommonFunctions :: rfts ( '/proc/meminfo' , $mbuf )) {
$swaptotal = null ;
$swapfree = null ;
2024-09-07 20:53:46 +10:00
$bufe = preg_split ( " / \n / " , $mbuf , - 1 , PREG_SPLIT_NO_EMPTY );
foreach ( $bufe as $buf ) {
2025-05-14 16:14:01 +01:00
if ( preg_match ( '/^MemTotal:\s+(\d+)\s*kB/i' , $buf , $ar_buf )) {
2024-09-07 20:53:46 +10:00
$this -> sys -> setMemTotal ( $ar_buf [ 1 ] * 1024 );
2025-05-14 16:14:01 +01:00
} elseif ( preg_match ( '/^MemFree:\s+(\d+)\s*kB/i' , $buf , $ar_buf )) {
2024-09-07 20:53:46 +10:00
$this -> sys -> setMemFree ( $ar_buf [ 1 ] * 1024 );
2025-05-14 16:14:01 +01:00
} elseif ( preg_match ( '/^Cached:\s+(\d+)\s*kB/i' , $buf , $ar_buf )) {
2024-09-07 20:53:46 +10:00
$this -> sys -> setMemCache ( $ar_buf [ 1 ] * 1024 );
2025-05-14 16:14:01 +01:00
} elseif ( preg_match ( '/^Buffers:\s+(\d+)\s*kB/i' , $buf , $ar_buf )) {
2024-09-07 20:53:46 +10:00
$this -> sys -> setMemBuffer ( $ar_buf [ 1 ] * 1024 );
2025-05-14 16:14:01 +01:00
} elseif ( preg_match ( '/^SwapTotal:\s+(\d+)\s*kB/i' , $buf , $ar_buf )) {
$swaptotal = $ar_buf [ 1 ] * 1024 ;
} elseif ( preg_match ( '/^SwapFree:\s+(\d+)\s*kB/i' , $buf , $ar_buf )) {
$swapfree = $ar_buf [ 1 ] * 1024 ;
2024-09-07 20:53:46 +10:00
}
}
$this -> sys -> setMemUsed ( $this -> sys -> getMemTotal () - $this -> sys -> getMemFree ());
// values for splitting memory usage
2025-05-14 16:14:01 +01:00
if (( $this -> sys -> getMemCache () !== null ) && ( $this -> sys -> getMemBuffer () !== null )) {
2024-09-07 20:53:46 +10:00
$this -> sys -> setMemApplication ( $this -> sys -> getMemUsed () - $this -> sys -> getMemCache () - $this -> sys -> getMemBuffer ());
}
2025-05-14 16:14:01 +01:00
if (( $sbuf !== null ) || CommonFunctions :: rfts ( '/proc/swaps' , $sbuf , 0 , 4096 , false )) {
2024-09-07 20:53:46 +10:00
$swaps = preg_split ( " / \n / " , $sbuf , - 1 , PREG_SPLIT_NO_EMPTY );
unset ( $swaps [ 0 ]);
foreach ( $swaps as $swap ) {
$ar_buf = preg_split ( '/\s+/' , $swap , 5 );
$dev = new DiskDevice ();
$dev -> setMountPoint ( $ar_buf [ 0 ]);
$dev -> setName ( " SWAP " );
$dev -> setTotal ( $ar_buf [ 2 ] * 1024 );
$dev -> setUsed ( $ar_buf [ 3 ] * 1024 );
$dev -> setFree ( $dev -> getTotal () - $dev -> getUsed ());
$this -> sys -> setSwapDevices ( $dev );
}
2025-05-14 16:14:01 +01:00
} elseif (( $swaptotal !== null ) && ( $swapfree !== null ) && ( $swaptotal > 0 )) {
$dev = new DiskDevice ();
$dev -> setName ( " SWAP " );
$dev -> setTotal ( $swaptotal );
$dev -> setFree ( $swapfree );
$dev -> setUsed ( $dev -> getTotal () - $dev -> getFree ());
$this -> sys -> setSwapDevices ( $dev );
2024-09-07 20:53:46 +10:00
}
}
}
/**
* filesystem information
*
* @ return void
*/
2025-05-14 16:14:01 +01:00
protected function _filesystems ()
2024-09-07 20:53:46 +10:00
{
$df_args = " " ;
$hideFstypes = array ();
if ( defined ( 'PSI_HIDE_FS_TYPES' ) && is_string ( PSI_HIDE_FS_TYPES )) {
if ( preg_match ( ARRAY_EXP , PSI_HIDE_FS_TYPES )) {
$hideFstypes = eval ( PSI_HIDE_FS_TYPES );
} else {
$hideFstypes = array ( PSI_HIDE_FS_TYPES );
}
}
foreach ( $hideFstypes as $Fstype ) {
$df_args .= " -x $Fstype " ;
}
if ( $df_args !== " " ) {
2025-05-14 16:14:01 +01:00
$df_args = trim ( $df_args ); // trim spaces
2024-09-07 20:53:46 +10:00
$arrResult = Parser :: df ( " -P $df_args 2>/dev/null " );
} else {
$arrResult = Parser :: df ( " -P 2>/dev/null " );
}
foreach ( $arrResult as $dev ) {
$this -> sys -> setDiskDevices ( $dev );
}
}
/**
* Distribution
*
* @ return void
*/
2025-05-14 16:14:01 +01:00
protected function _distro ()
2024-09-07 20:53:46 +10:00
{
$this -> sys -> setDistribution ( " Linux " );
2025-05-14 16:14:01 +01:00
$list = @ parse_ini_file ( PSI_APP_ROOT . " /data/distros.ini " , true );
2024-09-07 20:53:46 +10:00
if ( ! $list ) {
return ;
}
2025-05-14 16:14:01 +01:00
$_ignore_lsb_release = false ;
$_Distrib = " " ;
$_DistribIcon = " " ;
2024-09-07 20:53:46 +10:00
// We have the '2>/dev/null' because Ubuntu gives an error on this command which causes the distro to be unknown
2025-05-14 16:14:01 +01:00
if ( CommonFunctions :: executeProgram ( 'lsb_release' , '-a 2>/dev/null' , $distro_info , PSI_DEBUG ) && strlen ( $distro_info ) > 0 ) {
$distro_tmp = preg_split ( " / \r ? \n / " , $distro_info , - 1 , PREG_SPLIT_NO_EMPTY );
2024-09-07 20:53:46 +10:00
foreach ( $distro_tmp as $info ) {
$info_tmp = preg_split ( '/:/' , $info , 2 );
2025-05-14 16:14:01 +01:00
if ( isset ( $distro_tmp [ 0 ]) && ( $distro_tmp [ 0 ] !== null ) && ( trim ( $distro_tmp [ 0 ]) != " " ) &&
isset ( $distro_tmp [ 1 ]) && ( $distro_tmp [ 1 ] !== null ) && ( trim ( $distro_tmp [ 1 ]) != " " )) {
2024-09-07 20:53:46 +10:00
$distro [ trim ( $info_tmp [ 0 ])] = trim ( $info_tmp [ 1 ]);
}
}
2025-05-14 16:14:01 +01:00
2024-09-07 20:53:46 +10:00
if ( ! isset ( $distro [ 'Distributor ID' ]) && ! isset ( $distro [ 'Description' ])) { // Systems like StartOS
2025-05-14 16:14:01 +01:00
if ( isset ( $distro_tmp [ 0 ]) && ( $distro_tmp [ 0 ] !== null ) && ( trim ( $distro_tmp [ 0 ]) != " " )) {
$_Distrib = trim ( $distro_tmp [ 0 ]);
2024-09-07 20:53:46 +10:00
if ( preg_match ( '/^(\S+)\s*/' , $distro_tmp [ 0 ], $id_buf )
2025-05-14 16:14:01 +01:00
&& isset ( $list [ strtolower ( trim ( $id_buf [ 1 ]))][ 'Image' ])) {
$_DistribIcon = $list [ strtolower ( trim ( $id_buf [ 1 ]))][ 'Image' ];
// set ignore lsb_release for some distributions
if ( isset ( $list [ strtolower ( trim ( $id_buf [ 1 ]))][ 'Test' ]) && ( $list [ strtolower ( trim ( $id_buf [ 1 ]))][ 'Test' ] === " nolsbfirst " )) $_ignore_lsb_release = true ;
2024-09-07 20:53:46 +10:00
}
}
} else {
2025-05-14 16:14:01 +01:00
if ( isset ( $distro [ 'Description' ])) {
if ( preg_match ( '/^NAME=\s*"?([^"\r\n]+)"?\s*$/' , $distro [ 'Description' ], $name_tmp )) {
$distro [ 'Description' ] = trim ( $name_tmp [ 1 ]);
} elseif (( $distro [ 'Description' ] === " Rolling Release " ) && isset ( $distro [ 'Distributor ID' ]) && ( $distro [ 'Distributor ID' ] != " n/a " )) {
$distro [ 'Description' ] = $distro [ 'Distributor ID' ] . " " . $distro [ 'Description' ];
}
2024-09-07 20:53:46 +10:00
}
if ( isset ( $distro [ 'Description' ])
&& ( $distro [ 'Description' ] != " n/a " )
2025-05-14 16:14:01 +01:00
&& ( ! isset ( $distro [ 'Distributor ID' ])
|| (( $distro [ 'Distributor ID' ] != " n/a " )
&& ( $distro [ 'Description' ] != $distro [ 'Distributor ID' ])))) {
$_Distrib = $distro [ 'Description' ];
if ( isset ( $distro [ 'Release' ]) && ( $distro [ 'Release' ] != " n/a " )
&& ( $distro [ 'Release' ] != $distro [ 'Description' ]) && strstr ( $distro [ 'Release' ], " . " )){
if ( preg_match ( " /^( \ d+) \ .[0]+ $ / " , $distro [ 'Release' ], $match_buf )) {
$tofind = $match_buf [ 1 ];
} else {
$tofind = $distro [ 'Release' ];
}
if ( ! preg_match ( " /^ " . $tofind . " [ \ s \ .]|[ \ ( \ [] " . $tofind . " [ \ . \ ) \ ]]| \ s " . $tofind . " $ | \ s " . $tofind . " [ \ s \ .]/ " , $distro [ 'Description' ])) {
$_Distrib .= " " . $distro [ 'Release' ];
}
2024-09-07 20:53:46 +10:00
}
2025-05-14 16:14:01 +01:00
} elseif ( isset ( $distro [ 'Distributor ID' ])) {
if ( $distro [ 'Distributor ID' ] != " n/a " ) {
$_Distrib = $distro [ 'Distributor ID' ];
if ( isset ( $distro [ 'Release' ]) && ( $distro [ 'Release' ] != " n/a " )) {
$_Distrib .= " " . $distro [ 'Release' ];
}
if ( isset ( $distro [ 'Codename' ]) && ( $distro [ 'Codename' ] != " n/a " )) {
$_Distrib .= " ( " . $distro [ 'Codename' ] . " ) " ;
}
} elseif ( isset ( $distro [ 'Description' ]) && ( $distro [ 'Description' ] != " n/a " )) {
$_Distrib = $distro [ 'Description' ];
2024-09-07 20:53:46 +10:00
}
}
2025-05-14 16:14:01 +01:00
if ( isset ( $distro [ 'Distributor ID' ])) {
$distrib = $distro [ 'Distributor ID' ];
$distrib2 = $distrib ;
$distrib3 = $distrib ;
if ( isset ( $distro [ 'Description' ])) {
$distarr = preg_split ( " / \ s/ " , $distro [ 'Description' ], - 1 , PREG_SPLIT_NO_EMPTY );
if ( isset ( $distarr [ 0 ])) {
if ( $distrib != " n/a " ) {
$distrib2 .= ' ' . $distarr [ 0 ];
} else {
$distrib2 = $distarr [ 0 ];
}
}
if ( isset ( $distarr [ 1 ])) {
if ( $distrib != " n/a " ) {
$distrib3 .= ' ' . $distarr [ 0 ] . ' ' . $distarr [ 1 ];
} else {
$distrib3 = $distarr [ 0 ] . ' ' . $distarr [ 1 ];
}
}
}
if (( $distrib !== $distrib3 ) && isset ( $list [ strtolower ( $distrib3 )][ 'Image' ])) {
$_DistribIcon = $list [ strtolower ( $distrib3 )][ 'Image' ];
// set ignore lsb_release for some distributions
if ( isset ( $list [ strtolower ( $distrib3 )][ 'Test' ]) && ( $list [ strtolower ( $distrib3 )][ 'Test' ] === " nolsbfirst " )) $_ignore_lsb_release = true ;
} elseif (( $distrib !== $distrib2 ) && isset ( $list [ strtolower ( $distrib2 )][ 'Image' ])) {
$_DistribIcon = $list [ strtolower ( $distrib2 )][ 'Image' ];
// set ignore lsb_release for some distributions
if ( isset ( $list [ strtolower ( $distrib2 )][ 'Test' ]) && ( $list [ strtolower ( $distrib2 )][ 'Test' ] === " nolsbfirst " )) $_ignore_lsb_release = true ;
} elseif (( $distrib !== " n/a " ) && isset ( $list [ strtolower ( $distrib )][ 'Image' ])) {
$_DistribIcon = $list [ strtolower ( $distrib )][ 'Image' ];
// set ignore lsb_release for some distributions
if ( isset ( $list [ strtolower ( $distrib )][ 'Test' ]) && ( $list [ strtolower ( $distrib )][ 'Test' ] === " nolsbfirst " )) $_ignore_lsb_release = true ;
}
2024-09-07 20:53:46 +10:00
}
}
2025-05-14 16:14:01 +01:00
}
if ( ! $_ignore_lsb_release ) { // don't ignore lsb_release
if ( $_Distrib !== " " ) $this -> sys -> setDistribution ( preg_replace ( " / - Version:| Build:| Release| version| build| based in Ubuntu/i " , " " , $_Distrib ));
if ( $_DistribIcon !== " " ) $this -> sys -> setDistributionIcon ( $_DistribIcon );
}
// if the distribution is still unknown
if ( $this -> sys -> getDistribution () == " Linux " ) {
2024-09-07 20:53:46 +10:00
/* default error handler */
if ( function_exists ( 'errorHandlerPsi' )) {
restore_error_handler ();
}
/* fatal errors only */
$old_err_rep = error_reporting ();
error_reporting ( E_ERROR );
// Fall back in case 'lsb_release' does not exist but exist /etc/lsb-release
if ( CommonFunctions :: fileexists ( $filename = " /etc/lsb-release " )
&& CommonFunctions :: rfts ( $filename , $buf , 0 , 4096 , false )
2025-05-14 16:14:01 +01:00
&& ( preg_match ( '/^DISTRIB_ID="?([^"\r\n]+)/m' , $buf , $id_buf ) || preg_match ( '/^DISTRIB_DESCRIPTION="?([^"\r\n]+)/m' , $buf , $id_buf ))) {
if ( preg_match ( '/^DISTRIB_DESCRIPTION="?([^"\r\n]+)/m' , $buf , $desc_buf )
2024-09-07 20:53:46 +10:00
&& ( trim ( $desc_buf [ 1 ]) != trim ( $id_buf [ 1 ]))) {
2025-05-14 16:14:01 +01:00
if ( $desc_buf [ 1 ] === " Rolling Release " ) {
$desc_buf [ 1 ] = $id_buf [ 1 ] . " " . $desc_buf [ 1 ];
}
$this -> sys -> setDistribution ( preg_replace ( " / - Version:| Build:| Release| version| build| based in Ubuntu/i " , " " , trim ( $desc_buf [ 1 ])));
if ( preg_match ( '/^DISTRIB_RELEASE="?([^"\r\n]+)/m' , $buf , $vers_buf )
&& ( trim ( $vers_buf [ 1 ]) != trim ( $desc_buf [ 1 ])) && strstr ( $vers_buf [ 1 ], " . " )){
if ( preg_match ( " /^( \ d+) \ .[0]+ $ / " , trim ( $vers_buf [ 1 ]), $match_buf )) {
$tofind = $match_buf [ 1 ];
} else {
$tofind = trim ( $vers_buf [ 1 ]);
}
if ( ! preg_match ( " /^ " . $tofind . " [ \ s \ .]|[ \ ( \ [] " . $tofind . " [ \ . \ ) \ ]]| \ s " . $tofind . " $ | \ s " . $tofind . " [ \ s \ .]/ " , trim ( $desc_buf [ 1 ]))) {
$this -> sys -> setDistribution ( $this -> sys -> getDistribution () . " " . trim ( $vers_buf [ 1 ]));
}
}
$distrib = trim ( $id_buf [ 1 ]);
$distrib2 = $distrib ;
$distrib3 = $distrib ;
$distarr = preg_split ( " / \ s/ " , trim ( $desc_buf [ 1 ]), - 1 , PREG_SPLIT_NO_EMPTY );
if ( isset ( $distarr [ 0 ])) {
$distrib2 .= ' ' . $distarr [ 0 ];
}
if ( isset ( $distarr [ 1 ])) {
$distrib3 .= ' ' . $distarr [ 0 ] . ' ' . $distarr [ 1 ];
}
if (( $distrib !== $distrib3 ) && isset ( $list [ strtolower ( $distrib3 )][ 'Image' ])) {
$this -> sys -> setDistributionIcon ( $list [ strtolower ( $distrib3 )][ 'Image' ]);
} elseif (( $distrib !== $distrib2 ) && isset ( $list [ strtolower ( $distrib2 )][ 'Image' ])) {
$this -> sys -> setDistributionIcon ( $list [ strtolower ( $distrib2 )][ 'Image' ]);
} elseif (( $distrib !== " n/a " ) && isset ( $list [ strtolower ( $distrib )][ 'Image' ])) {
$this -> sys -> setDistributionIcon ( $list [ strtolower ( $distrib )][ 'Image' ]);
}
2024-09-07 20:53:46 +10:00
} else {
2025-05-14 16:14:01 +01:00
if ( isset ( $list [ strtolower ( trim ( $id_buf [ 1 ]))][ 'Name' ])) {
$this -> sys -> setDistribution ( trim ( $list [ strtolower ( trim ( $id_buf [ 1 ]))][ 'Name' ]));
2024-09-07 20:53:46 +10:00
} else {
$this -> sys -> setDistribution ( trim ( $id_buf [ 1 ]));
}
2025-05-14 16:14:01 +01:00
if ( preg_match ( '/^DISTRIB_RELEASE="?([^"\r\n]+)/m' , $buf , $vers_buf )) {
2024-09-07 20:53:46 +10:00
$this -> sys -> setDistribution ( $this -> sys -> getDistribution () . " " . trim ( $vers_buf [ 1 ]));
}
2025-05-14 16:14:01 +01:00
if ( preg_match ( '/^DISTRIB_CODENAME="?([^"\r\n]+)/m' , $buf , $vers_buf )) {
2024-09-07 20:53:46 +10:00
$this -> sys -> setDistribution ( $this -> sys -> getDistribution () . " ( " . trim ( $vers_buf [ 1 ]) . " ) " );
}
2025-05-14 16:14:01 +01:00
if ( isset ( $list [ strtolower ( trim ( $id_buf [ 1 ]))][ 'Image' ])) {
$this -> sys -> setDistributionIcon ( $list [ strtolower ( trim ( $id_buf [ 1 ]))][ 'Image' ]);
}
2024-09-07 20:53:46 +10:00
}
} else { // otherwise find files specific for distribution
foreach ( $list as $section => $distribution ) {
if ( ! isset ( $distribution [ 'Files' ])) {
continue ;
} else {
foreach ( preg_split ( " /;/ " , $distribution [ 'Files' ], - 1 , PREG_SPLIT_NO_EMPTY ) as $filename ) {
if ( CommonFunctions :: fileexists ( $filename )) {
$distro = $distribution ;
if ( isset ( $distribution [ 'Mode' ]) && ( strtolower ( $distribution [ 'Mode' ]) == " detection " )) {
$buf = " " ;
} elseif ( isset ( $distribution [ 'Mode' ]) && ( strtolower ( $distribution [ 'Mode' ]) == " execute " )) {
if ( ! CommonFunctions :: executeProgram ( $filename , '2>/dev/null' , $buf , PSI_DEBUG )) {
$buf = " " ;
2025-05-14 16:14:01 +01:00
} elseif ( preg_match ( '/^pve-manager\/([\d.]+)\//' , $buf , $vers_buf )) { // Proxmox version
$buf = $vers_buf [ 1 ];
2024-09-07 20:53:46 +10:00
}
} else {
if ( ! CommonFunctions :: rfts ( $filename , $buf , 1 , 4096 , false )) {
$buf = " " ;
2025-05-14 16:14:01 +01:00
if ( isset ( $distribution [ 'Mode' ]) && ( strtolower ( $distribution [ 'Mode' ]) == " analyse " )) {
break ;
}
2024-09-07 20:53:46 +10:00
} elseif ( isset ( $distribution [ 'Mode' ]) && ( strtolower ( $distribution [ 'Mode' ]) == " analyse " )) {
2025-05-14 16:14:01 +01:00
if ( preg_match ( '/^(\S+)\s*/' , preg_replace ( '/^red\s+/' , 'red' , strtolower ( $buf )), $id_buf )
2024-09-07 20:53:46 +10:00
&& isset ( $list [ trim ( $id_buf [ 1 ])][ 'Image' ])) {
$distro = $list [ trim ( $id_buf [ 1 ])];
}
}
}
2025-05-14 16:14:01 +01:00
if (( $buf !== null ) && ( trim ( $buf ) !== " " )) {
$buf = preg_replace ( " / - Version:| Build:| Release| version| build/i " , " " , $buf );
}
2024-09-07 20:53:46 +10:00
if ( isset ( $distro [ 'Image' ])) {
$this -> sys -> setDistributionIcon ( $distro [ 'Image' ]);
}
if ( isset ( $distribution [ 'Name' ])) {
2025-05-14 16:14:01 +01:00
if (( $buf === null ) || ( trim ( $buf ) == " " )) {
2024-09-07 20:53:46 +10:00
$this -> sys -> setDistribution ( $distribution [ 'Name' ]);
} else {
$this -> sys -> setDistribution ( $distribution [ 'Name' ] . " " . trim ( $buf ));
}
} else {
2025-05-14 16:14:01 +01:00
if (( $buf === null ) || ( trim ( $buf ) == " " )) {
$this -> sys -> setDistribution ( preg_replace ( '/linux/' , 'Linux' , ucwords ( $section )));
2024-09-07 20:53:46 +10:00
} else {
$this -> sys -> setDistribution ( trim ( $buf ));
}
}
if ( isset ( $distribution [ 'Files2' ])) {
foreach ( preg_split ( " /;/ " , $distribution [ 'Files2' ], - 1 , PREG_SPLIT_NO_EMPTY ) as $filename2 ) {
if ( CommonFunctions :: fileexists ( $filename2 ) && CommonFunctions :: rfts ( $filename2 , $buf , 0 , 4096 , false )) {
2025-05-14 16:14:01 +01:00
if ( preg_match ( '/^majorversion="?([^"\r\n]+)/m' , $buf , $maj_buf )
&& preg_match ( '/^minorversion="?([^"\r\n]+)/m' , $buf , $min_buf )) {
2024-09-07 20:53:46 +10:00
$distr2 = $maj_buf [ 1 ] . '.' . $min_buf [ 1 ];
2025-05-14 16:14:01 +01:00
if ( preg_match ( '/^buildphase="?([^"\r\n]+)/m' , $buf , $pha_buf ) && ( $pha_buf [ 1 ] !== " 0 " )) {
2024-09-07 20:53:46 +10:00
$distr2 .= '.' . $pha_buf [ 1 ];
}
2025-05-14 16:14:01 +01:00
if ( preg_match ( '/^buildnumber="?([^"\r\n]+)/m' , $buf , $num_buf )) {
2024-09-07 20:53:46 +10:00
$distr2 .= '-' . $num_buf [ 1 ];
}
2025-05-14 16:14:01 +01:00
if ( preg_match ( '/^builddate="?([^"\r\n]+)/m' , $buf , $dat_buf )) {
2024-09-07 20:53:46 +10:00
$distr2 .= ' (' . $dat_buf [ 1 ] . ')' ;
}
$this -> sys -> setDistribution ( $this -> sys -> getDistribution () . " " . $distr2 );
2025-05-14 16:14:01 +01:00
} elseif ( preg_match ( '/^elive-codename:\s*([^\r\n]+)/m' , $buf , $cod_buf )
&& preg_match ( '/^elive-version:\s*([^\r\n]+)/m' , $buf , $ver_buf )) {
$this -> sys -> setDistribution ( $this -> sys -> getDistribution () . " " . trim ( $cod_buf [ 1 ]) . " " . trim ( $ver_buf [ 1 ]));
} elseif ( preg_match ( '/^VERSION=["\']?([^"\'\r\n]+)/im' , $buf , $vers_buf )
|| preg_match ( '/^VERSION_ID=["\']?([^"\'\r\n]+)/m' , $buf , $vers_buf )) {
$this -> sys -> setDistribution ( $this -> sys -> getDistribution () . " " . trim ( $vers_buf [ 1 ]));
} elseif ( preg_match ( '/^DISTRIB_ID=[\'"]?([^\'"\r\n]+)/m' , $buf , $id_buf )) {
if ( preg_match ( '/^DESCRIPTION="?([^"\r\n]+)/m' , $buf , $desc_buf )
&& ( trim ( $desc_buf [ 1 ]) != trim ( $id_buf [ 1 ]))) {
$this -> sys -> setDistribution ( trim ( $desc_buf [ 1 ]));
} else {
if ( isset ( $list [ strtolower ( trim ( $id_buf [ 1 ]))][ 'Name' ])) {
$this -> sys -> setDistribution ( trim ( $list [ strtolower ( trim ( $id_buf [ 1 ]))][ 'Name' ]));
} else {
$this -> sys -> setDistribution ( trim ( $id_buf [ 1 ]));
}
if ( preg_match ( '/^RELEASE="?([^"\r\n]+)/m' , $buf , $vers_buf ) || preg_match ( '/^DISTRIB_RELEASE=[\'"]?([^\'"\r\n]+)/m' , $buf , $vers_buf )) {
$this -> sys -> setDistribution ( $this -> sys -> getDistribution () . " " . trim ( $vers_buf [ 1 ]));
}
if ( preg_match ( '/^CODENAME="?([^"\r\n]+)/m' , $buf , $vers_buf )) {
$this -> sys -> setDistribution ( $this -> sys -> getDistribution () . " ( " . trim ( $vers_buf [ 1 ]) . " ) " );
}
}
2024-09-07 20:53:46 +10:00
} else {
$distr2 = trim ( substr ( $buf , 0 , strpos ( $buf , " \n " )));
2025-05-14 16:14:01 +01:00
if (( $distr2 !== null ) && ( $distr2 != " " )) {
2024-09-07 20:53:46 +10:00
$this -> sys -> setDistribution ( $this -> sys -> getDistribution () . " " . $distr2 );
}
}
break ;
}
}
}
break 2 ;
}
}
}
}
}
// if the distribution is still unknown
if ( $this -> sys -> getDistribution () == " Linux " ) {
2025-05-14 16:14:01 +01:00
if ( $_ignore_lsb_release ) { // if lsb_release was ignored
if ( $_Distrib !== " " ) $this -> sys -> setDistribution ( preg_replace ( " / - Version:| Build:| Release| version| build| based in Ubuntu/i " , " " , $_Distrib ));
if ( $_DistribIcon !== " " ) $this -> sys -> setDistributionIcon ( $_DistribIcon );
}
}
// if the distribution is still unknown
if ( $this -> sys -> getDistribution () == " Linux " ) {
if ((( defined ( 'PSI_EMU_PORT' ) && CommonFunctions :: executeProgram ( 'cat' , '/etc/os-release' , $buf , false ))
|| ( ! defined ( 'PSI_EMU_PORT' ) && CommonFunctions :: fileexists ( $filename = " /etc/os-release " ) && CommonFunctions :: rfts ( $filename , $buf , 0 , 4096 , false )))
&& ( preg_match ( '/^TAILS_VERSION_ID="?([^"\r\n]+)/m' , $buf , $tid_buf ) || preg_match ( '/^NAME=["\']?([^"\'\r\n]+)/m' , $buf , $id_buf ) || preg_match ( '/^DISTRIB_ID=["\']?([^"\'\r\n]+)/m' , $buf , $id_buf ))) {
if ( preg_match ( '/^TAILS_VERSION_ID="?([^"\r\n]+)/m' , $buf , $tid_buf )) {
if ( preg_match ( '/^TAILS_PRODUCT_NAME="?([^"\r\n]+)/m' , $buf , $desc_buf )) {
$this -> sys -> setDistribution ( trim ( $desc_buf [ 1 ]) . " " . trim ( $tid_buf [ 1 ]));
} else {
if ( isset ( $list [ 'tails' ][ 'Name' ])) {
$this -> sys -> setDistribution ( trim ( $list [ 'tails' ][ 'Name' ]) . " " . trim ( $tid_buf [ 1 ]));
} else {
$this -> sys -> setDistribution ( 'Tails' . " " . trim ( $tid_buf [ 1 ]));
}
}
$this -> sys -> setDistributionIcon ( $list [ 'tails' ][ 'Image' ]);
} else {
$addversion = false ;
$distrib = trim ( $id_buf [ 1 ]);
if ( preg_match ( '/^PRETTY_NAME=["\']?([^"\'\r\n]+)/m' , $buf , $desc_buf )
&& ! preg_match ( '/\$/' , $desc_buf [ 1 ]) // if is not defined by variable
&& ( $distrib !== trim ( $desc_buf [ 1 ]))) {
if ( isset ( $list [ strtolower ( $distrib )][ 'Name' ]) && ! preg_match ( " / " . $list [ strtolower ( $distrib )][ 'Name' ] . " /i " , trim ( $desc_buf [ 1 ]))) {
$this -> sys -> setDistribution ( $list [ strtolower ( $distrib )][ 'Name' ] . " " . preg_replace ( " / - Version:| Build:| Release| version| build| based in Ubuntu/i " , " " , trim ( $desc_buf [ 1 ])));
} else {
$this -> sys -> setDistribution ( preg_replace ( " / - Version:| Build:| Release| version| build| based in Ubuntu/i " , " " , trim ( $desc_buf [ 1 ])));
}
$distrib2 = $distrib ;
$distrib3 = $distrib ;
$distarr = preg_split ( " / \ s/ " , trim ( $desc_buf [ 1 ]), - 1 , PREG_SPLIT_NO_EMPTY );
if ( isset ( $distarr [ 0 ])) {
$distrib2 .= ' ' . $distarr [ 0 ];
}
if ( isset ( $distarr [ 1 ])) {
$distrib3 .= ' ' . $distarr [ 0 ] . ' ' . $distarr [ 1 ];
}
if (( $distrib !== $distrib3 ) && isset ( $list [ strtolower ( $distrib3 )][ 'Image' ])) {
$this -> sys -> setDistributionIcon ( $list [ strtolower ( $distrib3 )][ 'Image' ]);
if ( count ( $distarr ) == 2 ) {
$addversion = true ;
}
} elseif (( $distrib !== $distrib2 ) && isset ( $list [ strtolower ( $distrib2 )][ 'Image' ])) {
$this -> sys -> setDistributionIcon ( $list [ strtolower ( $distrib2 )][ 'Image' ]);
if ( count ( $distarr ) == 1 ) {
$addversion = true ;
}
} elseif (( $distrib !== " n/a " ) && isset ( $list [ strtolower ( $distrib )][ 'Image' ])) {
$this -> sys -> setDistributionIcon ( $list [ strtolower ( $distrib )][ 'Image' ]);
}
} else {
if ( isset ( $list [ strtolower ( $distrib )][ 'Name' ])) {
$this -> sys -> setDistribution ( trim ( $list [ strtolower ( $distrib )][ 'Name' ]));
} else {
$this -> sys -> setDistribution ( $distrib );
}
if ( isset ( $list [ strtolower ( $distrib )][ 'Image' ])) {
$this -> sys -> setDistributionIcon ( $list [ strtolower ( $distrib )][ 'Image' ]);
}
$addversion = true ;
}
if ( $addversion ) {
if ( preg_match ( '/^VERSION=["\']?([^"\'\r\n]+)/m' , $buf , $vers_buf )
|| preg_match ( '/^VERSION_ID=["\']?([^"\'\r\n]+)/m' , $buf , $vers_buf )
|| preg_match ( '/^DISTRIB_RELEASE=["\']?([^"\'\r\n]+)/m' , $buf , $vers_buf )
|| preg_match ( '/^IMAGE_VERSION=["\']?([^"\'\r\n]+)/m' , $buf , $vers_buf )) {
$this -> sys -> setDistribution ( $this -> sys -> getDistribution () . " " . trim ( $vers_buf [ 1 ]));
}
if ( ! strstr ( $this -> sys -> getDistribution (), " ( " ) && ( preg_match ( '/^VERSION_CODENAME="?([^"\r\n]+)/m' , $buf , $vers_buf )
|| preg_match ( '/^DISTRIB_CODENAME="?([^"\r\n]+)/m' , $buf , $vers_buf ))) {
$this -> sys -> setDistribution ( $this -> sys -> getDistribution () . " ( " . trim ( $vers_buf [ 1 ]) . " ) " );
}
}
}
} elseif ( CommonFunctions :: fileexists ( $filename = " /etc/DISTRO_SPECS " )
2024-09-07 20:53:46 +10:00
&& CommonFunctions :: rfts ( $filename , $buf , 0 , 4096 , false )
2025-05-14 16:14:01 +01:00
&& preg_match ( '/^DISTRO_NAME=["\']([^"\']+)/m' , $buf , $id_buf )) {
if ( isset ( $list [ strtolower ( trim ( $id_buf [ 1 ]))][ 'Name' ])) {
$dist = trim ( $list [ strtolower ( trim ( $id_buf [ 1 ]))][ 'Name' ]);
2024-09-07 20:53:46 +10:00
} else {
$dist = trim ( $id_buf [ 1 ]);
}
2025-05-14 16:14:01 +01:00
if ( preg_match ( '/^DISTRO_VERSION=([^$#\n\r]+)/m' , $buf , $vers_buf )) {
2024-09-07 20:53:46 +10:00
$this -> sys -> setDistribution ( trim ( $dist . " " . trim ( $vers_buf [ 1 ])));
} else {
$this -> sys -> setDistribution ( $dist );
}
2025-05-14 16:14:01 +01:00
if ( isset ( $list [ strtolower ( trim ( $id_buf [ 1 ]))][ 'Image' ])) {
$this -> sys -> setDistributionIcon ( $list [ strtolower ( trim ( $id_buf [ 1 ]))][ 'Image' ]);
2024-09-07 20:53:46 +10:00
} else {
2025-05-14 16:14:01 +01:00
if ( isset ( $list [ 'puppy' ][ 'Image' ])) {
$this -> sys -> setDistributionIcon ( $list [ 'puppy' ][ 'Image' ]);
if ( ! preg_match ( " /puppy/i " , $dist = $this -> sys -> getDistribution ())) {
$this -> sys -> setDistribution ( " Puppy " . $dist );
}
2024-09-07 20:53:46 +10:00
}
}
} elseif (( CommonFunctions :: fileexists ( $filename = " /etc/distro-release " )
&& CommonFunctions :: rfts ( $filename , $buf , 1 , 4096 , false )
2025-05-14 16:14:01 +01:00
&& ( $buf !== null ) && ( trim ( $buf ) != " " ))
2024-09-07 20:53:46 +10:00
|| ( CommonFunctions :: fileexists ( $filename = " /etc/system-release " )
&& CommonFunctions :: rfts ( $filename , $buf , 1 , 4096 , false )
2025-05-14 16:14:01 +01:00
&& ( $buf !== null ) && ( trim ( $buf ) != " " ))) {
$this -> sys -> setDistribution ( preg_replace ( " / - Version:| Build:| Release| version| build| based in Ubuntu/i " , " " , trim ( $buf )));
if ( preg_match ( '/^(\S+)\s*/' , preg_replace ( '/^red\s+/' , 'red' , strtolower ( $buf )), $id_buf )
2024-09-07 20:53:46 +10:00
&& isset ( $list [ trim ( $id_buf [ 1 ])][ 'Image' ])) {
$this -> sys -> setDistributionIcon ( $list [ trim ( $id_buf [ 1 ])][ 'Image' ]);
}
2025-05-14 16:14:01 +01:00
} elseif ( CommonFunctions :: fileexists ( $filename = " /etc/debian_version " )) {
if ( ! CommonFunctions :: rfts ( $filename , $buf , 1 , 4096 , false )) {
$buf = " " ;
2024-09-07 20:53:46 +10:00
}
2025-05-14 16:14:01 +01:00
if ( isset ( $list [ 'debian' ][ 'Image' ])) {
$this -> sys -> setDistributionIcon ( $list [ 'debian' ][ 'Image' ]);
2024-09-07 20:53:46 +10:00
}
2025-05-14 16:14:01 +01:00
if ( isset ( $list [ 'debian' ][ 'Name' ])) {
if (( $buf === null ) || ( trim ( $buf ) == " " )) {
$this -> sys -> setDistribution ( $list [ 'debian' ][ 'Name' ]);
2024-09-07 20:53:46 +10:00
} else {
2025-05-14 16:14:01 +01:00
$this -> sys -> setDistribution ( $list [ 'debian' ][ 'Name' ] . " " . trim ( $buf ));
2024-09-07 20:53:46 +10:00
}
} else {
2025-05-14 16:14:01 +01:00
if (( $buf === null ) || ( trim ( $buf ) == " " )) {
$this -> sys -> setDistribution ( 'Debian' );
2024-09-07 20:53:46 +10:00
} else {
2025-05-14 16:14:01 +01:00
$this -> sys -> setDistribution ( trim ( $buf ));
2024-09-07 20:53:46 +10:00
}
}
2025-05-14 16:14:01 +01:00
} elseif ( CommonFunctions :: fileexists ( $filename = " /etc/slackware-version " )) {
2024-09-07 20:53:46 +10:00
if ( ! CommonFunctions :: rfts ( $filename , $buf , 1 , 4096 , false )) {
$buf = " " ;
}
2025-05-14 16:14:01 +01:00
if ( isset ( $list [ 'slackware' ][ 'Image' ])) {
$this -> sys -> setDistributionIcon ( $list [ 'slackware' ][ 'Image' ]);
2024-09-07 20:53:46 +10:00
}
2025-05-14 16:14:01 +01:00
if ( isset ( $list [ 'slackware' ][ 'Name' ])) {
if (( $buf === null ) || ( trim ( $buf ) == " " )) {
$this -> sys -> setDistribution ( $list [ 'slackware' ][ 'Name' ]);
2024-09-07 20:53:46 +10:00
} else {
2025-05-14 16:14:01 +01:00
$this -> sys -> setDistribution ( $list [ 'slackware' ][ 'Name' ] . " " . trim ( $buf ));
2024-09-07 20:53:46 +10:00
}
} else {
2025-05-14 16:14:01 +01:00
if (( $buf === null ) || ( trim ( $buf ) == " " )) {
$this -> sys -> setDistribution ( 'Slackware' );
2024-09-07 20:53:46 +10:00
} else {
$this -> sys -> setDistribution ( trim ( $buf ));
}
}
2025-05-14 16:14:01 +01:00
} elseif ( CommonFunctions :: fileexists ( $filename = " /etc/config/uLinux.conf " )
&& CommonFunctions :: rfts ( $filename , $buf , 0 , 4096 , false )
&& preg_match ( " /^Rsync \ sModel \ s*= \ s*QNAP/m " , $buf )
&& preg_match ( " /^Version \ s*= \ s*([ \ d \ .]+) \r ? \n Build \ sNumber \ s*= \ s*( \ S+)/m " , $buf , $ver_buf )) {
$buf = $ver_buf [ 1 ] . " - " . $ver_buf [ 2 ];
if ( isset ( $list [ 'qts' ][ 'Image' ])) {
$this -> sys -> setDistributionIcon ( $list [ 'qts' ][ 'Image' ]);
}
if ( isset ( $list [ 'qts' ][ 'Name' ])) {
$this -> sys -> setDistribution ( $list [ 'qts' ][ 'Name' ] . " " . trim ( $buf ));
} else {
$this -> sys -> setDistribution ( trim ( $buf ));
}
2024-09-07 20:53:46 +10:00
}
}
/* restore error level */
error_reporting ( $old_err_rep );
/* restore error handler */
if ( function_exists ( 'errorHandlerPsi' )) {
set_error_handler ( 'errorHandlerPsi' );
}
}
}
/**
* Processes
*
* @ return void
*/
protected function _processes ()
{
2025-05-14 16:14:01 +01:00
$process = CommonFunctions :: findglob ( '/proc/*/status' , GLOB_NOSORT );
if ( is_array ( $process ) && (( $total = count ( $process )) > 0 )) {
2024-09-07 20:53:46 +10:00
$processes [ '*' ] = 0 ;
$buf = " " ;
for ( $i = 0 ; $i < $total ; $i ++ ) {
if ( CommonFunctions :: rfts ( $process [ $i ], $buf , 0 , 4096 , false )) {
2025-05-14 16:14:01 +01:00
$processes [ '*' ] ++ ; // current total
2024-09-07 20:53:46 +10:00
if ( preg_match ( '/^State:\s+(\w)/m' , $buf , $state )) {
if ( isset ( $processes [ $state [ 1 ]])) {
$processes [ $state [ 1 ]] ++ ;
} else {
$processes [ $state [ 1 ]] = 1 ;
}
}
}
}
if ( ! ( $processes [ '*' ] > 0 )) {
2025-05-14 16:14:01 +01:00
$processes [ '*' ] = $processes [ ' ' ] = $total ; // all unknown
2024-09-07 20:53:46 +10:00
}
$this -> sys -> setProcesses ( $processes );
}
}
/**
* get the information
*
* @ see PSI_Interface_OS :: build ()
*
2025-05-14 16:14:01 +01:00
* @ return void
2024-09-07 20:53:46 +10:00
*/
public function build ()
{
2025-05-14 16:14:01 +01:00
if ( ! $this -> blockname || $this -> blockname === 'vitals' ) {
$this -> _distro ();
$this -> _hostname ();
$this -> _kernel ();
$this -> _uptime ();
$this -> _users ();
$this -> _loadavg ();
$this -> _processes ();
}
if ( ! $this -> blockname || $this -> blockname === 'hardware' ) {
$this -> _machine ();
$this -> _cpuinfo ();
$this -> _virtualizer ();
$this -> _pci ();
$this -> _ide ();
$this -> _scsi ();
$this -> _nvme ();
$this -> _usb ();
$this -> _i2c ();
}
if ( ! $this -> blockname || $this -> blockname === 'memory' ) {
$this -> _memory ();
}
if ( ! $this -> blockname || $this -> blockname === 'filesystem' ) {
$this -> _filesystems ();
}
if ( ! $this -> blockname || $this -> blockname === 'network' ) {
$this -> _network ();
}
2024-09-07 20:53:46 +10:00
}
}