#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; }