Subversion Repositories ALCASAR

Rev

Rev 1764 | Rev 2976 | Go to most recent revision | 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
    /**
30
     * Assoc array of all CPUs loads.
31
     */
32
    protected $_cpu_loads;
325 richard 33
 
2770 rexy 34
    /**
35
     * Machine
36
     *
37
     * @return void
38
     */
39
    private function _machine()
40
    {
41
        $machine = "";
42
        if ((CommonFunctions::rfts('/var/log/dmesg', $result, 0, 4096, false)
43
              && preg_match('/^[\s\[\]\.\d]*DMI:\s*(.*)/m', $result, $ar_buf))
44
           ||(CommonFunctions::executeProgram('dmesg', '', $result, false)
45
              && preg_match('/^[\s\[\]\.\d]*DMI:\s*(.*)/m', $result, $ar_buf))) {
46
            $machine = trim($ar_buf[1]);
47
        } else { //data from /sys/devices/virtual/dmi/id/
48
            $product = "";
49
            $board = "";
50
            $bios = "";
51
            if (CommonFunctions::rfts('/sys/devices/virtual/dmi/id/board_vendor', $buf, 1, 4096, false) && (trim($buf)!="")) {
52
                $machine = trim($buf);
53
            }
54
            if (CommonFunctions::rfts('/sys/devices/virtual/dmi/id/product_name', $buf, 1, 4096, false) && (trim($buf)!="")) {
55
                $product = trim($buf);
56
            }
57
            if (CommonFunctions::rfts('/sys/devices/virtual/dmi/id/board_name', $buf, 1, 4096, false) && (trim($buf)!="")) {
58
                $board = trim($buf);
59
            }
60
            if (CommonFunctions::rfts('/sys/devices/virtual/dmi/id/bios_version', $buf, 1, 4096, false) && (trim($buf)!="")) {
61
                $bios = trim($buf);
62
            }
63
            if (CommonFunctions::rfts('/sys/devices/virtual/dmi/id/bios_date', $buf, 1, 4096, false) && (trim($buf)!="")) {
64
                $bios = trim($bios." ".trim($buf));
65
            }
66
            if ($product != "") {
67
                $machine .= " ".$product;
68
            }
69
            if ($board != "") {
70
                $machine .= "/".$board;
71
            }
72
            if ($bios != "") {
73
                $machine .= ", BIOS ".$bios;
74
            }
75
        }
325 richard 76
 
2770 rexy 77
        if ($machine != "") {
78
            $machine = trim(preg_replace("/^\/,?/", "", preg_replace("/ ?(To be filled by O\.E\.M\.|System manufacturer|System Product Name|Not Specified) ?/i", "", $machine)));
79
        }
325 richard 80
 
2770 rexy 81
        if (CommonFunctions::fileexists($filename="/etc/config/uLinux.conf") // QNAP detection
82
           && CommonFunctions::rfts($filename, $buf, 0, 4096, false)
83
           && preg_match("/^Rsync\sModel\s*=\s*QNAP/m", $buf)
84
           && CommonFunctions::fileexists($filename="/etc/platform.conf") // Platform detection
85
           && CommonFunctions::rfts($filename, $buf, 0, 4096, false)
86
           && preg_match("/^DISPLAY_NAME\s*=\s*(\S+)/m", $buf, $mach_buf) && ($mach_buf[1]!=="")) {
87
            if ($machine != "") {
88
                $machine = "QNAP ".$mach_buf[1].' - '.$machine;
89
            } else {
90
                $machine = "QNAP ".$mach_buf[1];
91
            }
92
        }
93
 
94
        if ($machine != "") {
95
            $this->sys->setMachine($machine);
96
        }
1764 richard 97
    }
325 richard 98
 
2770 rexy 99
    /**
100
     * Hostname
101
     *
102
     * @return void
103
     */
104
    protected function _hostname()
105
    {
106
        if (PSI_USE_VHOST === true) {
107
            if (CommonFunctions::readenv('SERVER_NAME', $hnm)) $this->sys->setHostname($hnm);
108
        } else {
109
            if (CommonFunctions::rfts('/proc/sys/kernel/hostname', $result, 1, 4096, PSI_DEBUG && (PSI_OS != 'Android'))) {
110
                $result = trim($result);
111
                $ip = gethostbyname($result);
112
                if ($ip != $result) {
113
                    $this->sys->setHostname(gethostbyaddr($ip));
114
                }
115
            } elseif (CommonFunctions::executeProgram('hostname', '', $ret)) {
116
                $this->sys->setHostname($ret);
117
            }
325 richard 118
 
2770 rexy 119
        }
120
    }
325 richard 121
 
2770 rexy 122
    /**
123
     * Kernel Version
124
     *
125
     * @return void
126
     */
127
    private function _kernel()
128
    {
129
        $result = "";
130
        if (CommonFunctions::executeProgram($uname="uptrack-uname", '-r', $strBuf, false) || // show effective kernel if ksplice uptrack is installed
131
            CommonFunctions::executeProgram($uname="uname", '-r', $strBuf, PSI_DEBUG)) {
132
            $result = $strBuf;
133
            if (CommonFunctions::executeProgram($uname, '-v', $strBuf, PSI_DEBUG)) {
134
                if (preg_match('/SMP/', $strBuf)) {
135
                    $result .= ' (SMP)';
136
                }
137
            }
138
            if (CommonFunctions::executeProgram($uname, '-m', $strBuf, PSI_DEBUG)) {
139
                $result .= ' '.$strBuf;
140
            }
141
        } elseif (CommonFunctions::rfts('/proc/version', $strBuf, 1) &&  preg_match('/version\s+(\S+)/', $strBuf, $ar_buf)) {
142
            $result = $ar_buf[1];
143
            if (preg_match('/SMP/', $strBuf)) {
144
                $result .= ' (SMP)';
145
            }
146
        }
147
        if ($result != "") {
148
            if (CommonFunctions::rfts('/proc/self/cgroup', $strBuf2, 0, 4096, false)) {
149
                if (preg_match('/:\/lxc\//m', $strBuf2)) {
150
                    $result .= ' [lxc]';
151
                } elseif (preg_match('/:\/docker\//m', $strBuf2)) {
152
                    $result .= ' [docker]';
153
                } elseif (preg_match('/:\/system\.slice\/docker\-/m', $strBuf2)) {
154
                    $result .= ' [docker]';
155
                }
156
            }
157
            if (CommonFunctions::rfts('/proc/version', $strBuf2, 1, 4096, false)
158
                && preg_match('/^Linux version [\d\.-]+-Microsoft/', $strBuf2)) {
159
                    $result .= ' [lxss]';
160
            }
161
            $this->sys->setKernel($result);
162
        }
163
    }
325 richard 164
 
2770 rexy 165
    /**
166
     * UpTime
167
     * time the system is running
168
     *
169
     * @return void
170
     */
171
    protected function _uptime()
172
    {
173
        if (CommonFunctions::rfts('/proc/uptime', $buf, 1, 4096, PSI_OS != 'Android')) {
174
            $ar_buf = preg_split('/ /', $buf);
175
            $this->sys->setUptime(trim($ar_buf[0]));
176
        } elseif (CommonFunctions::executeProgram('uptime', '', $buf)) {
177
            if (preg_match("/up (\d+) day[s]?,[ ]+(\d+):(\d+),/", $buf, $ar_buf)) {
178
                $min = $ar_buf[3];
179
                $hours = $ar_buf[2];
180
                $days = $ar_buf[1];
181
                $this->sys->setUptime($days * 86400 + $hours * 3600 + $min * 60);
182
            } elseif (preg_match("/up (\d+) day[s]?,[ ]+(\d+) min,/", $buf, $ar_buf)) {
183
                $min = $ar_buf[2];
184
                $days = $ar_buf[1];
185
                $this->sys->setUptime($days * 86400 + $min * 60);
186
            } elseif (preg_match("/up[ ]+(\d+):(\d+),/", $buf, $ar_buf)) {
187
                $min = $ar_buf[2];
188
                $hours = $ar_buf[1];
189
                $this->sys->setUptime($hours * 3600 + $min * 60);
190
            } elseif (preg_match("/up[ ]+(\d+) min,/", $buf, $ar_buf)) {
191
                $min = $ar_buf[1];
192
                $this->sys->setUptime($min * 60);
193
            }
194
        }
195
    }
325 richard 196
 
2770 rexy 197
    /**
198
     * Processor Load
199
     * optionally create a loadbar
200
     *
201
     * @return void
202
     */
203
    protected function _loadavg()
204
    {
205
        if (CommonFunctions::rfts('/proc/loadavg', $buf, 1, 4096, PSI_OS != 'Android')) {
206
            $result = preg_split("/\s/", $buf, 4);
207
            // don't need the extra values, only first three
208
            unset($result[3]);
209
            $this->sys->setLoad(implode(' ', $result));
210
        } elseif (CommonFunctions::executeProgram('uptime', '', $buf) && preg_match("/load average: (.*), (.*), (.*)$/", $buf, $ar_buf)) {
211
            $this->sys->setLoad($ar_buf[1].' '.$ar_buf[2].' '.$ar_buf[3]);
212
        }
213
        if (PSI_LOAD_BAR) {
214
            $this->sys->setLoadPercent($this->_parseProcStat('cpu'));
215
        }
325 richard 216
    }
217
 
2770 rexy 218
    /**
219
     * fill the load for a individual cpu, through parsing /proc/stat for the specified cpu
220
     *
221
     * @param String $cpuline cpu for which load should be meassured
222
     *
223
     * @return Integer
224
     */
225
    protected function _parseProcStat($cpuline)
226
    {
227
        if (is_null($this->_cpu_loads)) {
228
            $this->_cpu_loads = array();
325 richard 229
 
2770 rexy 230
            $cpu_tmp = array();
231
            if (CommonFunctions::rfts('/proc/stat', $buf)) {
232
                if (preg_match_all('/^(cpu[0-9]*) (.*)/m', $buf, $matches, PREG_SET_ORDER)) {
233
                    foreach ($matches as $line) {
234
                        $cpu = $line[1];
235
                        $buf2 = $line[2];
325 richard 236
 
2770 rexy 237
                        $cpu_tmp[$cpu] = array();
325 richard 238
 
2770 rexy 239
                        $ab = 0;
240
                        $ac = 0;
241
                        $ad = 0;
242
                        $ae = 0;
243
                        sscanf($buf2, "%Ld %Ld %Ld %Ld", $ab, $ac, $ad, $ae);
244
                        $cpu_tmp[$cpu]['load'] = $ab + $ac + $ad; // cpu.user + cpu.sys
245
                        $cpu_tmp[$cpu]['total'] = $ab + $ac + $ad + $ae; // cpu.total
246
                    }
247
                }
248
 
249
                // we need a second value, wait 1 second befor getting (< 1 second no good value will occour)
250
                sleep(1);
251
 
252
                if (CommonFunctions::rfts('/proc/stat', $buf)) {
253
                    if (preg_match_all('/^(cpu[0-9]*) (.*)/m', $buf, $matches, PREG_SET_ORDER)) {
254
                        foreach ($matches as $line) {
255
                            $cpu = $line[1];
256
                            if (isset($cpu_tmp[$cpu])) {
257
                                $buf2 = $line[2];
258
 
259
                                $ab = 0;
260
                                $ac = 0;
261
                                $ad = 0;
262
                                $ae = 0;
263
                                sscanf($buf2, "%Ld %Ld %Ld %Ld", $ab, $ac, $ad, $ae);
264
                                $load2 = $ab + $ac + $ad; // cpu.user + cpu.sys
265
                                $total2 = $ab + $ac + $ad + $ae; // cpu.total
266
                                $total = $cpu_tmp[$cpu]['total'];
267
                                $load = $cpu_tmp[$cpu]['load'];
268
                                $this->_cpu_loads[$cpu] = 0;
269
                                if ($total > 0 && $total2 > 0 && $load > 0 && $load2 > 0 && $total2 != $total && $load2 != $load) {
270
                                    $this->_cpu_loads[$cpu] = (100 * ($load2 - $load)) / ($total2 - $total);
271
                                }
272
                            }
273
                        }
274
                    }
275
                }
276
            }
277
        }
278
 
279
        if (isset($this->_cpu_loads[$cpuline])) {
280
            return $this->_cpu_loads[$cpuline];
325 richard 281
        } else {
2770 rexy 282
            return 0;
283
        }
284
    }
