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