From 0b567585484fa90d4f6968d29b0f406c2176be6e Mon Sep 17 00:00:00 2001 From: Riley Beckett Date: Thu, 17 Sep 2026 17:45:37 -0400 Subject: make root and descdir envvars also tabs -> spaces --- snag/src/build_db.c | 143 +++++++++++++++++++++++++++++----------------------- 1 file changed, 79 insertions(+), 64 deletions(-) (limited to 'snag/src/build_db.c') diff --git a/snag/src/build_db.c b/snag/src/build_db.c index 06099f6..2ec79cc 100644 --- a/snag/src/build_db.c +++ b/snag/src/build_db.c @@ -24,7 +24,8 @@ #define API_MESSAGE_NONE 0 #define API_MESSAGE_FINISHED 1 #define API_MESSAGE_TEST 2 -#define API_MESSAGE_GET_VAR 3 + +extern char** environment; bool set_child_sandbox(const package_build_t* build) { struct landlock_ruleset_attr ruleset_attr = { @@ -158,41 +159,41 @@ bool set_child_sandbox(const package_build_t* build) { bool package_setup_build(const package_info_t* info, package_build_t* build) { - // get timestamp string - char timestamp_str[32]; - { - // get time in ms - struct timespec ts; - if (clock_gettime(CLOCK_REALTIME, &ts) != 0) die("failed to get time: %s", strerror(errno)); - unsigned long long total_ms = ((unsigned long long)ts.tv_sec * 1000) + (ts.tv_nsec / 1000000); - snprintf(timestamp_str, sizeof(timestamp_str), "%llu", total_ms); - } + // get timestamp string + char timestamp_str[32]; + { + // get time in ms + struct timespec ts; + if (clock_gettime(CLOCK_REALTIME, &ts) != 0) die("failed to get time: %s", strerror(errno)); + unsigned long long total_ms = ((unsigned long long)ts.tv_sec * 1000) + (ts.tv_nsec / 1000000); + snprintf(timestamp_str, sizeof(timestamp_str), "%llu", total_ms); + } - // create build info - memset(build, 0, sizeof(*build)); - build->package = info; - build->directory = vastrcat(cfg.build_db, "/", info->attrs.id, "-", timestamp_str); + // create build info + memset(build, 0, sizeof(*build)); + build->package = info; + build->directory = vastrcat(cfg.build_db, "/", info->attrs.id, "-", timestamp_str); - // create build directory - if (mkdir(build->directory, 0777) == -1) die("failed to create build directory: %s", strerror(errno)); + // create build directory + if (mkdir(build->directory, 0777) == -1) die("failed to create build directory: %s", strerror(errno)); - // (re)create symlink to build directory - char* symlink_name = vastrcat(cfg.build_db, "/", info->attrs.id); - if (unlink(symlink_name) == -1 && errno != ENOENT) die("failed to remove build symlink '%s': %s", symlink_name, strerror(errno)); - if (symlink(build->directory + cfg.build_db_len + 1, symlink_name) == -1) die("failed to create build symlink '%s': %s", symlink_name, strerror(errno)); - free(symlink_name); + // (re)create symlink to build directory + char* symlink_name = vastrcat(cfg.build_db, "/", info->attrs.id); + if (unlink(symlink_name) == -1 && errno != ENOENT) die("failed to remove build symlink '%s': %s", symlink_name, strerror(errno)); + if (symlink(build->directory + cfg.build_db_len + 1, symlink_name) == -1) die("failed to create build symlink '%s': %s", symlink_name, strerror(errno)); + free(symlink_name); build->fakeroot = join_path(build->directory, "fakeroot"); - if (mkdir(build->fakeroot, 0777) == -1) die("failed to create fakeroot directory: %s", strerror(errno)); + if (mkdir(build->fakeroot, 0777) == -1) die("failed to create fakeroot directory: %s", strerror(errno)); - // unpack package source (eventually this will be done by swenu api) - build->source_directory = join_path(build->directory, "source"); - unpack_source(&info->attrs.source, build->source_directory); + // unpack package source (eventually this will be done by swenu api) + build->source_directory = join_path(build->directory, "source"); + unpack_source(&info->attrs.source, build->source_directory); - // todo - create paths for log files - // todo - create rebuild script + // todo - create paths for log files + // todo - create rebuild script - return true; + return true; } void build_run(const package_build_t* build) { @@ -202,15 +203,16 @@ void build_run(const package_build_t* build) { int api_to_sh[2] = {0}; if (pipe(api_to_sh) < 0) die("failed to open api response pipe: %s", strerror(errno)); - // PIPE and FORK to run install script + // PIPE and FORK to run install script int child_output[2] = {0}; if (pipe(child_output) < 0) die("failed to pipe: %s", strerror(errno)); pid_t pid = fork(); if (pid < 0) die("failed to fork: %s", strerror(errno)); if (pid == 0) { - // child proc - // connect my stdout and stderr to the pipe + uint8_t errorcode = 0; + // child proc + // connect my stdout and stderr to the pipe close(child_output[0]); dup2(child_output[1], STDOUT_FILENO); dup2(child_output[1], STDERR_FILENO); @@ -222,30 +224,57 @@ void build_run(const package_build_t* build) { snprintf(buf1, sizeof(buf1), "%d", api_from_sh[1]); char buf2[12]; snprintf(buf2, sizeof(buf2), "%d", api_to_sh[0]); - // exec into install script - chdir(build->source_directory); + // exec into install script + chdir(build->source_directory); if (!set_child_sandbox(build)) { int finished = API_MESSAGE_FINISHED; write(api_from_sh[1], &finished, sizeof(finished)); die("CHILD - landlock sandbox failed not running script"); } + // should make this more general currently very rigid + int num_envvars = 0; + for (; environment[num_envvars]; num_envvars++); + num_envvars += 2; + char** newenvp = calloc(sizeof(char*), num_envvars + 1); + int i = 0; + for (; environment[i]; i++) { + newenvp[i] = environment[i]; + } + char* descdir = vastrcat("descdir=", build->package->desc_dir); + if (!descdir) { + errorcode = 1; + goto error; + } + char* root = vastrcat("root=", build->fakeroot); + if (!descdir) { + errorcode = 2; + goto error; + } + newenvp[i++] = descdir; + newenvp[i++] = root; + newenvp[i] = NULL; char* argv[] = { cfg.build_package_script, buf1, buf2, build->package->script_path, NULL }; - execv(cfg.build_package_script, argv); + execve(cfg.build_package_script, argv, newenvp); + error: int finished = API_MESSAGE_FINISHED; write(api_from_sh[1], &finished, sizeof(finished)); - // what are you still doing here? - die("CHILD - execve to %s failed: %s", cfg.build_package_script, strerror(errno)); + // what are you still doing here? + switch (errorcode) { + case 0: die("CHILD - execve to %s failed: %s", cfg.build_package_script, strerror(errno)); + case 1: die("CHILD - allocating descdir envvar failed: %s", strerror(errno)); + case 2: die("CHILD - allocating root envvar failed: %s", strerror(errno)); + } } else { - // parent proc, close write end of pipe - close(child_output[1]); + // parent proc, close write end of pipe + close(child_output[1]); // close unused api pipes close(api_from_sh[1]); close(api_to_sh[0]); - } + } // all of this should be rewritten - char buf[4096]; - ssize_t bytes_read = 0; + char buf[4096]; + ssize_t bytes_read = 0; struct pollfd pollfds[] = { { .fd = api_from_sh[0], .events = POLLIN, .revents = 0 }, { .fd = child_output[0], .events = POLLIN, .revents = 0 } @@ -275,39 +304,25 @@ void build_run(const package_build_t* build) { printf("api test\n"); write(api_to_sh[1], "api test\n", strlen("api test\n")); break; - case API_MESSAGE_GET_VAR: - bytes_read = read(api_from_sh[0], buf, sizeof(buf)); - if (strncmp(buf, "root", sizeof("root") - 1) == 0) { - char* tmp = vastrcat(build->fakeroot, "\n"); - write(api_to_sh[1], tmp, strlen(tmp)); - free(tmp); - } - if (strncmp(buf, "descdir", sizeof("descdir") - 1) == 0) { - char* tmp = vastrcat(build->package->desc_dir, "\n"); - write(api_to_sh[1], tmp, strlen(tmp)); - free(tmp); - } - // failure, failed to work (asked for bad var) - break; case API_MESSAGE_NONE: - break; + break; } } } while ((bytes_read = read(child_output[0], buf, sizeof(buf))) > 0) { - // print build out, can log and stuff in future - printf("%.*s", (int)bytes_read, buf); - } + // print build out, can log and stuff in future + printf("%.*s", (int)bytes_read, buf); + } if (bytes_read < 0) die("failed to read from pipe: %s", strerror(errno)); - close(child_output[0]); + close(child_output[0]); // close api pipes - close(api_from_sh[0]); - close(api_to_sh[1]); + close(api_from_sh[0]); + close(api_to_sh[1]); - // reap the child to finish + // reap the child to finish int wstatus; if (waitpid(pid, &wstatus, 0) < 0) die("waitpid failed: %s", strerror(errno)); - if (WEXITSTATUS(wstatus) != 0) die("the child failed to execute install script"); + if (WEXITSTATUS(wstatus) != 0) die("the child failed to execute install script"); } int nftw_callback(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf) { -- cgit v1.2.3