ohmu
·
2026-10-15
1#include "common/printing.h"
2#include "common/jsonconfig.h"
3#include "common/strutil.h"
4#include "detection/bios/bios.h"
5#include "modules/bios/bios.h"
6
7bool ffPrintBios(FFBiosOptions* options) {
8 bool success = false;
9 FFBiosResult bios;
10 ffStrbufInit(&bios.date);
11 ffStrbufInit(&bios.release);
12 ffStrbufInit(&bios.vendor);
13 ffStrbufInit(&bios.version);
14 ffStrbufInit(&bios.type);
15
16 const char* error = ffDetectBios(&bios);
17
18 FF_STRBUF_AUTO_DESTROY key = ffStrbufCreate();
19
20 if (error) {
21 ffPrintError(FF_MODULE_GET_DISPLAY_NAME(Bios), 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, "%s", error);
22 goto exit;
23 }
24
25 if (bios.version.length == 0) {
26 ffPrintError(FF_MODULE_GET_DISPLAY_NAME(Bios), 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, "bios_version is not set.");
27 goto exit;
28 }
29
30 if (options->moduleArgs.key.length == 0) {
31 if (bios.type.length == 0) {
32 ffStrbufSetStatic(&bios.type, "Unknown");
33 } else if (ffStrbufIgnCaseEqualS(&bios.type, "BIOS")) {
34 ffStrbufSetStatic(&bios.type, "Legacy");
35 }
36
37 ffStrbufSetF(&key, "%s (%s)", FF_MODULE_GET_DISPLAY_NAME(Bios), bios.type.chars);
38 } else {
39 ffStrbufClear(&key);
40 FF_PARSE_FORMAT_STRING_CHECKED(&key, &options->moduleArgs.key, ((FFformatarg[]) {
41 FF_ARG(bios.type, "type"),
42 FF_ARG(options->moduleArgs.keyIcon, "icon"),
43 FF_ARG(FF_MODULE_GET_DISPLAY_NAME(Bios), "module-name"),
44 }));
45 }
46
47 if (options->moduleArgs.outputFormat.length == 0) {
48 ffPrintLogoAndKey(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY);
49 ffStrbufWriteTo(&bios.version, stdout);
50 if (bios.release.length) {
51 printf(" (%s)\n", bios.release.chars);
52 } else {
53 putchar('\n');
54 }
55 } else {
56 FF_PRINT_FORMAT_CHECKED(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY, ((FFformatarg[]) {
57 FF_ARG(bios.date, "date"),
58 FF_ARG(bios.release, "release"),
59 FF_ARG(bios.vendor, "vendor"),
60 FF_ARG(bios.version, "version"),
61 FF_ARG(bios.type, "type"),
62 }));
63 }
64 success = true;
65
66exit:
67 ffStrbufDestroy(&bios.date);
68 ffStrbufDestroy(&bios.release);
69 ffStrbufDestroy(&bios.vendor);
70 ffStrbufDestroy(&bios.version);
71 ffStrbufDestroy(&bios.type);
72
73 return success;
74}
75
76void ffParseBiosJsonObject(FFBiosOptions* options, yyjson_val* module) {
77 yyjson_val *key, *val;
78 size_t idx, max;
79 yyjson_obj_foreach (module, idx, max, key, val) {
80 if (ffJsonConfigParseModuleArgs(key, val, &options->moduleArgs)) {
81 continue;
82 }
83
84 ffPrintError(FF_MODULE_GET_DISPLAY_NAME(Bios), 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, "Unknown JSON key %s", unsafe_yyjson_get_str(key));
85 }
86}
87
88[[gnu::cold]]
89void ffGenerateBiosJsonConfig(FFBiosOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module) {
90 ffJsonConfigGenerateModuleArgsConfig(doc, module, &options->moduleArgs);
91}
92
93bool ffGenerateBiosJsonResult([[maybe_unused]] FFBiosOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module) {
94 bool success = false;
95 FFBiosResult bios;
96 ffStrbufInit(&bios.date);
97 ffStrbufInit(&bios.release);
98 ffStrbufInit(&bios.vendor);
99 ffStrbufInit(&bios.version);
100 ffStrbufInit(&bios.type);
101
102 const char* error = ffDetectBios(&bios);
103
104 if (error) {
105 yyjson_mut_obj_add_str(doc, module, "error", error);
106 goto exit;
107 }
108
109 yyjson_mut_val* obj = yyjson_mut_obj_add_obj(doc, module, "result");
110 yyjson_mut_obj_add_strbuf(doc, obj, "date", &bios.date);
111 yyjson_mut_obj_add_strbuf(doc, obj, "release", &bios.release);
112 yyjson_mut_obj_add_strbuf(doc, obj, "vendor", &bios.vendor);
113 yyjson_mut_obj_add_strbuf(doc, obj, "version", &bios.version);
114 yyjson_mut_obj_add_strbuf(doc, obj, "type", &bios.type);
115 success = true;
116
117exit:
118 ffStrbufDestroy(&bios.date);
119 ffStrbufDestroy(&bios.release);
120 ffStrbufDestroy(&bios.vendor);
121 ffStrbufDestroy(&bios.version);
122 ffStrbufDestroy(&bios.type);
123 return success;
124}
125
126void ffInitBiosOptions(FFBiosOptions* options) {
127 ffOptionInitModuleArg(&options->moduleArgs, "");
128}
129
130void ffDestroyBiosOptions(FFBiosOptions* options) {
131 ffOptionDestroyModuleArg(&options->moduleArgs);
132}
133
134FFModuleBaseInfo ffBiosModuleInfo = {
135 .name = "BIOS",
136 .description = "Print first-stage bootloader information (name, version, release date, etc.)",
137 .displayName = {
138 .en = "BIOS",
139 .ar = "BIOS",
140 .cs = "BIOS",
141 .de = "BIOS",
142 .es = "BIOS",
143 .fi = "BIOS",
144 .fr = "BIOS",
145 .gl = "BIOS",
146 .he = "BIOS",
147 .id = "BIOS",
148 .it = "BIOS",
149 .ja = "BIOS",
150 .ko = "BIOS",
151 .pl = "BIOS",
152 .pt = "BIOS",
153 .ru = "BIOS",
154 .tr = "BIOS",
155 .uk = "BIOS",
156 .vi = "BIOS",
157 .zh_CN = "BIOS",
158 .zh_TW = "BIOS",
159 },
160 .initOptions = (void*) ffInitBiosOptions,
161 .destroyOptions = (void*) ffDestroyBiosOptions,
162 .parseJsonObject = (void*) ffParseBiosJsonObject,
163 .printModule = (void*) ffPrintBios,
164 .generateJsonResult = (void*) ffGenerateBiosJsonResult,
165 .generateJsonConfig = (void*) ffGenerateBiosJsonConfig,
166 .formatArgs = FF_FORMAT_ARG_LIST(((FFModuleFormatArg[]){
167 { "BIOS date", "date" },
168 { "BIOS release", "release" },
169 { "BIOS vendor", "vendor" },
170 { "BIOS version", "version" },
171 { "Firmware type *", "type" },
172 })),
173 .defaultOrder = 5,
174};