325 richard 285
 
2770 rexy 286
    /**
287
     * CPU information
288
     * All of the tags here are highly architecture dependant.
289
     *
290
     * @return void
291
     */
292
    protected function _cpuinfo()
293
    {
294
        if (CommonFunctions::rfts('/proc/cpuinfo', $bufr)) {
295
            $cpulist = null;
296
            $raslist = null;
325 richard 297
 
2770 rexy 298
            // sparc
299
            if (preg_match('/\nCpu(\d+)Bogo\s*:/i', $bufr)) {
300
                $bufr = preg_replace('/\nCpu(\d+)ClkTck\s*:/i', "\nCpu0ClkTck:", preg_replace('/\nCpu(\d+)Bogo\s*:/i', "\n\nprocessor: $1\nCpu0Bogo:", $bufr));
301
            } else {
302
                $bufr = preg_replace('/\nCpu(\d+)ClkTck\s*:/i', "\n\nprocessor: $1\nCpu0ClkTck:", $bufr);
303
            }
325 richard 304
 
2770 rexy 305
            if (preg_match('/\nprocessor\s*:\s*\d+\r?\nprocessor\s*:\s*\d+/', $bufr)) {
306
                $bufr = preg_replace('/^(processor\s*:\s*\d+)\r?$/m', "$1\n", $bufr);
307
            }
325 richard 308
 
2770 rexy 309
            // IBM/S390
310
            $bufr = preg_replace('/\ncpu number\s*:\s*(\d+)\r?\ncpu MHz dynamic\s*:\s*(\d+)/m', "\nprocessor:$1\nclock:$2", $bufr);
311
 
312
            $processors = preg_split('/\s?\n\s?\n/', trim($bufr));
313
 
314
            //first stage
315
            $_arch = null;
316
            $_impl = null;
317
            $_part = null;
318
            $_hard = null;
319
            $_revi = null;
320
            $_cpus = null;
321
            $_buss = null;
322
            $_bogo = null;
323
            $_vend = null;
324
            $procname = null;
325
            foreach ($processors as $processor) if (!preg_match('/^\s*processor\s*:/mi', $processor)) {
326
                $details = preg_split("/\n/", $processor, -1, PREG_SPLIT_NO_EMPTY);
327
                foreach ($details as $detail) {
328
                    $arrBuff = preg_split('/\s*:\s*/', trim($detail));
329
                    if ((count($arrBuff) == 2) && (($arrBuff1 = trim($arrBuff[1])) !== '')) {
330
                        switch (strtolower($arrBuff[0])) {
331
                        case 'cpu architecture':
332
                            $_arch = $arrBuff1;
333
                            break;
334
                        case 'cpu implementer':
335
                            $_impl = $arrBuff1;
336
                            break;
337
                        case 'cpu part':
338
                            $_part = $arrBuff1;
339
                            break;
340
                        case 'hardware':
341
                            $_hard = $arrBuff1;
342
                            break;
343
                        case 'revision':
344
                            $_revi = $arrBuff1;
345
                            break;
346
                        case 'cpu frequency':
347
                            if (preg_match('/^(\d+)\s+Hz/i', $arrBuff1, $bufr2)) {
348
                                $_cpus = round($bufr2[1]/1000000);
349
                            }
350
                            break;
351
                        case 'system bus frequency':
352
                            if (preg_match('/^(\d+)\s+Hz/i', $arrBuff1, $bufr2)) {
353
                                $_buss = round($bufr2[1]/1000000);
354
                            }
355
                            break;
356
                        case 'bogomips per cpu':
357
                            $_bogo = round($arrBuff1);
358
                            break;
359
                        case 'vendor_id':
360
                            $_vend = $arrBuff1;
361
                        case 'cpu':
362
                            $procname = $arrBuff1;
363
                            break;
364
                        }
365
                    }
366
                }
367
            }
368
 
369
            //second stage
370
            $cpucount = 0;
371
            $speedset = false;
372
            foreach ($processors as $processor) if (preg_match('/^\s*processor\s*:/mi', $processor)) {
373
                $proc = null;
374
                $arch = null;
375
                $impl = null;
376
                $part = null;
377
                $dev = new CpuDevice();
378
                $details = preg_split("/\n/", $processor, -1, PREG_SPLIT_NO_EMPTY);
379
                foreach ($details as $detail) {
380
                    $arrBuff = preg_split('/\s*:\s*/', trim($detail));
381
                    if ((count($arrBuff) == 2) && (($arrBuff1 = trim($arrBuff[1])) !== '')) {
382
                        switch (strtolower($arrBuff[0])) {
383
                        case 'processor':
384
                            $proc = $arrBuff1;
385
                            if (is_numeric($proc)) {
386
                                if (strlen($procname)>0) {
387
                                    $dev->setModel($procname);
388
                                }
389
                            } else {
390
                                $procname = $proc;
391
                                $dev->setModel($procname);
392
                            }
393
                            break;
394
                        case 'model name':
395
                        case 'cpu model':
396
                        case 'cpu type':
397
                        case 'cpu':
398
                            $dev->setModel($arrBuff1);
399
                            break;
400
                        case 'cpu mhz':
401
                        case 'clock':
402
                            if ($arrBuff1 > 0) { //openSUSE fix
403
                                $dev->setCpuSpeed($arrBuff1);
404
                                $speedset = true;
405
                            }
406
                            break;
407
                        case 'cpu mhz static':
408
                            if ($arrBuff1 > 0) { //openSUSE fix
409
                                $dev->setCpuSpeedMax($arrBuff1);
410
                            }
411
                            break;
412
                        case 'cycle frequency [hz]':
413
                            $dev->setCpuSpeed($arrBuff1 / 1000000);
414
                            $speedset = true;
415
                            break;
416
                        case 'cpu0clktck':
417
                            $dev->setCpuSpeed(hexdec($arrBuff1) / 1000000); // Linux sparc64
418
                            $speedset = true;
419
                            break;
420
                        case 'l3 cache':
421
                        case 'cache size':
422
                            $dev->setCache(trim(preg_replace("/[a-zA-Z]/", "", $arrBuff1)) * 1024);
423
                            break;
424
                        case 'initial bogomips':
425
                        case 'bogomips':
426
                        case 'cpu0bogo':
427
                            $dev->setBogomips(round($arrBuff1));
428
                            break;
429
                        case 'flags':
430
                            if (preg_match("/ vmx/", $arrBuff1)) {
431
                                $dev->setVirt("vmx");
432
                            } elseif (preg_match("/ svm/", $arrBuff1)) {
433
                                $dev->setVirt("svm");
434
                            } elseif (preg_match("/ hypervisor/", $arrBuff1)) {
435
                                $dev->setVirt("hypervisor");
436
                            }
437
                            break;
438
                        case 'i size':
439
                        case 'd size':
440
                            if ($dev->getCache() === null) {
441
                                $dev->setCache($arrBuff1 * 1024);
442
                            } else {
443
                                $dev->setCache($dev->getCache() + ($arrBuff1 * 1024));
444
                            }
445
                            break;
446
                        case 'cpu architecture':
447
                            $arch = $arrBuff1;
448
                            break;
449
                        case 'cpu implementer':
450
                            $impl = $arrBuff1;
451
                            break;
452
                        case 'cpu part':
453
                            $part = $arrBuff1;
454
                            break;
455
                        case 'vendor_id':
456
                            $dev->setVendorId($arrBuff1);
457
                            break;
458
                        }
459
                    }
460
                }
461
                if ($arch === null) $arch = $_arch;
462
                if ($impl === null) $impl = $_impl;
463
                if ($part === null) $part = $_part;
464
 
465
                // sparc64 specific code follows
466
                // This adds the ability to display the cache that a CPU has
467
                // Originally made by Sven Blumenstein <bazik@gentoo.org> in 2004
468
                // Modified by Tom Weustink <freshy98@gmx.net> in 2004
469
                $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');
470
                foreach ($sparclist as $name) {
471
                    if (CommonFunctions::rfts('/proc/openprom/'.$name.'/ecache-size', $buf, 1, 32, false)) {
472
                        $dev->setCache(base_convert(trim($buf), 16, 10));
473
                    }
474
                }
475
                // sparc64 specific code ends
476
 
477
                // XScale detection code
478
                if (($arch === "5TE") && ($dev->getBogomips() != null)) {
479
                    $dev->setCpuSpeed($dev->getBogomips()); //BogoMIPS are not BogoMIPS on this CPU, it's the speed
480
                    $speedset = true;
481
                    $dev->setBogomips(null); // no BogoMIPS available, unset previously set BogoMIPS
482
                }
483
 
484
                if (($dev->getBusSpeed() == 0) && ($_buss !== null)) {
485
                    $dev->setBusSpeed($_buss);
486
                }
487
                if (($dev->getCpuSpeed() == 0) && ($_cpus !== null)) {
488
                    $dev->setCpuSpeed($_cpus);
489
                    $speedset = true;
490
                }
491
                if (($dev->getBogomips() == 0) && ($_bogo !== null)) {
492
                    $dev->setBogomips($_bogo);
493
                }
494
                if (($dev->getVendorId() === null) && ($_vend !== null)) {
495
                    $dev->setVendorId($_vend);
496
                }
497
 
498
                if ($proc != null) {
499
                    if (!is_numeric($proc)) {
500
                        $proc = 0;
501
                    }
502
                    // variable speed processors specific code follows
503
                    if (CommonFunctions::rfts('/sys/devices/system/cpu/cpu'.$proc.'/cpufreq/cpuinfo_cur_freq', $buf, 1, 4096, false)) {
504
                        $dev->setCpuSpeed(trim($buf) / 1000);
505
                        $speedset = true;
506
                    } elseif (CommonFunctions::rfts('/sys/devices/system/cpu/cpu'.$proc.'/cpufreq/scaling_cur_freq', $buf, 1, 4096, false)) {
507
                        $dev->setCpuSpeed(trim($buf) / 1000);
508
                        $speedset = true;
509
                    }
510
                    if (CommonFunctions::rfts('/sys/devices/system/cpu/cpu'.$proc.'/cpufreq/cpuinfo_max_freq', $buf, 1, 4096, false)) {
511
                        $dev->setCpuSpeedMax(trim($buf) / 1000);
512
                    }
513
                    if (CommonFunctions::rfts('/sys/devices/system/cpu/cpu'.$proc.'/cpufreq/cpuinfo_min_freq', $buf, 1, 4096, false)) {
514
                        $dev->setCpuSpeedMin(trim($buf) / 1000);
515
                    }
516
                    // variable speed processors specific code ends
517
                    if (PSI_LOAD_BAR) {
518
                            $dev->setLoad($this->_parseProcStat('cpu'.$proc));
519
                    }
520
/*
521
                    if (CommonFunctions::rfts('/proc/acpi/thermal_zone/THRM/temperature', $buf, 1, 4096, false)
522
                       &&  preg_match("/(\S+)\sC$/", $buf, $value)) {
523
                        $dev->setTemp(value[1]);
524
                    }
525
*/
526
                    if (($arch !== null) && ($impl !== null) && ($part !== null)) {
527
                        if (($impl === '0x41')
528
                           && (($_hard === 'BCM2708') || ($_hard === 'BCM2835') || ($_hard === 'BCM2709') || ($_hard === 'BCM2836') || ($_hard === 'BCM2710') || ($_hard === 'BCM2837') || ($_hard === 'BCM2711') || ($_hard === 'BCM2838'))
529
                           && ($_revi !== null)) { // Raspberry Pi detection (instead of 'cat /proc/device-tree/model')
530
                            if ($raslist === null) $raslist = @parse_ini_file(PSI_APP_ROOT."/data/raspberry.ini", true);
531
                            if ($raslist && !preg_match('/[^0-9a-f]/', $_revi)) {
532
                                if (($revidec = hexdec($_revi)) & 0x800000) {
533
                                    if ($this->sys->getMachine() === '') {
534
                                        $manufacturer = ($revidec >> 16) & 15;
535
                                        if (isset($raslist['manufacturer'][$manufacturer])) {
536
                                            $manuf = ' '.$raslist['manufacturer'][$manufacturer];
537
                                        } else {
538
                                            $manuf = '';
539
                                        }
540
                                        $model = ($revidec >> 4) & 255;
541
                                        if (isset($raslist['model'][$model])) {
542
                                            $this->sys->setMachine('Raspberry Pi '.$raslist['model'][$model].' (PCB 1.'.($revidec & 15).$manuf.')');
543
                                        } else {
544
                                            $this->sys->setMachine('Raspberry Pi (PCB 1.'.($revidec & 15).$manuf.')');
545
                                        }
546
                                    }
547
                                } else {
548
                                    if ($this->sys->getMachine() === '') {
549
                                        if (isset($raslist['old'][$revidec & 0x7fffff])) {
550
                                            $this->sys->setMachine('Raspberry Pi '.$raslist['old'][$revidec & 0x7fffff]);
551
                                        } else {
552
                                            $this->sys->setMachine('Raspberry Pi');
553
                                        }
554
                                    }
555
                                }
556
                            }
557
                        } elseif (($_hard !== null) && ($this->sys->getMachine() === '')) { // other ARM hardware
558
                            $this->sys->setMachine($_hard);
559
                        }
560
                        if ($cpulist === null) $cpulist = @parse_ini_file(PSI_APP_ROOT."/data/cpus.ini", true);
561
                        if ($cpulist && (isset($cpulist['cpu'][$cpuimplpart = strtolower($impl.','.$part)]))) {
562
                            if (($cpumodel = $dev->getModel()) !== '') {
563
                                $dev->setModel($cpumodel.' - '.$cpulist['cpu'][$cpuimplpart]);
564
                            } else {
565
                                $dev->setModel($cpulist['cpu'][$cpuimplpart]);
566
                            }
567
                        }
568
                    } elseif (($_hard !== null) && ($this->sys->getMachine() === '')) { // other hardware
569
                        $this->sys->setMachine($_hard);
570
                    }
571
 
572
                    if ($dev->getModel() === "") {
573
                        $dev->setModel("unknown");
574
                    }
575
                    $cpucount++;
576
                    $this->sys->setCpus($dev);
577
                }
578
            }
579
 
580
            $cpudevices = glob('/sys/devices/system/cpu/cpu*/uevent', GLOB_NOSORT);
581
            if (is_array($cpudevices) && (($cpustopped = count($cpudevices)-$cpucount) > 0)) {
582
                for (; $cpustopped > 0; $cpustopped--) {
583
                    $dev = new CpuDevice();
584
                    $dev->setModel("stopped");
585
                    if ($speedset) {
586
                        $dev->setCpuSpeed(-1);
587
                    }
588
                    $this->sys->setCpus($dev);
589
                }
590
            }
591
        }
325 richard 592
    }
