diff options
| author | Jack Jamison <jackqjamison@gmail.com> | 2026-07-20 15:16:13 -0400 |
|---|---|---|
| committer | Jack Jamison <jackqjamison@gmail.com> | 2026-07-20 15:16:13 -0400 |
| commit | 0ad03c0647b94683c26045bbc143b0d6450d914f (patch) | |
| tree | 8aae29f86cebd7d567bca274e8fa43c388c89cea /snag/main.c | |
| parent | 3ae746e5ac3f8feb80a8619127956fb93ba47ca0 (diff) | |
read package info into snag
Diffstat (limited to 'snag/main.c')
| -rw-r--r-- | snag/main.c | 81 |
1 files changed, 78 insertions, 3 deletions
diff --git a/snag/main.c b/snag/main.c index 9eacf33..10a5f86 100644 --- a/snag/main.c +++ b/snag/main.c @@ -1,12 +1,17 @@ #include <stdio.h> #include <stdbool.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> -#define DESC_DIR "../snaggies" +#define PKG_DB "../snaggies" +#define PKG_INFO_CMD "./snagpkginfo.sh" typedef struct { char* id; char* name; char* desc; + char* script_path; } package_info_t; void subcmd_install(char* pkgs[], size_t count); @@ -25,9 +30,79 @@ void subcmd_install(char* pkgs[], size_t count) { // install each package listed for (int i = 0; i < count; ++i) { - char* package = pkgs[i]; - printf("Installing '%s'\n", package); + char* pkgid = pkgs[i]; // load package description + package_info_t info; + if (load_package_info(&info, pkgid)) { + printf("Installing '%s'\n", info.name); + } } } + +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; + } + + // run getpkginfo script that outputs package attributes + 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"); + if (getinfo_fp == NULL) { + perror("failed to popen getpkginfo"); + exit(1); // fatal error + } + + // go through each NULL delimited section of the output + 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 getpkginfo process + if (pclose(getinfo_fp) != 0) { + perror("failed to pclose getpkginfo"); + exit(1); // fatal error + } + + return true; +} |
