summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--AUTHORS3
-rw-r--r--agent/ChangeLog6
-rw-r--r--agent/gpg-agent.c31
-rw-r--r--agent/w32main.c154
-rw-r--r--doc/gpg-agent.texi10
-rw-r--r--g10/gpg.c2
-rw-r--r--jnlib/ChangeLog14
-rw-r--r--jnlib/Makefile.am19
-rw-r--r--jnlib/stringhelp.c26
-rw-r--r--jnlib/stringhelp.h5
-rw-r--r--jnlib/t-stringhelp.c94
-rw-r--r--jnlib/t-support.c111
-rw-r--r--jnlib/t-support.h52
-rw-r--r--jnlib/w32-afunix.c54
-rw-r--r--scd/scdaemon.c2
-rw-r--r--sm/gpgsm.c2
-rw-r--r--tools/ChangeLog5
-rw-r--r--tools/gpgconf-comp.c15
18 files changed, 550 insertions, 55 deletions
diff --git a/AUTHORS b/AUTHORS
index 799a2aee6..548bc8a61 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -128,6 +128,9 @@ GnuPG.
The RPM specs file scripts/gnupg.spec has been contributed by
several people.
+The function build_argv in agent/w32main.c is based on code from
+Alexandre Julliard.
+
Copyright
=========
diff --git a/agent/ChangeLog b/agent/ChangeLog
index e23cd99a9..19564556e 100644
--- a/agent/ChangeLog
+++ b/agent/ChangeLog
@@ -5,10 +5,14 @@
2007-06-18 Werner Koch <wk@g10code.com>
+ * w32main.c (build_argv): New.
+ (WinMain): Use it.
+
* command.c (cmd_killagent) [W32]: New.
(cmd_getinfo): New.
* gpg-agent.c (get_agent_ssh_socket_name): New.
-
+ (no_force_standard_socket) New.
+ (create_server_socket): Use it.
* Makefile.am (gpg_agent_res_ldflags): Pass windows option to ld.
2007-06-14 Werner Koch <wk@g10code.com>
diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c
index 419f3769a..8907e9234 100644
--- a/agent/gpg-agent.c
+++ b/agent/gpg-agent.c
@@ -93,6 +93,7 @@ enum cmd_and_opt_values
oMinPassphraseLen,
oUseStandardSocket,
oNoUseStandardSocket,
+ oNoReuseStandardSocket,
oIgnoreCacheForSigning,
oAllowMarkTrusted,
@@ -130,6 +131,7 @@ static ARGPARSE_OPTS opts[] = {
{ oUseStandardSocket, "use-standard-socket", 0,
N_("use a standard location for the socket")},
{ oNoUseStandardSocket, "no-use-standard-socket", 0, "@"},
+ { oNoReuseStandardSocket, "no-reuse-standard-socket", 0, "@"},
{ oPinentryProgram, "pinentry-program", 2 ,
N_("|PGM|use PGM as the PIN-Entry program") },
@@ -186,6 +188,10 @@ static char *socket_name;
/* Name of the communication socket used for ssh-agent-emulation. */
static char *socket_name_ssh;
+/* If set to true and a standard socket is requested, we won't try to
+ bind to a socket which is already in use. */
+static int no_reuse_standard_socket;
+
/* Default values for options passed to the pinentry. */
static char *default_display;
static char *default_ttyname;
@@ -215,7 +221,7 @@ static pid_t parent_pid = (pid_t)(-1);
static char *create_socket_name (int use_standard_socket,
char *standard_name, char *template);
-static int create_server_socket (int is_standard_name, const char *name);
+static int create_server_socket (int is_standard_name, char *name);
static void create_directories (void);
static void agent_init_default_ctrl (ctrl_t ctrl);
@@ -621,6 +627,7 @@ main (int argc, char **argv )
case oUseStandardSocket: standard_socket = 1; break;
case oNoUseStandardSocket: standard_socket = 0; break;
+ case oNoReuseStandardSocket: no_reuse_standard_socket = 1; break;
case oKeepTTY: opt.keep_tty = 1; break;
case oKeepDISPLAY: opt.keep_display = 1; break;
@@ -715,7 +722,7 @@ main (int argc, char **argv )
#define GC_OPT_FLAG_NO_ARG_DESC (1UL << 6)
filename = make_filename (opt.homedir, "gpg-agent.conf", NULL );
- filename_esc = percent_escape (filename);
+ filename_esc = percent_escape (filename, NULL);
printf ("gpgconf-gpg-agent.conf:%lu:\"%s\n",
GC_OPT_FLAG_DEFAULT, filename_esc);
@@ -1226,10 +1233,10 @@ create_socket_name (int use_standard_socket,
/* Create a Unix domain socket with NAME. IS_STANDARD_NAME indicates
- whether a non-random socket is used. Returns the filedescriptor or
+ whether a non-random socket is used. Returns the file descriptor or
terminates the process in case of an error. */
static int
-create_server_socket (int is_standard_name, const char *name)
+create_server_socket (int is_standard_name, char *name)
{
struct sockaddr_un *serv_addr;
socklen_t len;
@@ -1257,14 +1264,16 @@ create_server_socket (int is_standard_name, const char *name)
#ifdef HAVE_W32_SYSTEM
rc = _w32_sock_bind (fd, (struct sockaddr*) serv_addr, len);
- if (is_standard_name && rc == -1 )
+ if (is_standard_name && rc == -1 && errno == WSAEADDRINUSE
+ && !no_reuse_standard_socket)
{
remove (name);
- rc = bind (fd, (struct sockaddr*) serv_addr, len);
+ rc = _w32_sock_bind (fd, (struct sockaddr*) serv_addr, len);
}
#else
rc = bind (fd, (struct sockaddr*) serv_addr, len);
- if (is_standard_name && rc == -1 && errno == EADDRINUSE)
+ if (is_standard_name && rc == -1 && errno == EADDRINUSE
+ && !no_reuse_standard_socket)
{
remove (name);
rc = bind (fd, (struct sockaddr*) serv_addr, len);
@@ -1272,9 +1281,15 @@ create_server_socket (int is_standard_name, const char *name)
#endif
if (rc == -1)
{
+ /* We use gpg_strerror here because it allows us to get strings
+ for some W32 socket error codes. */
log_error (_("error binding socket to `%s': %s\n"),
- serv_addr->sun_path, strerror (errno));
+ serv_addr->sun_path,
+ gpg_strerror (gpg_error_from_errno (errno)));
+
close (fd);
+ if (is_standard_name && no_reuse_standard_socket)
+ *name = 0; /* Inhibit removal of the socket by cleanup(). */
agent_exit (2);
}
diff --git a/agent/w32main.c b/agent/w32main.c
index 5fccb7ea2..176050220 100644
--- a/agent/w32main.c
+++ b/agent/w32main.c
@@ -1,5 +1,6 @@
/* 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.
*
@@ -37,6 +38,136 @@ 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 = malloc (argc * sizeof *argv);
+ if (!argv)
+ {
+ free (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
wndw_proc (HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
@@ -155,24 +286,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);
}
-
-
-
-
-
diff --git a/doc/gpg-agent.texi b/doc/gpg-agent.texi
index 3f0412538..a079b3095 100644
--- a/doc/gpg-agent.texi
+++ b/doc/gpg-agent.texi
@@ -369,18 +369,20 @@ this option at runtime does not kill an already forked scdaemon.
@item --use-standard-socket
@itemx --no-use-standard-socket
+@itemx --no-reuse-standard-socket
@opindex use-standard-socket
@opindex no-use-standard-socket
+@opindex no-reuse-standard-socket
By enabling this option @command{gpg-agent} will listen on the socket
named @file{S.gpg-agent}, located in the home directory, and not create
a random socket below a temporary directory. Tools connecting to
@command{gpg-agent} should first try to connect to the socket given in
environment variable @var{GPG_AGENT_INFO} and the fall back to this
socket. This option may not be used if the home directory is mounted as
-a remote file system.
-
-@noindent
-Note, that as of now, W32 systems default to this option.
+a remote file system. If @option{--no-reuse-standard-socket} is used,
+@command{gpg-agent} will not try to reuse a socket which is already in
+use. Note, that @option{--use-standard-socket} is the default on
+Windows systems.
@item --display @var{string}
diff --git a/g10/gpg.c b/g10/gpg.c
index 1e202f681..44ea8048e 100644
--- a/g10/gpg.c
+++ b/g10/gpg.c
@@ -1456,7 +1456,7 @@ list_config(char *items)
static void
gpgconf_list (const char *configfile)
{
- char *configfile_esc = percent_escape (configfile);
+ char *configfile_esc = percent_escape (configfile, NULL);
/* The following definitions are taken from gnupg/tools/gpgconf-comp.c. */
#define GC_OPT_FLAG_NONE 0UL
diff --git a/jnlib/ChangeLog b/jnlib/ChangeLog
index f98b1a282..4826ce4cd 100644
--- a/jnlib/ChangeLog
+++ b/jnlib/ChangeLog
@@ -1,3 +1,17 @@
+2007-06-19 Werner Koch <wk@g10code.com>
+
+ * Makefile.am: Add support for regression tests.
+ * t-support.h, t-support.c: New.
+ * t-stringhelp.c: New.
+
+ * stringhelp.c (percent_escape): Add arg EXTRA to make it a more
+ general function. Changed all callers.
+
+2007-06-18 Werner Koch <wk@g10code.com>
+
+ * w32-afunix.c (_w32_sock_bind): Changed to properly detect an
+ already used socket.
+
2007-06-18 Marcus Brinkmann <marcus@g10code.de>
* stringhelp.h (percent_escape): New prototype.
diff --git a/jnlib/Makefile.am b/jnlib/Makefile.am
index 0f593bb3f..eb447b592 100644
--- a/jnlib/Makefile.am
+++ b/jnlib/Makefile.am
@@ -23,6 +23,8 @@
## Process this file with automake to produce Makefile.in
EXTRA_DIST = README
+noinst_PROGRAMS = $(module_tests)
+TESTS = $(module_tests)
AM_CPPFLAGS = -I$(top_srcdir)/intl
@@ -51,3 +53,20 @@ endif
# For GnuPG we don't need the xmalloc stuff.
# xmalloc.c xmalloc.h
+
+#
+# Module tests.
+#
+# These tests should only be used at the canonical location of jnlib
+# which is the GnuPG package. The reason for this is that t-support.c
+# defines replacements for the actual used memory allocation functions
+# so that there is no dependency on libgcrypt.
+#
+module_tests = t-stringhelp
+
+t_jnlib_src = t-support.c t-support.h
+t_jnlib_ldadd = libjnlib.a $(LIBINTL) $(LIBICONV)
+
+t_stringhelp_SOURCES = t-stringhelp.c $(t_jnlib_src)
+t_stringhelp_LDADD = $(t_jnlib_ldadd)
+
diff --git a/jnlib/stringhelp.c b/jnlib/stringhelp.c
index 49d91c075..2050cddb3 100644
--- a/jnlib/stringhelp.c
+++ b/jnlib/stringhelp.c
@@ -34,6 +34,8 @@
#include "stringhelp.h"
+#define tohex_lower(n) ((n) < 10 ? ((n) + '0') : (((n) - 10) + 'a'))
+
/*
* Look for the substring SUB in buffer and return a pointer to that
* substring in BUFFER or NULL if not found.
@@ -827,19 +829,19 @@ memrchr (const void *buffer, int c, size_t n)
#endif /*HAVE_MEMRCHR*/
-/* Percent-escape the string STR by replacing colons with '%3a'. */
+/* Percent-escape the string STR by replacing colons with '%3a'. If
+ EXTRA is not NULL all characters in it are also escaped. */
char *
-percent_escape (const char *str)
+percent_escape (const char *str, const char *extra)
{
- int i = 0;
- int j = 0;
+ int i, j;
char *ptr;
if (!str)
return NULL;
- while (str[i])
- if (str[i++] == ':')
+ for (i=j=0; str[i]; i++)
+ if (str[i] == ':' || str[i] == '%' || (extra && strchr (extra, str[i])))
j++;
ptr = jnlib_xmalloc (i + 2 * j + 1);
i = 0;
@@ -851,6 +853,18 @@ percent_escape (const char *str)
ptr[i++] = '3';
ptr[i++] = 'a';
}
+ else if (*str == '%')
+ {
+ ptr[i++] = '%';
+ ptr[i++] = '2';
+ ptr[i++] = '5';
+ }
+ else if (extra && strchr (extra, *str))
+ {
+ ptr[i++] = '%';
+ ptr[i++] = tohex_lower ((*str>>4)&15);
+ ptr[i++] = tohex_lower (*str&15);
+ }
else
ptr[i++] = *str;
str++;
diff --git a/jnlib/stringhelp.h b/jnlib/stringhelp.h
index fdd887bf2..5f08745cb 100644
--- a/jnlib/stringhelp.h
+++ b/jnlib/stringhelp.h
@@ -117,8 +117,9 @@ isascii (int c)
#endif
#define STR2(v) STR(v)
-/* Percent-escape the string STR by replacing colons with '%3a'. */
-char *percent_escape (const char *str);
+/* Percent-escape the string STR by replacing colons with '%3a'. If
+ EXTRA is not NULL, also replace all characters given in EXTRA. */
+char *percent_escape (const char *str, const char *extra);
#endif /*LIBJNLIB_STRINGHELP_H*/
diff --git a/jnlib/t-stringhelp.c b/jnlib/t-stringhelp.c
new file mode 100644
index 000000000..27bea8940
--- /dev/null
+++ b/jnlib/t-stringhelp.c
@@ -0,0 +1,94 @@
+/* t-stringhelp.c - Regression tests for stringhelp.c
+ * Copyright (C) 2007 Free Software Foundation, Inc.
+ *
+ * This file is part of JNLIB.
+ *
+ * JNLIB is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * JNLIB 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser 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.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "stringhelp.h"
+
+#include "t-support.h"
+
+
+
+static void
+test_percent_escape (void)
+{
+ char *result;
+ static struct {
+ const char *extra;
+ const char *value;
+ const char *expected;
+ } tests[] =
+ {
+ { NULL, "", "" },
+ { NULL, "%", "%25" },
+ { NULL, "%%", "%25%25" },
+ { NULL, " %", " %25" },
+ { NULL, ":", "%3a" },
+ { NULL, " :", " %3a" },
+ { NULL, ": ", "%3a " },
+ { NULL, " : ", " %3a " },
+ { NULL, "::", "%3a%3a" },
+ { NULL, ": :", "%3a %3a" },
+ { NULL, "%:", "%25%3a" },
+ { NULL, ":%", "%3a%25" },
+ { "\\\n:", ":%", "%3a%25" },
+ { "\\\n:", "\\:%", "%5c%3a%25" },
+ { "\\\n:", "\n:%", "%0a%3a%25" },
+ { "\\\n:", "\xff:%", "\xff%3a%25" },
+ { "\\\n:", "\xfe:%", "\xfe%3a%25" },
+ { "\\\n:", "\x01:%", "\x01%3a%25" },
+ { "\x01", "\x01:%", "%01%3a%25" },
+ { "\xfe", "\xfe:%", "%fe%3a%25" },
+ { "\xfe", "\xff:%", "\xff%3a%25" },
+
+ { NULL, NULL, NULL }
+ };
+ int testno;
+
+ result = percent_escape (NULL, NULL);
+ if (result)
+ fail (0);
+ for (testno=0; tests[testno].value; testno++)
+ {
+ result = percent_escape (tests[testno].value, tests[testno].extra);
+ if (!result)
+ fail (testno);
+ if (strcmp (result, tests[testno].expected))
+ fail (testno);
+ xfree (result);
+ }
+
+}
+
+
+
+
+int
+main (int argc, char **argv)
+{
+ test_percent_escape ();
+
+ return 0;
+}
+
diff --git a/jnlib/t-support.c b/jnlib/t-support.c
new file mode 100644
index 000000000..d9d50e9a4
--- /dev/null
+++ b/jnlib/t-support.c
@@ -0,0 +1,111 @@
+/* t-support.c - helper functions for the regression tests.
+ * Copyright (C) 2007 Free Software Foundation, Inc.
+ *
+ * This file is part of JNLIB.
+ *
+ * JNLIB is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * JNLIB 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser 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.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "t-support.h"
+
+/* Replacements for the malloc functions as used here. */
+
+static void
+out_of_memory (void)
+{
+ fprintf (stderr,"error: out of core in regression tests: %s\n",
+ strerror (errno));
+ exit (2);
+}
+
+
+void *
+gcry_malloc (size_t n)
+{
+ return malloc (n);
+}
+
+void *
+gcry_xmalloc (size_t n)
+{
+ void *p = malloc (n);
+ if (!p)
+ out_of_memory ();
+ return p;
+}
+
+char *
+gcry_strdup (const char *string)
+{
+ return malloc (strlen (string)+1);
+}
+
+
+void *
+gcry_realloc (void *a, size_t n)
+{
+ return realloc (a, n);
+}
+
+void *
+gcry_xrealloc (void *a, size_t n)
+{
+ void *p = realloc (a, n);
+ if (!p)
+ out_of_memory ();
+ return p;
+}
+
+
+
+void *
+gcry_calloc (size_t n, size_t m)
+{
+ return calloc (n, m);
+}
+
+void *
+gcry_xcalloc (size_t n, size_t m)
+{
+ void *p = calloc (n, m);
+ if (!p)
+ out_of_memory ();
+ return p;
+}
+
+
+char *
+gcry_xstrdup (const char *string)
+{
+ void *p = malloc (strlen (string)+1);
+ if (!p)
+ out_of_memory ();
+ strcpy (p, string);
+ return p;
+}
+
+void
+gcry_free (void *a)
+{
+ if (a)
+ free (a);
+}
diff --git a/jnlib/t-support.h b/jnlib/t-support.h
new file mode 100644
index 000000000..661dfb46e
--- /dev/null
+++ b/jnlib/t-support.h
@@ -0,0 +1,52 @@
+/* t-support.h - Helper for the regression tests
+ * Copyright (C) 2007 Free Software Foundation, Inc.
+ *
+ * This file is part of JNLIB.
+ *
+ * JNLIB is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * JNLIB 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser 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.
+ */
+
+#ifndef LIBJNLIB_T_SUPPORT_H
+#define LIBJNLIB_T_SUPPORT_H 1
+
+#ifdef GCRYPT_VERSION
+#error The regression tests should not include with gcrypt.h
+#endif
+
+/* Repalcement prototypes. */
+void *gcry_xmalloc (size_t n);
+void *gcry_xcalloc (size_t n, size_t m);
+void *gcry_xrealloc (void *a, size_t n);
+char *gcry_xstrdup (const char * a);
+void gcry_free (void *a);
+
+/* Map the used xmalloc functions to those implemented by t-support.c */
+#define xmalloc(a) gcry_xmalloc ( (a) )
+#define xcalloc(a,b) gcry_xcalloc ( (a), (b) )
+#define xrealloc(a,n) gcry_xrealloc ( (a), (n) )
+#define xstrdup(a) gcry_xstrdup ( (a) )
+#define xfree(a) gcry_free ( (a) )
+
+
+/* Macros to print the result of a test. */
+#define pass() do { ; } while(0)
+#define fail(a) do { fprintf (stderr, "%s:%d: test %d failed\n",\
+ __FILE__,__LINE__, (a)); \
+ exit (1); \
+ } while(0)
+
+
+#endif /*LIBJNLIB_T_SUPPORT_H*/
diff --git a/jnlib/w32-afunix.c b/jnlib/w32-afunix.c
index dcce423c7..16132a230 100644
--- a/jnlib/w32-afunix.c
+++ b/jnlib/w32-afunix.c
@@ -22,11 +22,19 @@
#ifdef _WIN32
#include <stdio.h>
#include <windows.h>
+#include <fcntl.h>
+#include <sys/stat.h>
#include <io.h>
#include <errno.h>
#include "w32-afunix.h"
+#ifndef S_IRGRP
+# define S_IRGRP 0
+# define S_IWGRP 0
+#endif
+
+
int
_w32_close (int fd)
{
@@ -81,34 +89,56 @@ _w32_sock_connect (int sockfd, struct sockaddr * addr, int addrlen)
int
-_w32_sock_bind (int sockfd, struct sockaddr * addr, int addrlen)
+_w32_sock_bind (int sockfd, struct sockaddr *addr, int addrlen)
{
if (addr->sa_family == AF_LOCAL || addr->sa_family == AF_UNIX)
{
struct sockaddr_in myaddr;
- struct sockaddr_un * unaddr;
- FILE * fp;
+ struct sockaddr_un *unaddr;
+ int filefd;
+ FILE *fp;
int len = sizeof myaddr;
int rc;
+ unaddr = (struct sockaddr_un *)addr;
+
myaddr.sin_port = 0;
myaddr.sin_family = AF_INET;
myaddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
+ filefd = open (unaddr->sun_path,
+ (O_WRONLY|O_CREAT|O_EXCL|O_BINARY),
+ (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP));
+ if (filefd == -1)
+ {
+ if (errno == EEXIST)
+ errno = WSAEADDRINUSE;
+ return -1;
+ }
+ fp = fdopen (filefd, "wb");
+ if (!fp)
+ {
+ int save_e = errno;
+ close (filefd);
+ errno = save_e;
+ return -1;
+ }
+
rc = bind (sockfd, (struct sockaddr *)&myaddr, len);
+ if (!rc)
+ rc = getsockname (sockfd, (struct sockaddr *)&myaddr, &len);
if (rc)
- return rc;
- rc = getsockname (sockfd, (struct sockaddr *)&myaddr, &len);
- if (rc)
- return rc;
- unaddr = (struct sockaddr_un *)addr;
- fp = fopen (unaddr->sun_path, "wb");
- if (!fp)
- return -1;
+ {
+ int save_e = errno;
+ fclose (fp);
+ remove (unaddr->sun_path);
+ errno = save_e;
+ return rc;
+ }
fprintf (fp, "%d", myaddr.sin_port);
fclose (fp);
- /* we need this later. */
+ /* The caller expects these values. */
unaddr->sun_family = myaddr.sin_family;
unaddr->sun_port = myaddr.sin_port;
unaddr->sun_addr.s_addr = myaddr.sin_addr.s_addr;
diff --git a/scd/scdaemon.c b/scd/scdaemon.c
index 4e45907db..f9a99922f 100644
--- a/scd/scdaemon.c
+++ b/scd/scdaemon.c
@@ -551,7 +551,7 @@ main (int argc, char **argv )
#define GC_OPT_FLAG_NO_ARG_DESC (1UL << 6)
if (!config_filename)
filename = make_filename (opt.homedir, "scdaemon.conf", NULL );
- filename_esc = percent_escape (filename);
+ filename_esc = percent_escape (filename, NULL);
printf ("gpgconf-scdaemon.conf:%lu:\"%s\n",
GC_OPT_FLAG_DEFAULT, filename_esc);
diff --git a/sm/gpgsm.c b/sm/gpgsm.c
index 11b759b65..f6d2b8444 100644
--- a/sm/gpgsm.c
+++ b/sm/gpgsm.c
@@ -1393,7 +1393,7 @@ main ( int argc, char **argv)
a default, which is described by the value of the ARGDEF field. */
#define GC_OPT_FLAG_NO_ARG_DESC (1UL << 6)
- char *config_filename_esc = percent_escape (opt.config_filename);
+ char *config_filename_esc = percent_escape (opt.config_filename, NULL);
printf ("gpgconf-gpgsm.conf:%lu:\"%s\n",
GC_OPT_FLAG_DEFAULT, config_filename_esc);
diff --git a/tools/ChangeLog b/tools/ChangeLog
index c30ef7954..f36c33a40 100644
--- a/tools/ChangeLog
+++ b/tools/ChangeLog
@@ -1,3 +1,8 @@
+2007-06-19 Werner Koch <wk@g10code.com>
+
+ * gpgconf-comp.c (percent_escape): Rename to my_percent_escape.
+ Changed all callers.
+
2007-06-18 Marcus Brinkmann <marcus@g10code.de>
* gpgconf-comp.c (retrieve_options_from_file): Close LIST_FILE.
diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c
index 368d4988d..caf09d342 100644
--- a/tools/gpgconf-comp.c
+++ b/tools/gpgconf-comp.c
@@ -984,7 +984,7 @@ my_dgettext (const char *domain, const char *msgid)
/* Percent-Escape special characters. The string is valid until the
next invocation of the function. */
static char *
-percent_escape (const char *src)
+my_percent_escape (const char *src)
{
static char *esc_str;
static int esc_str_len;
@@ -1083,7 +1083,8 @@ gc_component_list_components (FILE *out)
{
const char *desc = gc_component[idx].desc;
desc = my_dgettext (gc_component[idx].desc_domain, desc);
- fprintf (out, "%s:%s\n", gc_component[idx].name, percent_escape (desc));
+ fprintf (out, "%s:%s\n",
+ gc_component[idx].name, my_percent_escape (desc));
}
}
@@ -1174,7 +1175,7 @@ list_one_option (const gc_option_t *option, FILE *out)
fprintf (out, " %s", gc_level[option->level].name);
/* The description field. */
- fprintf (out, ":%s", desc ? percent_escape (desc) : "");
+ fprintf (out, ":%s", desc ? my_percent_escape (desc) : "");
/* The type field. */
fprintf (out, ":%u", option->arg_type);
@@ -1188,7 +1189,7 @@ list_one_option (const gc_option_t *option, FILE *out)
gc_arg_type[gc_arg_type[option->arg_type].fallback].name);
/* The argument name field. */
- fprintf (out, ":%s", arg_name ? percent_escape (arg_name) : "");
+ fprintf (out, ":%s", arg_name ? my_percent_escape (arg_name) : "");
if (arg_name)
xfree (arg_name);
@@ -1458,7 +1459,7 @@ retrieve_options_from_program (gc_component_t component, gc_backend_t backend)
}
else if (gc_arg_type[option->arg_type].fallback
== GC_ARG_TYPE_STRING)
- opt_value = xasprintf ("\"%s", percent_escape (value));
+ opt_value = xasprintf ("\"%s", my_percent_escape (value));
else
{
/* FIXME: Verify that the number is sane. */
@@ -1549,12 +1550,12 @@ retrieve_options_from_file (gc_component_t component, gc_backend_t backend)
really append. */
if (list)
{
- new_list = xasprintf ("%s,\"%s", list, percent_escape (start));
+ new_list = xasprintf ("%s,\"%s", list, my_percent_escape (start));
xfree (list);
list = new_list;
}
else
- list = xasprintf ("\"%s", percent_escape (start));
+ list = xasprintf ("\"%s", my_percent_escape (start));
}
if (length < 0 || ferror (list_file))
gc_error (1, errno, "can not read list file %s", list_pathname);