Browse Source

Add I18N support.

Allow use of gettext for I18N support. Mark all user-visible
strings as translatable.
develop
Damien Goutte-Gattat 3 years ago
parent
commit
ee913f5b12
11 changed files with 122 additions and 74 deletions
  1. +9
    -0
      .gitignore
  2. +1
    -1
      Makefile.am
  3. +14
    -1
      configure.ac
  4. +10
    -0
      po/Makevars
  5. +6
    -0
      po/POTFILES.in
  6. +2
    -0
      src/Makefile.am
  7. +12
    -12
      src/gfsec-errors.h
  8. +38
    -34
      src/gfsec-split.c
  9. +27
    -23
      src/gfsec-use.c
  10. +1
    -1
      src/scheme-file.c
  11. +2
    -2
      src/scheme-gio.c

+ 9
- 0
.gitignore View File

@ -22,3 +22,12 @@ lib/.deps
lib/lib*.a
info/*.info
info/version.texi
# Gettext-generated files
po/Makefile.in.in
po/Rules-quot
po/gfsecret.pot
po/*.sed
po/*.header
po/*.sin
po/*.gmo

+ 1
- 1
Makefile.am View File

@ -1,4 +1,4 @@
SUBDIRS = lib src man info
SUBDIRS = po lib src man info
ACLOCAL_AMFLAGS = -I m4 --install


+ 14
- 1
configure.ac View File

@ -52,8 +52,21 @@ AS_IF([test $max_secret_size -eq 0],
AC_DEFINE_UNQUOTED([GFSEC_SECRET_MAX_SIZE], [$max_secret_size],
[Max size of secret.])
dnl I18N support
AM_GNU_GETTEXT([external])
AH_BOTTOM([#ifdef ENABLE_NLS
#include <libintl.h>
#define _(a) gettext(a)
#define n(a, b, c) ngettext(a, b, c)
#else
#define _(a) a
#define n(a, b, c) ((c) > 1 ? (b) : (a))
#define bindtextdomain(a, b)
#define textdomain(a)
#endif])
dnl Output files
AC_CONFIG_FILES([Makefile lib/Makefile src/Makefile
AC_CONFIG_FILES([Makefile lib/Makefile src/Makefile po/Makefile.in
man/Makefile man/gfsec-use.1 man/gfsec-split.1
info/Makefile])
AC_OUTPUT


+ 10
- 0
po/Makevars View File

@ -0,0 +1,10 @@
# Makefile variables for PO directory in any package using GNU gettext.
DOMAIN = $(PACKAGE)
subdir = po
top_builddir = ..
XGETTEXT_OPTIONS = --keyword=_ --keyword=N_
COPYRIGHT_HOLDER = Damien Goutte-Gattat
PACKAGE_GNU = no
MSGID_BUGS_ADDRESS = $(PACKAGE_BUGREPORT)
PO_DEPENDS_ON_POT = no
DIST_DEPENDS_ON_UPDATE_PO = yes

+ 6
- 0
po/POTFILES.in View File

@ -0,0 +1,6 @@
# List of source files which contain translatable strings.
src/gfsec-split.c
src/gfsec-use.c
src/gfsec-errors.h
src/scheme-file.c
src/scheme-gio.c

+ 2
- 0
src/Makefile.am View File

@ -15,3 +15,5 @@ gfsec_split_SOURCES = gfsec-split.c $(common_sources)
AM_CPPFLAGS = -I$(top_srcdir)/lib $(LIBGFSHARE_CFLAGS) $(LIBMTP_CFLAGS) $(GIO_CFLAGS)
AM_LDFLAGS = -L$(top_builddir)/lib $(LIBGFSHARE_LIBS) $(LIBMTP_LIBS) $(GIO_LIBS)
LDADD = -lgfsecret
DEFS = -DLOCALEDIR=\"$(localedir)\" @DEFS@

+ 12
- 12
src/gfsec-errors.h View File

@ -16,16 +16,16 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
GFSEC_ERROR(SUCCESS, 0, "Success")
GFSEC_ERROR(SUCCESS, 0, _("Success"))
GFSEC_ERROR(SYSTEM_ERROR, -1, strerror(errno))
GFSEC_ERROR(INVALID_CALL, -2, "A function was improperly called")
GFSEC_ERROR(NOT_ENOUGH_SHARES, -3, "Not enough shares available")
GFSEC_ERROR(TOO_MANY_SHARES, -4, "Too many shares")
GFSEC_ERROR(SHARE_NOT_AVAILABLE, -5, "A share is not available")
GFSEC_ERROR(INVALID_LENGTH, -6, "Shares have inconsistent lengths")
GFSEC_ERROR(INVALID_SHARE, -7, "Checksum failed for share data")
GFSEC_ERROR(CONFIG_LINE_TOO_LONG, -9, "Line too long")
GFSEC_ERROR(CONFIG_INVALID_URI, -10, "Invalid share URI")
GFSEC_ERROR(CONFIG_INVALID_HASH, -11, "Invalid hash value")
GFSEC_ERROR(CONFIG_UNKNOWN_SCHEME, -12, "Unknown URI scheme")
GFSEC_ERROR(CONFIG_INVALID_THRESHOLD, -13, "Invalid threshold")
GFSEC_ERROR(INVALID_CALL, -2, _("A function was improperly called"))
GFSEC_ERROR(NOT_ENOUGH_SHARES, -3, _("Not enough shares available"))
GFSEC_ERROR(TOO_MANY_SHARES, -4, _("Too many shares"))
GFSEC_ERROR(SHARE_NOT_AVAILABLE, -5, _("A share is not available"))
GFSEC_ERROR(INVALID_LENGTH, -6, _("Shares have inconsistent lengths"))
GFSEC_ERROR(INVALID_SHARE, -7, _("Checksum failed for share data"))
GFSEC_ERROR(CONFIG_LINE_TOO_LONG, -9, _("Line too long"))
GFSEC_ERROR(CONFIG_INVALID_URI, -10, _("Invalid share URI"))
GFSEC_ERROR(CONFIG_INVALID_HASH, -11, _("Invalid hash value"))
GFSEC_ERROR(CONFIG_UNKNOWN_SCHEME, -12, _("Unknown URI scheme"))
GFSEC_ERROR(CONFIG_INVALID_THRESHOLD, -13, _("Invalid threshold"))

+ 38
- 34
src/gfsec-split.c View File

@ -41,33 +41,33 @@
static void
usage(int status)
{
puts("Usage: gfsec-split [options] file uri...\n\
Split the specified file for later use with gfsec-use.\n");
puts(_("Usage: gfsec-split [options] file uri...\n\
Split the specified file for later use with gfsec-use.\n"));
puts("Options:\n\
puts(_("Options:\n\
-h, --help Display this help message.\n\
-v, --version Display the version message.\n");
-v, --version Display the version message.\n"));
puts("\
puts(_("\
-n, --threshold N Specify the minimal number of shares\n\
required to re-assemble the secret.\n\
Default is 2.\n\
-s, --share URI Add a share.\n\
-i, --interactive Prompt the user for share URIs.\n");
-i, --interactive Prompt the user for share URIs.\n"));
puts("\
puts(_("\
-c, --config FILE Write configuration to the specified\n\
file. Default is the basename of the\n\
splitted file in gfsecret's configuration\n\
directory.\n");
directory.\n"));
puts("\
-k, --keep Do not delete the original file.\n");
puts(_("\
-k, --keep Do not delete the original file.\n"));
puts("\
-l, --list-supports List available supports and exit.\n");
puts(_("\
-l, --list-supports List available supports and exit.\n"));
printf("Report bugs to <%s>.\n", PACKAGE_BUGREPORT);
printf(_("Report bugs to <%s>.\n"), PACKAGE_BUGREPORT);
exit(status);
}
@ -75,13 +75,13 @@ Split the specified file for later use with gfsec-use.\n");
static void
info(void)
{
printf("\
printf(_("\
gfsec-split (%s %s)\n\
Copyright (C) 2016 Damien Goutte-Gattat\n\
\n\
This program is released under the GNU General Public License.\n\
See the COPYING file or <http://www.gnu.org/licenses/gpl.html>.\n\
", PACKAGE_NAME, VERSION);
"), PACKAGE_NAME, VERSION);
exit(EXIT_SUCCESS);
}
@ -96,7 +96,7 @@ ask(const char *prompt)
printf("%s ", prompt);
if ( (n = getline(&buffer, &len, stdin)) == -1 )
err(EXIT_FAILURE, "Cannot read from standard input");
err(EXIT_FAILURE, _("Cannot read from standard input"));
else if ( n > 0 && buffer[n - 1] == '\n' )
buffer[n - 1] = '\0';
@ -142,13 +142,13 @@ prompt_for_share(gfsec_secret_t *cfg, gfsec_supports_list_t *list, unsigned numb
rc = -1;
printf("Select a support for share #%u:\n\n", number);
printf(_("Select a support for share #%u:\n\n"), number);
for ( i = 0; (unsigned)i < list->count; i++ )
printf(" (%d) %s\n", i+1, list->supports[i].description);
printf(" (x) Done\n\n");
printf(_(" (x) Done\n\n"));
while ( rc == -1 ) {
answer = ask ("Your choice?");
answer = ask (_("Your choice?"));
if ( (*answer == 'x' || *answer == 'X') && *(answer + 1) == '\0' )
rc = 1; /* We're done selecting supports. */
@ -157,7 +157,7 @@ prompt_for_share(gfsec_secret_t *cfg, gfsec_supports_list_t *list, unsigned numb
selected = strtol(answer, NULL, 10);
if ( selected > 0 && (unsigned)selected < list->count ) {
path = ask_nonempty("Specify a pathname on this support:");
path = ask_nonempty(_("Specify a pathname on this support:"));
share = gfsec_share_new();
gfsec_share_set_info(share, GFSEC_SHARE_NUMBER_AUTOASSIGN,
@ -165,7 +165,7 @@ prompt_for_share(gfsec_secret_t *cfg, gfsec_supports_list_t *list, unsigned numb
list->supports[selected - 1].authority,
path, NULL);
if ( (i = gfsec_secret_add_share(cfg, share)) != 0 )
errx(EXIT_FAILURE, "Cannot add share: %s", gfsec_error_string(i));
errx(EXIT_FAILURE, _("Cannot add share: %s"), gfsec_error_string(i));
rc = 0; /* Done for this share. */
@ -193,15 +193,15 @@ interactive_loop(gfsec_secret_t *cfg)
gfsec_support_destroy_list(list);
printf("\nThe following shares will be created:\n");
printf(_("\nThe following shares will be created:\n"));
for ( i = 0; i < cfg->n_shares; i++ ) {
gfsec_share_get_uri(cfg->shares[i], buffer, sizeof(buffer));
printf(" %s\n", buffer);
}
putchar('\n');
if ( ! ask_confirmation("Proceed (y/N)?") )
errx(EXIT_FAILURE, "Split cancelled");
if ( ! ask_confirmation(_("Proceed (y/N)?")) )
errx(EXIT_FAILURE, _("Split cancelled"));
}
static void
@ -230,7 +230,7 @@ get_uinteger_or_die(const char *arg)
errno = 0;
val = strtoul(arg, &endptr, 10);
if ( errno != 0 || endptr == arg )
errx(EXIT_FAILURE, "Invalid argument, unsigned integer expected: %s", arg);
errx(EXIT_FAILURE, _("Invalid argument, unsigned integer expected: %s"), arg);
return val;
}
@ -260,6 +260,10 @@ main(int argc, char **argv)
keep_original = list_mode = interactive = 0;
config_path = NULL;
setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
srandom(time(NULL));
cfg = gfsec_secret_new();
@ -285,7 +289,7 @@ main(int argc, char **argv)
case 's':
if ( (c = gfsec_parse_uri(optarg, cfg, 1)) != 0 )
errx(EXIT_FAILURE, "Cannot add share: %s", gfsec_error_string(c));
errx(EXIT_FAILURE, _("Cannot add share: %s"), gfsec_error_string(c));
break;
case 'i':
@ -327,32 +331,32 @@ main(int argc, char **argv)
}
if ( ! gcry_check_version(GCRYPT_VERSION) )
errx(EXIT_FAILURE, "libgcrypt version mismatch");
errx(EXIT_FAILURE, _("libgcrypt version mismatch"));
gcry_control(GCRYCTL_DISABLE_SECMEM, 0);
gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0);
if ( optind >= argc )
errx(EXIT_FAILURE, "Missing secret file");
errx(EXIT_FAILURE, _("Missing secret file"));
secret_file = argv[optind++];
transform_config_pathname(&config_path, secret_file);
if ( file_exists(config_path) != -1 )
errx(EXIT_FAILURE, "Configuration file %s already exists", config_path);
errx(EXIT_FAILURE, _("Configuration file %s already exists"), config_path);
if ( (c = gfsec_secret_set_secret_file(cfg, secret_file)) != 0 )
errx(EXIT_FAILURE, "Cannot set secret: %s", gfsec_error_string(c));
errx(EXIT_FAILURE, _("Cannot set secret: %s"), gfsec_error_string(c));
while ( optind < argc ) {
if ( (c = gfsec_parse_uri(argv[optind++], cfg, 1)) != 0 )
errx(EXIT_FAILURE, "Cannot add share: %s", gfsec_error_string(c));
errx(EXIT_FAILURE, _("Cannot add share: %s"), gfsec_error_string(c));
}
if ( interactive )
interactive_loop(cfg);
if ( (c = gfsec_secret_split(cfg, threshold)) != 0 )
errx(EXIT_FAILURE, "Cannot split secret: %s", gfsec_error_string(c));
errx(EXIT_FAILURE, _("Cannot split secret: %s"), gfsec_error_string(c));
for ( c = 0; c < cfg->n_shares; c++ ) {
gfsec_share_t *share;
@ -361,11 +365,11 @@ main(int argc, char **argv)
if ( gfsec_scheme_module_put_file(share->scheme, share->authority,
share->path, share->data, share->len)
!= GFSEC_SCHEME_STATUS_SUCCESS )
errx(EXIT_FAILURE, "Cannot write share");
errx(EXIT_FAILURE, _("Cannot write share"));
}
if ( (c = gfsec_write_config(cfg, config_path)) != 0 )
errx(EXIT_FAILURE, "Cannot write configuration file: %s",
errx(EXIT_FAILURE, _("Cannot write configuration file: %s"),
gfsec_error_string(c));
gfsec_secret_free(cfg);


+ 27
- 23
src/gfsec-use.c View File

@ -42,24 +42,24 @@
static void
usage(int status)
{
puts("Usage: gfsec-use [options] [command]\n\
puts(_("Usage: gfsec-use [options] [command]\n\
Rebuild a shared secret and run the specified command.\n\
If no command is specified, a shell is executed. The rebuilt\n\
secret is destroyed when the command or the shell terminates.\n");
secret is destroyed when the command or the shell terminates.\n"));
puts("Options:\n\
puts(_("Options:\n\
-h, --help Display this help message.\n\
-v, --version Display the version message.\n");
-v, --version Display the version message.\n"));
puts("\
puts(_("\
-c, --config FILE Read configuration from the specified\n\
file.\n\
-k, --keep Do not remove the reconstructed file\n\
once the command terminates.\n\
-o, --output FILE Write reconstructed secret in the specified\n\
file (override configuration file).\n");
file (override configuration file).\n"));
printf("Report bugs to <%s>.\n", PACKAGE_BUGREPORT);
printf(_("Report bugs to <%s>.\n"), PACKAGE_BUGREPORT);
exit(status);
}
@ -67,13 +67,13 @@ secret is destroyed when the command or the shell terminates.\n");
static void
info(void)
{
printf("\
printf(_("\
gfsec-use (%s %s)\n\
Copyright (C) 2016 Damien Goutte-Gattat\n\
\n\
This program is released under the GNU General Public License.\n\
See the COPYING file or <http://www.gnu.org/licenses/gpl.html>.\n\
", PACKAGE_NAME, VERSION);
"), PACKAGE_NAME, VERSION);
exit(EXIT_SUCCESS);
}
@ -139,11 +139,11 @@ get_share_data(gfsec_share_t *share)
gfsec_share_get_uri(share, buffer, sizeof(buffer));
if ( (rc = gfsec_share_set_data(share, data, len)) != 0 ) {
warnx("Cannot set data for share %s: %s", buffer, gfsec_error_string(rc));
warnx(_("Cannot set data for share %s: %s"), buffer, gfsec_error_string(rc));
free(data);
}
else
printf("Found share data in %s\n", buffer);
printf(_("Found share data in %s\n"), buffer);
}
return rc;
@ -172,6 +172,10 @@ main(int argc, char **argv)
cfg_file = output_file = NULL;
keep = 0;
setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
while ( (c = getopt_long(argc, argv, "hvc:ko:", options, NULL)) != -1 ) {
switch ( c ) {
case 'h':
@ -203,35 +207,35 @@ main(int argc, char **argv)
gfsec_scheme_module_init();
if ( ! gcry_check_version(GCRYPT_VERSION) )
errx(EXIT_FAILURE, "libgcrypt version mismatch");
errx(EXIT_FAILURE, _("libgcrypt version mismatch"));
gcry_control(GCRYCTL_DISABLE_SECMEM, 0);
gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0);
if ( get_config_file(cfg_file, cfg_path, sizeof(cfg_path)) == -1 )
err(EXIT_FAILURE, "Cannot find configuration file");
err(EXIT_FAILURE, _("Cannot find configuration file"));
if ( (c = gfsec_read_config(&cfg, cfg_path, &u)) != 0 ) {
if ( c == GFSEC_ERR_SYSTEM_ERROR )
err(EXIT_FAILURE, "Cannot read configuration file");
err(EXIT_FAILURE, _("Cannot read configuration file"));
else
errx(EXIT_FAILURE, "%s (line %u): %s", cfg_path, u, gfsec_error_string(c));
errx(EXIT_FAILURE, _("%s (line %u): %s"), cfg_path, u, gfsec_error_string(c));
}
if ( ! output_file && ! (output_file = cfg->filename) )
errx(EXIT_FAILURE, "No output file specified");
errx(EXIT_FAILURE, _("No output file specified"));
for ( u = 0; u < cfg->n_shares; u++ )
get_share_data(cfg->shares[u]);
if ( (c = gfsec_secret_can_combine(cfg)) != 0 )
errx(EXIT_FAILURE, "Cannot reconstitute secret: %s", gfsec_error_string(c));
errx(EXIT_FAILURE, _("Cannot reconstitute secret: %s"), gfsec_error_string(c));
if ( (c = gfsec_secret_combine(cfg)) != 0 )
errx(EXIT_FAILURE, "Error while reconstituting secret: %s", gfsec_error_string(c));
errx(EXIT_FAILURE, _("Error while reconstituting secret: %s"), gfsec_error_string(c));
if ( write_file(output_file, cfg->data, cfg->len) == -1 )
err(EXIT_FAILURE, "Cannot write secret");
err(EXIT_FAILURE, _("Cannot write secret"));
if ( keep && argc >= optind ) {
/* If we keep the file at the end and there is no command to
@ -242,7 +246,7 @@ main(int argc, char **argv)
if ( (pid = fork()) == -1 ) {
unlink(cfg->filename);
err(EXIT_FAILURE, "Cannot fork");
err(EXIT_FAILURE, _("Cannot fork"));
}
else if ( pid == 0 ) {
gfsec_secret_free(cfg);
@ -265,16 +269,16 @@ main(int argc, char **argv)
execvp(shell, args);
}
err(EXIT_FAILURE, "Cannot exec");
err(EXIT_FAILURE, _("Cannot exec"));
}
else if ( ! keep ) { /* No need to wait if we do not have to
remove the file at the end. */
int status;
if ( waitpid(pid, &status, 0) == -1 )
warn("Cannot wait for child process");
warn(_("Cannot wait for child process"));
printf("Removing secret.\n");
printf(_("Removing secret.\n"));
unlink(output_file);
}


+ 1
- 1
src/scheme-file.c View File

@ -69,7 +69,7 @@ gfsec_scheme_file_put_file(gfsec_scheme_t scheme,
int
gfsec_scheme_file_get_supports(gfsec_supports_list_t *list)
{
gfsec_support_add(list, GFSEC_SCHEME_FILE, xstrdup(""), xstrdup("Local filesystem"));
gfsec_support_add(list, GFSEC_SCHEME_FILE, xstrdup(""), xstrdup(_("Local filesystem")));
return 1;
}

+ 2
- 2
src/scheme-gio.c View File

@ -314,7 +314,7 @@ gfsec_scheme_gio_get_supports(gfsec_supports_list_t *list)
if ( label ) {
char *desc;
xasprintf(&desc, "External volume with label '%s'", label);
xasprintf(&desc, _("External volume with label '%s'"), label);
gfsec_support_add(list, GFSEC_SCHEME_LABEL, label, desc);
n += 1;
}
@ -322,7 +322,7 @@ gfsec_scheme_gio_get_supports(gfsec_supports_list_t *list)
if ( uuid ) {
char *desc;
xasprintf(&desc, "External volume with UUID %s", uuid);
xasprintf(&desc, _("External volume with UUID %s"), uuid);
gfsec_support_add(list, GFSEC_SCHEME_UUID, uuid, desc);
n += 1;
}


Loading…
Cancel
Save