From d598be66eddc0e925eee96e23d9f95c88cf1f6ed Mon Sep 17 00:00:00 2001 From: Jack Jamison Date: Mon, 20 Jul 2026 19:07:43 -0400 Subject: split into separate file, readme clarifications --- snag/pkg_db.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 snag/pkg_db.c (limited to 'snag/pkg_db.c') diff --git a/snag/pkg_db.c b/snag/pkg_db.c new file mode 100644 index 0000000..26e972d --- /dev/null +++ b/snag/pkg_db.c @@ -0,0 +1,81 @@ +#include "pkg_db.h" + +#include +#include +#include +#include + +#define PKG_DB "../packages" +#define PKG_INFO_CMD "./get_pkg_attrs.sh" + +bool load_package_info(package_info_t* info, char* pkgid) { + + // construct package description directory path and ensure it exists + size_t pkg_dir_len = strlen(PKG_DB) + strlen(pkgid) + 1; + char* pkg_dir = malloc(pkg_dir_len + 1); + snprintf(pkg_dir, pkg_dir_len + 1, "%s/%s", PKG_DB, pkgid); + if (access(pkg_dir, F_OK) != 0) { + fprintf(stderr, "Package '%s' not found in database\n", pkgid); + free(pkg_dir); + return false; + } + + // construct package description script path and ensure it exists + size_t script_path_len = pkg_dir_len + strlen(pkgid) + 4; + info->script_path = malloc(script_path_len + 1); + snprintf(info->script_path, script_path_len + 1, "%s/%s.sh", pkg_dir, pkgid); + free(pkg_dir); + if (access(info->script_path, F_OK) != 0) { + fprintf(stderr, "Package '%s' broken, doesn't have description script\n", pkgid); + free(info->script_path); + return false; + } + + // construct get_pkg_attrs script cmd and invoke it + size_t cmd_len = strlen(PKG_INFO_CMD) + script_path_len + 3; + char* cmd = malloc(cmd_len + 1); + snprintf(cmd, cmd_len + 1, "%s '%s'", PKG_INFO_CMD, info->script_path); + FILE* getinfo_fp = popen(cmd, "r"); + free(cmd); + if (getinfo_fp == NULL) { + perror("failed to popen get_pkg_attrs"); + exit(1); // fatal error + } + + // go through each NULL delimited section of the output (attributes) + size_t n = 0; + char* line = NULL; + ssize_t read; + while ((read = getdelim(&line, &n, '\0', getinfo_fp)) != -1) { + // read in property based on first attribute type character + char atype = line[0]; + char* avalue = line+1; + switch (atype) { + case 'i': + // id + info->id = strdup(avalue); + break; + case 'n': + // name + info->name = strdup(avalue); + break; + case 'd': + // description + info->desc = strdup(avalue); + break; + } + } + free(line); + + // close the get_pkg_attrs process + int close_err = pclose(getinfo_fp); + if (close_err == -1) { + perror("failed to pclose get_pkg_attrs"); + exit(1); // fatal error + } else if (close_err != 0) { + fprintf(stderr, "failed to execute get_pkg_attrs: %d\n", close_err); + exit(1); // fatal error + } + + return true; +} -- cgit v1.2.3