Compare commits

..

52 Commits

Author SHA1 Message Date
Carter Li 6769410753 Merge pull request #794 from fastfetch-cli/dev
Release: v2.9.2
2024-04-16 10:45:39 +08:00
李通洲 40b9af6c36 Release: v2.9.2 2024-04-16 10:16:31 +08:00
李通洲 e63dfdd8b1 Packages: fix parsing of JSON config; fix wording of json_schema 2024-04-16 10:16:31 +08:00
李通洲 a6639d7211 JsonSchema: don't generate error at custom options 2024-04-16 09:55:21 +08:00
李通洲 3e251f602a Packages: fix parsing of option --packages-disabled 2024-04-16 09:50:24 +08:00
李通洲 ec25ca9fc7 Shell: ignore time 2024-04-15 20:01:40 +08:00
李通洲 396d20f2da Presets: fix compatibility of newer nerd fonts
Fix #792
2024-04-14 22:51:49 +08:00
李通洲 49181fd0bf Doc: update changelog 2024-04-14 18:03:34 +08:00
李通洲 5eb1dbe7bf Logo (Builtin): add openSUSE MicroOS
Fix #789
2024-04-14 18:02:59 +08:00
Anjia Wang 690e988cab Logo: fix logo color of AOSC OS (#791)
Resolve issue: https://github.com/fastfetch-cli/fastfetch/issues/790
2024-04-13 16:44:46 +08:00
Ulices fd41770d6e Fix: bad LainOS logo (#788)
- No need to scape '\'
- Replace a tab with spaces
2024-04-13 08:09:51 +08:00
李通洲 fb26cb1394 Disk (Android): fix build
Android does support `statx`, but it requires targeting newer ANDROID_API version to be available
2024-04-11 19:49:57 +08:00
李通洲 4e4efa67e6 Doc: update issue templates 2024-04-11 14:47:00 +08:00
李通洲 0dfb1b6bb1 Doc: add code of conduct 2024-04-11 14:10:25 +08:00
李通洲 bcbca38b1e Terminal: tidy 2024-04-10 10:11:31 +08:00
李通洲 3f0ccf802c Presets: fix #786 [ci skip] 2024-04-09 22:51:16 +08:00
李通洲 691cb4ac24 Global: use time string when generating JSON result 2024-04-09 20:47:06 +08:00
李通洲 282939f548 Disk (Windows): detect create time 2024-04-09 20:47:06 +08:00
李通洲 6f35b2f382 Disk (Linux): detect create time 2024-04-09 20:47:06 +08:00
李通洲 6700f63091 Disk (macOS): detect create time 2024-04-09 15:15:33 +08:00
李通洲 5c37ebec70 Doc: update changelog 2024-04-09 09:05:10 +08:00
李通洲 28a419d252 fastfetch: always provide trailing new line when generating JSON output 2024-04-09 09:01:28 +08:00
李通洲 95128ee95f 3rdparty (yyjson): upgrade to 0.9.0
To make use of `YYJSON_WRITE_NEWLINE_AT_END`
2024-04-09 08:58:04 +08:00
李通洲 c94180b3d2 Terminal (Windows): ignore far.exe
Ref: https://github.com/fastfetch-cli/fastfetch/issues/784#issuecomment-2043052512
2024-04-08 23:37:53 +08:00
李通洲 12ca1a0cf7 TerminalFont (Windows): better portable mode detection of Windows Terminal
`.portable` can be a folder.

Fix #784
2024-04-08 22:29:24 +08:00
apocelipes 67564dfa2c Platform: fix a memory leak (#782) 2024-04-08 09:10:03 +08:00
Carter Li a1e79a9522 Merge pull request #779 from fastfetch-cli/dev
Release v2.9.1
2024-04-07 20:49:37 +08:00
李通洲 e16f8ef349 Release: v2.9.1 2024-04-07 20:47:19 +08:00
李通洲 fd1a2072b3 Cursor: tidy 2024-04-07 20:44:17 +08:00
李通洲 aa45e70910 Revert "fastfetch: add the missing new-line in config files (#772)"
Fix #778

This reverts commit 4430b7145e.
2024-04-07 20:41:01 +08:00
李通洲 5374feb24b Cursor (Linux): support hyprcursor detection
Fix: #776
2024-04-07 20:09:35 +08:00
李通洲 12ac0ac7a9 Cursor: tidy 2024-04-07 20:09:05 +08:00
李通洲 3d78666ed3 Doc: update changelog
weston-terminal font detection was not pushed in v2.9.0
2024-04-06 17:37:31 +08:00
Carter Li dd2cc116bd TerminalFont (Linux): support weston-terminal 2024-04-06 16:56:17 +08:00
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
54 changed files with 787 additions and 190 deletions
+7 -5
View File
@@ -13,6 +13,7 @@ assignees: ''
* What happened:
* What should happen:
* Fastfetch version used: <!-- please use the latest version, if possible -->
* Did it work in an older version: <!-- if yes, which version -->
* Where did you get the binary: <!-- Github Release / Github Actions / Installed with a package manager (What package manager) / Built from source yourself -->
* Does this issue still occurs in [the latest dev build](https://github.com/fastfetch-cli/fastfetch/actions/)?
@@ -41,18 +42,19 @@ Output of `fastfetch --list-features`:
//paste here
```
## If fastfatch crashed
## If fastfatch crashed or freezed
Paste the stacktrace here. You may get it with:
```
$ gdb -q -ex 'set confirm off' -ex run -ex 'bt full' -ex quit --args /path/to/fastfetch
```shell
# You may need Ctrl+C to stop the process if it freezes
gdb -q -ex 'set confirm off' -ex run -ex 'bt full' -ex quit --args /path/to/fastfetch
```
If you are able to identify which module crashed, the strace can be helpful too
```
$ strace /path/to/fastfetch --multithreading false --structure {MODULE} --pipe
```shell
strace /path/to/fastfetch --multithreading false -s {MODULE} --pipe
```
If you cannot do the instructions above, please upload the core dump file:
+22 -4
View File
@@ -7,10 +7,28 @@ assignees: ''
---
<!-- Before requesting a new feature, please try `fastfetch -c all.jsonc` to see if it has been supported -->
## Before requesting a new feature
# Current state:
* A lot of features are not enabled by default. Please try `fastfetch --list-modules` and `fastfetch -c all.jsonc` to see if it has been supported
* Fastfetch supports `Command` module, which can be used to grab output from a custom shell script. Please check if it fits your needs
# Wanted state:
```jsonc
// ~/.config/fastfetch/fastfetch.jsonc
{
"modules": [
{
"type": "command",
"text": "/path/to/your/script",
"key": "Feature Title"
}
]
}
```
# Why the change is sensible:
## Wanted features:
<!-- Your features here -->
## Motivation:
<!-- Your motivation here -->
+2
View File
@@ -7,6 +7,8 @@ assignees: ''
---
Tip: A logo can be displayed by fastfetch without getting into fastfetch's official repo. For highly customized logo for personal use, it's recommended to keep it locally. Please refer to https://github.com/fastfetch-cli/fastfetch/wiki/Migrate-Neofetch-Logo-To-Fastfetch
# OS
```
Paste content of /etc/os-release here. If this file doesn't exist, describe a way to identify the distro.
+47 -6
View File
@@ -1,11 +1,47 @@
# 2.8.10
# 2.9.2
Changes:
* 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
* To make use of the newly introduced `yyjson` flag `YYJSON_WRITE_NEWLINE_AT_END`, fastfetch now requires `yyjson` 0.9.0 or later
Features:
* Always add a final new-line when generating JSON output
* Detect partition create time, which can be used as OS installation time (Disk)
* Print time string when generating JSON result instead of UNIX epoch time number, which is more human-readable
Bugfixes:
* Fix a memory leak
* Better portable mode detection of Windows Terminal (TerminalFont, Windows)
* Fix parsing of option `--packages-disabled` (Packages)
* Don't use command `time` as a shell (Shell)
Logos:
* Add openSUSE MicroOS
* Fix color of AOSC OS
# 2.9.1
Features:
* Support weston-terminal (missed commit in v2.9.0) (TerminalFont, Linux)
* Support hyprcursor detection (#776, Cursor, Linux)
Bugfixes:
* Fix `fastfetch --gen-config` raises SIGSEGV when `~/.config/fastfetch` doesn't exist. Regression of `2.9.0` (#778)
# 2.9.0
Features:
* Support Lxterminal version detection (Terminal, Linux)
* Support weston-terminal version detection (Terminal, 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)
@@ -17,6 +53,11 @@ Bugfixes:
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
+8 -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.10
VERSION 2.9.2
LANGUAGES C
DESCRIPTION "Fast neofetch-like system information tool"
HOMEPAGE_URL "https://github.com/fastfetch-cli/fastfetch"
@@ -699,6 +699,9 @@ check_function_exists(wcwidth HAVE_WCWIDTH)
if(NOT HAVE_WCWIDTH)
list(APPEND LIBFASTFETCH_SRC src/3rdparty/mk_wcwidch/wcwidth.c)
endif()
if(LINUX)
check_function_exists(statx HAVE_STATX)
endif()
if(ENABLE_SYSTEM_YYJSON)
find_package(yyjson)
@@ -762,6 +765,10 @@ elseif(APPLE)
target_compile_definitions(libfastfetch PUBLIC _DARWIN_C_SOURCE)
endif()
if(HAVE_STATX)
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_STATX)
endif()
if(HAVE_WCWIDTH)
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_WCWIDTH)
endif()
+133
View File
@@ -0,0 +1,133 @@
# Contributor Covenant Code of Conduct
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, caste, color, religion, or sexual
identity and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our
community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the overall
community
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or advances of
any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email address,
without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official email address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
[INSERT CONTACT METHOD].
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series of
actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or permanent
ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within the
community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.1, available at
[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].
Community Impact Guidelines were inspired by
[Mozilla's code of conduct enforcement ladder][Mozilla CoC].
For answers to common questions about this code of conduct, see the FAQ at
[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at
[https://www.contributor-covenant.org/translations][translations].
[homepage]: https://www.contributor-covenant.org
[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
[Mozilla CoC]: https://github.com/mozilla/diversity
[FAQ]: https://www.contributor-covenant.org/faq
[translations]: https://www.contributor-covenant.org/translations
+6
View File
@@ -1,3 +1,9 @@
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
+1 -1
View File
@@ -1 +1 @@
fastfetch_2.8.9_source.buildinfo universe/utils optional
fastfetch_2.8.10_source.buildinfo universe/utils optional
+34 -4
View File
@@ -730,7 +730,6 @@
},
{
"type": "object",
"additionalProperties": false,
"description": "Run module with custom configurations",
"required": [
"type"
@@ -1438,6 +1437,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",
@@ -1572,9 +1576,35 @@
"description": "List installed package managers and count of installed packages"
},
"disabled": {
"description": "A colon separated list of package managers to be disabled when detecting",
"type": "string",
"default": "winget"
"description": "List of package managers to be disabled when detecting",
"type": "array",
"items": {
"type": "string",
"enum": [
"am",
"apk",
"brew",
"choco",
"dpkg",
"emerge",
"eopkg",
"flatpak",
"macports",
"nix",
"opkg",
"pacman",
"paludis",
"pkg",
"pkgtool",
"rpm",
"scoop",
"snap",
"winget",
"xbps"
],
"uniqueItems": true
},
"default": ["winget"]
},
"key": {
"$ref": "#/$defs/key"
+3 -3
View File
@@ -84,17 +84,17 @@
},
{
"type": "host",
"key": " PC",
"key": "󰌢 PC",
"keyColor": "green"
},
{
"type": "cpu",
"key": "│ ├",
"key": "│ ├󰻠",
"keyColor": "green"
},
{
"type": "gpu",
"key": "│ ├",
"key": "│ ├󰍛",
"keyColor": "green"
},
{
+3 -3
View File
@@ -23,7 +23,7 @@
"type": "os"
},
{
"key": " Machine ",
"key": " 󰌢 Machine ",
"keyColor": "green",
"type": "host"
},
@@ -64,12 +64,12 @@
"type": "terminal"
},
{
"key": " CPU ",
"key": " 󰻠 CPU ",
"keyColor": "yellow",
"type": "cpu"
},
{
"key": " GPU ",
"key": " 󰍛 GPU ",
"keyColor": "blue",
"type": "gpu"
},
+3 -3
View File
@@ -19,15 +19,15 @@
},
{
"type": "host",
"key": " "
"key": " 󰌢"
},
{
"type": "cpu",
"key": " "
"key": " 󰻠"
},
{
"type": "gpu",
"key": " "
"key": " 󰍛"
},
{
"type": "disk",
+1 -2
View File
@@ -14,8 +14,7 @@
},
{
"type": "icons",
"key": "I",
"format": "{5}"
"key": "I"
},
{
"type": "font",
+3 -3
View File
@@ -15,17 +15,17 @@
"modules": [
{
"type": "host",
"key": "╭─",
"key": "╭─󰌢",
"keyColor": "green"
},
{
"type": "cpu",
"key": "├─",
"key": "├─󰻠",
"keyColor": "green"
},
{
"type": "gpu",
"key": "├─",
"key": "├─󰍛",
"keyColor": "green"
},
{
+3 -3
View File
@@ -77,17 +77,17 @@
"break",
{
"type": "host",
"key": " PC",
"key": "󰌢 PC",
"keyColor": "green"
},
{
"type": "cpu",
"key": "├",
"key": "├󰻠",
"keyColor": "green"
},
{
"type": "gpu",
"key": "├",
"key": "├󰍛",
"keyColor": "green"
},
{
+1 -1
View File
@@ -33,7 +33,7 @@
},
{
"type": "memory",
"key": ""
"key": "󰻠"
},
{
"type": "packages",
+1 -1
View File
@@ -12,7 +12,7 @@
"uptime",
{
"type": "battery",
"format": "{/4}{-}{/}{4}%{?5} [{5}]{?}"
"format": "{/4}{-}{/}{4}{?5} [{5}]{?}"
},
"break",
"packages",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"home": "https://github.com/ibireme/yyjson",
"license": "MIT ( embed in source )",
"version": "0.8.0",
"version": "0.9.0",
"author": "ibireme"
}
+31 -5
View File
@@ -1407,6 +1407,7 @@ bool yyjson_mut_doc_set_val_pool_size(yyjson_mut_doc *doc, size_t count) {
void yyjson_mut_doc_free(yyjson_mut_doc *doc) {
if (doc) {
yyjson_alc alc = doc->alc;
memset(&doc->alc, 0, sizeof(alc));
unsafe_yyjson_str_pool_release(&doc->str_pool, &alc);
unsafe_yyjson_val_pool_release(&doc->val_pool, &alc);
alc.free(alc.ctx, doc);
@@ -8309,13 +8310,15 @@ static_inline u8 *yyjson_write_single(yyjson_val *val,
bool cpy = (enc_table == enc_table_cpy);
bool esc = has_write_flag(ESCAPE_UNICODE) != 0;
bool inv = has_write_flag(ALLOW_INVALID_UNICODE) != 0;
bool newline = has_write_flag(NEWLINE_AT_END) != 0;
const usize end_len = 2; /* '\n' and '\0' */
switch (unsafe_yyjson_get_type(val)) {
case YYJSON_TYPE_RAW:
str_len = unsafe_yyjson_get_len(val);
str_ptr = (const u8 *)unsafe_yyjson_get_str(val);
check_str_len(str_len);
incr_len(str_len + 1);
incr_len(str_len + end_len);
cur = write_raw(cur, str_ptr, str_len);
break;
@@ -8323,7 +8326,7 @@ static_inline u8 *yyjson_write_single(yyjson_val *val,
str_len = unsafe_yyjson_get_len(val);
str_ptr = (const u8 *)unsafe_yyjson_get_str(val);
check_str_len(str_len);
incr_len(str_len * 6 + 4);
incr_len(str_len * 6 + 2 + end_len);
if (likely(cpy) && unsafe_yyjson_get_subtype(val)) {
cur = write_string_noesc(cur, str_ptr, str_len);
} else {
@@ -8333,7 +8336,7 @@ static_inline u8 *yyjson_write_single(yyjson_val *val,
break;
case YYJSON_TYPE_NUM:
incr_len(32);
incr_len(32 + end_len);
cur = write_number(cur, val, flg);
if (unlikely(!cur)) goto fail_num;
break;
@@ -8349,13 +8352,13 @@ static_inline u8 *yyjson_write_single(yyjson_val *val,
break;
case YYJSON_TYPE_ARR:
incr_len(4);
incr_len(2 + end_len);
byte_copy_2(cur, "[]");
cur += 2;
break;
case YYJSON_TYPE_OBJ:
incr_len(4);
incr_len(2 + end_len);
byte_copy_2(cur, "{}");
cur += 2;
break;
@@ -8364,6 +8367,7 @@ static_inline u8 *yyjson_write_single(yyjson_val *val,
goto fail_type;
}
if (newline) *cur++ = '\n';
*cur = '\0';
*dat_len = (usize)(cur - hdr);
memset(err, 0, sizeof(yyjson_write_err));
@@ -8436,6 +8440,7 @@ static_inline u8 *yyjson_write_minify(const yyjson_val *root,
bool cpy = (enc_table == enc_table_cpy);
bool esc = has_write_flag(ESCAPE_UNICODE) != 0;
bool inv = has_write_flag(ALLOW_INVALID_UNICODE) != 0;
bool newline = has_write_flag(NEWLINE_AT_END) != 0;
alc_len = root->uni.ofs / sizeof(yyjson_val);
alc_len = alc_len * YYJSON_WRITER_ESTIMATED_MINIFY_RATIO + 64;
@@ -8542,6 +8547,11 @@ ctn_end:
}
doc_end:
if (newline) {
incr_len(2);
*(cur - 1) = '\n';
cur++;
}
*--cur = '\0';
*dat_len = (usize)(cur - hdr);
memset(err, 0, sizeof(yyjson_write_err));
@@ -8615,6 +8625,7 @@ static_inline u8 *yyjson_write_pretty(const yyjson_val *root,
bool esc = has_write_flag(ESCAPE_UNICODE) != 0;
bool inv = has_write_flag(ALLOW_INVALID_UNICODE) != 0;
usize spaces = has_write_flag(PRETTY_TWO_SPACES) ? 2 : 4;
bool newline = has_write_flag(NEWLINE_AT_END) != 0;
alc_len = root->uni.ofs / sizeof(yyjson_val);
alc_len = alc_len * YYJSON_WRITER_ESTIMATED_PRETTY_RATIO + 64;
@@ -8745,6 +8756,10 @@ ctn_end:
}
doc_end:
if (newline) {
incr_len(2);
*cur++ = '\n';
}
*cur = '\0';
*dat_len = (usize)(cur - hdr);
memset(err, 0, sizeof(yyjson_write_err));
@@ -8977,6 +8992,7 @@ static_inline u8 *yyjson_mut_write_minify(const yyjson_mut_val *root,
bool cpy = (enc_table == enc_table_cpy);
bool esc = has_write_flag(ESCAPE_UNICODE) != 0;
bool inv = has_write_flag(ALLOW_INVALID_UNICODE) != 0;
bool newline = has_write_flag(NEWLINE_AT_END) != 0;
alc_len = estimated_val_num * YYJSON_WRITER_ESTIMATED_MINIFY_RATIO + 64;
alc_len = size_align_up(alc_len, sizeof(yyjson_mut_write_ctx));
@@ -9087,6 +9103,11 @@ ctn_end:
}
doc_end:
if (newline) {
incr_len(2);
*(cur - 1) = '\n';
cur++;
}
*--cur = '\0';
*dat_len = (usize)(cur - hdr);
err->code = YYJSON_WRITE_SUCCESS;
@@ -9162,6 +9183,7 @@ static_inline u8 *yyjson_mut_write_pretty(const yyjson_mut_val *root,
bool esc = has_write_flag(ESCAPE_UNICODE) != 0;
bool inv = has_write_flag(ALLOW_INVALID_UNICODE) != 0;
usize spaces = has_write_flag(PRETTY_TWO_SPACES) ? 2 : 4;
bool newline = has_write_flag(NEWLINE_AT_END) != 0;
alc_len = estimated_val_num * YYJSON_WRITER_ESTIMATED_PRETTY_RATIO + 64;
alc_len = size_align_up(alc_len, sizeof(yyjson_mut_write_ctx));
@@ -9296,6 +9318,10 @@ ctn_end:
}
doc_end:
if (newline) {
incr_len(2);
*cur++ = '\n';
}
*cur = '\0';
*dat_len = (usize)(cur - hdr);
err->code = YYJSON_WRITE_SUCCESS;
+35 -21
View File
@@ -527,16 +527,16 @@ extern "C" {
#define YYJSON_VERSION_MAJOR 0
/** The minor version of yyjson. */
#define YYJSON_VERSION_MINOR 8
#define YYJSON_VERSION_MINOR 9
/** The patch version of yyjson. */
#define YYJSON_VERSION_PATCH 0
/** The version of yyjson in hex: `(major << 16) | (minor << 8) | (patch)`. */
#define YYJSON_VERSION_HEX 0x000800
#define YYJSON_VERSION_HEX 0x000900
/** The version string of yyjson. */
#define YYJSON_VERSION_STRING "0.8.0"
#define YYJSON_VERSION_STRING "0.9.0"
/** The version of yyjson in hex, same as `YYJSON_VERSION_HEX`. */
yyjson_api uint32_t yyjson_version(void);
@@ -738,7 +738,7 @@ typedef uint32_t yyjson_read_flag;
- Report error if double number is infinity.
- Report error if string contains invalid UTF-8 character or BOM.
- Report error on trailing commas, comments, inf and nan literals. */
static const yyjson_read_flag YYJSON_READ_NOFLAG = 0 << 0;
static const yyjson_read_flag YYJSON_READ_NOFLAG = 0;
/** Read the input data in-situ.
This option allows the reader to modify and use input data to store string
@@ -1067,7 +1067,7 @@ typedef uint32_t yyjson_write_flag;
- Report error on inf or nan number.
- Report error on invalid UTF-8 string.
- Do not escape unicode or slash. */
static const yyjson_write_flag YYJSON_WRITE_NOFLAG = 0 << 0;
static const yyjson_write_flag YYJSON_WRITE_NOFLAG = 0;
/** Write JSON pretty with 4 space indent. */
static const yyjson_write_flag YYJSON_WRITE_PRETTY = 1 << 0;
@@ -1096,6 +1096,10 @@ static const yyjson_write_flag YYJSON_WRITE_ALLOW_INVALID_UNICODE = 1 << 5;
This flag will override `YYJSON_WRITE_PRETTY` flag. */
static const yyjson_write_flag YYJSON_WRITE_PRETTY_TWO_SPACES = 1 << 6;
/** Adds a newline character `\n` at the end of the JSON.
This can be helpful for text editors or NDJSON. */
static const yyjson_write_flag YYJSON_WRITE_NEWLINE_AT_END = 1 << 7;
/** Result code for JSON writer */
@@ -3695,7 +3699,7 @@ yyjson_api_inline bool yyjson_mut_obj_add_strcpy(yyjson_mut_doc *doc,
The `len` should be the length of the `val`, in bytes.
This function allows duplicated key in one object.
@warning The key/value strings are not copied, you should keep these strings
@warning The key strings are not copied, you should keep these strings
unmodified for the lifetime of this JSON document. */
yyjson_api_inline bool yyjson_mut_obj_add_strncpy(yyjson_mut_doc *doc,
yyjson_mut_val *obj,
@@ -4829,6 +4833,7 @@ yyjson_api_inline size_t yyjson_doc_get_val_count(yyjson_doc *doc) {
yyjson_api_inline void yyjson_doc_free(yyjson_doc *doc) {
if (doc) {
yyjson_alc alc = doc->alc;
memset(&doc->alc, 0, sizeof(alc));
if (doc->str_pool) alc.free(alc.ctx, doc->str_pool);
alc.free(alc.ctx, doc);
}
@@ -5668,6 +5673,7 @@ yyjson_api_inline yyjson_mut_val *yyjson_mut_bool(yyjson_mut_doc *doc,
if (yyjson_likely(doc)) {
yyjson_mut_val *val = unsafe_yyjson_mut_val(doc, 1);
if (yyjson_likely(val)) {
_val = !!_val;
val->tag = YYJSON_TYPE_BOOL | (uint8_t)((uint8_t)_val << 3);
return val;
}
@@ -5920,7 +5926,8 @@ yyjson_api_inline yyjson_mut_val *yyjson_mut_arr(yyjson_mut_doc *doc) {
yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_with_bool(
yyjson_mut_doc *doc, const bool *vals, size_t count) {
yyjson_mut_arr_with_func({
val->tag = YYJSON_TYPE_BOOL | (uint8_t)((uint8_t)vals[i] << 3);
bool _val = !!vals[i];
val->tag = YYJSON_TYPE_BOOL | (uint8_t)((uint8_t)_val << 3);
});
}
@@ -6872,6 +6879,7 @@ yyjson_api_inline bool yyjson_mut_obj_add_bool(yyjson_mut_doc *doc,
const char *_key,
bool _val) {
yyjson_mut_obj_add_func({
_val = !!_val;
val->tag = YYJSON_TYPE_BOOL | (uint8_t)((uint8_t)(_val) << 3);
});
}
@@ -7730,33 +7738,39 @@ yyjson_api_inline bool yyjson_ptr_get_bool(
}
/**
Set provided `value` if the JSON Pointer (RFC 6901) exists and is type uint.
Returns true if value at `ptr` exists and is the correct type, otherwise false.
Set provided `value` if the JSON Pointer (RFC 6901) exists and is an integer
that fits in `uint64_t`. Returns true if successful, otherwise false.
*/
yyjson_api_inline bool yyjson_ptr_get_uint(
yyjson_val *root, const char *ptr, uint64_t *value) {
yyjson_val *val = yyjson_ptr_get(root, ptr);
if (value && yyjson_is_uint(val)) {
*value = unsafe_yyjson_get_uint(val);
return true;
} else {
return false;
if (value && val) {
uint64_t ret = val->uni.u64;
if (unsafe_yyjson_is_uint(val) ||
(unsafe_yyjson_is_sint(val) && !(ret >> 63))) {
*value = ret;
return true;
}
}
return false;
}
/**
Set provided `value` if the JSON Pointer (RFC 6901) exists and is type sint.
Returns true if value at `ptr` exists and is the correct type, otherwise false.
Set provided `value` if the JSON Pointer (RFC 6901) exists and is an integer
that fits in `int64_t`. Returns true if successful, otherwise false.
*/
yyjson_api_inline bool yyjson_ptr_get_sint(
yyjson_val *root, const char *ptr, int64_t *value) {
yyjson_val *val = yyjson_ptr_get(root, ptr);
if (value && yyjson_is_sint(val)) {
*value = unsafe_yyjson_get_sint(val);
return true;
} else {
return false;
if (value && val) {
int64_t ret = val->uni.i64;
if (unsafe_yyjson_is_sint(val) ||
(unsafe_yyjson_is_uint(val) && ret >= 0)) {
*value = ret;
return true;
}
}
return false;
}
/**
+5 -5
View File
@@ -100,19 +100,19 @@ void ffParseGTK(FFstrbuf* buffer, const FFstrbuf* gtk2, const FFstrbuf* gtk3, co
{
if(gtk2->length > 0 && gtk3->length > 0 && gtk4->length > 0)
{
if((ffStrbufIgnCaseComp(gtk2, gtk3) == 0) && (ffStrbufIgnCaseComp(gtk2, gtk4) == 0))
if((ffStrbufIgnCaseEqual(gtk2, gtk3)) && (ffStrbufIgnCaseEqual(gtk2, gtk4)))
{
ffStrbufAppend(buffer, gtk4);
ffStrbufAppendS(buffer, " [GTK2/3/4]");
}
else if(ffStrbufIgnCaseComp(gtk2, gtk3) == 0)
else if(ffStrbufIgnCaseEqual(gtk2, gtk3))
{
ffStrbufAppend(buffer, gtk3);
ffStrbufAppendS(buffer, " [GTK2/3], ");
ffStrbufAppend(buffer, gtk4);
ffStrbufAppendS(buffer, " [GTK4]");
}
else if(ffStrbufIgnCaseComp(gtk3, gtk4) == 0)
else if(ffStrbufIgnCaseEqual(gtk3, gtk4))
{
ffStrbufAppend(buffer, gtk2);
ffStrbufAppendS(buffer, " [GTK2], ");
@@ -131,7 +131,7 @@ void ffParseGTK(FFstrbuf* buffer, const FFstrbuf* gtk2, const FFstrbuf* gtk3, co
}
else if(gtk2->length > 0 && gtk3->length > 0)
{
if(ffStrbufIgnCaseComp(gtk2, gtk3) == 0)
if(ffStrbufIgnCaseEqual(gtk2, gtk3))
{
ffStrbufAppend(buffer, gtk3);
ffStrbufAppendS(buffer, " [GTK2/3]");
@@ -146,7 +146,7 @@ void ffParseGTK(FFstrbuf* buffer, const FFstrbuf* gtk2, const FFstrbuf* gtk3, co
}
else if(gtk3->length > 0 && gtk4->length > 0)
{
if(ffStrbufIgnCaseComp(gtk3, gtk4) == 0)
if(ffStrbufIgnCaseEqual(gtk3, gtk4))
{
ffStrbufAppend(buffer, gtk4);
ffStrbufAppendS(buffer, " [GTK3/4]");
+36 -2
View File
@@ -1,12 +1,12 @@
#pragma once
#include <stdint.h>
#include <time.h>
#include <stdio.h>
#ifdef _WIN32
#include <synchapi.h>
#include <profileapi.h>
#include <sysinfoapi.h>
#else
#include <time.h>
#endif
static inline uint64_t ffTimeGetTick() //In msec
@@ -45,3 +45,37 @@ static inline void ffTimeSleep(uint32_t msec)
nanosleep(&(struct timespec){ msec / 1000, (long) (msec % 1000) * 1000000 }, NULL);
#endif
}
#ifdef _WIN32
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wformat"
#endif
// Not thread-safe
static inline const char* ffTimeToFullStr(uint64_t msec)
{
if (msec == 0) return "";
time_t tsec = (time_t) (msec / 1000);
const struct tm* tm = localtime(&tsec);
static char buf[32];
strftime(buf, __builtin_strlen("0000-00-00T00:00:00") + 1, "%FT%T", tm);
snprintf(buf + __builtin_strlen("0000-00-00T00:00:00"), __builtin_strlen(".000") + 1, ".%03u", (unsigned) (msec % 1000));
strftime(buf + __builtin_strlen("0000-00-00T00:00:00.000"), __builtin_strlen("+0000") + 1, "%z", tm);
return buf;
}
// Not thread-safe
static inline const char* ffTimeToShortStr(uint64_t msec)
{
if (msec == 0) return "";
time_t tsec = (time_t) (msec / 1000);
static char buf[32];
strftime(buf, sizeof(buf), "%F %T", localtime(&tsec));
return buf;
}
#ifdef _WIN32
#pragma GCC diagnostic pop
#endif
+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",
+19 -4
View File
@@ -68,18 +68,33 @@ static bool detectCursorFromEnv(FFCursorResult* result)
return true;
}
static bool detectCursorHyprcursor(FFCursorResult* result)
{
const char* hyprcursor_theme = getenv("HYPRCURSOR_THEME");
if(!ffStrSet(hyprcursor_theme))
return false;
ffStrbufAppendS(&result->theme, hyprcursor_theme);
ffStrbufAppendS(&result->size, getenv("HYPRCURSOR_SIZE"));
return true;
}
void ffDetectCursor(FFCursorResult* result)
{
const FFDisplayServerResult* wmde = ffConnectDisplayServer();
if(ffStrbufCompS(&wmde->wmPrettyName, FF_WM_PRETTY_WSLG) == 0)
if(ffStrbufEqualS(&wmde->wmPrettyName, FF_WM_PRETTY_WSLG))
ffStrbufAppendS(&result->error, "WSLg uses native windows cursor");
else if(ffStrbufIgnCaseCompS(&wmde->wmProtocolName, FF_WM_PROTOCOL_TTY) == 0)
else if(ffStrbufIgnCaseEqualS(&wmde->wmProtocolName, FF_WM_PROTOCOL_TTY))
ffStrbufAppendS(&result->error, "Cursor isn't supported in TTY");
else if(ffStrbufIgnCaseCompS(&wmde->dePrettyName, FF_DE_PRETTY_PLASMA) == 0)
else if(ffStrbufIgnCaseEqualS(&wmde->dePrettyName, FF_DE_PRETTY_PLASMA))
detectCursorFromConfigFile("kcminputrc", "cursorTheme =", "Breeze", "cursorSize =", "24", result);
else if(ffStrbufStartsWithIgnCaseS(&wmde->dePrettyName, FF_DE_PRETTY_LXQT))
else if(ffStrbufIgnCaseEqualS(&wmde->dePrettyName, FF_DE_PRETTY_LXQT))
detectCursorFromConfigFile("lxqt/session.conf", "cursor_theme =", "Adwaita", "cursor_size =", "24", result);
else if(ffStrbufIgnCaseEqualS(&wmde->wmPrettyName, FF_WM_PRETTY_HYPRLAND) && detectCursorHyprcursor(result))
return;
else if(
!detectCursorGTK(result) &&
!detectCursorFromEnv(result) &&
+2
View File
@@ -17,6 +17,8 @@ typedef struct FFDisk
uint32_t filesUsed;
uint32_t filesTotal;
uint64_t createTime;
} FFDisk;
/**
+5
View File
@@ -3,6 +3,7 @@
#include "util/stringUtils.h"
#include <sys/mount.h>
#include <sys/stat.h>
#ifdef __FreeBSD__
#include <libgeom.h>
@@ -130,6 +131,10 @@ const char* ffDetectDisksImpl(FFlist* disks)
if(fs->f_flags & MNT_RDONLY)
disk->type |= FF_DISK_VOLUME_TYPE_READONLY_BIT;
struct stat st;
if(stat(fs->f_mntonname, &st) == 0)
disk->createTime = (uint64_t)((st.st_birthtimespec.tv_sec * 1000) + (st.st_birthtimespec.tv_nsec / 1000000));
}
return NULL;
+8 -1
View File
@@ -6,9 +6,9 @@
#include <limits.h>
#include <ctype.h>
#include <dirent.h>
#include <mntent.h>
#include <sys/stat.h>
#include <sys/statvfs.h>
#include <mntent.h>
#include <sys/mount.h>
#ifdef __USE_LARGEFILE64
@@ -241,6 +241,13 @@ static void detectStats(FFDisk* disk)
if(fs.f_flag & ST_RDONLY)
disk->type |= FF_DISK_VOLUME_TYPE_READONLY_BIT;
disk->createTime = 0;
#ifdef FF_HAVE_STATX
struct statx stx;
if (statx(0, disk->mountpoint.chars, 0, STATX_BTIME, &stx) == 0 && (stx.stx_mask & STATX_BTIME))
disk->createTime = (uint64_t)((stx.stx_btime.tv_sec * 1000) + (stx.stx_btime.tv_nsec / 1000000));
#endif
}
const char* ffDetectDisksImpl(FFlist* disks)
+6
View File
@@ -71,6 +71,12 @@ const char* ffDetectDisksImpl(FFlist* disks)
disk->type |= FF_DISK_VOLUME_TYPE_READONLY_BIT;
}
WIN32_FILE_ATTRIBUTE_DATA data;
if(GetFileAttributesExW(mountpoint, GetFileExInfoStandard, &data) && data.ftCreationTime.dwHighDateTime > 0)
disk->createTime = (*(uint64_t*) &data.ftCreationTime - 116444736000000000ull) / 10000ull;
else
disk->createTime = 0;
ffStrbufInitWS(&disk->mountpoint, mountpoint);
if (mountpoint[2] == L'\\' && mountpoint[3] == L'\0')
{
@@ -21,6 +21,7 @@
#define FF_WM_PRETTY_XFWM4 "Xfwm4"
#define FF_WM_PRETTY_OPENBOX "Openbox"
#define FF_WM_PRETTY_I3 "i3"
#define FF_WM_PRETTY_HYPRLAND "Hyprland"
#define FF_WM_PRETTY_WAYFIRE "Wayfire"
#define FF_WM_PRETTY_SWAY "Sway"
#define FF_WM_PRETTY_BSPWM "bspwm"
+5
View File
@@ -52,6 +52,9 @@ static const char* parseEnv(void)
if(getenv("TDE_FULL_SESSION") != NULL)
return "Trinity";
if(getenv("HYPRLAND_CMD") != NULL)
return "Hyprland";
#ifdef __linux__
if(
getenv("WAYLAND_DISPLAY") != NULL &&
@@ -116,6 +119,8 @@ static void applyPrettyNameIfWM(FFDisplayServerResult* result, const char* name)
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_ICEWM);
else if(ffStrEqualsIgnCase(name, "dtwm"))
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_DTWM);
else if(ffStrEqualsIgnCase(name, "hyprland"))
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_HYPRLAND);
}
static void applyNameIfWM(FFDisplayServerResult* result, const char* processName)
+2 -2
View File
@@ -151,9 +151,9 @@ const FFQtResult* ffDetectQt(void)
const FFDisplayServerResult* wmde = ffConnectDisplayServer();
if(ffStrbufIgnCaseCompS(&wmde->dePrettyName, FF_DE_PRETTY_PLASMA) == 0)
if(ffStrbufIgnCaseEqualS(&wmde->dePrettyName, FF_DE_PRETTY_PLASMA))
detectPlasma(&result);
else if(ffStrbufIgnCaseCompS(&wmde->dePrettyName, FF_DE_PRETTY_LXQT) == 0)
else if(ffStrbufIgnCaseEqualS(&wmde->dePrettyName, FF_DE_PRETTY_LXQT))
detectLXQt(&result);
return &result;
+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)
+3 -3
View File
@@ -160,7 +160,7 @@ static const char* detectFromWTImpl(FFstrbuf* content, FFstrbuf* name, double* s
#include <shlobj.h>
#endif
static void detectFromWindowsTeriminal(const FFstrbuf* terminalExe, FFTerminalFontResult* terminalFont)
static void detectFromWindowsTerminal(const FFstrbuf* terminalExe, FFTerminalFontResult* terminalFont)
{
//https://learn.microsoft.com/en-us/windows/terminal/install#settings-json-file
FF_STRBUF_AUTO_DESTROY json = ffStrbufCreate();
@@ -174,7 +174,7 @@ static void detectFromWindowsTeriminal(const FFstrbuf* terminalExe, FFTerminalFo
char* pathEnd = jsonPath + strlen(jsonPath);
strncpy(pathEnd, ".portable", sizeof(jsonPath) - (size_t) (pathEnd - jsonPath) - 1);
if(ffPathExists(jsonPath, FF_PATHTYPE_FILE))
if(ffPathExists(jsonPath, FF_PATHTYPE_ANY))
{
strncpy(pathEnd, "settings\\settings.json", sizeof(jsonPath) - (size_t) (pathEnd - jsonPath) - 1);
if(!ffAppendFileBuffer(jsonPath, &json))
@@ -432,7 +432,7 @@ static bool detectTerminalFontCommon(const FFTerminalResult* terminal, FFTermina
//Used by both Linux (WSL) and Windows
else if(ffStrbufIgnCaseEqualS(&terminal->processName, "Windows Terminal") ||
ffStrbufIgnCaseEqualS(&terminal->processName, "WindowsTerminal.exe"))
detectFromWindowsTeriminal(&terminal->exe, terminalFont);
detectFromWindowsTerminal(&terminal->exe, terminalFont);
#endif
else
@@ -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);
@@ -331,6 +325,19 @@ static void detectWarp(FFTerminalFontResult* terminalFont)
}
}
static void detectWestonTerminal(FFTerminalFontResult* terminalFont)
{
FF_STRBUF_AUTO_DESTROY font = ffStrbufCreate();
FF_STRBUF_AUTO_DESTROY size = ffStrbufCreate();
ffParsePropFileConfigValues("weston.ini", 2, (FFpropquery[]) {
{"font=", &font},
{"font-size=", &size},
});
if (!font.length) ffStrbufSetStatic(&font, "DejaVu Sans Mono");
if (!size.length) ffStrbufSetStatic(&size, "14");
ffFontInitValues(&terminalFont->font, font.chars, size.chars);
}
void ffDetectTerminalFontPlatform(const FFTerminalResult* terminal, FFTerminalFontResult* terminalFont)
{
if(ffStrbufIgnCaseEqualS(&terminal->processName, "konsole"))
@@ -361,4 +368,6 @@ void ffDetectTerminalFontPlatform(const FFTerminalResult* terminal, FFTerminalFo
detectSt(terminalFont, terminal->pid);
else if(ffStrbufIgnCaseEqualS(&terminal->processName, "warp"))
detectWarp(terminalFont);
else if(ffStrbufIgnCaseEqualS(&terminal->processName, "weston-terminal"))
detectWestonTerminal(terminalFont);
}
+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,6 +231,7 @@ static pid_t getShellInfo(FFShellResult* result, pid_t pid)
ffStrEquals(name, "ltrace") ||
ffStrEquals(name, "perf") ||
ffStrEquals(name, "guake-wrapped") ||
ffStrEquals(name, "time") ||
ffStrContainsIgnCase(name, "debug") ||
ffStrContainsIgnCase(name, "not-found") ||
ffStrEndsWith(name, ".sh")
@@ -98,16 +98,14 @@ static uint32_t getShellInfo(FFShellResult* result, uint32_t pid)
if(
ffStrbufIgnCaseEqualS(&result->prettyName, "sudo") ||
ffStrbufIgnCaseEqualS(&result->prettyName, "su") ||
ffStrbufIgnCaseEqualS(&result->prettyName, "doas") ||
ffStrbufIgnCaseEqualS(&result->prettyName, "strace") ||
ffStrbufIgnCaseEqualS(&result->prettyName, "sshd") ||
ffStrbufIgnCaseEqualS(&result->prettyName, "gdb") ||
ffStrbufIgnCaseEqualS(&result->prettyName, "lldb") ||
ffStrbufIgnCaseEqualS(&result->prettyName, "guake-wrapped") ||
ffStrbufIgnCaseEqualS(&result->prettyName, "python") || // python on windows generates shim executables
ffStrbufIgnCaseEqualS(&result->prettyName, "fastfetch") || // scoop warps the real binaries with a "shim" exe
ffStrbufIgnCaseEqualS(&result->prettyName, "flashfetch") ||
ffStrbufContainIgnCaseS(&result->prettyName, "debug") ||
ffStrbufContainIgnCaseS(&result->prettyName, "time") ||
ffStrbufStartsWithIgnCaseS(&result->prettyName, "ConEmu") // https://github.com/fastfetch-cli/fastfetch/issues/488#issuecomment-1619982014
) {
ffStrbufClear(&result->processName);
@@ -260,6 +258,7 @@ static bool detectDefaultTerminal(FFTerminalResult* result)
if(ffPathExists(result->exe.chars, FF_PATHTYPE_FILE))
{
result->exeName = result->exe.chars + ffStrbufLastIndexC(&result->exe, '\\') + 1;
ffStrbufSet(&result->exePath, &result->exe);
}
else
{
@@ -294,7 +293,7 @@ static uint32_t getTerminalInfo(FFTerminalResult* result, uint32_t pid)
while (pid != 0 && getProcessInfo(pid, &ppid, &result->processName, &result->exe, &result->exeName, &result->exePath, &hasGui))
{
if(!hasGui)
if(!hasGui || ffStrbufIgnCaseEqualS(&result->processName, "far.exe")) // Far includes GUI objects...
{
//We are in nested shell
ffStrbufClear(&result->processName);
+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)
+3 -6
View File
@@ -819,10 +819,7 @@ 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);
putchar('\n');
}
yyjson_mut_write_fp(stdout, instance.state.resultDoc, YYJSON_WRITE_INF_AND_NAN_AS_NULL | YYJSON_WRITE_PRETTY_TWO_SPACES | YYJSON_WRITE_NEWLINE_AT_END, NULL, NULL);
else
ffFinish();
}
@@ -841,11 +838,11 @@ static void writeConfigFile(FFdata* data, const FFstrbuf* filename)
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);
yyjson_mut_write_fp(stdout, doc, YYJSON_WRITE_INF_AND_NAN_AS_NULL | YYJSON_WRITE_PRETTY_TWO_SPACES | YYJSON_WRITE_NEWLINE_AT_END, NULL, NULL);
else
{
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);
FF_AUTO_FREE const char* str = yyjson_mut_write(doc, YYJSON_WRITE_INF_AND_NAN_AS_NULL | YYJSON_WRITE_PRETTY_TWO_SPACES | YYJSON_WRITE_NEWLINE_AT_END, &len);
if (!str)
{
printf("Error: failed to generate config file\n");
+1
View File
@@ -21,6 +21,7 @@ int main(void)
&options->title,
&options->separator,
&options->os,
&options->host,
&options->kernel,
&options->uptime,
&options->packages,
+5 -5
View File
@@ -1,8 +1,8 @@
${c2} /==\\
\\==/
${c2} /==\
\==/
${c1} · · · · · · ·
· · · · · · · · · ·
· · · ${c2}.-======-.${c1}· · · ·
· · · ${c2}.-======-.${c1}· · · ·
${c2} .::.${c1} ·${c2}.-============-.${c1}· ${c2}.::.
.:==:${c1}· ${c2}.:===:'${c1}. ·· .${c2}':===:.${c1} ·${c2}:==:.
.:===:${c1} · ${c2}:===.${c1} · ${c3}.--.${c1} · ${c2}.===:${c1} · ${c2}:===:.
@@ -12,8 +12,8 @@ ${c2} .::.${c1} ·${c2}.-============-.${c1}· ${c2}.::.
':===:${c1} · ${c2}:===.${c1} · ${c3}'--'${c1} · ${c2}.===:${c1} · ${c2}:===:'
':==:${c1}· ${c2}':===:.${c1}' ·· '${c2}.:===:'${c1} ·${c2}:==:'
'::'${c1} · ${c2}'===-. .-==='${c1} · ${c2}'::'
${c2}/==\\${c1} · · · ${c2}:=== ===:${c1} · · · ${c2}/==\\
\\==/${c1} · · ·${c2}:===${c1} ·${c2}===:${c1}· · · ${c2}\\==/${c2}
${c2}/==\${c1} · · · ${c2}:=== ===:${c1} · · · ${c2}/==\
\==/${c1} · · ·${c2}:===${c1} ·${c2}===:${c1}· · · ${c2}\==/${c2}
.-. ${c1}· ${c2}:===${c1}· ${c2}===:${c1} ·${c2} ${c2}.-.
.===. .=== ===. .===.
.======== ========.
+10
View File
@@ -0,0 +1,10 @@
⣀⣠⣴⣶⣶⣿⣿⣿⣿⣶⣶⣦⣄⣀
⢀⣴⣾⣿⠿⠛⠉⠉ ⠉⠉⠛⠿⣿⣷⣦⡀
⣴⣿⡿⠋ ⠙⢿⣿⣦
⣾⣿⡟ ⣠⣴⣶⣿⣿⣶⣦⣄ ⢻⣿⣷
⣠⣤⣤⣤⣤⣤⣤⣼⣿⣿ ⣼⣿⡟⠉ ⠉⢻⣿⣧ ⣿⣿⣧⣤⣤⣤⣤⣤⣤⣄
⠙⠛⠛⠛⠛⠛⠛⢻⣿⣿ ⢻⣿⣧⡀ ⢀⣼⣿⡟ ⣿⣿⡟⠛⠛⠛⠛⠛⠛⠋
⢿⣿⣇ ⠙⠿⣿⣿⣿⣿⠿⠋ ⣸⣿⡿
⠈⢻⣿⣧⣀ ⣀⣾⣿⡟⠁
⠙⠻⣿⣷⣦⣄⣀ ⣀⣠⣴⣾⣿⠟⠋
⠉⠛⠿⢿⣿⣿⣿⣿⣿⣿⡿⠿⠛⠉
+9 -1
View File
@@ -224,7 +224,7 @@ static const FFlogo A[] = {
.colors = {
FF_COLOR_FG_BLUE,
FF_COLOR_FG_BLACK,
FF_COLOR_FG_GREEN,
FF_COLOR_FG_RED,
FF_COLOR_FG_YELLOW,
},
},
@@ -2932,6 +2932,14 @@ static const FFlogo O[] = {
.colorKeys = FF_COLOR_FG_GREEN,
.colorTitle = FF_COLOR_FG_GREEN,
},
// openSuseMicroOS
{
.names = {"opensuse-microos", "opensuse_microos"},
.lines = FASTFETCH_DATATEXT_LOGO_OPENSUSE_MICROOS,
.colors = {
FF_COLOR_FG_GREEN,
},
},
// OpenSuseLeap
{
.names = {"opensuse_leap", "open_suse_leap", "opensuse-leap", "open-suse-leap", "suse_leap", "suse-leap", "opensuseleap"},
+11 -1
View File
@@ -2,11 +2,12 @@
#include "common/jsonconfig.h"
#include "common/parsing.h"
#include "common/percent.h"
#include "common/time.h"
#include "detection/disk/disk.h"
#include "modules/disk/disk.h"
#include "util/stringUtils.h"
#define FF_DISK_NUM_FORMAT_ARGS 11
#define FF_DISK_NUM_FORMAT_ARGS 12
#pragma GCC diagnostic ignored "-Wsign-conversion"
static void printDisk(FFDiskOptions* options, const FFDisk* disk)
@@ -112,6 +113,7 @@ static void printDisk(FFDiskOptions* options, const FFDisk* disk)
bool isExternal = !!(disk->type & FF_DISK_VOLUME_TYPE_EXTERNAL_BIT);
bool isHidden = !!(disk->type & FF_DISK_VOLUME_TYPE_HIDDEN_BIT);
bool isReadOnly = !!(disk->type & FF_DISK_VOLUME_TYPE_READONLY_BIT);
FF_PRINT_FORMAT_CHECKED(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY, FF_DISK_NUM_FORMAT_ARGS, ((FFformatarg[]) {
{FF_FORMAT_ARG_TYPE_STRBUF, &usedPretty},
{FF_FORMAT_ARG_TYPE_STRBUF, &totalPretty},
@@ -124,6 +126,7 @@ static void printDisk(FFDiskOptions* options, const FFDisk* disk)
{FF_FORMAT_ARG_TYPE_STRBUF, &disk->filesystem},
{FF_FORMAT_ARG_TYPE_STRBUF, &disk->name},
{FF_FORMAT_ARG_TYPE_BOOL, &isReadOnly},
{FF_FORMAT_ARG_TYPE_STRING, ffTimeToShortStr(disk->createTime)},
}));
}
}
@@ -448,6 +451,12 @@ void ffGenerateDiskJsonResult(FFDiskOptions* options, yyjson_mut_doc* doc, yyjso
yyjson_mut_arr_add_str(doc, typeArr, "Hidden");
if(item->type & FF_DISK_VOLUME_TYPE_READONLY_BIT)
yyjson_mut_arr_add_str(doc, typeArr, "Read-only");
const char* pstr = ffTimeToFullStr(item->createTime);
if (*pstr)
yyjson_mut_obj_add_strcpy(doc, obj, "createTime", pstr);
else
yyjson_mut_obj_add_null(doc, obj, "createTime");
}
FF_LIST_FOR_EACH(FFDisk, item, disks)
@@ -473,6 +482,7 @@ void ffPrintDiskHelpFormat(void)
"Filesystem",
"Label / name",
"True if read-only",
"Create time in local timezone",
}));
}
+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
+111 -43
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},
}));
}
@@ -121,32 +123,63 @@ bool ffParsePackagesCommandOptions(FFPackagesOptions* options, const char* key,
*end = '\0';
#define FF_TEST_PACKAGE_NAME(name) else if (ffStrEqualsIgnCase(start, #name)) { options->disabled |= FF_PACKAGES_FLAG_ ## name ## _BIT; }
if (false);
FF_TEST_PACKAGE_NAME(APK)
FF_TEST_PACKAGE_NAME(BREW)
FF_TEST_PACKAGE_NAME(CHOCO)
FF_TEST_PACKAGE_NAME(DPKG)
FF_TEST_PACKAGE_NAME(EMERGE)
FF_TEST_PACKAGE_NAME(EOPKG)
FF_TEST_PACKAGE_NAME(FLATPAK)
FF_TEST_PACKAGE_NAME(NIX)
FF_TEST_PACKAGE_NAME(OPKG)
FF_TEST_PACKAGE_NAME(PACMAN)
FF_TEST_PACKAGE_NAME(PALUDIS)
FF_TEST_PACKAGE_NAME(PKG)
FF_TEST_PACKAGE_NAME(PKGTOOL)
FF_TEST_PACKAGE_NAME(MACPORTS)
FF_TEST_PACKAGE_NAME(RPM)
FF_TEST_PACKAGE_NAME(SCOOP)
FF_TEST_PACKAGE_NAME(SNAP)
FF_TEST_PACKAGE_NAME(WINGET)
FF_TEST_PACKAGE_NAME(XBPS)
switch (toupper(start[0]))
{
case 'A': if (false);
FF_TEST_PACKAGE_NAME(APK)
FF_TEST_PACKAGE_NAME(AM)
break;
case 'B': if (false);
FF_TEST_PACKAGE_NAME(BREW)
break;
case 'C': if (false);
FF_TEST_PACKAGE_NAME(CHOCO)
break;
case 'D': if (false);
FF_TEST_PACKAGE_NAME(DPKG)
break;
case 'E': if (false);
FF_TEST_PACKAGE_NAME(EMERGE)
FF_TEST_PACKAGE_NAME(EOPKG)
break;
case 'F': if (false);
FF_TEST_PACKAGE_NAME(FLATPAK)
break;
case 'M': if (false);
FF_TEST_PACKAGE_NAME(MACPORTS)
break;
case 'N': if (false);
FF_TEST_PACKAGE_NAME(NIX)
break;
case 'O': if (false);
FF_TEST_PACKAGE_NAME(OPKG)
break;
case 'P': if (false);
FF_TEST_PACKAGE_NAME(PACMAN)
FF_TEST_PACKAGE_NAME(PKG)
FF_TEST_PACKAGE_NAME(PKGTOOL)
FF_TEST_PACKAGE_NAME(PALUDIS)
break;
case 'R': if (false);
FF_TEST_PACKAGE_NAME(RPM)
break;
case 'S': if (false);
FF_TEST_PACKAGE_NAME(SCOOP)
FF_TEST_PACKAGE_NAME(SNAP)
break;
case 'W': if (false);
FF_TEST_PACKAGE_NAME(WINGET)
break;
case 'X': if (false);
FF_TEST_PACKAGE_NAME(XBPS)
break;
}
#undef FF_TEST_PACKAGE_NAME
if (end)
{
start = end + 1;
end = strchr(end, ':');
end = strchr(start, ':');
}
else
break;
@@ -190,28 +223,60 @@ void ffParsePackagesJsonObject(FFPackagesOptions* options, yyjson_val* module)
const char* flag = yyjson_get_str(flagObj);
#define FF_TEST_PACKAGE_NAME(name) else if (ffStrEqualsIgnCase(flag, #name)) { options->disabled |= FF_PACKAGES_FLAG_ ## name ## _BIT; }
if (false);
FF_TEST_PACKAGE_NAME(APK)
FF_TEST_PACKAGE_NAME(BREW)
FF_TEST_PACKAGE_NAME(CHOCO)
FF_TEST_PACKAGE_NAME(DPKG)
FF_TEST_PACKAGE_NAME(EMERGE)
FF_TEST_PACKAGE_NAME(EOPKG)
FF_TEST_PACKAGE_NAME(FLATPAK)
FF_TEST_PACKAGE_NAME(NIX)
FF_TEST_PACKAGE_NAME(OPKG)
FF_TEST_PACKAGE_NAME(PACMAN)
FF_TEST_PACKAGE_NAME(PALUDIS)
FF_TEST_PACKAGE_NAME(PKG)
FF_TEST_PACKAGE_NAME(PKGTOOL)
FF_TEST_PACKAGE_NAME(MACPORTS)
FF_TEST_PACKAGE_NAME(RPM)
FF_TEST_PACKAGE_NAME(SCOOP)
FF_TEST_PACKAGE_NAME(SNAP)
FF_TEST_PACKAGE_NAME(WINGET)
FF_TEST_PACKAGE_NAME(XBPS)
switch (toupper(flag[0]))
{
case 'A': if (false);
FF_TEST_PACKAGE_NAME(APK)
FF_TEST_PACKAGE_NAME(AM)
break;
case 'B': if (false);
FF_TEST_PACKAGE_NAME(BREW)
break;
case 'C': if (false);
FF_TEST_PACKAGE_NAME(CHOCO)
break;
case 'D': if (false);
FF_TEST_PACKAGE_NAME(DPKG)
break;
case 'E': if (false);
FF_TEST_PACKAGE_NAME(EMERGE)
FF_TEST_PACKAGE_NAME(EOPKG)
break;
case 'F': if (false);
FF_TEST_PACKAGE_NAME(FLATPAK)
break;
case 'M': if (false);
FF_TEST_PACKAGE_NAME(MACPORTS)
break;
case 'N': if (false);
FF_TEST_PACKAGE_NAME(NIX)
break;
case 'O': if (false);
FF_TEST_PACKAGE_NAME(OPKG)
break;
case 'P': if (false);
FF_TEST_PACKAGE_NAME(PACMAN)
FF_TEST_PACKAGE_NAME(PKG)
FF_TEST_PACKAGE_NAME(PKGTOOL)
FF_TEST_PACKAGE_NAME(PALUDIS)
break;
case 'R': if (false);
FF_TEST_PACKAGE_NAME(RPM)
break;
case 'S': if (false);
FF_TEST_PACKAGE_NAME(SCOOP)
FF_TEST_PACKAGE_NAME(SNAP)
break;
case 'W': if (false);
FF_TEST_PACKAGE_NAME(WINGET)
break;
case 'X': if (false);
FF_TEST_PACKAGE_NAME(XBPS)
break;
}
#undef FF_TEST_PACKAGE_NAME
}
continue;
}
}
@@ -250,6 +315,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 +361,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 +392,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",
}));
}
+5 -6
View File
@@ -1,10 +1,11 @@
#include "common/printing.h"
#include "common/jsonconfig.h"
#include "common/time.h"
#include "detection/uptime/uptime.h"
#include "modules/uptime/uptime.h"
#include "util/stringUtils.h"
#define FF_UPTIME_NUM_FORMAT_ARGS 7
#define FF_UPTIME_NUM_FORMAT_ARGS 6
void ffPrintUptime(FFUptimeOptions* options)
{
@@ -83,8 +84,7 @@ void ffPrintUptime(FFUptimeOptions* options)
{FF_FORMAT_ARG_TYPE_UINT, &minutes},
{FF_FORMAT_ARG_TYPE_UINT, &seconds},
{FF_FORMAT_ARG_TYPE_UINT, &milliseconds},
{FF_FORMAT_ARG_TYPE_UINT64, &result.uptime},
{FF_FORMAT_ARG_TYPE_UINT64, &result.bootTime},
{FF_FORMAT_ARG_TYPE_STRING, ffTimeToShortStr(result.uptime)},
}));
}
}
@@ -137,7 +137,7 @@ void ffGenerateUptimeJsonResult(FF_MAYBE_UNUSED FFUptimeOptions* options, yyjson
yyjson_mut_val* obj = yyjson_mut_obj_add_obj(doc, module, "result");
yyjson_mut_obj_add_uint(doc, obj, "uptime", result.uptime);
yyjson_mut_obj_add_uint(doc, obj, "bootTime", result.bootTime);
yyjson_mut_obj_add_strcpy(doc, obj, "bootTime", ffTimeToFullStr(result.bootTime));
}
void ffPrintUptimeHelpFormat(void)
@@ -148,8 +148,7 @@ void ffPrintUptimeHelpFormat(void)
"Minutes",
"Seconds",
"Milliseconds",
"Uptime in unix timestamp (ms)",
"Boot time in unix timestamp (ms)",
"Boot time in local timezone",
}));
}
+9 -11
View File
@@ -1,11 +1,10 @@
#include "common/printing.h"
#include "common/jsonconfig.h"
#include "common/time.h"
#include "detection/users/users.h"
#include "modules/users/users.h"
#include "util/stringUtils.h"
#include <time.h>
#pragma GCC diagnostic ignored "-Wformat" // warning: unknown conversion type character 'F' in format
#define FF_USERS_NUM_FORMAT_ARGS 5
@@ -57,12 +56,7 @@ void ffPrintUsers(FFUsersOptions* options)
ffStrbufAppendF(&result, "@%s", user->hostName.chars);
if(user->loginTime)
{
char buf[64];
time_t time = (time_t) (user->loginTime / 1000);
strftime(buf, sizeof(buf), "%FT%T%z", localtime(&time));
ffStrbufAppendF(&result, " - login time %s", buf);
}
ffStrbufAppendF(&result, " - login time %s", ffTimeToShortStr(user->loginTime));
ffStrbufPutTo(&result, stdout);
}
@@ -79,7 +73,7 @@ void ffPrintUsers(FFUsersOptions* options)
{FF_FORMAT_ARG_TYPE_STRBUF, &user->hostName},
{FF_FORMAT_ARG_TYPE_STRBUF, &user->sessionName},
{FF_FORMAT_ARG_TYPE_STRBUF, &user->clientIp},
{FF_FORMAT_ARG_TYPE_UINT64, &user->loginTime},
{FF_FORMAT_ARG_TYPE_STRING, ffTimeToShortStr(user->loginTime)},
}));
}
}
@@ -163,7 +157,11 @@ void ffGenerateUsersJsonResult(FF_MAYBE_UNUSED FFUsersOptions* options, yyjson_m
yyjson_mut_obj_add_strbuf(doc, obj, "hostName", &user->hostName);
yyjson_mut_obj_add_strbuf(doc, obj, "sessionName", &user->sessionName);
yyjson_mut_obj_add_strbuf(doc, obj, "clientIp", &user->clientIp);
yyjson_mut_obj_add_uint(doc, obj, "loginTime", user->loginTime);
const char* pstr = ffTimeToFullStr(user->loginTime);
if (*pstr)
yyjson_mut_obj_add_strcpy(doc, obj, "loginTime", pstr);
else
yyjson_mut_obj_add_null(doc, obj, "loginTime");
}
exit:
@@ -183,7 +181,7 @@ void ffPrintUsersHelpFormat(void)
"Host name",
"Session name",
"Client IP",
"Login Time"
"Login Time in local timezone"
}));
}
+1
View File
@@ -52,6 +52,7 @@ void ffPlatformDestroy(FFPlatform* platform)
FF_LIST_FOR_EACH(FFstrbuf, dir, platform->dataDirs)
ffStrbufDestroy(dir);
ffListDestroy(&platform->dataDirs);
ffStrbufDestroy(&platform->exePath);
ffStrbufDestroy(&platform->userName);
ffStrbufDestroy(&platform->hostName);