diff --git a/CMakeLists.txt b/CMakeLists.txt index 575b6b108..7d81d21e5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -340,6 +340,7 @@ set(LIBFASTFETCH_SRC src/modules/de/de.c src/modules/disk/disk.c src/modules/diskio/diskio.c + src/modules/dns/dns.c src/modules/editor/editor.c src/modules/font/font.c src/modules/gpu/gpu.c @@ -417,6 +418,7 @@ if(LINUX) src/detection/cursor/cursor_linux.c src/detection/bluetooth/bluetooth_linux.c src/detection/disk/disk_linux.c + src/detection/dns/dns_linux.c src/detection/physicaldisk/physicaldisk_linux.c src/detection/physicalmemory/physicalmemory_linux.c src/detection/diskio/diskio_linux.c @@ -487,6 +489,7 @@ elseif(ANDROID) src/detection/cursor/cursor_nosupport.c src/detection/cpuusage/cpuusage_linux.c src/detection/disk/disk_linux.c + src/detection/dns/dns_nosupport.c src/detection/physicaldisk/physicaldisk_linux.c src/detection/physicalmemory/physicalmemory_nosupport.c src/detection/diskio/diskio_linux.c @@ -548,6 +551,7 @@ elseif(BSD) src/detection/cpuusage/cpuusage_bsd.c src/detection/cursor/cursor_linux.c src/detection/disk/disk_bsd.c + src/detection/dns/dns_linux.c src/detection/physicaldisk/physicaldisk_bsd.c src/detection/physicalmemory/physicalmemory_linux.c src/detection/diskio/diskio_bsd.c @@ -619,6 +623,7 @@ elseif(APPLE) src/detection/cpuusage/cpuusage_apple.c src/detection/cursor/cursor_apple.m src/detection/disk/disk_bsd.c + src/detection/dns/dns_linux.c src/detection/physicaldisk/physicaldisk_apple.c src/detection/physicalmemory/physicalmemory_apple.m src/detection/diskio/diskio_apple.c @@ -684,6 +689,7 @@ elseif(WIN32) src/detection/physicaldisk/physicaldisk_windows.c src/detection/diskio/diskio_windows.c src/detection/displayserver/displayserver_windows.c + src/detection/dns/dns_linux.c src/detection/font/font_windows.c src/detection/gpu/gpu_windows.c src/detection/host/host_windows.c diff --git a/src/common/modules.c b/src/common/modules.c index 9580ccb06..d7607aa3a 100644 --- a/src/common/modules.c +++ b/src/common/modules.c @@ -34,6 +34,7 @@ static FFModuleBaseInfo* D[] = { (void*) &instance.config.modules.display, (void*) &instance.config.modules.disk, (void*) &instance.config.modules.diskIo, + (void*) &instance.config.modules.dns, NULL, }; diff --git a/src/detection/dns/dns.h b/src/detection/dns/dns.h new file mode 100644 index 000000000..fdcfc5163 --- /dev/null +++ b/src/detection/dns/dns.h @@ -0,0 +1,5 @@ +#pragma once + +#include "fastfetch.h" + +const char* ffDetectDNS(FFlist* results /* list of FFstrbuf */); diff --git a/src/detection/dns/dns_linux.c b/src/detection/dns/dns_linux.c new file mode 100644 index 000000000..7e78c289f --- /dev/null +++ b/src/detection/dns/dns_linux.c @@ -0,0 +1,32 @@ +#include "detection/dns/dns.h" + +#include +#include + +const char* ffDetectDNS(FFlist* results) +{ + if (res_init() < 0) + return "res_init() failed"; + + for (int i = 0; i < _res.nscount; ++i) + { + struct sockaddr_in* addr = &_res.nsaddr_list[i]; + char addressBuffer[INET_ADDRSTRLEN + 4]; + inet_ntop(AF_INET, &addr->sin_addr, addressBuffer, INET_ADDRSTRLEN); + + FFstrbuf* result = (FFstrbuf*) ffListAdd(results); + ffStrbufInitS(result, addressBuffer); + } + + for (int i = 0; i < _res._u._ext.nscount; ++i) + { + struct sockaddr_in6* addr = _res._u._ext.nsaddrs[i]; + char addressBuffer[INET6_ADDRSTRLEN + 4]; + inet_ntop(AF_INET6, &addr->sin6_addr, addressBuffer, INET6_ADDRSTRLEN); + + FFstrbuf* result = (FFstrbuf*) ffListAdd(results); + ffStrbufInitS(result, addressBuffer); + } + + return NULL; +} diff --git a/src/detection/dns/dns_nosupport.c b/src/detection/dns/dns_nosupport.c new file mode 100644 index 000000000..f92597962 --- /dev/null +++ b/src/detection/dns/dns_nosupport.c @@ -0,0 +1,6 @@ +#include "detection/dns/dns.h" + +const char* ffDetectDNS(FF_MAYBE_UNUSED FFlist* results) +{ + return "Not supported on this platform"; +} diff --git a/src/modules/dns/dns.c b/src/modules/dns/dns.c new file mode 100644 index 000000000..49e80f325 --- /dev/null +++ b/src/modules/dns/dns.c @@ -0,0 +1,141 @@ +#include "common/printing.h" +#include "common/jsonconfig.h" +#include "detection/dns/dns.h" +#include "modules/dns/dns.h" +#include "util/stringUtils.h" + +#define FF_DNS_NUM_FORMAT_ARGS 1 + +void ffPrintDNS(FFDNSOptions* options) +{ + FF_LIST_AUTO_DESTROY result = ffListCreate(sizeof(FFstrbuf)); + + const char* error = ffDetectDNS(&result); + + if (error) + { + ffPrintError(FF_DNS_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, "%s", error); + return; + } + + if (result.length == 0) + { + ffPrintError(FF_DNS_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, "NO DNS detected"); + return; + } + + FF_STRBUF_AUTO_DESTROY buf = ffStrbufCreate(); + FF_LIST_FOR_EACH(FFstrbuf, item, result) + { + if (buf.length) + ffStrbufAppendC(&buf, ' '); + ffStrbufAppend(&buf, item); + } + + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(FF_DNS_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT); + + ffStrbufPutTo(&buf, stdout); + } + else + { + FF_PRINT_FORMAT_CHECKED(FF_DNS_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, FF_DNS_NUM_FORMAT_ARGS, ((FFformatarg[]) { + {FF_FORMAT_ARG_TYPE_STRBUF, &buf, "result"}, + })); + } + + FF_LIST_FOR_EACH(FFstrbuf, item, result) + { + ffStrbufDestroy(item); + } +} + +bool ffParseDNSCommandOptions(FFDNSOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_DNS_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + return false; +} + +void ffParseDNSJsonObject(FFDNSOptions* options, yyjson_val* module) +{ + yyjson_val *key_, *val; + size_t idx, max; + yyjson_obj_foreach(module, idx, max, key_, val) + { + const char* key = yyjson_get_str(key_); + if(ffStrEqualsIgnCase(key, "type")) + continue; + + if (ffJsonConfigParseModuleArgs(key, val, &options->moduleArgs)) + continue; + + ffPrintError(FF_DNS_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, "Unknown JSON key %s", key); + } +} + +void ffGenerateDNSJsonConfig(FFDNSOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module) +{ + __attribute__((__cleanup__(ffDestroyDNSOptions))) FFDNSOptions defaultOptions; + ffInitDNSOptions(&defaultOptions); + + ffJsonConfigGenerateModuleArgsConfig(doc, module, &defaultOptions.moduleArgs, &options->moduleArgs); +} + +void ffGenerateDNSJsonResult(FF_MAYBE_UNUSED FFDNSOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module) +{ + FF_LIST_AUTO_DESTROY result = ffListCreate(sizeof(FFstrbuf)); + + const char* error = ffDetectDNS(&result); + + if (error) + { + yyjson_mut_obj_add_str(doc, module, "error", error); + goto exit; + } + + yyjson_mut_val* arr = yyjson_mut_obj_add_arr(doc, module, "result"); + + FF_LIST_FOR_EACH(FFstrbuf, item, result) + { + yyjson_mut_arr_add_strbuf(doc, arr, item); + } + +exit: + FF_LIST_FOR_EACH(FFstrbuf, item, result) + { + ffStrbufDestroy(item); + } +} + +void ffPrintDNSHelpFormat(void) +{ + FF_PRINT_MODULE_FORMAT_HELP_CHECKED(FF_DNS_MODULE_NAME, "{1}", FF_DNS_NUM_FORMAT_ARGS, ((const char* []) { + "DNS result - result", + })); +} + +void ffInitDNSOptions(FFDNSOptions* options) +{ + ffOptionInitModuleBaseInfo( + &options->moduleInfo, + FF_DNS_MODULE_NAME, + "Print configured DNS servers", + ffParseDNSCommandOptions, + ffParseDNSJsonObject, + ffPrintDNS, + ffGenerateDNSJsonResult, + ffPrintDNSHelpFormat, + ffGenerateDNSJsonConfig + ); + ffOptionInitModuleArg(&options->moduleArgs); +} + +void ffDestroyDNSOptions(FFDNSOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} diff --git a/src/modules/dns/dns.h b/src/modules/dns/dns.h new file mode 100644 index 000000000..a26504d59 --- /dev/null +++ b/src/modules/dns/dns.h @@ -0,0 +1,9 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_DNS_MODULE_NAME "DNS" + +void ffPrintDNS(FFDNSOptions* options); +void ffInitDNSOptions(FFDNSOptions* options); +void ffDestroyDNSOptions(FFDNSOptions* options); diff --git a/src/modules/dns/option.h b/src/modules/dns/option.h new file mode 100644 index 000000000..f0cd6bf1c --- /dev/null +++ b/src/modules/dns/option.h @@ -0,0 +1,11 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" + +typedef struct FFDNSOptions +{ + FFModuleBaseInfo moduleInfo; + FFModuleArgs moduleArgs; +} FFDNSOptions; diff --git a/src/modules/modules.h b/src/modules/modules.h index 0e4587691..58ce1b98d 100644 --- a/src/modules/modules.h +++ b/src/modules/modules.h @@ -23,6 +23,7 @@ #include "modules/diskio/diskio.h" #include "modules/display/display.h" #include "modules/de/de.h" +#include "modules/dns/dns.h" #include "modules/editor/editor.h" #include "modules/font/font.h" #include "modules/gamepad/gamepad.h" diff --git a/src/modules/options.h b/src/modules/options.h index 7c0ff7129..49bd8fe6b 100644 --- a/src/modules/options.h +++ b/src/modules/options.h @@ -23,6 +23,7 @@ #include "modules/disk/option.h" #include "modules/diskio/option.h" #include "modules/display/option.h" +#include "modules/dns/option.h" #include "modules/editor/option.h" #include "modules/font/option.h" #include "modules/host/option.h" diff --git a/src/options/modules.c b/src/options/modules.c index 095449a8e..7d80b2d86 100644 --- a/src/options/modules.c +++ b/src/options/modules.c @@ -24,6 +24,7 @@ void ffOptionsInitModules(FFOptionsModules* options) ffInitDiskOptions(&options->disk); ffInitDiskIOOptions(&options->diskIo); ffInitDisplayOptions(&options->display); + ffInitDNSOptions(&options->dns); ffInitEditorOptions(&options->editor); ffInitFontOptions(&options->font); ffInitGPUOptions(&options->gpu); @@ -94,6 +95,7 @@ void ffOptionsDestroyModules(FFOptionsModules* options) ffDestroyDiskOptions(&options->disk); ffDestroyDiskIOOptions(&options->diskIo); ffDestroyDisplayOptions(&options->display); + ffDestroyDNSOptions(&options->dns); ffDestroyEditorOptions(&options->editor); ffDestroyFontOptions(&options->font); ffDestroyGPUOptions(&options->gpu); diff --git a/src/options/modules.h b/src/options/modules.h index c8f46b892..fdfae5e47 100644 --- a/src/options/modules.h +++ b/src/options/modules.h @@ -25,6 +25,7 @@ typedef struct FFOptionsModules FFDiskOptions disk; FFDiskIOOptions diskIo; FFDisplayOptions display; + FFDNSOptions dns; FFEditorOptions editor; FFFontOptions font; FFGPUOptions gpu;