From: Michael Tremer Date: Tue, 2 Aug 2022 17:48:45 +0000 (+0000) Subject: jail: Add interface to simply execute scripts X-Git-Tag: 0.9.28~618 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a45ed6b0d83d0697edabd70197797e4a71d04f0b;p=pakfire.git jail: Add interface to simply execute scripts Signed-off-by: Michael Tremer --- diff --git a/src/libpakfire/include/pakfire/jail.h b/src/libpakfire/include/pakfire/jail.h index 981e5046c..288b824b4 100644 --- a/src/libpakfire/include/pakfire/jail.h +++ b/src/libpakfire/include/pakfire/jail.h @@ -51,6 +51,8 @@ int pakfire_jail_import_env(struct pakfire_jail* jail, const char* env[]); // Execute int pakfire_jail_exec(struct pakfire_jail* jail, const char* argv[]); +int pakfire_jail_exec_script(struct pakfire_jail* jail, + const char* script, const size_t size, const char* args[]); #endif diff --git a/src/libpakfire/jail.c b/src/libpakfire/jail.c index 6cccaf08c..22ed9eaf4 100644 --- a/src/libpakfire/jail.c +++ b/src/libpakfire/jail.c @@ -1074,3 +1074,83 @@ ERROR: return exit; } + +int pakfire_jail_exec_script(struct pakfire_jail* jail, + const char* script, const size_t size, const char* args[]) { + char path[PATH_MAX]; + const char** argv = NULL; + int r; + + const char* root = pakfire_get_path(jail->pakfire); + + // Write the scriptlet to disk + r = pakfire_path_join(path, root, "pakfire-script.XXXXXX"); + if (r < 0) + goto ERROR; + + // Open a temporary file + int fd = mkstemp(path); + if (fd < 0) { + ERROR(jail->pakfire, "Could not open a temporary file: %m\n"); + r = 1; + goto ERROR; + } + + DEBUG(jail->pakfire, "Writing script to %s:\n%.*s\n", path, (int)size, script); + + // Write data + ssize_t bytes_written = write(fd, script, size); + if (bytes_written < (ssize_t)size) { + ERROR(jail->pakfire, "Could not write script to file %s: %m\n", path); + r = 1; + goto ERROR; + } + + // Make the script executable + r = fchmod(fd, S_IRUSR|S_IWUSR|S_IXUSR); + if (r) { + ERROR(jail->pakfire, "Could not set executable permissions on %s: %m\n", path); + goto ERROR; + } + + // Close file + r = close(fd); + if (r) { + ERROR(jail->pakfire, "Could not close script file %s: %m\n", path); + r = 1; + goto ERROR; + } + + // Count how many arguments were passed + unsigned int argc = 1; + if (args) { + for (const char** arg = args; *arg; arg++) + argc++; + } + + argv = calloc(argc + 1, sizeof(*argv)); + if (!argv) { + ERROR(jail->pakfire, "Could not allocate argv: %m\n"); + goto ERROR; + } + + // Set command + argv[0] = (root) ? pakfire_path_relpath(root, path) : path; + + // Copy args + for (unsigned int i = 1; i < argc; i++) + argv[i] = args[i-1]; + + // Run the script + r = pakfire_jail_exec(jail, argv); + +ERROR: + if (argv) + free(argv); + + // Remove script from disk + if (*path) + unlink(path); + + return r; +}