master ohmu/fastfetch-openbsd / src / detection / physicaldisk / physicaldisk_sunos.c
ohmu  ·  2026-10-15
  1#include "physicaldisk.h"
  2#include "common/debug.h"
  3#include "common/strutil.h"
  4#include "sys/scsi/generic/inquiry.h"
  5
  6#include <libdevinfo.h>
  7#include <sys/stat.h>
  8
  9struct FFWalkTreeBundle {
 10    FFPhysicalDiskOptions* options;
 11    FFlist* disks;
 12};
 13
 14static int walkDevTree(di_node_t node, di_minor_t minor, struct FFWalkTreeBundle* bundle) {
 15    FFPhysicalDiskOptions* options = bundle->options;
 16    FFlist* result = bundle->disks;
 17
 18    if (di_minor_spectype(minor) != S_IFCHR || !ffStrEquals(di_minor_name(minor), "a,raw")) {
 19        return DI_WALK_CONTINUE;
 20    }
 21
 22    char* productId;
 23    char* vendorId;
 24    if (di_prop_lookup_strings(DDI_DEV_T_ANY, node, "inquiry-product-id", &productId) > 0 && di_prop_lookup_strings(DDI_DEV_T_ANY, node, "inquiry-vendor-id", &vendorId) > 0) {
 25        FF_STRBUF_AUTO_DESTROY name = ffStrbufCreateF("%s %s", vendorId, productId);
 26        if (options->namePrefix.length && !ffStrbufStartsWithIgnCase(&name, &options->namePrefix)) {
 27            return DI_WALK_CONTINUE;
 28        }
 29
 30        int* value;
 31
 32        FFPhysicalDiskType type = FF_PHYSICALDISK_TYPE_NONE;
 33        uint64_t size = 0;
 34        int64_t* nblocks;
 35        if (di_prop_lookup_int64(DDI_DEV_T_ANY, node, "device-nblocks", &nblocks) > 0) {
 36            if (*nblocks == 0) {
 37                if (options->hideType & FF_PHYSICALDISK_TYPE_UNUSED) {
 38                    return DI_WALK_CONTINUE;
 39                }
 40
 41                type |= FF_PHYSICALDISK_TYPE_UNUSED;
 42            } else if (di_prop_lookup_ints(DDI_DEV_T_ANY, node, "device-blksize", &value) > 0) {
 43                size = (uint64_t) ((uint64_t) *nblocks * (uint64_t) *value);
 44            }
 45        }
 46
 47        FFPhysicalDiskResult* device = FF_LIST_ADD(FFPhysicalDiskResult, *result);
 48        ffStrbufInitMove(&device->name, &name);
 49        ffStrbufInitF(&device->devPath, "/devices%s", di_devfs_path(node));
 50        ffStrbufInit(&device->serial);
 51        ffStrbufInit(&device->revision);
 52        ffStrbufInit(&device->interconnect);
 53        device->temperature = FF_PHYSICALDISK_TEMP_UNSET;
 54        device->type = type;
 55        device->size = size;
 56
 57        char* buf;
 58        bool usb = false;
 59        if (di_prop_lookup_strings(DDI_DEV_T_ANY, node, "inquiry-serial-no", &buf) > 0) {
 60            ffStrbufSetS(&device->serial, buf);
 61            ffStrbufTrimSpace(&device->serial);
 62        } else {
 63            di_node_t parent = di_parent_node(node);
 64            if (parent != DI_NODE_NIL && di_prop_lookup_strings(DDI_DEV_T_ANY, parent, "usb-serialno", &buf) > 0) {
 65                ffStrbufSetS(&device->serial, buf);
 66                usb = true;
 67            }
 68        }
 69        if (di_prop_lookup_strings(DDI_DEV_T_ANY, node, "inquiry-revision-id", &buf) > 0) {
 70            ffStrbufSetS(&device->revision, buf);
 71            ffStrbufTrimRightSpace(&device->revision);
 72        }
 73
 74        if (usb) {
 75            ffStrbufSetStatic(&device->interconnect, "USB");
 76        } else if (di_prop_lookup_strings(DDI_DEV_T_ANY, node, "class", &buf) > 0) {
 77            ffStrbufSetS(&device->interconnect, buf);
 78        } else {
 79            di_node_t parent = di_parent_node(node);
 80            if (parent != DI_NODE_NIL && di_prop_lookup_strings(DDI_DEV_T_ANY, parent, "model", &buf) > 0) {
 81                ffStrbufSetS(&device->interconnect, buf);
 82            }
 83        }
 84
 85        device->type |= di_prop_find(DDI_DEV_T_ANY, node, "removable-media") ? FF_PHYSICALDISK_TYPE_REMOVABLE : FF_PHYSICALDISK_TYPE_FIXED;
 86
 87        if (di_prop_lookup_ints(DDI_DEV_T_ANY, node, "device-solid-state", &value) > 0) {
 88            device->type |= *value ? FF_PHYSICALDISK_TYPE_SSD : FF_PHYSICALDISK_TYPE_HDD;
 89        }
 90        if (di_prop_lookup_ints(DDI_DEV_T_ANY, node, "inquiry-device-type", &value) > 0) {
 91            device->type |= *value == DTYPE_DIRECT ? FF_PHYSICALDISK_TYPE_READWRITE : *value == DTYPE_RODIRECT ? FF_PHYSICALDISK_TYPE_READONLY
 92                                                                                                               : 0;
 93        }
 94    }
 95
 96    return DI_WALK_CONTINUE;
 97}
 98
 99const char* ffDetectPhysicalDisk(FFlist* result, FFPhysicalDiskOptions* options) {
100    di_node_t rootNode = di_init("/", DINFOCPYALL);
101    if (rootNode == DI_NODE_NIL) {
102        FF_DEBUG("di_init() failed");
103        return "di_init() failed";
104    }
105    di_walk_minor(rootNode, DDI_NT_BLOCK, DI_WALK_CLDFIRST, &(struct FFWalkTreeBundle) { options, result }, (void*) walkDevTree);
106    di_fini(rootNode);
107
108    return nullptr;
109}