Skip to content

Commit 3cd81ec

Browse files
committed
PhysicalDisk: add new module
1 parent 0f497a5 commit 3cd81ec

File tree

14 files changed

+708
-0
lines changed

14 files changed

+708
-0
lines changed

CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,7 @@ set(LIBFASTFETCH_SRC
340340
src/modules/opengl/opengl.c
341341
src/modules/os/os.c
342342
src/modules/packages/packages.c
343+
src/modules/physicaldisk/physicaldisk.c
343344
src/modules/processes/processes.c
344345
src/modules/player/player.c
345346
src/modules/poweradapter/poweradapter.c
@@ -394,6 +395,7 @@ if(LINUX)
394395
src/detection/cursor/cursor_linux.c
395396
src/detection/bluetooth/bluetooth_linux.c
396397
src/detection/disk/disk_linux.c
398+
src/detection/physicaldisk/physicaldisk_linux.c
397399
src/detection/diskio/diskio_linux.c
398400
src/detection/displayserver/linux/displayserver_linux.c
399401
src/detection/displayserver/linux/drm.c
@@ -453,6 +455,7 @@ elseif(ANDROID)
453455
src/detection/cursor/cursor_nosupport.c
454456
src/detection/cpuusage/cpuusage_linux.c
455457
src/detection/disk/disk_linux.c
458+
src/detection/physicaldisk/physicaldisk_linux.c
456459
src/detection/diskio/diskio_linux.c
457460
src/detection/displayserver/displayserver_android.c
458461
src/detection/font/font_nosupport.c
@@ -506,6 +509,7 @@ elseif(BSD)
506509
src/detection/cpuusage/cpuusage_bsd.c
507510
src/detection/cursor/cursor_linux.c
508511
src/detection/disk/disk_bsd.c
512+
src/detection/physicaldisk/physicaldisk_bsd.c
509513
src/detection/diskio/diskio_bsd.c
510514
src/detection/displayserver/linux/displayserver_linux.c
511515
src/detection/displayserver/linux/drm.c
@@ -566,6 +570,7 @@ elseif(APPLE)
566570
src/detection/cpuusage/cpuusage_apple.c
567571
src/detection/cursor/cursor_apple.m
568572
src/detection/disk/disk_bsd.c
573+
src/detection/physicaldisk/physicaldisk_apple.c
569574
src/detection/diskio/diskio_apple.c
570575
src/detection/displayserver/displayserver_apple.c
571576
src/detection/font/font_apple.m
@@ -619,6 +624,7 @@ elseif(WIN32)
619624
src/detection/cpuusage/cpuusage_windows.c
620625
src/detection/cursor/cursor_windows.c
621626
src/detection/disk/disk_windows.c
627+
src/detection/physicaldisk/physicaldisk_windows.c
622628
src/detection/diskio/diskio_windows.c
623629
src/detection/displayserver/displayserver_windows.c
624630
src/detection/font/font_windows.c

src/common/modules.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ static FFModuleBaseInfo* O[] = {
9696

9797
static FFModuleBaseInfo* P[] = {
9898
(void*) &instance.config.modules.packages,
99+
(void*) &instance.config.modules.physicalDisk,
99100
(void*) &instance.config.modules.player,
100101
(void*) &instance.config.modules.powerAdapter,
101102
(void*) &instance.config.modules.processes,
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#include "fastfetch.h"
2+
3+
typedef enum FFPhysicalDiskType
4+
{
5+
FF_PHYSICALDISK_TYPE_NONE = 0,
6+
7+
// If neither is set, it's unknown
8+
FF_PHYSICALDISK_TYPE_HDD = 1 << 0,
9+
FF_PHYSICALDISK_TYPE_SSD = 1 << 1,
10+
11+
FF_PHYSICALDISK_TYPE_FIXED = 1 << 2,
12+
FF_PHYSICALDISK_TYPE_REMOVABLE = 1 << 3,
13+
} FFPhysicalDiskType;
14+
15+
typedef struct FFPhysicalDiskResult
16+
{
17+
FFstrbuf name;
18+
FFstrbuf interconnect;
19+
FFstrbuf serial;
20+
FFstrbuf devPath;
21+
FFPhysicalDiskType type;
22+
uint64_t size;
23+
} FFPhysicalDiskResult;
24+
25+
const char* ffDetectPhysicalDisk(FFlist* result, FFPhysicalDiskOptions* options);
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
#include "physicaldisk.h"
2+
#include "util/apple/cf_helpers.h"
3+
4+
#include <IOKit/IOKitLib.h>
5+
#include <IOKit/IOBSD.h>
6+
#include <IOKit/storage/IOMedia.h>
7+
#include <IOKit/storage/IOBlockStorageDriver.h>
8+
#include <IOKit/storage/IOStorageDeviceCharacteristics.h>
9+
#include <IOKit/storage/IOStorageProtocolCharacteristics.h>
10+
11+
static inline void wrapIoObjectRelease(io_service_t* service)
12+
{
13+
assert(service);
14+
if (*service)
15+
IOObjectRelease(*service);
16+
}
17+
#define FF_IOOBJECT_AUTO_RELEASE __attribute__((__cleanup__(wrapIoObjectRelease)))
18+
19+
const char* ffDetectPhysicalDisk(FFlist* result, FFPhysicalDiskOptions* options)
20+
{
21+
FF_IOOBJECT_AUTO_RELEASE io_iterator_t iterator = 0;
22+
if(IOServiceGetMatchingServices(MACH_PORT_NULL, IOServiceMatching(kIOMediaClass), &iterator) != KERN_SUCCESS)
23+
return "IOServiceGetMatchingServices() failed";
24+
25+
io_registry_entry_t registryEntry;
26+
while((registryEntry = IOIteratorNext(iterator)) != 0)
27+
{
28+
FF_IOOBJECT_AUTO_RELEASE io_registry_entry_t entryPartition = registryEntry;
29+
30+
io_name_t deviceName;
31+
if (IORegistryEntryGetName(registryEntry, deviceName) != KERN_SUCCESS)
32+
continue;
33+
34+
if (options->namePrefix.length && strncmp(deviceName, options->namePrefix.chars, options->namePrefix.length) != 0)
35+
continue;
36+
37+
FF_IOOBJECT_AUTO_RELEASE io_registry_entry_t entryDriver = 0;
38+
if (IORegistryEntryGetParentEntry(entryPartition, kIOServicePlane, &entryDriver) != KERN_SUCCESS)
39+
continue;
40+
41+
if (!IOObjectConformsTo(entryDriver, kIOBlockStorageDriverClass)) // physical disk only
42+
continue;
43+
44+
FFPhysicalDiskResult* device = (FFPhysicalDiskResult*) ffListAdd(result);
45+
ffStrbufInit(&device->serial);
46+
ffStrbufInitS(&device->name, deviceName);
47+
ffStrbufInit(&device->devPath);
48+
ffStrbufInit(&device->interconnect);
49+
device->type = FF_PHYSICALDISK_TYPE_NONE;
50+
device->size = 0;
51+
52+
FF_CFTYPE_AUTO_RELEASE CFBooleanRef removable = IORegistryEntryCreateCFProperty(entryPartition, CFSTR(kIOMediaRemovableKey), kCFAllocatorDefault, kNilOptions);
53+
device->type |= CFBooleanGetValue(removable) ? FF_PHYSICALDISK_TYPE_REMOVABLE : FF_PHYSICALDISK_TYPE_FIXED;
54+
55+
FF_CFTYPE_AUTO_RELEASE CFStringRef bsdName = IORegistryEntryCreateCFProperty(entryPartition, CFSTR(kIOBSDNameKey), kCFAllocatorDefault, kNilOptions);
56+
if (bsdName)
57+
{
58+
ffCfStrGetString(bsdName, &device->devPath);
59+
ffStrbufPrependS(&device->devPath, "/dev/");
60+
}
61+
62+
FF_CFTYPE_AUTO_RELEASE CFNumberRef mediaSize = IORegistryEntryCreateCFProperty(entryPartition, CFSTR(kIOMediaSizeKey), kCFAllocatorDefault, kNilOptions);
63+
if (mediaSize)
64+
ffCfNumGetInt64(mediaSize, (int64_t*) &device->size);
65+
else
66+
device->size = 0;
67+
68+
FF_IOOBJECT_AUTO_RELEASE io_registry_entry_t entryPhysical = 0;
69+
if (IORegistryEntryGetParentEntry(entryDriver, kIOServicePlane, &entryPhysical) == KERN_SUCCESS)
70+
{
71+
FF_CFTYPE_AUTO_RELEASE CFDictionaryRef protocolCharacteristics = IORegistryEntryCreateCFProperty(entryPhysical, CFSTR(kIOPropertyProtocolCharacteristicsKey), kCFAllocatorDefault, kNilOptions);
72+
if (protocolCharacteristics)
73+
ffCfDictGetString(protocolCharacteristics, CFSTR(kIOPropertyPhysicalInterconnectTypeKey), &device->interconnect);
74+
75+
FF_CFTYPE_AUTO_RELEASE CFDictionaryRef deviceCharacteristics = IORegistryEntryCreateCFProperty(entryPhysical, CFSTR(kIOPropertyDeviceCharacteristicsKey), kCFAllocatorDefault, kNilOptions);
76+
if (deviceCharacteristics)
77+
{
78+
ffCfDictGetString(deviceCharacteristics, CFSTR(kIOPropertyProductSerialNumberKey), &device->serial);
79+
80+
CFStringRef mediumType = (CFStringRef) CFDictionaryGetValue(deviceCharacteristics, CFSTR(kIOPropertyMediumTypeKey));
81+
if (mediumType)
82+
{
83+
if (CFStringCompare(mediumType, CFSTR(kIOPropertyMediumTypeSolidStateKey), 0) == 0)
84+
device->type |= FF_PHYSICALDISK_TYPE_SSD;
85+
else if (CFStringCompare(mediumType, CFSTR(kIOPropertyMediumTypeRotationalKey), 0) == 0)
86+
device->type |= FF_PHYSICALDISK_TYPE_HDD;
87+
}
88+
}
89+
}
90+
}
91+
92+
return NULL;
93+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
#include "physicaldisk.h"
2+
#include "util/stringUtils.h"
3+
4+
#include <devstat.h>
5+
#include <memory.h>
6+
#include <fcntl.h>
7+
#include <sys/ioctl.h>
8+
#include <sys/disk.h>
9+
#include <libgeom.h>
10+
11+
const char* ffDetectPhysicalDisk(FFlist* result, FFPhysicalDiskOptions* options)
12+
{
13+
struct gmesh geomTree;
14+
if (geom_gettree(&geomTree) < 0)
15+
return "geom_gettree() failed";
16+
17+
if (geom_stats_open() < 0)
18+
return "geom_stats_open() failed";
19+
20+
void* snap = geom_stats_snapshot_get();
21+
struct devstat* snapIter;
22+
while ((snapIter = geom_stats_snapshot_next(snap)) != NULL)
23+
{
24+
if (snapIter->device_type & DEVSTAT_TYPE_PASS)
25+
continue;
26+
struct gident* geomId = geom_lookupid(&geomTree, snapIter->id);
27+
if (geomId == NULL)
28+
continue;
29+
if (geomId->lg_what != ISPROVIDER)
30+
continue;
31+
struct gprovider* provider = (struct gprovider*) geomId->lg_ptr;
32+
if (provider->lg_geom->lg_rank != 1)
33+
continue;
34+
35+
FF_STRBUF_AUTO_DESTROY name = ffStrbufCreateS(provider->lg_name);
36+
FF_STRBUF_AUTO_DESTROY identifier = ffStrbufCreate();
37+
FFPhysicalDiskType type = FF_PHYSICALDISK_TYPE_NONE;
38+
for (struct gconfig* ptr = provider->lg_config.lh_first; ptr; ptr = ptr->lg_config.le_next)
39+
{
40+
if (ffStrEquals(ptr->lg_name, "descr"))
41+
ffStrbufSetS(&name, ptr->lg_val);
42+
else if (ffStrEquals(ptr->lg_name, "rotationrate") && !ffStrEquals(ptr->lg_val, "unknown"))
43+
type |= ffStrEquals(ptr->lg_val, "0") ? FF_PHYSICALDISK_TYPE_SSD : FF_PHYSICALDISK_TYPE_HDD;
44+
else if (ffStrEquals(ptr->lg_name, "ident"))
45+
ffStrbufSetS(&identifier, ptr->lg_val);
46+
}
47+
48+
if (options->namePrefix.length && !ffStrbufStartsWith(&name, &options->namePrefix))
49+
continue;
50+
51+
FFPhysicalDiskResult* device = (FFPhysicalDiskResult*) ffListAdd(result);
52+
ffStrbufInitF(&device->devPath, "/dev/%s", provider->lg_name);
53+
ffStrbufInitMove(&device->serial, &identifier);
54+
ffStrbufInit(&device->interconnect);
55+
switch (snapIter->device_type & DEVSTAT_TYPE_IF_MASK)
56+
{
57+
case DEVSTAT_TYPE_IF_SCSI: ffStrbufAppendS(&device->interconnect, "SCSI"); break;
58+
case DEVSTAT_TYPE_IF_IDE: ffStrbufAppendS(&device->interconnect, "IDE"); break;
59+
case DEVSTAT_TYPE_IF_OTHER: ffStrbufAppendS(&device->interconnect, "OTHER"); break;
60+
}
61+
device->size = (uint64_t) provider->lg_mediasize;
62+
ffStrbufInitMove(&device->name, &name);
63+
device->type = type;
64+
}
65+
66+
geom_stats_snapshot_free(snap);
67+
geom_stats_close();
68+
69+
return NULL;
70+
}
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
#include "physicaldisk.h"
2+
#include "common/io/io.h"
3+
#include "common/properties.h"
4+
#include "util/stringUtils.h"
5+
6+
#include <ctype.h>
7+
#include <limits.h>
8+
9+
const char* ffDetectPhysicalDisk(FFlist* result, FFPhysicalDiskOptions* options)
10+
{
11+
FF_AUTO_CLOSE_DIR DIR* sysBlockDirp = opendir("/sys/block/");
12+
if(sysBlockDirp == NULL)
13+
return "opendir(\"/sys/block/\") == NULL";
14+
15+
struct dirent* sysBlockEntry;
16+
while ((sysBlockEntry = readdir(sysBlockDirp)) != NULL)
17+
{
18+
const char* const devName = sysBlockEntry->d_name;
19+
20+
if (devName[0] == '.')
21+
continue;
22+
23+
char pathSysBlock[PATH_MAX];
24+
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s", devName);
25+
26+
char pathSysDeviceReal[PATH_MAX] = "";
27+
readlink(pathSysBlock, pathSysDeviceReal, sizeof(pathSysDeviceReal) - 1);
28+
29+
if (strstr(pathSysDeviceReal, "/virtual/")) // virtual device
30+
continue;
31+
32+
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device", devName);
33+
if (!ffPathExists(pathSysBlock, FF_PATHTYPE_DIRECTORY))
34+
continue;
35+
36+
FFPhysicalDiskResult* device = (FFPhysicalDiskResult*) ffListAdd(result);
37+
device->type = FF_PHYSICALDISK_TYPE_NONE;
38+
ffStrbufInit(&device->name);
39+
40+
{
41+
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device/vendor", devName);
42+
ffAppendFileBuffer(pathSysBlock, &device->name);
43+
if (device->name.length > 0)
44+
ffStrbufAppendC(&device->name, ' ');
45+
46+
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device/model", devName);
47+
ffAppendFileBuffer(pathSysBlock, &device->name);
48+
ffStrbufTrim(&device->name, ' ');
49+
50+
if (device->name.length == 0)
51+
ffStrbufSetS(&device->name, devName);
52+
53+
if (options->namePrefix.length && !ffStrbufStartsWith(&device->name, &options->namePrefix))
54+
{
55+
ffStrbufDestroy(&device->name);
56+
result->length--;
57+
continue;
58+
}
59+
}
60+
61+
ffStrbufInitF(&device->devPath, "/dev/%s", devName);
62+
63+
{
64+
ffStrbufInit(&device->interconnect);
65+
if (strstr(pathSysDeviceReal, "/usb") != NULL)
66+
ffStrbufSetS(&device->interconnect, "usb");
67+
else
68+
{
69+
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device/transport", devName);
70+
if (!ffAppendFileBuffer(pathSysBlock, &device->interconnect))
71+
{
72+
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device/uevent", devName);
73+
if (ffParsePropFile(pathSysBlock, "DEVTYPE=", &device->interconnect))
74+
ffStrbufSubstrBeforeLastC(&device->interconnect, '_');
75+
}
76+
}
77+
}
78+
79+
{
80+
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/queue/rotational", devName);
81+
char isRotationalChar = '1';
82+
if (ffReadFileData(pathSysBlock, 1, &isRotationalChar) > 0)
83+
device->type |= isRotationalChar == '1' ? FF_PHYSICALDISK_TYPE_HDD : FF_PHYSICALDISK_TYPE_SSD;
84+
}
85+
86+
{
87+
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/size", devName);
88+
char blkSize[32];
89+
ssize_t fileSize = ffReadFileData(pathSysBlock, sizeof(blkSize) - 1, blkSize);
90+
if (fileSize > 0)
91+
{
92+
blkSize[fileSize] = 0;
93+
device->size = (uint64_t) strtoul(blkSize, NULL, 10) * 512;
94+
}
95+
else
96+
device->size = 0;
97+
}
98+
99+
{
100+
char removableChar = '0';
101+
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/removable", devName);
102+
if (ffReadFileData(pathSysBlock, 1, &removableChar) > 0)
103+
device->type |= removableChar == '1' ? FF_PHYSICALDISK_TYPE_REMOVABLE : FF_PHYSICALDISK_TYPE_FIXED;
104+
}
105+
106+
{
107+
ffStrbufInit(&device->serial);
108+
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device/serial", devName);
109+
ffReadFileBuffer(pathSysBlock, &device->serial);
110+
}
111+
}
112+
113+
return NULL;
114+
}

0 commit comments

Comments
 (0)