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