]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/journal/journalctl.c
dbb05e0527e3d4113877ef5448fee0f07aae4cc3
[thirdparty/systemd.git] / src / journal / journalctl.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4 This file is part of systemd.
5
6 Copyright 2011 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <errno.h>
23 #include <fcntl.h>
24 #include <fnmatch.h>
25 #include <getopt.h>
26 #include <linux/fs.h>
27 #include <locale.h>
28 #include <poll.h>
29 #include <signal.h>
30 #include <stddef.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <sys/inotify.h>
35 #include <sys/stat.h>
36 #include <unistd.h>
37
38 #include "sd-bus.h"
39 #include "sd-journal.h"
40
41 #include "acl-util.h"
42 #include "bus-error.h"
43 #include "bus-util.h"
44 #include "catalog.h"
45 #include "fd-util.h"
46 #include "fileio.h"
47 #include "fsprg.h"
48 #include "hostname-util.h"
49 #include "journal-def.h"
50 #include "journal-internal.h"
51 #include "journal-qrcode.h"
52 #include "journal-vacuum.h"
53 #include "journal-verify.h"
54 #include "log.h"
55 #include "logs-show.h"
56 #include "mkdir.h"
57 #include "pager.h"
58 #include "path-util.h"
59 #include "set.h"
60 #include "sigbus.h"
61 #include "strv.h"
62 #include "terminal-util.h"
63 #include "unit-name.h"
64
65 #define DEFAULT_FSS_INTERVAL_USEC (15*USEC_PER_MINUTE)
66
67 enum {
68 /* Special values for arg_lines */
69 ARG_LINES_DEFAULT = -2,
70 ARG_LINES_ALL = -1,
71 };
72
73 static OutputMode arg_output = OUTPUT_SHORT;
74 static bool arg_utc = false;
75 static bool arg_pager_end = false;
76 static bool arg_follow = false;
77 static bool arg_full = true;
78 static bool arg_all = false;
79 static bool arg_no_pager = false;
80 static int arg_lines = ARG_LINES_DEFAULT;
81 static bool arg_no_tail = false;
82 static bool arg_quiet = false;
83 static bool arg_merge = false;
84 static bool arg_boot = false;
85 static sd_id128_t arg_boot_id = {};
86 static int arg_boot_offset = 0;
87 static bool arg_dmesg = false;
88 static const char *arg_cursor = NULL;
89 static const char *arg_after_cursor = NULL;
90 static bool arg_show_cursor = false;
91 static const char *arg_directory = NULL;
92 static char **arg_file = NULL;
93 static int arg_priorities = 0xFF;
94 static const char *arg_verify_key = NULL;
95 #ifdef HAVE_GCRYPT
96 static usec_t arg_interval = DEFAULT_FSS_INTERVAL_USEC;
97 static bool arg_force = false;
98 #endif
99 static usec_t arg_since, arg_until;
100 static bool arg_since_set = false, arg_until_set = false;
101 static char **arg_syslog_identifier = NULL;
102 static char **arg_system_units = NULL;
103 static char **arg_user_units = NULL;
104 static const char *arg_field = NULL;
105 static bool arg_catalog = false;
106 static bool arg_reverse = false;
107 static int arg_journal_type = 0;
108 static char *arg_root = NULL;
109 static const char *arg_machine = NULL;
110 static uint64_t arg_vacuum_size = 0;
111 static uint64_t arg_vacuum_n_files = 0;
112 static usec_t arg_vacuum_time = 0;
113
114 static enum {
115 ACTION_SHOW,
116 ACTION_NEW_ID128,
117 ACTION_PRINT_HEADER,
118 ACTION_SETUP_KEYS,
119 ACTION_VERIFY,
120 ACTION_DISK_USAGE,
121 ACTION_LIST_CATALOG,
122 ACTION_DUMP_CATALOG,
123 ACTION_UPDATE_CATALOG,
124 ACTION_LIST_BOOTS,
125 ACTION_FLUSH,
126 ACTION_ROTATE,
127 ACTION_VACUUM,
128 } arg_action = ACTION_SHOW;
129
130 typedef struct BootId {
131 sd_id128_t id;
132 uint64_t first;
133 uint64_t last;
134 LIST_FIELDS(struct BootId, boot_list);
135 } BootId;
136
137 static void pager_open_if_enabled(void) {
138
139 if (arg_no_pager)
140 return;
141
142 pager_open(arg_pager_end);
143 }
144
145 static char *format_timestamp_maybe_utc(char *buf, size_t l, usec_t t) {
146
147 if (arg_utc)
148 return format_timestamp_utc(buf, l, t);
149
150 return format_timestamp(buf, l, t);
151 }
152
153 static int parse_boot_descriptor(const char *x, sd_id128_t *boot_id, int *offset) {
154 sd_id128_t id = SD_ID128_NULL;
155 int off = 0, r;
156
157 if (strlen(x) >= 32) {
158 char *t;
159
160 t = strndupa(x, 32);
161 r = sd_id128_from_string(t, &id);
162 if (r >= 0)
163 x += 32;
164
165 if (*x != '-' && *x != '+' && *x != 0)
166 return -EINVAL;
167
168 if (*x != 0) {
169 r = safe_atoi(x, &off);
170 if (r < 0)
171 return r;
172 }
173 } else {
174 r = safe_atoi(x, &off);
175 if (r < 0)
176 return r;
177 }
178
179 if (boot_id)
180 *boot_id = id;
181
182 if (offset)
183 *offset = off;
184
185 return 0;
186 }
187
188 static void help(void) {
189
190 pager_open_if_enabled();
191
192 printf("%s [OPTIONS...] [MATCHES...]\n\n"
193 "Query the journal.\n\n"
194 "Flags:\n"
195 " --system Show the system journal\n"
196 " --user Show the user journal for the current user\n"
197 " -M --machine=CONTAINER Operate on local container\n"
198 " -S --since=DATE Show entries not older than the specified date\n"
199 " -U --until=DATE Show entries not newer than the specified date\n"
200 " -c --cursor=CURSOR Show entries starting at the specified cursor\n"
201 " --after-cursor=CURSOR Show entries after the specified cursor\n"
202 " --show-cursor Print the cursor after all the entries\n"
203 " -b --boot[=ID] Show current boot or the specified boot\n"
204 " --list-boots Show terse information about recorded boots\n"
205 " -k --dmesg Show kernel message log from the current boot\n"
206 " -u --unit=UNIT Show logs from the specified unit\n"
207 " --user-unit=UNIT Show logs from the specified user unit\n"
208 " -t --identifier=STRING Show entries with the specified syslog identifier\n"
209 " -p --priority=RANGE Show entries with the specified priority\n"
210 " -e --pager-end Immediately jump to the end in the pager\n"
211 " -f --follow Follow the journal\n"
212 " -n --lines[=INTEGER] Number of journal entries to show\n"
213 " --no-tail Show all lines, even in follow mode\n"
214 " -r --reverse Show the newest entries first\n"
215 " -o --output=STRING Change journal output mode (short, short-iso,\n"
216 " short-precise, short-monotonic, verbose,\n"
217 " export, json, json-pretty, json-sse, cat)\n"
218 " --utc Express time in Coordinated Universal Time (UTC)\n"
219 " -x --catalog Add message explanations where available\n"
220 " --no-full Ellipsize fields\n"
221 " -a --all Show all fields, including long and unprintable\n"
222 " -q --quiet Do not show info messages and privilege warning\n"
223 " --no-pager Do not pipe output into a pager\n"
224 " -m --merge Show entries from all available journals\n"
225 " -D --directory=PATH Show journal files from directory\n"
226 " --file=PATH Show journal file\n"
227 " --root=ROOT Operate on catalog files underneath the root ROOT\n"
228 #ifdef HAVE_GCRYPT
229 " --interval=TIME Time interval for changing the FSS sealing key\n"
230 " --verify-key=KEY Specify FSS verification key\n"
231 " --force Override of the FSS key pair with --setup-keys\n"
232 #endif
233 "\nCommands:\n"
234 " -h --help Show this help text\n"
235 " --version Show package version\n"
236 " -F --field=FIELD List all values that a specified field takes\n"
237 " --new-id128 Generate a new 128-bit ID\n"
238 " --disk-usage Show total disk usage of all journal files\n"
239 " --vacuum-size=BYTES Reduce disk usage below specified size\n"
240 " --vacuum-files=INT Leave only the specified number of journal files\n"
241 " --vacuum-time=TIME Remove journal files older than specified time\n"
242 " --flush Flush all journal data from /run into /var\n"
243 " --rotate Request immediate rotation of the journal files\n"
244 " --header Show journal header information\n"
245 " --list-catalog Show all message IDs in the catalog\n"
246 " --dump-catalog Show entries in the message catalog\n"
247 " --update-catalog Update the message catalog database\n"
248 #ifdef HAVE_GCRYPT
249 " --setup-keys Generate a new FSS key pair\n"
250 " --verify Verify journal file consistency\n"
251 #endif
252 , program_invocation_short_name);
253 }
254
255 static int parse_argv(int argc, char *argv[]) {
256
257 enum {
258 ARG_VERSION = 0x100,
259 ARG_NO_PAGER,
260 ARG_NO_FULL,
261 ARG_NO_TAIL,
262 ARG_NEW_ID128,
263 ARG_LIST_BOOTS,
264 ARG_USER,
265 ARG_SYSTEM,
266 ARG_ROOT,
267 ARG_HEADER,
268 ARG_SETUP_KEYS,
269 ARG_FILE,
270 ARG_INTERVAL,
271 ARG_VERIFY,
272 ARG_VERIFY_KEY,
273 ARG_DISK_USAGE,
274 ARG_AFTER_CURSOR,
275 ARG_SHOW_CURSOR,
276 ARG_USER_UNIT,
277 ARG_LIST_CATALOG,
278 ARG_DUMP_CATALOG,
279 ARG_UPDATE_CATALOG,
280 ARG_FORCE,
281 ARG_UTC,
282 ARG_FLUSH,
283 ARG_ROTATE,
284 ARG_VACUUM_SIZE,
285 ARG_VACUUM_FILES,
286 ARG_VACUUM_TIME,
287 };
288
289 static const struct option options[] = {
290 { "help", no_argument, NULL, 'h' },
291 { "version" , no_argument, NULL, ARG_VERSION },
292 { "no-pager", no_argument, NULL, ARG_NO_PAGER },
293 { "pager-end", no_argument, NULL, 'e' },
294 { "follow", no_argument, NULL, 'f' },
295 { "force", no_argument, NULL, ARG_FORCE },
296 { "output", required_argument, NULL, 'o' },
297 { "all", no_argument, NULL, 'a' },
298 { "full", no_argument, NULL, 'l' },
299 { "no-full", no_argument, NULL, ARG_NO_FULL },
300 { "lines", optional_argument, NULL, 'n' },
301 { "no-tail", no_argument, NULL, ARG_NO_TAIL },
302 { "new-id128", no_argument, NULL, ARG_NEW_ID128 },
303 { "quiet", no_argument, NULL, 'q' },
304 { "merge", no_argument, NULL, 'm' },
305 { "boot", optional_argument, NULL, 'b' },
306 { "list-boots", no_argument, NULL, ARG_LIST_BOOTS },
307 { "this-boot", optional_argument, NULL, 'b' }, /* deprecated */
308 { "dmesg", no_argument, NULL, 'k' },
309 { "system", no_argument, NULL, ARG_SYSTEM },
310 { "user", no_argument, NULL, ARG_USER },
311 { "directory", required_argument, NULL, 'D' },
312 { "file", required_argument, NULL, ARG_FILE },
313 { "root", required_argument, NULL, ARG_ROOT },
314 { "header", no_argument, NULL, ARG_HEADER },
315 { "identifier", required_argument, NULL, 't' },
316 { "priority", required_argument, NULL, 'p' },
317 { "setup-keys", no_argument, NULL, ARG_SETUP_KEYS },
318 { "interval", required_argument, NULL, ARG_INTERVAL },
319 { "verify", no_argument, NULL, ARG_VERIFY },
320 { "verify-key", required_argument, NULL, ARG_VERIFY_KEY },
321 { "disk-usage", no_argument, NULL, ARG_DISK_USAGE },
322 { "cursor", required_argument, NULL, 'c' },
323 { "after-cursor", required_argument, NULL, ARG_AFTER_CURSOR },
324 { "show-cursor", no_argument, NULL, ARG_SHOW_CURSOR },
325 { "since", required_argument, NULL, 'S' },
326 { "until", required_argument, NULL, 'U' },
327 { "unit", required_argument, NULL, 'u' },
328 { "user-unit", required_argument, NULL, ARG_USER_UNIT },
329 { "field", required_argument, NULL, 'F' },
330 { "catalog", no_argument, NULL, 'x' },
331 { "list-catalog", no_argument, NULL, ARG_LIST_CATALOG },
332 { "dump-catalog", no_argument, NULL, ARG_DUMP_CATALOG },
333 { "update-catalog", no_argument, NULL, ARG_UPDATE_CATALOG },
334 { "reverse", no_argument, NULL, 'r' },
335 { "machine", required_argument, NULL, 'M' },
336 { "utc", no_argument, NULL, ARG_UTC },
337 { "flush", no_argument, NULL, ARG_FLUSH },
338 { "rotate", no_argument, NULL, ARG_ROTATE },
339 { "vacuum-size", required_argument, NULL, ARG_VACUUM_SIZE },
340 { "vacuum-files", required_argument, NULL, ARG_VACUUM_FILES },
341 { "vacuum-time", required_argument, NULL, ARG_VACUUM_TIME },
342 {}
343 };
344
345 int c, r;
346
347 assert(argc >= 0);
348 assert(argv);
349
350 while ((c = getopt_long(argc, argv, "hefo:aln::qmb::kD:p:c:S:U:t:u:F:xrM:", options, NULL)) >= 0)
351
352 switch (c) {
353
354 case 'h':
355 help();
356 return 0;
357
358 case ARG_VERSION:
359 return version();
360
361 case ARG_NO_PAGER:
362 arg_no_pager = true;
363 break;
364
365 case 'e':
366 arg_pager_end = true;
367
368 if (arg_lines == ARG_LINES_DEFAULT)
369 arg_lines = 1000;
370
371 break;
372
373 case 'f':
374 arg_follow = true;
375 break;
376
377 case 'o':
378 arg_output = output_mode_from_string(optarg);
379 if (arg_output < 0) {
380 log_error("Unknown output format '%s'.", optarg);
381 return -EINVAL;
382 }
383
384 if (arg_output == OUTPUT_EXPORT ||
385 arg_output == OUTPUT_JSON ||
386 arg_output == OUTPUT_JSON_PRETTY ||
387 arg_output == OUTPUT_JSON_SSE ||
388 arg_output == OUTPUT_CAT)
389 arg_quiet = true;
390
391 break;
392
393 case 'l':
394 arg_full = true;
395 break;
396
397 case ARG_NO_FULL:
398 arg_full = false;
399 break;
400
401 case 'a':
402 arg_all = true;
403 break;
404
405 case 'n':
406 if (optarg) {
407 if (streq(optarg, "all"))
408 arg_lines = ARG_LINES_ALL;
409 else {
410 r = safe_atoi(optarg, &arg_lines);
411 if (r < 0 || arg_lines < 0) {
412 log_error("Failed to parse lines '%s'", optarg);
413 return -EINVAL;
414 }
415 }
416 } else {
417 arg_lines = 10;
418
419 /* Hmm, no argument? Maybe the next
420 * word on the command line is
421 * supposed to be the argument? Let's
422 * see if there is one, and is
423 * parsable. */
424 if (optind < argc) {
425 int n;
426 if (streq(argv[optind], "all")) {
427 arg_lines = ARG_LINES_ALL;
428 optind++;
429 } else if (safe_atoi(argv[optind], &n) >= 0 && n >= 0) {
430 arg_lines = n;
431 optind++;
432 }
433 }
434 }
435
436 break;
437
438 case ARG_NO_TAIL:
439 arg_no_tail = true;
440 break;
441
442 case ARG_NEW_ID128:
443 arg_action = ACTION_NEW_ID128;
444 break;
445
446 case 'q':
447 arg_quiet = true;
448 break;
449
450 case 'm':
451 arg_merge = true;
452 break;
453
454 case 'b':
455 arg_boot = true;
456
457 if (optarg) {
458 r = parse_boot_descriptor(optarg, &arg_boot_id, &arg_boot_offset);
459 if (r < 0) {
460 log_error("Failed to parse boot descriptor '%s'", optarg);
461 return -EINVAL;
462 }
463 } else {
464
465 /* Hmm, no argument? Maybe the next
466 * word on the command line is
467 * supposed to be the argument? Let's
468 * see if there is one and is parsable
469 * as a boot descriptor... */
470
471 if (optind < argc &&
472 parse_boot_descriptor(argv[optind], &arg_boot_id, &arg_boot_offset) >= 0)
473 optind++;
474 }
475
476 break;
477
478 case ARG_LIST_BOOTS:
479 arg_action = ACTION_LIST_BOOTS;
480 break;
481
482 case 'k':
483 arg_boot = arg_dmesg = true;
484 break;
485
486 case ARG_SYSTEM:
487 arg_journal_type |= SD_JOURNAL_SYSTEM;
488 break;
489
490 case ARG_USER:
491 arg_journal_type |= SD_JOURNAL_CURRENT_USER;
492 break;
493
494 case 'M':
495 arg_machine = optarg;
496 break;
497
498 case 'D':
499 arg_directory = optarg;
500 break;
501
502 case ARG_FILE:
503 r = glob_extend(&arg_file, optarg);
504 if (r < 0)
505 return log_error_errno(r, "Failed to add paths: %m");
506 break;
507
508 case ARG_ROOT:
509 r = parse_path_argument_and_warn(optarg, true, &arg_root);
510 if (r < 0)
511 return r;
512 break;
513
514 case 'c':
515 arg_cursor = optarg;
516 break;
517
518 case ARG_AFTER_CURSOR:
519 arg_after_cursor = optarg;
520 break;
521
522 case ARG_SHOW_CURSOR:
523 arg_show_cursor = true;
524 break;
525
526 case ARG_HEADER:
527 arg_action = ACTION_PRINT_HEADER;
528 break;
529
530 case ARG_VERIFY:
531 arg_action = ACTION_VERIFY;
532 break;
533
534 case ARG_DISK_USAGE:
535 arg_action = ACTION_DISK_USAGE;
536 break;
537
538 case ARG_VACUUM_SIZE:
539 r = parse_size(optarg, 1024, &arg_vacuum_size);
540 if (r < 0) {
541 log_error("Failed to parse vacuum size: %s", optarg);
542 return r;
543 }
544
545 arg_action = ACTION_VACUUM;
546 break;
547
548 case ARG_VACUUM_FILES:
549 r = safe_atou64(optarg, &arg_vacuum_n_files);
550 if (r < 0) {
551 log_error("Failed to parse vacuum files: %s", optarg);
552 return r;
553 }
554
555 arg_action = ACTION_VACUUM;
556 break;
557
558 case ARG_VACUUM_TIME:
559 r = parse_sec(optarg, &arg_vacuum_time);
560 if (r < 0) {
561 log_error("Failed to parse vacuum time: %s", optarg);
562 return r;
563 }
564
565 arg_action = ACTION_VACUUM;
566 break;
567
568 #ifdef HAVE_GCRYPT
569 case ARG_FORCE:
570 arg_force = true;
571 break;
572
573 case ARG_SETUP_KEYS:
574 arg_action = ACTION_SETUP_KEYS;
575 break;
576
577
578 case ARG_VERIFY_KEY:
579 arg_action = ACTION_VERIFY;
580 arg_verify_key = optarg;
581 arg_merge = false;
582 break;
583
584 case ARG_INTERVAL:
585 r = parse_sec(optarg, &arg_interval);
586 if (r < 0 || arg_interval <= 0) {
587 log_error("Failed to parse sealing key change interval: %s", optarg);
588 return -EINVAL;
589 }
590 break;
591 #else
592 case ARG_SETUP_KEYS:
593 case ARG_VERIFY_KEY:
594 case ARG_INTERVAL:
595 case ARG_FORCE:
596 log_error("Forward-secure sealing not available.");
597 return -EOPNOTSUPP;
598 #endif
599
600 case 'p': {
601 const char *dots;
602
603 dots = strstr(optarg, "..");
604 if (dots) {
605 char *a;
606 int from, to, i;
607
608 /* a range */
609 a = strndup(optarg, dots - optarg);
610 if (!a)
611 return log_oom();
612
613 from = log_level_from_string(a);
614 to = log_level_from_string(dots + 2);
615 free(a);
616
617 if (from < 0 || to < 0) {
618 log_error("Failed to parse log level range %s", optarg);
619 return -EINVAL;
620 }
621
622 arg_priorities = 0;
623
624 if (from < to) {
625 for (i = from; i <= to; i++)
626 arg_priorities |= 1 << i;
627 } else {
628 for (i = to; i <= from; i++)
629 arg_priorities |= 1 << i;
630 }
631
632 } else {
633 int p, i;
634
635 p = log_level_from_string(optarg);
636 if (p < 0) {
637 log_error("Unknown log level %s", optarg);
638 return -EINVAL;
639 }
640
641 arg_priorities = 0;
642
643 for (i = 0; i <= p; i++)
644 arg_priorities |= 1 << i;
645 }
646
647 break;
648 }
649
650 case 'S':
651 r = parse_timestamp(optarg, &arg_since);
652 if (r < 0) {
653 log_error("Failed to parse timestamp: %s", optarg);
654 return -EINVAL;
655 }
656 arg_since_set = true;
657 break;
658
659 case 'U':
660 r = parse_timestamp(optarg, &arg_until);
661 if (r < 0) {
662 log_error("Failed to parse timestamp: %s", optarg);
663 return -EINVAL;
664 }
665 arg_until_set = true;
666 break;
667
668 case 't':
669 r = strv_extend(&arg_syslog_identifier, optarg);
670 if (r < 0)
671 return log_oom();
672 break;
673
674 case 'u':
675 r = strv_extend(&arg_system_units, optarg);
676 if (r < 0)
677 return log_oom();
678 break;
679
680 case ARG_USER_UNIT:
681 r = strv_extend(&arg_user_units, optarg);
682 if (r < 0)
683 return log_oom();
684 break;
685
686 case 'F':
687 arg_field = optarg;
688 break;
689
690 case 'x':
691 arg_catalog = true;
692 break;
693
694 case ARG_LIST_CATALOG:
695 arg_action = ACTION_LIST_CATALOG;
696 break;
697
698 case ARG_DUMP_CATALOG:
699 arg_action = ACTION_DUMP_CATALOG;
700 break;
701
702 case ARG_UPDATE_CATALOG:
703 arg_action = ACTION_UPDATE_CATALOG;
704 break;
705
706 case 'r':
707 arg_reverse = true;
708 break;
709
710 case ARG_UTC:
711 arg_utc = true;
712 break;
713
714 case ARG_FLUSH:
715 arg_action = ACTION_FLUSH;
716 break;
717
718 case ARG_ROTATE:
719 arg_action = ACTION_ROTATE;
720 break;
721
722 case '?':
723 return -EINVAL;
724
725 default:
726 assert_not_reached("Unhandled option");
727 }
728
729 if (arg_follow && !arg_no_tail && !arg_since && arg_lines == ARG_LINES_DEFAULT)
730 arg_lines = 10;
731
732 if (!!arg_directory + !!arg_file + !!arg_machine > 1) {
733 log_error("Please specify either -D/--directory= or --file= or -M/--machine=, not more than one.");
734 return -EINVAL;
735 }
736
737 if (arg_since_set && arg_until_set && arg_since > arg_until) {
738 log_error("--since= must be before --until=.");
739 return -EINVAL;
740 }
741
742 if (!!arg_cursor + !!arg_after_cursor + !!arg_since_set > 1) {
743 log_error("Please specify only one of --since=, --cursor=, and --after-cursor.");
744 return -EINVAL;
745 }
746
747 if (arg_follow && arg_reverse) {
748 log_error("Please specify either --reverse= or --follow=, not both.");
749 return -EINVAL;
750 }
751
752 if (!IN_SET(arg_action, ACTION_SHOW, ACTION_DUMP_CATALOG, ACTION_LIST_CATALOG) && optind < argc) {
753 log_error("Extraneous arguments starting with '%s'", argv[optind]);
754 return -EINVAL;
755 }
756
757 if ((arg_boot || arg_action == ACTION_LIST_BOOTS) && (arg_file || arg_directory || arg_merge)) {
758 log_error("Using --boot or --list-boots with --file, --directory or --merge is not supported.");
759 return -EINVAL;
760 }
761
762 return 1;
763 }
764
765 static int generate_new_id128(void) {
766 sd_id128_t id;
767 int r;
768 unsigned i;
769
770 r = sd_id128_randomize(&id);
771 if (r < 0)
772 return log_error_errno(r, "Failed to generate ID: %m");
773
774 printf("As string:\n"
775 SD_ID128_FORMAT_STR "\n\n"
776 "As UUID:\n"
777 "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n\n"
778 "As macro:\n"
779 "#define MESSAGE_XYZ SD_ID128_MAKE(",
780 SD_ID128_FORMAT_VAL(id),
781 SD_ID128_FORMAT_VAL(id));
782 for (i = 0; i < 16; i++)
783 printf("%02x%s", id.bytes[i], i != 15 ? "," : "");
784 fputs(")\n\n", stdout);
785
786 printf("As Python constant:\n"
787 ">>> import uuid\n"
788 ">>> MESSAGE_XYZ = uuid.UUID('" SD_ID128_FORMAT_STR "')\n",
789 SD_ID128_FORMAT_VAL(id));
790
791 return 0;
792 }
793
794 static int add_matches(sd_journal *j, char **args) {
795 char **i;
796 bool have_term = false;
797
798 assert(j);
799
800 STRV_FOREACH(i, args) {
801 int r;
802
803 if (streq(*i, "+")) {
804 if (!have_term)
805 break;
806 r = sd_journal_add_disjunction(j);
807 have_term = false;
808
809 } else if (path_is_absolute(*i)) {
810 _cleanup_free_ char *p, *t = NULL, *t2 = NULL;
811 const char *path;
812 _cleanup_free_ char *interpreter = NULL;
813 struct stat st;
814
815 p = canonicalize_file_name(*i);
816 path = p ? p : *i;
817
818 if (lstat(path, &st) < 0)
819 return log_error_errno(errno, "Couldn't stat file: %m");
820
821 if (S_ISREG(st.st_mode) && (0111 & st.st_mode)) {
822 if (executable_is_script(path, &interpreter) > 0) {
823 _cleanup_free_ char *comm;
824
825 comm = strndup(basename(path), 15);
826 if (!comm)
827 return log_oom();
828
829 t = strappend("_COMM=", comm);
830
831 /* Append _EXE only if the interpreter is not a link.
832 Otherwise, it might be outdated often. */
833 if (lstat(interpreter, &st) == 0 &&
834 !S_ISLNK(st.st_mode)) {
835 t2 = strappend("_EXE=", interpreter);
836 if (!t2)
837 return log_oom();
838 }
839 } else
840 t = strappend("_EXE=", path);
841 } else if (S_ISCHR(st.st_mode))
842 (void) asprintf(&t, "_KERNEL_DEVICE=c%u:%u", major(st.st_rdev), minor(st.st_rdev));
843 else if (S_ISBLK(st.st_mode))
844 (void) asprintf(&t, "_KERNEL_DEVICE=b%u:%u", major(st.st_rdev), minor(st.st_rdev));
845 else {
846 log_error("File is neither a device node, nor regular file, nor executable: %s", *i);
847 return -EINVAL;
848 }
849
850 if (!t)
851 return log_oom();
852
853 r = sd_journal_add_match(j, t, 0);
854 if (t2)
855 r = sd_journal_add_match(j, t2, 0);
856 have_term = true;
857
858 } else {
859 r = sd_journal_add_match(j, *i, 0);
860 have_term = true;
861 }
862
863 if (r < 0)
864 return log_error_errno(r, "Failed to add match '%s': %m", *i);
865 }
866
867 if (!strv_isempty(args) && !have_term) {
868 log_error("\"+\" can only be used between terms");
869 return -EINVAL;
870 }
871
872 return 0;
873 }
874
875 static void boot_id_free_all(BootId *l) {
876
877 while (l) {
878 BootId *i = l;
879 LIST_REMOVE(boot_list, l, i);
880 free(i);
881 }
882 }
883
884 static int discover_next_boot(
885 sd_journal *j,
886 BootId **boot,
887 bool advance_older,
888 bool read_realtime) {
889
890 int r;
891 char match[9+32+1] = "_BOOT_ID=";
892 _cleanup_free_ BootId *next_boot = NULL;
893
894 assert(j);
895 assert(boot);
896
897 /* We expect the journal to be on the last position of a boot
898 * (in relation to the direction we are going), so that the next
899 * invocation of sd_journal_next/previous will be from a different
900 * boot. We then collect any information we desire and then jump
901 * to the last location of the new boot by using a _BOOT_ID match
902 * coming from the other journal direction. */
903
904 /* Make sure we aren't restricted by any _BOOT_ID matches, so that
905 * we can actually advance to a *different* boot. */
906 sd_journal_flush_matches(j);
907
908 if (advance_older)
909 r = sd_journal_previous(j);
910 else
911 r = sd_journal_next(j);
912 if (r < 0)
913 return r;
914 else if (r == 0)
915 return 0; /* End of journal, yay. */
916
917 next_boot = new0(BootId, 1);
918 if (!next_boot)
919 return -ENOMEM;
920
921 r = sd_journal_get_monotonic_usec(j, NULL, &next_boot->id);
922 if (r < 0)
923 return r;
924
925 if (read_realtime) {
926 r = sd_journal_get_realtime_usec(j, &next_boot->first);
927 if (r < 0)
928 return r;
929 }
930
931 /* Now seek to the last occurrence of this boot ID. */
932 sd_id128_to_string(next_boot->id, match + 9);
933 r = sd_journal_add_match(j, match, sizeof(match) - 1);
934 if (r < 0)
935 return r;
936
937 if (advance_older)
938 r = sd_journal_seek_head(j);
939 else
940 r = sd_journal_seek_tail(j);
941 if (r < 0)
942 return r;
943
944 if (advance_older)
945 r = sd_journal_next(j);
946 else
947 r = sd_journal_previous(j);
948 if (r < 0)
949 return r;
950 else if (r == 0)
951 return -ENODATA; /* This shouldn't happen. We just came from this very boot ID. */
952
953 if (read_realtime) {
954 r = sd_journal_get_realtime_usec(j, &next_boot->last);
955 if (r < 0)
956 return r;
957 }
958
959 *boot = next_boot;
960 next_boot = NULL;
961
962 return 0;
963 }
964
965 static int get_boots(
966 sd_journal *j,
967 BootId **boots,
968 BootId *query_ref_boot,
969 int ref_boot_offset) {
970
971 bool skip_once;
972 int r, count = 0;
973 BootId *head = NULL, *tail = NULL;
974 const bool advance_older = query_ref_boot && ref_boot_offset <= 0;
975
976 assert(j);
977
978 /* Adjust for the asymmetry that offset 0 is
979 * the last (and current) boot, while 1 is considered the
980 * (chronological) first boot in the journal. */
981 skip_once = query_ref_boot && sd_id128_is_null(query_ref_boot->id) && ref_boot_offset < 0;
982
983 /* Advance to the earliest/latest occurrence of our reference
984 * boot ID (taking our lookup direction into account), so that
985 * discover_next_boot() can do its job.
986 * If no reference is given, the journal head/tail will do,
987 * they're "virtual" boots after all. */
988 if (query_ref_boot && !sd_id128_is_null(query_ref_boot->id)) {
989 char match[9+32+1] = "_BOOT_ID=";
990
991 sd_journal_flush_matches(j);
992
993 sd_id128_to_string(query_ref_boot->id, match + 9);
994 r = sd_journal_add_match(j, match, sizeof(match) - 1);
995 if (r < 0)
996 return r;
997
998 if (advance_older)
999 r = sd_journal_seek_head(j);
1000 else
1001 r = sd_journal_seek_tail(j);
1002 if (r < 0)
1003 return r;
1004
1005 if (advance_older)
1006 r = sd_journal_next(j);
1007 else
1008 r = sd_journal_previous(j);
1009 if (r < 0)
1010 return r;
1011 else if (r == 0)
1012 goto finish;
1013 else if (ref_boot_offset == 0) {
1014 count = 1;
1015 goto finish;
1016 }
1017 } else {
1018 if (advance_older)
1019 r = sd_journal_seek_tail(j);
1020 else
1021 r = sd_journal_seek_head(j);
1022 if (r < 0)
1023 return r;
1024
1025 /* No sd_journal_next/previous here. */
1026 }
1027
1028 for (;;) {
1029 _cleanup_free_ BootId *current = NULL;
1030
1031 r = discover_next_boot(j, &current, advance_older, !query_ref_boot);
1032 if (r < 0) {
1033 boot_id_free_all(head);
1034 return r;
1035 }
1036
1037 if (!current)
1038 break;
1039
1040 if (query_ref_boot) {
1041 if (!skip_once)
1042 ref_boot_offset += advance_older ? 1 : -1;
1043 skip_once = false;
1044
1045 if (ref_boot_offset == 0) {
1046 count = 1;
1047 query_ref_boot->id = current->id;
1048 break;
1049 }
1050 } else {
1051 LIST_INSERT_AFTER(boot_list, head, tail, current);
1052 tail = current;
1053 current = NULL;
1054 count++;
1055 }
1056 }
1057
1058 finish:
1059 if (boots)
1060 *boots = head;
1061
1062 sd_journal_flush_matches(j);
1063
1064 return count;
1065 }
1066
1067 static int list_boots(sd_journal *j) {
1068 int w, i, count;
1069 BootId *id, *all_ids;
1070
1071 assert(j);
1072
1073 count = get_boots(j, &all_ids, NULL, 0);
1074 if (count < 0)
1075 return log_error_errno(count, "Failed to determine boots: %m");
1076 if (count == 0)
1077 return count;
1078
1079 pager_open_if_enabled();
1080
1081 /* numbers are one less, but we need an extra char for the sign */
1082 w = DECIMAL_STR_WIDTH(count - 1) + 1;
1083
1084 i = 0;
1085 LIST_FOREACH(boot_list, id, all_ids) {
1086 char a[FORMAT_TIMESTAMP_MAX], b[FORMAT_TIMESTAMP_MAX];
1087
1088 printf("% *i " SD_ID128_FORMAT_STR " %s—%s\n",
1089 w, i - count + 1,
1090 SD_ID128_FORMAT_VAL(id->id),
1091 format_timestamp_maybe_utc(a, sizeof(a), id->first),
1092 format_timestamp_maybe_utc(b, sizeof(b), id->last));
1093 i++;
1094 }
1095
1096 boot_id_free_all(all_ids);
1097
1098 return 0;
1099 }
1100
1101 static int add_boot(sd_journal *j) {
1102 char match[9+32+1] = "_BOOT_ID=";
1103 int r;
1104 BootId ref_boot_id = {};
1105
1106 assert(j);
1107
1108 if (!arg_boot)
1109 return 0;
1110
1111 if (arg_boot_offset == 0 && sd_id128_equal(arg_boot_id, SD_ID128_NULL))
1112 return add_match_this_boot(j, arg_machine);
1113
1114 ref_boot_id.id = arg_boot_id;
1115 r = get_boots(j, NULL, &ref_boot_id, arg_boot_offset);
1116 assert(r <= 1);
1117 if (r <= 0) {
1118 const char *reason = (r == 0) ? "No such boot ID in journal" : strerror(-r);
1119
1120 if (sd_id128_is_null(arg_boot_id))
1121 log_error("Failed to look up boot %+i: %s", arg_boot_offset, reason);
1122 else
1123 log_error("Failed to look up boot ID "SD_ID128_FORMAT_STR"%+i: %s",
1124 SD_ID128_FORMAT_VAL(arg_boot_id), arg_boot_offset, reason);
1125
1126 return r == 0 ? -ENODATA : r;
1127 }
1128
1129 sd_id128_to_string(ref_boot_id.id, match + 9);
1130
1131 r = sd_journal_add_match(j, match, sizeof(match) - 1);
1132 if (r < 0)
1133 return log_error_errno(r, "Failed to add match: %m");
1134
1135 r = sd_journal_add_conjunction(j);
1136 if (r < 0)
1137 return log_error_errno(r, "Failed to add conjunction: %m");
1138
1139 return 0;
1140 }
1141
1142 static int add_dmesg(sd_journal *j) {
1143 int r;
1144 assert(j);
1145
1146 if (!arg_dmesg)
1147 return 0;
1148
1149 r = sd_journal_add_match(j, "_TRANSPORT=kernel", strlen("_TRANSPORT=kernel"));
1150 if (r < 0)
1151 return log_error_errno(r, "Failed to add match: %m");
1152
1153 r = sd_journal_add_conjunction(j);
1154 if (r < 0)
1155 return log_error_errno(r, "Failed to add conjunction: %m");
1156
1157 return 0;
1158 }
1159
1160 static int get_possible_units(
1161 sd_journal *j,
1162 const char *fields,
1163 char **patterns,
1164 Set **units) {
1165
1166 _cleanup_set_free_free_ Set *found;
1167 const char *field;
1168 int r;
1169
1170 found = set_new(&string_hash_ops);
1171 if (!found)
1172 return -ENOMEM;
1173
1174 NULSTR_FOREACH(field, fields) {
1175 const void *data;
1176 size_t size;
1177
1178 r = sd_journal_query_unique(j, field);
1179 if (r < 0)
1180 return r;
1181
1182 SD_JOURNAL_FOREACH_UNIQUE(j, data, size) {
1183 char **pattern, *eq;
1184 size_t prefix;
1185 _cleanup_free_ char *u = NULL;
1186
1187 eq = memchr(data, '=', size);
1188 if (eq)
1189 prefix = eq - (char*) data + 1;
1190 else
1191 prefix = 0;
1192
1193 u = strndup((char*) data + prefix, size - prefix);
1194 if (!u)
1195 return -ENOMEM;
1196
1197 STRV_FOREACH(pattern, patterns)
1198 if (fnmatch(*pattern, u, FNM_NOESCAPE) == 0) {
1199 log_debug("Matched %s with pattern %s=%s", u, field, *pattern);
1200
1201 r = set_consume(found, u);
1202 u = NULL;
1203 if (r < 0 && r != -EEXIST)
1204 return r;
1205
1206 break;
1207 }
1208 }
1209 }
1210
1211 *units = found;
1212 found = NULL;
1213 return 0;
1214 }
1215
1216 /* This list is supposed to return the superset of unit names
1217 * possibly matched by rules added with add_matches_for_unit... */
1218 #define SYSTEM_UNITS \
1219 "_SYSTEMD_UNIT\0" \
1220 "COREDUMP_UNIT\0" \
1221 "UNIT\0" \
1222 "OBJECT_SYSTEMD_UNIT\0" \
1223 "_SYSTEMD_SLICE\0"
1224
1225 /* ... and add_matches_for_user_unit */
1226 #define USER_UNITS \
1227 "_SYSTEMD_USER_UNIT\0" \
1228 "USER_UNIT\0" \
1229 "COREDUMP_USER_UNIT\0" \
1230 "OBJECT_SYSTEMD_USER_UNIT\0"
1231
1232 static int add_units(sd_journal *j) {
1233 _cleanup_strv_free_ char **patterns = NULL;
1234 int r, count = 0;
1235 char **i;
1236
1237 assert(j);
1238
1239 STRV_FOREACH(i, arg_system_units) {
1240 _cleanup_free_ char *u = NULL;
1241
1242 r = unit_name_mangle(*i, UNIT_NAME_GLOB, &u);
1243 if (r < 0)
1244 return r;
1245
1246 if (string_is_glob(u)) {
1247 r = strv_push(&patterns, u);
1248 if (r < 0)
1249 return r;
1250 u = NULL;
1251 } else {
1252 r = add_matches_for_unit(j, u);
1253 if (r < 0)
1254 return r;
1255 r = sd_journal_add_disjunction(j);
1256 if (r < 0)
1257 return r;
1258 count ++;
1259 }
1260 }
1261
1262 if (!strv_isempty(patterns)) {
1263 _cleanup_set_free_free_ Set *units = NULL;
1264 Iterator it;
1265 char *u;
1266
1267 r = get_possible_units(j, SYSTEM_UNITS, patterns, &units);
1268 if (r < 0)
1269 return r;
1270
1271 SET_FOREACH(u, units, it) {
1272 r = add_matches_for_unit(j, u);
1273 if (r < 0)
1274 return r;
1275 r = sd_journal_add_disjunction(j);
1276 if (r < 0)
1277 return r;
1278 count ++;
1279 }
1280 }
1281
1282 patterns = strv_free(patterns);
1283
1284 STRV_FOREACH(i, arg_user_units) {
1285 _cleanup_free_ char *u = NULL;
1286
1287 r = unit_name_mangle(*i, UNIT_NAME_GLOB, &u);
1288 if (r < 0)
1289 return r;
1290
1291 if (string_is_glob(u)) {
1292 r = strv_push(&patterns, u);
1293 if (r < 0)
1294 return r;
1295 u = NULL;
1296 } else {
1297 r = add_matches_for_user_unit(j, u, getuid());
1298 if (r < 0)
1299 return r;
1300 r = sd_journal_add_disjunction(j);
1301 if (r < 0)
1302 return r;
1303 count ++;
1304 }
1305 }
1306
1307 if (!strv_isempty(patterns)) {
1308 _cleanup_set_free_free_ Set *units = NULL;
1309 Iterator it;
1310 char *u;
1311
1312 r = get_possible_units(j, USER_UNITS, patterns, &units);
1313 if (r < 0)
1314 return r;
1315
1316 SET_FOREACH(u, units, it) {
1317 r = add_matches_for_user_unit(j, u, getuid());
1318 if (r < 0)
1319 return r;
1320 r = sd_journal_add_disjunction(j);
1321 if (r < 0)
1322 return r;
1323 count ++;
1324 }
1325 }
1326
1327 /* Complain if the user request matches but nothing whatsoever was
1328 * found, since otherwise everything would be matched. */
1329 if (!(strv_isempty(arg_system_units) && strv_isempty(arg_user_units)) && count == 0)
1330 return -ENODATA;
1331
1332 r = sd_journal_add_conjunction(j);
1333 if (r < 0)
1334 return r;
1335
1336 return 0;
1337 }
1338
1339 static int add_priorities(sd_journal *j) {
1340 char match[] = "PRIORITY=0";
1341 int i, r;
1342 assert(j);
1343
1344 if (arg_priorities == 0xFF)
1345 return 0;
1346
1347 for (i = LOG_EMERG; i <= LOG_DEBUG; i++)
1348 if (arg_priorities & (1 << i)) {
1349 match[sizeof(match)-2] = '0' + i;
1350
1351 r = sd_journal_add_match(j, match, strlen(match));
1352 if (r < 0)
1353 return log_error_errno(r, "Failed to add match: %m");
1354 }
1355
1356 r = sd_journal_add_conjunction(j);
1357 if (r < 0)
1358 return log_error_errno(r, "Failed to add conjunction: %m");
1359
1360 return 0;
1361 }
1362
1363
1364 static int add_syslog_identifier(sd_journal *j) {
1365 int r;
1366 char **i;
1367
1368 assert(j);
1369
1370 STRV_FOREACH(i, arg_syslog_identifier) {
1371 char *u;
1372
1373 u = strjoina("SYSLOG_IDENTIFIER=", *i);
1374 r = sd_journal_add_match(j, u, 0);
1375 if (r < 0)
1376 return r;
1377 r = sd_journal_add_disjunction(j);
1378 if (r < 0)
1379 return r;
1380 }
1381
1382 r = sd_journal_add_conjunction(j);
1383 if (r < 0)
1384 return r;
1385
1386 return 0;
1387 }
1388
1389 static int setup_keys(void) {
1390 #ifdef HAVE_GCRYPT
1391 size_t mpk_size, seed_size, state_size, i;
1392 uint8_t *mpk, *seed, *state;
1393 int fd = -1, r;
1394 sd_id128_t machine, boot;
1395 char *p = NULL, *k = NULL;
1396 struct FSSHeader h;
1397 uint64_t n;
1398 struct stat st;
1399
1400 r = stat("/var/log/journal", &st);
1401 if (r < 0 && errno != ENOENT && errno != ENOTDIR)
1402 return log_error_errno(errno, "stat(\"%s\") failed: %m", "/var/log/journal");
1403
1404 if (r < 0 || !S_ISDIR(st.st_mode)) {
1405 log_error("%s is not a directory, must be using persistent logging for FSS.",
1406 "/var/log/journal");
1407 return r < 0 ? -errno : -ENOTDIR;
1408 }
1409
1410 r = sd_id128_get_machine(&machine);
1411 if (r < 0)
1412 return log_error_errno(r, "Failed to get machine ID: %m");
1413
1414 r = sd_id128_get_boot(&boot);
1415 if (r < 0)
1416 return log_error_errno(r, "Failed to get boot ID: %m");
1417
1418 if (asprintf(&p, "/var/log/journal/" SD_ID128_FORMAT_STR "/fss",
1419 SD_ID128_FORMAT_VAL(machine)) < 0)
1420 return log_oom();
1421
1422 if (arg_force) {
1423 r = unlink(p);
1424 if (r < 0 && errno != ENOENT) {
1425 r = log_error_errno(errno, "unlink(\"%s\") failed: %m", p);
1426 goto finish;
1427 }
1428 } else if (access(p, F_OK) >= 0) {
1429 log_error("Sealing key file %s exists already. Use --force to recreate.", p);
1430 r = -EEXIST;
1431 goto finish;
1432 }
1433
1434 if (asprintf(&k, "/var/log/journal/" SD_ID128_FORMAT_STR "/fss.tmp.XXXXXX",
1435 SD_ID128_FORMAT_VAL(machine)) < 0) {
1436 r = log_oom();
1437 goto finish;
1438 }
1439
1440 mpk_size = FSPRG_mskinbytes(FSPRG_RECOMMENDED_SECPAR);
1441 mpk = alloca(mpk_size);
1442
1443 seed_size = FSPRG_RECOMMENDED_SEEDLEN;
1444 seed = alloca(seed_size);
1445
1446 state_size = FSPRG_stateinbytes(FSPRG_RECOMMENDED_SECPAR);
1447 state = alloca(state_size);
1448
1449 fd = open("/dev/random", O_RDONLY|O_CLOEXEC|O_NOCTTY);
1450 if (fd < 0) {
1451 r = log_error_errno(errno, "Failed to open /dev/random: %m");
1452 goto finish;
1453 }
1454
1455 log_info("Generating seed...");
1456 r = loop_read_exact(fd, seed, seed_size, true);
1457 if (r < 0) {
1458 log_error_errno(r, "Failed to read random seed: %m");
1459 goto finish;
1460 }
1461
1462 log_info("Generating key pair...");
1463 FSPRG_GenMK(NULL, mpk, seed, seed_size, FSPRG_RECOMMENDED_SECPAR);
1464
1465 log_info("Generating sealing key...");
1466 FSPRG_GenState0(state, mpk, seed, seed_size);
1467
1468 assert(arg_interval > 0);
1469
1470 n = now(CLOCK_REALTIME);
1471 n /= arg_interval;
1472
1473 safe_close(fd);
1474 fd = mkostemp_safe(k, O_WRONLY|O_CLOEXEC);
1475 if (fd < 0) {
1476 r = log_error_errno(errno, "Failed to open %s: %m", k);
1477 goto finish;
1478 }
1479
1480 /* Enable secure remove, exclusion from dump, synchronous
1481 * writing and in-place updating */
1482 r = chattr_fd(fd, FS_SECRM_FL|FS_NODUMP_FL|FS_SYNC_FL|FS_NOCOW_FL, FS_SECRM_FL|FS_NODUMP_FL|FS_SYNC_FL|FS_NOCOW_FL);
1483 if (r < 0)
1484 log_warning_errno(errno, "Failed to set file attributes: %m");
1485
1486 zero(h);
1487 memcpy(h.signature, "KSHHRHLP", 8);
1488 h.machine_id = machine;
1489 h.boot_id = boot;
1490 h.header_size = htole64(sizeof(h));
1491 h.start_usec = htole64(n * arg_interval);
1492 h.interval_usec = htole64(arg_interval);
1493 h.fsprg_secpar = htole16(FSPRG_RECOMMENDED_SECPAR);
1494 h.fsprg_state_size = htole64(state_size);
1495
1496 r = loop_write(fd, &h, sizeof(h), false);
1497 if (r < 0) {
1498 log_error_errno(r, "Failed to write header: %m");
1499 goto finish;
1500 }
1501
1502 r = loop_write(fd, state, state_size, false);
1503 if (r < 0) {
1504 log_error_errno(r, "Failed to write state: %m");
1505 goto finish;
1506 }
1507
1508 if (link(k, p) < 0) {
1509 r = log_error_errno(errno, "Failed to link file: %m");
1510 goto finish;
1511 }
1512
1513 if (on_tty()) {
1514 fprintf(stderr,
1515 "\n"
1516 "The new key pair has been generated. The " ANSI_HIGHLIGHT "secret sealing key" ANSI_NORMAL " has been written to\n"
1517 "the following local file. This key file is automatically updated when the\n"
1518 "sealing key is advanced. It should not be used on multiple hosts.\n"
1519 "\n"
1520 "\t%s\n"
1521 "\n"
1522 "Please write down the following " ANSI_HIGHLIGHT "secret verification key" ANSI_NORMAL ". It should be stored\n"
1523 "at a safe location and should not be saved locally on disk.\n"
1524 "\n\t" ANSI_HIGHLIGHT_RED, p);
1525 fflush(stderr);
1526 }
1527 for (i = 0; i < seed_size; i++) {
1528 if (i > 0 && i % 3 == 0)
1529 putchar('-');
1530 printf("%02x", ((uint8_t*) seed)[i]);
1531 }
1532
1533 printf("/%llx-%llx\n", (unsigned long long) n, (unsigned long long) arg_interval);
1534
1535 if (on_tty()) {
1536 char tsb[FORMAT_TIMESPAN_MAX], *hn;
1537
1538 fprintf(stderr,
1539 ANSI_NORMAL "\n"
1540 "The sealing key is automatically changed every %s.\n",
1541 format_timespan(tsb, sizeof(tsb), arg_interval, 0));
1542
1543 hn = gethostname_malloc();
1544
1545 if (hn) {
1546 hostname_cleanup(hn);
1547 fprintf(stderr, "\nThe keys have been generated for host %s/" SD_ID128_FORMAT_STR ".\n", hn, SD_ID128_FORMAT_VAL(machine));
1548 } else
1549 fprintf(stderr, "\nThe keys have been generated for host " SD_ID128_FORMAT_STR ".\n", SD_ID128_FORMAT_VAL(machine));
1550
1551 #ifdef HAVE_QRENCODE
1552 /* If this is not an UTF-8 system don't print any QR codes */
1553 if (is_locale_utf8()) {
1554 fputs("\nTo transfer the verification key to your phone please scan the QR code below:\n\n", stderr);
1555 print_qr_code(stderr, seed, seed_size, n, arg_interval, hn, machine);
1556 }
1557 #endif
1558 free(hn);
1559 }
1560
1561 r = 0;
1562
1563 finish:
1564 safe_close(fd);
1565
1566 if (k) {
1567 unlink(k);
1568 free(k);
1569 }
1570
1571 free(p);
1572
1573 return r;
1574 #else
1575 log_error("Forward-secure sealing not available.");
1576 return -EOPNOTSUPP;
1577 #endif
1578 }
1579
1580 static int verify(sd_journal *j) {
1581 int r = 0;
1582 Iterator i;
1583 JournalFile *f;
1584
1585 assert(j);
1586
1587 log_show_color(true);
1588
1589 ORDERED_HASHMAP_FOREACH(f, j->files, i) {
1590 int k;
1591 usec_t first = 0, validated = 0, last = 0;
1592
1593 #ifdef HAVE_GCRYPT
1594 if (!arg_verify_key && JOURNAL_HEADER_SEALED(f->header))
1595 log_notice("Journal file %s has sealing enabled but verification key has not been passed using --verify-key=.", f->path);
1596 #endif
1597
1598 k = journal_file_verify(f, arg_verify_key, &first, &validated, &last, true);
1599 if (k == -EINVAL) {
1600 /* If the key was invalid give up right-away. */
1601 return k;
1602 } else if (k < 0) {
1603 log_warning_errno(k, "FAIL: %s (%m)", f->path);
1604 r = k;
1605 } else {
1606 char a[FORMAT_TIMESTAMP_MAX], b[FORMAT_TIMESTAMP_MAX], c[FORMAT_TIMESPAN_MAX];
1607 log_info("PASS: %s", f->path);
1608
1609 if (arg_verify_key && JOURNAL_HEADER_SEALED(f->header)) {
1610 if (validated > 0) {
1611 log_info("=> Validated from %s to %s, final %s entries not sealed.",
1612 format_timestamp_maybe_utc(a, sizeof(a), first),
1613 format_timestamp_maybe_utc(b, sizeof(b), validated),
1614 format_timespan(c, sizeof(c), last > validated ? last - validated : 0, 0));
1615 } else if (last > 0)
1616 log_info("=> No sealing yet, %s of entries not sealed.",
1617 format_timespan(c, sizeof(c), last - first, 0));
1618 else
1619 log_info("=> No sealing yet, no entries in file.");
1620 }
1621 }
1622 }
1623
1624 return r;
1625 }
1626
1627 static int access_check_var_log_journal(sd_journal *j) {
1628 #ifdef HAVE_ACL
1629 _cleanup_strv_free_ char **g = NULL;
1630 const char* dir;
1631 #endif
1632 int r;
1633
1634 assert(j);
1635
1636 if (arg_quiet)
1637 return 0;
1638
1639 /* If we are root, we should have access, don't warn. */
1640 if (getuid() == 0)
1641 return 0;
1642
1643 /* If we are in the 'systemd-journal' group, we should have
1644 * access too. */
1645 r = in_group("systemd-journal");
1646 if (r < 0)
1647 return log_error_errno(r, "Failed to check if we are in the 'systemd-journal' group: %m");
1648 if (r > 0)
1649 return 0;
1650
1651 #ifdef HAVE_ACL
1652 if (laccess("/run/log/journal", F_OK) >= 0)
1653 dir = "/run/log/journal";
1654 else
1655 dir = "/var/log/journal";
1656
1657 /* If we are in any of the groups listed in the journal ACLs,
1658 * then all is good, too. Let's enumerate all groups from the
1659 * default ACL of the directory, which generally should allow
1660 * access to most journal files too. */
1661 r = acl_search_groups(dir, &g);
1662 if (r < 0)
1663 return log_error_errno(r, "Failed to search journal ACL: %m");
1664 if (r > 0)
1665 return 0;
1666
1667 /* Print a pretty list, if there were ACLs set. */
1668 if (!strv_isempty(g)) {
1669 _cleanup_free_ char *s = NULL;
1670
1671 /* Thre are groups in the ACL, let's list them */
1672 r = strv_extend(&g, "systemd-journal");
1673 if (r < 0)
1674 return log_oom();
1675
1676 strv_sort(g);
1677 strv_uniq(g);
1678
1679 s = strv_join(g, "', '");
1680 if (!s)
1681 return log_oom();
1682
1683 log_notice("Hint: You are currently not seeing messages from other users and the system.\n"
1684 " Users in groups '%s' can see all messages.\n"
1685 " Pass -q to turn off this notice.", s);
1686 return 1;
1687 }
1688 #endif
1689
1690 /* If no ACLs were found, print a short version of the message. */
1691 log_notice("Hint: You are currently not seeing messages from other users and the system.\n"
1692 " Users in the 'systemd-journal' group can see all messages. Pass -q to\n"
1693 " turn off this notice.");
1694
1695 return 1;
1696 }
1697
1698 static int access_check(sd_journal *j) {
1699 Iterator it;
1700 void *code;
1701 int r = 0;
1702
1703 assert(j);
1704
1705 if (set_isempty(j->errors)) {
1706 if (ordered_hashmap_isempty(j->files))
1707 log_notice("No journal files were found.");
1708
1709 return 0;
1710 }
1711
1712 if (set_contains(j->errors, INT_TO_PTR(-EACCES))) {
1713 (void) access_check_var_log_journal(j);
1714
1715 if (ordered_hashmap_isempty(j->files))
1716 r = log_error_errno(EACCES, "No journal files were opened due to insufficient permissions.");
1717 }
1718
1719 SET_FOREACH(code, j->errors, it) {
1720 int err;
1721
1722 err = -PTR_TO_INT(code);
1723 assert(err > 0);
1724
1725 if (err == EACCES)
1726 continue;
1727
1728 log_warning_errno(err, "Error was encountered while opening journal files: %m");
1729 if (r == 0)
1730 r = -err;
1731 }
1732
1733 return r;
1734 }
1735
1736 static int flush_to_var(void) {
1737 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1738 _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL;
1739 _cleanup_close_ int watch_fd = -1;
1740 int r;
1741
1742 /* Quick exit */
1743 if (access("/run/systemd/journal/flushed", F_OK) >= 0)
1744 return 0;
1745
1746 /* OK, let's actually do the full logic, send SIGUSR1 to the
1747 * daemon and set up inotify to wait for the flushed file to appear */
1748 r = bus_connect_system_systemd(&bus);
1749 if (r < 0)
1750 return log_error_errno(r, "Failed to get D-Bus connection: %m");
1751
1752 r = sd_bus_call_method(
1753 bus,
1754 "org.freedesktop.systemd1",
1755 "/org/freedesktop/systemd1",
1756 "org.freedesktop.systemd1.Manager",
1757 "KillUnit",
1758 &error,
1759 NULL,
1760 "ssi", "systemd-journald.service", "main", SIGUSR1);
1761 if (r < 0) {
1762 log_error("Failed to kill journal service: %s", bus_error_message(&error, r));
1763 return r;
1764 }
1765
1766 mkdir_p("/run/systemd/journal", 0755);
1767
1768 watch_fd = inotify_init1(IN_NONBLOCK|IN_CLOEXEC);
1769 if (watch_fd < 0)
1770 return log_error_errno(errno, "Failed to create inotify watch: %m");
1771
1772 r = inotify_add_watch(watch_fd, "/run/systemd/journal", IN_CREATE|IN_DONT_FOLLOW|IN_ONLYDIR);
1773 if (r < 0)
1774 return log_error_errno(errno, "Failed to watch journal directory: %m");
1775
1776 for (;;) {
1777 if (access("/run/systemd/journal/flushed", F_OK) >= 0)
1778 break;
1779
1780 if (errno != ENOENT)
1781 return log_error_errno(errno, "Failed to check for existence of /run/systemd/journal/flushed: %m");
1782
1783 r = fd_wait_for_event(watch_fd, POLLIN, USEC_INFINITY);
1784 if (r < 0)
1785 return log_error_errno(r, "Failed to wait for event: %m");
1786
1787 r = flush_fd(watch_fd);
1788 if (r < 0)
1789 return log_error_errno(r, "Failed to flush inotify events: %m");
1790 }
1791
1792 return 0;
1793 }
1794
1795 static int rotate(void) {
1796 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1797 _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL;
1798 int r;
1799
1800 r = bus_connect_system_systemd(&bus);
1801 if (r < 0)
1802 return log_error_errno(r, "Failed to get D-Bus connection: %m");
1803
1804 r = sd_bus_call_method(
1805 bus,
1806 "org.freedesktop.systemd1",
1807 "/org/freedesktop/systemd1",
1808 "org.freedesktop.systemd1.Manager",
1809 "KillUnit",
1810 &error,
1811 NULL,
1812 "ssi", "systemd-journald.service", "main", SIGUSR2);
1813 if (r < 0)
1814 return log_error_errno(r, "Failed to kill journal service: %s", bus_error_message(&error, r));
1815
1816 return 0;
1817 }
1818
1819 int main(int argc, char *argv[]) {
1820 int r;
1821 _cleanup_journal_close_ sd_journal *j = NULL;
1822 bool need_seek = false;
1823 sd_id128_t previous_boot_id;
1824 bool previous_boot_id_valid = false, first_line = true;
1825 int n_shown = 0;
1826 bool ellipsized = false;
1827
1828 setlocale(LC_ALL, "");
1829 log_parse_environment();
1830 log_open();
1831
1832 r = parse_argv(argc, argv);
1833 if (r <= 0)
1834 goto finish;
1835
1836 signal(SIGWINCH, columns_lines_cache_reset);
1837 sigbus_install();
1838
1839 /* Increase max number of open files to 16K if we can, we
1840 * might needs this when browsing journal files, which might
1841 * be split up into many files. */
1842 setrlimit_closest(RLIMIT_NOFILE, &RLIMIT_MAKE_CONST(16384));
1843
1844 if (arg_action == ACTION_NEW_ID128) {
1845 r = generate_new_id128();
1846 goto finish;
1847 }
1848
1849 if (arg_action == ACTION_FLUSH) {
1850 r = flush_to_var();
1851 goto finish;
1852 }
1853
1854 if (arg_action == ACTION_ROTATE) {
1855 r = rotate();
1856 goto finish;
1857 }
1858
1859 if (arg_action == ACTION_SETUP_KEYS) {
1860 r = setup_keys();
1861 goto finish;
1862 }
1863
1864 if (arg_action == ACTION_UPDATE_CATALOG ||
1865 arg_action == ACTION_LIST_CATALOG ||
1866 arg_action == ACTION_DUMP_CATALOG) {
1867
1868 _cleanup_free_ char *database;
1869
1870 database = path_join(arg_root, CATALOG_DATABASE, NULL);
1871 if (!database) {
1872 r = log_oom();
1873 goto finish;
1874 }
1875
1876 if (arg_action == ACTION_UPDATE_CATALOG) {
1877 r = catalog_update(database, arg_root, catalog_file_dirs);
1878 if (r < 0)
1879 log_error_errno(r, "Failed to list catalog: %m");
1880 } else {
1881 bool oneline = arg_action == ACTION_LIST_CATALOG;
1882
1883 pager_open_if_enabled();
1884 if (optind < argc)
1885 r = catalog_list_items(stdout, database,
1886 oneline, argv + optind);
1887 else
1888 r = catalog_list(stdout, database, oneline);
1889 if (r < 0)
1890 log_error_errno(r, "Failed to list catalog: %m");
1891 }
1892
1893 goto finish;
1894 }
1895
1896 if (arg_directory)
1897 r = sd_journal_open_directory(&j, arg_directory, arg_journal_type);
1898 else if (arg_file)
1899 r = sd_journal_open_files(&j, (const char**) arg_file, 0);
1900 else if (arg_machine)
1901 r = sd_journal_open_container(&j, arg_machine, 0);
1902 else
1903 r = sd_journal_open(&j, !arg_merge*SD_JOURNAL_LOCAL_ONLY + arg_journal_type);
1904 if (r < 0) {
1905 log_error_errno(r, "Failed to open %s: %m",
1906 arg_directory ? arg_directory : arg_file ? "files" : "journal");
1907 goto finish;
1908 }
1909
1910 r = access_check(j);
1911 if (r < 0)
1912 goto finish;
1913
1914 if (arg_action == ACTION_VERIFY) {
1915 r = verify(j);
1916 goto finish;
1917 }
1918
1919 if (arg_action == ACTION_PRINT_HEADER) {
1920 journal_print_header(j);
1921 r = 0;
1922 goto finish;
1923 }
1924
1925 if (arg_action == ACTION_DISK_USAGE) {
1926 uint64_t bytes = 0;
1927 char sbytes[FORMAT_BYTES_MAX];
1928
1929 r = sd_journal_get_usage(j, &bytes);
1930 if (r < 0)
1931 goto finish;
1932
1933 printf("Archived and active journals take up %s on disk.\n",
1934 format_bytes(sbytes, sizeof(sbytes), bytes));
1935 goto finish;
1936 }
1937
1938 if (arg_action == ACTION_VACUUM) {
1939 Directory *d;
1940 Iterator i;
1941
1942 HASHMAP_FOREACH(d, j->directories_by_path, i) {
1943 int q;
1944
1945 if (d->is_root)
1946 continue;
1947
1948 q = journal_directory_vacuum(d->path, arg_vacuum_size, arg_vacuum_n_files, arg_vacuum_time, NULL, true);
1949 if (q < 0) {
1950 log_error_errno(q, "Failed to vacuum %s: %m", d->path);
1951 r = q;
1952 }
1953 }
1954
1955 goto finish;
1956 }
1957
1958 if (arg_action == ACTION_LIST_BOOTS) {
1959 r = list_boots(j);
1960 goto finish;
1961 }
1962
1963 /* add_boot() must be called first!
1964 * It may need to seek the journal to find parent boot IDs. */
1965 r = add_boot(j);
1966 if (r < 0)
1967 goto finish;
1968
1969 r = add_dmesg(j);
1970 if (r < 0)
1971 goto finish;
1972
1973 r = add_units(j);
1974 if (r < 0) {
1975 log_error_errno(r, "Failed to add filter for units: %m");
1976 goto finish;
1977 }
1978
1979 r = add_syslog_identifier(j);
1980 if (r < 0) {
1981 log_error_errno(r, "Failed to add filter for syslog identifiers: %m");
1982 goto finish;
1983 }
1984
1985 r = add_priorities(j);
1986 if (r < 0)
1987 goto finish;
1988
1989 r = add_matches(j, argv + optind);
1990 if (r < 0)
1991 goto finish;
1992
1993 if (_unlikely_(log_get_max_level() >= LOG_DEBUG)) {
1994 _cleanup_free_ char *filter;
1995
1996 filter = journal_make_match_string(j);
1997 if (!filter)
1998 return log_oom();
1999
2000 log_debug("Journal filter: %s", filter);
2001 }
2002
2003 if (arg_field) {
2004 const void *data;
2005 size_t size;
2006
2007 r = sd_journal_set_data_threshold(j, 0);
2008 if (r < 0) {
2009 log_error_errno(r, "Failed to unset data size threshold: %m");
2010 goto finish;
2011 }
2012
2013 r = sd_journal_query_unique(j, arg_field);
2014 if (r < 0) {
2015 log_error_errno(r, "Failed to query unique data objects: %m");
2016 goto finish;
2017 }
2018
2019 SD_JOURNAL_FOREACH_UNIQUE(j, data, size) {
2020 const void *eq;
2021
2022 if (arg_lines >= 0 && n_shown >= arg_lines)
2023 break;
2024
2025 eq = memchr(data, '=', size);
2026 if (eq)
2027 printf("%.*s\n", (int) (size - ((const uint8_t*) eq - (const uint8_t*) data + 1)), (const char*) eq + 1);
2028 else
2029 printf("%.*s\n", (int) size, (const char*) data);
2030
2031 n_shown ++;
2032 }
2033
2034 r = 0;
2035 goto finish;
2036 }
2037
2038 /* Opening the fd now means the first sd_journal_wait() will actually wait */
2039 if (arg_follow) {
2040 r = sd_journal_get_fd(j);
2041 if (r < 0) {
2042 log_error_errno(r, "Failed to get journal fd: %m");
2043 goto finish;
2044 }
2045 }
2046
2047 if (arg_cursor || arg_after_cursor) {
2048 r = sd_journal_seek_cursor(j, arg_cursor ?: arg_after_cursor);
2049 if (r < 0) {
2050 log_error_errno(r, "Failed to seek to cursor: %m");
2051 goto finish;
2052 }
2053
2054 if (!arg_reverse)
2055 r = sd_journal_next_skip(j, 1 + !!arg_after_cursor);
2056 else
2057 r = sd_journal_previous_skip(j, 1 + !!arg_after_cursor);
2058
2059 if (arg_after_cursor && r < 2) {
2060 /* We couldn't find the next entry after the cursor. */
2061 if (arg_follow)
2062 need_seek = true;
2063 else
2064 arg_lines = 0;
2065 }
2066
2067 } else if (arg_since_set && !arg_reverse) {
2068 r = sd_journal_seek_realtime_usec(j, arg_since);
2069 if (r < 0) {
2070 log_error_errno(r, "Failed to seek to date: %m");
2071 goto finish;
2072 }
2073 r = sd_journal_next(j);
2074
2075 } else if (arg_until_set && arg_reverse) {
2076 r = sd_journal_seek_realtime_usec(j, arg_until);
2077 if (r < 0) {
2078 log_error_errno(r, "Failed to seek to date: %m");
2079 goto finish;
2080 }
2081 r = sd_journal_previous(j);
2082
2083 } else if (arg_lines >= 0) {
2084 r = sd_journal_seek_tail(j);
2085 if (r < 0) {
2086 log_error_errno(r, "Failed to seek to tail: %m");
2087 goto finish;
2088 }
2089
2090 r = sd_journal_previous_skip(j, arg_lines);
2091
2092 } else if (arg_reverse) {
2093 r = sd_journal_seek_tail(j);
2094 if (r < 0) {
2095 log_error_errno(r, "Failed to seek to tail: %m");
2096 goto finish;
2097 }
2098
2099 r = sd_journal_previous(j);
2100
2101 } else {
2102 r = sd_journal_seek_head(j);
2103 if (r < 0) {
2104 log_error_errno(r, "Failed to seek to head: %m");
2105 goto finish;
2106 }
2107
2108 r = sd_journal_next(j);
2109 }
2110
2111 if (r < 0) {
2112 log_error_errno(r, "Failed to iterate through journal: %m");
2113 goto finish;
2114 }
2115 if (r == 0) {
2116 if (arg_follow)
2117 need_seek = true;
2118 else {
2119 printf("-- No entries --\n");
2120 goto finish;
2121 }
2122 }
2123
2124 if (!arg_follow)
2125 pager_open_if_enabled();
2126
2127 if (!arg_quiet) {
2128 usec_t start, end;
2129 char start_buf[FORMAT_TIMESTAMP_MAX], end_buf[FORMAT_TIMESTAMP_MAX];
2130
2131 r = sd_journal_get_cutoff_realtime_usec(j, &start, &end);
2132 if (r < 0) {
2133 log_error_errno(r, "Failed to get cutoff: %m");
2134 goto finish;
2135 }
2136
2137 if (r > 0) {
2138 if (arg_follow)
2139 printf("-- Logs begin at %s. --\n",
2140 format_timestamp_maybe_utc(start_buf, sizeof(start_buf), start));
2141 else
2142 printf("-- Logs begin at %s, end at %s. --\n",
2143 format_timestamp_maybe_utc(start_buf, sizeof(start_buf), start),
2144 format_timestamp_maybe_utc(end_buf, sizeof(end_buf), end));
2145 }
2146 }
2147
2148 for (;;) {
2149 while (arg_lines < 0 || n_shown < arg_lines || (arg_follow && !first_line)) {
2150 int flags;
2151
2152 if (need_seek) {
2153 if (!arg_reverse)
2154 r = sd_journal_next(j);
2155 else
2156 r = sd_journal_previous(j);
2157 if (r < 0) {
2158 log_error_errno(r, "Failed to iterate through journal: %m");
2159 goto finish;
2160 }
2161 if (r == 0)
2162 break;
2163 }
2164
2165 if (arg_until_set && !arg_reverse) {
2166 usec_t usec;
2167
2168 r = sd_journal_get_realtime_usec(j, &usec);
2169 if (r < 0) {
2170 log_error_errno(r, "Failed to determine timestamp: %m");
2171 goto finish;
2172 }
2173 if (usec > arg_until)
2174 goto finish;
2175 }
2176
2177 if (arg_since_set && arg_reverse) {
2178 usec_t usec;
2179
2180 r = sd_journal_get_realtime_usec(j, &usec);
2181 if (r < 0) {
2182 log_error_errno(r, "Failed to determine timestamp: %m");
2183 goto finish;
2184 }
2185 if (usec < arg_since)
2186 goto finish;
2187 }
2188
2189 if (!arg_merge && !arg_quiet) {
2190 sd_id128_t boot_id;
2191
2192 r = sd_journal_get_monotonic_usec(j, NULL, &boot_id);
2193 if (r >= 0) {
2194 if (previous_boot_id_valid &&
2195 !sd_id128_equal(boot_id, previous_boot_id))
2196 printf("%s-- Reboot --%s\n",
2197 ansi_highlight(), ansi_normal());
2198
2199 previous_boot_id = boot_id;
2200 previous_boot_id_valid = true;
2201 }
2202 }
2203
2204 flags =
2205 arg_all * OUTPUT_SHOW_ALL |
2206 arg_full * OUTPUT_FULL_WIDTH |
2207 on_tty() * OUTPUT_COLOR |
2208 arg_catalog * OUTPUT_CATALOG |
2209 arg_utc * OUTPUT_UTC;
2210
2211 r = output_journal(stdout, j, arg_output, 0, flags, &ellipsized);
2212 need_seek = true;
2213 if (r == -EADDRNOTAVAIL)
2214 break;
2215 else if (r < 0 || ferror(stdout))
2216 goto finish;
2217
2218 n_shown++;
2219 }
2220
2221 if (!arg_follow) {
2222 if (arg_show_cursor) {
2223 _cleanup_free_ char *cursor = NULL;
2224
2225 r = sd_journal_get_cursor(j, &cursor);
2226 if (r < 0 && r != -EADDRNOTAVAIL)
2227 log_error_errno(r, "Failed to get cursor: %m");
2228 else if (r >= 0)
2229 printf("-- cursor: %s\n", cursor);
2230 }
2231
2232 break;
2233 }
2234
2235 r = sd_journal_wait(j, (uint64_t) -1);
2236 if (r < 0) {
2237 log_error_errno(r, "Couldn't wait for journal event: %m");
2238 goto finish;
2239 }
2240
2241 first_line = false;
2242 }
2243
2244 finish:
2245 pager_close();
2246
2247 strv_free(arg_file);
2248
2249 strv_free(arg_syslog_identifier);
2250 strv_free(arg_system_units);
2251 strv_free(arg_user_units);
2252
2253 free(arg_root);
2254
2255 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
2256 }