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