mirror of
https://github.com/EnumeratedDev/stormfetch.git
synced 2026-09-16 07:56:12 +00:00
125 lines
2.6 KiB
Go
125 lines
2.6 KiB
Go
package main
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"slices"
|
|
"strings"
|
|
"syscall"
|
|
)
|
|
|
|
type partition struct {
|
|
Device string
|
|
MountPoint string
|
|
Label string
|
|
FileystemType string
|
|
TotalSize uint64
|
|
UsedSize uint64
|
|
FreeSize uint64
|
|
}
|
|
|
|
func GetMountedPartitions(hiddenPartitions, hiddenFilesystems []string) []partition {
|
|
// Get all filesystem and partition labels
|
|
fslabels, err := os.ReadDir("/dev/disk/by-label")
|
|
if err != nil && !os.IsNotExist(err) {
|
|
return nil
|
|
}
|
|
partlabels, err := os.ReadDir("/dev/disk/by-partlabel")
|
|
if err != nil && !os.IsNotExist(err) {
|
|
return nil
|
|
}
|
|
labels := make(map[string]string)
|
|
for _, entry := range partlabels {
|
|
link, err := filepath.EvalSymlinks(filepath.Join("/dev/disk/by-partlabel/", entry.Name()))
|
|
if err != nil {
|
|
continue
|
|
}
|
|
labels[link] = entry.Name()
|
|
}
|
|
for _, entry := range fslabels {
|
|
link, err := filepath.EvalSymlinks(filepath.Join("/dev/disk/by-label/", entry.Name()))
|
|
if err != nil {
|
|
continue
|
|
}
|
|
labels[link] = entry.Name()
|
|
}
|
|
|
|
// Get all mounted partitions
|
|
file, err := os.ReadFile("/proc/mounts")
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
|
|
var partitions []partition
|
|
for _, entry := range strings.Split(string(file), "\n") {
|
|
fields := strings.Fields(entry)
|
|
if entry == "" {
|
|
continue
|
|
}
|
|
|
|
// Skip virtual partitions not under /dev
|
|
if !strings.HasPrefix(fields[0], "/dev") {
|
|
continue
|
|
}
|
|
|
|
// Skip partition if explicitly hidden
|
|
if slices.Contains(hiddenPartitions, fields[0]) {
|
|
continue
|
|
}
|
|
|
|
// Skip filesystem if explicitely hidden
|
|
if slices.Contains(hiddenFilesystems, fields[2]) {
|
|
continue
|
|
}
|
|
|
|
device, err := filepath.EvalSymlinks(fields[0])
|
|
if err != nil {
|
|
device = fields[0]
|
|
}
|
|
|
|
p := partition{
|
|
Device: device,
|
|
MountPoint: fields[1],
|
|
Label: "",
|
|
FileystemType: fields[2],
|
|
TotalSize: 0,
|
|
UsedSize: 0,
|
|
FreeSize: 0,
|
|
}
|
|
|
|
// Skip already added partitions
|
|
skip := false
|
|
for _, part := range partitions {
|
|
if part.Device == p.Device {
|
|
skip = true
|
|
}
|
|
}
|
|
if skip {
|
|
continue
|
|
}
|
|
|
|
// Set partition label if available
|
|
if value, ok := labels[p.Device]; ok {
|
|
p.Label = strings.ReplaceAll(value, "\\x20", " ")
|
|
}
|
|
|
|
// Get partition total, used and free space
|
|
buf := new(syscall.Statfs_t)
|
|
err = syscall.Statfs(p.MountPoint, buf)
|
|
if err != nil {
|
|
continue
|
|
}
|
|
totalBlocks := buf.Blocks
|
|
freeBlocks := buf.Bfree
|
|
usedBlocks := totalBlocks - freeBlocks
|
|
blockSize := uint64(buf.Bsize)
|
|
|
|
p.TotalSize = totalBlocks * blockSize
|
|
p.FreeSize = freeBlocks * blockSize
|
|
p.UsedSize = usedBlocks * blockSize
|
|
|
|
partitions = append(partitions, p)
|
|
}
|
|
return partitions
|
|
}
|