core: New global flags "inst-type".

* src/gpgme.c (gpgme_set_global_flag): Add flag "inst-type".
* src/w32-util.c (_gpgme_set_get_inst_type): New.
(INST_TYPE_GPG4WIN_DIR): New.
(INST_TYPE_GPGDESK_DIR): New.
(_gpgme_get_gpgconf_path): Implement this flag.  Replace fixed strings
by the macros.
* src/posix-util.c (_gpgme_set_get_inst_type): New dummy.
--

This is intended for use by Kleopatra to reliable find the expected
GnuPG installation.
This commit is contained in:
Werner Koch 2022-10-26 12:10:57 +02:00
parent f1802682c3
commit 1c9694f8d5
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
5 changed files with 68 additions and 4 deletions

View File

@ -727,6 +727,13 @@ is not met, GPGME fails early instead of trying to use the existent
version. The given version must be a string with major, minor, and
micro number. Example: "2.1.0".
@item inst-type
The installation type is used to prefer a certain GnuPG installation.
The value is interpreted as an integer: A value of 0 is ignored, a
value of 1 indicates an installation scheme as used by Gpg4win, a
value of 2 indicates an installation scheme as used by GnuPG Desktop
on Windows. All other values are reserved.
@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

View File

@ -79,6 +79,11 @@ 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, "inst-type"))
{
_gpgme_set_get_inst_type (value);
return 0;
}
else if (!strcmp (name, "w32-inst-dir"))
return _gpgme_set_override_inst_dir (value);
else

View File

@ -79,6 +79,15 @@ _gpgme_set_override_inst_dir (const char *dir)
return 0;
}
/* Dummy function - see w32-util.c for the actual code. */
int
_gpgme_set_get_inst_type (const char *value)
{
(void)value;
return 0; /* Posix installation type is fixed. */
}
/* Find an executable program in the colon seperated paths. */
static char *
walk_path_str (const char *path_str, const char *pgm)

View File

@ -24,6 +24,7 @@
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);
int _gpgme_set_get_inst_type (const char *value);
char *_gpgme_get_gpg_path (void);
char *_gpgme_get_gpgconf_path (void);

View File

@ -83,6 +83,11 @@
# define GNUPG_REGKEY_3 "Software\\GnuPG"
#endif
/* Relative name parts for different installation types. */
#define INST_TYPE_GPG4WIN_DIR "\\..\\..\\GnuPG\\bin"
#define INST_TYPE_GPGDESK_DIR "\\..\\GnuPG\\bin"
DEFINE_STATIC_LOCK (get_path_lock);
/* The module handle of this DLL. If we are linked statically,
@ -536,6 +541,27 @@ _gpgme_set_override_inst_dir (const char *dir)
}
/* Used by gpgme_set_global_flag to set the installation type.
* VALUE is a string interpreted as integer with this meaning:
* 0 = standard
* 1 = Gpg4win 4 style
* 2 = GnuPG (VS-)Desktop style
* If VALUE is NULL, nothing is changed. The return value is the
* previous value.
*/
int
_gpgme_set_get_inst_type (const char *value)
{
static int inst_type;
int previous_type;
previous_type = inst_type;
if (value)
inst_type = atoi (value);
return previous_type;
}
/* 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
@ -593,12 +619,28 @@ _gpgme_get_gpgconf_path (void)
{
char *gpgconf = NULL;
const char *inst_dir, *name;
int inst_type;
char *dir;
name = default_gpgconf_name? get_basename(default_gpgconf_name):"gpgconf.exe";
/* 1. Try to find gpgconf.exe in the installation directory of gpgme. */
/* 0. If an installation type is requested try to find gpgconf.exe
* depending on that installation type. */
inst_dir = _gpgme_get_inst_dir ();
if (inst_dir)
if (inst_dir
&& (inst_type = _gpgme_set_get_inst_type (NULL))
&& (inst_type == 1 || inst_type == 2))
{
dir = _gpgme_strconcat (inst_dir,
inst_type == 1? INST_TYPE_GPG4WIN_DIR
/* */ : INST_TYPE_GPGDESK_DIR,
NULL);
gpgconf = find_program_in_dir (dir, name);
free (dir);
}
/* 1. Try to find gpgconf.exe in the installation directory of gpgme. */
if (!gpgconf && inst_dir)
{
gpgconf = find_program_in_dir (inst_dir, name);
}
@ -648,7 +690,7 @@ _gpgme_get_gpgconf_path (void)
/* 5. Try to find gpgconf.exe relative to us as Gpg4win installs it. */
if (!gpgconf && inst_dir)
{
char *dir = _gpgme_strconcat (inst_dir, "\\..\\..\\GnuPG\\bin", NULL);
dir = _gpgme_strconcat (inst_dir, INST_TYPE_GPG4WIN_DIR, NULL);
gpgconf = find_program_in_dir (dir, name);
free (dir);
}
@ -656,7 +698,7 @@ _gpgme_get_gpgconf_path (void)
/* 6. Try to find gpgconf.exe relative to us as GnuPG VSD installs it. */
if (!gpgconf && inst_dir)
{
char *dir = _gpgme_strconcat (inst_dir, "\\..\\GnuPG\\bin", NULL);
dir = _gpgme_strconcat (inst_dir, INST_TYPE_GPGDESK_DIR, NULL);
gpgconf = find_program_in_dir (dir, name);
free (dir);
}