]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/journal/journalctl.c
Merge pull request #8554 from poettering/chase-trail-slash
[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 = v;
926 v = NULL;
927 } else {
928 r = strv_extend_strv(&arg_output_fields, v, true);
929 if (r < 0)
930 return log_oom();
931 }
932 break;
933 }
934
935 case '?':
936 return -EINVAL;
937
938 default:
939 assert_not_reached("Unhandled option");
940 }
941
942 if (arg_follow && !arg_no_tail && !arg_since && arg_lines == ARG_LINES_DEFAULT)
943 arg_lines = 10;
944
945 if (!!arg_directory + !!arg_file + !!arg_machine + !!arg_root > 1) {
946 log_error("Please specify at most one of -D/--directory=, --file=, -M/--machine=, --root.");
947 return -EINVAL;
948 }
949
950 if (arg_since_set && arg_until_set && arg_since > arg_until) {
951 log_error("--since= must be before --until=.");
952 return -EINVAL;
953 }
954
955 if (!!arg_cursor + !!arg_after_cursor + !!arg_since_set > 1) {
956 log_error("Please specify only one of --since=, --cursor=, and --after-cursor.");
957 return -EINVAL;
958 }
959
960 if (arg_follow && arg_reverse) {
961 log_error("Please specify either --reverse= or --follow=, not both.");
962 return -EINVAL;
963 }
964
965 if (!IN_SET(arg_action, ACTION_SHOW, ACTION_DUMP_CATALOG, ACTION_LIST_CATALOG) && optind < argc) {
966 log_error("Extraneous arguments starting with '%s'", argv[optind]);
967 return -EINVAL;
968 }
969
970 if ((arg_boot || arg_action == ACTION_LIST_BOOTS) && arg_merge) {
971 log_error("Using --boot or --list-boots with --merge is not supported.");
972 return -EINVAL;
973 }
974
975 if (!strv_isempty(arg_system_units) && arg_journal_type == SD_JOURNAL_CURRENT_USER) {
976 /* Specifying --user and --unit= at the same time makes no sense (as the former excludes the user
977 * journal, but the latter excludes the system journal, thus resulting in empty output). Let's be nice
978 * to users, and automatically turn --unit= into --user-unit= if combined with --user. */
979 r = strv_extend_strv(&arg_user_units, arg_system_units, true);
980 if (r < 0)
981 return r;
982
983 arg_system_units = strv_free(arg_system_units);
984 }
985
986
987 #if HAVE_PCRE2
988 if (arg_pattern) {
989 unsigned flags;
990
991 if (arg_case_sensitive >= 0)
992 flags = !arg_case_sensitive * PCRE2_CASELESS;
993 else {
994 _cleanup_(pcre2_match_data_freep) pcre2_match_data *md = NULL;
995 bool has_case;
996 _cleanup_(pcre2_code_freep) pcre2_code *cs = NULL;
997
998 md = pcre2_match_data_create(1, NULL);
999 if (!md)
1000 return log_oom();
1001
1002 r = pattern_compile("[[:upper:]]", 0, &cs);
1003 if (r < 0)
1004 return r;
1005
1006 r = pcre2_match(cs, (PCRE2_SPTR8) arg_pattern, PCRE2_ZERO_TERMINATED, 0, 0, md, NULL);
1007 has_case = r >= 0;
1008
1009 flags = !has_case * PCRE2_CASELESS;
1010 }
1011
1012 log_debug("Doing case %s matching based on %s",
1013 flags & PCRE2_CASELESS ? "insensitive" : "sensitive",
1014 arg_case_sensitive >= 0 ? "request" : "pattern casing");
1015
1016 r = pattern_compile(arg_pattern, flags, &arg_compiled_pattern);
1017 if (r < 0)
1018 return r;
1019 }
1020 #endif
1021
1022 return 1;
1023 }
1024
1025 static int generate_new_id128(void) {
1026 sd_id128_t id;
1027 int r;
1028 unsigned i;
1029
1030 r = sd_id128_randomize(&id);
1031 if (r < 0)
1032 return log_error_errno(r, "Failed to generate ID: %m");
1033
1034 printf("As string:\n"
1035 SD_ID128_FORMAT_STR "\n\n"
1036 "As UUID:\n"
1037 "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n\n"
1038 "As man:sd-id128(3) macro:\n"
1039 "#define MESSAGE_XYZ SD_ID128_MAKE(",
1040 SD_ID128_FORMAT_VAL(id),
1041 SD_ID128_FORMAT_VAL(id));
1042 for (i = 0; i < 16; i++)
1043 printf("%02x%s", id.bytes[i], i != 15 ? "," : "");
1044 fputs(")\n\n", stdout);
1045
1046 printf("As Python constant:\n"
1047 ">>> import uuid\n"
1048 ">>> MESSAGE_XYZ = uuid.UUID('" SD_ID128_FORMAT_STR "')\n",
1049 SD_ID128_FORMAT_VAL(id));
1050
1051 return 0;
1052 }
1053
1054 static int add_matches(sd_journal *j, char **args) {
1055 char **i;
1056 bool have_term = false;
1057
1058 assert(j);
1059
1060 STRV_FOREACH(i, args) {
1061 int r;
1062
1063 if (streq(*i, "+")) {
1064 if (!have_term)
1065 break;
1066 r = sd_journal_add_disjunction(j);
1067 have_term = false;
1068
1069 } else if (path_is_absolute(*i)) {
1070 _cleanup_free_ char *p = NULL, *t = NULL, *t2 = NULL, *interpreter = NULL;
1071 struct stat st;
1072
1073 r = chase_symlinks(*i, NULL, CHASE_TRAIL_SLASH, &p);
1074 if (r < 0)
1075 return log_error_errno(r, "Couldn't canonicalize path: %m");
1076
1077 if (lstat(p, &st) < 0)
1078 return log_error_errno(errno, "Couldn't stat file: %m");
1079
1080 if (S_ISREG(st.st_mode) && (0111 & st.st_mode)) {
1081 if (executable_is_script(p, &interpreter) > 0) {
1082 _cleanup_free_ char *comm;
1083
1084 comm = strndup(basename(p), 15);
1085 if (!comm)
1086 return log_oom();
1087
1088 t = strappend("_COMM=", comm);
1089 if (!t)
1090 return log_oom();
1091
1092 /* Append _EXE only if the interpreter is not a link.
1093 Otherwise, it might be outdated often. */
1094 if (lstat(interpreter, &st) == 0 && !S_ISLNK(st.st_mode)) {
1095 t2 = strappend("_EXE=", interpreter);
1096 if (!t2)
1097 return log_oom();
1098 }
1099 } else {
1100 t = strappend("_EXE=", p);
1101 if (!t)
1102 return log_oom();
1103 }
1104
1105 r = sd_journal_add_match(j, t, 0);
1106
1107 if (r >=0 && t2)
1108 r = sd_journal_add_match(j, t2, 0);
1109
1110 } else if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) {
1111 r = add_matches_for_device(j, p);
1112 if (r < 0)
1113 return r;
1114 } else {
1115 log_error("File is neither a device node, nor regular file, nor executable: %s", *i);
1116 return -EINVAL;
1117 }
1118
1119 have_term = true;
1120 } else {
1121 r = sd_journal_add_match(j, *i, 0);
1122 have_term = true;
1123 }
1124
1125 if (r < 0)
1126 return log_error_errno(r, "Failed to add match '%s': %m", *i);
1127 }
1128
1129 if (!strv_isempty(args) && !have_term) {
1130 log_error("\"+\" can only be used between terms");
1131 return -EINVAL;
1132 }
1133
1134 return 0;
1135 }
1136
1137 static void boot_id_free_all(BootId *l) {
1138
1139 while (l) {
1140 BootId *i = l;
1141 LIST_REMOVE(boot_list, l, i);
1142 free(i);
1143 }
1144 }
1145
1146 static int discover_next_boot(sd_journal *j,
1147 sd_id128_t previous_boot_id,
1148 bool advance_older,
1149 BootId **ret) {
1150
1151 _cleanup_free_ BootId *next_boot = NULL;
1152 char match[9+32+1] = "_BOOT_ID=";
1153 sd_id128_t boot_id;
1154 int r;
1155
1156 assert(j);
1157 assert(ret);
1158
1159 /* We expect the journal to be on the last position of a boot
1160 * (in relation to the direction we are going), so that the next
1161 * invocation of sd_journal_next/previous will be from a different
1162 * boot. We then collect any information we desire and then jump
1163 * to the last location of the new boot by using a _BOOT_ID match
1164 * coming from the other journal direction. */
1165
1166 /* Make sure we aren't restricted by any _BOOT_ID matches, so that
1167 * we can actually advance to a *different* boot. */
1168 sd_journal_flush_matches(j);
1169
1170 do {
1171 if (advance_older)
1172 r = sd_journal_previous(j);
1173 else
1174 r = sd_journal_next(j);
1175 if (r < 0)
1176 return r;
1177 else if (r == 0)
1178 return 0; /* End of journal, yay. */
1179
1180 r = sd_journal_get_monotonic_usec(j, NULL, &boot_id);
1181 if (r < 0)
1182 return r;
1183
1184 /* We iterate through this in a loop, until the boot ID differs from the previous one. Note that
1185 * normally, this will only require a single iteration, as we seeked to the last entry of the previous
1186 * boot entry already. However, it might happen that the per-journal-field entry arrays are less
1187 * complete than the main entry array, and hence might reference an entry that's not actually the last
1188 * one of the boot ID as last one. Let's hence use the per-field array is initial seek position to
1189 * speed things up, but let's not trust that it is complete, and hence, manually advance as
1190 * necessary. */
1191
1192 } while (sd_id128_equal(boot_id, previous_boot_id));
1193
1194 next_boot = new0(BootId, 1);
1195 if (!next_boot)
1196 return -ENOMEM;
1197
1198 next_boot->id = boot_id;
1199
1200 r = sd_journal_get_realtime_usec(j, &next_boot->first);
1201 if (r < 0)
1202 return r;
1203
1204 /* Now seek to the last occurrence of this boot ID. */
1205 sd_id128_to_string(next_boot->id, match + 9);
1206 r = sd_journal_add_match(j, match, sizeof(match) - 1);
1207 if (r < 0)
1208 return r;
1209
1210 if (advance_older)
1211 r = sd_journal_seek_head(j);
1212 else
1213 r = sd_journal_seek_tail(j);
1214 if (r < 0)
1215 return r;
1216
1217 if (advance_older)
1218 r = sd_journal_next(j);
1219 else
1220 r = sd_journal_previous(j);
1221 if (r < 0)
1222 return r;
1223 else if (r == 0) {
1224 log_debug("Whoopsie! We found a boot ID but can't read its last entry.");
1225 return -ENODATA; /* This shouldn't happen. We just came from this very boot ID. */
1226 }
1227
1228 r = sd_journal_get_realtime_usec(j, &next_boot->last);
1229 if (r < 0)
1230 return r;
1231
1232 *ret = next_boot;
1233 next_boot = NULL;
1234
1235 return 0;
1236 }
1237
1238 static int get_boots(
1239 sd_journal *j,
1240 BootId **boots,
1241 sd_id128_t *boot_id,
1242 int offset) {
1243
1244 bool skip_once;
1245 int r, count = 0;
1246 BootId *head = NULL, *tail = NULL, *id;
1247 const bool advance_older = boot_id && offset <= 0;
1248 sd_id128_t previous_boot_id;
1249
1250 assert(j);
1251
1252 /* Adjust for the asymmetry that offset 0 is
1253 * the last (and current) boot, while 1 is considered the
1254 * (chronological) first boot in the journal. */
1255 skip_once = boot_id && sd_id128_is_null(*boot_id) && offset <= 0;
1256
1257 /* Advance to the earliest/latest occurrence of our reference
1258 * boot ID (taking our lookup direction into account), so that
1259 * discover_next_boot() can do its job.
1260 * If no reference is given, the journal head/tail will do,
1261 * they're "virtual" boots after all. */
1262 if (boot_id && !sd_id128_is_null(*boot_id)) {
1263 char match[9+32+1] = "_BOOT_ID=";
1264
1265 sd_journal_flush_matches(j);
1266
1267 sd_id128_to_string(*boot_id, match + 9);
1268 r = sd_journal_add_match(j, match, sizeof(match) - 1);
1269 if (r < 0)
1270 return r;
1271
1272 if (advance_older)
1273 r = sd_journal_seek_head(j); /* seek to oldest */
1274 else
1275 r = sd_journal_seek_tail(j); /* seek to newest */
1276 if (r < 0)
1277 return r;
1278
1279 if (advance_older)
1280 r = sd_journal_next(j); /* read the oldest entry */
1281 else
1282 r = sd_journal_previous(j); /* read the most recently added entry */
1283 if (r < 0)
1284 return r;
1285 else if (r == 0)
1286 goto finish;
1287 else if (offset == 0) {
1288 count = 1;
1289 goto finish;
1290 }
1291
1292 /* At this point the read pointer is positioned at the oldest/newest occurence of the reference boot
1293 * ID. After flushing the matches, one more invocation of _previous()/_next() will hence place us at
1294 * the following entry, which must then have an older/newer boot ID */
1295 } else {
1296
1297 if (advance_older)
1298 r = sd_journal_seek_tail(j); /* seek to newest */
1299 else
1300 r = sd_journal_seek_head(j); /* seek to oldest */
1301 if (r < 0)
1302 return r;
1303
1304 /* No sd_journal_next()/_previous() here.
1305 *
1306 * At this point the read pointer is positioned after the newest/before the oldest entry in the whole
1307 * journal. The next invocation of _previous()/_next() will hence position us at the newest/oldest
1308 * entry we have. */
1309 }
1310
1311 previous_boot_id = SD_ID128_NULL;
1312 for (;;) {
1313 _cleanup_free_ BootId *current = NULL;
1314
1315 r = discover_next_boot(j, previous_boot_id, advance_older, &current);
1316 if (r < 0) {
1317 boot_id_free_all(head);
1318 return r;
1319 }
1320
1321 if (!current)
1322 break;
1323
1324 previous_boot_id = current->id;
1325
1326 if (boot_id) {
1327 if (!skip_once)
1328 offset += advance_older ? 1 : -1;
1329 skip_once = false;
1330
1331 if (offset == 0) {
1332 count = 1;
1333 *boot_id = current->id;
1334 break;
1335 }
1336 } else {
1337 LIST_FOREACH(boot_list, id, head) {
1338 if (sd_id128_equal(id->id, current->id)) {
1339 /* boot id already stored, something wrong with the journal files */
1340 /* exiting as otherwise this problem would cause forever loop */
1341 goto finish;
1342 }
1343 }
1344 LIST_INSERT_AFTER(boot_list, head, tail, current);
1345 tail = current;
1346 current = NULL;
1347 count++;
1348 }
1349 }
1350
1351 finish:
1352 if (boots)
1353 *boots = head;
1354
1355 sd_journal_flush_matches(j);
1356
1357 return count;
1358 }
1359
1360 static int list_boots(sd_journal *j) {
1361 int w, i, count;
1362 BootId *id, *all_ids;
1363
1364 assert(j);
1365
1366 count = get_boots(j, &all_ids, NULL, 0);
1367 if (count < 0)
1368 return log_error_errno(count, "Failed to determine boots: %m");
1369 if (count == 0)
1370 return count;
1371
1372 (void) pager_open(arg_no_pager, arg_pager_end);
1373
1374 /* numbers are one less, but we need an extra char for the sign */
1375 w = DECIMAL_STR_WIDTH(count - 1) + 1;
1376
1377 i = 0;
1378 LIST_FOREACH(boot_list, id, all_ids) {
1379 char a[FORMAT_TIMESTAMP_MAX], b[FORMAT_TIMESTAMP_MAX];
1380
1381 printf("% *i " SD_ID128_FORMAT_STR " %s—%s\n",
1382 w, i - count + 1,
1383 SD_ID128_FORMAT_VAL(id->id),
1384 format_timestamp_maybe_utc(a, sizeof(a), id->first),
1385 format_timestamp_maybe_utc(b, sizeof(b), id->last));
1386 i++;
1387 }
1388
1389 boot_id_free_all(all_ids);
1390
1391 return 0;
1392 }
1393
1394 static int add_boot(sd_journal *j) {
1395 char match[9+32+1] = "_BOOT_ID=";
1396 sd_id128_t boot_id;
1397 int r;
1398
1399 assert(j);
1400
1401 if (!arg_boot)
1402 return 0;
1403
1404 /* Take a shortcut and use the current boot_id, which we can do very quickly.
1405 * We can do this only when we logs are coming from the current machine,
1406 * so take the slow path if log location is specified. */
1407 if (arg_boot_offset == 0 && sd_id128_is_null(arg_boot_id) &&
1408 !arg_directory && !arg_file && !arg_root)
1409
1410 return add_match_this_boot(j, arg_machine);
1411
1412 boot_id = arg_boot_id;
1413 r = get_boots(j, NULL, &boot_id, arg_boot_offset);
1414 assert(r <= 1);
1415 if (r <= 0) {
1416 const char *reason = (r == 0) ? "No such boot ID in journal" : strerror(-r);
1417
1418 if (sd_id128_is_null(arg_boot_id))
1419 log_error("Data from the specified boot (%+i) is not available: %s",
1420 arg_boot_offset, reason);
1421 else
1422 log_error("Data from the specified boot ("SD_ID128_FORMAT_STR") is not available: %s",
1423 SD_ID128_FORMAT_VAL(arg_boot_id), reason);
1424
1425 return r == 0 ? -ENODATA : r;
1426 }
1427
1428 sd_id128_to_string(boot_id, match + 9);
1429
1430 r = sd_journal_add_match(j, match, sizeof(match) - 1);
1431 if (r < 0)
1432 return log_error_errno(r, "Failed to add match: %m");
1433
1434 r = sd_journal_add_conjunction(j);
1435 if (r < 0)
1436 return log_error_errno(r, "Failed to add conjunction: %m");
1437
1438 return 0;
1439 }
1440
1441 static int add_dmesg(sd_journal *j) {
1442 int r;
1443 assert(j);
1444
1445 if (!arg_dmesg)
1446 return 0;
1447
1448 r = sd_journal_add_match(j, "_TRANSPORT=kernel",
1449 STRLEN("_TRANSPORT=kernel"));
1450 if (r < 0)
1451 return log_error_errno(r, "Failed to add match: %m");
1452
1453 r = sd_journal_add_conjunction(j);
1454 if (r < 0)
1455 return log_error_errno(r, "Failed to add conjunction: %m");
1456
1457 return 0;
1458 }
1459
1460 static int get_possible_units(
1461 sd_journal *j,
1462 const char *fields,
1463 char **patterns,
1464 Set **units) {
1465
1466 _cleanup_set_free_free_ Set *found;
1467 const char *field;
1468 int r;
1469
1470 found = set_new(&string_hash_ops);
1471 if (!found)
1472 return -ENOMEM;
1473
1474 NULSTR_FOREACH(field, fields) {
1475 const void *data;
1476 size_t size;
1477
1478 r = sd_journal_query_unique(j, field);
1479 if (r < 0)
1480 return r;
1481
1482 SD_JOURNAL_FOREACH_UNIQUE(j, data, size) {
1483 char **pattern, *eq;
1484 size_t prefix;
1485 _cleanup_free_ char *u = NULL;
1486
1487 eq = memchr(data, '=', size);
1488 if (eq)
1489 prefix = eq - (char*) data + 1;
1490 else
1491 prefix = 0;
1492
1493 u = strndup((char*) data + prefix, size - prefix);
1494 if (!u)
1495 return -ENOMEM;
1496
1497 STRV_FOREACH(pattern, patterns)
1498 if (fnmatch(*pattern, u, FNM_NOESCAPE) == 0) {
1499 log_debug("Matched %s with pattern %s=%s", u, field, *pattern);
1500
1501 r = set_consume(found, u);
1502 u = NULL;
1503 if (r < 0 && r != -EEXIST)
1504 return r;
1505
1506 break;
1507 }
1508 }
1509 }
1510
1511 *units = found;
1512 found = NULL;
1513 return 0;
1514 }
1515
1516 /* This list is supposed to return the superset of unit names
1517 * possibly matched by rules added with add_matches_for_unit... */
1518 #define SYSTEM_UNITS \
1519 "_SYSTEMD_UNIT\0" \
1520 "COREDUMP_UNIT\0" \
1521 "UNIT\0" \
1522 "OBJECT_SYSTEMD_UNIT\0" \
1523 "_SYSTEMD_SLICE\0"
1524
1525 /* ... and add_matches_for_user_unit */
1526 #define USER_UNITS \
1527 "_SYSTEMD_USER_UNIT\0" \
1528 "USER_UNIT\0" \
1529 "COREDUMP_USER_UNIT\0" \
1530 "OBJECT_SYSTEMD_USER_UNIT\0"
1531
1532 static int add_units(sd_journal *j) {
1533 _cleanup_strv_free_ char **patterns = NULL;
1534 int r, count = 0;
1535 char **i;
1536
1537 assert(j);
1538
1539 STRV_FOREACH(i, arg_system_units) {
1540 _cleanup_free_ char *u = NULL;
1541
1542 r = unit_name_mangle(*i, UNIT_NAME_MANGLE_GLOB | (arg_quiet ? 0 : UNIT_NAME_MANGLE_WARN), &u);
1543 if (r < 0)
1544 return r;
1545
1546 if (string_is_glob(u)) {
1547 r = strv_push(&patterns, u);
1548 if (r < 0)
1549 return r;
1550 u = NULL;
1551 } else {
1552 r = add_matches_for_unit(j, u);
1553 if (r < 0)
1554 return r;
1555 r = sd_journal_add_disjunction(j);
1556 if (r < 0)
1557 return r;
1558 count++;
1559 }
1560 }
1561
1562 if (!strv_isempty(patterns)) {
1563 _cleanup_set_free_free_ Set *units = NULL;
1564 Iterator it;
1565 char *u;
1566
1567 r = get_possible_units(j, SYSTEM_UNITS, patterns, &units);
1568 if (r < 0)
1569 return r;
1570
1571 SET_FOREACH(u, units, it) {
1572 r = add_matches_for_unit(j, u);
1573 if (r < 0)
1574 return r;
1575 r = sd_journal_add_disjunction(j);
1576 if (r < 0)
1577 return r;
1578 count++;
1579 }
1580 }
1581
1582 patterns = strv_free(patterns);
1583
1584 STRV_FOREACH(i, arg_user_units) {
1585 _cleanup_free_ char *u = NULL;
1586
1587 r = unit_name_mangle(*i, UNIT_NAME_MANGLE_GLOB | (arg_quiet ? 0 : UNIT_NAME_MANGLE_WARN), &u);
1588 if (r < 0)
1589 return r;
1590
1591 if (string_is_glob(u)) {
1592 r = strv_push(&patterns, u);
1593 if (r < 0)
1594 return r;
1595 u = NULL;
1596 } else {
1597 r = add_matches_for_user_unit(j, u, getuid());
1598 if (r < 0)
1599 return r;
1600 r = sd_journal_add_disjunction(j);
1601 if (r < 0)
1602 return r;
1603 count++;
1604 }
1605 }
1606
1607 if (!strv_isempty(patterns)) {
1608 _cleanup_set_free_free_ Set *units = NULL;
1609 Iterator it;
1610 char *u;
1611
1612 r = get_possible_units(j, USER_UNITS, patterns, &units);
1613 if (r < 0)
1614 return r;
1615
1616 SET_FOREACH(u, units, it) {
1617 r = add_matches_for_user_unit(j, u, getuid());
1618 if (r < 0)
1619 return r;
1620 r = sd_journal_add_disjunction(j);
1621 if (r < 0)
1622 return r;
1623 count++;
1624 }
1625 }
1626
1627 /* Complain if the user request matches but nothing whatsoever was
1628 * found, since otherwise everything would be matched. */
1629 if (!(strv_isempty(arg_system_units) && strv_isempty(arg_user_units)) && count == 0)
1630 return -ENODATA;
1631
1632 r = sd_journal_add_conjunction(j);
1633 if (r < 0)
1634 return r;
1635
1636 return 0;
1637 }
1638
1639 static int add_priorities(sd_journal *j) {
1640 char match[] = "PRIORITY=0";
1641 int i, r;
1642 assert(j);
1643
1644 if (arg_priorities == 0xFF)
1645 return 0;
1646
1647 for (i = LOG_EMERG; i <= LOG_DEBUG; i++)
1648 if (arg_priorities & (1 << i)) {
1649 match[sizeof(match)-2] = '0' + i;
1650
1651 r = sd_journal_add_match(j, match, strlen(match));
1652 if (r < 0)
1653 return log_error_errno(r, "Failed to add match: %m");
1654 }
1655
1656 r = sd_journal_add_conjunction(j);
1657 if (r < 0)
1658 return log_error_errno(r, "Failed to add conjunction: %m");
1659
1660 return 0;
1661 }
1662
1663
1664 static int add_syslog_identifier(sd_journal *j) {
1665 int r;
1666 char **i;
1667
1668 assert(j);
1669
1670 STRV_FOREACH(i, arg_syslog_identifier) {
1671 char *u;
1672
1673 u = strjoina("SYSLOG_IDENTIFIER=", *i);
1674 r = sd_journal_add_match(j, u, 0);
1675 if (r < 0)
1676 return r;
1677 r = sd_journal_add_disjunction(j);
1678 if (r < 0)
1679 return r;
1680 }
1681
1682 r = sd_journal_add_conjunction(j);
1683 if (r < 0)
1684 return r;
1685
1686 return 0;
1687 }
1688
1689 static int setup_keys(void) {
1690 #if HAVE_GCRYPT
1691 size_t mpk_size, seed_size, state_size, i;
1692 uint8_t *mpk, *seed, *state;
1693 int fd = -1, r;
1694 sd_id128_t machine, boot;
1695 char *p = NULL, *k = NULL;
1696 struct FSSHeader h;
1697 uint64_t n;
1698 struct stat st;
1699
1700 r = stat("/var/log/journal", &st);
1701 if (r < 0 && !IN_SET(errno, ENOENT, ENOTDIR))
1702 return log_error_errno(errno, "stat(\"%s\") failed: %m", "/var/log/journal");
1703
1704 if (r < 0 || !S_ISDIR(st.st_mode)) {
1705 log_error("%s is not a directory, must be using persistent logging for FSS.",
1706 "/var/log/journal");
1707 return r < 0 ? -errno : -ENOTDIR;
1708 }
1709
1710 r = sd_id128_get_machine(&machine);
1711 if (r < 0)
1712 return log_error_errno(r, "Failed to get machine ID: %m");
1713
1714 r = sd_id128_get_boot(&boot);
1715 if (r < 0)
1716 return log_error_errno(r, "Failed to get boot ID: %m");
1717
1718 if (asprintf(&p, "/var/log/journal/" SD_ID128_FORMAT_STR "/fss",
1719 SD_ID128_FORMAT_VAL(machine)) < 0)
1720 return log_oom();
1721
1722 if (arg_force) {
1723 r = unlink(p);
1724 if (r < 0 && errno != ENOENT) {
1725 r = log_error_errno(errno, "unlink(\"%s\") failed: %m", p);
1726 goto finish;
1727 }
1728 } else if (access(p, F_OK) >= 0) {
1729 log_error("Sealing key file %s exists already. Use --force to recreate.", p);
1730 r = -EEXIST;
1731 goto finish;
1732 }
1733
1734 if (asprintf(&k, "/var/log/journal/" SD_ID128_FORMAT_STR "/fss.tmp.XXXXXX",
1735 SD_ID128_FORMAT_VAL(machine)) < 0) {
1736 r = log_oom();
1737 goto finish;
1738 }
1739
1740 mpk_size = FSPRG_mskinbytes(FSPRG_RECOMMENDED_SECPAR);
1741 mpk = alloca(mpk_size);
1742
1743 seed_size = FSPRG_RECOMMENDED_SEEDLEN;
1744 seed = alloca(seed_size);
1745
1746 state_size = FSPRG_stateinbytes(FSPRG_RECOMMENDED_SECPAR);
1747 state = alloca(state_size);
1748
1749 fd = open("/dev/random", O_RDONLY|O_CLOEXEC|O_NOCTTY);
1750 if (fd < 0) {
1751 r = log_error_errno(errno, "Failed to open /dev/random: %m");
1752 goto finish;
1753 }
1754
1755 log_info("Generating seed...");
1756 r = loop_read_exact(fd, seed, seed_size, true);
1757 if (r < 0) {
1758 log_error_errno(r, "Failed to read random seed: %m");
1759 goto finish;
1760 }
1761
1762 log_info("Generating key pair...");
1763 FSPRG_GenMK(NULL, mpk, seed, seed_size, FSPRG_RECOMMENDED_SECPAR);
1764
1765 log_info("Generating sealing key...");
1766 FSPRG_GenState0(state, mpk, seed, seed_size);
1767
1768 assert(arg_interval > 0);
1769
1770 n = now(CLOCK_REALTIME);
1771 n /= arg_interval;
1772
1773 safe_close(fd);
1774 fd = mkostemp_safe(k);
1775 if (fd < 0) {
1776 r = log_error_errno(fd, "Failed to open %s: %m", k);
1777 goto finish;
1778 }
1779
1780 /* Enable secure remove, exclusion from dump, synchronous
1781 * writing and in-place updating */
1782 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);
1783 if (r < 0)
1784 log_warning_errno(r, "Failed to set file attributes: %m");
1785
1786 zero(h);
1787 memcpy(h.signature, "KSHHRHLP", 8);
1788 h.machine_id = machine;
1789 h.boot_id = boot;
1790 h.header_size = htole64(sizeof(h));
1791 h.start_usec = htole64(n * arg_interval);
1792 h.interval_usec = htole64(arg_interval);
1793 h.fsprg_secpar = htole16(FSPRG_RECOMMENDED_SECPAR);
1794 h.fsprg_state_size = htole64(state_size);
1795
1796 r = loop_write(fd, &h, sizeof(h), false);
1797 if (r < 0) {
1798 log_error_errno(r, "Failed to write header: %m");
1799 goto finish;
1800 }
1801
1802 r = loop_write(fd, state, state_size, false);
1803 if (r < 0) {
1804 log_error_errno(r, "Failed to write state: %m");
1805 goto finish;
1806 }
1807
1808 if (link(k, p) < 0) {
1809 r = log_error_errno(errno, "Failed to link file: %m");
1810 goto finish;
1811 }
1812
1813 if (on_tty()) {
1814 fprintf(stderr,
1815 "\n"
1816 "The new key pair has been generated. The %ssecret sealing key%s has been written to\n"
1817 "the following local file. This key file is automatically updated when the\n"
1818 "sealing key is advanced. It should not be used on multiple hosts.\n"
1819 "\n"
1820 "\t%s\n"
1821 "\n"
1822 "Please write down the following %ssecret verification key%s. It should be stored\n"
1823 "at a safe location and should not be saved locally on disk.\n"
1824 "\n\t%s",
1825 ansi_highlight(), ansi_normal(),
1826 p,
1827 ansi_highlight(), ansi_normal(),
1828 ansi_highlight_red());
1829 fflush(stderr);
1830 }
1831 for (i = 0; i < seed_size; i++) {
1832 if (i > 0 && i % 3 == 0)
1833 putchar('-');
1834 printf("%02x", ((uint8_t*) seed)[i]);
1835 }
1836
1837 printf("/%llx-%llx\n", (unsigned long long) n, (unsigned long long) arg_interval);
1838
1839 if (on_tty()) {
1840 char tsb[FORMAT_TIMESPAN_MAX], *hn;
1841
1842 fprintf(stderr,
1843 "%s\n"
1844 "The sealing key is automatically changed every %s.\n",
1845 ansi_normal(),
1846 format_timespan(tsb, sizeof(tsb), arg_interval, 0));
1847
1848 hn = gethostname_malloc();
1849
1850 if (hn) {
1851 hostname_cleanup(hn);
1852 fprintf(stderr, "\nThe keys have been generated for host %s/" SD_ID128_FORMAT_STR ".\n", hn, SD_ID128_FORMAT_VAL(machine));
1853 } else
1854 fprintf(stderr, "\nThe keys have been generated for host " SD_ID128_FORMAT_STR ".\n", SD_ID128_FORMAT_VAL(machine));
1855
1856 #if HAVE_QRENCODE
1857 /* If this is not an UTF-8 system don't print any QR codes */
1858 if (is_locale_utf8()) {
1859 fputs("\nTo transfer the verification key to your phone please scan the QR code below:\n\n", stderr);
1860 print_qr_code(stderr, seed, seed_size, n, arg_interval, hn, machine);
1861 }
1862 #endif
1863 free(hn);
1864 }
1865
1866 r = 0;
1867
1868 finish:
1869 safe_close(fd);
1870
1871 if (k) {
1872 unlink(k);
1873 free(k);
1874 }
1875
1876 free(p);
1877
1878 return r;
1879 #else
1880 log_error("Forward-secure sealing not available.");
1881 return -EOPNOTSUPP;
1882 #endif
1883 }
1884
1885 static int verify(sd_journal *j) {
1886 int r = 0;
1887 Iterator i;
1888 JournalFile *f;
1889
1890 assert(j);
1891
1892 log_show_color(true);
1893
1894 ORDERED_HASHMAP_FOREACH(f, j->files, i) {
1895 int k;
1896 usec_t first = 0, validated = 0, last = 0;
1897
1898 #if HAVE_GCRYPT
1899 if (!arg_verify_key && JOURNAL_HEADER_SEALED(f->header))
1900 log_notice("Journal file %s has sealing enabled but verification key has not been passed using --verify-key=.", f->path);
1901 #endif
1902
1903 k = journal_file_verify(f, arg_verify_key, &first, &validated, &last, true);
1904 if (k == -EINVAL) {
1905 /* If the key was invalid give up right-away. */
1906 return k;
1907 } else if (k < 0) {
1908 log_warning_errno(k, "FAIL: %s (%m)", f->path);
1909 r = k;
1910 } else {
1911 char a[FORMAT_TIMESTAMP_MAX], b[FORMAT_TIMESTAMP_MAX], c[FORMAT_TIMESPAN_MAX];
1912 log_info("PASS: %s", f->path);
1913
1914 if (arg_verify_key && JOURNAL_HEADER_SEALED(f->header)) {
1915 if (validated > 0) {
1916 log_info("=> Validated from %s to %s, final %s entries not sealed.",
1917 format_timestamp_maybe_utc(a, sizeof(a), first),
1918 format_timestamp_maybe_utc(b, sizeof(b), validated),
1919 format_timespan(c, sizeof(c), last > validated ? last - validated : 0, 0));
1920 } else if (last > 0)
1921 log_info("=> No sealing yet, %s of entries not sealed.",
1922 format_timespan(c, sizeof(c), last - first, 0));
1923 else
1924 log_info("=> No sealing yet, no entries in file.");
1925 }
1926 }
1927 }
1928
1929 return r;
1930 }
1931
1932 static int flush_to_var(void) {
1933 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
1934 _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
1935 _cleanup_close_ int watch_fd = -1;
1936 int r;
1937
1938 if (arg_machine) {
1939 log_error("--flush is not supported in conjunction with --machine=.");
1940 return -EOPNOTSUPP;
1941 }
1942
1943 /* Quick exit */
1944 if (access("/run/systemd/journal/flushed", F_OK) >= 0)
1945 return 0;
1946
1947 /* OK, let's actually do the full logic, send SIGUSR1 to the
1948 * daemon and set up inotify to wait for the flushed file to appear */
1949 r = bus_connect_system_systemd(&bus);
1950 if (r < 0)
1951 return log_error_errno(r, "Failed to get D-Bus connection: %m");
1952
1953 r = sd_bus_call_method(
1954 bus,
1955 "org.freedesktop.systemd1",
1956 "/org/freedesktop/systemd1",
1957 "org.freedesktop.systemd1.Manager",
1958 "KillUnit",
1959 &error,
1960 NULL,
1961 "ssi", "systemd-journald.service", "main", SIGUSR1);
1962 if (r < 0)
1963 return log_error_errno(r, "Failed to kill journal service: %s", bus_error_message(&error, r));
1964
1965 mkdir_p("/run/systemd/journal", 0755);
1966
1967 watch_fd = inotify_init1(IN_NONBLOCK|IN_CLOEXEC);
1968 if (watch_fd < 0)
1969 return log_error_errno(errno, "Failed to create inotify watch: %m");
1970
1971 r = inotify_add_watch(watch_fd, "/run/systemd/journal", IN_CREATE|IN_DONT_FOLLOW|IN_ONLYDIR);
1972 if (r < 0)
1973 return log_error_errno(errno, "Failed to watch journal directory: %m");
1974
1975 for (;;) {
1976 if (access("/run/systemd/journal/flushed", F_OK) >= 0)
1977 break;
1978
1979 if (errno != ENOENT)
1980 return log_error_errno(errno, "Failed to check for existence of /run/systemd/journal/flushed: %m");
1981
1982 r = fd_wait_for_event(watch_fd, POLLIN, USEC_INFINITY);
1983 if (r < 0)
1984 return log_error_errno(r, "Failed to wait for event: %m");
1985
1986 r = flush_fd(watch_fd);
1987 if (r < 0)
1988 return log_error_errno(r, "Failed to flush inotify events: %m");
1989 }
1990
1991 return 0;
1992 }
1993
1994 static int send_signal_and_wait(int sig, const char *watch_path) {
1995 _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
1996 _cleanup_close_ int watch_fd = -1;
1997 usec_t start;
1998 int r;
1999
2000 if (arg_machine) {
2001 log_error("--sync and --rotate are not supported in conjunction with --machine=.");
2002 return -EOPNOTSUPP;
2003 }
2004
2005 start = now(CLOCK_MONOTONIC);
2006
2007 /* This call sends the specified signal to journald, and waits
2008 * for acknowledgment by watching the mtime of the specified
2009 * flag file. This is used to trigger syncing or rotation and
2010 * then wait for the operation to complete. */
2011
2012 for (;;) {
2013 usec_t tstamp;
2014
2015 /* See if a sync happened by now. */
2016 r = read_timestamp_file(watch_path, &tstamp);
2017 if (r < 0 && r != -ENOENT)
2018 return log_error_errno(errno, "Failed to read %s: %m", watch_path);
2019 if (r >= 0 && tstamp >= start)
2020 return 0;
2021
2022 /* Let's ask for a sync, but only once. */
2023 if (!bus) {
2024 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
2025
2026 r = bus_connect_system_systemd(&bus);
2027 if (r < 0)
2028 return log_error_errno(r, "Failed to get D-Bus connection: %m");
2029
2030 r = sd_bus_call_method(
2031 bus,
2032 "org.freedesktop.systemd1",
2033 "/org/freedesktop/systemd1",
2034 "org.freedesktop.systemd1.Manager",
2035 "KillUnit",
2036 &error,
2037 NULL,
2038 "ssi", "systemd-journald.service", "main", sig);
2039 if (r < 0)
2040 return log_error_errno(r, "Failed to kill journal service: %s", bus_error_message(&error, r));
2041
2042 continue;
2043 }
2044
2045 /* Let's install the inotify watch, if we didn't do that yet. */
2046 if (watch_fd < 0) {
2047
2048 mkdir_p("/run/systemd/journal", 0755);
2049
2050 watch_fd = inotify_init1(IN_NONBLOCK|IN_CLOEXEC);
2051 if (watch_fd < 0)
2052 return log_error_errno(errno, "Failed to create inotify watch: %m");
2053
2054 r = inotify_add_watch(watch_fd, "/run/systemd/journal", IN_MOVED_TO|IN_DONT_FOLLOW|IN_ONLYDIR);
2055 if (r < 0)
2056 return log_error_errno(errno, "Failed to watch journal directory: %m");
2057
2058 /* Recheck the flag file immediately, so that we don't miss any event since the last check. */
2059 continue;
2060 }
2061
2062 /* OK, all preparatory steps done, let's wait until
2063 * inotify reports an event. */
2064
2065 r = fd_wait_for_event(watch_fd, POLLIN, USEC_INFINITY);
2066 if (r < 0)
2067 return log_error_errno(r, "Failed to wait for event: %m");
2068
2069 r = flush_fd(watch_fd);
2070 if (r < 0)
2071 return log_error_errno(r, "Failed to flush inotify events: %m");
2072 }
2073
2074 return 0;
2075 }
2076
2077 static int rotate(void) {
2078 return send_signal_and_wait(SIGUSR2, "/run/systemd/journal/rotated");
2079 }
2080
2081 static int sync_journal(void) {
2082 return send_signal_and_wait(SIGRTMIN+1, "/run/systemd/journal/synced");
2083 }
2084
2085 int main(int argc, char *argv[]) {
2086 int r;
2087 _cleanup_(sd_journal_closep) sd_journal *j = NULL;
2088 bool need_seek = false;
2089 sd_id128_t previous_boot_id;
2090 bool previous_boot_id_valid = false, first_line = true;
2091 int n_shown = 0;
2092 bool ellipsized = false;
2093
2094 setlocale(LC_ALL, "");
2095 log_parse_environment();
2096 log_open();
2097
2098 r = parse_argv(argc, argv);
2099 if (r <= 0)
2100 goto finish;
2101
2102 signal(SIGWINCH, columns_lines_cache_reset);
2103 sigbus_install();
2104
2105 /* Increase max number of open files to 16K if we can, we
2106 * might needs this when browsing journal files, which might
2107 * be split up into many files. */
2108 setrlimit_closest(RLIMIT_NOFILE, &RLIMIT_MAKE_CONST(16384));
2109
2110 switch (arg_action) {
2111
2112 case ACTION_NEW_ID128:
2113 r = generate_new_id128();
2114 goto finish;
2115
2116 case ACTION_SETUP_KEYS:
2117 r = setup_keys();
2118 goto finish;
2119
2120 case ACTION_LIST_CATALOG:
2121 case ACTION_DUMP_CATALOG:
2122 case ACTION_UPDATE_CATALOG: {
2123 _cleanup_free_ char *database;
2124
2125 database = path_join(arg_root, CATALOG_DATABASE, NULL);
2126 if (!database) {
2127 r = log_oom();
2128 goto finish;
2129 }
2130
2131 if (arg_action == ACTION_UPDATE_CATALOG) {
2132 r = catalog_update(database, arg_root, catalog_file_dirs);
2133 if (r < 0)
2134 log_error_errno(r, "Failed to list catalog: %m");
2135 } else {
2136 bool oneline = arg_action == ACTION_LIST_CATALOG;
2137
2138 (void) pager_open(arg_no_pager, arg_pager_end);
2139
2140 if (optind < argc)
2141 r = catalog_list_items(stdout, database, oneline, argv + optind);
2142 else
2143 r = catalog_list(stdout, database, oneline);
2144 if (r < 0)
2145 log_error_errno(r, "Failed to list catalog: %m");
2146 }
2147
2148 goto finish;
2149 }
2150
2151 case ACTION_FLUSH:
2152 r = flush_to_var();
2153 goto finish;
2154
2155 case ACTION_SYNC:
2156 r = sync_journal();
2157 goto finish;
2158
2159 case ACTION_ROTATE:
2160 r = rotate();
2161 goto finish;
2162
2163 case ACTION_SHOW:
2164 case ACTION_PRINT_HEADER:
2165 case ACTION_VERIFY:
2166 case ACTION_DISK_USAGE:
2167 case ACTION_LIST_BOOTS:
2168 case ACTION_VACUUM:
2169 case ACTION_LIST_FIELDS:
2170 case ACTION_LIST_FIELD_NAMES:
2171 /* These ones require access to the journal files, continue below. */
2172 break;
2173
2174 default:
2175 assert_not_reached("Unknown action");
2176 }
2177
2178 if (arg_directory)
2179 r = sd_journal_open_directory(&j, arg_directory, arg_journal_type);
2180 else if (arg_root)
2181 r = sd_journal_open_directory(&j, arg_root, arg_journal_type | SD_JOURNAL_OS_ROOT);
2182 else if (arg_file_stdin) {
2183 int ifd = STDIN_FILENO;
2184 r = sd_journal_open_files_fd(&j, &ifd, 1, 0);
2185 } else if (arg_file)
2186 r = sd_journal_open_files(&j, (const char**) arg_file, 0);
2187 else if (arg_machine) {
2188 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
2189 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
2190 _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
2191 int fd;
2192
2193 if (geteuid() != 0) {
2194 /* The file descriptor returned by OpenMachineRootDirectory() will be owned by users/groups of
2195 * the container, thus we need root privileges to override them. */
2196 log_error("Using the --machine= switch requires root privileges.");
2197 r = -EPERM;
2198 goto finish;
2199 }
2200
2201 r = sd_bus_open_system(&bus);
2202 if (r < 0) {
2203 log_error_errno(r, "Failed to open system bus: %m");
2204 goto finish;
2205 }
2206
2207 r = sd_bus_call_method(
2208 bus,
2209 "org.freedesktop.machine1",
2210 "/org/freedesktop/machine1",
2211 "org.freedesktop.machine1.Manager",
2212 "OpenMachineRootDirectory",
2213 &error,
2214 &reply,
2215 "s", arg_machine);
2216 if (r < 0) {
2217 log_error_errno(r, "Failed to open root directory: %s", bus_error_message(&error, r));
2218 goto finish;
2219 }
2220
2221 r = sd_bus_message_read(reply, "h", &fd);
2222 if (r < 0) {
2223 bus_log_parse_error(r);
2224 goto finish;
2225 }
2226
2227 fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
2228 if (fd < 0) {
2229 r = log_error_errno(errno, "Failed to duplicate file descriptor: %m");
2230 goto finish;
2231 }
2232
2233 r = sd_journal_open_directory_fd(&j, fd, SD_JOURNAL_OS_ROOT);
2234 if (r < 0)
2235 safe_close(fd);
2236 } else
2237 r = sd_journal_open(&j, !arg_merge*SD_JOURNAL_LOCAL_ONLY + arg_journal_type);
2238 if (r < 0) {
2239 log_error_errno(r, "Failed to open %s: %m", arg_directory ?: arg_file ? "files" : "journal");
2240 goto finish;
2241 }
2242
2243 r = journal_access_check_and_warn(j, arg_quiet,
2244 !(arg_journal_type == SD_JOURNAL_CURRENT_USER || arg_user_units));
2245 if (r < 0)
2246 goto finish;
2247
2248 switch (arg_action) {
2249
2250 case ACTION_NEW_ID128:
2251 case ACTION_SETUP_KEYS:
2252 case ACTION_LIST_CATALOG:
2253 case ACTION_DUMP_CATALOG:
2254 case ACTION_UPDATE_CATALOG:
2255 case ACTION_FLUSH:
2256 case ACTION_SYNC:
2257 case ACTION_ROTATE:
2258 assert_not_reached("Unexpected action.");
2259
2260 case ACTION_PRINT_HEADER:
2261 journal_print_header(j);
2262 r = 0;
2263 goto finish;
2264
2265 case ACTION_VERIFY:
2266 r = verify(j);
2267 goto finish;
2268
2269 case ACTION_DISK_USAGE: {
2270 uint64_t bytes = 0;
2271 char sbytes[FORMAT_BYTES_MAX];
2272
2273 r = sd_journal_get_usage(j, &bytes);
2274 if (r < 0)
2275 goto finish;
2276
2277 printf("Archived and active journals take up %s in the file system.\n",
2278 format_bytes(sbytes, sizeof(sbytes), bytes));
2279 goto finish;
2280 }
2281
2282 case ACTION_LIST_BOOTS:
2283 r = list_boots(j);
2284 goto finish;
2285
2286 case ACTION_VACUUM: {
2287 Directory *d;
2288 Iterator i;
2289
2290 HASHMAP_FOREACH(d, j->directories_by_path, i) {
2291 int q;
2292
2293 if (d->is_root)
2294 continue;
2295
2296 q = journal_directory_vacuum(d->path, arg_vacuum_size, arg_vacuum_n_files, arg_vacuum_time, NULL, !arg_quiet);
2297 if (q < 0) {
2298 log_error_errno(q, "Failed to vacuum %s: %m", d->path);
2299 r = q;
2300 }
2301 }
2302
2303 goto finish;
2304 }
2305
2306 case ACTION_LIST_FIELD_NAMES: {
2307 const char *field;
2308
2309 SD_JOURNAL_FOREACH_FIELD(j, field) {
2310 printf("%s\n", field);
2311 n_shown++;
2312 }
2313
2314 r = 0;
2315 goto finish;
2316 }
2317
2318 case ACTION_SHOW:
2319 case ACTION_LIST_FIELDS:
2320 break;
2321
2322 default:
2323 assert_not_reached("Unknown action");
2324 }
2325
2326 if (arg_boot_offset != 0 &&
2327 sd_journal_has_runtime_files(j) > 0 &&
2328 sd_journal_has_persistent_files(j) == 0) {
2329 log_info("Specifying boot ID or boot offset has no effect, no persistent journal was found.");
2330 r = 0;
2331 goto finish;
2332 }
2333 /* add_boot() must be called first!
2334 * It may need to seek the journal to find parent boot IDs. */
2335 r = add_boot(j);
2336 if (r < 0)
2337 goto finish;
2338
2339 r = add_dmesg(j);
2340 if (r < 0)
2341 goto finish;
2342
2343 r = add_units(j);
2344 if (r < 0) {
2345 log_error_errno(r, "Failed to add filter for units: %m");
2346 goto finish;
2347 }
2348
2349 r = add_syslog_identifier(j);
2350 if (r < 0) {
2351 log_error_errno(r, "Failed to add filter for syslog identifiers: %m");
2352 goto finish;
2353 }
2354
2355 r = add_priorities(j);
2356 if (r < 0)
2357 goto finish;
2358
2359 r = add_matches(j, argv + optind);
2360 if (r < 0)
2361 goto finish;
2362
2363 if (DEBUG_LOGGING) {
2364 _cleanup_free_ char *filter;
2365
2366 filter = journal_make_match_string(j);
2367 if (!filter)
2368 return log_oom();
2369
2370 log_debug("Journal filter: %s", filter);
2371 }
2372
2373 if (arg_action == ACTION_LIST_FIELDS) {
2374 const void *data;
2375 size_t size;
2376
2377 assert(arg_field);
2378
2379 r = sd_journal_set_data_threshold(j, 0);
2380 if (r < 0) {
2381 log_error_errno(r, "Failed to unset data size threshold: %m");
2382 goto finish;
2383 }
2384
2385 r = sd_journal_query_unique(j, arg_field);
2386 if (r < 0) {
2387 log_error_errno(r, "Failed to query unique data objects: %m");
2388 goto finish;
2389 }
2390
2391 SD_JOURNAL_FOREACH_UNIQUE(j, data, size) {
2392 const void *eq;
2393
2394 if (arg_lines >= 0 && n_shown >= arg_lines)
2395 break;
2396
2397 eq = memchr(data, '=', size);
2398 if (eq)
2399 printf("%.*s\n", (int) (size - ((const uint8_t*) eq - (const uint8_t*) data + 1)), (const char*) eq + 1);
2400 else
2401 printf("%.*s\n", (int) size, (const char*) data);
2402
2403 n_shown++;
2404 }
2405
2406 r = 0;
2407 goto finish;
2408 }
2409
2410 /* Opening the fd now means the first sd_journal_wait() will actually wait */
2411 if (arg_follow) {
2412 r = sd_journal_get_fd(j);
2413 if (r == -EMEDIUMTYPE) {
2414 log_error_errno(r, "The --follow switch is not supported in conjunction with reading from STDIN.");
2415 goto finish;
2416 }
2417 if (r < 0) {
2418 log_error_errno(r, "Failed to get journal fd: %m");
2419 goto finish;
2420 }
2421 }
2422
2423 if (arg_cursor || arg_after_cursor) {
2424 r = sd_journal_seek_cursor(j, arg_cursor ?: arg_after_cursor);
2425 if (r < 0) {
2426 log_error_errno(r, "Failed to seek to cursor: %m");
2427 goto finish;
2428 }
2429
2430 if (!arg_reverse)
2431 r = sd_journal_next_skip(j, 1 + !!arg_after_cursor);
2432 else
2433 r = sd_journal_previous_skip(j, 1 + !!arg_after_cursor);
2434
2435 if (arg_after_cursor && r < 2) {
2436 /* We couldn't find the next entry after the cursor. */
2437 if (arg_follow)
2438 need_seek = true;
2439 else
2440 arg_lines = 0;
2441 }
2442
2443 } else if (arg_since_set && !arg_reverse) {
2444 r = sd_journal_seek_realtime_usec(j, arg_since);
2445 if (r < 0) {
2446 log_error_errno(r, "Failed to seek to date: %m");
2447 goto finish;
2448 }
2449 r = sd_journal_next(j);
2450
2451 } else if (arg_until_set && arg_reverse) {
2452 r = sd_journal_seek_realtime_usec(j, arg_until);
2453 if (r < 0) {
2454 log_error_errno(r, "Failed to seek to date: %m");
2455 goto finish;
2456 }
2457 r = sd_journal_previous(j);
2458
2459 } else if (arg_lines >= 0) {
2460 r = sd_journal_seek_tail(j);
2461 if (r < 0) {
2462 log_error_errno(r, "Failed to seek to tail: %m");
2463 goto finish;
2464 }
2465
2466 r = sd_journal_previous_skip(j, arg_lines);
2467
2468 } else if (arg_reverse) {
2469 r = sd_journal_seek_tail(j);
2470 if (r < 0) {
2471 log_error_errno(r, "Failed to seek to tail: %m");
2472 goto finish;
2473 }
2474
2475 r = sd_journal_previous(j);
2476
2477 } else {
2478 r = sd_journal_seek_head(j);
2479 if (r < 0) {
2480 log_error_errno(r, "Failed to seek to head: %m");
2481 goto finish;
2482 }
2483
2484 r = sd_journal_next(j);
2485 }
2486
2487 if (r < 0) {
2488 log_error_errno(r, "Failed to iterate through journal: %m");
2489 goto finish;
2490 }
2491 if (r == 0)
2492 need_seek = true;
2493
2494 if (!arg_follow)
2495 (void) pager_open(arg_no_pager, arg_pager_end);
2496
2497 if (!arg_quiet && (arg_lines != 0 || arg_follow)) {
2498 usec_t start, end;
2499 char start_buf[FORMAT_TIMESTAMP_MAX], end_buf[FORMAT_TIMESTAMP_MAX];
2500
2501 r = sd_journal_get_cutoff_realtime_usec(j, &start, &end);
2502 if (r < 0) {
2503 log_error_errno(r, "Failed to get cutoff: %m");
2504 goto finish;
2505 }
2506
2507 if (r > 0) {
2508 if (arg_follow)
2509 printf("-- Logs begin at %s. --\n",
2510 format_timestamp_maybe_utc(start_buf, sizeof(start_buf), start));
2511 else
2512 printf("-- Logs begin at %s, end at %s. --\n",
2513 format_timestamp_maybe_utc(start_buf, sizeof(start_buf), start),
2514 format_timestamp_maybe_utc(end_buf, sizeof(end_buf), end));
2515 }
2516 }
2517
2518 for (;;) {
2519 while (arg_lines < 0 || n_shown < arg_lines || (arg_follow && !first_line)) {
2520 int flags;
2521 size_t highlight[2] = {};
2522
2523 if (need_seek) {
2524 if (!arg_reverse)
2525 r = sd_journal_next(j);
2526 else
2527 r = sd_journal_previous(j);
2528 if (r < 0) {
2529 log_error_errno(r, "Failed to iterate through journal: %m");
2530 goto finish;
2531 }
2532 if (r == 0)
2533 break;
2534 }
2535
2536 if (arg_until_set && !arg_reverse) {
2537 usec_t usec;
2538
2539 r = sd_journal_get_realtime_usec(j, &usec);
2540 if (r < 0) {
2541 log_error_errno(r, "Failed to determine timestamp: %m");
2542 goto finish;
2543 }
2544 if (usec > arg_until)
2545 goto finish;
2546 }
2547
2548 if (arg_since_set && arg_reverse) {
2549 usec_t usec;
2550
2551 r = sd_journal_get_realtime_usec(j, &usec);
2552 if (r < 0) {
2553 log_error_errno(r, "Failed to determine timestamp: %m");
2554 goto finish;
2555 }
2556 if (usec < arg_since)
2557 goto finish;
2558 }
2559
2560 if (!arg_merge && !arg_quiet) {
2561 sd_id128_t boot_id;
2562
2563 r = sd_journal_get_monotonic_usec(j, NULL, &boot_id);
2564 if (r >= 0) {
2565 if (previous_boot_id_valid &&
2566 !sd_id128_equal(boot_id, previous_boot_id))
2567 printf("%s-- Reboot --%s\n",
2568 ansi_highlight(), ansi_normal());
2569
2570 previous_boot_id = boot_id;
2571 previous_boot_id_valid = true;
2572 }
2573 }
2574
2575 #if HAVE_PCRE2
2576 if (arg_compiled_pattern) {
2577 _cleanup_(pcre2_match_data_freep) pcre2_match_data *md = NULL;
2578 const void *message;
2579 size_t len;
2580 PCRE2_SIZE *ovec;
2581
2582 md = pcre2_match_data_create(1, NULL);
2583 if (!md)
2584 return log_oom();
2585
2586 r = sd_journal_get_data(j, "MESSAGE", &message, &len);
2587 if (r < 0) {
2588 if (r == -ENOENT) {
2589 need_seek = true;
2590 continue;
2591 }
2592
2593 log_error_errno(r, "Failed to get MESSAGE field: %m");
2594 goto finish;
2595 }
2596
2597 assert_se(message = startswith(message, "MESSAGE="));
2598
2599 r = pcre2_match(arg_compiled_pattern,
2600 message,
2601 len - strlen("MESSAGE="),
2602 0, /* start at offset 0 in the subject */
2603 0, /* default options */
2604 md,
2605 NULL);
2606 if (r == PCRE2_ERROR_NOMATCH) {
2607 need_seek = true;
2608 continue;
2609 }
2610 if (r < 0) {
2611 unsigned char buf[LINE_MAX];
2612 int r2;
2613
2614 r2 = pcre2_get_error_message(r, buf, sizeof buf);
2615 log_error("Pattern matching failed: %s",
2616 r2 < 0 ? "unknown error" : (char*) buf);
2617 r = -EINVAL;
2618 goto finish;
2619 }
2620
2621 ovec = pcre2_get_ovector_pointer(md);
2622 highlight[0] = ovec[0];
2623 highlight[1] = ovec[1];
2624 }
2625 #endif
2626
2627 flags =
2628 arg_all * OUTPUT_SHOW_ALL |
2629 arg_full * OUTPUT_FULL_WIDTH |
2630 colors_enabled() * OUTPUT_COLOR |
2631 arg_catalog * OUTPUT_CATALOG |
2632 arg_utc * OUTPUT_UTC |
2633 arg_no_hostname * OUTPUT_NO_HOSTNAME;
2634
2635 r = output_journal(stdout, j, arg_output, 0, flags,
2636 arg_output_fields, highlight, &ellipsized);
2637 need_seek = true;
2638 if (r == -EADDRNOTAVAIL)
2639 break;
2640 else if (r < 0 || ferror(stdout))
2641 goto finish;
2642
2643 n_shown++;
2644
2645 /* If journalctl take a long time to process messages, and during that time journal file
2646 * rotation occurs, a journalctl client will keep those rotated files open until it calls
2647 * sd_journal_process(), which typically happens as a result of calling sd_journal_wait() below
2648 * in the "following" case. By periodically calling sd_journal_process() during the processing
2649 * loop we shrink the window of time a client instance has open file descriptors for rotated
2650 * (deleted) journal files. */
2651 if ((n_shown % PROCESS_INOTIFY_INTERVAL) == 0) {
2652 r = sd_journal_process(j);
2653 if (r < 0) {
2654 log_error_errno(r, "Failed to process inotify events: %m");
2655 goto finish;
2656 }
2657 }
2658 }
2659
2660 if (!arg_follow) {
2661 if (n_shown == 0 && !arg_quiet)
2662 printf("-- No entries --\n");
2663
2664 if (arg_show_cursor) {
2665 _cleanup_free_ char *cursor = NULL;
2666
2667 r = sd_journal_get_cursor(j, &cursor);
2668 if (r < 0 && r != -EADDRNOTAVAIL)
2669 log_error_errno(r, "Failed to get cursor: %m");
2670 else if (r >= 0)
2671 printf("-- cursor: %s\n", cursor);
2672 }
2673
2674 break;
2675 }
2676
2677 fflush(stdout);
2678 r = sd_journal_wait(j, (uint64_t) -1);
2679 if (r < 0) {
2680 log_error_errno(r, "Couldn't wait for journal event: %m");
2681 goto finish;
2682 }
2683
2684 first_line = false;
2685 }
2686
2687 finish:
2688 fflush(stdout);
2689 pager_close();
2690
2691 strv_free(arg_file);
2692
2693 strv_free(arg_syslog_identifier);
2694 strv_free(arg_system_units);
2695 strv_free(arg_user_units);
2696 strv_free(arg_output_fields);
2697
2698 free(arg_root);
2699 free(arg_verify_key);
2700
2701 #if HAVE_PCRE2
2702 if (arg_compiled_pattern)
2703 pcre2_code_free(arg_compiled_pattern);
2704 #endif
2705
2706 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
2707 }