summaryrefslogtreecommitdiff
path: root/src/journal/journalctl.c
diff options
context:
space:
mode:
authorDaan De Meyer <daan.j.demeyer@gmail.com>2022-07-22 14:49:42 +0200
committerDaan De Meyer <daan.j.demeyer@gmail.com>2022-07-25 14:16:17 +0200
commit75db32dcd810cb6f4bc0148c3e280c5c04203491 (patch)
treed200b732eeae976392e8c64ac87782ecaa0f022e /src/journal/journalctl.c
parent05abe850330fdef145d8d45d5a2e33d76a0a8d21 (diff)
downloadsystemd-75db32dcd810cb6f4bc0148c3e280c5c04203491.tar.gz
journal: Move more pattern matching logic into pcre2-util
To avoid having "#if HAVE_PCRE2" all throughout the code, let's confine the pcre2 header specific stuff to pcre2-util.c. Instead of exposing all the individual symbols from pcre2, let's only expose three high level functions that do all we need: - pcre2_pattern_compile(): Compile the regex - pcre2_pattern_matches(): Check if the compiled regex matches a message - pcre2_pattern_free(): Free the compiled regex We expose the compiled pcre2 pattern (which is of type pcre2_code *) as a void pointer to avoid having to include pcre2.h in all code where we work with compiled pcre2 patterns. For readability, we typedef void to pcre2_pattern and use that as the type specifier for compiled pcre2 patterns.
Diffstat (limited to 'src/journal/journalctl.c')
-rw-r--r--src/journal/journalctl.c116
1 files changed, 10 insertions, 106 deletions
diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c
index 127c3d491b..5cc92b5f36 100644
--- a/src/journal/journalctl.c
+++ b/src/journal/journalctl.c
@@ -13,11 +13,6 @@
#include <sys/stat.h>
#include <unistd.h>
-#if HAVE_PCRE2
-# define PCRE2_CODE_UNIT_WIDTH 8
-# include <pcre2.h>
-#endif
-
#include "sd-bus.h"
#include "sd-device.h"
#include "sd-journal.h"
@@ -133,11 +128,9 @@ static uint64_t arg_vacuum_size = 0;
static uint64_t arg_vacuum_n_files = 0;
static usec_t arg_vacuum_time = 0;
static char **arg_output_fields = NULL;
-#if HAVE_PCRE2
static const char *arg_pattern = NULL;
static pcre2_code *arg_compiled_pattern = NULL;
-static int arg_case_sensitive = -1; /* -1 means be smart */
-#endif
+static PatternCompileCase arg_case = PATTERN_COMPILE_CASE_AUTO;
STATIC_DESTRUCTOR_REGISTER(arg_file, strv_freep);
STATIC_DESTRUCTOR_REGISTER(arg_facilities, set_freep);
@@ -148,9 +141,7 @@ STATIC_DESTRUCTOR_REGISTER(arg_user_units, strv_freep);
STATIC_DESTRUCTOR_REGISTER(arg_root, freep);
STATIC_DESTRUCTOR_REGISTER(arg_image, freep);
STATIC_DESTRUCTOR_REGISTER(arg_output_fields, strv_freep);
-#if HAVE_PCRE2
-STATIC_DESTRUCTOR_REGISTER(arg_compiled_pattern, sym_pcre2_code_freep);
-#endif
+STATIC_DESTRUCTOR_REGISTER(arg_compiled_pattern, pattern_freep);
static enum {
ACTION_SHOW,
@@ -180,29 +171,6 @@ typedef struct BootId {
LIST_FIELDS(struct BootId, boot_list);
} BootId;
-#if HAVE_PCRE2
-static int pattern_compile(const char *pattern, unsigned flags, pcre2_code **out) {
- int errorcode, r;
- PCRE2_SIZE erroroffset;
- pcre2_code *p;
-
- p = sym_pcre2_compile((PCRE2_SPTR8) pattern,
- PCRE2_ZERO_TERMINATED, flags, &errorcode, &erroroffset, NULL);
- if (!p) {
- unsigned char buf[LINE_MAX];
-
- r = sym_pcre2_get_error_message(errorcode, buf, sizeof buf);
-
- return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
- "Bad pattern \"%s\": %s", pattern,
- r < 0 ? "unknown error" : (char *)buf);
- }
-
- *out = p;
- return 0;
-}
-#endif
-
static int add_matches_for_device(sd_journal *j, const char *devpath) {
_cleanup_(sd_device_unrefp) sd_device *device = NULL;
sd_device *d = NULL;
@@ -918,7 +886,6 @@ static int parse_argv(int argc, char *argv[]) {
break;
}
-#if HAVE_PCRE2
case 'g':
arg_pattern = optarg;
break;
@@ -928,16 +895,11 @@ static int parse_argv(int argc, char *argv[]) {
r = parse_boolean(optarg);
if (r < 0)
return log_error_errno(r, "Bad --case-sensitive= argument \"%s\": %m", optarg);
- arg_case_sensitive = r;
+ arg_case = r ? PATTERN_COMPILE_CASE_SENSITIVE : PATTERN_COMPILE_CASE_INSENSITIVE;
} else
- arg_case_sensitive = true;
+ arg_case = PATTERN_COMPILE_CASE_SENSITIVE;
break;
-#else
- case 'g':
- case ARG_CASE_SENSITIVE:
- return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Compiled without pattern matching support");
-#endif
case 'S':
r = parse_timestamp(optarg, &arg_since);
@@ -1114,44 +1076,11 @@ static int parse_argv(int argc, char *argv[]) {
arg_system_units = strv_free(arg_system_units);
}
-#if HAVE_PCRE2
if (arg_pattern) {
- unsigned flags;
-
- r = dlopen_pcre2();
- if (r < 0)
- return r;
-
- if (arg_case_sensitive >= 0)
- flags = !arg_case_sensitive * PCRE2_CASELESS;
- else {
- _cleanup_(sym_pcre2_match_data_freep) pcre2_match_data *md = NULL;
- bool has_case;
- _cleanup_(sym_pcre2_code_freep) pcre2_code *cs = NULL;
-
- md = sym_pcre2_match_data_create(1, NULL);
- if (!md)
- return log_oom();
-
- r = pattern_compile("[[:upper:]]", 0, &cs);
- if (r < 0)
- return r;
-
- r = sym_pcre2_match(cs, (PCRE2_SPTR8) arg_pattern, PCRE2_ZERO_TERMINATED, 0, 0, md, NULL);
- has_case = r >= 0;
-
- flags = !has_case * PCRE2_CASELESS;
- }
-
- log_debug("Doing case %s matching based on %s",
- flags & PCRE2_CASELESS ? "insensitive" : "sensitive",
- arg_case_sensitive >= 0 ? "request" : "pattern casing");
-
- r = pattern_compile(arg_pattern, flags, &arg_compiled_pattern);
+ r = pattern_compile_and_log(arg_pattern, arg_case, &arg_compiled_pattern);
if (r < 0)
return r;
}
-#endif
return 1;
}
@@ -2703,16 +2632,9 @@ int main(int argc, char *argv[]) {
}
}
-#if HAVE_PCRE2
if (arg_compiled_pattern) {
- _cleanup_(sym_pcre2_match_data_freep) pcre2_match_data *md = NULL;
const void *message;
size_t len;
- PCRE2_SIZE *ovec;
-
- md = sym_pcre2_match_data_create(1, NULL);
- if (!md)
- return log_oom();
r = sd_journal_get_data(j, "MESSAGE", &message, &len);
if (r < 0) {
@@ -2727,33 +2649,15 @@ int main(int argc, char *argv[]) {
assert_se(message = startswith(message, "MESSAGE="));
- r = sym_pcre2_match(arg_compiled_pattern,
- message,
- len - strlen("MESSAGE="),
- 0, /* start at offset 0 in the subject */
- 0, /* default options */
- md,
- NULL);
- if (r == PCRE2_ERROR_NOMATCH) {
+ r = pattern_matches_and_log(arg_compiled_pattern, message,
+ len - strlen("MESSAGE="), highlight);
+ if (r < 0)
+ goto finish;
+ if (r == 0) {
need_seek = true;
continue;
}
- if (r < 0) {
- unsigned char buf[LINE_MAX];
- int r2;
-
- r2 = sym_pcre2_get_error_message(r, buf, sizeof buf);
- log_error("Pattern matching failed: %s",
- r2 < 0 ? "unknown error" : (char*) buf);
- r = -EINVAL;
- goto finish;
- }
-
- ovec = sym_pcre2_get_ovector_pointer(md);
- highlight[0] = ovec[0];
- highlight[1] = ovec[1];
}
-#endif
flags =
arg_all * OUTPUT_SHOW_ALL |