aboutsummaryrefslogtreecommitdiffstats
path: root/common/homedir.c
diff options
context:
space:
mode:
Diffstat (limited to 'common/homedir.c')
-rw-r--r--common/homedir.c81
1 files changed, 64 insertions, 17 deletions
diff --git a/common/homedir.c b/common/homedir.c
index 59b713526..6b40bb6bf 100644
--- a/common/homedir.c
+++ b/common/homedir.c
@@ -884,15 +884,60 @@ get_default_pinentry_name (int reset)
}
+/* If set, 'gnupg_module_name' returns modules from that build
+ * directory. */
+static char *gnupg_build_directory;
+
+/* For sanity checks. */
+static int gnupg_module_name_called;
+
+
+/* Set NEWDIR as the new build directory. This will make
+ * 'gnupg_module_name' return modules from that build directory. Must
+ * be called before any invocation of 'gnupg_module_name', and must
+ * not be called twice. It can be used by test suites to make sure
+ * the components from the build directory are used instead of
+ * potentially outdated installed ones. */
+void
+gnupg_set_builddir (const char *newdir)
+{
+ log_assert (! gnupg_module_name_called);
+ log_assert (! gnupg_build_directory);
+ gnupg_build_directory = xtrystrdup (newdir);
+}
+
+
+/* If no build directory has been configured, try to set it from the
+ * environment. We only do this in development builds to avoid
+ * increasing the set of influential environment variables and hence
+ * the attack surface of production builds. */
+static void
+gnupg_set_builddir_from_env (void)
+{
+#ifdef IS_DEVELOPMENT_VERSION
+ if (gnupg_build_directory)
+ return;
+
+ gnupg_build_directory = getenv ("GNUPG_BUILDDIR");
+#endif
+}
+
+
/* Return the file name of a helper tool. WHICH is one of the
GNUPG_MODULE_NAME_foo constants. */
const char *
gnupg_module_name (int which)
{
-#define X(a,b) do { \
+ gnupg_set_builddir_from_env ();
+ gnupg_module_name_called = 1;
+
+#define X(a,b,c) do { \
static char *name; \
if (!name) \
- name = xstrconcat (gnupg_ ## a (), DIRSEP_S b EXEEXT_S, NULL); \
+ name = gnupg_build_directory \
+ ? xstrconcat (gnupg_build_directory, \
+ DIRSEP_S b DIRSEP_S c EXEEXT_S, NULL) \
+ : xstrconcat (gnupg_ ## a (), DIRSEP_S c EXEEXT_S, NULL); \
return name; \
} while (0)
@@ -902,7 +947,7 @@ gnupg_module_name (int which)
#ifdef GNUPG_DEFAULT_AGENT
return GNUPG_DEFAULT_AGENT;
#else
- X(bindir, "gpg-agent");
+ X(bindir, "agent", "gpg-agent");
#endif
case GNUPG_MODULE_NAME_PINENTRY:
@@ -916,55 +961,57 @@ gnupg_module_name (int which)
#ifdef GNUPG_DEFAULT_SCDAEMON
return GNUPG_DEFAULT_SCDAEMON;
#else
- X(libexecdir, "scdaemon");
+ X(libexecdir, "scd", "scdaemon");
#endif
case GNUPG_MODULE_NAME_DIRMNGR:
#ifdef GNUPG_DEFAULT_DIRMNGR
return GNUPG_DEFAULT_DIRMNGR;
#else
- X(bindir, DIRMNGR_NAME);
+ X(bindir, "dirmngr", DIRMNGR_NAME);
#endif
case GNUPG_MODULE_NAME_PROTECT_TOOL:
#ifdef GNUPG_DEFAULT_PROTECT_TOOL
return GNUPG_DEFAULT_PROTECT_TOOL;
#else
- X(libexecdir, "gpg-protect-tool");
+ X(libexecdir, "agent", "gpg-protect-tool");
#endif
case GNUPG_MODULE_NAME_DIRMNGR_LDAP:
#ifdef GNUPG_DEFAULT_DIRMNGR_LDAP
return GNUPG_DEFAULT_DIRMNGR_LDAP;
#else
- X(libexecdir, "dirmngr_ldap");
+ X(libexecdir, "dirmngr", "dirmngr_ldap");
#endif
case GNUPG_MODULE_NAME_CHECK_PATTERN:
- X(libexecdir, "gpg-check-pattern");
+ X(libexecdir, "tools", "gpg-check-pattern");
case GNUPG_MODULE_NAME_GPGSM:
- X(bindir, "gpgsm");
+ X(bindir, "sm", "gpgsm");
case GNUPG_MODULE_NAME_GPG:
#if USE_GPG2_HACK
- X(bindir, GPG_NAME "2");
-#else
- X(bindir, GPG_NAME);
+ if (! gnupg_build_directory)
+ X(bindir, "g10", GPG_NAME "2");
+ else
#endif
+ X(bindir, "g10", GPG_NAME);
case GNUPG_MODULE_NAME_GPGV:
#if USE_GPG2_HACK
- X(bindir, GPG_NAME "v2");
-#else
- X(bindir, GPG_NAME "v");
+ if (! gnupg_build_directory)
+ X(bindir, "g10", GPG_NAME "v2");
+ else
#endif
+ X(bindir, "g10", GPG_NAME "v");
case GNUPG_MODULE_NAME_CONNECT_AGENT:
- X(bindir, "gpg-connect-agent");
+ X(bindir, "tools", "gpg-connect-agent");
case GNUPG_MODULE_NAME_GPGCONF:
- X(bindir, "gpgconf");
+ X(bindir, "tools", "gpgconf");
default:
BUG ();