master ohmu/fastfetch-openbsd / src / modules / publicip / publicip.c
ohmu  ·  2026-10-15
  1#include "common/printing.h"
  2#include "common/jsonconfig.h"
  3#include "common/strutil.h"
  4#include "modules/publicip/publicip.h"
  5#include "detection/publicip/publicip.h"
  6
  7bool ffPrintPublicIp(FFPublicIPOptions* options) {
  8    FFPublicIpResult result;
  9    ffStrbufInit(&result.ip);
 10    ffStrbufInit(&result.location);
 11    const char* error = ffDetectPublicIp(options, &result);
 12
 13    if (error) {
 14        ffPrintError(FF_MODULE_GET_DISPLAY_NAME(PublicIP), 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, "%s", error);
 15        return false;
 16    }
 17
 18    if (options->moduleArgs.outputFormat.length == 0) {
 19        ffPrintLogoAndKey(FF_MODULE_GET_DISPLAY_NAME(PublicIP), 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT);
 20        if (result.location.length) {
 21            printf("%s (%s)\n", result.ip.chars, result.location.chars);
 22        } else {
 23            ffStrbufPutTo(&result.ip, stdout);
 24        }
 25    } else {
 26        FF_PRINT_FORMAT_CHECKED(FF_MODULE_GET_DISPLAY_NAME(PublicIP), 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, ((FFformatarg[]) {
 27                                                                                                              FF_ARG(result.ip, "ip"),
 28                                                                                                              FF_ARG(result.location, "location"),
 29                                                                                                          }));
 30    }
 31
 32    ffStrbufDestroy(&result.ip);
 33    ffStrbufDestroy(&result.location);
 34
 35    return true;
 36}
 37
 38void ffParsePublicIpJsonObject(FFPublicIPOptions* options, yyjson_val* module) {
 39    yyjson_val *key, *val;
 40    size_t idx, max;
 41    yyjson_obj_foreach (module, idx, max, key, val) {
 42        if (ffJsonConfigParseModuleArgs(key, val, &options->moduleArgs)) {
 43            continue;
 44        }
 45
 46        if (unsafe_yyjson_equals_str(key, "url")) {
 47            ffStrbufSetJsonVal(&options->url, val);
 48            continue;
 49        }
 50
 51        if (unsafe_yyjson_equals_str(key, "timeout")) {
 52            options->timeout = (uint32_t) yyjson_get_uint(val);
 53            continue;
 54        }
 55
 56        if (unsafe_yyjson_equals_str(key, "ipv6")) {
 57            options->ipv6 = yyjson_get_bool(val);
 58            continue;
 59        }
 60
 61        ffPrintError(FF_MODULE_GET_DISPLAY_NAME(PublicIP), 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, "Unknown JSON key %s", unsafe_yyjson_get_str(key));
 62    }
 63}
 64
 65[[gnu::cold]]
 66void ffGeneratePublicIpJsonConfig(FFPublicIPOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module) {
 67    ffJsonConfigGenerateModuleArgsConfig(doc, module, &options->moduleArgs);
 68
 69    yyjson_mut_obj_add_strbuf(doc, module, "url", &options->url);
 70
 71    yyjson_mut_obj_add_uint(doc, module, "timeout", options->timeout);
 72
 73    yyjson_mut_obj_add_bool(doc, module, "ipv6", options->ipv6);
 74}
 75
 76bool ffGeneratePublicIpJsonResult(FFPublicIPOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module) {
 77    FFPublicIpResult result;
 78    ffStrbufInit(&result.ip);
 79    ffStrbufInit(&result.location);
 80    const char* error = ffDetectPublicIp(options, &result);
 81
 82    if (error) {
 83        yyjson_mut_obj_add_str(doc, module, "error", error);
 84        return false;
 85    }
 86
 87    yyjson_mut_val* obj = yyjson_mut_obj_add_obj(doc, module, "result");
 88    yyjson_mut_obj_add_strbuf(doc, obj, "ip", &result.ip);
 89    yyjson_mut_obj_add_strbuf(doc, obj, "location", &result.location);
 90
 91    ffStrbufDestroy(&result.ip);
 92    ffStrbufDestroy(&result.location);
 93
 94    return true;
 95}
 96
 97void ffInitPublicIpOptions(FFPublicIPOptions* options) {
 98    ffOptionInitModuleArg(&options->moduleArgs, "󰩠");
 99
100    ffStrbufInit(&options->url);
101    options->timeout = 0;
102    options->ipv6 = false;
103}
104
105void ffDestroyPublicIpOptions(FFPublicIPOptions* options) {
106    ffOptionDestroyModuleArg(&options->moduleArgs);
107
108    ffStrbufDestroy(&options->url);
109}
110
111FFModuleBaseInfo ffPublicIPModuleInfo = {
112    .name = "PublicIp",
113    .description = "Print your public IP address and related information",
114    .displayName = {
115        .en = "Public IP",
116        .ar = "عنوان IP العام",
117        .cs = "Veřejná IP",
118        .de = "Öffentliche IP",
119        .es = "IP pública",
120        .fi = "Julkinen IP",
121        .fr = "IP publique",
122        .gl = "IP pública",
123        .he = "IP ציבורי",
124        .id = "IP Publik",
125        .it = "IP pubblica",
126        .ja = "パブリックIP",
127        .ko = "공용 IP",
128        .pl = "Publiczne IP",
129        .pt = "IP público",
130        .ru = "Внешний IP",
131        .tr = "Genel IP",
132        .uk = "Публічна IP",
133        .vi = "IP công khai",
134        .zh_CN = "公网 IP",
135        .zh_TW = "公網 IP",
136    },
137    .initOptions = (void*) ffInitPublicIpOptions,
138    .destroyOptions = (void*) ffDestroyPublicIpOptions,
139    .parseJsonObject = (void*) ffParsePublicIpJsonObject,
140    .printModule = (void*) ffPrintPublicIp,
141    .generateJsonResult = (void*) ffGeneratePublicIpJsonResult,
142    .generateJsonConfig = (void*) ffGeneratePublicIpJsonConfig,
143    .formatArgs = FF_FORMAT_ARG_LIST(((FFModuleFormatArg[]) {
144        { "Public IP address", "ip" },
145        { "Location", "location" },
146    })),
147    .defaultOrder = 49,
148};