Compare commits

..

No commits in common. "23b13549fa28d7b6b8584a349bd91568de6703d7" and "48625dc437589d328de09887d1ebc360233f5acf" have entirely different histories.

16 changed files with 462 additions and 378 deletions

View File

@ -41,6 +41,7 @@
<filename>hybrid-sleep.target</filename>,
<filename>suspend-then-hibernate.target</filename>,
<filename>initrd.target</filename>,
<filename>initrd-cryptsetup.target</filename>,
<filename>initrd-fs.target</filename>,
<filename>initrd-root-device.target</filename>,
<filename>initrd-root-fs.target</filename>,
@ -182,8 +183,10 @@
<varlistentry>
<term><filename>cryptsetup.target</filename></term>
<listitem>
<para>A target that pulls in setup services for all
encrypted block devices.</para>
<para>A target that pulls in setup services for local encrypted block devices.
See <filename>remote-cryptsetup.target</filename> below for the equivalent target for remote
volumes, and <filename>initrd-cryptsetup.target</filename> below for the equivalent target in the
initrd.</para>
</listitem>
</varlistentry>
<varlistentry>
@ -352,12 +355,20 @@
<varlistentry>
<term><filename>initrd.target</filename></term>
<listitem>
<para>This is the default target in the initramfs, similar to <filename>default.target</filename>
<para>This is the default target in the initrd, similar to <filename>default.target</filename>
in the main system. It is used to mount the real root and transition to it. See
<citerefentry><refentrytitle>bootup</refentrytitle><manvolnum>7</manvolnum></citerefentry> for
more discussion.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><filename>initrd-cryptsetup.target</filename></term>
<listitem>
<para>A target that pulls in setup services for all encrypted block devices. See
<filename>cryptsetup.target</filename> and <filename>remote-cryptsetup.target</filename> for the
equivalent targets in the real root.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><filename>initrd-fs.target</filename></term>
<listitem>
@ -549,7 +560,9 @@
<para>Similar to <filename>cryptsetup.target</filename>, but for encrypted
devices which are accessed over the network. It is used for
<citerefentry><refentrytitle>crypttab</refentrytitle><manvolnum>8</manvolnum></citerefentry>
entries marked with <option>_netdev</option>.</para>
entries marked with <option>_netdev</option>.
See <filename>cryptsetup.target</filename> for the equivalent target for local volumes, and
<filename>initrd-cryptsetup.target</filename> for the equivalent target in the initrd.</para>
</listitem>
</varlistentry>
<varlistentry>

View File

