Subversion Repositories ALCASAR

Rev

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