#include <uuid/uuid.h>
#include <pakfire/build.h>
-#include <pakfire/execute.h>
#include <pakfire/dist.h>
#include <pakfire/file.h>
#include <pakfire/jail.h>
return NULL;
}
-static int pakfire_build_run_script(struct pakfire* pakfire, const char* filename, const char* args[],
- pakfire_execute_logging_callback logging_callback, void* data) {
+static int pakfire_build_run_script(struct pakfire* pakfire, const char* filename,
+ const char* args[], char*** output) {
struct pakfire_jail* jail = NULL;
char* script = NULL;
size_t size = 0;
if (!jail)
goto ERROR;
- // Configure logging
- if (logging_callback) {
- r = pakfire_jail_set_log_callback(jail, logging_callback, data);
- if (r)
- goto ERROR;
- }
-
// Execute the script
- r = pakfire_jail_exec_script(jail, script, size, args);
+ r = pakfire_jail_exec_script(jail, script, size, args, output);
if (r) {
ERROR(pakfire, "Script '%s' failed with status %d\n", filename, r);
}
};
// Find all provides
- r = pakfire_build_run_script(pakfire, "find-provides", args,
- pakfire_execute_capture_stdout_to_array, &provides);
+ r = pakfire_build_run_script(pakfire, "find-provides", args, &provides);
if (r) {
ERROR(pakfire, "find-provides returned with error %d\n", r);
goto ERROR;
}
// Find all requires
- r = pakfire_build_run_script(pakfire, "find-requires", args,
- pakfire_execute_capture_stdout_to_array, &requires);
+ r = pakfire_build_run_script(pakfire, "find-requires", args, &requires);
if (r) {
ERROR(pakfire, "find-requires returned with error %d\n", r);
goto ERROR;
};
// Find all pre-requires
- r = pakfire_build_run_script(pakfire, "find-prerequires", args,
- pakfire_execute_capture_stdout_to_array, &prerequires);
+ r = pakfire_build_run_script(pakfire, "find-prerequires", args, &prerequires);
if (r)
goto ERROR;
}
// Run the script
- r = pakfire_jail_exec_script(jail, script, strlen(script), NULL);
+ r = pakfire_jail_exec_script(jail, script, strlen(script), NULL, NULL);
if (r) {
ERROR(pakfire, "Build stage '%s' failed with status %d\n", stage, r);
}
// Run them one by one
for (const char** script = post_build_scripts; *script; script++) {
- int r = pakfire_build_run_script(pakfire, *script, args, NULL, NULL);
+ int r = pakfire_build_run_script(pakfire, *script, args, NULL);
if (r)
return r;
}
#define LDCONFIG "/sbin/ldconfig"
-static int default_logging_callback(struct pakfire* pakfire, void* data, int priority,
- const char* line, size_t length) {
- switch (priority) {
- case LOG_INFO:
- INFO(pakfire, "%s", line);
- break;
-
- case LOG_ERR:
- ERROR(pakfire, "%s", line);
- break;
- }
-
- return 0;
-}
-
-int pakfire_execute_capture_stdout(struct pakfire* pakfire, void* data, int priority,
- const char* line, size_t length) {
- char** output = (char**)data;
-
- // Append everything from stdout to a buffer
- if (priority == LOG_INFO) {
- int r = asprintf(output, "%s%s", (output && *output) ? *output : "", line);
- if (r)
- return 1;
- }
-
- // Send everything else to the default logger
- return default_logging_callback(pakfire, NULL, priority, line, length);
-}
-
-int pakfire_execute_capture_stdout_to_array(struct pakfire* pakfire, void* data, int priority,
- const char* line, size_t length) {
- char*** array = (char***)data;
-
- // Append everything from stdout to an array
- if (priority == LOG_INFO) {
- length = 0;
-
- // Create a copy of line
- char* message = strdup(line);
- if (!message)
- return 1;
-
- // Remove any trailing newline
- pakfire_remove_trailing_newline(message);
-
- // Determine the length of the existing array
- if (*array) {
- for (char** element = *array; *element; element++)
- length++;
- }
-
- // Allocate space
- *array = reallocarray(*array, length + 2, sizeof(**array));
- if (!*array)
- return 1;
-
- // Append message and terminate the array
- (*array)[length] = message;
- (*array)[length + 1] = NULL;
-
- return 0;
- }
-
- // Send everything else to the default logger
- return default_logging_callback(pakfire, NULL, priority, line, length);
-}
-
PAKFIRE_EXPORT int pakfire_execute(struct pakfire* pakfire, const char* argv[], char* envp[],
int flags, pakfire_execute_logging_callback logging_callback, void* data) {
struct pakfire_jail* jail = NULL;
goto ERROR;
// Execute the command
- r = pakfire_jail_exec(jail, argv);
+ r = pakfire_jail_exec(jail, argv, NULL);
ERROR:
if (jail)
};
// Execute /bin/bash
- return pakfire_jail_run(pakfire, argv, PAKFIRE_JAIL_INTERACTIVE);
+ return pakfire_jail_run(pakfire, argv, PAKFIRE_JAIL_INTERACTIVE, NULL);
}
int pakfire_execute_ldconfig(struct pakfire* pakfire) {
};
// Run ldconfig
- return pakfire_jail_run(pakfire, argv, 0);
+ return pakfire_jail_run(pakfire, argv, 0, NULL);
}
#ifdef PAKFIRE_PRIVATE
-int pakfire_execute_capture_stdout(struct pakfire* pakfire, void* data, int priority,
- const char* line, size_t length);
-int pakfire_execute_capture_stdout_to_array(struct pakfire* pakfire, void* data, int priority,
- const char* line, size_t length);
int pakfire_execute_shell(struct pakfire* pakfire);
int pakfire_execute_ldconfig(struct pakfire* pakfire);
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(struct pakfire_jail* jail, const char* argv[], char*** output);
int pakfire_jail_exec_script(struct pakfire_jail* jail,
- const char* script, const size_t size, const char* args[]);
+ const char* script, const size_t size, const char* args[], char*** output);
// Convenience functions
-int pakfire_jail_run(struct pakfire* pakfire, const char* argv[], int flags);
+int pakfire_jail_run(struct pakfire* pakfire, const char* argv[], int flags, char*** output);
int pakfire_jail_run_script(struct pakfire* pakfire,
- const char* script, const size_t length, const char* argv[], int flags);
+ const char* script, const size_t length, const char* argv[], int flags, char*** output);
#endif
return r;
}
+static int pakfire_jail_capture_stdout(struct pakfire* pakfire, void* data, int priority,
+ const char* line, size_t length) {
+ char*** array = (char***)data;
+
+ // Append everything from stdout to an array
+ if (priority == LOG_INFO) {
+ length = 0;
+
+ // Create a copy of line
+ char* message = strdup(line);
+ if (!message)
+ return 1;
+
+ // Remove any trailing newline
+ pakfire_remove_trailing_newline(message);
+
+ // Determine the length of the existing array
+ if (*array) {
+ for (char** element = *array; *element; element++)
+ length++;
+ }
+
+ // Allocate space
+ *array = reallocarray(*array, length + 2, sizeof(**array));
+ if (!*array)
+ return 1;
+
+ // Append message and terminate the array
+ (*array)[length] = message;
+ (*array)[length + 1] = NULL;
+
+ return 0;
+ }
+
+ // Send everything else to the default logger
+ return pakfire_jail_default_log_callback(pakfire, NULL, priority, line, length);
+}
+
// Capabilities
static int pakfire_jail_drop_capabilities(struct pakfire_jail* jail) {
}
// Run a command in the jail
-int pakfire_jail_exec(struct pakfire_jail* jail, const char* argv[]) {
+static int __pakfire_jail_exec(struct pakfire_jail* jail, const char* argv[]) {
int exit = -1;
int r;
return exit;
}
+int pakfire_jail_exec(struct pakfire_jail* jail, const char* argv[], char*** output) {
+ int r;
+
+ // Store logging callback
+ pakfire_jail_log_callback log_callback = jail->log_callback;
+ void* log_data = jail->log_data;
+
+ // Capture output if requested by user
+ if (output)
+ pakfire_jail_set_log_callback(jail, pakfire_jail_capture_stdout, output);
+
+ // Run exec()
+ r = __pakfire_jail_exec(jail, argv);
+
+ // Restore log callback
+ pakfire_jail_set_log_callback(jail, log_callback, log_data);
+
+ return r;
+}
+
int pakfire_jail_exec_script(struct pakfire_jail* jail,
- const char* script, const size_t size, const char* args[]) {
+ const char* script, const size_t size, const char* args[], char*** output) {
char path[PATH_MAX];
const char** argv = NULL;
int r;
argv[i] = args[i-1];
// Run the script
- r = pakfire_jail_exec(jail, argv);
+ r = pakfire_jail_exec(jail, argv, output);
ERROR:
if (argv)
A convenience function that creates a new jail, runs the given command and destroys
the jail again.
*/
-int pakfire_jail_run(struct pakfire* pakfire, const char* argv[], int flags) {
+int pakfire_jail_run(struct pakfire* pakfire, const char* argv[], int flags, char*** output) {
struct pakfire_jail* jail = NULL;
int r;
goto ERROR;
// Execute the command
- r = pakfire_jail_exec(jail, argv);
+ r = pakfire_jail_exec(jail, argv, output);
ERROR:
if (jail)
}
int pakfire_jail_run_script(struct pakfire* pakfire,
- const char* script, const size_t length, const char* argv[], int flags) {
+ const char* script, const size_t length, const char* argv[], int flags, char*** output) {
struct pakfire_jail* jail = NULL;
int r;
goto ERROR;
// Execute the command
- r = pakfire_jail_exec_script(jail, script, length, argv);
+ r = pakfire_jail_exec_script(jail, script, length, argv, output);
ERROR:
if (jail)
#define PCRE2_CODE_UNIT_WIDTH 8
#include <pcre2.h>
-#include <pakfire/execute.h>
+#include <pakfire/jail.h>
#include <pakfire/logging.h>
#include <pakfire/package.h>
#include <pakfire/parser.h>
argv[2] = (const char*)command;
// The output of the command
- char* output = NULL;
+ char** stdout = NULL;
// Execute the command inside the Pakfire environment
- r = pakfire_execute(parser->pakfire, argv, NULL, 0,
- pakfire_execute_capture_stdout, &output);
+ r = pakfire_jail_run(parser->pakfire, argv, 0, &stdout);
if (r) {
// Just log this and continue
DEBUG(parser->pakfire, "Command '%s' failed with return code %d\n", command, r);
}
+ // Join all output together
+ char* output = pakfire_string_join(stdout, "");
+
// Strip newline from output
if (output)
pakfire_remove_trailing_newline(output);
pcre2_substring_free(pattern);
pattern = NULL;
+ if (stdout) {
+ for (char** line = stdout; *line; line++)
+ free(*line);
+ free(stdout);
+ }
+
if (output)
free(output);
}
// Detect what kind of script this is and run it
if (pakfire_scriptlet_is_shell_script(scriptlet))
return pakfire_jail_run_script(scriptlet->pakfire,
- scriptlet->data, scriptlet->size, NULL, 0);
+ scriptlet->data, scriptlet->size, NULL, 0, NULL);
ERROR(scriptlet->pakfire, "Scriptlet is of an unknown kind\n");
errno = ENOTSUP;
ASSERT_SUCCESS(pakfire_jail_create(&jail, t->pakfire, 0));
// Try to execute something
- ASSERT(pakfire_jail_exec(jail, argv) == 127);
+ ASSERT(pakfire_jail_exec(jail, argv, NULL) == 127);
// Destroy it
ASSERT_NULL(pakfire_jail_unref(jail));