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