Extend localization support.

Localize purr.c so both main executables are localized, plus some
library code. Refactor some message printing so localization is easier.
This commit is contained in:
Érico Rolim 2020-11-11 01:18:17 -03:00 committed by Érico Nogueira Rolim
parent 4cb82f0bff
commit 4b3f41d0f9
8 changed files with 317 additions and 53 deletions

4
gemi.c
View File

@ -124,7 +124,7 @@ int main(int argc, char **argv)
char request[GEMINI_REQUEST];
int written = snprintf(request, going_to_write, "%s%s%s\r\n", scheme, domain, path);
if (written >= going_to_write) {
fputs(_("truncated request!\n"), stderr);
fputs(_("error: truncated request!\n"), stderr);
goto early_out;
}
if (debug) fprintf(stderr, _("request: %s"), request);
@ -218,7 +218,7 @@ int main(int argc, char **argv)
if ((socket = host_connect(domain, port, debug)) < 0) {
fputs(_("host_connect(): couldn't open socket or find domain\n"), stderr);
host_connect_error_message();
}
signal(SIGPIPE, SIG_IGN);

View File

@ -1 +1,4 @@
gemi.c
purr.c
urls.c
read_certs.c

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: purr-c\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-11-11 00:08-0300\n"
"POT-Creation-Date: 2020-11-11 01:28-0300\n"
"PO-Revision-Date: 2020-11-11 00:08-0300\n"
"Last-Translator: Automatically generated\n"
"Language-Team: none\n"
@ -18,7 +18,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
#: gemi.c:27
#: gemi.c:26
msgid ""
"Usage: gemi [options] <url>\n"
"Options:\n"
@ -32,7 +32,7 @@ msgid ""
" -r: number of redirections (internal use)\n"
"Environment:\n"
msgstr ""
"Uso: gemi [opções] <url>\n"
"Forma de uso: gemi [opções] <url>\n"
"Opçõess:\n"
" -b: modo navegador (experimental)\n"
" -p: utilizar paginador: valor de PAGER (padrão é o programa less)\n"
@ -48,9 +48,9 @@ msgstr ""
msgid "this isn't a gemini url!\n"
msgstr "isso não é um endereço gemini!\n"
#: gemi.c:127
msgid "truncated request!\n"
msgstr "o pedido foi truncado!\n"
#: gemi.c:127 purr.c:354
msgid "error: truncated request!\n"
msgstr "erro: o pedido foi truncado!\n"
#: gemi.c:130
#, c-format
@ -70,10 +70,6 @@ msgstr "HOME é longo demais!\n"
msgid "error reading cert file: '%s'\n"
msgstr "erro ao ler o arquivo de certificado: '%s'\n"
#: gemi.c:221
msgid "host_connect(): couldn't open socket or find domain\n"
msgstr "host_connect(): não foi possível abrir a socket ou achar o domínio\n"
#: gemi.c:262
msgid "null public key\n"
msgstr "chave pública nula\n"
@ -117,7 +113,8 @@ msgstr "Links encontrados: %d\n"
#: gemi.c:359
msgid "Input link number (starts at 0) or control char ('?' or 'i'): "
msgstr "Entre o número do link (começa em 0) ou caractere de controle ('?' ou 'i'): "
msgstr ""
"Entre o número do link (começa em 0) ou caractere de controle ('?' ou 'i'): "
#: gemi.c:375
#, c-format
@ -140,3 +137,138 @@ msgstr "Entrada ruim!\n"
#: gemi.c:428
msgid "Unsupported protocol!\n"
msgstr "Protocolo não suportado!\n"
#: purr.c:29
msgid ""
"Usage: meow [options] <file>\n"
" send <file> in encrypted format\n"
msgstr ""
"Forma de uso: meow [opções] <arquivo>\n"
" enviar <arquivo> de forma encriptada\n"
#: purr.c:33
msgid ""
"Usage meowd [options] <url>\n"
" receive encrypted file from <url>\n"
msgstr ""
"Forma de uso: meowd [opções] <url>\n"
" receber arquivo encriptado de <url>\n"
#: purr.c:37
msgid ""
"Usage: purr [options] <action> <file>|<url>\n"
" action: s[end] | r[ecv]\n"
msgstr ""
"Forma de uso: purr [opções] <ação> <arquivo>|<url>\n"
" acão: s[end] | r[ecv] (enviar ou receber)\n"
#: purr.c:43
#, c-format
msgid ""
"%sOptions:\n"
" -a <algo>: choose algorithm, none available\n"
" -u <url>: URL to use for send functionality\n"
" -p <port>: port to use for send\n"
" -o <output_file>: use file instead of stdout\n"
" -n: don't strip HTTP header from response\n"
" -e: encrypt content: limited to 128KiB files\n"
" -d: debug\n"
" -h: show this dialog\n"
"Environment:\n"
msgstr ""
"%sOpções:\n"
" -a <algo>: escolher algoritmo, nenhum disponível\n"
" -u <url>: URL utilizada para envio\n"
" -p <porta>: porta utilizada para envio\n"
" -o <arquivo_de_saída>: utilize esse arquivo ao invés da saída padrão\n"
" -n: não esconder cabeçalho HTTP da resposta\n"
" -e: encriptar conteúdo: limitado a aquivos de 128KiB\n"
" -d: rodar em modo de debug\n"
" -h: mostrar essa mensagem\n"
"Ambiente:\n"
#: purr.c:155
msgid "couldn't open output stream"
msgstr "não foi possível abrir stream de saída"
#: purr.c:171
msgid "couldn't open output file"
msgstr "não foi possível abrir arquivo de saída"
#: purr.c:182
msgid "discarding url arg...\n"
msgstr "descartando argumento de URL...\n"
#: purr.c:219
msgid "couldn't parse URL!\n"
msgstr "não foi possível parsear a URL!\n"
#: purr.c:223
msgid "only supports HTTP and HTTPS for now!\n"
msgstr "apenas suporta HTTP e HTTPS por enquanto!\n"
#: purr.c:253
msgid "error decoding url"
msgstr "erro ao decodificar a URL"
#: purr.c:275
msgid "reading certs...\n"
msgstr "lendo certificados...\n"
#: purr.c:279
msgid "couldn't open certs\n"
msgstr "não foi possível abrir certificados\n"
#: purr.c:310
msgid "ALPN mismatch\n"
msgstr "desencontro de ALPN\n"
#: purr.c:386
msgid "couldn't clean up received link"
msgstr "não foi possível limpar o link recebido"
#. offset is 0 when use_stream is true, so no double printing is done
#: purr.c:417
msgid "might not have written all data\n"
msgstr "pode ser que nem todos os dados tenham sido escritos\n"
#: urls.c:39
msgid "scheme is too long"
msgstr "o nome de protocolo é longo demais"
#: urls.c:51 urls.c:92
msgid "unknown protocol"
msgstr "protocolo desconhecido"
#: urls.c:127
msgid "malformed URL"
msgstr "URL mal formada"
#: urls.c:166 urls.c:173
msgid "malformed KEY and/or IV input"
msgstr "entrada de chave ou vetor de inicialização mal formada"
#: urls.c:210
msgid "unsupported addr result"
msgstr "resultado de endereço não suportado"
#: urls.c:215
msgid "IP address"
msgstr "endereço IP"
#: urls.c:245
msgid "couldn't open socket or find domain"
msgstr "não foi possível abrir a socket ou achar o domínio"
#: read_certs.c:18
msgid "CA_CERT_SSL_FILE: certificates file, default is /etc/ssl/certs.pem"
msgstr "CA_CERT_SSL_FILE: arquivo de certificados, padrão é /etc/ssl/certs.pem"
#: read_certs.c:146
#, c-format
msgid "X509 err code: %d\n"
msgstr "código de erro X509: %d\n"
#: read_certs.c:195
msgid "non supported key\n"
msgstr "chave não suportado\n"

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: purr-c\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-11-11 00:06-0300\n"
"POT-Creation-Date: 2020-11-11 01:28-0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -17,7 +17,7 @@ msgstr ""
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
#: gemi.c:27
#: gemi.c:26
msgid ""
"Usage: gemi [options] <url>\n"
"Options:\n"
@ -36,8 +36,8 @@ msgstr ""
msgid "this isn't a gemini url!\n"
msgstr ""
#: gemi.c:127
msgid "truncated request!\n"
#: gemi.c:127 purr.c:354
msgid "error: truncated request!\n"
msgstr ""
#: gemi.c:130
@ -58,10 +58,6 @@ msgstr ""
msgid "error reading cert file: '%s'\n"
msgstr ""
#: gemi.c:221
msgid "host_connect(): couldn't open socket or find domain\n"
msgstr ""
#: gemi.c:262
msgid "null public key\n"
msgstr ""
@ -128,3 +124,122 @@ msgstr ""
#: gemi.c:428
msgid "Unsupported protocol!\n"
msgstr ""
#: purr.c:29
msgid ""
"Usage: meow [options] <file>\n"
" send <file> in encrypted format\n"
msgstr ""
#: purr.c:33
msgid ""
"Usage meowd [options] <url>\n"
" receive encrypted file from <url>\n"
msgstr ""
#: purr.c:37
msgid ""
"Usage: purr [options] <action> <file>|<url>\n"
" action: s[end] | r[ecv]\n"
msgstr ""
#: purr.c:43
#, c-format
msgid ""
"%sOptions:\n"
" -a <algo>: choose algorithm, none available\n"
" -u <url>: URL to use for send functionality\n"
" -p <port>: port to use for send\n"
" -o <output_file>: use file instead of stdout\n"
" -n: don't strip HTTP header from response\n"
" -e: encrypt content: limited to 128KiB files\n"
" -d: debug\n"
" -h: show this dialog\n"
"Environment:\n"
msgstr ""
#: purr.c:155
msgid "couldn't open output stream"
msgstr ""
#: purr.c:171
msgid "couldn't open output file"
msgstr ""
#: purr.c:182
msgid "discarding url arg...\n"
msgstr ""
#: purr.c:219
msgid "couldn't parse URL!\n"
msgstr ""
#: purr.c:223
msgid "only supports HTTP and HTTPS for now!\n"
msgstr ""
#: purr.c:253
msgid "error decoding url"
msgstr ""
#: purr.c:275
msgid "reading certs...\n"
msgstr ""
#: purr.c:279
msgid "couldn't open certs\n"
msgstr ""
#: purr.c:310
msgid "ALPN mismatch\n"
msgstr ""
#: purr.c:386
msgid "couldn't clean up received link"
msgstr ""
#. offset is 0 when use_stream is true, so no double printing is done
#: purr.c:417
msgid "might not have written all data\n"
msgstr ""
#: urls.c:39
msgid "scheme is too long"
msgstr ""
#: urls.c:51 urls.c:92
msgid "unknown protocol"
msgstr ""
#: urls.c:127
msgid "malformed URL"
msgstr ""
#: urls.c:166 urls.c:173
msgid "malformed KEY and/or IV input"
msgstr ""
#: urls.c:210
msgid "unsupported addr result"
msgstr ""
#: urls.c:215
msgid "IP address"
msgstr ""
#: urls.c:245
msgid "couldn't open socket or find domain"
msgstr ""
#: read_certs.c:18
msgid "CA_CERT_SSL_FILE: certificates file, default is /etc/ssl/certs.pem"
msgstr ""
#: read_certs.c:146
#, c-format
msgid "X509 err code: %d\n"
msgstr ""
#: read_certs.c:195
msgid "non supported key\n"
msgstr ""