593
 
2770 rexy 594
    /**
595
     * PCI devices
596
     *
597
     * @return void
598
     */
599
    private function _pci()
600
    {
601
        if ($arrResults = Parser::lspci()) {
602
            foreach ($arrResults as $dev) {
603
                $this->sys->setPciDevices($dev);
604
            }
605
        } elseif (CommonFunctions::rfts('/proc/pci', $strBuf, 0, 4096, false)) {
606
            $booDevice = false;
607
            $arrBuf = preg_split("/\n/", $strBuf, -1, PREG_SPLIT_NO_EMPTY);
608
            foreach ($arrBuf as $strLine) {
609
                if (preg_match('/^\s*Bus\s/', $strLine)) {
610
                    $booDevice = true;
611
                    continue;
612
                }
613
                if ($booDevice) {
614
                    $dev = new HWDevice();
615
                    $dev->setName(preg_replace('/\([^\)]+\)\.$/', '', trim($strLine)));
616
                    $this->sys->setPciDevices($dev);
617
/*
618
                    list($strKey, $strValue) = preg_split('/: /', $strLine, 2);
619
                    if (!preg_match('/bridge/i', $strKey) && !preg_match('/USB/i ', $strKey)) {
620
                        $dev = new HWDevice();
621
                        $dev->setName(preg_replace('/\([^\)]+\)\.$/', '', trim($strValue)));
622
                        $this->sys->setPciDevices($dev);
623
                    }
624
*/
625
                    $booDevice = false;
626
                }
627
            }
628
        } else {
629
            $pcidevices = glob('/sys/bus/pci/devices/*/uevent', GLOB_NOSORT);
630
            if (is_array($pcidevices) && (($total = count($pcidevices)) > 0)) {
631
                $buf = "";
632
                for ($i = 0; $i < $total; $i++) {
633
                    if (CommonFunctions::rfts($pcidevices[$i], $buf, 0, 4096, false) && (trim($buf) != "")) {
634
                        $pcibuf = "";
635
                        if (preg_match("/^PCI_CLASS=(\S+)/m", trim($buf), $subbuf)) {
636
                            $pcibuf = "Class ".$subbuf[1].":";
637
                        }
638
                        if (preg_match("/^PCI_ID=(\S+)/m", trim($buf), $subbuf)) {
639
                            $pcibuf .= " Device ".$subbuf[1];
640
                        }
641
                        if (preg_match("/^DRIVER=(\S+)/m", trim($buf), $subbuf)) {
642
                            $pcibuf .= " Driver ".$subbuf[1];
643
                        }
644
                        $dev = new HWDevice();
645
                        if (trim($pcibuf) != "") {
646
                            $dev->setName(trim($pcibuf));
647
                        } else {
648
                            $dev->setName("unknown");
649
                        }
650
                        $this->sys->setPciDevices($dev);
651
                    }
652
                }
653
            }
654
        }
655
    }
325 richard 656
 
2770 rexy 657
    /**
658
     * IDE devices
659
     *
660
     * @return void
661
     */
662
    private function _ide()
663
    {
664
        $bufd = CommonFunctions::gdc('/proc/ide', false);
665
        foreach ($bufd as $file) {
666
            if (preg_match('/^hd/', $file)) {
667
                $dev = new HWDevice();
668
                $dev->setName(trim($file));
669
                if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS && CommonFunctions::rfts("/proc/ide/".$file."/media", $buf, 1)) {
670
                    if (trim($buf) == 'disk') {
671
                        if (CommonFunctions::rfts("/proc/ide/".$file."/capacity", $buf, 1, 4096, false) || CommonFunctions::rfts("/sys/block/".$file."/size", $buf, 1, 4096, false)) {
672
                            $dev->setCapacity(trim($buf) * 512);
673
                        }
674
                    }
675
                }
676
                if (CommonFunctions::rfts("/proc/ide/".$file."/model", $buf, 1)) {
677
                    $dev->setName($dev->getName().": ".trim($buf));
678
                }
679
                $this->sys->setIdeDevices($dev);
680
            }
681
        }
682
    }
325 richard 683
 
2770 rexy 684
    /**
685
     * SCSI devices
686
     *
687
     * @return void
688
     */
689
    private function _scsi()
690
    {
691
        $getline = 0;
692
        $device = null;
693
        $scsiid = null;
694
        if (CommonFunctions::executeProgram('lsscsi', '-c', $bufr, PSI_DEBUG) || CommonFunctions::rfts('/proc/scsi/scsi', $bufr, 0, 4096, PSI_DEBUG)) {
695
            $bufe = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY);
696
            foreach ($bufe as $buf) {
697
                if (preg_match('/Host: scsi(\d+) Channel: (\d+) Target: (\d+) Lun: (\d+)/i', $buf, $scsiids)
698
                   || preg_match('/Host: scsi(\d+) Channel: (\d+) Id: (\d+) Lun: (\d+)/i', $buf, $scsiids)) {
699
                    $scsiid = $scsiids;
700
                    $getline = 1;
701
                    continue;
702
                }
703
                if ($getline == 1) {
704
                    preg_match('/Vendor: (.*) Model: (.*) Rev: (.*)/i', $buf, $devices);
705
                    $getline = 2;
706
                    $device = $devices;
707
                    continue;
708
                }
709
                if ($getline == 2) {
710
                    preg_match('/Type:\s+(\S+)/i', $buf, $dev_type);
711
 
712
                    $dev = new HWDevice();
713
                    $dev->setName($device[1].' '.$device[2].' ('.$dev_type[1].')');
714
 
715
                    if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS
716
                       && ($dev_type[1]==='Direct-Access')) {
717
                       $sizelist = glob('/sys/bus/scsi/devices/'.intval($scsiid[1]).':'.intval($scsiid[2]).':'.intval($scsiid[3]).':'.intval($scsiid[4]).'/*/*/size', GLOB_NOSORT);
718
                       if (is_array($sizelist) && (($total = count($sizelist)) > 0)) {
719
                           $buf = "";
720
                           for ($i = 0; $i < $total; $i++) {
721
                               if (CommonFunctions::rfts($sizelist[$i], $buf, 1, 4096, false) && (($buf=trim($buf)) != "") && ($buf > 0)) {
722
                                   $dev->setCapacity($buf * 512);
723
                                   break;
724
                               }
725
                           }
726
                       }
727
                    }
728
                    $this->sys->setScsiDevices($dev);
729
                    $getline = 0;
730
                }
325 richard 731
            }
