[git] GPA - branch, master, updated. gpa-0.9.4-6-g398fd02

by Werner Koch cvs at cvs.gnupg.org
Mon Aug 12 19:16:06 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 "The GNU Privacy Assistant".

The branch, master has been updated
       via  398fd028c762dd6c0fc7a5945f55eb2dbd2edaec (commit)
      from  6742525110270b0098e41157edfb13e36483f1ca (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 398fd028c762dd6c0fc7a5945f55eb2dbd2edaec
Author: Werner Koch <wk at gnupg.org>
Date:   Mon Aug 12 18:44:06 2013 +0200

    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.

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;
+}

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

Summary of changes:
 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(-)


hooks/post-receive
-- 
The GNU Privacy Assistant
http://git.gnupg.org




More information about the Gnupg-commits mailing list