agent: Use different translation func for Pinentry strings.

* po/Makevars (XGETTEXT_OPTIONS): Add keyword "L_".
* common/i18n.c (i18n_localegettext): New stub.
* common/i18n.h: Expand the LunderscoreIMPL macro.
* agent/agent.h (L_): New.
(LunderscoreIMPL): New.
* agent/call-pinentry.c (setup_qualitybar): Add arg ctrl anc change
caller.
* agent/findkey.c (try_unprotect_cb): Add local var ctrl.
* agent/genkey.c (check_passphrase_constraints): Replace xtryasprintf
by xtrystrdup to avoid gcc warning.  Unfortinately this changes the
string.
(agent_ask_new_passphrase): Cleanup the use of initial_errtext.
--

Static strings in gpg-agent need to be translated according to the
locale set by the caller.  This is required so that a gpg-agent can be
started in one locale and a gpg can be run in another.  If we don't do
this the static strings (prompt, buttons) are not or in the wrong
locale translated while dynamic strings (e.g. key description) uses
the locale of gpg.

This is only the first part of the change the actual local switching
still needs to be implemented.

Debian-bug-id: 788983
Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
Werner Koch 2015-06-30 21:58:02 +02:00
parent d8bc89ab88
commit e76d4c05b2
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
10 changed files with 135 additions and 105 deletions

View File

@ -295,6 +295,21 @@ cache_mode_t;
typedef int (*lookup_ttl_t)(const char *hexgrip);
/* This is a special version of the usual _() gettext macro. It
assumes a server connection control variable with the name "ctrl"
and uses that to translate a string according to the locale set for
the connection. The macro LunderscoreIMPL is used by i18n to
actually define the inline function when needed. */
#define L_(a) agent_Lunderscore (ctrl, (a))
#define LunderscoreIMPL \
static inline const char * \
agent_Lunderscore (ctrl_t ctrl, const char *string) \
{ \
return ctrl? i18n_localegettext (ctrl->lc_messages, string) \
/* */: gettext (string); \
}
/*-- gpg-agent.c --*/
void agent_exit (int rc) GPGRT_GCC_A_NR; /* Also implemented in other tools */
gpg_error_t agent_copy_startup_env (ctrl_t ctrl);

View File

