mirror of
git://git.gnupg.org/gnupg.git
synced 2025-07-02 22:46:30 +02:00
w32: Add code to support a portable use of GnuPG.
* common/homedir.c (w32_bin_is_bin, w32_portable_app) [W32]: New. (check_portable_app) [W32]: New. (standard_homedir, default_homedir) [W32]: Support the portable flag. (w32_rootdir, w32_commondir) [W32]: Ditto. (gnupg_bindir) [W32]: Ditto. -- A portable use of GnuPG under Windows means that GnuPG uses a home directory depending on the location of the actual binary. No registry variables are considered. The portable mode is enabled if in the installation directory of the the binary "gpgconf.exe" and a file "gpgconf.ctl" are found. The latter file shall be empty or consist only of empty or '#'-style comment lines. Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
parent
aff557409c
commit
4f90c7b914
3 changed files with 152 additions and 34 deletions
156
common/homedir.c
156
common/homedir.c
|
@ -1,5 +1,6 @@
|
|||
/* homedir.c - Setup the home directory.
|
||||
* Copyright (C) 2004, 2006, 2007 Free Software Foundation, Inc.
|
||||
* Copyright (C) 2004, 2006, 2007 Free Software Foundation, Inc.
|
||||
* Copyright (C) 2013 Werner Koch
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
|
@ -47,6 +48,33 @@
|
|||
#include "sysutils.h"
|
||||
|
||||
|
||||
#ifdef HAVE_W32_SYSTEM
|
||||
/* A flag used to indicate that a control file for gpgconf has been
|
||||
detected. Under Windows the presence of this file indicates a
|
||||
portable installations and triggers several changes:
|
||||
|
||||
- The GNUGHOME directory is fixed relative to installation
|
||||
directory. All other means to set the home directory are
|
||||
ignored.
|
||||
|
||||
- All registry variables are ignored.
|
||||
|
||||
This flag is not used on Unix systems.
|
||||
*/
|
||||
static int w32_portable_app;
|
||||
|
||||
/* This flag is true if this process' binary has been installed under
|
||||
bin and not in the root directory. */
|
||||
static int w32_bin_is_bin;
|
||||
|
||||
/* Just a little prototype. */
|
||||
static const char *w32_rootdir (void);
|
||||
|
||||
#endif /*HAVE_W32_SYSTEM*/
|
||||
|
||||
|
||||
|
||||
|
||||
/* This is a helper function to load a Windows function from either of
|
||||
one DLLs. */
|
||||
#ifdef HAVE_W32_SYSTEM
|
||||
|
@ -99,28 +127,39 @@ standard_homedir (void)
|
|||
|
||||
if (!dir)
|
||||
{
|
||||
char path[MAX_PATH];
|
||||
const char *rdir;
|
||||
|
||||
/* It might be better to use LOCAL_APPDATA because this is
|
||||
defined as "non roaming" and thus more likely to be kept
|
||||
locally. For private keys this is desired. However, given
|
||||
that many users copy private keys anyway forth and back,
|
||||
using a system roaming services might be better than to let
|
||||
them do it manually. A security conscious user will anyway
|
||||
use the registry entry to have better control. */
|
||||
if (w32_shgetfolderpath (NULL, CSIDL_APPDATA|CSIDL_FLAG_CREATE,
|
||||
NULL, 0, path) >= 0)
|
||||
rdir = w32_rootdir ();
|
||||
if (w32_portable_app)
|
||||
{
|
||||
char *tmp = xmalloc (strlen (path) + 6 +1);
|
||||
strcpy (stpcpy (tmp, path), "\\gnupg");
|
||||
dir = tmp;
|
||||
|
||||
/* Try to create the directory if it does not yet exists. */
|
||||
if (access (dir, F_OK))
|
||||
CreateDirectory (dir, NULL);
|
||||
dir = xstrconcat (rdir, DIRSEP_S "home", NULL);
|
||||
}
|
||||
else
|
||||
dir = GNUPG_DEFAULT_HOMEDIR;
|
||||
{
|
||||
char path[MAX_PATH];
|
||||
|
||||
/* It might be better to use LOCAL_APPDATA because this is
|
||||
defined as "non roaming" and thus more likely to be kept
|
||||
locally. For private keys this is desired. However,
|
||||
given that many users copy private keys anyway forth and
|
||||
back, using a system roaming services might be better
|
||||
than to let them do it manually. A security conscious
|
||||
user will anyway use the registry entry to have better
|
||||
control. */
|
||||
if (w32_shgetfolderpath (NULL, CSIDL_APPDATA|CSIDL_FLAG_CREATE,
|
||||
NULL, 0, path) >= 0)
|
||||
{
|
||||
char *tmp = xmalloc (strlen (path) + 6 +1);
|
||||
strcpy (stpcpy (tmp, path), "\\gnupg");
|
||||
dir = tmp;
|
||||
|
||||
/* Try to create the directory if it does not yet exists. */
|
||||
if (access (dir, F_OK))
|
||||
CreateDirectory (dir, NULL);
|
||||
}
|
||||
else
|
||||
dir = GNUPG_DEFAULT_HOMEDIR;
|
||||
}
|
||||
}
|
||||
return dir;
|
||||
#else/*!HAVE_W32_SYSTEM*/
|
||||
|
@ -135,6 +174,13 @@ default_homedir (void)
|
|||
{
|
||||
const char *dir;
|
||||
|
||||
#ifdef HAVE_W32_SYSTEM
|
||||
/* For a portable application we only use the standard homedir. */
|
||||
w32_rootdir ();
|
||||
if (w32_portable_app)
|
||||
return standard_homedir ();
|
||||
#endif /*HAVE_W32_SYSTEM*/
|
||||
|
||||
dir = getenv ("GNUPGHOME");
|
||||
#ifdef HAVE_W32_SYSTEM
|
||||
if (!dir || !*dir)
|
||||
|
@ -172,6 +218,31 @@ default_homedir (void)
|
|||
|
||||
|
||||
#ifdef HAVE_W32_SYSTEM
|
||||
/* Check whether gpgconf is installed and if so read the gpgconf.ctl
|
||||
file. */
|
||||
static void
|
||||
check_portable_app (const char *dir)
|
||||
{
|
||||
char *fname;
|
||||
|
||||
fname = xstrconcat (dir, DIRSEP_S "gpgconf.exe", NULL);
|
||||
if (access (fname, F_OK))
|
||||
log_error ("required binary '%s' is not installed\n", fname);
|
||||
else
|
||||
{
|
||||
strcpy (fname + strlen (fname) - 3, "ctl");
|
||||
if (!access (fname, F_OK))
|
||||
{
|
||||
/* gpgconf.ctl file found. Record this fact. */
|
||||
w32_portable_app = 1;
|
||||
|
||||
/* FIXME: We should read the file to detect special flags
|
||||
and print a warning if we don't understand them. */
|
||||
}
|
||||
}
|
||||
xfree (fname);
|
||||
}
|
||||
|
||||
static const char *
|
||||
w32_rootdir (void)
|
||||
{
|
||||
|
@ -190,8 +261,22 @@ w32_rootdir (void)
|
|||
got_dir = 1;
|
||||
p = strrchr (dir, DIRSEP_C);
|
||||
if (p)
|
||||
*p = 0;
|
||||
else
|
||||
{
|
||||
*p = 0;
|
||||
|
||||
check_portable_app (dir);
|
||||
|
||||
/* If we are installed below "bin" we strip that and use
|
||||
the top directory instead. */
|
||||
p = strrchr (dir, DIRSEP_C);
|
||||
|
||||
if (p && !strcmp (p+1, "bin"))
|
||||
{
|
||||
*p = 0;
|
||||
w32_bin_is_bin = 1;
|
||||
}
|
||||
}
|
||||
if (!p)
|
||||
{
|
||||
log_debug ("bad filename `%s' returned for this process\n", dir);
|
||||
*dir = 0;
|
||||
|
@ -211,8 +296,17 @@ w32_commondir (void)
|
|||
|
||||
if (!dir)
|
||||
{
|
||||
const char *rdir;
|
||||
char path[MAX_PATH];
|
||||
|
||||
/* Make sure that w32_rootdir has been called so that we are
|
||||
able to check the portable application flag. The common dir
|
||||
is identical to the rootdir. In that case there is also no
|
||||
need to strdup its value. */
|
||||
rdir = w32_rootdir ();
|
||||
if (w32_portable_app)
|
||||
return rdir;
|
||||
|
||||
if (w32_shgetfolderpath (NULL, CSIDL_COMMON_APPDATA,
|
||||
NULL, 0, path) >= 0)
|
||||
{
|
||||
|
@ -226,7 +320,7 @@ w32_commondir (void)
|
|||
{
|
||||
/* Ooops: Not defined - probably an old Windows version.
|
||||
Use the installation directory instead. */
|
||||
dir = xstrdup (w32_rootdir ());
|
||||
dir = xstrdup (rdir);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -235,8 +329,6 @@ w32_commondir (void)
|
|||
#endif /*HAVE_W32_SYSTEM*/
|
||||
|
||||
|
||||
|
||||
|
||||
/* Return the name of the sysconfdir. This is a static string. This
|
||||
function is required because under Windows we can't simply compile
|
||||
it in. */
|
||||
|
@ -265,7 +357,19 @@ const char *
|
|||
gnupg_bindir (void)
|
||||
{
|
||||
#ifdef HAVE_W32_SYSTEM
|
||||
return w32_rootdir ();
|
||||
const char *rdir;
|
||||
|
||||
rdir = w32_rootdir ();
|
||||
if (w32_bin_is_bin)
|
||||
{
|
||||
static char *name;
|
||||
|
||||
if (!name)
|
||||
name = xstrconcat (rdir, DIRSEP_S "bin", NULL);
|
||||
return name;
|
||||
}
|
||||
else
|
||||
return rdir;
|
||||
#else /*!HAVE_W32_SYSTEM*/
|
||||
return GNUPG_BINDIR;
|
||||
#endif /*!HAVE_W32_SYSTEM*/
|
||||
|
@ -278,7 +382,7 @@ const char *
|
|||
gnupg_libexecdir (void)
|
||||
{
|
||||
#ifdef HAVE_W32_SYSTEM
|
||||
return w32_rootdir ();
|
||||
return gnupg_bindir ();
|
||||
#else /*!HAVE_W32_SYSTEM*/
|
||||
return GNUPG_LIBEXECDIR;
|
||||
#endif /*!HAVE_W32_SYSTEM*/
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue