Bug Summary

File:build-scan/../src/journal/journalctl.c
Warning:line 1126, column 17
Use of memory after it is freed

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name journalctl.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -relaxed-aliasing -menable-no-infs -menable-no-nans -menable-unsafe-fp-math -fno-signed-zeros -mreassociate -freciprocal-math -fdenormal-fp-math=preserve-sign,preserve-sign -ffp-contract=fast -fno-rounding-math -ffast-math -ffinite-math-only -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/12.0.0 -include config.h -I journalctl.p -I . -I .. -I src/basic -I ../src/basic -I src/shared -I ../src/shared -I src/systemd -I ../src/systemd -I src/journal -I ../src/journal -I src/journal-remote -I ../src/journal-remote -I src/nspawn -I ../src/nspawn -I src/resolve -I ../src/resolve -I src/timesync -I ../src/timesync -I ../src/time-wait-sync -I src/login -I ../src/login -I src/udev -I ../src/udev -I src/libudev -I ../src/libudev -I src/core -I ../src/core -I ../src/libsystemd/sd-bus -I ../src/libsystemd/sd-device -I ../src/libsystemd/sd-hwdb -I ../src/libsystemd/sd-id128 -I ../src/libsystemd/sd-netlink -I ../src/libsystemd/sd-network -I src/libsystemd-network -I ../src/libsystemd-network -D _FILE_OFFSET_BITS=64 -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/12.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wwrite-strings -Wno-unused-parameter -Wno-missing-field-initializers -Wno-unused-result -Wno-format-signedness -Wno-error=nonnull -std=gnu99 -fconst-strings -fdebug-compilation-dir /home/mrc0mmand/repos/@redhat-plumbers/systemd-rhel8/build-scan -ferror-limit 19 -fvisibility hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcolor-diagnostics -analyzer-output=html -faddrsig -o /tmp/scan-build-2021-07-16-221226-1465241-1 -x c ../src/journal/journalctl.c
1/* SPDX-License-Identifier: LGPL-2.1+ */
2
3#include <errno(*__errno_location ()).h>
4#include <fcntl.h>
5#include <fnmatch.h>
6#include <getopt.h>
7#include <linux1/fs.h>
8#include <locale.h>
9#include <poll.h>
10#include <signal.h>
11#include <stddef.h>
12#include <stdio.h>
13#include <stdlib.h>
14#include <string.h>
15#include <sys/inotify.h>
16#include <sys/stat.h>
17#include <unistd.h>
18
19#if HAVE_PCRE21
20# define PCRE2_CODE_UNIT_WIDTH8 8
21# include <pcre2.h>
22#endif
23
24#include "sd-bus.h"
25#include "sd-journal.h"
26
27#include "acl-util.h"
28#include "alloc-util.h"
29#include "bus-error.h"
30#include "bus-util.h"
31#include "catalog.h"
32#include "chattr-util.h"
33#include "fd-util.h"
34#include "fileio.h"
35#include "fs-util.h"
36#include "fsprg.h"
37#include "glob-util.h"
38#include "hostname-util.h"
39#include "io-util.h"
40#include "journal-def.h"
41#include "journal-internal.h"
42#include "journal-qrcode.h"
43#include "journal-util.h"
44#include "journal-vacuum.h"
45#include "journal-verify.h"
46#include "locale-util.h"
47#include "log.h"
48#include "logs-show.h"
49#include "mkdir.h"
50#include "pager.h"
51#include "parse-util.h"
52#include "path-util.h"
53#include "rlimit-util.h"
54#include "set.h"
55#include "sigbus.h"
56#include "string-table.h"
57#include "strv.h"
58#include "syslog-util.h"
59#include "terminal-util.h"
60#include "udev-util.h"
61#include "udev.h"
62#include "unit-name.h"
63#include "user-util.h"
64
65#define DEFAULT_FSS_INTERVAL_USEC(15*((usec_t) (60ULL*((usec_t) 1000000ULL)))) (15*USEC_PER_MINUTE((usec_t) (60ULL*((usec_t) 1000000ULL))))
66
67#define PROCESS_INOTIFY_INTERVAL1024 1024 /* Every 1,024 messages processed */
68
69#if HAVE_PCRE21
70DEFINE_TRIVIAL_CLEANUP_FUNC(pcre2_match_data*, pcre2_match_data_free)static inline void pcre2_match_data_freep(pcre2_match_data_8*
*p) { if (*p) pcre2_match_data_free_8(*p); }
;
71DEFINE_TRIVIAL_CLEANUP_FUNC(pcre2_code*, pcre2_code_free)static inline void pcre2_code_freep(pcre2_code_8* *p) { if (*
p) pcre2_code_free_8(*p); }
;
72
73static int pattern_compile(const char *pattern, unsigned flags, pcre2_codepcre2_code_8 **out) {
74 int errorcode, r;
75 PCRE2_SIZEsize_t erroroffset;
76 pcre2_codepcre2_code_8 *p;
77
78 p = pcre2_compilepcre2_compile_8((PCRE2_SPTR8) pattern,
79 PCRE2_ZERO_TERMINATED(~(size_t)0), flags, &errorcode, &erroroffset, NULL((void*)0));
80 if (!p) {
81 unsigned char buf[LINE_MAX2048];
82
83 r = pcre2_get_error_messagepcre2_get_error_message_8(errorcode, buf, sizeof buf);
84
85 log_error("Bad pattern \"%s\": %s",({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 87, __func__, "Bad pattern \"%s\": %s"
, pattern, r < 0 ? "unknown error" : (char*) buf) : -abs(_e
); })
86 pattern,({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 87, __func__, "Bad pattern \"%s\": %s"
, pattern, r < 0 ? "unknown error" : (char*) buf) : -abs(_e
); })
87 r < 0 ? "unknown error" : (char*) buf)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 87, __func__, "Bad pattern \"%s\": %s"
, pattern, r < 0 ? "unknown error" : (char*) buf) : -abs(_e
); })
;
88 return -EINVAL22;
89 }
90
91 *out = p;
92 return 0;
93}
94
95#endif
96
97enum {
98 /* Special values for arg_lines */
99 ARG_LINES_DEFAULT = -2,
100 ARG_LINES_ALL = -1,
101};
102
103static OutputMode arg_output = OUTPUT_SHORT;
104static bool_Bool arg_utc = false0;
105static bool_Bool arg_pager_end = false0;
106static bool_Bool arg_follow = false0;
107static bool_Bool arg_full = true1;
108static bool_Bool arg_all = false0;
109static bool_Bool arg_no_pager = false0;
110static int arg_lines = ARG_LINES_DEFAULT;
111static bool_Bool arg_no_tail = false0;
112static bool_Bool arg_quiet = false0;
113static bool_Bool arg_merge = false0;
114static bool_Bool arg_boot = false0;
115static sd_id128_t arg_boot_id = {};
116static int arg_boot_offset = 0;
117static bool_Bool arg_dmesg = false0;
118static bool_Bool arg_no_hostname = false0;
119static const char *arg_cursor = NULL((void*)0);
120static const char *arg_after_cursor = NULL((void*)0);
121static bool_Bool arg_show_cursor = false0;
122static const char *arg_directory = NULL((void*)0);
123static char **arg_file = NULL((void*)0);
124static bool_Bool arg_file_stdin = false0;
125static int arg_priorities = 0xFF;
126static char *arg_verify_key = NULL((void*)0);
127#if HAVE_GCRYPT1
128static usec_t arg_interval = DEFAULT_FSS_INTERVAL_USEC(15*((usec_t) (60ULL*((usec_t) 1000000ULL))));
129static bool_Bool arg_force = false0;
130#endif
131static usec_t arg_since, arg_until;
132static bool_Bool arg_since_set = false0, arg_until_set = false0;
133static char **arg_syslog_identifier = NULL((void*)0);
134static char **arg_system_units = NULL((void*)0);
135static char **arg_user_units = NULL((void*)0);
136static const char *arg_field = NULL((void*)0);
137static bool_Bool arg_catalog = false0;
138static bool_Bool arg_reverse = false0;
139static int arg_journal_type = 0;
140static char *arg_root = NULL((void*)0);
141static const char *arg_machine = NULL((void*)0);
142static uint64_t arg_vacuum_size = 0;
143static uint64_t arg_vacuum_n_files = 0;
144static usec_t arg_vacuum_time = 0;
145static char **arg_output_fields = NULL((void*)0);
146
147#if HAVE_PCRE21
148static const char *arg_pattern = NULL((void*)0);
149static pcre2_codepcre2_code_8 *arg_compiled_pattern = NULL((void*)0);
150static int arg_case_sensitive = -1; /* -1 means be smart */
151#endif
152
153static enum {
154 ACTION_SHOW,
155 ACTION_NEW_ID128,
156 ACTION_PRINT_HEADER,
157 ACTION_SETUP_KEYS,
158 ACTION_VERIFY,
159 ACTION_DISK_USAGE,
160 ACTION_LIST_CATALOG,
161 ACTION_DUMP_CATALOG,
162 ACTION_UPDATE_CATALOG,
163 ACTION_LIST_BOOTS,
164 ACTION_FLUSH,
165 ACTION_SYNC,
166 ACTION_ROTATE,
167 ACTION_VACUUM,
168 ACTION_LIST_FIELDS,
169 ACTION_LIST_FIELD_NAMES,
170} arg_action = ACTION_SHOW;
171
172typedef struct BootId {
173 sd_id128_t id;
174 uint64_t first;
175 uint64_t last;
176 LIST_FIELDS(struct BootId, boot_list)struct BootId *boot_list_next, *boot_list_prev;
177} BootId;
178
179static int add_matches_for_device(sd_journal *j, const char *devpath) {
180 _cleanup_(udev_unrefp)__attribute__((cleanup(udev_unrefp))) struct udev *udev = NULL((void*)0);
181 _cleanup_(udev_device_unrefp)__attribute__((cleanup(udev_device_unrefp))) struct udev_device *device = NULL((void*)0);
182 struct udev_device *d = NULL((void*)0);
183 struct stat st;
184 int r;
185
186 assert(j)do { if ((__builtin_expect(!!(!(j)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("j"), "../src/journal/journalctl.c", 186
, __PRETTY_FUNCTION__); } while (0)
;
187 assert(devpath)do { if ((__builtin_expect(!!(!(devpath)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("devpath"), "../src/journal/journalctl.c"
, 187, __PRETTY_FUNCTION__); } while (0)
;
188
189 if (!path_startswith(devpath, "/dev/")) {
190 log_error("Devpath does not start with /dev/")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 190, __func__, "Devpath does not start with /dev/"
) : -abs(_e); })
;
191 return -EINVAL22;
192 }
193
194 udev = udev_new();
195 if (!udev)
196 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/journal/journalctl.c"
, 196, __func__)
;
197
198 if (stat(devpath, &st) < 0)
199 return log_error_errno(errno, "Couldn't stat file: %m")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/journal/journalctl.c", 199, __func__
, "Couldn't stat file: %m") : -abs(_e); })
;
200
201 r = udev_device_new_from_stat_rdev(udev, &st, &device);
202 if (r < 0)
203 return log_error_errno(r, "Failed to get udev device from devnum %u:%u: %m", major(st.st_rdev), minor(st.st_rdev))({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 203, __func__, "Failed to get udev device from devnum %u:%u: %m"
, gnu_dev_major (st.st_rdev), gnu_dev_minor (st.st_rdev)) : -
abs(_e); })
;
204
205 d = device;
206 while (d) {
207 _cleanup_free___attribute__((cleanup(freep))) char *match = NULL((void*)0);
208 const char *subsys, *sysname, *devnode;
209
210 subsys = udev_device_get_subsystem(d);
211 if (!subsys) {
212 d = udev_device_get_parent(d);
213 continue;
214 }
215
216 sysname = udev_device_get_sysname(d);
217 if (!sysname) {
218 d = udev_device_get_parent(d);
219 continue;
220 }
221
222 match = strjoin("_KERNEL_DEVICE=+", subsys, ":", sysname)strjoin_real(("_KERNEL_DEVICE=+"), subsys, ":", sysname, ((void
*)0))
;
223 if (!match)
224 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/journal/journalctl.c"
, 224, __func__)
;
225
226 r = sd_journal_add_match(j, match, 0);
227 if (r < 0)
228 return log_error_errno(r, "Failed to add match: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 228, __func__, "Failed to add match: %m"
) : -abs(_e); })
;
229
230 devnode = udev_device_get_devnode(d);
231 if (devnode) {
232 _cleanup_free___attribute__((cleanup(freep))) char *match1 = NULL((void*)0);
233
234 r = stat(devnode, &st);
235 if (r < 0)
236 return log_error_errno(r, "Failed to stat() device node \"%s\": %m", devnode)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 236, __func__, "Failed to stat() device node \"%s\": %m"
, devnode) : -abs(_e); })
;
237
238 r = asprintf(&match1, "_KERNEL_DEVICE=%c%u:%u", S_ISBLK(st.st_mode)((((st.st_mode)) & 0170000) == (0060000)) ? 'b' : 'c', major(st.st_rdev)gnu_dev_major (st.st_rdev), minor(st.st_rdev)gnu_dev_minor (st.st_rdev));
239 if (r < 0)
240 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/journal/journalctl.c"
, 240, __func__)
;
241
242 r = sd_journal_add_match(j, match1, 0);
243 if (r < 0)
244 return log_error_errno(r, "Failed to add match: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 244, __func__, "Failed to add match: %m"
) : -abs(_e); })
;
245 }
246
247 d = udev_device_get_parent(d);
248 }
249
250 r = add_match_this_boot(j, arg_machine);
251 if (r < 0)
252 return log_error_errno(r, "Failed to add match for the current boot: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 252, __func__, "Failed to add match for the current boot: %m"
) : -abs(_e); })
;
253
254 return 0;
255}
256
257static char *format_timestamp_maybe_utc(char *buf, size_t l, usec_t t) {
258
259 if (arg_utc)
260 return format_timestamp_utc(buf, l, t);
261
262 return format_timestamp(buf, l, t);
263}
264
265static int parse_boot_descriptor(const char *x, sd_id128_t *boot_id, int *offset) {
266 sd_id128_t id = SD_ID128_NULL((const sd_id128_t) { .qwords = { 0, 0 }});
267 int off = 0, r;
268
269 if (strlen(x) >= 32) {
270 char *t;
271
272 t = strndupa(x, 32)(__extension__ ({ const char *__old = (x); size_t __len = strnlen
(__old, (32)); char *__new = (char *) __builtin_alloca (__len
+ 1); __new[__len] = '\0'; (char *) memcpy (__new, __old, __len
); }))
;
273 r = sd_id128_from_string(t, &id);
274 if (r >= 0)
275 x += 32;
276
277 if (!IN_SET(*x, 0, '-', '+')({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){0, '-', '+'})/sizeof(int)]; switch(*x) {
case 0: case '-': case '+': _found = 1; break; default: break
; } _found; })
)
278 return -EINVAL22;
279
280 if (*x != 0) {
281 r = safe_atoi(x, &off);
282 if (r < 0)
283 return r;
284 }
285 } else {
286 r = safe_atoi(x, &off);
287 if (r < 0)
288 return r;
289 }
290
291 if (boot_id)
292 *boot_id = id;
293
294 if (offset)
295 *offset = off;
296
297 return 0;
298}
299
300static void help(void) {
301
302 (void) pager_open(arg_no_pager, arg_pager_end);
303
304 printf("%s [OPTIONS...] [MATCHES...]\n\n"
305 "Query the journal.\n\n"
306 "Options:\n"
307 " --system Show the system journal\n"
308 " --user Show the user journal for the current user\n"
309 " -M --machine=CONTAINER Operate on local container\n"
310 " -S --since=DATE Show entries not older than the specified date\n"
311 " -U --until=DATE Show entries not newer than the specified date\n"
312 " -c --cursor=CURSOR Show entries starting at the specified cursor\n"
313 " --after-cursor=CURSOR Show entries after the specified cursor\n"
314 " --show-cursor Print the cursor after all the entries\n"
315 " -b --boot[=ID] Show current boot or the specified boot\n"
316 " --list-boots Show terse information about recorded boots\n"
317 " -k --dmesg Show kernel message log from the current boot\n"
318 " -u --unit=UNIT Show logs from the specified unit\n"
319 " --user-unit=UNIT Show logs from the specified user unit\n"
320 " -t --identifier=STRING Show entries with the specified syslog identifier\n"
321 " -p --priority=RANGE Show entries with the specified priority\n"
322 " -g --grep=PATTERN Show entries with MESSAGE matching PATTERN\n"
323 " --case-sensitive[=BOOL] Force case sensitive or insenstive matching\n"
324 " -e --pager-end Immediately jump to the end in the pager\n"
325 " -f --follow Follow the journal\n"
326 " -n --lines[=INTEGER] Number of journal entries to show\n"
327 " --no-tail Show all lines, even in follow mode\n"
328 " -r --reverse Show the newest entries first\n"
329 " -o --output=STRING Change journal output mode (short, short-precise,\n"
330 " short-iso, short-iso-precise, short-full,\n"
331 " short-monotonic, short-unix, verbose, export,\n"
332 " json, json-pretty, json-sse, cat, with-unit)\n"
333 " --output-fields=LIST Select fields to print in verbose/export/json modes\n"
334 " --utc Express time in Coordinated Universal Time (UTC)\n"
335 " -x --catalog Add message explanations where available\n"
336 " --no-full Ellipsize fields\n"
337 " -a --all Show all fields, including long and unprintable\n"
338 " -q --quiet Do not show info messages and privilege warning\n"
339 " --no-pager Do not pipe output into a pager\n"
340 " --no-hostname Suppress output of hostname field\n"
341 " -m --merge Show entries from all available journals\n"
342 " -D --directory=PATH Show journal files from directory\n"
343 " --file=PATH Show journal file\n"
344 " --root=ROOT Operate on files below a root directory\n"
345#if HAVE_GCRYPT1
346 " --interval=TIME Time interval for changing the FSS sealing key\n"
347 " --verify-key=KEY Specify FSS verification key\n"
348 " --force Override of the FSS key pair with --setup-keys\n"
349#endif
350 "\nCommands:\n"
351 " -h --help Show this help text\n"
352 " --version Show package version\n"
353 " -N --fields List all field names currently used\n"
354 " -F --field=FIELD List all values that a specified field takes\n"
355 " --disk-usage Show total disk usage of all journal files\n"
356 " --vacuum-size=BYTES Reduce disk usage below specified size\n"
357 " --vacuum-files=INT Leave only the specified number of journal files\n"
358 " --vacuum-time=TIME Remove journal files older than specified time\n"
359 " --verify Verify journal file consistency\n"
360 " --sync Synchronize unwritten journal messages to disk\n"
361 " --flush Flush all journal data from /run into /var\n"
362 " --rotate Request immediate rotation of the journal files\n"
363 " --header Show journal header information\n"
364 " --list-catalog Show all message IDs in the catalog\n"
365 " --dump-catalog Show entries in the message catalog\n"
366 " --update-catalog Update the message catalog database\n"
367 " --new-id128 Generate a new 128-bit ID\n"
368#if HAVE_GCRYPT1
369 " --setup-keys Generate a new FSS key pair\n"
370#endif
371 , program_invocation_short_name);
372}
373
374static int parse_argv(int argc, char *argv[]) {
375
376 enum {
377 ARG_VERSION = 0x100,
378 ARG_NO_PAGER,
379 ARG_NO_FULL,
380 ARG_NO_TAIL,
381 ARG_NEW_ID128,
382 ARG_THIS_BOOT,
383 ARG_LIST_BOOTS,
384 ARG_USER,
385 ARG_SYSTEM,
386 ARG_ROOT,
387 ARG_HEADER,
388 ARG_SETUP_KEYS,
389 ARG_FILE,
390 ARG_INTERVAL,
391 ARG_VERIFY,
392 ARG_VERIFY_KEY,
393 ARG_DISK_USAGE,
394 ARG_AFTER_CURSOR,
395 ARG_SHOW_CURSOR,
396 ARG_USER_UNIT,
397 ARG_LIST_CATALOG,
398 ARG_DUMP_CATALOG,
399 ARG_UPDATE_CATALOG,
400 ARG_FORCE,
401 ARG_CASE_SENSITIVE,
402 ARG_UTC,
403 ARG_SYNC,
404 ARG_FLUSH,
405 ARG_ROTATE,
406 ARG_VACUUM_SIZE,
407 ARG_VACUUM_FILES,
408 ARG_VACUUM_TIME,
409 ARG_NO_HOSTNAME,
410 ARG_OUTPUT_FIELDS,
411 };
412
413 static const struct option options[] = {
414 { "help", no_argument0, NULL((void*)0), 'h' },
415 { "version" , no_argument0, NULL((void*)0), ARG_VERSION },
416 { "no-pager", no_argument0, NULL((void*)0), ARG_NO_PAGER },
417 { "pager-end", no_argument0, NULL((void*)0), 'e' },
418 { "follow", no_argument0, NULL((void*)0), 'f' },
419 { "force", no_argument0, NULL((void*)0), ARG_FORCE },
420 { "output", required_argument1, NULL((void*)0), 'o' },
421 { "all", no_argument0, NULL((void*)0), 'a' },
422 { "full", no_argument0, NULL((void*)0), 'l' },
423 { "no-full", no_argument0, NULL((void*)0), ARG_NO_FULL },
424 { "lines", optional_argument2, NULL((void*)0), 'n' },
425 { "no-tail", no_argument0, NULL((void*)0), ARG_NO_TAIL },
426 { "new-id128", no_argument0, NULL((void*)0), ARG_NEW_ID128 },
427 { "quiet", no_argument0, NULL((void*)0), 'q' },
428 { "merge", no_argument0, NULL((void*)0), 'm' },
429 { "this-boot", no_argument0, NULL((void*)0), ARG_THIS_BOOT }, /* deprecated */
430 { "boot", optional_argument2, NULL((void*)0), 'b' },
431 { "list-boots", no_argument0, NULL((void*)0), ARG_LIST_BOOTS },
432 { "dmesg", no_argument0, NULL((void*)0), 'k' },
433 { "system", no_argument0, NULL((void*)0), ARG_SYSTEM },
434 { "user", no_argument0, NULL((void*)0), ARG_USER },
435 { "directory", required_argument1, NULL((void*)0), 'D' },
436 { "file", required_argument1, NULL((void*)0), ARG_FILE },
437 { "root", required_argument1, NULL((void*)0), ARG_ROOT },
438 { "header", no_argument0, NULL((void*)0), ARG_HEADER },
439 { "identifier", required_argument1, NULL((void*)0), 't' },
440 { "priority", required_argument1, NULL((void*)0), 'p' },
441 { "grep", required_argument1, NULL((void*)0), 'g' },
442 { "case-sensitive", optional_argument2, NULL((void*)0), ARG_CASE_SENSITIVE },
443 { "setup-keys", no_argument0, NULL((void*)0), ARG_SETUP_KEYS },
444 { "interval", required_argument1, NULL((void*)0), ARG_INTERVAL },
445 { "verify", no_argument0, NULL((void*)0), ARG_VERIFY },
446 { "verify-key", required_argument1, NULL((void*)0), ARG_VERIFY_KEY },
447 { "disk-usage", no_argument0, NULL((void*)0), ARG_DISK_USAGE },
448 { "cursor", required_argument1, NULL((void*)0), 'c' },
449 { "after-cursor", required_argument1, NULL((void*)0), ARG_AFTER_CURSOR },
450 { "show-cursor", no_argument0, NULL((void*)0), ARG_SHOW_CURSOR },
451 { "since", required_argument1, NULL((void*)0), 'S' },
452 { "until", required_argument1, NULL((void*)0), 'U' },
453 { "unit", required_argument1, NULL((void*)0), 'u' },
454 { "user-unit", required_argument1, NULL((void*)0), ARG_USER_UNIT },
455 { "field", required_argument1, NULL((void*)0), 'F' },
456 { "fields", no_argument0, NULL((void*)0), 'N' },
457 { "catalog", no_argument0, NULL((void*)0), 'x' },
458 { "list-catalog", no_argument0, NULL((void*)0), ARG_LIST_CATALOG },
459 { "dump-catalog", no_argument0, NULL((void*)0), ARG_DUMP_CATALOG },
460 { "update-catalog", no_argument0, NULL((void*)0), ARG_UPDATE_CATALOG },
461 { "reverse", no_argument0, NULL((void*)0), 'r' },
462 { "machine", required_argument1, NULL((void*)0), 'M' },
463 { "utc", no_argument0, NULL((void*)0), ARG_UTC },
464 { "flush", no_argument0, NULL((void*)0), ARG_FLUSH },
465 { "sync", no_argument0, NULL((void*)0), ARG_SYNC },
466 { "rotate", no_argument0, NULL((void*)0), ARG_ROTATE },
467 { "vacuum-size", required_argument1, NULL((void*)0), ARG_VACUUM_SIZE },
468 { "vacuum-files", required_argument1, NULL((void*)0), ARG_VACUUM_FILES },
469 { "vacuum-time", required_argument1, NULL((void*)0), ARG_VACUUM_TIME },
470 { "no-hostname", no_argument0, NULL((void*)0), ARG_NO_HOSTNAME },
471 { "output-fields", required_argument1, NULL((void*)0), ARG_OUTPUT_FIELDS },
472 {}
473 };
474
475 int c, r;
476
477 assert(argc >= 0)do { if ((__builtin_expect(!!(!(argc >= 0)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("argc >= 0"), "../src/journal/journalctl.c"
, 477, __PRETTY_FUNCTION__); } while (0)
;
478 assert(argv)do { if ((__builtin_expect(!!(!(argv)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("argv"), "../src/journal/journalctl.c", 478
, __PRETTY_FUNCTION__); } while (0)
;
479
480 while ((c = getopt_long(argc, argv, "hefo:aln::qmb::kD:p:g:c:S:U:t:u:NF:xrM:", options, NULL((void*)0))) >= 0)
481
482 switch (c) {
483
484 case 'h':
485 help();
486 return 0;
487
488 case ARG_VERSION:
489 return version();
490
491 case ARG_NO_PAGER:
492 arg_no_pager = true1;
493 break;
494
495 case 'e':
496 arg_pager_end = true1;
497
498 if (arg_lines == ARG_LINES_DEFAULT)
499 arg_lines = 1000;
500
501 break;
502
503 case 'f':
504 arg_follow = true1;
505 break;
506
507 case 'o':
508 if (streq(optarg, "help")(strcmp((optarg),("help")) == 0)) {
509 DUMP_STRING_TABLE(output_mode, OutputMode, _OUTPUT_MODE_MAX)do { OutputMode _k; flockfile(stdout); for (_k = 0; _k < (
_OUTPUT_MODE_MAX); _k++) { const char *_t; _t = output_mode_to_string
(_k); if (!_t) continue; fputs_unlocked(_t, stdout); fputc_unlocked
('\n', stdout); } funlockfile(stdout); } while(0)
;
510 return 0;
511 }
512
513 arg_output = output_mode_from_string(optarg);
514 if (arg_output < 0) {
515 log_error("Unknown output format '%s'.", optarg)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 515, __func__, "Unknown output format '%s'."
, optarg) : -abs(_e); })
;
516 return -EINVAL22;
517 }
518
519 if (IN_SET(arg_output, OUTPUT_EXPORT, OUTPUT_JSON, OUTPUT_JSON_PRETTY, OUTPUT_JSON_SSE, OUTPUT_CAT)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){OUTPUT_EXPORT, OUTPUT_JSON, OUTPUT_JSON_PRETTY
, OUTPUT_JSON_SSE, OUTPUT_CAT})/sizeof(int)]; switch(arg_output
) { case OUTPUT_EXPORT: case OUTPUT_JSON: case OUTPUT_JSON_PRETTY
: case OUTPUT_JSON_SSE: case OUTPUT_CAT: _found = 1; break; default
: break; } _found; })
)
520 arg_quiet = true1;
521
522 break;
523
524 case 'l':
525 arg_full = true1;
526 break;
527
528 case ARG_NO_FULL:
529 arg_full = false0;
530 break;
531
532 case 'a':
533 arg_all = true1;
534 break;
535
536 case 'n':
537 if (optarg) {
538 if (streq(optarg, "all")(strcmp((optarg),("all")) == 0))
539 arg_lines = ARG_LINES_ALL;
540 else {
541 r = safe_atoi(optarg, &arg_lines);
542 if (r < 0 || arg_lines < 0) {
543 log_error("Failed to parse lines '%s'", optarg)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 543, __func__, "Failed to parse lines '%s'"
, optarg) : -abs(_e); })
;
544 return -EINVAL22;
545 }
546 }
547 } else {
548 arg_lines = 10;
549
550 /* Hmm, no argument? Maybe the next
551 * word on the command line is
552 * supposed to be the argument? Let's
553 * see if there is one, and is
554 * parsable. */
555 if (optind < argc) {
556 int n;
557 if (streq(argv[optind], "all")(strcmp((argv[optind]),("all")) == 0)) {
558 arg_lines = ARG_LINES_ALL;
559 optind++;
560 } else if (safe_atoi(argv[optind], &n) >= 0 && n >= 0) {
561 arg_lines = n;
562 optind++;
563 }
564 }
565 }
566
567 break;
568
569 case ARG_NO_TAIL:
570 arg_no_tail = true1;
571 break;
572
573 case ARG_NEW_ID128:
574 arg_action = ACTION_NEW_ID128;
575 break;
576
577 case 'q':
578 arg_quiet = true1;
579 break;
580
581 case 'm':
582 arg_merge = true1;
583 break;
584
585 case ARG_THIS_BOOT:
586 arg_boot = true1;
587 break;
588
589 case 'b':
590 arg_boot = true1;
591
592 if (optarg) {
593 r = parse_boot_descriptor(optarg, &arg_boot_id, &arg_boot_offset);
594 if (r < 0) {
595 log_error("Failed to parse boot descriptor '%s'", optarg)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 595, __func__, "Failed to parse boot descriptor '%s'"
, optarg) : -abs(_e); })
;
596 return -EINVAL22;
597 }
598 } else {
599
600 /* Hmm, no argument? Maybe the next
601 * word on the command line is
602 * supposed to be the argument? Let's
603 * see if there is one and is parsable
604 * as a boot descriptor... */
605
606 if (optind < argc &&
607 parse_boot_descriptor(argv[optind], &arg_boot_id, &arg_boot_offset) >= 0)
608 optind++;
609 }
610
611 break;
612
613 case ARG_LIST_BOOTS:
614 arg_action = ACTION_LIST_BOOTS;
615 break;
616
617 case 'k':
618 arg_boot = arg_dmesg = true1;
619 break;
620
621 case ARG_SYSTEM:
622 arg_journal_type |= SD_JOURNAL_SYSTEM;
623 break;
624
625 case ARG_USER:
626 arg_journal_type |= SD_JOURNAL_CURRENT_USER;
627 break;
628
629 case 'M':
630 arg_machine = optarg;
631 break;
632
633 case 'D':
634 arg_directory = optarg;
635 break;
636
637 case ARG_FILE:
638 if (streq(optarg, "-")(strcmp((optarg),("-")) == 0))
639 /* An undocumented feature: we can read journal files from STDIN. We don't document
640 * this though, since after all we only support this for mmap-able, seekable files, and
641 * not for example pipes which are probably the primary usecase for reading things from
642 * STDIN. To avoid confusion we hence don't document this feature. */
643 arg_file_stdin = true1;
644 else {
645 r = glob_extend(&arg_file, optarg);
646 if (r < 0)
647 return log_error_errno(r, "Failed to add paths: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 647, __func__, "Failed to add paths: %m"
) : -abs(_e); })
;
648 }
649 break;
650
651 case ARG_ROOT:
652 r = parse_path_argument_and_warn(optarg, true1, &arg_root);
653 if (r < 0)
654 return r;
655 break;
656
657 case 'c':
658 arg_cursor = optarg;
659 break;
660
661 case ARG_AFTER_CURSOR:
662 arg_after_cursor = optarg;
663 break;
664
665 case ARG_SHOW_CURSOR:
666 arg_show_cursor = true1;
667 break;
668
669 case ARG_HEADER:
670 arg_action = ACTION_PRINT_HEADER;
671 break;
672
673 case ARG_VERIFY:
674 arg_action = ACTION_VERIFY;
675 break;
676
677 case ARG_DISK_USAGE:
678 arg_action = ACTION_DISK_USAGE;
679 break;
680
681 case ARG_VACUUM_SIZE:
682 r = parse_size(optarg, 1024, &arg_vacuum_size);
683 if (r < 0) {
684 log_error("Failed to parse vacuum size: %s", optarg)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 684, __func__, "Failed to parse vacuum size: %s"
, optarg) : -abs(_e); })
;
685 return r;
686 }
687
688 arg_action = ACTION_VACUUM;
689 break;
690
691 case ARG_VACUUM_FILES:
692 r = safe_atou64(optarg, &arg_vacuum_n_files);
693 if (r < 0) {
694 log_error("Failed to parse vacuum files: %s", optarg)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 694, __func__, "Failed to parse vacuum files: %s"
, optarg) : -abs(_e); })
;
695 return r;
696 }
697
698 arg_action = ACTION_VACUUM;
699 break;
700
701 case ARG_VACUUM_TIME:
702 r = parse_sec(optarg, &arg_vacuum_time);
703 if (r < 0) {
704 log_error("Failed to parse vacuum time: %s", optarg)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 704, __func__, "Failed to parse vacuum time: %s"
, optarg) : -abs(_e); })
;
705 return r;
706 }
707
708 arg_action = ACTION_VACUUM;
709 break;
710
711#if HAVE_GCRYPT1
712 case ARG_FORCE:
713 arg_force = true1;
714 break;
715
716 case ARG_SETUP_KEYS:
717 arg_action = ACTION_SETUP_KEYS;
718 break;
719
720 case ARG_VERIFY_KEY:
721 arg_action = ACTION_VERIFY;
722 r = free_and_strdup(&arg_verify_key, optarg);
723 if (r < 0)
724 return r;
725 /* Use memset not string_erase so this doesn't look confusing
726 * in ps or htop output. */
727 memset(optarg, 'x', strlen(optarg));
728
729 arg_merge = false0;
730 break;
731
732 case ARG_INTERVAL:
733 r = parse_sec(optarg, &arg_interval);
734 if (r < 0 || arg_interval <= 0) {
735 log_error("Failed to parse sealing key change interval: %s", optarg)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 735, __func__, "Failed to parse sealing key change interval: %s"
, optarg) : -abs(_e); })
;
736 return -EINVAL22;
737 }
738 break;
739#else
740 case ARG_SETUP_KEYS:
741 case ARG_VERIFY_KEY:
742 case ARG_INTERVAL:
743 case ARG_FORCE:
744 log_error("Forward-secure sealing not available.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 744, __func__, "Forward-secure sealing not available."
) : -abs(_e); })
;
745 return -EOPNOTSUPP95;
746#endif
747
748 case 'p': {
749 const char *dots;
750
751 dots = strstr(optarg, "..");
752 if (dots) {
753 char *a;
754 int from, to, i;
755
756 /* a range */
757 a = strndup(optarg, dots - optarg);
758 if (!a)
759 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/journal/journalctl.c"
, 759, __func__)
;
760
761 from = log_level_from_string(a);
762 to = log_level_from_string(dots + 2);
763 free(a);
764
765 if (from < 0 || to < 0) {
766 log_error("Failed to parse log level range %s", optarg)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 766, __func__, "Failed to parse log level range %s"
, optarg) : -abs(_e); })
;
767 return -EINVAL22;
768 }
769
770 arg_priorities = 0;
771
772 if (from < to) {
773 for (i = from; i <= to; i++)
774 arg_priorities |= 1 << i;
775 } else {
776 for (i = to; i <= from; i++)
777 arg_priorities |= 1 << i;
778 }
779
780 } else {
781 int p, i;
782
783 p = log_level_from_string(optarg);
784 if (p < 0) {
785 log_error("Unknown log level %s", optarg)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 785, __func__, "Unknown log level %s"
, optarg) : -abs(_e); })
;
786 return -EINVAL22;
787 }
788
789 arg_priorities = 0;
790
791 for (i = 0; i <= p; i++)
792 arg_priorities |= 1 << i;
793 }
794
795 break;
796 }
797
798#if HAVE_PCRE21
799 case 'g':
800 arg_pattern = optarg;
801 break;
802
803 case ARG_CASE_SENSITIVE:
804 if (optarg) {
805 r = parse_boolean(optarg);
806 if (r < 0)
807 return log_error_errno(r, "Bad --case-sensitive= argument \"%s\": %m", optarg)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 807, __func__, "Bad --case-sensitive= argument \"%s\": %m"
, optarg) : -abs(_e); })
;
808 arg_case_sensitive = r;
809 } else
810 arg_case_sensitive = true1;
811
812 break;
813#else
814 case 'g':
815 case ARG_CASE_SENSITIVE:
816 return log_error("Compiled without pattern matching support")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 816, __func__, "Compiled without pattern matching support"
) : -abs(_e); })
;
817#endif
818
819 case 'S':
820 r = parse_timestamp(optarg, &arg_since);
821 if (r < 0) {
822 log_error("Failed to parse timestamp: %s", optarg)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 822, __func__, "Failed to parse timestamp: %s"
, optarg) : -abs(_e); })
;
823 return -EINVAL22;
824 }
825 arg_since_set = true1;
826 break;
827
828 case 'U':
829 r = parse_timestamp(optarg, &arg_until);
830 if (r < 0) {
831 log_error("Failed to parse timestamp: %s", optarg)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 831, __func__, "Failed to parse timestamp: %s"
, optarg) : -abs(_e); })
;
832 return -EINVAL22;
833 }
834 arg_until_set = true1;
835 break;
836
837 case 't':
838 r = strv_extend(&arg_syslog_identifier, optarg);
839 if (r < 0)
840 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/journal/journalctl.c"
, 840, __func__)
;
841 break;
842
843 case 'u':
844 r = strv_extend(&arg_system_units, optarg);
845 if (r < 0)
846 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/journal/journalctl.c"
, 846, __func__)
;
847 break;
848
849 case ARG_USER_UNIT:
850 r = strv_extend(&arg_user_units, optarg);
851 if (r < 0)
852 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/journal/journalctl.c"
, 852, __func__)
;
853 break;
854
855 case 'F':
856 arg_action = ACTION_LIST_FIELDS;
857 arg_field = optarg;
858 break;
859
860 case 'N':
861 arg_action = ACTION_LIST_FIELD_NAMES;
862 break;
863
864 case ARG_NO_HOSTNAME:
865 arg_no_hostname = true1;
866 break;
867
868 case 'x':
869 arg_catalog = true1;
870 break;
871
872 case ARG_LIST_CATALOG:
873 arg_action = ACTION_LIST_CATALOG;
874 break;
875
876 case ARG_DUMP_CATALOG:
877 arg_action = ACTION_DUMP_CATALOG;
878 break;
879
880 case ARG_UPDATE_CATALOG:
881 arg_action = ACTION_UPDATE_CATALOG;
882 break;
883
884 case 'r':
885 arg_reverse = true1;
886 break;
887
888 case ARG_UTC:
889 arg_utc = true1;
890 break;
891
892 case ARG_FLUSH:
893 arg_action = ACTION_FLUSH;
894 break;
895
896 case ARG_ROTATE:
897 arg_action = ACTION_ROTATE;
898 break;
899
900 case ARG_SYNC:
901 arg_action = ACTION_SYNC;
902 break;
903
904 case ARG_OUTPUT_FIELDS: {
905 _cleanup_strv_free___attribute__((cleanup(strv_freep))) char **v = NULL((void*)0);
906
907 v = strv_split(optarg, ",");
908 if (!v)
909 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/journal/journalctl.c"
, 909, __func__)
;
910
911 if (!arg_output_fields)
912 arg_output_fields = TAKE_PTR(v)({ typeof(v) _ptr_ = (v); (v) = ((void*)0); _ptr_; });
913 else {
914 r = strv_extend_strv(&arg_output_fields, v, true1);
915 if (r < 0)
916 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/journal/journalctl.c"
, 916, __func__)
;
917 }
918 break;
919 }
920
921 case '?':
922 return -EINVAL22;
923
924 default:
925 assert_not_reached("Unhandled option")do { log_assert_failed_unreachable_realm(LOG_REALM_SYSTEMD, (
"Unhandled option"), "../src/journal/journalctl.c", 925, __PRETTY_FUNCTION__
); } while (0)
;
926 }
927
928 if (arg_follow && !arg_no_tail && !arg_since && arg_lines == ARG_LINES_DEFAULT)
929 arg_lines = 10;
930
931 if (!!arg_directory + !!arg_file + !!arg_machine + !!arg_root > 1) {
932 log_error("Please specify at most one of -D/--directory=, --file=, -M/--machine=, --root.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 932, __func__, "Please specify at most one of -D/--directory=, --file=, -M/--machine=, --root."
) : -abs(_e); })
;
933 return -EINVAL22;
934 }
935
936 if (arg_since_set && arg_until_set && arg_since > arg_until) {
937 log_error("--since= must be before --until=.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 937, __func__, "--since= must be before --until=."
) : -abs(_e); })
;
938 return -EINVAL22;
939 }
940
941 if (!!arg_cursor + !!arg_after_cursor + !!arg_since_set > 1) {
942 log_error("Please specify only one of --since=, --cursor=, and --after-cursor.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 942, __func__, "Please specify only one of --since=, --cursor=, and --after-cursor."
) : -abs(_e); })
;
943 return -EINVAL22;
944 }
945
946 if (arg_follow && arg_reverse) {
947 log_error("Please specify either --reverse= or --follow=, not both.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 947, __func__, "Please specify either --reverse= or --follow=, not both."
) : -abs(_e); })
;
948 return -EINVAL22;
949 }
950
951 if (!IN_SET(arg_action, ACTION_SHOW, ACTION_DUMP_CATALOG, ACTION_LIST_CATALOG)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){ACTION_SHOW, ACTION_DUMP_CATALOG, ACTION_LIST_CATALOG
})/sizeof(int)]; switch(arg_action) { case ACTION_SHOW: case ACTION_DUMP_CATALOG
: case ACTION_LIST_CATALOG: _found = 1; break; default: break
; } _found; })
&& optind < argc) {
952 log_error("Extraneous arguments starting with '%s'", argv[optind])({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 952, __func__, "Extraneous arguments starting with '%s'"
, argv[optind]) : -abs(_e); })
;
953 return -EINVAL22;
954 }
955
956 if ((arg_boot || arg_action == ACTION_LIST_BOOTS) && arg_merge) {
957 log_error("Using --boot or --list-boots with --merge is not supported.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 957, __func__, "Using --boot or --list-boots with --merge is not supported."
) : -abs(_e); })
;
958 return -EINVAL22;
959 }
960
961 if (!strv_isempty(arg_system_units) && arg_journal_type == SD_JOURNAL_CURRENT_USER) {
962 /* Specifying --user and --unit= at the same time makes no sense (as the former excludes the user
963 * journal, but the latter excludes the system journal, thus resulting in empty output). Let's be nice
964 * to users, and automatically turn --unit= into --user-unit= if combined with --user. */
965 r = strv_extend_strv(&arg_user_units, arg_system_units, true1);
966 if (r < 0)
967 return r;
968
969 arg_system_units = strv_free(arg_system_units);
970 }
971
972#if HAVE_PCRE21
973 if (arg_pattern) {
974 unsigned flags;
975
976 if (arg_case_sensitive >= 0)
977 flags = !arg_case_sensitive * PCRE2_CASELESS0x00000008u;
978 else {
979 _cleanup_(pcre2_match_data_freep)__attribute__((cleanup(pcre2_match_data_freep))) pcre2_match_datapcre2_match_data_8 *md = NULL((void*)0);
980 bool_Bool has_case;
981 _cleanup_(pcre2_code_freep)__attribute__((cleanup(pcre2_code_freep))) pcre2_codepcre2_code_8 *cs = NULL((void*)0);
982
983 md = pcre2_match_data_createpcre2_match_data_create_8(1, NULL((void*)0));
984 if (!md)
985 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/journal/journalctl.c"
, 985, __func__)
;
986
987 r = pattern_compile("[[:upper:]]", 0, &cs);
988 if (r < 0)
989 return r;
990
991 r = pcre2_matchpcre2_match_8(cs, (PCRE2_SPTR8) arg_pattern, PCRE2_ZERO_TERMINATED(~(size_t)0), 0, 0, md, NULL((void*)0));
992 has_case = r >= 0;
993
994 flags = !has_case * PCRE2_CASELESS0x00000008u;
995 }
996
997 log_debug("Doing case %s matching based on %s",({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 999, __func__, "Doing case %s matching based on %s"
, flags & 0x00000008u ? "insensitive" : "sensitive", arg_case_sensitive
>= 0 ? "request" : "pattern casing") : -abs(_e); })
998 flags & PCRE2_CASELESS ? "insensitive" : "sensitive",({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 999, __func__, "Doing case %s matching based on %s"
, flags & 0x00000008u ? "insensitive" : "sensitive", arg_case_sensitive
>= 0 ? "request" : "pattern casing") : -abs(_e); })
999 arg_case_sensitive >= 0 ? "request" : "pattern casing")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 999, __func__, "Doing case %s matching based on %s"
, flags & 0x00000008u ? "insensitive" : "sensitive", arg_case_sensitive
>= 0 ? "request" : "pattern casing") : -abs(_e); })
;
1000
1001 r = pattern_compile(arg_pattern, flags, &arg_compiled_pattern);
1002 if (r < 0)
1003 return r;
1004 }
1005#endif
1006
1007 return 1;
1008}
1009
1010static int generate_new_id128(void) {
1011 sd_id128_t id;
1012 int r;
1013 unsigned i;
1014
1015 r = sd_id128_randomize(&id);
1016 if (r < 0)
1017 return log_error_errno(r, "Failed to generate ID: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 1017, __func__, "Failed to generate ID: %m"
) : -abs(_e); })
;
1018
1019 printf("As string:\n"
1020 SD_ID128_FORMAT_STR"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x" "\n\n"
1021 "As UUID:\n"
1022 "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n\n"
1023 "As man:sd-id128(3) macro:\n"
1024 "#define MESSAGE_XYZ SD_ID128_MAKE(",
1025 SD_ID128_FORMAT_VAL(id)(id).bytes[0], (id).bytes[1], (id).bytes[2], (id).bytes[3], (
id).bytes[4], (id).bytes[5], (id).bytes[6], (id).bytes[7], (id
).bytes[8], (id).bytes[9], (id).bytes[10], (id).bytes[11], (id
).bytes[12], (id).bytes[13], (id).bytes[14], (id).bytes[15]
,
1026 SD_ID128_FORMAT_VAL(id)(id).bytes[0], (id).bytes[1], (id).bytes[2], (id).bytes[3], (
id).bytes[4], (id).bytes[5], (id).bytes[6], (id).bytes[7], (id
).bytes[8], (id).bytes[9], (id).bytes[10], (id).bytes[11], (id
).bytes[12], (id).bytes[13], (id).bytes[14], (id).bytes[15]
);
1027 for (i = 0; i < 16; i++)
1028 printf("%02x%s", id.bytes[i], i != 15 ? "," : "");
1029 fputs(")\n\n", stdoutstdout);
1030
1031 printf("As Python constant:\n"
1032 ">>> import uuid\n"
1033 ">>> MESSAGE_XYZ = uuid.UUID('" SD_ID128_FORMAT_STR"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x" "')\n",
1034 SD_ID128_FORMAT_VAL(id)(id).bytes[0], (id).bytes[1], (id).bytes[2], (id).bytes[3], (
id).bytes[4], (id).bytes[5], (id).bytes[6], (id).bytes[7], (id
).bytes[8], (id).bytes[9], (id).bytes[10], (id).bytes[11], (id
).bytes[12], (id).bytes[13], (id).bytes[14], (id).bytes[15]
);
1035
1036 return 0;
1037}
1038
1039static int add_matches(sd_journal *j, char **args) {
1040 char **i;
1041 bool_Bool have_term = false0;
1042
1043 assert(j)do { if ((__builtin_expect(!!(!(j)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("j"), "../src/journal/journalctl.c", 1043
, __PRETTY_FUNCTION__); } while (0)
;
1044
1045 STRV_FOREACH(i, args)for ((i) = (args); (i) && *(i); (i)++) {
1046 int r;
1047
1048 if (streq(*i, "+")(strcmp((*i),("+")) == 0)) {
1049 if (!have_term)
1050 break;
1051 r = sd_journal_add_disjunction(j);
1052 have_term = false0;
1053
1054 } else if (path_is_absolute(*i)) {
1055 _cleanup_free___attribute__((cleanup(freep))) char *p = NULL((void*)0), *t = NULL((void*)0), *t2 = NULL((void*)0), *interpreter = NULL((void*)0);
1056 struct stat st;
1057
1058 r = chase_symlinks(*i, NULL((void*)0), CHASE_TRAIL_SLASH, &p);
1059 if (r < 0)
1060 return log_error_errno(r, "Couldn't canonicalize path: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 1060, __func__, "Couldn't canonicalize path: %m"
) : -abs(_e); })
;
1061
1062 if (lstat(p, &st) < 0)
1063 return log_error_errno(errno, "Couldn't stat file: %m")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/journal/journalctl.c", 1063, __func__
, "Couldn't stat file: %m") : -abs(_e); })
;
1064
1065 if (S_ISREG(st.st_mode)((((st.st_mode)) & 0170000) == (0100000)) && (0111 & st.st_mode)) {
1066 if (executable_is_script(p, &interpreter) > 0) {
1067 _cleanup_free___attribute__((cleanup(freep))) char *comm;
1068
1069 comm = strndup(basename(p), 15);
1070 if (!comm)
1071 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/journal/journalctl.c"
, 1071, __func__)
;
1072
1073 t = strappend("_COMM=", comm);
1074 if (!t)
1075 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/journal/journalctl.c"
, 1075, __func__)
;
1076
1077 /* Append _EXE only if the interpreter is not a link.
1078 Otherwise, it might be outdated often. */
1079 if (lstat(interpreter, &st) == 0 && !S_ISLNK(st.st_mode)((((st.st_mode)) & 0170000) == (0120000))) {
1080 t2 = strappend("_EXE=", interpreter);
1081 if (!t2)
1082 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/journal/journalctl.c"
, 1082, __func__)
;
1083 }
1084 } else {
1085 t = strappend("_EXE=", p);
1086 if (!t)
1087 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/journal/journalctl.c"
, 1087, __func__)
;
1088 }
1089
1090 r = sd_journal_add_match(j, t, 0);
1091
1092 if (r >=0 && t2)
1093 r = sd_journal_add_match(j, t2, 0);
1094
1095 } else if (S_ISCHR(st.st_mode)((((st.st_mode)) & 0170000) == (0020000)) || S_ISBLK(st.st_mode)((((st.st_mode)) & 0170000) == (0060000))) {
1096 r = add_matches_for_device(j, p);
1097 if (r < 0)
1098 return r;
1099 } else {
1100 log_error("File is neither a device node, nor regular file, nor executable: %s", *i)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 1100, __func__, "File is neither a device node, nor regular file, nor executable: %s"
, *i) : -abs(_e); })
;
1101 return -EINVAL22;
1102 }
1103
1104 have_term = true1;
1105 } else {
1106 r = sd_journal_add_match(j, *i, 0);
1107 have_term = true1;
1108 }
1109
1110 if (r < 0)
1111 return log_error_errno(r, "Failed to add match '%s': %m", *i)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 1111, __func__, "Failed to add match '%s': %m"
, *i) : -abs(_e); })
;
1112 }
1113
1114 if (!strv_isempty(args) && !have_term) {
1115 log_error("\"+\" can only be used between terms")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 1115, __func__, "\"+\" can only be used between terms"
) : -abs(_e); })
;
1116 return -EINVAL22;
1117 }
1118
1119 return 0;
1120}
1121
1122static void boot_id_free_all(BootId *l) {
1123
1124 while (l) {
13
Loop condition is true. Entering loop body
21
Loop condition is true. Entering loop body
1125 BootId *i = l;
1126 LIST_REMOVE(boot_list, l, i)do { typeof(*(l)) **_head = &(l), *_item = (i); do { if (
(__builtin_expect(!!(!(_item)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD
, ("_item"), "../src/journal/journalctl.c", 1126, __PRETTY_FUNCTION__
); } while (0); if (_item->boot_list_next) _item->boot_list_next
->boot_list_prev = _item->boot_list_prev; if (_item->
boot_list_prev) _item->boot_list_prev->boot_list_next =
_item->boot_list_next; else { do { if ((__builtin_expect(
!!(!(*_head == _item)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD
, ("*_head == _item"), "../src/journal/journalctl.c", 1126, __PRETTY_FUNCTION__
); } while (0); *_head = _item->boot_list_next; } _item->
boot_list_next = _item->boot_list_prev = ((void*)0); } while
(0)
;
14
Taking false branch
15
Loop condition is false. Exiting loop
16
Taking false branch
17
Assuming field 'boot_list_prev' is non-null
18
Taking true branch
19
Loop condition is false. Exiting loop
22
Taking false branch
23
Loop condition is false. Exiting loop
24
Use of memory after it is freed
1127 free(i);
20
Memory is released
1128 }
1129}
1130
1131static int discover_next_boot(sd_journal *j,
1132 sd_id128_t previous_boot_id,
1133 bool_Bool advance_older,
1134 BootId **ret) {
1135
1136 _cleanup_free___attribute__((cleanup(freep))) BootId *next_boot = NULL((void*)0);
1137 char match[9+32+1] = "_BOOT_ID=";
1138 sd_id128_t boot_id;
1139 int r;
1140
1141 assert(j)do { if ((__builtin_expect(!!(!(j)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("j"), "../src/journal/journalctl.c", 1141
, __PRETTY_FUNCTION__); } while (0)
;
1142 assert(ret)do { if ((__builtin_expect(!!(!(ret)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("ret"), "../src/journal/journalctl.c", 1142
, __PRETTY_FUNCTION__); } while (0)
;
1143
1144 /* We expect the journal to be on the last position of a boot
1145 * (in relation to the direction we are going), so that the next
1146 * invocation of sd_journal_next/previous will be from a different
1147 * boot. We then collect any information we desire and then jump
1148 * to the last location of the new boot by using a _BOOT_ID match
1149 * coming from the other journal direction. */
1150
1151 /* Make sure we aren't restricted by any _BOOT_ID matches, so that
1152 * we can actually advance to a *different* boot. */
1153 sd_journal_flush_matches(j);
1154
1155 do {
1156 if (advance_older)
1157 r = sd_journal_previous(j);
1158 else
1159 r = sd_journal_next(j);
1160 if (r < 0)
1161 return r;
1162 else if (r == 0)
1163 return 0; /* End of journal, yay. */
1164
1165 r = sd_journal_get_monotonic_usec(j, NULL((void*)0), &boot_id);
1166 if (r < 0)
1167 return r;
1168
1169 /* We iterate through this in a loop, until the boot ID differs from the previous one. Note that
1170 * normally, this will only require a single iteration, as we seeked to the last entry of the previous
1171 * boot entry already. However, it might happen that the per-journal-field entry arrays are less
1172 * complete than the main entry array, and hence might reference an entry that's not actually the last
1173 * one of the boot ID as last one. Let's hence use the per-field array is initial seek position to
1174 * speed things up, but let's not trust that it is complete, and hence, manually advance as
1175 * necessary. */
1176
1177 } while (sd_id128_equal(boot_id, previous_boot_id));
1178
1179 next_boot = new0(BootId, 1)((BootId*) calloc((1), sizeof(BootId)));
1180 if (!next_boot)
1181 return -ENOMEM12;
1182
1183 next_boot->id = boot_id;
1184
1185 r = sd_journal_get_realtime_usec(j, &next_boot->first);
1186 if (r < 0)
1187 return r;
1188
1189 /* Now seek to the last occurrence of this boot ID. */
1190 sd_id128_to_string(next_boot->id, match + 9);
1191 r = sd_journal_add_match(j, match, sizeof(match) - 1);
1192 if (r < 0)
1193 return r;
1194
1195 if (advance_older)
1196 r = sd_journal_seek_head(j);
1197 else
1198 r = sd_journal_seek_tail(j);
1199 if (r < 0)
1200 return r;
1201
1202 if (advance_older)
1203 r = sd_journal_next(j);
1204 else
1205 r = sd_journal_previous(j);
1206 if (r < 0)
1207 return r;
1208 else if (r == 0) {
1209 log_debug("Whoopsie! We found a boot ID but can't read its last entry.")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 1209, __func__, "Whoopsie! We found a boot ID but can't read its last entry."
) : -abs(_e); })
;
1210 return -ENODATA61; /* This shouldn't happen. We just came from this very boot ID. */
1211 }
1212
1213 r = sd_journal_get_realtime_usec(j, &next_boot->last);
1214 if (r < 0)
1215 return r;
1216
1217 *ret = TAKE_PTR(next_boot)({ typeof(next_boot) _ptr_ = (next_boot); (next_boot) = ((void
*)0); _ptr_; })
;
1218
1219 return 0;
1220}
1221
1222static int get_boots(
1223 sd_journal *j,
1224 BootId **boots,
1225 sd_id128_t *boot_id,
1226 int offset) {
1227
1228 bool_Bool skip_once;
1229 int r, count = 0;
1230 BootId *head = NULL((void*)0), *tail = NULL((void*)0), *id;
1231 const bool_Bool advance_older = boot_id && offset <= 0;
1232 sd_id128_t previous_boot_id;
1233
1234 assert(j)do { if ((__builtin_expect(!!(!(j)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("j"), "../src/journal/journalctl.c", 1234
, __PRETTY_FUNCTION__); } while (0)
;
1235
1236 /* Adjust for the asymmetry that offset 0 is
1237 * the last (and current) boot, while 1 is considered the
1238 * (chronological) first boot in the journal. */
1239 skip_once = boot_id && sd_id128_is_null(*boot_id) && offset <= 0;
1240
1241 /* Advance to the earliest/latest occurrence of our reference
1242 * boot ID (taking our lookup direction into account), so that
1243 * discover_next_boot() can do its job.
1244 * If no reference is given, the journal head/tail will do,
1245 * they're "virtual" boots after all. */
1246 if (boot_id && !sd_id128_is_null(*boot_id)) {
1247 char match[9+32+1] = "_BOOT_ID=";
1248
1249 sd_journal_flush_matches(j);
1250
1251 sd_id128_to_string(*boot_id, match + 9);
1252 r = sd_journal_add_match(j, match, sizeof(match) - 1);
1253 if (r < 0)
1254 return r;
1255
1256 if (advance_older)
1257 r = sd_journal_seek_head(j); /* seek to oldest */
1258 else
1259 r = sd_journal_seek_tail(j); /* seek to newest */
1260 if (r < 0)
1261 return r;
1262
1263 if (advance_older)
1264 r = sd_journal_next(j); /* read the oldest entry */
1265 else
1266 r = sd_journal_previous(j); /* read the most recently added entry */
1267 if (r < 0)
1268 return r;
1269 else if (r == 0)
1270 goto finish;
1271 else if (offset == 0) {
1272 count = 1;
1273 goto finish;
1274 }
1275
1276 /* At this point the read pointer is positioned at the oldest/newest occurence of the reference boot
1277 * ID. After flushing the matches, one more invocation of _previous()/_next() will hence place us at
1278 * the following entry, which must then have an older/newer boot ID */
1279 } else {
1280
1281 if (advance_older)
1282 r = sd_journal_seek_tail(j); /* seek to newest */
1283 else
1284 r = sd_journal_seek_head(j); /* seek to oldest */
1285 if (r < 0)
1286 return r;
1287
1288 /* No sd_journal_next()/_previous() here.
1289 *
1290 * At this point the read pointer is positioned after the newest/before the oldest entry in the whole
1291 * journal. The next invocation of _previous()/_next() will hence position us at the newest/oldest
1292 * entry we have. */
1293 }
1294
1295 previous_boot_id = SD_ID128_NULL((const sd_id128_t) { .qwords = { 0, 0 }});
1296 for (;;) {
1297 _cleanup_free___attribute__((cleanup(freep))) BootId *current = NULL((void*)0);
1298
1299 r = discover_next_boot(j, previous_boot_id, advance_older, &current);
1300 if (r < 0) {
1301 boot_id_free_all(head);
1302 return r;
1303 }
1304
1305 if (!current)
1306 break;
1307
1308 previous_boot_id = current->id;
1309
1310 if (boot_id) {
1311 if (!skip_once)
1312 offset += advance_older ? 1 : -1;
1313 skip_once = false0;
1314
1315 if (offset == 0) {
1316 count = 1;
1317 *boot_id = current->id;
1318 break;
1319 }
1320 } else {
1321 LIST_FOREACH(boot_list, id, head)for ((id) = (head); (id); (id) = (id)->boot_list_next) {
1322 if (sd_id128_equal(id->id, current->id)) {
1323 /* boot id already stored, something wrong with the journal files */
1324 /* exiting as otherwise this problem would cause forever loop */
1325 goto finish;
1326 }
1327 }
1328 LIST_INSERT_AFTER(boot_list, head, tail, current)do { typeof(*(head)) **_head = &(head), *_a = (tail), *_b
= (current); do { if ((__builtin_expect(!!(!(_b)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("_b"), "../src/journal/journalctl.c", 1328
, __PRETTY_FUNCTION__); } while (0); if (!_a) { if ((_b->boot_list_next
= *_head)) _b->boot_list_next->boot_list_prev = _b; _b
->boot_list_prev = ((void*)0); *_head = _b; } else { if ((
_b->boot_list_next = _a->boot_list_next)) _b->boot_list_next
->boot_list_prev = _b; _b->boot_list_prev = _a; _a->
boot_list_next = _b; } } while (0)
;
1329 tail = TAKE_PTR(current)({ typeof(current) _ptr_ = (current); (current) = ((void*)0);
_ptr_; })
;
1330 count++;
1331 }
1332 }
1333
1334finish:
1335 if (boots)
1336 *boots = head;
1337
1338 sd_journal_flush_matches(j);
1339
1340 return count;
1341}
1342
1343static int list_boots(sd_journal *j) {
1344 int w, i, count;
1345 BootId *id, *all_ids;
1346
1347 assert(j)do { if ((__builtin_expect(!!(!(j)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("j"), "../src/journal/journalctl.c", 1347
, __PRETTY_FUNCTION__); } while (0)
;
1
Assuming 'j' is non-null
2
Taking false branch
3
Loop condition is false. Exiting loop
1348
1349 count = get_boots(j, &all_ids, NULL((void*)0), 0);
1350 if (count < 0)
4
Assuming 'count' is >= 0
5
Taking false branch
1351 return log_error_errno(count, "Failed to determine boots: %m")({ int _level = ((3)), _e = ((count)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 1351, __func__, "Failed to determine boots: %m"
) : -abs(_e); })
;
1352 if (count == 0)
6
Assuming 'count' is not equal to 0
7
Taking false branch
1353 return count;
1354
1355 (void) pager_open(arg_no_pager, arg_pager_end);
1356
1357 /* numbers are one less, but we need an extra char for the sign */
1358 w = DECIMAL_STR_WIDTH(count - 1)({ typeof(count - 1) _x_ = (count - 1); unsigned ans = 1; while
((_x_ /= 10) != 0) ans++; ans; })
+ 1;
8
Assuming the condition is false
9
Loop condition is false. Execution continues on line 1358
1359
1360 i = 0;
1361 LIST_FOREACH(boot_list, id, all_ids)for ((id) = (all_ids); (id); (id) = (id)->boot_list_next) {
10
Loop condition is true. Entering loop body
11
Loop condition is false. Execution continues on line 1372
1362 char a[FORMAT_TIMESTAMP_MAX(3+1+10+1+8+1+6+1+6+1)], b[FORMAT_TIMESTAMP_MAX(3+1+10+1+8+1+6+1+6+1)];
1363
1364 printf("% *i " SD_ID128_FORMAT_STR"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x" " %s—%s\n",
1365 w, i - count + 1,
1366 SD_ID128_FORMAT_VAL(id->id)(id->id).bytes[0], (id->id).bytes[1], (id->id).bytes
[2], (id->id).bytes[3], (id->id).bytes[4], (id->id).
bytes[5], (id->id).bytes[6], (id->id).bytes[7], (id->
id).bytes[8], (id->id).bytes[9], (id->id).bytes[10], (id
->id).bytes[11], (id->id).bytes[12], (id->id).bytes[
13], (id->id).bytes[14], (id->id).bytes[15]
,
1367 format_timestamp_maybe_utc(a, sizeof(a), id->first),
1368 format_timestamp_maybe_utc(b, sizeof(b), id->last));
1369 i++;
1370 }
1371
1372 boot_id_free_all(all_ids);
12
Calling 'boot_id_free_all'
1373
1374 return 0;
1375}
1376
1377static int add_boot(sd_journal *j) {
1378 char match[9+32+1] = "_BOOT_ID=";
1379 sd_id128_t boot_id;
1380 int r;
1381
1382 assert(j)do { if ((__builtin_expect(!!(!(j)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("j"), "../src/journal/journalctl.c", 1382
, __PRETTY_FUNCTION__); } while (0)
;
1383
1384 if (!arg_boot)
1385 return 0;
1386
1387 /* Take a shortcut and use the current boot_id, which we can do very quickly.
1388 * We can do this only when we logs are coming from the current machine,
1389 * so take the slow path if log location is specified. */
1390 if (arg_boot_offset == 0 && sd_id128_is_null(arg_boot_id) &&
1391 !arg_directory && !arg_file && !arg_root)
1392
1393 return add_match_this_boot(j, arg_machine);
1394
1395 boot_id = arg_boot_id;
1396 r = get_boots(j, NULL((void*)0), &boot_id, arg_boot_offset);
1397 assert(r <= 1)do { if ((__builtin_expect(!!(!(r <= 1)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("r <= 1"), "../src/journal/journalctl.c"
, 1397, __PRETTY_FUNCTION__); } while (0)
;
1398 if (r <= 0) {
1399 const char *reason = (r == 0) ? "No such boot ID in journal" : strerror(-r);
1400
1401 if (sd_id128_is_null(arg_boot_id))
1402 log_error("Data from the specified boot (%+i) is not available: %s",({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 1403, __func__, "Data from the specified boot (%+i) is not available: %s"
, arg_boot_offset, reason) : -abs(_e); })
1403 arg_boot_offset, reason)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 1403, __func__, "Data from the specified boot (%+i) is not available: %s"
, arg_boot_offset, reason) : -abs(_e); })
;
1404 else
1405 log_error("Data from the specified boot ("SD_ID128_FORMAT_STR") is not available: %s",({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 1406, __func__, "Data from the specified boot ("
"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
") is not available: %s", (arg_boot_id).bytes[0], (arg_boot_id
).bytes[1], (arg_boot_id).bytes[2], (arg_boot_id).bytes[3], (
arg_boot_id).bytes[4], (arg_boot_id).bytes[5], (arg_boot_id).
bytes[6], (arg_boot_id).bytes[7], (arg_boot_id).bytes[8], (arg_boot_id
).bytes[9], (arg_boot_id).bytes[10], (arg_boot_id).bytes[11],
(arg_boot_id).bytes[12], (arg_boot_id).bytes[13], (arg_boot_id
).bytes[14], (arg_boot_id).bytes[15], reason) : -abs(_e); })
1406 SD_ID128_FORMAT_VAL(arg_boot_id), reason)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 1406, __func__, "Data from the specified boot ("
"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
") is not available: %s", (arg_boot_id).bytes[0], (arg_boot_id
).bytes[1], (arg_boot_id).bytes[2], (arg_boot_id).bytes[3], (
arg_boot_id).bytes[4], (arg_boot_id).bytes[5], (arg_boot_id).
bytes[6], (arg_boot_id).bytes[7], (arg_boot_id).bytes[8], (arg_boot_id
).bytes[9], (arg_boot_id).bytes[10], (arg_boot_id).bytes[11],
(arg_boot_id).bytes[12], (arg_boot_id).bytes[13], (arg_boot_id
).bytes[14], (arg_boot_id).bytes[15], reason) : -abs(_e); })
;
1407
1408 return r == 0 ? -ENODATA61 : r;
1409 }
1410
1411 sd_id128_to_string(boot_id, match + 9);
1412
1413 r = sd_journal_add_match(j, match, sizeof(match) - 1);
1414 if (r < 0)
1415 return log_error_errno(r, "Failed to add match: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 1415, __func__, "Failed to add match: %m"
) : -abs(_e); })
;
1416
1417 r = sd_journal_add_conjunction(j);
1418 if (r < 0)
1419 return log_error_errno(r, "Failed to add conjunction: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 1419, __func__, "Failed to add conjunction: %m"
) : -abs(_e); })
;
1420
1421 return 0;
1422}
1423
1424static int add_dmesg(sd_journal *j) {
1425 int r;
1426 assert(j)do { if ((__builtin_expect(!!(!(j)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("j"), "../src/journal/journalctl.c", 1426
, __PRETTY_FUNCTION__); } while (0)
;
1427
1428 if (!arg_dmesg)
1429 return 0;
1430
1431 r = sd_journal_add_match(j, "_TRANSPORT=kernel",
1432 STRLEN("_TRANSPORT=kernel")(sizeof("""_TRANSPORT=kernel""") - 1));
1433 if (r < 0)
1434 return log_error_errno(r, "Failed to add match: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 1434, __func__, "Failed to add match: %m"
) : -abs(_e); })
;
1435
1436 r = sd_journal_add_conjunction(j);
1437 if (r < 0)
1438 return log_error_errno(r, "Failed to add conjunction: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 1438, __func__, "Failed to add conjunction: %m"
) : -abs(_e); })
;
1439
1440 return 0;
1441}
1442
1443static int get_possible_units(
1444 sd_journal *j,
1445 const char *fields,
1446 char **patterns,
1447 Set **units) {
1448
1449 _cleanup_set_free_free___attribute__((cleanup(set_free_freep))) Set *found;
1450 const char *field;
1451 int r;
1452
1453 found = set_new(&string_hash_ops)internal_set_new(&string_hash_ops );
1454 if (!found)
1455 return -ENOMEM12;
1456
1457 NULSTR_FOREACH(field, fields)for ((field) = (fields); (field) && *(field); (field)
= strchr((field), 0)+1)
{
1458 const void *data;
1459 size_t size;
1460
1461 r = sd_journal_query_unique(j, field);
1462 if (r < 0)
1463 return r;
1464
1465 SD_JOURNAL_FOREACH_UNIQUE(j, data, size)for (sd_journal_restart_unique(j); sd_journal_enumerate_unique
((j), &(data), &(size)) > 0; )
{
1466 char **pattern, *eq;
1467 size_t prefix;
1468 _cleanup_free___attribute__((cleanup(freep))) char *u = NULL((void*)0);
1469
1470 eq = memchr(data, '=', size);
1471 if (eq)
1472 prefix = eq - (char*) data + 1;
1473 else
1474 prefix = 0;
1475
1476 u = strndup((char*) data + prefix, size - prefix);
1477 if (!u)
1478 return -ENOMEM12;
1479
1480 STRV_FOREACH(pattern, patterns)for ((pattern) = (patterns); (pattern) && *(pattern);
(pattern)++)
1481 if (fnmatch(*pattern, u, FNM_NOESCAPE(1 << 1)) == 0) {
1482 log_debug("Matched %s with pattern %s=%s", u, field, *pattern)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 1482, __func__, "Matched %s with pattern %s=%s"
, u, field, *pattern) : -abs(_e); })
;
1483
1484 r = set_consume(found, u);
1485 u = NULL((void*)0);
1486 if (r < 0 && r != -EEXIST17)
1487 return r;
1488
1489 break;
1490 }
1491 }
1492 }
1493
1494 *units = TAKE_PTR(found)({ typeof(found) _ptr_ = (found); (found) = ((void*)0); _ptr_
; })
;
1495
1496 return 0;
1497}
1498
1499/* This list is supposed to return the superset of unit names
1500 * possibly matched by rules added with add_matches_for_unit... */
1501#define SYSTEM_UNITS"_SYSTEMD_UNIT\0" "COREDUMP_UNIT\0" "UNIT\0" "OBJECT_SYSTEMD_UNIT\0"
"_SYSTEMD_SLICE\0"
\
1502 "_SYSTEMD_UNIT\0" \
1503 "COREDUMP_UNIT\0" \
1504 "UNIT\0" \
1505 "OBJECT_SYSTEMD_UNIT\0" \
1506 "_SYSTEMD_SLICE\0"
1507
1508/* ... and add_matches_for_user_unit */
1509#define USER_UNITS"_SYSTEMD_USER_UNIT\0" "USER_UNIT\0" "COREDUMP_USER_UNIT\0" "OBJECT_SYSTEMD_USER_UNIT\0" \
1510 "_SYSTEMD_USER_UNIT\0" \
1511 "USER_UNIT\0" \
1512 "COREDUMP_USER_UNIT\0" \
1513 "OBJECT_SYSTEMD_USER_UNIT\0"
1514
1515static int add_units(sd_journal *j) {
1516 _cleanup_strv_free___attribute__((cleanup(strv_freep))) char **patterns = NULL((void*)0);
1517 int r, count = 0;
1518 char **i;
1519
1520 assert(j)do { if ((__builtin_expect(!!(!(j)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("j"), "../src/journal/journalctl.c", 1520
, __PRETTY_FUNCTION__); } while (0)
;
1521
1522 STRV_FOREACH(i, arg_system_units)for ((i) = (arg_system_units); (i) && *(i); (i)++) {
1523 _cleanup_free___attribute__((cleanup(freep))) char *u = NULL((void*)0);
1524
1525 r = unit_name_mangle(*i, UNIT_NAME_MANGLE_GLOB | (arg_quiet ? 0 : UNIT_NAME_MANGLE_WARN), &u);
1526 if (r < 0)
1527 return r;
1528
1529 if (string_is_glob(u)) {
1530 r = strv_push(&patterns, u);
1531 if (r < 0)
1532 return r;
1533 u = NULL((void*)0);
1534 } else {
1535 r = add_matches_for_unit(j, u);
1536 if (r < 0)
1537 return r;
1538 r = sd_journal_add_disjunction(j);
1539 if (r < 0)
1540 return r;
1541 count++;
1542 }
1543 }
1544
1545 if (!strv_isempty(patterns)) {
1546 _cleanup_set_free_free___attribute__((cleanup(set_free_freep))) Set *units = NULL((void*)0);
1547 Iterator it;
1548 char *u;
1549
1550 r = get_possible_units(j, SYSTEM_UNITS"_SYSTEMD_UNIT\0" "COREDUMP_UNIT\0" "UNIT\0" "OBJECT_SYSTEMD_UNIT\0"
"_SYSTEMD_SLICE\0"
, patterns, &units);
1551 if (r < 0)
1552 return r;
1553
1554 SET_FOREACH(u, units, it)for ((it) = ((Iterator) { .idx = ((2147483647 *2U +1U) - 1), .
next_key = ((void*)0) }); set_iterate((units), &(it), (void
**)&(u)); )
{
1555 r = add_matches_for_unit(j, u);
1556 if (r < 0)
1557 return r;
1558 r = sd_journal_add_disjunction(j);
1559 if (r < 0)
1560 return r;
1561 count++;
1562 }
1563 }
1564
1565 patterns = strv_free(patterns);
1566
1567 STRV_FOREACH(i, arg_user_units)for ((i) = (arg_user_units); (i) && *(i); (i)++) {
1568 _cleanup_free___attribute__((cleanup(freep))) char *u = NULL((void*)0);
1569
1570 r = unit_name_mangle(*i, UNIT_NAME_MANGLE_GLOB | (arg_quiet ? 0 : UNIT_NAME_MANGLE_WARN), &u);
1571 if (r < 0)
1572 return r;
1573
1574 if (string_is_glob(u)) {
1575 r = strv_push(&patterns, u);
1576 if (r < 0)
1577 return r;
1578 u = NULL((void*)0);
1579 } else {
1580 r = add_matches_for_user_unit(j, u, getuid());
1581 if (r < 0)
1582 return r;
1583 r = sd_journal_add_disjunction(j);
1584 if (r < 0)
1585 return r;
1586 count++;
1587 }
1588 }
1589
1590 if (!strv_isempty(patterns)) {
1591 _cleanup_set_free_free___attribute__((cleanup(set_free_freep))) Set *units = NULL((void*)0);
1592 Iterator it;
1593 char *u;
1594
1595 r = get_possible_units(j, USER_UNITS"_SYSTEMD_USER_UNIT\0" "USER_UNIT\0" "COREDUMP_USER_UNIT\0" "OBJECT_SYSTEMD_USER_UNIT\0", patterns, &units);
1596 if (r < 0)
1597 return r;
1598
1599 SET_FOREACH(u, units, it)for ((it) = ((Iterator) { .idx = ((2147483647 *2U +1U) - 1), .
next_key = ((void*)0) }); set_iterate((units), &(it), (void
**)&(u)); )
{
1600 r = add_matches_for_user_unit(j, u, getuid());
1601 if (r < 0)
1602 return r;
1603 r = sd_journal_add_disjunction(j);
1604 if (r < 0)
1605 return r;
1606 count++;
1607 }
1608 }
1609
1610 /* Complain if the user request matches but nothing whatsoever was
1611 * found, since otherwise everything would be matched. */
1612 if (!(strv_isempty(arg_system_units) && strv_isempty(arg_user_units)) && count == 0)
1613 return -ENODATA61;
1614
1615 r = sd_journal_add_conjunction(j);
1616 if (r < 0)
1617 return r;
1618
1619 return 0;
1620}
1621
1622static int add_priorities(sd_journal *j) {
1623 char match[] = "PRIORITY=0";
1624 int i, r;
1625 assert(j)do { if ((__builtin_expect(!!(!(j)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("j"), "../src/journal/journalctl.c", 1625
, __PRETTY_FUNCTION__); } while (0)
;
1626
1627 if (arg_priorities == 0xFF)
1628 return 0;
1629
1630 for (i = LOG_EMERG0; i <= LOG_DEBUG7; i++)
1631 if (arg_priorities & (1 << i)) {
1632 match[sizeof(match)-2] = '0' + i;
1633
1634 r = sd_journal_add_match(j, match, strlen(match));
1635 if (r < 0)
1636 return log_error_errno(r, "Failed to add match: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 1636, __func__, "Failed to add match: %m"
) : -abs(_e); })
;
1637 }
1638
1639 r = sd_journal_add_conjunction(j);
1640 if (r < 0)
1641 return log_error_errno(r, "Failed to add conjunction: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 1641, __func__, "Failed to add conjunction: %m"
) : -abs(_e); })
;
1642
1643 return 0;
1644}
1645
1646static int add_syslog_identifier(sd_journal *j) {
1647 int r;
1648 char **i;
1649
1650 assert(j)do { if ((__builtin_expect(!!(!(j)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("j"), "../src/journal/journalctl.c", 1650
, __PRETTY_FUNCTION__); } while (0)
;
1651
1652 STRV_FOREACH(i, arg_syslog_identifier)for ((i) = (arg_syslog_identifier); (i) && *(i); (i)++
)
{
1653 char *u;
1654
1655 u = strjoina("SYSLOG_IDENTIFIER=", *i)({ const char *_appendees_[] = { "SYSLOG_IDENTIFIER=", *i }; char
*_d_, *_p_; size_t _len_ = 0; size_t _i_; for (_i_ = 0; _i_ <
__extension__ (__builtin_choose_expr( !__builtin_types_compatible_p
(typeof(_appendees_), typeof(&*(_appendees_))), sizeof(_appendees_
)/sizeof((_appendees_)[0]), ((void)0))) && _appendees_
[_i_]; _i_++) _len_ += strlen(_appendees_[_i_]); _p_ = _d_ = __builtin_alloca
(_len_ + 1); for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr
( !__builtin_types_compatible_p(typeof(_appendees_), typeof(&
*(_appendees_))), sizeof(_appendees_)/sizeof((_appendees_)[0]
), ((void)0))) && _appendees_[_i_]; _i_++) _p_ = stpcpy
(_p_, _appendees_[_i_]); *_p_ = 0; _d_; })
;
1656 r = sd_journal_add_match(j, u, 0);
1657 if (r < 0)
1658 return r;
1659 r = sd_journal_add_disjunction(j);
1660 if (r < 0)
1661 return r;
1662 }
1663
1664 r = sd_journal_add_conjunction(j);
1665 if (r < 0)
1666 return r;
1667
1668 return 0;
1669}
1670
1671static int setup_keys(void) {
1672#if HAVE_GCRYPT1
1673 size_t mpk_size, seed_size, state_size, i;
1674 uint8_t *mpk, *seed, *state;
1675 int fd = -1, r;
1676 sd_id128_t machine, boot;
1677 char *p = NULL((void*)0), *k = NULL((void*)0);
1678 struct FSSHeader h;
1679 uint64_t n;
1680 struct stat st;
1681
1682 r = stat("/var/log/journal", &st);
1683 if (r < 0 && !IN_SET(errno, ENOENT, ENOTDIR)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){2, 20})/sizeof(int)]; switch((*__errno_location
())) { case 2: case 20: _found = 1; break; default: break; }
_found; })
)
1684 return log_error_errno(errno, "stat(\"%s\") failed: %m", "/var/log/journal")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/journal/journalctl.c", 1684, __func__
, "stat(\"%s\") failed: %m", "/var/log/journal") : -abs(_e); }
)
;
1685
1686 if (r < 0 || !S_ISDIR(st.st_mode)((((st.st_mode)) & 0170000) == (0040000))) {
1687 log_error("%s is not a directory, must be using persistent logging for FSS.",({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 1688, __func__, "%s is not a directory, must be using persistent logging for FSS."
, "/var/log/journal") : -abs(_e); })
1688 "/var/log/journal")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 1688, __func__, "%s is not a directory, must be using persistent logging for FSS."
, "/var/log/journal") : -abs(_e); })
;
1689 return r < 0 ? -errno(*__errno_location ()) : -ENOTDIR20;
1690 }
1691
1692 r = sd_id128_get_machine(&machine);
1693 if (r < 0)
1694 return log_error_errno(r, "Failed to get machine ID: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 1694, __func__, "Failed to get machine ID: %m"
) : -abs(_e); })
;
1695
1696 r = sd_id128_get_boot(&boot);
1697 if (r < 0)
1698 return log_error_errno(r, "Failed to get boot ID: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 1698, __func__, "Failed to get boot ID: %m"
) : -abs(_e); })
;
1699
1700 if (asprintf(&p, "/var/log/journal/" SD_ID128_FORMAT_STR"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x" "/fss",
1701 SD_ID128_FORMAT_VAL(machine)(machine).bytes[0], (machine).bytes[1], (machine).bytes[2], (
machine).bytes[3], (machine).bytes[4], (machine).bytes[5], (machine
).bytes[6], (machine).bytes[7], (machine).bytes[8], (machine)
.bytes[9], (machine).bytes[10], (machine).bytes[11], (machine
).bytes[12], (machine).bytes[13], (machine).bytes[14], (machine
).bytes[15]
) < 0)
1702 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/journal/journalctl.c"
, 1702, __func__)
;
1703
1704 if (arg_force) {
1705 r = unlink(p);
1706 if (r < 0 && errno(*__errno_location ()) != ENOENT2) {
1707 r = log_error_errno(errno, "unlink(\"%s\") failed: %m", p)({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/journal/journalctl.c", 1707, __func__
, "unlink(\"%s\") failed: %m", p) : -abs(_e); })
;
1708 goto finish;
1709 }
1710 } else if (access(p, F_OK0) >= 0) {
1711 log_error("Sealing key file %s exists already. Use --force to recreate.", p)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 1711, __func__, "Sealing key file %s exists already. Use --force to recreate."
, p) : -abs(_e); })
;
1712 r = -EEXIST17;
1713 goto finish;
1714 }
1715
1716 if (asprintf(&k, "/var/log/journal/" SD_ID128_FORMAT_STR"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x" "/fss.tmp.XXXXXX",
1717 SD_ID128_FORMAT_VAL(machine)(machine).bytes[0], (machine).bytes[1], (machine).bytes[2], (
machine).bytes[3], (machine).bytes[4], (machine).bytes[5], (machine
).bytes[6], (machine).bytes[7], (machine).bytes[8], (machine)
.bytes[9], (machine).bytes[10], (machine).bytes[11], (machine
).bytes[12], (machine).bytes[13], (machine).bytes[14], (machine
).bytes[15]
) < 0) {
1718 r = log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/journal/journalctl.c"
, 1718, __func__)
;
1719 goto finish;
1720 }
1721
1722 mpk_size = FSPRG_mskinbytes(FSPRG_RECOMMENDED_SECPAR1536);
1723 mpk = alloca(mpk_size)__builtin_alloca (mpk_size);
1724
1725 seed_size = FSPRG_RECOMMENDED_SEEDLEN(96/8);
1726 seed = alloca(seed_size)__builtin_alloca (seed_size);
1727
1728 state_size = FSPRG_stateinbytes(FSPRG_RECOMMENDED_SECPAR1536);
1729 state = alloca(state_size)__builtin_alloca (state_size);
1730
1731 fd = open("/dev/random", O_RDONLY00|O_CLOEXEC02000000|O_NOCTTY0400);
1732 if (fd < 0) {
1733 r = log_error_errno(errno, "Failed to open /dev/random: %m")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/journal/journalctl.c", 1733, __func__
, "Failed to open /dev/random: %m") : -abs(_e); })
;
1734 goto finish;
1735 }
1736
1737 log_info("Generating seed...")({ int _level = (((6))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 1737, __func__, "Generating seed..."
) : -abs(_e); })
;
1738 r = loop_read_exact(fd, seed, seed_size, true1);
1739 if (r < 0) {
1740 log_error_errno(r, "Failed to read random seed: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 1740, __func__, "Failed to read random seed: %m"
) : -abs(_e); })
;
1741 goto finish;
1742 }
1743
1744 log_info("Generating key pair...")({ int _level = (((6))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 1744, __func__, "Generating key pair..."
) : -abs(_e); })
;
1745 FSPRG_GenMK(NULL((void*)0), mpk, seed, seed_size, FSPRG_RECOMMENDED_SECPAR1536);
1746
1747 log_info("Generating sealing key...")({ int _level = (((6))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 1747, __func__, "Generating sealing key..."
) : -abs(_e); })
;
1748 FSPRG_GenState0(state, mpk, seed, seed_size);
1749
1750 assert(arg_interval > 0)do { if ((__builtin_expect(!!(!(arg_interval > 0)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("arg_interval > 0"), "../src/journal/journalctl.c"
, 1750, __PRETTY_FUNCTION__); } while (0)
;
1751
1752 n = now(CLOCK_REALTIME0);
1753 n /= arg_interval;
1754
1755 safe_close(fd);
1756 fd = mkostemp_safe(k);
1757 if (fd < 0) {
1758 r = log_error_errno(fd, "Failed to open %s: %m", k)({ int _level = ((3)), _e = ((fd)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 1758, __func__, "Failed to open %s: %m"
, k) : -abs(_e); })
;
1759 goto finish;
1760 }
1761
1762 /* Enable secure remove, exclusion from dump, synchronous
1763 * writing and in-place updating */
1764 r = chattr_fd(fd, FS_SECRM_FL0x00000001|FS_NODUMP_FL0x00000040|FS_SYNC_FL0x00000008|FS_NOCOW_FL0x00800000, FS_SECRM_FL0x00000001|FS_NODUMP_FL0x00000040|FS_SYNC_FL0x00000008|FS_NOCOW_FL0x00800000);
1765 if (r < 0)
1766 log_warning_errno(r, "Failed to set file attributes: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 1766, __func__, "Failed to set file attributes: %m"
) : -abs(_e); })
;
1767
1768 zero(h)(({ size_t _l_ = (sizeof(h)); void *_x_ = (&(h)); _l_ == 0
? _x_ : memset(_x_, 0, _l_); }))
;
1769 memcpy(h.signature, "KSHHRHLP", 8);
1770 h.machine_id = machine;
1771 h.boot_id = boot;
1772 h.header_size = htole64(sizeof(h));
1773 h.start_usec = htole64(n * arg_interval);
1774 h.interval_usec = htole64(arg_interval);
1775 h.fsprg_secpar = htole16(FSPRG_RECOMMENDED_SECPAR1536);
1776 h.fsprg_state_size = htole64(state_size);
1777
1778 r = loop_write(fd, &h, sizeof(h), false0);
1779 if (r < 0) {
1780 log_error_errno(r, "Failed to write header: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 1780, __func__, "Failed to write header: %m"
) : -abs(_e); })
;
1781 goto finish;
1782 }
1783
1784 r = loop_write(fd, state, state_size, false0);
1785 if (r < 0) {
1786 log_error_errno(r, "Failed to write state: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 1786, __func__, "Failed to write state: %m"
) : -abs(_e); })
;
1787 goto finish;
1788 }
1789
1790 if (link(k, p) < 0) {
1791 r = log_error_errno(errno, "Failed to link file: %m")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/journal/journalctl.c", 1791, __func__
, "Failed to link file: %m") : -abs(_e); })
;
1792 goto finish;
1793 }
1794
1795 if (on_tty()) {
1796 fprintf(stderrstderr,
1797 "\n"
1798 "The new key pair has been generated. The %ssecret sealing key%s has been written to\n"
1799 "the following local file. This key file is automatically updated when the\n"
1800 "sealing key is advanced. It should not be used on multiple hosts.\n"
1801 "\n"
1802 "\t%s\n"
1803 "\n"
1804 "Please write down the following %ssecret verification key%s. It should be stored\n"
1805 "at a safe location and should not be saved locally on disk.\n"
1806 "\n\t%s",
1807 ansi_highlight(), ansi_normal(),
1808 p,
1809 ansi_highlight(), ansi_normal(),
1810 ansi_highlight_red());
1811 fflush(stderrstderr);
1812 }
1813 for (i = 0; i < seed_size; i++) {
1814 if (i > 0 && i % 3 == 0)
1815 putchar('-');
1816 printf("%02x", ((uint8_t*) seed)[i]);
1817 }
1818
1819 printf("/%llx-%llx\n", (unsigned long long) n, (unsigned long long) arg_interval);
1820
1821 if (on_tty()) {
1822 char tsb[FORMAT_TIMESPAN_MAX64], *hn;
1823
1824 fprintf(stderrstderr,
1825 "%s\n"
1826 "The sealing key is automatically changed every %s.\n",
1827 ansi_normal(),
1828 format_timespan(tsb, sizeof(tsb), arg_interval, 0));
1829
1830 hn = gethostname_malloc();
1831
1832 if (hn) {
1833 hostname_cleanup(hn);
1834 fprintf(stderrstderr, "\nThe keys have been generated for host %s/" SD_ID128_FORMAT_STR"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x" ".\n", hn, SD_ID128_FORMAT_VAL(machine)(machine).bytes[0], (machine).bytes[1], (machine).bytes[2], (
machine).bytes[3], (machine).bytes[4], (machine).bytes[5], (machine
).bytes[6], (machine).bytes[7], (machine).bytes[8], (machine)
.bytes[9], (machine).bytes[10], (machine).bytes[11], (machine
).bytes[12], (machine).bytes[13], (machine).bytes[14], (machine
).bytes[15]
);
1835 } else
1836 fprintf(stderrstderr, "\nThe keys have been generated for host " SD_ID128_FORMAT_STR"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x" ".\n", SD_ID128_FORMAT_VAL(machine)(machine).bytes[0], (machine).bytes[1], (machine).bytes[2], (
machine).bytes[3], (machine).bytes[4], (machine).bytes[5], (machine
).bytes[6], (machine).bytes[7], (machine).bytes[8], (machine)
.bytes[9], (machine).bytes[10], (machine).bytes[11], (machine
).bytes[12], (machine).bytes[13], (machine).bytes[14], (machine
).bytes[15]
);
1837
1838#if HAVE_QRENCODE1
1839 /* If this is not an UTF-8 system don't print any QR codes */
1840 if (is_locale_utf8()) {
1841 fputs("\nTo transfer the verification key to your phone please scan the QR code below:\n\n", stderrstderr);
1842 print_qr_code(stderrstderr, seed, seed_size, n, arg_interval, hn, machine);
1843 }
1844#endif
1845 free(hn);
1846 }
1847
1848 r = 0;
1849
1850finish:
1851 safe_close(fd);
1852
1853 if (k) {
1854 unlink(k);
1855 free(k);
1856 }
1857
1858 free(p);
1859
1860 return r;
1861#else
1862 log_error("Forward-secure sealing not available.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 1862, __func__, "Forward-secure sealing not available."
) : -abs(_e); })
;
1863 return -EOPNOTSUPP95;
1864#endif
1865}
1866
1867static int verify(sd_journal *j) {
1868 int r = 0;
1869 Iterator i;
1870 JournalFile *f;
1871
1872 assert(j)do { if ((__builtin_expect(!!(!(j)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("j"), "../src/journal/journalctl.c", 1872
, __PRETTY_FUNCTION__); } while (0)
;
1873
1874 log_show_color(true1);
1875
1876 ORDERED_HASHMAP_FOREACH(f, j->files, i)for ((i) = ((Iterator) { .idx = ((2147483647 *2U +1U) - 1), .
next_key = ((void*)0) }); ordered_hashmap_iterate((j->files
), &(i), (void**)&(f), ((void*)0)); )
{
1877 int k;
1878 usec_t first = 0, validated = 0, last = 0;
1879
1880#if HAVE_GCRYPT1
1881 if (!arg_verify_key && JOURNAL_HEADER_SEALED(f->header)(!!(le32toh((f->header)->compatible_flags) & HEADER_COMPATIBLE_SEALED
))
)
1882 log_notice("Journal file %s has sealing enabled but verification key has not been passed using --verify-key=.", f->path)({ int _level = (((5))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 1882, __func__, "Journal file %s has sealing enabled but verification key has not been passed using --verify-key=."
, f->path) : -abs(_e); })
;
1883#endif
1884
1885 k = journal_file_verify(f, arg_verify_key, &first, &validated, &last, true1);
1886 if (k == -EINVAL22) {
1887 /* If the key was invalid give up right-away. */
1888 return k;
1889 } else if (k < 0) {
1890 log_warning_errno(k, "FAIL: %s (%m)", f->path)({ int _level = ((4)), _e = ((k)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 1890, __func__, "FAIL: %s (%m)"
, f->path) : -abs(_e); })
;
1891 r = k;
1892 } else {
1893 char a[FORMAT_TIMESTAMP_MAX(3+1+10+1+8+1+6+1+6+1)], b[FORMAT_TIMESTAMP_MAX(3+1+10+1+8+1+6+1+6+1)], c[FORMAT_TIMESPAN_MAX64];
1894 log_info("PASS: %s", f->path)({ int _level = (((6))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 1894, __func__, "PASS: %s", f
->path) : -abs(_e); })
;
1895
1896 if (arg_verify_key && JOURNAL_HEADER_SEALED(f->header)(!!(le32toh((f->header)->compatible_flags) & HEADER_COMPATIBLE_SEALED
))
) {
1897 if (validated > 0) {
1898 log_info("=> Validated from %s to %s, final %s entries not sealed.",({ int _level = (((6))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 1901, __func__, "=> Validated from %s to %s, final %s entries not sealed."
, format_timestamp_maybe_utc(a, sizeof(a), first), format_timestamp_maybe_utc
(b, sizeof(b), validated), format_timespan(c, sizeof(c), last
> validated ? last - validated : 0, 0)) : -abs(_e); })
1899 format_timestamp_maybe_utc(a, sizeof(a), first),({ int _level = (((6))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 1901, __func__, "=> Validated from %s to %s, final %s entries not sealed."
, format_timestamp_maybe_utc(a, sizeof(a), first), format_timestamp_maybe_utc
(b, sizeof(b), validated), format_timespan(c, sizeof(c), last
> validated ? last - validated : 0, 0)) : -abs(_e); })
1900 format_timestamp_maybe_utc(b, sizeof(b), validated),({ int _level = (((6))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 1901, __func__, "=> Validated from %s to %s, final %s entries not sealed."
, format_timestamp_maybe_utc(a, sizeof(a), first), format_timestamp_maybe_utc
(b, sizeof(b), validated), format_timespan(c, sizeof(c), last
> validated ? last - validated : 0, 0)) : -abs(_e); })
1901 format_timespan(c, sizeof(c), last > validated ? last - validated : 0, 0))({ int _level = (((6))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 1901, __func__, "=> Validated from %s to %s, final %s entries not sealed."
, format_timestamp_maybe_utc(a, sizeof(a), first), format_timestamp_maybe_utc
(b, sizeof(b), validated), format_timespan(c, sizeof(c), last
> validated ? last - validated : 0, 0)) : -abs(_e); })
;
1902 } else if (last > 0)
1903 log_info("=> No sealing yet, %s of entries not sealed.",({ int _level = (((6))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 1904, __func__, "=> No sealing yet, %s of entries not sealed."
, format_timespan(c, sizeof(c), last - first, 0)) : -abs(_e);
})
1904 format_timespan(c, sizeof(c), last - first, 0))({ int _level = (((6))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 1904, __func__, "=> No sealing yet, %s of entries not sealed."
, format_timespan(c, sizeof(c), last - first, 0)) : -abs(_e);
})
;
1905 else
1906 log_info("=> No sealing yet, no entries in file.")({ int _level = (((6))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 1906, __func__, "=> No sealing yet, no entries in file."
) : -abs(_e); })
;
1907 }
1908 }
1909 }
1910
1911 return r;
1912}
1913
1914static int flush_to_var(void) {
1915 _cleanup_(sd_bus_error_free)__attribute__((cleanup(sd_bus_error_free))) sd_bus_error error = SD_BUS_ERROR_NULL((const sd_bus_error) {(((void*)0)), (((void*)0)), 0});
1916 _cleanup_(sd_bus_flush_close_unrefp)__attribute__((cleanup(sd_bus_flush_close_unrefp))) sd_bus *bus = NULL((void*)0);
1917 _cleanup_close___attribute__((cleanup(closep))) int watch_fd = -1;
1918 int r;
1919
1920 if (arg_machine) {
1921 log_error("--flush is not supported in conjunction with --machine=.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 1921, __func__, "--flush is not supported in conjunction with --machine=."
) : -abs(_e); })
;
1922 return -EOPNOTSUPP95;
1923 }
1924
1925 /* Quick exit */
1926 if (access("/run/systemd/journal/flushed", F_OK0) >= 0)
1927 return 0;
1928
1929 /* OK, let's actually do the full logic, send SIGUSR1 to the
1930 * daemon and set up inotify to wait for the flushed file to appear */
1931 r = bus_connect_system_systemd(&bus);
1932 if (r < 0)
1933 return log_error_errno(r, "Failed to get D-Bus connection: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 1933, __func__, "Failed to get D-Bus connection: %m"
) : -abs(_e); })
;
1934
1935 r = sd_bus_call_method(
1936 bus,
1937 "org.freedesktop.systemd1",
1938 "/org/freedesktop/systemd1",
1939 "org.freedesktop.systemd1.Manager",
1940 "KillUnit",
1941 &error,
1942 NULL((void*)0),
1943 "ssi", "systemd-journald.service", "main", SIGUSR110);
1944 if (r < 0)
1945 return log_error_errno(r, "Failed to kill journal service: %s", bus_error_message(&error, r))({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 1945, __func__, "Failed to kill journal service: %s"
, bus_error_message(&error, r)) : -abs(_e); })
;
1946
1947 mkdir_p("/run/systemd/journal", 0755);
1948
1949 watch_fd = inotify_init1(IN_NONBLOCKIN_NONBLOCK|IN_CLOEXECIN_CLOEXEC);
1950 if (watch_fd < 0)
1951 return log_error_errno(errno, "Failed to create inotify watch: %m")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/journal/journalctl.c", 1951, __func__
, "Failed to create inotify watch: %m") : -abs(_e); })
;
1952
1953 r = inotify_add_watch(watch_fd, "/run/systemd/journal", IN_CREATE0x00000100|IN_DONT_FOLLOW0x02000000|IN_ONLYDIR0x01000000);
1954 if (r < 0)
1955 return log_error_errno(errno, "Failed to watch journal directory: %m")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/journal/journalctl.c", 1955, __func__
, "Failed to watch journal directory: %m") : -abs(_e); })
;
1956
1957 for (;;) {
1958 if (access("/run/systemd/journal/flushed", F_OK0) >= 0)
1959 break;
1960
1961 if (errno(*__errno_location ()) != ENOENT2)
1962 return log_error_errno(errno, "Failed to check for existence of /run/systemd/journal/flushed: %m")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/journal/journalctl.c", 1962, __func__
, "Failed to check for existence of /run/systemd/journal/flushed: %m"
) : -abs(_e); })
;
1963
1964 r = fd_wait_for_event(watch_fd, POLLIN0x001, USEC_INFINITY((usec_t) -1));
1965 if (r < 0)
1966 return log_error_errno(r, "Failed to wait for event: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 1966, __func__, "Failed to wait for event: %m"
) : -abs(_e); })
;
1967
1968 r = flush_fd(watch_fd);
1969 if (r < 0)
1970 return log_error_errno(r, "Failed to flush inotify events: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 1970, __func__, "Failed to flush inotify events: %m"
) : -abs(_e); })
;
1971 }
1972
1973 return 0;
1974}
1975
1976static int send_signal_and_wait(int sig, const char *watch_path) {
1977 _cleanup_(sd_bus_flush_close_unrefp)__attribute__((cleanup(sd_bus_flush_close_unrefp))) sd_bus *bus = NULL((void*)0);
1978 _cleanup_close___attribute__((cleanup(closep))) int watch_fd = -1;
1979 usec_t start;
1980 int r;
1981
1982 if (arg_machine) {
1983 log_error("--sync and --rotate are not supported in conjunction with --machine=.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 1983, __func__, "--sync and --rotate are not supported in conjunction with --machine=."
) : -abs(_e); })
;
1984 return -EOPNOTSUPP95;
1985 }
1986
1987 start = now(CLOCK_MONOTONIC1);
1988
1989 /* This call sends the specified signal to journald, and waits
1990 * for acknowledgment by watching the mtime of the specified
1991 * flag file. This is used to trigger syncing or rotation and
1992 * then wait for the operation to complete. */
1993
1994 for (;;) {
1995 usec_t tstamp;
1996
1997 /* See if a sync happened by now. */
1998 r = read_timestamp_file(watch_path, &tstamp);
1999 if (r < 0 && r != -ENOENT2)
2000 return log_error_errno(errno, "Failed to read %s: %m", watch_path)({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/journal/journalctl.c", 2000, __func__
, "Failed to read %s: %m", watch_path) : -abs(_e); })
;
2001 if (r >= 0 && tstamp >= start)
2002 return 0;
2003
2004 /* Let's ask for a sync, but only once. */
2005 if (!bus) {
2006 _cleanup_(sd_bus_error_free)__attribute__((cleanup(sd_bus_error_free))) sd_bus_error error = SD_BUS_ERROR_NULL((const sd_bus_error) {(((void*)0)), (((void*)0)), 0});
2007
2008 r = bus_connect_system_systemd(&bus);
2009 if (r < 0)
2010 return log_error_errno(r, "Failed to get D-Bus connection: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 2010, __func__, "Failed to get D-Bus connection: %m"
) : -abs(_e); })
;
2011
2012 r = sd_bus_call_method(
2013 bus,
2014 "org.freedesktop.systemd1",
2015 "/org/freedesktop/systemd1",
2016 "org.freedesktop.systemd1.Manager",
2017 "KillUnit",
2018 &error,
2019 NULL((void*)0),
2020 "ssi", "systemd-journald.service", "main", sig);
2021 if (r < 0)
2022 return log_error_errno(r, "Failed to kill journal service: %s", bus_error_message(&error, r))({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 2022, __func__, "Failed to kill journal service: %s"
, bus_error_message(&error, r)) : -abs(_e); })
;
2023
2024 continue;
2025 }
2026
2027 /* Let's install the inotify watch, if we didn't do that yet. */
2028 if (watch_fd < 0) {
2029
2030 mkdir_p("/run/systemd/journal", 0755);
2031
2032 watch_fd = inotify_init1(IN_NONBLOCKIN_NONBLOCK|IN_CLOEXECIN_CLOEXEC);
2033 if (watch_fd < 0)
2034 return log_error_errno(errno, "Failed to create inotify watch: %m")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/journal/journalctl.c", 2034, __func__
, "Failed to create inotify watch: %m") : -abs(_e); })
;
2035
2036 r = inotify_add_watch(watch_fd, "/run/systemd/journal", IN_MOVED_TO0x00000080|IN_DONT_FOLLOW0x02000000|IN_ONLYDIR0x01000000);
2037 if (r < 0)
2038 return log_error_errno(errno, "Failed to watch journal directory: %m")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/journal/journalctl.c", 2038, __func__
, "Failed to watch journal directory: %m") : -abs(_e); })
;
2039
2040 /* Recheck the flag file immediately, so that we don't miss any event since the last check. */
2041 continue;
2042 }
2043
2044 /* OK, all preparatory steps done, let's wait until
2045 * inotify reports an event. */
2046
2047 r = fd_wait_for_event(watch_fd, POLLIN0x001, USEC_INFINITY((usec_t) -1));
2048 if (r < 0)
2049 return log_error_errno(r, "Failed to wait for event: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 2049, __func__, "Failed to wait for event: %m"
) : -abs(_e); })
;
2050
2051 r = flush_fd(watch_fd);
2052 if (r < 0)
2053 return log_error_errno(r, "Failed to flush inotify events: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 2053, __func__, "Failed to flush inotify events: %m"
) : -abs(_e); })
;
2054 }
2055
2056 return 0;
2057}
2058
2059static int rotate(void) {
2060 return send_signal_and_wait(SIGUSR212, "/run/systemd/journal/rotated");
2061}
2062
2063static int sync_journal(void) {
2064 return send_signal_and_wait(SIGRTMIN(__libc_current_sigrtmin ())+1, "/run/systemd/journal/synced");
2065}
2066
2067int main(int argc, char *argv[]) {
2068 int r;
2069 _cleanup_(sd_journal_closep)__attribute__((cleanup(sd_journal_closep))) sd_journal *j = NULL((void*)0);
2070 bool_Bool need_seek = false0;
2071 sd_id128_t previous_boot_id;
2072 bool_Bool previous_boot_id_valid = false0, first_line = true1;
2073 int n_shown = 0;
2074 bool_Bool ellipsized = false0;
2075
2076 setlocale(LC_ALL6, "");
2077 log_parse_environment()log_parse_environment_realm(LOG_REALM_SYSTEMD);
2078 log_open();
2079
2080 r = parse_argv(argc, argv);
2081 if (r <= 0)
2082 goto finish;
2083
2084 signal(SIGWINCH28, columns_lines_cache_reset);
2085 sigbus_install();
2086
2087 /* Increase max number of open files to 16K if we can, we
2088 * might needs this when browsing journal files, which might
2089 * be split up into many files. */
2090 setrlimit_closest(RLIMIT_NOFILERLIMIT_NOFILE, &RLIMIT_MAKE_CONST(16384)((struct rlimit) { 16384, 16384 }));
2091
2092 switch (arg_action) {
2093
2094 case ACTION_NEW_ID128:
2095 r = generate_new_id128();
2096 goto finish;
2097
2098 case ACTION_SETUP_KEYS:
2099 r = setup_keys();
2100 goto finish;
2101
2102 case ACTION_LIST_CATALOG:
2103 case ACTION_DUMP_CATALOG:
2104 case ACTION_UPDATE_CATALOG: {
2105 _cleanup_free___attribute__((cleanup(freep))) char *database;
2106
2107 database = path_join(arg_root, CATALOG_DATABASE"/var/lib/systemd/catalog/database", NULL((void*)0));
2108 if (!database) {
2109 r = log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/journal/journalctl.c"
, 2109, __func__)
;
2110 goto finish;
2111 }
2112
2113 if (arg_action == ACTION_UPDATE_CATALOG) {
2114 r = catalog_update(database, arg_root, catalog_file_dirs);
2115 if (r < 0)
2116 log_error_errno(r, "Failed to list catalog: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 2116, __func__, "Failed to list catalog: %m"
) : -abs(_e); })
;
2117 } else {
2118 bool_Bool oneline = arg_action == ACTION_LIST_CATALOG;
2119
2120 (void) pager_open(arg_no_pager, arg_pager_end);
2121
2122 if (optind < argc)
2123 r = catalog_list_items(stdoutstdout, database, oneline, argv + optind);
2124 else
2125 r = catalog_list(stdoutstdout, database, oneline);
2126 if (r < 0)
2127 log_error_errno(r, "Failed to list catalog: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 2127, __func__, "Failed to list catalog: %m"
) : -abs(_e); })
;
2128 }
2129
2130 goto finish;
2131 }
2132
2133 case ACTION_FLUSH:
2134 r = flush_to_var();
2135 goto finish;
2136
2137 case ACTION_SYNC:
2138 r = sync_journal();
2139 goto finish;
2140
2141 case ACTION_ROTATE:
2142 r = rotate();
2143 goto finish;
2144
2145 case ACTION_SHOW:
2146 case ACTION_PRINT_HEADER:
2147 case ACTION_VERIFY:
2148 case ACTION_DISK_USAGE:
2149 case ACTION_LIST_BOOTS:
2150 case ACTION_VACUUM:
2151 case ACTION_LIST_FIELDS:
2152 case ACTION_LIST_FIELD_NAMES:
2153 /* These ones require access to the journal files, continue below. */
2154 break;
2155
2156 default:
2157 assert_not_reached("Unknown action")do { log_assert_failed_unreachable_realm(LOG_REALM_SYSTEMD, (
"Unknown action"), "../src/journal/journalctl.c", 2157, __PRETTY_FUNCTION__
); } while (0)
;
2158 }
2159
2160 if (arg_directory)
2161 r = sd_journal_open_directory(&j, arg_directory, arg_journal_type);
2162 else if (arg_root)
2163 r = sd_journal_open_directory(&j, arg_root, arg_journal_type | SD_JOURNAL_OS_ROOT);
2164 else if (arg_file_stdin) {
2165 int ifd = STDIN_FILENO0;
2166 r = sd_journal_open_files_fd(&j, &ifd, 1, 0);
2167 } else if (arg_file)
2168 r = sd_journal_open_files(&j, (const char**) arg_file, 0);
2169 else if (arg_machine) {
2170 _cleanup_(sd_bus_error_free)__attribute__((cleanup(sd_bus_error_free))) sd_bus_error error = SD_BUS_ERROR_NULL((const sd_bus_error) {(((void*)0)), (((void*)0)), 0});
2171 _cleanup_(sd_bus_message_unrefp)__attribute__((cleanup(sd_bus_message_unrefp))) sd_bus_message *reply = NULL((void*)0);
2172 _cleanup_(sd_bus_flush_close_unrefp)__attribute__((cleanup(sd_bus_flush_close_unrefp))) sd_bus *bus = NULL((void*)0);
2173 int fd;
2174
2175 if (geteuid() != 0) {
2176 /* The file descriptor returned by OpenMachineRootDirectory() will be owned by users/groups of
2177 * the container, thus we need root privileges to override them. */
2178 log_error("Using the --machine= switch requires root privileges.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 2178, __func__, "Using the --machine= switch requires root privileges."
) : -abs(_e); })
;
2179 r = -EPERM1;
2180 goto finish;
2181 }
2182
2183 r = sd_bus_open_system(&bus);
2184 if (r < 0) {
2185 log_error_errno(r, "Failed to open system bus: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 2185, __func__, "Failed to open system bus: %m"
) : -abs(_e); })
;
2186 goto finish;
2187 }
2188
2189 r = sd_bus_call_method(
2190 bus,
2191 "org.freedesktop.machine1",
2192 "/org/freedesktop/machine1",
2193 "org.freedesktop.machine1.Manager",
2194 "OpenMachineRootDirectory",
2195 &error,
2196 &reply,
2197 "s", arg_machine);
2198 if (r < 0) {
2199 log_error_errno(r, "Failed to open root directory: %s", bus_error_message(&error, r))({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 2199, __func__, "Failed to open root directory: %s"
, bus_error_message(&error, r)) : -abs(_e); })
;
2200 goto finish;
2201 }
2202
2203 r = sd_bus_message_read(reply, "h", &fd);
2204 if (r < 0) {
2205 bus_log_parse_error(r);
2206 goto finish;
2207 }
2208
2209 fd = fcntl(fd, F_DUPFD_CLOEXEC1030, 3);
2210 if (fd < 0) {
2211 r = log_error_errno(errno, "Failed to duplicate file descriptor: %m")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/journal/journalctl.c", 2211, __func__
, "Failed to duplicate file descriptor: %m") : -abs(_e); })
;
2212 goto finish;
2213 }
2214
2215 r = sd_journal_open_directory_fd(&j, fd, SD_JOURNAL_OS_ROOT);
2216 if (r < 0)
2217 safe_close(fd);
2218 } else
2219 r = sd_journal_open(&j, !arg_merge*SD_JOURNAL_LOCAL_ONLY + arg_journal_type);
2220 if (r < 0) {
2221 log_error_errno(r, "Failed to open %s: %m", arg_directory ?: arg_file ? "files" : "journal")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 2221, __func__, "Failed to open %s: %m"
, arg_directory ?: arg_file ? "files" : "journal") : -abs(_e)
; })
;
2222 goto finish;
2223 }
2224
2225 r = journal_access_check_and_warn(j, arg_quiet,
2226 !(arg_journal_type == SD_JOURNAL_CURRENT_USER || arg_user_units));
2227 if (r < 0)
2228 goto finish;
2229
2230 switch (arg_action) {
2231
2232 case ACTION_NEW_ID128:
2233 case ACTION_SETUP_KEYS:
2234 case ACTION_LIST_CATALOG:
2235 case ACTION_DUMP_CATALOG:
2236 case ACTION_UPDATE_CATALOG:
2237 case ACTION_FLUSH:
2238 case ACTION_SYNC:
2239 case ACTION_ROTATE:
2240 assert_not_reached("Unexpected action.")do { log_assert_failed_unreachable_realm(LOG_REALM_SYSTEMD, (
"Unexpected action."), "../src/journal/journalctl.c", 2240, __PRETTY_FUNCTION__
); } while (0)
;
2241
2242 case ACTION_PRINT_HEADER:
2243 journal_print_header(j);
2244 r = 0;
2245 goto finish;
2246
2247 case ACTION_VERIFY:
2248 r = verify(j);
2249 goto finish;
2250
2251 case ACTION_DISK_USAGE: {
2252 uint64_t bytes = 0;
2253 char sbytes[FORMAT_BYTES_MAX8];
2254
2255 r = sd_journal_get_usage(j, &bytes);
2256 if (r < 0)
2257 goto finish;
2258
2259 printf("Archived and active journals take up %s in the file system.\n",
2260 format_bytes(sbytes, sizeof(sbytes), bytes));
2261 goto finish;
2262 }
2263
2264 case ACTION_LIST_BOOTS:
2265 r = list_boots(j);
2266 goto finish;
2267
2268 case ACTION_VACUUM: {
2269 Directory *d;
2270 Iterator i;
2271
2272 HASHMAP_FOREACH(d, j->directories_by_path, i)for ((i) = ((Iterator) { .idx = ((2147483647 *2U +1U) - 1), .
next_key = ((void*)0) }); hashmap_iterate((j->directories_by_path
), &(i), (void**)&(d), ((void*)0)); )
{
2273 int q;
2274
2275 if (d->is_root)
2276 continue;
2277
2278 q = journal_directory_vacuum(d->path, arg_vacuum_size, arg_vacuum_n_files, arg_vacuum_time, NULL((void*)0), !arg_quiet);
2279 if (q < 0) {
2280 log_error_errno(q, "Failed to vacuum %s: %m", d->path)({ int _level = ((3)), _e = ((q)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 2280, __func__, "Failed to vacuum %s: %m"
, d->path) : -abs(_e); })
;
2281 r = q;
2282 }
2283 }
2284
2285 goto finish;
2286 }
2287
2288 case ACTION_LIST_FIELD_NAMES: {
2289 const char *field;
2290
2291 SD_JOURNAL_FOREACH_FIELD(j, field)for (sd_journal_restart_fields(j); sd_journal_enumerate_fields
((j), &(field)) > 0; )
{
2292 printf("%s\n", field);
2293 n_shown++;
2294 }
2295
2296 r = 0;
2297 goto finish;
2298 }
2299
2300 case ACTION_SHOW:
2301 case ACTION_LIST_FIELDS:
2302 break;
2303
2304 default:
2305 assert_not_reached("Unknown action")do { log_assert_failed_unreachable_realm(LOG_REALM_SYSTEMD, (
"Unknown action"), "../src/journal/journalctl.c", 2305, __PRETTY_FUNCTION__
); } while (0)
;
2306 }
2307
2308 if (arg_boot_offset != 0 &&
2309 sd_journal_has_runtime_files(j) > 0 &&
2310 sd_journal_has_persistent_files(j) == 0) {
2311 log_info("Specifying boot ID or boot offset has no effect, no persistent journal was found.")({ int _level = (((6))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 2311, __func__, "Specifying boot ID or boot offset has no effect, no persistent journal was found."
) : -abs(_e); })
;
2312 r = 0;
2313 goto finish;
2314 }
2315 /* add_boot() must be called first!
2316 * It may need to seek the journal to find parent boot IDs. */
2317 r = add_boot(j);
2318 if (r < 0)
2319 goto finish;
2320
2321 r = add_dmesg(j);
2322 if (r < 0)
2323 goto finish;
2324
2325 r = add_units(j);
2326 if (r < 0) {
2327 log_error_errno(r, "Failed to add filter for units: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 2327, __func__, "Failed to add filter for units: %m"
) : -abs(_e); })
;
2328 goto finish;
2329 }
2330
2331 r = add_syslog_identifier(j);
2332 if (r < 0) {
2333 log_error_errno(r, "Failed to add filter for syslog identifiers: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 2333, __func__, "Failed to add filter for syslog identifiers: %m"
) : -abs(_e); })
;
2334 goto finish;
2335 }
2336
2337 r = add_priorities(j);
2338 if (r < 0)
2339 goto finish;
2340
2341 r = add_matches(j, argv + optind);
2342 if (r < 0)
2343 goto finish;
2344
2345 if (DEBUG_LOGGING(__builtin_expect(!!(log_get_max_level_realm(LOG_REALM_SYSTEMD
) >= 7),0))
) {
2346 _cleanup_free___attribute__((cleanup(freep))) char *filter;
2347
2348 filter = journal_make_match_string(j);
2349 if (!filter)
2350 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/journal/journalctl.c"
, 2350, __func__)
;
2351
2352 log_debug("Journal filter: %s", filter)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 2352, __func__, "Journal filter: %s"
, filter) : -abs(_e); })
;
2353 }
2354
2355 if (arg_action == ACTION_LIST_FIELDS) {
2356 const void *data;
2357 size_t size;
2358
2359 assert(arg_field)do { if ((__builtin_expect(!!(!(arg_field)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("arg_field"), "../src/journal/journalctl.c"
, 2359, __PRETTY_FUNCTION__); } while (0)
;
2360
2361 r = sd_journal_set_data_threshold(j, 0);
2362 if (r < 0) {
2363 log_error_errno(r, "Failed to unset data size threshold: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 2363, __func__, "Failed to unset data size threshold: %m"
) : -abs(_e); })
;
2364 goto finish;
2365 }
2366
2367 r = sd_journal_query_unique(j, arg_field);
2368 if (r < 0) {
2369 log_error_errno(r, "Failed to query unique data objects: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 2369, __func__, "Failed to query unique data objects: %m"
) : -abs(_e); })
;
2370 goto finish;
2371 }
2372
2373 SD_JOURNAL_FOREACH_UNIQUE(j, data, size)for (sd_journal_restart_unique(j); sd_journal_enumerate_unique
((j), &(data), &(size)) > 0; )
{
2374 const void *eq;
2375
2376 if (arg_lines >= 0 && n_shown >= arg_lines)
2377 break;
2378
2379 eq = memchr(data, '=', size);
2380 if (eq)
2381 printf("%.*s\n", (int) (size - ((const uint8_t*) eq - (const uint8_t*) data + 1)), (const char*) eq + 1);
2382 else
2383 printf("%.*s\n", (int) size, (const char*) data);
2384
2385 n_shown++;
2386 }
2387
2388 r = 0;
2389 goto finish;
2390 }
2391
2392 /* Opening the fd now means the first sd_journal_wait() will actually wait */
2393 if (arg_follow) {
2394 r = sd_journal_get_fd(j);
2395 if (r == -EMFILE24) {
2396 log_warning("Insufficent watch descriptors available. Reverting to -n.")({ int _level = (((4))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 2396, __func__, "Insufficent watch descriptors available. Reverting to -n."
) : -abs(_e); })
;
2397 arg_follow = false0;
2398 } else if (r == -EMEDIUMTYPE124) {
2399 log_error_errno(r, "The --follow switch is not supported in conjunction with reading from STDIN.")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 2399, __func__, "The --follow switch is not supported in conjunction with reading from STDIN."
) : -abs(_e); })
;
2400 goto finish;
2401 } else if (r < 0) {
2402 log_error_errno(r, "Failed to get journal fd: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 2402, __func__, "Failed to get journal fd: %m"
) : -abs(_e); })
;
2403 goto finish;
2404 }
2405 }
2406
2407 if (arg_cursor || arg_after_cursor) {
2408 r = sd_journal_seek_cursor(j, arg_cursor ?: arg_after_cursor);
2409 if (r < 0) {
2410 log_error_errno(r, "Failed to seek to cursor: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 2410, __func__, "Failed to seek to cursor: %m"
) : -abs(_e); })
;
2411 goto finish;
2412 }
2413
2414 if (!arg_reverse)
2415 r = sd_journal_next_skip(j, 1 + !!arg_after_cursor);
2416 else
2417 r = sd_journal_previous_skip(j, 1 + !!arg_after_cursor);
2418
2419 if (arg_after_cursor && r < 2) {
2420 /* We couldn't find the next entry after the cursor. */
2421 if (arg_follow)
2422 need_seek = true1;
2423 else
2424 arg_lines = 0;
2425 }
2426
2427 } else if (arg_since_set && !arg_reverse) {
2428 r = sd_journal_seek_realtime_usec(j, arg_since);
2429 if (r < 0) {
2430 log_error_errno(r, "Failed to seek to date: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 2430, __func__, "Failed to seek to date: %m"
) : -abs(_e); })
;
2431 goto finish;
2432 }
2433 r = sd_journal_next(j);
2434
2435 } else if (arg_until_set && arg_reverse) {
2436 r = sd_journal_seek_realtime_usec(j, arg_until);
2437 if (r < 0) {
2438 log_error_errno(r, "Failed to seek to date: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 2438, __func__, "Failed to seek to date: %m"
) : -abs(_e); })
;
2439 goto finish;
2440 }
2441 r = sd_journal_previous(j);
2442
2443 } else if (arg_lines >= 0) {
2444 r = sd_journal_seek_tail(j);
2445 if (r < 0) {
2446 log_error_errno(r, "Failed to seek to tail: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 2446, __func__, "Failed to seek to tail: %m"
) : -abs(_e); })
;
2447 goto finish;
2448 }
2449
2450 r = sd_journal_previous_skip(j, arg_lines);
2451
2452 } else if (arg_reverse) {
2453 r = sd_journal_seek_tail(j);
2454 if (r < 0) {
2455 log_error_errno(r, "Failed to seek to tail: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 2455, __func__, "Failed to seek to tail: %m"
) : -abs(_e); })
;
2456 goto finish;
2457 }
2458
2459 r = sd_journal_previous(j);
2460
2461 } else {
2462 r = sd_journal_seek_head(j);
2463 if (r < 0) {
2464 log_error_errno(r, "Failed to seek to head: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 2464, __func__, "Failed to seek to head: %m"
) : -abs(_e); })
;
2465 goto finish;
2466 }
2467
2468 r = sd_journal_next(j);
2469 }
2470
2471 if (r < 0) {
2472 log_error_errno(r, "Failed to iterate through journal: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 2472, __func__, "Failed to iterate through journal: %m"
) : -abs(_e); })
;
2473 goto finish;
2474 }
2475 if (r == 0)
2476 need_seek = true1;
2477
2478 if (!arg_follow)
2479 (void) pager_open(arg_no_pager, arg_pager_end);
2480
2481 if (!arg_quiet && (arg_lines != 0 || arg_follow)) {
2482 usec_t start, end;
2483 char start_buf[FORMAT_TIMESTAMP_MAX(3+1+10+1+8+1+6+1+6+1)], end_buf[FORMAT_TIMESTAMP_MAX(3+1+10+1+8+1+6+1+6+1)];
2484
2485 r = sd_journal_get_cutoff_realtime_usec(j, &start, &end);
2486 if (r < 0) {
2487 log_error_errno(r, "Failed to get cutoff: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 2487, __func__, "Failed to get cutoff: %m"
) : -abs(_e); })
;
2488 goto finish;
2489 }
2490
2491 if (r > 0) {
2492 if (arg_follow)
2493 printf("-- Logs begin at %s. --\n",
2494 format_timestamp_maybe_utc(start_buf, sizeof(start_buf), start));
2495 else
2496 printf("-- Logs begin at %s, end at %s. --\n",
2497 format_timestamp_maybe_utc(start_buf, sizeof(start_buf), start),
2498 format_timestamp_maybe_utc(end_buf, sizeof(end_buf), end));
2499 }
2500 }
2501
2502 for (;;) {
2503 while (arg_lines < 0 || n_shown < arg_lines || (arg_follow && !first_line)) {
2504 int flags;
2505 size_t highlight[2] = {};
2506
2507 if (need_seek) {
2508 if (!arg_reverse)
2509 r = sd_journal_next(j);
2510 else
2511 r = sd_journal_previous(j);
2512 if (r < 0) {
2513 log_error_errno(r, "Failed to iterate through journal: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 2513, __func__, "Failed to iterate through journal: %m"
) : -abs(_e); })
;
2514 goto finish;
2515 }
2516 if (r == 0)
2517 break;
2518 }
2519
2520 if (arg_until_set && !arg_reverse) {
2521 usec_t usec;
2522
2523 r = sd_journal_get_realtime_usec(j, &usec);
2524 if (r < 0) {
2525 log_error_errno(r, "Failed to determine timestamp: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 2525, __func__, "Failed to determine timestamp: %m"
) : -abs(_e); })
;
2526 goto finish;
2527 }
2528 if (usec > arg_until)
2529 goto finish;
2530 }
2531
2532 if (arg_since_set && arg_reverse) {
2533 usec_t usec;
2534
2535 r = sd_journal_get_realtime_usec(j, &usec);
2536 if (r < 0) {
2537 log_error_errno(r, "Failed to determine timestamp: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 2537, __func__, "Failed to determine timestamp: %m"
) : -abs(_e); })
;
2538 goto finish;
2539 }
2540 if (usec < arg_since)
2541 goto finish;
2542 }
2543
2544 if (!arg_merge && !arg_quiet) {
2545 sd_id128_t boot_id;
2546
2547 r = sd_journal_get_monotonic_usec(j, NULL((void*)0), &boot_id);
2548 if (r >= 0) {
2549 if (previous_boot_id_valid &&
2550 !sd_id128_equal(boot_id, previous_boot_id))
2551 printf("%s-- Reboot --%s\n",
2552 ansi_highlight(), ansi_normal());
2553
2554 previous_boot_id = boot_id;
2555 previous_boot_id_valid = true1;
2556 }
2557 }
2558
2559#if HAVE_PCRE21
2560 if (arg_compiled_pattern) {
2561 _cleanup_(pcre2_match_data_freep)__attribute__((cleanup(pcre2_match_data_freep))) pcre2_match_datapcre2_match_data_8 *md = NULL((void*)0);
2562 const void *message;
2563 size_t len;
2564 PCRE2_SIZEsize_t *ovec;
2565
2566 md = pcre2_match_data_createpcre2_match_data_create_8(1, NULL((void*)0));
2567 if (!md)
2568 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/journal/journalctl.c"
, 2568, __func__)
;
2569
2570 r = sd_journal_get_data(j, "MESSAGE", &message, &len);
2571 if (r < 0) {
2572 if (r == -ENOENT2) {
2573 need_seek = true1;
2574 continue;
2575 }
2576
2577 log_error_errno(r, "Failed to get MESSAGE field: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 2577, __func__, "Failed to get MESSAGE field: %m"
) : -abs(_e); })
;
2578 goto finish;
2579 }
2580
2581 assert_se(message = startswith(message, "MESSAGE="))do { if ((__builtin_expect(!!(!(message = startswith(message,
"MESSAGE="))),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD
, ("message = startswith(message, \"MESSAGE=\")"), "../src/journal/journalctl.c"
, 2581, __PRETTY_FUNCTION__); } while (0)
;
2582
2583 r = pcre2_matchpcre2_match_8(arg_compiled_pattern,
2584 message,
2585 len - strlen("MESSAGE="),
2586 0, /* start at offset 0 in the subject */
2587 0, /* default options */
2588 md,
2589 NULL((void*)0));
2590 if (r == PCRE2_ERROR_NOMATCH(-1)) {
2591 need_seek = true1;
2592 continue;
2593 }
2594 if (r < 0) {
2595 unsigned char buf[LINE_MAX2048];
2596 int r2;
2597
2598 r2 = pcre2_get_error_messagepcre2_get_error_message_8(r, buf, sizeof buf);
2599 log_error("Pattern matching failed: %s",({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 2600, __func__, "Pattern matching failed: %s"
, r2 < 0 ? "unknown error" : (char*) buf) : -abs(_e); })
2600 r2 < 0 ? "unknown error" : (char*) buf)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 2600, __func__, "Pattern matching failed: %s"
, r2 < 0 ? "unknown error" : (char*) buf) : -abs(_e); })
;
2601 r = -EINVAL22;
2602 goto finish;
2603 }
2604
2605 ovec = pcre2_get_ovector_pointerpcre2_get_ovector_pointer_8(md);
2606 highlight[0] = ovec[0];
2607 highlight[1] = ovec[1];
2608 }
2609#endif
2610
2611 flags =
2612 arg_all * OUTPUT_SHOW_ALL |
2613 arg_full * OUTPUT_FULL_WIDTH |
2614 colors_enabled() * OUTPUT_COLOR |
2615 arg_catalog * OUTPUT_CATALOG |
2616 arg_utc * OUTPUT_UTC |
2617 arg_no_hostname * OUTPUT_NO_HOSTNAME;
2618
2619 r = show_journal_entry(stdoutstdout, j, arg_output, 0, flags,
2620 arg_output_fields, highlight, &ellipsized);
2621 need_seek = true1;
2622 if (r == -EADDRNOTAVAIL99)
2623 break;
2624 else if (r < 0 || ferror(stdoutstdout))
2625 goto finish;
2626
2627 n_shown++;
2628
2629 /* If journalctl take a long time to process messages, and during that time journal file
2630 * rotation occurs, a journalctl client will keep those rotated files open until it calls
2631 * sd_journal_process(), which typically happens as a result of calling sd_journal_wait() below
2632 * in the "following" case. By periodically calling sd_journal_process() during the processing
2633 * loop we shrink the window of time a client instance has open file descriptors for rotated
2634 * (deleted) journal files. */
2635 if ((n_shown % PROCESS_INOTIFY_INTERVAL1024) == 0) {
2636 r = sd_journal_process(j);
2637 if (r < 0) {
2638 log_error_errno(r, "Failed to process inotify events: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 2638, __func__, "Failed to process inotify events: %m"
) : -abs(_e); })
;
2639 goto finish;
2640 }
2641 }
2642 }
2643
2644 if (!arg_follow) {
2645 if (n_shown == 0 && !arg_quiet)
2646 printf("-- No entries --\n");
2647
2648 if (arg_show_cursor) {
2649 _cleanup_free___attribute__((cleanup(freep))) char *cursor = NULL((void*)0);
2650
2651 r = sd_journal_get_cursor(j, &cursor);
2652 if (r < 0 && r != -EADDRNOTAVAIL99)
2653 log_error_errno(r, "Failed to get cursor: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 2653, __func__, "Failed to get cursor: %m"
) : -abs(_e); })
;
2654 else if (r >= 0)
2655 printf("-- cursor: %s\n", cursor);
2656 }
2657
2658 break;
2659 }
2660
2661 fflush(stdoutstdout);
2662 r = sd_journal_wait(j, (uint64_t) -1);
2663 if (r < 0) {
2664 log_error_errno(r, "Couldn't wait for journal event: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/journal/journalctl.c", 2664, __func__, "Couldn't wait for journal event: %m"
) : -abs(_e); })
;
2665 goto finish;
2666 }
2667
2668 first_line = false0;
2669 }
2670
2671finish:
2672 fflush(stdoutstdout);
2673 pager_close();
2674
2675 strv_free(arg_file);
2676
2677 strv_free(arg_syslog_identifier);
2678 strv_free(arg_system_units);
2679 strv_free(arg_user_units);
2680 strv_free(arg_output_fields);
2681
2682 free(arg_root);
2683 free(arg_verify_key);
2684
2685#if HAVE_PCRE21
2686 if (arg_compiled_pattern)
2687 pcre2_code_freepcre2_code_free_8(arg_compiled_pattern);
2688#endif
2689
2690 return r < 0 ? EXIT_FAILURE1 : EXIT_SUCCESS0;
2691}