Files
AetherForge/agent/client/syscheck_unix.go
AetherForge d52479c9a6 feat: Telegram fleet alerts, forge sigil scramble, UI polish, agent ops
- Calibrate: per-event Telegram/SMTP toggles, test notification, chat ID help
- Notify on agent connect/reconnect, offline/hashrate/rejection, forge complete
- Sigil scramble post-forge uniquification and Dispense Reveal ceremony
- Full system check, desktop push, BITS/host-binary persistence, Path Tracer
- Dashboard/Crucible visual polish, haptics, sacred geometry, mobile nav
- README documents alerts, sigil scramble, and pack-usb workflow
- USB bundle repacked via pack-usb.bat (AetherForge.exe + synced agent source)
2026-06-03 20:32:59 -07:00

139 lines
3.7 KiB
Go

//go:build !windows
package client
import (
"os"
"os/exec"
"os/user"
"runtime"
"strconv"
"strings"
)
func collectSysCheckPlatform(r *FullSysCheckReport) {
hw := &SysCheckHardware{}
if out, err := exec.Command("uname", "-a").CombinedOutput(); err == nil {
parts := strings.Fields(string(out))
if len(parts) >= 3 {
hw.Manufacturer = parts[2]
}
}
if runtime.GOOS == "darwin" {
if out, err := exec.Command("sysctl", "-n", "hw.model").CombinedOutput(); err == nil {
hw.Model = strings.TrimSpace(string(out))
}
if out, err := exec.Command("sysctl", "-n", "hw.memsize").CombinedOutput(); err == nil {
if n, err := strconv.ParseInt(strings.TrimSpace(string(out)), 10, 64); err == nil {
hw.MemoryGB = float64(n) / (1024 * 1024 * 1024)
}
}
} else {
if out, err := exec.Command("sh", "-c", "grep -m1 'model name' /proc/cpuinfo | cut -d: -f2").CombinedOutput(); err == nil {
hw.CPUs = []SysCheckCPU{{Name: strings.TrimSpace(string(out))}}
}
if out, err := exec.Command("sh", "-c", "grep -c ^processor /proc/cpuinfo").CombinedOutput(); err == nil {
if n, err := strconv.Atoi(strings.TrimSpace(string(out))); err == nil && len(hw.CPUs) > 0 {
hw.CPUs[0].Logical = n
}
}
if out, err := exec.Command("free", "-b").CombinedOutput(); err == nil {
lines := strings.Split(string(out), "\n")
if len(lines) > 1 {
fields := strings.Fields(lines[1])
if len(fields) >= 2 {
if total, err := strconv.ParseInt(fields[1], 10, 64); err == nil {
hw.MemoryGB = float64(total) / (1024 * 1024 * 1024)
}
}
}
}
}
if out, err := exec.Command("df", "-h").CombinedOutput(); err == nil {
hw.Disks = parseDfOutput(string(out))
}
if out, err := exec.Command("sh", "-c", "cat /proc/uptime 2>/dev/null || sysctl -n kern.boottime 2>/dev/null").CombinedOutput(); err == nil {
fields := strings.Fields(string(out))
if len(fields) > 0 {
if sec, err := strconv.ParseFloat(fields[0], 64); err == nil {
hw.UptimeHours = sec / 3600
}
}
}
r.Hardware = hw
if r.Identity == nil {
r.Identity = &SysCheckIdentity{}
}
if u, err := user.Current(); err == nil {
r.Identity.Username = u.Username
}
r.Identity.MACAddress = primaryMACAddress()
if r.Environment == nil {
r.Environment = &SysCheckEnvironment{}
}
r.Environment.HomeDir = os.Getenv("HOME")
r.Environment.TempDir = os.Getenv("TMPDIR")
if r.Environment.TempDir == "" {
r.Environment.TempDir = "/tmp"
}
if r.Network == nil {
r.Network = &SysCheckNetwork{}
}
if out, err := exec.Command("sh", "-c", "ip route show default 2>/dev/null || route -n get default 2>/dev/null").CombinedOutput(); err == nil {
r.Network.RoutesSummary = strings.TrimSpace(string(out))
for _, line := range strings.Split(string(out), "\n") {
if strings.Contains(line, "via") || strings.Contains(line, "gateway:") {
fields := strings.Fields(line)
for i, f := range fields {
if f == "via" && i+1 < len(fields) {
r.Network.DefaultGateway = fields[i+1]
break
}
if strings.HasPrefix(f, "gateway:") {
r.Network.DefaultGateway = strings.TrimPrefix(f, "gateway:")
break
}
}
break
}
}
}
}
func parseDfOutput(raw string) []SysCheckDisk {
var disks []SysCheckDisk
for _, line := range strings.Split(raw, "\n")[1:] {
fields := strings.Fields(line)
if len(fields) < 6 {
continue
}
mount := fields[len(fields)-1]
disks = append(disks, SysCheckDisk{
Mount: mount,
FSType: fields[0],
TotalGB: parseSizeGB(fields[1]),
FreeGB: parseSizeGB(fields[3]),
})
}
return disks
}
func parseSizeGB(s string) float64 {
s = strings.TrimSuffix(s, "G")
s = strings.TrimSuffix(s, "T")
s = strings.TrimSuffix(s, "M")
f, _ := strconv.ParseFloat(s, 64)
if strings.HasSuffix(s, "T") {
return f * 1024
}
return f
}