chiark / gitweb /
treewide: sanitize loop_write
[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         r = loop_write(fd, &h, sizeof(h), false);
1410         if (r < 0) {
1411                 log_error_errno(r, "Failed to write header: %m");
1412                 goto finish;
1413         }
1414
1415         r = loop_write(fd, state, state_size, false);
1416         if (r < 0) {
1417                 log_error_errno(r, "Failed to write state: %m");
1418                 goto finish;
1419         }
1420
1421         if (link(k, p) < 0) {
1422                 log_error_errno(errno, "Failed to link file: %m");
1423                 r = -errno;
1424                 goto finish;
1425         }
1426
1427         if (on_tty()) {
1428                 fprintf(stderr,
1429                         "\n"
1430                         "The new key pair has been generated. The " ANSI_HIGHLIGHT_ON "secret sealing key" ANSI_HIGHLIGHT_OFF " has been written to\n"
1431                         "the following local file. This key file is automatically updated when the\n"
1432                         "sealing key is advanced. It should not be used on multiple hosts.\n"
1433                         "\n"
1434                         "\t%s\n"
1435                         "\n"
1436                         "Please write down the following " ANSI_HIGHLIGHT_ON "secret verification key" ANSI_HIGHLIGHT_OFF ". It should be stored\n"
1437                         "at a safe location and should not be saved locally on disk.\n"
1438                         "\n\t" ANSI_HIGHLIGHT_RED_ON, p);
1439                 fflush(stderr);
1440         }
1441         for (i = 0; i < seed_size; i++) {
1442                 if (i > 0 && i % 3 == 0)
1443                         putchar('-');
1444                 printf("%02x", ((uint8_t*) seed)[i]);
1445         }
1446
1447         printf("/%llx-%llx\n", (unsigned long long) n, (unsigned long long) arg_interval);
1448
1449         if (on_tty()) {
1450                 char tsb[FORMAT_TIMESPAN_MAX], *hn;
1451
1452                 fprintf(stderr,
1453                         ANSI_HIGHLIGHT_OFF "\n"
1454                         "The sealing key is automatically changed every %s.\n",
1455                         format_timespan(tsb, sizeof(tsb), arg_interval, 0));
1456
1457                 hn = gethostname_malloc();
1458
1459                 if (hn) {
1460                         hostname_cleanup(hn, false);
1461                         fprintf(stderr, "\nThe keys have been generated for host %s/" SD_ID128_FORMAT_STR ".\n", hn, SD_ID128_FORMAT_VAL(machine));
1462                 } else
1463                         fprintf(stderr, "\nThe keys have been generated for host " SD_ID128_FORMAT_STR ".\n", SD_ID128_FORMAT_VAL(machine));
1464
1465 #ifdef HAVE_QRENCODE
1466                 /* If this is not an UTF-8 system don't print any QR codes */
1467                 if (is_locale_utf8()) {
1468                         fputs("\nTo transfer the verification key to your phone please scan the QR code below:\n\n", stderr);
1469                         print_qr_code(stderr, seed, seed_size, n, arg_interval, hn, machine);
1470                 }
1471 #endif
1472                 free(hn);
1473         }
1474
1475         r = 0;
1476
1477 finish:
1478         safe_close(fd);
1479
1480         if (k) {
1481                 unlink(k);
1482                 free(k);
1483         }
1484
1485         free(p);
1486
1487         return r;
1488 #else
1489         log_error("Forward-secure sealing not available.");
1490         return -ENOTSUP;
1491 #endif
1492 }
1493
1494 static int verify(sd_journal *j) {
1495         int r = 0;
1496         Iterator i;
1497         JournalFile *f;
1498
1499         assert(j);
1500
1501         log_show_color(true);
1502
1503         ORDERED_HASHMAP_FOREACH(f, j->files, i) {
1504                 int k;
1505                 usec_t first, validated, last;
1506
1507 #ifdef HAVE_GCRYPT
1508                 if (!arg_verify_key && JOURNAL_HEADER_SEALED(f->header))
1509                         log_notice("Journal file %s has sealing enabled but verification key has not been passed using --verify-key=.", f->path);
1510 #endif
1511
1512                 k = journal_file_verify(f, arg_verify_key, &first, &validated, &last, true);
1513                 if (k == -EINVAL) {
1514                         /* If the key was invalid give up right-away. */
1515                         return k;
1516                 } else if (k < 0) {
1517                         log_warning("FAIL: %s (%s)", f->path, strerror(-k));
1518                         r = k;
1519                 } else {
1520                         char a[FORMAT_TIMESTAMP_MAX], b[FORMAT_TIMESTAMP_MAX], c[FORMAT_TIMESPAN_MAX];
1521                         log_info("PASS: %s", f->path);
1522
1523                         if (arg_verify_key && JOURNAL_HEADER_SEALED(f->header)) {
1524                                 if (validated > 0) {
1525                                         log_info("=> Validated from %s to %s, final %s entries not sealed.",
1526                                                  format_timestamp_maybe_utc(a, sizeof(a), first),
1527                                                  format_timestamp_maybe_utc(b, sizeof(b), validated),
1528                                                  format_timespan(c, sizeof(c), last > validated ? last - validated : 0, 0));
1529                                 } else if (last > 0)
1530                                         log_info("=> No sealing yet, %s of entries not sealed.",
1531                                                  format_timespan(c, sizeof(c), last - first, 0));
1532                                 else
1533                                         log_info("=> No sealing yet, no entries in file.");
1534                         }
1535                 }
1536         }
1537
1538         return r;
1539 }
1540
1541 #ifdef HAVE_ACL
1542 static int access_check_var_log_journal(sd_journal *j) {
1543         _cleanup_strv_free_ char **g = NULL;
1544         bool have_access;
1545         int r;
1546
1547         assert(j);
1548
1549         have_access = in_group("systemd-journal") > 0;
1550
1551         if (!have_access) {
1552                 /* Let's enumerate all groups from the default ACL of
1553                  * the directory, which generally should allow access
1554                  * to most journal files too */
1555                 r = search_acl_groups(&g, "/var/log/journal/", &have_access);
1556                 if (r < 0)
1557                         return r;
1558         }
1559
1560         if (!have_access) {
1561
1562                 if (strv_isempty(g))
1563                         log_notice("Hint: You are currently not seeing messages from other users and the system.\n"
1564                                    "      Users in the 'systemd-journal' group can see all messages. Pass -q to\n"
1565                                    "      turn off this notice.");
1566                 else {
1567                         _cleanup_free_ char *s = NULL;
1568
1569                         r = strv_extend(&g, "systemd-journal");
1570                         if (r < 0)
1571                                 return log_oom();
1572
1573                         strv_sort(g);
1574                         strv_uniq(g);
1575
1576                         s = strv_join(g, "', '");
1577                         if (!s)
1578                                 return log_oom();
1579
1580                         log_notice("Hint: You are currently not seeing messages from other users and the system.\n"
1581                                    "      Users in the groups '%s' can see all messages.\n"
1582                                    "      Pass -q to turn off this notice.", s);
1583                 }
1584         }
1585
1586         return 0;
1587 }
1588 #endif
1589
1590 static int access_check(sd_journal *j) {
1591         Iterator it;
1592         void *code;
1593         int r = 0;
1594
1595         assert(j);
1596
1597         if (set_isempty(j->errors)) {
1598                 if (ordered_hashmap_isempty(j->files))
1599                         log_notice("No journal files were found.");
1600                 return 0;
1601         }
1602
1603         if (set_contains(j->errors, INT_TO_PTR(-EACCES))) {
1604 #ifdef HAVE_ACL
1605                 /* If /var/log/journal doesn't even exist,
1606                  * unprivileged users have no access at all */
1607                 if (access("/var/log/journal", F_OK) < 0 &&
1608                     geteuid() != 0 &&
1609                     in_group("systemd-journal") <= 0) {
1610                         log_error("Unprivileged users cannot access messages, unless persistent log storage is\n"
1611                                   "enabled. Users in the 'systemd-journal' group may always access messages.");
1612                         return -EACCES;
1613                 }
1614
1615                 /* If /var/log/journal exists, try to pring a nice
1616                    notice if the user lacks access to it */
1617                 if (!arg_quiet && geteuid() != 0) {
1618                         r = access_check_var_log_journal(j);
1619                         if (r < 0)
1620                                 return r;
1621                 }
1622 #else
1623                 if (geteuid() != 0 && in_group("systemd-journal") <= 0) {
1624                         log_error("Unprivileged users cannot access messages. Users in the 'systemd-journal' group\n"
1625                                   "group may access messages.");
1626                         return -EACCES;
1627                 }
1628 #endif
1629
1630                 if (ordered_hashmap_isempty(j->files)) {
1631                         log_error("No journal files were opened due to insufficient permissions.");
1632                         r = -EACCES;
1633                 }
1634         }
1635
1636         SET_FOREACH(code, j->errors, it) {
1637                 int err;
1638
1639                 err = -PTR_TO_INT(code);
1640                 assert(err > 0);
1641
1642                 if (err != EACCES)
1643                         log_warning_errno(err, "Error was encountered while opening journal files: %m");
1644         }
1645
1646         return r;
1647 }
1648
1649 static int flush_to_var(void) {
1650         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1651         _cleanup_bus_close_unref_ sd_bus *bus = NULL;
1652         _cleanup_close_ int watch_fd = -1;
1653         int r;
1654
1655         /* Quick exit */
1656         if (access("/run/systemd/journal/flushed", F_OK) >= 0)
1657                 return 0;
1658
1659         /* OK, let's actually do the full logic, send SIGUSR1 to the
1660          * daemon and set up inotify to wait for the flushed file to appear */
1661         r = bus_open_system_systemd(&bus);
1662         if (r < 0)
1663                 return log_error_errno(r, "Failed to get D-Bus connection: %m");
1664
1665         r = sd_bus_call_method(
1666                         bus,
1667                         "org.freedesktop.systemd1",
1668                         "/org/freedesktop/systemd1",
1669                         "org.freedesktop.systemd1.Manager",
1670                         "KillUnit",
1671                         &error,
1672                         NULL,
1673                         "ssi", "systemd-journald.service", "main", SIGUSR1);
1674         if (r < 0) {
1675                 log_error("Failed to kill journal service: %s", bus_error_message(&error, r));
1676                 return r;
1677         }
1678
1679         mkdir_p("/run/systemd/journal", 0755);
1680
1681         watch_fd = inotify_init1(IN_NONBLOCK|IN_CLOEXEC);
1682         if (watch_fd < 0)
1683                 return log_error_errno(errno, "Failed to create inotify watch: %m");
1684
1685         r = inotify_add_watch(watch_fd, "/run/systemd/journal", IN_CREATE|IN_DONT_FOLLOW|IN_ONLYDIR);
1686         if (r < 0)
1687                 return log_error_errno(errno, "Failed to watch journal directory: %m");
1688
1689         for (;;) {
1690                 if (access("/run/systemd/journal/flushed", F_OK) >= 0)
1691                         break;
1692
1693                 if (errno != ENOENT)
1694                         return log_error_errno(errno, "Failed to check for existance of /run/systemd/journal/flushed: %m");
1695
1696                 r = fd_wait_for_event(watch_fd, POLLIN, USEC_INFINITY);
1697                 if (r < 0)
1698                         return log_error_errno(r, "Failed to wait for event: %m");
1699
1700                 r = flush_fd(watch_fd);
1701                 if (r < 0)
1702                         return log_error_errno(r, "Failed to flush inotify events: %m");
1703         }
1704
1705         return 0;
1706 }
1707
1708 int main(int argc, char *argv[]) {
1709         int r;
1710         _cleanup_journal_close_ sd_journal *j = NULL;
1711         bool need_seek = false;
1712         sd_id128_t previous_boot_id;
1713         bool previous_boot_id_valid = false, first_line = true;
1714         int n_shown = 0;
1715         bool ellipsized = false;
1716
1717         setlocale(LC_ALL, "");
1718         log_parse_environment();
1719         log_open();
1720
1721         r = parse_argv(argc, argv);
1722         if (r <= 0)
1723                 goto finish;
1724
1725         signal(SIGWINCH, columns_lines_cache_reset);
1726
1727         if (arg_action == ACTION_NEW_ID128) {
1728                 r = generate_new_id128();
1729                 goto finish;
1730         }
1731
1732         if (arg_action == ACTION_FLUSH) {
1733                 r = flush_to_var();
1734                 goto finish;
1735         }
1736
1737         if (arg_action == ACTION_SETUP_KEYS) {
1738                 r = setup_keys();
1739                 goto finish;
1740         }
1741
1742         if (arg_action == ACTION_UPDATE_CATALOG ||
1743             arg_action == ACTION_LIST_CATALOG ||
1744             arg_action == ACTION_DUMP_CATALOG) {
1745
1746                 _cleanup_free_ char *database;
1747
1748                 database = path_join(arg_root, CATALOG_DATABASE, NULL);
1749                 if (!database) {
1750                         r = log_oom();
1751                         goto finish;
1752                 }
1753
1754                 if (arg_action == ACTION_UPDATE_CATALOG) {
1755                         r = catalog_update(database, arg_root, catalog_file_dirs);
1756                         if (r < 0)
1757                                 log_error_errno(r, "Failed to list catalog: %m");
1758                 } else {
1759                         bool oneline = arg_action == ACTION_LIST_CATALOG;
1760
1761                         if (optind < argc)
1762                                 r = catalog_list_items(stdout, database,
1763                                                        oneline, argv + optind);
1764                         else
1765                                 r = catalog_list(stdout, database, oneline);
1766                         if (r < 0)
1767                                 log_error_errno(r, "Failed to list catalog: %m");
1768                 }
1769
1770                 goto finish;
1771         }
1772
1773         if (arg_directory)
1774                 r = sd_journal_open_directory(&j, arg_directory, arg_journal_type);
1775         else if (arg_file)
1776                 r = sd_journal_open_files(&j, (const char**) arg_file, 0);
1777         else if (arg_machine)
1778                 r = sd_journal_open_container(&j, arg_machine, 0);
1779         else
1780                 r = sd_journal_open(&j, !arg_merge*SD_JOURNAL_LOCAL_ONLY + arg_journal_type);
1781         if (r < 0) {
1782                 log_error_errno(r, "Failed to open %s: %m",
1783                                 arg_directory ? arg_directory : arg_file ? "files" : "journal");
1784                 return EXIT_FAILURE;
1785         }
1786
1787         r = access_check(j);
1788         if (r < 0)
1789                 return EXIT_FAILURE;
1790
1791         if (arg_action == ACTION_VERIFY) {
1792                 r = verify(j);
1793                 goto finish;
1794         }
1795
1796         if (arg_action == ACTION_PRINT_HEADER) {
1797                 journal_print_header(j);
1798                 return EXIT_SUCCESS;
1799         }
1800
1801         if (arg_action == ACTION_DISK_USAGE) {
1802                 uint64_t bytes = 0;
1803                 char sbytes[FORMAT_BYTES_MAX];
1804
1805                 r = sd_journal_get_usage(j, &bytes);
1806                 if (r < 0)
1807                         return EXIT_FAILURE;
1808
1809                 printf("Archived and active journals take up %s on disk.\n",
1810                        format_bytes(sbytes, sizeof(sbytes), bytes));
1811                 return EXIT_SUCCESS;
1812         }
1813
1814         if (arg_action == ACTION_VACUUM) {
1815                 Directory *d;
1816                 Iterator i;
1817
1818                 HASHMAP_FOREACH(d, j->directories_by_path, i) {
1819                         int q;
1820
1821                         if (d->is_root)
1822                                 continue;
1823
1824                         q = journal_directory_vacuum(d->path, arg_vacuum_size, arg_vacuum_time, NULL, true);
1825                         if (q < 0) {
1826                                 log_error_errno(q, "Failed to vacuum: %m");
1827                                 r = q;
1828                         }
1829                 }
1830
1831                 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
1832         }
1833
1834         if (arg_action == ACTION_LIST_BOOTS) {
1835                 r = list_boots(j);
1836                 goto finish;
1837         }
1838
1839         /* add_boot() must be called first!
1840          * It may need to seek the journal to find parent boot IDs. */
1841         r = add_boot(j);
1842         if (r < 0)
1843                 return EXIT_FAILURE;
1844
1845         r = add_dmesg(j);
1846         if (r < 0)
1847                 return EXIT_FAILURE;
1848
1849         r = add_units(j);
1850         strv_free(arg_system_units);
1851         strv_free(arg_user_units);
1852
1853         if (r < 0) {
1854                 log_error_errno(r, "Failed to add filter for units: %m");
1855                 return EXIT_FAILURE;
1856         }
1857
1858         r = add_syslog_identifier(j);
1859         if (r < 0) {
1860                 log_error_errno(r, "Failed to add filter for syslog identifiers: %m");
1861                 return EXIT_FAILURE;
1862         }
1863
1864         r = add_priorities(j);
1865         if (r < 0) {
1866                 log_error_errno(r, "Failed to add filter for priorities: %m");
1867                 return EXIT_FAILURE;
1868         }
1869
1870         r = add_matches(j, argv + optind);
1871         if (r < 0) {
1872                 log_error_errno(r, "Failed to add filters: %m");
1873                 return EXIT_FAILURE;
1874         }
1875
1876         if (_unlikely_(log_get_max_level() >= LOG_PRI(LOG_DEBUG))) {
1877                 _cleanup_free_ char *filter;
1878
1879                 filter = journal_make_match_string(j);
1880                 log_debug("Journal filter: %s", filter);
1881         }
1882
1883         if (arg_field) {
1884                 const void *data;
1885                 size_t size;
1886
1887                 r = sd_journal_set_data_threshold(j, 0);
1888                 if (r < 0) {
1889                         log_error("Failed to unset data size threshold");
1890                         return EXIT_FAILURE;
1891                 }
1892
1893                 r = sd_journal_query_unique(j, arg_field);
1894                 if (r < 0) {
1895                         log_error_errno(r, "Failed to query unique data objects: %m");
1896                         return EXIT_FAILURE;
1897                 }
1898
1899                 SD_JOURNAL_FOREACH_UNIQUE(j, data, size) {
1900                         const void *eq;
1901
1902                         if (arg_lines >= 0 && n_shown >= arg_lines)
1903                                 break;
1904
1905                         eq = memchr(data, '=', size);
1906                         if (eq)
1907                                 printf("%.*s\n", (int) (size - ((const uint8_t*) eq - (const uint8_t*) data + 1)), (const char*) eq + 1);
1908                         else
1909                                 printf("%.*s\n", (int) size, (const char*) data);
1910
1911                         n_shown ++;
1912                 }
1913
1914                 return EXIT_SUCCESS;
1915         }
1916
1917         /* Opening the fd now means the first sd_journal_wait() will actually wait */
1918         if (arg_follow) {
1919                 r = sd_journal_get_fd(j);
1920                 if (r < 0)
1921                         return EXIT_FAILURE;
1922         }
1923
1924         if (arg_cursor || arg_after_cursor) {
1925                 r = sd_journal_seek_cursor(j, arg_cursor ?: arg_after_cursor);
1926                 if (r < 0) {
1927                         log_error_errno(r, "Failed to seek to cursor: %m");
1928                         return EXIT_FAILURE;
1929                 }
1930                 if (!arg_reverse)
1931                         r = sd_journal_next_skip(j, 1 + !!arg_after_cursor);
1932                 else
1933                         r = sd_journal_previous_skip(j, 1 + !!arg_after_cursor);
1934
1935                 if (arg_after_cursor && r < 2) {
1936                         /* We couldn't find the next entry after the cursor. */
1937                         if (arg_follow)
1938                                 need_seek = true;
1939                         else
1940                                 arg_lines = 0;
1941                 }
1942
1943         } else if (arg_since_set && !arg_reverse) {
1944                 r = sd_journal_seek_realtime_usec(j, arg_since);
1945                 if (r < 0) {
1946                         log_error_errno(r, "Failed to seek to date: %m");
1947                         return EXIT_FAILURE;
1948                 }
1949                 r = sd_journal_next(j);
1950
1951         } else if (arg_until_set && arg_reverse) {
1952                 r = sd_journal_seek_realtime_usec(j, arg_until);
1953                 if (r < 0) {
1954                         log_error_errno(r, "Failed to seek to date: %m");
1955                         return EXIT_FAILURE;
1956                 }
1957                 r = sd_journal_previous(j);
1958
1959         } else if (arg_lines >= 0) {
1960                 r = sd_journal_seek_tail(j);
1961                 if (r < 0) {
1962                         log_error_errno(r, "Failed to seek to tail: %m");
1963                         return EXIT_FAILURE;
1964                 }
1965
1966                 r = sd_journal_previous_skip(j, arg_lines);
1967
1968         } else if (arg_reverse) {
1969                 r = sd_journal_seek_tail(j);
1970                 if (r < 0) {
1971                         log_error_errno(r, "Failed to seek to tail: %m");
1972                         return EXIT_FAILURE;
1973                 }
1974
1975                 r = sd_journal_previous(j);
1976
1977         } else {
1978                 r = sd_journal_seek_head(j);
1979                 if (r < 0) {
1980                         log_error_errno(r, "Failed to seek to head: %m");
1981                         return EXIT_FAILURE;
1982                 }
1983
1984                 r = sd_journal_next(j);
1985         }
1986
1987         if (r < 0) {
1988                 log_error_errno(r, "Failed to iterate through journal: %m");
1989                 return EXIT_FAILURE;
1990         }
1991
1992         if (!arg_follow)
1993                 pager_open_if_enabled();
1994
1995         if (!arg_quiet) {
1996                 usec_t start, end;
1997                 char start_buf[FORMAT_TIMESTAMP_MAX], end_buf[FORMAT_TIMESTAMP_MAX];
1998
1999                 r = sd_journal_get_cutoff_realtime_usec(j, &start, &end);
2000                 if (r < 0) {
2001                         log_error_errno(r, "Failed to get cutoff: %m");
2002                         goto finish;
2003                 }
2004
2005                 if (r > 0) {
2006                         if (arg_follow)
2007                                 printf("-- Logs begin at %s. --\n",
2008                                        format_timestamp_maybe_utc(start_buf, sizeof(start_buf), start));
2009                         else
2010                                 printf("-- Logs begin at %s, end at %s. --\n",
2011                                        format_timestamp_maybe_utc(start_buf, sizeof(start_buf), start),
2012                                        format_timestamp_maybe_utc(end_buf, sizeof(end_buf), end));
2013                 }
2014         }
2015
2016         for (;;) {
2017                 while (arg_lines < 0 || n_shown < arg_lines || (arg_follow && !first_line)) {
2018                         int flags;
2019
2020                         if (need_seek) {
2021                                 if (!arg_reverse)
2022                                         r = sd_journal_next(j);
2023                                 else
2024                                         r = sd_journal_previous(j);
2025                                 if (r < 0) {
2026                                         log_error_errno(r, "Failed to iterate through journal: %m");
2027                                         goto finish;
2028                                 }
2029                                 if (r == 0)
2030                                         break;
2031                         }
2032
2033                         if (arg_until_set && !arg_reverse) {
2034                                 usec_t usec;
2035
2036                                 r = sd_journal_get_realtime_usec(j, &usec);
2037                                 if (r < 0) {
2038                                         log_error_errno(r, "Failed to determine timestamp: %m");
2039                                         goto finish;
2040                                 }
2041                                 if (usec > arg_until)
2042                                         goto finish;
2043                         }
2044
2045                         if (arg_since_set && arg_reverse) {
2046                                 usec_t usec;
2047
2048                                 r = sd_journal_get_realtime_usec(j, &usec);
2049                                 if (r < 0) {
2050                                         log_error_errno(r, "Failed to determine timestamp: %m");
2051                                         goto finish;
2052                                 }
2053                                 if (usec < arg_since)
2054                                         goto finish;
2055                         }
2056
2057                         if (!arg_merge && !arg_quiet) {
2058                                 sd_id128_t boot_id;
2059
2060                                 r = sd_journal_get_monotonic_usec(j, NULL, &boot_id);
2061                                 if (r >= 0) {
2062                                         if (previous_boot_id_valid &&
2063                                             !sd_id128_equal(boot_id, previous_boot_id))
2064                                                 printf("%s-- Reboot --%s\n",
2065                                                        ansi_highlight(), ansi_highlight_off());
2066
2067                                         previous_boot_id = boot_id;
2068                                         previous_boot_id_valid = true;
2069                                 }
2070                         }
2071
2072                         flags =
2073                                 arg_all * OUTPUT_SHOW_ALL |
2074                                 arg_full * OUTPUT_FULL_WIDTH |
2075                                 on_tty() * OUTPUT_COLOR |
2076                                 arg_catalog * OUTPUT_CATALOG |
2077                                 arg_utc * OUTPUT_UTC;
2078
2079                         r = output_journal(stdout, j, arg_output, 0, flags, &ellipsized);
2080                         need_seek = true;
2081                         if (r == -EADDRNOTAVAIL)
2082                                 break;
2083                         else if (r < 0 || ferror(stdout))
2084                                 goto finish;
2085
2086                         n_shown++;
2087                 }
2088
2089                 if (!arg_follow) {
2090                         if (arg_show_cursor) {
2091                                 _cleanup_free_ char *cursor = NULL;
2092
2093                                 r = sd_journal_get_cursor(j, &cursor);
2094                                 if (r < 0 && r != -EADDRNOTAVAIL)
2095                                         log_error_errno(r, "Failed to get cursor: %m");
2096                                 else if (r >= 0)
2097                                         printf("-- cursor: %s\n", cursor);
2098                         }
2099
2100                         break;
2101                 }
2102
2103                 r = sd_journal_wait(j, (uint64_t) -1);
2104                 if (r < 0) {
2105                         log_error_errno(r, "Couldn't wait for journal event: %m");
2106                         goto finish;
2107                 }
2108
2109                 first_line = false;
2110         }
2111
2112 finish:
2113         pager_close();
2114
2115         strv_free(arg_file);
2116
2117         return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
2118 }