chiark / gitweb /
treewide: use log_*_errno whenever %m is in the format string
[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                                 log_error_errno(errno, "Couldn't stat file: %m");
799                                 return -errno;
800                         }
801
802                         if (S_ISREG(st.st_mode) && (0111 & st.st_mode)) {
803                                 if (executable_is_script(path, &interpreter) > 0) {
804                                         _cleanup_free_ char *comm;
805
806                                         comm = strndup(basename(path), 15);
807                                         if (!comm)
808                                                 return log_oom();
809
810                                         t = strappend("_COMM=", comm);
811
812                                         /* Append _EXE only if the interpreter is not a link.
813                                            Otherwise, it might be outdated often. */
814                                         if (lstat(interpreter, &st) == 0 &&
815                                             !S_ISLNK(st.st_mode)) {
816                                                 t2 = strappend("_EXE=", interpreter);
817                                                 if (!t2)
818                                                         return log_oom();
819                                         }
820                                 } else
821                                         t = strappend("_EXE=", path);
822                         } else if (S_ISCHR(st.st_mode)) {
823                                 if (asprintf(&t, "_KERNEL_DEVICE=c%u:%u",
824                                              major(st.st_rdev),
825                                              minor(st.st_rdev)) < 0)
826                                         return -ENOMEM;
827                         } else if (S_ISBLK(st.st_mode)) {
828                                 if (asprintf(&t, "_KERNEL_DEVICE=b%u:%u",
829                                              major(st.st_rdev),
830                                              minor(st.st_rdev)) < 0)
831                                         return -ENOMEM;
832                         } else {
833                                 log_error("File is neither a device node, nor regular file, nor executable: %s", *i);
834                                 return -EINVAL;
835                         }
836
837                         if (!t)
838                                 return log_oom();
839
840                         r = sd_journal_add_match(j, t, 0);
841                         if (t2)
842                                 r = sd_journal_add_match(j, t2, 0);
843                         have_term = true;
844
845                 } else {
846                         r = sd_journal_add_match(j, *i, 0);
847                         have_term = true;
848                 }
849
850                 if (r < 0)
851                         return log_error_errno(r, "Failed to add match '%s': %m", *i);
852         }
853
854         if (!strv_isempty(args) && !have_term) {
855                 log_error("\"+\" can only be used between terms");
856                 return -EINVAL;
857         }
858
859         return 0;
860 }
861
862 static int boot_id_cmp(const void *a, const void *b) {
863         uint64_t _a, _b;
864
865         _a = ((const boot_id_t *)a)->first;
866         _b = ((const boot_id_t *)b)->first;
867
868         return _a < _b ? -1 : (_a > _b ? 1 : 0);
869 }
870
871 static int get_boots(sd_journal *j,
872                      boot_id_t **boots,
873                      unsigned int *count,
874                      boot_id_t *query_ref_boot) {
875         int r;
876         const void *data;
877         size_t length, allocated = 0;
878
879         assert(j);
880         assert(boots);
881         assert(count);
882
883         r = sd_journal_query_unique(j, "_BOOT_ID");
884         if (r < 0)
885                 return r;
886
887         *count = 0;
888         SD_JOURNAL_FOREACH_UNIQUE(j, data, length) {
889                 boot_id_t *id;
890
891                 assert(startswith(data, "_BOOT_ID="));
892
893                 if (!GREEDY_REALLOC(*boots, allocated, *count + 1))
894                         return log_oom();
895
896                 id = *boots + *count;
897
898                 r = sd_id128_from_string(((const char *)data) + strlen("_BOOT_ID="), &id->id);
899                 if (r < 0)
900                         continue;
901
902                 r = sd_journal_add_match(j, data, length);
903                 if (r < 0)
904                         return r;
905
906                 r = sd_journal_seek_head(j);
907                 if (r < 0)
908                         return r;
909
910                 r = sd_journal_next(j);
911                 if (r < 0)
912                         return r;
913                 else if (r == 0)
914                         goto flush;
915
916                 r = sd_journal_get_realtime_usec(j, &id->first);
917                 if (r < 0)
918                         return r;
919
920                 if (query_ref_boot) {
921                         id->last = 0;
922                         if (sd_id128_equal(id->id, query_ref_boot->id))
923                                 *query_ref_boot = *id;
924                 } else {
925                         r = sd_journal_seek_tail(j);
926                         if (r < 0)
927                                 return r;
928
929                         r = sd_journal_previous(j);
930                         if (r < 0)
931                                 return r;
932                         else if (r == 0)
933                                 goto flush;
934
935                         r = sd_journal_get_realtime_usec(j, &id->last);
936                         if (r < 0)
937                                 return r;
938                 }
939
940                 (*count)++;
941         flush:
942                 sd_journal_flush_matches(j);
943         }
944
945         qsort_safe(*boots, *count, sizeof(boot_id_t), boot_id_cmp);
946         return 0;
947 }
948
949 static int list_boots(sd_journal *j) {
950         int r, w, i;
951         unsigned int count;
952         boot_id_t *id;
953         _cleanup_free_ boot_id_t *all_ids = NULL;
954
955         assert(j);
956
957         r = get_boots(j, &all_ids, &count, NULL);
958         if (r < 0)
959                 return r;
960
961         pager_open_if_enabled();
962
963         /* numbers are one less, but we need an extra char for the sign */
964         w = DECIMAL_STR_WIDTH(count - 1) + 1;
965
966         for (id = all_ids, i = 0; id < all_ids + count; id++, i++) {
967                 char a[FORMAT_TIMESTAMP_MAX], b[FORMAT_TIMESTAMP_MAX];
968
969                 printf("% *i " SD_ID128_FORMAT_STR " %s—%s\n",
970                        w, i - count + 1,
971                        SD_ID128_FORMAT_VAL(id->id),
972                        format_timestamp_maybe_utc(a, sizeof(a), id->first),
973                        format_timestamp_maybe_utc(b, sizeof(b), id->last));
974         }
975
976         return 0;
977 }
978
979 static int get_boot_id_by_offset(sd_journal *j, sd_id128_t *boot_id, int offset) {
980         int r;
981         unsigned int count;
982         boot_id_t ref_boot_id = {}, *id;
983         _cleanup_free_ boot_id_t *all_ids = NULL;
984
985         assert(j);
986         assert(boot_id);
987
988         ref_boot_id.id = *boot_id;
989         r = get_boots(j, &all_ids, &count, &ref_boot_id);
990         if (r < 0)
991                 return r;
992
993         if (sd_id128_equal(*boot_id, SD_ID128_NULL)) {
994                 if (offset > (int) count || offset <= -(int)count)
995                         return -EADDRNOTAVAIL;
996
997                 *boot_id = all_ids[(offset <= 0)*count + offset - 1].id;
998         } else {
999                 id = bsearch(&ref_boot_id, all_ids, count, sizeof(boot_id_t), boot_id_cmp);
1000
1001                 if (!id ||
1002                     offset <= 0 ? (id - all_ids) + offset < 0 :
1003                                     (id - all_ids) + offset >= (int) count)
1004                         return -EADDRNOTAVAIL;
1005
1006                 *boot_id = (id + offset)->id;
1007         }
1008
1009         return 0;
1010 }
1011
1012 static int add_boot(sd_journal *j) {
1013         char match[9+32+1] = "_BOOT_ID=";
1014         int r;
1015
1016         assert(j);
1017
1018         if (!arg_boot)
1019                 return 0;
1020
1021         if (arg_boot_offset == 0 && sd_id128_equal(arg_boot_id, SD_ID128_NULL))
1022                 return add_match_this_boot(j, arg_machine);
1023
1024         r = get_boot_id_by_offset(j, &arg_boot_id, arg_boot_offset);
1025         if (r < 0) {
1026                 if (sd_id128_equal(arg_boot_id, SD_ID128_NULL))
1027                         log_error_errno(r, "Failed to look up boot %+i: %m", arg_boot_offset);
1028                 else
1029                         log_error("Failed to look up boot ID "SD_ID128_FORMAT_STR"%+i: %s",
1030                                   SD_ID128_FORMAT_VAL(arg_boot_id), arg_boot_offset, strerror(-r));
1031                 return r;
1032         }
1033
1034         sd_id128_to_string(arg_boot_id, match + 9);
1035
1036         r = sd_journal_add_match(j, match, sizeof(match) - 1);
1037         if (r < 0)
1038                 return log_error_errno(r, "Failed to add match: %m");
1039
1040         r = sd_journal_add_conjunction(j);
1041         if (r < 0)
1042                 return r;
1043
1044         return 0;
1045 }
1046
1047 static int add_dmesg(sd_journal *j) {
1048         int r;
1049         assert(j);
1050
1051         if (!arg_dmesg)
1052                 return 0;
1053
1054         r = sd_journal_add_match(j, "_TRANSPORT=kernel", strlen("_TRANSPORT=kernel"));
1055         if (r < 0)
1056                 return log_error_errno(r, "Failed to add match: %m");
1057
1058         r = sd_journal_add_conjunction(j);
1059         if (r < 0)
1060                 return r;
1061
1062         return 0;
1063 }
1064
1065 static int get_possible_units(sd_journal *j,
1066                               const char *fields,
1067                               char **patterns,
1068                               Set **units) {
1069         _cleanup_set_free_free_ Set *found;
1070         const char *field;
1071         int r;
1072
1073         found = set_new(&string_hash_ops);
1074         if (!found)
1075                 return log_oom();
1076
1077         NULSTR_FOREACH(field, fields) {
1078                 const void *data;
1079                 size_t size;
1080
1081                 r = sd_journal_query_unique(j, field);
1082                 if (r < 0)
1083                         return r;
1084
1085                 SD_JOURNAL_FOREACH_UNIQUE(j, data, size) {
1086                         char **pattern, *eq;
1087                         size_t prefix;
1088                         _cleanup_free_ char *u = NULL;
1089
1090                         eq = memchr(data, '=', size);
1091                         if (eq)
1092                                 prefix = eq - (char*) data + 1;
1093                         else
1094                                 prefix = 0;
1095
1096                         u = strndup((char*) data + prefix, size - prefix);
1097                         if (!u)
1098                                 return log_oom();
1099
1100                         STRV_FOREACH(pattern, patterns)
1101                                 if (fnmatch(*pattern, u, FNM_NOESCAPE) == 0) {
1102                                         log_debug("Matched %s with pattern %s=%s", u, field, *pattern);
1103
1104                                         r = set_consume(found, u);
1105                                         u = NULL;
1106                                         if (r < 0 && r != -EEXIST)
1107                                                 return r;
1108
1109                                         break;
1110                                 }
1111                 }
1112         }
1113
1114         *units = found;
1115         found = NULL;
1116         return 0;
1117 }
1118
1119 /* This list is supposed to return the superset of unit names
1120  * possibly matched by rules added with add_matches_for_unit... */
1121 #define SYSTEM_UNITS                 \
1122         "_SYSTEMD_UNIT\0"            \
1123         "COREDUMP_UNIT\0"            \
1124         "UNIT\0"                     \
1125         "OBJECT_SYSTEMD_UNIT\0"      \
1126         "_SYSTEMD_SLICE\0"
1127
1128 /* ... and add_matches_for_user_unit */
1129 #define USER_UNITS                   \
1130         "_SYSTEMD_USER_UNIT\0"       \
1131         "USER_UNIT\0"                \
1132         "COREDUMP_USER_UNIT\0"       \
1133         "OBJECT_SYSTEMD_USER_UNIT\0"
1134
1135 static int add_units(sd_journal *j) {
1136         _cleanup_strv_free_ char **patterns = NULL;
1137         int r, count = 0;
1138         char **i;
1139
1140         assert(j);
1141
1142         STRV_FOREACH(i, arg_system_units) {
1143                 _cleanup_free_ char *u = NULL;
1144
1145                 u = unit_name_mangle(*i, MANGLE_GLOB);
1146                 if (!u)
1147                         return log_oom();
1148
1149                 if (string_is_glob(u)) {
1150                         r = strv_push(&patterns, u);
1151                         if (r < 0)
1152                                 return r;
1153                         u = NULL;
1154                 } else {
1155                         r = add_matches_for_unit(j, u);
1156                         if (r < 0)
1157                                 return r;
1158                         r = sd_journal_add_disjunction(j);
1159                         if (r < 0)
1160                                 return r;
1161                         count ++;
1162                 }
1163         }
1164
1165         if (!strv_isempty(patterns)) {
1166                 _cleanup_set_free_free_ Set *units = NULL;
1167                 Iterator it;
1168                 char *u;
1169
1170                 r = get_possible_units(j, SYSTEM_UNITS, patterns, &units);
1171                 if (r < 0)
1172                         return r;
1173
1174                 SET_FOREACH(u, units, it) {
1175                         r = add_matches_for_unit(j, u);
1176                         if (r < 0)
1177                                 return r;
1178                         r = sd_journal_add_disjunction(j);
1179                         if (r < 0)
1180                                 return r;
1181                         count ++;
1182                 }
1183         }
1184
1185         strv_free(patterns);
1186         patterns = NULL;
1187
1188         STRV_FOREACH(i, arg_user_units) {
1189                 _cleanup_free_ char *u = NULL;
1190
1191                 u = unit_name_mangle(*i, MANGLE_GLOB);
1192                 if (!u)
1193                         return log_oom();
1194
1195                 if (string_is_glob(u)) {
1196                         r = strv_push(&patterns, u);
1197                         if (r < 0)
1198                                 return r;
1199                         u = NULL;
1200                 } else {
1201                         r = add_matches_for_user_unit(j, u, getuid());
1202                         if (r < 0)
1203                                 return r;
1204                         r = sd_journal_add_disjunction(j);
1205                         if (r < 0)
1206                                 return r;
1207                         count ++;
1208                 }
1209         }
1210
1211         if (!strv_isempty(patterns)) {
1212                 _cleanup_set_free_free_ Set *units = NULL;
1213                 Iterator it;
1214                 char *u;
1215
1216                 r = get_possible_units(j, USER_UNITS, patterns, &units);
1217                 if (r < 0)
1218                         return r;
1219
1220                 SET_FOREACH(u, units, it) {
1221                         r = add_matches_for_user_unit(j, u, getuid());
1222                         if (r < 0)
1223                                 return r;
1224                         r = sd_journal_add_disjunction(j);
1225                         if (r < 0)
1226                                 return r;
1227                         count ++;
1228                 }
1229         }
1230
1231         /* Complain if the user request matches but nothing whatsoever was
1232          * found, since otherwise everything would be matched. */
1233         if (!(strv_isempty(arg_system_units) && strv_isempty(arg_user_units)) && count == 0)
1234                 return -ENODATA;
1235
1236         r = sd_journal_add_conjunction(j);
1237         if (r < 0)
1238                 return r;
1239
1240         return 0;
1241 }
1242
1243 static int add_priorities(sd_journal *j) {
1244         char match[] = "PRIORITY=0";
1245         int i, r;
1246         assert(j);
1247
1248         if (arg_priorities == 0xFF)
1249                 return 0;
1250
1251         for (i = LOG_EMERG; i <= LOG_DEBUG; i++)
1252                 if (arg_priorities & (1 << i)) {
1253                         match[sizeof(match)-2] = '0' + i;
1254
1255                         r = sd_journal_add_match(j, match, strlen(match));
1256                         if (r < 0)
1257                                 return log_error_errno(r, "Failed to add match: %m");
1258                 }
1259
1260         r = sd_journal_add_conjunction(j);
1261         if (r < 0)
1262                 return r;
1263
1264         return 0;
1265 }
1266
1267
1268 static int add_syslog_identifier(sd_journal *j) {
1269         int r;
1270         char **i;
1271
1272         assert(j);
1273
1274         STRV_FOREACH(i, arg_syslog_identifier) {
1275                 char *u;
1276
1277                 u = strappenda("SYSLOG_IDENTIFIER=", *i);
1278                 r = sd_journal_add_match(j, u, 0);
1279                 if (r < 0)
1280                         return r;
1281                 r = sd_journal_add_disjunction(j);
1282                 if (r < 0)
1283                         return r;
1284         }
1285
1286         r = sd_journal_add_conjunction(j);
1287         if (r < 0)
1288                 return r;
1289
1290         return 0;
1291 }
1292
1293 static int setup_keys(void) {
1294 #ifdef HAVE_GCRYPT
1295         size_t mpk_size, seed_size, state_size, i;
1296         uint8_t *mpk, *seed, *state;
1297         ssize_t l;
1298         int fd = -1, r, attr = 0;
1299         sd_id128_t machine, boot;
1300         char *p = NULL, *k = NULL;
1301         struct FSSHeader h;
1302         uint64_t n;
1303         struct stat st;
1304
1305         r = stat("/var/log/journal", &st);
1306         if (r < 0 && errno != ENOENT && errno != ENOTDIR) {
1307                 log_error_errno(errno, "stat(\"%s\") failed: %m", "/var/log/journal");
1308                 return -errno;
1309         }
1310
1311         if (r < 0 || !S_ISDIR(st.st_mode)) {
1312                 log_error("%s is not a directory, must be using persistent logging for FSS.",
1313                           "/var/log/journal");
1314                 return r < 0 ? -errno : -ENOTDIR;
1315         }
1316
1317         r = sd_id128_get_machine(&machine);
1318         if (r < 0)
1319                 return log_error_errno(r, "Failed to get machine ID: %m");
1320
1321         r = sd_id128_get_boot(&boot);
1322         if (r < 0)
1323                 return log_error_errno(r, "Failed to get boot ID: %m");
1324
1325         if (asprintf(&p, "/var/log/journal/" SD_ID128_FORMAT_STR "/fss",
1326                      SD_ID128_FORMAT_VAL(machine)) < 0)
1327                 return log_oom();
1328
1329         if (access(p, F_OK) >= 0) {
1330                 if (arg_force) {
1331                         r = unlink(p);
1332                         if (r < 0) {
1333                                 log_error_errno(errno, "unlink(\"%s\") failed: %m", p);
1334                                 r = -errno;
1335                                 goto finish;
1336                         }
1337                 } else {
1338                         log_error("Sealing key file %s exists already. (--force to recreate)", p);
1339                         r = -EEXIST;
1340                         goto finish;
1341                 }
1342         }
1343
1344         if (asprintf(&k, "/var/log/journal/" SD_ID128_FORMAT_STR "/fss.tmp.XXXXXX",
1345                      SD_ID128_FORMAT_VAL(machine)) < 0) {
1346                 r = log_oom();
1347                 goto finish;
1348         }
1349
1350         mpk_size = FSPRG_mskinbytes(FSPRG_RECOMMENDED_SECPAR);
1351         mpk = alloca(mpk_size);
1352
1353         seed_size = FSPRG_RECOMMENDED_SEEDLEN;
1354         seed = alloca(seed_size);
1355
1356         state_size = FSPRG_stateinbytes(FSPRG_RECOMMENDED_SECPAR);
1357         state = alloca(state_size);
1358
1359         fd = open("/dev/random", O_RDONLY|O_CLOEXEC|O_NOCTTY);
1360         if (fd < 0) {
1361                 log_error_errno(errno, "Failed to open /dev/random: %m");
1362                 r = -errno;
1363                 goto finish;
1364         }
1365
1366         log_info("Generating seed...");
1367         l = loop_read(fd, seed, seed_size, true);
1368         if (l < 0 || (size_t) l != seed_size) {
1369                 log_error_errno(EIO, "Failed to read random seed: %m");
1370                 r = -EIO;
1371                 goto finish;
1372         }
1373
1374         log_info("Generating key pair...");
1375         FSPRG_GenMK(NULL, mpk, seed, seed_size, FSPRG_RECOMMENDED_SECPAR);
1376
1377         log_info("Generating sealing key...");
1378         FSPRG_GenState0(state, mpk, seed, seed_size);
1379
1380         assert(arg_interval > 0);
1381
1382         n = now(CLOCK_REALTIME);
1383         n /= arg_interval;
1384
1385         safe_close(fd);
1386         fd = mkostemp_safe(k, O_WRONLY|O_CLOEXEC);
1387         if (fd < 0) {
1388                 log_error_errno(errno, "Failed to open %s: %m", k);
1389                 r = -errno;
1390                 goto finish;
1391         }
1392
1393         /* Enable secure remove, exclusion from dump, synchronous
1394          * writing and in-place updating */
1395         if (ioctl(fd, FS_IOC_GETFLAGS, &attr) < 0)
1396                 log_warning_errno(errno, "FS_IOC_GETFLAGS failed: %m");
1397
1398         attr |= FS_SECRM_FL|FS_NODUMP_FL|FS_SYNC_FL|FS_NOCOW_FL;
1399
1400         if (ioctl(fd, FS_IOC_SETFLAGS, &attr) < 0)
1401                 log_warning_errno(errno, "FS_IOC_SETFLAGS failed: %m");
1402
1403         zero(h);
1404         memcpy(h.signature, "KSHHRHLP", 8);
1405         h.machine_id = machine;
1406         h.boot_id = boot;
1407         h.header_size = htole64(sizeof(h));
1408         h.start_usec = htole64(n * arg_interval);
1409         h.interval_usec = htole64(arg_interval);
1410         h.fsprg_secpar = htole16(FSPRG_RECOMMENDED_SECPAR);
1411         h.fsprg_state_size = htole64(state_size);
1412
1413         l = loop_write(fd, &h, sizeof(h), false);
1414         if (l < 0 || (size_t) l != sizeof(h)) {
1415                 log_error_errno(EIO, "Failed to write header: %m");
1416                 r = -EIO;
1417                 goto finish;
1418         }
1419
1420         l = loop_write(fd, state, state_size, false);
1421         if (l < 0 || (size_t) l != state_size) {
1422                 log_error_errno(EIO, "Failed to write state: %m");
1423                 r = -EIO;
1424                 goto finish;
1425         }
1426
1427         if (link(k, p) < 0) {
1428                 log_error_errno(errno, "Failed to link file: %m");
1429                 r = -errno;
1430                 goto finish;
1431         }
1432
1433         if (on_tty()) {
1434                 fprintf(stderr,
1435                         "\n"
1436                         "The new key pair has been generated. The " ANSI_HIGHLIGHT_ON "secret sealing key" ANSI_HIGHLIGHT_OFF " has been written to\n"
1437                         "the following local file. This key file is automatically updated when the\n"
1438                         "sealing key is advanced. It should not be used on multiple hosts.\n"
1439                         "\n"
1440                         "\t%s\n"
1441                         "\n"
1442                         "Please write down the following " ANSI_HIGHLIGHT_ON "secret verification key" ANSI_HIGHLIGHT_OFF ". It should be stored\n"
1443                         "at a safe location and should not be saved locally on disk.\n"
1444                         "\n\t" ANSI_HIGHLIGHT_RED_ON, p);
1445                 fflush(stderr);
1446         }
1447         for (i = 0; i < seed_size; i++) {
1448                 if (i > 0 && i % 3 == 0)
1449                         putchar('-');
1450                 printf("%02x", ((uint8_t*) seed)[i]);
1451         }
1452
1453         printf("/%llx-%llx\n", (unsigned long long) n, (unsigned long long) arg_interval);
1454
1455         if (on_tty()) {
1456                 char tsb[FORMAT_TIMESPAN_MAX], *hn;
1457
1458                 fprintf(stderr,
1459                         ANSI_HIGHLIGHT_OFF "\n"
1460                         "The sealing key is automatically changed every %s.\n",
1461                         format_timespan(tsb, sizeof(tsb), arg_interval, 0));
1462
1463                 hn = gethostname_malloc();
1464
1465                 if (hn) {
1466                         hostname_cleanup(hn, false);
1467                         fprintf(stderr, "\nThe keys have been generated for host %s/" SD_ID128_FORMAT_STR ".\n", hn, SD_ID128_FORMAT_VAL(machine));
1468                 } else
1469                         fprintf(stderr, "\nThe keys have been generated for host " SD_ID128_FORMAT_STR ".\n", SD_ID128_FORMAT_VAL(machine));
1470
1471 #ifdef HAVE_QRENCODE
1472                 /* If this is not an UTF-8 system don't print any QR codes */
1473                 if (is_locale_utf8()) {
1474                         fputs("\nTo transfer the verification key to your phone please scan the QR code below:\n\n", stderr);
1475                         print_qr_code(stderr, seed, seed_size, n, arg_interval, hn, machine);
1476                 }
1477 #endif
1478                 free(hn);
1479         }
1480
1481         r = 0;
1482
1483 finish:
1484         safe_close(fd);
1485
1486         if (k) {
1487                 unlink(k);
1488                 free(k);
1489         }
1490
1491         free(p);
1492
1493         return r;
1494 #else
1495         log_error("Forward-secure sealing not available.");
1496         return -ENOTSUP;
1497 #endif
1498 }
1499
1500 static int verify(sd_journal *j) {
1501         int r = 0;
1502         Iterator i;
1503         JournalFile *f;
1504
1505         assert(j);
1506
1507         log_show_color(true);
1508
1509         ORDERED_HASHMAP_FOREACH(f, j->files, i) {
1510                 int k;
1511                 usec_t first, validated, last;
1512
1513 #ifdef HAVE_GCRYPT
1514                 if (!arg_verify_key && JOURNAL_HEADER_SEALED(f->header))
1515                         log_notice("Journal file %s has sealing enabled but verification key has not been passed using --verify-key=.", f->path);
1516 #endif
1517
1518                 k = journal_file_verify(f, arg_verify_key, &first, &validated, &last, true);
1519                 if (k == -EINVAL) {
1520                         /* If the key was invalid give up right-away. */
1521                         return k;
1522                 } else if (k < 0) {
1523                         log_warning("FAIL: %s (%s)", f->path, strerror(-k));
1524                         r = k;
1525                 } else {
1526                         char a[FORMAT_TIMESTAMP_MAX], b[FORMAT_TIMESTAMP_MAX], c[FORMAT_TIMESPAN_MAX];
1527                         log_info("PASS: %s", f->path);
1528
1529                         if (arg_verify_key && JOURNAL_HEADER_SEALED(f->header)) {
1530                                 if (validated > 0) {
1531                                         log_info("=> Validated from %s to %s, final %s entries not sealed.",
1532                                                  format_timestamp_maybe_utc(a, sizeof(a), first),
1533                                                  format_timestamp_maybe_utc(b, sizeof(b), validated),
1534                                                  format_timespan(c, sizeof(c), last > validated ? last - validated : 0, 0));
1535                                 } else if (last > 0)
1536                                         log_info("=> No sealing yet, %s of entries not sealed.",
1537                                                  format_timespan(c, sizeof(c), last - first, 0));
1538                                 else
1539                                         log_info("=> No sealing yet, no entries in file.");
1540                         }
1541                 }
1542         }
1543
1544         return r;
1545 }
1546
1547 #ifdef HAVE_ACL
1548 static int access_check_var_log_journal(sd_journal *j) {
1549         _cleanup_strv_free_ char **g = NULL;
1550         bool have_access;
1551         int r;
1552
1553         assert(j);
1554
1555         have_access = in_group("systemd-journal") > 0;
1556
1557         if (!have_access) {
1558                 /* Let's enumerate all groups from the default ACL of
1559                  * the directory, which generally should allow access
1560                  * to most journal files too */
1561                 r = search_acl_groups(&g, "/var/log/journal/", &have_access);
1562                 if (r < 0)
1563                         return r;
1564         }
1565
1566         if (!have_access) {
1567
1568                 if (strv_isempty(g))
1569                         log_notice("Hint: You are currently not seeing messages from other users and the system.\n"
1570                                    "      Users in the 'systemd-journal' group can see all messages. Pass -q to\n"
1571                                    "      turn off this notice.");
1572                 else {
1573                         _cleanup_free_ char *s = NULL;
1574
1575                         r = strv_extend(&g, "systemd-journal");
1576                         if (r < 0)
1577                                 return log_oom();
1578
1579                         strv_sort(g);
1580                         strv_uniq(g);
1581
1582                         s = strv_join(g, "', '");
1583                         if (!s)
1584                                 return log_oom();
1585
1586                         log_notice("Hint: You are currently not seeing messages from other users and the system.\n"
1587                                    "      Users in the groups '%s' can see all messages.\n"
1588                                    "      Pass -q to turn off this notice.", s);
1589                 }
1590         }
1591
1592         return 0;
1593 }
1594 #endif
1595
1596 static int access_check(sd_journal *j) {
1597         Iterator it;
1598         void *code;
1599         int r = 0;
1600
1601         assert(j);
1602
1603         if (set_isempty(j->errors)) {
1604                 if (ordered_hashmap_isempty(j->files))
1605                         log_notice("No journal files were found.");
1606                 return 0;
1607         }
1608
1609         if (set_contains(j->errors, INT_TO_PTR(-EACCES))) {
1610 #ifdef HAVE_ACL
1611                 /* If /var/log/journal doesn't even exist,
1612                  * unprivileged users have no access at all */
1613                 if (access("/var/log/journal", F_OK) < 0 &&
1614                     geteuid() != 0 &&
1615                     in_group("systemd-journal") <= 0) {
1616                         log_error("Unprivileged users cannot access messages, unless persistent log storage is\n"
1617                                   "enabled. Users in the 'systemd-journal' group may always access messages.");
1618                         return -EACCES;
1619                 }
1620
1621                 /* If /var/log/journal exists, try to pring a nice
1622                    notice if the user lacks access to it */
1623                 if (!arg_quiet && geteuid() != 0) {
1624                         r = access_check_var_log_journal(j);
1625                         if (r < 0)
1626                                 return r;
1627                 }
1628 #else
1629                 if (geteuid() != 0 && in_group("systemd-journal") <= 0) {
1630                         log_error("Unprivileged users cannot access messages. Users in the 'systemd-journal' group\n"
1631                                   "group may access messages.");
1632                         return -EACCES;
1633                 }
1634 #endif
1635
1636                 if (ordered_hashmap_isempty(j->files)) {
1637                         log_error("No journal files were opened due to insufficient permissions.");
1638                         r = -EACCES;
1639                 }
1640         }
1641
1642         SET_FOREACH(code, j->errors, it) {
1643                 int err;
1644
1645                 err = -PTR_TO_INT(code);
1646                 assert(err > 0);
1647
1648                 if (err != EACCES)
1649                         log_warning_errno(err, "Error was encountered while opening journal files: %m");
1650         }
1651
1652         return r;
1653 }
1654
1655 static int flush_to_var(void) {
1656         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1657         _cleanup_bus_close_unref_ sd_bus *bus = NULL;
1658         _cleanup_close_ int watch_fd = -1;
1659         int r;
1660
1661         /* Quick exit */
1662         if (access("/run/systemd/journal/flushed", F_OK) >= 0)
1663                 return 0;
1664
1665         /* OK, let's actually do the full logic, send SIGUSR1 to the
1666          * daemon and set up inotify to wait for the flushed file to appear */
1667         r = bus_open_system_systemd(&bus);
1668         if (r < 0)
1669                 return log_error_errno(r, "Failed to get D-Bus connection: %m");
1670
1671         r = sd_bus_call_method(
1672                         bus,
1673                         "org.freedesktop.systemd1",
1674                         "/org/freedesktop/systemd1",
1675                         "org.freedesktop.systemd1.Manager",
1676                         "KillUnit",
1677                         &error,
1678                         NULL,
1679                         "ssi", "systemd-journald.service", "main", SIGUSR1);
1680         if (r < 0) {
1681                 log_error("Failed to kill journal service: %s", bus_error_message(&error, r));
1682                 return r;
1683         }
1684
1685         mkdir_p("/run/systemd/journal", 0755);
1686
1687         watch_fd = inotify_init1(IN_NONBLOCK|IN_CLOEXEC);
1688         if (watch_fd < 0) {
1689                 log_error_errno(errno, "Failed to create inotify watch: %m");
1690                 return -errno;
1691         }
1692
1693         r = inotify_add_watch(watch_fd, "/run/systemd/journal", IN_CREATE|IN_DONT_FOLLOW|IN_ONLYDIR);
1694         if (r < 0) {
1695                 log_error_errno(errno, "Failed to watch journal directory: %m");
1696                 return -errno;
1697         }
1698
1699         for (;;) {
1700                 if (access("/run/systemd/journal/flushed", F_OK) >= 0)
1701                         break;
1702
1703                 if (errno != ENOENT) {
1704                         log_error_errno(errno, "Failed to check for existance of /run/systemd/journal/flushed: %m");
1705                         return -errno;
1706                 }
1707
1708                 r = fd_wait_for_event(watch_fd, POLLIN, USEC_INFINITY);
1709                 if (r < 0)
1710                         return log_error_errno(r, "Failed to wait for event: %m");
1711
1712                 r = flush_fd(watch_fd);
1713                 if (r < 0)
1714                         return log_error_errno(r, "Failed to flush inotify events: %m");
1715         }
1716
1717         return 0;
1718 }
1719
1720 int main(int argc, char *argv[]) {
1721         int r;
1722         _cleanup_journal_close_ sd_journal *j = NULL;
1723         bool need_seek = false;
1724         sd_id128_t previous_boot_id;
1725         bool previous_boot_id_valid = false, first_line = true;
1726         int n_shown = 0;
1727         bool ellipsized = false;
1728
1729         setlocale(LC_ALL, "");
1730         log_parse_environment();
1731         log_open();
1732
1733         r = parse_argv(argc, argv);
1734         if (r <= 0)
1735                 goto finish;
1736
1737         signal(SIGWINCH, columns_lines_cache_reset);
1738
1739         if (arg_action == ACTION_NEW_ID128) {
1740                 r = generate_new_id128();
1741                 goto finish;
1742         }
1743
1744         if (arg_action == ACTION_FLUSH) {
1745                 r = flush_to_var();
1746                 goto finish;
1747         }
1748
1749         if (arg_action == ACTION_SETUP_KEYS) {
1750                 r = setup_keys();
1751                 goto finish;
1752         }
1753
1754         if (arg_action == ACTION_UPDATE_CATALOG ||
1755             arg_action == ACTION_LIST_CATALOG ||
1756             arg_action == ACTION_DUMP_CATALOG) {
1757
1758                 _cleanup_free_ char *database;
1759
1760                 database = path_join(arg_root, CATALOG_DATABASE, NULL);
1761                 if (!database) {
1762                         r = log_oom();
1763                         goto finish;
1764                 }
1765
1766                 if (arg_action == ACTION_UPDATE_CATALOG) {
1767                         r = catalog_update(database, arg_root, catalog_file_dirs);
1768                         if (r < 0)
1769                                 log_error_errno(r, "Failed to list catalog: %m");
1770                 } else {
1771                         bool oneline = arg_action == ACTION_LIST_CATALOG;
1772
1773                         if (optind < argc)
1774                                 r = catalog_list_items(stdout, database,
1775                                                        oneline, argv + optind);
1776                         else
1777                                 r = catalog_list(stdout, database, oneline);
1778                         if (r < 0)
1779                                 log_error_errno(r, "Failed to list catalog: %m");
1780                 }
1781
1782                 goto finish;
1783         }
1784
1785         if (arg_directory)
1786                 r = sd_journal_open_directory(&j, arg_directory, arg_journal_type);
1787         else if (arg_file)
1788                 r = sd_journal_open_files(&j, (const char**) arg_file, 0);
1789         else if (arg_machine)
1790                 r = sd_journal_open_container(&j, arg_machine, 0);
1791         else
1792                 r = sd_journal_open(&j, !arg_merge*SD_JOURNAL_LOCAL_ONLY + arg_journal_type);
1793         if (r < 0) {
1794                 log_error_errno(r, "Failed to open %s: %m",
1795                                 arg_directory ? arg_directory : arg_file ? "files" : "journal");
1796                 return EXIT_FAILURE;
1797         }
1798
1799         r = access_check(j);
1800         if (r < 0)
1801                 return EXIT_FAILURE;
1802
1803         if (arg_action == ACTION_VERIFY) {
1804                 r = verify(j);
1805                 goto finish;
1806         }
1807
1808         if (arg_action == ACTION_PRINT_HEADER) {
1809                 journal_print_header(j);
1810                 return EXIT_SUCCESS;
1811         }
1812
1813         if (arg_action == ACTION_DISK_USAGE) {
1814                 uint64_t bytes = 0;
1815                 char sbytes[FORMAT_BYTES_MAX];
1816
1817                 r = sd_journal_get_usage(j, &bytes);
1818                 if (r < 0)
1819                         return EXIT_FAILURE;
1820
1821                 printf("Archived and active journals take up %s on disk.\n",
1822                        format_bytes(sbytes, sizeof(sbytes), bytes));
1823                 return EXIT_SUCCESS;
1824         }
1825
1826         if (arg_action == ACTION_VACUUM) {
1827                 Directory *d;
1828                 Iterator i;
1829
1830                 HASHMAP_FOREACH(d, j->directories_by_path, i) {
1831                         int q;
1832
1833                         if (d->is_root)
1834                                 continue;
1835
1836                         q = journal_directory_vacuum(d->path, arg_vacuum_size, arg_vacuum_time, NULL, true);
1837                         if (q < 0) {
1838                                 log_error_errno(q, "Failed to vacuum: %m");
1839                                 r = q;
1840                         }
1841                 }
1842
1843                 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
1844         }
1845
1846         if (arg_action == ACTION_LIST_BOOTS) {
1847                 r = list_boots(j);
1848                 goto finish;
1849         }
1850
1851         /* add_boot() must be called first!
1852          * It may need to seek the journal to find parent boot IDs. */
1853         r = add_boot(j);
1854         if (r < 0)
1855                 return EXIT_FAILURE;
1856
1857         r = add_dmesg(j);
1858         if (r < 0)
1859                 return EXIT_FAILURE;
1860
1861         r = add_units(j);
1862         strv_free(arg_system_units);
1863         strv_free(arg_user_units);
1864
1865         if (r < 0) {
1866                 log_error_errno(r, "Failed to add filter for units: %m");
1867                 return EXIT_FAILURE;
1868         }
1869
1870         r = add_syslog_identifier(j);
1871         if (r < 0) {
1872                 log_error_errno(r, "Failed to add filter for syslog identifiers: %m");
1873                 return EXIT_FAILURE;
1874         }
1875
1876         r = add_priorities(j);
1877         if (r < 0) {
1878                 log_error_errno(r, "Failed to add filter for priorities: %m");
1879                 return EXIT_FAILURE;
1880         }
1881
1882         r = add_matches(j, argv + optind);
1883         if (r < 0) {
1884                 log_error_errno(r, "Failed to add filters: %m");
1885                 return EXIT_FAILURE;
1886         }
1887
1888         if (_unlikely_(log_get_max_level() >= LOG_PRI(LOG_DEBUG))) {
1889                 _cleanup_free_ char *filter;
1890
1891                 filter = journal_make_match_string(j);
1892                 log_debug("Journal filter: %s", filter);
1893         }
1894
1895         if (arg_field) {
1896                 const void *data;
1897                 size_t size;
1898
1899                 r = sd_journal_set_data_threshold(j, 0);
1900                 if (r < 0) {
1901                         log_error("Failed to unset data size threshold");
1902                         return EXIT_FAILURE;
1903                 }
1904
1905                 r = sd_journal_query_unique(j, arg_field);
1906                 if (r < 0) {
1907                         log_error_errno(r, "Failed to query unique data objects: %m");
1908                         return EXIT_FAILURE;
1909                 }
1910
1911                 SD_JOURNAL_FOREACH_UNIQUE(j, data, size) {
1912                         const void *eq;
1913
1914                         if (arg_lines >= 0 && n_shown >= arg_lines)
1915                                 break;
1916
1917                         eq = memchr(data, '=', size);
1918                         if (eq)
1919                                 printf("%.*s\n", (int) (size - ((const uint8_t*) eq - (const uint8_t*) data + 1)), (const char*) eq + 1);
1920                         else
1921                                 printf("%.*s\n", (int) size, (const char*) data);
1922
1923                         n_shown ++;
1924                 }
1925
1926                 return EXIT_SUCCESS;
1927         }
1928
1929         /* Opening the fd now means the first sd_journal_wait() will actually wait */
1930         if (arg_follow) {
1931                 r = sd_journal_get_fd(j);
1932                 if (r < 0)
1933                         return EXIT_FAILURE;
1934         }
1935
1936         if (arg_cursor || arg_after_cursor) {
1937                 r = sd_journal_seek_cursor(j, arg_cursor ?: arg_after_cursor);
1938                 if (r < 0) {
1939                         log_error_errno(r, "Failed to seek to cursor: %m");
1940                         return EXIT_FAILURE;
1941                 }
1942                 if (!arg_reverse)
1943                         r = sd_journal_next_skip(j, 1 + !!arg_after_cursor);
1944                 else
1945                         r = sd_journal_previous_skip(j, 1 + !!arg_after_cursor);
1946
1947                 if (arg_after_cursor && r < 2 && !arg_follow)
1948                         /* We couldn't find the next entry after the cursor. */
1949                         arg_lines = 0;
1950
1951         } else if (arg_since_set && !arg_reverse) {
1952                 r = sd_journal_seek_realtime_usec(j, arg_since);
1953                 if (r < 0) {
1954                         log_error_errno(r, "Failed to seek to date: %m");
1955                         return EXIT_FAILURE;
1956                 }
1957                 r = sd_journal_next(j);
1958
1959         } else if (arg_until_set && arg_reverse) {
1960                 r = sd_journal_seek_realtime_usec(j, arg_until);
1961                 if (r < 0) {
1962                         log_error_errno(r, "Failed to seek to date: %m");
1963                         return EXIT_FAILURE;
1964                 }
1965                 r = sd_journal_previous(j);
1966
1967         } else if (arg_lines >= 0) {
1968                 r = sd_journal_seek_tail(j);
1969                 if (r < 0) {
1970                         log_error_errno(r, "Failed to seek to tail: %m");
1971                         return EXIT_FAILURE;
1972                 }
1973
1974                 r = sd_journal_previous_skip(j, arg_lines);
1975
1976         } else if (arg_reverse) {
1977                 r = sd_journal_seek_tail(j);
1978                 if (r < 0) {
1979                         log_error_errno(r, "Failed to seek to tail: %m");
1980                         return EXIT_FAILURE;
1981                 }
1982
1983                 r = sd_journal_previous(j);
1984
1985         } else {
1986                 r = sd_journal_seek_head(j);
1987                 if (r < 0) {
1988                         log_error_errno(r, "Failed to seek to head: %m");
1989                         return EXIT_FAILURE;
1990                 }
1991
1992                 r = sd_journal_next(j);
1993         }
1994
1995         if (r < 0) {
1996                 log_error_errno(r, "Failed to iterate through journal: %m");
1997                 return EXIT_FAILURE;
1998         }
1999
2000         if (!arg_follow)
2001                 pager_open_if_enabled();
2002
2003         if (!arg_quiet) {
2004                 usec_t start, end;
2005                 char start_buf[FORMAT_TIMESTAMP_MAX], end_buf[FORMAT_TIMESTAMP_MAX];
2006
2007                 r = sd_journal_get_cutoff_realtime_usec(j, &start, &end);
2008                 if (r < 0) {
2009                         log_error_errno(r, "Failed to get cutoff: %m");
2010                         goto finish;
2011                 }
2012
2013                 if (r > 0) {
2014                         if (arg_follow)
2015                                 printf("-- Logs begin at %s. --\n",
2016                                        format_timestamp_maybe_utc(start_buf, sizeof(start_buf), start));
2017                         else
2018                                 printf("-- Logs begin at %s, end at %s. --\n",
2019                                        format_timestamp_maybe_utc(start_buf, sizeof(start_buf), start),
2020                                        format_timestamp_maybe_utc(end_buf, sizeof(end_buf), end));
2021                 }
2022         }
2023
2024         for (;;) {
2025                 while (arg_lines < 0 || n_shown < arg_lines || (arg_follow && !first_line)) {
2026                         int flags;
2027
2028                         if (need_seek) {
2029                                 if (!arg_reverse)
2030                                         r = sd_journal_next(j);
2031                                 else
2032                                         r = sd_journal_previous(j);
2033                                 if (r < 0) {
2034                                         log_error_errno(r, "Failed to iterate through journal: %m");
2035                                         goto finish;
2036                                 }
2037                                 if (r == 0)
2038                                         break;
2039                         }
2040
2041                         if (arg_until_set && !arg_reverse) {
2042                                 usec_t usec;
2043
2044                                 r = sd_journal_get_realtime_usec(j, &usec);
2045                                 if (r < 0) {
2046                                         log_error_errno(r, "Failed to determine timestamp: %m");
2047                                         goto finish;
2048                                 }
2049                                 if (usec > arg_until)
2050                                         goto finish;
2051                         }
2052
2053                         if (arg_since_set && arg_reverse) {
2054                                 usec_t usec;
2055
2056                                 r = sd_journal_get_realtime_usec(j, &usec);
2057                                 if (r < 0) {
2058                                         log_error_errno(r, "Failed to determine timestamp: %m");
2059                                         goto finish;
2060                                 }
2061                                 if (usec < arg_since)
2062                                         goto finish;
2063                         }
2064
2065                         if (!arg_merge && !arg_quiet) {
2066                                 sd_id128_t boot_id;
2067
2068                                 r = sd_journal_get_monotonic_usec(j, NULL, &boot_id);
2069                                 if (r >= 0) {
2070                                         if (previous_boot_id_valid &&
2071                                             !sd_id128_equal(boot_id, previous_boot_id))
2072                                                 printf("%s-- Reboot --%s\n",
2073                                                        ansi_highlight(), ansi_highlight_off());
2074
2075                                         previous_boot_id = boot_id;
2076                                         previous_boot_id_valid = true;
2077                                 }
2078                         }
2079
2080                         flags =
2081                                 arg_all * OUTPUT_SHOW_ALL |
2082                                 arg_full * OUTPUT_FULL_WIDTH |
2083                                 on_tty() * OUTPUT_COLOR |
2084                                 arg_catalog * OUTPUT_CATALOG |
2085                                 arg_utc * OUTPUT_UTC;
2086
2087                         r = output_journal(stdout, j, arg_output, 0, flags, &ellipsized);
2088                         need_seek = true;
2089                         if (r == -EADDRNOTAVAIL)
2090                                 break;
2091                         else if (r < 0 || ferror(stdout))
2092                                 goto finish;
2093
2094                         n_shown++;
2095                 }
2096
2097                 if (!arg_follow) {
2098                         if (arg_show_cursor) {
2099                                 _cleanup_free_ char *cursor = NULL;
2100
2101                                 r = sd_journal_get_cursor(j, &cursor);
2102                                 if (r < 0 && r != -EADDRNOTAVAIL)
2103                                         log_error_errno(r, "Failed to get cursor: %m");
2104                                 else if (r >= 0)
2105                                         printf("-- cursor: %s\n", cursor);
2106                         }
2107
2108                         break;
2109                 }
2110
2111                 r = sd_journal_wait(j, (uint64_t) -1);
2112                 if (r < 0) {
2113                         log_error_errno(r, "Couldn't wait for journal event: %m");
2114                         goto finish;
2115                 }
2116
2117                 first_line = false;
2118         }
2119
2120 finish:
2121         pager_close();
2122
2123         strv_free(arg_file);
2124
2125         return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
2126 }