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