From 47cd20aa321a096e49f6fc255242de740be70f96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=BD=D0=B0=D0=B1?= Date: Sat, 25 Nov 2023 17:30:20 +0100 Subject: [PATCH] Translate to Polish --- .gitignore | 2 + LICENSES/0BSD | 10 ++ Makefile | 25 ++- po/pl.po | 282 +++++++++++++++++++++++++++++++ src/bin/zfs-tpm-list.cpp | 66 ++++++-- src/bin/zfs-tpm1x-change-key.cpp | 7 +- src/bin/zfs-tpm1x-load-key.cpp | 9 +- src/bin/zfs-tpm2-change-key.cpp | 16 +- src/common.hpp | 2 +- src/fd.cpp | 44 +++-- src/fd.hpp | 8 +- src/main.hpp | 31 ++-- src/main_clear.hpp | 2 +- src/parse.hpp | 4 +- src/tpm1x.cpp | 6 +- src/tpm2.cpp | 34 ++-- src/zfs.cpp | 10 +- src/zfs.hpp | 16 +- src/zfs_meat.cpp | 9 +- tzpfms.sublime-project | 5 + 20 files changed, 492 insertions(+), 96 deletions(-) create mode 100644 LICENSES/0BSD create mode 100644 po/pl.po diff --git a/.gitignore b/.gitignore index 09c0269..9450eee 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,5 @@ !initrd/** !init.d !init.d/** +!po +!po/** diff --git a/LICENSES/0BSD b/LICENSES/0BSD new file mode 100644 index 0000000..d2a45fa --- /dev/null +++ b/LICENSES/0BSD @@ -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. diff --git a/Makefile b/Makefile index 466f4fc..637c8c8 100644 --- a/Makefile +++ b/Makefile @@ -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 $< > $@ diff --git a/po/pl.po b/po/pl.po new file mode 100644 index 0000000..3cea4af --- /dev/null +++ b/po/pl.po @@ -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" diff --git a/src/bin/zfs-tpm-list.cpp b/src/bin/zfs-tpm-list.cpp index 45ca7e3..37f7cb6 100644 --- a/src/bin/zfs-tpm-list.cpp +++ b/src/bin/zfs-tpm-list.cpp @@ -6,6 +6,7 @@ #include "../zfs.hpp" #include +#include #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(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(max_name_len), name, separator, // static_cast(max_backend_len), backend, separator, // static_cast(max_key_available_len), key_available, separator, // - static_cast(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]); diff --git a/src/bin/zfs-tpm1x-change-key.cpp b/src/bin/zfs-tpm1x-change-key.cpp index f587206..9ebf34f 100644 --- a/src/bin/zfs-tpm1x-change-key.cpp +++ b/src/bin/zfs-tpm1x-change-key.cpp @@ -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{}; diff --git a/src/bin/zfs-tpm1x-load-key.cpp b/src/bin/zfs-tpm1x-load-key.cpp index 2047771..616d9fa 100644 --- a/src/bin/zfs-tpm1x-load-key.cpp +++ b/src/bin/zfs-tpm1x-load-key.cpp @@ -5,7 +5,6 @@ // #include #define WRAPPING_KEY_LEN 32 -#include #include #include #include @@ -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"); diff --git a/src/bin/zfs-tpm2-change-key.cpp b/src/bin/zfs-tpm2-change-key.cpp index 934607b..5354bf5 100644 --- a/src/bin/zfs-tpm2-change-key.cpp +++ b/src/bin/zfs-tpm2-change-key.cpp @@ -5,7 +5,6 @@ // #include #define WRAPPING_KEY_LEN 32 -#include #include #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); diff --git a/src/common.hpp b/src/common.hpp index d4b5ed9..e43bfa9 100644 --- a/src/common.hpp +++ b/src/common.hpp @@ -30,4 +30,4 @@ struct quickscope_wrapper { }; template -quickscope_wrapper(F)->quickscope_wrapper; +quickscope_wrapper(F) -> quickscope_wrapper; diff --git a/src/fd.cpp b/src/fd.cpp index 2a190d1..6cd8118 100644 --- a/src/fd.cpp +++ b/src/fd.cpp @@ -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(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); diff --git a/src/fd.hpp b/src/fd.hpp index 03b4b14..3d9e1dc 100644 --- a/src/fd.hpp +++ b/src/fd.hpp @@ -5,16 +5,16 @@ #include "common.hpp" -#include #include +#include template 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; } diff --git a/src/main.hpp b/src/main.hpp index 0b8f6a6..e9807f4 100644 --- a/src/main.hpp +++ b/src/main.hpp @@ -5,10 +5,13 @@ #include "common.hpp" +#include #include +#include #include #include #include +#define gettext_noop(s) s #define TRY_PTR(what, ...) TRY_GENERIC(what, !, , errno, __LINE__, strerror, __VA_ARGS__) @@ -23,6 +26,11 @@ template 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 -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)); } diff --git a/src/main_clear.hpp b/src/main_clear.hpp index e86e721..f382c7d 100644 --- a/src/main_clear.hpp +++ b/src/main_clear.hpp @@ -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)); diff --git a/src/parse.hpp b/src/parse.hpp index bb2372c..af3bdc0 100644 --- a/src/parse.hpp +++ b/src/parse.hpp @@ -1,13 +1,13 @@ -/* SPDX-License-Identifier: MIT */ +// SPDX-License-Identifier: 0BSD #pragma once #include +#include #include #include -#include #include diff --git a/src/tpm1x.cpp b/src/tpm1x.cpp index cc09831..61ce501 100644 --- a/src/tpm1x.cpp +++ b/src/tpm1x.cpp @@ -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) { diff --git a/src/tpm2.cpp b/src/tpm2.cpp index 88fbfb0..4926a07 100644 --- a/src/tpm2.cpp +++ b/src/tpm2.cpp @@ -9,7 +9,8 @@ #include #include #include -#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 #include #include @@ -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; } diff --git a/src/zfs.cpp b/src/zfs.cpp index b84d4aa..196340d 100644 --- a/src/zfs.cpp +++ b/src/zfs.cpp @@ -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; } diff --git a/src/zfs.hpp b/src/zfs.hpp index 5c37731..5a0af1a 100644 --- a/src/zfs.hpp +++ b/src/zfs.hpp @@ -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); diff --git a/src/zfs_meat.cpp b/src/zfs_meat.cpp index 9a8a80b..2317fb8 100644 --- a/src/zfs_meat.cpp +++ b/src/zfs_meat.cpp @@ -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; }); diff --git a/tzpfms.sublime-project b/tzpfms.sublime-project index 42f072d..bcf0ba0 100644 --- a/tzpfms.sublime-project +++ b/tzpfms.sublime-project @@ -45,6 +45,11 @@ "name": "Manpages", "path": "man" }, + { + "follow_symlinks": true, + "name": "Localisation", + "path": "po" + }, { "follow_symlinks": true, "name": "Build scripts",