[Gpg4win-commits] [git] Gpg4win - branch, master, updated. gpg4win-2.1.1-52-g8bd9716

by Werner Koch cvs at cvs.gnupg.org
Mon Aug 12 19:20:07 CEST 2013


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GnuPG for Windows".

The branch, master has been updated
       via  8bd9716ddf6483d435bee18a9dc82400f52eab53 (commit)
      from  fa945a89654fff709fd304d1c29e5372f0602075 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 8bd9716ddf6483d435bee18a9dc82400f52eab53
Author: Werner Koch <wk at gnupg.org>
Date:   Mon Aug 12 18:51:54 2013 +0200

    gpa: Detect homedir via gpgconf.
    
    * patches/gpa-0.9.4/03-homedir-via-gpgconf.patch: New.
    * Makefile.am (EXTRA_DIST): Add patch.
    --
    
    This improves the portable use of GPA.

diff --git a/Makefile.am b/Makefile.am
index 45d5caf..7ef46bb 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -50,8 +50,8 @@ EXTRA_DIST = autogen.sh README.GIT ONEWS \
         patches/libgpg-error-1.12/01-fix-get-string.patch \
 	patches/gpa-0.9.4/01-bin-encrypt.patch \
         patches/gpa-0.9.4/02-cms-detection.patch \
-        patches/gpa-0.9.4/02-x509-import.patch
-
+        patches/gpa-0.9.4/02-x509-import.patch \
+        patches/gpa-0.9.4/03-homedir-via-gpgconf.patch
 
 copy-news:
 	cp NEWS doc/website/NEWS.last
diff --git a/patches/gpa-0.9.4/03-homedir-via-gpgconf.patch b/patches/gpa-0.9.4/03-homedir-via-gpgconf.patch
new file mode 100755
index 0000000..6f83e98
--- /dev/null
+++ b/patches/gpa-0.9.4/03-homedir-via-gpgconf.patch
@@ -0,0 +1,1032 @@
+#! /bin/sh
+patch -p1 -l -f $* < $0
+exit $?
+
+From 398fd028c762dd6c0fc7a5945f55eb2dbd2edaec Mon Sep 17 00:00:00 2001
+From: Werner Koch <wk at gnupg.org>
+Date: Mon, 12 Aug 2013 18:44:06 +0200
+Subject: [PATCH] Detect default homedir via gpgconf.
+
+* src/server.c (decode_percent_string): Move to ..
+* src/utils.c (decode_percent_string): here.
+* src/gpgmetools.c (gpa_start_simple_gpg_command): Add arg use_stderr
+and change all callers.
+(gpg_simple_stdio_cb): Implement the !use_stderr case.
+* src/get-path.c: Include string.h and gpa.h.
+(struct homedir_from_gpgconf_s): New.
+(homedir_from_gpgconf_parser): New.
+(homedir_from_gpgconf): New.
+(default_homedir): First try to detect via gpgconf.
+--
+
+It would be useful to equip GPGME with a function to parse the output
+of "gpgconf --list-dir".  Until then we need to go into some length to
+read it.
+---
+ src/cm-netkey.c  |  132 +++++++++++++++++++++++++++---------------------------
+ src/get-path.c   |   85 ++++++++++++++++++++++++++++++++---
+ src/gpa.h        |    1 +
+ src/gpgmetools.c |   75 ++++++++++++++++++++-----------
+ src/gpgmetools.h |    1 +
+ src/server.c     |   47 -------------------
+ src/utils.c      |   65 +++++++++++++++++++++++----
+ 7 files changed, 252 insertions(+), 154 deletions(-)
+
+diff --git a/src/cm-netkey.c b/src/cm-netkey.c
+index 8b4aba2..8ddbcb7 100644
+--- a/src/cm-netkey.c
++++ b/src/cm-netkey.c
+@@ -14,7 +14,7 @@
+  * License for more details.
+  *
+  * You should have received a copy of the GNU General Public License
+- * along with this program; if not, see <http://www.gnu.org/licenses/>.
++ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+  */
+
+ #ifdef HAVE_CONFIG_H
+@@ -26,7 +26,7 @@
+ #include <string.h>
+ #include <assert.h>
+
+-#include "gpa.h"
++#include "gpa.h"
+ #include "gtktools.h"
+ #include "convert.h"
+ #include "gpa-key-details.h"
+@@ -49,7 +49,7 @@ enum
+     ENTRY_SIGG_PUK_RETRYCOUNTER,
+
+     ENTRY_LAST
+-  };
++  };
+
+
+ /* A structure for PIN information.  */
+@@ -65,7 +65,7 @@ struct pininfo_s
+
+
+ /* Object's class definition.  */
+-struct _GpaCMNetkeyClass
++struct _GpaCMNetkeyClass
+ {
+   GpaCMObjectClass parent_class;
+ };
+@@ -106,7 +106,7 @@ static void gpa_cm_netkey_finalize (GObject *object);
+
+
+ 

