Translate to Polish

This commit is contained in:
наб 2023-11-25 17:30:20 +01:00
parent e78ba80bc9
commit 47cd20aa32
No known key found for this signature in database
GPG Key ID: BCFD0B018D2658F1
20 changed files with 492 additions and 96 deletions

2
.gitignore vendored
View File

@ -21,3 +21,5 @@
!initrd/**
!init.d
!init.d/**
!po
!po/**

10
LICENSES/0BSD Normal file
View File

@ -0,0 +1,10 @@
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

View File

@ -12,8 +12,10 @@ SED ?= sed
MANDOC ?= mandoc
PKGCONF ?= pkgconf
SHELLCHECK ?= shellcheck
OUTDIR ?= out/
BLDDIR ?= out/build/
NOLOCREGEN ?=
OUTDIR := out/
BLDDIR := out/build/
SYSTEMD_SYSTEM_UNITDIR := $(shell $(PKGCONF) --variable=systemd_system_unit_dir systemd 2>/dev/null || echo /usr/lib/systemd/system)
@ -31,6 +33,9 @@ COMMON_SOURCES := $(filter-out $(BINARY_SOURCES),$(sort $(wildcard src/*.cpp src
MANPAGE_HEADERS := $(sort $(wildcard man/*.h))
MANPAGE_SOURCES := $(sort $(wildcard man/*.[0-8].pp))
INITRD_HEADERS := $(sort $(wildcard initrd/*.h))
ifneq (,$(shell command -v msgfmt))
LOCALES := $(wildcard po/*.po)
endif
ifdef TZPFMS_PASSPHRASE_HELPER
@ -52,10 +57,10 @@ endif
.PHONY : all clean build shellcheck i-t dracut init.d-systemd manpages htmlpages
.PHONY : all locales clean build shellcheck i-t dracut init.d-systemd manpages htmlpages
all : build manpages htmlpages shellcheck i-t init.d-systemd dracut
all : build locales manpages htmlpages shellcheck i-t init.d-systemd dracut
shellcheck : i-t dracut
find $(OUTDIR)initramfs-tools/ $(OUTDIR)dracut/ init.d/ -name '*.sh' -exec echo $(SHELLCHECK) --exclude SC1091,SC2093 {} + | sh -x
@ -66,11 +71,23 @@ clean :
build : $(subst src/bin/,$(OUTDIR),$(subst .cpp,,$(BINARY_SOURCES)))
manpages : $(patsubst man/%.pp,$(OUTDIR)man/%,$(MANPAGE_SOURCES))
htmlpages : $(patsubst man/%.pp,$(OUTDIR)man/%.html,$(MANPAGE_SOURCES)) $(OUTDIR)man/style.css
locales : $(patsubst po/%.po,$(OUTDIR)loc/%/LC_MESSAGES/tzpfms.mo,$(LOCALES))
i-t : $(OUTDIR)initramfs-tools/usr/share/initramfs-tools/hooks/tzpfms $(OUTDIR)initramfs-tools/usr/share/tzpfms/initramfs-tools-zfs-patch.sh
dracut : $(patsubst initrd/dracut/%,$(OUTDIR)dracut/usr/lib/dracut/modules.d/91tzpfms/%,$(sort $(wildcard initrd/dracut/*.sh)))
init.d-systemd : $(OUTDIR)systemd/$(SYSTEMD_SYSTEM_UNITDIR)/zfs-load-key@.service.d/tzpfms.conf $(OUTDIR)systemd/usr/libexec/tzpfms-zfs-load-key@
$(BLDDIR)tzpfms.pot: src/*.[ch]pp src/bin/*.[ch]pp
@mkdir -p $(@D)
$(NOLOCREGEN)xgettext --check=ellipsis-unicode -kfgettext -kfngettext:1,2 --from-code=UTF-8 -c -io- $^ | sed -n '/^#[:.]/,$$p' > $@
$(NOLOCREGEN)$(foreach l,$(LOCALES),msgmerge --backup=off --no-wrap -Uiq $(l) $@ &&) :
@>> $@
$(OUTDIR)loc/%/LC_MESSAGES/tzpfms.mo : po/%.po $(BLDDIR)tzpfms.pot
@mkdir -p $(@D)
msgfmt --statistics --check-format --check-domain -o $@ $<
$(OUTDIR)initramfs-tools/usr/share/initramfs-tools/hooks/tzpfms: initrd/initramfs-tools/hook $(INITRD_HEADERS)
@mkdir -p $(dir $@)
$(AWK) -f pp.awk $< > $@

282
po/pl.po Normal file
View File

@ -0,0 +1,282 @@
# SPDX-License-Identifier: 0BSD
msgid ""
msgstr "Language: pl\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
#: src/fd.cpp:79
#, c-format
msgid "Passphrase for %s"
msgstr "Hasło do %s"
#: src/fd.cpp:81
#, c-format
msgid "Passphrase for %s (again)"
msgstr "Powtórz hasło do %s"
#: src/fd.cpp:83
#, c-format
msgid "New passphrase for %s"
msgstr "Nowe hasło do %s"
#. newkey && again
#: src/fd.cpp:85
#, c-format
msgid "New passphrase for %s (again)"
msgstr "Powtórz howe hasło do %s"
#. exit status
#: src/fd.cpp:132
#, c-format
msgid "Helper '%s' failed with %d.\n"
msgstr "'%s' zawiódł: %d.\n"
#: src/fd.cpp:135
#, c-format
msgid "Helper '%s' died to signal %d: %s.\n"
msgstr "'%s' zabity przez sygnał %d: %s.\n"
#: src/fd.cpp:171
#, c-format
msgid "Enter passphrase for %s: "
msgstr "Hasło do %s"
#: src/fd.cpp:173
#, c-format
msgid "Enter passphrase for new %s: "
msgstr "Hasło do nowego %s"
#: src/fd.cpp:175
#, c-format
msgid "Re-enter passphrase for %s: "
msgstr "Ponownie, hasło do %s"
#. again && newkey
#: src/fd.cpp:177
#, c-format
msgid "Re-enter passphrase for new %s: "
msgstr "Ponownie, hasło do nowego %s"
#: src/fd.cpp:254 src/fd.cpp:270
#, c-format
msgid "Passphrase too long (max %zu)\n"
msgstr "Hasło za długie (maks. %zu)\n"
#: src/fd.cpp:268
#, c-format
msgid "Passphrase too short (min %u)\n"
msgstr "Hasło za krótkie (maks. %u)\n"
#: src/fd.cpp:278
#, c-format
msgid "Provided passphrases do not match.\n"
msgstr "Hasła się różnią\n"
#: src/main.hpp:46 src/main.hpp:59 src/main.hpp:64
#, c-format
msgid "usage: %s [-hV] %s%s%s\n"
msgstr "składnia: %s [-hV] %s%s%s\n"
#. as-in argument in a usage string
#: src/main.hpp:72
msgid "dataset"
msgstr "dataset"
#: src/main.hpp:76
#, c-format
msgid "No dataset to act on?\n"
"usage: %s [-hV] %s%sdataset\n"
msgstr "Nie podano datasetu?\n"
"składnia: %s [-hV] %s%sdataset\n"
#: src/main.hpp:81
#, c-format
msgid "usage: %s [-hV] %s%sdataset\n"
msgstr "składnia: %s [-hV] %s%sdataset\n"
#: src/main.hpp:91
#, c-format
msgid "Dataset %s not encrypted?\n"
msgstr "Dataset %s nie jest zaszyfrowany?\n"
#: src/main.hpp:93
#, c-format
msgid "Using dataset %s's encryption root %s instead.\n"
msgstr "Używam zamiast %s jego korzenia szyfrowania %s.\n"
#. user-supplied parameter, errno
#: src/tpm1x.cpp:101
#, c-format
msgid "PCR %s: %s\n"
msgstr "PCR %s: %s\n"
#. user-supplied parameter
#: src/tpm1x.cpp:104
#, c-format
msgid "PCR %s: too large (max 229).\n"
msgstr "PCR %s: za duży (maks. 229)\n"
#. == TPM2_NUM_PCR_BANKS
#: src/tpm2.cpp:116
#, c-format
msgid "Too many PCR banks specified! Can only have up to %zu\n"
msgstr "Zbyt wiele grup PCRów! Mogę przyjąć maks. %zu\n"
#. comma-separated list follows
#: src/tpm2.cpp:133
#, c-format
msgid "Unknown hash algorithm %s.\n"
"Can be any of case-insensitive "
msgstr "Nie znany algorytm haszowania %s.\n"
"Można użyć dowolnego z (rozmiar liter nie ma znaczenia): "
#. user-passed parameter
#: src/tpm2.cpp:164
#, c-format
msgid "PCR bank \"%s\": no algorithm; need alg:PCR[,PCR]…\n"
msgstr "PCR bank \"%s\": nie podano algorytmu; potrzebuję alg:PCR[,PCR]…\n"
#. %s=dataset name, then TPM2. noun for "Enter passphrase for" prompt
#. %s=dataset, then TPM1.X. noun for "Enter passphrase for" prompt
#: src/tpm2.cpp:374 src/bin/zfs-tpm1x-change-key.cpp:108
#, c-format
msgid "%s %s wrapping key (or empty for none)"
msgstr "klucza zawijania %2$s dla %1$s (puste żeby nie używać żadnego)"
#. %s=dataset name, then TPM2. noun for "Enter passphrase for" prompt
#. %s=dataset name, then TPM1.x. noun for "Enter passphrase for" prompt
#: src/tpm2.cpp:425 src/bin/zfs-tpm1x-load-key.cpp:63
#, c-format
msgid "%s %s wrapping key"
msgstr "klucza zawijania %2$s dla %1$s"
#: src/tpm2.cpp:439
#, c-format
msgid "Couldn't unseal wrapping key with PCR policy: %s\n"
msgstr "Nie udało się rozpieczętować klucza zawijania z polityką PCR: %s\n"
#: src/zfs.cpp:101
#, c-format
msgid "You might need to run \"zfs inherit %s %s\" and \"zfs inherit %s %s\" to fully clear metadata!\n"
msgstr "Możliwe, że potrzebujesz uruchomić \"zfs inherit %s %s\" i \"zfs inherit %s %s\" żeby całkowicie pozbyć się metadanych!\n"
#: src/zfs.cpp:116
#, c-format
msgid "Dataset %s not encrypted with tzpfms!\n"
msgstr "Dataset %s nie jest szyfrowany tzpfms!\n"
#: src/zfs.cpp:118
#, c-format
msgid "Dataset %s encrypted with tzpfms back-end %s, but we are %s.\n"
msgstr "Dataset %s szyfrowany tzpfms %s, ale ten program rozumie %s.\n"
#: src/zfs.cpp:122
#, c-format
msgid "Dataset %s missing key data.\n"
msgstr "Dataset %s nie ma klucza.\n"
#. / Mimic libzfs error output
#: src/zfs.hpp:26
#, c-format
msgid "Key change error: Key must be loaded.\n"
msgstr "Błąd zmiany klucza: Klucz musi być załadowany.\n"
#. dataset name: (null), 0A123...
#. dataset name: TPM1.X, (null)
#: src/zfs.hpp:70
#, c-format
msgid "Inconsistent tzpfms metadata for %s: back-end is %s, but handle is %s?\n"
msgstr "Niespójne metadane tzpfms dla %s: tzpfms %s ale obiekt z kluczem %s?\n"
#: src/zfs.hpp:75
#, c-format
msgid "Dataset %s was encrypted with tzpfms back-end %s before, but we are %s. You will have to free handle %s for back-end %s manually!\n"
msgstr "Dataset %s był zaszyfrowany tzpfms %s, ale ten program rozumie %s. Konieczne będzie ręczne usunięcie obiektu z kluczem %s %s!\n"
#: src/zfs_meat.cpp:33
#, c-format
msgid "Key for %s changed\n"
msgstr "Klucz do %s zmieniony\n"
#: src/zfs_meat.cpp:46
#, c-format
msgid "Key for %s OK\n"
msgstr "Klucz do %s OK\n"
#: src/zfs_meat.cpp:48
#, c-format
msgid "Key for %s loaded\n"
msgstr "Klucz do %s załadowany\n"
#: src/bin/zfs-tpm1x-change-key.cpp:30
msgid "[-b backup-file] [-P PCR[,PCR]…]"
msgstr "[-b plik-z-backupem] [-P PCR[,PCR]…]"
#. 0A1234... follows
#: src/bin/zfs-tpm1x-load-key.cpp:71
#, c-format
msgid "Wrong sealed data length (%u != %zu): "
msgstr "Zła długość zaplombowanych danych (%u != %zu): "
#: src/bin/zfs-tpm2-change-key.cpp:25
msgid "[-b backup-file] [-P algorithm:PCR[,PCR]…[+algorithm:PCR[,PCR]…]… [-A]]"
msgstr "[-b plik-z-backupem] [-P algorytm:PCR[,PCR]…[+algorytm:PCR[,PCR]…]… [-A]]"
#: src/bin/zfs-tpm2-change-key.cpp:72
#, c-format
msgid "Couldn't parse previous persistent handle for dataset %s. You might need to run \"tpm2_evictcontrol -c %s\" or equivalent!\n"
msgstr "Nie udało się rozczytać poprzedniego obiektu z kluczem dla %s. Możliwe, że potrzeba będzie uruchomić \"tpm2_evictcontrol -c %s\", albo jego ekwiwalent!\n"
#: src/bin/zfs-tpm2-change-key.cpp:78
#, c-format
msgid "Couldn't free previous persistent handle for dataset %s. You might need to run \"tpm2_evictcontrol -c 0x%X\" or equivalent!\n"
msgstr "Nie udało się uwolnić poprzedniego obiektu z kluczem dla %s. Możliwe, że potrzeba będzie uruchomić \"tpm2_evictcontrol -c 0x%X\", albo jego ekwiwalent!\n"
#: src/bin/zfs-tpm2-change-key.cpp:94
#, c-format
msgid "Couldn't free persistent handle. You might need to run \"tpm2_evictcontrol -c 0x%X\" or equivalent!\n"
msgstr "Nie udało się uwolnić obiektu z kluczem. Możliwe, że potrzeba będzie uruchomić \"tpm2_evictcontrol -c 0x%X\", albo jego ekwiwalent!\n"
#. for KEYSTATUS column
#: src/bin/zfs-tpm-list.cpp:44
msgid "unavailable"
msgstr "niedostępny"
#: src/bin/zfs-tpm-list.cpp:44
msgid "available"
msgstr "dostępny"
#. for COHERENT column
#: src/bin/zfs-tpm-list.cpp:46
msgid "no"
msgstr "nie"
#: src/bin/zfs-tpm-list.cpp:46
msgid "yes"
msgstr "tak"
#: src/bin/zfs-tpm-list.cpp:88
msgid "[-H] [-r|-d max] [-a|-b back-end] [-u|-l]"
msgstr "[-H] [-r|-d maks.] [-a|-b rodzaj-tzpfms] [-u|-l]"
#: src/bin/zfs-tpm-list.cpp:88
msgid "[filesystem|volume]…"
msgstr "[system-plików|wolumin]…"
#: src/bin/zfs-tpm-list.cpp:152 src/bin/zfs-tpm-list.cpp:173
msgid "NAME"
msgstr "NAZWA"
#: src/bin/zfs-tpm-list.cpp:153 src/bin/zfs-tpm-list.cpp:173
msgid "BACK-END"
msgstr "RODZAJ"
#: src/bin/zfs-tpm-list.cpp:154 src/bin/zfs-tpm-list.cpp:173
msgid "KEYSTATUS"
msgstr "KLUCZ"
#: src/bin/zfs-tpm-list.cpp:173
msgid "COHERENT"
msgstr "SPÓJNY"

View File

@ -6,6 +6,7 @@
#include "../zfs.hpp"
#include <algorithm>
#include <wchar.h>
#define TZPFMS_BACKEND_MAX_LEN 16
@ -19,8 +20,11 @@ enum class key_loadedness : char {
/// zfs(8) uses struct zprop_get_cbdata_t, which is powerful, but inscrutable; we have a fixed format, which makes this easier
struct output_line {
static const char * const key_available_display[2];
static const char * const coherent_display[2];
static const char * key_available_display[2];
static const char * coherent_display[2];
static uint8_t key_available_display_width[2];
static void init_display();
char name[ZFS_MAX_DATASET_NAME_LEN + 1];
@ -36,8 +40,42 @@ struct output_line {
const char * backend_display() const { return (this->backend[0] != '\0') ? this->backend : "-"; }
};
const char * const output_line::key_available_display[2]{"unavailable", key_available_display[0] + 2};
const char * const output_line::coherent_display[2]{"no", "yes"};
// for KEYSTATUS column
const char * output_line::key_available_display[2]{gettext_noop("unavailable"), gettext_noop("available")};
// for COHERENT column
const char * output_line::coherent_display[2]{gettext_noop("no"), gettext_noop("yes")};
uint8_t output_line::key_available_display_width[2];
// infallible strings only
static int strwidth(const char * str) {
int ret{};
wchar_t c;
mbstate_t state{};
auto len = strlen(str);
for(;;)
switch(auto rd = mbrtowc(&c, str, len, &state)) {
case 0: // NUL
case(size_t)-1: // EILSEQ
case(size_t)-2: // ENODATA
return ret;
default:
ret += wcwidth(c) ?: 0;
str += rd;
len -= rd;
break;
}
}
void output_line::init_display() {
key_available_display[false] = gettext(key_available_display[false]);
key_available_display[true] = gettext(key_available_display[true]);
key_available_display_width[false] = strwidth(key_available_display[false]);
key_available_display_width[true] = strwidth(key_available_display[true]);
coherent_display[false] = gettext(coherent_display[false]);
coherent_display[true] = gettext(coherent_display[true]);
}
int main(int argc, char ** argv) {
@ -47,7 +85,7 @@ int main(int argc, char ** argv) {
const char * backend_restrixion = nullptr;
auto key_loadedness_restrixion = key_loadedness::none;
return do_bare_main(
argc, argv, "Hrd:ab:ul", "[-H] [-r|-d max] [-a|-b back-end] [-u|-l]", "[filesystem|volume]…",
argc, argv, "Hrd:ab:ul", gettext_noop("[-H] [-r|-d max] [-a|-b back-end] [-u|-l]"), gettext_noop("[filesystem|volume]…"),
[&](auto arg) {
switch(arg) {
case 'H':
@ -104,35 +142,35 @@ int main(int argc, char ** argv) {
return 0;
}));
output_line::init_display();
size_t max_name_len = 0;
size_t max_backend_len = 0;
size_t max_key_available_len = 0;
size_t max_coherent_len = 0;
auto separator = "\t";
if(human) {
max_name_len = strlen("NAME");
max_backend_len = strlen("BACK-END");
max_key_available_len = strlen("KEYSTATUS");
max_coherent_len = strlen("COHERENT");
max_name_len = strwidth(gettext("NAME"));
max_backend_len = strwidth(gettext("BACK-END"));
max_key_available_len = strwidth(gettext("KEYSTATUS"));
separator = " ";
for(auto cur = lines; cur != lines + lines_len; ++cur)
if(cur->included(print_nontzpfms, backend_restrixion, key_loadedness_restrixion)) {
max_name_len = std::max(max_name_len, strlen(cur->name));
max_backend_len = std::max(max_backend_len, strlen(cur->backend_display()));
max_key_available_len = std::max(max_key_available_len, strlen(output_line::key_available_display[cur->key_available]));
max_key_available_len = std::max(max_key_available_len, static_cast<size_t>(output_line::key_available_display_width[cur->key_available]));
}
}
auto println = [&](auto name, auto backend, auto key_available, auto coherent) {
printf("%-*s%s%-*s%s%-*s%s%-*s\n", //
printf("%-*s%s%-*s%s%-*s%s%s\n", //
static_cast<int>(max_name_len), name, separator, //
static_cast<int>(max_backend_len), backend, separator, //
static_cast<int>(max_key_available_len), key_available, separator, //
static_cast<int>(max_coherent_len), coherent);
coherent);
};
if(human)
println("NAME", "BACK-END", "KEYSTATUS", "COHERENT");
println(gettext("NAME"), gettext("BACK-END"), gettext("KEYSTATUS"), gettext("COHERENT"));
for(auto cur = lines; cur != lines + lines_len; ++cur)
if(cur->included(print_nontzpfms, backend_restrixion, key_loadedness_restrixion))
println(cur->name, cur->backend_display(), output_line::key_available_display[cur->key_available], output_line::coherent_display[cur->coherent]);

View File

@ -27,7 +27,7 @@ int main(int argc, char ** argv) {
uint32_t * pcrs{};
size_t pcrs_len{};
return do_main(
argc, argv, "b:P:", "[-b backup-file] [-P PCR[,PCR]…]",
argc, argv, "b:P:", gettext_noop("[-b backup-file] [-P PCR[,PCR]…]"),
[&](auto o) {
switch(o) {
case 'b':
@ -103,8 +103,9 @@ int main(int argc, char ** argv) {
}};
{
char what_for[ZFS_MAX_DATASET_NAME_LEN + 40 + 1];
snprintf(what_for, sizeof(what_for), "%s TPM1.X wrapping key (or empty for none)", zfs_get_name(dataset));
char what_for[ZFS_MAX_DATASET_NAME_LEN + 512 + 1];
// %s=dataset, then TPM1.X. noun for "Enter passphrase for" prompt
snprintf(what_for, sizeof(what_for), gettext("%s %s wrapping key (or empty for none)"), zfs_get_name(dataset), THIS_BACKEND);
uint8_t * parent_key_passphrase{};
size_t parent_key_passphrase_len{};

View File

@ -5,7 +5,6 @@
// #include <sys/zio_crypt.h>
#define WRAPPING_KEY_LEN 32
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -59,15 +58,17 @@ int main(int argc, char ** argv) {
TRY_TPM1X("load sealed object from blob", Tspi_SetAttribData(sealed_object, TSS_TSPATTRIB_ENCDATA_BLOB, TSS_TSPATTRIB_ENCDATABLOB_BLOB,
handle.sealed_object_blob_len, handle.sealed_object_blob));
char what_for[ZFS_MAX_DATASET_NAME_LEN + 20 + 1];
snprintf(what_for, sizeof(what_for), "%s TPM1.X wrapping key", zfs_get_name(dataset));
char what_for[ZFS_MAX_DATASET_NAME_LEN + 512 + 1];
// %s=dataset name, then TPM1.x. noun for "Enter passphrase for" prompt
snprintf(what_for, sizeof(what_for), gettext("%s %s wrapping key"), zfs_get_name(dataset), THIS_BACKEND);
uint8_t * loaded_wrap_key{};
uint32_t loaded_wrap_key_len{};
TRY_MAIN(try_policy_or_passphrase("unseal wrapping key", what_for, parent_key_policy,
[&] { return Tspi_Data_Unseal(sealed_object, parent_key, &loaded_wrap_key_len, &loaded_wrap_key); }));
if(loaded_wrap_key_len != sizeof(wrap_key)) {
fprintf(stderr, "Wrong sealed data length (%" PRIu32 " != %zu): ", loaded_wrap_key_len, sizeof(wrap_key));
// 0A1234... follows
fprintf(stderr, gettext("Wrong sealed data length (%u != %zu): "), loaded_wrap_key_len, sizeof(wrap_key));
for(auto i = 0u; i < loaded_wrap_key_len; ++i)
fprintf(stderr, "%02hhX", loaded_wrap_key[i]);
fprintf(stderr, "\n");

View File

@ -5,7 +5,6 @@
// #include <sys/zio_crypt.h>
#define WRAPPING_KEY_LEN 32
#include <inttypes.h>
#include <stdio.h>
#include "../fd.hpp"
@ -23,7 +22,7 @@ int main(int argc, char ** argv) {
TPML_PCR_SELECTION pcrs{};
bool allow_PCR_or_pass{};
return do_main(
argc, argv, "b:P:A", "[-b backup-file] [-P algorithm:PCR[,PCR]…[+algorithm:PCR[,PCR]…]… [-A]]",
argc, argv, "b:P:A", gettext_noop("[-b backup-file] [-P algorithm:PCR[,PCR]…[+algorithm:PCR[,PCR]…]… [-A]]"),
[&](auto o) {
switch(o) {
case 'b':
@ -69,14 +68,15 @@ int main(int argc, char ** argv) {
TRY_MAIN(verify_backend(dataset, THIS_BACKEND, [&](auto previous_handle_s) {
TPMI_DH_PERSISTENT previous_handle{};
if(tpm2_parse_prop(zfs_get_name(dataset), previous_handle_s, previous_handle, nullptr))
fprintf(stderr, "Couldn't parse previous persistent handle for dataset %s. You might need to run \"tpm2_evictcontrol -c %s\" or equivalent!\n",
fprintf(stderr,
gettext("Couldn't parse previous persistent handle for dataset %s. You might need to run \"tpm2_evictcontrol -c %s\" or equivalent!\n"),
zfs_get_name(dataset), previous_handle_s);
else {
if(tpm2_free_persistent(tpm2_ctx, tpm2_session, previous_handle))
fprintf(stderr,
"Couldn't free previous persistent handle for dataset %s. You might need to run \"tpm2_evictcontrol -c 0x%" PRIX32
"\" or equivalent!\n",
zfs_get_name(dataset), previous_handle);
fprintf(
stderr,
gettext("Couldn't free previous persistent handle for dataset %s. You might need to run \"tpm2_evictcontrol -c 0x%X\" or equivalent!\n"),
zfs_get_name(dataset), previous_handle);
}
}));
@ -91,7 +91,7 @@ int main(int argc, char ** argv) {
bool ok = false; // Try to free the persistent handle if we're unsuccessful in actually using it later on
quickscope_wrapper persistent_clearer{[&] {
if(!ok && tpm2_free_persistent(tpm2_ctx, tpm2_session, persistent_handle))
fprintf(stderr, "Couldn't free persistent handle. You might need to run \"tpm2_evictcontrol -c 0x%" PRIX32 "\" or equivalent!\n",
fprintf(stderr, gettext("Couldn't free persistent handle. You might need to run \"tpm2_evictcontrol -c 0x%X\" or equivalent!\n"),
persistent_handle);
if(!ok)
clear_key_props(dataset);

View File

@ -30,4 +30,4 @@ struct quickscope_wrapper {
};
template <class F>
quickscope_wrapper(F)->quickscope_wrapper<F>;
quickscope_wrapper(F) -> quickscope_wrapper<F>;

View File

@ -74,8 +74,17 @@ static int get_key_material_helper(const char * helper, const char * whom, bool
if(auto pid = TRY_HELPER("create child", fork()); pid == 0) { // child
dup2(pipes[1], 1);
const char * fmt;
if(!newkey && !again)
fmt = gettext("Passphrase for %s");
else if(!newkey && again)
fmt = gettext("Passphrase for %s (again)");
else if(newkey && !again)
fmt = gettext("New passphrase for %s");
else // newkey && again
fmt = gettext("New passphrase for %s (again)");
char * msg;
if(asprintf(&msg, "%sassphrase for %s%s", newkey ? "New p" : "P", whom, again ? " (again)" : "") == -1)
if(asprintf(&msg, fmt, whom) == -1)
msg = const_cast<char *>(whom);
execl("/bin/sh", "sh", "-c", helper, helper, msg, whom, newkey ? "new" : "", again ? "again" : "", nullptr);
@ -119,13 +128,11 @@ static int get_key_material_helper(const char * helper, const char * whom, bool
case 127: // ENOENT, error already written by shell or child
return -1;
default:
fprintf(stderr, "Helper '%s' failed with %d.\n", helper, WEXITSTATUS(err));
return __LINE__;
// exit status
return fprintf(stderr, gettext("Helper '%s' failed with %d.\n"), helper, WEXITSTATUS(err)), __LINE__;
}
else {
fprintf(stderr, "Helper '%s' died to signal %d: %s.\n", helper, WTERMSIG(err), strsignal(WTERMSIG(err)));
return __LINE__;
}
else
return fprintf(stderr, gettext("Helper '%s' died to signal %d: %s.\n"), helper, WTERMSIG(err), strsignal(WTERMSIG(err))), __LINE__;
}
@ -147,8 +154,8 @@ static int get_key_material_raw(const char * whom, bool again, bool newkey, uint
caught_interrupt = 0;
act.sa_handler = [](auto sig) {
caught_interrupt = sig;
fputs("^C\n", stderr);
caught_interrupt = sig;
fputs("^C\n", stderr);
};
sigaction(SIGINT, &act, &osigint);
@ -156,7 +163,16 @@ static int get_key_material_raw(const char * whom, bool again, bool newkey, uint
sigaction(SIGTSTP, &act, &osigtstp);
// Prompt for the key
printf("%s %spassphrase for %s: ", again ? "Re-enter" : "Enter", newkey ? "new " : "", whom);
const char * fmt;
if(!again && !newkey)
fmt = gettext("Enter passphrase for %s: ");
else if(!again && newkey)
fmt = gettext("Enter passphrase for new %s: ");
else if(again && !newkey)
fmt = gettext("Re-enter passphrase for %s: ");
else // again && newkey
fmt = gettext("Re-enter passphrase for new %s: ");
printf(fmt, whom);
fflush(stdout);
// Disable the terminal echo for key input
@ -232,7 +248,7 @@ int read_known_passphrase(const char * whom, uint8_t *& buf, size_t & len_out, s
if(len_out <= max_len)
return 0;
fprintf(stderr, "Passphrase too long (max %zu)\n", max_len);
fprintf(stderr, gettext("Passphrase too long (max %zu)\n"), max_len);
free(buf);
buf = nullptr;
len_out = 0;
@ -246,9 +262,9 @@ int read_new_passphrase(const char * whom, uint8_t *& buf, size_t & len_out, siz
quickscope_wrapper first_passphrase_deleter{[&] { free(first_passphrase); }};
if(first_passphrase_len != 0 && first_passphrase_len < MIN_PASSPHRASE_LEN)
return fprintf(stderr, "Passphrase too short (min %u)\n", MIN_PASSPHRASE_LEN), __LINE__;
return fprintf(stderr, gettext("Passphrase too short (min %u)\n"), MIN_PASSPHRASE_LEN), __LINE__;
if(first_passphrase_len > max_len)
return fprintf(stderr, "Passphrase too long (max %zu)\n", max_len), __LINE__;
return fprintf(stderr, gettext("Passphrase too long (max %zu)\n"), max_len), __LINE__;
uint8_t * second_passphrase{};
size_t second_passphrase_len{};
@ -256,7 +272,7 @@ int read_new_passphrase(const char * whom, uint8_t *& buf, size_t & len_out, siz
quickscope_wrapper second_passphrase_deleter{[&] { free(second_passphrase); }};
if(second_passphrase_len != first_passphrase_len || memcmp(first_passphrase, second_passphrase, first_passphrase_len))
return fprintf(stderr, "Provided keys do not match.\n"), __LINE__;
return fprintf(stderr, gettext("Provided passphrases do not match.\n")), __LINE__;
if(second_passphrase_len)
buf = std::exchange(second_passphrase, nullptr);

View File

@ -5,16 +5,16 @@
#include "common.hpp"
#include <unistd.h>
#include <stdint.h>
#include <unistd.h>
template <class F>
int with_stdin_at(int fd, F && what) {
auto stdin_saved = TRY("dup() stdin", dup(0));
auto stdin_saved = dup(0);
quickscope_wrapper stdin_saved_deleter{[=] { close(stdin_saved); }};
TRY("dup2() onto stdin", dup2(fd, 0));
dup2(fd, 0);
clearerr(stdin);
if(int ret = what()) {
@ -22,7 +22,7 @@ int with_stdin_at(int fd, F && what) {
return ret;
}
TRY("dup2() stdin back onto stdin", dup2(stdin_saved, 0));
dup2(stdin_saved, 0);
return 0;
}

View File

@ -5,10 +5,13 @@
#include "common.hpp"
#include <libintl.h>
#include <libzfs.h>
#include <locale.h>
#include <stdlib.h>
#include <type_traits>
#include <unistd.h>
#define gettext_noop(s) s
#define TRY_PTR(what, ...) TRY_GENERIC(what, !, , errno, __LINE__, strerror, __VA_ARGS__)
@ -23,6 +26,11 @@ template <class G, class M, class V = int (*)()>
static int do_bare_main(
int argc, char ** argv, const char * getoptions, const char * usage, const char * dataset_usage, G && getoptfn, M && main,
V && validate = []() { return 0; }) {
setlocale(LC_ALL, "");
// bindtextdomain("tzpfms", "/usr/share/locale");
bindtextdomain("tzpfms", "out/loc");
textdomain("tzpfms");
const auto libz = TRY_PTR("initialise libzfs", libzfs_init());
quickscope_wrapper libz_deleter{[=] { libzfs_fini(libz); }};
@ -35,7 +43,8 @@ static int do_bare_main(
switch(opt) {
case '?':
case 'h':
fprintf(opt == 'h' ? stdout : stderr, "Usage: %s [-hV] %s%s%s\n", argv[0], usage, strlen(usage) ? " " : "", dataset_usage);
fprintf(opt == 'h' ? stdout : stderr, gettext("usage: %s [-hV] %s%s%s\n"), argv[0], *usage ? gettext(usage) : "", *usage ? " " : "",
gettext(dataset_usage));
return opt == 'h' ? 0 : __LINE__;
case 'V':
puts("tzpfms version " TZPFMS_VERSION);
@ -47,29 +56,29 @@ static int do_bare_main(
TRY_MAIN(getoptfn(opt));
else {
if(auto err = getoptfn(opt))
return fprintf(stderr, "Usage: %s [-hV] %s%s%s\n", argv[0], usage, strlen(usage) ? " " : "", dataset_usage), err;
return fprintf(stderr, gettext("usage: %s [-hV] %s%s%s\n"), argv[0], *usage ? gettext(usage) : "", *usage ? " " : "", gettext(dataset_usage)), err;
}
}
if(auto err = validate())
return fprintf(stderr, "Usage: %s [-hV] %s%s%s\n", argv[0], usage, strlen(usage) ? " " : "", dataset_usage), err;
return fprintf(stderr, gettext("usage: %s [-hV] %s%s%s\n"), argv[0], *usage ? gettext(usage) : "", *usage ? " " : "", gettext(dataset_usage)), err;
return main(libz);
}
template <class G, class M, class V = int (*)()>
static int do_main(
int argc, char ** argv, const char * getoptions, const char * usage, G && getoptfn, M && main, V && validate = []() { return 0; }) {
static int do_main(int argc, char ** argv, const char * getoptions, const char * usage, G && getoptfn, M && main, V && validate = []() { return 0; }) {
return do_bare_main(
argc, argv, getoptions, usage, "dataset", getoptfn,
// as-in argument in a usage string
argc, argv, getoptions, usage, gettext_noop("dataset"), getoptfn,
[&](auto libz) {
if(!*(argv + optind))
return fprintf(stderr,
"No dataset to act on?\n"
"Usage: %s [-hV] %s%sdataset\n",
gettext("No dataset to act on?\n"
"usage: %s [-hV] %s%sdataset\n"),
argv[0], usage, strlen(usage) ? " " : ""),
__LINE__;
if(*(argv + optind + 1))
return fprintf(stderr, "Usage: %s [-hV] %s%sdataset\n", argv[0], usage, strlen(usage) ? " " : ""), __LINE__;
return fprintf(stderr, gettext("usage: %s [-hV] %s%sdataset\n"), argv[0], usage, strlen(usage) ? " " : ""), __LINE__;
auto dataset = TRY_PTR(nullptr, zfs_open(libz, argv[optind], ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME));
quickscope_wrapper dataset_deleter{[&] { zfs_close(dataset); }};
@ -79,9 +88,9 @@ static int do_main(
TRY("get encryption root", zfs_crypto_get_encryption_root(dataset, &dataset_is_root, encryption_root));
if(!dataset_is_root && !strlen(encryption_root))
return fprintf(stderr, "Dataset %s not encrypted?\n", zfs_get_name(dataset)), __LINE__;
return fprintf(stderr, gettext("Dataset %s not encrypted?\n"), zfs_get_name(dataset)), __LINE__;
else if(!dataset_is_root) {
fprintf(stderr, "Using dataset %s's encryption root %s instead.\n", zfs_get_name(dataset), encryption_root);
fprintf(stderr, gettext("Using dataset %s's encryption root %s instead.\n"), zfs_get_name(dataset), encryption_root);
zfs_close(dataset);
dataset = TRY_PTR(nullptr, zfs_open(libz, encryption_root, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME));
}

View File

@ -13,7 +13,7 @@ int do_clear_main(int argc, char ** argv, const char * this_backend, H && handle
return do_main(
argc, argv, "", "", [&](auto) {},
[&](auto dataset) {
REQUIRE_KEY_LOADED(dataset);
REQUIRE_KEY_LOADED(dataset);
char * handle_s{};
TRY_MAIN(parse_key_props(dataset, this_backend, handle_s));

View File

@ -1,13 +1,13 @@
/* SPDX-License-Identifier: MIT */
// SPDX-License-Identifier: 0BSD
#pragma once
#include <charconv>
#include <errno.h>
#include <limits>
#include <stdio.h>
#include <errno.h>
#include <string.h>

