#include "validate.h" #include #include static bool is_known_bootloader(const char *name) { return strcmp(name, "limine") == 0 || strcmp(name, "grub") == 0 || strcmp(name, "syslinux") == 0; } /** * validate() - Run static checks on the system config. * @cfg: Configuration to inspect. * * Covers what resolve() does not: hostname presence, bootloader * recognition, non-null kernel/shell pointers, and uniqueness of user * and service names. Pkg references (kernel, shells, declared pkgs) * are all closure roots — resolve() auto-discovers transitive deps, * so no "is in the package list" check is needed. Errors are printed * to stderr. * * Return: true if every check passes. */ bool validate(const system_cfg *cfg) { bool ok = true; if (cfg->hostname == nullptr || cfg->hostname[0] == '\0') { fprintf(stderr, "nb: hostname is empty\n"); ok = false; } if (!is_known_bootloader(cfg->boot.bootloader)) { fprintf(stderr, "nb: unknown bootloader '%s'\n", cfg->boot.bootloader); ok = false; } if (cfg->boot.kernel == nullptr) { fprintf(stderr, "nb: boot.kernel is null\n"); ok = false; } for (size_t i = 0; i < cfg->users.len; i++) { const user *u = &cfg->users.data[i]; if (u->name == nullptr || u->name[0] == '\0') { fprintf(stderr, "nb: user[%zu] has empty name\n", i); ok = false; continue; } if (u->shell == nullptr) { fprintf(stderr, "nb: user '%s' has null shell\n", u->name); ok = false; } for (size_t j = i + 1; j < cfg->users.len; j++) { if (strcmp(u->name, cfg->users.data[j].name) == 0) { fprintf(stderr, "nb: duplicate user name '%s'\n", u->name); ok = false; } } } for (size_t i = 0; i < cfg->services.len; i++) { const service *s = &cfg->services.data[i]; if (s->name == nullptr || s->name[0] == '\0') { fprintf(stderr, "nb: service[%zu] has empty name\n", i); ok = false; continue; } for (size_t j = i + 1; j < cfg->services.len; j++) { if (strcmp(s->name, cfg->services.data[j].name) == 0) { fprintf(stderr, "nb: duplicate service name '%s'\n", s->name); ok = false; } } } return ok; }