aboutsummaryrefslogtreecommitdiff
path: root/snag/src
diff options
context:
space:
mode:
Diffstat (limited to 'snag/src')
-rw-r--r--snag/src/build_db.c143
-rw-r--r--snag/src/main.c5
-rw-r--r--snag/src/package_db.c116
3 files changed, 141 insertions, 123 deletions
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) {
diff --git a/snag/src/main.c b/snag/src/main.c
index b0c0e4b..5893ed7 100644
--- a/snag/src/main.c
+++ b/snag/src/main.c
@@ -6,10 +6,13 @@
#include "build_db.h"
#include "source_db.h"
+char **environment;
+
int cmd_install(char* cmd_name, ArgParser* parser);
-int main(int argc, char* argv[]) {
+int main(int argc, char* argv[], char *envp[]) {
+ environment = envp;
// initialize config
cfg_init();
diff --git a/snag/src/package_db.c b/snag/src/package_db.c
index f2a105e..74a7937 100644
--- a/snag/src/package_db.c
+++ b/snag/src/package_db.c
@@ -15,76 +15,76 @@ 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
+ // construct package description directory path and ensure it exists
// desc_dir = "pkg_db/pkgid"
- size_t desc_dir_len = cfg.package_db_len + pkgid_len + 1;
+ size_t desc_dir_len = cfg.package_db_len + pkgid_len + 1;
info->desc_dir = emalloc(desc_dir_len + 1, "desc_dir");
- {
- memcpy(info->desc_dir, cfg.package_db, cfg.package_db_len);
- info->desc_dir[cfg.package_db_len] = '/';
- memcpy(info->desc_dir + cfg.package_db_len + 1, pkgid, pkgid_len);
- info->desc_dir[desc_dir_len] = '\0';
- if (access(info->desc_dir, F_OK) != 0) {
- print("Package '%s' not found\n", pkgid);
- free(info->desc_dir);
- return false;
- }
- }
+ {
+ memcpy(info->desc_dir, cfg.package_db, cfg.package_db_len);
+ info->desc_dir[cfg.package_db_len] = '/';
+ memcpy(info->desc_dir + cfg.package_db_len + 1, pkgid, pkgid_len);
+ info->desc_dir[desc_dir_len] = '\0';
+ if (access(info->desc_dir, F_OK) != 0) {
+ print("Package '%s' not found\n", pkgid);
+ free(info->desc_dir);
+ return false;
+ }
+ }
- // construct package description script path and ensure it exists
- // script_path = "desc_dir/pkgid.sh"
- size_t script_path_len = desc_dir_len + pkgid_len + 4;
- info->script_path = emalloc(script_path_len + 1, "info->script_path");
- {
- memcpy(info->script_path, info->desc_dir, desc_dir_len);
- info->script_path[desc_dir_len] = '/';
- memcpy(&info->script_path[desc_dir_len + 1], pkgid, pkgid_len);
- memcpy(&info->script_path[script_path_len - 3], ".sh", 3);
- info->script_path[script_path_len] = '\0';
- if (access(info->script_path, F_OK) != 0) {
- print("Package '%s' broken, doesn't have description script\n", pkgid);
- free(info->script_path);
- free(info->desc_dir);
- return false;
- }
- }
+ // construct package description script path and ensure it exists
+ // script_path = "desc_dir/pkgid.sh"
+ size_t script_path_len = desc_dir_len + pkgid_len + 4;
+ info->script_path = emalloc(script_path_len + 1, "info->script_path");
+ {
+ memcpy(info->script_path, info->desc_dir, desc_dir_len);
+ info->script_path[desc_dir_len] = '/';
+ memcpy(&info->script_path[desc_dir_len + 1], pkgid, pkgid_len);
+ memcpy(&info->script_path[script_path_len - 3], ".sh", 3);
+ info->script_path[script_path_len] = '\0';
+ if (access(info->script_path, F_OK) != 0) {
+ print("Package '%s' broken, doesn't have description script\n", pkgid);
+ free(info->script_path);
+ free(info->desc_dir);
+ return false;
+ }
+ }
- // PIPE and FORK to run pkg attrs script
+ // PIPE and FORK to run pkg attrs script
int pipefds[2] = {0};
if (pipe(pipefds) < 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 to the pipe
+ // child proc
+ // connect my stdout to the pipe
close(pipefds[0]);
dup2(pipefds[1], STDOUT_FILENO);
close(pipefds[1]);
- // exec into get attr script
+ // exec into get attr script
char* argv[] = { cfg.get_package_info_script, info->script_path, NULL };
char* envp[] = { NULL };
execve(cfg.get_package_info_script, argv, envp);
- // what are you still doing here?
- die("CHILD - execve to %s failed: %s", cfg.get_package_info_script, strerror(errno));
+ // what are you still doing here?
+ die("CHILD - execve to %s failed: %s", cfg.get_package_info_script, strerror(errno));
} else {
- // parent proc, close write end of pipe
- close(pipefds[1]);
- }
+ // parent proc, close write end of pipe
+ close(pipefds[1]);
+ }
- // wait for child to finish
+ // wait for 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 get_pkg_attr script: %d", WEXITSTATUS(wstatus));
+ if (WEXITSTATUS(wstatus) != 0) die("the child failed to execute get_pkg_attr script: %d", WEXITSTATUS(wstatus));
- // read all bytes from pipe into attr buffer
+ // 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) die("failed to read from pipe: %s", strerror(errno));
- close(pipefds[0]);
+ close(pipefds[0]);
- // read attributes from attr buffer
- // attribute format: type (char), data value (null terminated str)
- // todo(jqj): switch over to dynamically allocated buffer
+ // 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->attrs.buffer[i];
i++;
@@ -95,22 +95,22 @@ bool load_package_info(char* pkgid, package_info_t* info) {
info->attrs.name = &info->attrs.buffer[i]; break;
case 'd':
info->attrs.desc = &info->attrs.buffer[i]; break;
- case 'w':
- info->attrs.webpage = &info->attrs.buffer[i]; break;
- case 'l':
- info->attrs.license = &info->attrs.buffer[i]; break;
- case 'v':
- info->attrs.version = &info->attrs.buffer[i]; break;
+ case 'w':
+ info->attrs.webpage = &info->attrs.buffer[i]; break;
+ case 'l':
+ info->attrs.license = &info->attrs.buffer[i]; break;
+ case 'v':
+ info->attrs.version = &info->attrs.buffer[i]; break;
case 's':
- info->attrs.source.name = &info->attrs.buffer[i]; break;
- case 'u':
- info->attrs.source.url = &info->attrs.buffer[i]; break;
- case 'c':
- info->attrs.source.checksum = &info->attrs.buffer[i]; break;
+ info->attrs.source.name = &info->attrs.buffer[i]; break;
+ case 'u':
+ info->attrs.source.url = &info->attrs.buffer[i]; break;
+ case 'c':
+ info->attrs.source.checksum = &info->attrs.buffer[i]; break;
}
while(info->attrs.buffer[i] != '\0' && i < bytes_read) i++;
i++;
}
- return true;
+ return true;
}