]> git.ipfire.org Git - pakfire.git/commitdiff
jail: Add interface to simply execute scripts
authorMichael Tremer <michael.tremer@ipfire.org>
Tue, 2 Aug 2022 17:48:45 +0000 (17:48 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Tue, 2 Aug 2022 17:48:45 +0000 (17:48 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libpakfire/include/pakfire/jail.h
src/libpakfire/jail.c

index 981e5046cfe709d4935b10dd54f2cea847a94487..288b824b4bbbe35bb5a15ab4027c27d6ec691665 100644 (file)
@@ -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
 
index 6cccaf08ce394dadecb10e84692a27122aaf3864..22ed9eaf4a003ef28c156538fea1a186bbee367e 100644 (file)
@@ -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;
+}