]> git.ipfire.org Git - pakfire.git/commitdiff
log streamer: Move line sanitization from PTY
authorMichael Tremer <michael.tremer@ipfire.org>
Sat, 22 Mar 2025 15:50:53 +0000 (15:50 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Sat, 22 Mar 2025 15:50:53 +0000 (15:50 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/pakfire/log_stream.c
src/pakfire/pty.c

index 485cd5dd34c9096d36e8c3118e36a63e58de6d4d..bbb8a5ad64d22299b102ef7b3b46531d755072eb 100644 (file)
@@ -19,6 +19,7 @@
 #############################################################################*/
 
 #include <errno.h>
+#include <ctype.h>
 #include <fcntl.h>
 
 #include <systemd/sd-event.h>
@@ -26,6 +27,8 @@
 #include <pakfire/ctx.h>
 #include <pakfire/log_stream.h>
 
+#define MAX_LINE_LENGTH 16384
+
 struct pakfire_log_stream {
        struct pakfire_ctx* ctx;
        int nrefs;
@@ -111,6 +114,123 @@ struct pakfire_log_stream* pakfire_log_stream_unref(struct pakfire_log_stream* s
        return NULL;
 }
 
+
+#define pakfire_log_stream_sanitize_line(self, line, buffer, buffer_length) \
+       __pakfire_log_stream_sanitize_line(self, line, sizeof(line), buffer, buffer_length)
+
+static int __pakfire_log_stream_sanitize_line(struct pakfire_log_stream* self,
+               char* line, ssize_t line_length, const char* buffer, ssize_t length) {
+       ssize_t i = 0;
+       int num;
+
+       // The cursor position
+       int cursor = 0;
+
+       while (i < length) {
+               switch (buffer[i]) {
+                       // Escape
+                       case '\x1b':
+                               // Skip the escape character
+                               i++;
+
+                               // CSI
+                               if (i < length && buffer[i] == '[') {
+                                       i++;
+
+                                       // Reset number
+                                       num = 0;
+
+                                       // Parse the number
+                                       while (i < length) {
+                                               // Skip any ';'
+                                               if (buffer[i] == ';') {
+                                                       i++;
+                                                       continue;
+
+                                               // Parse any digits
+                                               } else if (isdigit(buffer[i])) {
+                                                       num = num * 10 + (buffer[i] - '0');
+                                                       i++;
+                                                       continue;
+                                               }
+
+                                               // Break on all other characters
+                                               break;
+                                       }
+
+                                       // Parse the command
+                                       if (i < length) {
+                                               char command = buffer[i++];
+
+                                               switch (command) {
+                                                       // Move the cursor to the left
+                                                       case 'D':
+                                                               cursor -= (num > 0) ? num : 1;
+
+                                                               // Don't go too far left
+                                                               if (cursor < 0)
+                                                                       cursor = 0;
+                                                               break;
+
+                                                       // Move the cursor to the right
+                                                       case 'C':
+                                                               cursor += (num > 0) ? num : 1;
+
+                                                               // Don't go too far right
+                                                               if (cursor >= length)
+                                                                       cursor = length - 1;
+                                                               break;
+
+                                                       // Move to a certain column
+                                                       case 'G':
+                                                               cursor = (num > 0) ? num - 1 : 0;
+
+                                                               // Don't go too far right
+                                                               if (cursor >= length)
+                                                                       cursor = length - 1;
+                                                               break;
+
+                                                       // Ignore any other sequences
+                                                       default:
+                                                               break;
+                                               }
+                                       }
+                               }
+                               break;
+
+                       // Backspace
+                       case '\x08':
+                               if (cursor > 0) {
+                                       cursor--;
+
+                                       // Erase the previous character
+                                       line[cursor] = ' ';
+                               }
+                               i++;
+                               break;
+
+                       // Carriage Return
+                       case '\x0d':
+                               // Erase everything up to the cursor
+                               memset(line, '\0', cursor);
+
+                               cursor = 0;
+                               i++;
+                               break;
+
+                       // Normal characters
+                       default:
+                               if (cursor < line_length - 1)
+                                       line[cursor++] = buffer[i];
+                               i++;
+                               break;
+               }
+       }
+
+       // Return the length of the output
+       return cursor;
+}
+
 static int pakfire_log_stream_fill_buffer(struct pakfire_log_stream* stream, int fd) {
        ssize_t bytes_read;
 
@@ -128,6 +248,7 @@ static int pakfire_log_stream_fill_buffer(struct pakfire_log_stream* stream, int
 }
 
 static int pakfire_log_stream_drain_buffer(struct pakfire_log_stream* stream) {
+       char line[MAX_LINE_LENGTH] = {};
        const char* eol = NULL;
        size_t length;
        int r;
@@ -152,8 +273,13 @@ static int pakfire_log_stream_drain_buffer(struct pakfire_log_stream* stream) {
                else
                        length = stream->buffered;
 
+               // Sanitize the line
+               r = pakfire_log_stream_sanitize_line(stream, line, stream->buffer, length);
+               if (r < 0)
+                       return r;
+
                // Call the callback
-               r = stream->callback(stream, stream->buffer, length, stream->data);
+               r = stream->callback(stream, line, r, stream->data);
                if (r)
                        return r;
 
index 4f3c1ab9f8c126d386ec9d32e58b05c6d779bf7e..9f665b3280d8ec1895b5653dc4b98f3d154dfa74 100644 (file)
@@ -400,134 +400,12 @@ static int pakfire_pty_fill_buffer(struct pakfire_pty* pty, int fd, struct pakfi
        return bytes_read;
 }
 
-#define pakfire_pty_sanitize_line(pty, line, buffer, buffer_length) \
-       __pakfire_pty_sanitize_line(pty, line, sizeof(line), buffer, buffer_length)
-
-static int __pakfire_pty_sanitize_line(struct pakfire_pty* self,
-               char* line, ssize_t line_length, const char* buffer, ssize_t length) {
-       ssize_t i = 0;
-       int num;
-
-       // The cursor position
-       int cursor = 0;
-
-       while (i < length) {
-               switch (buffer[i]) {
-                       // Escape
-                       case '\x1b':
-                               // Skip the escape character
-                               i++;
-
-                               // CSI
-                               if (i < length && buffer[i] == '[') {
-                                       i++;
-
-                                       // Reset number
-                                       num = 0;
-
-                                       // Parse the number
-                                       while (i < length) {
-                                               // Skip any ';'
-                                               if (buffer[i] == ';') {
-                                                       i++;
-                                                       continue;
-
-                                               // Parse any digits
-                                               } else if (isdigit(buffer[i])) {
-                                                       num = num * 10 + (buffer[i] - '0');
-                                                       i++;
-                                                       continue;
-                                               }
-
-                                               // Break on all other characters
-                                               break;
-                                       }
-
-                                       // Parse the command
-                                       if (i < length) {
-                                               char command = buffer[i++];
-
-                                               switch (command) {
-                                                       // Move the cursor to the left
-                                                       case 'D':
-                                                               cursor -= (num > 0) ? num : 1;
-
-                                                               // Don't go too far left
-                                                               if (cursor < 0)
-                                                                       cursor = 0;
-                                                               break;
-
-                                                       // Move the cursor to the right
-                                                       case 'C':
-                                                               cursor += (num > 0) ? num : 1;
-
-                                                               // Don't go too far right
-                                                               if (cursor >= length)
-                                                                       cursor = length - 1;
-                                                               break;
-
-                                                       // Move to a certain column
-                                                       case 'G':
-                                                               cursor = (num > 0) ? num - 1 : 0;
-
-                                                               // Don't go too far right
-                                                               if (cursor >= length)
-                                                                       cursor = length - 1;
-                                                               break;
-
-                                                       // Ignore any other sequences
-                                                       default:
-                                                               break;
-                                               }
-                                       }
-                               }
-                               break;
-
-                       // Backspace
-                       case '\x08':
-                               if (cursor > 0) {
-                                       cursor--;
-
-                                       // Erase the previous character
-                                       line[cursor] = ' ';
-                               }
-                               i++;
-                               break;
-
-                       // Carriage Return
-                       case '\x0d':
-                               // Erase everything up to the cursor
-                               memset(line, '\0', cursor);
-
-                               cursor = 0;
-                               i++;
-                               break;
-
-                       // Normal characters
-                       default:
-                               if (cursor < line_length - 1)
-                                       line[cursor++] = buffer[i];
-                               i++;
-                               break;
-               }
-       }
-
-       return 0;
-}
-
 static ssize_t pakfire_pty_send_line(struct pakfire_pty* self,
                struct pakfire_pty_stdio* stdio, const char* buffer, ssize_t length) {
-       char line[MAX_LINE_LENGTH] = {};
        int r;
 
-       // Sanitize the line
-       r = pakfire_pty_sanitize_line(self, line, buffer, length);
-       if (r < 0)
-               return r;
-
        // Call the callback
-       r = stdio->callbacks.stdout_callback(self->ctx,
-                       stdio->callbacks.data, line, strlen(line));
+       r = stdio->callbacks.stdout_callback(self->ctx, stdio->callbacks.data, buffer, length);
        if (r < 0)
                return r;