2770 rexy 732
        }
325 richard 733
    }
734
 
2770 rexy 735
    /**
736
     * USB devices
737
     *
738
     * @return void
739
     */
740
    protected function _usb()
741
    {
742
        $usbarray = array();
743
        if (CommonFunctions::executeProgram('lsusb', (PSI_OS != 'Android')?'':'2>/dev/null', $bufr, PSI_DEBUG && (PSI_OS != 'Android'), 5) && ($bufr !== "")) {
744
            $bufe = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY);
745
            foreach ($bufe as $buf) {
746
                $device = preg_split("/ /", $buf, 7);
747
                if (((isset($device[6]) && trim($device[6]) != "")) ||
748
                    ((isset($device[5]) && trim($device[5]) != ""))) {
749
                    $usbid = intval($device[1]).'-'.intval(trim($device[3],':')).' '.$device[5];
750
                    if ((isset($device[6]) && trim($device[6]) != "")) {
751
                        $usbarray[$usbid]['name'] = trim($device[6]);
752
                    } else {
753
                        $usbarray[$usbid]['name'] = 'unknown';
754
                    }
755
                }
756
            }
757
        }
325 richard 758
 
2770 rexy 759
        $usbdevices = glob('/sys/bus/usb/devices/*/idProduct', GLOB_NOSORT);
760
        if (is_array($usbdevices) && (($total = count($usbdevices)) > 0)) {
761
            for ($i = 0; $i < $total; $i++) {
762
                if (CommonFunctions::rfts($usbdevices[$i], $idproduct, 1, 4096, false) && (($idproduct=trim($idproduct)) != "")) { //is readable
763
                    $busnum = CommonFunctions::rolv($usbdevices[$i], '/\/idProduct$/', '/busnum');
764
                    $devnum = CommonFunctions::rolv($usbdevices[$i], '/\/idProduct$/', '/devnum');
765
                    $idvendor = CommonFunctions::rolv($usbdevices[$i], '/\/idProduct$/', '/idVendor');
766
                    if (($busnum!==null) && ($devnum!==null) && ($idvendor!==null)) {
767
                        $usbid = intval($busnum).'-'.intval($devnum).' '.$idvendor.':'.$idproduct;
768
                        $manufacturer = CommonFunctions::rolv($usbdevices[$i], '/\/idProduct$/', '/manufacturer');
769
                        if ($manufacturer!==null) {
770
                            $usbarray[$usbid]['manufacturer'] = $manufacturer;
771
                        }
772
                        $product = CommonFunctions::rolv($usbdevices[$i], '/\/idProduct$/', '/product');
773
                        if ($product!==null) {
774
                            $usbarray[$usbid]['product'] = $product;
775
                        }
776
                        if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS
777
                           && defined('PSI_SHOW_DEVICES_SERIAL') && PSI_SHOW_DEVICES_SERIAL) {
778
                            $serial = CommonFunctions::rolv($usbdevices[$i], '/\/idProduct$/', '/serial');
779
                            if (($serial!==null) && !preg_match('/\W/', $serial)) {
780
                                $usbarray[$usbid]['serial'] = $serial;
781
                            }
782
                        }
783
                    }
784
                }
785
            }
786
        }
325 richard 787
 
2770 rexy 788
        if ((count($usbarray) == 0) && CommonFunctions::rfts('/proc/bus/usb/devices', $bufr, 0, 4096, false)) {
789
            $devnum = -1;
790
            $bufe = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY);
791
            foreach ($bufe as $buf) {
792
                if (preg_match('/^T/', $buf)) {
793
                    $devnum++;
794
                } elseif (preg_match('/^S:/', $buf)) {
795
                    list($key, $value) = preg_split('/: /', $buf, 2);
796
                    list($key, $value2) = preg_split('/=/', $value, 2);
797
                    switch (trim($key)) {
798
                    case 'Manufacturer':
799
                        $usbarray[$devnum]['manufacturer'] = trim($value2);
800
                        break;
801
                    case 'Product':
802
                        $usbarray[$devnum]['product'] = trim($value2);
803
                        break;
804
                    case 'SerialNumber':
805
                        if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS
806
                           && defined('PSI_SHOW_DEVICES_SERIAL') && PSI_SHOW_DEVICES_SERIAL
807
                           && !preg_match('/\W/', trim($value2))) {
808
                            $usbarray[$devnum]['serial'] = trim($value2);
809
                         }
810
                         break;
811
                    }
812
                }
813
            }
814
        }
325 richard 815
 
2770 rexy 816
        if ((count($usbarray) == 0) && CommonFunctions::rfts('/proc/bus/input/devices', $bufr, 0, 4096, false)) {
817
            $devnam = "unknown";
818
            $bufe = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY);
819
            foreach ($bufe as $buf) {
820
                if (preg_match('/^I:\s+(.+)/', $buf, $bufr)
821
                   && isset($bufr[1]) && (trim($bufr[1])!=="")) {
822
                    $devnam = trim($bufr[1]);
823
                    $usbarray[$devnam]['phys'] = 'unknown';
824
                } elseif (preg_match('/^N:\s+Name="([^"]+)"/', $buf, $bufr2)
825
                   && isset($bufr2[1]) && (trim($bufr2[1])!=="")) {
826
                    $usbarray[$devnam]['name'] = trim($bufr2[1]);
827
                } elseif (preg_match('/^P:\s+Phys=(.*)/', $buf, $bufr2)
828
                   && isset($bufr2[1]) && (trim($bufr2[1])!=="")) {
829
                    $usbarray[$devnam]['phys'] = trim($bufr2[1]);
830
                } elseif (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS
831
                   && defined('PSI_SHOW_DEVICES_SERIAL') && PSI_SHOW_DEVICES_SERIAL
832
                   && preg_match('/^U:\s+Uniq=(.+)/', $buf, $bufr2)
833
                   && isset($bufr2[1]) && (trim($bufr2[1])!=="")) {
834
                    $usbarray[$devnam]['serial'] = trim($bufr2[1]);
835
                }
836
            }
837
        }
325 richard 838
 
2770 rexy 839
        foreach ($usbarray as $usbdev) if (!isset($usbdev['phys']) || preg_match('/^usb-/', $usbdev['phys'])) {
840
            $dev = new HWDevice();
325 richard 841
 
2770 rexy 842
            if (isset($usbdev['manufacturer']) && (($manufacturer=$usbdev['manufacturer']) !== 'no manufacturer')) {
843
                if (preg_match("/^linux\s/i", $manufacturer)) {
844
                    $manufacturer = 'Linux Foundation';
845
                }
846
                if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS) {
847
                    $dev->setManufacturer($manufacturer);
848
                }
849
            } else {
850
                $manufacturer = '';
851
            }
852
 
853
            if (isset($usbdev['product'])) {
854
                $product = $usbdev['product'];
855
                if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS) {
856
                    $dev->setProduct($product);
857
                }
858
            } else {
859
                $product = '';
860
            }
861
 
862
            if (defined('PSI_SHOW_DEVICES_INFOS') && PSI_SHOW_DEVICES_INFOS
863
                && defined('PSI_SHOW_DEVICES_SERIAL') && PSI_SHOW_DEVICES_SERIAL
864
                && isset($usbdev['serial'])) {
865
                $dev->setSerial($usbdev['serial']);
866
            }
867
 
868
            if (isset($usbdev['name']) && (($name=$usbdev['name']) !== 'unknown')) {
869
                $dev->setName($name);
870
            } else {
871
                if (($newname = trim($manufacturer.' '.$product)) !== '') {
872
                    $dev->setName($newname);
873
                } else {
874
                    $dev->setName('unknown');
875
                }
876
            }
877
 
878
            $this->sys->setUsbDevices($dev);
879
        }
325 richard 880
    }
881
 
2770 rexy 882
    /**
883
     * I2C devices
884
     *
885
     * @return void
886
     */
887
    protected function _i2c()
888
    {
889
        $i2cdevices = glob('/sys/bus/i2c/devices/*/name', GLOB_NOSORT);
890
        if (is_array($i2cdevices) && (($total = count($i2cdevices)) > 0)) {
891
            $buf = "";
892
            for ($i = 0; $i < $total; $i++) {
893
                if (CommonFunctions::rfts($i2cdevices[$i], $buf, 1, 4096, false) && (trim($buf) != "")) {
894
                    $dev = new HWDevice();
895
                    $dev->setName(trim($buf));
896
                    $this->sys->setI2cDevices($dev);
897
                }
898
            }
899
        }
900
    }
325 richard 901
 
2770 rexy 902
    /**
903
     * NVMe devices
904
     *
905
     * @return void
906
     */
907
    protected function _nvme()
908
    {
909
        if (CommonFunctions::executeProgram('nvme', 'list', $bufr, PSI_DEBUG) && ($bufr!="")) {
910
            $bufe = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY);
911
            $count = 0;
912
            $nlocate = array();
913
            $nsize = array();
914
            foreach ($bufe as $buf) {
915
                if ($count == 1) {
916
                    $locid = 0;
917
                    $nlocate[0] = 0;
918
                    $total = strlen($buf);
919
                    $begin = true;
920
                    for ($i = 0; $i < $total; $i++) {
921
                        if ($begin) {
922
                            if ($buf[$i] !== '-') {
923
                                $nsize[$locid] = $i - $nlocate[$locid];
924
                                $locid++;
925
                                $begin = false;
926
                            }
927
                        } else {
928
                            if ($buf[$i] === '-') {
929
                                $nlocate[$locid] = $i;
930
                                $begin = true;
931
                            }
932
                        }
933
                    }
934
                    if ($begin) {
935
                        $nsize[$locid] = $i - $nlocate[$locid];
936
                    }
937
                } elseif ($count > 1) {
938
                    if (isset($nlocate[2]) && isset($nsize[2])) {
939
                        $dev = new HWDevice();
940
                        $dev->setName(trim(substr($buf, $nlocate[2], $nsize[2])));
941
                        if (defined('PSI_SHOW_DEVICES_INFOS') && (PSI_SHOW_DEVICES_INFOS)) {
942
                            if (isset($nlocate[4]) && isset($nsize[4])) {
943
                                if (preg_match('/\/\s*([0-9\.]+)\s*(B|KB|MB|GB|TB|PB)$/', str_replace(',', '.', trim(substr($buf, $nlocate[4], $nsize[4]))), $tmpbuf)) {
944
                                    switch ($tmpbuf[2]) {
945
                                        case 'B':
946
                                            $dev->setCapacity($tmpbuf[1]);
947
                                            break;
948
                                        case 'KB':
949
                                            $dev->setCapacity(1000*$tmpbuf[1]);
950
                                            break;
951
                                        case 'MB':
952
                                            $dev->setCapacity(1000*1000*$tmpbuf[1]);
953
                                            break;
954
                                        case 'GB':
955
                                            $dev->setCapacity(1000*1000*1000*$tmpbuf[1]);
956
                                            break;
957
                                        case 'TB':
958
                                            $dev->setCapacity(1000*1000*1000*1000*$tmpbuf[1]);
959
                                            break;
960
                                        case 'PB':
961
                                            $dev->setCapacity(1000*1000*1000*1000*1000*$tmpbuf[1]);
962
                                            break;
963
                                    }
964
                                }
965
                            }
966
                            if (defined('PSI_SHOW_DEVICES_SERIAL') && PSI_SHOW_DEVICES_SERIAL) {
967
                                if (isset($nlocate[1]) && isset($nsize[1])) {
968
                                    $dev->setSerial(trim(substr($buf, $nlocate[1], $nsize[1])));
969
                                }
970
                            }
971
                        }
972
                        $this->sys->setNvmeDevices($dev);
973
                    }
974
                }
975
                $count++;
976
            }
977
        }
