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