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