Subversion Repositories ALCASAR

Rev

Rev 3100 | Details | Compare with Previous | Last modification | View Log

Rev Author Line No. Line
2770 rexy 1
<?php
2
/**
3
 * Linux System Class
4
 *
5
 * PHP version 5
6
 *
7
 * @category  PHP
8
 * @package   PSI Linux OS class
9
 * @author    Michael Cramer <BigMichi1@users.sourceforge.net>
10
 * @copyright 2009 phpSysInfo
11
 * @license   http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
12
 * @version   SVN: $Id: class.Linux.inc.php 712 2012-12-05 14:09:18Z namiltd $
13
 * @link      http://phpsysinfo.sourceforge.net
14
 */
15
 /**
16
 * Linux sysinfo class
17
 * get all the required information from Linux system
18
 *
19
 * @category  PHP
20
 * @package   PSI Linux OS class
21
 * @author    Michael Cramer <BigMichi1@users.sourceforge.net>
22
 * @copyright 2009 phpSysInfo
23
 * @license   http://opensource.org/licenses/gpl-2.0.php GNU General Public License version 2, or (at your option) any later version
24
 * @version   Release: 3.0
25
 * @link      http://phpsysinfo.sourceforge.net
26
 */
27
class Linux extends OS
28
{
29
    /**
3037 rexy 30
     * Uptime command result.
31
     */
32
    private $_uptime = null;
33
 
34
    /**
2770 rexy 35
     * Assoc array of all CPUs loads.
36
     */
3100 rexy 37
    protected $_cpu_loads = null;
325 richard 38
 
2770 rexy 39
    /**
3037 rexy 40
     * Version string.
2770 rexy 41
     */
3037 rexy 42
    private $_kernel_string = null;
43
 
44
    /**
45
     * Array of info from Bios.
46
     */
47
    private $_machine_info = null;
48
 
49
    /**
50
     * Array of info from dmesg.
51
     */
52
    private $_dmesg_info = null;
53
 
54
    /**
55
     * Result of systemd-detect-virt.
56
     */
57
    private $system_detect_virt = null;
58
 
59
     /**
60
      * Get info from dmesg
61
      *
62
      * @return array
63
      */
64
    private function _get_dmesg_info()
2770 rexy 65
    {
3037 rexy 66
        if ($this->_dmesg_info === null) {
67
            $this->_dmesg_info = array();
68
            if (CommonFunctions::rfts('/var/log/dmesg', $result, 0, 4096, false)) {
69
                if (preg_match('/^[\s\[\]\.\d]*DMI:\s*(.+)/m', $result, $ar_buf)) {
70
                    $this->_dmesg_info['dmi'] = trim($ar_buf[1]);
71
                }
72
                if (defined('PSI_SHOW_VIRTUALIZER_INFO') && PSI_SHOW_VIRTUALIZER_INFO && ($this->system_detect_virt === null) && preg_match('/^[\s\[\]\.\d]*Hypervisor detected:\s*(.+)/m', $result, $ar_buf)) {
73
                    $this->_dmesg_info['hypervisor'] = trim($ar_buf[1]);
74
                }
2770 rexy 75
            }
3037 rexy 76
            if ((count($this->_dmesg_info) < ((defined('PSI_SHOW_VIRTUALIZER_INFO') && PSI_SHOW_VIRTUALIZER_INFO && ($this->system_detect_virt === null))?2:1)) && CommonFunctions::executeProgram('dmesg', '', $result, false)) {
77
                if (!isset($this->_dmesg_info['dmi']) && preg_match('/^[\s\[\]\.\d]*DMI:\s*(.+)/m', $result, $ar_buf)) {
78
                    $this->_dmesg_info['dmi'] = trim($ar_buf[1]);
79
                }
80
                if (defined('PSI_SHOW_VIRTUALIZER_INFO') && PSI_SHOW_VIRTUALIZER_INFO && ($this->system_detect_virt === null) && !isset($this->_dmesg_info['hypervisor']) && preg_match('/^[\s\[\]\.\d]*Hypervisor detected:\s*(.+)/m', $result, $ar_buf)) {
81
                    $this->_dmesg_info['hypervisor'] = trim($ar_buf[1]);
82
                }
2770 rexy 83
            }
3037 rexy 84
        }
85
 
86
        return $this->_dmesg_info;
87
    }
88
 
89
    /**
90
     * Get machine info
91
     *
92
     * @return string
93
     */
94
    private function _get_machine_info()
95
    {
96
        if ($this->_machine_info === null) {
97
            $this->_machine_info = array();
98
            if (defined('PSI_SHOW_VIRTUALIZER_INFO') && PSI_SHOW_VIRTUALIZER_INFO) {
99
                if (CommonFunctions::executeProgram('systemd-detect-virt', '-v', $resultv, false)) {
100
                    $this->system_detect_virt = $resultv;
101
                }
2770 rexy 102
            }
3037 rexy 103
            $vendor_array = array();
104
            if ((($dmesg = $this->_get_dmesg_info()) !== null) && isset($dmesg['dmi'])) {
105
                $this->_machine_info['machine'] = $dmesg['dmi'];
106
                if (defined('PSI_SHOW_VIRTUALIZER_INFO') && PSI_SHOW_VIRTUALIZER_INFO && ($this->system_detect_virt === null)) {
107
                    /* Test this before sys_vendor to detect KVM over QEMU */
108
                    if (CommonFunctions::rfts('/sys/devices/virtual/dmi/id/product_name', $buf, 1, 4096, false) && (trim($buf)!="")) {
109
                        $vendor_array[] = $product_name = trim($buf);
110
                    } else {
111
                        $product_name = '';
112
                    }
113
                    if (CommonFunctions::rfts('/sys/devices/virtual/dmi/id/sys_vendor', $buf, 1, 4096, false) && (trim($buf)!="")) {
114
                        $vendor_array[] = trim($buf);
115
                    }
116
                    if (CommonFunctions::rfts('/sys/devices/virtual/dmi/id/board_vendor', $buf, 1, 4096, false) && (trim($buf)!="")) {
117
                        if ($product_name != "") {
118
                            $vendor_array[] = trim($buf)." ".$product_name;
119
                        } else {
120
                            $vendor_array[] = trim($buf);
121
                        }
122
                    } else {
123
                        $vendor_array[] = $dmesg['dmi'];
124
                    }
125
                    if (CommonFunctions::rfts('/sys/devices/virtual/dmi/id/bios_vendor', $buf, 1, 4096, false) && (trim($buf)!="")) {
126
                        $vendor_array[] = trim($buf);
127
                    }
128
                    if (CommonFunctions::rfts('/sys/devices/virtual/dmi/id/product_version', $buf, 1, 4096, false) && (trim($buf)!="")) {
129
                        $vendor_array[] = trim($buf);
130
                    }
131
                }
132
            } else { // 'machine' data from /sys/devices/virtual/dmi/id/
133
                $bios = "";
134
                if (defined('PSI_SHOW_VIRTUALIZER_INFO') && PSI_SHOW_VIRTUALIZER_INFO && ($this->system_detect_virt === null)) {
135
                    // Test this before sys_vendor to detect KVM over QEMU
136
                    if (CommonFunctions::rfts('/sys/devices/virtual/dmi/id/product_name', $buf, 1, 4096, false) && (trim($buf)!="")) {
137
                        $vendor_array[] = $product_name = trim($buf);
138
                    } else {
139
                        $product_name = '';
140
                    }
141
 
142
                    if (CommonFunctions::rfts('/sys/devices/virtual/dmi/id/sys_vendor', $buf, 1, 4096, false) && (trim($buf)!="")) {
143
                        $vendor_array[] = trim($buf);
144
                    }
145
                    if (CommonFunctions::rfts('/sys/devices/virtual/dmi/id/board_vendor', $buf, 1, 4096, false) && (trim($buf)!="")) {
146
                        if ($product_name != "") {
147
                            $this->_machine_info['machine'] = trim($buf)." ".$product_name;
148
                        } else {
149
                            $this->_machine_info['machine'] = trim($buf);
150
                        }
151
                        $vendor_array[] = $this->_machine_info["machine"];
152
                    } elseif ($product_name != "") {
153
                        $this->_machine_info['machine'] = $product_name;
154
                    }
155
 
156
                    if (CommonFunctions::rfts('/sys/devices/virtual/dmi/id/bios_vendor', $buf, 1, 4096, false) && (trim($buf)!="")) {
157
                        $vendor_array[] = trim($buf);
158
                    }
159
                    if (CommonFunctions::rfts('/sys/devices/virtual/dmi/id/product_version', $buf, 1, 4096, false) && (trim($buf)!="")) {
160
                        $vendor_array[] = trim($buf);
161
                    }
162
                } else {
163
                    if (CommonFunctions::rfts('/sys/devices/virtual/dmi/id/board_vendor', $buf, 1, 4096, false) && (trim($buf)!="")) {
164
                        $this->_machine_info['machine'] = trim($buf);
165
                    }
166
                    if (CommonFunctions::rfts('/sys/devices/virtual/dmi/id/product_name', $buf, 1, 4096, false) && (trim($buf)!="")) {
167
                        if (isset($this->_machine_info['machine'])) {
168
                            $this->_machine_info['machine'] .= " ".trim($buf);
169
                        } else {
170
                            $this->_machine_info['machine'] = trim($buf);
171
                        }
172
                    }
173
                }
174
                if (CommonFunctions::rfts('/sys/devices/virtual/dmi/id/board_name', $buf, 1, 4096, false) && (trim($buf)!="")) {
175
                    if (isset($this->_machine_info['machine'])) {
176
                        $this->_machine_info['machine'] .= "/".trim($buf);
177
                    } else {
178
                        $this->_machine_info['machine'] = trim($buf);
179
                    }
180
                }
181
                if (CommonFunctions::rfts('/sys/devices/virtual/dmi/id/bios_version', $buf, 1, 4096, false) && (trim($buf)!="")) {
182
                    $bios = trim($buf);
183
                }
184
                if (CommonFunctions::rfts('/sys/devices/virtual/dmi/id/bios_date', $buf, 1, 4096, false) && (trim($buf)!="")) {
185
                    $bios = trim($bios." ".trim($buf));
186
                }
187
                if ($bios != "") {
188
                    if (isset($this->_machine_info['machine'])) {
189
                        $this->_machine_info['machine'] .= ", BIOS ".$bios;
190
                    } else {
191
                        $this->_machine_info['machine'] = "BIOS ".$bios;
192
                    }
193
                }
2770 rexy 194
            }
3037 rexy 195
            if (isset($this->_machine_info['machine'])) {
196
                $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'])));
2770 rexy 197
            }
3037 rexy 198
 
3100 rexy 199
            if (defined('PSI_SHOW_VIRTUALIZER_INFO') && PSI_SHOW_VIRTUALIZER_INFO && ($this->system_detect_virt === null) && count($vendor_array) > 0) {
3037 rexy 200
                $virt = CommonFunctions::decodevirtualizer($vendor_array);
201
                if ($virt !== null) {
202
                    $this->_machine_info['hypervisor'] = $virt;
203
                }
2770 rexy 204
            }
3037 rexy 205
        }
206
 
207
        return $this->_machine_info;
208
    }
209
 
210
    /**
211
     * Get kernel string
212
     *
213
     * @return string
214
     */
215
    private function _get_kernel_string()
216
    {
217
        if ($this->_kernel_string === null) {
218
            $this->_kernel_string = "";
3100 rexy 219
            if ($this->sys->getOS() == 'SSH') {
220
                if (CommonFunctions::executeProgram('uname', '-s', $strBuf, false) && ($strBuf !== '')) {
221
                    $this->sys->setOS($strBuf);
222
                } else {
223
                    return $this->_kernel_string;
224
                }
225
            }
226
            if ((CommonFunctions::executeProgram($uname="uptrack-uname", '-r', $strBuf, false) && ($strBuf !== '')) || // show effective kernel if ksplice uptrack is installed
227
                (CommonFunctions::executeProgram($uname="uname", '-r', $strBuf, PSI_DEBUG) && ($strBuf !== ''))) {
3037 rexy 228
                $this->_kernel_string = $strBuf;
3100 rexy 229
                if (CommonFunctions::executeProgram($uname, '-v', $strBuf, PSI_DEBUG) && ($strBuf !== '')) {
3037 rexy 230
                    if (preg_match('/ SMP /', $strBuf)) {
231
                        $this->_kernel_string .= ' (SMP)';
232
                    }
233
                }
3100 rexy 234
                if (CommonFunctions::executeProgram($uname, '-m', $strBuf, PSI_DEBUG) && ($strBuf !== '')) {
3037 rexy 235
                    $this->_kernel_string .= ' '.$strBuf;
236
                }
237
            } elseif (CommonFunctions::rfts('/proc/version', $strBuf, 1)) {
3100 rexy 238
                if (preg_match('/\/Hurd-([^\)]+)/', $strBuf, $ar_buf)) {
3037 rexy 239
                    $this->_kernel_string = $ar_buf[1];
3100 rexy 240
                } elseif (preg_match('/version\s+(\S+)/', $strBuf, $ar_buf)) {
241
                    $this->_kernel_string = $ar_buf[1];
3037 rexy 242
                    if (preg_match('/ SMP /', $strBuf)) {
243
                        $this->_kernel_string .= ' (SMP)';
244
                    }
245
                }
2770 rexy 246
            }
247
        }
325 richard 248
 
3037 rexy 249
        return $this->_kernel_string;
250
    }
251
 
252
    /**
3100 rexy 253
     * check OS type
254
     */
255
    public function __construct($blockname = false)
256
    {
257
        parent::__construct($blockname);
258
        $this->_get_kernel_string();
259
    }
260
 
261
    /**
3037 rexy 262
     * Machine
263
     *
264
     * @return void
265
     */
3100 rexy 266
    protected function _machine()
3037 rexy 267
    {
268
        $machine_info = $this->_get_machine_info();
269
        if (isset($machine_info['machine'])) {
270
            $machine = $machine_info['machine'];
271
        } else {
272
            $machine = "";
2770 rexy 273
        }
325 richard 274
 
2770 rexy 275
        if (CommonFunctions::fileexists($filename="/etc/config/uLinux.conf") // QNAP detection
276
           && CommonFunctions::rfts($filename, $buf, 0, 4096, false)
277
           && preg_match("/^Rsync\sModel\s*=\s*QNAP/m", $buf)
278
           && CommonFunctions::fileexists($filename="/etc/platform.conf") // Platform detection
279
           && CommonFunctions::rfts($filename, $buf, 0, 4096, false)
280
           && preg_match("/^DISPLAY_NAME\s*=\s*(\S+)/m", $buf, $mach_buf) && ($mach_buf[1]!=="")) {
3037 rexy 281
            if ($machine !== "") {
2770 rexy 282
                $machine = "QNAP ".$mach_buf[1].' - '.$machine;
283
            } else {
284
                $machine = "QNAP ".$mach_buf[1];
285
            }
286
        }
287
 
3037 rexy 288
        if ($machine !== "") {
2770 rexy 289
            $this->sys->setMachine($machine);
290
        }
1764 richard 291
    }
325 richard 292
 
2770 rexy 293
    /**
294
     * Hostname
295
     *
296
     * @return void
297
     */
298
    protected function _hostname()
299
    {
3100 rexy 300
        if (PSI_USE_VHOST && !defined('PSI_EMU_PORT')) {
2770 rexy 301
            if (CommonFunctions::readenv('SERVER_NAME', $hnm)) $this->sys->setHostname($hnm);
302
        } else {
303
            if (CommonFunctions::rfts('/proc/sys/kernel/hostname', $result, 1, 4096, PSI_DEBUG && (PSI_OS != 'Android'))) {
304
                $result = trim($result);
305
                $ip = gethostbyname($result);
306
                if ($ip != $result) {
307
                    $this->sys->setHostname(gethostbyaddr($ip));
308
                }
3179 rexy 309
            } elseif (CommonFunctions::executeProgram('hostname', '', $ret, false)) {
2770 rexy 310
                $this->sys->setHostname($ret);
3179 rexy 311
            } elseif (CommonFunctions::executeProgram('uname', '-n', $ret, false)) {
312
                $this->sys->setHostname($ret);
2770 rexy 313
            }
3179 rexy 314
 
2770 rexy 315
        }
316
    }
325 richard 317
 
2770 rexy 318
    /**
319
     * Kernel Version
320
     *
321
     * @return void
322
     */
3100 rexy 323
    protected function _kernel()
2770 rexy 324
    {
3037 rexy 325
        if (($verBuf = $this->_get_kernel_string()) != "") {
326
            $this->sys->setKernel($verBuf);
327
        }
328
    }
329
 
330
    /**
331
     * Virtualizer info
332
     *
333
     * @return void
334
     */
335
    protected function _virtualizer()
336
    {
337
        if (!defined('PSI_SHOW_VIRTUALIZER_INFO') || !PSI_SHOW_VIRTUALIZER_INFO) {
338
            return;
339
        }
340
        if ($this->system_detect_virt !== null) {
341
            if (($this->system_detect_virt !== "") && ($this->system_detect_virt !== "none")) {
342
                $this->sys->setVirtualizer($this->system_detect_virt);
343
            }
344
            if (($verBuf = $this->_get_kernel_string()) !== "") {
345
                if (preg_match('/^[\d\.-]+-microsoft-standard/', $verBuf)) {
346
                    $this->sys->setVirtualizer('wsl2', 'wsl'); // Windows Subsystem for Linux 2
2770 rexy 347
                }
348
            }
3037 rexy 349
            if (CommonFunctions::executeProgram('systemd-detect-virt', '-c', $resultc, false) && ($resultc !== "") && ($resultc !== "none")) {
350
                $this->sys->setVirtualizer($resultc);
2770 rexy 351
            }
3037 rexy 352
        } else {
353
            $cpuvirt = $this->sys->getVirtualizer(); // previous info from _cpuinfo()
354
 
355
            $novm = true;
356
            // code based on src/basic/virt.c from systemd-detect-virt source code (https://github.com/systemd/systemd)
357
 
3100 rexy 358
            // First, try to detect Oracle Virtualbox, Amazon EC2 Nitro and Parallels, even if they use KVM,
359
            // as well as Xen even if it cloaks as Microsoft Hyper-V. Attempt to detect uml at this stage also
360
            // since it runs as a user-process nested inside other VMs. Also check for Xen now, because Xen PV
361
            // mode does not override CPUID when nested inside another hypervisor.
3037 rexy 362
            $machine_info = $this->_get_machine_info();
363
            if (isset($machine_info['hypervisor'])) {
364
                $hypervisor = $machine_info['hypervisor'];
3100 rexy 365
                if (($hypervisor === 'oracle') || ($hypervisor === 'amazon') || ($hypervisor === 'xen') || ($hypervisor === 'parallels')) {
3037 rexy 366
                    $this->sys->setVirtualizer($hypervisor);
367
                    $novm = false;
368
                }
2770 rexy 369
            }
3037 rexy 370
 
371
            // Detect UML
372
            if ($novm) {
373
                if (isset($cpuvirt["cpuid:UserModeLinux"])) {
374
                    $this->sys->setVirtualizer('uml'); // User-mode Linux
375
                    $novm = false;
376
                }
377
            }
378
 
379
            // Detect Xen
380
            if ($novm && is_dir('/proc/xen')) {
381
                // xen Dom0 is detected as XEN in hypervisor and maybe others.
382
                // In order to detect the Dom0 as not virtualization we need to
383
                // double-check it
384
                if (CommonFunctions::rfts('/sys/hypervisor/properties/features', $features, 1, 4096, false)) {
385
                    if ((hexdec($features) & 2048) == 0) { // XENFEAT_dom0 is not set
386
                        $this->sys->setVirtualizer('xen'); // Xen hypervisor (only domU, not dom0)
387
                        $novm = false;
388
                    }
389
                } elseif (CommonFunctions::rfts('/proc/xen/capabilities', $capabilities, 1, 4096, false) && !preg_match('/control_d/', $capabilities)) { // control_d not in capabilities
390
                    $this->sys->setVirtualizer('xen'); // Xen hypervisor (only domU, not dom0)
391
                    $novm = false;
392
                }
393
            }
394
 
395
            // Second, try to detect from CPUID, this will report KVM for whatever software is used even if info in DMI is overwritten.
396
            // Since the vendor_id in /proc/cpuinfo is overwritten on virtualization we use values from msr-cpuid.
397
            if ($novm && CommonFunctions::executeProgram('msr-cpuid', '', $bufr, false)
398
               && (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))) {
399
                $virt = CommonFunctions::decodevirtualizer($cpuid[1].$cpuid[2].$cpuid[3]);
400
                if ($virt !== null) {
401
                    $this->sys->setVirtualizer($virt);
402
                }
403
            }
404
 
405
            // Third, try to detect from DMI.
406
            if ($novm && isset($hypervisor)) {
407
                $this->sys->setVirtualizer($hypervisor);
408
                $novm = false;
409
            }
410
 
411
            // Check high-level hypervisor sysfs file
412
            if ($novm && CommonFunctions::rfts('/sys/hypervisor/type', $type, 1, 4096, false) && ($type === "xen")) {
413
                $this->sys->setVirtualizer('xen'); // Xen hypervisor
414
                $novm = false;
415
            }
416
 
417
            if ($novm) {
418
                if (CommonFunctions::rfts('/proc/device-tree/hypervisor/compatible', $compatible, 1, 4096, false)) {
419
                    switch ($compatible) {
420
                    case 'linux,kvm':
421
                        $this->sys->setVirtualizer('kvm'); // KVM
422
                        $novm = false;
423
                        break;
424
                    case 'vmware':
425
                        $this->sys->setVirtualizer('vmware'); // VMware
426
                        $novm = false;
427
                        break;
428
                    case 'xen':
429
                        $this->sys->setVirtualizer('xen'); // Xen hypervisor
430
                        $novm = false;
431
                    }
432
                } else {
433
                    if (CommonFunctions::fileexists('/proc/device-tree/ibm,partition-name')
434
                       && CommonFunctions::fileexists('/proc/device-tree/hmc-managed?')
435
                       && CommonFunctions::fileexists('/proc/device-tree/chosen/qemu,graphic-width')) {
436
                        $this->sys->setVirtualizer('powervm'); // IBM PowerVM hypervisor
437
                        $novm = false;
438
                    } else {
439
                        $names = CommonFunctions::findglob('/proc/device-tree', GLOB_NOSORT);
440
                        if (is_array($names) && (($total = count($names)) > 0)) {
441
                            for ($i = 0; $i < $total; $i++) {
442
                                if (preg_match('/fw-cfg/', $names[$i])) {
443
                                    $this->sys->setVirtualizer('qemu'); // QEMU
444
                                    $novm = false;
445
                                    break;
446
                                }
447
                            }
448
                        }
3179 rexy 449
                        if (CommonFunctions::rfts('/proc/device-tree/compatible', $compatible, 1, 4096, false) && ($compatible === "qemu,pseries")) {
450
                            $this->sys->setVirtualizer('qemu'); // QEMU
451
                            $novm = false;
452
                        }
3037 rexy 453
                    }
454
                }
455
            }
456
 
457
            if ($novm && CommonFunctions::rfts('/proc/sysinfo', $sysinfo, 0, 4096, false) && preg_match('//VM00 Control Program:\s*(\S+)/m', $sysinfo, $vcp)) {
458
                if ($vcp[1] === 'z/VM') {
459
                    $this->sys->setVirtualizer('zvm'); // s390 z/VM
460
                } else {
461
                    $this->sys->setVirtualizer('kvm'); // KVM
462
                }
463
                $novm = false;
464
            }
465
 
466
            // Additional tests outside of the systemd-detect-virt source code
467
            if ($novm && (($dmesg = $this->_get_dmesg_info()) !== null) && isset($dmesg['hypervisor'])) {
468
                switch ($dmesg['hypervisor']) {
469
                case 'VMware':
470
                    $this->sys->setVirtualizer('vmware'); // VMware
471
                    $novm = false;
472
                    break;
473
                case 'KVM':
474
                    $this->sys->setVirtualizer('kvm'); // KVM
475
                    $novm = false;
476
                    break;
477
                case 'Microsoft HyperV':
478
                case 'Microsoft Hyper-V':
479
                    $this->sys->setVirtualizer('microsoft'); // Hyper-V
480
                    $novm = false;
481
                    break;
482
                case 'ACRN':
483
                    $this->sys->setVirtualizer('acrn'); // ACRN hypervisor
484
                    $novm = false;
485
                    break;
486
                case 'Jailhouse':
487
                    $this->sys->setVirtualizer('jailhouse'); // Jailhouse
488
                    $novm = false;
489
                    break;
490
                case 'Xen':
491
                case 'Xen PV':
492
                case 'Xen HVM':
493
                    // xen Dom0 is detected as XEN in hypervisor and maybe others.
494
                    // In order to detect the Dom0 as not virtualization we need to
495
                    // double-check it
496
                    if (CommonFunctions::rfts('/sys/hypervisor/properties/features', $features, 1, 4096, false)) {
497
                        if ((hexdec($features) & 2048) == 0) { // XENFEAT_dom0 is not set
498
                            $this->sys->setVirtualizer('xen'); // Xen hypervisor (only domU, not dom0)
499
                            $novm = false;
500
                        }
501
                    } elseif (CommonFunctions::rfts('/proc/xen/capabilities', $capabilities, 1, 4096, false) && !preg_match('/control_d/', $capabilities)) { // control_d not in capabilities
502
                        $this->sys->setVirtualizer('xen'); // Xen hypervisor (only domU, not dom0)
503
                        $novm = false;
504
                    }
505
                }
506
            }
507
 
508
            // Detect QEMU cpu
509
            if ($novm && isset($cpuvirt["cpuid:QEMU"])) {
510
                $this->sys->setVirtualizer('qemu'); // QEMU
511
                $novm = false;
512
            }
513
 
514
            if ($novm && isset($cpuvirt["hypervisor"])) {
515
                $this->sys->setVirtualizer('unknown');
516
            }
517
 
518
            if ((count(CommonFunctions::gdc('/proc/vz', false)) == 0) && (count(CommonFunctions::gdc('/proc/bc', false)) > 0)) {
519
                $this->sys->setVirtualizer('openvz'); // OpenVZ/Virtuozzo
520
            }
521
 
522
            if (($verBuf = $this->_get_kernel_string()) !== "") {
523
                if (preg_match('/^[\d\.-]+-Microsoft/', $verBuf)) {
524
                    $this->sys->setVirtualizer('wsl'); // Windows Subsystem for Linux
525
                } elseif (preg_match('/^[\d\.-]+-microsoft-standard/', $verBuf)) {
526
                    $this->sys->setVirtualizer('wsl2'); // Windows Subsystem for Linux 2
527
                }
528
            }
529
 
2770 rexy 530
            if (CommonFunctions::rfts('/proc/self/cgroup', $strBuf2, 0, 4096, false)) {
3037 rexy 531
               if (preg_match('/:\/lxc\//m', $strBuf2)) {
532
                    $this->sys->setVirtualizer('lxc'); // Linux container
2770 rexy 533
                } elseif (preg_match('/:\/docker\//m', $strBuf2)) {
3037 rexy 534
                    $this->sys->setVirtualizer('docker'); // Docker
2770 rexy 535
                } elseif (preg_match('/:\/system\.slice\/docker\-/m', $strBuf2)) {
3037 rexy 536
                    $this->sys->setVirtualizer('docker'); // Docker
2770 rexy 537
                }
538
            }
539
        }
540
    }
