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