+ fputs(")\n\n", stdout);
+
+ printf("As Python constant:\n"
+ ">>> import uuid\n"
+ ">>> MESSAGE_XYZ = uuid.UUID('" SD_ID128_FORMAT_STR "')\n",
+ SD_ID128_FORMAT_VAL(id));
+
+ return 0;
+}
+
+static int add_matches(sd_journal *j, char **args) {
+ char **i;
+
+ assert(j);
+
+ STRV_FOREACH(i, args) {
+ int r;
+
+ if (streq(*i, "+"))
+ r = sd_journal_add_disjunction(j);
+ else if (path_is_absolute(*i)) {
+ char _cleanup_free_ *p, *t = NULL;
+ const char *path;
+ struct stat st;
+
+ p = canonicalize_file_name(*i);
+ path = p ? p : *i;
+
+ if (stat(path, &st) < 0) {
+ log_error("Couldn't stat file: %m");
+ return -errno;
+ }
+
+ if (S_ISREG(st.st_mode) && (0111 & st.st_mode))
+ t = strappend("_EXE=", path);
+ else if (S_ISCHR(st.st_mode))
+ asprintf(&t, "_KERNEL_DEVICE=c%u:%u", major(st.st_rdev), minor(st.st_rdev));
+ else if (S_ISBLK(st.st_mode))
+ asprintf(&t, "_KERNEL_DEVICE=b%u:%u", major(st.st_rdev), minor(st.st_rdev));
+ else {
+ log_error("File is not a device node, regular file or is not executable: %s", *i);
+ return -EINVAL;
+ }
+
+ if (!t)
+ return log_oom();
+
+ r = sd_journal_add_match(j, t, 0);
+ } else
+ r = sd_journal_add_match(j, *i, 0);
+
+ if (r < 0) {
+ log_error("Failed to add match '%s': %s", *i, strerror(-r));
+ return r;
+ }
+ }
+
+ return 0;
+}
+
+static int add_this_boot(sd_journal *j) {
+ char match[9+32+1] = "_BOOT_ID=";
+ sd_id128_t boot_id;
+ int r;
+
+ assert(j);
+
+ if (!arg_this_boot)
+ return 0;
+
+ r = sd_id128_get_boot(&boot_id);
+ if (r < 0) {
+ log_error("Failed to get boot id: %s", strerror(-r));
+ return r;
+ }
+
+ sd_id128_to_string(boot_id, match + 9);
+ r = sd_journal_add_match(j, match, strlen(match));
+ if (r < 0) {
+ log_error("Failed to add match: %s", strerror(-r));
+ return r;
+ }
+
+ return 0;
+}
+
+static int add_unit(sd_journal *j) {
+ _cleanup_free_ char *m = NULL, *u = NULL;
+ int r;
+
+ assert(j);
+
+ if (isempty(arg_unit))
+ return 0;
+
+ u = unit_name_mangle(arg_unit);
+ if (!u)
+ return log_oom();
+
+ if (arg_unit_system)
+ r = add_matches_for_unit(j, u);
+ else
+ r = add_matches_for_user_unit(j, u, getuid());
+ if (r < 0)
+ return r;
+
+ return 0;
+}
+
+static int add_priorities(sd_journal *j) {
+ char match[] = "PRIORITY=0";
+ int i, r;
+
+ assert(j);
+
+ if (arg_priorities == 0xFF)
+ return 0;
+
+ for (i = LOG_EMERG; i <= LOG_DEBUG; i++)
+ if (arg_priorities & (1 << i)) {
+ match[sizeof(match)-2] = '0' + i;
+
+ r = sd_journal_add_match(j, match, strlen(match));
+ if (r < 0) {
+ log_error("Failed to add match: %s", strerror(-r));
+ return r;
+ }
+ }
+
+ return 0;
+}
+
+static int setup_keys(void) {
+#ifdef HAVE_GCRYPT
+ size_t mpk_size, seed_size, state_size, i;
+ uint8_t *mpk, *seed, *state;
+ ssize_t l;
+ int fd = -1, r, attr = 0;
+ sd_id128_t machine, boot;
+ char *p = NULL, *k = NULL;
+ struct FSSHeader h;
+ uint64_t n;
+
+ r = sd_id128_get_machine(&machine);
+ if (r < 0) {
+ log_error("Failed to get machine ID: %s", strerror(-r));
+ return r;
+ }
+
+ r = sd_id128_get_boot(&boot);
+ if (r < 0) {
+ log_error("Failed to get boot ID: %s", strerror(-r));
+ return r;
+ }
+
+ if (asprintf(&p, "/var/log/journal/" SD_ID128_FORMAT_STR "/fss",
+ SD_ID128_FORMAT_VAL(machine)) < 0)
+ return log_oom();
+
+ if (access(p, F_OK) >= 0) {
+ log_error("Sealing key file %s exists already.", p);
+ r = -EEXIST;
+ goto finish;
+ }
+
+ if (asprintf(&k, "/var/log/journal/" SD_ID128_FORMAT_STR "/fss.tmp.XXXXXX",
+ SD_ID128_FORMAT_VAL(machine)) < 0) {
+ r = log_oom();
+ goto finish;
+ }
+
+ mpk_size = FSPRG_mskinbytes(FSPRG_RECOMMENDED_SECPAR);
+ mpk = alloca(mpk_size);
+
+ seed_size = FSPRG_RECOMMENDED_SEEDLEN;
+ seed = alloca(seed_size);
+
+ state_size = FSPRG_stateinbytes(FSPRG_RECOMMENDED_SECPAR);
+ state = alloca(state_size);
+
+ fd = open("/dev/random", O_RDONLY|O_CLOEXEC|O_NOCTTY);
+ if (fd < 0) {
+ log_error("Failed to open /dev/random: %m");
+ r = -errno;
+ goto finish;
+ }
+
+ log_info("Generating seed...");
+ l = loop_read(fd, seed, seed_size, true);
+ if (l < 0 || (size_t) l != seed_size) {
+ log_error("Failed to read random seed: %s", strerror(EIO));
+ r = -EIO;
+ goto finish;
+ }
+
+ log_info("Generating key pair...");
+ FSPRG_GenMK(NULL, mpk, seed, seed_size, FSPRG_RECOMMENDED_SECPAR);
+
+ log_info("Generating sealing key...");
+ FSPRG_GenState0(state, mpk, seed, seed_size);
+
+ assert(arg_interval > 0);
+
+ n = now(CLOCK_REALTIME);
+ n /= arg_interval;
+
+ close_nointr_nofail(fd);
+ fd = mkostemp(k, O_WRONLY|O_CLOEXEC|O_NOCTTY);
+ if (fd < 0) {
+ log_error("Failed to open %s: %m", k);
+ r = -errno;
+ goto finish;
+ }