mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-11-05 20:54:21 +01:00
Chore: run clang-format
```bash find . -type f \( -name "*.c" -o -name "*.h" -o -name "*.cpp" -o -name "*.hpp" \) ! -path "src/3rdparty/*" -print0 | xargs -0 clang-format -i ```
This commit is contained in:
+22
-24
@@ -1,31 +1,29 @@
|
||||
#include "disk.h"
|
||||
|
||||
static int compareDisks(const FFDisk* disk1, const FFDisk* disk2)
|
||||
{
|
||||
static int compareDisks(const FFDisk* disk1, const FFDisk* disk2) {
|
||||
return ffStrbufComp(&disk1->mountpoint, &disk2->mountpoint);
|
||||
}
|
||||
|
||||
const char* ffDetectDisks(FFDiskOptions* options, FFlist* disks)
|
||||
{
|
||||
const char* ffDetectDisks(FFDiskOptions* options, FFlist* disks) {
|
||||
const char* error = ffDetectDisksImpl(options, disks);
|
||||
|
||||
if (error) return error;
|
||||
if (disks->length == 0) return NULL;
|
||||
if (error) {
|
||||
return error;
|
||||
}
|
||||
if (disks->length == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//We need to sort the disks, so that we can detect, which disk a path resides on
|
||||
// For example for /boot/efi/bootmgr we need to check /boot/efi before /boot
|
||||
//Note that we sort alphabetically here for a better ordering when printing the list,
|
||||
// so the check must be done in reverse order
|
||||
// We need to sort the disks, so that we can detect, which disk a path resides on
|
||||
// For example for /boot/efi/bootmgr we need to check /boot/efi before /boot
|
||||
// Note that we sort alphabetically here for a better ordering when printing the list,
|
||||
// so the check must be done in reverse order
|
||||
ffListSort(disks, (void*) compareDisks);
|
||||
FF_LIST_FOR_EACH(FFDisk, disk, *disks)
|
||||
{
|
||||
if(disk->bytesTotal == 0)
|
||||
FF_LIST_FOR_EACH (FFDisk, disk, *disks) {
|
||||
if (disk->bytesTotal == 0) {
|
||||
disk->type |= FF_DISK_VOLUME_TYPE_UNKNOWN_BIT;
|
||||
else
|
||||
{
|
||||
disk->bytesUsed = disk->bytesTotal - (
|
||||
options->calcType == FF_DISK_CALC_TYPE_FREE ? disk->bytesFree : disk->bytesAvailable
|
||||
);
|
||||
} else {
|
||||
disk->bytesUsed = disk->bytesTotal - (options->calcType == FF_DISK_CALC_TYPE_FREE ? disk->bytesFree : disk->bytesAvailable);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,13 +31,11 @@ const char* ffDetectDisks(FFDiskOptions* options, FFlist* disks)
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <fnmatch.h>
|
||||
# include <fnmatch.h>
|
||||
|
||||
bool ffDiskMatchesFolderPatterns(FFstrbuf* folders, const char* path, char separator)
|
||||
{
|
||||
bool ffDiskMatchesFolderPatterns(FFstrbuf* folders, const char* path, char separator) {
|
||||
uint32_t startIndex = 0;
|
||||
while(startIndex < folders->length)
|
||||
{
|
||||
while (startIndex < folders->length) {
|
||||
uint32_t sepIndex = ffStrbufNextIndexC(folders, startIndex, separator);
|
||||
|
||||
char savedSep = folders->chars[sepIndex]; // Can be '\0' if at end
|
||||
@@ -48,7 +44,9 @@ bool ffDiskMatchesFolderPatterns(FFstrbuf* folders, const char* path, char separ
|
||||
bool matched = fnmatch(&folders->chars[startIndex], path, 0) == 0;
|
||||
folders->chars[sepIndex] = savedSep;
|
||||
|
||||
if (matched) return true;
|
||||
if (matched) {
|
||||
return true;
|
||||
}
|
||||
|
||||
startIndex = sepIndex + 1;
|
||||
}
|
||||
|
||||
@@ -4,13 +4,12 @@
|
||||
#include "modules/disk/option.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#define FF_DISK_FOLDER_SEPARATOR ';'
|
||||
# define FF_DISK_FOLDER_SEPARATOR ';'
|
||||
#else
|
||||
#define FF_DISK_FOLDER_SEPARATOR ':'
|
||||
# define FF_DISK_FOLDER_SEPARATOR ':'
|
||||
#endif
|
||||
|
||||
typedef struct FFDisk
|
||||
{
|
||||
typedef struct FFDisk {
|
||||
FFstrbuf mountFrom;
|
||||
FFstrbuf mountpoint;
|
||||
FFstrbuf filesystem;
|
||||
|
||||
+106
-92
@@ -6,168 +6,180 @@
|
||||
#include <sys/stat.h>
|
||||
|
||||
#ifdef __NetBSD__
|
||||
#include <sys/types.h>
|
||||
#include <sys/statvfs.h>
|
||||
#define statfs statvfs
|
||||
#define f_flags f_flag
|
||||
#define f_bsize f_frsize
|
||||
# include <sys/types.h>
|
||||
# include <sys/statvfs.h>
|
||||
# define statfs statvfs
|
||||
# define f_flags f_flag
|
||||
# define f_bsize f_frsize
|
||||
#endif
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#if __has_include(<libgeom.h>)
|
||||
#include <libgeom.h>
|
||||
# if __has_include(<libgeom.h>)
|
||||
# include <libgeom.h>
|
||||
|
||||
static const char* detectFsLabel(struct statfs* fs, FFDisk* disk)
|
||||
{
|
||||
if (!ffStrStartsWith(fs->f_mntfromname, "/dev/"))
|
||||
static const char* detectFsLabel(struct statfs* fs, FFDisk* disk) {
|
||||
if (!ffStrStartsWith(fs->f_mntfromname, "/dev/")) {
|
||||
return "Only block devices are supported";
|
||||
}
|
||||
|
||||
// Detect volume label in geom tree
|
||||
static struct gmesh geomTree;
|
||||
static struct gclass* cLabels;
|
||||
if (!cLabels)
|
||||
{
|
||||
if (geomTree.lg_ident)
|
||||
if (!cLabels) {
|
||||
if (geomTree.lg_ident) {
|
||||
return "Previous geom_gettree() failed";
|
||||
}
|
||||
|
||||
if (geom_gettree(&geomTree) < 0)
|
||||
{
|
||||
geomTree.lg_ident = (void*)(intptr_t)-1;
|
||||
if (geom_gettree(&geomTree) < 0) {
|
||||
geomTree.lg_ident = (void*) (intptr_t) -1;
|
||||
return "geom_gettree() failed";
|
||||
}
|
||||
|
||||
for (cLabels = geomTree.lg_class.lh_first; cLabels && !ffStrEquals(cLabels->lg_name, "LABEL"); cLabels = cLabels->lg_class.le_next);
|
||||
if (!cLabels)
|
||||
if (!cLabels) {
|
||||
return "Class LABEL is not found";
|
||||
}
|
||||
}
|
||||
|
||||
for (struct ggeom* label = cLabels->lg_geom.lh_first; label; label = label->lg_geom.le_next)
|
||||
{
|
||||
for (struct ggeom* label = cLabels->lg_geom.lh_first; label; label = label->lg_geom.le_next) {
|
||||
struct gprovider* provider = label->lg_provider.lh_first;
|
||||
if (!provider || !ffStrEquals(label->lg_name, fs->f_mntfromname + strlen("/dev/"))) continue;
|
||||
if (!provider || !ffStrEquals(label->lg_name, fs->f_mntfromname + strlen("/dev/"))) {
|
||||
continue;
|
||||
}
|
||||
const char* str = strchr(provider->lg_name, '/');
|
||||
ffStrbufSetS(&disk->name, str ? str + 1 : provider->lg_name);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#else
|
||||
static const char* detectFsLabel(FF_MAYBE_UNUSED struct statfs* fs, FF_MAYBE_UNUSED FFDisk* disk)
|
||||
{
|
||||
# else
|
||||
static const char* detectFsLabel(FF_MAYBE_UNUSED struct statfs* fs, FF_MAYBE_UNUSED FFDisk* disk) {
|
||||
return "Fastfetch was compiled without libgeom support";
|
||||
}
|
||||
#endif
|
||||
# endif
|
||||
|
||||
static void detectFsInfo(struct statfs* fs, FFDisk* disk)
|
||||
{
|
||||
if(ffStrbufEqualS(&disk->filesystem, "zfs"))
|
||||
{
|
||||
static void detectFsInfo(struct statfs* fs, FFDisk* disk) {
|
||||
if (ffStrbufEqualS(&disk->filesystem, "zfs")) {
|
||||
disk->type = !ffStrbufStartsWithS(&disk->mountFrom, "zroot/") || ffStrbufStartsWithS(&disk->mountFrom, "zroot/ROOT/")
|
||||
? FF_DISK_VOLUME_TYPE_REGULAR_BIT
|
||||
: FF_DISK_VOLUME_TYPE_SUBVOLUME_BIT;
|
||||
}
|
||||
else if(fs->f_flags & MNT_IGNORE)
|
||||
} else if (fs->f_flags & MNT_IGNORE) {
|
||||
disk->type = FF_DISK_VOLUME_TYPE_HIDDEN_BIT;
|
||||
else if(!(fs->f_flags & MNT_LOCAL))
|
||||
} else if (!(fs->f_flags & MNT_LOCAL)) {
|
||||
disk->type = FF_DISK_VOLUME_TYPE_EXTERNAL_BIT;
|
||||
else
|
||||
} else {
|
||||
disk->type = FF_DISK_VOLUME_TYPE_REGULAR_BIT;
|
||||
}
|
||||
|
||||
detectFsLabel(fs, disk);
|
||||
}
|
||||
#elif __APPLE__
|
||||
#include "common/apple/cf_helpers.h"
|
||||
# include "common/apple/cf_helpers.h"
|
||||
|
||||
#include <sys/attr.h>
|
||||
#include <unistd.h>
|
||||
# include <sys/attr.h>
|
||||
# include <unistd.h>
|
||||
|
||||
#ifndef MAC_OS_X_VERSION_10_15
|
||||
#define MNT_REMOVABLE 0x00000200
|
||||
#endif
|
||||
# ifndef MAC_OS_X_VERSION_10_15
|
||||
# define MNT_REMOVABLE 0x00000200
|
||||
# endif
|
||||
|
||||
struct CmnAttrBuf {
|
||||
uint32_t length;
|
||||
uint32_t length;
|
||||
attrreference_t nameRef;
|
||||
char nameSpace[NAME_MAX * 3 + 1];
|
||||
char nameSpace[NAME_MAX * 3 + 1];
|
||||
} __attribute__((aligned(4), packed));
|
||||
|
||||
void detectFsInfo(struct statfs* fs, FFDisk* disk)
|
||||
{
|
||||
if(fs->f_flags & MNT_DONTBROWSE)
|
||||
void detectFsInfo(struct statfs* fs, FFDisk* disk) {
|
||||
if (fs->f_flags & MNT_DONTBROWSE) {
|
||||
disk->type = FF_DISK_VOLUME_TYPE_HIDDEN_BIT;
|
||||
else if(fs->f_flags & MNT_REMOVABLE || !(fs->f_flags & MNT_LOCAL))
|
||||
} else if (fs->f_flags & MNT_REMOVABLE || !(fs->f_flags & MNT_LOCAL)) {
|
||||
disk->type = FF_DISK_VOLUME_TYPE_EXTERNAL_BIT;
|
||||
else
|
||||
} else {
|
||||
disk->type = FF_DISK_VOLUME_TYPE_REGULAR_BIT;
|
||||
}
|
||||
|
||||
struct CmnAttrBuf attrBuf;
|
||||
if (getattrlist(disk->mountpoint.chars, &(struct attrlist) {
|
||||
.bitmapcount = ATTR_BIT_MAP_COUNT,
|
||||
.commonattr = ATTR_CMN_NAME,
|
||||
}, &attrBuf, sizeof(attrBuf), 0) == 0)
|
||||
.bitmapcount = ATTR_BIT_MAP_COUNT,
|
||||
.commonattr = ATTR_CMN_NAME,
|
||||
},
|
||||
&attrBuf,
|
||||
sizeof(attrBuf),
|
||||
0) == 0) {
|
||||
ffStrbufInitNS(&disk->name, attrBuf.nameRef.attr_length - 1 /* excluding '\0' */, attrBuf.nameSpace);
|
||||
}
|
||||
}
|
||||
#else
|
||||
static void detectFsInfo(struct statfs* fs, FFDisk* disk)
|
||||
{
|
||||
#ifdef MNT_IGNORE
|
||||
if(fs->f_flags & MNT_IGNORE)
|
||||
static void detectFsInfo(struct statfs* fs, FFDisk* disk) {
|
||||
# ifdef MNT_IGNORE
|
||||
if (fs->f_flags & MNT_IGNORE) {
|
||||
disk->type = FF_DISK_VOLUME_TYPE_HIDDEN_BIT;
|
||||
else
|
||||
#endif
|
||||
if(!(fs->f_flags & MNT_LOCAL))
|
||||
} else
|
||||
# endif
|
||||
if (!(fs->f_flags & MNT_LOCAL)) {
|
||||
disk->type = FF_DISK_VOLUME_TYPE_EXTERNAL_BIT;
|
||||
else
|
||||
} else {
|
||||
disk->type = FF_DISK_VOLUME_TYPE_REGULAR_BIT;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
const char* ffDetectDisksImpl(FFDiskOptions* options, FFlist* disks)
|
||||
{
|
||||
#ifndef __NetBSD__
|
||||
const char* ffDetectDisksImpl(FFDiskOptions* options, FFlist* disks) {
|
||||
#ifndef __NetBSD__
|
||||
int size = getfsstat(NULL, 0, MNT_WAIT);
|
||||
if(size <= 0) return "getfsstat(NULL, 0, MNT_WAIT) failed";
|
||||
#else
|
||||
if (size <= 0) {
|
||||
return "getfsstat(NULL, 0, MNT_WAIT) failed";
|
||||
}
|
||||
#else
|
||||
int size = getvfsstat(NULL, 0, ST_WAIT);
|
||||
if(size <= 0) return "getvfsstat(NULL, 0, ST_WAIT) failed";
|
||||
#endif
|
||||
if (size <= 0) {
|
||||
return "getvfsstat(NULL, 0, ST_WAIT) failed";
|
||||
}
|
||||
#endif
|
||||
|
||||
FF_AUTO_FREE struct statfs* buf = malloc(sizeof(*buf) * (unsigned) size);
|
||||
#ifndef __NetBSD__
|
||||
if(getfsstat(buf, (int) (sizeof(*buf) * (unsigned) size), MNT_NOWAIT) <= 0)
|
||||
#ifndef __NetBSD__
|
||||
if (getfsstat(buf, (int) (sizeof(*buf) * (unsigned) size), MNT_NOWAIT) <= 0) {
|
||||
return "getfsstat(buf, size, MNT_NOWAIT) failed";
|
||||
#else
|
||||
if(getvfsstat(buf, sizeof(*buf) * (unsigned) size, ST_NOWAIT) <= 0)
|
||||
}
|
||||
#else
|
||||
if (getvfsstat(buf, sizeof(*buf) * (unsigned) size, ST_NOWAIT) <= 0) {
|
||||
return "getvfsstat(buf, size, ST_NOWAIT) failed";
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
for(struct statfs* fs = buf; fs < buf + size; ++fs)
|
||||
{
|
||||
if(__builtin_expect(options->folders.length > 0, 0))
|
||||
{
|
||||
if(!ffStrbufSeparatedContainS(&options->folders, fs->f_mntonname, FF_DISK_FOLDER_SEPARATOR))
|
||||
for (struct statfs* fs = buf; fs < buf + size; ++fs) {
|
||||
if (__builtin_expect(options->folders.length > 0, 0)) {
|
||||
if (!ffStrbufSeparatedContainS(&options->folders, fs->f_mntonname, FF_DISK_FOLDER_SEPARATOR)) {
|
||||
continue;
|
||||
}
|
||||
} else if (!ffStrEquals(fs->f_mntonname, "/") && !ffStrStartsWith(fs->f_mntfromname, "/dev/") && !ffStrEquals(fs->f_fstypename, "zfs") && !ffStrEquals(fs->f_fstypename, "fusefs.sshfs")) {
|
||||
continue;
|
||||
}
|
||||
else if(!ffStrEquals(fs->f_mntonname, "/") && !ffStrStartsWith(fs->f_mntfromname, "/dev/") && !ffStrEquals(fs->f_fstypename, "zfs") && !ffStrEquals(fs->f_fstypename, "fusefs.sshfs"))
|
||||
continue;
|
||||
|
||||
if (options->hideFolders.length && ffDiskMatchesFolderPatterns(&options->hideFolders, fs->f_mntonname, FF_DISK_FOLDER_SEPARATOR))
|
||||
if (options->hideFolders.length && ffDiskMatchesFolderPatterns(&options->hideFolders, fs->f_mntonname, FF_DISK_FOLDER_SEPARATOR)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (options->hideFS.length && ffStrbufSeparatedContainS(&options->hideFS, fs->f_fstypename, ':'))
|
||||
if (options->hideFS.length && ffStrbufSeparatedContainS(&options->hideFS, fs->f_fstypename, ':')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#ifdef __FreeBSD__
|
||||
// f_bavail and f_ffree are signed on FreeBSD...
|
||||
if(fs->f_bavail < 0) fs->f_bavail = 0;
|
||||
if(fs->f_ffree < 0) fs->f_ffree = 0;
|
||||
#endif
|
||||
if (fs->f_bavail < 0) {
|
||||
fs->f_bavail = 0;
|
||||
}
|
||||
if (fs->f_ffree < 0) {
|
||||
fs->f_ffree = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
FFDisk* disk = ffListAdd(disks);
|
||||
|
||||
disk->bytesTotal = (uint64_t)fs->f_blocks * (uint64_t)fs->f_bsize;
|
||||
disk->bytesFree = (uint64_t)fs->f_bfree * (uint64_t)fs->f_bsize;
|
||||
disk->bytesAvailable = (uint64_t)fs->f_bavail * (uint64_t)fs->f_bsize;
|
||||
disk->bytesTotal = (uint64_t) fs->f_blocks * (uint64_t) fs->f_bsize;
|
||||
disk->bytesFree = (uint64_t) fs->f_bfree * (uint64_t) fs->f_bsize;
|
||||
disk->bytesAvailable = (uint64_t) fs->f_bavail * (uint64_t) fs->f_bsize;
|
||||
disk->bytesUsed = 0; // To be filled in ./disk.c
|
||||
|
||||
disk->filesTotal = (uint32_t) fs->f_files;
|
||||
@@ -182,17 +194,19 @@ const char* ffDetectDisksImpl(FFDiskOptions* options, FFlist* disks)
|
||||
|
||||
detectFsInfo(fs, disk);
|
||||
|
||||
if(fs->f_flags & MNT_RDONLY)
|
||||
if (fs->f_flags & MNT_RDONLY) {
|
||||
disk->type |= FF_DISK_VOLUME_TYPE_READONLY_BIT;
|
||||
}
|
||||
|
||||
#ifdef __OpenBSD__
|
||||
#define st_birthtimespec __st_birthtim
|
||||
#endif
|
||||
#ifndef __DragonFly__
|
||||
#ifdef __OpenBSD__
|
||||
# define st_birthtimespec __st_birthtim
|
||||
#endif
|
||||
#ifndef __DragonFly__
|
||||
struct stat st;
|
||||
if(stat(fs->f_mntonname, &st) == 0 && st.st_birthtimespec.tv_sec > 0)
|
||||
disk->createTime = (uint64_t)(((uint64_t) st.st_birthtimespec.tv_sec * 1000) + ((uint64_t) st.st_birthtimespec.tv_nsec / 1000000));
|
||||
#endif
|
||||
if (stat(fs->f_mntonname, &st) == 0 && st.st_birthtimespec.tv_sec > 0) {
|
||||
disk->createTime = (uint64_t) (((uint64_t) st.st_birthtimespec.tv_sec * 1000) + ((uint64_t) st.st_birthtimespec.tv_nsec / 1000000));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
extern "C"
|
||||
{
|
||||
extern "C" {
|
||||
#include "disk.h"
|
||||
#include "common/stringUtils.h"
|
||||
}
|
||||
@@ -7,36 +6,40 @@ extern "C"
|
||||
#include <Directory.h>
|
||||
#include <Path.h>
|
||||
|
||||
const char* ffDetectDisksImpl(FFDiskOptions* options, FFlist* disks)
|
||||
{
|
||||
const char* ffDetectDisksImpl(FFDiskOptions* options, FFlist* disks) {
|
||||
int32 pos = 0;
|
||||
|
||||
for (dev_t dev; (dev = next_dev(&pos)) >= B_OK;)
|
||||
{
|
||||
for (dev_t dev; (dev = next_dev(&pos)) >= B_OK;) {
|
||||
fs_info fs;
|
||||
if (fs_stat_dev(dev, &fs) < 0) continue;
|
||||
if (fs_stat_dev(dev, &fs) < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
node_ref node(fs.dev, fs.root);
|
||||
BDirectory dir(&node);
|
||||
BPath path(&dir);
|
||||
if (path.InitCheck() != B_OK) continue;
|
||||
|
||||
if (__builtin_expect(options->folders.length, 0))
|
||||
{
|
||||
if (!ffStrbufSeparatedContainS(&options->folders, path.Path(), FF_DISK_FOLDER_SEPARATOR))
|
||||
continue;
|
||||
if (path.InitCheck() != B_OK) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (options->hideFolders.length && ffDiskMatchesFolderPatterns(&options->hideFolders, path.Path(), FF_DISK_FOLDER_SEPARATOR))
|
||||
continue;
|
||||
if (__builtin_expect(options->folders.length, 0)) {
|
||||
if (!ffStrbufSeparatedContainS(&options->folders, path.Path(), FF_DISK_FOLDER_SEPARATOR)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (options->hideFS.length && ffStrbufSeparatedContainS(&options->hideFS, fs.fsh_name, ':'))
|
||||
if (options->hideFolders.length && ffDiskMatchesFolderPatterns(&options->hideFolders, path.Path(), FF_DISK_FOLDER_SEPARATOR)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (options->hideFS.length && ffStrbufSeparatedContainS(&options->hideFS, fs.fsh_name, ':')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
FFDisk* disk = (FFDisk*) ffListAdd(disks);
|
||||
|
||||
disk->bytesTotal = (uint64_t)fs.total_blocks * (uint64_t) fs.block_size;
|
||||
disk->bytesFree = (uint64_t)fs.free_blocks * (uint64_t) fs.block_size;
|
||||
disk->bytesTotal = (uint64_t) fs.total_blocks * (uint64_t) fs.block_size;
|
||||
disk->bytesFree = (uint64_t) fs.free_blocks * (uint64_t) fs.block_size;
|
||||
disk->bytesAvailable = disk->bytesFree;
|
||||
disk->bytesUsed = 0; // To be filled in ./disk.c
|
||||
|
||||
@@ -48,18 +51,24 @@ const char* ffDetectDisksImpl(FFDiskOptions* options, FFlist* disks)
|
||||
ffStrbufInitS(&disk->filesystem, fs.fsh_name);
|
||||
ffStrbufInitS(&disk->name, fs.volume_name);
|
||||
disk->type = FF_DISK_VOLUME_TYPE_NONE;
|
||||
if (!(fs.flags & B_FS_IS_PERSISTENT))
|
||||
if (!(fs.flags & B_FS_IS_PERSISTENT)) {
|
||||
disk->type = (FFDiskVolumeType) (disk->type | FF_DISK_VOLUME_TYPE_HIDDEN_BIT);
|
||||
if (fs.flags & B_FS_IS_READONLY)
|
||||
}
|
||||
if (fs.flags & B_FS_IS_READONLY) {
|
||||
disk->type = (FFDiskVolumeType) (disk->type | FF_DISK_VOLUME_TYPE_READONLY_BIT);
|
||||
if (fs.flags & B_FS_IS_REMOVABLE)
|
||||
}
|
||||
if (fs.flags & B_FS_IS_REMOVABLE) {
|
||||
disk->type = (FFDiskVolumeType) (disk->type | FF_DISK_VOLUME_TYPE_EXTERNAL_BIT);
|
||||
if (disk->type == FF_DISK_VOLUME_TYPE_NONE) disk->type = FF_DISK_VOLUME_TYPE_REGULAR_BIT;
|
||||
}
|
||||
if (disk->type == FF_DISK_VOLUME_TYPE_NONE) {
|
||||
disk->type = FF_DISK_VOLUME_TYPE_REGULAR_BIT;
|
||||
}
|
||||
disk->createTime = 0;
|
||||
|
||||
time_t crTime;
|
||||
if (dir.GetCreationTime(&crTime) == B_OK)
|
||||
if (dir.GetCreationTime(&crTime) == B_OK) {
|
||||
disk->createTime = (uint64_t) crTime * 1000;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+143
-125
@@ -11,98 +11,113 @@
|
||||
#include <sys/statvfs.h>
|
||||
|
||||
#if defined(STATX_BTIME) && !defined(__ANDROID__)
|
||||
#include <sys/syscall.h>
|
||||
# include <sys/syscall.h>
|
||||
#endif
|
||||
|
||||
#ifdef __USE_LARGEFILE64
|
||||
#define stat stat64
|
||||
#define statvfs statvfs64
|
||||
#define dirent dirent64
|
||||
#define readdir readdir64
|
||||
# define stat stat64
|
||||
# define statvfs statvfs64
|
||||
# define dirent dirent64
|
||||
# define readdir readdir64
|
||||
#endif
|
||||
|
||||
static bool isPhysicalDevice(const struct mntent* device)
|
||||
{
|
||||
#ifndef __ANDROID__ //On Android, `/dev` is not accessible, so that the following checks always fail
|
||||
static bool isPhysicalDevice(const struct mntent* device) {
|
||||
#ifndef __ANDROID__ // On Android, `/dev` is not accessible, so that the following checks always fail
|
||||
|
||||
//Always show the root path
|
||||
if(ffStrEquals(device->mnt_dir, "/"))
|
||||
// Always show the root path
|
||||
if (ffStrEquals(device->mnt_dir, "/")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if(ffStrEquals(device->mnt_fsname, "none"))
|
||||
if (ffStrEquals(device->mnt_fsname, "none")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//DrvFs is a filesystem plugin to WSL that was designed to support interop between WSL and the Windows filesystem.
|
||||
if(ffStrEquals(device->mnt_type, "9p"))
|
||||
// DrvFs is a filesystem plugin to WSL that was designed to support interop between WSL and the Windows filesystem.
|
||||
if (ffStrEquals(device->mnt_type, "9p")) {
|
||||
return ffStrContains(device->mnt_opts, "aname=drvfs");
|
||||
}
|
||||
|
||||
//ZFS pool
|
||||
if(ffStrEquals(device->mnt_type, "zfs"))
|
||||
// ZFS pool
|
||||
if (ffStrEquals(device->mnt_type, "zfs")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//sshfs
|
||||
if(ffStrEquals(device->mnt_type, "fuse.sshfs"))
|
||||
// sshfs
|
||||
if (ffStrEquals(device->mnt_type, "fuse.sshfs")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//Pseudo filesystems don't have a device in /dev
|
||||
if(!ffStrStartsWith(device->mnt_fsname, "/dev/"))
|
||||
// Pseudo filesystems don't have a device in /dev
|
||||
if (!ffStrStartsWith(device->mnt_fsname, "/dev/")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//#731
|
||||
if(ffStrEquals(device->mnt_type, "bcachefs"))
|
||||
// #731
|
||||
if (ffStrEquals(device->mnt_type, "bcachefs")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if(
|
||||
ffStrStartsWith(device->mnt_fsname + 5, "loop") || //Ignore loop devices
|
||||
ffStrStartsWith(device->mnt_fsname + 5, "ram") || //Ignore ram devices
|
||||
ffStrStartsWith(device->mnt_fsname + 5, "fd") //Ignore fd devices
|
||||
) return false;
|
||||
|
||||
if (ffStrStartsWith(device->mnt_dir, "/bedrock/")) // Ignore Bedrock Linux subvolumes
|
||||
if (
|
||||
ffStrStartsWith(device->mnt_fsname + 5, "loop") || // Ignore loop devices
|
||||
ffStrStartsWith(device->mnt_fsname + 5, "ram") || // Ignore ram devices
|
||||
ffStrStartsWith(device->mnt_fsname + 5, "fd") // Ignore fd devices
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ffStrStartsWith(device->mnt_dir, "/bedrock/")) { // Ignore Bedrock Linux subvolumes
|
||||
return false;
|
||||
}
|
||||
|
||||
struct stat deviceStat;
|
||||
if(stat(device->mnt_fsname, &deviceStat) != 0)
|
||||
if (stat(device->mnt_fsname, &deviceStat) != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//Ignore all devices that are not block devices
|
||||
if(!S_ISBLK(deviceStat.st_mode))
|
||||
// Ignore all devices that are not block devices
|
||||
if (!S_ISBLK(deviceStat.st_mode)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#else
|
||||
#else
|
||||
|
||||
//Pseudo filesystems don't have a device in /dev
|
||||
if(!ffStrStartsWith(device->mnt_fsname, "/dev/"))
|
||||
// Pseudo filesystems don't have a device in /dev
|
||||
if (!ffStrStartsWith(device->mnt_fsname, "/dev/")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(
|
||||
ffStrStartsWith(device->mnt_fsname + 5, "loop") || //Ignore loop devices
|
||||
ffStrStartsWith(device->mnt_fsname + 5, "ram") || //Ignore ram devices
|
||||
ffStrStartsWith(device->mnt_fsname + 5, "fd") //Ignore fd devices
|
||||
) return false;
|
||||
if (
|
||||
ffStrStartsWith(device->mnt_fsname + 5, "loop") || // Ignore loop devices
|
||||
ffStrStartsWith(device->mnt_fsname + 5, "ram") || // Ignore ram devices
|
||||
ffStrStartsWith(device->mnt_fsname + 5, "fd") // Ignore fd devices
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// https://source.android.com/docs/core/ota/apex?hl=zh-cn
|
||||
if(ffStrStartsWith(device->mnt_dir, "/apex/"))
|
||||
if (ffStrStartsWith(device->mnt_dir, "/apex/")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif // __ANDROID__
|
||||
#endif // __ANDROID__
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void detectNameFromPath(FFDisk* disk, const struct stat* deviceStat, FFstrbuf* basePath)
|
||||
{
|
||||
static void detectNameFromPath(FFDisk* disk, const struct stat* deviceStat, FFstrbuf* basePath) {
|
||||
FF_AUTO_CLOSE_DIR DIR* dir = opendir(basePath->chars);
|
||||
if(dir == NULL)
|
||||
if (dir == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t basePathLength = basePath->length;
|
||||
|
||||
struct dirent* entry;
|
||||
while((entry = readdir(dir)) != NULL)
|
||||
{
|
||||
if(entry->d_name[0] == '.')
|
||||
while ((entry = readdir(dir)) != NULL) {
|
||||
if (entry->d_name[0] == '.') {
|
||||
continue;
|
||||
}
|
||||
|
||||
ffStrbufAppendS(basePath, entry->d_name);
|
||||
|
||||
@@ -111,205 +126,208 @@ static void detectNameFromPath(FFDisk* disk, const struct stat* deviceStat, FFst
|
||||
|
||||
ffStrbufSubstrBefore(basePath, basePathLength);
|
||||
|
||||
if(!ret || deviceStat->st_ino != entryStat.st_ino)
|
||||
if (!ret || deviceStat->st_ino != entryStat.st_ino) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ffStrbufAppendS(&disk->name, entry->d_name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void detectName(FFDisk* disk)
|
||||
{
|
||||
static void detectName(FFDisk* disk) {
|
||||
struct stat deviceStat;
|
||||
if(stat(disk->mountFrom.chars, &deviceStat) != 0)
|
||||
if (stat(disk->mountFrom.chars, &deviceStat) != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY basePath = ffStrbufCreate();
|
||||
|
||||
//Try label first
|
||||
// Try label first
|
||||
ffStrbufSetS(&basePath, "/dev/disk/by-label/");
|
||||
detectNameFromPath(disk, &deviceStat, &basePath);
|
||||
|
||||
if(disk->name.length == 0)
|
||||
{
|
||||
//Try partlabel second
|
||||
if (disk->name.length == 0) {
|
||||
// Try partlabel second
|
||||
ffStrbufSetS(&basePath, "/dev/disk/by-partlabel/");
|
||||
detectNameFromPath(disk, &deviceStat, &basePath);
|
||||
}
|
||||
|
||||
if (disk->name.length == 0) return;
|
||||
if (disk->name.length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
ffStrbufDecodeHexEscapeSequences(&disk->name);
|
||||
}
|
||||
|
||||
#ifdef __ANDROID__
|
||||
|
||||
static void detectType(FF_MAYBE_UNUSED const FFlist* disks, FFDisk* currentDisk, FF_MAYBE_UNUSED struct mntent* device)
|
||||
{
|
||||
if(ffStrbufEqualS(¤tDisk->mountpoint, "/") || ffStrbufEqualS(¤tDisk->mountpoint, "/storage/emulated"))
|
||||
static void detectType(FF_MAYBE_UNUSED const FFlist* disks, FFDisk* currentDisk, FF_MAYBE_UNUSED struct mntent* device) {
|
||||
if (ffStrbufEqualS(¤tDisk->mountpoint, "/") || ffStrbufEqualS(¤tDisk->mountpoint, "/storage/emulated")) {
|
||||
currentDisk->type = FF_DISK_VOLUME_TYPE_REGULAR_BIT;
|
||||
else if(ffStrbufStartsWithS(¤tDisk->mountpoint, "/mnt/media_rw/"))
|
||||
} else if (ffStrbufStartsWithS(¤tDisk->mountpoint, "/mnt/media_rw/")) {
|
||||
currentDisk->type = FF_DISK_VOLUME_TYPE_EXTERNAL_BIT;
|
||||
else
|
||||
} else {
|
||||
currentDisk->type = FF_DISK_VOLUME_TYPE_HIDDEN_BIT;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static bool isSubvolume(const FFlist* disks, FFDisk* currentDisk)
|
||||
{
|
||||
if(ffStrbufEqualS(¤tDisk->mountFrom, "drvfs")) // WSL Windows drives
|
||||
static bool isSubvolume(const FFlist* disks, FFDisk* currentDisk) {
|
||||
if (ffStrbufEqualS(¤tDisk->mountFrom, "drvfs")) { // WSL Windows drives
|
||||
return false;
|
||||
}
|
||||
|
||||
if(ffStrbufEqualS(¤tDisk->filesystem, "zfs"))
|
||||
{
|
||||
//ZFS subvolumes
|
||||
if (ffStrbufEqualS(¤tDisk->filesystem, "zfs")) {
|
||||
// ZFS subvolumes
|
||||
uint32_t index = ffStrbufFirstIndexC(¤tDisk->mountFrom, '/');
|
||||
if (index == currentDisk->mountFrom.length)
|
||||
if (index == currentDisk->mountFrom.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY zpoolName = ffStrbufCreateNS(index, currentDisk->mountFrom.chars);
|
||||
for(uint32_t i = 0; i < disks->length - 1; i++)
|
||||
{
|
||||
for (uint32_t i = 0; i < disks->length - 1; i++) {
|
||||
const FFDisk* otherDevice = FF_LIST_GET(FFDisk, *disks, i);
|
||||
if(ffStrbufEqualS(&otherDevice->filesystem, "zfs") && ffStrbufStartsWith(&otherDevice->mountFrom, &zpoolName))
|
||||
if (ffStrbufEqualS(&otherDevice->filesystem, "zfs") && ffStrbufStartsWith(&otherDevice->mountFrom, &zpoolName)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
//Filter all disks which device was already found. This catches BTRFS subvolumes.
|
||||
for(uint32_t i = 0; i < disks->length - 1; i++)
|
||||
{
|
||||
} else {
|
||||
// Filter all disks which device was already found. This catches BTRFS subvolumes.
|
||||
for (uint32_t i = 0; i < disks->length - 1; i++) {
|
||||
const FFDisk* otherDevice = FF_LIST_GET(FFDisk, *disks, i);
|
||||
|
||||
if(ffStrbufEqual(¤tDisk->mountFrom, &otherDevice->mountFrom))
|
||||
if (ffStrbufEqual(¤tDisk->mountFrom, &otherDevice->mountFrom)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool isRemovable(FFDisk* currentDisk)
|
||||
{
|
||||
if (!ffStrbufStartsWithS(¤tDisk->mountFrom, "/dev/"))
|
||||
static bool isRemovable(FFDisk* currentDisk) {
|
||||
if (!ffStrbufStartsWithS(¤tDisk->mountFrom, "/dev/")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
char sysBlockPartition[64];
|
||||
snprintf(sysBlockPartition, ARRAY_SIZE(sysBlockPartition), "/sys/class/block/%s", currentDisk->mountFrom.chars + strlen("/dev/"));
|
||||
|
||||
char sysBlockVolume[PATH_MAX]; // /sys/devices/pci0000:00/0000:00:14.0/usb4/4-3/4-3:1.0/host0/target0:0:0/0:0:0:0/block/sda/sda1
|
||||
if (realpath(sysBlockPartition, sysBlockVolume) == NULL)
|
||||
if (realpath(sysBlockPartition, sysBlockVolume) == NULL) {
|
||||
return false;
|
||||
}
|
||||
char* lastSlash = strrchr(sysBlockVolume, '/');
|
||||
if (lastSlash == NULL)
|
||||
if (lastSlash == NULL) {
|
||||
return false;
|
||||
}
|
||||
strcpy(lastSlash + 1, "removable");
|
||||
|
||||
char removableChar = '0';
|
||||
return ffReadFileData(sysBlockVolume, 1, &removableChar) > 0 && removableChar == '1';
|
||||
}
|
||||
|
||||
static void detectType(const FFlist* disks, FFDisk* currentDisk, struct mntent* device)
|
||||
{
|
||||
if(hasmntopt(device, "x-gvfs-hide") || hasmntopt(device, "hidden"))
|
||||
static void detectType(const FFlist* disks, FFDisk* currentDisk, struct mntent* device) {
|
||||
if (hasmntopt(device, "x-gvfs-hide") || hasmntopt(device, "hidden")) {
|
||||
currentDisk->type = FF_DISK_VOLUME_TYPE_HIDDEN_BIT;
|
||||
else if(isSubvolume(disks, currentDisk))
|
||||
} else if (isSubvolume(disks, currentDisk)) {
|
||||
currentDisk->type = FF_DISK_VOLUME_TYPE_SUBVOLUME_BIT;
|
||||
else if(isRemovable(currentDisk))
|
||||
} else if (isRemovable(currentDisk)) {
|
||||
currentDisk->type = FF_DISK_VOLUME_TYPE_EXTERNAL_BIT;
|
||||
else
|
||||
} else {
|
||||
currentDisk->type = FF_DISK_VOLUME_TYPE_REGULAR_BIT;
|
||||
if (hasmntopt(device, MNTOPT_RO))
|
||||
}
|
||||
if (hasmntopt(device, MNTOPT_RO)) {
|
||||
currentDisk->type |= FF_DISK_VOLUME_TYPE_READONLY_BIT;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void detectStats(FFDisk* disk)
|
||||
{
|
||||
static void detectStats(FFDisk* disk) {
|
||||
struct statvfs fs;
|
||||
if(statvfs(disk->mountpoint.chars, &fs) != 0)
|
||||
memset(&fs, 0, sizeof(fs)); //Set all values to 0, so our values get initialized to 0 too
|
||||
if (statvfs(disk->mountpoint.chars, &fs) != 0) {
|
||||
memset(&fs, 0, sizeof(fs)); // Set all values to 0, so our values get initialized to 0 too
|
||||
}
|
||||
|
||||
disk->bytesTotal = fs.f_blocks * (uint64_t) fs.f_frsize;
|
||||
disk->bytesFree = fs.f_bfree * (uint64_t) fs.f_frsize;
|
||||
disk->bytesAvailable = fs.f_bavail * (uint64_t) fs.f_frsize;
|
||||
disk->bytesUsed = 0; // To be filled in ./disk.c
|
||||
|
||||
if (fs.f_files >= fs.f_ffree)
|
||||
{
|
||||
if (fs.f_files >= fs.f_ffree) {
|
||||
disk->filesTotal = (uint32_t) fs.f_files;
|
||||
disk->filesUsed = (uint32_t) (disk->filesTotal - fs.f_ffree);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// Windows filesystem in WSL
|
||||
disk->filesTotal = disk->filesUsed = 0;
|
||||
}
|
||||
|
||||
disk->createTime = 0;
|
||||
#ifdef SYS_statx
|
||||
#ifdef SYS_statx
|
||||
struct statx stx;
|
||||
if (syscall(SYS_statx, 0, disk->mountpoint.chars, 0, STATX_BTIME, &stx) == 0 && (stx.stx_mask & STATX_BTIME) && stx.stx_btime.tv_sec > 685065600 /*birth of Linux*/)
|
||||
disk->createTime = (uint64_t)((stx.stx_btime.tv_sec * 1000) + (stx.stx_btime.tv_nsec / 1000000));
|
||||
#endif
|
||||
if (syscall(SYS_statx, 0, disk->mountpoint.chars, 0, STATX_BTIME, &stx) == 0 && (stx.stx_mask & STATX_BTIME) && stx.stx_btime.tv_sec > 685065600 /*birth of Linux*/) {
|
||||
disk->createTime = (uint64_t) ((stx.stx_btime.tv_sec * 1000) + (stx.stx_btime.tv_nsec / 1000000));
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __ANDROID__ // hasmntopt requires a higher Android API level
|
||||
if(fs.f_flag & ST_RDONLY)
|
||||
#ifdef __ANDROID__ // hasmntopt requires a higher Android API level
|
||||
if (fs.f_flag & ST_RDONLY) {
|
||||
disk->type |= FF_DISK_VOLUME_TYPE_READONLY_BIT;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
const char* ffDetectDisksImpl(FFDiskOptions* options, FFlist* disks)
|
||||
{
|
||||
const char* ffDetectDisksImpl(FFDiskOptions* options, FFlist* disks) {
|
||||
FILE* mountsFile = setmntent("/proc/mounts", "r");
|
||||
if(mountsFile == NULL)
|
||||
if (mountsFile == NULL) {
|
||||
return "setmntent(\"/proc/mounts\", \"r\") == NULL";
|
||||
}
|
||||
|
||||
struct mntent* device;
|
||||
|
||||
while((device = getmntent(mountsFile)))
|
||||
{
|
||||
if (__builtin_expect(options->folders.length > 0, false))
|
||||
{
|
||||
if (!ffStrbufSeparatedContainS(&options->folders, device->mnt_dir, FF_DISK_FOLDER_SEPARATOR))
|
||||
while ((device = getmntent(mountsFile))) {
|
||||
if (__builtin_expect(options->folders.length > 0, false)) {
|
||||
if (!ffStrbufSeparatedContainS(&options->folders, device->mnt_dir, FF_DISK_FOLDER_SEPARATOR)) {
|
||||
continue;
|
||||
}
|
||||
} else if (!isPhysicalDevice(device)) {
|
||||
continue;
|
||||
}
|
||||
else if(!isPhysicalDevice(device))
|
||||
continue;
|
||||
|
||||
if (options->hideFolders.length && ffDiskMatchesFolderPatterns(&options->hideFolders, device->mnt_dir, FF_DISK_FOLDER_SEPARATOR))
|
||||
if (options->hideFolders.length && ffDiskMatchesFolderPatterns(&options->hideFolders, device->mnt_dir, FF_DISK_FOLDER_SEPARATOR)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (options->hideFS.length && ffStrbufSeparatedContainS(&options->hideFS, device->mnt_type, ':'))
|
||||
if (options->hideFS.length && ffStrbufSeparatedContainS(&options->hideFS, device->mnt_type, ':')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
//We have a valid device, add it to the list
|
||||
// We have a valid device, add it to the list
|
||||
FFDisk* disk = ffListAdd(disks);
|
||||
disk->type = FF_DISK_VOLUME_TYPE_NONE;
|
||||
|
||||
//detect mountFrom
|
||||
// detect mountFrom
|
||||
ffStrbufInitS(&disk->mountFrom, device->mnt_fsname);
|
||||
|
||||
//detect mountpoint
|
||||
// detect mountpoint
|
||||
ffStrbufInitS(&disk->mountpoint, device->mnt_dir);
|
||||
|
||||
//detect filesystem
|
||||
// detect filesystem
|
||||
ffStrbufInitS(&disk->filesystem, device->mnt_type);
|
||||
|
||||
//detect name
|
||||
// detect name
|
||||
ffStrbufInit(&disk->name);
|
||||
detectName(disk); // Also detects external devices
|
||||
|
||||
//detect type
|
||||
// detect type
|
||||
detectType(disks, disk, device);
|
||||
|
||||
//Detects stats
|
||||
// Detects stats
|
||||
detectStats(disk);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include "disk.h"
|
||||
|
||||
const char* ffDetectDisksImpl(FF_MAYBE_UNUSED FFDiskOptions* options, FF_MAYBE_UNUSED FFlist* disks)
|
||||
{
|
||||
const char* ffDetectDisksImpl(FF_MAYBE_UNUSED FFDiskOptions* options, FF_MAYBE_UNUSED FFlist* disks) {
|
||||
return "Not supported on this platform";
|
||||
}
|
||||
|
||||
@@ -8,85 +8,88 @@
|
||||
#include <sys/mount.h>
|
||||
#include <sys/mnttab.h>
|
||||
|
||||
static bool isPhysicalDevice(const struct mnttab* device)
|
||||
{
|
||||
//Always show the root path
|
||||
if(ffStrEquals(device->mnt_mountp, "/"))
|
||||
static bool isPhysicalDevice(const struct mnttab* device) {
|
||||
// Always show the root path
|
||||
if (ffStrEquals(device->mnt_mountp, "/")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if(ffStrEquals(device->mnt_special, "none"))
|
||||
if (ffStrEquals(device->mnt_special, "none")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//ZFS pool
|
||||
if(ffStrEquals(device->mnt_fstype, "zfs"))
|
||||
// ZFS pool
|
||||
if (ffStrEquals(device->mnt_fstype, "zfs")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//Pseudo filesystems don't have a device in /dev
|
||||
if(!ffStrStartsWith(device->mnt_special, "/dev/"))
|
||||
// Pseudo filesystems don't have a device in /dev
|
||||
if (!ffStrStartsWith(device->mnt_special, "/dev/")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
struct stat deviceStat;
|
||||
if(stat(device->mnt_special, &deviceStat) != 0)
|
||||
if (stat(device->mnt_special, &deviceStat) != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//Ignore all devices that are not block devices
|
||||
if(!S_ISBLK(deviceStat.st_mode))
|
||||
// Ignore all devices that are not block devices
|
||||
if (!S_ISBLK(deviceStat.st_mode)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool isSubvolume(const FFlist* disks, FFDisk* currentDisk)
|
||||
{
|
||||
if(ffStrbufEqualS(¤tDisk->filesystem, "zfs"))
|
||||
{
|
||||
//ZFS subvolumes
|
||||
static bool isSubvolume(const FFlist* disks, FFDisk* currentDisk) {
|
||||
if (ffStrbufEqualS(¤tDisk->filesystem, "zfs")) {
|
||||
// ZFS subvolumes
|
||||
uint32_t index = ffStrbufFirstIndexC(¤tDisk->mountFrom, '/');
|
||||
if (index == currentDisk->mountFrom.length)
|
||||
if (index == currentDisk->mountFrom.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY zpoolName = ffStrbufCreateNS(index, currentDisk->mountFrom.chars);
|
||||
for(uint32_t i = 0; i < disks->length - 1; i++)
|
||||
{
|
||||
for (uint32_t i = 0; i < disks->length - 1; i++) {
|
||||
const FFDisk* otherDevice = FF_LIST_GET(FFDisk, *disks, i);
|
||||
if(ffStrbufEqualS(&otherDevice->filesystem, "zfs") && ffStrbufStartsWith(&otherDevice->mountFrom, &zpoolName))
|
||||
if (ffStrbufEqualS(&otherDevice->filesystem, "zfs") && ffStrbufStartsWith(&otherDevice->mountFrom, &zpoolName)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
//Filter all disks which device was already found. This catches BTRFS subvolumes.
|
||||
for(uint32_t i = 0; i < disks->length - 1; i++)
|
||||
{
|
||||
} else {
|
||||
// Filter all disks which device was already found. This catches BTRFS subvolumes.
|
||||
for (uint32_t i = 0; i < disks->length - 1; i++) {
|
||||
const FFDisk* otherDevice = FF_LIST_GET(FFDisk, *disks, i);
|
||||
|
||||
if(ffStrbufEqual(¤tDisk->mountFrom, &otherDevice->mountFrom))
|
||||
if (ffStrbufEqual(¤tDisk->mountFrom, &otherDevice->mountFrom)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void detectType(const FFlist* disks, FFDisk* currentDisk, struct mnttab* device)
|
||||
{
|
||||
if(hasmntopt(device, MNTOPT_NOBROWSE))
|
||||
static void detectType(const FFlist* disks, FFDisk* currentDisk, struct mnttab* device) {
|
||||
if (hasmntopt(device, MNTOPT_NOBROWSE)) {
|
||||
currentDisk->type = FF_DISK_VOLUME_TYPE_HIDDEN_BIT;
|
||||
else if(isSubvolume(disks, currentDisk))
|
||||
} else if (isSubvolume(disks, currentDisk)) {
|
||||
currentDisk->type = FF_DISK_VOLUME_TYPE_SUBVOLUME_BIT;
|
||||
else
|
||||
} else {
|
||||
currentDisk->type = FF_DISK_VOLUME_TYPE_REGULAR_BIT;
|
||||
if (hasmntopt(device, MNTOPT_RO))
|
||||
}
|
||||
if (hasmntopt(device, MNTOPT_RO)) {
|
||||
currentDisk->type |= FF_DISK_VOLUME_TYPE_READONLY_BIT;
|
||||
}
|
||||
}
|
||||
|
||||
static void detectStats(FFDisk* disk)
|
||||
{
|
||||
static void detectStats(FFDisk* disk) {
|
||||
struct statvfs fs;
|
||||
if(statvfs(disk->mountpoint.chars, &fs) != 0)
|
||||
if (statvfs(disk->mountpoint.chars, &fs) != 0) {
|
||||
memset(&fs, 0, sizeof(fs));
|
||||
}
|
||||
|
||||
disk->bytesTotal = fs.f_blocks * fs.f_frsize;
|
||||
disk->bytesFree = fs.f_bfree * fs.f_frsize;
|
||||
@@ -101,31 +104,32 @@ static void detectStats(FFDisk* disk)
|
||||
disk->createTime = 0;
|
||||
}
|
||||
|
||||
const char* ffDetectDisksImpl(FFDiskOptions* options, FFlist* disks)
|
||||
{
|
||||
const char* ffDetectDisksImpl(FFDiskOptions* options, FFlist* disks) {
|
||||
FF_AUTO_CLOSE_FILE FILE* mountsFile = fopen(MNTTAB, "r");
|
||||
if(mountsFile == NULL)
|
||||
if (mountsFile == NULL) {
|
||||
return "fopen(\"" MNTTAB "\", \"r\") == NULL";
|
||||
}
|
||||
|
||||
struct mnttab device;
|
||||
|
||||
while (getmntent(mountsFile, &device) == 0)
|
||||
{
|
||||
if (__builtin_expect(options->folders.length, 0))
|
||||
{
|
||||
if (!ffStrbufSeparatedContainS(&options->folders, device.mnt_mountp, FF_DISK_FOLDER_SEPARATOR))
|
||||
while (getmntent(mountsFile, &device) == 0) {
|
||||
if (__builtin_expect(options->folders.length, 0)) {
|
||||
if (!ffStrbufSeparatedContainS(&options->folders, device.mnt_mountp, FF_DISK_FOLDER_SEPARATOR)) {
|
||||
continue;
|
||||
}
|
||||
} else if (!isPhysicalDevice(&device)) {
|
||||
continue;
|
||||
}
|
||||
else if(!isPhysicalDevice(&device))
|
||||
continue;
|
||||
|
||||
if (options->hideFolders.length && ffDiskMatchesFolderPatterns(&options->hideFolders, device.mnt_mountp, FF_DISK_FOLDER_SEPARATOR))
|
||||
if (options->hideFolders.length && ffDiskMatchesFolderPatterns(&options->hideFolders, device.mnt_mountp, FF_DISK_FOLDER_SEPARATOR)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (options->hideFS.length && ffStrbufSeparatedContainS(&options->hideFS, device.mnt_fstype, ':'))
|
||||
if (options->hideFS.length && ffStrbufSeparatedContainS(&options->hideFS, device.mnt_fstype, ':')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
//We have a valid device, add it to the list
|
||||
// We have a valid device, add it to the list
|
||||
FFDisk* disk = ffListAdd(disks);
|
||||
disk->type = FF_DISK_VOLUME_TYPE_NONE;
|
||||
ffStrbufInitS(&disk->mountFrom, device.mnt_special);
|
||||
|
||||
@@ -9,16 +9,15 @@
|
||||
#include <ntstatus.h>
|
||||
#include <stdalign.h>
|
||||
|
||||
const char* ffDetectDisksImpl(FFDiskOptions* options, FFlist* disks)
|
||||
{
|
||||
const char* ffDetectDisksImpl(FFDiskOptions* options, FFlist* disks) {
|
||||
PROCESS_DEVICEMAP_INFORMATION_EX info = {};
|
||||
ULONG size = 0;
|
||||
if(!NT_SUCCESS(NtQueryInformationProcess(NtCurrentProcess(), ProcessDeviceMap, &info, sizeof(info), &size)))
|
||||
if (!NT_SUCCESS(NtQueryInformationProcess(NtCurrentProcess(), ProcessDeviceMap, &info, sizeof(info), &size))) {
|
||||
return "NtQueryInformationProcess(ProcessDeviceMap) failed";
|
||||
}
|
||||
|
||||
// For cross-platform portability; used by `presets/examples/13.jsonc`
|
||||
if (options->folders.length == 1 && options->folders.chars[0] == '/')
|
||||
{
|
||||
if (options->folders.length == 1 && options->folders.chars[0] == '/') {
|
||||
options->folders.chars[0] = (char) SharedUserData->NtSystemRoot[0];
|
||||
ffStrbufAppendS(&options->folders, ":\\");
|
||||
}
|
||||
@@ -26,29 +25,31 @@ const char* ffDetectDisksImpl(FFDiskOptions* options, FFlist* disks)
|
||||
wchar_t mountpointW[] = L"X:\\";
|
||||
char mountpointA[] = "X:\\";
|
||||
|
||||
for (wchar_t i = L'A'; i <= L'Z'; i++)
|
||||
{
|
||||
if (!(info.Query.DriveMap & (1 << (i - L'A'))))
|
||||
for (wchar_t i = L'A'; i <= L'Z'; i++) {
|
||||
if (!(info.Query.DriveMap & (1 << (i - L'A')))) {
|
||||
continue;
|
||||
}
|
||||
mountpointW[0] = i;
|
||||
mountpointA[0] = (char) i;
|
||||
|
||||
UINT driveType = info.Query.DriveType[i - L'A'];
|
||||
|
||||
if (__builtin_expect((long) options->folders.length, 0))
|
||||
{
|
||||
if (!ffStrbufSeparatedContainNS(&options->folders, 3, mountpointA, FF_DISK_FOLDER_SEPARATOR))
|
||||
if (__builtin_expect((long) options->folders.length, 0)) {
|
||||
if (!ffStrbufSeparatedContainNS(&options->folders, 3, mountpointA, FF_DISK_FOLDER_SEPARATOR)) {
|
||||
continue;
|
||||
}
|
||||
} else if (driveType == DRIVE_NO_ROOT_DIR) {
|
||||
continue;
|
||||
}
|
||||
else if(driveType == DRIVE_NO_ROOT_DIR)
|
||||
continue;
|
||||
|
||||
if (options->hideFolders.length && ffStrbufSeparatedContainNS(&options->hideFolders, 3, mountpointA, FF_DISK_FOLDER_SEPARATOR))
|
||||
if (options->hideFolders.length && ffStrbufSeparatedContainNS(&options->hideFolders, 3, mountpointA, FF_DISK_FOLDER_SEPARATOR)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
FF_AUTO_CLOSE_FD HANDLE handle = CreateFileW(mountpointW, FILE_READ_ATTRIBUTES, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
|
||||
if (handle == INVALID_HANDLE_VALUE)
|
||||
if (handle == INVALID_HANDLE_VALUE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
IO_STATUS_BLOCK iosb;
|
||||
|
||||
@@ -58,11 +59,11 @@ const char* ffDetectDisksImpl(FFDiskOptions* options, FFlist* disks)
|
||||
: NULL;
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY diskFileSystemBuf = ffStrbufCreate();
|
||||
if (fsAttr)
|
||||
{
|
||||
if (fsAttr) {
|
||||
ffStrbufSetNWS(&diskFileSystemBuf, fsAttr->FileSystemNameLength / sizeof(WCHAR), fsAttr->FileSystemName);
|
||||
if (options->hideFS.length && ffStrbufSeparatedContain(&options->hideFS, &diskFileSystemBuf, ':'))
|
||||
if (options->hideFS.length && ffStrbufSeparatedContain(&options->hideFS, &diskFileSystemBuf, ':')) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
FFDisk* disk = ffListAdd(disks);
|
||||
@@ -81,14 +82,15 @@ const char* ffDetectDisksImpl(FFDiskOptions* options, FFlist* disks)
|
||||
disk->type = driveType == DRIVE_REMOVABLE || driveType == DRIVE_REMOTE || driveType == DRIVE_CDROM
|
||||
? FF_DISK_VOLUME_TYPE_EXTERNAL_BIT
|
||||
: driveType == DRIVE_FIXED
|
||||
? FF_DISK_VOLUME_TYPE_REGULAR_BIT
|
||||
: FF_DISK_VOLUME_TYPE_HIDDEN_BIT;
|
||||
? FF_DISK_VOLUME_TYPE_REGULAR_BIT
|
||||
: FF_DISK_VOLUME_TYPE_HIDDEN_BIT;
|
||||
|
||||
{
|
||||
wchar_t volumeName[MAX_PATH + 1];
|
||||
mountpointW[2] = L'\0';
|
||||
if(QueryDosDeviceW(mountpointW, volumeName, ARRAY_SIZE(volumeName)))
|
||||
if (QueryDosDeviceW(mountpointW, volumeName, ARRAY_SIZE(volumeName))) {
|
||||
ffStrbufSetWS(&disk->mountFrom, volumeName);
|
||||
}
|
||||
mountpointW[2] = L'\\';
|
||||
}
|
||||
|
||||
@@ -97,24 +99,24 @@ const char* ffDetectDisksImpl(FFDiskOptions* options, FFlist* disks)
|
||||
? (FILE_FS_VOLUME_INFORMATION*) bufFsVolume
|
||||
: NULL;
|
||||
|
||||
if (fsVolume)
|
||||
{
|
||||
if (fsVolume->VolumeLabelLength > 0)
|
||||
if (fsVolume) {
|
||||
if (fsVolume->VolumeLabelLength > 0) {
|
||||
ffStrbufSetNWS(&disk->name, fsVolume->VolumeLabelLength / sizeof(WCHAR), fsVolume->VolumeLabel);
|
||||
if (fsVolume->VolumeCreationTime.QuadPart)
|
||||
}
|
||||
if (fsVolume->VolumeCreationTime.QuadPart) {
|
||||
disk->createTime = ffFileTimeToUnixMs((uint64_t) fsVolume->VolumeCreationTime.QuadPart);
|
||||
}
|
||||
}
|
||||
|
||||
if (fsAttr)
|
||||
{
|
||||
if (fsAttr) {
|
||||
ffStrbufInitMove(&disk->filesystem, &diskFileSystemBuf);
|
||||
if(fsAttr->FileSystemAttributes & FILE_READ_ONLY_VOLUME)
|
||||
if (fsAttr->FileSystemAttributes & FILE_READ_ONLY_VOLUME) {
|
||||
disk->type |= FF_DISK_VOLUME_TYPE_READONLY_BIT;
|
||||
}
|
||||
}
|
||||
|
||||
FILE_FS_FULL_SIZE_INFORMATION fsFullSize;
|
||||
if (NT_SUCCESS(NtQueryVolumeInformationFile(handle, &iosb, &fsFullSize, sizeof(fsFullSize), FileFsFullSizeInformation)))
|
||||
{
|
||||
if (NT_SUCCESS(NtQueryVolumeInformationFile(handle, &iosb, &fsFullSize, sizeof(fsFullSize), FileFsFullSizeInformation))) {
|
||||
uint64_t units = fsFullSize.BytesPerSector * fsFullSize.SectorsPerAllocationUnit;
|
||||
disk->bytesTotal = (uint64_t) fsFullSize.TotalAllocationUnits.QuadPart * units;
|
||||
disk->bytesFree = (uint64_t) fsFullSize.ActualAvailableAllocationUnits.QuadPart * units;
|
||||
|
||||
Reference in New Issue
Block a user