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