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};