978
    }
325 richard 979
 
2770 rexy 980
    /**
981
     * Network devices
982
     * includes also rx/tx bytes
983
     *
984
     * @return void
985
     */
986
    protected function _network()
987
    {
988
        if (CommonFunctions::rfts('/proc/net/dev', $bufr, 0, 4096, PSI_DEBUG)) {
989
            $bufe = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY);
990
            foreach ($bufe as $buf) {
991
                if (preg_match('/:/', $buf)) {
992
                    list($dev_name, $stats_list) = preg_split('/:/', $buf, 2);
993
                    $stats = preg_split('/\s+/', trim($stats_list));
994
                    $dev = new NetDevice();
995
                    $dev->setName(trim($dev_name));
996
                    $dev->setRxBytes($stats[0]);
997
                    $dev->setTxBytes($stats[8]);
998
                    $dev->setErrors($stats[2] + $stats[10]);
999
                    $dev->setDrops($stats[3] + $stats[11]);
1000
                    if (defined('PSI_SHOW_NETWORK_INFOS') && (PSI_SHOW_NETWORK_INFOS)) {
1001
                        $macaddr = "";
1002
                        if ((CommonFunctions::executeProgram('ip', 'addr show '.trim($dev_name), $bufr2, PSI_DEBUG) && ($bufr2!=""))
1003
                           || CommonFunctions::executeProgram('ifconfig', trim($dev_name).' 2>/dev/null', $bufr2, PSI_DEBUG)) {
1004
                            $bufe2 = preg_split("/\n/", $bufr2, -1, PREG_SPLIT_NO_EMPTY);
1005
                            foreach ($bufe2 as $buf2) {
1006
//                                if (preg_match('/^'.trim($dev_name).'\s+Link\sencap:Ethernet\s+HWaddr\s(\S+)/i', $buf2, $ar_buf2)
1007
                                if (preg_match('/\s+encap:Ethernet\s+HWaddr\s(\S+)/i', $buf2, $ar_buf2)
1008
                                   || preg_match('/\s+encap:UNSPEC\s+HWaddr\s(\S+)-00-00-00-00-00-00-00-00-00-00\s*$/i', $buf2, $ar_buf2)
1009
                                   || preg_match('/^\s+ether\s+(\S+)\s+txqueuelen/i', $buf2, $ar_buf2)
1010
                                   || preg_match('/^\s+link\/ether\s+(\S+)\s+brd/i', $buf2, $ar_buf2)
1011
                                   || preg_match('/^\s+link\/ether\s+(\S+)$/i', $buf2, $ar_buf2)
1012
                                   || preg_match('/^\s+link\/ieee802.11\s+(\S+)$/i', $buf2, $ar_buf2)) {
1013
                                    if (!defined('PSI_HIDE_NETWORK_MACADDR') || !PSI_HIDE_NETWORK_MACADDR) {
1014
                                        $macaddr = preg_replace('/:/', '-', strtoupper($ar_buf2[1]));
1015
                                        if ($macaddr === '00-00-00-00-00-00') { // empty
1016
                                            $macaddr = "";
1017
                                        }
1018
                                    }
1019
                                } elseif (preg_match('/^\s+inet\saddr:(\S+)\s+P-t-P:(\S+)/i', $buf2, $ar_buf2)
1020
                                       || preg_match('/^\s+inet\s+(\S+)\s+netmask.+destination\s+(\S+)/i', $buf2, $ar_buf2)
1021
                                       || preg_match('/^\s+inet\s+([^\/\s]+).*peer\s+([^\/\s]+).*\s+scope\s((global)|(host))/i', $buf2, $ar_buf2)) {
1022
                                    if ($ar_buf2[1] != $ar_buf2[2]) {
1023
                                        $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1].";:".$ar_buf2[2]);
1024
                                    } else {
1025
                                        $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1]);
1026
                                    }
1027
                                } elseif ((preg_match('/^\s+inet\saddr:(\S+)/i', $buf2, $ar_buf2)
1028
                                   || preg_match('/^\s+inet\s+(\S+)\s+netmask/i', $buf2, $ar_buf2)
1029
                                   || preg_match('/^'.trim($dev_name).':\s+ip\s+(\S+)\s+mask/i', $buf2, $ar_buf2)
1030
                                   || preg_match('/^\s+inet6\saddr:\s([^\/\s]+)(.+)\s+Scope:[GH]/i', $buf2, $ar_buf2)
1031
                                   || preg_match('/^\s+inet6\s+(\S+)\s+prefixlen(.+)((<global>)|(<host>))/i', $buf2, $ar_buf2)
1032
                                   || preg_match('/^\s+inet6?\s+([^\/\s]+).*\s+scope\s((global)|(host))/i', $buf2, $ar_buf2))
1033
                                   && ($ar_buf2[1]!="::") && !preg_match('/^fe80::/i', $ar_buf2[1])) {
1034
                                    $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').strtolower($ar_buf2[1]));
1035
                                }
1036
                            }
1037
                        }
1038
                        if ($macaddr != "") {
1039
                            $dev->setInfo($macaddr.($dev->getInfo()?';'.$dev->getInfo():''));
1040
                        }
1041
                        if (CommonFunctions::rfts('/sys/class/net/'.trim($dev_name).'/speed', $buf, 1, 4096, false) && (($speed=trim($buf))!="") && ($buf > 0) && ($buf < 65535)) {
1042
                            if ($speed > 1000) {
1043
                                $speed = $speed/1000;
1044
                                $unit = "G";
1045
                            } else {
1046
                                $unit = "M";
1047
                            }
1048
                            if (CommonFunctions::rfts('/sys/class/net/'.trim($dev_name).'/duplex', $buf, 1, 4096, false) && (($duplex=strtolower(trim($buf)))!="") && ($duplex!='unknown')) {
1049
                                $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$speed.$unit.'b/s '.$duplex);
1050
                            } else {
1051
                                $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$speed.$unit.'b/s');
1052
                            }
1053
                        }
1054
                    }
1055
                    $this->sys->setNetDevices($dev);
1056
                }
1057
            }
1058
        } elseif (CommonFunctions::executeProgram('ip', 'addr show', $bufr, PSI_DEBUG) && ($bufr!="")) {
1059
            $lines = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY);
1060
            $was = false;
1061
            $macaddr = "";
1062
            $speedinfo = "";
1063
            $dev = null;
1064
            foreach ($lines as $line) {
1065
                if (preg_match("/^\d+:\s+([^\s:]+)/", $line, $ar_buf)) {
1066
                    if ($was) {
1067
                        if ($macaddr != "") {
1068
                            $dev->setInfo($macaddr.($dev->getInfo()?';'.$dev->getInfo():''));
1069
                        }
1070
                        if ($speedinfo != "") {
1071
                            $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$speedinfo);
1072
                        }
1073
                        $this->sys->setNetDevices($dev);
1074
                    }
1075
                    $speedinfo = "";
1076
                    $macaddr = "";
1077
                    $dev = new NetDevice();
1078
                    $dev->setName($ar_buf[1]);
1079
                    if (CommonFunctions::executeProgram('ip', '-s link show '.$ar_buf[1], $bufr2, PSI_DEBUG) && ($bufr2!="")
1080
                       && 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)) {
1081
                        $dev->setRxBytes($ar_buf2[1]);
1082
                        $dev->setTxBytes($ar_buf2[4]);
1083
                        $dev->setErrors($ar_buf2[2]+$ar_buf2[5]);
1084
                        $dev->setDrops($ar_buf2[3]+$ar_buf2[6]);
1085
                    }
1086
                    $was = true;
1087
                    if (defined('PSI_SHOW_NETWORK_INFOS') && (PSI_SHOW_NETWORK_INFOS)) {
1088
                        if (CommonFunctions::rfts('/sys/class/net/'.$ar_buf[1].'/speed', $buf, 1, 4096, false) && (trim($buf)!="")) {
1089
                            $speed = trim($buf);
1090
                            if ($speed > 1000) {
1091
                                $speed = $speed/1000;
1092
                                $unit = "G";
1093
                            } else {
1094
                                $unit = "M";
1095
                            }
1096
                            if (CommonFunctions::rfts('/sys/class/net/'.$ar_buf[1].'/duplex', $buf, 1, 4096, false) && (trim($buf)!="")) {
1097
                                $speedinfo = $speed.$unit.'b/s '.strtolower(trim($buf));
1098
                            } else {
1099
                                $speedinfo = $speed.$unit.'b/s';
1100
                            }
1101
                        }
1102
                    }
1103
                } else {
1104
                    if ($was) {
1105
                        if (defined('PSI_SHOW_NETWORK_INFOS') && (PSI_SHOW_NETWORK_INFOS)) {
1106
                            if (preg_match('/^\s+link\/ether\s+(\S+)\s+brd/i', $line, $ar_buf2)) {
1107
                                if (!defined('PSI_HIDE_NETWORK_MACADDR') || !PSI_HIDE_NETWORK_MACADDR) $macaddr = preg_replace('/:/', '-', strtoupper($ar_buf2[1]));
1108
                            } elseif (preg_match('/^\s+inet\s+([^\/\s]+).*peer\s+([^\/\s]+).*\s+scope\s((global)|(host))/i', $line, $ar_buf2)) {
1109
                                if ($ar_buf2[1] != $ar_buf2[2]) {
1110
                                     $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1].";:".$ar_buf2[2]);
1111
                                } else {
1112
                                     $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1]);
1113
                                }
1114
                            } elseif (preg_match('/^\s+inet6?\s+([^\/\s]+).*\s+scope\s((global)|(host))/i', $line, $ar_buf2)
1115
                                     && ($ar_buf2[1]!="::") && !preg_match('/^fe80::/i', $ar_buf2[1])) {
1116
                                $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').strtolower($ar_buf2[1]));
1117
                            }
