* pinentry/pinentry-curses.c (convert_utf8_string): Renamed to
authorWerner Koch <wk@gnupg.org>
Fri, 8 Nov 2002 19:54:49 +0000 (19:54 +0000)
committerWerner Koch <wk@gnupg.org>
Fri, 8 Nov 2002 19:54:49 +0000 (19:54 +0000)
* pinentry/pinentry.c (pinentry_utf8_to_local): this. Changed
callers.
(pinentry_local_to_utf8): New.
(cmd_getpin): Convert result back to UTF-8.
* gtk/pinentry-gtk.c (create_utf8_label): New.
(create_window): Use it here to set the prompts.

ChangeLog
NEWS
gtk/pinentry-gtk.c
pinentry/pinentry-curses.c
pinentry/pinentry.c
pinentry/pinentry.h

index 86c7bc7..a5060c9 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2002-11-08  Werner Koch  <wk@gnupg.org>
+
+       * pinentry/pinentry-curses.c (convert_utf8_string): Renamed to 
+       * pinentry/pinentry.c (pinentry_utf8_to_local): this. Changed
+       callers.
+       (pinentry_local_to_utf8): New.
+       (cmd_getpin): Convert result back to UTF-8.
+       * gtk/pinentry-gtk.c (create_utf8_label): New.
+       (create_window): Use it here to set the prompts.
+
+2002-11-06  Werner Koch  <wk@gnupg.org>
+
+       * pinentry/pinentry-curses.c (dialog_run): Fixed retrun value tests
+       for fopen.
+
 2002-11-05  Werner Koch  <wk@gnupg.org>
 
        * secmem/util.c (init_uids): Make it a prototype.
diff --git a/NEWS b/NEWS
index b37a119..135e46d 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,8 @@ Noteworthy changes in version 0.6.6 (unreleased)
  * Fixed handling of DISPLAY and --display for the sake of the curses
    fallback.
 
+ * UTF-8 conversion does now work for the GTK+ and CURSES version.
+
 Noteworthy changes in version 0.6.5 (2002-09-30)
 ------------------------------------------------
 
index 0a05649..2cb0c97 100644 (file)
@@ -172,6 +172,24 @@ confirm_button_clicked (GtkWidget *widget, gpointer data)
 
 
 static GtkWidget *
+create_utf8_label (char *text)
+{
+  GtkWidget *w;
+  char *buf;
+
+  buf = pinentry_utf8_to_local (pinentry->lc_ctype, text);
+  if (buf)
+    {
+      w = gtk_label_new (buf);
+      free (buf);
+    }
+  else /* no core - simply don't convert */
+    w = gtk_label_new (text);
+  return w;
+}
+
+
+static GtkWidget *
 create_window (int confirm_mode)
 {
   GtkWidget *w;
@@ -208,7 +226,7 @@ create_window (int confirm_mode)
 
   if (pinentry->description)
     {
-      w = gtk_label_new (pinentry->description);
+      w = create_utf8_label (pinentry->description);
       gtk_box_pack_start (GTK_BOX(box), w, TRUE, FALSE, 0);
     }
   if (pinentry->error && !confirm_mode)
@@ -218,7 +236,7 @@ create_window (int confirm_mode)
       GdkColor color[1] = {{0, 0xffff, 0, 0}};
       gboolean success[1];
 
-      w = gtk_label_new (pinentry->error);
+      w = create_utf8_label (pinentry->error);
       gtk_box_pack_start (GTK_BOX(box), w, TRUE, FALSE, 5);
 
       /* fixme: Do we need to release something, or is there a more
@@ -245,7 +263,7 @@ create_window (int confirm_mode)
     {
       if (pinentry->prompt)
         {
-          w = gtk_label_new (pinentry->prompt);
+          w = create_utf8_label (pinentry->prompt);
           gtk_box_pack_start (GTK_BOX(ebox), w, FALSE, FALSE, 0);
         }
       entry = gtk_secure_entry_new ();
index c95681b..695de8e 100644 (file)
@@ -74,53 +74,6 @@ struct dialog
 typedef struct dialog *dialog_t;
 
 \f
-static char *
-convert_utf8_string (char *lc_ctype, char *text)
-{
-  char *old_ctype;
-  char *target_encoding;
-  iconv_t cd;
-  char *input = text;
-  size_t input_len = strlen (text) + 1;
-  char *output;
-  size_t output_len;
-  char *output_buf;
-  size_t processed;
-
-  /* If no locale setting could be determined, simply copy the
-     string.  */
-  if (!lc_ctype)
-    return strdup (text);
-
-  old_ctype = strdup (setlocale (LC_CTYPE, NULL));
-  if (!old_ctype)
-    return NULL;
-  setlocale (LC_CTYPE, lc_ctype);
-  target_encoding = nl_langinfo (CODESET);
-  setlocale (LC_CTYPE, old_ctype);
-  free (old_ctype);
-
-  /* This is overkill, but simplifies the iconv invocation greatly.  */
-  output_len = input_len * MB_LEN_MAX;
-  output_buf = output = malloc (output_len);
-  if (!output)
-    return NULL;
-
-  cd = iconv_open (target_encoding, "UTF-8");
-  if (cd == (iconv_t) -1)
-    {
-      free (output);
-      return NULL;
-    }
-  processed = iconv (cd, &input, &input_len, &output, &output_len);
-  iconv_close (cd);
-  if (processed == (size_t) -1 || input_len)
-    {
-      free (output_buf);
-      return NULL;
-    }
-  return output_buf;
-}
 
 
 static int
