More cleanup of "allow to".
[gnupg.git] / agent / w32main.c
index 5fccb7e..d907fe5 100644 (file)
@@ -1,11 +1,12 @@
 /* w32main.c - W32 main entry pint and taskbar support for the GnuPG Agent
  * Copyright (C) 2007 Free Software Foundation, Inc.
+ * Copyright 1996, 1998 Alexandre Julliard
  *
  * This file is part of GnuPG.
  *
  * GnuPG 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
+ * the Free Software Foundation; either version 3 of the License, or
  * (at your option) any later version.
  *
  * GnuPG is distributed in the hope that it will be useful,
@@ -14,9 +15,7 @@
  * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
- * USA.
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
 #include <config.h>
@@ -37,10 +36,140 @@ static HINSTANCE glob_hinst;
 static HWND glob_hwnd;
 
 
+/* Build an argv array from the command in CMDLINE.  RESERVED is the
+   number of args to reserve before the first one.  This code is based
+   on Alexandre Julliard's LGPLed wine-0.9.34/dlls/kernel32/process.c
+   and modified to fit into our framework.  The function returns NULL
+   on error; on success an arry with the argiments is returned.  This
+   array has been allocaqted using a plain malloc (and not the usual
+   xtrymalloc). */
+static char **
+build_argv (char *cmdline_arg, int reserved)
+{
+  int argc;
+  char **argv;
+  char *cmdline, *s, *arg, *d;
+  int in_quotes, bs_count;
+
+  cmdline = malloc (strlen (cmdline_arg) + 1);
+  if (!cmdline)
+    return NULL;
+  strcpy (cmdline, cmdline_arg);
+
+  /* First determine the required size of the array.  */
+  argc = reserved + 1;
+  bs_count = 0;
+  in_quotes = 0;
+  s = cmdline;
+  for (;;)
+    {
+      if ( !*s || ((*s==' ' || *s=='\t') && !in_quotes)) /* A space.  */
+        {
+          argc++;
+          /* Skip the remaining spaces.  */
+          while (*s==' ' || *s=='\t')
+            s++;
+          if (!*s)
+            break;
+          bs_count = 0;
+        }
+      else if (*s=='\\')
+        {
+          bs_count++;
+          s++;
+        }
+      else if ( (*s == '\"') && !(bs_count & 1))
+        {
+          /* Unescaped '\"' */
+          in_quotes = !in_quotes;
+          bs_count=0;
+          s++;
+        }
+      else /* A regular character. */
+        {
+          bs_count = 0;
+          s++;
+        }
+    }
+
+  argv = xtrymalloc (argc * sizeof *argv);
+  if (!argv)
+    {
+      xfree (cmdline);
+      return NULL;
+    }
+
+  /* Now actually parse the command line.  */
+  argc = reserved;
+  bs_count = 0;
+  in_quotes=0;
+  arg = d = s = cmdline;
+  while (*s)
+    {
+      if ((*s==' ' || *s=='\t') && !in_quotes)
+        {
+          /* Close the argument and copy it. */
+          *d = 0;
+          argv[argc++] = arg;
+
+          /* Skip the remaining spaces. */
+          do
+            s++;
+          while (*s==' ' || *s=='\t');
+
+          /* Start with a new argument */
+          arg = d = s;
+          bs_count = 0;
+        }
+      else if (*s=='\\')
+        {
+          *d++ = *s++;
+          bs_count++;
+        }
+      else if (*s=='\"')
+        {
+          if ( !(bs_count & 1) )
+            {
+              /* Preceded by an even number of backslashes, this is
+                 half that number of backslashes, plus a '\"' which we
+                 discard.  */
+              d -= bs_count/2;
+              s++;
+              in_quotes = !in_quotes;
+            }
+          else
+            {
+              /* Preceded by an odd number of backslashes, this is
+                 half that number of backslashes followed by a '\"'.  */
+              d = d - bs_count/2 - 1;
+              *d++ ='\"';
+              s++;
+            }
+          bs_count=0;
+        }
+      else /* A regular character. */
+        {
+          *d++ = *s++;
+          bs_count = 0;
+        }
+    }
+
+  if (*arg)
+    {
+      *d = 0;
+      argv[argc++] = arg;
+    }
+  argv[argc] = NULL;
+
+  return argv;
+}
+
+
+
 /* Our window message processing function.  */
-static LRESULT CALLBACK 
+static LRESULT CALLBACK
 wndw_proc (HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
-{              
+{
 
   switch (msg)
     {
@@ -104,14 +233,14 @@ handle_taskbar (void *ctx)
   nid.hWnd = glob_hwnd;
   nid.uID = 1;
   nid.hIcon = LoadIcon (glob_hinst, MAKEINTRESOURCE (1));
-  mem2str (nid.szTip, "GnuPG Agent version "PACKAGE_VERSION,
+  mem2str (nid.szTip, GPG_AGENT_NAME " version "PACKAGE_VERSION,
            sizeof nid.szTip);
   Shell_NotifyIcon (NIM_ADD, &nid);
   DestroyIcon (nid.hIcon);
 
   fprintf (stderr, "%s: enter\n", __func__);
-  while ( (rc=GetMessage (&msg, hwnd,  0, 0)) ) 
-    { 
+  while ( (rc=GetMessage (&msg, hwnd,  0, 0)) )
+    {
       if (rc == -1)
         {
           log_error ("getMessage failed: %s\n", w32_strerror (-1));
@@ -129,7 +258,7 @@ handle_taskbar (void *ctx)
 
 /* This function initializes the Window system and sets up the taskbar
    icon.  We only have very limited GUI support just to give the
-   taskbar icon a little bit of life.  This fucntion is called once to
+   taskbar icon a little bit of life.  This function is called once to
    fire up the icon.  */
 int
 w32_setup_taskbar (void)
@@ -155,24 +284,23 @@ w32_setup_taskbar (void)
 
 
 /* The main entry point for the Windows version.  We save away all GUI
-   related stuff, parse the commandline and finally call the real
+   related stuff, parse the command line and finally call the real
    main.  */
 int WINAPI
 WinMain (HINSTANCE hinst, HINSTANCE hprev, LPSTR cmdline, int showcmd)
 {
-  /* Fixme: We need a parser for the command line.  Should be
-     available in some CRT code - need to see whether we can find a
-     GNU version.  For nopw we call gpg-agent with a couple of fixed arguments 
-   */
-  char *argv[] = { "gpg-agent.exe", "--daemon", "-v", "--debug-all", NULL };
+  char **argv;
+  int argc;
 
+  /* We use the GetCommandLine function because that also includes the
+     program name in contrast to the CMDLINE arg. */
+  argv = build_argv (GetCommandLineA (), 0);
+  if (!argv)
+    return 2; /* Can't do much about a malloc failure.  */
+  for (argc=0; argv[argc]; argc++)
+    ;
 
   glob_hinst = hinst;
 
-  return w32_main (DIM(argv)-1, argv);
+  return w32_main (argc, argv);
 }
-
-
-
-
-