!C99Shell v. 2.5 [PHP 8 Update] [24.05.2025]!

Software: Apache/2.4.41 (Ubuntu). PHP/8.0.30 

uname -a: Linux apirnd 5.4.0-204-generic #224-Ubuntu SMP Thu Dec 5 13:38:28 UTC 2024 x86_64 

uid=33(www-data) gid=33(www-data) groups=33(www-data) 

Safe-mode: OFF (not secure)

/var/www/html/billing/sysinfo/lib/   drwxr-xr-x
Free 13.23 GB of 57.97 GB (22.82%)
Home    Back    Forward    UPDIR    Refresh    Search    Buffer    Encoder    Tools    Proc.    FTP brute    Sec.    SQL    PHP-code    Update    Self remove    Logout    


Viewing file:     class.OS_Linux.php (37.24 KB)      -rw-r--r--
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
<?php

/**
 * This file is part of Linfo (c) 2010 Joseph Gillotti.
 * 
 * Linfo is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * Linfo is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with Linfo.  If not, see <http://www.gnu.org/licenses/>.
*/

/**
 * Keep out hackers...
 */
defined('IN_INFO') or exit;

/**
 * Get info on a usual linux system
 * Works by exclusively looking around /proc and /sys
 * Totally ignores CallExt class, very deliberately
 * Also deliberately ignores trying to find out the distro. 
 */