@ -464,7 +464,7 @@ start_pinentry (ctrl_t ctrl)
{
if (!opt.allow_external_cache && tbl[idx].what == 1)
continue; /* No need for it. */
s = _(tbl[idx].value);
s = L_(tbl[idx].value);
if (*s == '|' && (s2=strchr (s+1,'|')))
s = s2+1;
if (asprintf (&optstr, "OPTION default-%s=%s", tbl[idx].key, s) < 0 )
@ -695,7 +695,7 @@ inq_quality (void *opaque, const char *line)
/* Helper for agent_askpin and agent_get_passphrase. */
static int
setup_qualitybar (void)
setup_qualitybar (ctrl_t ctrl)
{
int rc;
char line[ASSUAN_LINELENGTH];
@ -704,7 +704,7 @@ setup_qualitybar (void)
/* TRANSLATORS: This string is displayed by Pinentry as the label
for the quality bar. */
tmpstr = try_percent_escape (_("Quality:"), "\t\r\n\f\v");
tmpstr = try_percent_escape (L_("Quality:"), "\t\r\n\f\v");
snprintf (line, DIM(line)-1, "SETQUALITYBAR %s", tmpstr? tmpstr:"");
line[DIM(line)-1] = 0;
xfree (tmpstr);
@ -726,7 +726,7 @@ setup_qualitybar (void)
tooltip is limited to about 900 characters. If you do not
translate this entry, a default english text (see source)
will be used. */
tooltip = _("pinentry.qualitybar.tooltip");
tooltip = L_("pinentry.qualitybar.tooltip");
if (!strcmp ("pinentry.qualitybar.tooltip", tooltip))
tooltip = ("The quality of the text entered above.\n"
"Please ask your administrator for "
@ -836,11 +836,11 @@ agent_askpin (ctrl_t ctrl,
if (!pininfo || pininfo->max_length < 1)
return gpg_error (GPG_ERR_INV_VALUE);
if (!desc_text && pininfo->min_digits)
desc_text = _("Please enter your PIN, so that the secret key "
"can be unlocked for this session");
desc_text = L_("Please enter your PIN, so that the secret key "
"can be unlocked for this session");
else if (!desc_text)
desc_text = _("Please enter your passphrase, so that the secret key "
"can be unlocked for this session");
desc_text = L_("Please enter your passphrase, so that the secret key "
"can be unlocked for this session");
if (prompt_text)
is_pin = !!strstr (prompt_text, "PIN");
@ -877,7 +877,7 @@ agent_askpin (ctrl_t ctrl,
return unlock_pinentry (rc);
snprintf (line, DIM(line)-1, "SETPROMPT %s",
prompt_text? prompt_text : is_pin? "PIN:" : "Passphrase:");
prompt_text? prompt_text : is_pin? L_("PIN:") : L_("Passphrase:"));
line[DIM(line)-1] = 0;
rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
if (rc)
@ -888,7 +888,7 @@ agent_askpin (ctrl_t ctrl,
to the pinentry. */
if (pininfo->with_qualitybar && opt.min_passphrase_len )
{
rc = setup_qualitybar ();
rc = setup_qualitybar (ctrl);
if (rc)
return unlock_pinentry (rc);
}
@ -906,7 +906,7 @@ agent_askpin (ctrl_t ctrl,
if (pininfo->with_repeat)
{
snprintf (line, DIM(line)-1, "SETREPEATERROR %s",
_("does not match - try again"));
L_("does not match - try again"));
line[DIM(line)-1] = 0;
rc = assuan_transact (entry_ctx, line,
NULL, NULL, NULL, NULL, NULL, NULL);
@ -927,7 +927,7 @@ agent_askpin (ctrl_t ctrl,
/* TRANSLATORS: The string is appended to an error message in
the pinentry. The %s is the actual error message, the
two %d give the current and maximum number of tries. */
snprintf (line, DIM(line)-1, _("SETERROR %s (try %d of %d)"),
snprintf (line, DIM(line)-1, L_("SETERROR %s (try %d of %d)"),
errtext, pininfo->failed_tries+1, pininfo->max_tries);
line[DIM(line)-1] = 0;
rc = assuan_transact (entry_ctx, line,
@ -939,7 +939,7 @@ agent_askpin (ctrl_t ctrl,
if (pininfo->with_repeat)
{
snprintf (line, DIM(line)-1, "SETREPEAT %s", _("Repeat:"));
snprintf (line, DIM(line)-1, "SETREPEAT %s", L_("Repeat:"));
line[DIM(line)-1] = 0;
rc = assuan_transact (entry_ctx, line,
NULL, NULL, NULL, NULL, NULL, NULL);
@ -969,8 +969,8 @@ agent_askpin (ctrl_t ctrl,
rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_FULLY_CANCELED);
if (gpg_err_code (rc) == GPG_ERR_ASS_TOO_MUCH_DATA)
errtext = is_pin? _("PIN too long")
: _("Passphrase too long");
errtext = is_pin? L_("PIN too long")
: L_("Passphrase too long");
else if (rc)
return unlock_pinentry (rc);
@ -978,12 +978,12 @@ agent_askpin (ctrl_t ctrl,
{
/* do some basic checks on the entered PIN. */
if (!all_digitsp (pininfo->pin))
errtext = _("Invalid characters in PIN");
errtext = L_("Invalid characters in PIN");
else if (pininfo->max_digits
&& strlen (pininfo->pin) > pininfo->max_digits)
errtext = _("PIN too long");
errtext = L_("PIN too long");
else if (strlen (pininfo->pin) < pininfo->min_digits)
errtext = _("PIN too short");
errtext = L_("PIN too short");
}
if (!errtext && pininfo->check_cb)
@ -995,8 +995,7 @@ agent_askpin (ctrl_t ctrl,
errtext = pininfo->cb_errtext;
else if (gpg_err_code (rc) == GPG_ERR_BAD_PASSPHRASE
|| gpg_err_code (rc) == GPG_ERR_BAD_PIN)
errtext = (is_pin? _("Bad PIN")
: _("Bad Passphrase"));
errtext = (is_pin? L_("Bad PIN") : L_("Bad Passphrase"));
else if (rc)
return unlock_pinentry (rc);
}
@ -1069,7 +1068,7 @@ agent_get_passphrase (ctrl_t ctrl,
return rc;
if (!prompt)
prompt = desc && strstr (desc, "PIN")? "PIN": _("Passphrase");
prompt = desc && strstr (desc, "PIN")? L_("PIN:"): L_("Passphrase:");
/* If we have a KEYINFO string and are normal, user, or ssh cache
@ -1109,7 +1108,7 @@ agent_get_passphrase (ctrl_t ctrl,
if (with_qualitybar && opt.min_passphrase_len)
{
rc = setup_qualitybar ();
rc = setup_qualitybar (ctrl);
if (rc)
return unlock_pinentry (rc);
}

View File

@ -2804,14 +2804,14 @@ data_sign (ctrl_t ctrl, ssh_key_type_spec_t *spec,
gcry_sexp_release (key);
if (err)
goto out;
prompt = xtryasprintf (_("An ssh process requested the use of key%%0A"
" %s%%0A"
" (%s)%%0A"
"Do you want to allow this?"),
prompt = xtryasprintf (L_("An ssh process requested the use of key%%0A"
" %s%%0A"
" (%s)%%0A"
"Do you want to allow this?"),
fpr, comment? comment:"");
xfree (fpr);
gcry_free (comment);
err = agent_get_confirmation (ctrl, prompt, _("Allow"), _("Deny"), 0);
err = agent_get_confirmation (ctrl, prompt, L_("Allow"), L_("Deny"), 0);
xfree (prompt);
if (err)
goto out;
@ -2820,8 +2820,8 @@ data_sign (ctrl_t ctrl, ssh_key_type_spec_t *spec,
/* Create signature. */
ctrl->use_auth_call = 1;
err = agent_pksign_do (ctrl, NULL,
_("Please enter the passphrase "
"for the ssh key%%0A %F%%0A (%c)"),
L_("Please enter the passphrase "
"for the ssh key%%0A %F%%0A (%c)"),
&signature_sexp,
CACHE_MODE_SSH, ttl_from_sshcontrol,
hash, hashlen);
@ -3059,7 +3059,7 @@ ssh_identity_register (ctrl_t ctrl, ssh_key_type_spec_t *spec,
unsigned char *buffer = NULL;
size_t buffer_n;
char *description = NULL;
const char *description2 = _("Please re-enter this passphrase");
const char *description2 = L_("Please re-enter this passphrase");
char *comment = NULL;
char *key_fpr = NULL;
const char *initial_errtext = NULL;
@ -3083,11 +3083,11 @@ ssh_identity_register (ctrl_t ctrl, ssh_key_type_spec_t *spec,
goto out;
if ( asprintf (&description,
_("Please enter a passphrase to protect"
" the received secret key%%0A"
" %s%%0A"
" %s%%0A"
"within gpg-agent's key storage"),
L_("Please enter a passphrase to protect"
" the received secret key%%0A"
" %s%%0A"
" %s%%0A"
"within gpg-agent's key storage"),
key_fpr, comment ? comment : "") < 0)
{
err = gpg_error_from_syserror ();
@ -3123,7 +3123,7 @@ ssh_identity_register (ctrl_t ctrl, ssh_key_type_spec_t *spec,
if (err == -1)
{ /* The re-entered one did not match and the user did not
hit cancel. */
initial_errtext = _("does not match - try again");
initial_errtext = L_("does not match - try again");
goto next_try;
}
}

View File

@ -89,9 +89,9 @@ ask_for_card (ctrl_t ctrl, const unsigned char *shadow_info, char **r_kid)
"%s:%%0A%%0A"
" \"%.*s\"",
no_card
? _("Please insert the card with serial number")
: _("Please remove the current card and "
"insert the one with serial number"),
? L_("Please insert the card with serial number")
: L_("Please remove the current card and "
"insert the one with serial number"),
want_sn_displen, want_sn) < 0)
{
rc = out_of_core ();
@ -201,19 +201,19 @@ getpin_cb (void *opaque, const char *info, char *buf, size_t maxbuf)
for (s=info+1; s < ends; s++)
{
if (*s == 'A')
prompt = _("Admin PIN");
prompt = L_("Admin PIN");
else if (*s == 'P')
{
/* TRANSLATORS: A PUK is the Personal Unblocking Code
used to unblock a PIN. */
prompt = _("PUK");
prompt = L_("PUK");
is_puk = 1;
}
else if (*s == 'N')
newpin = 1;
else if (*s == 'R')
{
prompt = _("Reset Code");
prompt = L_("Reset Code");
resetcode = 1;
}
}
@ -239,7 +239,7 @@ getpin_cb (void *opaque, const char *info, char *buf, size_t maxbuf)
char *desc;
if ( asprintf (&desc,
_("%s%%0A%%0AUse the reader's pinpad for input."),
L_("%s%%0A%%0AUse the reader's pinpad for input."),
info) < 0 )
rc = gpg_error_from_syserror ();
else
@ -288,18 +288,18 @@ getpin_cb (void *opaque, const char *info, char *buf, size_t maxbuf)
pi2->max_tries = 1;
rc = agent_askpin (ctrl,
(resetcode?
_("Repeat this Reset Code"):
L_("Repeat this Reset Code"):
is_puk?
_("Repeat this PUK"):
_("Repeat this PIN")),
L_("Repeat this PUK"):
L_("Repeat this PIN")),
prompt, NULL, pi2, NULL, 0);
if (!rc && strcmp (pi->pin, pi2->pin))
{
again_text = (resetcode?
N_("Reset Code not correctly repeated; try again"):
L_("Reset Code not correctly repeated; try again"):
is_puk?
N_("PUK not correctly repeated; try again"):
N_("PIN not correctly repeated; try again"));
L_("PUK not correctly repeated; try again"):
L_("PIN not correctly repeated; try again"));
xfree (pi2);
xfree (pi);
goto again;
@ -311,7 +311,7 @@ getpin_cb (void *opaque, const char *info, char *buf, size_t maxbuf)
{
char *desc;
if ( asprintf (&desc,
_("Please enter the PIN%s%s%s to unlock the card"),
L_("Please enter the PIN%s%s%s to unlock the card"),
info? " (":"",
info? info:"",
info? ")":"") < 0)

View File

@ -115,6 +115,7 @@ static int
try_unprotect_cb (struct pin_entry_info_s *pi)
{
struct try_unprotect_arg_s *arg = pi->check_cb_arg;
ctrl_t ctrl = arg->ctrl;
size_t dummy;
gpg_error_t err;
gnupg_isotime_t now, protected_at, tmptime;
@ -123,18 +124,18 @@ try_unprotect_cb (struct pin_entry_info_s *pi)
assert (!arg->unprotected_key);
arg->change_required = 0;
err = agent_unprotect (arg->ctrl, arg->protected_key, pi->pin, protected_at,
err = agent_unprotect (ctrl, arg->protected_key, pi->pin, protected_at,
&arg->unprotected_key, &dummy);
if (err)
return err;
if (!opt.max_passphrase_days || arg->ctrl->in_passwd)
if (!opt.max_passphrase_days || ctrl->in_passwd)
return 0; /* No regular passphrase change required. */
if (!*protected_at)
{
/* No protection date known - must force passphrase change. */
desc = xtrystrdup (_("Note: This passphrase has never been changed.%0A"
"Please change it now."));
desc = xtrystrdup (L_("Note: This passphrase has never been changed.%0A"
"Please change it now."));
if (!desc)
return gpg_error_from_syserror ();
}
@ -149,8 +150,8 @@ try_unprotect_cb (struct pin_entry_info_s *pi)
{
/* Passphrase "expired". */
desc = xtryasprintf
(_("This passphrase has not been changed%%0A"
"since %.4s-%.2s-%.2s. Please change it now."),
(L_("This passphrase has not been changed%%0A"
"since %.4s-%.2s-%.2s. Please change it now."),
protected_at, protected_at+4, protected_at+6);
if (!desc)
return gpg_error_from_syserror ();
@ -162,16 +163,16 @@ try_unprotect_cb (struct pin_entry_info_s *pi)
/* Change required. */
if (opt.enforce_passphrase_constraints)
{
err = agent_get_confirmation (arg->ctrl, desc,
_("Change passphrase"), NULL, 0);
err = agent_get_confirmation (ctrl, desc,
L_("Change passphrase"), NULL, 0);
if (!err)
arg->change_required = 1;
}
else
{
err = agent_get_confirmation (arg->ctrl, desc,
_("Change passphrase"),
_("I'll change it later"), 0);
err = agent_get_confirmation (ctrl, desc,
L_("Change passphrase"),
L_("I'll change it later"), 0);
if (!err)
arg->change_required = 1;
else if (gpg_err_code (err) == GPG_ERR_CANCELED
@ -1257,8 +1258,8 @@ agent_delete_key (ctrl_t ctrl, const char *desc_text,
if (!desc_text)
{
default_desc = xtryasprintf
("Do you really want to delete the key identified by keygrip%%0A"
" %s%%0A %%C%%0A?", hexgrip);
(L_("Do you really want to delete the key identified by keygrip%%0A"
" %s%%0A %%C%%0A?"), hexgrip);
desc_text = default_desc;
}
@ -1281,7 +1282,7 @@ agent_delete_key (ctrl_t ctrl, const char *desc_text,
goto leave;
err = agent_get_confirmation (ctrl, desc_text_final,
_("Delete key"), _("No"), 0);
L_("Delete key"), L_("No"), 0);
if (err)
goto leave;
@ -1292,10 +1293,10 @@ agent_delete_key (ctrl_t ctrl, const char *desc_text,
{
err = agent_get_confirmation
(ctrl,
_("Warning: This key is also listed for use with SSH!\n"
"Deleting the key might remove your ability to "
"access remote machines."),
_("Delete key"), _("No"), 0);
L_("Warning: This key is also listed for use with SSH!\n"
"Deleting the key might remove your ability to "
"access remote machines."),
L_("Delete key"), L_("No"), 0);
if (err)
goto leave;
}

View File

@ -155,13 +155,13 @@ take_this_one_anyway2 (ctrl_t ctrl, const char *desc, const char *anyway_btn)
if (opt.enforce_passphrase_constraints)
{
err = agent_show_message (ctrl, desc, _("Enter new passphrase"));
err = agent_show_message (ctrl, desc, L_("Enter new passphrase"));
if (!err)
err = gpg_error (GPG_ERR_CANCELED);
}
else
err = agent_get_confirmation (ctrl, desc,
anyway_btn, _("Enter new passphrase"), 0);
anyway_btn, L_("Enter new passphrase"), 0);
return err;
}
@ -169,7 +169,7 @@ take_this_one_anyway2 (ctrl_t ctrl, const char *desc, const char *anyway_btn)
static int
take_this_one_anyway (ctrl_t ctrl, const char *desc)
{
return take_this_one_anyway2 (ctrl, desc, _("Take this one anyway"));
return take_this_one_anyway2 (ctrl, desc, L_("Take this one anyway"));
}
@ -196,12 +196,12 @@ check_passphrase_constraints (ctrl_t ctrl, const char *pw,
if (!*pw)
{
const char *desc = (opt.enforce_passphrase_constraints?
_("You have not entered a passphrase!%0A"
"An empty passphrase is not allowed.") :
_("You have not entered a passphrase - "
"this is in general a bad idea!%0A"
"Please confirm that you do not want to "
"have any protection on your key."));
L_("You have not entered a passphrase!%0A"
"An empty passphrase is not allowed.") :
L_("You have not entered a passphrase - "
"this is in general a bad idea!%0A"
"Please confirm that you do not want to "
"have any protection on your key."));
err = 1;
if (failed_constraint)
@ -210,7 +210,7 @@ check_passphrase_constraints (ctrl_t ctrl, const char *pw,
*failed_constraint = xstrdup (desc);
else
err = take_this_one_anyway2 (ctrl, desc,
_("Yes, protection is not needed"));
L_("Yes, protection is not needed"));
}
goto leave;
@ -271,9 +271,8 @@ check_passphrase_constraints (ctrl_t ctrl, const char *pw,
goto leave;
}
msg3 = xtryasprintf
(_("A passphrase may not be a known term or match%%0A"
"certain pattern."));
msg3 = xtrystrdup (L_("A passphrase may not be a known term or match%0A"
"certain pattern."));
if (!msg3)
{
err = gpg_error_from_syserror ();
@ -287,7 +286,7 @@ check_passphrase_constraints (ctrl_t ctrl, const char *pw,
size_t n;
msg = strconcat
(_("Warning: You have entered an insecure passphrase."),
(L_("Warning: You have entered an insecure passphrase."),
"%0A%0A",
msg1? msg1 : "", msg1? "%0A" : "",
msg2? msg2 : "", msg2? "%0A" : "",
@ -345,9 +344,8 @@ agent_ask_new_passphrase (ctrl_t ctrl, const char *prompt,
{
gpg_error_t err;
const char *text1 = prompt;
const char *text2 = _("Please re-enter this passphrase");
const char *text2 = L_("Please re-enter this passphrase");
char *initial_errtext = NULL;
int initial_errtext_do_free = 0;
struct pin_entry_info_s *pi, *pi2;
*r_passphrase = NULL;
@ -385,17 +383,12 @@ agent_ask_new_passphrase (ctrl_t ctrl, const char *prompt,
next_try:
err = agent_askpin (ctrl, text1, NULL, initial_errtext, pi, NULL, 0);
if (initial_errtext_do_free)
{
xfree (initial_errtext);
initial_errtext_do_free = 0;
}
xfree (initial_errtext);
initial_errtext = NULL;
if (!err)
{
if (check_passphrase_constraints (ctrl, pi->pin, &initial_errtext))
{
initial_errtext_do_free = 1;
pi->failed_tries = 0;
pi2->failed_tries = 0;
goto next_try;
@ -408,8 +401,10 @@ agent_ask_new_passphrase (ctrl_t ctrl, const char *prompt,
if (err == -1)
{ /* The re-entered one did not match and the user did not
hit cancel. */
initial_errtext = _("does not match - try again");
goto next_try;
initial_errtext = xtrystrdup (L_("does not match - try again"));
if (initial_errtext)
goto next_try;
err = gpg_error_from_syserror ();
}
}
}
@ -421,6 +416,8 @@ agent_ask_new_passphrase (ctrl_t ctrl, const char *prompt,
if (!*r_passphrase)
err = gpg_error_from_syserror ();
}
xfree (initial_errtext);
xfree (pi);
return err;
}
@ -467,8 +464,8 @@ agent_genkey (ctrl_t ctrl, const char *cache_nonce,
else
{
rc = agent_ask_new_passphrase (ctrl,
_("Please enter the passphrase to%0A"
"protect your new key"),
L_("Please enter the passphrase to%0A"
"protect your new key"),
&passphrase_buffer);
if (rc)
return rc;
@ -593,7 +590,7 @@ agent_protect_and_store (ctrl_t ctrl, gcry_sexp_t s_skey,
*passphrase_addr = NULL;
}
err = agent_ask_new_passphrase (ctrl,
_("Please enter the new passphrase"),
L_("Please enter the new passphrase"),
&pass);
if (!err)
err = store_key (s_skey, pass, 1, ctrl->s2k_count);

View File

@ -651,16 +651,16 @@ agent_marktrusted (ctrl_t ctrl, const char *name, const char *fpr, int flag)
plain % sign, you need to encode it as "%%25". The
"%s" gets replaced by the name as stored in the
certificate. */
_("Do you ultimately trust%%0A"
" \"%s\"%%0A"
"to correctly certify user certificates?"),
L_("Do you ultimately trust%%0A"
" \"%s\"%%0A"
"to correctly certify user certificates?"),
nameformatted);
if (!desc)
{
xfree (nameformatted);
return out_of_core ();
}
err = agent_get_confirmation (ctrl, desc, _("Yes"), _("No"), 1);
err = agent_get_confirmation (ctrl, desc, L_("Yes"), L_("No"), 1);
xfree (desc);
if (!err)
yes_i_trust = 1;
@ -694,10 +694,10 @@ agent_marktrusted (ctrl_t ctrl, const char *name, const char *fpr, int flag)
"%%25". The second "%s" gets replaced by a hexdecimal
fingerprint string whereas the first one receives the name
as stored in the certificate. */
_("Please verify that the certificate identified as:%%0A"
" \"%s\"%%0A"
"has the fingerprint:%%0A"
" %s"), nameformatted, fprformatted);
L_("Please verify that the certificate identified as:%%0A"
" \"%s\"%%0A"
"has the fingerprint:%%0A"
" %s"), nameformatted, fprformatted);
if (!desc)
{
xfree (fprformatted);
@ -708,7 +708,7 @@ agent_marktrusted (ctrl_t ctrl, const char *name, const char *fpr, int flag)
/* TRANSLATORS: "Correct" is the label of a button and intended
to be hit if the fingerprint matches the one of the CA. The
other button is "the default "Cancel" of the Pinentry. */
err = agent_get_confirmation (ctrl, desc, _("Correct"), _("Wrong"), 1);
err = agent_get_confirmation (ctrl, desc, L_("Correct"), L_("Wrong"), 1);
xfree (desc);
if (gpg_err_code (err) == GPG_ERR_NOT_CONFIRMED)
yes_i_trust = 0;

View File

@ -113,3 +113,15 @@ i18n_utf8 (const char *string)
i18n_switchback (saved);
return result;
}
/* A variant of gettext which allows to specify the local to use for
translating the message. The function assumes that utf-8 is used
for the encoding. FIXME: The locale back and forth switching is
likely very expensive, thus we should consider to implement our own
cache here. */
const char *
i18n_localegettext (const char *lc_messages, const char *string)
{
return _(string);
}

View File

@ -42,6 +42,12 @@ void i18n_init (void);
char *i18n_switchto_utf8 (void);
void i18n_switchback (char *saved_codeset);
const char *i18n_utf8 (const char *string);
const char *i18n_localegettext (const char *lc_messages, const char *string);
/* If a module wants a local L_() fucntion we define it here. */
#ifdef LunderscoreIMPL
LunderscoreIMPL
#endif
#endif /*GNUPG_COMMON_I18N_H*/

View File

@ -8,7 +8,7 @@ subdir = po
top_builddir = ..
# These options get passed to xgettext.
XGETTEXT_OPTIONS = --keyword=_ --keyword=N_
XGETTEXT_OPTIONS = --keyword=_ --keyword=N_ --keyword=L_
# This is the copyright holder that gets inserted into the header of the
# $(DOMAIN).pot file. Set this to the copyright holder of the surrounding