325 richard 541
 
2770 rexy 542
    /**
543
     * UpTime
544
     * time the system is running
545
     *
546
     * @return void
547
     */
3100 rexy 548
    protected function _uptime($bufu = null)
2770 rexy 549
    {
550
        if (CommonFunctions::rfts('/proc/uptime', $buf, 1, 4096, PSI_OS != 'Android')) {
551
            $ar_buf = preg_split('/ /', $buf);
552
            $this->sys->setUptime(trim($ar_buf[0]));
3100 rexy 553
        } elseif (($this->_uptime !== null) || ($bufu !== null) || CommonFunctions::executeProgram('uptime', '', $bufu)) {
554
            if (($this->_uptime === null) && ($bufu !== null)) {
555
                $this->_uptime = $bufu;
556
            }
3037 rexy 557
            if (preg_match("/up (\d+) day[s]?,[ ]+(\d+):(\d+),/", $this->_uptime, $ar_buf)) {
2770 rexy 558
                $min = $ar_buf[3];
559
                $hours = $ar_buf[2];
560
                $days = $ar_buf[1];
561
                $this->sys->setUptime($days * 86400 + $hours * 3600 + $min * 60);
3037 rexy 562
            } elseif (preg_match("/up (\d+) day[s]?,[ ]+(\d+) min,/", $this->_uptime, $ar_buf)) {
2770 rexy 563
                $min = $ar_buf[2];
564
                $days = $ar_buf[1];
565
                $this->sys->setUptime($days * 86400 + $min * 60);
3037 rexy 566
            } elseif (preg_match("/up[ ]+(\d+):(\d+),/", $this->_uptime, $ar_buf)) {
2770 rexy 567
                $min = $ar_buf[2];
568
                $hours = $ar_buf[1];
569
                $this->sys->setUptime($hours * 3600 + $min * 60);
3100 rexy 570
            } elseif (preg_match("/up[ ]+(\d+):(\d+):(\d+)/", $this->_uptime, $ar_buf)) {
571
                $sec = $ar_buf[3];
572
                $min = $ar_buf[2];
573
                $hours = $ar_buf[1];
574
                $this->sys->setUptime($hours * 3600 + $min * 60 + $sec);
3037 rexy 575
            } elseif (preg_match("/up[ ]+(\d+) min,/", $this->_uptime, $ar_buf)) {
2770 rexy 576
                $min = $ar_buf[1];
577
                $this->sys->setUptime($min * 60);
3100 rexy 578
            } elseif (preg_match("/up[ ]+(\d+) day[s]?,[ ]+(\d+) hour[s]?,[ ]+(\d+) minute[s]?/", $this->_uptime, $ar_buf)) {
579
                $min = $ar_buf[3];
580
                $hours = $ar_buf[2];
581
                $days = $ar_buf[1];
582
                $this->sys->setUptime($days * 86400 + $hours * 3600 + $min * 60);
2770 rexy 583
            }
584
        }
585
    }
325 richard 586
 
2770 rexy 587
    /**
588
     * Processor Load
589
     * optionally create a loadbar
590
     *
591
     * @return void
592
     */
3100 rexy 593
    protected function _loadavg($buf = null)
2770 rexy 594
    {
3100 rexy 595
        if ((($buf !== null) || CommonFunctions::rfts('/proc/loadavg', $buf, 1, 4096, PSI_OS != 'Android')) && preg_match("/^\d/", trim($buf))) {
2770 rexy 596
            $result = preg_split("/\s/", $buf, 4);
597
            // don't need the extra values, only first three
598
            unset($result[3]);
599
            $this->sys->setLoad(implode(' ', $result));
3100 rexy 600
        } elseif (($buf === null) && ((($this->_uptime !== null) || CommonFunctions::executeProgram('uptime', '', $this->_uptime)) && preg_match("/load average: (.*), (.*), (.*)$/", $this->_uptime, $ar_buf))) {
601
              $this->sys->setLoad($ar_buf[1].' '.$ar_buf[2].' '.$ar_buf[3]);
2770 rexy 602
        }
603
        if (PSI_LOAD_BAR) {
604
            $this->sys->setLoadPercent($this->_parseProcStat('cpu'));
605
        }
325 richard 606
    }
607
 
2770 rexy 608
    /**
609
     * fill the load for a individual cpu, through parsing /proc/stat for the specified cpu
610
     *
611
     * @param String $cpuline cpu for which load should be meassured
612
     *
3037 rexy 613
     * @return int
2770 rexy 614
     */
615
    protected function _parseProcStat($cpuline)
616
    {
3037 rexy 617
        if ($this->_cpu_loads === null) {
2770 rexy 618
            $this->_cpu_loads = array();
325 richard 619
 
2770 rexy 620
            $cpu_tmp = array();
2976 rexy 621
            if (CommonFunctions::rfts('/proc/stat', $buf, 0, 4096, PSI_DEBUG && (PSI_OS != 'Android'))) {
2770 rexy 622
                if (preg_match_all('/^(cpu[0-9]*) (.*)/m', $buf, $matches, PREG_SET_ORDER)) {
623
                    foreach ($matches as $line) {
624
                        $cpu = $line[1];
625
                        $buf2 = $line[2];
325 richard 626
 
2770 rexy 627
                        $cpu_tmp[$cpu] = array();
325 richard 628
 
2770 rexy 629
                        $ab = 0;
630
                        $ac = 0;
631
                        $ad = 0;
632
                        $ae = 0;
633
                        sscanf($buf2, "%Ld %Ld %Ld %Ld", $ab, $ac, $ad, $ae);
634
                        $cpu_tmp[$cpu]['load'] = $ab + $ac + $ad; // cpu.user + cpu.sys
635
                        $cpu_tmp[$cpu]['total'] = $ab + $ac + $ad + $ae; // cpu.total
636
                    }
637
                }
638
 
639
                // we need a second value, wait 1 second befor getting (< 1 second no good value will occour)
640
                sleep(1);
641
 
2976 rexy 642
                if (CommonFunctions::rfts('/proc/stat', $buf, 0, 4096, PSI_DEBUG)) {
2770 rexy 643
                    if (preg_match_all('/^(cpu[0-9]*) (.*)/m', $buf, $matches, PREG_SET_ORDER)) {
644
                        foreach ($matches as $line) {
645
                            $cpu = $line[1];
646
                            if (isset($cpu_tmp[$cpu])) {
647
                                $buf2 = $line[2];
648
 
649
                                $ab = 0;
650
                                $ac = 0;
651
                                $ad = 0;
652
                                $ae = 0;
653
                                sscanf($buf2, "%Ld %Ld %Ld %Ld", $ab, $ac, $ad, $ae);
654
                                $load2 = $ab + $ac + $ad; // cpu.user + cpu.sys
655
                                $total2 = $ab + $ac + $ad + $ae; // cpu.total
656
                                $total = $cpu_tmp[$cpu]['total'];
657
                                $load = $cpu_tmp[$cpu]['load'];
658
                                $this->_cpu_loads[$cpu] = 0;
659
                                if ($total > 0 && $total2 > 0 && $load > 0 && $load2 > 0 && $total2 != $total && $load2 != $load) {
660
                                    $this->_cpu_loads[$cpu] = (100 * ($load2 - $load)) / ($total2 - $total);
661
                                }
662
                            }
663
                        }
664
                    }
665
                }
666
            }
667
        }
668
 
669
        if (isset($this->_cpu_loads[$cpuline])) {
670
            return $this->_cpu_loads[$cpuline];
325 richard 671
        } else {
2976 rexy 672
            return null;
2770 rexy 673
        }
674
    }