1118
                        }
1119
                    }
1120
                }
1121
            }
1122
            if ($was) {
1123
                if ($macaddr != "") {
1124
                    $dev->setInfo($macaddr.($dev->getInfo()?';'.$dev->getInfo():''));
1125
                }
1126
                if ($speedinfo != "") {
1127
                    $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$speedinfo);
1128
                }
1129
                $this->sys->setNetDevices($dev);
1130
            }
1131
        } elseif (CommonFunctions::executeProgram('ifconfig', '-a', $bufr, PSI_DEBUG)) {
1132
            $lines = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY);
1133
            $was = false;
1134
            $errors = 0;
1135
            $drops = 0;
1136
            $macaddr = "";
1137
            $speedinfo = "";
1138
            $dev = null;
1139
            foreach ($lines as $line) {
1140
                if (preg_match("/^([^\s:]+)/", $line, $ar_buf)) {
1141
                    if ($was) {
1142
                        $dev->setErrors($errors);
1143
                        $dev->setDrops($drops);
1144
                        if ($macaddr != "") {
1145
                            $dev->setInfo($macaddr.($dev->getInfo()?';'.$dev->getInfo():''));
1146
                        }
1147
                        if ($speedinfo != "") {
1148
                            $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$speedinfo);
1149
                        }
1150
                        $this->sys->setNetDevices($dev);
1151
                    }
1152
                    $errors = 0;
1153
                    $drops = 0;
1154
                    $speedinfo = "";
1155
                    $macaddr = "";
1156
                    $dev = new NetDevice();
1157
                    $dev->setName($ar_buf[1]);
1158
                    $was = true;
1159
                    if (defined('PSI_SHOW_NETWORK_INFOS') && (PSI_SHOW_NETWORK_INFOS)) {
1160
                        if (CommonFunctions::rfts('/sys/class/net/'.$ar_buf[1].'/speed', $buf, 1, 4096, false) && (trim($buf)!="")) {
1161
                            $speed = trim($buf);
1162
                            if ($speed > 1000) {
1163
                                $speed = $speed/1000;
1164
                                $unit = "G";
1165
                            } else {
1166
                                $unit = "M";
1167
                            }
1168
                            if (CommonFunctions::rfts('/sys/class/net/'.$ar_buf[1].'/duplex', $buf, 1, 4096, false) && (trim($buf)!="")) {
1169
                                $speedinfo = $speed.$unit.'b/s '.strtolower(trim($buf));
1170
                            } else {
1171
                                $speedinfo = $speed.$unit.'b/s';
1172
                            }
1173
                        }
1174
                        if (preg_match('/^'.$ar_buf[1].'\s+Link\sencap:Ethernet\s+HWaddr\s(\S+)/i', $line, $ar_buf2))
1175
                            if (!defined('PSI_HIDE_NETWORK_MACADDR') || !PSI_HIDE_NETWORK_MACADDR) $macaddr = preg_replace('/:/', '-', strtoupper($ar_buf2[1]));
1176
                        elseif (preg_match('/^'.$ar_buf[1].':\s+ip\s+(\S+)\s+mask/i', $line, $ar_buf2))
1177
                            $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1]);
1178
                    }
1179
                } else {
1180
                    if ($was) {
1181
                        if (preg_match('/\sRX bytes:(\d+)\s/i', $line, $ar_buf2)) {
1182
                            $dev->setRxBytes($ar_buf2[1]);
1183
                        }
1184
                        if (preg_match('/\sTX bytes:(\d+)\s/i', $line, $ar_buf2)) {
1185
                            $dev->setTxBytes($ar_buf2[1]);
1186
                        }
325 richard 1187
 
2770 rexy 1188
                        if (preg_match('/\sRX packets:\d+\serrors:(\d+)\sdropped:(\d+)/i', $line, $ar_buf2)) {
1189
                            $errors +=$ar_buf2[1];
1190
                            $drops +=$ar_buf2[2];
1191
                        } elseif (preg_match('/\sTX packets:\d+\serrors:(\d+)\sdropped:(\d+)/i', $line, $ar_buf2)) {
1192
                            $errors +=$ar_buf2[1];
1193
                            $drops +=$ar_buf2[2];
1194
                        }
1195
 
1196
                        if (defined('PSI_SHOW_NETWORK_INFOS') && (PSI_SHOW_NETWORK_INFOS)) {
1197
                            if (preg_match('/\s+encap:Ethernet\s+HWaddr\s(\S+)/i', $line, $ar_buf2)
1198
                             || preg_match('/^\s+ether\s+(\S+)\s+txqueuelen/i', $line, $ar_buf2)) {
1199
                                if (!defined('PSI_HIDE_NETWORK_MACADDR') || !PSI_HIDE_NETWORK_MACADDR) $macaddr = preg_replace('/:/', '-', strtoupper($ar_buf2[1]));
1200
                            } elseif (preg_match('/^\s+inet\saddr:(\S+)\s+P-t-P:(\S+)/i', $line, $ar_buf2)
1201
                                  || preg_match('/^\s+inet\s+(\S+)\s+netmask.+destination\s+(\S+)/i', $line, $ar_buf2)) {
1202
                                if ($ar_buf2[1] != $ar_buf2[2]) {
1203
                                     $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1].";:".$ar_buf2[2]);
1204
                                } else {
1205
                                     $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$ar_buf2[1]);
1206
                                }
1207
                            } elseif ((preg_match('/^\s+inet\saddr:(\S+)/i', $line, $ar_buf2)
1208
                                  || preg_match('/^\s+inet\s+(\S+)\s+netmask/i', $line, $ar_buf2)
1209
                                  || preg_match('/^\s+inet6\saddr:\s([^\/\s]+)(.+)\s+Scope:[GH]/i', $line, $ar_buf2)
1210
                                  || preg_match('/^\s+inet6\s+(\S+)\s+prefixlen(.+)((<global>)|(<host>))/i', $line, $ar_buf2))
1211
                                  && ($ar_buf2[1]!="::") && !preg_match('/^fe80::/i', $ar_buf2[1])) {
1212
                                $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').strtolower($ar_buf2[1]));
1213
                            }
1214
                        }
1215
                    }
1216
                }
1217
            }
1218
            if ($was) {
1219
                $dev->setErrors($errors);
1220
                $dev->setDrops($drops);
1221
                if ($macaddr != "") {
1222
                    $dev->setInfo($macaddr.($dev->getInfo()?';'.$dev->getInfo():''));
1223
                }
1224
                if ($speedinfo != "") {
1225
                    $dev->setInfo(($dev->getInfo()?$dev->getInfo().';':'').$speedinfo);
1226
                }
1227
                $this->sys->setNetDevices($dev);
1228
            }
1229
        }
325 richard 1230
    }
1231
 
2770 rexy 1232
    /**
1233
     * Physical memory information and Swap Space information
1234
     *
1235
     * @return void
1236
     */
1237
    protected function _memory()
1238
    {
1239
        if (CommonFunctions::rfts('/proc/meminfo', $mbuf)) {
1240
            $bufe = preg_split("/\n/", $mbuf, -1, PREG_SPLIT_NO_EMPTY);
1241
            foreach ($bufe as $buf) {
1242
                if (preg_match('/^MemTotal:\s+(\d+)\s*kB/i', $buf, $ar_buf)) {
1243
                    $this->sys->setMemTotal($ar_buf[1] * 1024);
1244
                } elseif (preg_match('/^MemFree:\s+(\d+)\s*kB/i', $buf, $ar_buf)) {
1245
                    $this->sys->setMemFree($ar_buf[1] * 1024);
1246
                } elseif (preg_match('/^Cached:\s+(\d+)\s*kB/i', $buf, $ar_buf)) {
1247
                    $this->sys->setMemCache($ar_buf[1] * 1024);
1248
                } elseif (preg_match('/^Buffers:\s+(\d+)\s*kB/i', $buf, $ar_buf)) {
1249
                    $this->sys->setMemBuffer($ar_buf[1] * 1024);
1250
                }
1251
            }
1252
            $this->sys->setMemUsed($this->sys->getMemTotal() - $this->sys->getMemFree());
1253
            // values for splitting memory usage
1254
            if ($this->sys->getMemCache() !== null && $this->sys->getMemBuffer() !== null) {
1255
                $this->sys->setMemApplication($this->sys->getMemUsed() - $this->sys->getMemCache() - $this->sys->getMemBuffer());
1256
            }
1257
            if (CommonFunctions::rfts('/proc/swaps', $sbuf, 0, 4096, false)) {
1258
                $swaps = preg_split("/\n/", $sbuf, -1, PREG_SPLIT_NO_EMPTY);
1259
                unset($swaps[0]);
1260
                foreach ($swaps as $swap) {
1261
                    $ar_buf = preg_split('/\s+/', $swap, 5);
1262
                    $dev = new DiskDevice();
1263
                    $dev->setMountPoint($ar_buf[0]);
1264
                    $dev->setName("SWAP");
1265
                    $dev->setTotal($ar_buf[2] * 1024);
1266
                    $dev->setUsed($ar_buf[3] * 1024);
1267
                    $dev->setFree($dev->getTotal() - $dev->getUsed());
1268
                    $this->sys->setSwapDevices($dev);
1269
                }
1270
            }
1271
        }
1272
    }
325 richard 1273
 
2770 rexy 1274
    /**
1275
     * filesystem information
1276
     *
1277
     * @return void
1278
     */
1279
    private function _filesystems()
1280
    {
1281
        $df_args = "";
1282
        $hideFstypes = array();
1283
        if (defined('PSI_HIDE_FS_TYPES') && is_string(PSI_HIDE_FS_TYPES)) {
1284
            if (preg_match(ARRAY_EXP, PSI_HIDE_FS_TYPES)) {
1285
                $hideFstypes = eval(PSI_HIDE_FS_TYPES);
1286
            } else {
1287
                $hideFstypes = array(PSI_HIDE_FS_TYPES);
1288
            }
1289
        }
1290
        foreach ($hideFstypes as $Fstype) {
1291
            $df_args .= "-x $Fstype ";
1292
        }
1293
        if ($df_args !== "") {
1294
            $df_args = trim($df_args); //trim spaces
1295
            $arrResult = Parser::df("-P $df_args 2>/dev/null");
1296
        } else {
1297
            $arrResult = Parser::df("-P 2>/dev/null");
1298
        }
1299
        foreach ($arrResult as $dev) {
1300
            $this->sys->setDiskDevices($dev);
1301
        }
1302
    }
325 richard 1303
 
2770 rexy 1304
    /**
1305
     * Distribution
1306
     *
1307
     * @return void
1308
     */
1309
    protected function _distro()