@@ -143,7 +96,7 @@ dialog_create (pinentry_t pinentry, dialog_t dialog)
 
   if (pinentry->description)
     {
-      description = convert_utf8_string (pinentry->lc_ctype,
+      description = pinentry_utf8_to_local (pinentry->lc_ctype,
                                         pinentry->description);
       if (!description)
        {
@@ -153,7 +106,7 @@ dialog_create (pinentry_t pinentry, dialog_t dialog)
     }
   if (pinentry->error)
     {
-      error = convert_utf8_string (pinentry->lc_ctype,
+      error = pinentry_utf8_to_local (pinentry->lc_ctype,
                                   pinentry->error);
       if (!error)
        {
@@ -163,7 +116,7 @@ dialog_create (pinentry_t pinentry, dialog_t dialog)
     }
   if (pinentry->prompt)
     {
-      prompt = convert_utf8_string (pinentry->lc_ctype,
+      prompt = pinentry_utf8_to_local (pinentry->lc_ctype,
                                    pinentry->prompt);
       if (!prompt)
        {
@@ -200,9 +153,9 @@ dialog_create (pinentry_t pinentry, dialog_t dialog)
       cancel[len + 2] = '\0';
     }
 
-  dialog->ok = convert_utf8_string (pinentry->lc_ctype,
+  dialog->ok = pinentry_utf8_to_local (pinentry->lc_ctype,
                                    ok ? ok : STRING_OK);
-  dialog->cancel = convert_utf8_string (pinentry->lc_ctype,
+  dialog->cancel = pinentry_utf8_to_local (pinentry->lc_ctype,
                                        cancel ? cancel : STRING_CANCEL);
   if (!dialog->ok || !dialog->cancel)
     {
@@ -578,8 +531,8 @@ static int
 dialog_run (pinentry_t pinentry, const char *tty_name, const char *tty_type)
 {
   struct dialog diag;
-  FILE *ttyfi = 0;
-  FILE *ttyfo = 0;
+  FILE *ttyfi = NULL;
+  FILE *ttyfo = NULL;
   SCREEN *screen = 0;
   int done = 0;
 
@@ -587,10 +540,10 @@ dialog_run (pinentry_t pinentry, const char *tty_name, const char *tty_type)
   if (tty_name)
     {
       ttyfi = fopen (tty_name, "r");
-      if (ttyfi < 0)
+      if (!ttyfi)
        return -1;
       ttyfo = fopen (tty_name, "w");
-      if (ttyfo < 0)
+      if (!ttyfo)
        {
          int err = errno;
          fclose (ttyfi);
index e4e7959..4c39981 100644 (file)
 #include <string.h>
 #include <getopt.h>
 #include <unistd.h>
+#include <locale.h>
+#include <iconv.h>
+#include <langinfo.h>
+#include <limits.h>
 
 #include "assuan.h"
 #include "memory.h"
@@ -55,6 +59,116 @@ struct pinentry pinentry =
   };
 
 \f
+char *
+pinentry_utf8_to_local (char *lc_ctype, char *text)
+{
+  char *old_ctype;
+  char *target_encoding;
+  iconv_t cd;
+  char *input = text;
+  size_t input_len = strlen (text) + 1;
+  char *output;
+  size_t output_len;
+  char *output_buf;
+  size_t processed;
+
+  /* If no locale setting could be determined, simply copy the
+     string.  */
+  if (!lc_ctype)
+    return strdup (text);
+
+  old_ctype = strdup (setlocale (LC_CTYPE, NULL));
+  if (!old_ctype)
+    return NULL;
+  setlocale (LC_CTYPE, lc_ctype);
+  target_encoding = nl_langinfo (CODESET);
+  setlocale (LC_CTYPE, old_ctype);
+  free (old_ctype);
+
+  /* This is overkill, but simplifies the iconv invocation greatly.  */
+  output_len = input_len * MB_LEN_MAX;
+  output_buf = output = malloc (output_len);
+  if (!output)
+    return NULL;
+
+  cd = iconv_open (target_encoding, "UTF-8");
+  if (cd == (iconv_t) -1)
+    {
+      free (output);
+      return NULL;
+    }
+  processed = iconv (cd, &input, &input_len, &output, &output_len);
+  iconv_close (cd);
+  if (processed == (size_t) -1 || input_len)
+    {
+      free (output_buf);
+      return NULL;
+    }
+  return output_buf;
+}
+
+/* Convert TEXT whcih is encoded according to LC_CTYPE to UTF-8.  With
+   SECURE set to true, use secure memory for the returned buffer.
+   Return NULL on error. */
+char *
+pinentry_local_to_utf8 (char *lc_ctype, char *text, int secure)
+{
+  char *old_ctype;
+  char *source_encoding;
+  iconv_t cd;
+  char *input = text;
+  size_t input_len = strlen (text) + 1;
+  char *output;
+  size_t output_len;
+  char *output_buf;
+  size_t processed;
+
+  /* If no locale setting could be determined, simply copy the
+     string.  */
+  if (!lc_ctype)
+    {
+      output_buf = secure? secmem_malloc (input_len) : malloc (input_len);
+      if (output_buf)
+        strcpy (output_buf, input);
+      return output_buf;
+    }
+
+  old_ctype = strdup (setlocale (LC_CTYPE, NULL));
+  if (!old_ctype)
+    return NULL;
+  setlocale (LC_CTYPE, lc_ctype);
+  source_encoding = nl_langinfo (CODESET);
+  setlocale (LC_CTYPE, old_ctype);
+  free (old_ctype);
+
+  /* This is overkill, but simplifies the iconv invocation greatly.  */
+  output_len = input_len * MB_LEN_MAX;
+  output_buf = output = secure? secmem_malloc (output_len):malloc (output_len);
+  if (!output)
+    return NULL;
+
+  cd = iconv_open ("UTF-8", source_encoding);
+  if (cd == (iconv_t) -1)
+    {
+      if (secure)
+        secmem_free (output);
+      else
+        free (output);
+      return NULL;
+    }
+  processed = iconv (cd, &input, &input_len, &output, &output_len);
+  iconv_close (cd);
+  if (processed == (size_t) -1 || input_len)
+    {
+      if (secure)
+        secmem_free (output);
+      else
+        free (output_buf);
+      return NULL;
+    }
+  return output_buf;
+}
+
 /* Try to make room for at least LEN bytes in the pinentry.  Returns
    new buffer on success and 0 on failure or when the old buffer is
    sufficient.  */
@@ -410,7 +524,21 @@ cmd_getpin (ASSUAN_CONTEXT ctx, char *line)
   if (result < 0)
     return ASSUAN_Canceled;
 
-  result = assuan_send_data (ctx, pinentry.pin, result);
+  if (result && pinentry.pin)
+    {
+      char *p;
+
+      p = pinentry_local_to_utf8 (pinentry.lc_ctype, pinentry.pin, 1);
+      if (p)
+        {
+          result = assuan_send_data (ctx, p, strlen (p));
+          secmem_free (p);
+        }
+      else /* Most likely we can't convert between the character sets. */
+        result = ASSUAN_Invalid_Data;
+    }
+  else
+    result = assuan_send_data (ctx, pinentry.pin, result);
   if (pinentry.pin)
     {
       secmem_free (pinentry.pin);
index b9b2c10..982c386 100644 (file)
@@ -80,6 +80,16 @@ typedef int (*pinentry_cmd_handler_t) (pinentry_t pin);
    error.  Otherwise, 0 is returned.  */
 int pinentry_loop (void);
 
+
+/* Convert the UTF-8 encoded string TEXT to the encoding given in
+   LC_CTYPE.  Return NULL on error. */
+char *pinentry_utf8_to_local (char *lc_ctype, char *text);
+
+/* Convert TEXT whcih is encoded according to LC_CTYPE to UTF-8.  With
+   SECURE set to true, use secure memory for the returned buffer.
+   Return NULL on error. */
+char *pinentry_local_to_utf8 (char *lc_ctype, char *text, int secure);
+
 /* Try to make room for at least LEN bytes for the pin in the pinentry
    PIN.  Returns new buffer on success and 0 on failure.  */
 char *pinentry_setbufferlen (pinentry_t pin, int len);
@@ -106,3 +116,5 @@ extern pinentry_cmd_handler_t pinentry_cmd_handler;
 #endif
 
 #endif /* PINENTRY_H */
+
+