325 richard 675
 
2770 rexy 676
    /**
677
     * CPU information
678
     * All of the tags here are highly architecture dependant.
679
     *
680
     * @return void
681
     */
3100 rexy 682
    protected function _cpuinfo($bufr = null)
2770 rexy 683
    {
3100 rexy 684
        if (($bufr !== null) || CommonFunctions::rfts('/proc/cpuinfo', $bufr)) {
2770 rexy 685
            $cpulist = null;
686
            $raslist = null;
325 richard 687
 
2770 rexy 688
            // sparc
689
            if (preg_match('/\nCpu(\d+)Bogo\s*:/i', $bufr)) {
690
                $bufr = preg_replace('/\nCpu(\d+)ClkTck\s*:/i', "\nCpu0ClkTck:", preg_replace('/\nCpu(\d+)Bogo\s*:/i', "\n\nprocessor: $1\nCpu0Bogo:", $bufr));
691
            } else {
692
                $bufr = preg_replace('/\nCpu(\d+)ClkTck\s*:/i', "\n\nprocessor: $1\nCpu0ClkTck:", $bufr);
693
            }
325 richard 694
 
2770 rexy 695
            if (preg_match('/\nprocessor\s*:\s*\d+\r?\nprocessor\s*:\s*\d+/', $bufr)) {
696
                $bufr = preg_replace('/^(processor\s*:\s*\d+)\r?$/m', "$1\n", $bufr);
697
            }
325 richard 698
 
2770 rexy 699
            // IBM/S390
700
            $bufr = preg_replace('/\ncpu number\s*:\s*(\d+)\r?\ncpu MHz dynamic\s*:\s*(\d+)/m', "\nprocessor:$1\nclock:$2", $bufr);
701
 
3179 rexy 702
            // machine
703
            $bufr = preg_replace('/(\nmachine\s*:\s*[^\r\n]+)/m', "$1\n", $bufr);
704
 
2770 rexy 705
            $processors = preg_split('/\s?\n\s?\n/', trim($bufr));
706
 
707
            //first stage
708
            $_arch = null;
709
            $_impl = null;
710
            $_part = null;
3037 rexy 711
            $_vari = null;
2770 rexy 712
            $_hard = null;
713
            $_revi = null;
714
            $_cpus = null;
715
            $_buss = null;
716
            $_bogo = null;
717
            $_vend = null;
718
            $procname = null;
719
            foreach ($processors as $processor) if (!preg_match('/^\s*processor\s*:/mi', $processor)) {
720
                $details = preg_split("/\n/", $processor, -1, PREG_SPLIT_NO_EMPTY);
721
                foreach ($details as $detail) {
722
                    $arrBuff = preg_split('/\s*:\s*/', trim($detail));
723
                    if ((count($arrBuff) == 2) && (($arrBuff1 = trim($arrBuff[1])) !== '')) {
724
                        switch (strtolower($arrBuff[0])) {
725
                        case 'cpu architecture':
726
                            $_arch = $arrBuff1;
727
                            break;
728
                        case 'cpu implementer':
729
                            $_impl = $arrBuff1;
730
                            break;
731
                        case 'cpu part':
732
                            $_part = $arrBuff1;
733
                            break;
3037 rexy 734
                        case 'cpu variant':
735
                            $_vari = $arrBuff1;
736
                            break;
3179 rexy 737
                        case 'machine':
2770 rexy 738
                        case 'hardware':
739
                            $_hard = $arrBuff1;
740
                            break;
741
                        case 'revision':
742
                            $_revi = $arrBuff1;
743
                            break;
744
                        case 'cpu frequency':
745
                            if (preg_match('/^(\d+)\s+Hz/i', $arrBuff1, $bufr2)) {
746
                                $_cpus = round($bufr2[1]/1000000);
3100 rexy 747
                            } elseif (preg_match('/^(\d+)\s+MHz/i', $arrBuff1, $bufr2)) {
748
                                $_cpus = $bufr2[1];
2770 rexy 749
                            }
750
                            break;
751
                        case 'system bus frequency':
752
                            if (preg_match('/^(\d+)\s+Hz/i', $arrBuff1, $bufr2)) {
753
                                $_buss = round($bufr2[1]/1000000);
3100 rexy 754
                            } elseif (preg_match('/^(\d+)\s+MHz/i', $arrBuff1, $bufr2)) {
755
                                $_buss = $bufr2[1];
2770 rexy 756
                            }
757
                            break;
758
                        case 'bogomips per cpu':
759
                            $_bogo = round($arrBuff1);
760
                            break;
761
                        case 'vendor_id':
762
                            $_vend = $arrBuff1;
3037 rexy 763
                            break;
2770 rexy 764
                        case 'cpu':
765
                            $procname = $arrBuff1;
766
                        }
767
                    }
768
                }
769
            }
770
 
771
            //second stage
772
            $cpucount = 0;
773
            $speedset = false;
774
            foreach ($processors as $processor) if (preg_match('/^\s*processor\s*:/mi', $processor)) {
775
                $proc = null;
776
                $arch = null;
777
                $impl = null;
778
                $part = null;
3037 rexy 779
                $vari = null;
2770 rexy 780
                $dev = new CpuDevice();
781
                $details = preg_split("/\n/", $processor, -1, PREG_SPLIT_NO_EMPTY);
782
                foreach ($details as $detail) {
783
                    $arrBuff = preg_split('/\s*:\s*/', trim($detail));
784
                    if ((count($arrBuff) == 2) && (($arrBuff1 = trim($arrBuff[1])) !== '')) {
785
                        switch (strtolower($arrBuff[0])) {
786
                        case 'processor':
787
                            $proc = $arrBuff1;
788
                            if (is_numeric($proc)) {
3100 rexy 789
                                if (($procname !== null) && (strlen($procname) > 0)) {
2770 rexy 790
                                    $dev->setModel($procname);
791
                                }
792
                            } else {
793
                                $procname = $proc;
794
                                $dev->setModel($procname);
795
                            }
796
                            break;
797
                        case 'model name':
798
                        case 'cpu model':
799
                        case 'cpu type':
800
                        case 'cpu':
801
                            $dev->setModel($arrBuff1);
802
                            break;
3100 rexy 803
                        case 'cpu frequency':
804
                            if (preg_match('/^(\d+)\s+Hz/i', $arrBuff1, $bufr2)) {
805
                                if (($tmpsp = round($bufr2[1]/1000000)) > 0) {
806
                                    $dev->setCpuSpeed($tmpsp);
807
                                    $speedset = true;
808
                                }
809
                            } elseif (preg_match('/^(\d+)\s+MHz/i', $arrBuff1, $bufr2)) {
810
                                if ($bufr2[1] > 0) {
811
                                    $dev->setCpuSpeed($bufr2[1]);
812
                                    $speedset = true;
813
                                }
814
                            }
815
                            break;
2770 rexy 816
                        case 'cpu mhz':
817
                        case 'clock':
3100 rexy 818
                            if ($arrBuff1 > 0) {
2770 rexy 819
                                $dev->setCpuSpeed($arrBuff1);
820
                                $speedset = true;
821
                            }
822
                            break;
823
                        case 'cpu mhz static':
3100 rexy 824
                            $dev->setCpuSpeedMax($arrBuff1);
2770 rexy 825
                            break;
826
                        case 'cycle frequency [hz]':
3100 rexy 827
                            if (($tmpsp = round($arrBuff1/1000000)) > 0) {
828
                                $dev->setCpuSpeed($tmpsp);
829
                                $speedset = true;
830
                            }
2770 rexy 831
                            break;
3100 rexy 832
                        case 'cpu0clktck': // Linux sparc64
833
                            if (($tmpsp = round(hexdec($arrBuff1)/1000000)) > 0) {
834
                                $dev->setCpuSpeed($tmpsp);
835
                                $speedset = true;
836
                            }
2770 rexy 837
                            break;
838
                        case 'l3 cache':
839
                        case 'cache size':
840
                            $dev->setCache(trim(preg_replace("/[a-zA-Z]/", "", $arrBuff1)) * 1024);
841
                            break;
842
                        case 'initial bogomips':
843
                        case 'bogomips':
844
                        case 'cpu0bogo':
845
                            $dev->setBogomips(round($arrBuff1));
846
                            break;
847
                        case 'flags':
848
                            if (preg_match("/ vmx/", $arrBuff1)) {
849
                                $dev->setVirt("vmx");
850
                            } elseif (preg_match("/ svm/", $arrBuff1)) {
851
                                $dev->setVirt("svm");
852
                            }
3037 rexy 853
                            if (preg_match("/ hypervisor/", $arrBuff1)) {
854
                                if ($dev->getVirt() === null) {
855
                                    $dev->setVirt("hypervisor");
856
                                }
857
                                if (defined('PSI_SHOW_VIRTUALIZER_INFO') && PSI_SHOW_VIRTUALIZER_INFO && ($this->system_detect_virt === null)) {
858
                                    $this->sys->setVirtualizer("hypervisor", false);
859
                                }
860
                            }
2770 rexy 861
                            break;
862
                        case 'i size':
863
                        case 'd size':
864
                            if ($dev->getCache() === null) {
865
                                $dev->setCache($arrBuff1 * 1024);
866
                            } else {
867
                                $dev->setCache($dev->getCache() + ($arrBuff1 * 1024));
868
                            }
869
                            break;
870
                        case 'cpu architecture':
871
                            $arch = $arrBuff1;
872
                            break;
873
                        case 'cpu implementer':
874
                            $impl = $arrBuff1;
875
                            break;
876
                        case 'cpu part':
877
                            $part = $arrBuff1;
878
                            break;
3037 rexy 879
                        case 'cpu variant':
880
                            $vari = $arrBuff1;
881
                            break;
2770 rexy 882
                        case 'vendor_id':
883
                            $dev->setVendorId($arrBuff1);
3037 rexy 884
                            if (defined('PSI_SHOW_VIRTUALIZER_INFO') && PSI_SHOW_VIRTUALIZER_INFO && preg_match('/^User Mode Linux/', $arrBuff1)) {
885
                                $this->sys->setVirtualizer("cpuid:UserModeLinux", false);
886
                            }
2770 rexy 887
                        }
888
                    }
889
                }
890
                if ($arch === null) $arch = $_arch;
891
                if ($impl === null) $impl = $_impl;
892
                if ($part === null) $part = $_part;
3037 rexy 893
                if ($vari === null) $vari = $_vari;
2770 rexy 894
 
895
                // sparc64 specific code follows
896
                // This adds the ability to display the cache that a CPU has
897
                // Originally made by Sven Blumenstein <bazik@gentoo.org> in 2004
898
                // Modified by Tom Weustink <freshy98@gmx.net> in 2004
899
                $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');
900
                foreach ($sparclist as $name) {
901
                    if (CommonFunctions::rfts('/proc/openprom/'.$name.'/ecache-size', $buf, 1, 32, false)) {
902
                        $dev->setCache(base_convert(trim($buf), 16, 10));
903
                    }
904
                }
905
                // sparc64 specific code ends
906
 
907
                // XScale detection code
3100 rexy 908
                if (($arch === "5TE") && (($bogo = $dev->getBogomips()) !== null) && ($bogo > 0)) {
909
                    $dev->setCpuSpeed($bogo); // BogoMIPS are not BogoMIPS on this CPU, it's the speed
2770 rexy 910
                    $speedset = true;
911
                    $dev->setBogomips(null); // no BogoMIPS available, unset previously set BogoMIPS
912
                }
913
 
914
                if (($dev->getBusSpeed() == 0) && ($_buss !== null)) {
915
                    $dev->setBusSpeed($_buss);
916
                }
3100 rexy 917
                if (($dev->getCpuSpeed() == 0) && ($_cpus !== null) && ($_cpus > 0)) {
2770 rexy 918
                    $dev->setCpuSpeed($_cpus);
919
                    $speedset = true;
920
                }
921
                if (($dev->getBogomips() == 0) && ($_bogo !== null)) {
922
                    $dev->setBogomips($_bogo);
923
                }
924
                if (($dev->getVendorId() === null) && ($_vend !== null)) {
925
                    $dev->setVendorId($_vend);
3037 rexy 926
                     if (defined('PSI_SHOW_VIRTUALIZER_INFO') && PSI_SHOW_VIRTUALIZER_INFO && preg_match('/^User Mode Linux/', $_vend)) {
927
                        $this->sys->setVirtualizer("cpuid:UserModeLinux", false);
928
                    }
2770 rexy 929
                }
930
 
3037 rexy 931
                if ($proc !== null) {
2770 rexy 932
                    if (!is_numeric($proc)) {
933
                        $proc = 0;
934
                    }
935
                    // variable speed processors specific code follows
3100 rexy 936
                    if (CommonFunctions::rfts('/sys/devices/system/cpu/cpu'.$proc.'/cpufreq/cpuinfo_cur_freq', $buf, 1, 4096, false)
937
                       || CommonFunctions::rfts('/sys/devices/system/cpu/cpu'.$proc.'/cpufreq/scaling_cur_freq', $buf, 1, 4096, false)) {
938
                        if (round(trim($buf)/1000) > 0) {
939
                            $dev->setCpuSpeed(round(trim($buf)/1000));
940
                            $speedset = true;
941
                        }
2770 rexy 942
                    }
3100 rexy 943
                    if (CommonFunctions::rfts('/sys/devices/system/cpu/cpu'.$proc.'/cpufreq/cpuinfo_max_freq', $buf, 1, 4096, false)
944
                       || CommonFunctions::rfts('/sys/devices/system/cpu/cpu'.$proc.'/cpufreq/scaling_max_freq', $buf, 1, 4096, false)) {
945
                        $dev->setCpuSpeedMax(round(trim($buf)/1000));
2770 rexy 946
                    }
3100 rexy 947
                    if (CommonFunctions::rfts('/sys/devices/system/cpu/cpu'.$proc.'/cpufreq/cpuinfo_min_freq', $buf, 1, 4096, false)
948
                       || CommonFunctions::rfts('/sys/devices/system/cpu/cpu'.$proc.'/cpufreq/scaling_min_freq', $buf, 1, 4096, false)) {
949
                        $dev->setCpuSpeedMin(round(trim($buf)/1000));
2770 rexy 950
                    }
951
                    // variable speed processors specific code ends
952
                    if (PSI_LOAD_BAR) {
953
                            $dev->setLoad($this->_parseProcStat('cpu'.$proc));
954
                    }
955
/*
956
                    if (CommonFunctions::rfts('/proc/acpi/thermal_zone/THRM/temperature', $buf, 1, 4096, false)
957
                       &&  preg_match("/(\S+)\sC$/", $buf, $value)) {
958
                        $dev->setTemp(value[1]);
959
                    }
960
*/
961
                    if (($arch !== null) && ($impl !== null) && ($part !== null)) {
962
                        if (($impl === '0x41')
963
                           && (($_hard === 'BCM2708') || ($_hard === 'BCM2835') || ($_hard === 'BCM2709') || ($_hard === 'BCM2836') || ($_hard === 'BCM2710') || ($_hard === 'BCM2837') || ($_hard === 'BCM2711') || ($_hard === 'BCM2838'))
964
                           && ($_revi !== null)) { // Raspberry Pi detection (instead of 'cat /proc/device-tree/model')
965
                            if ($raslist === null) $raslist = @parse_ini_file(PSI_APP_ROOT."/data/raspberry.ini", true);
3100 rexy 966
                            $oldmach = $this->sys->getMachine();
967
                            if (($oldmach !== '') && preg_match("/^raspberrypi rpi(,.+)/", $oldmach, $machbuf)) {
968
                                $oldmachend = $machbuf[1];
969
                            } else {
970
                                 $oldmachend = '';
971
                            }
2770 rexy 972
                            if ($raslist && !preg_match('/[^0-9a-f]/', $_revi)) {
973
                                if (($revidec = hexdec($_revi)) & 0x800000) {
3100 rexy 974
                                    if (($oldmach === '') || ($oldmachend !== '')) {
2770 rexy 975
                                        $manufacturer = ($revidec >> 16) & 15;
976
                                        if (isset($raslist['manufacturer'][$manufacturer])) {
977
                                            $manuf = ' '.$raslist['manufacturer'][$manufacturer];
978
                                        } else {
979
                                            $manuf = '';
980
                                        }
981
                                        $model = ($revidec >> 4) & 255;
982
                                        if (isset($raslist['model'][$model])) {
3100 rexy 983
                                            $this->sys->setMachine('Raspberry Pi '.$raslist['model'][$model].' (PCB 1.'.($revidec & 15).$manuf.')'.$oldmachend);
2770 rexy 984
                                        } else {
3100 rexy 985
                                            $this->sys->setMachine('Raspberry Pi (PCB 1.'.($revidec & 15).$manuf.')'.$oldmachend);
2770 rexy 986
                                        }
987
                                    }
988
                                } else {
3100 rexy 989
                                    if (($oldmach === '') || ($oldmachend !== '')) {
2770 rexy 990
                                        if (isset($raslist['old'][$revidec & 0x7fffff])) {
3100 rexy 991
                                            $this->sys->setMachine('Raspberry Pi '.$raslist['old'][$revidec & 0x7fffff].$oldmachend);
2770 rexy 992
                                        } else {
3100 rexy 993
                                            $this->sys->setMachine('Raspberry Pi'.$oldmachend);
2770 rexy 994
                                        }
995
                                    }
996
                                }
997
                            }
998
                        } elseif (($_hard !== null) && ($this->sys->getMachine() === '')) { // other ARM hardware
999
                            $this->sys->setMachine($_hard);
1000
                        }
1001
                        if ($cpulist === null) $cpulist = @parse_ini_file(PSI_APP_ROOT."/data/cpus.ini", true);
3037 rexy 1002
                        if ($cpulist && (((($vari !== null) && isset($cpulist['cpu'][$cpufromlist = strtolower($impl.','.$part.','.$vari)]))
1003
                           || isset($cpulist['cpu'][$cpufromlist = strtolower($impl.','.$part)])))) {
2770 rexy 1004
                            if (($cpumodel = $dev->getModel()) !== '') {
3037 rexy 1005
                                $dev->setModel($cpumodel.' - '.$cpulist['cpu'][$cpufromlist]);
2770 rexy 1006
                            } else {
3037 rexy 1007
                                $dev->setModel($cpulist['cpu'][$cpufromlist]);
2770 rexy 1008
                            }
1009
                        }
1010
                    } elseif (($_hard !== null) && ($this->sys->getMachine() === '')) { // other hardware
1011
                        $this->sys->setMachine($_hard);
1012
                    }
1013
 
3037 rexy 1014
                    $cpumodel = $dev->getModel();
1015
                    if (defined('PSI_SHOW_VIRTUALIZER_INFO') && PSI_SHOW_VIRTUALIZER_INFO && ($this->system_detect_virt === null) && preg_match('/^QEMU Virtual CPU version /', $cpumodel)) {
1016
                        $this->sys->setVirtualizer("cpuid:QEMU", false);
2770 rexy 1017
                    }
3037 rexy 1018
                    if ($cpumodel === "") {
1019
                        if (($vendid = $dev->getVendorId()) !== "") {
1020
                            $dev->setModel($vendid);
1021
                        } else {
1022
                            $dev->setModel("unknown");
1023
                        }
1024
                    }
2770 rexy 1025
                    $cpucount++;
1026
                    $this->sys->setCpus($dev);
1027
                }
1028
            }
1029
 
3037 rexy 1030
            $cpudevices = CommonFunctions::findglob('/sys/devices/system/cpu/cpu*/uevent', GLOB_NOSORT);
2770 rexy 1031
            if (is_array($cpudevices) && (($cpustopped = count($cpudevices)-$cpucount) > 0)) {
1032
                for (; $cpustopped > 0; $cpustopped--) {
1033
                    $dev = new CpuDevice();
1034
                    $dev->setModel("stopped");
1035
                    if ($speedset) {
1036
                        $dev->setCpuSpeed(-1);
1037
                    }
1038
                    $this->sys->setCpus($dev);
1039
                }
1040
            }
1041
        }
325 richard 1042
    }
