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