diff options
| author | Jack Jamison <jackqjamison@gmail.com> | 2026-07-21 10:18:22 -0400 |
|---|---|---|
| committer | Jack Jamison <jackqjamison@gmail.com> | 2026-07-21 10:18:22 -0400 |
| commit | 8b82a228ef754778caec172f5882e80ae57f536b (patch) | |
| tree | 738269bfe54f1531fdde0d807f8fc6aab6e10302 /snag/pkg_db.c | |
| parent | ea598e719d557a876a52d0cbecb21c1fb8ff917f (diff) | |
clean up buffer, and add function to run install script
Diffstat (limited to 'snag/pkg_db.c')
| -rw-r--r-- | snag/pkg_db.c | 97 |
1 files changed, 75 insertions, 22 deletions
diff --git a/snag/pkg_db.c b/snag/pkg_db.c index ad9eff3..032c089 100644 --- a/snag/pkg_db.c +++ b/snag/pkg_db.c @@ -8,23 +8,26 @@ #include <errno.h> #include <sys/wait.h> -#define PKG_DB "../packages" -#define PKG_DB_LEN (sizeof(PKG_DB) - 1) #define PKG_INFO_CMD "./get_pkg_attrs.sh" +#define PKG_INST_CMD "./run_pkg_install.sh" -bool load_package_info(package_info_t* info, char* pkgid) { +// note: fixed location of package database for now +const char pkg_db[] = "../packages"; +const size_t pkg_db_len = sizeof(pkg_db) - 1; + +bool load_package_info(char* pkgid, package_info_t* info) { memset(info, 0, sizeof(*info)); size_t pkgid_len = strlen(pkgid); // construct package description directory path and ensure it exists - // pkg_dir = "PKG_DB/pkgid" - size_t pkg_dir_len = PKG_DB_LEN + pkgid_len + 1; + // pkg_dir = "pkg_db/pkgid" + size_t pkg_dir_len = pkg_db_len + pkgid_len + 1; char* pkg_dir = emalloc(pkg_dir_len + 1, "pkg_dir"); { - memcpy(pkg_dir, PKG_DB, PKG_DB_LEN); - pkg_dir[PKG_DB_LEN] = '/'; - memcpy(pkg_dir + PKG_DB_LEN + 1, pkgid, pkgid_len); + memcpy(pkg_dir, pkg_db, pkg_db_len); + pkg_dir[pkg_db_len] = '/'; + memcpy(pkg_dir + pkg_db_len + 1, pkgid, pkgid_len); pkg_dir[pkg_dir_len] = '\0'; if (access(pkg_dir, F_OK) != 0) { eprintf("Package '%s' not found\n", pkgid); @@ -41,7 +44,8 @@ bool load_package_info(package_info_t* info, char* pkgid) { memcpy(info->script_path, pkg_dir, pkg_dir_len); info->script_path[pkg_dir_len] = '/'; memcpy(&info->script_path[pkg_dir_len + 1], pkgid, pkgid_len); - memcpy(&info->script_path[script_path_len - 3], ".sh", 4); + memcpy(&info->script_path[script_path_len - 3], ".sh", 3); + info->script_path[script_path_len] = '\0'; free(pkg_dir); if (access(info->script_path, F_OK) != 0) { eprintf("Package '%s' broken, doesn't have description script\n", pkgid); @@ -50,15 +54,15 @@ bool load_package_info(package_info_t* info, char* pkgid) { } } - // PIPE and FORK to run get pkg attrs script + // PIPE and FORK to run pkg attrs script int pipefds[2] = {0}; if (pipe(pipefds) < 0) error_out("failed to pipe: %s", strerror(errno)); pid_t pid = fork(); if (pid < 0) error_out("failed to fork: %s", strerror(errno)); - // child proc if (pid == 0) { - // write my stdout the the pipe + // child proc + // write my stdout to the pipe close(pipefds[0]); dup2(pipefds[1], STDOUT_FILENO); close(pipefds[1]); @@ -66,36 +70,85 @@ bool load_package_info(package_info_t* info, char* pkgid) { char* argv[] = { PKG_INFO_CMD, info->script_path, NULL }; char* envp[] = { NULL }; execve(PKG_INFO_CMD, argv, envp); + // what are you still doing here? error_out("execve failed"); - } + } else { + // parent proc, close write end of pipe + close(pipefds[1]); + } // wait for child to finish int wstatus; if (waitpid(pid, &wstatus, 0) < 0) error_out("waitpid failed: %s", strerror(errno)); if (WEXITSTATUS(wstatus) != 0) error_out("failed to execute get pkg attr script"); - // read all bytes from pipe - ssize_t bytes_read = read(pipefds[0], info->package_attrs, sizeof(info->package_attrs)); - if (bytes_read < 0) error_out("Failed to read from pipe"); + // read all bytes from pipe into attr buffer + ssize_t bytes_read = read(pipefds[0], info->attrs.buffer, sizeof(info->attrs.buffer)); + if (bytes_read < 0) error_out("failed to read from pipe: %s", strerror(errno)); + close(pipefds[0]); - // read attributes from pipe data + // read attributes from attr buffer + // attribute format: type (char), data value (null terminated str) + // todo(jqj): switch over to dynamically allocated buffer for (int i = 0; i < bytes_read;) { - char atype = info->package_attrs[i]; + char atype = info->attrs.buffer[i]; i++; switch (atype) { case 'i': - info->attrs.id = &info->package_attrs[i]; + info->attrs.id = &info->attrs.buffer[i]; break; case 'n': - info->attrs.name = &info->package_attrs[i]; + info->attrs.name = &info->attrs.buffer[i]; break; case 'd': - info->attrs.desc = &info->package_attrs[i]; + info->attrs.desc = &info->attrs.buffer[i]; break; } - for(;info->package_attrs[i] && i < bytes_read; i++); + for(;info->attrs.buffer[i] && i < bytes_read; i++); i++; } return true; } + +void run_package_install(const package_info_t* info) { + + // PIPE and FORK to run install script + int pipefds[2] = {0}; + if (pipe(pipefds) < 0) error_out("failed to pipe: %s", strerror(errno)); + pid_t pid = fork(); + if (pid < 0) error_out("failed to fork: %s", strerror(errno)); + + if (pid == 0) { + // child proc + // write my stdout and stderr to the pipe + close(pipefds[0]); + dup2(pipefds[1], STDOUT_FILENO); + dup2(pipefds[1], STDERR_FILENO); + close(pipefds[1]); + // exec into install script + char* argv[] = { PKG_INST_CMD, info->script_path, NULL }; + char* envp[] = { NULL }; + execve(PKG_INST_CMD, argv, envp); + // what are you still doing here? + error_out("execve failed"); + } else { + // parent proc, close write end of pipe + close(pipefds[1]); + } + + // read from the pipe until EOF + char buf[4096]; + ssize_t bytes_read = 0; + while ((bytes_read = read(pipefds[0], buf, sizeof(buf))) > 0) { + // print build out, can log and stuff in future + printf("%.*s", (int)bytes_read, buf); + } + if (bytes_read < 0) error_out("failed to read from pipe: %s", strerror(errno)); + close(pipefds[0]); + + // reap the child to finish + int wstatus; + if (waitpid(pid, &wstatus, 0) < 0) error_out("waitpid failed: %s", strerror(errno)); + if (WEXITSTATUS(wstatus) != 0) error_out("failed to execute install script"); +} |