47
purr.c
View File

@ -16,6 +16,7 @@
#include "purr.h"
#include "mmap_file.h"
#include "read_certs.h"
#include "translation.h"
const char *progname;
@ -24,22 +25,22 @@ static void usage(bool fail)
{
char *proghelp;
if (strcmp(progname, "meow") == 0) {
proghelp =
proghelp = _(
"Usage: meow [options] <file>\n"
" send <file> in encrypted format\n";
" send <file> in encrypted format\n");
} else if (strcmp(progname, "meowd") == 0) {
proghelp =
proghelp = _(
"Usage meowd [options] <url>\n"
" receive encrypted file from <url>\n";
" receive encrypted file from <url>\n");
} else {
proghelp =
proghelp = _(
"Usage: purr [options] <action> <file>|<url>\n"
" action: s[end] | r[ecv]\n";
" action: s[end] | r[ecv]\n");
}
FILE *stream = fail ? stderr : stdout;
fprintf(stream,
"%s"
_("%s"
"Options:\n"
" -a <algo>: choose algorithm, none available\n"
" -u <url>: URL to use for send functionality\n"
@ -49,7 +50,7 @@ static void usage(bool fail)
" -e: encrypt content: limited to 128KiB files\n"
" -d: debug\n"
" -h: show this dialog\n"
"Environment:\n",
"Environment:\n"),
proghelp
);
bearssl_read_certs_help(stream);
@ -66,6 +67,10 @@ int main (int argc, char **argv)
bool send = false, recv = false;
setlocale(LC_MESSAGES, "");
bindtextdomain(GETTEXT_PACKAGE, GETTEXT_DIR);
textdomain(GETTEXT_PACKAGE);
#ifdef HAVE_PROG_INVOCATION
progname = program_invocation_short_name;
#elif HAVE_GETPROGNAME
@ -147,7 +152,7 @@ int main (int argc, char **argv)
if (output_file && strcmp(output_file, "-")) {
output_print = fopen(output_file, "we");
if (output_print == NULL) {
perror("couldn't open output stream");
perror(_("couldn't open output stream"));
exit(EXIT_FAILURE);
}
}
@ -163,7 +168,7 @@ int main (int argc, char **argv)
output = create_mmap_from_FILE(output_print, "w");
}
if (ERROR_MMAP(output)) {
perror("couldn't open output file");
perror(_("couldn't open output file"));
exit(EXIT_FAILURE);
}
@ -179,7 +184,7 @@ int main (int argc, char **argv)
}
if (url_opt) {
fputs("discarding url arg...\n", stderr);
fputs(_("discarding url arg...\n"), stderr);
}
url = argv[1];
} else if (send) {
@ -216,11 +221,11 @@ int main (int argc, char **argv)
char *scheme = NULL, *link = NULL, *path = NULL, *port = NULL;
int portn = clean_up_link(url, &scheme, &link, &path, &port);
if (portn == -1) {
fputs("couldn't parse URL!\n", stderr);
fputs(_("couldn't parse URL!\n"), stderr);
rv = EXIT_FAILURE;
goto early_out;
} else if (portn != HTTPS_PORT && portn != HTTP_PORT) {
fputs("only supports HTTP and HTTPS for now!\n", stderr);
fputs(_("only supports HTTP and HTTPS for now!\n"), stderr);
rv = EXIT_FAILURE;
goto early_out;
}
@ -250,7 +255,7 @@ int main (int argc, char **argv)
} else if (recv && encrypt) {
int err = get_encryption_params(path, &key, &iv);
if (err) {
fputs("get_encription_params(): error decoding url\n", stderr);
fprintf(stderr, "get_encryption_params(): %s\n", _("error decoding url"));
rv = EXIT_FAILURE;
goto early_out;
}
@ -272,11 +277,11 @@ int main (int argc, char **argv)
int socket;
if (ssl) {
if (debug) {
fputs("reading certs...\n", stderr);
fputs(_("reading certs...\n"), stderr);
}
if (bearssl_read_certs(&btas, NULL) == 0) {
fputs("couldn't open certs\n", stderr);
fputs(_("couldn't open certs\n"), stderr);
goto early_out;
}
br_ssl_client_init_full(&sc, &xc, btas.ta, btas.n);
@ -291,7 +296,7 @@ int main (int argc, char **argv)
socket = host_connect(link, port, debug);
if (socket < 0) {
fputs("couldn't open socket / find domain\n", stderr);
host_connect_error_message();
goto early_out;
}
// avoid crashing on socket release
@ -307,7 +312,7 @@ int main (int argc, char **argv)
if (alpn) {
fprintf(stderr, "ALPN: %s\n", alpn);
} else {
fputs("ALPN mismatch\n", stderr);
fputs(_("ALPN mismatch\n"), stderr);
}
}
}
@ -351,7 +356,7 @@ int main (int argc, char **argv)
}
if (written >= going_to_write) {
fputs("error: truncated request!\n", stderr);
fputs(_("error: truncated request!\n"), stderr);
goto out;
}
if (debug) {
@ -383,7 +388,7 @@ int main (int argc, char **argv)
int portn_res =
clean_up_link((char *)output.data, &scheme_res, &link_res, &path_res, &port_res);
if (portn_res == -1) {
fprintf(stderr, "couldn't clean up received link: %s\n", (char *)output.data);
fprintf(stderr, "%s: %s\n", _("couldn't clean up received link"), (char *)output.data);
goto out;
}
@ -414,7 +419,7 @@ int main (int argc, char **argv)
fwrite(output.data, 1, output.offset, output_print);
} else if ((off_t)fwrite(output.data, 1, output.offset, output_print) < output.offset) {
// offset is 0 when use_stream is true, so no double printing is done
fputs("might not have written all data\n", stderr);
fputs(_("might not have written all data\n"), stderr);
}
out:

