[git] GPA - branch, master, updated. gpa-0.9.4-20-g63c1b56

by Werner Koch cvs at cvs.gnupg.org
Tue Apr 8 20:54:21 CEST 2014


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  63c1b56a0ec6641534c2ffaff174fe7e46dc9fbd (commit)
      from  a74c29602482d361d289dc6248208fa6f2bc36c4 (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 63c1b56a0ec6641534c2ffaff174fe7e46dc9fbd
Author: Werner Koch <wk at gnupg.org>
Date:   Tue Apr 8 19:14:08 2014 +0200

    w32: Add launch-gpa tool
    
    * src/launch-gpa.c: New.
    * src/Makefile.am (bin_PROGRAMS) [W32]: Add launch-gpa
    (launch_gpa_LDFLAGS): New.
    --
    
    This tool is used to start gpa so that Window does not allocate a
    console.

diff --git a/src/Makefile.am b/src/Makefile.am
index 72c9efe..d961144 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -58,6 +58,10 @@ endif
 
 
 bin_PROGRAMS = gpa
+if HAVE_W32_SYSTEM
+ bin_PROGRAMS += launch-gpa
+endif
+
 noinst_PROGRAMS = dndtest
 
 AM_CPPFLAGS = -I$(top_srcdir)/intl -I$(top_srcdir)/pixmaps
@@ -70,6 +74,11 @@ LDADD = $(GPGME_LIBS) $(LIBASSUAN_LIBS) $(GPG_ERROR_LIBS) \
 gpa_LDFLAGS = $(gpa_res_ldflag)
 gpa_DEPENDENCIES = $(gpa_deps)
 
+if HAVE_W32_SYSTEM
+launch_gpa_SOURCES = launch-gpa.c
+launch_gpa_LDFLAGS = -mwindows
+endif
+
 if ENABLE_CARD_MANAGER
 gpa_cardman_sources = \
                 cardman.c cardman.h \
diff --git a/src/gpgmetools.c b/src/gpgmetools.c
index 5a8641a..23db6c1 100644
--- a/src/gpgmetools.c
+++ b/src/gpgmetools.c
@@ -1442,7 +1442,27 @@ gpg_simple_stdio_cb (GIOChannel *channel, GIOCondition condition,
    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.  */
+   with LINE set to NULL.
+
+   This function is used to run
+
+    gpgsm --learn-card
+    gpgconf --list-dirs
+    gpg-connect-agent NOP /bye
+
+   The problem is that under Windows g_spawn does not allow to specify
+   flags for the underlying CreateProcess.  Thus it is not possible to
+   create a process detached (i.e. without a console); the result is
+   that a windows pops up.  I can see two solutions: (1) Use a wrapper
+   process to start them detached. or (2) move the required function
+   into GPGME and use that new API.
+
+   With the latest GnuPG we can even forget about gpg-connect-agent
+   and use "gpgconf --launch gpg-agent" instead.  However that is no
+   solution if we are required to use an old gnupg.
+
+
+  */
 gpg_error_t
 gpa_start_simple_gpg_command (gboolean (*cb)(void *opaque, char *line),
                               void *cb_arg, gpgme_protocol_t protocol,
diff --git a/src/launch-gpa.c b/src/launch-gpa.c
new file mode 100644
index 0000000..1ceed06
--- /dev/null
+++ b/src/launch-gpa.c
@@ -0,0 +1,206 @@
+/* launch-gpa.c - Wrapper to start GPA under Windows.
+ * Copyright (C) 2014 g10 Code GmbH
+ *
+ * This file is part of GPA
+ *
+ * GPA is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GPA is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+ * 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/>.
+ */
+
+/* This wrapper merely starts gpa in detached mode.  Building gpa as
+   console program has the advantage that debugging is easier and we
+   get a nice help menu on the command line.  Tricks building as
+   windows subsystem and using AllocConsole don't work well because
+   the shell might have already created a console window before we get
+   control.  */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <windows.h>
+
+static char *
+build_commandline (char **argv)
+{
+  int i;
+  int n = 0;
+  char *buf;
+  char *p;
+
+  /* We have to quote some things because under Windows the program
+     parses the commandline and does some unquoting.  We enclose the
+     whole argument in double-quotes, and escape literal double-quotes
+     as well as backslashes with a backslash.  We end up with a
+     trailing space at the end of the line, but that is harmless.  */
+  for (i = 0; argv[i]; i++)
+    {
+      p = argv[i];
+      /* The leading double-quote.  */
+      n++;
+      while (*p)
+	{
+	  /* An extra one for each literal that must be escaped.  */
+	  if (*p == '\\' || *p == '"')
+	    n++;
+	  n++;
+	  p++;
+	}
+      /* The trailing double-quote and the delimiter.  */
+      n += 2;
+    }
+  /* And a trailing zero.  */
+  n++;
+
+  buf = p = malloc (n);
+  if (!buf)
+    return NULL;
+  for (i = 0; argv[i]; i++)
+    {
+      char *argvp = argv[i];
+
+      *(p++) = '"';
+      while (*argvp)
+	{
+	  if (*argvp == '\\' || *argvp == '"')
+	    *(p++) = '\\';
+	  *(p++) = *(argvp++);
+	}
+      *(p++) = '"';
+      *(p++) = ' ';
+    }
+  *(p++) = 0;
+
+  return buf;
+}
+
+
+int
+main (int argc, char **argv)
+{
+  char me[256];
+  int i;
+  char pgm[MAX_PATH+100];
+  char *p, *p0, *p1, *arg0;
+  char *arg_string;
+  SECURITY_ATTRIBUTES sec_attr;
+  STARTUPINFOA si;
+  int cr_flags;
+  PROCESS_INFORMATION pi =
+    {
+      NULL,      /* returns process handle */
+      0,         /* returns primary thread handle */
+      0,         /* returns pid */
+      0          /* returns tid */
+    };
+
+  p = argc?argv[0]:"?";
+  p0 = strrchr (p, '/');
+  p1 = strrchr (p, '\\');
+  if (p0 && p1)
+    p = p0 > p1? p0+1 : p1+1;
+  else if (p0)
+    p = p0+1;
+  else if (p1)
+    p = p1+1;
+
+  for (i=0; *p && i < sizeof me - 1; i++)
+    me[i] = *p++;
+  me[i] = 0;
+  p = strchr (me, '.');
+  if (p)
+    *p = 0;
+  strlwr (me);
+
+  if (!GetModuleFileNameA (NULL, pgm, sizeof (pgm) - 1))
+    {
+      fprintf (stderr, "%s: error getting my own name: rc=%d\n",
+               me, (int)GetLastError ());
+      return 2;
+    }
+
+  /* Remove the "launch-" part from the module name.  */
+  p0 = strrchr (pgm, '\\');
+  if (!p0)
+    goto leave;
+  p0++;
+  arg0 = p0;
+  if (strnicmp (p0, "launch-", 7))
+    goto leave;
+  for (p = p0+7; *p; p++)
+    *p0++ = *p;
+  *p0 = 0;
+
+  /* Hack to output our own version along with the real file name
+     before the actual, we require that the --version option is given
+     twice.  Not very useful for a -mwindows program, though.  */
+  if (argc > 2
+      && !strcmp(argv[1], "--version")
+      && !strcmp(argv[2], "--version"))
+    {
+      printf (stdout, "%s %s ;%s\n", me, PACKAGE_VERSION, pgm);
+      fflush (stdout);
+    }
+
+  p = argv[0];
+  argv[0] = arg0;
+  arg_string = build_commandline (argv);
+  argv[0] = p;
+  if (!arg_string)
+    {
+      fprintf (stderr, "%s: error building command line\n", me);
+      return 2;
+    }
+
+  memset (&sec_attr, 0, sizeof sec_attr);
+  sec_attr.nLength = sizeof sec_attr;
+  sec_attr.bInheritHandle = FALSE;
+
+  memset (&si, 0, sizeof si);
+  si.cb = sizeof (si);
+  si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
+  si.wShowWindow = SW_HIDE;
+  si.hStdInput = INVALID_HANDLE_VALUE;
+  si.hStdOutput = INVALID_HANDLE_VALUE;
+  si.hStdError = INVALID_HANDLE_VALUE;
+
+  cr_flags  = CREATE_DEFAULT_ERROR_MODE;
+  cr_flags |= DETACHED_PROCESS;
+  cr_flags |= GetPriorityClass (GetCurrentProcess ());
+  if (!CreateProcessA (pgm,
+		       arg_string,
+		       NULL,          /* process security attributes */
+		       NULL,          /* thread security attributes */
+		       FALSE,         /* inherit handles */
+		       cr_flags,      /* creation flags */
+		       NULL,          /* environment */
+		       NULL,          /* use current drive/directory */
+		       &si,           /* startup information */
+		       &pi))          /* returns process information */
+    {
+      fprintf (stderr, "%s: executing `%s' failed: rc=%d\n",
+	       me, pgm, (int) GetLastError ());
+      free (arg_string);
+      return 2;
+     }
+
+  free (arg_string);
+  return 0;
+
+ leave:
+  fprintf (stderr, "%s: internal error parsing my own name `%s'\n",
+           me, pgm);
+  return 2;
+}

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

Summary of changes:
 src/Makefile.am  |    9 +++
 src/gpgmetools.c |   22 +++++-
 src/launch-gpa.c |  206 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 236 insertions(+), 1 deletion(-)
 create mode 100644 src/launch-gpa.c


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




More information about the Gnupg-commits mailing list