From bb600aa8fd2f9575ee7afc64c978e3e7523b1173 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 28 Oct 2015 16:24:30 +0100 Subject: [PATCH] w32: Add new global flag "w32-inst-dir". * src/gpgme.c (gpgme_set_global_flag): Add flag "w32-inst-dir"; * src/posix-util.c (_gpgme_set_override_inst_dir): New stub. * src/w32-util.c (override_inst_dir): New var. (_gpgme_get_inst_dir): Return this var is set. (_gpgme_set_override_inst_dir): New. -- See https://lists.gnupg.org/pipermail/gnupg-devel/2015-September/030267.html for background. Signed-off-by: Werner Koch --- doc/gpgme.texi | 10 ++++++++++ src/gpgme.c | 2 ++ src/posix-util.c | 9 +++++++++ src/sys-util.h | 1 + src/w32-util.c | 30 +++++++++++++++++++++++++++++- 5 files changed, 51 insertions(+), 1 deletion(-) diff --git a/doc/gpgme.texi b/doc/gpgme.texi index a764ce42..1c680b51 100644 --- a/doc/gpgme.texi +++ b/doc/gpgme.texi @@ -701,6 +701,16 @@ directory part is used as the default installation directory; the @code{.exe} suffix is added by GPGME. Use forward slashed even under Windows. +@item "w32-inst-dir" +On Windows GPGME needs to know its installation directory to find its +spawn helper. This is in general no problem because a DLL has this +information. Some applications however link statically to GPGME and +thus GPGME can only figure out the installation directory of this +application which may be wrong in certain cases. By supplying an +installation directory as value to this flag, GPGME will assume that +that directory is the installation directory. This flag has no effect +on non-Windows platforms. + @end table This function returns @code{0} on success. In contrast to other diff --git a/src/gpgme.c b/src/gpgme.c index 3c4e8e92..0b42ea19 100644 --- a/src/gpgme.c +++ b/src/gpgme.c @@ -75,6 +75,8 @@ gpgme_set_global_flag (const char *name, const char *value) return _gpgme_set_default_gpgconf_name (value); else if (!strcmp (name, "gpg-name")) return _gpgme_set_default_gpg_name (value); + else if (!strcmp (name, "w32-inst-dir")) + return _gpgme_set_override_inst_dir (value); else return -1; } diff --git a/src/posix-util.c b/src/posix-util.c index f7e0a171..0fce5c29 100644 --- a/src/posix-util.c +++ b/src/posix-util.c @@ -71,6 +71,15 @@ _gpgme_set_default_gpgconf_name (const char *name) } +/* Dummy function - see w32-util.c for the actual code. */ +int +_gpgme_set_override_inst_dir (const char *dir) +{ + (void)dir; + return 0; +} + + /* Find an executable program PGM along the envvar PATH. */ static char * walk_path (const char *pgm) diff --git a/src/sys-util.h b/src/sys-util.h index 589634b2..541c5575 100644 --- a/src/sys-util.h +++ b/src/sys-util.h @@ -23,6 +23,7 @@ /*-- {posix,w32}-util.c --*/ int _gpgme_set_default_gpg_name (const char *name); int _gpgme_set_default_gpgconf_name (const char *name); +int _gpgme_set_override_inst_dir (const char *dir); char *_gpgme_get_gpg_path (void); char *_gpgme_get_gpgconf_path (void); diff --git a/src/w32-util.c b/src/w32-util.c index 9aba26f5..f611b6c0 100644 --- a/src/w32-util.c +++ b/src/w32-util.c @@ -85,7 +85,10 @@ static HMODULE my_hmodule; binaries. The are set only once by gpgme_set_global_flag. */ static char *default_gpg_name; static char *default_gpgconf_name; - +/* If this variable is not NULL the value is assumed to be the + installation directory. The variable may only be set once by + gpgme_set_global_flag and accessed by _gpgme_get_inst_dir. */ +static char *override_inst_dir; #ifdef HAVE_ALLOW_SET_FOREGROUND_WINDOW @@ -347,6 +350,9 @@ _gpgme_get_inst_dir (void) { static char *inst_dir; + if (override_inst_dir) + return override_inst_dir; + LOCK (get_path_lock); if (!inst_dir) { @@ -456,6 +462,28 @@ _gpgme_set_default_gpgconf_name (const char *name) } +/* Set the override installation directory. This function may only be + called by gpgme_set_global_flag. Returns 0 on success. */ +int +_gpgme_set_override_inst_dir (const char *dir) +{ + if (!override_inst_dir) + { + override_inst_dir = malloc (strlen (dir) + 1); + if (override_inst_dir) + { + strcpy (override_inst_dir, dir); + replace_slashes (override_inst_dir); + /* Remove a trailing slash. */ + if (*override_inst_dir + && override_inst_dir[strlen (override_inst_dir)-1] == '\\') + override_inst_dir[strlen (override_inst_dir)-1] = 0; + } + } + return !override_inst_dir; +} + + /* Return the full file name of the GPG binary. This function is used iff gpgconf was not found and thus it can be assumed that gpg2 is not installed. This function is only called by get_gpgconf_item