+-/************************************************************
++/************************************************************
+  *******************   Implementation   *********************
+  ************************************************************/
+
+@@ -127,13 +127,13 @@ clear_card_data (GpaCMNetkey *card)
+ /* Put the PIN information into the field with ENTRY_ID.  If BUTTON is
+    not NULL its sensitivity is set as well. */
+ static void
+-update_entry_retry_counter (GpaCMNetkey *card, int entry_id,
++update_entry_retry_counter (GpaCMNetkey *card, int entry_id,
+                             struct pininfo_s *info, int any_isnull,
+                             int is_puk, GtkWidget *button)
+ {
+   char numbuf[50];
+   const char *string;
+-
++
+   if (!info->valid)
+     string = _("unknown");
+   else if (info->nullpin)
+@@ -150,12 +150,12 @@ update_entry_retry_counter (GpaCMNetkey *card, int entry_id,
+   gtk_label_set_text (GTK_LABEL (card->entries[entry_id]), string);
+   if (button)
+     {
+-      gtk_button_set_label (GTK_BUTTON (button),
++      gtk_button_set_label (GTK_BUTTON (button),
+                             (info->valid && !info->nullpin
+                              && (info->blocked || !info->tries_left))
+                             ? (is_puk? _("Reset PUK") : _("Reset PIN"))
+                             : (is_puk? _("Change PUK"): _("Change PIN")));
+-      gtk_widget_set_sensitive (button,
++      gtk_widget_set_sensitive (button,
+                                 (info->valid && !any_isnull
+                                  && !info->nullpin && !info->blocked
+                                  && !info->nopin));
+@@ -168,12 +168,12 @@ update_entry_retry_counter (GpaCMNetkey *card, int entry_id,
+ static void
+ update_entry_chv_status (GpaCMNetkey *card, int entry_id, char *string)
+ {
+-  struct {
++  struct {
+     int info_idx;
+     int is_puk;
+     int entry_id;
+     GtkWidget *widget;
+-  } tbl[] =
++  } tbl[] =
+     {
+       {  0, 0, ENTRY_PIN_RETRYCOUNTER },
+       {  1, 1, ENTRY_PUK_RETRYCOUNTER  },
+@@ -190,7 +190,7 @@ update_entry_chv_status (GpaCMNetkey *card, int entry_id, char *string)
+   tbl[3].widget = card->change_sigg_puk_btn;
+
+   (void)entry_id; /* Not used.  */
+-
++
+   for (idx=0; idx < DIM (card->pininfo); idx++)
+     memset (&card->pininfo[idx], 0, sizeof card->pininfo[0]);
+
+@@ -203,7 +203,7 @@ update_entry_chv_status (GpaCMNetkey *card, int entry_id, char *string)
+         string++;
+       while (spacep (string))
+         string++;
+-
++
+       card->pininfo[idx].valid = 1;
+       if (value >= 0)
+         card->pininfo[idx].tries_left = value;
+@@ -224,7 +224,7 @@ update_entry_chv_status (GpaCMNetkey *card, int entry_id, char *string)
+     if (tbl[idx].info_idx < DIM (card->pininfo))
+       update_entry_retry_counter (card, tbl[idx].entry_id,
+                                   &card->pininfo[tbl[idx].info_idx],
+-                                  any_isnull,
++                                  any_isnull,
+                                   tbl[idx].is_puk, tbl[idx].widget);
+
+   gtk_widget_set_no_show_all (card->warning_frame, FALSE);
+@@ -371,7 +371,7 @@ reload_more_data (GpaCMNetkey *card)
+
+       align = gtk_alignment_new (0.5, 0, 0, 0);
+       button = gtk_button_new_with_label (_("Learn keys"));
+-      gpa_add_tooltip
++      gpa_add_tooltip
+         (button, _("For some or all of the keys available on the card, "
+                    "the GnuPG crypto engine does not yet know the "
+                    "corresponding certificates.\n"
+@@ -404,7 +404,7 @@ static gboolean
+ reload_more_data_idle_cb (void *user_data)
+ {
+   GpaCMNetkey *card = user_data;
+-
++
+   if (card->reloading)
+     {
+       g_debug ("already reloading (count=%d)", card->reloading);
+@@ -414,7 +414,7 @@ reload_more_data_idle_cb (void *user_data)
+
+   card->reloading++;
+   reload_more_data (card);
+-  g_object_unref (card);
++  g_object_unref (card);
+   card->reloading--;
+
+   return FALSE;  /* Remove us from the idle queue.  */
+@@ -450,17 +450,17 @@ scd_getattr_cb (void *opaque, const char *status, const char *args)
+           if (parm->updfnc)
+             parm->updfnc (parm->card, entry_id, tmp);
+           else if (GTK_IS_LABEL (parm->card->entries[entry_id]))
+-            gtk_label_set_text
++            gtk_label_set_text
+               (GTK_LABEL (parm->card->entries[entry_id]), tmp);
+           else
+-            gtk_entry_set_text
++            gtk_entry_set_text
+               (GTK_ENTRY (parm->card->entries[entry_id]), tmp);
+           xfree (tmp);
+         }
+     }
+
+   return 0;
+-}
++}
+
+
+ /* Use the assuan machinery to load the bulk of the OpenPGP card data.  */
+@@ -509,7 +509,7 @@ reload_data (GpaCMNetkey *card)
+         {
+           /* The NKS-VERSION is only supported by GnuPG > 2.0.11
+              thus we ignore the error.  */
+-          gtk_label_set_text
++          gtk_label_set_text
+             (GTK_LABEL (card->entries[attrtbl[attridx].entry_id]),
+              _("unknown"));
+         }
+@@ -519,7 +519,7 @@ reload_data (GpaCMNetkey *card)
+             ; /* Lost the card.  */
+           else
+             {
+-              g_debug ("assuan command `%s' failed: %s <%s>\n",
++              g_debug ("assuan command `%s' failed: %s <%s>\n",
+                        command, gpg_strerror (err), gpg_strsource (err));
+             }
+           clear_card_data (card);
+@@ -537,7 +537,7 @@ reload_data (GpaCMNetkey *card)
+
+
+ /* A structure used to pass data to the learn_keys_gpg_status_cb.  */
+-struct learn_keys_gpg_status_parm
++struct learn_keys_gpg_status_parm
+ {
+   GpaCMNetkey    *card;
+   GtkWidget      *button;
+@@ -546,11 +546,11 @@ struct learn_keys_gpg_status_parm
+
+
+ /* Helper for learn_keys_clicked_cb.  */
+-static gboolean
++static gboolean
+ learn_keys_gpg_status_cb (void *opaque, char *line)
+ {
+   struct learn_keys_gpg_status_parm *parm = opaque;
+-
++
+   if (!line)
+     {
+       /* We are finished with the command.  */
+@@ -590,7 +590,7 @@ learn_keys_clicked_cb (GtkButton *button, void *user_data)
+
+   widget = gtk_progress_bar_new ();
+   gtk_container_add (GTK_CONTAINER (button), widget);
+-  gtk_progress_bar_set_text (GTK_PROGRESS_BAR (widget),
++  gtk_progress_bar_set_text (GTK_PROGRESS_BAR (widget),
+                               _("Learning keys ..."));
+   gtk_widget_show_all (GTK_WIDGET (button));
+
+@@ -600,8 +600,8 @@ learn_keys_clicked_cb (GtkButton *button, void *user_data)
+   parm->button = GTK_WIDGET (button);
+   parm->pbar = GTK_PROGRESS_BAR (widget);
+
+-  err = gpa_start_simple_gpg_command
+-    (learn_keys_gpg_status_cb, parm, GPGME_PROTOCOL_CMS,
++  err = gpa_start_simple_gpg_command
++    (learn_keys_gpg_status_cb, parm, GPGME_PROTOCOL_CMS, 1,
+      "--learn-card", "-v", NULL);
+   if (err)
+     {
+@@ -633,7 +633,7 @@ change_nullpin (GpaCMNetkey *card)
+   else
+     return; /* Oops: No NullPIN.  */
+
+-  string = g_strdup_printf
++  string = g_strdup_printf
+     (_("<b>Setting the Initial PIN</b> (%s)\n\n"
+        "You selected to set the initial PIN of your card.  "
+        "The PIN is currently set to the NullPIN.  Setting an "
+@@ -653,12 +653,12 @@ change_nullpin (GpaCMNetkey *card)
+          "PIN to the same value as used for the NKS keys.")
+      : _("You are now setting the PIN for the NKS keys used for standard "
+          "signatures, encryption and authentication."));
+-
++
+   /* FIXME:  How do we figure out our GtkWindow?  */
+   dialog = gtk_message_dialog_new_with_markup (NULL /*GTK_WINDOW (card)*/,
+                                                GTK_DIALOG_DESTROY_WITH_PARENT,
+-                                               GTK_MESSAGE_INFO,
+-                                               GTK_BUTTONS_OK_CANCEL,
++                                               GTK_MESSAGE_INFO,
++                                               GTK_BUTTONS_OK_CANCEL,
+                                                NULL);
+   gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG (dialog), string);
+   g_free (string);
+@@ -679,7 +679,7 @@ change_nullpin (GpaCMNetkey *card)
+         okay = 0; /* No need to reload the data.  */
+       else if (err)
+         {
+-          char *message = g_strdup_printf
++          char *message = g_strdup_printf
+             (_("Error changing the NullPIN.\n"
+                "(%s <%s>)"), gpg_strerror (err), gpg_strsource (err));
+           gpa_window_error (message, NULL);
+@@ -709,7 +709,7 @@ change_or_reset_pin (GpaCMNetkey *card, int info_idx)
+   g_return_if_fail (gpgagent);
+   g_return_if_fail (info_idx < DIM (card->pininfo));
+
+-  if (!card->pininfo[info_idx].valid
++  if (!card->pininfo[info_idx].valid
+       || card->pininfo[info_idx].nopin
+       || card->pininfo[info_idx].nullpin)
+     {
+@@ -741,7 +741,7 @@ change_or_reset_pin (GpaCMNetkey *card, int info_idx)
+                 "of the PIN and the corresponding PUK are both down "
+                 "to zero, the keys controlled by the PIN are not anymore "
+                 "usable and there is no way to unblock them!")
+-            : is_puk
++            : is_puk
+             ? _("<b>Resetting a PUK</b>\n"
+                 "\n"
+                 "Although <i>PUK</i> stands for <i>PIN Unblocking Code</i> "
+@@ -766,12 +766,12 @@ change_or_reset_pin (GpaCMNetkey *card, int info_idx)
+                 "value of the PUK and then to enter a new value for the "
+                 "blocked PIN and repeat that new value at another prompt.")
+             );
+-
++
+   /* FIXME:  How do we figure out our GtkWindow?  */
+   dialog = gtk_message_dialog_new_with_markup (NULL /*GTK_WINDOW (card)*/,
+                                                GTK_DIALOG_DESTROY_WITH_PARENT,
+-                                               GTK_MESSAGE_INFO,
+-                                               GTK_BUTTONS_OK_CANCEL,
++                                               GTK_MESSAGE_INFO,
++                                               GTK_BUTTONS_OK_CANCEL,
+                                                NULL);
+   gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG (dialog), string);
+   okay = (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK);
+@@ -783,13 +783,13 @@ change_or_reset_pin (GpaCMNetkey *card, int info_idx)
+                 reset_mode? " --reset":"", pwidstr);
+       err = gpgme_op_assuan_transact (gpgagent, command,
+                                       NULL, NULL, NULL, NULL, NULL, NULL);
+-      if (!err)
++      if (!err)
+         err = gpgme_op_assuan_result (gpgagent)->err;
+       if (gpg_err_code (err) == GPG_ERR_CANCELED)
+         okay = 0; /* No need to reload the data.  */
+-      else if (err)
++      else if (err)
+         {
+-          char *message = g_strdup_printf
++          char *message = g_strdup_printf
+             (_("Error changing or resetting the PIN/PUK.\n"
+                "(%s <%s>)"), gpg_strerror (err), gpg_strsource (err));
+           gpa_window_error (message, NULL);
+@@ -840,12 +840,12 @@ add_table_row (GtkWidget *table, int *rowidx,
+   label = gtk_label_new (labelstr);
+   gtk_label_set_width_chars  (GTK_LABEL (label), 22);
+   gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+-  gtk_table_attach (GTK_TABLE (table), label, 0, 1,
+-                    *rowidx, *rowidx + 1, GTK_FILL, GTK_SHRINK, 0, 0);
++  gtk_table_attach (GTK_TABLE (table), label, 0, 1,
++                    *rowidx, *rowidx + 1, GTK_FILL, GTK_SHRINK, 0, 0);
+
+   if (is_label)
+     gtk_misc_set_alignment (GTK_MISC (widget), 0, 0.5);
+-
++
+   if (readonly)
+     {
+       if (!is_label && GTK_IS_ENTRY (widget))
+@@ -859,7 +859,7 @@ add_table_row (GtkWidget *table, int *rowidx,
+       if (is_label)
+         gtk_label_set_selectable (GTK_LABEL (widget), TRUE);
+     }
+-
++
+   gtk_table_attach (GTK_TABLE (table), widget, 1, 2,
+                     *rowidx, *rowidx + 1, GTK_FILL, GTK_SHRINK, 0, 0);
+   if (widget2)
+@@ -893,17 +893,17 @@ construct_data_widget (GpaCMNetkey *card)
+   gtk_container_set_border_width (GTK_CONTAINER (table), 10);
+   gtk_container_add (GTK_CONTAINER (frame), table);
+   rowidx = 0;
+-
++
+   card->entries[ENTRY_SERIALNO] = gtk_label_new (NULL);
+   add_table_row (table, &rowidx, _("Serial number:"),
+                  card->entries[ENTRY_SERIALNO], NULL, 0);
+
+   card->entries[ENTRY_NKS_VERSION] = gtk_label_new (NULL);
+-  add_table_row (table, &rowidx, _("Card version:"),
++  add_table_row (table, &rowidx, _("Card version:"),
+                  card->entries[ENTRY_NKS_VERSION], NULL, 0);
+
+   gtk_box_pack_start (GTK_BOX (card), frame, FALSE, TRUE, 0);
+-
++
+
+   /* Warning frame.  */
+   frame = gtk_frame_new (NULL);
+@@ -939,7 +939,7 @@ construct_data_widget (GpaCMNetkey *card)
+      widgets are added while figuring out the keys of the card.  */
+   label = gtk_label_new (_("scanning ..."));
+   gtk_container_add (GTK_CONTAINER (frame), label);
+-
++
+   gtk_box_pack_start (GTK_BOX (card), frame, FALSE, TRUE, 0);
+   card->keys_frame = frame;
+
+@@ -957,42 +957,42 @@ construct_data_widget (GpaCMNetkey *card)
+
+   card->entries[ENTRY_PIN_RETRYCOUNTER] = gtk_label_new (NULL);
+   button = gtk_button_new ();
+-  add_table_row (table, &rowidx, _("PIN retry counter:"),
++  add_table_row (table, &rowidx, _("PIN retry counter:"),
+                  card->entries[ENTRY_PIN_RETRYCOUNTER], button, 1);
+-  card->change_pin_btn = button;
++  card->change_pin_btn = button;
+   g_signal_connect (G_OBJECT (button), "clicked",
+                     G_CALLBACK (change_pin_clicked_cb), card);
+
+   card->entries[ENTRY_PUK_RETRYCOUNTER] = gtk_label_new (NULL);
+   button = gtk_button_new ();
+-  add_table_row (table, &rowidx, _("PUK retry counter:"),
++  add_table_row (table, &rowidx, _("PUK retry counter:"),
+                  card->entries[ENTRY_PUK_RETRYCOUNTER], button, 1);
+-  card->change_puk_btn = button;
++  card->change_puk_btn = button;
+   g_signal_connect (G_OBJECT (button), "clicked",
+                     G_CALLBACK (change_pin_clicked_cb), card);
+
+   card->entries[ENTRY_SIGG_PIN_RETRYCOUNTER] = gtk_label_new (NULL);
+   button = gtk_button_new ();
+-  add_table_row (table, &rowidx, _("SigG PIN retry counter:"),
++  add_table_row (table, &rowidx, _("SigG PIN retry counter:"),
+                  card->entries[ENTRY_SIGG_PIN_RETRYCOUNTER], button, 1);
+-  card->change_sigg_pin_btn = button;
++  card->change_sigg_pin_btn = button;
+   g_signal_connect (G_OBJECT (button), "clicked",
+                     G_CALLBACK (change_pin_clicked_cb), card);
+
+   card->entries[ENTRY_SIGG_PUK_RETRYCOUNTER] = gtk_label_new (NULL);
+   button = gtk_button_new ();
+-  add_table_row (table, &rowidx, _("SigG PUK retry counter:"),
++  add_table_row (table, &rowidx, _("SigG PUK retry counter:"),
+                  card->entries[ENTRY_SIGG_PUK_RETRYCOUNTER], button, 1);
+-  card->change_sigg_puk_btn = button;
++  card->change_sigg_puk_btn = button;
+   g_signal_connect (G_OBJECT (button), "clicked",
+                     G_CALLBACK (change_pin_clicked_cb), card);
+-
++
+   gtk_box_pack_start (GTK_BOX (card), frame, FALSE, TRUE, 0);
+ }
+
+
+ 

+-/************************************************************
++/************************************************************
+  ******************   Object Management  ********************
+  ************************************************************/
+
+@@ -1002,7 +1002,7 @@ gpa_cm_netkey_class_init (void *class_ptr, void *class_data)
+   GpaCMNetkeyClass *klass = class_ptr;
+
+   parent_class = g_type_class_peek_parent (klass);
+-
++
+   G_OBJECT_CLASS (klass)->finalize = gpa_cm_netkey_finalize;
+ }
+
+@@ -1019,7 +1019,7 @@ gpa_cm_netkey_init (GTypeInstance *instance, void *class_ptr)
+
+ static void
+ gpa_cm_netkey_finalize (GObject *object)
+-{
++{
+ /*   GpaCMNetkey *card = GPA_CM_NETKEY (object); */
+
+   parent_class->finalize (object);
+@@ -1031,7 +1031,7 @@ GType
+ gpa_cm_netkey_get_type (void)
+ {
+   static GType this_type = 0;
+-
++
+   if (!this_type)
+     {
+       static const GTypeInfo this_info =
+@@ -1046,23 +1046,23 @@ gpa_cm_netkey_get_type (void)
+	  0,    /* n_preallocs */
+	  gpa_cm_netkey_init
+	};
+-
++
+       this_type = g_type_register_static (GPA_CM_OBJECT_TYPE,
+                                           "GpaCMNetkey",
+                                           &this_info, 0);
+     }
+-
++
+   return this_type;
+ }
+
+ 

+-/************************************************************
++/************************************************************
+  **********************  Public API  ************************
+  ************************************************************/
+ GtkWidget *
+ gpa_cm_netkey_new ()
+ {
+-  return GTK_WIDGET (g_object_new (GPA_CM_NETKEY_TYPE, NULL));
++  return GTK_WIDGET (g_object_new (GPA_CM_NETKEY_TYPE, NULL));
+ }
+
+
+diff --git a/src/get-path.c b/src/get-path.c
+index f50e21b..71fe0e1 100644
+--- a/src/get-path.c
++++ b/src/get-path.c
+@@ -1,6 +1,6 @@
+ /* get-path.c - Find a system path.
+    Copyright (C) 2000-2002 G-N-U GmbH.
+-   Copyright (C) 2005, 2008 g10 Code GmbH.
++   Copyright (C) 2005, 2008, 2013 g10 Code GmbH.
+
+    This file is part of GPA.
+
+@@ -23,7 +23,10 @@
+ #endif
+
+ #include <glib.h>
++#include <string.h>
++#include <gpgme.h>
+
++#include "gpa.h"
+ #include "get-path.h"
+
+ 

+@@ -31,7 +34,7 @@
+
+ #include <unistd.h>
+
+-#include <windows.h>
++#include <windows.h>
+
+ #include "w32reg.h"
+
+@@ -55,7 +58,7 @@ w32_strerror (int w32_errno)
+ {
+   static char strerr[256];
+   int ec = (int) GetLastError ();
+-
++
+   if (w32_errno == 0)
+     w32_errno = ec;
+   FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM, NULL, w32_errno,
+@@ -103,7 +106,7 @@ dlclose (void *hd)
+       return 0;
+     }
+   return -1;
+-}
++}
+
+
+ static HRESULT
+@@ -143,13 +146,83 @@ w32_shgetfolderpath (HWND a, int b, HANDLE c, DWORD d, LPSTR e)
+
+ #endif	/* G_OS_WIN32 */
+
++
++
++
+ 

++struct homedir_from_gpgconf_s
++{
++  GMainLoop *loop;
++  char *homedir;
++};
++
++static gboolean
++homedir_from_gpgconf_parser (void *opaque, char *line)
++{
++  struct homedir_from_gpgconf_s *parm = opaque;
++  char *value, *p;
++
++  if (!line)
++    {
++      /* We are finished with the command.  Stop the loop.  */
++      g_main_loop_quit (parm->loop);
++      return FALSE; /* (The return code does not matter here.)  */
++    }
++
++  value = strchr (line, ':');
++  if (!value)
++    return TRUE; /* Invalid line - keep on running.  */;
++  *value++ = 0;
++  if (strcmp (line, "homedir"))
++    return TRUE; /* Not the right item - keep on running.  */
++
++  p = strchr (value, ':');
++  if (p)
++    *p = 0;
++  decode_percent_string (value);
++  parm->homedir = g_strdup (value);
++  return FALSE; /* Ready - force an EOF.  */
++}
++
++
++/* Retrieve the default home directory via gpgconf and return it as a
++   malloced string.  If this is not possible, return NULL.  */
++static char *
++homedir_from_gpgconf (void)
++{
++  struct homedir_from_gpgconf_s parm;
++
++  memset (&parm, 0, sizeof parm);
++
++  parm.loop = g_main_loop_new (NULL, TRUE);
++
++  if (gpa_start_simple_gpg_command
++      (homedir_from_gpgconf_parser, &parm,
++       GPGME_PROTOCOL_GPGCONF, 0, "--list-dirs", NULL))
++    {
++      g_main_loop_unref (parm.loop);
++      return NULL;
++    }
++
++  g_main_loop_run (parm.loop);
++  g_main_loop_unref (parm.loop);
++  return parm.homedir;
++}
++
++
+ /* Get the path to the default home directory.  */
+ gchar *
+ default_homedir (void)
+ {
+   gchar *dir;
+
++  dir = homedir_from_gpgconf ();
++  if (dir)
++    {
++      g_debug ("Found homedir '%s' via gpgconf", dir);
++      return dir;
++    }
++
+   /* g_getenv returns string in filename encoding.  */
+   dir = (gchar *) g_getenv ("GNUPGHOME");
+   if (dir && dir[0])
+@@ -166,7 +239,7 @@ default_homedir (void)
+	  dir = NULL;
+	}
+     }
+-
++
+   if (! dir)
+     {
+       char path[MAX_PATH];
+@@ -178,7 +251,7 @@ default_homedir (void)
+          using a system roaming serives might be better than to let
+          them do it manually.  A security conscious user will anyway
+          use the registry entry to have better control.  */
+-      if (w32_shgetfolderpath (NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE,
++      if (w32_shgetfolderpath (NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE,
+                                NULL, 0, path) >= 0)
+         {
+	  dir = g_build_filename (path, "gnupg", NULL);
+diff --git a/src/gpa.h b/src/gpa.h
+index a20d704..a321698 100644
+--- a/src/gpa.h
++++ b/src/gpa.h
+@@ -131,6 +131,7 @@ char *decode_c_string (const char *src);
+ char *percent_escape (const char *string,
+                       const char *delimiters, int space2plus);
+ size_t percent_unescape (char *string, int plus2space);
++void decode_percent_string (char *str);
+
+
+ /*-- Convenience macros. -- */
+diff --git a/src/gpgmetools.c b/src/gpgmetools.c
+index 5d4beae..a6ff3d8 100644
+--- a/src/gpgmetools.c
++++ b/src/gpgmetools.c
+@@ -1435,20 +1435,21 @@ is_gpg_version_at_least (const char *need_version)
+ }
+
+
+-/* Structure used to communicate with gpg_simple_stderr_cb.  */
+-struct gpg_simple_stderr_parm_s
++/* Structure used to communicate with gpg_simple_stdio_cb.  */
++struct gpg_simple_stdio_parm_s
+ {
+   gboolean (*cb)(void *opaque, char *line);
+   void *cb_arg;
+   GString *string;
++  int only_status_lines;
+ };
+
+ /* Helper for gpa_start_simple_gpg_command.  */
+ static gboolean
+-gpg_simple_stderr_cb (GIOChannel *channel, GIOCondition condition,
+-                      void *user_data)
++gpg_simple_stdio_cb (GIOChannel *channel, GIOCondition condition,
++                     void *user_data)
+ {
+-  struct gpg_simple_stderr_parm_s *parm = user_data;
++  struct gpg_simple_stdio_parm_s *parm = user_data;
+   GIOStatus status;
+   char *line, *p;
+
+@@ -1461,27 +1462,41 @@ gpg_simple_stderr_cb (GIOChannel *channel, GIOCondition condition,
+         {
+           line = parm->string->str;
+
++          /* Strip line terminator.  */
++          p = strchr (line, '\n');
++          if (p)
++            {
++              if (p > line && p[-1] == '\r')
++                p[-1] = 0;
++              else
++                *p = 0;
++            }
++
+           /* We care only about status lines.  */
+-          if (!strncmp (line, "[GNUPG:] ", 9))
++          if (parm->only_status_lines && !strncmp (line, "[GNUPG:] ", 9))
+             {
+               line += 9;
+
+-              /* Strip line terminator.  */
+-              p = strchr (line, '\n');
+-              if (p)
++              /* Call user callback.  */
++              if (parm->cb && !parm->cb (parm->cb_arg, line))
+                 {
+-                  if (p > line && p[-1] == '\r')
+-                    p[-1] = 0;
+-                  else
+-                    *p = 0;
++                  /* User requested EOF.  */
++                  goto cleanup;
+                 }
+-
++              /* Return direct so that we do not run into the G_IO_HUP
++                 check.  This is required to read all buffered input.  */
++              return TRUE;  /* Keep on watching this channel. */
++            }
++          else if (!parm->only_status_lines)
++            {
+               /* Call user callback.  */
+               if (parm->cb && !parm->cb (parm->cb_arg, line))
+                 {
+                   /* User requested EOF.  */
+                   goto cleanup;
+                 }
++
++              return TRUE;  /* Keep on watching this channel. */
+             }
+         }
+       if (status != G_IO_STATUS_NORMAL && status != G_IO_STATUS_AGAIN )
+@@ -1517,20 +1532,22 @@ gpg_simple_stderr_cb (GIOChannel *channel, GIOCondition condition,
+    is used to call gpg-connect-agent.
+
+    If the function returns success the provided callback CB is called
+-   for each line received on STDERR.  EOF is send to this callback by
+-   passing a LINE argument of NULL.  The callback may use this for
+-   cleanup. If the callback returns FALSE, an EOF is forced with the
+-   result that the callback is called once more with LINE set to NULL.  */
++   for each line received on stdout (respective stderr if USE_STADERR
++   is true).  EOF is send to this callback by passing a LINE as NULL.
++   The callback may use this for cleanup.  If the callback returns
++   FALSE, an EOF is forced so that the callback is called once more
++   with LINE set to NULL.  */
+ gpg_error_t
+ gpa_start_simple_gpg_command (gboolean (*cb)(void *opaque, char *line),
+                               void *cb_arg, gpgme_protocol_t protocol,
++                              int use_stderr,
+                               const char *first_arg, ...)
+ {
+   char *argv[24];
+   int argc;
+-  int fd_stderr;
++  int fd_stdio;
+   GIOChannel *channel;
+-  struct gpg_simple_stderr_parm_s *parm = NULL;
++  struct gpg_simple_stdio_parm_s *parm = NULL;
+   char *freeme = NULL;
+
+   if (protocol == GPGME_PROTOCOL_OpenPGP)
+@@ -1571,11 +1588,17 @@ gpa_start_simple_gpg_command (gboolean (*cb)(void *opaque, char *line),
+   parm->cb = cb;
+   parm->cb_arg = cb_arg;
+   parm->string = g_string_sized_new (200);
++  parm->only_status_lines = use_stderr;
+
+   if (!g_spawn_async_with_pipes (NULL, argv, NULL,
+-                                 (G_SPAWN_STDOUT_TO_DEV_NULL),
++                                 (use_stderr
++                                  ? G_SPAWN_STDOUT_TO_DEV_NULL
++                                  : G_SPAWN_STDERR_TO_DEV_NULL),
+                                  NULL, NULL, NULL,
+-                                 NULL, NULL, &fd_stderr, NULL))
++                                 NULL,
++                                 use_stderr? NULL : &fd_stdio,
++                                 use_stderr? &fd_stdio : NULL,
++                                 NULL))
+     {
+       gpa_window_error (_("Calling the crypto engine program failed."), NULL);
+       xfree (parm);
+@@ -1584,9 +1607,9 @@ gpa_start_simple_gpg_command (gboolean (*cb)(void *opaque, char *line),
+     }
+   g_free (freeme);
+ #ifdef G_OS_WIN32
+-  channel = g_io_channel_win32_new_fd (fd_stderr);
++  channel = g_io_channel_win32_new_fd (fd_stdio);
+ #else
+-  channel = g_io_channel_unix_new (fd_stderr);
++  channel = g_io_channel_unix_new (fd_stdio);
+ #endif
+   g_io_channel_set_encoding (channel, NULL, NULL);
+   /* Note that we need a buffered channel, so that we can use the read
+@@ -1595,7 +1618,7 @@ gpa_start_simple_gpg_command (gboolean (*cb)(void *opaque, char *line),
+
+   /* Create a watch for the channel.  */
+   if (!g_io_add_watch (channel, (G_IO_IN|G_IO_HUP),
+-                       gpg_simple_stderr_cb, parm))
++                       gpg_simple_stdio_cb, parm))
+     {
+       g_debug ("error creating watch for gpg command");
+       g_io_channel_unref (channel);
+@@ -1613,7 +1636,7 @@ gpa_start_simple_gpg_command (gboolean (*cb)(void *opaque, char *line),
+ void
+ gpa_start_agent (void)
+ {
+-  gpa_start_simple_gpg_command (NULL, NULL, GPGME_PROTOCOL_ASSUAN,
++  gpa_start_simple_gpg_command (NULL, NULL, GPGME_PROTOCOL_ASSUAN, 1,
+                                 "NOP", "/bye", NULL);
+ }
+
+diff --git a/src/gpgmetools.h b/src/gpgmetools.h
+index 2953362..e8b2c34 100644
+--- a/src/gpgmetools.h
++++ b/src/gpgmetools.h
+@@ -209,6 +209,7 @@ gpg_error_t gpa_start_simple_gpg_command (gboolean (*cb)
+                                           (void *opaque, char *line),
+                                           void *cb_arg,
+                                           gpgme_protocol_t protocol,
++                                          int use_stderr,
+                                           const char *first_arg, ...
+                                           ) G_GNUC_NULL_TERMINATED;
+
+diff --git a/src/server.c b/src/server.c
+index d220ccb..1ce9a89 100644
+--- a/src/server.c
++++ b/src/server.c
+@@ -1255,53 +1255,6 @@ hextobyte (const char *str)
+ }
+
+
+-/* Decode the percent escaped string STR in place.  */
+-static void
+-decode_percent_string (char *str)
+-{
+-  char *src = str;
+-  char *dest = str;
+-
+-  /* Convert the string.  */
+-  while (*src)
+-    {
+-      if (*src != '%')
+-        {
+-          *(dest++) = *(src++);
+-          continue;
+-        }
+-      else
+-        {
+-          int val = hextobyte (&src[1]);
+-
+-          if (val == -1)
+-            {
+-              /* Should not happen.  */
+-              *(dest++) = *(src++);
+-              if (*src)
+-                *(dest++) = *(src++);
+-              if (*src)
+-                *(dest++) = *(src++);
+-            }
+-          else
+-            {
+-              if (!val)
+-                {
+-                  /* A binary zero is not representable in a C
+-                     string.  */
+-                  *(dest++) = '\\';
+-                  *(dest++) = '0';
+-                }
+-              else
+-                *((unsigned char *) dest++) = val;
+-              src += 3;
+-            }
+-        }
+-    }
+-  *(dest++) = 0;
+-}
+-
+-
+ /* FILE <file> [--continued]
+
+    Set the files on which to operate.
+diff --git a/src/utils.c b/src/utils.c
+index 1b8dbaa..0d3379f 100644
+--- a/src/utils.c
++++ b/src/utils.c
+@@ -65,7 +65,7 @@ xcalloc (size_t n, size_t m)
+     memset (p, 0, nbytes);
+   else
+     {
+-      g_error ("%s: failed to allocate %lu bytes",
++      g_error ("%s: failed to allocate %lu bytes",
+                G_STRLOC, (unsigned long)nbytes);
+       abort (); /* Just in case g_error returns.  */
+     }
+@@ -97,7 +97,7 @@ translate_sys2libc_fd (assuan_fd_t fd, int for_write)
+
+   if (fd == ASSUAN_INVALID_FD)
+     return -1;
+-
++
+   /* Note that _open_osfhandle is currently defined to take and return
+      a long.  */
+   x = _open_osfhandle ((long)fd, for_write ? 1 : 0);
+@@ -111,15 +111,15 @@ translate_sys2libc_fd (assuan_fd_t fd, int for_write)
+
+
+ #ifdef HAVE_W32_SYSTEM
+-int
++int
+ inet_aton (const char *cp, struct in_addr *inp)
+ {
+   if (!cp || !*cp || !inp)
+     {
+       errno = EINVAL;
+-      return 0;
++      return 0;
+     }
+-
++
+   if (!strcmp(cp, "255.255.255.255"))
+     {
+       /*  Although this is a valid address, the old inet_addr function
+@@ -127,7 +127,7 @@ inet_aton (const char *cp, struct in_addr *inp)
+         inp->s_addr = INADDR_NONE;
+         return 1;
+     }
+-
++
+   inp->s_addr = inet_addr (cp);
+   return (inp->s_addr != INADDR_NONE);
+ }
+@@ -226,9 +226,9 @@ decode_c_string (const char *src)
+		       this will also never be larger than the source
+		       string.  */
+		    *(dest++) = '\\';
+-		    *(dest++) = '0';
++		    *(dest++) = '0';
+		  }
+-		else
++		else
+		  *((unsigned char *) dest++) = val;
+		src += 4;
+	      }
+@@ -322,7 +322,7 @@ percent_unescape (char *string, int plus2space)
+   while (*string)
+     {
+       if (*string == '%' && string[1] && string[2])
+-        {
++        {
+           string++;
+           *p++ = xtoi_2 (string);
+           n++;
+@@ -345,3 +345,50 @@ percent_unescape (char *string, int plus2space)
+ }
+
+
++/* Decode the percent escaped string STR in place.  In contrast to
++   percent_unescape, this make sure that the result is a string and in
++   addition escapes embedded nuls. */
++void
++decode_percent_string (char *str)
++{
++  char *src = str;
++  char *dest = str;
++
++  /* Convert the string.  */
++  while (*src)
++    {
++      if (*src != '%')
++        {
++          *(dest++) = *(src++);
++          continue;
++        }
++      else
++        {
++          int val = hextobyte (&src[1]);
++
++          if (val == -1)
++            {
++              /* Should not happen.  */
++              *(dest++) = *(src++);
++              if (*src)
++                *(dest++) = *(src++);
++              if (*src)
++                *(dest++) = *(src++);
++            }
++          else
++            {
++              if (!val)
++                {
++                  /* A binary zero is not representable in a C
++                     string.  */
++                  *(dest++) = '\\';
++                  *(dest++) = '0';
++                }
++              else
++                *((unsigned char *) dest++) = val;
++              src += 3;
++            }
++        }
++    }
++  *(dest++) = 0;
++}
+--
+1.7.7.1

-----------------------------------------------------------------------

Summary of changes:
 Makefile.am                                    |    4 +-
 patches/gpa-0.9.4/03-homedir-via-gpgconf.patch | 1032 ++++++++++++++++++++++++
 2 files changed, 1034 insertions(+), 2 deletions(-)
 create mode 100755 patches/gpa-0.9.4/03-homedir-via-gpgconf.patch


hooks/post-receive
-- 
GnuPG for Windows
http://git.gnupg.org



More information about the Gpg4win-commits mailing list