chiark / gitweb /
treewide: another round of simplifications
[elogind.git] / src / journal / journalctl.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2011 Lennart Poettering
7
8   systemd is free software; you can redistribute it and/or modify it
9   under the terms of the GNU Lesser General Public License as published by
10   the Free Software Foundation; either version 2.1 of the License, or
11   (at your option) any later version.
12
13   systemd is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16   Lesser General Public License for more details.
17
18   You should have received a copy of the GNU Lesser General Public License
19   along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <locale.h>
23 #include <fcntl.h>
24 #include <fnmatch.h>
25 #include <errno.h>
26 #include <stddef.h>
27 #include <string.h>
28 #include <stdio.h>
29 #include <unistd.h>
30 #include <stdlib.h>
31 #include <time.h>
32 #include <getopt.h>
33 #include <signal.h>
34 #include <poll.h>
35 #include <sys/stat.h>
36 #include <sys/ioctl.h>
37 #include <sys/inotify.h>
38 #include <linux/fs.h>
39
40 #ifdef HAVE_ACL
41 #include <sys/acl.h>
42 #include "acl-util.h"
43 #endif
44
45 #include "sd-journal.h"
46 #include "sd-bus.h"
47
48 #include "log.h"
49 #include "logs-show.h"
50 #include "util.h"
51 #include "path-util.h"
52 #include "fileio.h"
53 #include "build.h"
54 #include "pager.h"
55 #include "strv.h"
56 #include "set.h"
57 #include "journal-internal.h"
58 #include "journal-def.h"
59 #include "journal-verify.h"
60 #include "journal-authenticate.h"
61 #include "journal-qrcode.h"
62 #include "journal-vacuum.h"
63 #include "fsprg.h"
64 #include "unit-name.h"
65 #include "catalog.h"
66 #include "mkdir.h"
67 #include "bus-util.h"
68 #include "bus-error.h"
69
70 #define DEFAULT_FSS_INTERVAL_USEC (15*USEC_PER_MINUTE)
71
72 enum {
73         /* Special values for arg_lines */
74         ARG_LINES_DEFAULT = -2,
75         ARG_LINES_ALL = -1,
76 };
77
78 static OutputMode arg_output = OUTPUT_SHORT;
79 static bool arg_utc = false;
80 static bool arg_pager_end = false;
81 static bool arg_follow = false;
82 static bool arg_full = true;
83 static bool arg_all = false;
84 static bool arg_no_pager = false;
85 static int arg_lines = ARG_LINES_DEFAULT;
86 static bool arg_no_tail = false;
87 static bool arg_quiet = false;
88 static bool arg_merge = false;
89 static bool arg_boot = false;
90 static sd_id128_t arg_boot_id = {};
91 static int arg_boot_offset = 0;
92 static bool arg_dmesg = false;
93 static const char *arg_cursor = NULL;
94 static const char *arg_after_cursor = NULL;
95 static bool arg_show_cursor = false;
96 static const char *arg_directory = NULL;
97 static char **arg_file = NULL;
98 static int arg_priorities = 0xFF;
99 static const char *arg_verify_key = NULL;
100 #ifdef HAVE_GCRYPT
101 static usec_t arg_interval = DEFAULT_FSS_INTERVAL_USEC;
102 static bool arg_force = false;
103 #endif
104 static usec_t arg_since, arg_until;
105 static bool arg_since_set = false, arg_until_set = false;
106 static char **arg_syslog_identifier = NULL;
107 static char **arg_system_units = NULL;
108 static char **arg_user_units = NULL;
109 static const char *arg_field = NULL;
110 static bool arg_catalog = false;
111 static bool arg_reverse = false;
112 static int arg_journal_type = 0;
113 static const char *arg_root = NULL;
114 static const char *arg_machine = NULL;
115 static off_t arg_vacuum_size = (off_t) -1;
116 static usec_t arg_vacuum_time = USEC_INFINITY;
117
118 static enum {
119         ACTION_SHOW,
120         ACTION_NEW_ID128,
121         ACTION_PRINT_HEADER,
122         ACTION_SETUP_KEYS,
123         ACTION_VERIFY,
124         ACTION_DISK_USAGE,
125         ACTION_LIST_CATALOG,
126         ACTION_DUMP_CATALOG,
127         ACTION_UPDATE_CATALOG,
128         ACTION_LIST_BOOTS,
129         ACTION_FLUSH,
130         ACTION_VACUUM,
131 } arg_action = ACTION_SHOW;
132
133 typedef struct boot_id_t {
134         sd_id128_t id;
135         uint64_t first;
136         uint64_t last;
137 } boot_id_t;
138
139 static void pager_open_if_enabled(void) {
140
141         if (arg_no_pager)
142                 return;
143
144         pager_open(arg_pager_end);
145 }
146
147 static char *format_timestamp_maybe_utc(char *buf, size_t l, usec_t t) {
148
149         if (arg_utc)
150                 return format_timestamp_utc(buf, l, t);
151
152         return format_timestamp(buf, l, t);
153 }
154
155 static int parse_boot_descriptor(const char *x, sd_id128_t *boot_id, int *offset) {
156         sd_id128_t id = SD_ID128_NULL;
157         int off = 0, r;
158
159         if (strlen(x) >= 32) {
160                 char *t;
161
162                 t = strndupa(x, 32);
163                 r = sd_id128_from_string(t, &id);
164                 if (r >= 0)
165                         x += 32;
166
167                 if (*x != '-' && *x != '+' && *x != 0)
168                         return -EINVAL;
169
170                 if (*x != 0) {
171                         r = safe_atoi(x, &off);
172                         if (r < 0)
173                                 return r;
174                 }
175         } else {
176                 r = safe_atoi(x, &off);
177                 if (r < 0)
178                         return r;
179         }
180
181         if (boot_id)
182                 *boot_id = id;
183
184         if (offset)
185                 *offset = off;
186
187         return 0;
188 }
189
190 static void help(void) {
191
192         pager_open_if_enabled();
193
194         printf("%s [OPTIONS...] [MATCHES...]\n\n"
195                "Query the journal.\n\n"
196                "Flags:\n"
197                "     --system              Show the system journal\n"
198                "     --user                Show the user journal for the current user\n"
199                "  -M --machine=CONTAINER   Operate on local container\n"
200                "     --since=DATE          Start showing entries on or newer than the specified date\n"
201                "     --until=DATE          Stop showing entries on or newer than the specified date\n"
202                "  -c --cursor=CURSOR       Start showing entries from the specified cursor\n"
203                "     --after-cursor=CURSOR Start showing entries from after the specified cursor\n"
204                "     --show-cursor         Print the cursor after all the entries\n"
205                "  -b --boot[=ID]           Show data only from ID or, if unspecified, the current boot\n"
206                "     --list-boots          Show terse information about recorded boots\n"
207                "  -k --dmesg               Show kernel message log from the current boot\n"
208                "  -u --unit=UNIT           Show data only from the specified unit\n"
209                "     --user-unit=UNIT      Show data only from the specified user session unit\n"
210                "  -t --identifier=STRING   Show only messages with the specified syslog identifier\n"
211                "  -p --priority=RANGE      Show only messages within the specified priority range\n"
212                "  -e --pager-end           Immediately jump to end of the journal in the pager\n"
213                "  -f --follow              Follow the journal\n"
214                "  -n --lines[=INTEGER]     Number of journal entries to show\n"
215                "     --no-tail             Show all lines, even in follow mode\n"
216                "  -r --reverse             Show the newest entries first\n"
217                "  -o --output=STRING       Change journal output mode (short, short-iso,\n"
218                "                                   short-precise, short-monotonic, verbose,\n"
219                "                                   export, json, json-pretty, json-sse, cat)\n"
220                "     --utc                 Express time in Coordinated Universal Time (UTC)\n"
221                "  -x --catalog             Add message explanations where available\n"
222                "     --no-full             Ellipsize fields\n"
223                "  -a --all                 Show all fields, including long and unprintable\n"
224                "  -q --quiet               Do not show privilege warning\n"
225                "     --no-pager            Do not pipe output into a pager\n"
226                "  -m --merge               Show entries from all available journals\n"
227                "  -D --directory=PATH      Show journal files from directory\n"
228                "     --file=PATH           Show journal file\n"
229                "     --root=ROOT           Operate on catalog files underneath the root ROOT\n"
230 #ifdef HAVE_GCRYPT
231                "     --interval=TIME       Time interval for changing the FSS sealing key\n"
232                "     --verify-key=KEY      Specify FSS verification key\n"
233                "     --force               Force overriding of the FSS key pair with --setup-keys\n"
234 #endif
235                "\nCommands:\n"
236                "  -h --help                Show this help text\n"
237                "     --version             Show package version\n"
238                "  -F --field=FIELD         List all values that a specified field takes\n"
239                "     --new-id128           Generate a new 128-bit ID\n"
240                "     --disk-usage          Show total disk usage of all journal files\n"
241                "     --vacuum-size=BYTES   Remove old journals until disk space drops below size\n"
242                "     --vacuum-time=TIME    Remove old journals until none left older than\n"
243                "     --flush               Flush all journal data from /run into /var\n"
244                "     --header              Show journal header information\n"
245                "     --list-catalog        Show message IDs of all entries in the message catalog\n"
246                "     --dump-catalog        Show entries in the message catalog\n"
247                "     --update-catalog      Update the message catalog database\n"
248 #ifdef HAVE_GCRYPT
249                "     --setup-keys          Generate a new FSS key pair\n"
250                "     --verify              Verify journal file consistency\n"
251 #endif
252                , program_invocation_short_name);
253 }
254
255 static int parse_argv(int argc, char *argv[]) {
256
257         enum {
258                 ARG_VERSION = 0x100,
259                 ARG_NO_PAGER,
260                 ARG_NO_FULL,
261                 ARG_NO_TAIL,
262                 ARG_NEW_ID128,
263                 ARG_LIST_BOOTS,
264                 ARG_USER,
265                 ARG_SYSTEM,
266                 ARG_ROOT,
267                 ARG_HEADER,
268                 ARG_SETUP_KEYS,
269                 ARG_FILE,
270                 ARG_INTERVAL,
271                 ARG_VERIFY,
272                 ARG_VERIFY_KEY,
273                 ARG_DISK_USAGE,
274                 ARG_SINCE,
275                 ARG_UNTIL,
276                 ARG_AFTER_CURSOR,
277                 ARG_SHOW_CURSOR,
278                 ARG_USER_UNIT,
279                 ARG_LIST_CATALOG,
280                 ARG_DUMP_CATALOG,
281                 ARG_UPDATE_CATALOG,
282                 ARG_FORCE,
283                 ARG_UTC,
284                 ARG_FLUSH,
285                 ARG_VACUUM_SIZE,
286                 ARG_VACUUM_TIME,
287         };
288
289         static const struct option options[] = {
290                 { "help",           no_argument,       NULL, 'h'                },
291                 { "version" ,       no_argument,       NULL, ARG_VERSION        },
292                 { "no-pager",       no_argument,       NULL, ARG_NO_PAGER       },
293                 { "pager-end",      no_argument,       NULL, 'e'                },
294                 { "follow",         no_argument,       NULL, 'f'                },
295                 { "force",          no_argument,       NULL, ARG_FORCE          },
296                 { "output",         required_argument, NULL, 'o'                },
297                 { "all",            no_argument,       NULL, 'a'                },
298                 { "full",           no_argument,       NULL, 'l'                },
299                 { "no-full",        no_argument,       NULL, ARG_NO_FULL        },
300                 { "lines",          optional_argument, NULL, 'n'                },
301                 { "no-tail",        no_argument,       NULL, ARG_NO_TAIL        },
302                 { "new-id128",      no_argument,       NULL, ARG_NEW_ID128      },
303                 { "quiet",          no_argument,       NULL, 'q'                },
304                 { "merge",          no_argument,       NULL, 'm'                },
305                 { "boot",           optional_argument, NULL, 'b'                },
306                 { "list-boots",     no_argument,       NULL, ARG_LIST_BOOTS     },
307                 { "this-boot",      optional_argument, NULL, 'b'                }, /* deprecated */
308                 { "dmesg",          no_argument,       NULL, 'k'                },
309                 { "system",         no_argument,       NULL, ARG_SYSTEM         },
310                 { "user",           no_argument,       NULL, ARG_USER           },
311                 { "directory",      required_argument, NULL, 'D'                },
312                 { "file",           required_argument, NULL, ARG_FILE           },
313                 { "root",           required_argument, NULL, ARG_ROOT           },
314                 { "header",         no_argument,       NULL, ARG_HEADER         },
315                 { "identifier",     required_argument, NULL, 't'                },
316                 { "priority",       required_argument, NULL, 'p'                },
317                 { "setup-keys",     no_argument,       NULL, ARG_SETUP_KEYS     },
318                 { "interval",       required_argument, NULL, ARG_INTERVAL       },
319                 { "verify",         no_argument,       NULL, ARG_VERIFY         },
320                 { "verify-key",     required_argument, NULL, ARG_VERIFY_KEY     },
321                 { "disk-usage",     no_argument,       NULL, ARG_DISK_USAGE     },
322                 { "cursor",         required_argument, NULL, 'c'                },
323                 { "after-cursor",   required_argument, NULL, ARG_AFTER_CURSOR   },
324                 { "show-cursor",    no_argument,       NULL, ARG_SHOW_CURSOR    },
325                 { "since",          required_argument, NULL, ARG_SINCE          },
326                 { "until",          required_argument, NULL, ARG_UNTIL          },
327                 { "unit",           required_argument, NULL, 'u'                },
328                 { "user-unit",      required_argument, NULL, ARG_USER_UNIT      },
329                 { "field",          required_argument, NULL, 'F'                },
330                 { "catalog",        no_argument,       NULL, 'x'                },
331                 { "list-catalog",   no_argument,       NULL, ARG_LIST_CATALOG   },
332                 { "dump-catalog",   no_argument,       NULL, ARG_DUMP_CATALOG   },
333                 { "update-catalog", no_argument,       NULL, ARG_UPDATE_CATALOG },
334                 { "reverse",        no_argument,       NULL, 'r'                },
335                 { "machine",        required_argument, NULL, 'M'                },
336                 { "utc",            no_argument,       NULL, ARG_UTC            },
337                 { "flush",          no_argument,       NULL, ARG_FLUSH          },
338                 { "vacuum-size",    required_argument, NULL, ARG_VACUUM_SIZE    },
339                 { "vacuum-time",    required_argument, NULL, ARG_VACUUM_TIME    },
340                 {}
341         };
342
343         int c, r;
344
345         assert(argc >= 0);
346         assert(argv);
347
348         while ((c = getopt_long(argc, argv, "hefo:aln::qmb::kD:p:c:t:u:F:xrM:", options, NULL)) >= 0)
349
350                 switch (c) {
351
352                 case 'h':
353                         help();
354                         return 0;
355
356                 case ARG_VERSION:
357                         puts(PACKAGE_STRING);
358                         puts(SYSTEMD_FEATURES);
359                         return 0;
360
361                 case ARG_NO_PAGER:
362                         arg_no_pager = true;
363                         break;
364
365                 case 'e':
366                         arg_pager_end = true;
367
368                         if (arg_lines == ARG_LINES_DEFAULT)
369                                 arg_lines = 1000;
370
371                         break;
372
373                 case 'f':
374                         arg_follow = true;
375                         break;
376
377                 case 'o':
378                         arg_output = output_mode_from_string(optarg);
379                         if (arg_output < 0) {
380                                 log_error("Unknown output format '%s'.", optarg);
381                                 return -EINVAL;
382                         }
383
384                         if (arg_output == OUTPUT_EXPORT ||
385                             arg_output == OUTPUT_JSON ||
386                             arg_output == OUTPUT_JSON_PRETTY ||
387                             arg_output == OUTPUT_JSON_SSE ||
388                             arg_output == OUTPUT_CAT)
389                                 arg_quiet = true;
390
391                         break;
392
393                 case 'l':
394                         arg_full = true;
395                         break;
396
397                 case ARG_NO_FULL:
398                         arg_full = false;
399                         break;
400
401                 case 'a':
402                         arg_all = true;
403                         break;
404
405                 case 'n':
406                         if (optarg) {
407                                 if (streq(optarg, "all"))
408                                         arg_lines = ARG_LINES_ALL;
409                                 else {
410                                         r = safe_atoi(optarg, &arg_lines);
411                                         if (r < 0 || arg_lines < 0) {
412                                                 log_error("Failed to parse lines '%s'", optarg);
413                                                 return -EINVAL;
414                                         }
415                                 }
416                         } else {
417                                 arg_lines = 10;
418
419                                 /* Hmm, no argument? Maybe the next
420                                  * word on the command line is
421                                  * supposed to be the argument? Let's
422                                  * see if there is one, and is
423                                  * parsable. */
424                                 if (optind < argc) {
425                                         int n;
426                                         if (streq(argv[optind], "all")) {
427                                                 arg_lines = ARG_LINES_ALL;
428                                                 optind++;
429                                         } else if (safe_atoi(argv[optind], &n) >= 0 && n >= 0) {
430                                                 arg_lines = n;
431                                                 optind++;
432                                         }
433                                 }
434                         }
435
436                         break;
437
438                 case ARG_NO_TAIL:
439                         arg_no_tail = true;
440                         break;
441
442                 case ARG_NEW_ID128:
443                         arg_action = ACTION_NEW_ID128;
444                         break;
445
446                 case 'q':
447                         arg_quiet = true;
448                         break;
449
450                 case 'm':
451                         arg_merge = true;
452                         break;
453
454                 case 'b':
455                         arg_boot = true;
456
457                         if (optarg) {
458                                 r =  parse_boot_descriptor(optarg, &arg_boot_id, &arg_boot_offset);
459                                 if (r < 0) {
460                                         log_error("Failed to parse boot descriptor '%s'", optarg);
461                                         return -EINVAL;
462                                 }
463                         } else {
464
465                                 /* Hmm, no argument? Maybe the next
466                                  * word on the command line is
467                                  * supposed to be the argument? Let's
468                                  * see if there is one and is parsable
469                                  * as a boot descriptor... */
470
471                                 if (optind < argc &&
472                                     parse_boot_descriptor(argv[optind], &arg_boot_id, &arg_boot_offset) >= 0)
473                                         optind++;
474                         }
475
476                         break;
477
478                 case ARG_LIST_BOOTS:
479                         arg_action = ACTION_LIST_BOOTS;
480                         break;
481
482                 case 'k':
483                         arg_boot = arg_dmesg = true;
484                         break;
485
486                 case ARG_SYSTEM:
487                         arg_journal_type |= SD_JOURNAL_SYSTEM;
488                         break;
489
490                 case ARG_USER:
491                         arg_journal_type |= SD_JOURNAL_CURRENT_USER;
492                         break;
493
494                 case 'M':
495                         arg_machine = optarg;
496                         break;
497
498                 case 'D':
499                         arg_directory = optarg;
500                         break;
501
502                 case ARG_FILE:
503                         r = glob_extend(&arg_file, optarg);
504                         if (r < 0)
505                                 return log_error_errno(r, "Failed to add paths: %m");
506                         break;
507
508                 case ARG_ROOT:
509                         arg_root = optarg;
510                         break;
511
512                 case 'c':
513                         arg_cursor = optarg;
514                         break;
515
516                 case ARG_AFTER_CURSOR:
517                         arg_after_cursor = optarg;
518                         break;
519
520                 case ARG_SHOW_CURSOR:
521                         arg_show_cursor = true;
522                         break;
523
524                 case ARG_HEADER:
525                         arg_action = ACTION_PRINT_HEADER;
526                         break;
527
528                 case ARG_VERIFY:
529                         arg_action = ACTION_VERIFY;
530                         break;
531
532                 case ARG_DISK_USAGE:
533                         arg_action = ACTION_DISK_USAGE;
534                         break;
535
536                 case ARG_VACUUM_SIZE:
537                         r = parse_size(optarg, 1024, &arg_vacuum_size);
538                         if (r < 0) {
539                                 log_error("Failed to parse vacuum size: %s", optarg);
540                                 return r;
541                         }
542
543                         arg_action = ACTION_VACUUM;
544                         break;
545
546                 case ARG_VACUUM_TIME:
547                         r = parse_sec(optarg, &arg_vacuum_time);
548                         if (r < 0) {
549                                 log_error("Failed to parse vacuum time: %s", optarg);
550                                 return r;
551                         }
552
553                         arg_action = ACTION_VACUUM;
554                         break;
555
556 #ifdef HAVE_GCRYPT
557                 case ARG_FORCE:
558                         arg_force = true;
559                         break;
560
561                 case ARG_SETUP_KEYS:
562                         arg_action = ACTION_SETUP_KEYS;
563                         break;
564
565
566                 case ARG_VERIFY_KEY:
567                         arg_action = ACTION_VERIFY;
568                         arg_verify_key = optarg;
569                         arg_merge = false;
570                         break;
571
572                 case ARG_INTERVAL:
573                         r = parse_sec(optarg, &arg_interval);
574                         if (r < 0 || arg_interval <= 0) {
575                                 log_error("Failed to parse sealing key change interval: %s", optarg);
576                                 return -EINVAL;
577                         }
578                         break;
579 #else
580                 case ARG_SETUP_KEYS:
581                 case ARG_VERIFY_KEY:
582                 case ARG_INTERVAL:
583                 case ARG_FORCE:
584                         log_error("Forward-secure sealing not available.");
585                         return -ENOTSUP;
586 #endif
587
588                 case 'p': {
589                         const char *dots;
590
591                         dots = strstr(optarg, "..");
592                         if (dots) {
593                                 char *a;
594                                 int from, to, i;
595
596                                 /* a range */
597                                 a = strndup(optarg, dots - optarg);
598                                 if (!a)
599                                         return log_oom();
600
601                                 from = log_level_from_string(a);
602                                 to = log_level_from_string(dots + 2);
603                                 free(a);
604
605                                 if (from < 0 || to < 0) {
606                                         log_error("Failed to parse log level range %s", optarg);
607                                         return -EINVAL;
608                                 }
609
610                                 arg_priorities = 0;
611
612                                 if (from < to) {
613                                         for (i = from; i <= to; i++)
614                                                 arg_priorities |= 1 << i;
615                                 } else {
616                                         for (i = to; i <= from; i++)
617                                                 arg_priorities |= 1 << i;
618                                 }
619
620                         } else {
621                                 int p, i;
622
623                                 p = log_level_from_string(optarg);
624                                 if (p < 0) {
625                                         log_error("Unknown log level %s", optarg);
626                                         return -EINVAL;
627                                 }
628
629                                 arg_priorities = 0;
630
631                                 for (i = 0; i <= p; i++)
632                                         arg_priorities |= 1 << i;
633                         }
634
635                         break;
636                 }
637
638                 case ARG_SINCE:
639                         r = parse_timestamp(optarg, &arg_since);
640                         if (r < 0) {
641                                 log_error("Failed to parse timestamp: %s", optarg);
642                                 return -EINVAL;
643                         }
644                         arg_since_set = true;
645                         break;
646
647                 case ARG_UNTIL:
648                         r = parse_timestamp(optarg, &arg_until);
649                         if (r < 0) {
650                                 log_error("Failed to parse timestamp: %s", optarg);
651                                 return -EINVAL;
652                         }
653                         arg_until_set = true;
654                         break;
655
656                 case 't':
657                         r = strv_extend(&arg_syslog_identifier, optarg);
658                         if (r < 0)
659                                 return log_oom();
660                         break;
661
662                 case 'u':
663                         r = strv_extend(&arg_system_units, optarg);
664                         if (r < 0)
665                                 return log_oom();
666                         break;
667
668                 case ARG_USER_UNIT:
669                         r = strv_extend(&arg_user_units, optarg);
670                         if (r < 0)
671                                 return log_oom();
672                         break;
673
674                 case 'F':
675                         arg_field = optarg;
676                         break;
677
678                 case 'x':
679                         arg_catalog = true;
680                         break;
681
682                 case ARG_LIST_CATALOG:
683                         arg_action = ACTION_LIST_CATALOG;
684                         break;
685
686                 case ARG_DUMP_CATALOG:
687                         arg_action = ACTION_DUMP_CATALOG;
688                         break;
689
690                 case ARG_UPDATE_CATALOG:
691                         arg_action = ACTION_UPDATE_CATALOG;
692                         break;
693
694                 case 'r':
695                         arg_reverse = true;
696                         break;
697
698                 case ARG_UTC:
699                         arg_utc = true;
700                         break;
701
702                 case ARG_FLUSH:
703                         arg_action = ACTION_FLUSH;
704                         break;
705
706                 case '?':
707                         return -EINVAL;
708
709                 default:
710                         assert_not_reached("Unhandled option");
711                 }
712
713         if (arg_follow && !arg_no_tail && !arg_since && arg_lines == ARG_LINES_DEFAULT)
714                 arg_lines = 10;
715
716         if (!!arg_directory + !!arg_file + !!arg_machine > 1) {
717                 log_error("Please specify either -D/--directory= or --file= or -M/--machine=, not more than one.");
718                 return -EINVAL;
719         }
720
721         if (arg_since_set && arg_until_set && arg_since > arg_until) {
722                 log_error("--since= must be before --until=.");
723                 return -EINVAL;
724         }
725
726         if (!!arg_cursor + !!arg_after_cursor + !!arg_since_set > 1) {
727                 log_error("Please specify only one of --since=, --cursor=, and --after-cursor.");
728                 return -EINVAL;
729         }
730
731         if (arg_follow && arg_reverse) {
732                 log_error("Please specify either --reverse= or --follow=, not both.");
733                 return -EINVAL;
734         }
735
736         if (arg_action != ACTION_SHOW && optind < argc) {
737                 log_error("Extraneous arguments starting with '%s'", argv[optind]);
738                 return -EINVAL;
739         }
740
741         return 1;
742 }
743
744 static int generate_new_id128(void) {
745         sd_id128_t id;
746         int r;
747         unsigned i;
748
749         r = sd_id128_randomize(&id);
750         if (r < 0)
751                 return log_error_errno(r, "Failed to generate ID: %m");
752
753         printf("As string:\n"
754                SD_ID128_FORMAT_STR "\n\n"
755                "As UUID:\n"
756                "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n\n"
757                "As macro:\n"
758                "#define MESSAGE_XYZ SD_ID128_MAKE(",
759                SD_ID128_FORMAT_VAL(id),
760                SD_ID128_FORMAT_VAL(id));
761         for (i = 0; i < 16; i++)
762                 printf("%02x%s", id.bytes[i], i != 15 ? "," : "");
763         fputs(")\n\n", stdout);
764
765         printf("As Python constant:\n"
766                ">>> import uuid\n"
767                ">>> MESSAGE_XYZ = uuid.UUID('" SD_ID128_FORMAT_STR "')\n",
768                SD_ID128_FORMAT_VAL(id));
769
770         return 0;
771 }
772
773 static int add_matches(sd_journal *j, char **args) {
774         char **i;
775         bool have_term = false;
776
777         assert(j);
778
779         STRV_FOREACH(i, args) {
780                 int r;
781
782                 if (streq(*i, "+")) {
783                         if (!have_term)
784                                 break;
785                         r = sd_journal_add_disjunction(j);
786                         have_term = false;
787
788                 } else if (path_is_absolute(*i)) {
789                         _cleanup_free_ char *p, *t = NULL, *t2 = NULL;
790                         const char *path;
791                         _cleanup_free_ char *interpreter = NULL;
792                         struct stat st;
793
794                         p = canonicalize_file_name(*i);
795                         path = p ? p : *i;
796
797                         if (stat(path, &st) < 0)
798                                 return log_error_errno(errno, "Couldn't stat file: %m");
799
800                         if (S_ISREG(st.st_mode) && (0111 & st.st_mode)) {
801                                 if (executable_is_script(path, &interpreter) > 0) {
802                                         _cleanup_free_ char *comm;
803
804                                         comm = strndup(basename(path), 15);
805                                         if (!comm)
806                                                 return log_oom();
807
808                                         t = strappend("_COMM=", comm);
809
810                                         /* Append _EXE only if the interpreter is not a link.
811                                            Otherwise, it might be outdated often. */
812                                         if (lstat(interpreter, &st) == 0 &&
813                                             !S_ISLNK(st.st_mode)) {
814                                                 t2 = strappend("_EXE=", interpreter);
815                                                 if (!t2)
816                                                         return log_oom();
817                                         }
818                                 } else
819                                         t = strappend("_EXE=", path);
820                         } else if (S_ISCHR(st.st_mode)) {
821                                 if (asprintf(&t, "_KERNEL_DEVICE=c%u:%u",
822                                              major(st.st_rdev),
823                                              minor(st.st_rdev)) < 0)
824                                         return -ENOMEM;
825                         } else if (S_ISBLK(st.st_mode)) {
826                                 if (asprintf(&t, "_KERNEL_DEVICE=b%u:%u",
827                                              major(st.st_rdev),
828                                              minor(st.st_rdev)) < 0)
829                                         return -ENOMEM;
830                         } else {
831                                 log_error("File is neither a device node, nor regular file, nor executable: %s", *i);
832                                 return -EINVAL;
833                         }
834
835                         if (!t)
836                                 return log_oom();
837
838                         r = sd_journal_add_match(j, t, 0);
839                         if (t2)
840                                 r = sd_journal_add_match(j, t2, 0);
841                         have_term = true;
842
843                 } else {
844                         r = sd_journal_add_match(j, *i, 0);
845                         have_term = true;
846                 }
847
848                 if (r < 0)
849                         return log_error_errno(r, "Failed to add match '%s': %m", *i);
850         }
851
852         if (!strv_isempty(args) && !have_term) {
853                 log_error("\"+\" can only be used between terms");
854                 return -EINVAL;
855         }
856
857         return 0;
858 }
859
860 static int boot_id_cmp(const void *a, const void *b) {
861         uint64_t _a, _b;
862
863         _a = ((const boot_id_t *)a)->first;
864         _b = ((const boot_id_t *)b)->first;
865
866         return _a < _b ? -1 : (_a > _b ? 1 : 0);
867 }
868
869 static int get_boots(sd_journal *j,
870                      boot_id_t **boots,
871                      unsigned int *count,
872                      boot_id_t *query_ref_boot) {
873         int r;
874         const void *data;
875         size_t length, allocated = 0;
876
877         assert(j);
878         assert(boots);
879         assert(count);
880
881         r = sd_journal_query_unique(j, "_BOOT_ID");
882         if (r < 0)
883                 return r;
884
885         *count = 0;
886         SD_JOURNAL_FOREACH_UNIQUE(j, data, length) {
887                 boot_id_t *id;
888
889                 assert(startswith(data, "_BOOT_ID="));
890
891                 if (!GREEDY_REALLOC(*boots, allocated, *count + 1))
892                         return log_oom();
893
894                 id = *boots + *count;
895
896                 r = sd_id128_from_string(((const char *)data) + strlen("_BOOT_ID="), &id->id);
897                 if (r < 0)
898                         continue;
899
900                 r = sd_journal_add_match(j, data, length);
901                 if (r < 0)
902                         return r;
903
904                 r = sd_journal_seek_head(j);
905                 if (r < 0)
906                         return r;
907
908                 r = sd_journal_next(j);
909                 if (r < 0)
910                         return r;
911                 else if (r == 0)
912                         goto flush;
913
914                 r = sd_journal_get_realtime_usec(j, &id->first);
915                 if (r < 0)
916                         return r;
917
918                 if (query_ref_boot) {
919                         id->last = 0;
920                         if (sd_id128_equal(id->id, query_ref_boot->id))
921                                 *query_ref_boot = *id;
922                 } else {
923                         r = sd_journal_seek_tail(j);
924                         if (r < 0)
925                                 return r;
926
927                         r = sd_journal_previous(j);
928                         if (r < 0)
929                                 return r;
930                         else if (r == 0)
931                                 goto flush;
932
933                         r = sd_journal_get_realtime_usec(j, &id->last);
934                         if (r < 0)
935                                 return r;
936                 }
937
938                 (*count)++;
939         flush:
940                 sd_journal_flush_matches(j);
941         }
942
943         qsort_safe(*boots, *count, sizeof(boot_id_t), boot_id_cmp);
944         return 0;
945 }
946
947 static int list_boots(sd_journal *j) {
948         int r, w, i;
949         unsigned int count;
950         boot_id_t *id;
951         _cleanup_free_ boot_id_t *all_ids = NULL;
952
953         assert(j);
954
955         r = get_boots(j, &all_ids, &count, NULL);
956         if (r < 0)
957                 return r;
958
959         pager_open_if_enabled();
960
961         /* numbers are one less, but we need an extra char for the sign */
962         w = DECIMAL_STR_WIDTH(count - 1) + 1;
963
964         for (id = all_ids, i = 0; id < all_ids + count; id++, i++) {
965                 char a[FORMAT_TIMESTAMP_MAX], b[FORMAT_TIMESTAMP_MAX];
966
967                 printf("% *i " SD_ID128_FORMAT_STR " %s—%s\n",
968                        w, i - count + 1,
969                        SD_ID128_FORMAT_VAL(id->id),
970                        format_timestamp_maybe_utc(a, sizeof(a), id->first),
971                        format_timestamp_maybe_utc(b, sizeof(b), id->last));
972         }
973
974         return 0;
975 }
976
977 static int get_boot_id_by_offset(sd_journal *j, sd_id128_t *boot_id, int offset) {
978         int r;
979         unsigned int count;
980         boot_id_t ref_boot_id = {}, *id;
981         _cleanup_free_ boot_id_t *all_ids = NULL;
982
983         assert(j);
984         assert(boot_id);
985
986         ref_boot_id.id = *boot_id;
987         r = get_boots(j, &all_ids, &count, &ref_boot_id);
988         if (r < 0)
989                 return r;
990
991         if (sd_id128_equal(*boot_id, SD_ID128_NULL)) {
992                 if (offset > (int) count || offset <= -(int)count)
993                         return -EADDRNOTAVAIL;
994
995                 *boot_id = all_ids[(offset <= 0)*count + offset - 1].id;
996         } else {
997                 id = bsearch(&ref_boot_id, all_ids, count, sizeof(boot_id_t), boot_id_cmp);
998
999                 if (!id ||
1000                     offset <= 0 ? (id - all_ids) + offset < 0 :
1001                                     (id - all_ids) + offset >= (int) count)
1002                         return -EADDRNOTAVAIL;
1003
1004                 *boot_id = (id + offset)->id;
1005         }
1006
1007         return 0;
1008 }
1009
1010 static int add_boot(sd_journal *j) {
1011         char match[9+32+1] = "_BOOT_ID=";
1012         int r;
1013
1014         assert(j);
1015
1016         if (!arg_boot)
1017                 return 0;
1018
1019         if (arg_boot_offset == 0 && sd_id128_equal(arg_boot_id, SD_ID128_NULL))
1020                 return add_match_this_boot(j, arg_machine);
1021
1022         r = get_boot_id_by_offset(j, &arg_boot_id, arg_boot_offset);
1023         if (r < 0) {
1024                 if (sd_id128_equal(arg_boot_id, SD_ID128_NULL))
1025                         log_error_errno(r, "Failed to look up boot %+i: %m", arg_boot_offset);
1026                 else
1027                         log_error("Failed to look up boot ID "SD_ID128_FORMAT_STR"%+i: %s",
1028                                   SD_ID128_FORMAT_VAL(arg_boot_id), arg_boot_offset, strerror(-r));
1029                 return r;
1030         }
1031
1032         sd_id128_to_string(arg_boot_id, match + 9);
1033
1034         r = sd_journal_add_match(j, match, sizeof(match) - 1);
1035         if (r < 0)
1036                 return log_error_errno(r, "Failed to add match: %m");
1037
1038         r = sd_journal_add_conjunction(j);
1039         if (r < 0)
1040                 return r;
1041
1042         return 0;
1043 }
1044
1045 static int add_dmesg(sd_journal *j) {
1046         int r;
1047         assert(j);
1048
1049         if (!arg_dmesg)
1050                 return 0;
1051
1052         r = sd_journal_add_match(j, "_TRANSPORT=kernel", strlen("_TRANSPORT=kernel"));
1053         if (r < 0)
1054                 return log_error_errno(r, "Failed to add match: %m");
1055
1056         r = sd_journal_add_conjunction(j);
1057         if (r < 0)
1058                 return r;
1059
1060         return 0;
1061 }
1062
1063 static int get_possible_units(sd_journal *j,
1064                               const char *fields,
1065                               char **patterns,
1066                               Set **units) {
1067         _cleanup_set_free_free_ Set *found;
1068         const char *field;
1069         int r;
1070
1071         found = set_new(&string_hash_ops);
1072         if (!found)
1073                 return log_oom();
1074
1075         NULSTR_FOREACH(field, fields) {
1076                 const void *data;
1077                 size_t size;
1078
1079                 r = sd_journal_query_unique(j, field);
1080                 if (r < 0)
1081                         return r;
1082
1083                 SD_JOURNAL_FOREACH_UNIQUE(j, data, size) {
1084                         char **pattern, *eq;
1085                         size_t prefix;
1086                         _cleanup_free_ char *u = NULL;
1087
1088                         eq = memchr(data, '=', size);
1089                         if (eq)
1090                                 prefix = eq - (char*) data + 1;
1091                         else
1092                                 prefix = 0;
1093
1094                         u = strndup((char*) data + prefix, size - prefix);
1095                         if (!u)
1096                                 return log_oom();
1097
1098                         STRV_FOREACH(pattern, patterns)
1099                                 if (fnmatch(*pattern, u, FNM_NOESCAPE) == 0) {
1100                                         log_debug("Matched %s with pattern %s=%s", u, field, *pattern);
1101
1102                                         r = set_consume(found, u);
1103                                         u = NULL;
1104                                         if (r < 0 && r != -EEXIST)
1105                                                 return r;
1106
1107                                         break;
1108                                 }
1109                 }
1110         }
1111
1112         *units = found;
1113         found = NULL;
1114         return 0;
1115 }
1116
1117 /* This list is supposed to return the superset of unit names
1118  * possibly matched by rules added with add_matches_for_unit... */
1119 #define SYSTEM_UNITS                 \
1120         "_SYSTEMD_UNIT\0"            \
1121         "COREDUMP_UNIT\0"            \
1122         "UNIT\0"                     \
1123         "OBJECT_SYSTEMD_UNIT\0"      \
1124         "_SYSTEMD_SLICE\0"
1125
1126 /* ... and add_matches_for_user_unit */
1127 #define USER_UNITS                   \
1128         "_SYSTEMD_USER_UNIT\0"       \
1129         "USER_UNIT\0"                \
1130         "COREDUMP_USER_UNIT\0"       \
1131         "OBJECT_SYSTEMD_USER_UNIT\0"
1132
1133 static int add_units(sd_journal *j) {
1134         _cleanup_strv_free_ char **patterns = NULL;
1135         int r, count = 0;
1136         char **i;
1137
1138         assert(j);
1139
1140         STRV_FOREACH(i, arg_system_units) {
1141                 _cleanup_free_ char *u = NULL;
1142
1143                 u = unit_name_mangle(*i, MANGLE_GLOB);
1144                 if (!u)
1145                         return log_oom();
1146
1147                 if (string_is_glob(u)) {
1148                         r = strv_push(&patterns, u);
1149                         if (r < 0)
1150                                 return r;
1151                         u = NULL;
1152                 } else {
1153                         r = add_matches_for_unit(j, u);
1154                         if (r < 0)
1155                                 return r;
1156                         r = sd_journal_add_disjunction(j);
1157                         if (r < 0)
1158                                 return r;
1159                         count ++;
1160                 }
1161         }
1162
1163         if (!strv_isempty(patterns)) {
1164                 _cleanup_set_free_free_ Set *units = NULL;
1165                 Iterator it;
1166                 char *u;
1167
1168                 r = get_possible_units(j, SYSTEM_UNITS, patterns, &units);
1169                 if (r < 0)
1170                         return r;
1171
1172                 SET_FOREACH(u, units, it) {
1173                         r = add_matches_for_unit(j, u);
1174                         if (r < 0)
1175                                 return r;
1176                         r = sd_journal_add_disjunction(j);
1177                         if (r < 0)
1178                                 return r;
1179                         count ++;
1180                 }
1181         }
1182
1183         strv_free(patterns);
1184         patterns = NULL;
1185
1186         STRV_FOREACH(i, arg_user_units) {
1187                 _cleanup_free_ char *u = NULL;
1188
1189                 u = unit_name_mangle(*i, MANGLE_GLOB);
1190                 if (!u)
1191                         return log_oom();
1192
1193                 if (string_is_glob(u)) {
1194                         r = strv_push(&patterns, u);
1195                         if (r < 0)
1196                                 return r;
1197                         u = NULL;
1198                 } else {
1199                         r = add_matches_for_user_unit(j, u, getuid());
1200                         if (r < 0)
1201                                 return r;
1202                         r = sd_journal_add_disjunction(j);
1203                         if (r < 0)
1204                                 return r;
1205                         count ++;
1206                 }
1207         }
1208
1209         if (!strv_isempty(patterns)) {
1210                 _cleanup_set_free_free_ Set *units = NULL;
1211                 Iterator it;
1212                 char *u;
1213
1214                 r = get_possible_units(j, USER_UNITS, patterns, &units);
1215                 if (r < 0)
1216                         return r;
1217
1218                 SET_FOREACH(u, units, it) {
1219                         r = add_matches_for_user_unit(j, u, getuid());
1220                         if (r < 0)
1221                                 return r;
1222                         r = sd_journal_add_disjunction(j);
1223                         if (r < 0)
1224                                 return r;
1225                         count ++;
1226                 }
1227         }
1228
1229         /* Complain if the user request matches but nothing whatsoever was
1230          * found, since otherwise everything would be matched. */
1231         if (!(strv_isempty(arg_system_units) && strv_isempty(arg_user_units)) && count == 0)
1232                 return -ENODATA;
1233
1234         r = sd_journal_add_conjunction(j);
1235         if (r < 0)
1236                 return r;
1237
1238         return 0;
1239 }
1240
1241 static int add_priorities(sd_journal *j) {
1242         char match[] = "PRIORITY=0";
1243         int i, r;
1244         assert(j);
1245
1246         if (arg_priorities == 0xFF)
1247                 return 0;
1248
1249         for (i = LOG_EMERG; i <= LOG_DEBUG; i++)
1250                 if (arg_priorities & (1 << i)) {
1251                         match[sizeof(match)-2] = '0' + i;
1252
1253                         r = sd_journal_add_match(j, match, strlen(match));
1254                         if (r < 0)
1255                                 return log_error_errno(r, "Failed to add match: %m");
1256                 }
1257
1258         r = sd_journal_add_conjunction(j);
1259         if (r < 0)
1260                 return r;
1261
1262         return 0;
1263 }
1264
1265
1266 static int add_syslog_identifier(sd_journal *j) {
1267         int r;
1268         char **i;
1269
1270         assert(j);
1271
1272         STRV_FOREACH(i, arg_syslog_identifier) {
1273                 char *u;
1274
1275                 u = strappenda("SYSLOG_IDENTIFIER=", *i);
1276                 r = sd_journal_add_match(j, u, 0);
1277                 if (r < 0)
1278                         return r;
1279                 r = sd_journal_add_disjunction(j);
1280                 if (r < 0)
1281                         return r;
1282         }
1283
1284         r = sd_journal_add_conjunction(j);
1285         if (r < 0)
1286                 return r;
1287
1288         return 0;
1289 }
1290
1291 static int setup_keys(void) {
1292 #ifdef HAVE_GCRYPT
1293         size_t mpk_size, seed_size, state_size, i;
1294         uint8_t *mpk, *seed, *state;
1295         ssize_t l;
1296         int fd = -1, r, attr = 0;
1297         sd_id128_t machine, boot;
1298         char *p = NULL, *k = NULL;
1299         struct FSSHeader h;
1300         uint64_t n;
1301         struct stat st;
1302
1303         r = stat("/var/log/journal", &st);
1304         if (r < 0 && errno != ENOENT && errno != ENOTDIR)
1305                 return log_error_errno(errno, "stat(\"%s\") failed: %m", "/var/log/journal");
1306
1307         if (r < 0 || !S_ISDIR(st.st_mode)) {
1308                 log_error("%s is not a directory, must be using persistent logging for FSS.",
1309                           "/var/log/journal");
1310                 return r < 0 ? -errno : -ENOTDIR;
1311         }
1312
1313         r = sd_id128_get_machine(&machine);
1314         if (r < 0)
1315                 return log_error_errno(r, "Failed to get machine ID: %m");
1316
1317         r = sd_id128_get_boot(&boot);
1318         if (r < 0)
1319                 return log_error_errno(r, "Failed to get boot ID: %m");
1320
1321         if (asprintf(&p, "/var/log/journal/" SD_ID128_FORMAT_STR "/fss",
1322                      SD_ID128_FORMAT_VAL(machine)) < 0)
1323                 return log_oom();
1324
1325         if (access(p, F_OK) >= 0) {
1326                 if (arg_force) {
1327                         r = unlink(p);
1328                         if (r < 0) {
1329                                 log_error_errno(errno, "unlink(\"%s\") failed: %m", p);
1330                                 r = -errno;
1331                                 goto finish;
1332                         }
1333                 } else {
1334                         log_error("Sealing key file %s exists already. (--force to recreate)", p);
1335                         r = -EEXIST;
1336                         goto finish;
1337                 }
1338         }
1339
1340         if (asprintf(&k, "/var/log/journal/" SD_ID128_FORMAT_STR "/fss.tmp.XXXXXX",
1341                      SD_ID128_FORMAT_VAL(machine)) < 0) {
1342                 r = log_oom();
1343                 goto finish;
1344         }
1345
1346         mpk_size = FSPRG_mskinbytes(FSPRG_RECOMMENDED_SECPAR);
1347         mpk = alloca(mpk_size);
1348
1349         seed_size = FSPRG_RECOMMENDED_SEEDLEN;
1350         seed = alloca(seed_size);
1351
1352         state_size = FSPRG_stateinbytes(FSPRG_RECOMMENDED_SECPAR);
1353         state = alloca(state_size);
1354
1355         fd = open("/dev/random", O_RDONLY|O_CLOEXEC|O_NOCTTY);
1356         if (fd < 0) {
1357                 log_error_errno(errno, "Failed to open /dev/random: %m");
1358                 r = -errno;
1359                 goto finish;
1360         }
1361
1362         log_info("Generating seed...");
1363         l = loop_read(fd, seed, seed_size, true);
1364         if (l < 0 || (size_t) l != seed_size) {
1365                 log_error_errno(EIO, "Failed to read random seed: %m");
1366                 r = -EIO;
1367                 goto finish;
1368         }
1369
1370         log_info("Generating key pair...");
1371         FSPRG_GenMK(NULL, mpk, seed, seed_size, FSPRG_RECOMMENDED_SECPAR);
1372
1373         log_info("Generating sealing key...");
1374         FSPRG_GenState0(state, mpk, seed, seed_size);
1375
1376         assert(arg_interval > 0);
1377
1378         n = now(CLOCK_REALTIME);
1379         n /= arg_interval;
1380
1381         safe_close(fd);
1382         fd = mkostemp_safe(k, O_WRONLY|O_CLOEXEC);
1383         if (fd < 0) {
1384                 log_error_errno(errno, "Failed to open %s: %m", k);
1385                 r = -errno;
1386                 goto finish;
1387         }
1388
1389         /* Enable secure remove, exclusion from dump, synchronous
1390          * writing and in-place updating */
1391         if (ioctl(fd, FS_IOC_GETFLAGS, &attr) < 0)
1392                 log_warning_errno(errno, "FS_IOC_GETFLAGS failed: %m");
1393
1394         attr |= FS_SECRM_FL|FS_NODUMP_FL|FS_SYNC_FL|FS_NOCOW_FL;
1395
1396         if (ioctl(fd, FS_IOC_SETFLAGS, &attr) < 0)
1397                 log_warning_errno(errno, "FS_IOC_SETFLAGS failed: %m");
1398
1399         zero(h);
1400         memcpy(h.signature, "KSHHRHLP", 8);
1401         h.machine_id = machine;
1402         h.boot_id = boot;
1403         h.header_size = htole64(sizeof(h));
1404         h.start_usec = htole64(n * arg_interval);
1405         h.interval_usec = htole64(arg_interval);
1406         h.fsprg_secpar = htole16(FSPRG_RECOMMENDED_SECPAR);
1407         h.fsprg_state_size = htole64(state_size);
1408
1409         l = loop_write(fd, &h, sizeof(h), false);
1410         if (l < 0 || (size_t) l != sizeof(h)) {
1411                 log_error_errno(EIO, "Failed to write header: %m");
1412                 r = -EIO;
1413                 goto finish;
1414         }
1415
1416         l = loop_write(fd, state, state_size, false);
1417         if (l < 0 || (size_t) l != state_size) {
1418                 log_error_errno(EIO, "Failed to write state: %m");
1419                 r = -EIO;
1420                 goto finish;
1421         }
1422
1423         if (link(k, p) < 0) {
1424                 log_error_errno(errno, "Failed to link file: %m");
1425                 r = -errno;
1426                 goto finish;
1427         }
1428
1429         if (on_tty()) {
1430                 fprintf(stderr,
1431                         "\n"
1432                         "The new key pair has been generated. The " ANSI_HIGHLIGHT_ON "secret sealing key" ANSI_HIGHLIGHT_OFF " has been written to\n"
1433                         "the following local file. This key file is automatically updated when the\n"
1434                         "sealing key is advanced. It should not be used on multiple hosts.\n"
1435                         "\n"
1436                         "\t%s\n"
1437                         "\n"
1438                         "Please write down the following " ANSI_HIGHLIGHT_ON "secret verification key" ANSI_HIGHLIGHT_OFF ". It should be stored\n"
1439                         "at a safe location and should not be saved locally on disk.\n"
1440                         "\n\t" ANSI_HIGHLIGHT_RED_ON, p);
1441                 fflush(stderr);
1442         }
1443         for (i = 0; i < seed_size; i++) {
1444                 if (i > 0 && i % 3 == 0)
1445                         putchar('-');
1446                 printf("%02x", ((uint8_t*) seed)[i]);
1447         }
1448
1449         printf("/%llx-%llx\n", (unsigned long long) n, (unsigned long long) arg_interval);
1450
1451         if (on_tty()) {
1452                 char tsb[FORMAT_TIMESPAN_MAX], *hn;
1453
1454                 fprintf(stderr,
1455                         ANSI_HIGHLIGHT_OFF "\n"
1456                         "The sealing key is automatically changed every %s.\n",
1457                         format_timespan(tsb, sizeof(tsb), arg_interval, 0));
1458
1459                 hn = gethostname_malloc();
1460
1461                 if (hn) {
1462                         hostname_cleanup(hn, false);
1463                         fprintf(stderr, "\nThe keys have been generated for host %s/" SD_ID128_FORMAT_STR ".\n", hn, SD_ID128_FORMAT_VAL(machine));
1464                 } else
1465                         fprintf(stderr, "\nThe keys have been generated for host " SD_ID128_FORMAT_STR ".\n", SD_ID128_FORMAT_VAL(machine));
1466
1467 #ifdef HAVE_QRENCODE
1468                 /* If this is not an UTF-8 system don't print any QR codes */
1469                 if (is_locale_utf8()) {
1470                         fputs("\nTo transfer the verification key to your phone please scan the QR code below:\n\n", stderr);
1471                         print_qr_code(stderr, seed, seed_size, n, arg_interval, hn, machine);
1472                 }
1473 #endif
1474                 free(hn);
1475         }
1476
1477         r = 0;
1478
1479 finish:
1480         safe_close(fd);
1481
1482         if (k) {
1483                 unlink(k);
1484                 free(k);
1485         }
1486
1487         free(p);
1488
1489         return r;
1490 #else
1491         log_error("Forward-secure sealing not available.");
1492         return -ENOTSUP;
1493 #endif
1494 }
1495
1496 static int verify(sd_journal *j) {
1497         int r = 0;
1498         Iterator i;
1499         JournalFile *f;
1500
1501         assert(j);
1502
1503         log_show_color(true);
1504
1505         ORDERED_HASHMAP_FOREACH(f, j->files, i) {
1506                 int k;
1507                 usec_t first, validated, last;
1508
1509 #ifdef HAVE_GCRYPT
1510                 if (!arg_verify_key && JOURNAL_HEADER_SEALED(f->header))
1511                         log_notice("Journal file %s has sealing enabled but verification key has not been passed using --verify-key=.", f->path);
1512 #endif
1513
1514                 k = journal_file_verify(f, arg_verify_key, &first, &validated, &last, true);
1515                 if (k == -EINVAL) {
1516                         /* If the key was invalid give up right-away. */
1517                         return k;
1518                 } else if (k < 0) {
1519                         log_warning("FAIL: %s (%s)", f->path, strerror(-k));
1520                         r = k;
1521                 } else {
1522                         char a[FORMAT_TIMESTAMP_MAX], b[FORMAT_TIMESTAMP_MAX], c[FORMAT_TIMESPAN_MAX];
1523                         log_info("PASS: %s", f->path);
1524
1525                         if (arg_verify_key && JOURNAL_HEADER_SEALED(f->header)) {
1526                                 if (validated > 0) {
1527                                         log_info("=> Validated from %s to %s, final %s entries not sealed.",
1528                                                  format_timestamp_maybe_utc(a, sizeof(a), first),
1529                                                  format_timestamp_maybe_utc(b, sizeof(b), validated),
1530                                                  format_timespan(c, sizeof(c), last > validated ? last - validated : 0, 0));
1531                                 } else if (last > 0)
1532                                         log_info("=> No sealing yet, %s of entries not sealed.",
1533                                                  format_timespan(c, sizeof(c), last - first, 0));
1534                                 else
1535                                         log_info("=> No sealing yet, no entries in file.");
1536                         }
1537                 }
1538         }
1539
1540         return r;
1541 }
1542
1543 #ifdef HAVE_ACL
1544 static int access_check_var_log_journal(sd_journal *j) {
1545         _cleanup_strv_free_ char **g = NULL;
1546         bool have_access;
1547         int r;
1548
1549         assert(j);
1550
1551         have_access = in_group("systemd-journal") > 0;
1552
1553         if (!have_access) {
1554                 /* Let's enumerate all groups from the default ACL of
1555                  * the directory, which generally should allow access
1556                  * to most journal files too */
1557                 r = search_acl_groups(&g, "/var/log/journal/", &have_access);
1558                 if (r < 0)
1559                         return r;
1560         }
1561
1562         if (!have_access) {
1563
1564                 if (strv_isempty(g))
1565                         log_notice("Hint: You are currently not seeing messages from other users and the system.\n"
1566                                    "      Users in the 'systemd-journal' group can see all messages. Pass -q to\n"
1567                                    "      turn off this notice.");
1568                 else {
1569                         _cleanup_free_ char *s = NULL;
1570
1571                         r = strv_extend(&g, "systemd-journal");
1572                         if (r < 0)
1573                                 return log_oom();
1574
1575                         strv_sort(g);
1576                         strv_uniq(g);
1577
1578                         s = strv_join(g, "', '");
1579                         if (!s)
1580                                 return log_oom();
1581
1582                         log_notice("Hint: You are currently not seeing messages from other users and the system.\n"
1583                                    "      Users in the groups '%s' can see all messages.\n"
1584                                    "      Pass -q to turn off this notice.", s);
1585                 }
1586         }
1587
1588         return 0;
1589 }
1590 #endif
1591
1592 static int access_check(sd_journal *j) {
1593         Iterator it;
1594         void *code;
1595         int r = 0;
1596
1597         assert(j);
1598
1599         if (set_isempty(j->errors)) {
1600                 if (ordered_hashmap_isempty(j->files))
1601                         log_notice("No journal files were found.");
1602                 return 0;
1603         }
1604
1605         if (set_contains(j->errors, INT_TO_PTR(-EACCES))) {
1606 #ifdef HAVE_ACL
1607                 /* If /var/log/journal doesn't even exist,
1608                  * unprivileged users have no access at all */
1609                 if (access("/var/log/journal", F_OK) < 0 &&
1610                     geteuid() != 0 &&
1611                     in_group("systemd-journal") <= 0) {
1612                         log_error("Unprivileged users cannot access messages, unless persistent log storage is\n"
1613                                   "enabled. Users in the 'systemd-journal' group may always access messages.");
1614                         return -EACCES;
1615                 }
1616
1617                 /* If /var/log/journal exists, try to pring a nice
1618                    notice if the user lacks access to it */
1619                 if (!arg_quiet && geteuid() != 0) {
1620                         r = access_check_var_log_journal(j);
1621                         if (r < 0)
1622                                 return r;
1623                 }
1624 #else
1625                 if (geteuid() != 0 && in_group("systemd-journal") <= 0) {
1626                         log_error("Unprivileged users cannot access messages. Users in the 'systemd-journal' group\n"
1627                                   "group may access messages.");
1628                         return -EACCES;
1629                 }
1630 #endif
1631
1632                 if (ordered_hashmap_isempty(j->files)) {
1633                         log_error("No journal files were opened due to insufficient permissions.");
1634                         r = -EACCES;
1635                 }
1636         }
1637
1638         SET_FOREACH(code, j->errors, it) {
1639                 int err;
1640
1641                 err = -PTR_TO_INT(code);
1642                 assert(err > 0);
1643
1644                 if (err != EACCES)
1645                         log_warning_errno(err, "Error was encountered while opening journal files: %m");
1646         }
1647
1648         return r;
1649 }
1650
1651 static int flush_to_var(void) {
1652         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1653         _cleanup_bus_close_unref_ sd_bus *bus = NULL;
1654         _cleanup_close_ int watch_fd = -1;
1655         int r;
1656
1657         /* Quick exit */
1658         if (access("/run/systemd/journal/flushed", F_OK) >= 0)
1659                 return 0;
1660
1661         /* OK, let's actually do the full logic, send SIGUSR1 to the
1662          * daemon and set up inotify to wait for the flushed file to appear */
1663         r = bus_open_system_systemd(&bus);
1664         if (r < 0)
1665                 return log_error_errno(r, "Failed to get D-Bus connection: %m");
1666
1667         r = sd_bus_call_method(
1668                         bus,
1669                         "org.freedesktop.systemd1",
1670                         "/org/freedesktop/systemd1",
1671                         "org.freedesktop.systemd1.Manager",
1672                         "KillUnit",
1673                         &error,
1674                         NULL,
1675                         "ssi", "systemd-journald.service", "main", SIGUSR1);
1676         if (r < 0) {
1677                 log_error("Failed to kill journal service: %s", bus_error_message(&error, r));
1678                 return r;
1679         }
1680
1681         mkdir_p("/run/systemd/journal", 0755);
1682
1683         watch_fd = inotify_init1(IN_NONBLOCK|IN_CLOEXEC);
1684         if (watch_fd < 0)
1685                 return log_error_errno(errno, "Failed to create inotify watch: %m");
1686
1687         r = inotify_add_watch(watch_fd, "/run/systemd/journal", IN_CREATE|IN_DONT_FOLLOW|IN_ONLYDIR);
1688         if (r < 0)
1689                 return log_error_errno(errno, "Failed to watch journal directory: %m");
1690
1691         for (;;) {
1692                 if (access("/run/systemd/journal/flushed", F_OK) >= 0)
1693                         break;
1694
1695                 if (errno != ENOENT)
1696                         return log_error_errno(errno, "Failed to check for existance of /run/systemd/journal/flushed: %m");
1697
1698                 r = fd_wait_for_event(watch_fd, POLLIN, USEC_INFINITY);
1699                 if (r < 0)
1700                         return log_error_errno(r, "Failed to wait for event: %m");
1701
1702                 r = flush_fd(watch_fd);
1703                 if (r < 0)
1704                         return log_error_errno(r, "Failed to flush inotify events: %m");
1705         }
1706
1707         return 0;
1708 }
1709
1710 int main(int argc, char *argv[]) {
1711         int r;
1712         _cleanup_journal_close_ sd_journal *j = NULL;
1713         bool need_seek = false;
1714         sd_id128_t previous_boot_id;
1715         bool previous_boot_id_valid = false, first_line = true;
1716         int n_shown = 0;
1717         bool ellipsized = false;
1718
1719         setlocale(LC_ALL, "");
1720         log_parse_environment();
1721         log_open();
1722
1723         r = parse_argv(argc, argv);
1724         if (r <= 0)
1725                 goto finish;
1726
1727         signal(SIGWINCH, columns_lines_cache_reset);
1728
1729         if (arg_action == ACTION_NEW_ID128) {
1730                 r = generate_new_id128();
1731                 goto finish;
1732         }
1733
1734         if (arg_action == ACTION_FLUSH) {
1735                 r = flush_to_var();
1736                 goto finish;
1737         }
1738
1739         if (arg_action == ACTION_SETUP_KEYS) {
1740                 r = setup_keys();
1741                 goto finish;
1742         }
1743
1744         if (arg_action == ACTION_UPDATE_CATALOG ||
1745             arg_action == ACTION_LIST_CATALOG ||
1746             arg_action == ACTION_DUMP_CATALOG) {
1747
1748                 _cleanup_free_ char *database;
1749
1750                 database = path_join(arg_root, CATALOG_DATABASE, NULL);
1751                 if (!database) {
1752                         r = log_oom();
1753                         goto finish;
1754                 }
1755
1756                 if (arg_action == ACTION_UPDATE_CATALOG) {
1757                         r = catalog_update(database, arg_root, catalog_file_dirs);
1758                         if (r < 0)
1759                                 log_error_errno(r, "Failed to list catalog: %m");
1760                 } else {
1761                         bool oneline = arg_action == ACTION_LIST_CATALOG;
1762
1763                         if (optind < argc)
1764                                 r = catalog_list_items(stdout, database,
1765                                                        oneline, argv + optind);
1766                         else
1767                                 r = catalog_list(stdout, database, oneline);
1768                         if (r < 0)
1769                                 log_error_errno(r, "Failed to list catalog: %m");
1770                 }
1771
1772                 goto finish;
1773         }
1774
1775         if (arg_directory)
1776                 r = sd_journal_open_directory(&j, arg_directory, arg_journal_type);
1777         else if (arg_file)
1778                 r = sd_journal_open_files(&j, (const char**) arg_file, 0);
1779         else if (arg_machine)
1780                 r = sd_journal_open_container(&j, arg_machine, 0);
1781         else
1782                 r = sd_journal_open(&j, !arg_merge*SD_JOURNAL_LOCAL_ONLY + arg_journal_type);
1783         if (r < 0) {
1784                 log_error_errno(r, "Failed to open %s: %m",
1785                                 arg_directory ? arg_directory : arg_file ? "files" : "journal");
1786                 return EXIT_FAILURE;
1787         }
1788
1789         r = access_check(j);
1790         if (r < 0)
1791                 return EXIT_FAILURE;
1792
1793         if (arg_action == ACTION_VERIFY) {
1794                 r = verify(j);
1795                 goto finish;
1796         }
1797
1798         if (arg_action == ACTION_PRINT_HEADER) {
1799                 journal_print_header(j);
1800                 return EXIT_SUCCESS;
1801         }
1802
1803         if (arg_action == ACTION_DISK_USAGE) {
1804                 uint64_t bytes = 0;
1805                 char sbytes[FORMAT_BYTES_MAX];
1806
1807                 r = sd_journal_get_usage(j, &bytes);
1808                 if (r < 0)
1809                         return EXIT_FAILURE;
1810
1811                 printf("Archived and active journals take up %s on disk.\n",
1812                        format_bytes(sbytes, sizeof(sbytes), bytes));
1813                 return EXIT_SUCCESS;
1814         }
1815
1816         if (arg_action == ACTION_VACUUM) {
1817                 Directory *d;
1818                 Iterator i;
1819
1820                 HASHMAP_FOREACH(d, j->directories_by_path, i) {
1821                         int q;
1822
1823                         if (d->is_root)
1824                                 continue;
1825
1826                         q = journal_directory_vacuum(d->path, arg_vacuum_size, arg_vacuum_time, NULL, true);
1827                         if (q < 0) {
1828                                 log_error_errno(q, "Failed to vacuum: %m");
1829                                 r = q;
1830                         }
1831                 }
1832
1833                 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
1834         }
1835
1836         if (arg_action == ACTION_LIST_BOOTS) {
1837                 r = list_boots(j);
1838                 goto finish;
1839         }
1840
1841         /* add_boot() must be called first!
1842          * It may need to seek the journal to find parent boot IDs. */
1843         r = add_boot(j);
1844         if (r < 0)
1845                 return EXIT_FAILURE;
1846
1847         r = add_dmesg(j);
1848         if (r < 0)
1849                 return EXIT_FAILURE;
1850
1851         r = add_units(j);
1852         strv_free(arg_system_units);
1853         strv_free(arg_user_units);
1854
1855         if (r < 0) {
1856                 log_error_errno(r, "Failed to add filter for units: %m");
1857                 return EXIT_FAILURE;
1858         }
1859
1860         r = add_syslog_identifier(j);
1861         if (r < 0) {
1862                 log_error_errno(r, "Failed to add filter for syslog identifiers: %m");
1863                 return EXIT_FAILURE;
1864         }
1865
1866         r = add_priorities(j);
1867         if (r < 0) {
1868                 log_error_errno(r, "Failed to add filter for priorities: %m");
1869                 return EXIT_FAILURE;
1870         }
1871
1872         r = add_matches(j, argv + optind);
1873         if (r < 0) {
1874                 log_error_errno(r, "Failed to add filters: %m");
1875                 return EXIT_FAILURE;
1876         }
1877
1878         if (_unlikely_(log_get_max_level() >= LOG_PRI(LOG_DEBUG))) {
1879                 _cleanup_free_ char *filter;
1880
1881                 filter = journal_make_match_string(j);
1882                 log_debug("Journal filter: %s", filter);
1883         }
1884
1885         if (arg_field) {
1886                 const void *data;
1887                 size_t size;
1888
1889                 r = sd_journal_set_data_threshold(j, 0);
1890                 if (r < 0) {
1891                         log_error("Failed to unset data size threshold");
1892                         return EXIT_FAILURE;
1893                 }
1894
1895                 r = sd_journal_query_unique(j, arg_field);
1896                 if (r < 0) {
1897                         log_error_errno(r, "Failed to query unique data objects: %m");
1898                         return EXIT_FAILURE;
1899                 }
1900
1901                 SD_JOURNAL_FOREACH_UNIQUE(j, data, size) {
1902                         const void *eq;
1903
1904                         if (arg_lines >= 0 && n_shown >= arg_lines)
1905                                 break;
1906
1907                         eq = memchr(data, '=', size);
1908                         if (eq)
1909                                 printf("%.*s\n", (int) (size - ((const uint8_t*) eq - (const uint8_t*) data + 1)), (const char*) eq + 1);
1910                         else
1911                                 printf("%.*s\n", (int) size, (const char*) data);
1912
1913                         n_shown ++;
1914                 }
1915
1916                 return EXIT_SUCCESS;
1917         }
1918
1919         /* Opening the fd now means the first sd_journal_wait() will actually wait */
1920         if (arg_follow) {
1921                 r = sd_journal_get_fd(j);
1922                 if (r < 0)
1923                         return EXIT_FAILURE;
1924         }
1925
1926         if (arg_cursor || arg_after_cursor) {
1927                 r = sd_journal_seek_cursor(j, arg_cursor ?: arg_after_cursor);
1928                 if (r < 0) {
1929                         log_error_errno(r, "Failed to seek to cursor: %m");
1930                         return EXIT_FAILURE;
1931                 }
1932                 if (!arg_reverse)
1933                         r = sd_journal_next_skip(j, 1 + !!arg_after_cursor);
1934                 else
1935                         r = sd_journal_previous_skip(j, 1 + !!arg_after_cursor);
1936
1937                 if (arg_after_cursor && r < 2 && !arg_follow)
1938                         /* We couldn't find the next entry after the cursor. */
1939                         arg_lines = 0;
1940
1941         } else if (arg_since_set && !arg_reverse) {
1942                 r = sd_journal_seek_realtime_usec(j, arg_since);
1943                 if (r < 0) {
1944                         log_error_errno(r, "Failed to seek to date: %m");
1945                         return EXIT_FAILURE;
1946                 }
1947                 r = sd_journal_next(j);
1948
1949         } else if (arg_until_set && arg_reverse) {
1950                 r = sd_journal_seek_realtime_usec(j, arg_until);
1951                 if (r < 0) {
1952                         log_error_errno(r, "Failed to seek to date: %m");
1953                         return EXIT_FAILURE;
1954                 }
1955                 r = sd_journal_previous(j);
1956
1957         } else if (arg_lines >= 0) {
1958                 r = sd_journal_seek_tail(j);
1959                 if (r < 0) {
1960                         log_error_errno(r, "Failed to seek to tail: %m");
1961                         return EXIT_FAILURE;
1962                 }
1963
1964                 r = sd_journal_previous_skip(j, arg_lines);
1965
1966         } else if (arg_reverse) {
1967                 r = sd_journal_seek_tail(j);
1968                 if (r < 0) {
1969                         log_error_errno(r, "Failed to seek to tail: %m");
1970                         return EXIT_FAILURE;
1971                 }
1972
1973                 r = sd_journal_previous(j);
1974
1975         } else {
1976                 r = sd_journal_seek_head(j);
1977                 if (r < 0) {
1978                         log_error_errno(r, "Failed to seek to head: %m");
1979                         return EXIT_FAILURE;
1980                 }
1981
1982                 r = sd_journal_next(j);
1983         }
1984
1985         if (r < 0) {
1986                 log_error_errno(r, "Failed to iterate through journal: %m");
1987                 return EXIT_FAILURE;
1988         }
1989
1990         if (!arg_follow)
1991                 pager_open_if_enabled();
1992
1993         if (!arg_quiet) {
1994                 usec_t start, end;
1995                 char start_buf[FORMAT_TIMESTAMP_MAX], end_buf[FORMAT_TIMESTAMP_MAX];
1996
1997                 r = sd_journal_get_cutoff_realtime_usec(j, &start, &end);
1998                 if (r < 0) {
1999                         log_error_errno(r, "Failed to get cutoff: %m");
2000                         goto finish;
2001                 }
2002
2003                 if (r > 0) {
2004                         if (arg_follow)
2005                                 printf("-- Logs begin at %s. --\n",
2006                                        format_timestamp_maybe_utc(start_buf, sizeof(start_buf), start));
2007                         else
2008                                 printf("-- Logs begin at %s, end at %s. --\n",
2009                                        format_timestamp_maybe_utc(start_buf, sizeof(start_buf), start),
2010                                        format_timestamp_maybe_utc(end_buf, sizeof(end_buf), end));
2011                 }
2012         }
2013
2014         for (;;) {
2015                 while (arg_lines < 0 || n_shown < arg_lines || (arg_follow && !first_line)) {
2016                         int flags;
2017
2018                         if (need_seek) {
2019                                 if (!arg_reverse)
2020                                         r = sd_journal_next(j);
2021                                 else
2022                                         r = sd_journal_previous(j);
2023                                 if (r < 0) {
2024                                         log_error_errno(r, "Failed to iterate through journal: %m");
2025                                         goto finish;
2026                                 }
2027                                 if (r == 0)
2028                                         break;
2029                         }
2030
2031                         if (arg_until_set && !arg_reverse) {
2032                                 usec_t usec;
2033
2034                                 r = sd_journal_get_realtime_usec(j, &usec);
2035                                 if (r < 0) {
2036                                         log_error_errno(r, "Failed to determine timestamp: %m");
2037                                         goto finish;
2038                                 }
2039                                 if (usec > arg_until)
2040                                         goto finish;
2041                         }
2042
2043                         if (arg_since_set && arg_reverse) {
2044                                 usec_t usec;
2045
2046                                 r = sd_journal_get_realtime_usec(j, &usec);
2047                                 if (r < 0) {
2048                                         log_error_errno(r, "Failed to determine timestamp: %m");
2049                                         goto finish;
2050                                 }
2051                                 if (usec < arg_since)
2052                                         goto finish;
2053                         }
2054
2055                         if (!arg_merge && !arg_quiet) {
2056                                 sd_id128_t boot_id;
2057
2058                                 r = sd_journal_get_monotonic_usec(j, NULL, &boot_id);
2059                                 if (r >= 0) {
2060                                         if (previous_boot_id_valid &&
2061                                             !sd_id128_equal(boot_id, previous_boot_id))
2062                                                 printf("%s-- Reboot --%s\n",
2063                                                        ansi_highlight(), ansi_highlight_off());
2064
2065                                         previous_boot_id = boot_id;
2066                                         previous_boot_id_valid = true;
2067                                 }
2068                         }
2069
2070                         flags =
2071                                 arg_all * OUTPUT_SHOW_ALL |
2072                                 arg_full * OUTPUT_FULL_WIDTH |
2073                                 on_tty() * OUTPUT_COLOR |
2074                                 arg_catalog * OUTPUT_CATALOG |
2075                                 arg_utc * OUTPUT_UTC;
2076
2077                         r = output_journal(stdout, j, arg_output, 0, flags, &ellipsized);
2078                         need_seek = true;
2079                         if (r == -EADDRNOTAVAIL)
2080                                 break;
2081                         else if (r < 0 || ferror(stdout))
2082                                 goto finish;
2083
2084                         n_shown++;
2085                 }
2086
2087                 if (!arg_follow) {
2088                         if (arg_show_cursor) {
2089                                 _cleanup_free_ char *cursor = NULL;
2090
2091                                 r = sd_journal_get_cursor(j, &cursor);
2092                                 if (r < 0 && r != -EADDRNOTAVAIL)
2093                                         log_error_errno(r, "Failed to get cursor: %m");
2094                                 else if (r >= 0)
2095                                         printf("-- cursor: %s\n", cursor);
2096                         }
2097
2098                         break;
2099                 }
2100
2101                 r = sd_journal_wait(j, (uint64_t) -1);
2102                 if (r < 0) {
2103                         log_error_errno(r, "Couldn't wait for journal event: %m");
2104                         goto finish;
2105                 }
2106
2107                 first_line = false;
2108         }
2109
2110 finish:
2111         pager_close();
2112
2113         strv_free(arg_file);
2114
2115         return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
2116 }