diff --git a/lib/OperatingSystems/SunOS.php b/lib/OperatingSystems/SunOS.php
new file mode 100644
index 00000000..53e135bc
--- /dev/null
+++ b/lib/OperatingSystems/SunOS.php
@@ -0,0 +1,252 @@
+
+ *
+ * @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 SunOS
+ *
+ * @package OCA\ServerInfo\OperatingSystems
+ */
+class SunOS implements IOperatingSystem {
+
+ /**
+ * @return bool
+ */
+ public function supported(): bool {
+ return false;
+ }
+
+ public function getMemory(): Memory {
+ $data = new Memory();
+
+ try {
+ $swapinfo = $this->executeCommand('/usr/sbin/swap -s');
+ } catch (\RuntimeException $e) {
+ $swapinfo = '';
+ }
+
+ $matches = [];
+ $pattern = '/(?\d+)k used, (?\d+)k available$/';
+
+ $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('/usr/bin/vmstat -p');
+ } catch (\RuntimeException $e) {
+ $meminfo = '';
+ }
+
+ $lines = explode("\n", $meminfo);
+ $relevantLine = explode(" ", trim($lines[2]));
+ $data->setMemTotal((int)($relevantLine[0] / 1024 / 1024));
+ $data->setMemAvailable(((int)($relevantLine[1] / 1024 / 1024));
+
+ unset($relevantLine);
+ unset($lines);
+
+ return $data;
+ }
+
+ public function getCpuName(): string {
+ $data = 'Unknown Processor';
+
+ try {
+ $modelCmd = $this->executeCommand('/usr/sbin/psrinfo -pv');
+ $modelAry = explode("\n", $coresCmd);
+ $model = trim($modelAry[count($modelAry)-1]);
+ $coresCmd = $this->executeCommand('/usr/sbin/psrinfo');
+ $cores = count(explode("\n", $coresCmd));
+
+ if ($numCores === 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('/usr/bin/kstat -p unix:0:system_misc:boot_time');
+ 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('/usr/sbin/ifconfig -a');
+ preg_match_all("/^(?<=(?!\t)).*(?=:)/m", $ifconfig, $interfaces);
+
+ foreach ($interfaces[0] as $interface) {
+ $iface = [];
+ $iface['interface'] = $interface;
+ $intface = $this->executeCommand('/usr/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('/usr/bin/df -Pk');
+ } 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;
+ }
+}
diff --git a/lib/Os.php b/lib/Os.php
index b3448f77..e9760e4c 100644
--- a/lib/Os.php
+++ b/lib/Os.php
@@ -26,6 +26,7 @@
use OCA\ServerInfo\OperatingSystems\DefaultOs;
use OCA\ServerInfo\OperatingSystems\FreeBSD;
use OCA\ServerInfo\OperatingSystems\IOperatingSystem;
+use OCA\ServerInfo\OperatingSystems\SunOS;
use OCA\ServerInfo\Resources\Memory;
class Os implements IOperatingSystem {
@@ -37,6 +38,8 @@ class Os implements IOperatingSystem {
public function __construct() {
if (PHP_OS === 'FreeBSD') {
$this->backend = new FreeBSD();
+ } elseif (PHP_OS === 'SunOS') {
+ $this->backend = new SunOS();
} else {
$this->backend = new DefaultOs();
}