View File

@ -97,9 +97,11 @@ int tpm1x_parse_pcrs(char * arg, uint32_t *& pcrs, size_t & pcrs_len) {
for(arg = strtok_r(arg, ", ", &sv); arg; arg = strtok_r(nullptr, ", ", &sv)) {
uint32_t pcr;
if(!parse_uint(arg, pcr))
return fprintf(stderr, "PCR %s: %s\n", arg, strerror(errno)), __LINE__;
// user-supplied parameter, errno
return fprintf(stderr, gettext("PCR %s: %s\n"), arg, strerror(errno)), __LINE__;
if(pcr >= 230)
return fprintf(stderr, "PCR %s: too large (max 229).\n", arg), __LINE__;
// user-supplied parameter
return fprintf(stderr, gettext("PCR %s: too large (max 229).\n"), arg), __LINE__;
auto idx = std::upper_bound(pcrs, pcrs + pcrs_len, pcr) - pcrs;
if(!idx || pcrs[idx - 1] != pcr) {

View File

@ -9,7 +9,8 @@
#include <algorithm>
#include <inttypes.h>
#include <iterator>
#define OPENSSL_SUPPRESS_DEPRECATED // SHA256_*(); supposedly replaced with EVP* but that's horseshit. we'll see how she turns out, given there's no reason given
#define OPENSSL_SUPPRESS_DEPRECATED // SHA256_*(); supposedly replaced with EVP* but that's horseshit. we'll see how she turns out, given there's no reason
// given
#include <openssl/sha.h>
#include <optional>
#include <utility>
@ -20,7 +21,7 @@ static int try_or_passphrase(const char * what, const char * what_for, ESYS_CONT
auto err = func();
for(int i = 0; err == TPM2_RC_9 + valid_error && i < 3; ++i) {
if(i)
fprintf(stderr, "Couldn't %s: %s\n", what, Tss2_RC_Decode(err));
fprintf(stderr, "Couldn't %s: %s\n", gettext(what), Tss2_RC_Decode(err));
uint8_t * pass{};
size_t pass_len{};
@ -37,7 +38,7 @@ static int try_or_passphrase(const char * what, const char * what_for, ESYS_CONT
// TRY_TPM2() unrolled because no constexpr/string-literal-template arguments until C++20, which is not supported by GCC 8, which we need for Buster
if(err != TPM2_RC_SUCCESS)
return fprintf(stderr, "Couldn't %s: %s\n", what, Tss2_RC_Decode(err)), __LINE__;
return fprintf(stderr, "Couldn't %s: %s\n", gettext(what), Tss2_RC_Decode(err)), __LINE__;
return 0;
}
@ -112,7 +113,8 @@ int tpm2_parse_pcrs(char * arg, TPML_PCR_SELECTION & pcrs) {
++per_hash;
if(bank == pcrs.pcrSelections + (sizeof(pcrs.pcrSelections) / sizeof(*pcrs.pcrSelections))) // == TPM2_NUM_PCR_BANKS
return fprintf(stderr, "Too many PCR banks specified! Can only have up to %zu\n", sizeof(pcrs.pcrSelections) / sizeof(*pcrs.pcrSelections)), __LINE__;
return fprintf(stderr, gettext("Too many PCR banks specified! Can only have up to %zu\n"), sizeof(pcrs.pcrSelections) / sizeof(*pcrs.pcrSelections)),
__LINE__;
if(auto sep = strchr(per_hash, ':')) {
*sep = '\0';
@ -127,8 +129,9 @@ int tpm2_parse_pcrs(char * arg, TPML_PCR_SELECTION & pcrs) {
if(!parse_uint(per_hash, bank->hash) || !std::binary_search(std::begin(tpm2_hash_algs), std::end(tpm2_hash_algs), tpm2_hash_algs_t{bank->hash, {}},
[&](auto && lhs, auto && rhs) { return lhs.alg < rhs.alg; })) {
fprintf(stderr,
"Unknown hash algorithm %s.\n"
"Can be any of case-insensitive ",
// comma-separated list follows
gettext("Unknown hash algorithm %s.\n"
"Can be any of case-insensitive "),
per_hash);
auto first = true;
for(auto && alg : tpm2_hash_algs)
@ -157,7 +160,8 @@ int tpm2_parse_pcrs(char * arg, TPML_PCR_SELECTION & pcrs) {
}
}
} else
return fprintf(stderr, "PCR bank \"%s\": no algorithm; need alg:PCR[,PCR]...\n", per_hash), __LINE__;
// user-passed parameter
return fprintf(stderr, gettext("PCR bank \"%s\": no algorithm; need alg:PCR[,PCR]…\n"), per_hash), __LINE__;
}
pcrs.count = bank - pcrs.pcrSelections;
@ -299,8 +303,8 @@ static int tpm2_police_pcrs(ESYS_CONTEXT * tpm2_ctx, const TPML_PCR_SELECTION &
return with_session(pcr_session);
}
int tpm2_seal(const char * dataset, ESYS_CONTEXT * tpm2_ctx, ESYS_TR tpm2_session, TPMI_DH_PERSISTENT & persistent_handle,
const TPML_PCR_SELECTION & pcrs, bool allow_PCR_or_pass, void * data, size_t data_len) {
int tpm2_seal(const char * dataset, ESYS_CONTEXT * tpm2_ctx, ESYS_TR tpm2_session, TPMI_DH_PERSISTENT & persistent_handle, const TPML_PCR_SELECTION & pcrs,
bool allow_PCR_or_pass, void * data, size_t data_len) {
ESYS_TR primary_handle = ESYS_TR_NONE;
quickscope_wrapper primary_handle_deleter{[&] { Esys_FlushContext(tpm2_ctx, primary_handle); }};
@ -365,8 +369,9 @@ int tpm2_seal(const char * dataset, ESYS_CONTEXT * tpm2_ctx, ESYS_TR tpm2_sessio
memcpy(secret_sens.sensitive.data.buffer, data, secret_sens.sensitive.data.size);
if(!pcrs.count || allow_PCR_or_pass) {
char what_for[ZFS_MAX_DATASET_NAME_LEN + 38 + 1];
snprintf(what_for, sizeof(what_for), "%s TPM2 wrapping key (or empty for none)", dataset);
char what_for[ZFS_MAX_DATASET_NAME_LEN + 512 + 1];
// %s=dataset name, then TPM2. noun for "Enter passphrase for" prompt
snprintf(what_for, sizeof(what_for), gettext("%s %s wrapping key (or empty for none)"), dataset, "TPM2");
uint8_t * passphrase{};
size_t passphrase_len{};
@ -415,8 +420,9 @@ int tpm2_seal(const char * dataset, ESYS_CONTEXT * tpm2_ctx, ESYS_TR tpm2_sessio
int tpm2_unseal(const char * dataset, ESYS_CONTEXT * tpm2_ctx, ESYS_TR tpm2_session, TPMI_DH_PERSISTENT persistent_handle, const TPML_PCR_SELECTION & pcrs,
void * data, size_t data_len) {
// Esys_FlushContext(tpm2_ctx, tpm2_session);
char what_for[ZFS_MAX_DATASET_NAME_LEN + 18 + 1];
snprintf(what_for, sizeof(what_for), "%s TPM2 wrapping key", dataset);
char what_for[ZFS_MAX_DATASET_NAME_LEN + 512 + 1];
// %s=dataset name, then TPM2. noun for "Enter passphrase for" prompt
snprintf(what_for, sizeof(what_for), gettext("%s %s wrapping key"), dataset, "TPM2");
// Entirely fake and not flushable (tpm:parameter(1):value is out of range or is not correct for the context)
ESYS_TR pandle;
@ -430,7 +436,7 @@ int tpm2_unseal(const char * dataset, ESYS_CONTEXT * tpm2_ctx, ESYS_TR tpm2_sess
// In case there's (PCR policy || passphrase): try PCR once; if it fails, fall back to passphrase
if(pcr_session != ESYS_TR_NONE) {
if(auto err = unseal(pcr_session); err != TPM2_RC_SUCCESS)
fprintf(stderr, "Couldn't %s with PCR policy: %s\n", "unseal wrapping key", Tss2_RC_Decode(err));
fprintf(stderr, gettext("Couldn't unseal wrapping key with PCR policy: %s\n"), Tss2_RC_Decode(err));
else
return 0;
}

View File

@ -98,8 +98,8 @@ int clear_key_props(zfs_handle_t * from) {
bool ok = false;
quickscope_wrapper props_deleter{[&] {
if(!ok)
fprintf(stderr, "You might need to run \"zfs inherit %s %s\" and \"zfs inherit %s %s\" to fully clear metadata!\n", PROPNAME_BACKEND, zfs_get_name(from),
PROPNAME_KEY, zfs_get_name(from));
fprintf(stderr, gettext("You might need to run \"zfs inherit %s %s\" and \"zfs inherit %s %s\" to fully clear metadata!\n"), PROPNAME_BACKEND,
zfs_get_name(from), PROPNAME_KEY, zfs_get_name(from));
}};
TRY("delete tzpfms.backend", zfs_prop_inherit(from, PROPNAME_BACKEND, B_FALSE));
@ -113,13 +113,13 @@ int parse_key_props(zfs_handle_t * in, const char * our_backend, char *& handle)
TRY_MAIN(lookup_userprop(in, PROPNAME_BACKEND, backend));
if(!backend)
return fprintf(stderr, "Dataset %s not encrypted with tzpfms!\n", zfs_get_name(in)), __LINE__;
return fprintf(stderr, gettext("Dataset %s not encrypted with tzpfms!\n"), zfs_get_name(in)), __LINE__;
if(strcmp(backend, our_backend))
return fprintf(stderr, "Dataset %s encrypted with tzpfms back-end %s, but we are %s.\n", zfs_get_name(in), backend, our_backend), __LINE__;
return fprintf(stderr, gettext("Dataset %s encrypted with tzpfms back-end %s, but we are %s.\n"), zfs_get_name(in), backend, our_backend), __LINE__;
TRY_MAIN(lookup_userprop(in, PROPNAME_KEY, handle));
if(!handle)
return fprintf(stderr, "Dataset %s missing key data.\n", zfs_get_name(in)), __LINE__;
return fprintf(stderr, gettext("Dataset %s missing key data.\n"), zfs_get_name(in)), __LINE__;
return 0;
}

View File

@ -20,10 +20,10 @@
/// Mimic libzfs error output
#define REQUIRE_KEY_LOADED(dataset) \
do { \
if(zfs_prop_get_int(dataset, ZFS_PROP_KEYSTATUS) == ZFS_KEYSTATUS_UNAVAILABLE) \
return fprintf(stderr, "Key change error: Key must be loaded.\n"), __LINE__; \
#define REQUIRE_KEY_LOADED(dataset) \
do { \
if(zfs_prop_get_int(dataset, ZFS_PROP_KEYSTATUS) == ZFS_KEYSTATUS_UNAVAILABLE) \
return fprintf(stderr, gettext("Key change error: Key must be loaded.\n")), __LINE__; \
} while(0)
@ -65,10 +65,14 @@ int verify_backend(zfs_handle_t * on, const char * this_backend, F && func) {
TRY_MAIN(lookup_userprop(on, PROPNAME_KEY, previous_handle));
if(!!previous_backend ^ !!previous_handle)
fprintf(stderr, "Inconsistent tzpfms metadata for %s: back-end is %s, but handle is %s?\n", zfs_get_name(on), previous_backend, previous_handle);
// dataset name: (null), 0A123...
// dataset name: TPM1.X, (null)
fprintf(stderr, gettext("Inconsistent tzpfms metadata for %s: back-end is %s, but handle is %s?\n"), zfs_get_name(on), previous_backend, previous_handle);
else if(previous_backend && previous_handle) {
if(strcmp(previous_backend, this_backend))
fprintf(stderr, "Dataset %s was encrypted with tzpfms back-end %s before, but we are %s. You will have to free handle %s for back-end %s manually!\n",
// dataset name: TPM1.X, TPM2. 0A1234..., TPM1.X
fprintf(stderr,
gettext("Dataset %s was encrypted with tzpfms back-end %s before, but we are %s. You will have to free handle %s for back-end %s manually!\n"),
zfs_get_name(on), previous_backend, this_backend, previous_handle, previous_backend);
else
func(previous_handle);

View File

@ -30,7 +30,7 @@ int change_key(zfs_handle_t * on, const uint8_t * wrap_key) {
if(zfs_crypto_rewrap(on, TRY_PTR("get rewrap args", rewrap_args()), B_FALSE))
return __LINE__; // Error printed by libzfs
else
printf("Key for %s changed\n", zfs_get_name(on));
printf(gettext("Key for %s changed\n"), zfs_get_name(on));
return 0;
});
@ -41,8 +41,11 @@ int load_key(zfs_handle_t * for_d, const uint8_t * wrap_key, bool noop) {
return with_stdin_at_buffer(wrap_key, WRAPPING_KEY_LEN, [&] {
if(zfs_crypto_load_key(for_d, noop ? B_TRUE : B_FALSE, nullptr))
return __LINE__; // Error printed by libzfs
else
printf("Key for %s %s\n", zfs_get_name(for_d), noop ? "OK" : "loaded");
else //
if(noop)
printf(gettext("Key for %s OK\n"), zfs_get_name(for_d));
else
printf(gettext("Key for %s loaded\n"), zfs_get_name(for_d));
return 0;
});

View File

@ -45,6 +45,11 @@
"name": "Manpages",
"path": "man"
},
{
"follow_symlinks": true,
"name": "Localisation",
"path": "po"
},
{
"follow_symlinks": true,
"name": "Build scripts",