struct pakfire_log_buffer {
char data[BUFFER_SIZE];
size_t used;
+ int priority;
};
enum pakfire_jail_pty_io {
#endif /* ENABLE_DEBUG */
} pipes;
- // Communicate
- struct pakfire_jail_communicate {
- pakfire_jail_communicate_in in;
- pakfire_jail_communicate_out out;
- void* data;
- } communicate;
-
// Log buffers
struct pakfire_jail_buffers {
// Logging
free(jail);
}
-/*
- Passes any log messages on to the default pakfire log callback
-*/
-static int pakfire_jail_default_log_callback(struct pakfire* pakfire, void* data,
- int priority, const char* line, size_t length) {
- struct pakfire_ctx* ctx = pakfire_ctx(pakfire);
-
- if (pakfire_ctx_get_log_level(ctx) >= priority)
- pakfire_ctx_log(ctx, priority, NULL, 0, NULL, "%.*s", (int)length, line);
-
- pakfire_ctx_unref(ctx);
-
- return 0;
-}
-
static const char* pakfire_jail_uuid(struct pakfire_jail* jail) {
if (!*jail->__uuid)
uuid_unparse_lower(jail->uuid, jail->__uuid);
}
static int pakfire_jail_drain_buffer_with_callback(struct pakfire_jail* jail,
- struct pakfire_log_buffer* buffer, int priority, pakfire_jail_communicate_out callback, void* data) {
+ struct pakfire_log_buffer* buffer, pakfire_jail_stdout_callback callback, void* data) {
const char* eol = NULL;
int r;
const size_t length = eol - buffer->data + 1;
// Call the callback
- r = callback(jail->pakfire, data, priority, buffer->data, length);
+ r = callback(jail, data, buffer->data, length);
if (r) {
- CTX_ERROR(jail->ctx, "The logging callback returned an error: %d\n", r);
+ CTX_ERROR(jail->ctx, "The standard output callback returned an error: %d\n", r);
return r;
}
return 0;
}
+/*
+ Passes any log messages on to the default pakfire log callback
+*/
+static int pakfire_jail_log(struct pakfire_jail* jail,
+ void* data, const char* line, size_t length) {
+ int* priority = data;
+
+ if (pakfire_ctx_get_log_level(jail->ctx) >= *priority)
+ pakfire_ctx_log(jail->ctx, *priority, NULL, 0, NULL, "%.*s", (int)length, line);
+
+ return 0;
+}
+
/*
This function reads as much data as it can from the file descriptor.
If it finds a whole line in it, it will send it to the logger and repeat the process.
If not newline character is found, it will try to read more data until it finds one.
*/
static int pakfire_jail_handle_log(struct pakfire_jail* jail, struct pakfire_jail_exec* ctx,
- int priority, int fd, struct pakfire_log_buffer* buffer,
- pakfire_jail_communicate_out callback, void* data) {
+ int fd, struct pakfire_log_buffer* buffer, pakfire_jail_stdout_callback callback, void* data) {
int r;
// Fill up buffer from fd
return r;
// Drain the buffer
- r = pakfire_jail_drain_buffer_with_callback(jail, buffer, priority, callback, data);
+ r = pakfire_jail_drain_buffer_with_callback(jail, buffer, callback, data);
if (r)
return r;
CTX_DEBUG(jail->ctx, "Streaming standard input...\n");
// Calling the callback
- r = ctx->communicate.in(jail->pakfire, ctx->communicate.data, fd);
+ r = jail->callbacks.stdin.callback(jail, jail->callbacks.stdin.data, fd);
switch (r) {
case EOF:
return 0;
}
+static int pakfire_jail_command_output(struct pakfire_jail* jail, void* data,
+ const char* line, const size_t length) {
+ CTX_INFO(jail->ctx, "Command Output: %.*s", (int)length, line);
+
+ return 0;
+}
+
static int pakfire_jail_forward_pty(struct pakfire_jail* jail, struct pakfire_jail_exec* ctx) {
int r;
// Write to the master
if (ctx->pty.master.io & PAKFIRE_JAIL_PTY_READY_TO_WRITE) {
- if (ctx->communicate.in) {
+ if (jail->callbacks.stdin.callback) {
r = pakfire_jail_stream_stdin(jail, ctx, ctx->pty.master.fd);
if (r)
return r;
// Write to standard output
if (ctx->pty.stdout.io & PAKFIRE_JAIL_PTY_READY_TO_WRITE) {
// If we have a callback, we will send any output to the callback
- if (ctx->communicate.out) {
+ if (jail->callbacks.stdout.callback) {
r = pakfire_jail_drain_buffer_with_callback(jail, &ctx->pty.stdout.buffer,
- LOG_INFO, ctx->communicate.out, ctx->communicate.data);
+ jail->callbacks.stdout.callback, jail->callbacks.stdout.data);
if (r)
return r;
// Otherwise send the output to the default logger
} else {
r = pakfire_jail_drain_buffer_with_callback(jail, &ctx->pty.stdout.buffer,
- LOG_INFO, pakfire_jail_default_log_callback, NULL);
+ pakfire_jail_command_output, NULL);
if (r)
return r;
}
// Handle log INFO messages
} else if (log_INFO == fd) {
if (e & EPOLLIN) {
- r = pakfire_jail_handle_log(jail, ctx, LOG_INFO, fd,
- &ctx->buffers.log_INFO, pakfire_jail_default_log_callback, NULL);
+ r = pakfire_jail_handle_log(jail, ctx, fd, &ctx->buffers.log_INFO,
+ pakfire_jail_log, &ctx->buffers.log_INFO.priority);
if (r)
goto ERROR;
}
// Handle log ERROR messages
} else if (log_ERROR == fd) {
if (e & EPOLLIN) {
- r = pakfire_jail_handle_log(jail, ctx, LOG_ERR, fd,
- &ctx->buffers.log_ERROR, pakfire_jail_default_log_callback, NULL);
+ r = pakfire_jail_handle_log(jail, ctx, fd, &ctx->buffers.log_ERROR,
+ pakfire_jail_log, &ctx->buffers.log_ERROR.priority);
if (r)
goto ERROR;
}
// Handle log DEBUG messages
} else if (log_DEBUG == fd) {
if (e & EPOLLIN) {
- r = pakfire_jail_handle_log(jail, ctx, LOG_DEBUG, fd,
- &ctx->buffers.log_DEBUG, pakfire_jail_default_log_callback, NULL);
+ r = pakfire_jail_handle_log(jail, ctx, fd, &ctx->buffers.log_DEBUG,
+ pakfire_jail_log, &ctx->buffers.log_DEBUG.priority);
if (r)
goto ERROR;
}
return r;
}
-int pakfire_jail_capture_stdout(struct pakfire* pakfire, void* data,
- int priority, const char* line, size_t length) {
+int pakfire_jail_capture_stdout(struct pakfire_jail* jail, void* data,
+ const char* line, size_t length) {
char** output = (char**)data;
int r;
// Append everything from stdout to a buffer
- if (output && priority == LOG_INFO) {
- r = asprintf(output, "%s%.*s", (output && *output) ? *output : "", (int)length, line);
- if (r < 0)
- return -errno;
-
- return 0;
- }
+ r = asprintf(output, "%s%.*s", (output && *output) ? *output : "", (int)length, line);
+ if (r < 0)
+ return -errno;
- // Send everything else to the default logger
- return pakfire_jail_default_log_callback(pakfire, NULL, priority, line, length);
+ return 0;
}
// Capabilities
#endif /* ENABLE_DEBUG */
},
- .communicate = {
- .in = communicate_in,
- .out = communicate_out,
- .data = data,
+ .buffers = {
+ .log_INFO = {
+ .priority = LOG_INFO,
+ },
+
+ .log_ERROR = {
+ .priority = LOG_ERR,
+ },
+
+#ifdef ENABLE_DEBUG
+ .log_DEBUG = {
+ .priority = LOG_DEBUG,
+ },
+#endif /* ENABLE_DEBUG */
},
.pidfd = -1,
if (r)
goto ERROR;
+ // Set the callback that captures the output
+ pakfire_jail_set_stdout_callback(jail, pakfire_jail_capture_stdout, output);
+
// Execute the command
- r = pakfire_jail_exec(jail, argv, NULL, pakfire_jail_capture_stdout, output, 0);
+ r = pakfire_jail_exec(jail, argv, NULL, NULL, NULL, 0);
ERROR:
if (jail)