1310
    {
1311
        $this->sys->setDistribution("Linux");
1312
        $list = @parse_ini_file(PSI_APP_ROOT."/data/distros.ini", true);
1313
        if (!$list) {
1314
            return;
1315
        }
1316
        // We have the '2>/dev/null' because Ubuntu gives an error on this command which causes the distro to be unknown
1317
        if (CommonFunctions::executeProgram('lsb_release', '-a 2>/dev/null', $distro_info, PSI_DEBUG) && (strlen($distro_info) > 0)) {
1318
            $distro_tmp = preg_split("/\n/", $distro_info, -1, PREG_SPLIT_NO_EMPTY);
1319
            foreach ($distro_tmp as $info) {
1320
                $info_tmp = preg_split('/:/', $info, 2);
1321
                if (isset($distro_tmp[0]) && !is_null($distro_tmp[0]) && (trim($distro_tmp[0]) != "") &&
1322
                     isset($distro_tmp[1]) && !is_null($distro_tmp[1]) && (trim($distro_tmp[1]) != "")) {
1323
                    $distro[trim($info_tmp[0])] = trim($info_tmp[1]);
1324
                }
1325
            }
1326
            if (!isset($distro['Distributor ID']) && !isset($distro['Description'])) { // Systems like StartOS
1327
                if (isset($distro_tmp[0]) && !is_null($distro_tmp[0]) && (trim($distro_tmp[0]) != "")) {
1328
                    $this->sys->setDistribution(trim($distro_tmp[0]));
1329
                    if (preg_match('/^(\S+)\s*/', $distro_tmp[0], $id_buf)
1330
                        && isset($list[trim($id_buf[1])]['Image'])) {
1331
                            $this->sys->setDistributionIcon($list[trim($id_buf[1])]['Image']);
1332
                    }
1333
                }
1334
            } else {
1335
                if (isset($distro['Description'])
1336
                   && preg_match('/^NAME=\s*"?([^"\n]+)"?\s*$/', $distro['Description'], $name_tmp)) {
1337
                   $distro['Description'] = $name_tmp[1];
1338
                }
1339
                if (isset($distro['Description'])
1340
                   && ($distro['Description'] != "n/a")
1341
                   && (!isset($distro['Distributor ID'])
1342
                   || (($distro['Distributor ID'] != "n/a")
1343
                   && ($distro['Description'] != $distro['Distributor ID'])))) {
1344
                    $this->sys->setDistribution($distro['Description']);
1345
                    if (isset($distro['Release']) && ($distro['Release'] != "n/a")
1346
                       && ($distro['Release'] != $distro['Description']) && strstr($distro['Release'], ".")){
1347
                        if (preg_match("/^(\d+)\.[0]+$/", $distro['Release'], $match_buf)) {
1348
                            $tofind = $match_buf[1];
1349
                        } else {
1350
                            $tofind = $distro['Release'];
1351
                        }
1352
                        if (!preg_match("/^".$tofind."[\s\.]|[\(\[]".$tofind."[\.\)\]]|\s".$tofind."$|\s".$tofind."[\s\.]/", $distro['Description'])) {
1353
                            $this->sys->setDistribution($this->sys->getDistribution()." ".$distro['Release']);
1354
                        }
1355
                    }
1356
                } elseif (isset($distro['Distributor ID']) && ($distro['Distributor ID'] != "n/a")) {
1357
                    $this->sys->setDistribution($distro['Distributor ID']);
1358
                    if (isset($distro['Release']) && ($distro['Release'] != "n/a")) {
1359
                        $this->sys->setDistribution($this->sys->getDistribution()." ".$distro['Release']);
1360
                    }
1361
                    if (isset($distro['Codename']) && ($distro['Codename'] != "n/a")) {
1362
                        $this->sys->setDistribution($this->sys->getDistribution()." (".$distro['Codename'].")");
1363
                    }
1364
                }
1365
                if (isset($distro['Distributor ID']) && ($distro['Distributor ID'] != "n/a") && isset($list[$distro['Distributor ID']]['Image'])) {
1366
                    $this->sys->setDistributionIcon($list[$distro['Distributor ID']]['Image']);
1367
                } elseif (isset($distro['Description']) && ($distro['Description'] != "n/a")) {
1368
                    $this->sys->setDistribution($distro['Description']);
1369
                    if (isset($list[$distro['Description']]['Image'])) {
1370
                        $this->sys->setDistributionIcon($list[$distro['Description']]['Image']);
1371
                    }
1372
                }
1373
            }
1374
        } else {
1375
            /* default error handler */
1376
            if (function_exists('errorHandlerPsi')) {
1377
                restore_error_handler();
1378
            }
1379
            /* fatal errors only */
1380
            $old_err_rep = error_reporting();
1381
            error_reporting(E_ERROR);
325 richard 1382
 
2770 rexy 1383
            // Fall back in case 'lsb_release' does not exist but exist /etc/lsb-release
1384
            if (CommonFunctions::fileexists($filename="/etc/lsb-release")
1385
               && CommonFunctions::rfts($filename, $buf, 0, 4096, false)
1386
               && preg_match('/^DISTRIB_ID="?([^"\n]+)"?/m', $buf, $id_buf)) {
1387
                if (preg_match('/^DISTRIB_DESCRIPTION="?([^"\n]+)"?/m', $buf, $desc_buf)
1388
                   && (trim($desc_buf[1])!=trim($id_buf[1]))) {
1389
                    $this->sys->setDistribution(trim($desc_buf[1]));
1390
                    if (preg_match('/^DISTRIB_RELEASE="?([^"\n]+)"?/m', $buf, $vers_buf)
1391
                       && (trim($vers_buf[1])!=trim($desc_buf[1])) && strstr($vers_buf[1], ".")){
1392
                        if (preg_match("/^(\d+)\.[0]+$/", trim($vers_buf[1]), $match_buf)) {
1393
                            $tofind = $match_buf[1];
1394
                        } else {
1395
                            $tofind = trim($vers_buf[1]);
1396
                        }
1397
                        if (!preg_match("/^".$tofind."[\s\.]|[\(\[]".$tofind."[\.\)\]]|\s".$tofind."$|\s".$tofind."[\s\.]/", trim($desc_buf[1]))) {
1398
                            $this->sys->setDistribution($this->sys->getDistribution()." ".trim($vers_buf[1]));
1399
                        }
1400
                    }
1401
                } else {
1402
                    if (isset($list[trim($id_buf[1])]['Name'])) {
1403
                        $this->sys->setDistribution(trim($list[trim($id_buf[1])]['Name']));
1404
                    } else {
1405
                        $this->sys->setDistribution(trim($id_buf[1]));
1406
                    }
1407
                    if (preg_match('/^DISTRIB_RELEASE="?([^"\n]+)"?/m', $buf, $vers_buf)) {
1408
                        $this->sys->setDistribution($this->sys->getDistribution()." ".trim($vers_buf[1]));
1409
                    }
1410
                    if (preg_match('/^DISTRIB_CODENAME="?([^"\n]+)"?/m', $buf, $vers_buf)) {
1411
                        $this->sys->setDistribution($this->sys->getDistribution()." (".trim($vers_buf[1]).")");
1412
                    }
1413
                }
1414
                if (isset($list[trim($id_buf[1])]['Image'])) {
1415
                    $this->sys->setDistributionIcon($list[trim($id_buf[1])]['Image']);
1416
                }
1417
            } else { // otherwise find files specific for distribution
1418
                foreach ($list as $section=>$distribution) {
1419
                    if (!isset($distribution['Files'])) {
1420
                        continue;
1421
                    } else {
1422
                        foreach (preg_split("/;/", $distribution['Files'], -1, PREG_SPLIT_NO_EMPTY) as $filename) {
1423
                            if (CommonFunctions::fileexists($filename)) {
1424
                                $distro = $distribution;
1425
                                if (isset($distribution['Mode'])&&(strtolower($distribution['Mode'])=="detection")) {
1426
                                    $buf = "";
1427
                                } elseif (isset($distribution['Mode'])&&(strtolower($distribution['Mode'])=="execute")) {
1428
                                    if (!CommonFunctions::executeProgram($filename, '2>/dev/null', $buf, PSI_DEBUG)) {
1429
                                        $buf = "";
1430
                                    }
1431
                                } else {
1432
                                    if (!CommonFunctions::rfts($filename, $buf, 1, 4096, false)) {
1433
                                        $buf = "";
1434
                                    } elseif (isset($distribution['Mode'])&&(strtolower($distribution['Mode'])=="analyse")) {
1435
                                        if (preg_match('/^(\S+)\s*/', preg_replace('/^Red\s+/', 'Red', $buf), $id_buf)
1436
                                           && isset($list[trim($id_buf[1])]['Image'])) {
1437
                                            $distro = $list[trim($id_buf[1])];
1438
                                        }
1439
                                    }
1440
                                }
1441
                                if (isset($distro['Image'])) {
1442
                                    $this->sys->setDistributionIcon($distro['Image']);
1443
                                }
1444
                                if (isset($distribution['Name'])) {
1445
                                    if (is_null($buf) || (trim($buf) == "")) {
1446
                                        $this->sys->setDistribution($distribution['Name']);
1447
                                    } else {
1448
                                        $this->sys->setDistribution($distribution['Name']." ".trim($buf));
1449
                                    }
1450
                                } else {
1451
                                    if (is_null($buf) || (trim($buf) == "")) {
1452
                                        $this->sys->setDistribution($section);
1453
                                    } else {
1454
                                        $this->sys->setDistribution(trim($buf));
1455
                                    }
1456
                                }
1457
                                if (isset($distribution['Files2'])) {
1458
                                    foreach (preg_split("/;/", $distribution['Files2'], -1, PREG_SPLIT_NO_EMPTY) as $filename2) {
1459
                                        if (CommonFunctions::fileexists($filename2) && CommonFunctions::rfts($filename2, $buf, 0, 4096, false)) {
1460
                                            if (preg_match('/^majorversion="?([^"\n]+)"?/m', $buf, $maj_buf)
1461
                                               && preg_match('/^minorversion="?([^"\n]+)"?/m', $buf, $min_buf)) {
1462
                                                $distr2=$maj_buf[1].'.'.$min_buf[1];
1463
                                                if (preg_match('/^buildphase="?([^"\n]+)"?/m', $buf, $pha_buf) && ($pha_buf[1]!=="0")) {
1464
                                                    $distr2.='.'.$pha_buf[1];
1465
                                                }
1466
                                                if (preg_match('/^buildnumber="?([^"\n]+)"?/m', $buf, $num_buf)) {
1467
                                                    $distr2.='-'.$num_buf[1];
1468
                                                }
1469
                                                if (preg_match('/^builddate="?([^"\n]+)"?/m', $buf, $dat_buf)) {
1470
                                                    $distr2.=' ('.$dat_buf[1].')';
1471
                                                }
1472
                                                $this->sys->setDistribution($this->sys->getDistribution()." ".$distr2);
1473
                                            } else {
1474
                                                $distr2=trim(substr($buf, 0, strpos($buf, "\n")));
1475
                                                if (!is_null($distr2) && ($distr2 != "")) {
1476
                                                    $this->sys->setDistribution($this->sys->getDistribution()." ".$distr2);
1477
                                                }
1478
                                            }
1479
                                            break;
1480
                                        }
1481
                                    }
1482
                                }
1483
                                break 2;
1484
                            }
1485
                        }
1486
                    }
1487
                }
1488
            }
1489
            // if the distribution is still unknown
1490
            if ($this->sys->getDistribution() == "Linux") {
1491
                if (CommonFunctions::fileexists($filename="/etc/DISTRO_SPECS")
1492
                   && CommonFunctions::rfts($filename, $buf, 0, 4096, false)
1493
                   && preg_match('/^DISTRO_NAME=\'(.+)\'/m', $buf, $id_buf)) {
1494
                    if (isset($list[trim($id_buf[1])]['Name'])) {
1495
                        $dist = trim($list[trim($id_buf[1])]['Name']);
1496
                    } else {
1497
                        $dist = trim($id_buf[1]);
1498
                    }
1499
                    if (preg_match('/^DISTRO_VERSION=([^#\n\r]+)/m', $buf, $vers_buf)) {
1500
                        $this->sys->setDistribution(trim($dist." ".trim($vers_buf[1])));
1501
                    } else {
1502
                        $this->sys->setDistribution($dist);
1503
                    }
1504
                    if (isset($list[trim($id_buf[1])]['Image'])) {
1505
                        $this->sys->setDistributionIcon($list[trim($id_buf[1])]['Image']);
1506
                    } else {
1507
                        if (isset($list['Puppy']['Image'])) {
1508
                            $this->sys->setDistributionIcon($list['Puppy']['Image']);
1509
                        }
1510
                    }
1511
                } elseif ((CommonFunctions::fileexists($filename="/etc/distro-release")
1512
                        && CommonFunctions::rfts($filename, $buf, 1, 4096, false)
1513
                        && !is_null($buf) && (trim($buf) != ""))
1514
                    || (CommonFunctions::fileexists($filename="/etc/system-release")
1515
                        && CommonFunctions::rfts($filename, $buf, 1, 4096, false)
1516
                        && !is_null($buf) && (trim($buf) != ""))) {
1517
                    $this->sys->setDistribution(trim($buf));
1518
                    if (preg_match('/^(\S+)\s*/', preg_replace('/^Red\s+/', 'Red', $buf), $id_buf)
1519
                        && isset($list[trim($id_buf[1])]['Image'])) {
1520
                            $this->sys->setDistributionIcon($list[trim($id_buf[1])]['Image']);
1521
                    }
1522
                } elseif (CommonFunctions::fileexists($filename="/etc/solydxk/info")
1523
                   && CommonFunctions::rfts($filename, $buf, 0, 4096, false)
1524
                   && preg_match('/^DISTRIB_ID="?([^"\n]+)"?/m', $buf, $id_buf)) {
1525
                    if (preg_match('/^DESCRIPTION="?([^"\n]+)"?/m', $buf, $desc_buf)
1526
                       && (trim($desc_buf[1])!=trim($id_buf[1]))) {
1527
                        $this->sys->setDistribution(trim($desc_buf[1]));
1528
                    } else {
1529
                        if (isset($list[trim($id_buf[1])]['Name'])) {
1530
                            $this->sys->setDistribution(trim($list[trim($id_buf[1])]['Name']));
1531
                        } else {
1532
                            $this->sys->setDistribution(trim($id_buf[1]));
1533
                        }
1534
                        if (preg_match('/^RELEASE="?([^"\n]+)"?/m', $buf, $vers_buf)) {
1535
                            $this->sys->setDistribution($this->sys->getDistribution()." ".trim($vers_buf[1]));
1536
                        }
1537
                        if (preg_match('/^CODENAME="?([^"\n]+)"?/m', $buf, $vers_buf)) {
1538
                            $this->sys->setDistribution($this->sys->getDistribution()." (".trim($vers_buf[1]).")");
1539
                        }
1540
                    }
1541
                    if (isset($list[trim($id_buf[1])]['Image'])) {
1542
                        $this->sys->setDistributionIcon($list[trim($id_buf[1])]['Image']);
1543
                    } else {
1544
                        $this->sys->setDistributionIcon($list['SolydXK']['Image']);
1545
                    }
1546
                } elseif (CommonFunctions::fileexists($filename="/etc/os-release")
1547
                   && CommonFunctions::rfts($filename, $buf, 0, 4096, false)
1548
                   && (preg_match('/^TAILS_VERSION_ID="?([^"\n]+)"?/m', $buf, $tid_buf)
1549
                   || preg_match('/^NAME="?([^"\n]+)"?/m', $buf, $id_buf))) {
1550
                    if (preg_match('/^TAILS_VERSION_ID="?([^"\n]+)"?/m', $buf, $tid_buf)) {
1551
                        if (preg_match('/^TAILS_PRODUCT_NAME="?([^"\n]+)"?/m', $buf, $desc_buf)) {
1552
                            $this->sys->setDistribution(trim($desc_buf[1])." ".trim($tid_buf[1]));
1553
                        } else {
1554
                            if (isset($list['Tails']['Name'])) {
1555
                                $this->sys->setDistribution(trim($list['Tails']['Name'])." ".trim($tid_buf[1]));
1556
                            } else {
1557
                                $this->sys->setDistribution('Tails'." ".trim($tid_buf[1]));
1558
                            }
1559
                        }
1560
                        $this->sys->setDistributionIcon($list['Tails']['Image']);
1561
                    } else {
1562
                        if (preg_match('/^PRETTY_NAME="?([^"\n]+)"?/m', $buf, $desc_buf)
1563
                           && !preg_match('/\$/', $desc_buf[1])) { //if is not defined by variable
1564
                            $this->sys->setDistribution(trim($desc_buf[1]));
1565
                        } else {
1566
                            if (isset($list[trim($id_buf[1])]['Name'])) {
1567
                                $this->sys->setDistribution(trim($list[trim($id_buf[1])]['Name']));
1568
                            } else {
1569
                                $this->sys->setDistribution(trim($id_buf[1]));
1570
                            }
1571
                            if (preg_match('/^VERSION="?([^"\n]+)"?/m', $buf, $vers_buf)) {
1572
                                $this->sys->setDistribution($this->sys->getDistribution()." ".trim($vers_buf[1]));
1573
                            } elseif (preg_match('/^VERSION_ID="?([^"\n]+)"?/m', $buf, $vers_buf)) {
1574
                                $this->sys->setDistribution($this->sys->getDistribution()." ".trim($vers_buf[1]));
1575
                            }
1576
                        }
1577
                        if (isset($list[trim($id_buf[1])]['Image'])) {
1578
                            $this->sys->setDistributionIcon($list[trim($id_buf[1])]['Image']);
1579
                        }
1580
                    }
1581
                } elseif (CommonFunctions::fileexists($filename="/etc/debian_version")) {
1582
                    if (!CommonFunctions::rfts($filename, $buf, 1, 4096, false)) {
1583
                        $buf = "";
1584
                    }
1585
                    if (isset($list['Debian']['Image'])) {
1586
                        $this->sys->setDistributionIcon($list['Debian']['Image']);
1587
                    }
1588
                    if (isset($list['Debian']['Name'])) {
1589
                        if (is_null($buf) || (trim($buf) == "")) {
1590
                            $this->sys->setDistribution($list['Debian']['Name']);
1591
                        } else {
1592
                            $this->sys->setDistribution($list['Debian']['Name']." ".trim($buf));
1593
                        }
1594
                    } else {
1595
                        if (is_null($buf) || (trim($buf) == "")) {
1596
                            $this->sys->setDistribution('Debian');
1597
                        } else {
1598
                            $this->sys->setDistribution(trim($buf));
1599
                        }
1600
                    }
1601
                } elseif (CommonFunctions::fileexists($filename="/etc/config/uLinux.conf")
1602
                   && CommonFunctions::rfts($filename, $buf, 0, 4096, false)
1603
                   && preg_match("/^Rsync\sModel\s*=\s*QNAP/m", $buf)
1604
                   && preg_match("/^Version\s*=\s*([\d\.]+)\r?\nBuild\sNumber\s*=\s*(\S+)/m", $buf, $ver_buf)) {
1605
                    $buf = $ver_buf[1]."-".$ver_buf[2];
1606
                    if (isset($list['QTS']['Image'])) {
1607
                        $this->sys->setDistributionIcon($list['QTS']['Image']);
1608
                    }
1609
                    if (isset($list['QTS']['Name'])) {
1610
                        $this->sys->setDistribution($list['QTS']['Name']." ".trim($buf));
1611
                    } else {
1612
                        $this->sys->setDistribution(trim($buf));
1613
                    }
1614
                }
1615
            }
1616
            /* restore error level */
1617
            error_reporting($old_err_rep);
1618
            /* restore error handler */
1619
            if (function_exists('errorHandlerPsi')) {
1620
                set_error_handler('errorHandlerPsi');
1621
            }
1622
        }
1623
    }
