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