diff options
| author | dacctal <donotcontactmevia@email.invalid> | 2026-07-17 00:18:01 +0000 |
|---|---|---|
| committer | dacctal <donotcontactmevia@email.invalid> | 2026-07-17 00:18:01 +0000 |
| commit | 7019724ab5c818e18fb5ee61b6b14487c47da3ec (patch) | |
| tree | 0a7d60563c56a75fcfe7ecdd66f21bdc420fc1fa /src | |
| parent | 43e35385f741a3c48cf667fd55bc1175d1d2b927 (diff) | |
more features but memory leak
Diffstat (limited to 'src')
| -rw-r--r-- | src/build.c | 20 | ||||
| -rw-r--r-- | src/fetch.c | 4 | ||||
| -rw-r--r-- | src/help.c | 5 | ||||
| -rw-r--r-- | src/lua_globs.c | 9 | ||||
| -rw-r--r-- | src/lua_vars.c | 2 | ||||
| -rw-r--r-- | src/parse_args.c | 27 | ||||
| -rw-r--r-- | src/pkg_create.c | 39 | ||||
| -rw-r--r-- | src/pkg_exists.c | 54 | ||||
| -rw-r--r-- | src/pkg_free.c | 2 | ||||
| -rw-r--r-- | src/pkg_install.c (renamed from src/lua_install.c) | 36 | ||||
| -rw-r--r-- | src/pkg_remove.c | 199 |
11 files changed, 325 insertions, 72 deletions
diff --git a/src/build.c b/src/build.c index 0b97af7..740d739 100644 --- a/src/build.c +++ b/src/build.c @@ -12,7 +12,6 @@ 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 <https://www.gnu.org/licenses/>. @@ -35,8 +34,7 @@ bool target_build(lua_State *L, char* lua_file, str *target) { install_dependencies(L); } lua_pop(L, 1); - if (!lua_try_function(L, lua_file, "build")) - lua_pop(L, 2); + if (!lua_try_function(L, lua_file, "build")) return false; return true; } @@ -56,7 +54,7 @@ bool repo_build(package_t *pkg) { return false; } bool target_success = target_build(L, "init.lua", &pkg->target); - lua_pop(L, 3); + lua_pop(L, 4); return target_success; } @@ -119,24 +117,24 @@ bool config_build(package_t *pkg) { } bool build_loop(package_t *pkg) { - log_info("attempting init.lua: 'repositories.%.*s.build'", str_fmt(&pkg->name)); + if (flags.verbose) log_info("attempting init.lua: 'repositories.%.*s.build'", str_fmt(&pkg->name)); if (repo_build(pkg)) { return true; } - log_warn("failed init.lua: 'repositories.%.*s.build'", str_fmt(&pkg->name)); + if (flags.verbose) log_warn("failed init.lua: 'repositories.%.*s.build'", str_fmt(&pkg->name)); - log_info("attempting bldit.lua"); + if (flags.verbose) log_info("attempting bldit.lua"); if (bldit(pkg)) { return true; } - log_warn("failed bldit.lua"); + if (flags.verbose) log_warn("failed bldit.lua"); - log_info("attempting init.lua: 'build_systems'"); + if (flags.verbose) log_info("attempting init.lua: 'build_systems'"); if (config_build(pkg)) { return true; } - log_warn("failed init.lua: 'build_systems'"); + if (flags.verbose) log_warn("failed init.lua: 'build_systems'"); return false; } bool build(package_t *pkg) { char cwd[MAX_PATH_LEN]; getcwd(cwd, MAX_PATH_LEN); - if (str_equal_cstr(&pkg->src, cwd) && !pkg->is_local) chdir(pkg->src.data); + if (!str_equal_cstr(&pkg->src, cwd) && !pkg->is_local) chdir(pkg->src.data); if (build_loop(pkg)) return true; log_error("no usable build system was found for %.*s", str_fmt(&pkg->name)); diff --git a/src/fetch.c b/src/fetch.c index 87c632d..3792a5e 100644 --- a/src/fetch.c +++ b/src/fetch.c @@ -51,7 +51,7 @@ bool fetch(package_t *pkg) { if (pkg->url.data == NULL || pkg->src.data == NULL) { - log_warn("invalid pkg: url or src is NULL"); + if (flags.verbose) log_warn("invalid pkg: url or src is NULL"); return false; } @@ -97,7 +97,7 @@ bool fetch(package_t *pkg) { waitpid(pid, &status, 0); bool result = (WEXITSTATUS(status) == 0); - if (!result) { log_warn("git clone failed"); } + if (!result) { log_error("git clone failed"); } return result; } @@ -21,7 +21,6 @@ #include <stdio.h> #include "help.h" - #include "globs.h" void help(void) { @@ -70,7 +69,7 @@ void help(void) { printf(RED "subcommand flags" COLOR_RESET ":\n"); for (size_t i = 0; i < LENGTH(cmd_flags); i++) { - printf(COLOR_RESET "\t" GREEN "%-2s" COLOR_RESET ", " YELLOW + printf(COLOR_RESET " " GREEN "%-2s" COLOR_RESET ", " YELLOW "%-12s" BLUE "%-16s" GRAY "# %s\n" COLOR_RESET, cmd_flags[i].short_flag, cmd_flags[i].long_flag, cmd_flags[i].arg, cmd_flags[i].desc); @@ -78,7 +77,7 @@ void help(void) { printf("\n" RED "modifier flags" COLOR_RESET ":\n"); for (size_t i = 0; i < LENGTH(mod_flags); i++) { - printf(COLOR_RESET "\t" GREEN "%-2s" COLOR_RESET ", " YELLOW + printf(COLOR_RESET " " GREEN "%-2s" COLOR_RESET ", " YELLOW "%-12s" BLUE "%-16s" GRAY "# %s\n" COLOR_RESET, mod_flags[i].short_flag, mod_flags[i].long_flag, mod_flags[i].arg, mod_flags[i].desc); diff --git a/src/lua_globs.c b/src/lua_globs.c index b14eb3a..5f333a4 100644 --- a/src/lua_globs.c +++ b/src/lua_globs.c @@ -61,7 +61,7 @@ void init_lua_state(void) { } if (file_exists(cfg.repos.data)) { if (luaL_loadfile(L, cfg.repos.data) || lua_pcall(L, 0, 0, 0)) { - log_warn("cannot load repository file: %s", lua_tostring(L, -1)); + if (flags.verbose) log_warn("cannot load repository file: %s", lua_tostring(L, -1)); lua_pop(L, 1); } } @@ -76,7 +76,7 @@ void init_bldit_state(void) { luaL_openlibs(B); if (luaL_loadfile(B, "bldit.lua") || lua_pcall(B, 0, 0, 0)) { if (flags.verbose) - log_warn("cannot run bldit: %s", lua_tostring(B, -1)); + if (flags.verbose) log_warn("cannot run bldit: %s", lua_tostring(B, -1)); return; } lua_pushfstring(B, "%s", inst_dirs.prefix.data); @@ -140,7 +140,7 @@ bool lua_try_function(lua_State *L, char *lua_file, char *fname) { lua_isnt_type(fname, "function"); lua_pop(L, 1); } else if (lua_pcall(L, 0, 1, 0) != LUA_OK) { - log_warn( + if (flags.verbose) log_warn( "%s: '%s' function borked: %s", lua_file, fname, lua_tostring(L, -1) ); @@ -148,7 +148,7 @@ bool lua_try_function(lua_State *L, char *lua_file, char *fname) { return false; } if (!lua_isnumber(L, -1) || lua_tonumber(L, -1) != 0) { - log_warn( + if (flags.verbose) log_warn( "%s: '%s' failed: %s", lua_file, fname, lua_tostring(L, -1) ); @@ -166,7 +166,6 @@ bool lua_try_table(lua_State *L, char *lua_file, char *tname) { bldit_isnt_type(tname, "table"); else lua_isnt_type(tname, "table"); - lua_pop(L, 1); return false; } return true; diff --git a/src/lua_vars.c b/src/lua_vars.c index ddb4c5a..7420ae0 100644 --- a/src/lua_vars.c +++ b/src/lua_vars.c @@ -58,11 +58,9 @@ void init_install_directories(void) { void init_prefix_directory(void) { lua_getglobal(L, "prefix"); if (!lua_isstring(L, -1)) { -// printf(PRINT_ERROR "init.lua: 'prefix' is not a string.\n"); lua_isnt_type("prefix", "string."); return; } inst_dirs.prefix = mstr(lua_tostring(L, -1)); -// snprintf(prefix_dir, MAX_PATH_LEN, "%s", lua_tostring(L, -1)); lua_pop(L, 1); } diff --git a/src/parse_args.c b/src/parse_args.c index d4719c7..61e1fcb 100644 --- a/src/parse_args.c +++ b/src/parse_args.c @@ -23,14 +23,13 @@ #include "parse_args.h" +#include "build.h" #include "globs.h" #include "log.h" #include "str.h" // #include "declare.h" // #include "easter_egg.h" #include "help.h" -// #include "name_from_url.h" -// #include "pkg_build.h" #include "pkg.h" // #include "pkg_search.h" // #include "pkg_install.h" @@ -38,7 +37,7 @@ // #include "pkg_list.h" // #include "pkg_remove.h" // #include "pkgit_globals.h" -// #include "repo_add.h" +#include "add_repo.h" // #include "update.h" #define COMMAND(large, small) \ @@ -50,7 +49,10 @@ void cmd_add(char **argv, int i) { if (argv[i + 1]) { printf("add repo %s\n", argv[i + 1]); - // repo_add(argv[i + 1], name_from_url(argv[i + 1])); + str_slc arg = mstrslc(argv[i + 1]); + package_t pkg = pkg_create(arg); + add_repo(&pkg); + pkg_free(&pkg); } else { NOT_ENOUGH_ARGS(argv[i], "url"); } @@ -61,16 +63,16 @@ void cmd_build(int argc, char **argv, int i) { for (int j = i + 1; j < argc; j++) { if (argv[j][0] == '-') continue; - printf("build pkg %s\n", argv[j]); - // str_slc arg = mstrslc(argv[j]); - // package_t pkg = pkg_create(arg); - // pkg_build(pkg); + str_slc arg = mstrslc(argv[j]); + package_t pkg = pkg_create(arg); + build(&pkg); + pkg_free(&pkg); } } else { - printf("build pkg .\n"); - // str_slc arg = mstrslc("."); - // package_t pkg = pkg_create(arg); - // pkg_build(pkg); + str_slc arg = mstrslc("."); + package_t pkg = pkg_create(arg); + build(&pkg); + pkg_free(&pkg); } } @@ -79,7 +81,6 @@ void cmd_install(int argc, char **argv, int i) { for (int j = i + 1; j < argc; j++) { if (argv[j][0] == '-') continue; - printf("install pkg %s\n", argv[j]); str_slc arg = mstrslc(argv[j]); package_t pkg = pkg_create(arg); pkg_install(&pkg); diff --git a/src/pkg_create.c b/src/pkg_create.c index de20038..728a955 100644 --- a/src/pkg_create.c +++ b/src/pkg_create.c @@ -7,7 +7,6 @@ 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 @@ -15,7 +14,6 @@ You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>. - */ #include <string.h> @@ -26,8 +24,11 @@ #include "files.h" #include "globs.h" #include "log.h" +#include "pkgit_lua.h" #include "str.h" +str new_arg_str; + static str get_destdir(str_slc cwd, str_slc arg) { str_slc name = str_slc_from_after_delim(arg, '/'); if (str_slc_first(arg) == '.') @@ -75,29 +76,25 @@ static void assign_pkg_target(package_t *pkg, str *new_arg_str) { if (str_find_char(&pkg->target, '@')) pkg->target.len--; str_free(&tmp_arg); pkg->name.len -= pkg->target.len + 1; + } else if (!flags.verbose) { + pkg->target = mstr("quiet"); } else pkg->target = mstr("default"); } package_t pkg_create(str_slc arg) { package_t pkg = { .is_local = false, }; - char cwd[MAX_PATH_LEN]; getcwd(cwd, MAX_PATH_LEN); str_slc cwd_slc = mstrslc(cwd); str cwd_str = mstr(cwd); str dest_dir = get_destdir(cwd_slc, arg); - str new_arg_str = str_from_str_slc(arg); + str tmp_str = str_from_str_slc(arg); + str_copy_into(&new_arg_str, &tmp_str); + str_free(&tmp_str); bool is_installed_locally = is_directory(dest_dir.data); - - bool is_in_repos = false; - // for (size_t i = 0; i < cached_repos_count; i++) { - // if (strcmp(new_arg, cached_repos[i].source_key) == 0) { - // is_in_repos = true; - // break; - // } - // } + bool is_in_repos = pkg_exists(&new_arg_str); assign_pkg_version(&pkg, &new_arg_str); assign_pkg_target(&pkg, &new_arg_str); @@ -105,12 +102,12 @@ package_t pkg_create(str_slc arg) { str tmp = str_from_after_delim(&new_arg_str, '@'); new_arg_str.len -= tmp.len + 1; str_free(&tmp); - } - if (str_find_char(&new_arg_str, ',')) { + } if (str_find_char(&new_arg_str, ',')) { str tmp = str_from_after_delim(&new_arg_str, ','); new_arg_str.len -= tmp.len + 1; str_free(&tmp); } + if (strncmp(arg.data, "http", 4) == 0 || strncmp(arg.data, "ssh", 3) == 0) { pkg.url = new_arg_str; pkg.name = str_from_after_delim(&new_arg_str, '/'); @@ -119,12 +116,9 @@ package_t pkg_create(str_slc arg) { pkg.name = str_from_after_delim(&cwd_str, '/'); pkg.is_local = true; } else if (is_in_repos) { - // for (size_t i = 0; i < cached_repos_count; i++) { - // if (strcmp(new_arg, cached_repos[i].source_key) == 0) { - // pkg.url = strdup(cached_repos[i].source_value); - // break; - // } - // } + str tmp_url = pkg_get_url(&new_arg_str); + str_copy_into(&pkg.url, &tmp_url); + str_free(&tmp_url); pkg.name = new_arg_str; } else if (is_installed_locally) { pkg.url = mstr(""); @@ -132,12 +126,17 @@ package_t pkg_create(str_slc arg) { pkg.is_local = true; } else { log_error("'%.*s' is not a valid package", str_fmt(&arg)); + str_free(&cwd_str); + str_free(&dest_dir); + str_free(&new_arg_str); exit(EXIT_FAILURE); } + if (str_find_char(&new_arg_str, ',') && str_find_char(&new_arg_str, '@') ) pkg.name.len--; pkg.src = get_pkgsrc(pkg); + str_free(&cwd_str); str_free(&dest_dir); return pkg; diff --git a/src/pkg_exists.c b/src/pkg_exists.c new file mode 100644 index 0000000..05aa238 --- /dev/null +++ b/src/pkg_exists.c @@ -0,0 +1,54 @@ +/* + + pkgit - package it! + + Copyright (C) 2026 dacctal + 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 <https://www.gnu.org/licenses/>. + +*/ + +#include "pkgit_lua.h" +#include "str.h" + +bool pkg_exists(str *name) { + lua_getglobal(L, "repositories"); + if (!config_loaded || !lua_istable(L, -1)) { + lua_pop(L, 1); + return false; + } + if (!lua_try_table(L, "init.lua", name->data)) { + lua_pop(L, 2); + return false; + } + lua_pop(L, 2); + return true; +} + +str pkg_get_url(str *name) { + lua_getglobal(L, "repositories"); + if (!config_loaded || !lua_istable(L, -1)) { + lua_pop(L, 1); + return mstr(""); + } + if (!lua_try_table(L, "init.lua", name->data)) { + lua_pop(L, 2); + return mstr(""); + } + lua_getfield(L, -1, "url"); + if (lua_isstring(L, -1)) { + return mstr(lua_tostring(L, -1)); + } + lua_pop(L, 3); + return mstr(""); +} diff --git a/src/pkg_free.c b/src/pkg_free.c index 2b1d670..12659fe 100644 --- a/src/pkg_free.c +++ b/src/pkg_free.c @@ -1,4 +1,5 @@ #include "pkg.h" +#include "globs.h" void pkg_free(package_t *pkg) { str_free(&pkg->name); @@ -6,4 +7,5 @@ void pkg_free(package_t *pkg) { str_free(&pkg->version); str_free(&pkg->target); str_free(&pkg->src); + str_free(&new_arg_str); } diff --git a/src/lua_install.c b/src/pkg_install.c index 5bf5270..b727d01 100644 --- a/src/lua_install.c +++ b/src/pkg_install.c @@ -61,15 +61,12 @@ bool target_install(lua_State *L, char* lua_file, str *target) { lua_pop(L, 1); return false; } - lua_pop(L, 1); - lua_try_function(L, lua_file, "pre_install"); - lua_pop(L, 1); + //lua_try_function(L, lua_file, "pre_install"); if (!lua_try_function(L, lua_file, "install")) { lua_pop(L, 1); return false; } - lua_pop(L, 1); - lua_try_function(L, lua_file, "post_install"); + //lua_try_function(L, lua_file, "post_install"); lua_pop(L, 1); return true; } @@ -94,6 +91,10 @@ bool repo_install(package_t *pkg) { bool bldit_install(package_t *pkg) { init_bldit_state(); + if (!bldit_loaded) { + lua_close(B); + return false; + } //if (!is_bldit_usable()) { // log_error("bldit version is newer than the installed pkgit version"); // log_error("consider updating pkgit"); @@ -122,6 +123,7 @@ bool config_install(package_t *pkg) { str file_path = str_format("%.*s/%s", str_fmt(&pkg->src), key); if (access(file_path.data, F_OK) != 0) { lua_pop(L, 1); + str_free(&file_path); continue; } str_free(&file_path); @@ -131,6 +133,7 @@ bool config_install(package_t *pkg) { } target_success = target_install(L, "init.lua", &pkg->target); lua_pop(L, 2); + if (target_success) break; } lua_pop(L, 1); return target_success; @@ -142,7 +145,7 @@ void pkg_install(package_t *pkg) { log_info("%.*s is already installed.", str_fmt(&pkg->name)); return; } else { - log_warn("%.*s is already installed.", str_fmt(&pkg->name)); + if (flags.verbose) log_warn("%.*s is already installed.", str_fmt(&pkg->name)); } } char cwd[MAX_PATH_LEN]; @@ -177,20 +180,21 @@ void pkg_install(package_t *pkg) { } log_success("installed " GREEN "%.*s" COLOR_RESET , str_fmt(&pkg->name)); - bool repo_exists = false; + //bool repo_exists = false; + //for (size_t i = 0; i < cached_repos_count; i++) { //char *repo_name = name_from_url(cached_repos[i].source_key); //if (strcmp(repo_name, pkg.name) == 0) { repo_exists = true; } //free(repo_name); //} - if (!repo_exists) { - log_pkgit("adding " GREEN "%.*s" COLOR_RESET , &pkg->name); - if (pkg->url.len > 0) { - add_repo(pkg); - log_pkgit("added " GREEN "%.*s" COLOR_RESET , &pkg->name); - } - } else { - log_info("repo already exists, done"); - } + //if (!repo_exists) { + // log_pkgit("adding " GREEN "%.*s" COLOR_RESET , &pkg->name); + // if (pkg->url.len > 0) { + // add_repo(pkg); + // log_pkgit("added " GREEN "%.*s" COLOR_RESET , &pkg->name); + // } + //} else { + // log_info("repo already exists, done"); + //} } diff --git a/src/pkg_remove.c b/src/pkg_remove.c new file mode 100644 index 0000000..1d4be14 --- /dev/null +++ b/src/pkg_remove.c @@ -0,0 +1,199 @@ +/* + + pkgit - package it! + + Copyright (C) 2026 dacctal + 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 <https://www.gnu.org/licenses/>. + +*/ + +#include <ftw.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/stat.h> +#include <unistd.h> + +#include "pkgit_lua.h" +#include "files.h" +#include "globs.h" +#include "log.h" + +bool target_uninstall(lua_State *L, char* lua_file, str *target) { + if (!lua_try_table(L, lua_file, target->data)) { + lua_pop(L, 1); + return false; + } + if (!lua_try_function(L, lua_file, "uninstall")) { + lua_pop(L, 1); + return false; + } + lua_pop(L, 1); + return true; +} + +bool repo_uninstall(package_t *pkg) { + if (!config_loaded || !lua_istable(L, -1)) { + lua_isnt_type("repositories", "table"); + lua_pop(L, 1); + return false; + } + if (!lua_try_table(L, "init.lua", pkg->name.data)) { + lua_isnt_type(pkg->name.data, "table"); + lua_pop(L, 2); + return false; + } + if (!lua_try_table(L, "init.lua", "targets")) return false; + bool target_success = target_uninstall(L, "init.lua", &pkg->target); + lua_pop(L, 3); + return target_success; +} + +bool bldit_uninstall(package_t *pkg) { + init_bldit_state(); + if (!bldit_loaded) { + lua_close(B); + return false; + } + //if (!is_bldit_usable()) { + // log_error("bldit version is newer than the installed pkgit version"); + // log_error("consider updating pkgit"); + // if (!flags.force) return false; + //} + lua_pushfstring(B, "%s", inst_dirs.prefix.data); + lua_setglobal(B, "prefix"); + lua_pop(B, 1); + if (!lua_try_table(B, "bldit.lua", "targets")) return false; + bool target_success = target_uninstall(B, "bldit.lua", &pkg->target); + lua_pop(B, 2); + lua_close(B); + return target_success; +} + +bool config_uninstall(package_t *pkg) { + lua_getglobal(L, "build_systems"); + lua_pushnil(L); + bool target_success = false; + while (lua_next(L, -2) != 0) { + const char *key = lua_tostring(L, -2); + if (!lua_istable(L, -1)) { + lua_pop(L, 1); + continue; + } + str file_path = str_format("%.*s/%s", str_fmt(&pkg->src), key); + if (access(file_path.data, F_OK) != 0) { + lua_pop(L, 1); + str_free(&file_path); + continue; + } + str_free(&file_path); + if (!lua_try_table(L, "init.lua", "targets")) { + lua_pop(L, 2); + continue; + } + target_success = target_uninstall(L, "init.lua", &pkg->target); + lua_pop(L, 2); + if (target_success) break; + } + lua_pop(L, 1); + return target_success; +} + +static int remove_installed( + const char *src_path, const struct stat *sb, + int typeflag, struct FTW *ftwbuf +) { + (void)sb; + (void)ftwbuf; + + if (typeflag == FTW_F) { + const char *filename = src_path + ftwbuf->base; + const char *ext = strrchr(filename, '.'); + if (!ext) + ext = ""; + + if (strncmp(ext, ".so", 3) == 0) { + char dest[MAX_PATH_LEN]; + snprintf(dest, sizeof(dest), "%s/%s", inst_dirs.lib.data, filename); + if (file_exists(dest)) + remove(dest); + } else if (access(src_path, X_OK) == 0) { + if ( + strcmp(ext, ".sample") != 0 && + strcmp(filename, "bldit") != 0 && + strcmp(filename, "build.sh") != 0 && + strcmp(filename, "compile.sh") != 0 + ) { + char dest[MAX_PATH_LEN]; + snprintf(dest, sizeof(dest), "%s/%s", inst_dirs.bin.data, filename); + if (file_exists(dest)) + remove(dest); + } + } else if (strcmp(ext, ".h") == 0) { + char dest[MAX_PATH_LEN]; + snprintf(dest, sizeof(dest), "%s/%s", inst_dirs.include.data, filename); + if (file_exists(dest)) + remove(dest); + } + } + return 0; +} + +static int remove_tree( + const char *fpath, const struct stat *sb, + int typeflag, struct FTW *ftwbuf +) { + (void)sb; + (void)ftwbuf; + if (typeflag == FTW_F || typeflag == FTW_SL) { + unlink(fpath); + } else if (typeflag == FTW_DP) { + rmdir(fpath); + } + return 0; +} + +void remove_pkg(package_t *pkg) { + if (!is_directory(pkg->src.data)) { + log_error("%.*s is not installed!", str_fmt(&pkg->name)); + return; + } + chdir(pkg->src.data); + + bool uninstall_available = false; + if (!uninstall_available) if (repo_uninstall(pkg)) + uninstall_available = true; + if (!uninstall_available) if (bldit_uninstall(pkg)) + uninstall_available = true; + if (!uninstall_available) if (config_uninstall(pkg)) + uninstall_available = true; + + if (!uninstall_available) + log_error( + "no uninstall function availible for package: %.*s", + str_fmt(&pkg->name) + ); + + nftw(pkg->src.data, remove_installed, 64, FTW_PHYS); + const char *last_slash = strrchr(pkg->src.data, '/'); + char target[MAX_PATH_LEN]; + if (last_slash && last_slash != pkg->src.data) { + size_t parent_len = last_slash - pkg->src.data; + snprintf(target, sizeof(target), "%.*s", (int)parent_len, pkg->src.data); + } else { + snprintf(target, sizeof(target), "%s", pkg->src.data); + } + nftw(pkg->src.data, remove_tree, 64, FTW_DEPTH | FTW_PHYS); + log_success("removed %s", str_fmt(&pkg->name)); +} |