class OS_Linux {

    
// Keep these tucked away
    
protected
        
$settings$error;

    
/**
     * Constructor. Localizes settings
     * 
     * @param array $settings of linfo settings
     * @access public
     */
    
public function __construct($settings) {

        
// Localize settings
        
$this->settings $settings;

        
// Localize error handler
        
$this->error LinfoError::Fledging();

        
// Make sure we have what we need
        
if (!is_dir('/sys') || !is_dir('/proc'))
            throw new 
GetInfoException('This needs access to /proc and /sys to work.');
    }

    
/**
     * getAll 
     * 
     * @access public
     * @return array the info
     */
    
public function getAll() {

        
// Return everything, whilst obeying display permissions
        
return array(
            
'OS' => empty($this->settings['show']['os']) ? '' $this->getOS(),
            
'Kernel' => empty($this->settings['show']['kernel']) ? '' $this->getKernel(),
            
'Distro' => empty($this->settings['show']['distro']) ? '' $this->getDistro(),
            
'RAM' => empty($this->settings['show']['ram']) ? array() : $this->getRam(),
            
'HD' => empty($this->settings['show']['hd']) ? '' $this->getHD(),
            
'Mounts' => empty($this->settings['show']['mounts']) ? array() : $this->getMounts(),
            
'Load' => empty($this->settings['show']['load']) ? array() : $this->getLoad(),
            
'HostName' => empty($this->settings['show']['hostname']) ? '' $this->getHostName(),
            
'UpTime' => empty($this->settings['show']['uptime']) ? '' $this->getUpTime(),
            
'CPU' => empty($this->settings['show']['cpu']) ? array() : $this->getCPU(),
            
'CPUArchitecture' => empty($this->settings['show']['cpu']) ? array() : $this->getCPUArchitecture(),
            
'Network Devices' => empty($this->settings['show']['network']) ? array() : $this->getNet(),
            
'Devices' => empty($this->settings['show']['devices']) ? array() : $this->getDevs(),
            
'Temps' => empty($this->settings['show']['temps']) ? array(): $this->getTemps(),
            
'Battery' => empty($this->settings['show']['battery']) ? array(): $this->getBattery(),
            
'Raid' => empty($this->settings['show']['raid']) ? array(): $this->getRAID(),
            
'Wifi' => empty($this->settings['show']['wifi']) ? array(): $this->getWifi(),
            
'SoundCards' => empty($this->settings['show']['sound']) ? array(): $this->getSoundCards(),
            
'processStats' => empty($this->settings['show']['process_stats']) ? array() : $this->getProcessStats(),
            
'services' => empty($this->settings['show']['process_stats']) ? array() : $this->getServices(),
            
'numLoggedIn' => empty($this->settings['show']['numLoggedIn']) ? array() : $this->getNumLoggedIn()
        );
    }

    
/**
     * getOS 
     * 
     * @access private
     * @return string Linux
     */
    
private function getOS() {
        
        
// Linux, obviously
        
return 'Linux';
    }

    
/**
     * getKernel 
     * 
     * @access private
     * @return string kernel version
     */
    
private function getKernel() {
        
        
// Time?
        
if (!empty($this->settings['timer']))
            
$t = new LinfoTimerStart('Kernel');

        
// File containing info
        
$file '/proc/version';

        
// Make sure we can use it
        
if (!is_file($file) || !is_readable($file)) {
            
$this->error->add('Linfo Core''/proc/version not found');
            return 
'Unknown';
        }

        
// Get it
        
$contents getContents($file);

        
// Parse it
        
if (preg_match('/^Linux version (\S+).+$/'$contents$match) != 1) {
            
$this->error->add('Linfo Core''Error parsing /proc/version');
            return 
'Unknown';
        }

        
// Return it
        
return $match[1];
    }

    
/**
     * getHostName 
     * 
     * @access private
     * @return string the host name
     */
    
private function getHostName() {
        
        
// Time?
        
if (!empty($this->settings['timer']))
            
$t = new LinfoTimerStart('Hostname');

        
// File containing info
        
$file '/proc/sys/kernel/hostname';
        
        
// Get it
        
$hostname getContents($filefalse);

        
// Failed?
        
if ($hostname === false) {
            
$this->error->add('Linfo Core''Error getting /proc/sys/kernel/hostname');
            return 
'Unknown';
        }
        else {

            
// Didn't fail; return it
            
return $hostname;
        }
    }

    
/**
     * getRam 
     * 
     * @access private
     * @return array the memory information
     */
    
private function getRam(){
        
        
// Time?
        
if (!empty($this->settings['timer']))
            
$t = new LinfoTimerStart('Memory');

        
// We'll return the contents of this
        
$return = array();

        
// Files containing juicy info
        
$procFileSwap '/proc/swaps';
        
$procFileMem '/proc/meminfo';

        
// First off, these need to exist..
        
if (!is_readable($procFileSwap) || !is_readable($procFileMem)) {
            
$this->error->add('Linfo Core''/proc/swaps and/or /proc/meminfo are not readable');
            return array();
        }

        
// To hold their values
        
$memVals = array();
        
$swapVals = array();

        
// Get memContents
        
@preg_match_all('/^([^:]+)\:\s+(\d+)\s*(?:k[bB])?\s*/m'getContents($procFileMem), $matchesPREG_SET_ORDER);

        
// Deal with it
        
foreach ((array)$matches as $memInfo)
            
$memVals[$memInfo[1]] = $memInfo[2];

        
// Get swapContents
        
@preg_match_all('/^(\S+)\s+(\S+)\s+(\d+)\s(\d+)/m'getContents($procFileSwap), $matchesPREG_SET_ORDER);
        foreach ((array)
$matches as $swapDevice) {
            
            
// Append each swap device
            
$swapVals[] = array (
                
'device' => $swapDevice[1],
                
'type' => $swapDevice[2],
                
'size' => $swapDevice[3]*1024,
                
'used' => $swapDevice[4]*1024
            
);
        }

        
// Get individual vals
        
$return['type'] = 'Physical';
        
$return['total'] = $memVals['MemTotal']*1024;
        
$return['free'] = $memVals['MemFree']*1024 $memVals['Cached']*1024$memVals['Buffers']*1024;
        
$return['swapTotal'] = $memVals['SwapTotal']*1024;
        
$return['swapFree'] = $memVals['SwapFree']*1024 $memVals['SwapCached']*1024;
        
$return['swapCached'] = $memVals['SwapCached']*1024;
        
$return['swapInfo'] = $swapVals;

        
// Return it
        
return $return;
    }

    
/**
     * getCPU 
     * 
     * @access private
     * @return array of cpu info
     */
    
private function getCPU() {
        
        
// Time?
        
if (!empty($this->settings['timer']))
            
$t = new LinfoTimerStart('CPUs');

        
// File that has it
        
$file '/proc/cpuinfo';

        
// Not there?
        
if (!is_file($file) || !is_readable($file)) {
            
$this->error->add('Linfo Core''/proc/cpuinfo not readable');
            return array();
        }

        
/*
         * Get all info for all CPUs from the cpuinfo file
         */

        // Get contents
        
$contents trim(@file_get_contents($file));

        
// Lines
        
$lines explode("\n"$contents);

        
// Store CPUs here
        
$cpus = array();

        
// Holder for current CPU info
        
$cur_cpu = array();

        
// Go through lines in file
        
$num_lines count($lines);
        
        
// We use the key of the first line to separate CPUs
        
$first_line substr($lines[0], 0strpos($lines[0], ' '));
        
        for (
$i 0$i $num_lines$i++) {
            
            
// Approaching new CPU? Save current and start new info for this
            
if (strpos($lines[$i], $first_line) === && count($cur_cpu) > 0) {
                
$cpus[] = $cur_cpu;
                
$cur_cpu = array();
                
                
// Default to unknown
                
$cur_cpu['Model'] = 'Unknown';
            }

            
// Info here
            
$line explode(':'$lines[$i], 2);

            if (!
array_key_exists(1$line))
                continue;

            
$key trim($line[0]);
            
$value trim($line[1]);

            
            
// What we want are MHZ, Vendor, and Model.
            
switch ($key) {
                
                
// CPU model
                
case 'model name':
                case 
'cpu':
                case 
'Processor':
                    
$cur_cpu['Model'] = $value;
                break;

                
// Speed in MHz
                
case 'cpu MHz':
                    
$cur_cpu['MHz'] = $value;
                break;

                case 
'Cpu0ClkTck'// Old sun boxes
                    
$cur_cpu['MHz'] = hexdec($value) / 1000000;
                break;

                
// Brand/vendor
                
case 'vendor_id':
                    
$cur_cpu['Vendor'] = $value;
                break;
            }

        }

        
// Save remaining one
        
if (count($cur_cpu) > 0)
            
$cpus[] = $cur_cpu;

        
// Return them
        
return $cpus;
    }

    
// Famously interesting uptime
    
private function getUpTime () {
        
        
// Time?
        
if (!empty($this->settings['timer']))
            
$t = new LinfoTimerStart('Uptime');

        
// Get contents
        
$contents getContents('/proc/uptime'false);

        
// eh?
        
if ($contents === false) {
            
$this->error->add('Linfo Core''/proc/uptime does not exist.');
            return 
'Unknown';
        }

        
// Seconds
        
list($seconds) = explode(' '$contents1);

        
// Get it textual, as in days/minutes/hours/etc
        
$uptime seconds_convert(ceil($seconds));

        
// Now find out when the system was booted
        
$contents getContents('/proc/stat'false);

        
// Ugh
        
if ($contents === false)
            return 
$uptime// Settle for just uptime

        // Get date of boot
        
if (preg_match('/^btime (\d+)$/m'$contents$boot) != 1)
            return 
$uptime;

        
// Okay?
        
list(, $boot) = $boot;

        
// Return
        
return $uptime '; booted '.date($this->settings['dates'], $boot);
    }

    
/**
     * getHD 
     * 
     * @access private
     * @return array the hard drive info
     */
    
private function getHD() {
        
        
// Time?
        
if (!empty($this->settings['timer']))
            
$t = new LinfoTimerStart('Drives');

        
// Get partitions
        
$partitions = array();
        
$partitions_contents getContents('/proc/partitions');
        if (@
preg_match_all('/(\d+)\s+([a-z]{3})(\d+)$/m'$partitions_contents$partitions_matchPREG_SET_ORDER) > 0) {
            
// Go through each match
            
$num_partitions count($partitions_match);
            for (
$i 0$i $num_partitions$i++) {
                
$partition $partitions_match[$i];
                
$partitions[$partition[2]][] = array(
                    
'size' => $partition[1] * 1024,
                    
'number' => $partition[3]
                );
            }
        }
        
        
// Store drives here
        
$drives = array();
        
        
// Get actual drives
        
$drive_paths = (array) @glob('/sys/block/*/device/model'GLOB_NOSORT);
        
$num_drives count($drive_paths);
        for (
$i 0$i $num_drives$i++) {
            
            
// Path
            
$path $drive_paths[$i];

            
// Dirname of the drive's sys entry
            
$dirname dirname(dirname($path));

            
// Parts of the path
            
$parts explode('/'$path);

            
// Attempt getting read/write stats
            
if (preg_match('/^(\d+)\s+\d+\s+\d+\s+\d+\s+(\d+)\s+\d+\s+\d+\s+\d+\s+\d+\s+\d+\s+\d+$/'getContents(dirname(dirname($path)).'/stat'), $statMatches) !== 1) {
                
// Didn't get it
                
$reads false;
                
$writes false;
            }
            else
                
// Got it, save it
                
list(, $reads$writes) = $statMatches;

            
// Append this drive on
            
$drives[] = array(
                
'name' =>  getContents($path'Unknown'),
                
'vendor' => getContents(dirname($path).'/vendor''Unknown'),
                
'device' => '/dev/'.$parts[3],
                
'reads' => $reads,
                
'writes' => $writes,
                
'size' => getContents(dirname(dirname($path)).'/size'0) * 512,
                
'partitions' => array_key_exists($parts[3], $partitions) && is_array($partitions[$parts[3]]) ? $partitions[$parts[3]] : false 
            
);
        }

        
// Return drives
        
return $drives;
    }

    
/**
     * getTemps 
     * 
     * @access private
     * @return array the temps
     */
    
private function getTemps() {
    
        
// Time?
        
if (!empty($this->settings['timer']))
            
$t = new LinfoTimerStart('Temperature');

        
// Hold them here
        
$return = array();

        
// hddtemp?
        
if (array_key_exists('hddtemp', (array)$this->settings['temps']) && !empty($this->settings['temps']['hddtemp'])) {
            try {
                
// Initiate class
                
$hddtemp = new GetHddTemp($this->settings);

                
// Set mode, as in either daemon or syslog
                
$hddtemp->setMode($this->settings['hddtemp']['mode']);

                
// If we're daemon, save host and port
                
if ($this->settings['hddtemp']['mode'] == 'daemon') {
                    
$hddtemp->setAddress(
                        
$this->settings['hddtemp']['address']['host'],
                        
$this->settings['hddtemp']['address']['port']);
                }

                
// Result after working it
                
$hddtemp_res $hddtemp->work();

                
// If it's an array, it worked
                
if (is_array($hddtemp_res))
                    
// Save result
                    
$return array_merge($return$hddtemp_res);

            }

            
// There was an issue
            
catch (GetHddTempException $e) {
                
$this->error->add('hddtemp parser'$e->getMessage());
            }
        }

        
// mbmon?
        
if (array_key_exists('mbmon', (array)$this->settings['temps']) && !empty($this->settings['temps']['mbmon'])) {
            try {
                
// Initiate class
                
$mbmon = new GetMbMon;

                
// Set host and port
                
$mbmon->setAddress(
                    
$this->settings['mbmon']['address']['host'],
                    
$this->settings['mbmon']['address']['port']);

                
// Get result after working it
                
$mbmon_res $mbmon->work();

                
// If it's an array, it worked
                
if (is_array($mbmon_res))
                    
// Save result
                    
$return array_merge($return$mbmon_res);
            }
            catch (
GetMbMonException $e) {
                
$this->error->add('mbmon parser'$e->getMessage());
            }
        }

        
// sensord? (part of lm-sensors)
        
if (array_key_exists('sensord', (array)$this->settings['temps']) && !empty($this->settings['temps']['sensord'])) {
            try {
                
// Iniatate class
                
$sensord = new GetSensord;

                
// Work it
                
$sensord_res $sensord->work();

                
// If it's an array, it worked
                
if (is_array($sensord_res))
                    
// Save result
                    
$return array_merge($return$sensord_res);
            }
            catch (
GetSensordException $e) {
                
$this->error->add('sensord parser'$e->getMessage());
            }
        }

        
// hwmon? (probably the fastest of what's here)
        // too simple to be in its own class
        
if (array_key_exists('hwmon', (array)$this->settings['temps']) && !empty($this->settings['temps']['hwmon'])) {

            
// Store them here
            
$hwmon_vals = array();

            
// Wacky location
            
$hwmon_paths = (array) @glob('/sys/class/hwmon/hwmon*/*_label'GLOB_NOSORT);
            
$num_paths count($hwmon_paths);
            for (
$i 0$i $num_paths$i++) {

                
// The path
                
$path $hwmon_paths[$i];

                
// Get info here
                
$section rtrim($path'label');
                
$filename basename($path);
                
$label getContents($path);
                
$value getContents($section.'input');

                
// Determine units and possibly fix values
                
if (strpos($filename'fan') !== false)
                    
$unit 'RPM';
                elseif (
strpos($filename'temp') !== false) {
                    
$unit 'C';  // Always seems to be in celsius
                    
$value strlen($value) == substr($value02) : $value;  // Pointless extra 0's
                
}
                elseif (
preg_match('/^in\d_label$/'$filename)) {
                    
$unit 'v'
                }
                else 
                    
$unit ''// Not sure if there's a temp

                // Append values
                
$hwmon_vals[] = array(
                    
'path' => 'N/A',
                    
'name' => $label,
                    
'temp' => $value,
                    
'unit' => $unit
                
);
            }
            
            
// Save any if we have any
            
if (count($hwmon_vals) > 0)
                
$return array_merge($return$hwmon_vals);
        }

        
// Additional weird bullshit? In this case, laptop backlight percentage. lolwtf, right?
        
foreach ((array) @glob('/sys/{devices/virtual,class}/backlight/*/max_brightness'GLOB_NOSORT GLOB_BRACE) as $bl) {
            
$dir dirname($bl);
            if (!
is_file($dir.'/actual_brightness'))
                continue;
            
$max get_int_from_file($bl);
            
$cur get_int_from_file($dir.'/actual_brightness');
            if (
$max || $cur 0)
                continue;
            
$return[] = array(
                
'name' => 'Backlight brightness',
                
'temp' => round($cur/$max2)*100,
                
'unit' => '%',
                
'path' => 'N/A',
                
'bar' => true
            
);
        }

        
// Done
        
return $return;
    }

    
/**
     * getMounts 
     * 
     * @access private
     * @return array the mounted the file systems
     */
    
private function getMounts() {
        
        
// Time?
        
if (!empty($this->settings['timer']))
            
$t = new LinfoTimerStart('Mounted file systems');

        
// File
        
$contents getContents('/proc/mounts'false);

        
// Can't?
        
if ($contents == false)
            
$this->error->add('Linfo Core''/proc/mounts does not exist');

        
// Parse
        
if (@preg_match_all('/^(\S+) (\S+) (\S+) (.+) \d \d$/m'$contents$matchPREG_SET_ORDER) === false)
            
$this->error->add('Linfo Core''Error parsing /proc/mounts');

        
// Return these
        
$mounts = array();

        
// Populate
        
$num_matches count($match);
        for (
$i 0$i $num_matches$i++) {

            
// This mount
            
$mount $match[$i];
            
            
// Should we not show this?
            
if (in_array($mount[1], $this->settings['hide']['storage_devices']) || in_array($mount[3], $this->settings['hide']['filesystems']))
                continue;
            
            
// Spaces and other things in the mount path are escaped C style. Fix that.
            
$mount[2] = stripcslashes($mount[2]);
            
            
// Get these
            
$size = @disk_total_space($mount[2]);
            
$free = @disk_free_space($mount[2]);
            
$used $size != false && $free != false $size $free false;

            
// If it's a symlink, find out where it really goes.
            // (using realpath instead of readlink because the former gives absolute paths)
            
$symlink is_link($mount[1]) ? realpath($mount[1]) : false;
            
            
// Optionally get mount options
            
if ($this->settings['show']['mounts_options'] && !in_array($mount[3], (array) $this->settings['hide']['fs_mount_options'])) 
                
$mount_options explode(','$mount[4]);
            else 
                
$mount_options = array();

            
// Might be good, go for it
            
$mounts[] = array(
                
'device' => $symlink != false $symlink $mount[1],
                
'mount' => $mount[2],
                
'type' => $mount[3],
                
'size' => $size,
                
'used' => $used,
                
'free' => $free,
                
'free_percent' => ((bool)$free != false && (bool)$size != false round($free $size2) * 100 false),
                
'used_percent' => ((bool)$used != false && (bool)$size != false round($used $size2) * 100 false),
                
'options' => $mount_options
            
);
        }

        
// Return
        
return $mounts;
    }

    
/**
     * getDevs 
     * 
     * @access private
     * @return array of devices
     */
    
private function getDevs() {
        
        
// Time?
        
if (!empty($this->settings['timer']))
            
$t = new LinfoTimerStart('Hardware Devices');

        
// Location of useful paths
        
$pci_ids locate_actual_path(array(
            
'/usr/share/misc/pci.ids',    // debian/ubuntu
            
'/usr/share/pci.ids',        // opensuse
            
'/usr/share/hwdata/pci.ids',    // centos. maybe also redhat/fedora
        
));
        
$usb_ids locate_actual_path(array(
            
'/usr/share/misc/usb.ids',    // debian/ubuntu
            
'/usr/share/usb.ids',        // opensuse
            
'/usr/share/hwdata/usb.ids',    // centos. maybe also redhat/fedora
        
));

        
// Did we not get them?
        
$pci_ids || $this->error->add('Linux Device Finder''Cannot find pci.ids; ensure pciutils is installed.');
        
$usb_ids || $this->error->add('Linux Device Finder''Cannot find usb.ids; ensure usbutils is installed.');

        
// Class that does it
        
$hw = new HW_IDS($usb_ids$pci_ids);
        
$hw->work('linux');
        return 
$hw->result();
    }

    
/**
     * getRAID 
     * 
     * @access private
     * @return array of raid arrays
     */
    
private function getRAID() {
        
        
// Time?
        
if (!empty($this->settings['timer']))
            
$t = new LinfoTimerStart('RAID');
        
        
// Store it here
        
$raidinfo = array();

        
// mdadm?
        
if (array_key_exists('mdadm', (array)$this->settings['raid']) && !empty($this->settings['raid']['mdadm'])) {

            
// Try getting contents
            
$mdadm_contents getContents('/proc/mdstat'false);

            
// No?
            
if ($mdadm_contents === false)
                
$this->error->add('Linux softraid mdstat parser''/proc/mdstat does not exist.');

            
// Parse
            
@preg_match_all('/(\S+)\s*:\s*(\w+)\s*raid(\d+)\s*([\w+\[\d+\] (\(\w\))?]+)\n\s+(\d+) blocks\s*(?:super \d\.\d\s*)?(level \d\, [\w\d]+ chunk\, algorithm \d\s*)?\[(\d\/\d)\] \[([U\_]+)\]/mi', (string) $mdadm_contents$matchPREG_SET_ORDER);

            
// Store them here
            
$mdadm_arrays = array();

            
// Deal with entries
            
foreach ((array) $match as $array) {
                
                
// Temporarily store drives here
                
$drives = array();

                
// Parse drives
                
foreach (explode(' '$array[4]) as $drive) {

                    
// Parse?
                    
if(preg_match('/([\w\d]+)\[\d+\](\(\w\))?/'$drive$match_drive) == 1) {

                        
// Determine a status other than normal, like if it failed or is a spare
                        
if (array_key_exists(2$match_drive)) {
                            switch (
$match_drive[2]) {
                                case 
'(S)':
                                    
$drive_state 'spare';
                                break;
                                case 
'(F)':
                                    
$drive_state 'failed';
                                break;
                                case 
null:
                                    
$drive_state 'normal';
                                break;

                                
// I'm not sure if there are status codes other than the above
                                
default:
                                    
$drive_state 'unknown';
                                break;
                            }
                        }
                        else
                            
$drive_state 'normal';

                        
// Append this drive to the temp drives array
                        
$drives[] = array(
                            
'drive' => '/dev/'.$match_drive[1],
                            
'state' => $drive_state
                        
);
                    }
                }

                
// Add record of this array to arrays list
                
$mdadm_arrays[] = array(
                    
'device' => '/dev/'.$array[1],
                    
'status' => $array[2],
                    
'level' => $array[3],
                    
'drives' => $drives,
                    
'size' =>  byte_convert($array[5]*1024),
                    
'algorithm' => $array[6],
                    
'count' => $array[7],
                    
'chart' => $array[8]
                );
            }

            
// Append MD arrays to main raidinfo if it's good
            
if (is_array($mdadm_arrays) && count($mdadm_arrays) > )
                
$raidinfo array_merge($raidinfo$mdadm_arrays);
        }

        
// Return info
        
return $raidinfo;
    }

    
/**
     * getLoad 
     * 
     * @access private
     * @return array of current system load values
     */
    
private function getLoad() {
        
        
// Time?
        
if (!empty($this->settings['timer']))
            
$t = new LinfoTimerStart('Load Averages');

        
// File that has it
        
$file '/proc/loadavg';

        
// Get contents
        
$contents getContents($filefalse);

        
// ugh
        
if ($contents === false) {
            
$this->error->add('Linfo Core''/proc/loadavg unreadable');
            return array();
        }

        
// Parts
        
$parts explode(' '$contents);

        
// Return array of info
        
return array(
            
'now' => $parts[0],
            
'5min' => $parts[1],
            
'15min' => $parts[2]
        );
    }

    
/**
     * getNet 
     * 
     * @access private
     * @return array of network devices
     */
    
private function getNet() {
        
        
// Time?
        
if (!empty($this->settings['timer']))
            
$t = new LinfoTimerStart('Network Devices');

        
// Hold our return values
        
$return = array();

        
// Use glob to get paths
        
$nets = (array) @glob('/sys/class/net/*'GLOB_NOSORT);

        
// Get values for each device
        
$num_nets count($nets);
        for (
$i 0$i $num_nets$i++) {
            
            
// Path
            
$path $nets[$i];

            
// States
            
$operstate_contents getContents($path.'/operstate');
            switch (
$operstate_contents) {
                case 
'down':
                case 
'up':
                case 
'unknown':
                    
$state $operstate_contents;
                break;

                default:
                    
$state 'unknown';
                break;
            }

            
// motherfucker
            
if ($state 'unknown' && file_exists($path.'/carrier')) {
                 
$carrier getContents($path.'/carrier'false);
                if (!empty(
$carrier)) 
                    
$state 'up'
                else
                    
$state 'down'
            }

            
// Type
            
$type_contents strtoupper(getContents($path.'/device/modalias'));
            list(
$type) = explode(':'$type_contents2);
            
$type $type != 'USB' && $type != 'PCI' 'N/A' $type;

            
// Save and get info for each
            
$return[basename($path)] = array(

                
// Stats are stored in simple files just containing the number
                
'recieved' => array(
                    
'bytes' => get_int_from_file($path.'/statistics/rx_bytes'),
                    
'errors' => get_int_from_file($path.'/statistics/rx_errors'),
                    
'packets' => get_int_from_file($path.'/statistics/rx_packets')
                ),
                
'sent' => array(
                    
'bytes' => get_int_from_file($path.'/statistics/tx_bytes'),
                    
'errors' => get_int_from_file($path.'/statistics/tx_errors'),
                    
'packets' => get_int_from_file($path.'/statistics/rx_packets')
                ),

                
// These were determined above
                
'state' => $state,
                
'type' => $type
            
);
        }

        
// Return array of info
        
return $return;
    }

    
/**
     * getBattery 
     * 
     * @access private
     * @return array of battery status
     */
    
private function getBattery() {
        
        
// Time?
        
if (!empty($this->settings['timer']))
            
$t = new LinfoTimerStart('Batteries');
        
        
// Return values
        
$return = array();

        
// Here they should be
        
$bats = (array) @glob('/sys/class/power_supply/BAT*'GLOB_NOSORT);
    
        
// Get vals for each battery
        
foreach ($bats as $b) {

            
$go_for_it true;

            
// Fuck pointless cuntshit
            
foreach(array($b.'/manufacturer'$b.'/status'$b.'/charge_now') as $f)
                if (!
is_file($f))
                    
$go_for_it false// Continue out of two nested loops

            
if (!$go_for_it
                continue;

            
// Get these from the simple text files
            
$charge_full get_int_from_file($b.'/charge_full');
            
$charge_now get_int_from_file($b.'/charge_now');

            
// Alleged percentage
            
$percentage $charge_now != && $charge_full != ? (round($charge_now $charge_full4) * 100) : '?';

            
// Save result set
            
$return[] = array(
                
'charge_full' => $charge_full,
                
'charge_now' => $charge_now,
                
'percentage' => (is_numeric($percentage) && $percentage 100 100 $percentage ).'%',
                
'device' => getContents($b.'/manufacturer') . ' ' getContents($b.'/model_name''Unknown'),
                
'state' => getContents($b.'/status''Unknown')
            );
        }

        
// Give it
        
return $return;
    }

    
/**
     * getWifi 
     * 
     * @access private
     * @return array of wifi devices
     */
    
private function getWifi() {
        
        
// Time?
        
if (!empty($this->settings['timer']))
            
$t = new LinfoTimerStart('Wifi');

        
// Return these
        
$return = array();

        
// In here
        
$contents getContents('/proc/net/wireless');

        
// Oi
        
if ($contents == false) {
            
$this->error->add('Linux WiFi info parser''/proc/net/wireless does not exist');
            return 
$return;
        }

        
// Parse
        
@preg_match_all('/^ (\S+)\:\s*(\d+)\s*(\S+)\s*(\S+)\s*(\S+)\s*(\d+)\s*(\d+)\s*(\d+)\s*(\d+)\s*(\d+)\s*(\d+)\s*$/m'$contents$matchPREG_SET_ORDER);
        
        
// Match
        
foreach ($match as $wlan) {
            
$return[] = array(
                
'device' => $wlan[1],
                
'status' => $wlan[2],
                
'quality_link' => $wlan[3],
                
'quality_level' => $wlan[4],
                
'quality_noise' => $wlan[5],
                
'dis_nwid' => $wlan[6],
                
'dis_crypt' => $wlan[7],
                
'dis_frag' => $wlan[8],
                
'dis_retry' => $wlan[9],
                
'dis_misc' => $wlan[10],
                
'mis_beac' => $wlan[11]
            );
        }

        
// Done
        
return $return;
    }

    
/**
     * getSoundCards 
     * 
     * @access private
     * @return array of soundcards
     */
    
private function getSoundCards() {
        
        
// Time?
        
if (!empty($this->settings['timer']))
            
$t = new LinfoTimerStart('Sound cards');

        
// This should be it
        
$file '/proc/asound/cards';

        
// eh?
        
if (!is_file($file)) {
            
$this->error->add('Linux sound card detector''/proc/asound/cards does not exist');
        }

        
// Get contents and parse
        
$contents getContents($file);

        
// Parse
        
if (preg_match_all('/^\s*(\d+)\s\[[\s\w]+\]:\s(.+)$/m'$contents$matchesPREG_SET_ORDER) == 0)
            return array();

        
// eh?
        
$cards = array();

        
// Deal with results
        
foreach ($matches as $card)    
            
$cards[] = array(
                
'number' => $card[1],
                
'card' => $card[2],
            );

        
// Give cards
        
return $cards;
    }

    
/**
     * getProcessStats 
     * 
     * @access private
     * @return array of process stats
     */
    
private function getProcessStats() {
        
        
// Time?
        
if (!empty($this->settings['timer']))
            
$t = new LinfoTimerStart('Process Stats');

        
// We'll return this after stuffing it with useful info
        
$result = array(
            
'exists' => true
            
'totals' => array(
                
'running' => 0,
                
'zombie' => 0,
                
'sleeping' => 0,
                
'stopped' => 0,
            ),
            
'proc_total' => 0,
            
'threads' => 0
        
);
        
        
// Get all the paths to each process' status file
        
$processes = (array) @glob('/proc/*/status'GLOB_NOSORT);

        
// Total
        
$result['proc_total'] = count($processes);

        
// Go through each
        
for ($i 0$i $result['proc_total']; $i++) {
            
            
// Don't waste time if we can't use it
            
if (!is_readable($processes[$i]))
                continue;
            
            
// Get that file's contents
            
$status_contents getContents($processes[$i]);

            
// Try getting state
            
@preg_match('/^State:\s+(\w)/m'$status_contents$state_match);

            
// Well? Determine state
            
switch ($state_match[1]) {
                case 
'D'// disk sleep? wtf?
                
case 'S':
                    
$result['totals']['sleeping']++;
                break;
                case 
'Z':
                    
$result['totals']['zombie']++;
                break;
                case 
'R':
                    
$result['totals']['running']++;
                break;
                case 
'T':
                    
$result['totals']['stopped']++;
                break;
            }

            
// Try getting number of threads
            
@preg_match('/^Threads:\s+(\d+)/m'$status_contents$threads_match);

            
// Well?
            
if ($threads_match)
                list(, 
$threads) = $threads_match;

            
// Append it on if it's good
            
if (is_numeric($threads))
                
$result['threads'] = $result['threads'] + $threads;
        }

        
// Give off result
        
return $result;
    }

    
/**
     * getServices 
     * 
     * @access private
     * @return array the services
     */
    
private function getServices() {
        
        
// Time?
        
if (!empty($this->settings['timer']))
            
$t = new LinfoTimerStart('Services');

        
// We allowed?
        
if (!empty($settings['show']['services']) || !is_array($this->settings['services']) || count($this->settings['services']) == 0)
            return array();

        
// Temporarily keep statuses here
        
$statuses = array();

        
// A bit of unfucking potential missing values in config file
        
$this->settings['services']['executables'] = (array) $this->settings['services']['executables'];
        
$this->settings['services']['pidFiles'] = (array) $this->settings['services']['pidFiles'];

        
// Convert paths of executables to PID files
        
$pids = array();
        
$do_process_search false;
        if (
count($this->settings['services']['executables']) > 0) {
            
$potential_paths = @glob('/proc/*/cmdline');
            if (
is_array($potential_paths)) {
                
$num_paths count($potential_paths);
                
$do_process_search true;
            }
        }
            
        
// Should we go ahead and do the PID search based on executables?
        
if ($do_process_search) {
            
// Precache all process cmdlines
            
for ($i 0$i $num_paths$i++)
                
$cmdline_cache[$i] = explode("\x00"getContents($potential_paths[$i]));
            
            
// Go through the list of executables to search for
            
foreach ($this->settings['services']['executables'] as $service => $exec) {
                
// Go through pid file list. for loops are faster than foreach
                
for ($i 0$i $num_paths$i++) {
                    
$cmdline $cmdline_cache[$i];
                    
$match false;
                    if (
is_array($exec)) {
                        
$match true;
                        foreach (
$exec as $argn => $argv) {
                            if(
$cmdline[$argn] != $argv)
                                
$match false;
                        }
                    }
                    else if (
$cmdline[0] == $exec) {
                        
$match true;
                    }
                    
// If this one matches, stop here and save it
                    
if ($match) {
                        
// Get pid out of path to cmdline file
                        
$pids[$service] = substr($potential_paths[$i], /*strlen('/proc/')*/,
                                                
strpos($potential_paths[$i], '/'7)-6);
                        break;
                    }
                }
            }
        }

        
// PID files
        
foreach ($this->settings['services']['pidFiles'] as $service => $file) {
            
$pid getContents($filefalse);
            if (
$pid != false && is_numeric($pid))
                
$pids[$service] = $pid;
        }

        
// Deal with PIDs
        
foreach ($pids as $service => $pid) {
            
$path '/proc/'.$pid.'/status';
            
$status_contents getContents($pathfalse);
            if (
$status_contents == false) {
                
$statuses[$service] = array('state' => 'Down''threads' => 'N/A''pid' => $pid);
                continue;
            }

            
            
// Attempt getting info out of it
            
if (!preg_match_all('/^(\w+):\s+(\w+)/m'$status_contents$status_matchesPREG_SET_ORDER))
                continue;

            
// Initially set these as pointless
            
$state false;
            
$threads false;
            
$mem false;

            
// Go through
            //foreach ($status_matches as $status_match) {
            
for ($i 0$num count($status_matches); $i $num$i++) {

                
// What have we here?
                
switch ($status_matches[$i][1]) {

                    
// State section
                    
case 'State':
                        switch (
$status_matches[$i][2]) {
                            case 
'D'// disk sleep? wtf?
                            
case 'S':
                                
$state 'Up (Sleeping)';
                            break;
                            case 
'Z':
                                
$state 'Zombie';
                            break;
                            
// running
                            
case 'R':
                                
$state 'Up (Running)';
                            break;
                            
// stopped
                            
case 'T':
                                
$state 'Up (Stopped)';
                            break;
                            default:
                                continue;
                            break;
                        }
                    break;

                    
// Mem usage
                    
case 'VmRSS':
                        if (
is_numeric($status_matches[$i][2]))
                            
$mem $status_matches[$i][2] * 1024// Measured in kilobytes; we want bytes
                    
break;
                    
                    
// Thread count
                    
case 'Threads':
                        if (
is_numeric($status_matches[$i][2]))
                            
$threads $status_matches[$i][2];

                        
// Thread count should be last. Stop here to possibly save time assuming we have the other values
                        
if ($state !== false && $mem !== false && $threads !== false)
                            break;
                    break;
                }
            }


            
// Save info
            
$statuses[$service] = array(
                
'state' => $state $state '?',
                
'threads' => $threads,
                
'pid' => $pid,
                
'memory_usage' => $mem
            
);
        }

        return 
$statuses;
    }
    
    
/**
     * getDistro
     * 
     * @access private
     * @return array the distro,version or false
     */
    
private function getDistro() {
        
        
// Time?
        
if (!empty($this->settings['timer']))
            
$t = new LinfoTimerStart('Determining Distrobution');

        
// Seems the best way of doing it, as opposed to calling 'lsb_release -a', parsing /etc/issue, or 
        // just checking if distro specific version files exist without actually parsing them: 
        // - Allows multiple files of the same name for different distros/versions of distros, provided each
        // - uses different regular expression syntax.
        // - Also permits files that contain only the distro release version and nothing else,
        // - in which case passing false instead of a regex string snags the contents.
        // - And even also supports empty files, and just uses said file to identify the distro and ignore version

        // Store the distribution's files we check for, optional regex parsing string, and name of said distro here:
        
$distros = array(
            
            
// This snags ubuntu and other distros which use the lsb method of identifying themselves
            
array('/etc/lsb-release','/^DISTRIB_ID=([^$]+)$\n^DISTRIB_RELEASE=([^$]+)$\n^DISTRIB_CODENAME=([^$]+)$\n/m'false),
            
            
// These working snag versions
            
array('/etc/redhat-release''/^CentOS release ([\d\.]+) \(([^)]+)\)$/''CentOS'),
            array(
'/etc/redhat-release''/^Red Hat.+release (\S+) \(([^)]+)\)$/''RedHat'),
            array(
'/etc/fedora-release''/^Fedora(?: Core)? release (\d+) \(([^)]+)\)$/''Fedora'),
            array(
'/etc/gentoo-release''/([\d\.]+)$/''Gentoo'),
            array(
'/etc/SuSE-release''/^VERSION = ([\d\.]+)$/m''openSUSE'),
            array(
'/etc/slackware-version''/([\d\.]+)$/''Slackware'),

            
// These don't because they're empty 
            
array('/etc/arch-release''''Arch'),

            
// I'm unaware of the structure of these files, so versions are not picked up
            
array('/etc/mklinux-release''''MkLinux'),
            array(
'/etc/tinysofa-release ''''TinySofa'),
            array(
'/etc/turbolinux-release ''''TurboLinux'),
            array(
'/etc/yellowdog-release ''''YellowDog'),
            array(
'/etc/annvix-release ''''Annvix'),
            array(
'/etc/arklinux-release ''''Arklinux'),
            array(
'/etc/aurox-release ''''AuroxLinux'),
            array(
'/etc/blackcat-release ''''BlackCat'),
            array(
'/etc/cobalt-release ''''Cobalt'),
            array(
'/etc/immunix-release ''''Immunix'),
            array(
'/etc/lfs-release ''''Linux-From-Scratch'),
            array(
'/etc/linuxppc-release ''''Linux-PPC'),
            array(
'/etc/mklinux-release ''''MkLinux'),
            array(
'/etc/nld-release ''''NovellLinuxDesktop'),

            
// Leave this since debian derivitives might have it in addition to their own file
            // If it's last it ensures nothing else has it and thus it should be normal debian
            
array('/etc/debian_version'false'Debian'),
        );

        
// Hunt
        
foreach ($distros as $distro) {

            
// File we're checking for exists and is readable
            
if (file_exists($distro[0]) && is_readable($distro[0])) {

                
// Get it
                
$contents $distro[1] !== '' getContents($distro[0], '') : '';

                
// Don't use regex, this is enough; say version is the file's contents
                
if ($distro[1] === false) {
                    return array(
                        
'name' => $distro[2],
                        
'version' => $contents == '' false $contents
                    
);
                }
                
                
// No fucking idea what the version is. Don't use the file's contents for anything
                
elseif($distro[1] === '') {
                    return array(
                        
'name' => $distro[2],
                        
'version' => false
                    
);
                }

                
// Get the distro out of the regex as well?
                
elseif($distro[2] === false && preg_match($distro[1], $contents$m)) {
                    return array(
                        
'name' => $m[1],
                        
'version' => $m[2] . (isset($m[3]) ? ' ('.$m[3].')' '')
                    );
                }

                
// Our regex match it?
                
elseif(preg_match($distro[1], $contents$m)) {
                    return array(
                        
'name' => $distro[2],
                        
'version' => $m[1] . (isset($m[2]) ? ' ('.$m[2].')' '')
                    );
                }
            }
        }

        
// Return lack of result if we didn't find it
        
return false;
    }

    
/**
     * getCPUArchitecture
     * 
     * @access private
     * @return string the arch and bits
     */
    
private function getCPUArchitecture() {
        return 
php_uname('m');
    }

    
/**
     * getNumLoggedIn
     * 
     * @access private
     * @return number of logged in users with shells
     */
     
private function getNumLoggedIn() {

        
// Snag command line of every process in system
        
$procs glob('/proc/*/cmdline'GLOB_NOSORT);
        
        
// Store unqiue users here
        
$users = array();

        
// Each process
        
foreach ($procs as $proc) {

            
// Does the process match a popular shell, such as bash, csh, etc?
            
if (preg_match('/(?:bash|csh|zsh|ksh)$/'getContents($proc''))) {

                
// Who the fuck owns it, anyway? 
                
$owner fileowner(dirname($proc));

                
// Careful..
                
if (!is_numeric($owner))
                    continue;

                
// Have we not seen this user before?
                
if (!in_array($owner$users))
                    
$users[] = $owner;
            }
        }
        
        
// Give number of unique users with shells running
        
return count($users);
    }
}

:: Command execute ::

Enter:
 
Select:
 

:: Search ::
  - regexp 

:: Upload ::
 
[ Read-Only ]

:: Make Dir ::
 
[ Read-Only ]
:: Make File ::
 
[ Read-Only ]

:: Go Dir ::
 
:: Go File ::
 

--[ c99shell v. 2.5 [PHP 8 Update] [24.05.2025] | Generation time: 0.0097 ]--