1043
 
2770 rexy 1044
    /**
1045
     * PCI devices
1046
     *
1047
     * @return void
1048
     */
1049
    private function _pci()
1050
    {
1051
        if ($arrResults = Parser::lspci()) {
1052
            foreach ($arrResults as $dev) {
1053
                $this->sys->setPciDevices($dev);
1054
            }
1055
        } elseif (CommonFunctions::rfts('/proc/pci', $strBuf, 0, 4096, false)) {
1056
            $booDevice = false;
1057
            $arrBuf = preg_split("/\n/", $strBuf, -1, PREG_SPLIT_NO_EMPTY);
1058
            foreach ($arrBuf as $strLine) {
1059
                if (preg_match('/^\s*Bus\s/', $strLine)) {
1060
                    $booDevice = true;
1061
                    continue;
1062
                }
1063
                if ($booDevice) {
1064
                    $dev = new HWDevice();
2976 rexy 1065
                    $dev->setName(preg_replace('/\(rev\s[^\)]+\)\.$/', '', trim($strLine)));
2770 rexy 1066
                    $this->sys->setPciDevices($dev);
1067
/*
1068
                    list($strKey, $strValue) = preg_split('/: /', $strLine, 2);
1069
                    if (!preg_match('/bridge/i', $strKey) && !preg_match('/USB/i ', $strKey)) {
1070
                        $dev = new HWDevice();
2976 rexy 1071
                        $dev->setName(preg_replace('/\(rev\s[^\)]+\)\.$/', '', trim($strValue)));
2770 rexy 1072
                        $this->sys->setPciDevices($dev);
1073
                    }
1074
*/
1075
                    $booDevice = false;
1076
                }
1077
            }
1078
        } else {
3037 rexy 1079
            $pcidevices = CommonFunctions::findglob('/sys/bus/pci/devices/*/uevent', GLOB_NOSORT);
2770 rexy 1080
            if (is_array($pcidevices) && (($total = count($pcidevices)) > 0)) {
1081
                $buf = "";
1082
                for ($i = 0; $i < $total; $i++) {
1083
                    if (CommonFunctions::rfts($pcidevices[$i], $buf, 0, 4096, false) && (trim($buf) != "")) {
1084
                        $pcibuf = "";
1085
                        if (preg_match("/^PCI_CLASS=(\S+)/m", trim($buf), $subbuf)) {
1086
                            $pcibuf = "Class ".$subbuf[1].":";
1087
                        }
1088
                        if (preg_match("/^PCI_ID=(\S+)/m", trim($buf), $subbuf)) {
1089
                            $pcibuf .= " Device ".$subbuf[1];
1090
                        }
1091
                        if (preg_match("/^DRIVER=(\S+)/m", trim($buf), $subbuf)) {
1092
                            $pcibuf .= " Driver ".$subbuf[1];
1093
                        }
1094
                        $dev = new HWDevice();
1095
                        if (trim($pcibuf) != "") {
1096
                            $dev->setName(trim($pcibuf));
1097
                        } else {
1098
                            $dev->setName("unknown");
1099
                        }
1100
                        $this->sys->setPciDevices($dev);
1101
                    }
1102
                }
1103
            }
1104
        }
1105
    }
325 richard 1106
 
2770 rexy 1107
    /**
1108
     * IDE devices
1109
     *
1110
     * @return void
1111
     */
1112
    private function _ide()
1113
    {
1114
        $bufd = CommonFunctions::gdc('/proc/ide', false);
1115
        foreach ($bufd as $file) {
1116
            if (preg_match('/^hd/', $file)) {
1117
                $dev = new HWDevice();
1118
                $dev->setName(trim($file));
1119
                if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS && CommonFunctions::rfts("/proc/ide/".$file."/media", $buf, 1)) {
1120
                    if (trim($buf) == 'disk') {
1121
                        if (CommonFunctions::rfts("/proc/ide/".$file."/capacity", $buf, 1, 4096, false) || CommonFunctions::rfts("/sys/block/".$file."/size", $buf, 1, 4096, false)) {
1122
                            $dev->setCapacity(trim($buf) * 512);
1123
                        }
1124
                    }
1125
                }
1126
                if (CommonFunctions::rfts("/proc/ide/".$file."/model", $buf, 1)) {
1127
                    $dev->setName($dev->getName().": ".trim($buf));
1128
                }
1129
                $this->sys->setIdeDevices($dev);
1130
            }
1131
        }
1132
    }
325 richard 1133
 
2770 rexy 1134
    /**
1135
     * SCSI devices
1136
     *
1137
     * @return void
1138
     */
1139
    private function _scsi()
1140
    {
1141
        $getline = 0;
1142
        $device = null;
1143
        $scsiid = null;
1144
        if (CommonFunctions::executeProgram('lsscsi', '-c', $bufr, PSI_DEBUG) || CommonFunctions::rfts('/proc/scsi/scsi', $bufr, 0, 4096, PSI_DEBUG)) {
1145
            $bufe = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY);
1146
            foreach ($bufe as $buf) {
1147
                if (preg_match('/Host: scsi(\d+) Channel: (\d+) Target: (\d+) Lun: (\d+)/i', $buf, $scsiids)
1148
                   || preg_match('/Host: scsi(\d+) Channel: (\d+) Id: (\d+) Lun: (\d+)/i', $buf, $scsiids)) {
1149
                    $scsiid = $scsiids;
1150
                    $getline = 1;
1151
                    continue;
1152
                }
1153
                if ($getline == 1) {
1154
                    preg_match('/Vendor: (.*) Model: (.*) Rev: (.*)/i', $buf, $devices);
1155
                    $getline = 2;
1156
                    $device = $devices;
1157
                    continue;
1158
                }
1159
                if ($getline == 2) {
1160
                    preg_match('/Type:\s+(\S+)/i', $buf, $dev_type);
1161
 
1162
                    $dev = new HWDevice();
1163
                    $dev->setName($device[1].' '.$device[2].' ('.$dev_type[1].')');
1164
 
1165
                    if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS
1166
                       && ($dev_type[1]==='Direct-Access')) {
3037 rexy 1167
                       $sizelist = CommonFunctions::findglob('/sys/bus/scsi/devices/'.intval($scsiid[1]).':'.intval($scsiid[2]).':'.intval($scsiid[3]).':'.intval($scsiid[4]).'/*/*/size', GLOB_NOSORT);
2770 rexy 1168
                       if (is_array($sizelist) && (($total = count($sizelist)) > 0)) {
1169
                           $buf = "";
1170
                           for ($i = 0; $i < $total; $i++) {
1171
                               if (CommonFunctions::rfts($sizelist[$i], $buf, 1, 4096, false) && (($buf=trim($buf)) != "") && ($buf > 0)) {
1172
                                   $dev->setCapacity($buf * 512);
1173
                                   break;
1174
                               }
1175
                           }
1176
                       }
1177
                    }
1178
                    $this->sys->setScsiDevices($dev);
1179
                    $getline = 0;
1180
                }
325 richard 1181
            }
2770 rexy 1182
        }
325 richard 1183
    }
1184
 
2770 rexy 1185
    /**
1186
     * USB devices
1187
     *
1188
     * @return void
1189
     */
3100 rexy 1190
    protected function _usb($bufu = null)
2770 rexy 1191
    {
1192
        $usbarray = array();
3100 rexy 1193
        if ($nobufu = ($bufu === null)) {
1194
            if (CommonFunctions::executeProgram('lsusb', (PSI_OS != 'Android')?'':'2>/dev/null', $bufr, PSI_DEBUG && (PSI_OS != 'Android'), 5) && ($bufr !== "")) {
1195
                $bufe = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY);
1196
                foreach ($bufe as $buf) {
1197
                    $device = preg_split("/ /", $buf, 7);
1198
                    if (((isset($device[6]) && trim($device[6]) != "")) ||
1199
                        ((isset($device[5]) && trim($device[5]) != ""))) {
1200
                        $usbid = intval($device[1]).'-'.intval(trim($device[3], ':')).' '.$device[5];
1201
                        if ((isset($device[6]) && trim($device[6]) != "")) {
1202
                            $usbarray[$usbid]['name'] = trim($device[6]);
1203
                        } else {
1204
                            $usbarray[$usbid]['name'] = 'unknown';
1205
                        }
2770 rexy 1206
                    }
1207
                }
1208
            }
325 richard 1209
 
3100 rexy 1210
            $usbdevices = CommonFunctions::findglob('/sys/bus/usb/devices/*/idProduct', GLOB_NOSORT);
1211
            if (is_array($usbdevices) && (($total = count($usbdevices)) > 0)) {
1212
                for ($i = 0; $i < $total; $i++) {
1213
                    if (CommonFunctions::rfts($usbdevices[$i], $idproduct, 1, 4096, false) && (($idproduct=trim($idproduct)) != "")) { // is readable
1214
                        $busnum = CommonFunctions::rolv($usbdevices[$i], '/\/idProduct$/', '/busnum');
1215
                        $devnum = CommonFunctions::rolv($usbdevices[$i], '/\/idProduct$/', '/devnum');
1216
                        $idvendor = CommonFunctions::rolv($usbdevices[$i], '/\/idProduct$/', '/idVendor');
1217
                        if (($busnum!==null) && ($devnum!==null) && ($idvendor!==null)) {
1218
                            $usbid = intval($busnum).'-'.intval($devnum).' '.$idvendor.':'.$idproduct;
1219
                            $manufacturer = CommonFunctions::rolv($usbdevices[$i], '/\/idProduct$/', '/manufacturer');
1220
                            if ($manufacturer!==null) {
1221
                                $usbarray[$usbid]['manufacturer'] = $manufacturer;
2770 rexy 1222
                            }
3100 rexy 1223
                            $product = CommonFunctions::rolv($usbdevices[$i], '/\/idProduct$/', '/product');
1224
                            if ($product!==null) {
1225
                                $usbarray[$usbid]['product'] = $product;
1226
                            }
1227
                            $speed = CommonFunctions::rolv($usbdevices[$i], '/\/idProduct$/', '/speed');
1228
                            if ($product!==null) {
1229
                                $usbarray[$usbid]['speed'] = $speed;
1230
                            }
1231
                            if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS
1232
                               && defined('PSI_SHOW_DEVICES_SERIAL') && PSI_SHOW_DEVICES_SERIAL) {
1233
                                $serial = CommonFunctions::rolv($usbdevices[$i], '/\/idProduct$/', '/serial');
1234
                                if (($serial!==null) && !preg_match('/\W/', $serial)) {
1235
                                    $usbarray[$usbid]['serial'] = $serial;
1236
                                }
1237
                            }
2770 rexy 1238
                        }
1239
                    }
1240
                }
1241
            }
1242
        }
325 richard 1243
 
3100 rexy 1244
        if (!$nobufu || ((count($usbarray) == 0) && CommonFunctions::rfts('/proc/bus/usb/devices', $bufu, 0, 4096, false))) { // usb-devices
2770 rexy 1245
            $devnum = -1;
3100 rexy 1246
            $bufe = preg_split("/\n/", $bufu, -1, PREG_SPLIT_NO_EMPTY);
2770 rexy 1247
            foreach ($bufe as $buf) {
1248
                if (preg_match('/^T/', $buf)) {
1249
                    $devnum++;
2976 rexy 1250
                    if (preg_match('/\sSpd=([\d\.]+)/', $buf, $bufr)
1251
                       && isset($bufr[1]) && ($bufr[1]!=="")) {
1252
                        $usbarray[$devnum]['speed'] = $bufr[1];
1253
                    }
2770 rexy 1254
                } elseif (preg_match('/^S:/', $buf)) {
1255
                    list($key, $value) = preg_split('/: /', $buf, 2);
1256
                    list($key, $value2) = preg_split('/=/', $value, 2);
1257
                    switch (trim($key)) {
1258
                    case 'Manufacturer':
1259
                        $usbarray[$devnum]['manufacturer'] = trim($value2);
1260
                        break;
1261
                    case 'Product':
1262
                        $usbarray[$devnum]['product'] = trim($value2);
1263
                        break;
1264
                    case 'SerialNumber':
1265
                        if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS
1266
                           && defined('PSI_SHOW_DEVICES_SERIAL') && PSI_SHOW_DEVICES_SERIAL
1267
                           && !preg_match('/\W/', trim($value2))) {
1268
                            $usbarray[$devnum]['serial'] = trim($value2);
3037 rexy 1269
                        }
2770 rexy 1270
                    }
1271
                }
1272
            }
1273
        }
325 richard 1274
 
3100 rexy 1275
        if ($nobufu && (count($usbarray) == 0) && CommonFunctions::rfts('/proc/bus/input/devices', $bufr, 0, 4096, false)) {
2770 rexy 1276
            $devnam = "unknown";
1277
            $bufe = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY);
