From 94e6f4040d056edc609743b5895ec8c10e2f6888 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Tue, 18 Apr 2023 14:57:25 +0800 Subject: [PATCH] Network (macOS): init --- CMakeLists.txt | 3 ++ src/common/init.c | 6 ++++ src/detection/network/network.h | 18 ++++++++++ src/detection/network/network_apple.c | 42 ++++++++++++++++++++++ src/fastfetch.c | 4 +++ src/fastfetch.h | 4 +++ src/modules/network.c | 52 +++++++++++++++++++++++++++ src/util/FFstrbuf.h | 10 ++++++ src/util/apple/cf_helpers.c | 6 ++++ 9 files changed, 145 insertions(+) create mode 100644 src/detection/network/network.h create mode 100644 src/detection/network/network_apple.c create mode 100644 src/modules/network.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 9a115a63d..e9b4cff72 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -284,6 +284,7 @@ set(LIBFASTFETCH_SRC src/modules/locale.c src/modules/localip.c src/modules/memory.c + src/modules/network.c src/modules/opencl.c src/modules/opengl.c src/modules/os.c @@ -473,6 +474,7 @@ elseif(APPLE) src/detection/gamepad/gamepad_apple.c src/detection/media/media_apple.m src/detection/memory/memory_apple.c + src/detection/network/network_apple.c src/detection/opengl/opengl_apple.c src/detection/os/os_apple.m src/detection/packages/packages_apple.c @@ -710,6 +712,7 @@ if(APPLE) PRIVATE "-framework IOKit" PRIVATE "-framework OpenGL" PRIVATE "-framework OpenCL" + PRIVATE "-framework SystemConfiguration" PRIVATE "-weak_framework CoreDisplay" PRIVATE "-weak_framework DisplayServices -F /System/Library/PrivateFrameworks" PRIVATE "-weak_framework MediaRemote -F /System/Library/PrivateFrameworks" diff --git a/src/common/init.c b/src/common/init.c index b2fc6a447..cf196c1d3 100644 --- a/src/common/init.c +++ b/src/common/init.c @@ -115,6 +115,7 @@ static void defaultConfig(FFinstance* instance) initModuleArg(&instance->config.bluetooth); initModuleArg(&instance->config.sound); initModuleArg(&instance->config.gamepad); + initModuleArg(&instance->config.network); ffStrbufInitA(&instance->config.libPCI, 0); ffStrbufInitA(&instance->config.libVulkan, 0); @@ -203,6 +204,8 @@ static void defaultConfig(FFinstance* instance) ); ffListInit(&instance->config.commandKeys, sizeof(FFstrbuf)); ffListInit(&instance->config.commandTexts, sizeof(FFstrbuf)); + + ffStrbufInit(&instance->config.networkType); } void ffInitInstance(FFinstance* instance) @@ -383,6 +386,7 @@ static void destroyConfig(FFinstance* instance) destroyModuleArg(&instance->config.bluetooth); destroyModuleArg(&instance->config.sound); destroyModuleArg(&instance->config.gamepad); + destroyModuleArg(&instance->config.network); ffStrbufDestroy(&instance->config.libPCI); ffStrbufDestroy(&instance->config.libVulkan); @@ -426,6 +430,8 @@ static void destroyConfig(FFinstance* instance) FF_LIST_FOR_EACH(FFstrbuf, item, instance->config.commandTexts) ffStrbufDestroy(item); ffListDestroy(&instance->config.commandTexts); + + ffStrbufDestroy(&instance->config.networkType); } static void destroyState(FFinstance* instance) diff --git a/src/detection/network/network.h b/src/detection/network/network.h new file mode 100644 index 000000000..82c3064ed --- /dev/null +++ b/src/detection/network/network.h @@ -0,0 +1,18 @@ +#pragma once + +#ifndef FF_INCLUDED_detection_network_network +#define FF_INCLUDED_detection_network_network + +#include "fastfetch.h" + +typedef struct FFNetworkResult +{ + FFstrbuf name; + FFstrbuf type; + FFstrbuf address; + int32_t mtu; +} FFNetworkResult; + +const char* ffDetectNetwork(FFinstance* instance, FFlist* result); + +#endif diff --git a/src/detection/network/network_apple.c b/src/detection/network/network_apple.c new file mode 100644 index 000000000..23f527b6a --- /dev/null +++ b/src/detection/network/network_apple.c @@ -0,0 +1,42 @@ +#include "detection/network/network.h" +#include "util/apple/cf_helpers.h" + +#include + +const char* ffDetectNetwork(FFinstance* instance, FFlist* result) +{ + FF_STRBUF_AUTO_DESTROY sbType; + ffStrbufInit(&sbType); + + CFArrayRef FF_CFTYPE_AUTO_RELEASE array = SCNetworkInterfaceCopyAll(); + for (CFIndex i = 0, length = CFArrayGetCount(array); i < length; ++i) + { + SCNetworkInterfaceRef ni = CFArrayGetValueAtIndex(array, i), parent; + while ((parent = SCNetworkInterfaceGetInterface(ni))) + ni = parent; + + CFStringRef cfType = SCNetworkInterfaceGetInterfaceType(ni); + if (cfType) + ffCfStrGetString(cfType, &sbType); + else + ffStrbufAppendS(&sbType, "Unknown"); + + if (instance->config.networkType.length && !ffStrbufContainIgnCase(&instance->config.networkType, &sbType)) + continue; + + FFNetworkResult* item = (FFNetworkResult*) ffListAdd(result); + ffStrbufInitMove(&item->type, &sbType); + ffStrbufInit(&item->name); + ffStrbufInit(&item->address); + item->mtu = 0; + + ffCfStrGetString(SCNetworkInterfaceGetLocalizedDisplayName(ni), &item->name); + ffCfStrGetString(SCNetworkInterfaceGetHardwareAddressString(ni), &item->address); + SCNetworkInterfaceCopyMTU(ni, &item->mtu, nil, nil); + } + + if (result->length == 0) + return "No network interfaces found"; + + return NULL; +} diff --git a/src/fastfetch.c b/src/fastfetch.c index 355051aa6..1e174d93a 100644 --- a/src/fastfetch.c +++ b/src/fastfetch.c @@ -1341,6 +1341,8 @@ static void parseOption(FFinstance* instance, FFdata* data, const char* key, con } else if(strcasecmp(key, "--percent-type") == 0) instance->config.percentType = optionParseUInt32(key, value); + else if(strcasecmp(key, "--network-type") == 0) + optionParseString(key, value, &instance->config.networkType); else if(strcasecmp(key, "--command-shell") == 0) optionParseString(key, value, &instance->config.commandShell); else if(strcasecmp(key, "--command-key") == 0) @@ -1516,6 +1518,8 @@ static void parseStructureCommand(FFinstance* instance, FFdata* data, const char ffPrintSound(instance); else if(strcasecmp(line, "gamepad") == 0) ffPrintGamepad(instance); + else if(strcasecmp(line, "network") == 0) + ffPrintNetwork(instance); else ffPrintErrorString(instance, line, 0, NULL, NULL, ""); } diff --git a/src/fastfetch.h b/src/fastfetch.h index 0d25d31a8..b3c3de88b 100644 --- a/src/fastfetch.h +++ b/src/fastfetch.h @@ -163,6 +163,7 @@ typedef struct FFconfig FFModuleArgs bluetooth; FFModuleArgs sound; FFModuleArgs gamepad; + FFModuleArgs network; FFstrbuf libPCI; FFstrbuf libVulkan; @@ -243,6 +244,8 @@ typedef struct FFconfig FFstrbuf commandShell; FFlist commandKeys; FFlist commandTexts; + + FFstrbuf networkType; } FFconfig; typedef struct FFstate @@ -349,5 +352,6 @@ void ffPrintCommand(FFinstance* instance); void ffPrintBluetooth(FFinstance* instance); void ffPrintSound(FFinstance* instance); void ffPrintGamepad(FFinstance* instance); +void ffPrintNetwork(FFinstance* instance); #endif diff --git a/src/modules/network.c b/src/modules/network.c new file mode 100644 index 000000000..67809bc91 --- /dev/null +++ b/src/modules/network.c @@ -0,0 +1,52 @@ +#include "fastfetch.h" +#include "common/printing.h" +#include "detection/network/network.h" + +#define FF_NETWORK_MODULE_NAME "Network" +#define FF_NETWORK_NUM_FORMAT_ARGS 4 + +void ffPrintNetwork(FFinstance* instance) +{ + FF_LIST_AUTO_DESTROY networks; + ffListInit(&networks, sizeof(FFNetworkResult)); + const char* error = ffDetectNetwork(instance, &networks); + + if(error != NULL) + { + ffPrintError(instance, FF_NETWORK_MODULE_NAME, 0, &instance->config.network, "%s", error); + return; + } + + FF_STRBUF_AUTO_DESTROY key; + ffStrbufInit(&key); + + FF_LIST_FOR_EACH(FFNetworkResult, network, networks) + { + if(instance->config.network.key.length == 0) + { + ffStrbufSetF(&key, "%s (%s)", FF_NETWORK_MODULE_NAME, network->type.chars); + } + else + { + ffParseFormatString(&key, &instance->config.network.key, 1, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRBUF, &network->type}, + {FF_FORMAT_ARG_TYPE_STRBUF, &network->name}, + }); + } + + if (instance->config.network.outputFormat.length == 0) + { + ffPrintLogoAndKey(instance, key.chars, 0, NULL); + printf("%s - %s\n", network->name.chars, network->address.chars); + } + else + { + ffPrintFormatString(instance, key.chars, 0, NULL, &instance->config.network.outputFormat, FF_NETWORK_NUM_FORMAT_ARGS, (FFformatarg[]){ + {FF_FORMAT_ARG_TYPE_STRBUF, &network->type}, + {FF_FORMAT_ARG_TYPE_STRBUF, &network->name}, + {FF_FORMAT_ARG_TYPE_STRBUF, &network->address}, + {FF_FORMAT_ARG_TYPE_INT, &network->mtu}, + }); + } + } +} diff --git a/src/util/FFstrbuf.h b/src/util/FFstrbuf.h index d7d414dc1..d80a99483 100644 --- a/src/util/FFstrbuf.h +++ b/src/util/FFstrbuf.h @@ -204,11 +204,21 @@ static inline FF_C_NODISCARD bool ffStrbufContainS(const FFstrbuf* strbuf, const return strstr(strbuf->chars, str) != NULL; } +static inline FF_C_NODISCARD bool ffStrbufContain(const FFstrbuf* strbuf, const FFstrbuf* str) +{ + return ffStrbufContainS(strbuf, str->chars); +} + static inline FF_C_NODISCARD bool ffStrbufContainIgnCaseS(const FFstrbuf* strbuf, const char* str) { return strcasestr(strbuf->chars, str) != NULL; } +static inline FF_C_NODISCARD bool ffStrbufContainIgnCase(const FFstrbuf* strbuf, const FFstrbuf* str) +{ + return ffStrbufContainIgnCaseS(strbuf, str->chars); +} + static inline FF_C_NODISCARD uint32_t ffStrbufFirstIndexC(const FFstrbuf* strbuf, char c) { return ffStrbufNextIndexC(strbuf, 0, c); diff --git a/src/util/apple/cf_helpers.c b/src/util/apple/cf_helpers.c index f5c37b7ad..797b51b59 100644 --- a/src/util/apple/cf_helpers.c +++ b/src/util/apple/cf_helpers.c @@ -2,6 +2,12 @@ const char* ffCfStrGetString(CFStringRef str, FFstrbuf* result) { + if (!str) + { + ffStrbufClear(result); + return NULL; + } + uint32_t length = (uint32_t)CFStringGetLength(str); //CFString stores UTF16 characters, therefore may require larger buffer to convert to UTF8 string ffStrbufEnsureFree(result, length * 2);