Merge pull request #17454 from keszybz/journal-dlopen-cleanup
Journal dlopen cleanup and qrcode printing test
This commit is contained in:
commit
a1989bd84b
26
meson.build
26
meson.build
|
@ -1561,21 +1561,11 @@ meson_apply_m4 = find_program('tools/meson-apply-m4.sh')
|
||||||
|
|
||||||
includes = include_directories('src/basic',
|
includes = include_directories('src/basic',
|
||||||
'src/boot',
|
'src/boot',
|
||||||
|
'src/core',
|
||||||
'src/home',
|
'src/home',
|
||||||
'src/shared',
|
|
||||||
'src/systemd',
|
|
||||||
'src/journal',
|
'src/journal',
|
||||||
'src/journal-remote',
|
'src/journal-remote',
|
||||||
'src/nspawn',
|
'src/libsystemd-network',
|
||||||
'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-bus',
|
||||||
'src/libsystemd/sd-device',
|
'src/libsystemd/sd-device',
|
||||||
'src/libsystemd/sd-event',
|
'src/libsystemd/sd-event',
|
||||||
|
@ -1584,7 +1574,17 @@ includes = include_directories('src/basic',
|
||||||
'src/libsystemd/sd-netlink',
|
'src/libsystemd/sd-netlink',
|
||||||
'src/libsystemd/sd-network',
|
'src/libsystemd/sd-network',
|
||||||
'src/libsystemd/sd-resolve',
|
'src/libsystemd/sd-resolve',
|
||||||
'src/libsystemd-network',
|
'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',
|
||||||
'.')
|
'.')
|
||||||
|
|
||||||
add_project_arguments('-include', 'config.h', language : 'c')
|
add_project_arguments('-include', 'config.h', language : 'c')
|
||||||
|
|
|
@ -1,17 +1,12 @@
|
||||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
/* 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 "errno-util.h"
|
||||||
#include "homectl-recovery-key.h"
|
#include "homectl-recovery-key.h"
|
||||||
#include "libcrypt-util.h"
|
#include "libcrypt-util.h"
|
||||||
#include "locale-util.h"
|
#include "locale-util.h"
|
||||||
#include "memory-util.h"
|
#include "memory-util.h"
|
||||||
#include "modhex.h"
|
#include "modhex.h"
|
||||||
|
#include "qrcode-util.h"
|
||||||
#include "random-util.h"
|
#include "random-util.h"
|
||||||
#include "strv.h"
|
#include "strv.h"
|
||||||
#include "terminal-util.h"
|
#include "terminal-util.h"
|
||||||
|
@ -140,48 +135,6 @@ static int add_secret(JsonVariant **v, const char *password) {
|
||||||
return 0;
|
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) {
|
int identity_add_recovery_key(JsonVariant **v) {
|
||||||
_cleanup_(erase_and_freep) char *password = NULL, *hashed = NULL;
|
_cleanup_(erase_and_freep) char *password = NULL, *hashed = NULL;
|
||||||
int r;
|
int r;
|
||||||
|
@ -240,7 +193,7 @@ int identity_add_recovery_key(JsonVariant **v) {
|
||||||
"whenever authentication is requested.\n", stderr);
|
"whenever authentication is requested.\n", stderr);
|
||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
|
|
||||||
print_qr_code(password);
|
(void) print_qrcode(stderr, "You may optionally scan the recovery key off screen", password);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,97 +0,0 @@
|
||||||
/* 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;
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
/* 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);
|
|
|
@ -43,7 +43,6 @@
|
||||||
#include "io-util.h"
|
#include "io-util.h"
|
||||||
#include "journal-def.h"
|
#include "journal-def.h"
|
||||||
#include "journal-internal.h"
|
#include "journal-internal.h"
|
||||||
#include "journal-qrcode.h"
|
|
||||||
#include "journal-util.h"
|
#include "journal-util.h"
|
||||||
#include "journal-vacuum.h"
|
#include "journal-vacuum.h"
|
||||||
#include "journal-verify.h"
|
#include "journal-verify.h"
|
||||||
|
@ -60,6 +59,7 @@
|
||||||
#include "path-util.h"
|
#include "path-util.h"
|
||||||
#include "pcre2-dlopen.h"
|
#include "pcre2-dlopen.h"
|
||||||
#include "pretty-print.h"
|
#include "pretty-print.h"
|
||||||
|
#include "qrcode-util.h"
|
||||||
#include "random-util.h"
|
#include "random-util.h"
|
||||||
#include "rlimit-util.h"
|
#include "rlimit-util.h"
|
||||||
#include "set.h"
|
#include "set.h"
|
||||||
|
@ -1779,6 +1779,53 @@ static int add_syslog_identifier(sd_journal *j) {
|
||||||
return 0;
|
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) {
|
static int setup_keys(void) {
|
||||||
#if HAVE_GCRYPT
|
#if HAVE_GCRYPT
|
||||||
size_t mpk_size, seed_size, state_size;
|
size_t mpk_size, seed_size, state_size;
|
||||||
|
@ -1893,7 +1940,11 @@ static int setup_keys(void) {
|
||||||
|
|
||||||
k = mfree(k);
|
k = mfree(k);
|
||||||
|
|
||||||
_cleanup_free_ char *hn = NULL;
|
_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;
|
||||||
|
|
||||||
if (on_tty()) {
|
if (on_tty()) {
|
||||||
hn = gethostname_malloc();
|
hn = gethostname_malloc();
|
||||||
|
@ -1925,21 +1976,19 @@ static int setup_keys(void) {
|
||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < seed_size; i++) {
|
puts(key);
|
||||||
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()) {
|
if (on_tty()) {
|
||||||
fprintf(stderr, "%s", ansi_normal());
|
fprintf(stderr, "%s", ansi_normal());
|
||||||
#if HAVE_QRENCODE
|
#if HAVE_QRENCODE
|
||||||
(void) print_qr_code(stderr,
|
_cleanup_free_ char *url = NULL;
|
||||||
"\nTo transfer the verification key to your phone scan the QR code below:\n",
|
r = format_journal_url(seed, seed_size, n, arg_interval, hn, machine, true, &url);
|
||||||
seed, seed_size,
|
if (r < 0)
|
||||||
n, arg_interval,
|
return r;
|
||||||
hn, machine);
|
|
||||||
|
(void) print_qrcode(stderr,
|
||||||
|
"To transfer the verification key to your phone scan the QR code below",
|
||||||
|
url);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -107,11 +107,6 @@ journalctl_sources = files('''
|
||||||
pcre2-dlopen.h
|
pcre2-dlopen.h
|
||||||
'''.split())
|
'''.split())
|
||||||
|
|
||||||
if conf.get('HAVE_QRENCODE') == 1
|
|
||||||
journalctl_sources += files('journal-qrcode.c',
|
|
||||||
'journal-qrcode.h')
|
|
||||||
endif
|
|
||||||
|
|
||||||
install_data('journald.conf',
|
install_data('journald.conf',
|
||||||
install_dir : pkgsysconfdir)
|
install_dir : pkgsysconfdir)
|
||||||
|
|
||||||
|
|
|
@ -195,6 +195,8 @@ shared_sources = files('''
|
||||||
ptyfwd.h
|
ptyfwd.h
|
||||||
pwquality-util.c
|
pwquality-util.c
|
||||||
pwquality-util.h
|
pwquality-util.h
|
||||||
|
qrcode-util.c
|
||||||
|
qrcode-util.h
|
||||||
reboot-util.c
|
reboot-util.c
|
||||||
reboot-util.h
|
reboot-util.h
|
||||||
resize-fs.c
|
resize-fs.c
|
||||||
|
@ -304,13 +306,6 @@ if conf.get('HAVE_PAM') == 1
|
||||||
'''.split())
|
'''.split())
|
||||||
endif
|
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')
|
generate_ip_protocol_list = find_program('generate-ip-protocol-list.sh')
|
||||||
ip_protocol_list_txt = custom_target(
|
ip_protocol_list_txt = custom_target(
|
||||||
'ip-protocol-list.txt',
|
'ip-protocol-list.txt',
|
||||||
|
|
|
@ -1,25 +1,27 @@
|
||||||
#include "qrcode-util.h"
|
#include "qrcode-util.h"
|
||||||
|
|
||||||
|
#if HAVE_QRENCODE
|
||||||
|
#include <qrencode.h>
|
||||||
|
|
||||||
|
#include "dlfcn-util.h"
|
||||||
|
#include "locale-util.h"
|
||||||
#include "terminal-util.h"
|
#include "terminal-util.h"
|
||||||
|
|
||||||
#define ANSI_WHITE_ON_BLACK "\033[40;37;1m"
|
#define ANSI_WHITE_ON_BLACK "\033[40;37;1m"
|
||||||
|
|
||||||
static void print_border(FILE *output, unsigned width) {
|
static void print_border(FILE *output, unsigned width) {
|
||||||
unsigned x, y;
|
|
||||||
|
|
||||||
/* Four rows of border */
|
/* Four rows of border */
|
||||||
for (y = 0; y < 4; y += 2) {
|
for (unsigned y = 0; y < 4; y += 2) {
|
||||||
fputs(ANSI_WHITE_ON_BLACK, output);
|
fputs(ANSI_WHITE_ON_BLACK, output);
|
||||||
|
|
||||||
for (x = 0; x < 4 + width + 4; x++)
|
for (unsigned x = 0; x < 4 + width + 4; x++)
|
||||||
fputs("\342\226\210", output);
|
fputs("\342\226\210", output);
|
||||||
|
|
||||||
fputs(ANSI_NORMAL "\n", output);
|
fputs(ANSI_NORMAL "\n", output);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void write_qrcode(FILE *output, QRcode *qr) {
|
static void write_qrcode(FILE *output, QRcode *qr) {
|
||||||
unsigned x, y;
|
|
||||||
|
|
||||||
assert(qr);
|
assert(qr);
|
||||||
|
|
||||||
if (!output)
|
if (!output)
|
||||||
|
@ -27,17 +29,15 @@ void write_qrcode(FILE *output, QRcode *qr) {
|
||||||
|
|
||||||
print_border(output, qr->width);
|
print_border(output, qr->width);
|
||||||
|
|
||||||
for (y = 0; y < (unsigned) qr->width; y += 2) {
|
for (unsigned y = 0; y < (unsigned) qr->width; y += 2) {
|
||||||
const uint8_t *row1, *row2;
|
const uint8_t *row1 = qr->data + qr->width * y;
|
||||||
|
const uint8_t *row2 = row1 + qr->width;
|
||||||
row1 = qr->data + qr->width * y;
|
|
||||||
row2 = row1 + qr->width;
|
|
||||||
|
|
||||||
fputs(ANSI_WHITE_ON_BLACK, output);
|
fputs(ANSI_WHITE_ON_BLACK, output);
|
||||||
for (x = 0; x < 4; x++)
|
for (unsigned x = 0; x < 4; x++)
|
||||||
fputs("\342\226\210", output);
|
fputs("\342\226\210", output);
|
||||||
|
|
||||||
for (x = 0; x < (unsigned) qr->width; x ++) {
|
for (unsigned x = 0; x < (unsigned) qr->width; x++) {
|
||||||
bool a, b;
|
bool a, b;
|
||||||
|
|
||||||
a = row1[x] & 1;
|
a = row1[x] & 1;
|
||||||
|
@ -53,7 +53,7 @@ void write_qrcode(FILE *output, QRcode *qr) {
|
||||||
fputs("\342\226\210", output);
|
fputs("\342\226\210", output);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (x = 0; x < 4; x++)
|
for (unsigned x = 0; x < 4; x++)
|
||||||
fputs("\342\226\210", output);
|
fputs("\342\226\210", output);
|
||||||
fputs(ANSI_NORMAL "\n", output);
|
fputs(ANSI_NORMAL "\n", output);
|
||||||
}
|
}
|
||||||
|
@ -61,3 +61,45 @@ void write_qrcode(FILE *output, QRcode *qr) {
|
||||||
print_border(output, qr->width);
|
print_border(output, qr->width);
|
||||||
fflush(output);
|
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
|
||||||
|
|
|
@ -1,9 +1,13 @@
|
||||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
#if HAVE_QRENCODE
|
#if HAVE_QRENCODE
|
||||||
#include <qrencode.h>
|
int print_qrcode(FILE *out, const char *header, const char *string);
|
||||||
#include <stdio.h>
|
#else
|
||||||
|
static inline int print_qrcode(FILE *out, const char *header, const char *string) {
|
||||||
void write_qrcode(FILE *output, QRcode *qr);
|
return -EOPNOTSUPP;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -819,6 +819,10 @@ tests += [
|
||||||
[['src/test/test-psi-util.c'],
|
[['src/test/test-psi-util.c'],
|
||||||
[],
|
[],
|
||||||
[]],
|
[]],
|
||||||
|
|
||||||
|
[['src/test/test-qrcode-util.c'],
|
||||||
|
[libshared],
|
||||||
|
[libdl]],
|
||||||
]
|
]
|
||||||
|
|
||||||
############################################################
|
############################################################
|
||||||
|
|
23
src/test/test-qrcode-util.c
Normal file
23
src/test/test-qrcode-util.c
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
/* 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);
|
Loading…
Reference in a new issue