PageRenderTime 40ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 1ms

/src/sysinfo/includes/os/class.Linux.inc.php

https://github.com/bogus/findik-web-amf
PHP | 565 lines | 432 code | 1 blank | 132 comment | 93 complexity | 47e74966b53a846ebab2769beff66931 MD5 | raw file
Possible License(s): GPL-2.0
  1. <?php
  2. /**
  3. * Linux System Class
  4. *
  5. * PHP version 5
  6. *
  7. * @category PHP
  8. * @package PSI_OS
  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
  12. * @version SVN: $Id: class.Linux.inc.php 329 2009-09-07 11:21:44Z bigmichi1 $
  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_OS
  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
  24. * @version Release: 3.0
  25. * @link http://phpsysinfo.sourceforge.net
  26. */
  27. class Linux extends OS
  28. {
  29. /**
  30. * call parent constructor
  31. */
  32. public function __construct()
  33. {
  34. parent::__construct();
  35. }
  36. /**
  37. * Hostname
  38. *
  39. * @return void
  40. */
  41. private function _hostname()
  42. {
  43. if (PSI_USE_VHOST === true) {
  44. $this->sys->setHostname(getenv('SERVER_NAME'));
  45. } else {
  46. if (CommonFunctions::rfts('/proc/sys/kernel/hostname', $result, 1)) {
  47. $result = trim($result);
  48. $ip = gethostbyname($result);
  49. if ($ip != $result) {
  50. $this->sys->setHostname(gethostbyaddr($ip));
  51. }
  52. }
  53. }
  54. }
  55. /**
  56. * IP
  57. *
  58. * @return void
  59. */
  60. private function _ip()
  61. {
  62. if (PSI_USE_VHOST === true) {
  63. $this->sys->setIp(gethostbyname($this->_hostname()));
  64. } else {
  65. if (!($result = $_SERVER['SERVER_ADDR'])) {
  66. $this->sys->setIp(gethostbyname($this->_hostname()));
  67. } else {
  68. $this->sys->setIp($result);
  69. }
  70. }
  71. }
  72. /**
  73. * Kernel Version
  74. *
  75. * @return void
  76. */
  77. private function _kernel()
  78. {
  79. if (CommonFunctions::executeProgram('uname', '-r', $strBuf, PSI_DEBUG)) {
  80. $result = trim($strBuf);
  81. if (CommonFunctions::executeProgram('uname', '-v', $strBuf, PSI_DEBUG)) {
  82. if (preg_match('/SMP/', $strBuf)) {
  83. $result .= ' (SMP)';
  84. }
  85. }
  86. if (CommonFunctions::executeProgram('uname', '-m', $strBuf, PSI_DEBUG)) {
  87. $result .= ' '.trim($strBuf);
  88. }
  89. $this->sys->setKernel($result);
  90. } else {
  91. if (CommonFunctions::rfts('/proc/version', $strBuf, 1)) {
  92. if (preg_match('/version (.*?) /', $strBuf, $ar_buf)) {
  93. $result = $ar_buf[1];
  94. if (preg_match('/SMP/', $strBuf)) {
  95. $result .= ' (SMP)';
  96. }
  97. $this->sys->setKernel($result);
  98. }
  99. }
  100. }
  101. }
  102. /**
  103. * UpTime
  104. * time the system is running
  105. *
  106. * @return void
  107. */
  108. private function _uptime()
  109. {
  110. CommonFunctions::rfts('/proc/uptime', $buf, 1);
  111. $ar_buf = preg_split('/ /', $buf);
  112. $this->sys->setUptime(trim($ar_buf[0]));
  113. }
  114. /**
  115. * Number of Users
  116. *
  117. * @return void
  118. */
  119. private function _users()
  120. {
  121. if (CommonFunctions::executeProgram('who', '-q', $strBuf, PSI_DEBUG)) {
  122. $arrWho = preg_split('/=/', $strBuf);
  123. $this->sys->setUsers($arrWho[1]);
  124. }
  125. }
  126. /**
  127. * Processor Load
  128. * optionally create a loadbar
  129. *
  130. * @return void
  131. */
  132. private function _loadavg()
  133. {
  134. if (CommonFunctions::rfts('/proc/loadavg', $buf)) {
  135. $result = preg_split("/\s/", $buf, 4);
  136. // don't need the extra values, only first three
  137. unset($result[3]);
  138. $this->sys->setLoad(implode(' ', $result));
  139. }
  140. if (PSI_LOAD_BAR) {
  141. $this->sys->setLoadPercent($this->_parseProcStat('cpu'));
  142. }
  143. }
  144. /**
  145. * fill the load for a individual cpu, through parsing /proc/stat for the specified cpu
  146. *
  147. * @param String $cpuline cpu for which load should be meassured
  148. *
  149. * @return Integer
  150. */
  151. private function _parseProcStat($cpuline)
  152. {
  153. $load = 0;
  154. $load2 = 0;
  155. $total = 0;
  156. $total2 = 0;
  157. if (CommonFunctions::rfts('/proc/stat', $buf)) {
  158. $lines = preg_split("/\n/", $buf, -1, PREG_SPLIT_NO_EMPTY);
  159. foreach ($lines as $line) {
  160. if (preg_match('/^'.$cpuline.' (.*)/', $line, $matches)) {
  161. $ab = 0;
  162. $ac = 0;
  163. $ad = 0;
  164. $ae = 0;
  165. sscanf($buf, "%*s %Ld %Ld %Ld %Ld", $ab, $ac, $ad, $ae);
  166. $load = $ab + $ac + $ad; // cpu.user + cpu.sys
  167. $total = $ab + $ac + $ad + $ae; // cpu.total
  168. break;
  169. }
  170. }
  171. }
  172. // we need a second value, wait 1 second befor getting (< 1 second no good value will occour)
  173. sleep(1);
  174. if (CommonFunctions::rfts('/proc/stat', $buf)) {
  175. $lines = preg_split("/\n/", $buf, -1, PREG_SPLIT_NO_EMPTY);
  176. foreach ($lines as $line) {
  177. if (preg_match('/^'.$cpuline.' (.*)/', $line, $matches)) {
  178. $ab = 0;
  179. $ac = 0;
  180. $ad = 0;
  181. $ae = 0;
  182. sscanf($buf, "%*s %Ld %Ld %Ld %Ld", $ab, $ac, $ad, $ae);
  183. $load2 = $ab + $ac + $ad;
  184. $total2 = $ab + $ac + $ad + $ae;
  185. break;
  186. }
  187. }
  188. }
  189. if ($total > 0 && $total2 > 0 && $load > 0 && $load2 > 0 && $total2 != $total && $load2 != $load) {
  190. return (100 * ($load2 - $load)) / ($total2 - $total);
  191. }
  192. return 0;
  193. }
  194. /**
  195. * CPU information
  196. * All of the tags here are highly architecture dependant.
  197. *
  198. * @return void
  199. */
  200. private function _cpuinfo()
  201. {
  202. if (CommonFunctions::rfts('/proc/cpuinfo', $bufr)) {
  203. $processors = preg_split('/\s?\n\s?\n/', trim($bufr));
  204. foreach ($processors as $processor) {
  205. $dev = new CpuDevice();
  206. $details = preg_split("/\n/", $processor, -1, PREG_SPLIT_NO_EMPTY);
  207. foreach ($details as $detail) {
  208. $arrBuff = preg_split('/\s+:\s+/', trim($detail));
  209. if (count($arrBuff) == 2) {
  210. switch (strtolower($arrBuff[0])) {
  211. case 'processor':
  212. $dev->setLoad($this->_parseProcStat('cpu'.trim($arrBuff[1])));
  213. break;
  214. case 'model name':
  215. case 'cpu':
  216. $dev->setModel($arrBuff[1]);
  217. break;
  218. case 'cpu mhz':
  219. case 'clock':
  220. $dev->setCpuSpeed($arrBuff[1]);
  221. break;
  222. case 'cycle frequency [hz]':
  223. $dev->setCpuSpeed($arrBuff[1] / 1000000);
  224. break;
  225. case 'cpu0clktck':
  226. $dev->setCpuSpeed(hexdec($arrBuff[1]) / 1000000); // Linux sparc64
  227. break;
  228. case 'l2 cache':
  229. case 'cache size':
  230. $dev->setCache(preg_replace("/[a-zA-Z]/", "", $arrBuff[1]) * 1024);
  231. break;
  232. case 'bogomips':
  233. case 'cpu0bogo':
  234. $dev->setBogomips($arrBuff[1]);
  235. break;
  236. }
  237. }
  238. }
  239. // sparc64 specific code follows
  240. // This adds the ability to display the cache that a CPU has
  241. // Originally made by Sven Blumenstein <bazik@gentoo.org> in 2004
  242. // Modified by Tom Weustink <freshy98@gmx.net> in 2004
  243. $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');
  244. foreach ($sparclist as $name) {
  245. if (CommonFunctions::rfts('/proc/openprom/'.$name.'/ecache-size', $buf, 1, 32, false)) {
  246. $dev->setCache(base_convert($buf, 16, 10));
  247. }
  248. }
  249. // sparc64 specific code ends
  250. // XScale detection code
  251. if ($dev->getModel() === "") {
  252. foreach ($details as $detail) {
  253. $arrBuff = preg_split('/\s*:\s*/', trim($buf), 2);
  254. if (count($arrBuff) == 2) {
  255. switch (strtolower($arrBuff[0])) {
  256. case 'Processor':
  257. $dev->setModel($arrBuff[1]);
  258. break;
  259. case 'BogoMIPS':
  260. $dev->setCpuSpeed($arrBuff[1]); //BogoMIPS are not BogoMIPS on this CPU, it's the speed, no BogoMIPS available
  261. break;
  262. case 'I size':
  263. case 'D size':
  264. if ($dev->getCache() === null) {
  265. $dev->setCache($arrBuff[1] * 1024);
  266. } else {
  267. $dev->setCache($dev->getCache() + ($arrBuff[1] * 1024));
  268. }
  269. break;
  270. }
  271. }
  272. }
  273. }
  274. if (CommonFunctions::rfts('/proc/acpi/thermal_zone/THRM/temperature', $buf, 1, 4096, false)) {
  275. $dev->setTemp(substr($buf, 25, 2));
  276. }
  277. $this->sys->setCpus($dev);
  278. }
  279. }
  280. }
  281. /**
  282. * PCI devices
  283. *
  284. * @return void
  285. */
  286. private function _pci()
  287. {
  288. if (!$arrResults = Parser::lspci()) {
  289. if (CommonFunctions::rfts('/proc/pci', $strBuf, 0, 4096, false)) {
  290. $booDevice = false;
  291. $arrBuf = preg_split("/\n/", $strBuf, -1, PREG_SPLIT_NO_EMPTY);
  292. foreach ($arrBuf as $strLine) {
  293. if (preg_match('/Bus/', $strLine)) {
  294. $booDevice = true;
  295. continue;
  296. }
  297. if ($booDevice) {
  298. list($strKey, $strValue) = preg_split('/: /', $strLine, 2);
  299. if (!preg_match('/bridge/i', $strKey) && !preg_match('/USB/i ', $strKey)) {
  300. $dev = new HWDevice();
  301. $dev->setName(preg_replace('/\([^\)]+\)\.$/', '', trim($strValue)));
  302. $this->sys->setPciDevices($dev);
  303. }
  304. $booDevice = false;
  305. }
  306. }
  307. }
  308. } else {
  309. foreach ($arrResults as $dev) {
  310. $this->sys->setPciDevices($dev);
  311. }
  312. }
  313. }
  314. /**
  315. * IDE devices
  316. *
  317. * @return void
  318. */
  319. private function _ide()
  320. {
  321. $bufd = CommonFunctions::gdc('/proc/ide', false);
  322. foreach ($bufd as $file) {
  323. if (preg_match('/^hd/', $file)) {
  324. $dev = new HWDevice();
  325. $dev->setName(trim($file));
  326. if (CommonFunctions::rfts("/proc/ide/".$file."/media", $buf, 1)) {
  327. if (trim($buf) == 'disk') {
  328. if (CommonFunctions::rfts("/proc/ide/".$file."/capacity", $buf, 1, 4096, false) || CommonFunctions::rfts("/sys/block/".$file."/size", $buf, 1, 4096, false)) {
  329. $dev->setCapacity(trim($buf) * 512 / 1024);
  330. }
  331. }
  332. }
  333. if (CommonFunctions::rfts("/proc/ide/".$file."/model", $buf, 1)) {
  334. $dev->setName($dev->getName().": ".trim($buf));
  335. }
  336. $this->sys->setIdeDevices($dev);
  337. }
  338. }
  339. }
  340. /**
  341. * SCSI devices
  342. *
  343. * @return void
  344. */
  345. private function _scsi()
  346. {
  347. $get_type = false;
  348. $device = null;
  349. if (CommonFunctions::executeProgram('lsscsi', '-c', $bufr, PSI_DEBUG) || CommonFunctions::rfts('/proc/scsi/scsi', $bufr, 0, 4096, PSI_DEBUG)) {
  350. $bufe = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY);
  351. foreach ($bufe as $buf) {
  352. if (preg_match('/Vendor: (.*) Model: (.*) Rev: (.*)/i', $buf, $devices)) {
  353. $get_type = true;
  354. $device = $devices;
  355. continue;
  356. }
  357. if ($get_type) {
  358. preg_match('/Type:\s+(\S+)/i', $buf, $dev_type);
  359. $dev = new HWDevice();
  360. $dev->setName($device[1].' '.$device[2].' ('.$dev_type[1].')');
  361. $this->sys->setScsiDevices($dev);
  362. $get_type = false;
  363. }
  364. }
  365. }
  366. }
  367. /**
  368. * USB devices
  369. *
  370. * @return array
  371. */
  372. private function _usb()
  373. {
  374. $devnum = -1;
  375. if (!CommonFunctions::executeProgram('lsusb', '', $bufr, PSI_DEBUG)) {
  376. if (CommonFunctions::rfts('/proc/bus/usb/devices', $bufr, 0, 4096, false)) {
  377. $bufe = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY);
  378. foreach ($bufe as $buf) {
  379. if (preg_match('/^T/', $buf)) {
  380. $devnum += 1;
  381. $results[$devnum] = "";
  382. } elseif (preg_match('/^S:/', $buf)) {
  383. list($key, $value) = preg_split('/: /', $buf, 2);
  384. list($key, $value2) = preg_split('/=/', $value, 2);
  385. if (trim($key) != "SerialNumber") {
  386. $results[$devnum] .= " ".trim($value2);
  387. }
  388. }
  389. }
  390. foreach ($results as $var) {
  391. $dev = new HWDevice();
  392. $dev->setName($var);
  393. $this->sys->setUsbDevices($dev);
  394. }
  395. }
  396. } else {
  397. $bufe = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY);
  398. foreach ($bufe as $buf) {
  399. $device = preg_split("/ /", $buf, 7);
  400. if (isset($device[6]) && trim($device[6]) != "") {
  401. $dev = new HWDevice();
  402. $dev->setName(trim($device[6]));
  403. $this->sys->setUsbDevices($dev);
  404. }
  405. }
  406. }
  407. }
  408. /**
  409. * Network devices
  410. * includes also rx/tx bytes
  411. *
  412. * @return void
  413. */
  414. private function _network()
  415. {
  416. if (CommonFunctions::rfts('/proc/net/dev', $bufr)) {
  417. $bufe = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY);
  418. foreach ($bufe as $buf) {
  419. if (preg_match('/:/', $buf)) {
  420. list($dev_name, $stats_list) = preg_split('/:/', $buf, 2);
  421. $stats = preg_split('/\s+/', trim($stats_list));
  422. $dev = new NetDevice();
  423. $dev->setName(trim($dev_name));
  424. $dev->setRxBytes($stats[0]);
  425. $dev->setTxBytes($stats[8]);
  426. $dev->setErrors($stats[2] + $stats[10]);
  427. $dev->setDrops($stats[3] + $stats[11]);
  428. $this->sys->setNetDevices($dev);
  429. }
  430. }
  431. }
  432. }
  433. /**
  434. * Physical memory information and Swap Space information
  435. *
  436. * @return void
  437. */
  438. private function _memory()
  439. {
  440. if (CommonFunctions::rfts('/proc/meminfo', $bufr)) {
  441. $bufe = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY);
  442. foreach ($bufe as $buf) {
  443. if (preg_match('/^MemTotal:\s+(.*)\s*kB/i', $buf, $ar_buf)) {
  444. $this->sys->setMemTotal($ar_buf[1] * 1024);
  445. } elseif (preg_match('/^MemFree:\s+(.*)\s*kB/i', $buf, $ar_buf)) {
  446. $this->sys->setMemFree($ar_buf[1] * 1024);
  447. } elseif (preg_match('/^Cached:\s+(.*)\s*kB/i', $buf, $ar_buf)) {
  448. $this->sys->setMemCache($ar_buf[1] * 1024);
  449. } elseif (preg_match('/^Buffers:\s+(.*)\s*kB/i', $buf, $ar_buf)) {
  450. $this->sys->setMemBuffer($ar_buf[1] * 1024);
  451. }
  452. }
  453. $this->sys->setMemUsed($this->sys->getMemTotal() - $this->sys->getMemFree());
  454. // values for splitting memory usage
  455. if ($this->sys->getMemCache() !== null && $this->sys->getMemBuffer() !== null) {
  456. $this->sys->setMemApplication($this->sys->getMemUsed() - $this->sys->getMemCache() - $this->sys->getMemBuffer());
  457. }
  458. if (CommonFunctions::rfts('/proc/swaps', $bufr)) {
  459. $swaps = preg_split("/\n/", $bufr, -1, PREG_SPLIT_NO_EMPTY);
  460. unset($swaps[0]);
  461. foreach ($swaps as $swap) {
  462. $ar_buf = preg_split('/\s+/', $swap, 5);
  463. $dev = new DiskDevice();
  464. $dev->setMountPoint($ar_buf[0]);
  465. $dev->setName("SWAP");
  466. $dev->setTotal($ar_buf[2] * 1024);
  467. $dev->setUsed($ar_buf[3] * 1024);
  468. $dev->setFree($dev->getTotal() - $dev->getUsed());
  469. $this->sys->setSwapDevices($dev);
  470. }
  471. }
  472. }
  473. }
  474. /**
  475. * filesystem information
  476. *
  477. * @return void
  478. */
  479. private function _filesystems()
  480. {
  481. $arrResult = Parser::df("-P");
  482. foreach ($arrResult as $dev) {
  483. $this->sys->setDiskDevices($dev);
  484. }
  485. }
  486. /**
  487. * Distribution
  488. *
  489. * @return void
  490. */
  491. private function _distro()
  492. {
  493. $list = @parse_ini_file(APP_ROOT."/data/distros.ini", true);
  494. if (!$list) {
  495. return;
  496. }
  497. // We have the '2> /dev/null' because Ubuntu gives an error on this command which causes the distro to be unknown
  498. if (CommonFunctions::executeProgram('lsb_release', '-a 2> /dev/null', $distro_info, PSI_DEBUG)) {
  499. $distro_tmp = preg_split("/\n/", $distro_info, -1, PREG_SPLIT_NO_EMPTY);
  500. foreach ($distro_tmp as $info) {
  501. $info_tmp = preg_split('/:/', $info, 2);
  502. $distro[$info_tmp[0]] = trim($info_tmp[1]);
  503. if (isset($distro['Distributor ID']) && isset($list[$distro['Distributor ID']]['Image'])) {
  504. $this->sys->setDistributionIcon($list[$distro['Distributor ID']]['Image']);
  505. }
  506. if (isset($distro['Description'])) {
  507. $this->sys->setDistribution($distro['Description']);
  508. }
  509. }
  510. } else {
  511. // Fall back in case 'lsb_release' does not exist ;)
  512. foreach ($list as $section=>$distribution) {
  513. if (!isset($distribution["Files"])) {
  514. continue;
  515. } else {
  516. foreach (preg_split("/;/", $distribution["Files"], -1, PREG_SPLIT_NO_EMPTY) as $filename) {
  517. if (file_exists($filename)) {
  518. CommonFunctions::rfts($filename, $buf);
  519. if (isset($distribution["Image"])) {
  520. $this->sys->setDistributionIcon($distribution["Image"]);
  521. }
  522. if (isset($distribution["Name"])) {
  523. if ($distribution["Name"] == 'Synology') {
  524. $this->sys->setDistribution($distribution["Name"]);
  525. } else {
  526. $this->sys->setDistribution($distribution["Name"]." ".trim($buf));
  527. }
  528. } else {
  529. $this->sys->setDistribution(trim($buf));
  530. }
  531. return;
  532. }
  533. }
  534. }
  535. }
  536. }
  537. }
  538. /**
  539. * get the information
  540. *
  541. * @see PSI_Interface_OS::build()
  542. *
  543. * @return Void
  544. */
  545. function build()
  546. {
  547. $this->_distro();
  548. $this->_ip();
  549. $this->_hostname();
  550. $this->_kernel();
  551. $this->_uptime();
  552. $this->_users();
  553. $this->_cpuinfo();
  554. $this->_pci();
  555. $this->_ide();
  556. $this->_scsi();
  557. $this->_usb();
  558. $this->_network();
  559. $this->_memory();
  560. $this->_filesystems();
  561. $this->_loadavg();
  562. }
  563. }
  564. ?>