PageRenderTime 52ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/linfo/lib/class.OS_NetBSD.php

https://bitbucket.org/jeguejunior/osvaldonogueira
PHP | 515 lines | 301 code | 97 blank | 117 comment | 46 complexity | 447bf0905c515a612c31fb87a3d6fbc2 MD5 | raw file
Possible License(s): LGPL-3.0, GPL-3.0
  1. <?php
  2. /*
  3. * This file is part of Linfo (c) 2010 Joseph Gillotti.
  4. *
  5. * Linfo is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation, either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * Linfo is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with Linfo. If not, see <http://www.gnu.org/licenses/>.
  17. *
  18. */
  19. defined('IN_LINFO') or exit;
  20. /*
  21. * NetBSD info class. Differs slightly from FreeBSD's
  22. * TODO: netbsd's /proc contains really useful info
  23. * possibly get some stuff from it if it exists
  24. */
  25. class OS_NetBSD extends OS_BSD_Common {
  26. // Encapsulate these
  27. protected
  28. $settings,
  29. $exec,
  30. $error,
  31. $dmesg;
  32. // Start us off
  33. public function __construct($settings) {
  34. // Initiate parent
  35. parent::__construct($settings);
  36. // We search these folders for our commands
  37. $this->exec->setSearchPaths(array('/sbin', '/bin', '/usr/bin', '/usr/pkg/bin', '/usr/sbin'));
  38. // sysctl values we'll access below
  39. $this->GetSysCTL(array('kern.boottime', 'vm.loadavg'), false);
  40. }
  41. // Operating System
  42. public function getOS() {
  43. return 'NetBSD';
  44. }
  45. // Kernel version
  46. public function getKernel() {
  47. return php_uname('r');
  48. }
  49. // Host name
  50. public function getHostName() {
  51. return php_uname('n');
  52. }
  53. // Mounted file systems
  54. public function getMounts() {
  55. // Time it
  56. if (!empty($this->settings['timer']))
  57. $t = new LinfoTimerStart('Mounted file systems');
  58. // Try getting mount command
  59. try {
  60. $res = $this->exec->exec('mount');
  61. }
  62. catch (CallExtException $e) {
  63. $this->error->add('Linfo Core', 'Error running `mount` command');
  64. return array();
  65. }
  66. // Match the file systems
  67. if(@preg_match_all('/^(\S+) on (\S+) type (\S+)/m', $res, $mount_match, PREG_SET_ORDER) == 0)
  68. return array();
  69. // Store them here
  70. $mounts = array();
  71. // Go through each
  72. foreach ($mount_match as $mount) {
  73. // Should we not show this?
  74. if (in_array($mount[1], $this->settings['hide']['storage_devices']) || in_array($mount[3], $this->settings['hide']['filesystems']))
  75. continue;
  76. // Get these
  77. $size = @disk_total_space($mount[2]);
  78. $free = @disk_free_space($mount[2]);
  79. $used = $size - $free;
  80. // Might be good, go for it
  81. $mounts[] = array(
  82. 'device' => $mount[1],
  83. 'mount' => $mount[2],
  84. 'type' => $mount[3],
  85. 'size' => $size ,
  86. 'used' => $used,
  87. 'free' => $free,
  88. 'free_percent' => ((bool)$free != false && (bool)$size != false ? round($free / $size, 2) * 100 : false),
  89. 'used_percent' => ((bool)$used != false && (bool)$size != false ? round($used / $size, 2) * 100 : false)
  90. );
  91. }
  92. // Give them
  93. return $mounts;
  94. }
  95. // Get system load
  96. public function getLoad() {
  97. // Time?
  98. if (!empty($this->settings['timer']))
  99. $t = new LinfoTimerStart('Load Averages');
  100. // Try using sysctl to get load average
  101. $res = $this->sysctl['vm.loadavg'];
  102. // Match it
  103. if (@preg_match('/([\d\.]+) ([\d\.]+) ([\d\.]+)$/', $res, $load_match))
  104. return array(
  105. 'now' => $load_match[1],
  106. '5min' => $load_match[2],
  107. '15min' => $load_match[3]
  108. );
  109. // Match failed
  110. else
  111. return false;
  112. }
  113. // Get the always gloatable uptime
  114. public function getUpTime() {
  115. // Time?
  116. if (!empty($this->settings['timer']))
  117. $t = new LinfoTimerStart('Uptime');
  118. // Use sysctl
  119. $booted = strtotime($this->sysctl['kern.boottime']);
  120. // Give it
  121. return LinfoCommon::secondsConvert(time() - $booted) . '; booted ' . date($this->settings['dates'], $booted);
  122. }
  123. // Get network devices
  124. public function getNet() {
  125. // Time?
  126. if (!empty($this->settings['timer']))
  127. $t = new LinfoTimerStart('Network Devices');
  128. // Try using netstat
  129. try {
  130. $res = $this->exec->exec('netstat', '-nbdi');
  131. }
  132. catch(CallExtException $e) {
  133. $this->error->add('Linfo Core', 'Error using `netstat` to get network info');
  134. return array();
  135. }
  136. // Match the interfaces themselves
  137. if (preg_match_all('/^(\S+)\s+\d+\s+<Link>\s+[a-z0-9\:]+\s+(\d+)\s+(\d+)\s+\d+$/m', $res, $net_matches, PREG_SET_ORDER) == 0)
  138. return array();
  139. // Store statuses for each here
  140. $statuses = array();
  141. // Try using ifconfig to get statuses for each interface
  142. try {
  143. $ifconfig = $this->exec->exec('ifconfig', '-a');
  144. $current_nic = false;
  145. foreach ((array) explode("\n", $ifconfig) as $line) {
  146. if (preg_match('/^(\w+):/m', $line, $m) == 1)
  147. $current_nic = $m[1];
  148. elseif ($current_nic != false && preg_match('/^\s+status: (\w+)$/m', $line, $m) == 1) {
  149. $statuses[$current_nic] = $m[1];
  150. $current_nic = false;
  151. }
  152. }
  153. }
  154. catch(CallExtException $e) {}
  155. // Store interfaces here
  156. $nets = array();
  157. // Go through each
  158. foreach($net_matches as $net) {
  159. // See if we successfully found a status, and use it if so
  160. switch (array_key_exists($net[1], $statuses) ? $statuses[$net[1]] : 'unknown') {
  161. case 'active':
  162. $state = 'up';
  163. break;
  164. case 'inactive':
  165. $state = 'down';
  166. break;
  167. default:
  168. $state = 'unknown';
  169. break;
  170. }
  171. // Save this interface
  172. $nets[$net[1]] = array(
  173. 'recieved' => array(
  174. 'bytes' => $net[2],
  175. ),
  176. 'sent' => array(
  177. 'bytes' => $net[3],
  178. ),
  179. 'state' => $state,
  180. 'type' => 'Unknown' // TODO
  181. );
  182. }
  183. // Give it
  184. return $nets;
  185. }
  186. // Get drives
  187. public function getHD() {
  188. // Time?
  189. if (!empty($this->settings['timer']))
  190. $t = new LinfoTimerStart('CPU');
  191. $drives = array();
  192. $curr_hd = false;
  193. // Parse dmesg
  194. foreach (explode("\n", $this->dmesg) as $dmesg_line) {
  195. // Beginning of a drive entry
  196. if (preg_match('/^([a-z]{2}\d) at [^:]+: <([^>]+)> (\w+)/', $dmesg_line, $init_match)) {
  197. // If it's a cdrom just stop here and save it.
  198. if ($init_match[3] == 'cdrom') {
  199. // Save entry
  200. $drives[] = array(
  201. 'name' => preg_match('/^([^,]+)/', $init_match[2], $cd_match) ? $cd_match[1] : $init_match[2],
  202. 'vendor' => false, // I don't know if this is possible
  203. 'device' => '/dev/'.$init_match[1],
  204. // Not sure how to get the following:
  205. 'size' => false,
  206. 'reads' => false,
  207. 'writes' => false
  208. );
  209. }
  210. // Otherwise prep for further info on a later line
  211. elseif ($init_match[3] == 'disk') {
  212. $curr_hd = array($init_match[1], $init_match[2], $init_match[3]);
  213. }
  214. // Don't go any farther with this line
  215. continue;
  216. }
  217. // A hard drive setting line, that has size and stuff
  218. elseif ($curr_hd != false && preg_match('/^'.preg_quote($curr_hd[0]).': (\d+) MB/', $dmesg_line, $drive_match)) {
  219. // Try getting vendor or name
  220. $make = preg_match('/^([^,]+), ([^,]+)/', $curr_hd[1], $v_match) ? array($v_match[1], $v_match[2]) : false;
  221. // Save entry
  222. $drives[] = array(
  223. 'name' => $make ? $make[1] : $curr_hd[1],
  224. 'vendor' => $make ? $make[0] : false,
  225. 'device' => '/dev/'.$curr_hd[0],
  226. 'size' => $drive_match[1] * 1048576,
  227. // Not sure how to get the following:
  228. 'reads' => false,
  229. 'writes' => false
  230. );
  231. // We're done with this drive
  232. $curr_hd = false;
  233. // Don't go any farther with this line
  234. continue;
  235. }
  236. }
  237. // Give drives
  238. return $drives;
  239. }
  240. // Get cpu's
  241. public function getCPU() {
  242. // Time?
  243. if (!empty($this->settings['timer']))
  244. $t = new LinfoTimerStart('CPU');
  245. // Parse dmesg
  246. if (preg_match_all('/^cpu\d+ at [^:]+: (\S+) ([^,]+), (\d+)MHz/m', $this->dmesg, $cpu_matches, PREG_SET_ORDER) == 0)
  247. return array();
  248. // Store them here
  249. $cpus = array();
  250. // Store as many as possible
  251. foreach ($cpu_matches as $cpu_m)
  252. $cpus[] = array(
  253. 'Model' => $cpu_m[2],
  254. 'MHz' => $cpu_m[3],
  255. 'Vendor' => $cpu_m[1]
  256. );
  257. // Give them
  258. return $cpus;
  259. }
  260. // Get ram usage
  261. public function getRam() {
  262. // Time?
  263. if (!empty($this->settings['timer']))
  264. $t = new LinfoTimerStart('Memory');
  265. // Start us off at zilch
  266. $return = array();
  267. $return['type'] = 'Virtual';
  268. $return['total'] = 0;
  269. $return['free'] = 0;
  270. $return['swapTotal'] = 0;
  271. $return['swapFree'] = 0;
  272. $return['swapInfo'] = array();
  273. // Get virtual memory usage with vmstat
  274. try {
  275. // Get result of vmstat
  276. $vmstat = $this->exec->exec('vmstat', '-s');
  277. // Get bytes per page
  278. preg_match('/^\s+(\d+) bytes per page$/m', $vmstat, $bytes_per_page);
  279. // Did we?
  280. if (!is_numeric($bytes_per_page[1]) || $bytes_per_page[1] < 0)
  281. throw new Exception('Error parsing page size out of `vmstat`');
  282. else
  283. list(, $bytes_per_page) = $bytes_per_page;
  284. // Get available ram
  285. preg_match('/^\s+(\d+) pages managed$/m', $vmstat, $available_ram);
  286. // Did we?
  287. if (!is_numeric($available_ram[1]))
  288. throw new Exception('Error parsing managed pages out of `vmstat`');
  289. else
  290. list(, $available_ram) = $available_ram;
  291. // Get free ram
  292. preg_match('/^\s+(\d+) pages free$/m', $vmstat, $free_ram);
  293. // Did we?
  294. if (!is_numeric($free_ram[1]))
  295. throw new Exception('Error parsing free pages out of `vmstat`');
  296. else
  297. list(, $free_ram) = $free_ram;
  298. // Okay, cool. Total them up
  299. $return['total'] = $available_ram * $bytes_per_page;
  300. $return['free'] = $free_ram * $bytes_per_page;
  301. }
  302. catch (CallExtException $e) {
  303. $this->error->add('Linfo Core', 'Error using `vmstat` to get memory usage');
  304. }
  305. catch (Exception $e) {
  306. $this->error->add('Linfo Core', $e->getMessage());
  307. }
  308. // Get swap
  309. try {
  310. $swapinfo = $this->exec->exec('swapctl', '-l');
  311. @preg_match_all('/^(\S+)\s+(\d+)\s+(\d+)\s+(\d+)/m', $swapinfo, $sm, PREG_SET_ORDER);
  312. foreach ($sm as $swap) {
  313. $return['swapTotal'] += $swap[2]*1024;
  314. $return['swapFree'] += (($swap[2] - $swap[3])*1024);
  315. $ft = is_file ($ft) ? @filetype($swap[1]) : 'Unknown'; // TODO: I'd rather it be Partition or File
  316. $return['swapInfo'][] = array(
  317. 'device' => $swap[1],
  318. 'size' => $swap[2]*1024,
  319. 'used' => $swap[3]*1024,
  320. 'type' => ucfirst($ft)
  321. );
  322. }
  323. }
  324. catch (CallExtException $e) {
  325. $this->error->add('Linfo Core', 'Error using `swapctl` to get swap usage');
  326. }
  327. // Give it off
  328. return $return;
  329. }
  330. // Get devices
  331. public function getDevs() {
  332. // Time?
  333. if (!empty($this->settings['timer']))
  334. $t = new LinfoTimerStart('Hardware Devices');
  335. // Get them
  336. if(preg_match_all('/^([a-z]+\d+) at ([a-z]+)\d+[^:]+:(.+)/m', $this->dmesg, $devices_match, PREG_SET_ORDER) == 0)
  337. return array();
  338. // Keep them here
  339. $devices = array();
  340. // Store the type column for each key
  341. $sort_type = array();
  342. // Stuff it
  343. foreach ($devices_match as $device) {
  344. if ($device[2] == 'ppb' || strpos($device[3], 'vendor') !== false)
  345. continue;
  346. // Only call this once
  347. $type = strtoupper($device[2]);
  348. // Stuff entry
  349. $devices[] = array(
  350. 'vendor' => false, // Maybe todo?
  351. 'device' => $device[3],
  352. 'type' => $type
  353. );
  354. // For the sorting of this entry
  355. $sort_type[] = $type;
  356. }
  357. // Sort
  358. array_multisort($devices, SORT_STRING, $sort_type);
  359. // Give them
  360. return $devices;
  361. }
  362. // Get stats on processes
  363. public function getProcessStats() {
  364. // Time?
  365. if (!empty($this->settings['timer']))
  366. $t = new LinfoTimerStart('Process Stats');
  367. // We'll return this after stuffing it with useful info
  368. $result = array(
  369. 'exists' => true,
  370. 'totals' => array(
  371. 'running' => 0,
  372. 'zombie' => 0,
  373. 'sleeping' => 0,
  374. 'stopped' => 0,
  375. ),
  376. 'proc_total' => 0,
  377. 'threads' => false // I'm not sure how to get this
  378. );
  379. // Use ps
  380. try {
  381. // Get it
  382. $ps = $this->exec->exec('ps', 'ax');
  383. // Match them
  384. preg_match_all('/^\s*\d+\s+[\w?]+\s+([A-Z])\S*\s+.+$/m', $ps, $processes, PREG_SET_ORDER);
  385. // Get total
  386. $result['proc_total'] = count($processes);
  387. // Go through
  388. foreach ($processes as $process) {
  389. switch ($process[1]) {
  390. case 'S':
  391. case 'I':
  392. $result['totals']['sleeping']++;
  393. break;
  394. case 'Z':
  395. $result['totals']['zombie']++;
  396. break;
  397. case 'R':
  398. case 'D':
  399. case 'O':
  400. $result['totals']['running']++;
  401. break;
  402. case 'T':
  403. $result['totals']['stopped']++;
  404. break;
  405. }
  406. }
  407. }
  408. catch (CallExtException $e) {
  409. $this->error->add('Linfo Core', 'Error using `ps` to get process info');
  410. }
  411. // Give
  412. return $result;
  413. }
  414. // TODO:
  415. public function getRAID() {}
  416. public function getBattery() {}
  417. public function getTemps() {}
  418. }