chiark / gitweb /
logs-show: export logic to add matches for units
[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 <errno.h>
25 #include <stddef.h>
26 #include <string.h>
27 #include <stdio.h>
28 #include <unistd.h>
29 #include <stdlib.h>
30 #include <sys/poll.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 #include <systemd/sd-journal.h>
39
40 #include "log.h"
41 #include "util.h"
42 #include "path-util.h"
43 #include "build.h"
44 #include "pager.h"
45 #include "logs-show.h"
46 #include "strv.h"
47 #include "journal-internal.h"
48 #include "journal-def.h"
49 #include "journal-verify.h"
50 #include "journal-authenticate.h"
51 #include "journal-qrcode.h"
52 #include "fsprg.h"
53 #include "unit-name.h"
54 #include "catalog.h"
55
56 #define DEFAULT_FSS_INTERVAL_USEC (15*USEC_PER_MINUTE)
57
58 static OutputMode arg_output = OUTPUT_SHORT;
59 static bool arg_pager_end = false;
60 static bool arg_follow = false;
61 static bool arg_full = false;
62 static bool arg_all = false;
63 static bool arg_no_pager = false;
64 static int arg_lines = -1;
65 static bool arg_no_tail = false;
66 static bool arg_quiet = false;
67 static bool arg_merge = false;
68 static bool arg_this_boot = false;
69 static const char *arg_cursor = NULL;
70 static const char *arg_directory = NULL;
71 static int arg_priorities = 0xFF;
72 static const char *arg_verify_key = NULL;
73 #ifdef HAVE_GCRYPT
74 static usec_t arg_interval = DEFAULT_FSS_INTERVAL_USEC;
75 #endif
76 static usec_t arg_since, arg_until;
77 static bool arg_since_set = false, arg_until_set = false;
78 static const char *arg_unit = NULL;
79 static const char *arg_unit_type = NULL;
80 static const char *arg_field = NULL;
81 static bool arg_catalog = false;
82 static bool arg_reverse = false;
83
84 static enum {
85         ACTION_SHOW,
86         ACTION_NEW_ID128,
87         ACTION_PRINT_HEADER,
88         ACTION_SETUP_KEYS,
89         ACTION_VERIFY,
90         ACTION_DISK_USAGE,
91         ACTION_LIST_CATALOG,
92         ACTION_UPDATE_CATALOG
93 } arg_action = ACTION_SHOW;
94
95 static int help(void) {
96
97         printf("%s [OPTIONS...] [MATCHES...]\n\n"
98                "Query the journal.\n\n"
99                "Flags:\n"
100                "     --since=DATE        Start showing entries newer or of the specified date\n"
101                "     --until=DATE        Stop showing entries older or of the specified date\n"
102                "  -c --cursor=CURSOR     Start showing entries from specified cursor\n"
103                "  -b --this-boot         Show data only from current boot\n"
104                "  -u --unit=UNIT         Show data only from the specified unit\n"
105                "     --user-unit=UNIT    Show data only from the specified user session unit\n"
106                "  -p --priority=RANGE    Show only messages within the specified priority range\n"
107                "  -e --pager-end         Immediately jump to end of the journal in the pager\n"
108                "  -f --follow            Follow journal\n"
109                "  -n --lines[=INTEGER]   Number of journal entries to show\n"
110                "     --no-tail           Show all lines, even in follow mode\n"
111                "  -r --reverse           Show the newest entries first\n"
112                "  -o --output=STRING     Change journal output mode (short, short-monotonic,\n"
113                "                         verbose, export, json, json-pretty, json-sse, cat)\n"
114                "  -x --catalog           Add message explanations where available\n"
115                "     --full              Do not ellipsize fields\n"
116                "  -a --all               Show all fields, including long and unprintable\n"
117                "  -q --quiet             Don't show privilege warning\n"
118                "     --no-pager          Do not pipe output into a pager\n"
119                "  -m --merge             Show entries from all available journals\n"
120                "  -D --directory=PATH    Show journal files from directory\n"
121 #ifdef HAVE_GCRYPT
122                "     --interval=TIME     Time interval for changing the FSS sealing key\n"
123                "     --verify-key=KEY    Specify FSS verification key\n"
124 #endif
125                "\nCommands:\n"
126                "  -h --help              Show this help\n"
127                "     --version           Show package version\n"
128                "     --new-id128         Generate a new 128 Bit ID\n"
129                "     --header            Show journal header information\n"
130                "     --disk-usage        Show total disk usage\n"
131                "  -F --field=FIELD       List all values a certain field takes\n"
132                "     --list-catalog      Show message IDs of all entries in the message catalog\n"
133                "     --update-catalog    Update the message catalog database\n"
134 #ifdef HAVE_GCRYPT
135                "     --setup-keys        Generate new FSS key pair\n"
136                "     --verify            Verify journal file consistency\n"
137 #endif
138                , program_invocation_short_name);
139
140         return 0;
141 }
142
143 static int parse_argv(int argc, char *argv[]) {
144
145         enum {
146                 ARG_VERSION = 0x100,
147                 ARG_NO_PAGER,
148                 ARG_NO_TAIL,
149                 ARG_NEW_ID128,
150                 ARG_HEADER,
151                 ARG_FULL,
152                 ARG_SETUP_KEYS,
153                 ARG_INTERVAL,
154                 ARG_VERIFY,
155                 ARG_VERIFY_KEY,
156                 ARG_DISK_USAGE,
157                 ARG_SINCE,
158                 ARG_UNTIL,
159                 ARG_USER_UNIT,
160                 ARG_LIST_CATALOG,
161                 ARG_UPDATE_CATALOG
162         };
163
164         static const struct option options[] = {
165                 { "help",         no_argument,       NULL, 'h'              },
166                 { "version" ,     no_argument,       NULL, ARG_VERSION      },
167                 { "no-pager",     no_argument,       NULL, ARG_NO_PAGER     },
168                 { "pager-end",    no_argument,       NULL, 'e'              },
169                 { "follow",       no_argument,       NULL, 'f'              },
170                 { "output",       required_argument, NULL, 'o'              },
171                 { "all",          no_argument,       NULL, 'a'              },
172                 { "full",         no_argument,       NULL, ARG_FULL         },
173                 { "lines",        optional_argument, NULL, 'n'              },
174                 { "no-tail",      no_argument,       NULL, ARG_NO_TAIL      },
175                 { "new-id128",    no_argument,       NULL, ARG_NEW_ID128    },
176                 { "quiet",        no_argument,       NULL, 'q'              },
177                 { "merge",        no_argument,       NULL, 'm'              },
178                 { "this-boot",    no_argument,       NULL, 'b'              },
179                 { "directory",    required_argument, NULL, 'D'              },
180                 { "header",       no_argument,       NULL, ARG_HEADER       },
181                 { "priority",     required_argument, NULL, 'p'              },
182                 { "setup-keys",   no_argument,       NULL, ARG_SETUP_KEYS   },
183                 { "interval",     required_argument, NULL, ARG_INTERVAL     },
184                 { "verify",       no_argument,       NULL, ARG_VERIFY       },
185                 { "verify-key",   required_argument, NULL, ARG_VERIFY_KEY   },
186                 { "disk-usage",   no_argument,       NULL, ARG_DISK_USAGE   },
187                 { "cursor",       required_argument, NULL, 'c'              },
188                 { "since",        required_argument, NULL, ARG_SINCE        },
189                 { "until",        required_argument, NULL, ARG_UNTIL        },
190                 { "user-unit",    required_argument, NULL, ARG_USER_UNIT    },
191                 { "unit",         required_argument, NULL, 'u'              },
192                 { "field",        required_argument, NULL, 'F'              },
193                 { "catalog",      no_argument,       NULL, 'x'              },
194                 { "list-catalog", no_argument,       NULL, ARG_LIST_CATALOG },
195                 { "update-catalog",no_argument,      NULL, ARG_UPDATE_CATALOG },
196                 { "reverse",      no_argument,       NULL, 'r'              },
197                 { NULL,           0,                 NULL, 0                }
198         };
199
200         int c, r;
201
202         assert(argc >= 0);
203         assert(argv);
204
205         while ((c = getopt_long(argc, argv, "hefo:an::qmbD:p:c:u:F:xr", options, NULL)) >= 0) {
206
207                 switch (c) {
208
209                 case 'h':
210                         help();
211                         return 0;
212
213                 case ARG_VERSION:
214                         puts(PACKAGE_STRING);
215                         puts(SYSTEMD_FEATURES);
216                         return 0;
217
218                 case ARG_NO_PAGER:
219                         arg_no_pager = true;
220                         break;
221
222                 case 'e':
223                         arg_pager_end = true;
224
225                         if (arg_lines < 0)
226                                 arg_lines = 1000;
227
228                         break;
229
230                 case 'f':
231                         arg_follow = true;
232                         break;
233
234                 case 'o':
235                         arg_output = output_mode_from_string(optarg);
236                         if (arg_output < 0) {
237                                 log_error("Unknown output format '%s'.", optarg);
238                                 return -EINVAL;
239                         }
240
241                         if (arg_output == OUTPUT_EXPORT ||
242                             arg_output == OUTPUT_JSON ||
243                             arg_output == OUTPUT_JSON_PRETTY ||
244                             arg_output == OUTPUT_JSON_SSE ||
245                             arg_output == OUTPUT_CAT)
246                                 arg_quiet = true;
247
248                         break;
249
250                 case ARG_FULL:
251                         arg_full = true;
252                         break;
253
254                 case 'a':
255                         arg_all = true;
256                         break;
257
258                 case 'n':
259                         if (optarg) {
260                                 r = safe_atoi(optarg, &arg_lines);
261                                 if (r < 0 || arg_lines < 0) {
262                                         log_error("Failed to parse lines '%s'", optarg);
263                                         return -EINVAL;
264                                 }
265                         } else {
266                                 int n;
267
268                                 /* Hmm, no argument? Maybe the next
269                                  * word on the command line is
270                                  * supposed to be the argument? Let's
271                                  * see if there is one, and is
272                                  * parsable as a positive
273                                  * integer... */
274
275                                 if (optind < argc &&
276                                     safe_atoi(argv[optind], &n) >= 0 &&
277                                     n >= 0) {
278
279                                         arg_lines = n;
280                                         optind++;
281                                 } else
282                                         arg_lines = 10;
283                         }
284
285                         break;
286
287                 case ARG_NO_TAIL:
288                         arg_no_tail = true;
289                         break;
290
291                 case ARG_NEW_ID128:
292                         arg_action = ACTION_NEW_ID128;
293                         break;
294
295                 case 'q':
296                         arg_quiet = true;
297                         break;
298
299                 case 'm':
300                         arg_merge = true;
301                         break;
302
303                 case 'b':
304                         arg_this_boot = true;
305                         break;
306
307                 case 'D':
308                         arg_directory = optarg;
309                         break;
310
311                 case 'c':
312                         arg_cursor = optarg;
313                         break;
314
315                 case ARG_HEADER:
316                         arg_action = ACTION_PRINT_HEADER;
317                         break;
318
319                 case ARG_VERIFY:
320                         arg_action = ACTION_VERIFY;
321                         break;
322
323                 case ARG_DISK_USAGE:
324                         arg_action = ACTION_DISK_USAGE;
325                         break;
326
327 #ifdef HAVE_GCRYPT
328                 case ARG_SETUP_KEYS:
329                         arg_action = ACTION_SETUP_KEYS;
330                         break;
331
332
333                 case ARG_VERIFY_KEY:
334                         arg_action = ACTION_VERIFY;
335                         arg_verify_key = optarg;
336                         arg_merge = false;
337                         break;
338
339                 case ARG_INTERVAL:
340                         r = parse_usec(optarg, &arg_interval);
341                         if (r < 0 || arg_interval <= 0) {
342                                 log_error("Failed to parse sealing key change interval: %s", optarg);
343                                 return -EINVAL;
344                         }
345                         break;
346 #else
347                 case ARG_SETUP_KEYS:
348                 case ARG_VERIFY_KEY:
349                 case ARG_INTERVAL:
350                         log_error("Forward-secure sealing not available.");
351                         return -ENOTSUP;
352 #endif
353
354                 case 'p': {
355                         const char *dots;
356
357                         dots = strstr(optarg, "..");
358                         if (dots) {
359                                 char *a;
360                                 int from, to, i;
361
362                                 /* a range */
363                                 a = strndup(optarg, dots - optarg);
364                                 if (!a)
365                                         return log_oom();
366
367                                 from = log_level_from_string(a);
368                                 to = log_level_from_string(dots + 2);
369                                 free(a);
370
371                                 if (from < 0 || to < 0) {
372                                         log_error("Failed to parse log level range %s", optarg);
373                                         return -EINVAL;
374                                 }
375
376                                 arg_priorities = 0;
377
378                                 if (from < to) {
379                                         for (i = from; i <= to; i++)
380                                                 arg_priorities |= 1 << i;
381                                 } else {
382                                         for (i = to; i <= from; i++)
383                                                 arg_priorities |= 1 << i;
384                                 }
385
386                         } else {
387                                 int p, i;
388
389                                 p = log_level_from_string(optarg);
390                                 if (p < 0) {
391                                         log_error("Unknown log level %s", optarg);
392                                         return -EINVAL;
393                                 }
394
395                                 arg_priorities = 0;
396
397                                 for (i = 0; i <= p; i++)
398                                         arg_priorities |= 1 << i;
399                         }
400
401                         break;
402                 }
403
404                 case ARG_SINCE:
405                         r = parse_timestamp(optarg, &arg_since);
406                         if (r < 0) {
407                                 log_error("Failed to parse timestamp: %s", optarg);
408                                 return -EINVAL;
409                         }
410                         arg_since_set = true;
411                         break;
412
413                 case ARG_UNTIL:
414                         r = parse_timestamp(optarg, &arg_until);
415                         if (r < 0) {
416                                 log_error("Failed to parse timestamp: %s", optarg);
417                                 return -EINVAL;
418                         }
419                         arg_until_set = true;
420                         break;
421
422                 case ARG_USER_UNIT:
423                         arg_unit = optarg;
424                         arg_unit_type = "_SYSTEMD_USER_UNIT=";
425                         break;
426
427                 case 'u':
428                         arg_unit = optarg;
429                         arg_unit_type = "_SYSTEMD_UNIT=";
430                         break;
431
432                 case '?':
433                         return -EINVAL;
434
435                 case 'F':
436                         arg_field = optarg;
437                         break;
438
439                 case 'x':
440                         arg_catalog = true;
441                         break;
442
443                 case ARG_LIST_CATALOG:
444                         arg_action = ACTION_LIST_CATALOG;
445                         break;
446
447                 case ARG_UPDATE_CATALOG:
448                         arg_action = ACTION_UPDATE_CATALOG;
449                         break;
450
451                 case 'r':
452                         arg_reverse = true;
453                         break;
454
455                 default:
456                         log_error("Unknown option code %c", c);
457                         return -EINVAL;
458                 }
459         }
460
461         if (arg_follow && !arg_no_tail && arg_lines < 0)
462                 arg_lines = 10;
463
464         if (arg_since_set && arg_until_set && arg_since > arg_until) {
465                 log_error("--since= must be before --until=.");
466                 return -EINVAL;
467         }
468
469         if (arg_cursor && arg_since_set) {
470                 log_error("Please specify either --since= or --cursor=, not both.");
471                 return -EINVAL;
472         }
473
474         if (arg_follow && arg_reverse) {
475                 log_error("Please specify either --reverse= or --follow=, not both.");
476                 return -EINVAL;
477         }
478
479         return 1;
480 }
481
482 static int generate_new_id128(void) {
483         sd_id128_t id;
484         int r;
485         unsigned i;
486
487         r = sd_id128_randomize(&id);
488         if (r < 0) {
489                 log_error("Failed to generate ID: %s", strerror(-r));
490                 return r;
491         }
492
493         printf("As string:\n"
494                SD_ID128_FORMAT_STR "\n\n"
495                "As UUID:\n"
496                "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n\n"
497                "As macro:\n"
498                "#define MESSAGE_XYZ SD_ID128_MAKE(",
499                SD_ID128_FORMAT_VAL(id),
500                SD_ID128_FORMAT_VAL(id));
501         for (i = 0; i < 16; i++)
502                 printf("%02x%s", id.bytes[i], i != 15 ? "," : "");
503         fputs(")\n\n", stdout);
504
505         printf("As Python constant:\n"
506                ">>> import uuid\n"
507                ">>> MESSAGE_XYZ = uuid.UUID('" SD_ID128_FORMAT_STR "')\n",
508                SD_ID128_FORMAT_VAL(id));
509
510         return 0;
511 }
512
513 static int add_matches(sd_journal *j, char **args) {
514         char **i;
515         int r;
516
517         assert(j);
518
519         STRV_FOREACH(i, args) {
520
521                 if (streq(*i, "+"))
522                         r = sd_journal_add_disjunction(j);
523                 else if (path_is_absolute(*i)) {
524                         char *p, *t = NULL;
525                         const char *path;
526                         struct stat st;
527
528                         p = canonicalize_file_name(*i);
529                         path = p ? p : *i;
530
531                         if (stat(path, &st) < 0)  {
532                                 free(p);
533                                 log_error("Couldn't stat file: %m");
534                                 return -errno;
535                         }
536
537                         if (S_ISREG(st.st_mode) && (0111 & st.st_mode))
538                                 t = strappend("_EXE=", path);
539                         else if (S_ISCHR(st.st_mode))
540                                 asprintf(&t, "_KERNEL_DEVICE=c%u:%u", major(st.st_rdev), minor(st.st_rdev));
541                         else if (S_ISBLK(st.st_mode))
542                                 asprintf(&t, "_KERNEL_DEVICE=b%u:%u", major(st.st_rdev), minor(st.st_rdev));
543                         else {
544                                 free(p);
545                                 log_error("File is not a device node, regular file or is not executable: %s", *i);
546                                 return -EINVAL;
547                         }
548
549                         free(p);
550
551                         if (!t)
552                                 return log_oom();
553
554                         r = sd_journal_add_match(j, t, 0);
555                         free(t);
556                 } else
557                         r = sd_journal_add_match(j, *i, 0);
558
559                 if (r < 0) {
560                         log_error("Failed to add match '%s': %s", *i, strerror(-r));
561                         return r;
562                 }
563         }
564
565         return 0;
566 }
567
568 static int add_this_boot(sd_journal *j) {
569         char match[9+32+1] = "_BOOT_ID=";
570         sd_id128_t boot_id;
571         int r;
572
573         assert(j);
574
575         if (!arg_this_boot)
576                 return 0;
577
578         r = sd_id128_get_boot(&boot_id);
579         if (r < 0) {
580                 log_error("Failed to get boot id: %s", strerror(-r));
581                 return r;
582         }
583
584         sd_id128_to_string(boot_id, match + 9);
585         r = sd_journal_add_match(j, match, strlen(match));
586         if (r < 0) {
587                 log_error("Failed to add match: %s", strerror(-r));
588                 return r;
589         }
590
591         return 0;
592 }
593
594 static int add_unit(sd_journal *j) {
595         _cleanup_free_ char *m = NULL, *u = NULL;
596         int r;
597
598         assert(j);
599
600         if (isempty(arg_unit))
601                 return 0;
602
603         u = unit_name_mangle(arg_unit);
604         if (!u)
605                 return log_oom();
606
607         m = strappend(arg_unit_type, u);
608
609         if (!m)
610                 return log_oom();
611
612         r = sd_journal_add_match(j, m, strlen(m));
613         if (r < 0) {
614                 log_error("Failed to add match: %s", strerror(-r));
615                 return r;
616         }
617
618         return 0;
619 }
620
621 static int add_priorities(sd_journal *j) {
622         char match[] = "PRIORITY=0";
623         int i, r;
624
625         assert(j);
626
627         if (arg_priorities == 0xFF)
628                 return 0;
629
630         for (i = LOG_EMERG; i <= LOG_DEBUG; i++)
631                 if (arg_priorities & (1 << i)) {
632                         match[sizeof(match)-2] = '0' + i;
633
634                         r = sd_journal_add_match(j, match, strlen(match));
635                         if (r < 0) {
636                                 log_error("Failed to add match: %s", strerror(-r));
637                                 return r;
638                         }
639                 }
640
641         return 0;
642 }
643
644 static int setup_keys(void) {
645 #ifdef HAVE_GCRYPT
646         size_t mpk_size, seed_size, state_size, i;
647         uint8_t *mpk, *seed, *state;
648         ssize_t l;
649         int fd = -1, r, attr = 0;
650         sd_id128_t machine, boot;
651         char *p = NULL, *k = NULL;
652         struct FSSHeader h;
653         uint64_t n;
654
655         r = sd_id128_get_machine(&machine);
656         if (r < 0) {
657                 log_error("Failed to get machine ID: %s", strerror(-r));
658                 return r;
659         }
660
661         r = sd_id128_get_boot(&boot);
662         if (r < 0) {
663                 log_error("Failed to get boot ID: %s", strerror(-r));
664                 return r;
665         }
666
667         if (asprintf(&p, "/var/log/journal/" SD_ID128_FORMAT_STR "/fss",
668                      SD_ID128_FORMAT_VAL(machine)) < 0)
669                 return log_oom();
670
671         if (access(p, F_OK) >= 0) {
672                 log_error("Sealing key file %s exists already.", p);
673                 r = -EEXIST;
674                 goto finish;
675         }
676
677         if (asprintf(&k, "/var/log/journal/" SD_ID128_FORMAT_STR "/fss.tmp.XXXXXX",
678                      SD_ID128_FORMAT_VAL(machine)) < 0) {
679                 r = log_oom();
680                 goto finish;
681         }
682
683         mpk_size = FSPRG_mskinbytes(FSPRG_RECOMMENDED_SECPAR);
684         mpk = alloca(mpk_size);
685
686         seed_size = FSPRG_RECOMMENDED_SEEDLEN;
687         seed = alloca(seed_size);
688
689         state_size = FSPRG_stateinbytes(FSPRG_RECOMMENDED_SECPAR);
690         state = alloca(state_size);
691
692         fd = open("/dev/random", O_RDONLY|O_CLOEXEC|O_NOCTTY);
693         if (fd < 0) {
694                 log_error("Failed to open /dev/random: %m");
695                 r = -errno;
696                 goto finish;
697         }
698
699         log_info("Generating seed...");
700         l = loop_read(fd, seed, seed_size, true);
701         if (l < 0 || (size_t) l != seed_size) {
702                 log_error("Failed to read random seed: %s", strerror(EIO));
703                 r = -EIO;
704                 goto finish;
705         }
706
707         log_info("Generating key pair...");
708         FSPRG_GenMK(NULL, mpk, seed, seed_size, FSPRG_RECOMMENDED_SECPAR);
709
710         log_info("Generating sealing key...");
711         FSPRG_GenState0(state, mpk, seed, seed_size);
712
713         assert(arg_interval > 0);
714
715         n = now(CLOCK_REALTIME);
716         n /= arg_interval;
717
718         close_nointr_nofail(fd);
719         fd = mkostemp(k, O_WRONLY|O_CLOEXEC|O_NOCTTY);
720         if (fd < 0) {
721                 log_error("Failed to open %s: %m", k);
722                 r = -errno;
723                 goto finish;
724         }
725
726         /* Enable secure remove, exclusion from dump, synchronous
727          * writing and in-place updating */
728         if (ioctl(fd, FS_IOC_GETFLAGS, &attr) < 0)
729                 log_warning("FS_IOC_GETFLAGS failed: %m");
730
731         attr |= FS_SECRM_FL|FS_NODUMP_FL|FS_SYNC_FL|FS_NOCOW_FL;
732
733         if (ioctl(fd, FS_IOC_SETFLAGS, &attr) < 0)
734                 log_warning("FS_IOC_SETFLAGS failed: %m");
735
736         zero(h);
737         memcpy(h.signature, "KSHHRHLP", 8);
738         h.machine_id = machine;
739         h.boot_id = boot;
740         h.header_size = htole64(sizeof(h));
741         h.start_usec = htole64(n * arg_interval);
742         h.interval_usec = htole64(arg_interval);
743         h.fsprg_secpar = htole16(FSPRG_RECOMMENDED_SECPAR);
744         h.fsprg_state_size = htole64(state_size);
745
746         l = loop_write(fd, &h, sizeof(h), false);
747         if (l < 0 || (size_t) l != sizeof(h)) {
748                 log_error("Failed to write header: %s", strerror(EIO));
749                 r = -EIO;
750                 goto finish;
751         }
752
753         l = loop_write(fd, state, state_size, false);
754         if (l < 0 || (size_t) l != state_size) {
755                 log_error("Failed to write state: %s", strerror(EIO));
756                 r = -EIO;
757                 goto finish;
758         }
759
760         if (link(k, p) < 0) {
761                 log_error("Failed to link file: %m");
762                 r = -errno;
763                 goto finish;
764         }
765
766         if (on_tty()) {
767                 fprintf(stderr,
768                         "\n"
769                         "The new key pair has been generated. The " ANSI_HIGHLIGHT_ON "secret sealing key" ANSI_HIGHLIGHT_OFF " has been written to\n"
770                         "the following local file. This key file is automatically updated when the\n"
771                         "sealing key is advanced. It should not be used on multiple hosts.\n"
772                         "\n"
773                         "\t%s\n"
774                         "\n"
775                         "Please write down the following " ANSI_HIGHLIGHT_ON "secret verification key" ANSI_HIGHLIGHT_OFF ". It should be stored\n"
776                         "at a safe location and should not be saved locally on disk.\n"
777                         "\n\t" ANSI_HIGHLIGHT_RED_ON, p);
778                 fflush(stderr);
779         }
780         for (i = 0; i < seed_size; i++) {
781                 if (i > 0 && i % 3 == 0)
782                         putchar('-');
783                 printf("%02x", ((uint8_t*) seed)[i]);
784         }
785
786         printf("/%llx-%llx\n", (unsigned long long) n, (unsigned long long) arg_interval);
787
788         if (on_tty()) {
789                 char tsb[FORMAT_TIMESPAN_MAX], *hn;
790
791                 fprintf(stderr,
792                         ANSI_HIGHLIGHT_OFF "\n"
793                         "The sealing key is automatically changed every %s.\n",
794                         format_timespan(tsb, sizeof(tsb), arg_interval));
795
796                 hn = gethostname_malloc();
797
798                 if (hn) {
799                         hostname_cleanup(hn);
800                         fprintf(stderr, "\nThe keys have been generated for host %s/" SD_ID128_FORMAT_STR ".\n", hn, SD_ID128_FORMAT_VAL(machine));
801                 } else
802                         fprintf(stderr, "\nThe keys have been generated for host " SD_ID128_FORMAT_STR ".\n", SD_ID128_FORMAT_VAL(machine));
803
804 #ifdef HAVE_QRENCODE
805                 /* If this is not an UTF-8 system don't print any QR codes */
806                 if (is_locale_utf8()) {
807                         fputs("\nTo transfer the verification key to your phone please scan the QR code below:\n\n", stderr);
808                         print_qr_code(stderr, seed, seed_size, n, arg_interval, hn, machine);
809                 }
810 #endif
811                 free(hn);
812         }
813
814         r = 0;
815
816 finish:
817         if (fd >= 0)
818                 close_nointr_nofail(fd);
819
820         if (k) {
821                 unlink(k);
822                 free(k);
823         }
824
825         free(p);
826
827         return r;
828 #else
829         log_error("Forward-secure sealing not available.");
830         return -ENOTSUP;
831 #endif
832 }
833
834 static int verify(sd_journal *j) {
835         int r = 0;
836         Iterator i;
837         JournalFile *f;
838
839         assert(j);
840
841         log_show_color(true);
842
843         HASHMAP_FOREACH(f, j->files, i) {
844                 int k;
845                 usec_t first, validated, last;
846
847 #ifdef HAVE_GCRYPT
848                 if (!arg_verify_key && JOURNAL_HEADER_SEALED(f->header))
849                         log_notice("Journal file %s has sealing enabled but verification key has not been passed using --verify-key=.", f->path);
850 #endif
851
852                 k = journal_file_verify(f, arg_verify_key, &first, &validated, &last, true);
853                 if (k == -EINVAL) {
854                         /* If the key was invalid give up right-away. */
855                         return k;
856                 } else if (k < 0) {
857                         log_warning("FAIL: %s (%s)", f->path, strerror(-k));
858                         r = k;
859                 } else {
860                         char a[FORMAT_TIMESTAMP_MAX], b[FORMAT_TIMESTAMP_MAX], c[FORMAT_TIMESPAN_MAX];
861                         log_info("PASS: %s", f->path);
862
863                         if (arg_verify_key && JOURNAL_HEADER_SEALED(f->header)) {
864                                 if (validated > 0) {
865                                         log_info("=> Validated from %s to %s, final %s entries not sealed.",
866                                                  format_timestamp(a, sizeof(a), first),
867                                                  format_timestamp(b, sizeof(b), validated),
868                                                  format_timespan(c, sizeof(c), last > validated ? last - validated : 0));
869                                 } else if (last > 0)
870                                         log_info("=> No sealing yet, %s of entries not sealed.",
871                                                  format_timespan(c, sizeof(c), last - first));
872                                 else
873                                         log_info("=> No sealing yet, no entries in file.");
874                         }
875                 }
876         }
877
878         return r;
879 }
880
881 static int access_check(void) {
882
883 #ifdef HAVE_ACL
884         if (access("/var/log/journal", F_OK) < 0 && geteuid() != 0 && in_group("systemd-journal") <= 0) {
885                 log_error("Unprivileged users can't see messages unless persistent log storage is enabled. Users in the group 'systemd-journal' can always see messages.");
886                 return -EACCES;
887         }
888
889         if (!arg_quiet && geteuid() != 0 && in_group("systemd-journal") <= 0)
890                 log_warning("Showing user generated messages only. Users in the group 'systemd-journal' can see all messages. Pass -q to turn this notice off.");
891 #else
892         if (geteuid() != 0 && in_group("systemd-journal") <= 0) {
893                 log_error("No access to messages. Only users in the group 'systemd-journal' can see messages.");
894                 return -EACCES;
895         }
896 #endif
897
898         return 0;
899 }
900
901 int main(int argc, char *argv[]) {
902         int r;
903         sd_journal *j = NULL;
904         bool need_seek = false;
905         sd_id128_t previous_boot_id;
906         bool previous_boot_id_valid = false, first_line = true;
907         int n_shown = 0;
908
909         setlocale(LC_ALL, "");
910         log_parse_environment();
911         log_open();
912
913         r = parse_argv(argc, argv);
914         if (r <= 0)
915                 goto finish;
916
917         signal(SIGWINCH, columns_lines_cache_reset);
918
919         if (arg_action == ACTION_NEW_ID128) {
920                 r = generate_new_id128();
921                 goto finish;
922         }
923
924         if (arg_action == ACTION_SETUP_KEYS) {
925                 r = setup_keys();
926                 goto finish;
927         }
928
929         if (arg_action == ACTION_LIST_CATALOG)  {
930                 r = catalog_list(stdout);
931                 if (r < 0)
932                         log_error("Failed to list catalog: %s", strerror(-r));
933                 goto finish;
934         }
935
936         if (arg_action == ACTION_UPDATE_CATALOG)  {
937                 r = catalog_update();
938                 goto finish;
939         }
940
941         r = access_check();
942         if (r < 0)
943                 goto finish;
944
945         if (arg_directory)
946                 r = sd_journal_open_directory(&j, arg_directory, 0);
947         else
948                 r = sd_journal_open(&j, arg_merge ? 0 : SD_JOURNAL_LOCAL_ONLY);
949         if (r < 0) {
950                 log_error("Failed to open journal: %s", strerror(-r));
951                 goto finish;
952         }
953
954         if (arg_action == ACTION_VERIFY) {
955                 r = verify(j);
956                 goto finish;
957         }
958
959         if (arg_action == ACTION_PRINT_HEADER) {
960                 journal_print_header(j);
961                 r = 0;
962                 goto finish;
963         }
964
965         if (arg_action == ACTION_DISK_USAGE) {
966                 uint64_t bytes;
967                 char sbytes[FORMAT_BYTES_MAX];
968
969                 r = sd_journal_get_usage(j, &bytes);
970                 if (r < 0)
971                         goto finish;
972
973                 printf("Journals take up %s on disk.\n", format_bytes(sbytes, sizeof(sbytes), bytes));
974                 r = 0;
975                 goto finish;
976         }
977
978         r = add_this_boot(j);
979         if (r < 0)
980                 goto finish;
981
982         r = add_unit(j);
983         if (r < 0)
984                 goto finish;
985
986         r = add_matches(j, argv + optind);
987         if (r < 0)
988                 goto finish;
989
990         r = add_priorities(j);
991         if (r < 0)
992                 goto finish;
993
994         /* Opening the fd now means the first sd_journal_wait() will actually wait */
995         r = sd_journal_get_fd(j);
996         if (r < 0)
997                 goto finish;
998
999         if (arg_field) {
1000                 const void *data;
1001                 size_t size;
1002
1003                 r = sd_journal_query_unique(j, arg_field);
1004                 if (r < 0) {
1005                         log_error("Failed to query unique data objects: %s", strerror(-r));
1006                         goto finish;
1007                 }
1008
1009                 SD_JOURNAL_FOREACH_UNIQUE(j, data, size) {
1010                         const void *eq;
1011
1012                         if (arg_lines >= 0 && n_shown >= arg_lines)
1013                                 break;
1014
1015                         eq = memchr(data, '=', size);
1016                         if (eq)
1017                                 printf("%.*s\n", (int) (size - ((const uint8_t*) eq - (const uint8_t*) data + 1)), (const char*) eq + 1);
1018                         else
1019                                 printf("%.*s\n", (int) size, (const char*) data);
1020
1021                         n_shown ++;
1022                 }
1023
1024                 r = 0;
1025                 goto finish;
1026         }
1027
1028         if (arg_cursor) {
1029                 r = sd_journal_seek_cursor(j, arg_cursor);
1030                 if (r < 0) {
1031                         log_error("Failed to seek to cursor: %s", strerror(-r));
1032                         goto finish;
1033                 }
1034                 if (!arg_reverse)
1035                         r = sd_journal_next(j);
1036                 else
1037                         r = sd_journal_previous(j);
1038
1039         } else if (arg_since_set && !arg_reverse) {
1040                 r = sd_journal_seek_realtime_usec(j, arg_since);
1041                 if (r < 0) {
1042                         log_error("Failed to seek to date: %s", strerror(-r));
1043                         goto finish;
1044                 }
1045                 r = sd_journal_next(j);
1046
1047         } else if (arg_until_set && arg_reverse) {
1048                 r = sd_journal_seek_realtime_usec(j, arg_until);
1049                 if (r < 0) {
1050                         log_error("Failed to seek to date: %s", strerror(-r));
1051                         goto finish;
1052                 }
1053                 r = sd_journal_previous(j);
1054
1055         } else if (arg_lines >= 0) {
1056                 r = sd_journal_seek_tail(j);
1057                 if (r < 0) {
1058                         log_error("Failed to seek to tail: %s", strerror(-r));
1059                         goto finish;
1060                 }
1061
1062                 r = sd_journal_previous_skip(j, arg_lines);
1063
1064         } else if (arg_reverse) {
1065                 r = sd_journal_seek_tail(j);
1066                 if (r < 0) {
1067                         log_error("Failed to seek to tail: %s", strerror(-r));
1068                         goto finish;
1069                 }
1070
1071                 r = sd_journal_previous(j);
1072
1073         } else {
1074                 r = sd_journal_seek_head(j);
1075                 if (r < 0) {
1076                         log_error("Failed to seek to head: %s", strerror(-r));
1077                         goto finish;
1078                 }
1079
1080                 r = sd_journal_next(j);
1081         }
1082
1083         if (r < 0) {
1084                 log_error("Failed to iterate through journal: %s", strerror(-r));
1085                 goto finish;
1086         }
1087
1088         if (!arg_no_pager && !arg_follow)
1089                 pager_open(arg_pager_end);
1090
1091         if (!arg_quiet) {
1092                 usec_t start, end;
1093                 char start_buf[FORMAT_TIMESTAMP_MAX], end_buf[FORMAT_TIMESTAMP_MAX];
1094
1095                 r = sd_journal_get_cutoff_realtime_usec(j, &start, &end);
1096                 if (r < 0) {
1097                         log_error("Failed to get cutoff: %s", strerror(-r));
1098                         goto finish;
1099                 }
1100
1101                 if (r > 0) {
1102                         if (arg_follow)
1103                                 printf("-- Logs begin at %s. --\n",
1104                                        format_timestamp(start_buf, sizeof(start_buf), start));
1105                         else
1106                                 printf("-- Logs begin at %s, end at %s. --\n",
1107                                        format_timestamp(start_buf, sizeof(start_buf), start),
1108                                        format_timestamp(end_buf, sizeof(end_buf), end));
1109                 }
1110         }
1111
1112         for (;;) {
1113                 while (arg_lines < 0 || n_shown < arg_lines || (arg_follow && !first_line)) {
1114                         int flags;
1115
1116                         if (need_seek) {
1117                                 if (!arg_reverse)
1118                                         r = sd_journal_next(j);
1119                                 else
1120                                         r = sd_journal_previous(j);
1121                                 if (r < 0) {
1122                                         log_error("Failed to iterate through journal: %s", strerror(-r));
1123                                         goto finish;
1124                                 }
1125                         }
1126
1127                         if (r == 0)
1128                                 break;
1129
1130                         if (arg_until_set && !arg_reverse) {
1131                                 usec_t usec;
1132
1133                                 r = sd_journal_get_realtime_usec(j, &usec);
1134                                 if (r < 0) {
1135                                         log_error("Failed to determine timestamp: %s", strerror(-r));
1136                                         goto finish;
1137                                 }
1138                                 if (usec > arg_until)
1139                                         goto finish;
1140                         }
1141
1142                         if (arg_since_set && arg_reverse) {
1143                                 usec_t usec;
1144
1145                                 r = sd_journal_get_realtime_usec(j, &usec);
1146                                 if (r < 0) {
1147                                         log_error("Failed to determine timestamp: %s", strerror(-r));
1148                                         goto finish;
1149                                 }
1150                                 if (usec < arg_since)
1151                                         goto finish;
1152                         }
1153
1154                         if (!arg_merge) {
1155                                 sd_id128_t boot_id;
1156
1157                                 r = sd_journal_get_monotonic_usec(j, NULL, &boot_id);
1158                                 if (r >= 0) {
1159                                         if (previous_boot_id_valid &&
1160                                             !sd_id128_equal(boot_id, previous_boot_id))
1161                                                 printf(ANSI_HIGHLIGHT_ON "-- Reboot --" ANSI_HIGHLIGHT_OFF "\n");
1162
1163                                         previous_boot_id = boot_id;
1164                                         previous_boot_id_valid = true;
1165                                 }
1166                         }
1167
1168                         flags =
1169                                 arg_all * OUTPUT_SHOW_ALL |
1170                                 (arg_full || !on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
1171                                 on_tty() * OUTPUT_COLOR |
1172                                 arg_catalog * OUTPUT_CATALOG;
1173
1174                         r = output_journal(stdout, j, arg_output, 0, flags);
1175                         if (r < 0 || ferror(stdout))
1176                                 goto finish;
1177
1178                         need_seek = true;
1179                         n_shown++;
1180                 }
1181
1182                 if (!arg_follow)
1183                         break;
1184
1185                 r = sd_journal_wait(j, (uint64_t) -1);
1186                 if (r < 0) {
1187                         log_error("Couldn't wait for journal event: %s", strerror(-r));
1188                         goto finish;
1189                 }
1190
1191                 first_line = false;
1192         }
1193
1194 finish:
1195         if (j)
1196                 sd_journal_close(j);
1197
1198         pager_close();
1199
1200         return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
1201 }