* * @license AGPL-3.0 * * This code is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License, version 3, * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License, version 3, * along with this program. If not, see * */ namespace OCA\ServerInfo\OperatingSystems; use OCA\ServerInfo\Resources\Disk; use OCA\ServerInfo\Resources\Memory; /** * Class FreeBSD * * @package OCA\ServerInfo\OperatingSystems */ class FreeBSD implements IOperatingSystem { /** * @return bool */ public function supported(): bool { return false; } public function getMemory(): Memory { $data = new Memory(); try { $swapinfo = $this->executeCommand('/usr/sbin/swapinfo -k'); } catch (\RuntimeException $e) { $swapinfo = ''; } $matches = []; $pattern = '/(?>\/dev\/\w+)\s+(?>\d+)\s+(?\d+)\s+(?\d+)\s+(?\d+)/'; $result = preg_match_all($pattern, $swapinfo, $matches); if ($result === 1) { $data->setSwapTotal((int)($matches['Avail'][0] / 1024)); $data->setSwapFree(($data->getSwapTotal() - (int)($matches['Used'][0] / 1024))); } unset($matches, $result); try { $meminfo = $this->executeCommand('/sbin/sysctl -n hw.realmem hw.pagesize vm.stats.vm.v_inactive_count vm.stats.vm.v_cache_count vm.stats.vm.v_free_count'); } catch (\RuntimeException $e) { $meminfo = ''; } $lines = explode("\n", $meminfo); if (count($lines) > 4) { $data->setMemTotal((int)($lines[0] / 1024 / 1024)); $data->setMemAvailable((int)(($lines[1] * ($lines[2] + $lines[3] + $lines[4])) / 1024 / 1024)); } unset($lines); return $data; } public function getCpuName(): string { $data = 'Unknown Processor'; try { $model = $this->executeCommand('/sbin/sysctl -n hw.model'); $cores = $this->executeCommand('/sbin/sysctl -n kern.smp.cpus'); if ($cores === 1) { $data = $model . ' (1 core)'; } else { $data = $model . ' (' . $cores . ' cores)'; } } catch (\RuntimeException $e) { return $data; } return $data; } /** * @return string */ public function getTime() { $time = ''; try { $time = $this->executeCommand('date'); } catch (\RuntimeException $e) { return $time; } return $time; } public function getUptime(): int { $uptime = -1; try { $shell_boot = $this->executeCommand('/sbin/sysctl -n kern.boottime'); preg_match("/[\d]+/", $shell_boot, $boottime); $time = $this->executeCommand('date +%s'); $uptime = (int)$time - (int)$boottime[0]; } catch (\RuntimeException $e) { return $uptime; } return $uptime; } /** * @return string */ public function getNetworkInfo() { $result = []; $result['hostname'] = \gethostname(); try { $dns = $this->executeCommand('cat /etc/resolv.conf 2>/dev/null'); preg_match_all("/(?<=^nameserver ).\S*/m", $dns, $matches); $alldns = implode(' ', $matches[0]); $result['dns'] = $alldns; $netstat = $this->executeCommand('netstat -rn'); preg_match("/(?<=^default).*\b\d/m", $netstat, $gw); $result['gateway'] = $gw[0]; } catch (\RuntimeException $e) { return $result; } return $result; } /** * @return string */ public function getNetworkInterfaces() { $result = []; $ifconfig = $this->executeCommand('/sbin/ifconfig -a'); preg_match_all("/^(?<=(?!\t)).*(?=:)/m", $ifconfig, $interfaces); foreach ($interfaces[0] as $interface) { $iface = []; $iface['interface'] = $interface; $intface = $this->executeCommand('/sbin/ifconfig ' . $iface['interface']); preg_match_all("/(?<=inet ).\S*/m", $intface, $ipv4); preg_match_all("/(?<=inet6 )((.*(?=%))|(.\S*))/m", $intface, $ipv6); $iface['ipv4'] = implode(' ', $ipv4[0]); $iface['ipv6'] = implode(' ', $ipv6[0]); if ($iface['interface'] !== 'lo0') { preg_match_all("/(?<=ether ).*/m", $intface, $mac); preg_match("/(?<=status: ).*/m", $intface, $status); preg_match("/\b[0-9].*?(?=base)/m", $intface, $speed); preg_match("/(?<=\<).*(?=-)/m", $intface, $duplex); $iface['mac'] = implode(' ', $mac[0]); $iface['speed'] = $speed[0]; if (isset($status[0])) { $iface['status'] = $status[0]; } else { $iface['status'] = 'active'; } if (isset($iface['speed'])) { if (strpos($iface['speed'], 'G')) { $iface['speed'] = rtrim($iface['speed'], 'G'); $iface['speed'] = $iface['speed'] . ' Gbps'; } else { $iface['speed'] = $iface['speed'] . ' Mbps'; } } else { $iface['speed'] = 'unknown'; } if (isset($duplex[0])) { $iface['duplex'] = 'Duplex: ' . $duplex[0]; } else { $iface['duplex'] = ''; } } else { $iface['status'] = 'active'; $iface['speed'] = 'unknown'; $iface['duplex'] = ''; } $result[] = $iface; } return $result; } public function getDiskInfo(): array { $data = []; try { $disks = $this->executeCommand('df -TPk'); } catch (\RuntimeException $e) { return $data; } $matches = []; $pattern = '/^(?[\w\/-]+)\s*(?\w+)\s*(?\d+)\s*(?\d+)\s*(?\d+)\s*(?\d+%)\s*(?[\w\/-]+)$/m'; $result = preg_match_all($pattern, $disks, $matches); if ($result === 0 || $result === false) { return $data; } foreach ($matches['Filesystem'] as $i => $filesystem) { if (in_array($matches['Type'][$i], ['tmpfs', 'devtmpfs'], false)) { continue; } $disk = new Disk(); $disk->setDevice($filesystem); $disk->setFs($matches['Type'][$i]); $disk->setUsed((int)($matches['Used'][$i] / 1024)); $disk->setAvailable((int)($matches['Available'][$i] / 1024)); $disk->setPercent($matches['Capacity'][$i]); $disk->setMount($matches['Mounted'][$i]); $data[] = $disk; } return $data; } protected function executeCommand(string $command): string { $output = @shell_exec(escapeshellcmd($command)); if ($output === null || $output === '') { throw new \RuntimeException('No output for command: "' . $command . '"'); } return $output; } }