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