1624
 
1625
    /**
1626
     * Processes
1627
     *
1628
     * @return void
1629
     */
1630
    protected function _processes()
1631
    {
1632
        $process = glob('/proc/*/status', GLOB_NOSORT);
1633
        if (is_array($process) && (($total = count($process)) > 0)) {
1634
            $processes['*'] = 0;
1635
            $buf = "";
1636
            for ($i = 0; $i < $total; $i++) {
1637
                if (CommonFunctions::rfts($process[$i], $buf, 0, 4096, false)) {
1638
                    $processes['*']++; //current total
1639
                    if (preg_match('/^State:\s+(\w)/m', $buf, $state)) {
1640
                        if (isset($processes[$state[1]])) {
1641
                            $processes[$state[1]]++;
1642
                        } else {
1643
                            $processes[$state[1]] = 1;
1644
                        }
1645
                    }
1646
                }
1647
            }
1648
            if (!($processes['*'] > 0)) {
1649
                $processes['*'] = $processes[' '] = $total; //all unknown
1650
            }
1651
            $this->sys->setProcesses($processes);
1652
        }
1653
    }
1654
 
1655
    /**
1656
     * get the information
1657
     *
1658
     * @see PSI_Interface_OS::build()
1659
     *
1660
     * @return Void
1661
     */
1662
    public function build()
1663
    {
1664
        if (!$this->blockname || $this->blockname==='vitals') {
1665
            $this->_distro();
1666
            $this->_hostname();
1667
            $this->_kernel();
1668
            $this->_uptime();
1669
            $this->_users();
1670
            $this->_loadavg();
1671
            $this->_processes();
1672
        }
1673
        if (!$this->blockname || $this->blockname==='hardware') {
1674
            $this->_machine();
1675
            $this->_cpuinfo();
1676
            $this->_pci();
1677
            $this->_ide();
1678
            $this->_scsi();
1679
            $this->_nvme();
1680
            $this->_usb();
1681
            $this->_i2c();
1682
        }
1683
        if (!$this->blockname || $this->blockname==='network') {
1684
            $this->_network();
1685
        }
1686
        if (!$this->blockname || $this->blockname==='memory') {
1687
            $this->_memory();
1688
        }
1689
        if (!$this->blockname || $this->blockname==='filesystem') {
1690
            $this->_filesystems();
1691
        }
1692
    }
1693
}