2007-05-20 Marcus Brinkmann <marcus@g10code.de>
authorMarcus Brinkmann <mb@g10code.com>
Sun, 20 May 2007 16:40:30 +0000 (16:40 +0000)
committerMarcus Brinkmann <mb@g10code.com>
Sun, 20 May 2007 16:40:30 +0000 (16:40 +0000)
* src/gpgwrap.c (build_commandline): New function.
(main): Quote argument vector.

ChangeLog
src/gpgwrap.c

index dd6bda1..314d742 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,8 @@
 2007-05-20  Marcus Brinkmann  <marcus@g10code.de>
 
+       * src/gpgwrap.c (build_commandline): New function.
+       (main): Quote argument vector.
+
        * configure.ac: Comment advanced manual here as well.
 
 2007-05-19  Marcus Brinkmann  <marcus@g10code.de>
index be554f6..2910853 100644 (file)
 #include <windows.h>
 
 
+/* Return a copy of ARGV, but with proper quoting.  To release the
+   copy, you have to free argv_quoted[0] and argv_quoted.  */
+static char **
+build_commandline (const char * const *argv)
+{
+  int i;
+  int j;
+  int n = 0;
+  char *buf;
+  char *p;
+  char **argv_quoted;
+
+  /* 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 = (char *) 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++;
+
+  /* Allocate a new vector.  */
+  argv_quoted = malloc (sizeof (char *) * (i + 1));
+  if (!argv_quoted)
+    return NULL;
+
+  buf = p = malloc (n);
+  if (!buf)
+    {
+      free (argv_quoted);
+      return NULL;
+    }
+
+  for (i = 0; argv[i]; i++)
+    {
+      const char *argvp = argv[i];
+
+      argv_quoted[i] = p;
+
+      *(p++) = '"';
+      while (*argvp)
+       {
+         if (*argvp == '\\' || *argvp == '"')
+           *(p++) = '\\';
+         *(p++) = *(argvp++);
+       }
+      *(p++) = '"';
+      *(p++) = ' ';
+    }
+  *(p++) = 0;
+  argv_quoted[i] = NULL;
+
+  return argv_quoted;
+}
+
+
 int
 main (int argc, const char * const *argv)
 {
   int rc;
   char pgm[MAX_PATH+100];
   char *p, *p0;
+  char **argv_quoted;
 
-  if ( !GetModuleFileNameA (NULL, pgm, sizeof pgm -1) )
+  if (!GetModuleFileNameA (NULL, pgm, sizeof (pgm) - 1))
     {
       fprintf (stderr, "gpgwrap: error getting my own name: rc=%d\n",
                GetLastError());
@@ -69,7 +141,11 @@ main (int argc, const char * const *argv)
       fflush (stdout);
     }
 
-  execv (pgm, argv);
+  argv_quoted = build_commandline (argv);
+  if (!argv_quoted)
+    goto leave;
+
+  execv (pgm, (const char **) argv_quoted);
   fprintf (stderr, "gpgwrap: executing `%s' failed: %s\n",
            pgm, strerror (errno));
   return 2;
@@ -78,5 +154,3 @@ main (int argc, const char * const *argv)
            pgm);
   return 2;
 }
-
-