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