Compare commits

..

60 Commits

Author SHA1 Message Date
Carter Li ba2636dc1a Merge pull request #775 from fastfetch-cli/dev
Release: v2.9.0
2024-04-04 12:24:44 +08:00
李通洲 69589f1ad5 Release: v2.9.0 2024-04-04 12:22:52 +08:00
Carter Li 39da11de8e LocalIP (BSD): fix build 2024-04-04 19:42:33 +08:00
李通洲 8b7a4daeda TerminalFont: use system mono font if no config file is find 2024-04-04 11:09:28 +08:00
李通洲 82af7a5b52 Doc: update changelog 2024-04-04 10:52:42 +08:00
李通洲 a2d99695fd LocalIP: add new option localip-show-prefix-len 2024-04-04 10:42:44 +08:00
李通洲 3a2786a89f LocalIP: support network prefix detection for IPv6 2024-04-04 10:19:01 +08:00
李通洲 a6cb30d6c8 LocalIP: print all IPs if multiple IPs are assigned to the same interface 2024-04-04 10:09:06 +08:00
李通洲 de6b1f9542 LocalIP (Linux): fix network prefix detection when the value is greater than 24 2024-04-04 10:08:26 +08:00
李通洲 77431671bb Packages (Linux): add am support
Fix: #771
2024-04-03 21:08:55 +08:00
apocelipes 4430b7145e fastfetch: add the missing new-line in config files (#772) 2024-04-03 20:02:38 +08:00
kojq 898859cc7a Flashfetch: add the skipped "host" option from "Flashfetch: simplify implementation" (#770) 2024-04-02 22:36:20 +08:00
李通洲 43b96df112 Version: detect apple clang 2024-04-02 14:28:25 +08:00
李通洲 bb97893bd0 Doc: update changelog 2024-03-29 14:36:11 +08:00
李通洲 9b21ec6e1f Terminal (Linux): support weston-terminal version detection 2024-03-28 13:46:11 +08:00
李通洲 ffac354368 Terminal (Linux): support Lxterminal version detection 2024-03-26 19:28:07 +08:00
李通洲 a9aab51764 Doc: update changelog [ci skip] 2024-03-26 09:06:23 +08:00
Carter Li 4d1fc9ceb1 Packaging: update debian stuff 2024-03-25 15:04:24 +08:00
Carter Li e897a98153 Merge pull request #765 from fastfetch-cli/dev
Release v2.8.10
2024-03-25 14:22:43 +08:00
李通洲 0a8056d835 TerminalShell (Windows): adjustments
1. Don't pretty print CMD
2. Print conhost as Windows Console
2024-03-25 14:10:08 +08:00
李通洲 9681e176b3 Terminal (Windows): don't use wininit as terminal 2024-03-25 11:12:30 +08:00
李通洲 1f8be43881 Disk (Windows): use MS-DOS device name as mountFrom result, instead of useless GUID volume name 2024-03-25 10:09:35 +08:00
李通洲 30813551be Release: v2.8.10 2024-03-25 09:17:03 +08:00
李通洲 beb564f374 CI: try fixing Windows build 2024-03-25 09:17:03 +08:00
李通洲 5c97c012a9 Font (Linux): try fixing style detection 2024-03-24 18:32:50 +08:00
Carter Li 50da7cabd6 GPU (Apple): always use metal to detect vmem 2024-03-23 17:34:09 +08:00
李通洲 a6528cdfd6 Chore: simpify gitignore [ci skip]
And make scc happy
2024-03-22 10:09:58 +08:00
李通洲 588201fe46 Windows: update version.rc 2024-03-21 16:26:56 +08:00
李通洲 6184b5ee96 Doc: update changelog 2024-03-21 11:04:53 +08:00
李通洲 5e7baa9d0a PublicIP: error out if non-http protocol is specified 2024-03-21 11:01:23 +08:00
李通洲 79ae650c58 Networking: avoid short recv 2024-03-21 10:42:25 +08:00
李通洲 44107f289e Network (Windows): fix compiling 2024-03-20 16:09:17 +08:00
李通洲 75927a87b2 Networking: add timeout support for TCP connecting 2024-03-20 15:04:29 +08:00
李通洲 85da30ccf5 Networking: report detailed error messages; support --thread false for debugging 2024-03-20 13:54:27 +08:00
李通洲 f73c3b85c2 Doc: update changelog 2024-03-19 21:18:25 +08:00
李通洲 66bef2fc19 Network: trim trailing white spaces 2024-03-19 21:18:25 +08:00
李通洲 7c5eb021ee Terminal (Linux): ignore chezmoi
Fix #762
2024-03-18 09:03:10 +08:00
李通洲 f902e3b3d8 CPU (Android): don't detect manufactor of Qualcomm as ARM 2024-03-17 19:19:33 +08:00
李通洲 553124ab5b Presets: a new example
Ref: #761
2024-03-16 22:25:35 +08:00
李通洲 6c6d93370d Logo: fix colors of arco linux
Fix #759
2024-03-15 20:32:29 +08:00
Carter Li 55ae3a7dbd CPU (FreeBSD): don't display 0.00 GHz 2024-03-15 11:15:23 +08:00
Carter Li 586874080f Packaging: update debian stuff 2024-03-15 10:51:53 +08:00
Carter Li d5b91a8983 Merge pull request #758 from fastfetch-cli/dev
Release: v2.8.9
2024-03-15 09:50:54 +08:00
李通洲 72fee13112 Release: v2.8.9 2024-03-15 09:21:13 +08:00
李通洲 20ae897f39 fastfetch: remove unused #includes 2024-03-15 08:37:58 +08:00
李通洲 6f756d103f Doc: update changelog 2024-03-14 20:43:17 +08:00
李通洲 c9dd858ce3 CPU (Linux): bing cpuMHz back
It's used in WSL
2024-03-14 20:40:40 +08:00
李通洲 2e201eaaf7 CPU: bring min frequency back & code optimizations 2024-03-14 19:24:03 +08:00
李通洲 7c54dcba69 CPU (Linux): fix detection when .../base_frequency doesn't exist 2024-03-14 10:32:34 +08:00
李通洲 a107395707 Logo (Chafa): fix blurry result when specifying both width and height
Who knows why it was coded like that

Fix #757
2024-03-14 10:18:17 +08:00
李通洲 8a9fe22855 Logo: fix proxmox
Fix #756
2024-03-13 23:58:40 +08:00
李通洲 7e04e23528 CPU: rename min frequency to base frequency 2024-03-13 23:42:59 +08:00
李通洲 8d779f68f3 CPU: detect base frequency 2024-03-13 23:41:11 +08:00
李通洲 98ba08c1a0 CI (macOS): fix build 2024-03-13 10:37:45 +08:00
李通洲 a1499b82f8 Doc: update changelog 2024-03-13 08:44:09 +08:00
李通洲 c6c866d78a Host (Apple): add MacBook Air 2024 2024-03-12 18:27:02 +08:00
李通洲 7a6999bd20 Fastfetch: print final new line in --format json 2024-03-09 12:07:07 +08:00
李通洲 1084cf3523 Terminal (Linux): actually ignore SessionLeader 2024-03-09 11:52:31 +08:00
Carter Li ed5f2a3968 Chore: update screenshots 2024-03-08 15:58:47 +08:00
Carter Li 17e1d4b72d Package: update debian stuff 2024-03-08 10:03:31 +08:00
49 changed files with 731 additions and 334 deletions
+3 -4
View File
@@ -245,8 +245,7 @@ jobs:
- name: install required packages
run: |
brew update
HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1 brew install vulkan-loader vulkan-headers molten-vk imagemagick chafa
HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1 brew install --overwrite vulkan-loader vulkan-headers molten-vk imagemagick chafa
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
@@ -378,7 +377,7 @@ jobs:
with:
msystem: CLANG64
update: true
install: git mingw-w64-clang-x86_64-7zip mingw-w64-clang-x86_64-cmake mingw-w64-clang-x86_64-clang mingw-w64-clang-x86_64-vulkan-loader mingw-w64-clang-x86_64-opencl-icd
install: git mingw-w64-clang-x86_64-7zip mingw-w64-clang-x86_64-cmake mingw-w64-clang-x86_64-clang mingw-w64-clang-x86_64-vulkan-loader mingw-w64-clang-x86_64-vulkan-headers mingw-w64-clang-x86_64-opencl-icd
- name: print msys version
run: uname -a
@@ -440,7 +439,7 @@ jobs:
with:
msystem: CLANG32
update: true
install: git mingw-w64-clang-i686-7zip mingw-w64-clang-i686-cmake mingw-w64-clang-i686-clang mingw-w64-clang-i686-vulkan-loader mingw-w64-clang-i686-opencl-icd
install: git mingw-w64-clang-i686-7zip mingw-w64-clang-i686-cmake mingw-w64-clang-i686-clang mingw-w64-clang-i686-vulkan-loader mingw-w64-clang-i686-vulkan-headers mingw-w64-clang-i686-opencl-icd
- name: print msys version
run: uname -a
+6 -6
View File
@@ -1,9 +1,9 @@
**/build/
**/.vscode/
**/.cache/
**/.kdev4/
**/.DS_Store
/.vs
build/
.vs/
.vscode/
.cache/
.kdev4/
.DS_Store
cscope.*
tags
fastfetch.kdev4
+48
View File
@@ -1,3 +1,51 @@
# 2.9.0
Features:
* Support Lxterminal version detection (Terminal, Linux)
* Support weston-terminal version and font detection (TerminalFont, Linux)
* Support `am` package manager detection (#771, Packages, Linux)
* Support network prefix length detection for IPv6 (LocalIP)
* Display all IPs when multiple IPs are assigned to the same interface (LocalIP)
* Add option `--localip-show-prefix-len` to show network prefix length for both IPv4 and IPv6. Defaults to `true` (LocalIP)
Bugfixes:
* Fix network prefix length detection when the value is greater than 24 (#773, LocalIP, Linux)
* For xfce4-terminal, use system mono font if no config file is found (TerminalFont, Linux)
# 2.8.10
Bugfixes:
* Don't display 0.00 GHz (CPU, FreeBSD)
* Don't detect manufactor of Qualcomm as ARM (CPU, Android)
* Ignore `chezmoi` (Terminal, Linux)
* Trim trailing possible whitespaces (PublicIP)
* Fix detection compatibility for KDE 6 (Font, Linux)
* Always use Metal API to detect vmem size (GPU, macOS)
Features:
* Improve stability; print more useful error message; avoid misuse (PublicIP / Weather)
* Use MS-DOS device name as mountFrom result, instead of useless GUID volume name (Windows, Disk)
* Some adjustments to Terminal detection (Terminal, Windows)
* Don't pretty print CMD
* Print conhost as Windows Console
* Don't detect `wininit` as Terminal
Logo:
* Fix color of Arco Linux
# 2.8.9
Bugfixes:
* Don't detect `SessionLeader` as terminal, actually (Terminal, Linux)
* Fix blurry chafa result when specifying both width and height (#757, Logo)
Features:
* Support new MacBook Air (Host, macOS)
* Distinguish min frequency and base frequency (CPU)
Logo:
* Fix proxmox
# 2.8.8
Bugfixes:
+1 -1
View File
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.12.0) # target_link_libraries with OBJECT libs & project homepage url
project(fastfetch
VERSION 2.8.8
VERSION 2.9.0
LANGUAGES C
DESCRIPTION "Fast neofetch-like system information tool"
HOMEPAGE_URL "https://github.com/fastfetch-cli/fastfetch"
+18
View File
@@ -1,3 +1,21 @@
fastfetch (2.8.10) jammy; urgency=medium
* Update to 2.8.10
-- Carter Li <zhangsongcui@live.cn> Mon, 25 Mar 2024 15:01:53 +0800
fastfetch (2.8.9) jammy; urgency=medium
* Update to 2.8.9
-- Carter Li <zhangsongcui@live.cn> Fri, 15 Mar 2024 10:49:42 +0800
fastfetch (2.8.8) jammy; urgency=medium
* Update to 2.8.8
-- Carter Li <zhangsongcui@live.cn> Fri, 08 Mar 2024 09:59:41 +0800
fastfetch (2.8.6) jammy; urgency=medium
* Update to 2.8.6
+1 -1
View File
@@ -1 +1 @@
fastfetch_2.8.6_source.buildinfo universe/utils optional
fastfetch_2.8.10_source.buildinfo universe/utils optional
+5
View File
@@ -1438,6 +1438,11 @@
"type": "boolean",
"default": false
},
"showPrefixLen": {
"description": "Show network prefix length (/N)",
"type": "boolean",
"default": true
},
"compact": {
"description": "Show all IPs in one line",
"type": "boolean",
+104
View File
@@ -0,0 +1,104 @@
{
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
"logo": {
"type": "none"
},
"display": {
"separator": "-> "
},
"modules": [
{
"type": "title",
"format": " {6}{7}{8}"
},
"break",
{
"type": "custom",
"format": "┌───────────────────────────── \u001b[1mSystem Information\u001b[0m ─────────────────────────────┐" // `\u001b` is `\033`, or `\e`
},
"break",
{
"key": "  OS ",
"keyColor": "red",
"type": "os"
},
{
"key": "  Machine ",
"keyColor": "green",
"type": "host"
},
{
"key": "  Kernel ",
"keyColor": "magenta",
"type": "kernel"
},
{
"key": " 󰅐 Uptime ",
"keyColor": "red",
"type": "uptime"
},
{
"key": " 󰍹 Resolution ",
"keyColor": "yellow",
"type": "display",
"compactType": "original-with-refresh-rate"
},
{
"key": "  WM ",
"keyColor": "blue",
"type": "wm"
},
{
"key": "  DE ",
"keyColor": "green",
"type": "de"
},
{
"key": "  Shell ",
"keyColor": "cyan",
"type": "shell"
},
{
"key": "  Terminal ",
"keyColor": "red",
"type": "terminal"
},
{
"key": "  CPU ",
"keyColor": "yellow",
"type": "cpu"
},
{
"key": " ﬙ GPU ",
"keyColor": "blue",
"type": "gpu"
},
{
"key": " 󰑭 Memory ",
"keyColor": "magenta",
"type": "memory"
},
{
"key": " 󰩟 Local IP ",
"keyColor": "red",
"type": "localip",
"compact": true
},
{
"key": " 󰩠 Public IP ",
"keyColor": "cyan",
"type": "publicip"
},
"break",
{
"type": "custom",
"format": "└──────────────────────────────────────────────────────────────────────────────┘" // `\u001b` is `\033`, or `\e`
},
"break",
{
"type": "colors",
"paddingLeft": 34,
"symbol": "circle"
}
]
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

After

Width:  |  Height:  |  Size: 341 KiB

+19 -44
View File
@@ -2,6 +2,7 @@
#include "common/font.h"
#include <string.h>
#include <ctype.h>
void ffFontInit(FFfont* font)
{
@@ -66,59 +67,33 @@ void ffFontInitQt(FFfont* font, const char* data)
//See https://doc.qt.io/qt-5/qfont.html#toString
//Family
while(*data != ',' && *data != '\0')
{
ffStrbufAppendC(&font->name, *data);
++data;
}
if(*data != '\0')
++data;
data = ffStrbufAppendSUntilC(&font->name, data, ',');
ffStrbufTrim(&font->name, ' ');
if (!data) goto exit;
data++;
//Size
while(*data != ',' && *data != '\0')
{
ffStrbufAppendC(&font->size, *data);
++data;
}
if(*data != '\0')
++data;
data = ffStrbufAppendSUntilC(&font->size, data, ',');
ffStrbufTrim(&font->size, ' ');
if (!data) goto exit;
data++;
#define FF_FONT_QT_SKIP_VALUE \
while(*data != ',' && *data != '\0') \
++data; \
if(*data != '\0') \
++data;
FF_FONT_QT_SKIP_VALUE //Pixel size
FF_FONT_QT_SKIP_VALUE //Style hint
FF_FONT_QT_SKIP_VALUE //Font weight
FF_FONT_QT_SKIP_VALUE //Font style
FF_FONT_QT_SKIP_VALUE //Underline
FF_FONT_QT_SKIP_VALUE //Strike out
FF_FONT_QT_SKIP_VALUE //Fixed pitch
FF_FONT_QT_SKIP_VALUE //Always 0
#undef FF_FONT_QT_SKIP_VALUE
while(*data != '\0')
//Style
data = strrchr(data, ',');
if (!data) goto exit;
data++;
if (isalpha(*data))
{
while(*data == ' ')
++data;
if(*data == '\0')
break;
FFstrbuf* style = ffListAdd(&font->styles);
ffStrbufInit(style);
while(*data != ' ' && *data != '\0')
do
{
ffStrbufAppendC(style, *data);
++data;
}
FFstrbuf* style = ffListAdd(&font->styles);
ffStrbufInit(style);
data = ffStrbufAppendSUntilC(style, data, ' ');
if (data) data++;
} while (data);
}
exit:
fontInitPretty(font);
}
+4 -10
View File
@@ -20,15 +20,9 @@ typedef struct FFNetworkingState {
FFThreadType thread;
#endif
#endif
uint32_t timeout;
} FFNetworkingState;
bool ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* host, const char* path, const char* headers);
bool ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buffer, uint32_t timeout);
static inline bool ffNetworkingGetHttp(const char* host, const char* path, uint32_t timeout, const char* headers, FFstrbuf* buffer)
{
FFNetworkingState state;
if(ffNetworkingSendHttpRequest(&state, host, path, headers))
return ffNetworkingRecvHttpResponse(&state, buffer, timeout);
return false;
}
const char* ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* host, const char* path, const char* headers);
const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buffer);
+53 -21
View File
@@ -5,30 +5,50 @@
#include <sys/time.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h> // For FreeBSD
#include <netinet/tcp.h>
static void connectAndSend(FFNetworkingState* state)
static const char* connectAndSend(FFNetworkingState* state)
{
struct addrinfo hints = {
.ai_family = AF_INET,
.ai_socktype = SOCK_STREAM,
};
const char* ret = NULL;
struct addrinfo* addr;
if(getaddrinfo(state->host.chars, "80", &hints, &addr) != 0)
if(getaddrinfo(state->host.chars, "80", &(struct addrinfo) {
.ai_family = AF_INET,
.ai_socktype = SOCK_STREAM,
}, &addr) != 0)
{
ret = "getaddrinfo() failed";
goto error;
}
state->sockfd = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
if(state->sockfd == -1)
{
freeaddrinfo(addr);
ret = "socket() failed";
goto error;
}
if (state->timeout > 0)
{
FF_MAYBE_UNUSED uint32_t sec = state->timeout / 1000;
if (sec == 0) sec = 1;
#ifdef TCP_CONNECTIONTIMEOUT
setsockopt(state->sockfd, IPPROTO_TCP, TCP_CONNECTIONTIMEOUT, &sec, sizeof(sec));
#elif defined(TCP_KEEPINIT)
setsockopt(state->sockfd, IPPROTO_TCP, TCP_KEEPINIT, &sec, sizeof(sec));
#elif defined(TCP_USER_TIMEOUT)
setsockopt(state->sockfd, IPPROTO_TCP, TCP_USER_TIMEOUT, &state->timeout, sizeof(state->timeout));
#endif
}
if(connect(state->sockfd, addr->ai_addr, addr->ai_addrlen) == -1)
{
close(state->sockfd);
freeaddrinfo(addr);
ret = "connect() failed";
goto error;
}
@@ -37,6 +57,7 @@ static void connectAndSend(FFNetworkingState* state)
if(send(state->sockfd, state->command.chars, state->command.length, 0) < 0)
{
close(state->sockfd);
ret = "send() failed";
goto error;
}
@@ -48,11 +69,13 @@ error:
exit:
ffStrbufDestroy(&state->host);
ffStrbufDestroy(&state->command);
return ret;
}
FF_THREAD_ENTRY_DECL_WRAPPER(connectAndSend, FFNetworkingState*);
bool ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* host, const char* path, const char* headers)
const char* ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* host, const char* path, const char* headers)
{
ffStrbufInitS(&state->host, host);
@@ -66,22 +89,30 @@ bool ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* host, con
ffStrbufAppendS(&state->command, "\r\n");
#ifdef FF_HAVE_THREADS
if (instance.config.general.multithreading)
{
state->thread = ffThreadCreate(connectAndSendThreadMain, state);
return !!state->thread;
#else
connectAndSend(state);
return state->sockfd != -1;
return state->thread ? NULL : "ffThreadCreate(connectAndSend) failed";
}
#endif
return connectAndSend(state);
}
bool ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buffer, uint32_t timeout)
const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buffer)
{
uint32_t timeout = state->timeout;
#ifdef FF_HAVE_THREADS
if (instance.config.general.multithreading)
{
if (!ffThreadJoin(state->thread, timeout))
return false;
return "ffThreadJoin() failed or timeout";
}
#endif
if(state->sockfd == -1)
return false;
return "ffNetworkingSendHttpRequest() failed";
if(timeout > 0)
{
@@ -91,14 +122,15 @@ bool ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buffer, ui
setsockopt(state->sockfd, SOL_SOCKET, SO_RCVTIMEO, &timev, sizeof(timev));
}
ssize_t received = recv(state->sockfd, buffer->chars + buffer->length, ffStrbufGetFree(buffer), 0);
if(received > 0)
{
uint32_t recvStart;
do {
recvStart = buffer->length;
ssize_t received = recv(state->sockfd, buffer->chars + buffer->length, ffStrbufGetFree(buffer), 0);
if (received <= 0) break;
buffer->length += (uint32_t) received;
buffer->chars[buffer->length] = '\0';
}
} while (ffStrbufGetFree(buffer) > 0 && strstr(buffer->chars + recvStart, "\r\n\r\n") == NULL);
close(state->sockfd);
return ffStrbufStartsWithS(buffer, "HTTP/1.1 200 OK\r\n");
return ffStrbufStartsWithS(buffer, "HTTP/1.1 200 OK\r\n") ? NULL : "Invalid response";
}
+42 -25
View File
@@ -33,21 +33,20 @@ static const char* initWsaData(WSADATA* wsaData)
return NULL;
}
bool ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* host, const char* path, const char* headers)
const char* ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* host, const char* path, const char* headers)
{
static WSADATA wsaData;
if (wsaData.wVersion == 0)
{
if (initWsaData(&wsaData) != NULL)
const char* error = initWsaData(&wsaData);
if (error != NULL)
{
wsaData.wVersion = (WORD) -1;
return false;
return error;
}
}
else if (wsaData.wVersion == (WORD) -1)
return false;
memset(state, 0, sizeof(*state));
return "initWsaData() failed before";
struct addrinfo* addr;
@@ -55,26 +54,27 @@ bool ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* host, con
.ai_family = AF_INET,
.ai_socktype = SOCK_STREAM,
}, &addr) != 0)
return false;
return "getaddrinfo() failed";
state->sockfd = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
if(state->sockfd == INVALID_SOCKET)
{
freeaddrinfo(addr);
return false;
return "socket() failed";
}
{
//ConnectEx requires the socket to be initially bound
struct sockaddr_in addr = {
if(bind(state->sockfd, (SOCKADDR *) &(struct sockaddr_in) {
.sin_family = AF_INET,
.sin_addr.s_addr = INADDR_ANY,
.sin_port = 0,
};
if(bind(state->sockfd, (SOCKADDR *)&addr, sizeof(addr)) != 0)
}, sizeof(struct sockaddr_in)) != 0)
{
printf("bind %d\n", WSAGetLastError());
return false;
closesocket(state->sockfd);
freeaddrinfo(addr);
state->sockfd = INVALID_SOCKET;
return "bind() failed";
}
}
@@ -93,35 +93,52 @@ bool ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* host, con
if(!result && WSAGetLastError() != WSA_IO_PENDING)
{
closesocket(state->sockfd);
return false;
freeaddrinfo(addr);
state->sockfd = INVALID_SOCKET;
return "ConnectEx() failed";
}
return true;
return NULL;
}
bool ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buffer, uint32_t timeout)
const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buffer)
{
if (state->sockfd == INVALID_SOCKET)
return "ffNetworkingSendHttpRequest() failed";
uint32_t timeout = state->timeout;
if (timeout > 0)
{
if (WaitForSingleObject((HANDLE) state->sockfd, timeout) != WAIT_OBJECT_0)
{
CancelIo((HANDLE) state->sockfd);
closesocket(state->sockfd);
return "WaitForSingleObject(state->sockfd) failed or timeout";
}
}
DWORD transfer, flags;
if (!WSAGetOverlappedResult(state->sockfd, &state->overlapped, &transfer, TRUE, &flags))
{
closesocket(state->sockfd);
return false;
return "WSAGetOverlappedResult() failed";
}
if(timeout > 0)
{
//https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-setsockopt
setsockopt(state->sockfd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout, sizeof(timeout));
setsockopt(state->sockfd, SOL_SOCKET, SO_RCVTIMEO, (const char*) &timeout, sizeof(timeout));
}
ssize_t received = recv(state->sockfd, buffer->chars + buffer->length, (int)ffStrbufGetFree(buffer), 0);
if(received > 0)
{
buffer->length += (uint32_t) received;
uint32_t recvStart;
do {
recvStart = buffer->length;
ssize_t received = recv(state->sockfd, buffer->chars + buffer->length, (int) ffStrbufGetFree(buffer), 0);
if (received <= 0) break;
buffer->length = recvStart + (uint32_t) received;
buffer->chars[buffer->length] = '\0';
}
} while (ffStrbufGetFree(buffer) > 0 && strstr(buffer->chars + recvStart, "\r\n\r\n") == NULL);
closesocket(state->sockfd);
return ffStrbufStartsWithS(buffer, "HTTP/1.1 200 OK\r\n");
return ffStrbufStartsWithS(buffer, "HTTP/1.1 200 OK\r\n") ? NULL : "Invalid response";
}
+9
View File
@@ -1261,6 +1261,15 @@
"default": false
}
},
{
"long": "localip-show-prefix-len",
"desc": "Show network prefix length (/N) in local ip module",
"arg": {
"type": "bool",
"optional": true,
"default": true
}
},
{
"long": "localip-name-prefix",
"desc": "Show interfaces with given interface name prefix only",
+3 -1
View File
@@ -13,10 +13,12 @@ typedef struct FFCPUResult
uint16_t coresLogical;
uint16_t coresOnline;
double frequencyMin; // GHz
double frequencyBase; // GHz
double frequencyMax; // GHz
double frequencyMin; // GHz
double temperature;
} FFCPUResult;
const char* ffCPUDetectByCpuid(FFCPUResult* cpu);
const char* ffDetectCPU(const FFCPUOptions* options, FFCPUResult* cpu);
+1 -2
View File
@@ -60,14 +60,13 @@ static const char* detectFrequency(FFCPUResult* cpu)
ffCfDictGetData(properties, CFSTR("voltage-states5-sram"), pCoreLength - 8, 4, (uint8_t*) &aMax, NULL);
cpu->frequencyMax = aMax / (1000.0 * 1000 * 1000);
}
else
cpu->frequencyMax = 0.0;
return NULL;
}
#else
static const char* detectFrequency(FFCPUResult* cpu)
{
cpu->frequencyBase = ffSysctlGetInt64("hw.cpufrequency", 0) / 1000.0 / 1000.0 / 1000.0;
cpu->frequencyMin = ffSysctlGetInt64("hw.cpufrequency_min", 0) / 1000.0 / 1000.0 / 1000.0;
cpu->frequencyMax = ffSysctlGetInt64("hw.cpufrequency_max", 0);
if(cpu->frequencyMax > 0.0)
+2 -2
View File
@@ -11,8 +11,8 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
cpu->coresLogical = cpu->coresPhysical;
cpu->coresOnline = cpu->coresPhysical;
cpu->frequencyMin = ffSysctlGetInt("hw.clockrate", 0) / 1000.0;
cpu->frequencyMax = cpu->frequencyMin;
int clockRate = ffSysctlGetInt("hw.clockrate", 0);
cpu->frequencyBase = clockRate <= 0 ? 0.0/0.0 : clockRate / 1000.0;
cpu->temperature = FF_CPU_TEMP_UNSET;
if (options->temp)
+34 -21
View File
@@ -17,7 +17,10 @@
static void detectAndroid(FFCPUResult* cpu)
{
if (cpu->name.length == 0)
{
ffSettingsGetAndroidProperty("ro.soc.model", &cpu->name);
ffStrbufClear(&cpu->vendor); // We usually detect the vendor of CPU core as ARM, but instead we want the vendor of SOC
}
if (cpu->vendor.length == 0)
{
if (!ffSettingsGetAndroidProperty("ro.soc.manufacturer", &cpu->vendor))
@@ -94,11 +97,14 @@ static double getFrequency(FFstrbuf* basePath, const char* cpuinfoFileName, cons
if (ok)
return ffStrbufToDouble(buffer) / 1e6;
ffStrbufAppendS(basePath, scalingFileName);
ok = ffReadFileBuffer(basePath->chars, buffer);
ffStrbufSubstrBefore(basePath, baseLen);
if (ok)
return ffStrbufToDouble(buffer) / 1e6;
if (scalingFileName)
{
ffStrbufAppendS(basePath, scalingFileName);
ok = ffReadFileBuffer(basePath->chars, buffer);
ffStrbufSubstrBefore(basePath, baseLen);
if (ok)
return ffStrbufToDouble(buffer) / 1e6;
}
return 0.0/0.0;
}
@@ -111,7 +117,6 @@ static bool detectFrequency(FFCPUResult* cpu)
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
uint32_t baseLen = path.length;
bool flag = false;
struct dirent* entry;
while((entry = readdir(dir)) != NULL)
@@ -119,26 +124,34 @@ static bool detectFrequency(FFCPUResult* cpu)
if (ffStrStartsWith(entry->d_name, "policy") && isdigit(entry->d_name[strlen("policy")]))
{
ffStrbufAppendS(&path, entry->d_name);
double fmin = getFrequency(&path, "/cpuinfo_min_freq", "/scaling_min_freq", &buffer);
if (fmin != fmin) continue;
double fmax = getFrequency(&path, "/cpuinfo_max_freq", "/scaling_max_freq", &buffer);
if (fmax != fmax) continue;
if (flag)
double fbase = getFrequency(&path, "/base_frequency", NULL, &buffer);
if (fbase == fbase)
{
cpu->frequencyMin = cpu->frequencyMin < fmin ? cpu->frequencyMin : fmin;
cpu->frequencyMax = cpu->frequencyMax > fmax ? cpu->frequencyMax : fmax;
if (cpu->frequencyBase == cpu->frequencyBase)
cpu->frequencyBase = cpu->frequencyBase > fbase ? cpu->frequencyBase : fbase;
else
cpu->frequencyBase = fbase;
}
else
double fmax = getFrequency(&path, "/cpuinfo_max_freq", "/scaling_max_freq", &buffer);
if (fmax == fmax)
{
cpu->frequencyMin = fmin;
cpu->frequencyMax = fmax;
flag = true;
if (cpu->frequencyMax == cpu->frequencyMax)
cpu->frequencyMax = cpu->frequencyMax > fmax ? cpu->frequencyMax : fmax;
else
cpu->frequencyMax = fmax;
}
double fmin = getFrequency(&path, "/cpuinfo_min_freq", "/scaling_min_freq", &buffer);
if (fmin == fmin)
{
if (cpu->frequencyMin == cpu->frequencyMin)
cpu->frequencyMin = cpu->frequencyMin < fmin ? cpu->frequencyMin : fmin;
else
cpu->frequencyMin = fmin;
}
ffStrbufSubstrBefore(&path, baseLen);
}
}
return flag;
return true;
}
static double detectCPUTemp(void)
@@ -234,8 +247,8 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
cpu->coresOnline = (uint16_t) get_nprocs();
cpu->coresPhysical = (uint16_t) ffStrbufToUInt(&physicalCoresBuffer, cpu->coresLogical);
if (!detectFrequency(cpu))
cpu->frequencyMin = cpu->frequencyMax = ffStrbufToDouble(&cpuMHz) / 1000;
if (!detectFrequency(cpu) || cpu->frequencyBase != cpu->frequencyBase)
cpu->frequencyBase = ffStrbufToDouble(&cpuMHz) / 1000;
if(cpuUarch.length > 0)
{
+46 -33
View File
@@ -64,50 +64,53 @@ static const char* detectMaxSpeedBySmbios(FFCPUResult* cpu)
return "No active CPU is found in SMBIOS data";
}
double speed;
if (data->MaxSpeed > 0 && data->MaxSpeed < 30000) // VMware reports weird values
speed = data->MaxSpeed / 1000.0;
else
speed = data->CurrentSpeed / 1000.0;
{
double speed = data->MaxSpeed / 1000.0;
if (cpu->frequencyBase < speed)
cpu->frequencyMax = speed;
}
if (cpu->frequencyMax < speed)
cpu->frequencyMax = speed;
return NULL;
}
static const char* detectByOS(FFCPUResult* cpu)
static const char* detectNCores(FFCPUResult* cpu)
{
DWORD length = 0;
GetLogicalProcessorInformationEx(RelationAll, NULL, &length);
if (length == 0)
return "GetLogicalProcessorInformationEx(RelationAll, NULL, &length) failed";
SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX* FF_AUTO_FREE
pProcessorInfo = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX*)malloc(length);
if (!pProcessorInfo || !GetLogicalProcessorInformationEx(RelationAll, pProcessorInfo, &length))
return "GetLogicalProcessorInformationEx(RelationAll, pProcessorInfo, &length) failed";
for(
SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX* ptr = pProcessorInfo;
(uint8_t*)ptr < ((uint8_t*)pProcessorInfo) + length;
ptr = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX*)(((uint8_t*)ptr) + ptr->Size)
)
{
DWORD length = 0;
GetLogicalProcessorInformationEx(RelationAll, NULL, &length);
if (length == 0)
return "GetLogicalProcessorInformationEx(RelationAll, NULL, &length) failed";
SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX* FF_AUTO_FREE
pProcessorInfo = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX*)malloc(length);
if (pProcessorInfo && GetLogicalProcessorInformationEx(RelationAll, pProcessorInfo, &length))
if(ptr->Relationship == RelationProcessorCore)
++cpu->coresPhysical;
else if(ptr->Relationship == RelationGroup)
{
for(
SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX* ptr = pProcessorInfo;
(uint8_t*)ptr < ((uint8_t*)pProcessorInfo) + length;
ptr = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX*)(((uint8_t*)ptr) + ptr->Size)
)
for (uint32_t index = 0; index < ptr->Group.ActiveGroupCount; ++index)
{
if(ptr->Relationship == RelationProcessorCore)
++cpu->coresPhysical;
else if(ptr->Relationship == RelationGroup)
{
cpu->coresOnline += ptr->Group.GroupInfo->ActiveProcessorCount;
cpu->coresLogical += ptr->Group.GroupInfo->MaximumProcessorCount;
}
cpu->coresOnline += ptr->Group.GroupInfo[index].ActiveProcessorCount;
cpu->coresLogical += ptr->Group.GroupInfo[index].MaximumProcessorCount;
}
}
else
return "GetLogicalProcessorInformationEx(RelationAll, pProcessorInfo, &length) failed";
}
return NULL;
}
static const char* detectByRegistry(FFCPUResult* cpu)
{
FF_HKEY_AUTO_DESTROY hKey = NULL;
if(!ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", &hKey, NULL))
return "ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, L\"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0\", &hKey, NULL) failed";
@@ -115,24 +118,34 @@ static const char* detectByOS(FFCPUResult* cpu)
{
uint32_t mhz;
if(ffRegReadUint(hKey, L"~MHz", &mhz, NULL))
cpu->frequencyMin = cpu->frequencyMax = mhz / 1000.0;
cpu->frequencyBase = mhz / 1000.0;
}
ffRegReadStrbuf(hKey, L"ProcessorNameString", &cpu->name, NULL);
ffRegReadStrbuf(hKey, L"VendorIdentifier", &cpu->vendor, NULL);
if (cpu->coresLogical == 0)
{
DWORD cores;
if (RegQueryInfoKeyW(HKEY_LOCAL_MACHINE, L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor", NULL, NULL, &cores, NULL, NULL, NULL, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
cpu->coresOnline = cpu->coresPhysical = cpu->coresLogical = (uint16_t) cores;
}
return NULL;
}
const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
{
const char* error = detectByOS(cpu);
detectNCores(cpu);
const char* error = detectByRegistry(cpu);
if (error)
return error;
detectMaxSpeedBySmbios(cpu);
if(options->temp)
ffDetectSmbiosTemp(&cpu->temperature, NULL);
detectMaxSpeedBySmbios(cpu);
return NULL;
}
+12 -8
View File
@@ -15,7 +15,7 @@ const char* ffDetectDisksImpl(FFlist* disks)
for(uint32_t i = 0; i < length; i++)
{
const wchar_t* mountpoint = buf + i;
wchar_t* mountpoint = buf + i;
UINT driveType = GetDriveTypeW(mountpoint);
if(driveType == DRIVE_NO_ROOT_DIR)
@@ -25,13 +25,6 @@ const char* ffDetectDisksImpl(FFlist* disks)
}
FFDisk* disk = ffListAdd(disks);
ffStrbufInitWS(&disk->mountpoint, mountpoint);
wchar_t volumeName[64];
if(GetVolumeNameForVolumeMountPointW(mountpoint, volumeName, sizeof(volumeName) / sizeof(*volumeName)))
ffStrbufInitWS(&disk->mountFrom, volumeName);
else
ffStrbufInit(&disk->mountFrom);
if(!GetDiskFreeSpaceExW(
mountpoint,
@@ -78,6 +71,17 @@ const char* ffDetectDisksImpl(FFlist* disks)
disk->type |= FF_DISK_VOLUME_TYPE_READONLY_BIT;
}
ffStrbufInitWS(&disk->mountpoint, mountpoint);
if (mountpoint[2] == L'\\' && mountpoint[3] == L'\0')
{
wchar_t volumeName[MAX_PATH + 1];
mountpoint[2] = L'\0';
if(QueryDosDeviceW(mountpoint, volumeName, sizeof(volumeName) / sizeof(*volumeName)))
ffStrbufInitWS(&disk->mountFrom, volumeName);
else
ffStrbufInit(&disk->mountFrom);
}
//Unsupported
disk->filesUsed = 0;
disk->filesTotal = 0;
-4
View File
@@ -63,10 +63,6 @@ const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus)
ffStrbufInit(&gpu->driver); // Ok for both Apple and Intel
ffCfDictGetString(properties, CFSTR("CFBundleIdentifier"), &gpu->driver);
int vram; // Supported on Intel
if(!ffCfDictGetInt(properties, CFSTR("VRAM,totalMB"), &vram))
gpu->dedicated.total = (uint64_t) vram * 1024 * 1024;
if(ffCfDictGetInt(properties, CFSTR("gpu-core-count"), &gpu->coreCount)) // For Apple
gpu->coreCount = FF_GPU_CORE_COUNT_UNSET;
+2
View File
@@ -111,6 +111,8 @@ static const char* getProductNameWithHwModel(const FFstrbuf* hwModel)
else if(ffStrbufStartsWithS(hwModel, "Mac"))
{
const char* version = hwModel->chars + strlen("Mac");
if(ffStrEquals(version, "15,13")) return "MacBook Air (15-inch, M3, 2024)";
if(ffStrEquals(version, "15,2")) return "MacBook Air (13-inch, M3, 2024)";
if(ffStrEquals(version, "15,3")) return "MacBook Pro (14-inch, Nov 2023, Two Thunderbolt / USB 4 ports)";
if(ffStrEquals(version, "15,4")) return "iMac (24-inch, 2023, Two Thunderbolt / USB 4 ports)";
if(ffStrEquals(version, "15,5")) return "iMac (24-inch, 2023, Two Thunderbolt / USB 4 ports, Two USB 3 ports)";
+28 -8
View File
@@ -40,10 +40,12 @@ static void addNewIp(FFlist* list, const char* name, const char* addr, int type,
switch (type)
{
case AF_INET:
ffStrbufSetS(&ip->ipv4, addr);
if (ip->ipv4.length) ffStrbufAppendC(&ip->ipv4, ',');
ffStrbufAppendS(&ip->ipv4, addr);
break;
case AF_INET6:
ffStrbufSetS(&ip->ipv6, addr);
if (ip->ipv6.length) ffStrbufAppendC(&ip->ipv6, ',');
ffStrbufAppendS(&ip->ipv6, addr);
break;
case -1:
ffStrbufSetS(&ip->mac, addr);
@@ -83,12 +85,15 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
char addressBuffer[INET_ADDRSTRLEN + 4];
inet_ntop(AF_INET, &ipv4->sin_addr, addressBuffer, INET_ADDRSTRLEN);
struct sockaddr_in* netmask = (struct sockaddr_in*) ifa->ifa_netmask;
int cidr = __builtin_popcount(inet_netof(netmask->sin_addr));
if (cidr != 0)
if (options->showType & FF_LOCALIP_TYPE_PREFIX_LEN_BIT)
{
size_t len = strlen(addressBuffer);
snprintf(addressBuffer + len, 4, "/%d", cidr);
struct sockaddr_in* netmask = (struct sockaddr_in*) ifa->ifa_netmask;
int cidr = __builtin_popcount(netmask->sin_addr.s_addr);
if (cidr != 0)
{
size_t len = strlen(addressBuffer);
snprintf(addressBuffer + len, 4, "/%d", cidr);
}
}
addNewIp(results, ifa->ifa_name, addressBuffer, AF_INET, isDefaultRoute);
@@ -99,8 +104,23 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
continue;
struct sockaddr_in6* ipv6 = (struct sockaddr_in6 *)ifa->ifa_addr;
char addressBuffer[INET6_ADDRSTRLEN];
char addressBuffer[INET6_ADDRSTRLEN + 4];
inet_ntop(AF_INET6, &ipv6->sin6_addr, addressBuffer, INET6_ADDRSTRLEN);
if (options->showType & FF_LOCALIP_TYPE_PREFIX_LEN_BIT)
{
struct sockaddr_in6* netmask = (struct sockaddr_in6*) ifa->ifa_netmask;
int cidr = 0;
static_assert(sizeof(netmask->sin6_addr) % sizeof(uint64_t) == 0, "");
for (uint32_t i = 0; i < sizeof(netmask->sin6_addr) / sizeof(uint64_t); ++i)
cidr += __builtin_popcountll(((uint64_t*) &netmask->sin6_addr)[i]);
if (cidr != 0)
{
size_t len = strlen(addressBuffer);
snprintf(addressBuffer + len, 4, "/%d", cidr);
}
}
addNewIp(results, ifa->ifa_name, addressBuffer, AF_INET6, isDefaultRoute);
}
#if defined(__FreeBSD__) || defined(__APPLE__)
+15 -6
View File
@@ -6,7 +6,7 @@
#include "util/windows/unicode.h"
#include "localip.h"
static void addNewIp(FFlist* list, const char* name, const char* value, int type, bool newIp, bool defaultRoute)
static void addNewIp(FFlist* list, const char* name, const char* addr, int type, bool newIp, bool defaultRoute)
{
FFLocalIpResult* ip = NULL;
@@ -27,13 +27,15 @@ static void addNewIp(FFlist* list, const char* name, const char* value, int type
switch (type)
{
case AF_INET:
ffStrbufSetS(&ip->ipv4, value);
if (ip->ipv4.length) ffStrbufAppendC(&ip->ipv4, ',');
ffStrbufAppendS(&ip->ipv4, addr);
break;
case AF_INET6:
ffStrbufSetS(&ip->ipv6, value);
if (ip->ipv6.length) ffStrbufAppendC(&ip->ipv6, ',');
ffStrbufAppendS(&ip->ipv6, addr);
break;
case -1:
ffStrbufSetS(&ip->mac, value);
ffStrbufSetS(&ip->mac, addr);
break;
}
}
@@ -108,7 +110,7 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
char addressBuffer[INET_ADDRSTRLEN + 4];
inet_ntop(AF_INET, &ipv4->sin_addr, addressBuffer, INET_ADDRSTRLEN);
if (ifa->OnLinkPrefixLength)
if ((options->showType & FF_LOCALIP_TYPE_PREFIX_LEN_BIT) && ifa->OnLinkPrefixLength)
{
size_t len = strlen(addressBuffer);
snprintf(addressBuffer + len, 4, "/%u", (unsigned) ifa->OnLinkPrefixLength);
@@ -120,8 +122,15 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results)
else if (ifa->Address.lpSockaddr->sa_family == AF_INET6)
{
SOCKADDR_IN6* ipv6 = (SOCKADDR_IN6*) ifa->Address.lpSockaddr;
char addressBuffer[INET6_ADDRSTRLEN];
char addressBuffer[INET6_ADDRSTRLEN + 4];
inet_ntop(AF_INET6, &ipv6->sin6_addr, addressBuffer, INET6_ADDRSTRLEN);
if ((options->showType & FF_LOCALIP_TYPE_PREFIX_LEN_BIT) && ifa->OnLinkPrefixLength)
{
size_t len = strlen(addressBuffer);
snprintf(addressBuffer + len, 4, "/%u", (unsigned) ifa->OnLinkPrefixLength);
}
addNewIp(results, name, addressBuffer, AF_INET6, newIp, isDefaultRoute);
newIp = false;
}
+1
View File
@@ -4,6 +4,7 @@
typedef struct FFPackagesResult
{
uint32_t am;
uint32_t apk;
uint32_t brew;
uint32_t brewCask;
+38
View File
@@ -253,6 +253,43 @@ static uint32_t getRpmFromLibrpm(void)
#endif //FF_HAVE_RPM
static uint32_t getAM(FFstrbuf* baseDir)
{
// #771
uint32_t baseDirLength = baseDir->length;
ffStrbufAppendS(baseDir, "/opt");
uint32_t optDirLength = baseDir->length;
uint32_t result = 0;
ffStrbufAppendS(baseDir, "/am/APP-MANAGER");
if (ffPathExists(baseDir->chars, FF_PATHTYPE_FILE))
{
++result; // `am` itself is counted as a package too
ffStrbufSubstrBefore(baseDir, optDirLength);
FF_AUTO_CLOSE_DIR DIR* dirp = opendir(baseDir->chars);
if(dirp)
{
struct dirent *entry;
while ((entry = readdir(dirp)) != NULL)
{
if (entry->d_name[0] == '.') continue;
if (entry->d_type == DT_DIR)
{
ffStrbufAppendF(baseDir, "/%s/AM-updater", entry->d_name);
if (ffPathExists(baseDir->chars, FF_PATHTYPE_FILE))
++result;
ffStrbufSubstrBefore(baseDir, optDirLength);
}
}
}
}
ffStrbufSubstrBefore(baseDir, baseDirLength);
return result;
}
static void getPackageCounts(FFstrbuf* baseDir, FFPackagesResult* packageCounts, FFPackagesOptions* options)
{
if (!(options->disabled & FF_PACKAGES_FLAG_APK_BIT)) packageCounts->apk += getNumStrings(baseDir, "/lib/apk/db/installed", "C:Q");
@@ -277,6 +314,7 @@ static void getPackageCounts(FFstrbuf* baseDir, FFPackagesResult* packageCounts,
}
if (!(options->disabled & FF_PACKAGES_FLAG_PALUDIS_BIT)) packageCounts->paludis += countFilesRecursive(baseDir, "/var/db/paludis/repositories", "environment.bz2");
if (!(options->disabled & FF_PACKAGES_FLAG_OPKG_BIT)) packageCounts->opkg += getNumStrings(baseDir, "/usr/lib/opkg/status", "Package:"); // openwrt
if (!(options->disabled & FF_PACKAGES_FLAG_AM_BIT)) packageCounts->am = getAM(baseDir);
}
static void getPackageCountsRegular(FFstrbuf* baseDir, FFPackagesResult* packageCounts, FFPackagesOptions* options)
+26 -10
View File
@@ -1,23 +1,35 @@
#include "publicip.h"
#include "common/networking.h"
#define FF_UNITIALIZED ((const char*)(uintptr_t) -1)
static FFNetworkingState state;
static int status = -1;
static const char* status = FF_UNITIALIZED;
void ffPreparePublicIp(FFPublicIpOptions* options)
{
if (status != -1)
if (status != FF_UNITIALIZED)
{
fputs("Error: this module can only be used once due to internal limitations\n", stderr);
exit(1);
}
state.timeout = options->timeout;
if (options->url.length == 0)
status = ffNetworkingSendHttpRequest(&state, "ipinfo.io", "/json", NULL);
else
{
FF_STRBUF_AUTO_DESTROY host = ffStrbufCreateCopy(&options->url);
ffStrbufSubstrAfterFirstS(&host, "://");
uint32_t hostStartIndex = ffStrbufFirstIndexS(&host, "://");
if (hostStartIndex < host.length)
{
if (hostStartIndex != 4 || !ffStrbufStartsWithIgnCaseS(&host, "http"))
{
fputs("Error: only http: protocol is supported. Use `Command` module with `curl` if needed\n", stderr);
exit(1);
}
ffStrbufSubstrAfter(&host, hostStartIndex + (strlen("://") - 1));
}
uint32_t pathStartIndex = ffStrbufFirstIndexC(&host, '/');
FF_STRBUF_AUTO_DESTROY path = ffStrbufCreate();
@@ -41,18 +53,21 @@ static inline void wrapYyjsonFree(yyjson_doc** doc)
const char* ffDetectPublicIp(FFPublicIpOptions* options, FFPublicIpResult* result)
{
if (status == -1)
if (status == FF_UNITIALIZED)
ffPreparePublicIp(options);
if (status == 0)
return "Failed to connect to an IP detection server";
if (status != NULL)
return status;
FF_STRBUF_AUTO_DESTROY response = ffStrbufCreateA(4096);
bool success = ffNetworkingRecvHttpResponse(&state, &response, options->timeout);
if (success) ffStrbufSubstrAfterFirstS(&response, "\r\n\r\n");
const char* error = ffNetworkingRecvHttpResponse(&state, &response);
if (error == NULL)
ffStrbufSubstrAfterFirstS(&response, "\r\n\r\n");
else
return error;
if (!success || response.length == 0)
return "Failed to receive the server response";
if (response.length == 0)
return "Empty server response received";
if (options->url.length == 0)
{
@@ -69,5 +84,6 @@ const char* ffDetectPublicIp(FFPublicIpOptions* options, FFPublicIpResult* resul
ffStrbufDestroy(&result->ip);
ffStrbufInitMove(&result->ip, &response);
ffStrbufTrimRightSpace(&result->ip);
return NULL;
}
@@ -145,13 +145,7 @@ static void detectXFCETerminal(FFTerminalFontResult* terminalFont)
});
}
if (!configFound)
{
ffStrbufSetStatic(&terminalFont->error, "Couldn't find xfce4/xfconf/xfce-perchannel-xml/xfce4-terminal.xml or xfce4/terminal/terminalrc");
return;
}
if(useSysFont.length == 0 || ffStrbufIgnCaseCompS(&useSysFont, "false") == 0)
if(configFound && (useSysFont.length == 0 || ffStrbufIgnCaseCompS(&useSysFont, "false") == 0))
{
if(fontName.length == 0)
ffStrbufAppendF(&terminalFont->error, "Couldn't find FontName in %s", path);
+30 -1
View File
@@ -400,6 +400,29 @@ FF_MAYBE_UNUSED static bool getTerminalVersionSt(FF_MAYBE_UNUSED FFstrbuf* exe,
return version->length > 0;
}
FF_MAYBE_UNUSED static bool getTerminalVersionLxterminal(FFstrbuf* exe, FFstrbuf* version)
{
if(!getExeVersionRaw(exe, version)) return false;
// lxterminal 0.3.2
ffStrbufSubstrAfterFirstC(version, ' ');
return version->length > 0;
}
FF_MAYBE_UNUSED static bool getTerminalVersionWeston(FF_MAYBE_UNUSED FFstrbuf* exe, FFstrbuf* version)
{
// weston-terminal doesn't report a version, use weston version instead
if(ffProcessAppendStdOut(version, (char* const[]){
"weston",
"--version",
NULL
})) return false;
//weston 8.0.0
ffStrbufSubstrAfterFirstC(version, ' ');
return version->length > 0;
}
static bool getTerminalVersionContour(FFstrbuf* exe, FFstrbuf* version)
{
const char* env = getenv("TERMINAL_VERSION_STRING");
@@ -410,7 +433,7 @@ static bool getTerminalVersionContour(FFstrbuf* exe, FFstrbuf* version)
}
if(!getExeVersionRaw(exe, version)) return false;
// Contour Terminal Emulator 0.3.12.262
ffStrbufSubstrAfterFirstC(version, ' ');
ffStrbufSubstrAfterLastC(version, ' ');
return version->length > 0;
}
@@ -525,6 +548,12 @@ bool fftsGetTerminalVersion(FFstrbuf* processName, FF_MAYBE_UNUSED FFstrbuf* exe
if(ffStrbufIgnCaseEqualS(processName, "st"))
return getTerminalVersionSt(exe, version);
if(ffStrbufIgnCaseEqualS(processName, "lxterminal"))
return getTerminalVersionLxterminal(exe, version);
if(ffStrbufIgnCaseEqualS(processName, "weston-terminal"))
return getTerminalVersionWeston(exe, version);
if(ffStrbufIgnCaseEqualS(processName, "urxvt") ||
ffStrbufIgnCaseEqualS(processName, "urxvtd") ||
ffStrbufIgnCaseEqualS(processName, "rxvt") ||
@@ -231,7 +231,6 @@ static pid_t getShellInfo(FFShellResult* result, pid_t pid)
ffStrEquals(name, "ltrace") ||
ffStrEquals(name, "perf") ||
ffStrEquals(name, "guake-wrapped") ||
ffStrEquals(name, "SessionLeader") || // #750
ffStrContainsIgnCase(name, "debug") ||
ffStrContainsIgnCase(name, "not-found") ||
ffStrEndsWith(name, ".sh")
@@ -281,6 +280,7 @@ static pid_t getTerminalInfo(FFTerminalResult* result, pid_t pid)
ffStrEquals(name, "xonsh") || // works in Linux but not in macOS because kernel returns `Python` in this case
ffStrEquals(name, "login") ||
ffStrEquals(name, "sshd") ||
ffStrEquals(name, "chezmoi") || // #762
#ifdef __linux__
ffStrStartsWith(name, "flatpak-") || // #707
#endif
@@ -342,6 +342,7 @@ static void getTerminalFromEnv(FFTerminalResult* result)
!ffStrbufEqualS(&result->processName, "systemd") &&
!ffStrbufEqualS(&result->processName, "init") &&
!ffStrbufEqualS(&result->processName, "(init)") &&
!ffStrbufEqualS(&result->processName, "SessionLeader") && // #750
#endif
!ffStrbufEqualS(&result->processName, "0")
@@ -143,7 +143,7 @@ static void setShellInfoDetails(FFShellResult* result)
ffStrbufSetS(&result->prettyName, "Windows PowerShell ISE");
else if(ffStrbufIgnCaseEqualS(&result->prettyName, "cmd"))
{
ffStrbufClear(&result->prettyName);
ffStrbufSetS(&result->prettyName, "CMD");
FF_AUTO_CLOSE_FD HANDLE snapshot = NULL;
while(!(snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, result->pid)) && GetLastError() == ERROR_BAD_LENGTH) {}
@@ -156,15 +156,13 @@ static void setShellInfoDetails(FFShellResult* result)
{
if(wcsncmp(module.szModule, L"clink_dll_", strlen("clink_dll_")) == 0)
{
ffStrbufAppendS(&result->prettyName, "CMD (with Clink ");
ffStrbufAppendS(&result->prettyName, " (with Clink ");
getProductVersion(module.szExePath, &result->prettyName);
ffStrbufAppendC(&result->prettyName, ')');
break;
}
}
}
if(result->prettyName.length == 0)
ffStrbufAppendS(&result->prettyName, "Command Prompt");
}
else if(ffStrbufIgnCaseEqualS(&result->prettyName, "nu"))
ffStrbufSetS(&result->prettyName, "nushell");
@@ -313,7 +311,8 @@ static uint32_t getTerminalInfo(FFTerminalResult* result, uint32_t pid)
ffStrbufSubstrBefore(&result->prettyName, result->prettyName.length - 4);
if(ffStrbufIgnCaseEqualS(&result->prettyName, "sihost") ||
ffStrbufIgnCaseEqualS(&result->prettyName, "explorer")
ffStrbufIgnCaseEqualS(&result->prettyName, "explorer") ||
ffStrbufIgnCaseEqualS(&result->prettyName, "wininit")
) {
// A CUI program created by Windows Explorer will spawn a conhost as its child.
// However the conhost process is just a placeholder;
@@ -344,7 +343,7 @@ static void setTerminalInfoDetails(FFTerminalResult* result)
: "Windows Terminal"
);
else if(ffStrbufIgnCaseEqualS(&result->prettyName, "conhost"))
ffStrbufSetStatic(&result->prettyName, "Console Window Host");
ffStrbufSetStatic(&result->prettyName, "Windows Console");
else if(ffStrbufIgnCaseEqualS(&result->prettyName, "Code"))
ffStrbufSetStatic(&result->prettyName, "Visual Studio Code");
else if(ffStrbufIgnCaseEqualS(&result->prettyName, "explorer"))
+15 -1
View File
@@ -32,7 +32,21 @@ void ffDetectVersion(FFVersionResult* version)
version->cmakeBuiltType = FASTFETCH_PROJECT_CMAKE_BUILD_TYPE;
version->compileTime = __DATE__ ", " __TIME__;
#ifdef __clang__
version->compiler = "clang " FF_STR(__clang_major__) "." FF_STR(__clang_minor__) "." FF_STR(__clang_patchlevel__);
version->compiler =
#ifdef _MSC_VER
"clang-cl " ;
#elif defined(__APPLE__) && defined(__apple_build_version__)
"Apple clang "
#else
"clang "
#endif
FF_STR(__clang_major__) "." FF_STR(__clang_minor__) "." FF_STR(__clang_patchlevel__)
#if defined(__APPLE__) && defined(__apple_build_version__)
" (" FF_STR(__apple_build_version__) ")"
#endif
;
#elif defined(__GNUC__)
version->compiler = "gcc " FF_STR(__GNUC__) "." FF_STR(__GNUC_MINOR__) "." FF_STR(__GNUC_PATCHLEVEL__);
#elif defined(_MSC_VER)
+18 -9
View File
@@ -1,16 +1,19 @@
#include "weather.h"
#define FF_UNITIALIZED ((const char*)(uintptr_t) -1)
static FFNetworkingState state;
static int status = -1;
static const char* status = FF_UNITIALIZED;
void ffPrepareWeather(FFWeatherOptions* options)
{
if (status != -1)
if (status != FF_UNITIALIZED)
{
fputs("Error: this module can only be used once due to internal limitations\n", stderr);
exit(1);
}
state.timeout = options->timeout;
FF_STRBUF_AUTO_DESTROY path = ffStrbufCreateS("/");
if (options->location.length)
ffStrbufAppend(&path, &options->location);
@@ -21,18 +24,24 @@ void ffPrepareWeather(FFWeatherOptions* options)
const char* ffDetectWeather(FFWeatherOptions* options, FFstrbuf* result)
{
if(status == -1)
if(status == FF_UNITIALIZED)
ffPrepareWeather(options);
if(status == 0)
return "Failed to connect to 'wttr.in'";
if(status != NULL)
return status;
ffStrbufEnsureFree(result, 4095);
bool success = ffNetworkingRecvHttpResponse(&state, result, options->timeout);
if (success) ffStrbufSubstrAfterFirstS(result, "\r\n\r\n");
const char* error = ffNetworkingRecvHttpResponse(&state, result);
if (error == NULL)
{
ffStrbufSubstrAfterFirstS(result, "\r\n\r\n");
ffStrbufTrimRightSpace(result);
}
else
return error;
if(!success || result->length == 0)
return "Failed to receive the server response";
if(result->length == 0)
return "Empty server response received";
return NULL;
}
+20 -22
View File
@@ -1,20 +1,15 @@
#include "fastfetch.h"
#include "common/commandoption.h"
#include "common/printing.h"
#include "common/parsing.h"
#include "common/io/io.h"
#include "common/time.h"
#include "common/jsonconfig.h"
#include "detection/version/version.h"
#include "util/stringUtils.h"
#include "util/mallocHelper.h"
#include "logo/logo.h"
#include "fastfetch_datatext.h"
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <inttypes.h>
#ifdef WIN32
#include "util/windows/getline.h"
@@ -824,7 +819,11 @@ static void run(FFdata* data)
ffPrintCommandOption(data, instance.state.resultDoc);
if (instance.state.resultDoc)
{
yyjson_mut_write_fp(stdout, instance.state.resultDoc, YYJSON_WRITE_INF_AND_NAN_AS_NULL | YYJSON_WRITE_PRETTY_TWO_SPACES, NULL, NULL);
//TODO should use YYJSON_WRITE_NEWLINE_AT_END when it is available
putchar('\n');
}
else
ffFinish();
}
@@ -842,24 +841,23 @@ static void writeConfigFile(FFdata* data, const FFstrbuf* filename)
ffOptionsGenerateLibraryJsonConfig(&instance.config.library, doc);
ffMigrateCommandOptionToJsonc(data, doc);
if (ffStrbufEqualS(filename, "-"))
yyjson_mut_write_fp(stdout, doc, YYJSON_WRITE_INF_AND_NAN_AS_NULL | YYJSON_WRITE_PRETTY_TWO_SPACES, NULL, NULL);
else
FILE *fp = stdout;
bool writeToStdout = ffStrbufEqualS(filename, "-");
if (!writeToStdout)
fp = fopen(filename->chars, "w");
bool ok = yyjson_mut_write_fp(fp, doc, YYJSON_WRITE_INF_AND_NAN_AS_NULL | YYJSON_WRITE_PRETTY_TWO_SPACES, NULL, NULL);
//TODO should use YYJSON_WRITE_NEWLINE_AT_END when it is available
fputc('\n', fp);
if (!ok)
{
size_t len;
FF_AUTO_FREE const char* str = yyjson_mut_write(doc, YYJSON_WRITE_INF_AND_NAN_AS_NULL | YYJSON_WRITE_PRETTY_TWO_SPACES, &len);
if (!str)
{
printf("Error: failed to generate config file\n");
exit(1);
}
if (ffWriteFileData(filename->chars, len, str))
printf("The generated config file has been written in `%s`\n", filename->chars);
else
{
printf("Error: failed to write file in `%s`\n", filename->chars);
exit(1);
}
fprintf(stderr, "Error: failed to generate config in `%s`\n", writeToStdout ? "stdout" : filename->chars);
exit(1);
}
if (ok && !writeToStdout)
{
fclose(fp);
printf("The generated config file has been written in `%s`\n", filename->chars);
}
yyjson_mut_doc_free(doc);
+1
View File
@@ -21,6 +21,7 @@ int main(void)
&options->title,
&options->separator,
&options->os,
&options->host,
&options->kernel,
&options->uptime,
&options->packages,
+1 -1
View File
@@ -1,4 +1,4 @@
${c1} A
A
ooo
ooooo
ooooooo
+13 -13
View File
@@ -413,7 +413,7 @@ static const FFlogo A[] = {
.lines = FASTFETCH_DATATEXT_LOGO_ARCO,
.colors = {
FF_COLOR_FG_BLUE,
FF_COLOR_FG_GREEN,
FF_COLOR_FG_WHITE,
},
.colorKeys = FF_COLOR_FG_BLUE,
.colorTitle = FF_COLOR_FG_BLUE,
@@ -425,7 +425,7 @@ static const FFlogo A[] = {
.lines = FASTFETCH_DATATEXT_LOGO_ARCO_SMALL,
.colors = {
FF_COLOR_FG_BLUE,
FF_COLOR_FG_GREEN,
FF_COLOR_FG_WHITE,
},
.colorKeys = FF_COLOR_FG_BLUE,
.colorTitle = FF_COLOR_FG_BLUE,
@@ -3299,6 +3299,17 @@ static const FFlogo P[] = {
FF_COLOR_FG_WHITE,
},
},
// Proxmox
{
.names = {"proxmox"},
.lines = FASTFETCH_DATATEXT_LOGO_PROXMOX,
.colors = {
FF_COLOR_FG_WHITE,
FF_COLOR_FG_256 "202"
},
.colorKeys = FF_COLOR_FG_WHITE,
.colorTitle = FF_COLOR_FG_256 "202",
},
// PuffOS
{
.names = {"PuffOS"},
@@ -3558,17 +3569,6 @@ static const FFlogo R[] = {
.colorKeys = FF_COLOR_FG_BLUE,
.colorTitle = FF_COLOR_FG_BLUE,
},
// Proxmox
{
.names = {"proxmox"},
.lines = FASTFETCH_DATATEXT_LOGO_PROXMOX,
.colors = {
FF_COLOR_FG_WHITE,
FF_COLOR_FG_256 "202"
},
.colorKeys = FF_COLOR_FG_WHITE,
.colorTitle = FF_COLOR_FG_256 "202",
},
// LAST
{},
};
+2 -4
View File
@@ -768,10 +768,8 @@ static bool printImageIfExistsSlowPath(FFLogoType type, bool printError)
requestData.characterPixelWidth = 1;
requestData.characterPixelHeight = 1;
if(
(type != FF_LOGO_TYPE_IMAGE_CHAFA || instance.config.logo.width == 0 || instance.config.logo.height == 0) &&
!getCharacterPixelDimensions(&requestData)
) {
if(!getCharacterPixelDimensions(&requestData))
{
if(printError)
fputs("Logo: getCharacterPixelDimensions() failed", stderr);
return false;
+11 -7
View File
@@ -13,7 +13,7 @@ void ffPrintCPU(FFCPUOptions* options)
FFCPUResult cpu;
cpu.temperature = FF_CPU_TEMP_UNSET;
cpu.coresPhysical = cpu.coresLogical = cpu.coresOnline = 0;
cpu.frequencyMax = cpu.frequencyMin = 0;
cpu.frequencyMin = cpu.frequencyMax = cpu.frequencyBase = 0.0/0.0;
ffStrbufInit(&cpu.name);
ffStrbufInit(&cpu.vendor);
@@ -48,8 +48,11 @@ void ffPrintCPU(FFCPUOptions* options)
if(cpu.coresOnline > 1)
ffStrbufAppendF(&str, " (%u)", cpu.coresOnline);
if(cpu.frequencyMax > 0.0)
ffStrbufAppendF(&str, " @ %.*f GHz", options->freqNdigits, cpu.frequencyMax);
double freq = cpu.frequencyMax;
if(freq != freq)
freq = cpu.frequencyBase;
if(freq == freq)
ffStrbufAppendF(&str, " @ %.*f GHz", options->freqNdigits, freq);
if(cpu.temperature == cpu.temperature) //FF_CPU_TEMP_UNSET
{
@@ -69,7 +72,7 @@ void ffPrintCPU(FFCPUOptions* options)
{FF_FORMAT_ARG_TYPE_UINT16, &cpu.coresPhysical},
{FF_FORMAT_ARG_TYPE_UINT16, &cpu.coresLogical},
{FF_FORMAT_ARG_TYPE_UINT16, &cpu.coresOnline},
{FF_FORMAT_ARG_TYPE_DOUBLE, &cpu.frequencyMin},
{FF_FORMAT_ARG_TYPE_DOUBLE, &cpu.frequencyBase},
{FF_FORMAT_ARG_TYPE_DOUBLE, &cpu.frequencyMax},
{FF_FORMAT_ARG_TYPE_STRBUF, &tempStr}
}));
@@ -143,7 +146,7 @@ void ffGenerateCPUJsonResult(FFCPUOptions* options, yyjson_mut_doc* doc, yyjson_
FFCPUResult cpu;
cpu.temperature = FF_CPU_TEMP_UNSET;
cpu.coresPhysical = cpu.coresLogical = cpu.coresOnline = 0;
cpu.frequencyMax = cpu.frequencyMin = 0;
cpu.frequencyMin = cpu.frequencyMax = cpu.frequencyBase = 0.0/0.0;
ffStrbufInit(&cpu.name);
ffStrbufInit(&cpu.vendor);
@@ -169,8 +172,9 @@ void ffGenerateCPUJsonResult(FFCPUOptions* options, yyjson_mut_doc* doc, yyjson_
yyjson_mut_obj_add_uint(doc, cores, "online", cpu.coresOnline);
yyjson_mut_val* frequency = yyjson_mut_obj_add_obj(doc, obj, "frequency");
yyjson_mut_obj_add_real(doc, frequency, "min", cpu.frequencyMin);
yyjson_mut_obj_add_real(doc, frequency, "base", cpu.frequencyBase);
yyjson_mut_obj_add_real(doc, frequency, "max", cpu.frequencyMax);
yyjson_mut_obj_add_real(doc, frequency, "min", cpu.frequencyMin);
yyjson_mut_obj_add_real(doc, obj, "temperature", cpu.temperature);
}
@@ -187,7 +191,7 @@ void ffPrintCPUHelpFormat(void)
"Physical core count",
"Logical core count",
"Online core count",
"Min frequency",
"Base frequency",
"Max frequency",
"Temperature (formatted)"
}));
+10 -2
View File
@@ -422,8 +422,16 @@ void ffGenerateDiskJsonResult(FFDiskOptions* options, yyjson_mut_doc* doc, yyjso
yyjson_mut_obj_add_uint(doc, bytes, "used", item->bytesUsed);
yyjson_mut_val* files = yyjson_mut_obj_add_obj(doc, obj, "files");
yyjson_mut_obj_add_uint(doc, files, "total", item->filesTotal);
yyjson_mut_obj_add_uint(doc, files, "used", item->filesUsed);
if (item->filesTotal == 0 && item->filesUsed == 0)
{
yyjson_mut_obj_add_null(doc, files, "total");
yyjson_mut_obj_add_null(doc, files, "used");
}
else
{
yyjson_mut_obj_add_uint(doc, files, "total", item->filesTotal);
yyjson_mut_obj_add_uint(doc, files, "used", item->filesUsed);
}
yyjson_mut_obj_add_strbuf(doc, obj, "filesystem", &item->filesystem);
yyjson_mut_obj_add_strbuf(doc, obj, "mountpoint", &item->mountpoint);
+22 -1
View File
@@ -174,6 +174,15 @@ bool ffParseLocalIpCommandOptions(FFLocalIpOptions* options, const char* key, co
return true;
}
if (ffStrEqualsIgnCase(subKey, "show-prefix-len"))
{
if (ffOptionParseBoolean(value))
options->showType |= FF_LOCALIP_TYPE_PREFIX_LEN_BIT;
else
options->showType &= ~FF_LOCALIP_TYPE_PREFIX_LEN_BIT;
return true;
}
if(ffStrEqualsIgnCase(subKey, "compact"))
{
if (ffOptionParseBoolean(value))
@@ -247,6 +256,15 @@ void ffParseLocalIpJsonObject(FFLocalIpOptions* options, yyjson_val* module)
continue;
}
if (ffStrEqualsIgnCase(key, "showPrefixLen"))
{
if (yyjson_get_bool(val))
options->showType |= FF_LOCALIP_TYPE_PREFIX_LEN_BIT;
else
options->showType &= ~FF_LOCALIP_TYPE_PREFIX_LEN_BIT;
continue;
}
if (ffStrEqualsIgnCase(key, "compact"))
{
if (yyjson_get_bool(val))
@@ -293,6 +311,9 @@ void ffGenerateLocalIpJsonConfig(FFLocalIpOptions* options, yyjson_mut_doc* doc,
if (options->showType & FF_LOCALIP_TYPE_LOOP_BIT)
yyjson_mut_obj_add_bool(doc, module, "showLoop", true);
if (options->showType & FF_LOCALIP_TYPE_PREFIX_LEN_BIT)
yyjson_mut_obj_add_bool(doc, module, "showPrefixLen", true);
if (options->showType & FF_LOCALIP_TYPE_COMPACT_BIT)
yyjson_mut_obj_add_bool(doc, module, "compact", true);
}
@@ -369,7 +390,7 @@ void ffInitLocalIpOptions(FFLocalIpOptions* options)
);
ffOptionInitModuleArg(&options->moduleArgs);
options->showType = FF_LOCALIP_TYPE_IPV4_BIT;
options->showType = FF_LOCALIP_TYPE_IPV4_BIT | FF_LOCALIP_TYPE_PREFIX_LEN_BIT;
ffStrbufInit(&options->namePrefix);
options->defaultRouteOnly =
#ifdef __ANDROID__
+6 -5
View File
@@ -7,12 +7,13 @@
typedef enum FFLocalIpType
{
FF_LOCALIP_TYPE_NONE,
FF_LOCALIP_TYPE_LOOP_BIT = 1 << 0,
FF_LOCALIP_TYPE_IPV4_BIT = 1 << 1,
FF_LOCALIP_TYPE_IPV6_BIT = 1 << 2,
FF_LOCALIP_TYPE_MAC_BIT = 1 << 3,
FF_LOCALIP_TYPE_LOOP_BIT = 1 << 0,
FF_LOCALIP_TYPE_IPV4_BIT = 1 << 1,
FF_LOCALIP_TYPE_IPV6_BIT = 1 << 2,
FF_LOCALIP_TYPE_MAC_BIT = 1 << 3,
FF_LOCALIP_TYPE_PREFIX_LEN_BIT = 1 << 4,
FF_LOCALIP_TYPE_COMPACT_BIT = 1 << 10,
FF_LOCALIP_TYPE_COMPACT_BIT = 1 << 10,
} FFLocalIpType;
typedef struct FFLocalIpOptions
+1
View File
@@ -26,6 +26,7 @@ typedef enum FFPackagesFlags
FF_PACKAGES_FLAG_SNAP_BIT = 1 << 16,
FF_PACKAGES_FLAG_WINGET_BIT = 1 << 17,
FF_PACKAGES_FLAG_XBPS_BIT = 1 << 18,
FF_PACKAGES_FLAG_AM_BIT = 1 << 19,
} FFPackagesFlags;
typedef struct FFPackagesOptions
+9 -2
View File
@@ -4,7 +4,7 @@
#include "modules/packages/packages.h"
#include "util/stringUtils.h"
#define FF_PACKAGES_NUM_FORMAT_ARGS 25
#define FF_PACKAGES_NUM_FORMAT_ARGS 26
void ffPrintPackages(FFPackagesOptions* options)
{
@@ -64,6 +64,7 @@ void ffPrintPackages(FFPackagesOptions* options)
FF_PRINT_PACKAGE(paludis)
FF_PRINT_PACKAGE(winget)
FF_PRINT_PACKAGE(opkg)
FF_PRINT_PACKAGE(am)
putchar('\n');
}
@@ -95,6 +96,7 @@ void ffPrintPackages(FFPackagesOptions* options)
{FF_FORMAT_ARG_TYPE_UINT, &counts.paludis},
{FF_FORMAT_ARG_TYPE_UINT, &counts.winget},
{FF_FORMAT_ARG_TYPE_UINT, &counts.opkg},
{FF_FORMAT_ARG_TYPE_UINT, &counts.am},
}));
}
@@ -141,6 +143,7 @@ bool ffParsePackagesCommandOptions(FFPackagesOptions* options, const char* key,
FF_TEST_PACKAGE_NAME(SNAP)
FF_TEST_PACKAGE_NAME(WINGET)
FF_TEST_PACKAGE_NAME(XBPS)
FF_TEST_PACKAGE_NAME(AM)
#undef FF_TEST_PACKAGE_NAME
if (end)
@@ -210,6 +213,7 @@ void ffParsePackagesJsonObject(FFPackagesOptions* options, yyjson_val* module)
FF_TEST_PACKAGE_NAME(SNAP)
FF_TEST_PACKAGE_NAME(WINGET)
FF_TEST_PACKAGE_NAME(XBPS)
FF_TEST_PACKAGE_NAME(AM)
#undef FF_TEST_PACKAGE_NAME
}
}
@@ -250,6 +254,7 @@ void ffGeneratePackagesJsonConfig(FFPackagesOptions* options, yyjson_mut_doc* do
FF_TEST_PACKAGE_NAME(SNAP)
FF_TEST_PACKAGE_NAME(WINGET)
FF_TEST_PACKAGE_NAME(XBPS)
FF_TEST_PACKAGE_NAME(AM)
#undef FF_TEST_PACKAGE_NAME
}
}
@@ -295,6 +300,7 @@ void ffGeneratePackagesJsonResult(FF_MAYBE_UNUSED FFPackagesOptions* options, yy
FF_APPEND_PACKAGE_COUNT(winget)
FF_APPEND_PACKAGE_COUNT(xbps)
FF_APPEND_PACKAGE_COUNT(opkg)
FF_APPEND_PACKAGE_COUNT(am)
yyjson_mut_obj_add_strbuf(doc, obj, "pacmanBranch", &counts.pacmanBranch);
}
@@ -325,7 +331,8 @@ void ffPrintPackagesHelpFormat(void)
"Number of pkgtool packages",
"Number of paludis packages",
"Number of winget packages",
"Number of opkg packages"
"Number of opkg packages",
"Number of am packages",
}));
}
+3 -2
View File
@@ -159,16 +159,17 @@ void ffStrbufAppendVF(FFstrbuf* strbuf, const char* format, va_list arguments)
strbuf->length += (uint32_t) written;
}
void ffStrbufAppendSUntilC(FFstrbuf* strbuf, const char* value, char until)
const char* ffStrbufAppendSUntilC(FFstrbuf* strbuf, const char* value, char until)
{
if(value == NULL)
return;
return NULL;
char* end = strchr(value, until);
if(end == NULL)
ffStrbufAppendS(strbuf, value);
else
ffStrbufAppendNS(strbuf, (uint32_t) (end - value), value);
return end;
}
void ffStrbufSetF(FFstrbuf* strbuf, const char* format, ...)
+1 -1
View File
@@ -44,7 +44,7 @@ void ffStrbufAppendNS(FFstrbuf* strbuf, uint32_t length, const char* value);
void ffStrbufAppendTransformS(FFstrbuf* strbuf, const char* value, int(*transformFunc)(int));
FF_C_PRINTF(2, 3) void ffStrbufAppendF(FFstrbuf* strbuf, const char* format, ...);
void ffStrbufAppendVF(FFstrbuf* strbuf, const char* format, va_list arguments);
void ffStrbufAppendSUntilC(FFstrbuf* strbuf, const char* value, char until);
const char* ffStrbufAppendSUntilC(FFstrbuf* strbuf, const char* value, char until);
void ffStrbufPrependNS(FFstrbuf* strbuf, uint32_t length, const char* value);
+14
View File
@@ -154,3 +154,17 @@ bool ffRegGetSubKey(HKEY hKey, uint32_t index, FFstrbuf* result, FFstrbuf* error
ffStrbufSetWS(result, resultW);
return true;
}
bool ffRegGetNSubKeys(HKEY hKey, uint32_t* result, FFstrbuf* error)
{
DWORD buffer;
if(RegQueryInfoKeyW(hKey, NULL, NULL, NULL, &buffer, NULL, NULL, NULL, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
{
if (error)
ffStrbufAppendS(error, "RegQueryInfoKeyW(hKey) failed");
return false;
}
*result = buffer;
return true;
}
+1
View File
@@ -21,5 +21,6 @@ bool ffRegReadData(HKEY hKey, const wchar_t* valueNameW, uint8_t** result, uint3
bool ffRegReadUint(HKEY hKey, const wchar_t* valueNameW, uint32_t* result, FFstrbuf* error);
bool ffRegReadUint64(HKEY hKey, const wchar_t* valueNameW, uint64_t* result, FFstrbuf* error);
bool ffRegGetSubKey(HKEY hKey, uint32_t index, FFstrbuf* result, FFstrbuf* error);
bool ffRegGetNSubKeys(HKEY hKey, uint32_t* result, FFstrbuf* error);
#endif
+24 -42
View File
@@ -1,54 +1,36 @@
//
// Include the necessary resources
//
#ifdef RC_INVOKED
#include <winuser.h>
#include <winver.h>
#include <ntdef.h>
#include "fastfetch_config.h"
#ifdef RC_INVOKED
//
// Set up debug information
//
#if DEBUG
#define VER_DEBUG VS_FF_DEBUG
#else
#define VER_DEBUG 0
#endif
#define FF_TO_STR1(str) #str
#define FF_TO_STR(str) FF_TO_STR1(str)
CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "manifest.xml"
// ------- version info -------------------------------------------------------
VS_VERSION_INFO VERSIONINFO
FILEVERSION FASTFETCH_PROJECT_VERSION_MAJOR,FASTFETCH_PROJECT_VERSION_MINOR,FASTFETCH_PROJECT_VERSION_PATCH,FASTFETCH_PROJECT_VERSION_TWEAK_NUM
PRODUCTVERSION FASTFETCH_PROJECT_VERSION_MAJOR,FASTFETCH_PROJECT_VERSION_MINOR,FASTFETCH_PROJECT_VERSION_PATCH,FASTFETCH_PROJECT_VERSION_TWEAK_NUM
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
FILEFLAGS (VER_DEBUG|VS_FF_PRERELEASE)
FILEOS VOS_NT
FILETYPE VFT_APP
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "Comments", FASTFETCH_PROJECT_HOMEPAGE_URL
VALUE "FileDescription", FF_TO_STR(FASTFETCH_TARGET_BINARY_NAME) " - " FASTFETCH_PROJECT_DESCRIPTION
VALUE "FileVersion", FASTFETCH_PROJECT_VERSION FASTFETCH_PROJECT_VERSION_TWEAK
VALUE "InternalName", FF_TO_STR(FASTFETCH_TARGET_BINARY_NAME) ".exe"
VALUE "LegalCopyright", FASTFETCH_PROJECT_LICENSE
VALUE "OriginalFilename", FF_TO_STR(FASTFETCH_TARGET_BINARY_NAME) ".exe"
VALUE "ProductName", FASTFETCH_PROJECT_NAME
VALUE "ProductVersion", FASTFETCH_PROJECT_VERSION FASTFETCH_PROJECT_VERSION_TWEAK
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x0409,1252
END
END
FILEVERSION FASTFETCH_PROJECT_VERSION_MAJOR,FASTFETCH_PROJECT_VERSION_MINOR,FASTFETCH_PROJECT_VERSION_PATCH,FASTFETCH_PROJECT_VERSION_TWEAK_NUM
PRODUCTVERSION FASTFETCH_PROJECT_VERSION_MAJOR,FASTFETCH_PROJECT_VERSION_MINOR,FASTFETCH_PROJECT_VERSION_PATCH,FASTFETCH_PROJECT_VERSION_TWEAK_NUM
FILEOS VOS_NT
FILETYPE VFT_APP
{
BLOCK "StringFileInfo" {
BLOCK "040904b0" {
VALUE "Comments", FASTFETCH_PROJECT_DESCRIPTION
VALUE "FileDescription", FF_TO_STR(FASTFETCH_TARGET_BINARY_NAME)
VALUE "FileVersion", FASTFETCH_PROJECT_VERSION FASTFETCH_PROJECT_VERSION_TWEAK
VALUE "InternalName", FF_TO_STR(FASTFETCH_TARGET_BINARY_NAME)
VALUE "LegalCopyright", FASTFETCH_PROJECT_LICENSE
VALUE "OriginalFilename", FF_TO_STR(FASTFETCH_TARGET_BINARY_NAME) ".exe"
VALUE "ProductName", FASTFETCH_PROJECT_NAME " - " FASTFETCH_PROJECT_DESCRIPTION
VALUE "ProductVersion", FASTFETCH_PROJECT_VERSION FASTFETCH_PROJECT_VERSION_TWEAK
VALUE "CompanyName", FASTFETCH_PROJECT_HOMEPAGE_URL
}
}
BLOCK "VarFileInfo" {
VALUE "Translation", 0x0409, 1200
}
}
#endif