/* pow! - the pow!erful package manager Copyright (C) 2026 forever2k38 This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "config.h" #include "log.h" #include "lauxlib.h" #include "lualib.h" #include "stdlib.h" #include "string.h" int pow_open_config(pow_config *cfg, char *path) { int err; cfg->L = luaL_newstate(); if (!cfg->L) { return 1; } lua_State *L = cfg->L; // just easier to access luaL_openlibs(L); err = luaL_loadfile(L, path); if (err) { return 1; } err = lua_pcall(L, 0, 1, 0); if (err) { pow_log_error("%s\n", lua_tostring(L, -1)); return 1; } if (!lua_istable(L, -1)) { pow_log_error("bad config. you must return a table.\n"); return 1; } lua_getfield(L, -1, "repos"); // this will push the entire config table to -2 // and push repos to -1 if (lua_istable(L, -1)) { size_t repo_count = lua_objlen(L, -1); for (size_t i = 1; i <= repo_count; i++) { lua_rawgeti(L, -1, i); if (lua_istable(L, -1)) { pow_repo *repo = malloc(sizeof(pow_repo)); if (!repo) { lua_pop(L, 1); pow_log_error("malloc for repo failed, what the fuck? something really bad " "happened i guess\n"); return 1; } lua_getfield(L, -1, "path"); if (lua_isstring(L, -1)) { const char *path = lua_tostring(L, -1); const char *path_dup = strdup(path); if (!path_dup) { lua_pop(L, 1); lua_pop(L, 1); free(repo); pow_log_error( "malloc for path failed, what the fuck? something really bad " "happened i guess\n"); return 1; } repo->path = path_dup; } else { pow_log_error("invalid (or non existent) path for repo"); lua_pop(L, 1); lua_pop(L, 1); free(repo); continue; } pow_repo **repos = realloc(cfg->repos, (cfg->repos_count + 1) * sizeof(*repos)); if (!repos) { pow_log_error("failed realloc! bad things coming\n"); lua_pop(L, 1); lua_pop(L, 1); free(repo->path); free(repo); return 1; } repos[cfg->repos_count++] = repo; cfg->repos = repos; lua_pop(L, 1); } lua_pop(L, 1); } lua_pop(L, 1); lua_getfield(L, -1, "makeopts"); if (!lua_isstring(L, -1)) { pow_log_info("no makeopts specified"); } else { cfg->makeopts = strdup(lua_tostring(L, -1)); if (!cfg->makeopts) { pow_log_error("failed to strdup makeopts"); return 1; } } } return 0; } int pow_close_config(pow_config *cfg) { for (size_t i = 0; i < cfg->repos_count; i++) { free(cfg->repos[i]->path); free(cfg->repos[i]); } free(cfg->repos); free(cfg->makeopts); lua_close(cfg->L); return 0; }