Subversion Repositories ALCASAR

Rev

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