1278
            foreach ($bufe as $buf) {
1279
                if (preg_match('/^I:\s+(.+)/', $buf, $bufr)
1280
                   && isset($bufr[1]) && (trim($bufr[1])!=="")) {
1281
                    $devnam = trim($bufr[1]);
1282
                    $usbarray[$devnam]['phys'] = 'unknown';
1283
                } elseif (preg_match('/^N:\s+Name="([^"]+)"/', $buf, $bufr2)
1284
                   && isset($bufr2[1]) && (trim($bufr2[1])!=="")) {
1285
                    $usbarray[$devnam]['name'] = trim($bufr2[1]);
1286
                } elseif (preg_match('/^P:\s+Phys=(.*)/', $buf, $bufr2)
1287
                   && isset($bufr2[1]) && (trim($bufr2[1])!=="")) {
1288
                    $usbarray[$devnam]['phys'] = trim($bufr2[1]);
1289
                } elseif (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS
1290
                   && defined('PSI_SHOW_DEVICES_SERIAL') && PSI_SHOW_DEVICES_SERIAL
1291
                   && preg_match('/^U:\s+Uniq=(.+)/', $buf, $bufr2)
1292
                   && isset($bufr2[1]) && (trim($bufr2[1])!=="")) {
1293
                    $usbarray[$devnam]['serial'] = trim($bufr2[1]);
1294
                }
1295
            }
1296
        }
325 richard 1297
 
2770 rexy 1298
        foreach ($usbarray as $usbdev) if (!isset($usbdev['phys']) || preg_match('/^usb-/', $usbdev['phys'])) {
1299
            $dev = new HWDevice();
325 richard 1300
 
2770 rexy 1301
            if (isset($usbdev['manufacturer']) && (($manufacturer=$usbdev['manufacturer']) !== 'no manufacturer')) {
1302
                if (preg_match("/^linux\s/i", $manufacturer)) {
1303
                    $manufacturer = 'Linux Foundation';
1304
                }
1305
                if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS) {
1306
                    $dev->setManufacturer($manufacturer);
1307
                }
1308
            } else {
1309
                $manufacturer = '';
1310
            }
1311
 
1312
            if (isset($usbdev['product'])) {
1313
                $product = $usbdev['product'];
1314
                if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS) {
1315
                    $dev->setProduct($product);
1316
                }
1317
            } else {
1318
                $product = '';
1319
            }
1320
 
2976 rexy 1321
            if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS) {
1322
                if (isset($usbdev['speed'])) {
1323
                    $dev->setSpeed($usbdev['speed']);
1324
                }
1325
                if (defined('PSI_SHOW_DEVICES_SERIAL') && PSI_SHOW_DEVICES_SERIAL
1326
                   && isset($usbdev['serial'])) {
1327
                    $dev->setSerial($usbdev['serial']);
1328
                }
2770 rexy 1329
            }
1330
 
1331
            if (isset($usbdev['name']) && (($name=$usbdev['name']) !== 'unknown')) {
1332
                $dev->setName($name);
1333
            } else {
1334
                if (($newname = trim($manufacturer.' '.$product)) !== '') {
1335
                    $dev->setName($newname);
1336
                } else {
1337
                    $dev->setName('unknown');
1338
                }
1339
            }
1340
 
1341
            $this->sys->setUsbDevices($dev);
1342
        }
325 richard 1343
    }
1344
 
2770 rexy 1345
    /**
1346
     * I2C devices
1347
     *
1348
     * @return void
1349
     */
1350
    protected function _i2c()
1351
    {
3037 rexy 1352
        $i2cdevices = CommonFunctions::findglob('/sys/bus/i2c/devices/*/name', GLOB_NOSORT);
2770 rexy 1353
        if (is_array($i2cdevices) && (($total = count($i2cdevices)) > 0)) {
1354
            $buf = "";
1355
            for ($i = 0; $i < $total; $i++) {
1356
                if (CommonFunctions::rfts($i2cdevices[$i], $buf, 1, 4096, false) && (trim($buf) != "")) {
1357
                    $dev = new HWDevice();
3179 rexy 1358
                    $dev->setName(trim($buf, ": \n\r\t\v\x00"));
2770 rexy 1359
                    $this->sys->setI2cDevices($dev);
1360
                }
1361
            }
1362
        }
1363
    }
325 richard 1364
 
2770 rexy 1365
    /**
1366
     * NVMe devices
1367
     *
1368
     * @return void
1369
     */
1370
    protected function _nvme()
1371
    {
1372
        if (CommonFunctions::executeProgram('nvme', 'list', $bufr, PSI_DEBUG) && ($bufr!="")) {
1373
            $bufe = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY);
1374
            $count = 0;
1375
            $nlocate = array();
1376
            $nsize = array();
1377
            foreach ($bufe as $buf) {
1378
                if ($count == 1) {
1379
                    $locid = 0;
1380
                    $nlocate[0] = 0;
1381
                    $total = strlen($buf);
1382
                    $begin = true;
1383
                    for ($i = 0; $i < $total; $i++) {
1384
                        if ($begin) {
1385
                            if ($buf[$i] !== '-') {
1386
                                $nsize[$locid] = $i - $nlocate[$locid];
1387
                                $locid++;
1388
                                $begin = false;
1389
                            }
1390
                        } else {
1391
                            if ($buf[$i] === '-') {
1392
                                $nlocate[$locid] = $i;
1393
                                $begin = true;
1394
                            }
1395
                        }
1396
                    }
1397
                    if ($begin) {
1398
                        $nsize[$locid] = $i - $nlocate[$locid];
1399
                    }
1400
                } elseif ($count > 1) {
3179 rexy 1401
                    if (isset($nlocate[2]) && isset($nsize[2]) && (($nvname=trim(substr($buf, $nlocate[2], $nsize[2]))) !== '')) {
2770 rexy 1402
                        $dev = new HWDevice();
3179 rexy 1403
                        $dev->setName($nvname);
2770 rexy 1404
                        if (defined('PSI_SHOW_DEVICES_INFOS') && (PSI_SHOW_DEVICES_INFOS)) {
1405
                            if (isset($nlocate[4]) && isset($nsize[4])) {
1406
                                if (preg_match('/\/\s*([0-9\.]+)\s*(B|KB|MB|GB|TB|PB)$/', str_replace(',', '.', trim(substr($buf, $nlocate[4], $nsize[4]))), $tmpbuf)) {
1407
                                    switch ($tmpbuf[2]) {
3037 rexy 1408
                                    case 'B':
1409
                                        $dev->setCapacity($tmpbuf[1]);
1410
                                        break;
1411
                                    case 'KB':
1412
                                        $dev->setCapacity(1000*$tmpbuf[1]);
1413
                                        break;
1414
                                    case 'MB':
1415
                                        $dev->setCapacity(1000*1000*$tmpbuf[1]);
1416
                                        break;
1417
                                    case 'GB':
1418
                                        $dev->setCapacity(1000*1000*1000*$tmpbuf[1]);
1419
                                        break;
1420
                                    case 'TB':
1421
                                        $dev->setCapacity(1000*1000*1000*1000*$tmpbuf[1]);
1422
                                        break;
1423
                                    case 'PB':
1424
                                        $dev->setCapacity(1000*1000*1000*1000*1000*$tmpbuf[1]);
2770 rexy 1425
                                    }
1426
                                }
1427
                            }
1428
                            if (defined('PSI_SHOW_DEVICES_SERIAL') && PSI_SHOW_DEVICES_SERIAL) {
1429
                                if (isset($nlocate[1]) && isset($nsize[1])) {
1430
                                    $dev->setSerial(trim(substr($buf, $nlocate[1], $nsize[1])));
1431
                                }
1432
                            }
1433
                        }
1434
                        $this->sys->setNvmeDevices($dev);
1435
                    }
1436
                }
1437
                $count++;
1438
            }
1439
        }
1440
    }
325 richard 1441
 
2770 rexy 1442
    /**
1443
     * Network devices
1444
     * includes also rx/tx bytes
1445
     *
1446
     * @return void
1447
     */
3100 rexy 1448
    protected function _network($bufr = null)
2770 rexy 1449
    {
3100 rexy 1450
        if (($bufr === null) && CommonFunctions::rfts('/proc/net/dev', $bufr, 0, 4096, PSI_DEBUG)) {
2770 rexy 1451
            $bufe = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY);
1452
            foreach ($bufe as $buf) {
1453
                if (preg_match('/:/', $buf)) {
1454
                    list($dev_name, $stats_list) = preg_split('/:/', $buf, 2);
1455
                    $stats = preg_split('/\s+/', trim($stats_list));
1456
                    $dev = new NetDevice();
1457
                    $dev->setName(trim($dev_name));
1458
                    $dev->setRxBytes($stats[0]);
1459
                    $dev->setTxBytes($stats[8]);
1460
                    $dev->setErrors($stats[2] + $stats[10]);
1461
                    $dev->setDrops($stats[3] + $stats[11]);
3179 rexy 1462
                    if (((defined('PSI_SHOW_NETWORK_INFOS') && (PSI_SHOW_NETWORK_INFOS)) || (defined('PSI_SHOW_NETWORK_BRIDGE') && PSI_SHOW_NETWORK_BRIDGE))
1463
                       && CommonFunctions::executeProgram('ip', 'addr show '.trim($dev_name), $bufr2, PSI_DEBUG) && (trim($bufr2)!="")) {
1464
                        if (defined('PSI_SHOW_NETWORK_BRIDGE') && PSI_SHOW_NETWORK_BRIDGE && preg_match("/^\d+:\s+([^\s:@]+).+\s+master\s+(\S+)/", $bufr2, $brbufr)) {
1465
                            $dev->setBridge($brbufr[2]);
1466
                        }
1467
                    } else {
1468
                        $bufr2 = "";
1469
                    }
2770 rexy 1470
                    if (defined('PSI_SHOW_NETWORK_INFOS') && (PSI_SHOW_NETWORK_INFOS)) {
1471
                        $macaddr = "";
3179 rexy 1472
                        if (($bufr2!="") || CommonFunctions::executeProgram('ifconfig', trim($dev_name).' 2>/dev/null', $bufr2, PSI_DEBUG)) {
2770 rexy 1473
                            $bufe2 = preg_split("/\n/", $bufr2, -1, PREG_SPLIT_NO_EMPTY);
1474
                            foreach ($bufe2 as $buf2) {
1475
//                                if (preg_match('/^'.trim($dev_name).'\s+Link\sencap:Ethernet\s+HWaddr\s(\S+)/i', $buf2, $ar_buf2)
1476
                                if (preg_match('/\s+encap:Ethernet\s+HWaddr\s(\S+)/i', $buf2, $ar_buf2)
1477
                                   || preg_match('/\s+encap:UNSPEC\s+HWaddr\s(\S+)-00-00-00-00-00-00-00-00-00-00\s*$/i', $buf2, $ar_buf2)
1478
                                   || preg_match('/^\s+ether\s+(\S+)\s+txqueuelen/i', $buf2, $ar_buf2)
2976 rexy 1479
                                   || preg_match('/^\s+link\/\S+\s+(\S+)\s+brd/i', $buf2, $ar_buf2)
1480
                                   || preg_match('/^\s+link\/\S+\s+(\S+)$/i', $buf2, $ar_buf2)) {
2770 rexy 1481
                                    if (!defined('PSI_HIDE_NETWORK_MACADDR') || !PSI_HIDE_NETWORK_MACADDR) {
1482
                                        $macaddr = preg_replace('/:/', '-', strtoupper($ar_buf2[1]));
3037 rexy 1483
                                        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
2770 rexy 1484
                                            $macaddr = "";
1485
                                        }
1486
                                    }
1487
                                } elseif (preg_match('/^\s+inet\saddr:(\S+)\s+P-t-P:(\S+)/i', $buf2, $ar_buf2)
1488
                                       || preg_match('/^\s+inet\s+(\S+)\s+netmask.+destination\s+(\S+)/i', $buf2, $ar_buf2)
3179 rexy 1489
                                       || preg_match('/^\s+inet\s+([^\/\s]+).*peer\s+([^\/\s]+).*\s+scope\s((global)|(host))/i', $buf2, $ar_buf2)
1490
                                       /*|| preg_match('/^\s+link\/sit\s+([^\/\s]+).*peer\s+([^\/\s]+)/i', $buf2, $ar_buf2)*/) {
2770 rexy 1491
                                    if ($ar_buf2[1] != $ar_buf2[2]) {
1492
                                        $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1].";:".$ar_buf2[2]);
1493
                                    } else {
1494
                                        $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1]);
1495
                                    }
1496
                                } elseif ((preg_match('/^\s+inet\saddr:(\S+)/i', $buf2, $ar_buf2)
1497
                                   || preg_match('/^\s+inet\s+(\S+)\s+netmask/i', $buf2, $ar_buf2)
1498
                                   || preg_match('/^'.trim($dev_name).':\s+ip\s+(\S+)\s+mask/i', $buf2, $ar_buf2)
1499
                                   || preg_match('/^\s+inet6\saddr:\s([^\/\s]+)(.+)\s+Scope:[GH]/i', $buf2, $ar_buf2)
1500
                                   || preg_match('/^\s+inet6\s+(\S+)\s+prefixlen(.+)((<global>)|(<host>))/i', $buf2, $ar_buf2)
3100 rexy 1501
                                   || preg_match('/^\s+inet6?\s+([^\/\s]+).*\s+scope\s((global)|(host))/i', $buf2, $ar_buf2)
1502
                                   || preg_match('/^\s+inet\saddr6:\s+(\S+)\s+prefixlen(.+)/i', $buf2, $ar_buf2))
2770 rexy 1503
                                   && ($ar_buf2[1]!="::") && !preg_match('/^fe80::/i', $ar_buf2[1])) {
1504
                                    $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').strtolower($ar_buf2[1]));
1505
                                }
1506
                            }
1507
                        }
1508
                        if ($macaddr != "") {
1509
                            $dev->setInfo($macaddr.($dev->getInfo()?';'.$dev->getInfo():''));
1510
                        }
2976 rexy 1511
                        if ((!CommonFunctions::rfts('/sys/class/net/'.trim($dev_name).'/operstate', $buf, 1, 4096, false) || (($down=strtolower(trim($buf)))=="") || ($down!=="down")) &&
1512
                           (CommonFunctions::rfts('/sys/class/net/'.trim($dev_name).'/speed', $buf, 1, 4096, false) && (($speed=trim($buf))!="") && ($buf > 0) && ($buf < 65535))) {
2770 rexy 1513
                            if ($speed > 1000) {
1514
                                $speed = $speed/1000;
1515
                                $unit = "G";
1516
                            } else {
1517
                                $unit = "M";
1518
                            }
1519
                            if (CommonFunctions::rfts('/sys/class/net/'.trim($dev_name).'/duplex', $buf, 1, 4096, false) && (($duplex=strtolower(trim($buf)))!="") && ($duplex!='unknown')) {
1520
                                $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$speed.$unit.'b/s '.$duplex);
1521
                            } else {
1522
                                $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$speed.$unit.'b/s');
1523
                            }
1524
                        }
1525
                    }
1526
                    $this->sys->setNetDevices($dev);
1527
                }
1528
            }
3100 rexy 1529
        } elseif (($bufr === null) && CommonFunctions::executeProgram('ip', 'addr show', $bufr, PSI_DEBUG) && ($bufr!="")) {
2770 rexy 1530
            $lines = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY);
1531
            $was = false;
1532
            $macaddr = "";
1533
            $speedinfo = "";
1534
            $dev = null;
1535
            foreach ($lines as $line) {
3179 rexy 1536
                if (preg_match("/^\d+:\s+([^\s:@]+)(.*)/", $line, $ar_buf)) {
2770 rexy 1537
                    if ($was) {
1538
                        if ($macaddr != "") {
1539
                            $dev->setInfo($macaddr.($dev->getInfo()?';'.$dev->getInfo():''));
1540
                        }
1541
                        if ($speedinfo != "") {
1542
                            $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$speedinfo);
1543
                        }
1544
                        $this->sys->setNetDevices($dev);
1545
                    }
1546
                    $speedinfo = "";
1547
                    $macaddr = "";
1548
                    $dev = new NetDevice();
1549
                    $dev->setName($ar_buf[1]);
3179 rexy 1550
                    if (defined('PSI_SHOW_NETWORK_BRIDGE') && PSI_SHOW_NETWORK_BRIDGE
1551
                       && isset($ar_buf[2]) && (($ar_buf[2] = trim($ar_buf[2])) !=="") && preg_match("/\s+master\s+(\S+)/", $ar_buf[2], $bufr2)) {
1552
                        $dev->setBridge($bufr2[1]);
1553
                    }
1554
                    if (CommonFunctions::executeProgram('ip', '-s link show '.$ar_buf[1], $bufr2, false) && ($bufr2!="")
2770 rexy 1555
                       && 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)) {
1556
                        $dev->setRxBytes($ar_buf2[1]);
1557
                        $dev->setTxBytes($ar_buf2[4]);
1558
                        $dev->setErrors($ar_buf2[2]+$ar_buf2[5]);
1559
                        $dev->setDrops($ar_buf2[3]+$ar_buf2[6]);
3179 rexy 1560
                    } elseif (CommonFunctions::executeProgram('ifconfig', $ar_buf[1], $bufr2, false) && ($bufr2!="")) {
1561
                        if (preg_match('/\sRX bytes:(\d+)\s/im', $bufr2, $ar_buf2)) {
1562
                            $dev->setRxBytes($ar_buf2[1]);
1563
                        }
1564
                        if (preg_match('/\sTX bytes:(\d+)\s/im', $bufr2, $ar_buf2)) {
1565
                            $dev->setTxBytes($ar_buf2[1]);
1566
                        }
1567
                        $errors = 0;
1568
                        $drops = 0;
1569
                        if (preg_match('/\sRX packets:\d+\serrors:(\d+)\sdropped:(\d+)/im', $bufr2, $ar_buf2)) {
1570
                            $errors +=$ar_buf2[1];
1571
                            $drops +=$ar_buf2[2];
1572
                        }
1573
                        if (preg_match('/\sTX packets:\d+\serrors:(\d+)\sdropped:(\d+)/im', $bufr2, $ar_buf2)) {
1574
                            $errors +=$ar_buf2[1];
1575
                            $drops +=$ar_buf2[2];
1576
                        }
1577
                        $dev->setErrors($errors);
1578
                        $dev->setDrops($drops);
2770 rexy 1579
                    }
