summaryrefslogtreecommitdiffstats
path: root/collectors/log2journal/log2journal-replace.c
diff options
context:
space:
mode:
Diffstat (limited to 'collectors/log2journal/log2journal-replace.c')
-rw-r--r--collectors/log2journal/log2journal-replace.c111
1 files changed, 111 insertions, 0 deletions
diff --git a/collectors/log2journal/log2journal-replace.c b/collectors/log2journal/log2journal-replace.c
new file mode 100644
index 00000000..429d615d
--- /dev/null
+++ b/collectors/log2journal/log2journal-replace.c
@@ -0,0 +1,111 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#include "log2journal.h"
+
+void replace_node_free(REPLACE_NODE *rpn) {
+ hashed_key_cleanup(&rpn->name);
+ rpn->next = NULL;
+ freez(rpn);
+}
+
+void replace_pattern_cleanup(REPLACE_PATTERN *rp) {
+ if(rp->pattern) {
+ freez((void *)rp->pattern);
+ rp->pattern = NULL;
+ }
+
+ while(rp->nodes) {
+ REPLACE_NODE *rpn = rp->nodes;
+ rp->nodes = rpn->next;
+ replace_node_free(rpn);
+ }
+}
+
+static REPLACE_NODE *replace_pattern_add_node(REPLACE_NODE **head, bool is_variable, const char *text) {
+ REPLACE_NODE *new_node = callocz(1, sizeof(REPLACE_NODE));
+ if (!new_node)
+ return NULL;
+
+ hashed_key_set(&new_node->name, text);
+ new_node->is_variable = is_variable;
+ new_node->next = NULL;
+
+ if (*head == NULL)
+ *head = new_node;
+
+ else {
+ REPLACE_NODE *current = *head;
+
+ // append it
+ while (current->next != NULL)
+ current = current->next;
+
+ current->next = new_node;
+ }
+
+ return new_node;
+}
+
+bool replace_pattern_set(REPLACE_PATTERN *rp, const char *pattern) {
+ replace_pattern_cleanup(rp);
+
+ rp->pattern = strdupz(pattern);
+ const char *current = rp->pattern;
+
+ while (*current != '\0') {
+ if (*current == '$' && *(current + 1) == '{') {
+ // Start of a variable
+ const char *end = strchr(current, '}');
+ if (!end) {
+ log2stderr("Error: Missing closing brace in replacement pattern: %s", rp->pattern);
+ return false;
+ }
+
+ size_t name_length = end - current - 2; // Length of the variable name
+ char *variable_name = strndupz(current + 2, name_length);
+ if (!variable_name) {
+ log2stderr("Error: Memory allocation failed for variable name.");
+ return false;
+ }
+
+ REPLACE_NODE *node = replace_pattern_add_node(&(rp->nodes), true, variable_name);
+ if (!node) {
+ freez(variable_name);
+ log2stderr("Error: Failed to add replacement node for variable.");
+ return false;
+ }
+
+ current = end + 1; // Move past the variable
+ }
+ else {
+ // Start of literal text
+ const char *start = current;
+ while (*current != '\0' && !(*current == '$' && *(current + 1) == '{')) {
+ current++;
+ }
+
+ size_t text_length = current - start;
+ char *text = strndupz(start, text_length);
+ if (!text) {
+ log2stderr("Error: Memory allocation failed for literal text.");
+ return false;
+ }
+
+ REPLACE_NODE *node = replace_pattern_add_node(&(rp->nodes), false, text);
+ if (!node) {
+ freez(text);
+ log2stderr("Error: Failed to add replacement node for text.");
+ return false;
+ }
+ }
+ }
+
+ for(REPLACE_NODE *node = rp->nodes; node; node = node->next) {
+ if(node->is_variable) {
+ rp->has_variables = true;
+ break;
+ }
+ }
+
+ return true;
+}