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