PageRenderTime 203ms CodeModel.GetById 21ms RepoModel.GetById 4ms app.codeStats 0ms

/lib/class.OS_CYGWIN.php

https://bitbucket.org/rmarefaty/linfo
PHP | 944 lines | 486 code | 179 blank | 279 comment | 103 complexity | 69a241fa2595b30e84590c5540716836 MD5 | raw file
Possible License(s): GPL-3.0
  1. <?php
  2. class OS_CYGWIN {
  3. // Keep these tucked away
  4. protected
  5. $settings, $error;
  6. /**
  7. * Constructor. Localizes settings
  8. *
  9. * @param array $settings of linfo settings
  10. * @access public
  11. */
  12. public function __construct($settings) {
  13. // Localize settings
  14. $this->settings = $settings;
  15. // Localize error handler
  16. $this->error = LinfoError::Fledging();
  17. // Make sure we have what we need
  18. if (!is_dir('/proc'))
  19. throw new GetInfoException('This needs access to /proc to work.');
  20. }
  21. /**
  22. * getAll
  23. *
  24. * @access public
  25. * @return array the info
  26. */
  27. public function getAll() {
  28. // Return everything, whilst obeying display permissions
  29. return array(
  30. 'OS' => empty($this->settings['show']['os']) ? '' : $this->getOS(),
  31. 'Kernel' => empty($this->settings['show']['kernel']) ? '' : $this->getKernel(),
  32. 'RAM' => empty($this->settings['show']['ram']) ? array() : $this->getRam(),
  33. 'HD' => empty($this->settings['show']['hd']) ? '' : $this->getHD(),
  34. 'Mounts' => empty($this->settings['show']['mounts']) ? array() : $this->getMounts(),
  35. 'Load' => empty($this->settings['show']['load']) ? array() : $this->getLoad(),
  36. 'HostName' => empty($this->settings['show']['hostname']) ? '' : $this->getHostName(),
  37. 'UpTime' => empty($this->settings['show']['uptime']) ? '' : $this->getUpTime(),
  38. 'CPU' => empty($this->settings['show']['cpu']) ? array() : $this->getCPU(),
  39. 'CPUArchitecture' => empty($this->settings['show']['cpu']) ? array() : $this->getCPUArchitecture(),
  40. 'processStats' => empty($this->settings['show']['process_stats']) ? array() : $this->getProcessStats(),
  41. 'services' => empty($this->settings['show']['process_stats']) ? array() : $this->getServices()
  42. );
  43. }
  44. /**
  45. * getOS
  46. *
  47. * @access private
  48. * @return string Linux
  49. */
  50. private function getOS() {
  51. // Linux, obviously
  52. return 'Cygwin';
  53. }
  54. /**
  55. * getKernel
  56. *
  57. * @access private
  58. * @return string kernel version
  59. */
  60. private function getKernel() {
  61. // Time?
  62. if (!empty($this->settings['timer']))
  63. $t = new LinfoTimerStart('Kernel');
  64. // File containing info
  65. $file = '/proc/version';
  66. // Make sure we can use it
  67. if (!is_file($file) || !is_readable($file)) {
  68. $this->error->add('Linfo Core', '/proc/version not found');
  69. return 'Unknown';
  70. }
  71. // Get it
  72. $contents = getContents($file);
  73. // Return it
  74. return $contents;
  75. }
  76. /**
  77. * getHostName
  78. *
  79. * @access private
  80. * @return string the host name
  81. */
  82. private function getHostName() {
  83. return php_uname('n');
  84. }
  85. /**
  86. * getRam
  87. *
  88. * @access private
  89. * @return array the memory information
  90. */
  91. private function getRam(){
  92. // Time?
  93. if (!empty($this->settings['timer']))
  94. $t = new LinfoTimerStart('Memory');
  95. // We'll return the contents of this
  96. $return = array();
  97. // Files containing juicy info
  98. $procFileSwap = '/proc/swaps';
  99. $procFileMem = '/proc/meminfo';
  100. // First off, these need to exist..
  101. if (!is_readable($procFileSwap) || !is_readable($procFileMem)) {
  102. $this->error->add('Linfo Core', '/proc/swaps and/or /proc/meminfo are not readable');
  103. return array();
  104. }
  105. // To hold their values
  106. $memVals = array();
  107. $swapVals = array();
  108. // Get memContents
  109. @preg_match_all('/^([^:]+)\:\s+(\d+)\s*(?:k[bB])?\s*/m', getContents($procFileMem), $matches, PREG_SET_ORDER);
  110. // Deal with it
  111. foreach ((array)$matches as $memInfo)
  112. $memVals[$memInfo[1]] = $memInfo[2];
  113. // Get swapContents
  114. @preg_match_all('/^(\S+)\s+(\S+)\s+(\d+)\s(\d+)[^$]*$/m', getContents($procFileSwap), $matches, PREG_SET_ORDER);
  115. foreach ((array)$matches as $swapDevice) {
  116. // Append each swap device
  117. $swapVals[] = array (
  118. 'device' => $swapDevice[1],
  119. 'type' => $swapDevice[2],
  120. 'size' => $swapDevice[3]*1024,
  121. 'used' => $swapDevice[4]*1024
  122. );
  123. }
  124. // Get individual vals
  125. $return['type'] = 'Physical';
  126. $return['total'] = $memVals['MemTotal']*1024;
  127. $return['free'] = $memVals['MemFree']*1024;
  128. $return['swapTotal'] = $memVals['SwapTotal']*1024;
  129. $return['swapFree'] = $memVals['SwapFree']*1024;
  130. $return['swapCached'] = $memVals['SwapCached']*1024;
  131. $return['swapInfo'] = $swapVals;
  132. // Return it
  133. return $return;
  134. }
  135. /**
  136. * getCPU
  137. *
  138. * @access private
  139. * @return array of cpu info
  140. */
  141. private function getCPU() {
  142. // Time?
  143. if (!empty($this->settings['timer']))
  144. $t = new LinfoTimerStart('CPUs');
  145. // File that has it
  146. $file = '/proc/cpuinfo';
  147. // Not there?
  148. if (!is_file($file) || !is_readable($file)) {
  149. $this->error->add('Linfo Core', '/proc/cpuinfo not readable');
  150. return array();
  151. }
  152. /*
  153. * Get all info for all CPUs from the cpuinfo file
  154. */
  155. // Get contents
  156. $contents = trim(@file_get_contents($file));
  157. // Lines
  158. $lines = explode("\n", $contents);
  159. // Store CPUs here
  160. $cpus = array();
  161. // Holder for current CPU info
  162. $cur_cpu = array();
  163. // Go through lines in file
  164. $num_lines = count($lines);
  165. // We use the key of the first line to separate CPUs
  166. $first_line = substr($lines[0], 0, strpos($lines[0], ' '));
  167. for ($i = 0; $i < $num_lines; $i++) {
  168. // Approaching new CPU? Save current and start new info for this
  169. if (strpos($lines[$i], $first_line) === 0 && count($cur_cpu) > 0) {
  170. $cpus[] = $cur_cpu;
  171. $cur_cpu = array();
  172. // Default to unknown
  173. $cur_cpu['Model'] = 'Unknown';
  174. }
  175. // Info here
  176. $line = explode(':', $lines[$i], 2);
  177. $key = trim($line[0]);
  178. $value = trim($line[1]);
  179. // What we want are MHZ, Vendor, and Model.
  180. switch ($key) {
  181. // CPU model
  182. case 'model name':
  183. case 'cpu':
  184. case 'Processor':
  185. $cur_cpu['Model'] = $value;
  186. break;
  187. // Speed in MHz
  188. case 'cpu MHz':
  189. $cur_cpu['MHz'] = $value;
  190. break;
  191. case 'Cpu0ClkTck': // Old sun boxes
  192. $cur_cpu['MHz'] = hexdec($value) / 1000000;
  193. break;
  194. // Brand/vendor
  195. case 'vendor_id':
  196. $cur_cpu['Vendor'] = $value;
  197. break;
  198. }
  199. }
  200. // Save remaining one
  201. if (count($cur_cpu) > 0)
  202. $cpus[] = $cur_cpu;
  203. // Return them
  204. return $cpus;
  205. }
  206. // Famously interesting uptime
  207. private function getUpTime () {
  208. // Time?
  209. if (!empty($this->settings['timer']))
  210. $t = new LinfoTimerStart('Uptime');
  211. // Get contents
  212. $contents = getContents('/proc/uptime', false);
  213. // eh?
  214. if ($contents === false) {
  215. $this->error->add('Linfo Core', '/proc/uptime does not exist.');
  216. return 'Unknown';
  217. }
  218. // Seconds
  219. list($seconds) = explode(' ', $contents, 1);
  220. // Get it textual, as in days/minutes/hours/etc
  221. $uptime = seconds_convert(ceil($seconds));
  222. // Now find out when the system was booted
  223. $contents = getContents('/proc/stat', false);
  224. // Ugh
  225. if ($contents === false)
  226. return $uptime; // Settle for just uptime
  227. // Get date of boot
  228. if (preg_match('/^btime (\d+)$/m', $contents, $boot) != 1)
  229. return $uptime;
  230. // Okay?
  231. list(, $boot) = $boot;
  232. // Return
  233. return $uptime . '; booted '.date('m/d/y h:i A', $boot);
  234. }
  235. /**
  236. * getHD
  237. *
  238. * @access private
  239. * @return array the hard drive info
  240. */
  241. private function getHD() {
  242. // Time?
  243. if (!empty($this->settings['timer']))
  244. $t = new LinfoTimerStart('Drives');
  245. // Get partitions
  246. $partitions = array();
  247. $partitions_contents = getContents('/proc/partitions');
  248. if (@preg_match_all('/(\d+)\s+([a-z]{3})(\d+)$/m', $partitions_contents, $partitions_match, PREG_SET_ORDER) > 0) {
  249. // Go through each match
  250. $num_partitions = count($partitions_match);
  251. for ($i = 0; $i < $num_partitions; $i++) {
  252. $partition = $partitions_match[$i];
  253. $partitions[$partition[2]][] = array(
  254. 'size' => $partition[1] * 1024,
  255. 'number' => $partition[3]
  256. );
  257. }
  258. }
  259. // Store drives here
  260. $drives = array();
  261. // Get actual drives
  262. $drive_paths = (array) @glob('/sys/block/*/device/model', GLOB_NOSORT);
  263. $num_drives = count($drive_paths);
  264. for ($i = 0; $i < $num_drives; $i++) {
  265. // Path
  266. $path = $drive_paths[$i];
  267. // Dirname of the drive's sys entry
  268. $dirname = dirname(dirname($path));
  269. // Parts of the path
  270. $parts = explode('/', $path);
  271. // Attempt getting read/write stats
  272. if (preg_match('/^(\d+)\s+\d+\s+\d+\s+\d+\s+(\d+)\s+\d+\s+\d+\s+\d+\s+\d+\s+\d+\s+\d+$/', getContents(dirname(dirname($path)).'/stat'), $statMatches) !== 1) {
  273. // Didn't get it
  274. $reads = false;
  275. $writes = false;
  276. }
  277. else
  278. // Got it, save it
  279. list(, $reads, $writes) = $statMatches;
  280. // Append this drive on
  281. $drives[] = array(
  282. 'name' => getContents($path, 'Unknown'),
  283. 'vendor' => getContents(dirname($path).'/vendor', 'Unknown'),
  284. 'device' => '/dev/'.$parts[3],
  285. 'reads' => $reads,
  286. 'writes' => $writes,
  287. 'size' => getContents(dirname(dirname($path)).'/size', 0) * 512,
  288. 'partitions' => array_key_exists($parts[3], $partitions) && is_array($partitions[$parts[3]]) ? $partitions[$parts[3]] : false
  289. );
  290. }
  291. // Return drives
  292. return $drives;
  293. }
  294. /**
  295. * getTemps
  296. *
  297. * @access private
  298. * @return array the temps
  299. */
  300. private function getTemps() {
  301. // Time?
  302. if (!empty($this->settings['timer']))
  303. $t = new LinfoTimerStart('Temperature');
  304. // Hold them here
  305. $return = array();
  306. // Done
  307. return $return;
  308. }
  309. /**
  310. * getMounts
  311. *
  312. * @access private
  313. * @return array the mounted the file systems
  314. */
  315. private function getMounts() {
  316. // Time?
  317. if (!empty($this->settings['timer']))
  318. $t = new LinfoTimerStart('Mounted file systems');
  319. // File
  320. $contents = getContents('/proc/mounts', false);
  321. // Can't?
  322. if ($contents == false)
  323. $this->error->add('Linfo Core', '/proc/mounts does not exist');
  324. // Parse
  325. if (@preg_match_all('/^(\S+) (\S+) (\S+) (.+) \d \d$/m', $contents, $match, PREG_SET_ORDER) === false)
  326. $this->error->add('Linfo Core', 'Error parsing /proc/mounts');
  327. // Return these
  328. $mounts = array();
  329. // Populate
  330. $num_matches = count($match);
  331. for ($i = 0; $i < $num_matches; $i++) {
  332. // This mount
  333. $mount = $match[$i];
  334. // Should we not show this?
  335. if (in_array($mount[1], $this->settings['hide']['storage_devices']) || in_array($mount[3], $this->settings['hide']['filesystems']))
  336. continue;
  337. // Spaces and other things in the mount path are escaped C style. Fix that.
  338. $mount[2] = stripcslashes($mount[2]);
  339. // Get these
  340. $size = @disk_total_space($mount[2]);
  341. $free = @disk_free_space($mount[2]);
  342. $used = $size != false && $free != false ? $size - $free : false;
  343. // If it's a symlink, find out where it really goes.
  344. // (using realpath instead of readlink because the former gives absolute paths)
  345. $symlink = is_link($mount[1]) ? realpath($mount[1]) : false;
  346. // Optionally get mount options
  347. if ($this->settings['show']['mounts_options'] && !in_array($mount[3], (array) $this->settings['hide']['fs_mount_options']))
  348. $mount_options = explode(',', $mount[4]);
  349. else
  350. $mount_options = array();
  351. // Might be good, go for it
  352. $mounts[] = array(
  353. 'device' => $symlink != false ? $symlink : $mount[1],
  354. 'mount' => $mount[2],
  355. 'type' => $mount[3],
  356. 'size' => $size,
  357. 'used' => $used,
  358. 'free' => $free,
  359. 'free_percent' => ((bool)$free != false && (bool)$size != false ? round($free / $size, 2) * 100 : false),
  360. 'used_percent' => ((bool)$used != false && (bool)$size != false ? round($used / $size, 2) * 100 : false),
  361. 'options' => $mount_options
  362. );
  363. }
  364. // Return
  365. return $mounts;
  366. }
  367. /**
  368. * getDevs
  369. *
  370. * @access private
  371. * @return array of devices
  372. */
  373. private function getDevs() {
  374. // Time?
  375. if (!empty($this->settings['timer']))
  376. $t = new LinfoTimerStart('Hardware Devices');
  377. // Location of useful paths
  378. $pci_ids = locate_actual_path(array(
  379. '/usr/share/misc/pci.ids', // debian/ubuntu
  380. '/usr/share/pci.ids', // opensuse
  381. '/usr/share/hwdata/pci.ids', // centos. maybe also redhat/fedora
  382. ));
  383. $usb_ids = locate_actual_path(array(
  384. '/usr/share/misc/usb.ids', // debian/ubuntu
  385. '/usr/share/usb.ids', // opensuse
  386. '/usr/share/hwdata/usb.ids', // centos. maybe also redhat/fedora
  387. ));
  388. // Class that does it
  389. $hw = new HW_IDS($usb_ids, $pci_ids);
  390. $hw->work('linux');
  391. return $hw->result();
  392. }
  393. /**
  394. * getRAID
  395. *
  396. * @access private
  397. * @return array of raid arrays
  398. */
  399. private function getRAID() {
  400. // Time?
  401. if (!empty($this->settings['timer']))
  402. $t = new LinfoTimerStart('RAID');
  403. // Store it here
  404. $raidinfo = array();
  405. // Return info
  406. return $raidinfo;
  407. }
  408. /**
  409. * getLoad
  410. *
  411. * @access private
  412. * @return array of current system load values
  413. */
  414. private function getLoad() {
  415. // Time?
  416. if (!empty($this->settings['timer']))
  417. $t = new LinfoTimerStart('Load Averages');
  418. // File that has it
  419. $file = '/proc/loadavg';
  420. // Get contents
  421. $contents = getContents($file, false);
  422. // ugh
  423. if ($contents === false) {
  424. $this->error->add('Linfo Core', '/proc/loadavg unreadable');
  425. return array();
  426. }
  427. // Parts
  428. $parts = explode(' ', $contents);
  429. // Return array of info
  430. return array(
  431. 'now' => $parts[0],
  432. '5min' => $parts[1],
  433. '15min' => $parts[2]
  434. );
  435. }
  436. /**
  437. * getNet
  438. *
  439. * @access private
  440. * @return array of network devices
  441. */
  442. private function getNet() {
  443. // Time?
  444. if (!empty($this->settings['timer']))
  445. $t = new LinfoTimerStart('Network Devices');
  446. // Hold our return values
  447. $return = array();
  448. // Use glob to get paths
  449. $nets = (array) @glob('/sys/class/net/*', GLOB_NOSORT);
  450. // Get values for each device
  451. $num_nets = count($nets);
  452. for ($i = 0; $i < $num_nets; $i++) {
  453. // Path
  454. $path = $nets[$i];
  455. // States
  456. $operstate_contents = getContents($path.'/operstate');
  457. switch ($operstate_contents) {
  458. case 'down':
  459. case 'up':
  460. case 'unknown':
  461. $state = $operstate_contents;
  462. break;
  463. default:
  464. $state = 'unknown';
  465. break;
  466. }
  467. // motherfucker
  468. if ($state = 'unknown' && file_exists($path.'/carrier')) {
  469. $carrier = getContents($path.'/carrier', false);
  470. if (!empty($carrier))
  471. $state = 'up';
  472. else
  473. $state = 'down';
  474. }
  475. // Type
  476. $type_contents = strtoupper(getContents($path.'/device/modalias'));
  477. list($type) = explode(':', $type_contents, 2);
  478. $type = $type != 'USB' && $type != 'PCI' ? 'N/A' : $type;
  479. // Save and get info for each
  480. $return[end(explode('/', $path))] = array(
  481. // Stats are stored in simple files just containing the number
  482. 'recieved' => array(
  483. 'bytes' => get_int_from_file($path.'/statistics/rx_bytes'),
  484. 'errors' => get_int_from_file($path.'/statistics/rx_errors'),
  485. 'packets' => get_int_from_file($path.'/statistics/rx_packets')
  486. ),
  487. 'sent' => array(
  488. 'bytes' => get_int_from_file($path.'/statistics/tx_bytes'),
  489. 'errors' => get_int_from_file($path.'/statistics/tx_errors'),
  490. 'packets' => get_int_from_file($path.'/statistics/rx_packets')
  491. ),
  492. // These were determined above
  493. 'state' => $state,
  494. 'type' => $type
  495. );
  496. }
  497. // Return array of info
  498. return $return;
  499. }
  500. /**
  501. * getBattery
  502. *
  503. * @access private
  504. * @return array of battery status
  505. */
  506. private function getBattery() {
  507. // Time?
  508. if (!empty($this->settings['timer']))
  509. $t = new LinfoTimerStart('Batteries');
  510. // Return values
  511. $return = array();
  512. // Here they should be
  513. $bats = (array) @glob('/sys/class/power_supply/BAT*', GLOB_NOSORT);
  514. // Get vals for each battery
  515. foreach ($bats as $b) {
  516. // Get these from the simple text files
  517. $charge_full = get_int_from_file($b.'/charge_full');
  518. $charge_now = get_int_from_file($b.'/charge_now');
  519. // Save result set
  520. $return[] = array(
  521. 'charge_full' => $charge_full,
  522. 'charge_now' => $charge_now,
  523. 'percentage' => ($charge_now != 0 && $charge_full != 0 ? (round($charge_now / $charge_full, 4) * 100) : '?').'%',
  524. 'device' => getContents($b.'/manufacturer') . ' ' . getContents($b.'/model_name', 'Unknown'),
  525. 'state' => getContents($b.'/status', 'Unknown')
  526. );
  527. }
  528. // Give it
  529. return $return;
  530. }
  531. /**
  532. * getWifi
  533. *
  534. * @access private
  535. * @return array of wifi devices
  536. */
  537. private function getWifi() {
  538. // Time?
  539. if (!empty($this->settings['timer']))
  540. $t = new LinfoTimerStart('Wifi');
  541. // Return these
  542. $return = array();
  543. // Done
  544. return $return;
  545. }
  546. /**
  547. * getSoundCards
  548. *
  549. * @access private
  550. * @return array of soundcards
  551. */
  552. private function getSoundCards() {
  553. // Time?
  554. if (!empty($this->settings['timer']))
  555. $t = new LinfoTimerStart('Sound cards');
  556. $cards = array();
  557. // Give cards
  558. return $cards;
  559. }
  560. /**
  561. * getProcessStats
  562. *
  563. * @access private
  564. * @return array of process stats
  565. */
  566. private function getProcessStats() {
  567. // Time?
  568. if (!empty($this->settings['timer']))
  569. $t = new LinfoTimerStart('Process Stats');
  570. // We'll return this after stuffing it with useful info
  571. $result = array(
  572. 'exists' => true,
  573. 'totals' => array(
  574. 'running' => 0,
  575. 'zombie' => 0,
  576. 'sleeping' => 0,
  577. 'stopped' => 0,
  578. ),
  579. 'proc_total' => 0,
  580. 'threads' => 0
  581. );
  582. // Get all the paths to each process' status file
  583. $processes = (array) @glob('/proc/*/status', GLOB_NOSORT);
  584. // Total
  585. $result['proc_total'] = count($processes);
  586. // Go through each
  587. for ($i = 0; $i < $result['proc_total']; $i++) {
  588. // Don't waste time if we can't use it
  589. if (!is_readable($processes[$i]))
  590. continue;
  591. // Get that file's contents
  592. $status_contents = getContents($processes[$i]);
  593. // Try getting state
  594. @preg_match('/^State:\s+(\w)/m', $status_contents, $state_match);
  595. // Well? Determine state
  596. switch ($state_match[1]) {
  597. case 'D': // disk sleep? wtf?
  598. case 'S':
  599. $result['totals']['sleeping']++;
  600. break;
  601. case 'Z':
  602. $result['totals']['zombie']++;
  603. break;
  604. case 'R':
  605. $result['totals']['running']++;
  606. break;
  607. case 'T':
  608. $result['totals']['stopped']++;
  609. break;
  610. }
  611. // Try getting number of threads
  612. @preg_match('/^Threads:\s+(\d+)/m', $status_contents, $threads_match);
  613. // Well?
  614. if ($threads_match)
  615. list(, $threads) = $threads_match;
  616. // Append it on if it's good
  617. if (is_numeric($threads))
  618. $result['threads'] = $result['threads'] + $threads;
  619. }
  620. // Give off result
  621. return $result;
  622. }
  623. /**
  624. * getServices
  625. *
  626. * @access private
  627. * @return array the services
  628. */
  629. private function getServices() {
  630. // Time?
  631. if (!empty($this->settings['timer']))
  632. $t = new LinfoTimerStart('Services');
  633. // We allowed?
  634. if (!empty($settings['show']['services']) || !is_array($this->settings['services']) || count($this->settings['services']) == 0)
  635. return array();
  636. // Temporarily keep statuses here
  637. $statuses = array();
  638. // A bit of unfucking potential missing values in config file
  639. $this->settings['services']['executables'] = (array) $this->settings['services']['executables'];
  640. $this->settings['services']['pidFiles'] = (array) $this->settings['services']['pidFiles'];
  641. // Convert paths of executables to PID files
  642. $pids = array();
  643. $do_process_search = false;
  644. if (count($this->settings['services']['executables']) > 0) {
  645. $potential_paths = @glob('/proc/*/cmdline');
  646. if (is_array($potential_paths)) {
  647. $num_paths = count($potential_paths);
  648. $do_process_search = true;
  649. }
  650. }
  651. // Should we go ahead and do the PID search based on executables?
  652. if ($do_process_search) {
  653. // Precache all process cmdlines
  654. for ($i = 0; $i < $num_paths; $i++)
  655. $cmdline_cache[$i] = explode("\x00", getContents($potential_paths[$i]));
  656. // Go through the list of executables to search for
  657. foreach ($this->settings['services']['executables'] as $service => $exec) {
  658. // Go through pid file list. for loops are faster than foreach
  659. for ($i = 0; $i < $num_paths; $i++) {
  660. $cmdline = $cmdline_cache[$i];
  661. $match = false;
  662. if (is_array($exec)) {
  663. $match = true;
  664. foreach ($exec as $argn => $argv) {
  665. if($cmdline[$argn] != $argv)
  666. $match = false;
  667. }
  668. }
  669. else if ($cmdline[0] == $exec) {
  670. $match = true;
  671. }
  672. // If this one matches, stop here and save it
  673. if ($match) {
  674. // Get pid out of path to cmdline file
  675. $pids[$service] = substr($potential_paths[$i], 6 /*strlen('/proc/')*/,
  676. strpos($potential_paths[$i], '/', 7)-6);
  677. break;
  678. }
  679. }
  680. }
  681. }
  682. // PID files
  683. foreach ($this->settings['services']['pidFiles'] as $service => $file) {
  684. $pid = getContents($file, false);
  685. if ($pid != false && is_numeric($pid))
  686. $pids[$service] = $pid;
  687. }
  688. // Deal with PIDs
  689. foreach ($pids as $service => $pid) {
  690. $path = '/proc/'.$pid.'/status';
  691. $status_contents = getContents($path, false);
  692. if ($status_contents == false) {
  693. $statuses[$service] = array('state' => 'Down', 'threads' => 'N/A', 'pid' => $pid);
  694. continue;
  695. }
  696. // Attempt getting info out of it
  697. if (!preg_match_all('/^(\w+):\s+(\w+)/m', $status_contents, $status_matches, PREG_SET_ORDER))
  698. continue;
  699. // Initially set these as pointless
  700. $state = false;
  701. $threads = false;
  702. $mem = false;
  703. // Go through
  704. //foreach ($status_matches as $status_match) {
  705. for ($i = 0, $num = count($status_matches); $i < $num; $i++) {
  706. // What have we here?
  707. switch ($status_matches[$i][1]) {
  708. // State section
  709. case 'State':
  710. switch ($status_matches[$i][2]) {
  711. case 'D': // disk sleep? wtf?
  712. case 'S':
  713. $state = 'Up (Sleeping)';
  714. break;
  715. case 'Z':
  716. $state = 'Zombie';
  717. break;
  718. // running
  719. case 'R':
  720. $state = 'Up (Running)';
  721. break;
  722. // stopped
  723. case 'T':
  724. $state = 'Up (Stopped)';
  725. break;
  726. default:
  727. continue;
  728. break;
  729. }
  730. break;
  731. // Mem usage
  732. case 'VmRSS':
  733. if (is_numeric($status_matches[$i][2]))
  734. $mem = $status_matches[$i][2] * 1024; // Measured in kilobytes; we want bytes
  735. break;
  736. // Thread count
  737. case 'Threads':
  738. if (is_numeric($status_matches[$i][2]))
  739. $threads = $status_matches[$i][2];
  740. // Thread count should be last. Stop here to possibly save time assuming we have the other values
  741. if ($state !== false && $mem !== false && $threads !== false)
  742. break;
  743. break;
  744. }
  745. }
  746. // Save info
  747. $statuses[$service] = array(
  748. 'state' => $state ? $state : '?',
  749. 'threads' => $threads,
  750. 'pid' => $pid,
  751. 'memory_usage' => $mem
  752. );
  753. }
  754. return $statuses;
  755. }
  756. /**
  757. * getCPUArchitecture
  758. *
  759. * @access private
  760. * @return string the arch and bits
  761. */
  762. private function getCPUArchitecture() {
  763. return php_uname('m');
  764. }
  765. }