summaryrefslogtreecommitdiff
path: root/getDrives.go
diff options
context:
space:
mode:
Diffstat (limited to 'getDrives.go')
-rw-r--r--getDrives.go125
1 files changed, 125 insertions, 0 deletions
diff --git a/getDrives.go b/getDrives.go
new file mode 100644
index 0000000..35e4f49
--- /dev/null
+++ b/getDrives.go
@@ -0,0 +1,125 @@
+package main
+
+import (
+ "fmt"
+ "os"
+ "path/filepath"
+ "strings"
+)
+
+type DevInfo struct {
+ Name string
+ IsRaw bool
+ Type string
+ Parent string // raw device if this entry is a partition
+}
+
+func doDrives2() {
+ parts, err := parseProcPartitions()
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "Error reading /proc/partitions: %v\n", err)
+ os.Exit(1)
+ }
+
+ // Determine raw devices and type
+ devs := make(map[string]*DevInfo)
+ for _, p := range parts {
+ devs[p.Name] = &DevInfo{Name: p.Name}
+ }
+
+ for _, info := range devs {
+ sysPath := filepath.Join("/sys/block", info.Name)
+ if exists(sysPath) {
+ info.IsRaw = true
+ typ := detectType(sysPath)
+ info.Type = typ
+ } else {
+ info.IsRaw = false
+ info.Parent = findParent(info.Name, devs)
+ }
+ }
+
+ for _, info := range devs {
+ devPath := "/dev/" + info.Name
+ if info.IsRaw {
+ fmt.Printf("%-12s -> %-8s (raw)\n", devPath, info.Type)
+ } else {
+ if info.Parent != "" {
+ fmt.Printf("%-12s -> partition of /dev/%s\n", devPath, info.Parent)
+ } else {
+ fmt.Printf("%-12s -> unknown (no parent found)\n", devPath)
+ }
+ }
+ }
+}
+
+/*
+// parseProcPartitions parses /proc/partitions entries
+func parseProcPartitions() ([]struct {
+ Name string
+}, error) {
+ f, err := os.Open("/proc/partitions")
+ if err != nil {
+ return nil, err
+ }
+ defer f.Close()
+
+ scanner := bufio.NewScanner(f)
+ var parts []struct{ Name string }
+ for scanner.Scan() {
+ line := strings.TrimSpace(scanner.Text())
+ if line == "" || strings.HasPrefix(line, "major") {
+ continue
+ }
+ fields := strings.Fields(line)
+ if len(fields) < 4 {
+ continue
+ }
+ parts = append(parts, struct{ Name string }{Name: fields[3]})
+ }
+ return parts, scanner.Err()
+}
+*/
+
+// exists checks if the given path exists
+func exists(path string) bool {
+ _, err := os.Lstat(path)
+ return err == nil
+}
+
+// detectType determines device type by resolving sysPath and inspecting parent directories
+func detectType(sysPath string) string {
+ resolved, err := filepath.EvalSymlinks(sysPath)
+ if err != nil {
+ return "unknown"
+ }
+ resolved = filepath.ToSlash(resolved)
+
+ switch {
+ case strings.Contains(resolved, "/nvme"):
+ return "NVMe"
+ case strings.Contains(resolved, "/mmc_host") || strings.Contains(resolved, "/mmc"):
+ return "MMC/SD"
+ case strings.Contains(resolved, "/usb"):
+ return "USB"
+ case strings.Contains(resolved, "/loop"):
+ return "Loop"
+ case strings.Contains(resolved, "/ram"):
+ return "RAM disk"
+ default:
+ return "SCSI/SATA"
+ }
+}
+
+// findParent identifies the raw device for a partition, based on name heuristics
+func findParent(name string, devs map[string]*DevInfo) string {
+ for candidate := range devs {
+ if candidate == name {
+ continue
+ }
+ if strings.HasPrefix(name, candidate) {
+ return candidate
+ }
+ }
+ return ""
+}