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