diff --git a/CMakeLists.txt b/CMakeLists.txt
index d59a68ecf..79e059926 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -302,6 +302,7 @@ endif()
if(BSD OR APPLE)
list(APPEND LIBFASTFETCH_SRC
src/common/sysctl.c
+ src/detection/disk/disk_bsd.c
src/detection/uptime/uptime_bsd.c
src/detection/processes/processes_bsd.c
)
@@ -310,6 +311,8 @@ endif()
if(LINUX OR ANDROID)
list(APPEND LIBFASTFETCH_SRC
src/detection/cpu/cpu_linux.c
+ src/detection/cpuUsage/cpuUsage_linux.c
+ src/detection/disk/disk_linux.c
src/detection/memory/memory_linux.c
src/detection/processes/processes_linux.c
src/detection/swap/swap_linux.c
@@ -319,8 +322,6 @@ endif()
if(LINUX OR ANDROID OR BSD)
list(APPEND LIBFASTFETCH_SRC
- src/detection/cpuUsage/cpuUsage_linux.c
- src/detection/disk/disk_linux.c
src/detection/temps/temps_linux.c
src/detection/opengl/opengl_linux.c
src/detection/packages/packages_linux.c
@@ -331,12 +332,8 @@ endif()
if(LINUX OR BSD)
list(APPEND LIBFASTFETCH_SRC
- src/detection/host/host_linux.c
- src/detection/bios/bios_linux.c
- src/detection/board/board_linux.c
src/detection/os/os_linux.c
src/detection/gpu/gpu_linux.c
- src/detection/battery/battery_linux.c
src/detection/displayserver/linux/displayserver_linux.c
src/detection/displayserver/linux/wayland.c
src/detection/displayserver/linux/xcb.c
@@ -351,6 +348,15 @@ if(LINUX OR BSD)
)
endif()
+if(LINUX)
+ list(APPEND LIBFASTFETCH_SRC
+ src/detection/host/host_linux.c
+ src/detection/bios/bios_linux.c
+ src/detection/board/board_linux.c
+ src/detection/battery/battery_linux.c
+ )
+endif()
+
if(WIN32)
list(APPEND LIBFASTFETCH_SRC
src/common/processing_windows.c
@@ -418,8 +424,14 @@ endif()
if(BSD)
list(APPEND LIBFASTFETCH_SRC
src/detection/cpu/cpu_bsd.c
+ src/detection/cpuUsage/cpuUsage_bsd.c
src/detection/memory/memory_bsd.c
src/detection/swap/swap_bsd.c
+ src/detection/host/host_bsd.c
+
+ src/detection/battery/battery_nosupport.c
+ src/detection/bios/bios_nosupport.c
+ src/detection/board/board_nosupport.c
)
endif()
diff --git a/README.md b/README.md
index df0d96a52..52f99c321 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# Fastfetch
-Fastfetch is a [neofetch](https://github.com/dylanaraps/neofetch)-like tool for fetching system information and displaying them in a pretty way. It is written in pure c, with performance and customizability in mind. Currently Linux, Android, BSD, MacOS and Windows are supported.
+Fastfetch is a [neofetch](https://github.com/dylanaraps/neofetch)-like tool for fetching system information and displaying them in a pretty way. It is written in pure c, with performance and customizability in mind. Currently Linux, Android, FreeBSD, MacOS and Windows are supported.
@@ -26,7 +26,7 @@ Fastfetch dynamically loads needed libraries if they are available. On Linux, it
The following libraries are used if present at runtime:
-### Linux and BSD
+### Linux and FreeBSD
* [`libpci`](https://github.com/pciutils/pciutils): GPU output.
* [`libvulkan`](https://www.vulkan.org/): Vulkan module & fallback for GPU output.
@@ -48,7 +48,7 @@ The following libraries are used if present at runtime:
* [`libXFConf`](https://gitlab.xfce.org/xfce/xfconf): Needed for XFWM theme and XFCE Terminal font.
* [`libsqlite3`](https://www.sqlite.org/index.html): Needed for pkg & rpm package count.
* [`librpm`](http://rpm.org/): Slower fallback for rpm package count. Needed on openSUSE.
-* [`libcJSON`](https://github.com/DaveGamble/cJSON): Needed for Windows Terminal font ( Windows, WSL ).
+* [`libcJSON`](https://github.com/DaveGamble/cJSON): Needed for Windows Terminal font ( WSL ).
### macOS
@@ -86,7 +86,7 @@ AlmaLinux, Alpine, Android, Arch, Arco, Artix, Bedrock, CachyOS, CentOS, Crystal
##### Package managers
```
-Pacman, dpkg, rpm, emerge, xbps, nix, Flatpak, Snap, apk, pkg, brew, MacPorts, scoop
+Pacman, dpkg, rpm, emerge, xbps, nix, Flatpak, Snap, apk, pkg, brew, MacPorts, scoop, Chocolatey
```
##### WM themes
diff --git a/presets/all b/presets/all
index a1706f3b1..f68223bb8 100644
--- a/presets/all
+++ b/presets/all
@@ -1 +1 @@
---structure Title:Separator:OS:Host:Kernel:Uptime:Processes:Packages:Shell:Resolution:DE:WM:WMTheme:Theme:Icons:Font:Cursor:Terminal:TerminalFont:CPU:GPU:Memory:Swap:Disk:Battery:PowerAdapter:Player:Song:PublicIP:LocalIP:DateTime:Locale:Vulkan:OpenGL:OpenCL:Users:Weather:Break:Colors
+--structure Title:Separator:OS:Host:Kernel:Uptime:Processes:Packages:Shell:Resolution:DE:WM:WMTheme:Theme:Icons:Font:Cursor:Terminal:TerminalFont:CPU:CPUUsage:GPU:Memory:Swap:Disk:Battery:PowerAdapter:Player:Song:PublicIP:LocalIP:DateTime:Locale:Vulkan:OpenGL:OpenCL:Users:Weather:Break:Colors
diff --git a/src/common/sysctl.c b/src/common/sysctl.c
index 30e92383a..4f0f3b65c 100644
--- a/src/common/sysctl.c
+++ b/src/common/sysctl.c
@@ -2,11 +2,11 @@
#include
-void ffSysctlGetString(const char* propName, FFstrbuf* result)
+const char* ffSysctlGetString(const char* propName, FFstrbuf* result)
{
size_t neededLength;
if(sysctlbyname(propName, NULL, &neededLength, NULL, 0) != 0 || neededLength == 1) //neededLength is 1 for empty strings, because of the null terminator
- return;
+ return "sysctlbyname() failed";
ffStrbufEnsureFree(result, (uint32_t) neededLength - 1);
@@ -14,6 +14,8 @@ void ffSysctlGetString(const char* propName, FFstrbuf* result)
result->length += (uint32_t) neededLength - 1;
result->chars[result->length] = '\0';
+
+ return NULL;
}
int ffSysctlGetInt(const char* propName, int defaultValue)
diff --git a/src/common/sysctl.h b/src/common/sysctl.h
index 91e4ad8b6..562e625d5 100644
--- a/src/common/sysctl.h
+++ b/src/common/sysctl.h
@@ -4,12 +4,14 @@
#define FF_INCLUDED_common_sysctl
#include "fastfetch.h"
+#include "util/FFcheckmacros.h"
+
#include
#include
-void ffSysctlGetString(const char* propName, FFstrbuf* result);
-int ffSysctlGetInt(const char* propName, int defaultValue);
-int64_t ffSysctlGetInt64(const char* propName, int64_t defaultValue);
-void* ffSysctlGetData(int* request, u_int requestLength, size_t* resultLength);
+const char* ffSysctlGetString(const char* propName, FFstrbuf* result);
+FF_C_NODISCARD int ffSysctlGetInt(const char* propName, int defaultValue);
+FF_C_NODISCARD int64_t ffSysctlGetInt64(const char* propName, int64_t defaultValue);
+FF_C_NODISCARD void* ffSysctlGetData(int* request, u_int requestLength, size_t* resultLength);
#endif
diff --git a/src/detection/cpu/cpu_bsd.c b/src/detection/cpu/cpu_bsd.c
index 46f60b4e6..6f71f1ef6 100644
--- a/src/detection/cpu/cpu_bsd.c
+++ b/src/detection/cpu/cpu_bsd.c
@@ -5,7 +5,17 @@ void ffDetectCPUImpl(const FFinstance* instance, FFCPUResult* cpu, bool cached)
{
FF_UNUSED(instance);
- cpu->temperature = FF_CPU_TEMP_UNSET;
+ if (instance->config.cpuTemp)
+ {
+ FFstrbuf cpuTemp;
+ ffStrbufInit(&cpuTemp);
+ if(ffSysctlGetString("temperature", &cpuTemp))
+ cpu->temperature = FF_CPU_TEMP_UNSET;
+ else
+ cpu->temperature = ffStrbufToDouble(&cpuTemp);
+ }
+ else
+ cpu->temperature = FF_CPU_TEMP_UNSET;
if(cached)
return;
diff --git a/src/detection/cpuUsage/cpuUsage_bsd.c b/src/detection/cpuUsage/cpuUsage_bsd.c
new file mode 100644
index 000000000..d96064fd4
--- /dev/null
+++ b/src/detection/cpuUsage/cpuUsage_bsd.c
@@ -0,0 +1,19 @@
+#include "cpuUsage.h"
+
+#include
+#include
+#include
+
+const char* ffGetCpuUsageInfo(uint64_t* inUseAll, uint64_t* totalAll)
+{
+ // interrupt processing, user processes, system processing, lock spinning, and idling
+ uint64_t cpTime[5];
+ size_t neededLength = sizeof(cpTime);
+ if(sysctlbyname("kern.cp_time", cpTime, &neededLength, NULL, 0) != 0)
+ return "sysctlbyname(kern.cp_time) failed";
+
+ *inUseAll = cpTime[0] + cpTime[1] + cpTime[2] + cpTime[3];
+ *totalAll = *inUseAll + cpTime[4];
+
+ return NULL;
+}
diff --git a/src/detection/disk/disk_apple.m b/src/detection/disk/disk_apple.m
index 42c2e6a26..b2f7cec08 100644
--- a/src/detection/disk/disk_apple.m
+++ b/src/detection/disk/disk_apple.m
@@ -1,61 +1,17 @@
#include "disk.h"
-#include
+#include
#import
-#import
-void ffDetectDisksImpl(FFDiskResult* disks)
+void detectFsInfo(struct statfs* fs, FFDisk* disk)
{
- NSArray *keys = [NSArray arrayWithObjects:NSURLVolumeNameKey, nil];
- NSArray *urls = [NSFileManager.defaultManager mountedVolumeURLsIncludingResourceValuesForKeys:keys options:0];
+ // FreeBSD doesn't support these flags
+ if(fs->f_flags & MNT_DONTBROWSE)
+ disk->type = FF_DISK_TYPE_HIDDEN;
+ else if(fs->f_flags & MNT_REMOVABLE)
+ disk->type = FF_DISK_TYPE_EXTERNAL;
+ else
+ disk->type = FF_DISK_TYPE_REGULAR;
- if(urls == nil)
- {
- ffStrbufAppendS(&disks->error, "[NSFileManager.defaultManager mountedVolumeURLsIncludingResourceValuesForKeys] failed");
- return;
- }
-
- for (NSURL *url in urls)
- {
- FFDisk* disk = ffListAdd(&disks->disks);
-
- ffStrbufInitS(&disk->mountpoint, [url.relativePath cStringUsingEncoding:NSUTF8StringEncoding]);
-
- NSString* filesystem;
- BOOL removable;
- [NSWorkspace.sharedWorkspace getFileSystemInfoForPath:url.relativePath
- isRemovable:&removable
- isWritable:nil
- isUnmountable:nil
- description:nil
- type:&filesystem
- ];
- ffStrbufInitS(&disk->filesystem, [filesystem cStringUsingEncoding:NSUTF8StringEncoding]);
-
- NSError* error;
-
- NSNumber* isBrowsable;
- if([url getResourceValue:&isBrowsable forKey:NSURLVolumeIsBrowsableKey error:&error] == YES && !isBrowsable.boolValue)
- disk->type = FF_DISK_TYPE_HIDDEN;
- else if(removable)
- disk->type = FF_DISK_TYPE_EXTERNAL;
- else
- disk->type = FF_DISK_TYPE_REGULAR;
-
- NSString* volumeName;
- if([url getResourceValue:&volumeName forKey:NSURLVolumeNameKey error:&error] == YES)
- ffStrbufInitS(&disk->name, [volumeName cStringUsingEncoding:NSUTF8StringEncoding]);
- else
- ffStrbufInit(&disk->name);
-
- struct statvfs fs;
- if(statvfs(disk->mountpoint.chars, &fs) != 0)
- memset(&fs, 0, sizeof(struct statvfs)); //Set all values to 0, so our values get initialized to 0 too
-
- disk->bytesTotal = fs.f_blocks * fs.f_frsize;
- disk->bytesUsed = disk->bytesTotal - (fs.f_bavail * fs.f_frsize);
-
- disk->filesTotal = (uint32_t) fs.f_files;
- disk->filesUsed = (uint32_t) (disk->filesTotal - fs.f_ffree);
- }
+ ffStrbufInitS(&disk->name, [NSFileManager.defaultManager displayNameAtPath:@(fs->f_mntonname)].UTF8String);
}
diff --git a/src/detection/disk/disk_bsd.c b/src/detection/disk/disk_bsd.c
new file mode 100644
index 000000000..0e14ef3f2
--- /dev/null
+++ b/src/detection/disk/disk_bsd.c
@@ -0,0 +1,56 @@
+#include "disk.h"
+
+#include
+
+#ifdef __FreeBSD__
+static void detectFsInfo(struct statfs* fs, FFDisk* disk)
+{
+ if(
+ ffStrbufStartsWithS(&disk->mountpoint, "/boot") ||
+ ffStrbufStartsWithS(&disk->mountpoint, "/dev") ||
+ ffStrbufStartsWithS(&disk->mountpoint, "/var") ||
+ ffStrbufStartsWithS(&disk->mountpoint, "/tmp") ||
+ ffStrbufStartsWithS(&disk->mountpoint, "/proc") ||
+ ffStrbufStartsWithS(&disk->mountpoint, "/zroot")
+ )
+ disk->type = FF_DISK_TYPE_HIDDEN;
+ else if((fs->f_flags & MNT_NOSUID) || !(fs->f_flags & MNT_LOCAL))
+ disk->type = FF_DISK_TYPE_EXTERNAL;
+ else
+ disk->type = FF_DISK_TYPE_REGULAR;
+
+ ffStrbufInit(&disk->name);
+}
+#else
+void detectFsInfo(struct statfs* fs, FFDisk* disk);
+#endif
+
+void ffDetectDisksImpl(FFDiskResult* disks)
+{
+ struct statfs* buf;
+
+ int size = getmntinfo(&buf, MNT_WAIT);
+ if(size <= 0)
+ ffStrbufAppendS(&disks->error, "getmntinfo() failed");
+
+ for(struct statfs* fs = buf; fs < buf + size; ++fs)
+ {
+ FFDisk* disk = ffListAdd(&disks->disks);
+
+ #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
+
+ disk->bytesTotal = fs->f_blocks * fs->f_bsize;
+ disk->bytesUsed = disk->bytesTotal - ((uint64_t)fs->f_bavail * fs->f_bsize);
+
+ disk->filesTotal = (uint32_t) fs->f_files;
+ disk->filesUsed = (uint32_t) (disk->filesTotal - (uint64_t)fs->f_ffree);
+
+ ffStrbufInitS(&disk->mountpoint, fs->f_mntonname);
+ ffStrbufInitS(&disk->filesystem, fs->f_fstypename);
+ detectFsInfo(fs, disk);
+ }
+}
diff --git a/src/detection/host/host_bsd.c b/src/detection/host/host_bsd.c
new file mode 100644
index 000000000..13a43acda
--- /dev/null
+++ b/src/detection/host/host_bsd.c
@@ -0,0 +1,19 @@
+#include "host.h"
+#include "common/sysctl.h"
+
+void ffDetectHostImpl(FFHostResult* host)
+{
+ ffStrbufInit(&host->error);
+
+ ffStrbufInit(&host->productName);
+ ffStrbufInit(&host->productFamily);
+ ffStrbufInit(&host->productVersion);
+ ffStrbufInit(&host->productSku);
+
+ ffStrbufInit(&host->sysVendor);
+ ffStrbufInit(&host->chassisType);
+ ffStrbufInit(&host->chassisVendor);
+ ffStrbufInit(&host->chassisVersion);
+
+ ffStrbufAppendS(&host->error, ffSysctlGetString("hw.fdt.model", &host->productName));
+}
diff --git a/src/detection/terminalshell/terminalshell.c b/src/detection/terminalshell/terminalshell.c
index f4141a6b2..a99c498e4 100644
--- a/src/detection/terminalshell/terminalshell.c
+++ b/src/detection/terminalshell/terminalshell.c
@@ -71,6 +71,17 @@ static void getShellVersionFish(FFstrbuf* exe, FFstrbuf* version)
ffStrbufSubstrAfterLastC(version, ' ');
}
+static void getShellVersionTcsh(FFstrbuf* exe, FFstrbuf* version)
+{
+ ffProcessAppendStdOut(version, (char* const[]) {
+ exe->chars,
+ "--version",
+ NULL
+ }); // tcsh 6.24.01 (Astron) 2022-05-12 (aarch64-apple-darwin) options wide,nls,dl,al,kan,sm,rh,color,filec
+ ffStrbufSubstrAfterFirstC(version, ' '); // 6.24.01 (Astron) 2022-05-12 (aarch64-apple-darwin) options wide,nls,dl,al,kan,sm,rh,color,filec
+ ffStrbufSubstrBeforeFirstC(version, ' '); // 6.24.01
+}
+
static void getShellVersionPwsh(FFstrbuf* exe, FFstrbuf* version)
{
#ifdef _WIN32
@@ -128,6 +139,8 @@ bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* version)
getShellVersionFish(exe, version);
else if(strcasecmp(exeName, "pwsh") == 0)
getShellVersionPwsh(exe, version);
+ else if(strcasecmp(exeName, "csh") == 0 || strcasecmp(exeName, "tcsh") == 0)
+ getShellVersionTcsh(exe, version);
else if(strcasecmp(exeName, "nu") == 0)
getShellVersionNu(exe, version);
diff --git a/src/detection/terminalshell/terminalshell_linux.c b/src/detection/terminalshell/terminalshell_linux.c
index 5040cede5..57867fdb6 100644
--- a/src/detection/terminalshell/terminalshell_linux.c
+++ b/src/detection/terminalshell/terminalshell_linux.c
@@ -153,6 +153,8 @@ static void getTerminalShell(FFTerminalShellResult* result, pid_t pid)
strcasecmp(name, "sh") == 0 ||
strcasecmp(name, "zsh") == 0 ||
strcasecmp(name, "ksh") == 0 ||
+ strcasecmp(name, "csh") == 0 ||
+ strcasecmp(name, "tcsh") == 0 ||
strcasecmp(name, "fish") == 0 ||
strcasecmp(name, "dash") == 0 ||
strcasecmp(name, "pwsh") == 0 ||
@@ -251,11 +253,15 @@ static void getTerminalFromEnv(FFTerminalShellResult* result)
}
}
-static void getUserShellFromEnv(FFTerminalShellResult* result)
+static void getUserShellFromEnv(const FFinstance* instance, FFTerminalShellResult* result)
{
- ffStrbufAppendS(&result->userShellExe, getenv("SHELL"));
+ if(instance->state.passwd->pw_shell[0] != '\0')
+ ffStrbufAppendS(&result->userShellExe, instance->state.passwd->pw_shell);
+ else
+ ffStrbufAppendS(&result->userShellExe, getenv("SHELL"));
if(result->userShellExe.length == 0)
return;
+
setExeName(&result->userShellExe, &result->userShellExeName);
//If shell detection via processes failed
@@ -313,13 +319,21 @@ const FFTerminalShellResult* ffDetectTerminalShell(const FFinstance* instance)
}
init = true;
+ #ifdef __APPLE__
+ const uint32_t exePathLen = PROC_PIDPATHINFO_MAXSIZE;
+ #elif defined(MAXPATH)
+ const uint32_t exePathLen = MAXPATH;
+ #else
+ const uint32_t exePathLen = 260;
+ #endif
+
ffStrbufInit(&result.shellProcessName);
- ffStrbufInitA(&result.shellExe, 128);
+ ffStrbufInitA(&result.shellExe, exePathLen);
result.shellExeName = result.shellExe.chars;
ffStrbufInit(&result.shellVersion);
ffStrbufInit(&result.terminalProcessName);
- ffStrbufInitA(&result.terminalExe, 128);
+ ffStrbufInitA(&result.terminalExe, exePathLen);
result.terminalExeName = result.terminalExe.chars;
ffStrbufInit(&result.userShellExe);
@@ -329,7 +343,7 @@ const FFTerminalShellResult* ffDetectTerminalShell(const FFinstance* instance)
getTerminalShell(&result, getppid());
getTerminalFromEnv(&result);
- getUserShellFromEnv(&result);
+ getUserShellFromEnv(instance, &result);
getShellVersion(&result.shellExe, result.shellExeName, &result.shellVersion);
if(strcasecmp(result.shellExeName, result.userShellExeName) != 0)