1580
                    $was = true;
1581
                    if (defined('PSI_SHOW_NETWORK_INFOS') && (PSI_SHOW_NETWORK_INFOS)) {
2976 rexy 1582
                        if ((!CommonFunctions::rfts('/sys/class/net/'.$ar_buf[1].'/operstate', $buf, 1, 4096, false) || (($down=strtolower(trim($buf)))=="") || ($down!=="down")) &&
1583
                           (CommonFunctions::rfts('/sys/class/net/'.$ar_buf[1].'/speed', $buf, 1, 4096, false) && (($speed=trim($buf))!="") && ($buf > 0) && ($buf < 65535))) {
2770 rexy 1584
                            if ($speed > 1000) {
1585
                                $speed = $speed/1000;
1586
                                $unit = "G";
1587
                            } else {
1588
                                $unit = "M";
1589
                            }
2976 rexy 1590
                            if (CommonFunctions::rfts('/sys/class/net/'.$ar_buf[1].'/duplex', $buf, 1, 4096, false) && (($duplex=strtolower(trim($buf)))!="") && ($duplex!='unknown')) {
1591
                                $speedinfo = $speed.$unit.'b/s '.$duplex;
2770 rexy 1592
                            } else {
1593
                                $speedinfo = $speed.$unit.'b/s';
1594
                            }
1595
                        }
1596
                    }
1597
                } else {
1598
                    if ($was) {
1599
                        if (defined('PSI_SHOW_NETWORK_INFOS') && (PSI_SHOW_NETWORK_INFOS)) {
2976 rexy 1600
                            if (preg_match('/^\s+link\/\S+\s+(\S+)\s+brd/i', $line, $ar_buf2)
1601
                               || preg_match('/^\s+link\/\S+\s+(\S+)$/i', $line, $ar_buf2)) {
3037 rexy 1602
                                if (!defined('PSI_HIDE_NETWORK_MACADDR') || !PSI_HIDE_NETWORK_MACADDR) {
1603
                                    $macaddr = preg_replace('/:/', '-', strtoupper($ar_buf2[1]));
1604
                                    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
1605
                                        $macaddr = "";
1606
                                    }
1607
                                }
3179 rexy 1608
                            } elseif (preg_match('/^\s+inet\s+([^\/\s]+).*peer\s+([^\/\s]+).*\s+scope\s((global)|(host))/i', $line, $ar_buf2)
1609
                                     /*|| preg_match('/^\s+link\/sit\s+([^\/\s]+).*peer\s+([^\/\s]+)/i', $line, $ar_buf2)*/) {
2770 rexy 1610
                                if ($ar_buf2[1] != $ar_buf2[2]) {
1611
                                     $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1].";:".$ar_buf2[2]);
1612
                                } else {
1613
                                     $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1]);
1614
                                }
1615
                            } elseif (preg_match('/^\s+inet6?\s+([^\/\s]+).*\s+scope\s((global)|(host))/i', $line, $ar_buf2)
1616
                                     && ($ar_buf2[1]!="::") && !preg_match('/^fe80::/i', $ar_buf2[1])) {
1617
                                $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').strtolower($ar_buf2[1]));
1618
                            }
1619
                        }
1620
                    }
1621
                }
1622
            }
1623
            if ($was) {
1624
                if ($macaddr != "") {
1625
                    $dev->setInfo($macaddr.($dev->getInfo()?';'.$dev->getInfo():''));
1626
                }
1627
                if ($speedinfo != "") {
1628
                    $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$speedinfo);
1629
                }
1630
                $this->sys->setNetDevices($dev);
1631
            }
3100 rexy 1632
        } elseif (($bufr !== null) || CommonFunctions::executeProgram('ifconfig', '-a', $bufr, PSI_DEBUG)) {
2770 rexy 1633
            $lines = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY);
1634
            $was = false;
1635
            $errors = 0;
1636
            $drops = 0;
1637
            $macaddr = "";
1638
            $speedinfo = "";
1639
            $dev = null;
1640
            foreach ($lines as $line) {
1641
                if (preg_match("/^([^\s:]+)/", $line, $ar_buf)) {
1642
                    if ($was) {
1643
                        $dev->setErrors($errors);
1644
                        $dev->setDrops($drops);
1645
                        if ($macaddr != "") {
1646
                            $dev->setInfo($macaddr.($dev->getInfo()?';'.$dev->getInfo():''));
1647
                        }
1648
                        if ($speedinfo != "") {
1649
                            $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$speedinfo);
1650
                        }
1651
                        $this->sys->setNetDevices($dev);
1652
                    }
1653
                    $errors = 0;
1654
                    $drops = 0;
1655
                    $speedinfo = "";
1656
                    $macaddr = "";
1657
                    $dev = new NetDevice();
1658
                    $dev->setName($ar_buf[1]);
1659
                    $was = true;
1660
                    if (defined('PSI_SHOW_NETWORK_INFOS') && (PSI_SHOW_NETWORK_INFOS)) {
2976 rexy 1661
                        if ((!CommonFunctions::rfts('/sys/class/net/'.$ar_buf[1].'/operstate', $buf, 1, 4096, false) || (($down=strtolower(trim($buf)))=="") || ($down!=="down")) &&
1662
                           (CommonFunctions::rfts('/sys/class/net/'.$ar_buf[1].'/speed', $buf, 1, 4096, false) && (($speed=trim($buf))!="") && ($buf > 0) && ($buf < 65535))) {
2770 rexy 1663
                            if ($speed > 1000) {
1664
                                $speed = $speed/1000;
1665
                                $unit = "G";
1666
                            } else {
1667
                                $unit = "M";
1668
                            }
2976 rexy 1669
                            if (CommonFunctions::rfts('/sys/class/net/'.$ar_buf[1].'/duplex', $buf, 1, 4096, false) && (($duplex=strtolower(trim($buf)))!="") && ($duplex!='unknown')) {
1670
                                $speedinfo = $speed.$unit.'b/s '.$duplex;
2770 rexy 1671
                            } else {
1672
                                $speedinfo = $speed.$unit.'b/s';
1673
                            }
1674
                        }
2976 rexy 1675
                        if (preg_match('/^'.$ar_buf[1].'\s+Link\sencap:Ethernet\s+HWaddr\s(\S+)/i', $line, $ar_buf2)
1676
                           || 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)) {
1677
                            if (!defined('PSI_HIDE_NETWORK_MACADDR') || !PSI_HIDE_NETWORK_MACADDR) {
1678
                                $macaddr = preg_replace('/:/', '-', strtoupper($ar_buf2[1]));
1679
                                if ($macaddr === '00-00-00-00-00-00') { // empty
1680
                                    $macaddr = "";
1681
                                }
1682
                            }
1683
                        } elseif (preg_match('/^'.$ar_buf[1].':\s+ip\s+(\S+)\s+mask/i', $line, $ar_buf2))
2770 rexy 1684
                            $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1]);
1685
                    }
1686
                } else {
1687
                    if ($was) {
1688
                        if (preg_match('/\sRX bytes:(\d+)\s/i', $line, $ar_buf2)) {
1689
                            $dev->setRxBytes($ar_buf2[1]);
1690
                        }
1691
                        if (preg_match('/\sTX bytes:(\d+)\s/i', $line, $ar_buf2)) {
1692
                            $dev->setTxBytes($ar_buf2[1]);
1693
                        }
325 richard 1694
 
2770 rexy 1695
                        if (preg_match('/\sRX packets:\d+\serrors:(\d+)\sdropped:(\d+)/i', $line, $ar_buf2)) {
1696
                            $errors +=$ar_buf2[1];
1697
                            $drops +=$ar_buf2[2];
1698
                        } elseif (preg_match('/\sTX packets:\d+\serrors:(\d+)\sdropped:(\d+)/i', $line, $ar_buf2)) {
1699
                            $errors +=$ar_buf2[1];
1700
                            $drops +=$ar_buf2[2];
1701
                        }
1702
 
1703
                        if (defined('PSI_SHOW_NETWORK_INFOS') && (PSI_SHOW_NETWORK_INFOS)) {
1704
                            if (preg_match('/\s+encap:Ethernet\s+HWaddr\s(\S+)/i', $line, $ar_buf2)
2976 rexy 1705
                             || preg_match('/\s+encap:UNSPEC\s+HWaddr\s(\S+)-00-00-00-00-00-00-00-00-00-00\s*$/i', $line, $ar_buf2)
2770 rexy 1706
                             || preg_match('/^\s+ether\s+(\S+)\s+txqueuelen/i', $line, $ar_buf2)) {
2976 rexy 1707
                                if (!defined('PSI_HIDE_NETWORK_MACADDR') || !PSI_HIDE_NETWORK_MACADDR) {
1708
                                    $macaddr = preg_replace('/:/', '-', strtoupper($ar_buf2[1]));
1709
                                    if ($macaddr === '00-00-00-00-00-00') { // empty
1710
                                        $macaddr = "";
1711
                                    }
1712
                                }
2770 rexy 1713
                            } elseif (preg_match('/^\s+inet\saddr:(\S+)\s+P-t-P:(\S+)/i', $line, $ar_buf2)
1714
                                  || preg_match('/^\s+inet\s+(\S+)\s+netmask.+destination\s+(\S+)/i', $line, $ar_buf2)) {
1715
                                if ($ar_buf2[1] != $ar_buf2[2]) {
1716
                                     $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1].";:".$ar_buf2[2]);
1717
                                } else {
1718
                                     $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1]);
1719
                                }
1720
                            } elseif ((preg_match('/^\s+inet\saddr:(\S+)/i', $line, $ar_buf2)
1721
                                  || preg_match('/^\s+inet\s+(\S+)\s+netmask/i', $line, $ar_buf2)
1722
                                  || preg_match('/^\s+inet6\saddr:\s([^\/\s]+)(.+)\s+Scope:[GH]/i', $line, $ar_buf2)
3100 rexy 1723
                                  || preg_match('/^\s+inet6\s+(\S+)\s+prefixlen(.+)((<global>)|(<host>))/i', $line, $ar_buf2)
1724
                                  || preg_match('/^\s+inet\saddr6:\s+(\S+)\s+prefixlen(.+)/i', $line, $ar_buf2))
2770 rexy 1725
                                  && ($ar_buf2[1]!="::") && !preg_match('/^fe80::/i', $ar_buf2[1])) {
1726
                                $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').strtolower($ar_buf2[1]));
1727
                            }
1728
                        }
1729
                    }
1730
                }
1731
            }
1732
            if ($was) {
1733
                $dev->setErrors($errors);
1734
                $dev->setDrops($drops);
1735
                if ($macaddr != "") {
1736
                    $dev->setInfo($macaddr.($dev->getInfo()?';'.$dev->getInfo():''));
1737
                }
1738
                if ($speedinfo != "") {
1739
                    $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$speedinfo);
1740
                }
1741
                $this->sys->setNetDevices($dev);
1742
            }
1743
        }
325 richard 1744
    }
1745
 
2770 rexy 1746
    /**
1747
     * Physical memory information and Swap Space information
1748
     *
1749
     * @return void
1750
     */
3100 rexy 1751
    protected function _memory($mbuf = null, $sbuf = null)
2770 rexy 1752
    {
3100 rexy 1753
        if (($mbuf !== null) || CommonFunctions::rfts('/proc/meminfo', $mbuf)) {
3037 rexy 1754
            $swaptotal = null;
1755
            $swapfree = null;
2770 rexy 1756
            $bufe = preg_split("/\n/", $mbuf, -1, PREG_SPLIT_NO_EMPTY);
1757
            foreach ($bufe as $buf) {
1758
                if (preg_match('/^MemTotal:\s+(\d+)\s*kB/i', $buf, $ar_buf)) {
1759
                    $this->sys->setMemTotal($ar_buf[1] * 1024);
1760
                } elseif (preg_match('/^MemFree:\s+(\d+)\s*kB/i', $buf, $ar_buf)) {
1761
                    $this->sys->setMemFree($ar_buf[1] * 1024);
1762
                } elseif (preg_match('/^Cached:\s+(\d+)\s*kB/i', $buf, $ar_buf)) {
1763
                    $this->sys->setMemCache($ar_buf[1] * 1024);
1764
                } elseif (preg_match('/^Buffers:\s+(\d+)\s*kB/i', $buf, $ar_buf)) {
1765
                    $this->sys->setMemBuffer($ar_buf[1] * 1024);
3037 rexy 1766
                } elseif (preg_match('/^SwapTotal:\s+(\d+)\s*kB/i', $buf, $ar_buf)) {
1767
                    $swaptotal = $ar_buf[1] * 1024;
1768
                } elseif (preg_match('/^SwapFree:\s+(\d+)\s*kB/i', $buf, $ar_buf)) {
1769
                    $swapfree = $ar_buf[1] * 1024;
2770 rexy 1770
                }
1771
            }
1772
            $this->sys->setMemUsed($this->sys->getMemTotal() - $this->sys->getMemFree());
1773
            // values for splitting memory usage
3037 rexy 1774
            if (($this->sys->getMemCache() !== null) && ($this->sys->getMemBuffer() !== null)) {
2770 rexy 1775
                $this->sys->setMemApplication($this->sys->getMemUsed() - $this->sys->getMemCache() - $this->sys->getMemBuffer());
1776
            }
3100 rexy 1777
            if (($sbuf !== null) || CommonFunctions::rfts('/proc/swaps', $sbuf, 0, 4096, false)) {
2770 rexy 1778
                $swaps = preg_split("/\n/", $sbuf, -1, PREG_SPLIT_NO_EMPTY);
1779
                unset($swaps[0]);
1780
                foreach ($swaps as $swap) {
1781
                    $ar_buf = preg_split('/\s+/', $swap, 5);
1782
                    $dev = new DiskDevice();
1783
                    $dev->setMountPoint($ar_buf[0]);
1784
                    $dev->setName("SWAP");
1785
                    $dev->setTotal($ar_buf[2] * 1024);
1786
                    $dev->setUsed($ar_buf[3] * 1024);
1787
                    $dev->setFree($dev->getTotal() - $dev->getUsed());
1788
                    $this->sys->setSwapDevices($dev);
1789
                }
3037 rexy 1790
            } elseif (($swaptotal !== null) && ($swapfree !== null) && ($swaptotal > 0)) {
1791
                    $dev = new DiskDevice();
1792
                    $dev->setName("SWAP");
1793
                    $dev->setTotal($swaptotal);
1794
                    $dev->setFree($swapfree);
1795
                    $dev->setUsed($dev->getTotal() - $dev->getFree());
1796
                    $this->sys->setSwapDevices($dev);
2770 rexy 1797
            }
1798
        }
1799
    }
325 richard 1800
 
2770 rexy 1801
    /**
1802
     * filesystem information
1803
     *
1804
     * @return void
1805
     */
3100 rexy 1806
    protected function _filesystems()
2770 rexy 1807
    {
1808
        $df_args = "";
1809
        $hideFstypes = array();
1810
        if (defined('PSI_HIDE_FS_TYPES') && is_string(PSI_HIDE_FS_TYPES)) {
1811
            if (preg_match(ARRAY_EXP, PSI_HIDE_FS_TYPES)) {
1812
                $hideFstypes = eval(PSI_HIDE_FS_TYPES);
1813
            } else {
1814
                $hideFstypes = array(PSI_HIDE_FS_TYPES);
1815
            }
1816
        }
1817
        foreach ($hideFstypes as $Fstype) {
1818
            $df_args .= "-x $Fstype ";
1819
        }
1820
        if ($df_args !== "") {
3037 rexy 1821
            $df_args = trim($df_args); // trim spaces
2770 rexy 1822
            $arrResult = Parser::df("-P $df_args 2>/dev/null");
1823
        } else {
1824
            $arrResult = Parser::df("-P 2>/dev/null");
1825
        }
1826
        foreach ($arrResult as $dev) {
1827
            $this->sys->setDiskDevices($dev);
1828
        }
1829
    }
325 richard 1830
 
2770 rexy 1831
    /**
1832
     * Distribution
1833
     *
1834
     * @return void
1835
     */
1836
    protected function _distro()
