master ohmu/fastfetch-openbsd / src / modules / host / host.c
ohmu  ·  2026-10-15
  1#include "common/printing.h"
  2#include "common/jsonconfig.h"
  3#include "common/strutil.h"
  4#include "detection/host/host.h"
  5#include "modules/host/host.h"
  6
  7bool ffPrintHost(FFHostOptions* options) {
  8    bool success = false;
  9    FFHostResult host;
 10    ffStrbufInit(&host.family);
 11    ffStrbufInit(&host.name);
 12    ffStrbufInit(&host.version);
 13    ffStrbufInit(&host.sku);
 14    ffStrbufInit(&host.serial);
 15    ffStrbufInit(&host.uuid);
 16    ffStrbufInit(&host.vendor);
 17
 18    const char* error = ffDetectHost(&host);
 19    if (error) {
 20        ffPrintError(FF_MODULE_GET_DISPLAY_NAME(Host), 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, "%s", error);
 21        goto exit;
 22    }
 23
 24    if (host.name.length == 0 && host.family.length == 0) {
 25        ffPrintError(FF_MODULE_GET_DISPLAY_NAME(Host), 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, "neither product_family nor product_name is set by O.E.M.");
 26        goto exit;
 27    }
 28
 29    if (options->moduleArgs.outputFormat.length == 0) {
 30        ffPrintLogoAndKey(FF_MODULE_GET_DISPLAY_NAME(Host), 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT);
 31
 32        FF_STRBUF_AUTO_DESTROY output = ffStrbufCreate();
 33
 34        if (host.name.length > 0) {
 35            ffStrbufAppend(&output, &host.name);
 36        } else {
 37            ffStrbufAppend(&output, &host.family);
 38        }
 39
 40        if (host.version.length > 0) {
 41            ffStrbufAppendF(&output, " (%s)", host.version.chars);
 42        }
 43
 44        ffStrbufPutTo(&output, stdout);
 45    } else {
 46        FF_PRINT_FORMAT_CHECKED(FF_MODULE_GET_DISPLAY_NAME(Host), 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, ((FFformatarg[]) {
 47                                                                                                         FF_ARG(host.family, "family"),
 48                                                                                                         FF_ARG(host.name, "name"),
 49                                                                                                         FF_ARG(host.version, "version"),
 50                                                                                                         FF_ARG(host.sku, "sku"),
 51                                                                                                         FF_ARG(host.vendor, "vendor"),
 52                                                                                                         FF_ARG(host.serial, "serial"),
 53                                                                                                         FF_ARG(host.uuid, "uuid"),
 54                                                                                                     }));
 55    }
 56    success = true;
 57
 58exit:
 59    ffStrbufDestroy(&host.family);
 60    ffStrbufDestroy(&host.name);
 61    ffStrbufDestroy(&host.version);
 62    ffStrbufDestroy(&host.sku);
 63    ffStrbufDestroy(&host.serial);
 64    ffStrbufDestroy(&host.uuid);
 65    ffStrbufDestroy(&host.vendor);
 66
 67    return success;
 68}
 69
 70void ffParseHostJsonObject(FFHostOptions* options, yyjson_val* module) {
 71    yyjson_val *key, *val;
 72    size_t idx, max;
 73    yyjson_obj_foreach (module, idx, max, key, val) {
 74        if (ffJsonConfigParseModuleArgs(key, val, &options->moduleArgs)) {
 75            continue;
 76        }
 77
 78        ffPrintError(FF_MODULE_GET_DISPLAY_NAME(Host), 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, "Unknown JSON key %s", unsafe_yyjson_get_str(key));
 79    }
 80}
 81
 82[[gnu::cold]]
 83void ffGenerateHostJsonConfig(FFHostOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module) {
 84    ffJsonConfigGenerateModuleArgsConfig(doc, module, &options->moduleArgs);
 85}
 86
 87bool ffGenerateHostJsonResult([[maybe_unused]] FFHostOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module) {
 88    bool success = false;
 89    FFHostResult host;
 90    ffStrbufInit(&host.family);
 91    ffStrbufInit(&host.name);
 92    ffStrbufInit(&host.version);
 93    ffStrbufInit(&host.sku);
 94    ffStrbufInit(&host.serial);
 95    ffStrbufInit(&host.uuid);
 96    ffStrbufInit(&host.vendor);
 97
 98    const char* error = ffDetectHost(&host);
 99    if (error) {
100        yyjson_mut_obj_add_str(doc, module, "error", error);
101        goto exit;
102    }
103
104    if (host.family.length == 0 && host.name.length == 0) {
105        yyjson_mut_obj_add_str(doc, module, "error", "neither product_family nor product_name is set by O.E.M.");
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, "family", &host.family);
111    yyjson_mut_obj_add_strbuf(doc, obj, "name", &host.name);
112    yyjson_mut_obj_add_strbuf(doc, obj, "version", &host.version);
113    yyjson_mut_obj_add_strbuf(doc, obj, "sku", &host.sku);
114    yyjson_mut_obj_add_strbuf(doc, obj, "vendor", &host.vendor);
115    yyjson_mut_obj_add_strbuf(doc, obj, "serial", &host.serial);
116    yyjson_mut_obj_add_strbuf(doc, obj, "uuid", &host.uuid);
117    success = true;
118
119exit:
120    ffStrbufDestroy(&host.family);
121    ffStrbufDestroy(&host.name);
122    ffStrbufDestroy(&host.version);
123    ffStrbufDestroy(&host.sku);
124    ffStrbufDestroy(&host.serial);
125    ffStrbufDestroy(&host.uuid);
126    ffStrbufDestroy(&host.vendor);
127
128    return success;
129}
130
131void ffInitHostOptions(FFHostOptions* options) {
132    ffOptionInitModuleArg(&options->moduleArgs, "󰌢");
133}
134
135void ffDestroyHostOptions(FFHostOptions* options) {
136    ffOptionDestroyModuleArg(&options->moduleArgs);
137}
138
139FFModuleBaseInfo ffHostModuleInfo = {
140    .name = "Host",
141    .description = "Print your computer's product name",
142    .displayName = {
143        .en = "Host",
144        .ar = "المضيف",
145        .cs = "Hostitel",
146        .de = "Rechner",
147        .es = "Host",
148        .fi = "Isäntä",
149        .fr = "Hôte",
150        .gl = "Host",
151        .he = "מארח",
152        .id = "Host",
153        .it = "Host",
154        .ja = "ホスト",
155        .ko = "호스트",
156        .pl = "Host",
157        .pt = "Host",
158        .ru = "Модель",
159        .tr = "Cihaz",
160        .uk = "Хост",
161        .vi = "Máy chủ",
162        .zh_CN = "主机",
163        .zh_TW = "主機",
164    },
165    .initOptions = (void*) ffInitHostOptions,
166    .destroyOptions = (void*) ffDestroyHostOptions,
167    .parseJsonObject = (void*) ffParseHostJsonObject,
168    .printModule = (void*) ffPrintHost,
169    .generateJsonResult = (void*) ffGenerateHostJsonResult,
170    .generateJsonConfig = (void*) ffGenerateHostJsonConfig,
171    .formatArgs = FF_FORMAT_ARG_LIST(((FFModuleFormatArg[]) {
172        { "Product family", "family" },
173        { "Product name", "name" },
174        { "Product version", "version" },
175        { "Product sku", "sku" },
176        { "Product vendor", "vendor" },
177        { "Product serial number", "serial" },
178        { "Product uuid", "uuid" },
179    })),
180    .defaultOrder = 4,
181};