@ -1561,11 +1561,21 @@ meson_apply_m4 = find_program('tools/meson-apply-m4.sh')
includes = include_directories('src/basic',
'src/boot',
'src/core',
'src/home',
'src/shared',
'src/systemd',
'src/journal',
'src/journal-remote',
'src/libsystemd-network',
'src/nspawn',
'src/resolve',
'src/timesync',
'src/time-wait-sync',
'src/login',
'src/udev',
'src/libudev',
'src/core',
'src/shutdown',
'src/xdg-autostart-generator',
'src/libsystemd/sd-bus',
'src/libsystemd/sd-device',
'src/libsystemd/sd-event',
@ -1574,17 +1584,7 @@ includes = include_directories('src/basic',
'src/libsystemd/sd-netlink',
'src/libsystemd/sd-network',
'src/libsystemd/sd-resolve',
'src/libudev',
'src/login',
'src/nspawn',
'src/resolve',
'src/shared',
'src/shutdown',
'src/systemd',
'src/time-wait-sync',
'src/timesync',
'src/udev',
'src/xdg-autostart-generator',
'src/libsystemd-network',
'.')
add_project_arguments('-include', 'config.h', language : 'c')

View File

@ -455,10 +455,16 @@ static int create_disk(
}
}
const char *target;
if (in_initrd())
target = "initrd-cryptsetup.target";
else if (netdev)
target = "remote-cryptsetup.target";
else
target = "cryptsetup.target";
if (!nofail)
fprintf(f,
"Before=%s\n",
netdev ? "remote-cryptsetup.target" : "cryptsetup.target");
fprintf(f, "Before=%s\n", target);
if (password && !keydev) {
r = print_dependencies(f, password);
@ -521,8 +527,7 @@ static int create_disk(
return log_error_errno(r, "Failed to write unit file %s: %m", n);
if (!noauto) {
r = generator_add_symlink(arg_dest,
netdev ? "remote-cryptsetup.target" : "cryptsetup.target",
r = generator_add_symlink(arg_dest, target,
nofail ? "wants" : "requires", n);
if (r < 0)
return r;

View File

@ -1,12 +1,17 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
#if HAVE_QRENCODE
#include <qrencode.h>
#include "qrcode-util.h"
#endif
#include "dlfcn-util.h"
#include "errno-util.h"
#include "homectl-recovery-key.h"
#include "libcrypt-util.h"
#include "locale-util.h"
#include "memory-util.h"
#include "modhex.h"
#include "qrcode-util.h"
#include "random-util.h"
#include "strv.h"
#include "terminal-util.h"
@ -135,6 +140,48 @@ static int add_secret(JsonVariant **v, const char *password) {
return 0;
}
static int print_qr_code(const char *secret) {
#if HAVE_QRENCODE
QRcode* (*sym_QRcode_encodeString)(const char *string, int version, QRecLevel level, QRencodeMode hint, int casesensitive);
void (*sym_QRcode_free)(QRcode *qrcode);
_cleanup_(dlclosep) void *dl = NULL;
QRcode* qr;
int r;
/* If this is not an UTF-8 system or ANSI colors aren't supported/disabled don't print any QR
* codes */
if (!is_locale_utf8() || !colors_enabled())
return -EOPNOTSUPP;
dl = dlopen("libqrencode.so.4", RTLD_LAZY);
if (!dl)
return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
"QRCODE support is not installed: %s", dlerror());
r = dlsym_many_and_warn(
dl,
LOG_DEBUG,
&sym_QRcode_encodeString, "QRcode_encodeString",
&sym_QRcode_free, "QRcode_free",
NULL);
if (r < 0)
return r;
qr = sym_QRcode_encodeString(secret, 0, QR_ECLEVEL_L, QR_MODE_8, 0);
if (!qr)
return -ENOMEM;
fprintf(stderr, "\nYou may optionally scan the recovery key off screen:\n\n");
write_qrcode(stderr, qr);
fputc('\n', stderr);
sym_QRcode_free(qr);
#endif
return 0;
}
int identity_add_recovery_key(JsonVariant **v) {
_cleanup_(erase_and_freep) char *password = NULL, *hashed = NULL;
int r;
@ -193,7 +240,7 @@ int identity_add_recovery_key(JsonVariant **v) {
"whenever authentication is requested.\n", stderr);
fflush(stderr);
(void) print_qrcode(stderr, "You may optionally scan the recovery key off screen", password);
print_qr_code(password);
return 0;
}

View File

@ -0,0 +1,97 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
#include <errno.h>
#include <qrencode.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include "alloc-util.h"
#include "dlfcn-util.h"
#include "fd-util.h"
#include "fileio.h"
#include "journal-qrcode.h"
#include "locale-util.h"
#include "macro.h"
#include "qrcode-util.h"
#include "terminal-util.h"
int print_qr_code(
FILE *output,
const char *prefix_text,
const void *seed,
size_t seed_size,
uint64_t start,
uint64_t interval,
const char *hn,
sd_id128_t machine) {
QRcode* (*sym_QRcode_encodeString)(const char *string, int version, QRecLevel level, QRencodeMode hint, int casesensitive);
void (*sym_QRcode_free)(QRcode *qrcode);
_cleanup_(dlclosep) void *dl = NULL;
_cleanup_free_ char *url = NULL;
_cleanup_fclose_ FILE *f = NULL;
size_t url_size = 0;
QRcode* qr;
int r;
assert(seed);
assert(seed_size > 0);
/* If this is not an UTF-8 system or ANSI colors aren't supported/disabled don't print any QR
* codes */
if (!is_locale_utf8() || !colors_enabled())
return -EOPNOTSUPP;
dl = dlopen("libqrencode.so.4", RTLD_LAZY);
if (!dl)
return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
"QRCODE support is not installed: %s", dlerror());
r = dlsym_many_and_warn(
dl,
LOG_DEBUG,
&sym_QRcode_encodeString, "QRcode_encodeString",
&sym_QRcode_free, "QRcode_free",
NULL);
if (r < 0)
return r;
f = open_memstream_unlocked(&url, &url_size);
if (!f)
return -ENOMEM;
fputs("fss://", f);
for (size_t i = 0; i < seed_size; i++) {
if (i > 0 && i % 3 == 0)
fputc('-', f);
fprintf(f, "%02x", ((uint8_t*) seed)[i]);
}
fprintf(f, "/%"PRIx64"-%"PRIx64"?machine=" SD_ID128_FORMAT_STR,
start,
interval,
SD_ID128_FORMAT_VAL(machine));
if (hn)
fprintf(f, ";hostname=%s", hn);
r = fflush_and_check(f);
if (r < 0)
return r;
f = safe_fclose(f);
qr = sym_QRcode_encodeString(url, 0, QR_ECLEVEL_L, QR_MODE_8, 1);
if (!qr)
return -ENOMEM;
if (prefix_text)
fputs(prefix_text, output);
write_qrcode(output, qr);
sym_QRcode_free(qr);
return 0;
}

View File

@ -0,0 +1,9 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
#include <inttypes.h>
#include <stdio.h>
#include "sd-id128.h"
int print_qr_code(FILE *f, const char *prefix_text, const void *seed, size_t seed_size, uint64_t start, uint64_t interval, const char *hn, sd_id128_t machine);

View File

@ -43,6 +43,7 @@
#include "io-util.h"
#include "journal-def.h"
#include "journal-internal.h"
#include "journal-qrcode.h"
#include "journal-util.h"
#include "journal-vacuum.h"
#include "journal-verify.h"
@ -59,7 +60,6 @@
#include "path-util.h"
#include "pcre2-dlopen.h"
#include "pretty-print.h"
#include "qrcode-util.h"
#include "random-util.h"
#include "rlimit-util.h"
#include "set.h"
@ -1779,53 +1779,6 @@ static int add_syslog_identifier(sd_journal *j) {
return 0;
}
static int format_journal_url(
const void *seed,
size_t seed_size,
uint64_t start,
uint64_t interval,
const char *hn,
sd_id128_t machine,
bool full,
char **ret_url) {
_cleanup_free_ char *url = NULL;
_cleanup_fclose_ FILE *f = NULL;
size_t url_size = 0;
int r;
assert(seed);
assert(seed_size > 0);
f = open_memstream_unlocked(&url, &url_size);
if (!f)
return -ENOMEM;
if (full)
fputs("fss://", f);
for (size_t i = 0; i < seed_size; i++) {
if (i > 0 && i % 3 == 0)
fputc('-', f);
fprintf(f, "%02x", ((uint8_t*) seed)[i]);
}
fprintf(f, "/%"PRIx64"-%"PRIx64, start, interval);
if (full) {
fprintf(f, "?machine=" SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(machine));
if (hn)
fprintf(f, ";hostname=%s", hn);
}
r = fflush_and_check(f);
if (r < 0)
return r;
f = safe_fclose(f);
*ret_url = TAKE_PTR(url);
return 0;
}
static int setup_keys(void) {
#if HAVE_GCRYPT
size_t mpk_size, seed_size, state_size;
@ -1940,11 +1893,7 @@ static int setup_keys(void) {
k = mfree(k);
_cleanup_free_ char *hn = NULL, *key = NULL;
r = format_journal_url(seed, seed_size, n, arg_interval, hn, machine, false, &key);
if (r < 0)
return r;
_cleanup_free_ char *hn = NULL;
if (on_tty()) {
hn = gethostname_malloc();
@ -1976,19 +1925,21 @@ static int setup_keys(void) {
fflush(stderr);
}
puts(key);
for (size_t i = 0; i < seed_size; i++) {
if (i > 0 && i % 3 == 0)
putchar('-');
printf("%02x", ((uint8_t*) seed)[i]);
}
printf("/%llx-%llx\n", (unsigned long long) n, (unsigned long long) arg_interval);
if (on_tty()) {
fprintf(stderr, "%s", ansi_normal());
#if HAVE_QRENCODE
_cleanup_free_ char *url = NULL;
r = format_journal_url(seed, seed_size, n, arg_interval, hn, machine, true, &url);
if (r < 0)
return r;
(void) print_qrcode(stderr,
"To transfer the verification key to your phone scan the QR code below",
url);
(void) print_qr_code(stderr,
"\nTo transfer the verification key to your phone scan the QR code below:\n",
seed, seed_size,
n, arg_interval,
hn, machine);
#endif
}

View File

@ -107,6 +107,11 @@ journalctl_sources = files('''
pcre2-dlopen.h
'''.split())
if conf.get('HAVE_QRENCODE') == 1
journalctl_sources += files('journal-qrcode.c',
'journal-qrcode.h')
endif
install_data('journald.conf',
install_dir : pkgsysconfdir)

View File

@ -701,33 +701,6 @@ static void event_gc_signal_data(sd_event *e, const int64_t *priority, int sig)
event_unmask_signal_data(e, d, sig);
}
static void event_source_pp_prioq_reshuffle(sd_event_source *s) {
assert(s);
/* Reshuffles the pending + prepare prioqs. Called whenever the dispatch order changes, i.e. when
* they are enabled/disabled or marked pending and such. */
if (s->pending)
prioq_reshuffle(s->event->pending, s, &s->pending_index);
if (s->prepare)
prioq_reshuffle(s->event->prepare, s, &s->prepare_index);
}
static void event_source_time_prioq_reshuffle(sd_event_source *s) {
struct clock_data *d;
assert(s);
assert(EVENT_SOURCE_IS_TIME(s->type));
/* Called whenever the event source's timer ordering properties changed, i.e. time, accuracy,
* pending, enable state. Makes sure the two prioq's are ordered properly again. */
assert_se(d = event_get_clock_data(s->event, s->type));
prioq_reshuffle(d->earliest, s, &s->time.earliest_index);
prioq_reshuffle(d->latest, s, &s->time.latest_index);
d->needs_rearm = true;
}
static void source_disconnect(sd_event_source *s) {
sd_event *event;
@ -934,8 +907,16 @@ static int source_set_pending(sd_event_source *s, bool b) {
} else
assert_se(prioq_remove(s->event->pending, s, &s->pending_index));
if (EVENT_SOURCE_IS_TIME(s->type))
event_source_time_prioq_reshuffle(s);
if (EVENT_SOURCE_IS_TIME(s->type)) {
struct clock_data *d;
d = event_get_clock_data(s->event, s->type);
assert(d);
prioq_reshuffle(d->earliest, s, &s->time.earliest_index);
prioq_reshuffle(d->latest, s, &s->time.latest_index);
d->needs_rearm = true;
}
if (s->type == SOURCE_SIGNAL && !b) {
struct signal_data *d;
@ -2226,7 +2207,11 @@ _public_ int sd_event_source_set_priority(sd_event_source *s, int64_t priority)
} else
s->priority = priority;
event_source_pp_prioq_reshuffle(s);
if (s->pending)
prioq_reshuffle(s->event->pending, s, &s->pending_index);
if (s->prepare)
prioq_reshuffle(s->event->prepare, s, &s->prepare_index);
if (s->type == SOURCE_EXIT)
prioq_reshuffle(s->event->exit, s, &s->exit.prioq_index);
@ -2252,152 +2237,6 @@ _public_ int sd_event_source_get_enabled(sd_event_source *s, int *m) {
return s->enabled != SD_EVENT_OFF;
}
static int event_source_disable(sd_event_source *s) {
int r;
assert(s);
assert(s->enabled != SD_EVENT_OFF);
/* Unset the pending flag when this event source is disabled */
if (!IN_SET(s->type, SOURCE_DEFER, SOURCE_EXIT)) {
r = source_set_pending(s, false);
if (r < 0)
return r;
}
s->enabled = SD_EVENT_OFF;
switch (s->type) {
case SOURCE_IO:
source_io_unregister(s);
break;
case SOURCE_TIME_REALTIME:
case SOURCE_TIME_BOOTTIME:
case SOURCE_TIME_MONOTONIC:
case SOURCE_TIME_REALTIME_ALARM:
case SOURCE_TIME_BOOTTIME_ALARM:
event_source_time_prioq_reshuffle(s);
break;
case SOURCE_SIGNAL:
event_gc_signal_data(s->event, &s->priority, s->signal.sig);
break;
case SOURCE_CHILD:
assert(s->event->n_enabled_child_sources > 0);
s->event->n_enabled_child_sources--;
if (EVENT_SOURCE_WATCH_PIDFD(s))
source_child_pidfd_unregister(s);
else
event_gc_signal_data(s->event, &s->priority, SIGCHLD);
break;
case SOURCE_EXIT:
prioq_reshuffle(s->event->exit, s, &s->exit.prioq_index);
break;
case SOURCE_DEFER:
case SOURCE_POST:
case SOURCE_INOTIFY:
break;
default:
assert_not_reached("Wut? I shouldn't exist.");
}
return 0;
}
static int event_source_enable(sd_event_source *s, int m) {
int r;
assert(s);
assert(IN_SET(m, SD_EVENT_ON, SD_EVENT_ONESHOT));
assert(s->enabled == SD_EVENT_OFF);
/* Unset the pending flag when this event source is enabled */
if (!IN_SET(s->type, SOURCE_DEFER, SOURCE_EXIT)) {
r = source_set_pending(s, false);
if (r < 0)
return r;
}
s->enabled = m;
switch (s->type) {
case SOURCE_IO:
r = source_io_register(s, m, s->io.events);
if (r < 0) {
s->enabled = SD_EVENT_OFF;
return r;
}
break;
case SOURCE_TIME_REALTIME:
case SOURCE_TIME_BOOTTIME:
case SOURCE_TIME_MONOTONIC:
case SOURCE_TIME_REALTIME_ALARM:
case SOURCE_TIME_BOOTTIME_ALARM:
event_source_time_prioq_reshuffle(s);
break;
case SOURCE_SIGNAL:
r = event_make_signal_data(s->event, s->signal.sig, NULL);
if (r < 0) {
s->enabled = SD_EVENT_OFF;
event_gc_signal_data(s->event, &s->priority, s->signal.sig);
return r;
}
break;
case SOURCE_CHILD:
s->event->n_enabled_child_sources++;
if (EVENT_SOURCE_WATCH_PIDFD(s)) {
/* yes, we have pidfd */
r = source_child_pidfd_register(s, s->enabled);
if (r < 0) {
s->enabled = SD_EVENT_OFF;
s->event->n_enabled_child_sources--;
return r;
}
} else {
/* no pidfd, or something other to watch for than WEXITED */
r = event_make_signal_data(s->event, SIGCHLD, NULL);
if (r < 0) {
s->enabled = SD_EVENT_OFF;
s->event->n_enabled_child_sources--;
event_gc_signal_data(s->event, &s->priority, SIGCHLD);
return r;
}
}
break;
case SOURCE_EXIT:
prioq_reshuffle(s->event->exit, s, &s->exit.prioq_index);
break;
case SOURCE_DEFER:
case SOURCE_POST:
case SOURCE_INOTIFY:
break;
default:
assert_not_reached("Wut? I shouldn't exist.");
}
return 0;
}
_public_ int sd_event_source_set_enabled(sd_event_source *s, int m) {
int r;
@ -2405,29 +2244,182 @@ _public_ int sd_event_source_set_enabled(sd_event_source *s, int m) {
assert_return(IN_SET(m, SD_EVENT_OFF, SD_EVENT_ON, SD_EVENT_ONESHOT), -EINVAL);
assert_return(!event_pid_changed(s->event), -ECHILD);
/* If we are dead anyway, we are fine with turning off sources, but everything else needs to fail. */
/* If we are dead anyway, we are fine with turning off
* sources, but everything else needs to fail. */
if (s->event->state == SD_EVENT_FINISHED)
return m == SD_EVENT_OFF ? 0 : -ESTALE;
if (s->enabled == m) /* No change? */
if (s->enabled == m)
return 0;
if (m == SD_EVENT_OFF)
r = event_source_disable(s);
else {
if (s->enabled != SD_EVENT_OFF) {
/* Switching from "on" to "oneshot" or back? If that's the case, we can take a shortcut, the
* event source is already enabled after all. */
s->enabled = m;
return 0;
if (m == SD_EVENT_OFF) {
/* Unset the pending flag when this event source is disabled */
if (!IN_SET(s->type, SOURCE_DEFER, SOURCE_EXIT)) {
r = source_set_pending(s, false);
if (r < 0)
return r;
}
r = event_source_enable(s, m);
}
if (r < 0)
return r;
switch (s->type) {
case SOURCE_IO:
source_io_unregister(s);
s->enabled = m;
break;
case SOURCE_TIME_REALTIME:
case SOURCE_TIME_BOOTTIME:
case SOURCE_TIME_MONOTONIC:
case SOURCE_TIME_REALTIME_ALARM:
case SOURCE_TIME_BOOTTIME_ALARM: {
struct clock_data *d;
s->enabled = m;
d = event_get_clock_data(s->event, s->type);
assert(d);
prioq_reshuffle(d->earliest, s, &s->time.earliest_index);
prioq_reshuffle(d->latest, s, &s->time.latest_index);
d->needs_rearm = true;
break;
}
case SOURCE_SIGNAL:
s->enabled = m;
event_gc_signal_data(s->event, &s->priority, s->signal.sig);
break;
case SOURCE_CHILD:
s->enabled = m;
assert(s->event->n_enabled_child_sources > 0);
s->event->n_enabled_child_sources--;
if (EVENT_SOURCE_WATCH_PIDFD(s))
source_child_pidfd_unregister(s);
else
event_gc_signal_data(s->event, &s->priority, SIGCHLD);
break;
case SOURCE_EXIT:
s->enabled = m;
prioq_reshuffle(s->event->exit, s, &s->exit.prioq_index);
break;
case SOURCE_DEFER:
case SOURCE_POST:
case SOURCE_INOTIFY:
s->enabled = m;
break;
default:
assert_not_reached("Wut? I shouldn't exist.");
}
} else {
/* Unset the pending flag when this event source is enabled */
if (s->enabled == SD_EVENT_OFF && !IN_SET(s->type, SOURCE_DEFER, SOURCE_EXIT)) {
r = source_set_pending(s, false);
if (r < 0)
return r;
}
switch (s->type) {
case SOURCE_IO:
r = source_io_register(s, m, s->io.events);
if (r < 0)
return r;
s->enabled = m;
break;
case SOURCE_TIME_REALTIME:
case SOURCE_TIME_BOOTTIME:
case SOURCE_TIME_MONOTONIC:
case SOURCE_TIME_REALTIME_ALARM:
case SOURCE_TIME_BOOTTIME_ALARM: {
struct clock_data *d;
s->enabled = m;
d = event_get_clock_data(s->event, s->type);
assert(d);
prioq_reshuffle(d->earliest, s, &s->time.earliest_index);
prioq_reshuffle(d->latest, s, &s->time.latest_index);
d->needs_rearm = true;
break;
}
case SOURCE_SIGNAL:
s->enabled = m;
r = event_make_signal_data(s->event, s->signal.sig, NULL);
if (r < 0) {
s->enabled = SD_EVENT_OFF;
event_gc_signal_data(s->event, &s->priority, s->signal.sig);
return r;
}
break;
case SOURCE_CHILD:
if (s->enabled == SD_EVENT_OFF)
s->event->n_enabled_child_sources++;
s->enabled = m;
if (EVENT_SOURCE_WATCH_PIDFD(s)) {
/* yes, we have pidfd */
r = source_child_pidfd_register(s, s->enabled);
if (r < 0) {
s->enabled = SD_EVENT_OFF;
s->event->n_enabled_child_sources--;
return r;
}
} else {
/* no pidfd, or something other to watch for than WEXITED */
r = event_make_signal_data(s->event, SIGCHLD, NULL);
if (r < 0) {
s->enabled = SD_EVENT_OFF;
s->event->n_enabled_child_sources--;
event_gc_signal_data(s->event, &s->priority, SIGCHLD);
return r;
}
}
break;
case SOURCE_EXIT:
s->enabled = m;
prioq_reshuffle(s->event->exit, s, &s->exit.prioq_index);
break;
case SOURCE_DEFER:
case SOURCE_POST:
case SOURCE_INOTIFY:
s->enabled = m;
break;
default:
assert_not_reached("Wut? I shouldn't exist.");
}
}
if (s->pending)
prioq_reshuffle(s->event->pending, s, &s->pending_index);
if (s->prepare)
prioq_reshuffle(s->event->prepare, s, &s->prepare_index);
event_source_pp_prioq_reshuffle(s);
return 0;
}
@ -2442,6 +2434,7 @@ _public_ int sd_event_source_get_time(sd_event_source *s, uint64_t *usec) {
}
_public_ int sd_event_source_set_time(sd_event_source *s, uint64_t usec) {
struct clock_data *d;
int r;
assert_return(s, -EINVAL);
@ -2455,7 +2448,13 @@ _public_ int sd_event_source_set_time(sd_event_source *s, uint64_t usec) {
s->time.next = usec;
event_source_time_prioq_reshuffle(s);
d = event_get_clock_data(s->event, s->type);
assert(d);
prioq_reshuffle(d->earliest, s, &s->time.earliest_index);
prioq_reshuffle(d->latest, s, &s->time.latest_index);
d->needs_rearm = true;
return 0;
}
@ -2487,6 +2486,7 @@ _public_ int sd_event_source_get_time_accuracy(sd_event_source *s, uint64_t *use
}
_public_ int sd_event_source_set_time_accuracy(sd_event_source *s, uint64_t usec) {
struct clock_data *d;
int r;
assert_return(s, -EINVAL);
@ -2504,7 +2504,12 @@ _public_ int sd_event_source_set_time_accuracy(sd_event_source *s, uint64_t usec
s->time.accuracy = usec;
event_source_time_prioq_reshuffle(s);
d = event_get_clock_data(s->event, s->type);
assert(d);
prioq_reshuffle(d->latest, s, &s->time.latest_index);
d->needs_rearm = true;
return 0;
}
@ -2883,7 +2888,9 @@ static int process_timer(
if (r < 0)
return r;
event_source_time_prioq_reshuffle(s);
prioq_reshuffle(d->earliest, s, &s->time.earliest_index);
prioq_reshuffle(d->latest, s, &s->time.latest_index);
d->needs_rearm = true;
}
return 0;

View File

@ -195,8 +195,6 @@ shared_sources = files('''
ptyfwd.h
pwquality-util.c
pwquality-util.h
qrcode-util.c
qrcode-util.h
reboot-util.c
reboot-util.h
resize-fs.c
@ -306,6 +304,13 @@ if conf.get('HAVE_PAM') == 1
'''.split())
endif
if conf.get('HAVE_QRENCODE') == 1
shared_sources += files('''
qrcode-util.c
qrcode-util.h
'''.split())
endif
generate_ip_protocol_list = find_program('generate-ip-protocol-list.sh')
ip_protocol_list_txt = custom_target(
'ip-protocol-list.txt',

View File

@ -1,27 +1,25 @@
#include "qrcode-util.h"
#if HAVE_QRENCODE
#include <qrencode.h>
#include "dlfcn-util.h"
#include "locale-util.h"
#include "terminal-util.h"
#define ANSI_WHITE_ON_BLACK "\033[40;37;1m"
static void print_border(FILE *output, unsigned width) {
unsigned x, y;
/* Four rows of border */
for (unsigned y = 0; y < 4; y += 2) {
for (y = 0; y < 4; y += 2) {
fputs(ANSI_WHITE_ON_BLACK, output);
for (unsigned x = 0; x < 4 + width + 4; x++)
for (x = 0; x < 4 + width + 4; x++)
fputs("\342\226\210", output);
fputs(ANSI_NORMAL "\n", output);
}
}
static void write_qrcode(FILE *output, QRcode *qr) {
void write_qrcode(FILE *output, QRcode *qr) {
unsigned x, y;
assert(qr);
if (!output)
@ -29,15 +27,17 @@ static void write_qrcode(FILE *output, QRcode *qr) {
print_border(output, qr->width);
for (unsigned y = 0; y < (unsigned) qr->width; y += 2) {
const uint8_t *row1 = qr->data + qr->width * y;
const uint8_t *row2 = row1 + qr->width;
for (y = 0; y < (unsigned) qr->width; y += 2) {
const uint8_t *row1, *row2;
row1 = qr->data + qr->width * y;
row2 = row1 + qr->width;
fputs(ANSI_WHITE_ON_BLACK, output);
for (unsigned x = 0; x < 4; x++)
for (x = 0; x < 4; x++)
fputs("\342\226\210", output);
for (unsigned x = 0; x < (unsigned) qr->width; x++) {
for (x = 0; x < (unsigned) qr->width; x ++) {
bool a, b;
a = row1[x] & 1;
@ -53,7 +53,7 @@ static void write_qrcode(FILE *output, QRcode *qr) {
fputs("\342\226\210", output);
}
for (unsigned x = 0; x < 4; x++)
for (x = 0; x < 4; x++)
fputs("\342\226\210", output);
fputs(ANSI_NORMAL "\n", output);
}
@ -61,45 +61,3 @@ static void write_qrcode(FILE *output, QRcode *qr) {
print_border(output, qr->width);
fflush(output);
}
int print_qrcode(FILE *out, const char *header, const char *string) {
QRcode* (*sym_QRcode_encodeString)(const char *string, int version, QRecLevel level, QRencodeMode hint, int casesensitive);
void (*sym_QRcode_free)(QRcode *qrcode);
_cleanup_(dlclosep) void *dl = NULL;
QRcode* qr;
int r;
/* If this is not an UTF-8 system or ANSI colors aren't supported/disabled don't print any QR
* codes */
if (!is_locale_utf8() || !colors_enabled())
return -EOPNOTSUPP;
dl = dlopen("libqrencode.so.4", RTLD_LAZY);
if (!dl)
return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
"QRCODE support is not installed: %s", dlerror());
r = dlsym_many_and_warn(
dl,
LOG_DEBUG,
&sym_QRcode_encodeString, "QRcode_encodeString",
&sym_QRcode_free, "QRcode_free",
NULL);
if (r < 0)
return r;
qr = sym_QRcode_encodeString(string, 0, QR_ECLEVEL_L, QR_MODE_8, 0);
if (!qr)
return -ENOMEM;
if (header)
fprintf(out, "\n%s:\n\n", header);
write_qrcode(out, qr);
fputc('\n', out);
sym_QRcode_free(qr);
return 0;
}
#endif

View File

@ -1,13 +1,9 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
#include <stdio.h>
#include <errno.h>
#if HAVE_QRENCODE
int print_qrcode(FILE *out, const char *header, const char *string);
#else
static inline int print_qrcode(FILE *out, const char *header, const char *string) {
return -EOPNOTSUPP;
}
#include <qrencode.h>
#include <stdio.h>
void write_qrcode(FILE *output, QRcode *qr);
#endif

View File

@ -819,10 +819,6 @@ tests += [
[['src/test/test-psi-util.c'],
[],
[]],
[['src/test/test-qrcode-util.c'],
[libshared],
[libdl]],
]
############################################################

View File

@ -1,23 +0,0 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
#include "locale-util.h"
#include "main-func.h"
#include "qrcode-util.h"
#include "tests.h"
static int run(int argc, char **argv) {
int r;
test_setup_logging(LOG_DEBUG);
assert_se(setenv("SYSTEMD_COLORS", "1", 1) == 0); /* Force the qrcode to be printed */
r = print_qrcode(stdout, "This should say \"TEST\"", "TEST");
if (r == -EOPNOTSUPP)
return log_tests_skipped("not supported");
if (r < 0)
return log_error_errno(r, "Failed to print QR code: %m");
return 0;
}
DEFINE_MAIN_FUNCTION(run);

View File

@ -0,0 +1,17 @@
# SPDX-License-Identifier: LGPL-2.1+
#
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
[Unit]
Description=Initrd Encrypted Volumes
Documentation=man:systemd.special(7)
OnFailure=emergency.target
OnFailureJobMode=replace-irreversibly
AssertPathExists=/etc/initrd-release
DefaultDependencies=no
Conflicts=shutdown.target

View File

@ -22,12 +22,14 @@ units = [
'multi-user.target.wants/'],
['getty-pre.target', ''],
['graphical.target', '',
'default.target' + (with_runlevels ? ' runlevel5.target' : '')],
(with_runlevels ? 'runlevel5.target default.target' : 'default.target')],
['halt.target', ''],
['hibernate.target', 'ENABLE_HIBERNATE'],
['hybrid-sleep.target', 'ENABLE_HIBERNATE'],
['suspend-then-hibernate.target', 'ENABLE_HIBERNATE'],
['initrd-cleanup.service', 'ENABLE_INITRD'],
['initrd-cryptsetup.target', 'HAVE_LIBCRYPTSETUP ENABLE_INITRD',
'sysinit.target.wants/'],
['initrd-fs.target', 'ENABLE_INITRD'],
['initrd-parse-etc.service', 'ENABLE_INITRD'],
['initrd-root-device.target', 'ENABLE_INITRD'],
@ -59,9 +61,8 @@ units = [
'sysinit.target.wants/'],
['proc-sys-fs-binfmt_misc.mount', 'ENABLE_BINFMT'],
['reboot.target', '',
'ctrl-alt-del.target' + (with_runlevels ? ' runlevel6.target' : '')],
['remote-cryptsetup.target', 'HAVE_LIBCRYPTSETUP',
'initrd-root-device.target.wants/'],
(with_runlevels ? 'runlevel6.target ctrl-alt-del.target' : 'ctrl-alt-del.target')],
['remote-cryptsetup.target', 'HAVE_LIBCRYPTSETUP'],
['remote-fs-pre.target', ''],
['remote-fs.target', ''],
['rescue.target', '',