1
purr.h
View File

@ -70,6 +70,7 @@ int get_port_from_link(const char *);
int clean_up_link(const char *, char **, char **, char **, char **);
int get_encryption_params(char *, uint8_t **, uint8_t **);
int host_connect(const char *, const char *, bool);
void host_connect_error_message(void);
/* files.c */
size_t ssl_to_mmap(struct transmission_information);

View File

@ -4,6 +4,7 @@
#include <string.h>
#include "read_certs.h"
#include "translation.h"
struct append_dn_status {
uint8_t *dn;
@ -13,7 +14,8 @@ struct append_dn_status {
void bearssl_read_certs_help(FILE *stream)
{
fprintf(stream,
" CA_CERT_SSL_FILE: certificates file, default is /etc/ssl/certs.pem\n"
" %s\n",
_("CA_CERT_SSL_FILE: certificates file, default is /etc/ssl/certs.pem")
);
}
@ -141,7 +143,7 @@ size_t bearssl_read_certs(struct trust_anchors *tas, FILE *file)
case BR_PEM_END_OBJ:
err = br_x509_decoder_last_error(&x509);
if (err) {
fprintf(stderr, "X509 err code: %d\n", err);
fprintf(stderr, _("X509 err code: %d\n"), err);
} else {
// decoded succesfully, now to get the data
br_x509_trust_anchor ta =
@ -190,7 +192,7 @@ size_t bearssl_read_certs(struct trust_anchors *tas, FILE *file)
new_key.key_type = BR_KEYTYPE_EC;
new_key.key.ec = ec;
} else {
fputs("non supported key\n", stderr);
fputs(_("non supported key\n"), stderr);
}
ta.pkey = new_key;

22
urls.c
View File

@ -13,6 +13,7 @@
#include <sys/socket.h>
#include "purr.h"
#include "translation.h"
#define MAX_DOMAIN_LEN 254
#define MAX_SHORTY_LEN 16
@ -35,7 +36,7 @@ int get_port_from_link(const char *url)
if (scheme_separator) {
// found protocol specified, otherwise return error
if (scheme_separator - url + 3 > MAX_SHORTY_LEN) {
fputs("get_port_from_link(): scheme is too long!\n", stderr);
fprintf(stderr, "get_port_from_link(): %s\n", _("scheme is too long"));
return portn;
}
size_t scheme_len = scheme_separator - url + 3;
@ -47,7 +48,7 @@ int get_port_from_link(const char *url)
portn = GEMINI_PORT;
} else {
portn = UNKNOWN_PORT;
fputs("clean_up_link(): unknown protocol!\n", stderr);
fprintf(stderr, "clean_up_link(): %s\n", _("unknown protocol"));
}
}
@ -88,7 +89,7 @@ int clean_up_link(const char *dirty, char **schemep, char **cleanp, char **pathp
portn = get_port_from_link(dirty);
bool get_scheme_len = true;
if (portn == UNKNOWN_PORT) {
fputs("clean_up_link(): unknown protocol!\n", stderr);
fprintf(stderr, "clean_up_link(): %s\n", _("unknown protocol"));
return portn;
} else if (portn == NO_INFO_PORT || portn == HTTP_PORT) {
// no scheme defined -> default to HTTP
@ -123,7 +124,7 @@ int clean_up_link(const char *dirty, char **schemep, char **cleanp, char **pathp
return portn;
}
#define MALFORM_ERROR(p) do{if((p) == NULL || (p)[1] == 0) {fputs("get_encryption_params(): malformed URL\n", stderr); return rv;}}while(0);
#define MALFORM_ERROR(p) do{if((p) == NULL || (p)[1] == 0) {fprintf(stderr, "get_encryption_params(): %s\n", _("malformed URL")); return rv;}}while(0);
/*
* This function extracts encryption parameters from a path.
@ -162,14 +163,14 @@ int get_encryption_params(char *path, uint8_t **keyp, uint8_t **ivp)
size_t key_s_len = strlen(key_start), iv_s_len = strlen(iv_start);
// odd number of chars is an error, as well as being too big
if (key_s_len & 1 || iv_s_len & 1 || key_s_len / 2 > KEY_LEN || iv_s_len / 2 > IV_LEN) {
fputs("get_encryption_params(): malformed KEY and/or IV input\n", stderr);
fprintf(stderr, "get_encryption_params(): %s\n", _("malformed KEY and/or IV input"));
return rv;
}
int err = decode_hex(key_start, key, key_s_len / 2)
| decode_hex(iv_start, iv, iv_s_len / 2);
if (err) {
fputs("get_encryption_params(): malformed KEY and/or IV input\n", stderr);
fprintf(stderr, "get_encryption_params(): %s\n", _("malformed KEY and/or IV input"));
return rv;
}
@ -206,12 +207,12 @@ int host_connect(const char *host, const char *port, bool debug)
struct sockaddr_in6 *remote = (struct sockaddr_in6 *)p->ai_addr;
addr = &remote->sin6_addr;
} else {
fputs("host_connect(): unsupported addr result\n", stderr);
fprintf(stderr, "host_connect(): %s\n", _("unsupported addr result"));
continue;
}
inet_ntop(p->ai_family, addr, ip_addr, INET6_ADDRSTRLEN);
if (debug) fprintf(stderr, "IP addr: %s\n", ip_addr);
if (debug) fprintf(stderr, "%s: %s\n", _("IP address"), ip_addr);
// try to establish connection
fd = socket(p->ai_family, p->ai_socktype | SOCKET_FLAG, p->ai_protocol);
@ -238,3 +239,8 @@ int host_connect(const char *host, const char *port, bool debug)
freeaddrinfo(si);
return fd;
}
void host_connect_error_message(void)
{
fprintf(stderr, "host_connect(): %s\n", _("couldn't open socket or find domain"));
}