1837
    {
1838
        $this->sys->setDistribution("Linux");
1839
        $list = @parse_ini_file(PSI_APP_ROOT."/data/distros.ini", true);
1840
        if (!$list) {
1841
            return;
1842
        }
3179 rexy 1843
        $_ignore_lsb_release = false;
1844
        $_Distrib = "";
1845
        $_DistribIcon = "";
2770 rexy 1846
        // We have the '2>/dev/null' because Ubuntu gives an error on this command which causes the distro to be unknown
3037 rexy 1847
        if (CommonFunctions::executeProgram('lsb_release', '-a 2>/dev/null', $distro_info, PSI_DEBUG) && strlen($distro_info) > 0) {
1848
            $distro_tmp = preg_split("/\r?\n/", $distro_info, -1, PREG_SPLIT_NO_EMPTY);
2770 rexy 1849
            foreach ($distro_tmp as $info) {
1850
                $info_tmp = preg_split('/:/', $info, 2);
3037 rexy 1851
                if (isset($distro_tmp[0]) && ($distro_tmp[0] !== null) && (trim($distro_tmp[0]) != "") &&
1852
                     isset($distro_tmp[1]) && ($distro_tmp[1] !== null) && (trim($distro_tmp[1]) != "")) {
2770 rexy 1853
                    $distro[trim($info_tmp[0])] = trim($info_tmp[1]);
1854
                }
1855
            }
3179 rexy 1856
 
2770 rexy 1857
            if (!isset($distro['Distributor ID']) && !isset($distro['Description'])) { // Systems like StartOS
3037 rexy 1858
                if (isset($distro_tmp[0]) && ($distro_tmp[0] !== null) && (trim($distro_tmp[0]) != "")) {
3179 rexy 1859
                    $_Distrib = trim($distro_tmp[0]);
2770 rexy 1860
                    if (preg_match('/^(\S+)\s*/', $distro_tmp[0], $id_buf)
3179 rexy 1861
                        && isset($list[strtolower(trim($id_buf[1]))]['Image'])) {
1862
                            $_DistribIcon = $list[strtolower(trim($id_buf[1]))]['Image'];
1863
                            // set ignore lsb_release for some distributions
1864
                            if (isset($list[strtolower(trim($id_buf[1]))]['Test']) && ($list[strtolower(trim($id_buf[1]))]['Test'] === "nolsbfirst")) $_ignore_lsb_release = true;
2770 rexy 1865
                    }
1866
                }
1867
            } else {
3179 rexy 1868
                if (isset($distro['Description'])) {
1869
                   if (preg_match('/^NAME=\s*"?([^"\r\n]+)"?\s*$/', $distro['Description'], $name_tmp)) {
1870
                       $distro['Description'] = trim($name_tmp[1]);
1871
                   } elseif (($distro['Description']==="Rolling Release") && isset($distro['Distributor ID']) && ($distro['Distributor ID'] != "n/a")) {
1872
                       $distro['Description'] = $distro['Distributor ID']." ".$distro['Description'];
1873
                   }
3037 rexy 1874
                }
2770 rexy 1875
                if (isset($distro['Description'])
1876
                   && ($distro['Description'] != "n/a")
1877
                   && (!isset($distro['Distributor ID'])
1878
                   || (($distro['Distributor ID'] != "n/a")
1879
                   && ($distro['Description'] != $distro['Distributor ID'])))) {
3179 rexy 1880
                    $_Distrib = $distro['Description'];
2770 rexy 1881
                    if (isset($distro['Release']) && ($distro['Release'] != "n/a")
1882
                       && ($distro['Release'] != $distro['Description']) && strstr($distro['Release'], ".")){
1883
                        if (preg_match("/^(\d+)\.[0]+$/", $distro['Release'], $match_buf)) {
1884
                            $tofind = $match_buf[1];
1885
                        } else {
1886
                            $tofind = $distro['Release'];
1887
                        }
1888
                        if (!preg_match("/^".$tofind."[\s\.]|[\(\[]".$tofind."[\.\)\]]|\s".$tofind."$|\s".$tofind."[\s\.]/", $distro['Description'])) {
3179 rexy 1889
                            $_Distrib .= " ".$distro['Release'];
2770 rexy 1890
                        }
1891
                    }
3037 rexy 1892
                } elseif (isset($distro['Distributor ID'])) {
1893
                    if ($distro['Distributor ID'] != "n/a") {
3179 rexy 1894
                        $_Distrib = $distro['Distributor ID'];
3037 rexy 1895
                        if (isset($distro['Release']) && ($distro['Release'] != "n/a")) {
3179 rexy 1896
                            $_Distrib .= " ".$distro['Release'];
3037 rexy 1897
                        }
1898
                        if (isset($distro['Codename']) && ($distro['Codename'] != "n/a")) {
3179 rexy 1899
                            $_Distrib .= " (".$distro['Codename'].")";
3037 rexy 1900
                        }
1901
                    } elseif (isset($distro['Description']) && ($distro['Description'] != "n/a")) {
3179 rexy 1902
                        $_Distrib = $distro['Description'];
2770 rexy 1903
                    }
1904
                }
3037 rexy 1905
                if (isset($distro['Distributor ID'])) {
1906
                    $distrib = $distro['Distributor ID'];
3179 rexy 1907
                    $distrib2 = $distrib;
1908
                    $distrib3 = $distrib;
3037 rexy 1909
                    if (isset($distro['Description'])) {
1910
                        $distarr = preg_split("/\s/", $distro['Description'], -1, PREG_SPLIT_NO_EMPTY);
1911
                        if (isset($distarr[0])) {
1912
                            if ($distrib != "n/a") {
3179 rexy 1913
                                $distrib2 .= ' '.$distarr[0];
3037 rexy 1914
                            } else {
3179 rexy 1915
                                $distrib2 = $distarr[0];
3037 rexy 1916
                            }
1917
                        }
3179 rexy 1918
                        if (isset($distarr[1])) {
1919
                            if ($distrib != "n/a") {
1920
                                $distrib3 .= ' '.$distarr[0].' '.$distarr[1];
1921
                            } else {
1922
                                $distrib3 = $distarr[0].' '.$distarr[1];
1923
                            }
1924
                        }
2770 rexy 1925
                    }
3179 rexy 1926
                    if (($distrib!==$distrib3) && isset($list[strtolower($distrib3)]['Image'])) {
1927
                        $_DistribIcon = $list[strtolower($distrib3)]['Image'];
1928
                        // set ignore lsb_release for some distributions
1929
                        if (isset($list[strtolower($distrib3)]['Test']) && ($list[strtolower($distrib3)]['Test'] === "nolsbfirst")) $_ignore_lsb_release = true;
1930
                    } elseif (($distrib!==$distrib2) && isset($list[strtolower($distrib2)]['Image'])) {
1931
                        $_DistribIcon = $list[strtolower($distrib2)]['Image'];
1932
                        // set ignore lsb_release for some distributions
1933
                        if (isset($list[strtolower($distrib2)]['Test']) && ($list[strtolower($distrib2)]['Test'] === "nolsbfirst")) $_ignore_lsb_release = true;
1934
                    } elseif (($distrib!=="n/a") && isset($list[strtolower($distrib)]['Image'])) {
1935
                        $_DistribIcon = $list[strtolower($distrib)]['Image'];
1936
                        // set ignore lsb_release for some distributions
1937
                        if (isset($list[strtolower($distrib)]['Test']) && ($list[strtolower($distrib)]['Test'] === "nolsbfirst")) $_ignore_lsb_release = true;
3037 rexy 1938
                    }
2770 rexy 1939
                }
1940
            }
3179 rexy 1941
        }
1942
 
1943
        if (!$_ignore_lsb_release) {  // don't ignore lsb_release
1944
            if ($_Distrib !== "") $this->sys->setDistribution(preg_replace("/ - Version:| Build:| Release| version| build| based in Ubuntu/i", "", $_Distrib));
1945
            if ($_DistribIcon !== "") $this->sys->setDistributionIcon($_DistribIcon);
1946
        }
1947
 
1948
        // if the distribution is still unknown
1949
        if ($this->sys->getDistribution() == "Linux") {
2770 rexy 1950
            /* default error handler */
1951
            if (function_exists('errorHandlerPsi')) {
1952
                restore_error_handler();
1953
            }
1954
            /* fatal errors only */
1955
            $old_err_rep = error_reporting();
1956
            error_reporting(E_ERROR);
325 richard 1957
 
2770 rexy 1958
            // Fall back in case 'lsb_release' does not exist but exist /etc/lsb-release
1959
            if (CommonFunctions::fileexists($filename="/etc/lsb-release")
1960
               && CommonFunctions::rfts($filename, $buf, 0, 4096, false)
3179 rexy 1961
               && (preg_match('/^DISTRIB_ID="?([^"\r\n]+)/m', $buf, $id_buf) || preg_match('/^DISTRIB_DESCRIPTION="?([^"\r\n]+)/m', $buf, $id_buf))) {
3037 rexy 1962
                if (preg_match('/^DISTRIB_DESCRIPTION="?([^"\r\n]+)/m', $buf, $desc_buf)
2770 rexy 1963
                   && (trim($desc_buf[1])!=trim($id_buf[1]))) {
3179 rexy 1964
                    if ($desc_buf[1]==="Rolling Release") {
1965
                        $desc_buf[1] = $id_buf[1]." ".$desc_buf[1];
1966
                    }
1967
                    $this->sys->setDistribution(preg_replace("/ - Version:| Build:| Release| version| build| based in Ubuntu/i", "", trim($desc_buf[1])));
3037 rexy 1968
                    if (preg_match('/^DISTRIB_RELEASE="?([^"\r\n]+)/m', $buf, $vers_buf)
2770 rexy 1969
                       && (trim($vers_buf[1])!=trim($desc_buf[1])) && strstr($vers_buf[1], ".")){
1970
                        if (preg_match("/^(\d+)\.[0]+$/", trim($vers_buf[1]), $match_buf)) {
1971
                            $tofind = $match_buf[1];
1972
                        } else {
1973
                            $tofind = trim($vers_buf[1]);
1974
                        }
1975
                        if (!preg_match("/^".$tofind."[\s\.]|[\(\[]".$tofind."[\.\)\]]|\s".$tofind."$|\s".$tofind."[\s\.]/", trim($desc_buf[1]))) {
1976
                            $this->sys->setDistribution($this->sys->getDistribution()." ".trim($vers_buf[1]));
1977
                        }
1978
                    }
3179 rexy 1979
                    $distrib = trim($id_buf[1]);
1980
                    $distrib2 = $distrib;
1981
                    $distrib3 = $distrib;
1982
                    $distarr = preg_split("/\s/", trim($desc_buf[1]), -1, PREG_SPLIT_NO_EMPTY);
1983
                    if (isset($distarr[0])) {
1984
                        $distrib2 .= ' '.$distarr[0];
1985
                    }
1986
                    if (isset($distarr[1])) {
1987
                        $distrib3 .= ' '.$distarr[0].' '.$distarr[1];
1988
                    }
1989
                    if (($distrib!==$distrib3) && isset($list[strtolower($distrib3)]['Image'])) {
1990
                        $this->sys->setDistributionIcon($list[strtolower($distrib3)]['Image']);
1991
                    } elseif (($distrib!==$distrib2) && isset($list[strtolower($distrib2)]['Image'])) {
1992
                        $this->sys->setDistributionIcon($list[strtolower($distrib2)]['Image']);
1993
                    } elseif (($distrib!=="n/a") && isset($list[strtolower($distrib)]['Image'])) {
1994
                        $this->sys->setDistributionIcon($list[strtolower($distrib)]['Image']);
1995
                    }
2770 rexy 1996
                } else {
3179 rexy 1997
                    if (isset($list[strtolower(trim($id_buf[1]))]['Name'])) {
1998
                        $this->sys->setDistribution(trim($list[strtolower(trim($id_buf[1]))]['Name']));
2770 rexy 1999
                    } else {
2000
                        $this->sys->setDistribution(trim($id_buf[1]));
2001
                    }
3037 rexy 2002
                    if (preg_match('/^DISTRIB_RELEASE="?([^"\r\n]+)/m', $buf, $vers_buf)) {
2770 rexy 2003
                        $this->sys->setDistribution($this->sys->getDistribution()." ".trim($vers_buf[1]));
2004
                    }
3037 rexy 2005
                    if (preg_match('/^DISTRIB_CODENAME="?([^"\r\n]+)/m', $buf, $vers_buf)) {
2770 rexy 2006
                        $this->sys->setDistribution($this->sys->getDistribution()." (".trim($vers_buf[1]).")");
2007
                    }
3179 rexy 2008
                    if (isset($list[strtolower(trim($id_buf[1]))]['Image'])) {
2009
                        $this->sys->setDistributionIcon($list[strtolower(trim($id_buf[1]))]['Image']);
2010
                    }
2770 rexy 2011
                }
2012
            } else { // otherwise find files specific for distribution
2013
                foreach ($list as $section=>$distribution) {
2014
                    if (!isset($distribution['Files'])) {
2015
                        continue;
2016
                    } else {
2017
                        foreach (preg_split("/;/", $distribution['Files'], -1, PREG_SPLIT_NO_EMPTY) as $filename) {
2018
                            if (CommonFunctions::fileexists($filename)) {
2019
                                $distro = $distribution;
2020
                                if (isset($distribution['Mode'])&&(strtolower($distribution['Mode'])=="detection")) {
2021
                                    $buf = "";
2022
                                } elseif (isset($distribution['Mode'])&&(strtolower($distribution['Mode'])=="execute")) {
2023
                                    if (!CommonFunctions::executeProgram($filename, '2>/dev/null', $buf, PSI_DEBUG)) {
2024
                                        $buf = "";
2025
                                    }
2026
                                } else {
2027
                                    if (!CommonFunctions::rfts($filename, $buf, 1, 4096, false)) {
2028
                                        $buf = "";
3179 rexy 2029
                                        if (isset($distribution['Mode'])&&(strtolower($distribution['Mode'])=="analyse")) {
2030
                                            break;
2031
                                        }
2770 rexy 2032
                                    } elseif (isset($distribution['Mode'])&&(strtolower($distribution['Mode'])=="analyse")) {
3179 rexy 2033
                                        if (preg_match('/^(\S+)\s*/', preg_replace('/^red\s+/', 'red', strtolower($buf)), $id_buf)
2770 rexy 2034
                                           && isset($list[trim($id_buf[1])]['Image'])) {
2035
                                            $distro = $list[trim($id_buf[1])];
2036
                                        }
2037
                                    }
2038
                                }
3179 rexy 2039
                                if (($buf !== null) && (trim($buf) !== "")) {
2040
                                    $buf = preg_replace("/ - Version:| Build:| Release| version| build/i", "", $buf);
2041
                                }
2770 rexy 2042
                                if (isset($distro['Image'])) {
2043
                                    $this->sys->setDistributionIcon($distro['Image']);
2044
                                }
2045
                                if (isset($distribution['Name'])) {
3037 rexy 2046
                                    if (($buf === null) || (trim($buf) == "")) {
2770 rexy 2047
                                        $this->sys->setDistribution($distribution['Name']);
2048
                                    } else {
2049
                                        $this->sys->setDistribution($distribution['Name']." ".trim($buf));
2050
                                    }
2051
                                } else {
3037 rexy 2052
                                    if (($buf === null) || (trim($buf) == "")) {
3179 rexy 2053
                                        $this->sys->setDistribution(preg_replace('/linux/', 'Linux', ucwords($section)));
2770 rexy 2054
                                    } else {
2055
                                        $this->sys->setDistribution(trim($buf));
2056
                                    }
2057
                                }
2058
                                if (isset($distribution['Files2'])) {
2059
                                    foreach (preg_split("/;/", $distribution['Files2'], -1, PREG_SPLIT_NO_EMPTY) as $filename2) {
2060
                                        if (CommonFunctions::fileexists($filename2) && CommonFunctions::rfts($filename2, $buf, 0, 4096, false)) {
3037 rexy 2061
                                            if (preg_match('/^majorversion="?([^"\r\n]+)/m', $buf, $maj_buf)
2062
                                               && preg_match('/^minorversion="?([^"\r\n]+)/m', $buf, $min_buf)) {
2770 rexy 2063
                                                $distr2=$maj_buf[1].'.'.$min_buf[1];
3037 rexy 2064
                                                if (preg_match('/^buildphase="?([^"\r\n]+)/m', $buf, $pha_buf) && ($pha_buf[1]!=="0")) {
2770 rexy 2065
                                                    $distr2.='.'.$pha_buf[1];
2066
                                                }
3037 rexy 2067
                                                if (preg_match('/^buildnumber="?([^"\r\n]+)/m', $buf, $num_buf)) {
2770 rexy 2068
                                                    $distr2.='-'.$num_buf[1];
2069
                                                }
3037 rexy 2070
                                                if (preg_match('/^builddate="?([^"\r\n]+)/m', $buf, $dat_buf)) {
2770 rexy 2071
                                                    $distr2.=' ('.$dat_buf[1].')';
2072
                                                }
2073
                                                $this->sys->setDistribution($this->sys->getDistribution()." ".$distr2);
3179 rexy 2074
                                            } elseif (preg_match('/^elive-codename:\s*([^\r\n]+)/m', $buf, $cod_buf)
2075
                                               && preg_match('/^elive-version:\s*([^\r\n]+)/m', $buf, $ver_buf)) {
2076
                                                $this->sys->setDistribution($this->sys->getDistribution()." ".trim($cod_buf[1])." ".trim($ver_buf[1]));
2077
                                            } elseif (preg_match('/^VERSION=["\']?([^"\'\r\n]+)/im', $buf, $vers_buf)
2078
                                               || preg_match('/^VERSION_ID=["\']?([^"\'\r\n]+)/m', $buf, $vers_buf)) {
2079
                                                $this->sys->setDistribution($this->sys->getDistribution()." ".trim($vers_buf[1]));
2080
                                            } elseif (preg_match('/^DISTRIB_ID=[\'"]?([^\'"\r\n]+)/m', $buf, $id_buf)) {
2081
                                                if (preg_match('/^DESCRIPTION="?([^"\r\n]+)/m', $buf, $desc_buf)
2082
                                                   && (trim($desc_buf[1])!=trim($id_buf[1]))) {
2083
                                                    $this->sys->setDistribution(trim($desc_buf[1]));
2084
                                                } else {
2085
                                                    if (isset($list[strtolower(trim($id_buf[1]))]['Name'])) {
2086
                                                        $this->sys->setDistribution(trim($list[strtolower(trim($id_buf[1]))]['Name']));
2087
                                                    } else {
2088
                                                        $this->sys->setDistribution(trim($id_buf[1]));
2089
                                                    }
2090
                                                    if (preg_match('/^RELEASE="?([^"\r\n]+)/m', $buf, $vers_buf) || preg_match('/^DISTRIB_RELEASE=[\'"]?([^\'"\r\n]+)/m', $buf, $vers_buf)) {
2091
                                                        $this->sys->setDistribution($this->sys->getDistribution()." ".trim($vers_buf[1]));
2092
                                                    }
2093
                                                    if (preg_match('/^CODENAME="?([^"\r\n]+)/m', $buf, $vers_buf)) {
2094
                                                        $this->sys->setDistribution($this->sys->getDistribution()." (".trim($vers_buf[1]).")");
2095
                                                    }
2096
                                                }
2770 rexy 2097
                                            } else {
2098
                                                $distr2=trim(substr($buf, 0, strpos($buf, "\n")));
3037 rexy 2099
                                                if (($distr2 !== null) && ($distr2 != "")) {
2770 rexy 2100
                                                    $this->sys->setDistribution($this->sys->getDistribution()." ".$distr2);
2101
                                                }
2102
                                            }
2103
                                            break;
2104
                                        }
2105
                                    }
2106
                                }
2107
                                break 2;
2108
                            }
2109
                        }
2110
                    }
2111
                }
2112
            }
2113
            // if the distribution is still unknown
2114
            if ($this->sys->getDistribution() == "Linux") {
3179 rexy 2115
                if ($_ignore_lsb_release) { // if lsb_release was ignored
2116
                    if ($_Distrib !== "") $this->sys->setDistribution(preg_replace("/ - Version:| Build:| Release| version| build| based in Ubuntu/i", "", $_Distrib));
2117
                    if ($_DistribIcon !== "") $this->sys->setDistributionIcon($_DistribIcon);
2118
                }
2119
            }
2120
            // if the distribution is still unknown
2121
            if ($this->sys->getDistribution() == "Linux") {
2122
                if (((defined('PSI_EMU_PORT') && CommonFunctions::executeProgram('cat', '/etc/os-release', $buf, false))
2123
                    || (!defined('PSI_EMU_PORT') && CommonFunctions::fileexists($filename="/etc/os-release") && CommonFunctions::rfts($filename, $buf, 0, 4096, false)))
2124
                    && (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))) {
2125
                    if (preg_match('/^TAILS_VERSION_ID="?([^"\r\n]+)/m', $buf, $tid_buf)) {
2126
                        if (preg_match('/^TAILS_PRODUCT_NAME="?([^"\r\n]+)/m', $buf, $desc_buf)) {
2127
                            $this->sys->setDistribution(trim($desc_buf[1])." ".trim($tid_buf[1]));
2128
                        } else {
2129
                            if (isset($list['tails']['Name'])) {
2130
                                $this->sys->setDistribution(trim($list['tails']['Name'])." ".trim($tid_buf[1]));
2131
                            } else {
2132
                                $this->sys->setDistribution('Tails'." ".trim($tid_buf[1]));
2133
                            }
2134
                        }
2135
                        $this->sys->setDistributionIcon($list['tails']['Image']);
2136
                    } else {
2137
                        $addversion = false;
2138
                        $distrib = trim($id_buf[1]);
2139
                        if (preg_match('/^PRETTY_NAME=["\']?([^"\'\r\n]+)/m', $buf, $desc_buf)
2140
                           && !preg_match('/\$/', $desc_buf[1]) // if is not defined by variable
2141
                           && ($distrib!==trim($desc_buf[1]))) {
2142
                            if (isset($list[strtolower($distrib)]['Name']) && !preg_match("/".$list[strtolower($distrib)]['Name']."/i", trim($desc_buf[1]))) {
2143
                                $this->sys->setDistribution($list[strtolower($distrib)]['Name'] ." ". preg_replace("/ - Version:| Build:| Release| version| build| based in Ubuntu/i", "", trim($desc_buf[1])));
2144
                            } else {
2145
                                $this->sys->setDistribution(preg_replace("/ - Version:| Build:| Release| version| build| based in Ubuntu/i", "", trim($desc_buf[1])));
2146
                            }
2147
                            $distrib2 = $distrib;
2148
                            $distrib3 = $distrib;
2149
                            $distarr = preg_split("/\s/", trim($desc_buf[1]), -1, PREG_SPLIT_NO_EMPTY);
2150
                            if (isset($distarr[0])) {
2151
                                $distrib2 .= ' '.$distarr[0];
2152
                            }
2153
                            if (isset($distarr[1])) {
2154
                                $distrib3 .= ' '.$distarr[0].' '.$distarr[1];
2155
                            }
2156
                            if (($distrib!==$distrib3) && isset($list[strtolower($distrib3)]['Image'])) {
2157
                                $this->sys->setDistributionIcon($list[strtolower($distrib3)]['Image']);
2158
                                if (count($distarr) == 2) {
2159
                                    $addversion = true;
2160
                                }
2161
                            } elseif (($distrib!==$distrib2) && isset($list[strtolower($distrib2)]['Image'])) {
2162
                                $this->sys->setDistributionIcon($list[strtolower($distrib2)]['Image']);
2163
                                if (count($distarr) == 1) {
2164
                                    $addversion = true;
2165
                                }
2166
                            } elseif (($distrib!=="n/a") && isset($list[strtolower($distrib)]['Image'])) {
2167
                                $this->sys->setDistributionIcon($list[strtolower($distrib)]['Image']);
2168
                            }
2169
                        } else {
2170
                            if (isset($list[strtolower($distrib)]['Name'])) {
2171
                                $this->sys->setDistribution(trim($list[strtolower($distrib)]['Name']));
2172
                            } else {
2173
                                $this->sys->setDistribution($distrib);
2174
                            }
2175
                            if (isset($list[strtolower($distrib)]['Image'])) {
2176
                                $this->sys->setDistributionIcon($list[strtolower($distrib)]['Image']);
2177
                            }
2178
                            $addversion = true;
2179
                        }
2180
                        if ($addversion) {
2181
                            if (preg_match('/^VERSION=["\']?([^"\'\r\n]+)/m', $buf, $vers_buf)
2182
                               || preg_match('/^VERSION_ID=["\']?([^"\'\r\n]+)/m', $buf, $vers_buf)
2183
                               || preg_match('/^DISTRIB_RELEASE=["\']?([^"\'\r\n]+)/m', $buf, $vers_buf)
2184
                               || preg_match('/^IMAGE_VERSION=["\']?([^"\'\r\n]+)/m', $buf, $vers_buf)) {
2185
                                $this->sys->setDistribution($this->sys->getDistribution()." ".trim($vers_buf[1]));
2186
                            }
2187
                            if (!strstr($this->sys->getDistribution(), "(") && (preg_match('/^VERSION_CODENAME="?([^"\r\n]+)/m', $buf, $vers_buf)
2188
                               || preg_match('/^DISTRIB_CODENAME="?([^"\r\n]+)/m', $buf, $vers_buf))) {
2189
                                $this->sys->setDistribution($this->sys->getDistribution()." (".trim($vers_buf[1]).")");
2190
                            }
2191
                        }
2192
                    }
2193
                } elseif (CommonFunctions::fileexists($filename="/etc/DISTRO_SPECS")
2770 rexy 2194
                   && CommonFunctions::rfts($filename, $buf, 0, 4096, false)
3179 rexy 2195
                   && preg_match('/^DISTRO_NAME=["\']([^"\']+)/m', $buf, $id_buf)) {
2196
                    if (isset($list[strtolower(trim($id_buf[1]))]['Name'])) {
2197
                        $dist = trim($list[strtolower(trim($id_buf[1]))]['Name']);
2770 rexy 2198
                    } else {
2199
                        $dist = trim($id_buf[1]);
2200
                    }
3179 rexy 2201
                    if (preg_match('/^DISTRO_VERSION=([^$#\n\r]+)/m', $buf, $vers_buf)) {
2770 rexy 2202
                        $this->sys->setDistribution(trim($dist." ".trim($vers_buf[1])));
2203
                    } else {
2204
                        $this->sys->setDistribution($dist);
2205
                    }
3179 rexy 2206
                    if (isset($list[strtolower(trim($id_buf[1]))]['Image'])) {
2207
                        $this->sys->setDistributionIcon($list[strtolower(trim($id_buf[1]))]['Image']);
2770 rexy 2208
                    } else {
3179 rexy 2209
                        if (isset($list['puppy']['Image'])) {
2210
                            $this->sys->setDistributionIcon($list['puppy']['Image']);
2211
                            if (!preg_match("/puppy/i", $dist = $this->sys->getDistribution())) {
2212
                                $this->sys->setDistribution("Puppy ".$dist);
2213
                            }
2770 rexy 2214
                        }
2215
                    }
2216
                } elseif ((CommonFunctions::fileexists($filename="/etc/distro-release")
2217
                        && CommonFunctions::rfts($filename, $buf, 1, 4096, false)
3037 rexy 2218
                        && ($buf !== null) && (trim($buf) != ""))
2770 rexy 2219
                    || (CommonFunctions::fileexists($filename="/etc/system-release")
2220
                        && CommonFunctions::rfts($filename, $buf, 1, 4096, false)
3037 rexy 2221
                        && ($buf !== null) && (trim($buf) != ""))) {
3179 rexy 2222
                    $this->sys->setDistribution(preg_replace("/ - Version:| Build:| Release| version| build| based in Ubuntu/i", "", trim($buf)));
2223
                    if (preg_match('/^(\S+)\s*/', preg_replace('/^red\s+/', 'red', strtolower($buf)), $id_buf)
2770 rexy 2224
                        && isset($list[trim($id_buf[1])]['Image'])) {
2225
                            $this->sys->setDistributionIcon($list[trim($id_buf[1])]['Image']);
2226
                    }
2227
                } elseif (CommonFunctions::fileexists($filename="/etc/debian_version")) {
2228
                    if (!CommonFunctions::rfts($filename, $buf, 1, 4096, false)) {
2229
                        $buf = "";
2230
                    }
3179 rexy 2231
                    if (isset($list['debian']['Image'])) {
2232
                        $this->sys->setDistributionIcon($list['debian']['Image']);
2770 rexy 2233
                    }
3179 rexy 2234
                    if (isset($list['debian']['Name'])) {
3037 rexy 2235
                        if (($buf === null) || (trim($buf) == "")) {
3179 rexy 2236
                            $this->sys->setDistribution($list['debian']['Name']);
2770 rexy 2237
                        } else {
3179 rexy 2238
                            $this->sys->setDistribution($list['debian']['Name']." ".trim($buf));
2770 rexy 2239
                        }
2240
                    } else {
3037 rexy 2241
                        if (($buf === null) || (trim($buf) == "")) {
2770 rexy 2242
                            $this->sys->setDistribution('Debian');
2243
                        } else {
2244
                            $this->sys->setDistribution(trim($buf));
2245
                        }
2246
                    }
3100 rexy 2247
                } elseif (CommonFunctions::fileexists($filename="/etc/slackware-version")) {
2248
                    if (!CommonFunctions::rfts($filename, $buf, 1, 4096, false)) {
2249
                        $buf = "";
2250
                    }
3179 rexy 2251
                    if (isset($list['slackware']['Image'])) {
2252
                        $this->sys->setDistributionIcon($list['slackware']['Image']);
3100 rexy 2253
                    }
3179 rexy 2254
                    if (isset($list['slackware']['Name'])) {
3100 rexy 2255
                        if (($buf === null) || (trim($buf) == "")) {
3179 rexy 2256
                            $this->sys->setDistribution($list['slackware']['Name']);
3100 rexy 2257
                        } else {
3179 rexy 2258
                            $this->sys->setDistribution($list['slackware']['Name']." ".trim($buf));
3100 rexy 2259
                        }
2260
                    } else {
2261
                        if (($buf === null) || (trim($buf) == "")) {
2262
                            $this->sys->setDistribution('Slackware');
2263
                        } else {
2264
                            $this->sys->setDistribution(trim($buf));
2265
                        }
2266
                    }
2770 rexy 2267
                } elseif (CommonFunctions::fileexists($filename="/etc/config/uLinux.conf")
2268
                   && CommonFunctions::rfts($filename, $buf, 0, 4096, false)
2269
                   && preg_match("/^Rsync\sModel\s*=\s*QNAP/m", $buf)
2270
                   && preg_match("/^Version\s*=\s*([\d\.]+)\r?\nBuild\sNumber\s*=\s*(\S+)/m", $buf, $ver_buf)) {
2271
                    $buf = $ver_buf[1]."-".$ver_buf[2];
3179 rexy 2272
                    if (isset($list['qts']['Image'])) {
2273
                        $this->sys->setDistributionIcon($list['qts']['Image']);
2770 rexy 2274
                    }
3179 rexy 2275
                    if (isset($list['qts']['Name'])) {
2276
                        $this->sys->setDistribution($list['qts']['Name']." ".trim($buf));
2770 rexy 2277
                    } else {
2278
                        $this->sys->setDistribution(trim($buf));
2279
                    }
2280
                }
2281
            }
2282
            /* restore error level */
2283
            error_reporting($old_err_rep);
2284
            /* restore error handler */
2285
            if (function_exists('errorHandlerPsi')) {
2286
                set_error_handler('errorHandlerPsi');
2287
            }
2288
        }
