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