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