mirror of
https://github.com/EnumeratedDev/stormfetch.git
synced 2026-09-15 23:46:12 +00:00
184 lines
4.5 KiB
Go
184 lines
4.5 KiB
Go
package main
|
|
|
|
import (
|
|
"os"
|
|
"os/exec"
|
|
"path"
|
|
"strings"
|
|
"syscall"
|
|
|
|
"github.com/mitchellh/go-ps"
|
|
)
|
|
|
|
type DistroInfo struct {
|
|
ID string
|
|
LongName string
|
|
ShortName string
|
|
}
|
|
|
|
func GetDistroInfo() DistroInfo {
|
|
info := DistroInfo{
|
|
ID: "unknown",
|
|
LongName: "Unknown",
|
|
ShortName: "Unknown",
|
|
}
|
|
|
|
// Detect release file location
|
|
var releaseFile string
|
|
if _, err := os.Stat("/bedrock/etc/os-release"); os.Getenv("BEDROCK_RESTRICT") == "" && err == nil {
|
|
// Using Bedrock Linux
|
|
releaseFile = "/bedrock/etc/os-release"
|
|
} else if _, err := os.Stat("/etc/os-release"); err == nil {
|
|
// Using a regular linux distribution
|
|
releaseFile = "/etc/os-release"
|
|
} else {
|
|
return info
|
|
}
|
|
|
|
// Read release file
|
|
releaseMap, err := ReadKeyValueFile(releaseFile)
|
|
if err != nil {
|
|
return info
|
|
}
|
|
|
|
// Set struct fields
|
|
if id, ok := releaseMap["ID"]; ok {
|
|
info.ID = id
|
|
}
|
|
if longName, ok := releaseMap["PRETTY_NAME"]; ok {
|
|
info.LongName = longName
|
|
}
|
|
if shortName, ok := releaseMap["NAME"]; ok {
|
|
info.ShortName = shortName
|
|
}
|
|
|
|
return info
|
|
}
|
|
|
|
func GetDistroAsciiArt() string {
|
|
defaultAscii :=
|
|
` .--.
|
|
|o_o |
|
|
|:_/ |
|
|
// \ \
|
|
(| | )
|
|
/'\_ _/'\
|
|
\___)=(___/`
|
|
|
|
// Get ascii name to use
|
|
var asciiName string
|
|
if Ascii != "" {
|
|
asciiName = Ascii
|
|
} else if config.Ascii == "auto" {
|
|
asciiName = GetDistroInfo().ID
|
|
} else {
|
|
asciiName = config.Ascii
|
|
}
|
|
|
|
// Check for ascii art in home directory
|
|
userConfDir, err := os.UserConfigDir()
|
|
if err == nil {
|
|
if _, err := os.Stat(path.Join(userConfDir, "stormfetch/ascii/", asciiName)); err == nil {
|
|
if bytes, err := os.ReadFile(path.Join(userConfDir, "stormfetch/ascii/", asciiName)); err == nil {
|
|
return strings.TrimRight(string(bytes), "\n")
|
|
}
|
|
}
|
|
}
|
|
|
|
// Check for ascii art in system config directory
|
|
if _, err := os.Stat(path.Join(SystemConfigDir, "stormfetch/ascii/", asciiName)); err == nil {
|
|
if bytes, err := os.ReadFile(path.Join(SystemConfigDir, "stormfetch/ascii/", asciiName)); err == nil {
|
|
return strings.TrimRight(string(bytes), "\n")
|
|
}
|
|
}
|
|
|
|
return defaultAscii
|
|
}
|
|
|
|
func GetArch() string {
|
|
uname := syscall.Utsname{}
|
|
err := syscall.Uname(&uname)
|
|
if err != nil {
|
|
return "unknown"
|
|
}
|
|
|
|
var byteString [65]byte
|
|
var indexLength int
|
|
for ; uname.Machine[indexLength] != 0; indexLength++ {
|
|
byteString[indexLength] = uint8(uname.Machine[indexLength])
|
|
}
|
|
return string(byteString[:indexLength])
|
|
}
|
|
|
|
func GetKernel() (string, string) {
|
|
uname := syscall.Utsname{}
|
|
err := syscall.Uname(&uname)
|
|
if err != nil {
|
|
return "unknown", "unknown"
|
|
}
|
|
|
|
var kernelNameByteString [65]byte
|
|
var kernelNameLength int
|
|
for ; uname.Sysname[kernelNameLength] != 0; kernelNameLength++ {
|
|
kernelNameByteString[kernelNameLength] = uint8(uname.Sysname[kernelNameLength])
|
|
}
|
|
|
|
var kernelReleaseByteString [65]byte
|
|
var kernelReleaseLength int
|
|
for ; uname.Release[kernelReleaseLength] != 0; kernelReleaseLength++ {
|
|
kernelReleaseByteString[kernelReleaseLength] = uint8(uname.Release[kernelReleaseLength])
|
|
}
|
|
|
|
return string(kernelNameByteString[:kernelNameLength]), string(kernelReleaseByteString[:kernelReleaseLength])
|
|
}
|
|
|
|
func GetInitSystem() string {
|
|
process, err := ps.FindProcess(1)
|
|
if err != nil {
|
|
return ""
|
|
}
|
|
|
|
// Special cases
|
|
// OpenRC check
|
|
if _, err := os.Stat("/usr/sbin/openrc"); err == nil {
|
|
return "OpenRC " + runCommand("openrc --version | awk '{print $3}'", "/bin/sh")
|
|
}
|
|
|
|
// Default PID 1 process name checking
|
|
switch process.Executable() {
|
|
case "systemd":
|
|
return "Systemd " + runCommand("systemctl --version | head -n1 | awk '{print $2}'", "/bin/sh")
|
|
case "runit":
|
|
return "Runit"
|
|
case "dinit":
|
|
return "Dinit " + runCommand("dinit --version | head -n1 | awk '{print substr($3, 1, length($3)-1)}'", "/bin/sh")
|
|
case "enit":
|
|
return "Enit " + runCommand("enit --version | awk '{print $3}'", "/bin/sh")
|
|
default:
|
|
return process.Executable()
|
|
}
|
|
}
|
|
|
|
func GetLibc() string {
|
|
checkLibcOutput, err := exec.Command("ldd", "/usr/bin/ls").Output()
|
|
if err != nil {
|
|
return "Unknown"
|
|
}
|
|
|
|
if strings.Contains(string(checkLibcOutput), "ld-musl") {
|
|
// Using Musl Libc
|
|
output, _ := exec.Command("ldd").CombinedOutput()
|
|
return "Musl " + strings.TrimPrefix(strings.Split(strings.TrimSpace(string(output)), "\n")[1], "Version ")
|
|
} else {
|
|
// Using Glibc
|
|
cmd := exec.Command("ldd", "--version")
|
|
output, err := cmd.Output()
|
|
if err != nil {
|
|
return "Glibc"
|
|
}
|
|
outputSplit := strings.Split(strings.Split(strings.TrimSpace(string(output)), "\n")[0], " ")
|
|
ver := outputSplit[len(outputSplit)-1]
|
|
return "Glibc " + ver
|
|
}
|
|
}
|