2289
    }
2290
 
2291
    /**
2292
     * Processes
2293
     *
2294
     * @return void
2295
     */
2296
    protected function _processes()
2297
    {
3037 rexy 2298
        $process = CommonFunctions::findglob('/proc/*/status', GLOB_NOSORT);
2770 rexy 2299
        if (is_array($process) && (($total = count($process)) > 0)) {
2300
            $processes['*'] = 0;
2301
            $buf = "";
2302
            for ($i = 0; $i < $total; $i++) {
2303
                if (CommonFunctions::rfts($process[$i], $buf, 0, 4096, false)) {
3037 rexy 2304
                    $processes['*']++; // current total
2770 rexy 2305
                    if (preg_match('/^State:\s+(\w)/m', $buf, $state)) {
2306
                        if (isset($processes[$state[1]])) {
2307
                            $processes[$state[1]]++;
2308
                        } else {
2309
                            $processes[$state[1]] = 1;
2310
                        }
2311
                    }
2312
                }
2313
            }
2314
            if (!($processes['*'] > 0)) {
3037 rexy 2315
                $processes['*'] = $processes[' '] = $total; // all unknown
2770 rexy 2316
            }
2317
            $this->sys->setProcesses($processes);
2318
        }
2319
    }
2320
 
2321
    /**
2322
     * get the information
2323
     *
2324
     * @see PSI_Interface_OS::build()
2325
     *
3037 rexy 2326
     * @return void
2770 rexy 2327
     */
2328
    public function build()
2329
    {
2330
        if (!$this->blockname || $this->blockname==='vitals') {
2331
            $this->_distro();
2332
            $this->_hostname();
2333
            $this->_kernel();
2334
            $this->_uptime();
2335
            $this->_users();
2336
            $this->_loadavg();
2337
            $this->_processes();
2338
        }
2339
        if (!$this->blockname || $this->blockname==='hardware') {
2340
            $this->_machine();
2341
            $this->_cpuinfo();
3037 rexy 2342
            $this->_virtualizer();
2770 rexy 2343
            $this->_pci();
2344
            $this->_ide();
2345
            $this->_scsi();
2346
            $this->_nvme();
2347
            $this->_usb();
2348
            $this->_i2c();
2349
        }
2350
        if (!$this->blockname || $this->blockname==='memory') {
2351
            $this->_memory();
2352
        }
2353
        if (!$this->blockname || $this->blockname==='filesystem') {
2354
            $this->_filesystems();
2355
        }
3037 rexy 2356
        if (!$this->blockname || $this->blockname==='network') {
2357
            $this->_network();
2358
        }
2770 rexy 2359
    }
2360
}