]> git.ipfire.org Git - people/ms/pakfire.git/blobdiff - src/libpakfire/jail.c
jail: Replace communication callbacks by setting callbacks
[people/ms/pakfire.git] / src / libpakfire / jail.c
index 9433f925158cfb6cbbb3fda1a5bfcf13dfe88cb7..c5a663de5dceeab2b97b826d7fdf80420c20a3d9 100644 (file)
@@ -85,6 +85,7 @@ static const struct environ {
 struct pakfire_log_buffer {
        char data[BUFFER_SIZE];
        size_t used;
+       int priority;
 };
 
 enum pakfire_jail_pty_io {
@@ -181,13 +182,6 @@ struct pakfire_jail_exec {
 #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
@@ -251,21 +245,6 @@ static void pakfire_jail_free(struct pakfire_jail* jail) {
        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);
@@ -644,7 +623,7 @@ static int pakfire_jail_fill_buffer(struct pakfire_jail* jail, int fd, struct pa
 }
 
 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;
 
@@ -670,9 +649,9 @@ static int pakfire_jail_drain_buffer_with_callback(struct pakfire_jail* jail,
                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;
                }
 
@@ -719,14 +698,26 @@ static int pakfire_jail_drain_buffer(struct pakfire_jail* jail, int fd, struct p
        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
@@ -735,7 +726,7 @@ static int pakfire_jail_handle_log(struct pakfire_jail* jail, struct pakfire_jai
                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;
 
@@ -754,7 +745,7 @@ static int pakfire_jail_stream_stdin(struct pakfire_jail* jail,
        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:
@@ -1078,6 +1069,13 @@ static int pakfire_jail_setup_pty_forwarding(struct pakfire_jail* jail,
        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;
 
@@ -1100,7 +1098,7 @@ static int pakfire_jail_forward_pty(struct pakfire_jail* jail, struct pakfire_ja
 
                // 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;
@@ -1136,9 +1134,9 @@ static int pakfire_jail_forward_pty(struct pakfire_jail* jail, struct pakfire_ja
                // 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;
 
@@ -1153,7 +1151,7 @@ static int pakfire_jail_forward_pty(struct pakfire_jail* jail, struct pakfire_ja
                        // 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;
                        }
@@ -1354,8 +1352,8 @@ static int pakfire_jail_wait(struct pakfire_jail* jail, struct pakfire_jail_exec
                        // 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;
                                }
@@ -1363,8 +1361,8 @@ static int pakfire_jail_wait(struct pakfire_jail* jail, struct pakfire_jail_exec
                        // 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;
                                }
@@ -1373,8 +1371,8 @@ static int pakfire_jail_wait(struct pakfire_jail* jail, struct pakfire_jail_exec
                        // 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;
                                }
@@ -1413,22 +1411,17 @@ 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
@@ -2333,10 +2326,20 @@ static int __pakfire_jail_exec(struct pakfire_jail* jail, const char* argv[],
 #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,
@@ -2625,8 +2628,11 @@ int pakfire_jail_run(struct pakfire* pakfire, const char* argv[], int flags, cha
        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)