From 00c9756268b27f3fcccfe9dbc5334284b423bd28 Mon Sep 17 00:00:00 2001 From: Arslaan Pathan Date: Thu, 17 Sep 2026 15:21:11 +1200 Subject: clean slate --- README.md | 127 +------------- include/libmbpk.h | 44 ----- meson.build | 42 ----- src/libmbpk.c | 492 ----------------------------------------------------- src/mbpk-install.c | 20 --- 5 files changed, 2 insertions(+), 723 deletions(-) delete mode 100644 include/libmbpk.h delete mode 100644 meson.build delete mode 100644 src/libmbpk.c delete mode 100644 src/mbpk-install.c diff --git a/README.md b/README.md index bca474d..d8fd6f1 100644 --- a/README.md +++ b/README.md @@ -1,126 +1,3 @@ -# mbpk - -**M**inimal **B**inary **P**ackage **K**it - -## What is mbpk? - -`mbpk` is a dead-simple binary package manager, primarily developed for [Yerba Linux](https://git.arslaancodes.com/yerbalinux.git/about). - -Core functions are handled in libmbpk, whereas the commands themselves are simply wrappers around the library. - -## Package Format - -A package is a `.tar.zst` archive with the file extension `.mpk`. - -### Structure - -``` -pkgname-1.2.3.mpk --> pkg.ini # Metadata --> _install.tar.zst # This will be extracted to / --> post-install # Optional, runs after install --> pre-remove # Optional, runs before remove -``` - -#### pkg.ini - -```ini -name = pkgname -version = 1.2.3 -desc = testing testing 123, i like chicken nuggets, not 3 -deps = dep1 dep2 dep -maintainer = French Hacker -license = WTFPL -``` - -#### Scripts - -- `post-install`: Runs after `_install.tar.zst` is extracted -- `pre-remove`: Runs before files are removed - -If they don't exist, mbpk simply ignores them. -If they do exist, they are executed at their respective times. -Failure to execute these scripts will be ignored and the package manager will continue, warning the user. - -## Repositories - -Repository configuration is stored in `/etc/mbpk-repos.ini`. - -Configuration format is as follows: -```ini -# Example repository configuration for mbpk -# Format: name = url - -[core] -url = https://yerba.arslaancodes.com/repo/core - -[extra] -url = https://yerba.arslaancodes.com/repo/extra -``` - -Repos will be synchronized by copying them into `/var/lib/mbpk-repo/`. -For example, the repos from the previous configuration example would be at the following locations: -- `/var/lib/mbpk-repo/core` -- `/var/lib/mbpk-repo/extra` - -### Structure - -Repository structure is as follows: - -``` -core/ # Example repository name --> repo.ini # Repository metadata --> pkg/ - -> pkgname.ini # Package metadata - -> pkgname2.ini # More package metadata --> files/ - -> pkgname-1.2.3.mpk # Example package file -``` - -#### repo.ini - -```ini -name = core -desc = Core repo for Yerba Linux -url = https://yerba.arslaancodes.com/repo/core -packages = pkgname pkgname2 (...) -``` - -#### pkg/pkgname.ini - -```ini -name = pkgname -version = 1.2.3 -desc = testing testing 123, i like chicken nuggets, not 3 -url = https://yerba.arslaancodes.com/repo/core/files/pkgname-1.2.3.mpk -deps = dep1 dep2 dep3 -maintainer = French Hacker -license = WTFPL -``` - -## Database & Package Installation/Removal - -The database is dead-simple. - -Upon installing a package, the .mpk file will first be extracted to `/var/lib/mbpk/`. From there, the package manager will continue to extract `_install.tar.zst` to `/`. - -This installation flow ensures that the package database is automatically handled, because `/var/lib/mbpk` itself acts as a database of all packages. - -Removal of a package is simple: -- Read package metadata from the database -- Check for `pre-remove`, and run if it exists -- Use libarchive to list all files in `_install.tar.zst` and remove them respectively - -## Usage - -`mbpk` is not one standalone command-line tool, it is actually a combination of many binaries wrapping the `libmbpk` library. - -- `mbpk-install `: installs a package from a repository -- `mbpk-install-local `: installs a local package file -- `mbpk-remove `: removes a package -- `mbpk-list`: lists all installed packages -- `mbpk-update`: updates package repositories -- `mbpk-upgrade `: upgrades the specified package -- `mbpk-search `: searches repositories for a specified term -- `mbpk-info `: shows metadata of a requested installed package +# mbpk (Minimal Binary Package Kit) +xbps but rootless diff --git a/include/libmbpk.h b/include/libmbpk.h deleted file mode 100644 index 083a693..0000000 --- a/include/libmbpk.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef LIBMBPK_H -#define LIBMBPK_H - -#define MBPK_OK 0 -#define MBPK_DB_FAIL 1 -#define MBPK_REPO_FAIL 2 -#define MBPK_DL_FAIL 3 -#define MBPK_EXTRACT_FAIL 4 -#define MBPK_CURL_INIT_FAIL 5 -#define MBPK_CURL_PERFORM_FAIL 6 -#define MBPK_OUT_OF_MEMORY 7 - -typedef struct mbpk_pkg mbpk_pkg; - -struct mbpk_pkg { - const char *pkgname; - const char *version; - const char *desc; - const char *url; - mbpk_pkg **deps; - const char *maintainer; - const char *license; -}; - -int mbpk_init(void); -int mbpk_search(const char *package_name, mbpk_pkg ***pkgs); -int mbpk_search_exact(const char *package_name, mbpk_pkg **pkg); -int mbpk_get_installed_pkg(const char *package_name, mbpk_pkg **pkg); -int mbpk_pkg_from_file(const char *file_path, mbpk_pkg **pkg); -int mbpk_install(mbpk_pkg **pkg); -int mbpk_remove(mbpk_pkg **pkg); -int mbpk_list(mbpk_pkg ***pkgs, int *count); -int mbpk_info(const char *name, mbpk_pkg **pkg); -int mbpk_resolve_dependencies(mbpk_pkg **pkg, mbpk_pkg ***pkgs); -int mbpk_upgrade(mbpk_pkg **pkg); -int mbpk_upgrade_all(void); -int mbpk_update_repositories(void); -const char *mbpk_strerr(int code); -void mbpk_cleanup(void); - -void mbpk_pkg_free(mbpk_pkg *pkg); -void mbpk_pkg_free_list(mbpk_pkg **pkgs, int count); - -#endif diff --git a/meson.build b/meson.build deleted file mode 100644 index 8f89072..0000000 --- a/meson.build +++ /dev/null @@ -1,42 +0,0 @@ -project('mbpk', 'c', default_options: ['c_std=c89', 'warning_level=3']) - -add_project_arguments( - '-pedantic-errors', - '-Werror', - '-Wshadow', - '-Wconversion', - '-Wsign-conversion', - '-Wno-cast-qual', - language : 'c' -) - -inc = include_directories('include') - -deps = [] -deps += dependency('libcurl') -deps += dependency('libarchive') -deps += dependency('libzstd') -deps += dependency('inih') - -libdir = get_option('libdir') -bindir = get_option('bindir') - -libmbpk_src = [ - 'src/libmbpk.c' - ] - -libmbpk = shared_library('libmbpk', libmbpk_src, include_directories: inc, dependencies: deps, install: true, install_dir: libdir) - -install_headers('include/libmbpk.h') - -deps += declare_dependency(link_with: libmbpk, include_directories: inc, dependencies: deps) - -executable('mbpk-install', 'src/mbpk-install.c', dependencies: deps, install: true, install_dir: bindir) - -pkg = import('pkgconfig') -pkg.generate(libmbpk, - subdirs: 'libmbpk', - name: 'mbpk', - filebase: 'libmbpk', - description: 'Minimal Binary Package Kit') - diff --git a/src/libmbpk.c b/src/libmbpk.c deleted file mode 100644 index 8cf6f70..0000000 --- a/src/libmbpk.c +++ /dev/null @@ -1,492 +0,0 @@ -#define _POSIX_C_SOURCE 200809L -#define _XOPEN_SOURCE 700 -#include -#include -#include -#include "libmbpk.h" -#include "ini.h" -#include -#include -#include - -#define MBPK_DB_DIR "/var/lib/mbpk" -#define MBPK_REPO_DIR "/var/lib/mbpk-repo" -#define MBPK_REPO_CONFIG "/etc/mbpk-repos.ini" -#define MAX_REPOS 32 - -typedef struct { - const char *name; - const char *desc; - const char *url; - char **packages; -} mbpk_repository; - -struct curl_memory { - char* memory; - size_t size; -}; - -mbpk_repository *repos[MAX_REPOS]; -int repo_count = 0; - -static int unlink_cb(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf) { - int rv; - - /* silence, compiler */ - (void)sb; - (void)typeflag; - (void)ftwbuf; - - rv = remove(fpath); - if (rv) { - perror(fpath); - } - return rv; -} - -int rm_rf(const char *path) { - return nftw(path, unlink_cb, 64, FTW_DEPTH | FTW_PHYS); -} - -/* static char* strdup(const char *s) { - size_t size = strlen(s) + 1; - char* p = (char*)malloc(size); - if (p) { - memcpy(p, s, size); - } - return p; -} */ - -static char **split_string(const char *str) { - char *str_copy; - char *token; - char **result; - int count; - int i; - - count = 0; - - if (!str || !*str) { - return NULL; - } - - str_copy = strdup(str); - if (!str_copy) { - return NULL; - } - - token = strtok(str_copy, " "); - while (token) { - count++; - token = strtok(NULL, " "); - } - free(str_copy); - - if (count == 0) { - return NULL; - } - - result = malloc((unsigned long)(count + 1) * sizeof(char*)); - if (!result) { - return NULL; - } - - str_copy = strdup(str); - if (!str_copy) { - free(result); - return NULL; - } - - token = strtok(str_copy, " "); - i = 0; - while (token) { - result[i] = strdup(token); - if (!result[i]) { - while (i > 0) { - free((void*)result[--i]); - } - free(result); - free(str_copy); - return NULL; - } - i++; - token = strtok(NULL, " "); - } - result[count] = NULL; - free(str_copy); - return result; -} - -static void free_split_array(char **arr) { - int i; - if (!arr) { - return; - } - - for (i = 0; arr[i] != NULL; i++) { - free((void*)arr[i]); - } - free(arr); -} - -static size_t curl_memory_write_calback(void *contents, size_t size, size_t nmemb, void *userp) { - size_t realsize = size * nmemb; - struct curl_memory *mem = (struct curl_memory*)userp; - - char *ptr = realloc(mem->memory, mem->size + realsize + 1); - if (!ptr) { - return 0; - } - - mem->memory = ptr; - memcpy(&(mem->memory[mem->size]), contents, realsize); - mem->size += realsize; - mem->memory[mem->size] = 0; - - return realsize; -} - -int mbpk_init(void) { - CURLcode result; - struct stat st; - if (stat(MBPK_DB_DIR, &st) == -1) { - if (mkdir(MBPK_DB_DIR, 0755) == -1) { - return MBPK_DB_FAIL; - } - } - if (stat(MBPK_REPO_DIR, &st) == -1) { - if (mkdir(MBPK_REPO_DIR, 0755) == -1) { - return MBPK_REPO_FAIL; - } - } - result = curl_global_init(CURL_GLOBAL_ALL); - if (result != CURLE_OK) { - return MBPK_CURL_INIT_FAIL; - } - return MBPK_OK; -} - -static int repo_conf_handler(void* user, const char* section, const char* name, const char* value) { - /* SHUT UP COMPILER AAAAAAAAAAAAA */ - (void)user; - - if (!(strcmp(name, "url") == 0)) { - return 0; /* unknown name, error */ - } - - if (repo_count >= MAX_REPOS) { - return 0; /* too many repos */ - } - - repos[repo_count] = malloc(sizeof(mbpk_repository)); - if (repos[repo_count] == NULL) { - return 0; /* out of memory */ - } - - repos[repo_count]->name = strdup(section); - repos[repo_count]->desc = NULL; /* mbpk_update_repositories will fill this in later */ - repos[repo_count]->url = strdup(value); - repos[repo_count]->packages = NULL; /* mbpk_update_repositories will fill this in later */ - - if (repos[repo_count]->name == NULL || repos[repo_count]->url == NULL) { - free((void*)repos[repo_count]->name); - free((void*)repos[repo_count]->url); - free(repos[repo_count]); - repos[repo_count] = NULL; - return 0; /* out of memory */ - } - - repo_count++; - return 1; -} - -static int repo_ini_handler(void *user, const char *section, const char *name, const char *value) { - mbpk_repository *repo; - - /* SILENCE YOU COMPILER */ - (void)section; - - repo = (mbpk_repository*)user; - - if (strcmp(name, "name") == 0) { - free((void*)repo->name); - repo->name = strdup(value); - } else if (strcmp(name, "url") == 0) { - free((void*)repo->url); - repo->url = strdup(value); - } else if (strcmp(name, "desc") == 0) { - free((void*)repo->desc); - repo->desc = strdup(value); - } else if (strcmp(name, "packages") == 0) { - /* Do stuff here */ - if (repo->packages) { - free_split_array(repo->packages); - } - repo->packages = split_string(value); - } - - return 1; -} - -int mbpk_update_repositories(void) { - /* Declarations */ - struct stat st; - int i; - int j; - mbpk_repository *repo; - CURL *curl; - CURLcode result; - char *repo_ini_url; - char *repo_ini_path; - char *repo_dir; - char *pkg_ini_url; - char *pkg_dir; - char *pkg_ini_path; - size_t dir_len; - size_t repo_ini_path_len; - size_t pkg_ini_url_len; - size_t pkg_dir_len; - size_t pkg_ini_path_len; - FILE *fp; - struct curl_memory chunk; - - repo_count = 0; - if (ini_parse(MBPK_REPO_CONFIG, repo_conf_handler, NULL) < 0) { - return MBPK_REPO_FAIL; - } - - for (i = 0; i < repo_count; i++) { - repo = repos[i]; - printf("[libmbpk debug] processing repo %s\n", repo->name); - chunk.memory = malloc(1); - if (!chunk.memory) { - return MBPK_OUT_OF_MEMORY; - } - chunk.size = 0; - - curl = curl_easy_init(); - if (curl) { - repo_ini_url = malloc(strlen(repo->url) + strlen("/repo.ini") + 1); - if (!repo_ini_url) { - return MBPK_OUT_OF_MEMORY; - } - strcpy(repo_ini_url, repo->url); - strcat(repo_ini_url, "/repo.ini"); - printf("[libmbpk debug] URL: %s\n", repo_ini_url); - printf("[libmbpk debug] repo url field: %s\n", repo->url); - curl_easy_setopt(curl, CURLOPT_URL, repo_ini_url); - curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); /* follow redirects */ - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_memory_write_calback); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)&chunk); - curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1L); /* fail on errors like 404 */ - curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, ""); /* accept encoding like gzip */ - - result = curl_easy_perform(curl); - curl_easy_cleanup(curl); - free(repo_ini_url); - - if (result != CURLE_OK) { - printf("[libmbpk debug] perform cURL failed\n"); - free(chunk.memory); - return MBPK_CURL_PERFORM_FAIL; - } else { - printf("[libmbpk debug] %lu bytes received\n", (unsigned long)chunk.size); - printf("[libmbpk debug] Response:\n%s\n", chunk.memory); - } - } else { - free(chunk.memory); - return MBPK_CURL_INIT_FAIL; - } - - dir_len = strlen(MBPK_REPO_DIR) + 1 + strlen(repo->name) + 1; - repo_dir = malloc(dir_len); - if (!repo_dir) { - free(chunk.memory); - return MBPK_OUT_OF_MEMORY; - } - sprintf(repo_dir, "%s/%s", MBPK_REPO_DIR, repo->name); - - repo_ini_path_len = strlen(repo_dir) + 1 + strlen("repo.ini") + 1; - repo_ini_path = malloc(repo_ini_path_len); - if (!repo_ini_path) { - free(chunk.memory); - free(repo_dir); - return MBPK_OUT_OF_MEMORY; - } - sprintf(repo_ini_path, "%s/repo.ini", repo_dir); - - if (stat(repo_dir, &st) == -1) { - if (mkdir(repo_dir, 0755) == -1) { - free(chunk.memory); - free(repo_ini_path); - free(repo_dir); - return MBPK_REPO_FAIL; - } - } - - fp = fopen(repo_ini_path, "w"); - if (!fp) { - free(repo_ini_path); - free(repo_dir); - free(chunk.memory); - return MBPK_REPO_FAIL; - } - fwrite(chunk.memory, 1, chunk.size, fp); - fclose(fp); - free(chunk.memory); - - if (ini_parse(repo_ini_path, repo_ini_handler, (void*)repo) < 0) { - free(repo_ini_path); - return MBPK_REPO_FAIL; - } - free(repo_ini_path); - printf("[libmbpk debug] repo %s desc: %s\n", repo->name, repo->desc); - printf("[libmbpk debug] repo %s packages:\n", repo->name); - - pkg_dir_len = strlen(repo_dir) + 1 + strlen("pkg") + 1; - pkg_dir = malloc(pkg_dir_len); - if (!pkg_dir) { - return MBPK_OUT_OF_MEMORY; - } - sprintf(pkg_dir, "%s/pkg", repo_dir); - - if (stat(pkg_dir, &st) == 0) { - printf("[libmbpk debug] removing old pkg directory for %s\n", repo->name); - if (rm_rf(pkg_dir) != 0) { - free(pkg_dir); - free(repo_dir); - return MBPK_REPO_FAIL; - } - } - printf("[libmbpk debug] creating new pkg directory for %s\n", repo->name); - if (mkdir(pkg_dir, 0755) == -1) { - free(pkg_dir); - free(repo_dir); - return MBPK_REPO_FAIL; - } - - for (j = 0; repo->packages[j] != NULL; j++) { - chunk.memory = malloc(1); - if (!chunk.memory) { - free(pkg_dir); - free(repo_dir); - return MBPK_OUT_OF_MEMORY; - } - chunk.size = 0; /* oh fuck, thats why this didnt work - i was overwriting broken shit */ - printf(" %s\n", repo->packages[j]); - curl = curl_easy_init(); - if (curl) { - pkg_ini_url_len = strlen(repo->url) + 1 + strlen("pkg") + 1 + strlen(repo->packages[j]) + strlen(".ini") + 1; - pkg_ini_url = malloc(pkg_ini_url_len); - if (!pkg_ini_url) { - free(repo_dir); - return MBPK_OUT_OF_MEMORY; - } - sprintf(pkg_ini_url, "%s/pkg/%s.ini", repo->url, repo->packages[j]); - curl_easy_setopt(curl, CURLOPT_URL, pkg_ini_url); - curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); /* follow redirects */ - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_memory_write_calback); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)&chunk); - curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1L); /* fail on errors like 404 */ - curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, ""); /* accept encoding like gzip */ - - result = curl_easy_perform(curl); - curl_easy_cleanup(curl); - free(pkg_ini_url); - - if (result != CURLE_OK) { - printf("[libmbpk debug] perform cURL failed\n"); - free(chunk.memory); - free(pkg_dir); - free(repo_dir); - return MBPK_CURL_PERFORM_FAIL; - } else { - printf("[libmbpk debug] %lu bytes received\n", (unsigned long)chunk.size); - printf("[libmbpk debug] Response:\n%s\n", chunk.memory); - } - } else { - free(chunk.memory); - free(repo_dir); - free(pkg_dir); - return MBPK_CURL_INIT_FAIL; - } - - pkg_ini_path_len = strlen(pkg_dir) + 1 + strlen(repo->packages[j]) + strlen(".ini") + 1; - pkg_ini_path = malloc(pkg_ini_path_len); - if (!pkg_ini_path) { - free(chunk.memory); - free(pkg_dir); - free(repo_dir); - return MBPK_OUT_OF_MEMORY; - } - sprintf(pkg_ini_path, "%s/%s.ini", pkg_dir, repo->packages[j]); - - fp = fopen(pkg_ini_path, "w"); - if (!fp) { - free(pkg_ini_path); - free(pkg_dir); - free(repo_dir); - free(chunk.memory); - return MBPK_REPO_FAIL; - } - fwrite(chunk.memory, 1, chunk.size, fp); - fclose(fp); - - free(chunk.memory); - } - free(pkg_dir); - free(repo_dir); - } - - return MBPK_OK; -} - -void mbpk_cleanup(void) { - int i; - for (i = 0; i < repo_count; i++) { - if (repos[i]) { - free((void*)repos[i]->name); - free((void*)repos[i]->url); - free((void*)repos[i]->desc); - free((void*)repos[i]->packages); - free((void*)repos[i]); - repos[i] = NULL; - } - } - repo_count = 0; - curl_global_cleanup(); -} - -const char* mbpk_strerr(int code) { - const char* strerr; - switch (code) { - case MBPK_OK: - strerr = "MBPK_OK (0)"; - break; - case MBPK_DB_FAIL: - strerr = "MBPK_DB_FAIL (1)"; - break; - case MBPK_REPO_FAIL: - strerr = "MBPK_REPO_FAIL (2)"; - break; - case MBPK_DL_FAIL: - strerr = "MBPK_DL_FAIL (3)"; - break; - case MBPK_EXTRACT_FAIL: - strerr = "MBPK_EXTRACT_FAIL (4)"; - break; - case MBPK_CURL_INIT_FAIL: - strerr = "MBPK_CURL_INIT_FAIL (5)"; - break; - case MBPK_CURL_PERFORM_FAIL: - strerr = "MBPK_CURL_PERFORM_FAIL (6)"; - break; - case MBPK_OUT_OF_MEMORY: - strerr = "MBPK_OUT_OF_MEMORY (7)"; - break; - default: - strerr = "MBPK_UNKNOWN_ERR"; - break; - } - return strerr; -} diff --git a/src/mbpk-install.c b/src/mbpk-install.c deleted file mode 100644 index 9588373..0000000 --- a/src/mbpk-install.c +++ /dev/null @@ -1,20 +0,0 @@ -#include -#include "libmbpk.h" - -int main(void) { - int res; - printf("[mbpk_install] please note that mbpk_install is currently used as a test, and does not do what is said in the README. the proper wrapper binaries will be created once libmbpk is finished.\n"); - printf("[mbpk_install] calling mbpk_init()\n"); - res = mbpk_init(); - if (res != MBPK_OK) { - fprintf(stderr, "mbpk init failed: %s\n", mbpk_strerr(res)); - return 1; - } - printf("[mbpk_install] calling mbpk_update_repositories()\n"); - res = mbpk_update_repositories(); - if (res != MBPK_OK) { - fprintf(stderr, "mbpk repo failed: %s\n", mbpk_strerr(res)); - } - mbpk_cleanup(); - return 0; -} -- cgit v1.2.3