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